From: FruitieX Date: Wed, 21 Jul 2010 11:13:43 +0000 (+0300) Subject: laser secondary gauntlet, lots of improvements to code X-Git-Tag: xonotic-v0.1.0preview~423^2~26^2~1 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=28da13b2d80022464d46a2cf38ad2c86b65d6876;p=xonotic%2Fxonotic-data.pk3dir.git laser secondary gauntlet, lots of improvements to code --- diff --git a/balanceFruit.cfg b/balanceFruit.cfg index ba90c56aa..a2bfdfb46 100644 --- a/balanceFruit.cfg +++ b/balanceFruit.cfg @@ -219,10 +219,10 @@ set g_balance_laser_primary_shotangle 0 set g_balance_laser_primary_delay 0 set g_balance_laser_primary_gauntlet 0 set g_balance_laser_secondary 1 // when 1, a secondary laser mode exists -set g_balance_laser_secondary_damage 7 +set g_balance_laser_secondary_damage 110 // dps set g_balance_laser_secondary_edgedamage 0 -set g_balance_laser_secondary_force 75 -set g_balance_laser_secondary_radius 10 +set g_balance_laser_secondary_force 500 +set g_balance_laser_secondary_radius 45 set g_balance_laser_secondary_speed 0 set g_balance_laser_secondary_spread 0 set g_balance_laser_secondary_refire 0.066 diff --git a/particles/gauntletbeam.tga b/particles/gauntletbeam.tga new file mode 100644 index 000000000..20a6ee5ae Binary files /dev/null and b/particles/gauntletbeam.tga differ diff --git a/qcsrc/client/Defs.qc b/qcsrc/client/Defs.qc index b1c423b25..1b019d5be 100644 --- a/qcsrc/client/Defs.qc +++ b/qcsrc/client/Defs.qc @@ -234,6 +234,7 @@ float tempdb; float ClientProgsDB; vector hook_shotorigin[4]; vector electro_shotorigin[4]; +vector gauntlet_shotorigin[4]; #ifdef BLURTEST float blurtest_time0, blurtest_time1, blurtest_radius, blurtest_power; diff --git a/qcsrc/client/Main.qc b/qcsrc/client/Main.qc index 14a213ef2..ed851b9c1 100644 --- a/qcsrc/client/Main.qc +++ b/qcsrc/client/Main.qc @@ -1031,6 +1031,10 @@ void Ent_Init() electro_shotorigin[1] = decompressShotOrigin(ReadInt24_t()); electro_shotorigin[2] = decompressShotOrigin(ReadInt24_t()); electro_shotorigin[3] = decompressShotOrigin(ReadInt24_t()); + gauntlet_shotorigin[0] = decompressShotOrigin(ReadInt24_t()); + gauntlet_shotorigin[1] = decompressShotOrigin(ReadInt24_t()); + gauntlet_shotorigin[2] = decompressShotOrigin(ReadInt24_t()); + gauntlet_shotorigin[3] = decompressShotOrigin(ReadInt24_t()); if(forcefog) strunzone(forcefog); diff --git a/qcsrc/client/hook.qc b/qcsrc/client/hook.qc index 8644847b3..9f690d5bc 100644 --- a/qcsrc/client/hook.qc +++ b/qcsrc/client/hook.qc @@ -6,6 +6,12 @@ .float LGBeamKillTime; .float LGBeamSound; .float LGBeamSilent; +.vector GauntletBeamStart; +.vector GauntletBeamEnd; +.float GauntletBeamKillTime; +.float GauntletBeamSound; +.float GauntletBeamSilent; + void Draw_CylindricLine(vector from, vector to, float thickness, string texture, float aspect, float shift, vector rgb, float alpha, float drawflag) { @@ -138,6 +144,38 @@ void Draw_GrapplingHook() setorigin(self, a); } + if(time < self.GauntletBeamKillTime) + { + s = cvar("cl_gunalign"); + if(s != 1 && s != 2 && s != 4) + s = 3; // default value + --s; + vs = gauntlet_shotorigin[s]; + + if(self.sv_entnum == player_localentnum - 1) + { + b = view_origin + view_forward * MAX_SHOT_DISTANCE; + WarpZone_TraceLine(view_origin, b, MOVE_NORMAL, world); + a = view_origin + view_forward * vs_x + view_right * -vs_y + view_up * vs_z; + } + else + { + a = self.GauntletBeamStart; + b = self.GauntletBeamEnd; + } + + tex = "particles/gauntletbeam"; + rgb = '1 1 1'; + + Draw_GrapplingHook_trace_callback_tex = tex; + Draw_GrapplingHook_trace_callback_rnd = random(); + WarpZone_TraceBox_ThroughZone(a, '0 0 0', '0 0 0', b, MOVE_NORMAL, world, world, Draw_GrapplingHook_trace_callback); + Draw_GrapplingHook_trace_callback_tex = string_null; + + // helps the sound + setorigin(self, a); + } + if(time < self.LGBeamKillTime && !self.LGBeamSilent) { if(!self.LGBeamSound) @@ -154,6 +192,23 @@ void Draw_GrapplingHook() self.LGBeamSound = 0; } } + + if(time < self.GauntletBeamKillTime && !self.GauntletBeamSilent) + { + if(!self.GauntletBeamSound) + { + sound (self, CHAN_PROJECTILE, "weapons/gauntletbeam_fly.wav", VOL_BASE, ATTN_NORM); + self.GauntletBeamSound = 1; + } + } + else + { + if(self.GauntletBeamSound) + { + sound (self, CHAN_PROJECTILE, "misc/null.wav", VOL_BASE, ATTN_NORM); + self.GauntletBeamSound = 0; + } + } } void Net_GrapplingHook() @@ -201,10 +256,18 @@ void Net_GrapplingHook() p.LGBeamSilent = 1; p.draw = Draw_GrapplingHook; break; + case 3: // gauntlet beam + p.GauntletBeamKillTime = time + 0.1; + p.GauntletBeamStart = start; + p.GauntletBeamEnd = end; + p.GauntletBeamSilent = 0; + p.draw = Draw_GrapplingHook; + break; } } void Hook_Precache() { precache_sound("weapons/lgbeam_fly.wav"); + precache_sound("weapons/gauntletbeam_fly.wav"); } diff --git a/qcsrc/server/cl_client.qc b/qcsrc/server/cl_client.qc index f4b83c5d8..fda3e902f 100644 --- a/qcsrc/server/cl_client.qc +++ b/qcsrc/server/cl_client.qc @@ -1071,6 +1071,10 @@ float ClientInit_SendEntity(entity to, float sf) WriteInt24_t(MSG_ENTITY, compressShotOrigin(electro_shotorigin[1])); WriteInt24_t(MSG_ENTITY, compressShotOrigin(electro_shotorigin[2])); WriteInt24_t(MSG_ENTITY, compressShotOrigin(electro_shotorigin[3])); + WriteInt24_t(MSG_ENTITY, compressShotOrigin(gauntlet_shotorigin[0])); + WriteInt24_t(MSG_ENTITY, compressShotOrigin(gauntlet_shotorigin[1])); + WriteInt24_t(MSG_ENTITY, compressShotOrigin(gauntlet_shotorigin[2])); + WriteInt24_t(MSG_ENTITY, compressShotOrigin(gauntlet_shotorigin[3])); if(sv_foginterval && world.fog != "") WriteString(MSG_ENTITY, world.fog); else diff --git a/qcsrc/server/g_world.qc b/qcsrc/server/g_world.qc index 020c24bb3..07898df16 100644 --- a/qcsrc/server/g_world.qc +++ b/qcsrc/server/g_world.qc @@ -513,6 +513,7 @@ void spawnfunc_worldspawn (void) readlevelcvars(); GrappleHookInit(); ElectroInit(); + LaserInit(); player_count = 0; bot_waypoints_for_items = cvar("g_waypoints_for_items"); diff --git a/qcsrc/server/progs.src b/qcsrc/server/progs.src index 929b0df20..adf4b4a1d 100644 --- a/qcsrc/server/progs.src +++ b/qcsrc/server/progs.src @@ -44,6 +44,7 @@ portals.qh g_hook.qh w_electro.qh +w_laser.qh scores.qh diff --git a/qcsrc/server/w_laser.qc b/qcsrc/server/w_laser.qc index c716ae1e6..8633297a1 100644 --- a/qcsrc/server/w_laser.qc +++ b/qcsrc/server/w_laser.qc @@ -101,32 +101,105 @@ void W_Laser_Attack (float issecondary) } } -void W_Laser_Attack2 (float issecondary) // gauntlet +.entity gauntletbeam; +.float prevgauntletfire; +void gauntletbeam_think() { - float damage, force, myradius; - if(issecondary) + float damage, myforce, myradius; + if(self.cnt) { damage = cvar("g_balance_laser_secondary_damage"); - force = cvar("g_balance_laser_secondary_force"); + myforce = cvar("g_balance_laser_secondary_force"); myradius = cvar("g_balance_laser_secondary_radius"); } else { damage = cvar("g_balance_laser_primary_damage"); - force = cvar("g_balance_laser_primary_force"); + myforce = cvar("g_balance_laser_primary_force"); myradius = cvar("g_balance_laser_primary_radius"); } - W_SetupShot (self, TRUE, 0, "weapons/gauntlet_fire.wav", damage); + self.owner.prevgauntletfire = time; + if (self.owner.weaponentity.state != WS_INUSE || self != self.owner.gauntletbeam || self.owner.deadflag != DEAD_NO || (!self.owner.BUTTON_ATCK2 && self.cnt) || (!self.owner.BUTTON_ATCK && !self.cnt)) + { + remove(self); + return; + } + + self.nextthink = time; + + makevectors(self.owner.v_angle); + vector angle; + angle = v_forward; + + WarpZone_traceline_antilag(self.owner, self.owner.origin + self.owner.view_ofs, self.owner.origin + self.owner.view_ofs + angle * myradius, FALSE, self.owner, ANTILAG_LATENCY(self.owner)); + + // apply the damage + if(trace_fraction < 1) + { + vector force; + force = angle * myforce; + Damage (trace_ent, self.owner, self.owner, damage * frametime, WEP_ELECTRO, trace_endpos, force * frametime); + } + + // draw effect + vector vecs, org; + if(self.owner.weaponentity.movedir_x > 0) + { + vecs = self.owner.weaponentity.movedir; + vecs_y = -vecs_y; + } + else + vecs = '0 0 0'; + org = self.owner.origin + self.owner.view_ofs + v_forward * vecs_x + v_right * vecs_y + v_up * vecs_z; + + // TODO turn into a csqc entity + WriteByte(MSG_BROADCAST, SVC_TEMPENTITY); + WriteByte(MSG_BROADCAST, TE_CSQC_BEAM); + WriteByte(MSG_BROADCAST, num_for_edict(self.owner)); + WriteByte(MSG_BROADCAST, 3); + WriteCoord(MSG_BROADCAST, trace_endpos_x); + WriteCoord(MSG_BROADCAST, trace_endpos_y); + WriteCoord(MSG_BROADCAST, trace_endpos_z); + WriteCoord(MSG_BROADCAST, org_x); + WriteCoord(MSG_BROADCAST, org_y); + WriteCoord(MSG_BROADCAST, org_z); +} + +// experimental gauntlet +void W_Laser_Attack2 (float issecondary) +{ + // only play fire sound if 0.5 sec has passed since player let go the fire button + if(time - self.prevgauntletfire > 0.5) + { + sound (self, CHAN_WEAPON, "weapons/gauntlet_fire.wav", VOL_BASE, ATTN_NORM); + } - WarpZone_traceline_antilag(self, w_shotorg, w_shotorg + w_shotdir * (myradius + vlen(eX * self.velocity_x + eY * self.velocity_y)/5), FALSE, self, ANTILAG_LATENCY(self)); + entity beam, oldself; - pointparticles(particleeffectnum("laser_gauntletmuzzleflash"), w_shotorg, w_shotdir * 1000, 1); - pointparticles(particleeffectnum("laser_gauntlet"), w_shotorg + w_shotdir * (myradius + vlen(eX * self.velocity_x + eY * self.velocity_y)/5), w_shotdir * 1000, 1); - pointparticles(particleeffectnum("laser_gauntlet"), w_shotorg + w_shotdir * (myradius + vlen(eX * self.velocity_x + eY * self.velocity_y)/5) * 0.5, w_shotdir * 1000, 1); + self.gauntletbeam = beam = spawn(); + beam.solid = SOLID_NOT; + beam.think = gauntletbeam_think; + beam.owner = self; + beam.movetype = MOVETYPE_NONE; + beam.shot_spread = 0; + beam.bot_dodge = TRUE; + beam.bot_dodgerating = cvar("g_balance_laser_primary_damage"); + beam.cnt = issecondary; - if (trace_fraction < 1) - Damage(trace_ent, self, self, damage, WEP_LASER | HITTYPE_SECONDARY, trace_endpos, cvar("g_balance_laser_primary_force") * w_shotdir); + oldself = self; + self = beam; + self.think(); + self = oldself; +} + +void LaserInit() +{ + weapon_action(WEP_LASER, WR_PRECACHE); + gauntlet_shotorigin[0] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_LASER), FALSE, FALSE, 1); + gauntlet_shotorigin[1] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_LASER), FALSE, FALSE, 2); + gauntlet_shotorigin[2] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_LASER), FALSE, FALSE, 3); + gauntlet_shotorigin[3] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_LASER), FALSE, FALSE, 4); } void spawnfunc_weapon_laser (void) diff --git a/qcsrc/server/w_laser.qh b/qcsrc/server/w_laser.qh new file mode 100644 index 000000000..0f2c13703 --- /dev/null +++ b/qcsrc/server/w_laser.qh @@ -0,0 +1,2 @@ +void LaserInit(); +vector gauntlet_shotorigin[4]; diff --git a/sound/weapons/gauntlet_fire.ogg b/sound/weapons/gauntlet_fire.ogg index 01906932c..03802f65d 100644 Binary files a/sound/weapons/gauntlet_fire.ogg and b/sound/weapons/gauntlet_fire.ogg differ diff --git a/sound/weapons/gauntletbeam_fly.ogg b/sound/weapons/gauntletbeam_fly.ogg new file mode 100644 index 000000000..874d246f5 Binary files /dev/null and b/sound/weapons/gauntletbeam_fly.ogg differ