diff --git a/src/shared/player.qc b/src/shared/player.qc index 558dde3..34fa846 100644 --- a/src/shared/player.qc +++ b/src/shared/player.qc @@ -140,6 +140,7 @@ class player:NSClientPlayer float m_invulnFinishTime; float m_enviroFinishTime; float m_megaHealthTime; + float m_lightningTime; #endif virtual void Physics_Jump(void); diff --git a/src/shared/w_lightning.qc b/src/shared/w_lightning.qc index 7656f15..a956c8c 100644 --- a/src/shared/w_lightning.qc +++ b/src/shared/w_lightning.qc @@ -23,6 +23,107 @@ Crossbow Weapon */ +#ifdef CLIENT + + +#define LIGHTNINGBEAM_COUNT 16 +string g_lightning_beamtex; + +static float lightning_jitlut[BEAM_COUNT] = { + 0.000000, + 0.195090, + 0.382683, + 0.555570, + 0.707106, + 0.831469, + 0.923879, + 0.980785, + 1.000000, + 0.980786, + 0.923880, + 0.831471, + 0.707108, + 0.555572, + 0.382685, + 0.000000, +}; + +void +w_lightning_renderbeam(string spriteFrame, vector startOrg, vector endOrg, float beamWidth, float beamAmp, vector colorTint, float timeScale, float seedValue) +{ +#if 1 + vector vecPlayer; + NSClientPlayer pl; + + #define RANDOMNUM seedValue + + int s = (float)getproperty(VF_ACTIVESEAT); + pSeat = &g_seats[s]; + pl = (NSClientPlayer)pSeat->m_ePlayer; + vecPlayer = pl.GetEyePos(); + + if (spriteFrame) { + float last_progression = 0.0f; + makevectors(g_view.GetCameraAngle()); + setproperty(VF_ORIGIN, vecPlayer); + R_BeginPolygon(spriteFrame, DRAWFLAG_ADDITIVE, 0); + + for (float i = 0; i < LIGHTNINGBEAM_COUNT; i++) { + float progression = (i / (LIGHTNINGBEAM_COUNT-1)); + vector point; + vector jitter; + float a = 1.0f; + + /* our steps from a - b */ + point[0] = Math_Lerp(startOrg[0], endOrg[0], progression); + point[1] = Math_Lerp(startOrg[1], endOrg[1], progression); + point[2] = Math_Lerp(startOrg[2], endOrg[2], progression); + + /* get the direction the beam is 'looking' */ + makevectors(vectoangles(endOrg - startOrg)); + + /* nudge it a lil bit up/down left/right from its trajectory */ + /* these are all randomly chosen constants */ + jitter = v_right * (pseudorand((timeScale * time) + i + RANDOMNUM) - 0.5); + jitter += v_up * (pseudorand((timeScale * time) + i + 64.12 + RANDOMNUM) - 0.5); + jitter += v_right * (pseudorand(100 + ((timeScale*2) * time) + i + RANDOMNUM) - 0.5); + jitter += v_up * (pseudorand(100 + ((timeScale*2) * time) + i + 25.4 + RANDOMNUM) - 0.5); + jitter *= beamAmp; + + /* start/end points get less jittery the closer we get*/ + jitter *= lightning_jitlut[i]; + + /* apply jitter */ + point += jitter; + + R_PolygonVertex(point, [1, 0], colorTint, a); + + if (autocvar(cl_showoff, 0)) + dynamiclight_add(point, 150, [0.25, 0.25, 1.0]); + + + last_progression = progression; + } + + R_EndPolygonRibbon(beamWidth, [-1,0]); + } +#else + vector vecPlayer; + NSClientPlayer pl; + int s = (float)getproperty(VF_ACTIVESEAT); + pSeat = &g_seats[s]; + pl = (NSClientPlayer)pSeat->m_ePlayer; + vecPlayer = pl.GetEyePos(); + makevectors(g_view.GetCameraAngle()); + setproperty(VF_ORIGIN, vecPlayer); + R_BeginPolygon(spriteFrame, DRAWFLAG_ADDITIVE, 0); + R_PolygonVertex(startOrg, [1, 0], colorTint, 1.0); + R_PolygonVertex(endOrg, [1, 0], colorTint, 1.0); + R_EndPolygonRibbon(4, [-1,0]); +#endif +} +#endif + enum { LIGHTNING_IDLE, @@ -34,8 +135,10 @@ w_lightning_precache(void) { #ifdef SERVER Sound_Precache("weapon_lightning.start"); + Sound_Precache("weapon_lightning.shaft"); precache_model("models/g_light.mdl"); #else + g_lightning_beamtex = spriteframe("sprites/lgtning.spr", 0, 0.0f); precache_model("models/v_light.mdl"); precache_model("models/p_light.mdl"); #endif @@ -102,7 +205,9 @@ w_lightning_primary(player pl) #ifdef SERVER { if (pl.WaterLevel() > 1) { - // we're underwater... fry everyone */ + // we're underwater... fry everyone (around us) */ + float lightDmg = (float)pl.ammo_cells * 35.0f; + Damage_Radius(self.origin, self, lightDmg, lightDmg + 40, TRUE, WEAPON_LIGHTNING); } else { vector startPos = Weapons_GetCameraPos(pl); Weapons_MakeVectors(pl); @@ -134,7 +239,15 @@ w_lightning_primary(player pl) if (pl.HasQuadDamage()) { Sound_Play(pl, CHAN_ITEM, "item_artifact_super_damage.attack"); } - Sound_Play(pl, CHAN_WEAPON, "weapon_lightning.start"); + + if (!(pl.gflags & GF_EGONBEAM)) + Sound_Play(pl, CHAN_WEAPON, "weapon_lightning.start"); + else { + if (pl.m_lightningTime < time) { + Sound_Play(pl, CHAN_WEAPON, "weapon_lightning.shaft"); + pl.m_lightningTime = time + 0.6f; + } + } #endif Weapons_ViewAnimation(pl, LIGHTNING_SHOOT); @@ -143,6 +256,7 @@ w_lightning_primary(player pl) Weapons_ViewPunchAngle(pl, [-2,0,0]); pl.w_attack_next = 0.1f; + pl.gflags |= GF_EGONBEAM; } void @@ -210,6 +324,49 @@ w_lightning_type(player pl) return WPNTYPE_RANGED; } +void +w_lightning_postdraw(player pl, int thirdperson) +{ +#ifdef CLIENT + if (!(pl.gflags & GF_EGONBEAM)) + return; + + vector src; + vector endpos; + + if (thirdperson) { + makevectors(pl.v_angle); + src = pl.origin; + endpos = pl.origin + (v_forward * 1024); + traceline(src, endpos, MOVE_NORMAL, pl); + //w_lightning_beamfx(gettaginfo(pl.p_model, 10), trace_endpos, pl); + w_lightning_renderbeam(g_lightning_beamtex, gettaginfo(pl.p_model, 10), trace_endpos, trace_fraction * 32, trace_fraction * 48.0, [1,1,1], 60.0f, 12516); + } else { + vector gunpos = gettaginfo(pSeat->m_eViewModel, 33); + src = pl.GetEyePos(); + makevectors(view_angles); + gunpos += (v_up * -16) + (v_forward * 42); + endpos = src + v_forward * 1024; + traceline(src, endpos, FALSE, pl); + endpos = trace_endpos; + //w_lightning_beamfx(gunpos, endpos, pl); + w_lightning_renderbeam(g_lightning_beamtex, gunpos, endpos, trace_fraction * 32, trace_fraction * 48.0, [1,1,1], 60.0f, 125156); + } + + int i = (cltime*10.0f) % 11.0f; + vector fsize = [32,32]; + makevectors(view_angles); + trace_endpos += v_forward * -16; /* nudge towards our camera */ + dynamiclight_add(trace_endpos, 128, [0.5, 0.5, 1.0]); +#endif +} + +void +w_lightning_release(player pl) +{ + pl.gflags &= ~GF_EGONBEAM; +} + weapon_t w_lightning = { .name = "lightning", @@ -222,7 +379,7 @@ weapon_t w_lightning = .primary = w_lightning_primary, .secondary = __NULL__, .reload = __NULL__, - .release = __NULL__, + .release = w_lightning_release, .postdraw = w_lightning_crosshair, .precache = w_lightning_precache, .pickup = w_lightning_pickup, @@ -233,7 +390,8 @@ weapon_t w_lightning = .aimanim = w_lightning_aimanim, .isempty = w_lightning_isempty, .type = w_lightning_type, - .hudpic = w_lightning_hudpic + .hudpic = w_lightning_hudpic, + .predraw = w_lightning_postdraw }; #ifdef SERVER diff --git a/zpak001.pk3dir/sound/weapons_dmc.sndshd b/zpak001.pk3dir/sound/weapons_dmc.sndshd index 48986b9..0ea7696 100644 --- a/zpak001.pk3dir/sound/weapons_dmc.sndshd +++ b/zpak001.pk3dir/sound/weapons_dmc.sndshd @@ -62,4 +62,10 @@ weapon_lightning.start { alerts sample weapons/lstart.wav +} + +weapon_lightning.shaft +{ + alerts + sample weapons/lhit.wav } \ No newline at end of file