]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/w_laser.qc
properly draw the hook through warpzones again too; fix interpolation issues
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / w_laser.qc
index 00e0fff7473e2444483c7faa9bd91033a17f7336..abf1a39ef962d966bcd1b56482f14db7f38bbcbe 100644 (file)
@@ -101,18 +101,133 @@ void W_Laser_Attack (float issecondary)
        }
 }
 
-void W_Laser_Attack2 (void) // gauntlet
+.vector hook_start, hook_end;
+float gauntletbeam_send(entity to, float sf)
 {
-       W_SetupShot (self, TRUE, 0, "weapons/gauntlet_fire.wav", cvar("g_balance_laser_primary_damage"));
+       WriteByte(MSG_ENTITY, ENT_CLIENT_GAUNTLET);
+       sf = sf & 0x7F;
+       if(sound_allowed(MSG_BROADCAST, self.owner))
+               sf |= 0x80;
+       WriteByte(MSG_ENTITY, sf);
+       if(sf & 1)
+       {
+               WriteByte(MSG_ENTITY, num_for_edict(self.owner));
+       }
+       if(sf & 2)
+       {
+               WriteCoord(MSG_ENTITY, self.hook_start_x);
+               WriteCoord(MSG_ENTITY, self.hook_start_y);
+               WriteCoord(MSG_ENTITY, self.hook_start_z);
+       }
+       if(sf & 4)
+       {
+               WriteCoord(MSG_ENTITY, self.hook_end_x);
+               WriteCoord(MSG_ENTITY, self.hook_end_y);
+               WriteCoord(MSG_ENTITY, self.hook_end_z);
+       }
+       return TRUE;
+}
+.entity gauntletbeam;
+.float prevgauntletfire;
+void gauntletbeam_think()
+{
+       vector endpos;
+       float damage, myforce, myradius;
+       if(self.cnt)
+       {
+               damage = cvar("g_balance_laser_secondary_damage");
+               myforce = cvar("g_balance_laser_secondary_force");
+               myradius = cvar("g_balance_laser_secondary_radius");
+       }
+       else
+       {
+               damage = cvar("g_balance_laser_primary_damage");
+               myforce = cvar("g_balance_laser_primary_force");
+               myradius = cvar("g_balance_laser_primary_radius");
+       }
+
+       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;
 
-       WarpZone_traceline_antilag(self, w_shotorg, w_shotorg + w_shotdir * (cvar("g_balance_laser_primary_radius") + vlen(eX * self.velocity_x + eY * self.velocity_y)/5), FALSE, self, ANTILAG_LATENCY(self));
+       makevectors(self.owner.v_angle);
+       vector angle;
+       angle = v_forward;
+       // get effect origin
+       vector vecs, org;
+       if(self.owner.weaponentity.movedir_x > 0)
+               vecs = self.owner.weaponentity.movedir;
+       else
+               vecs = '0 0 0';
+       if(debug_shotorg != '0 0 0')
+               vecs = debug_shotorg;
+       org = self.owner.origin + self.owner.view_ofs + v_forward * vecs_x + v_right * -vecs_y + v_up * vecs_z;
+       
+       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));
+       endpos = WarpZone_UnTransformOrigin(WarpZone_trace_transform, trace_endpos);
+       WarpZone_traceline_antilag(self.owner, org, endpos, 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
+       if(org != self.hook_start)
+       {
+               self.SendFlags |= 2;
+               self.hook_start = org;
+       }
+       if(endpos != self.hook_end)
+       {
+               self.SendFlags |= 4;
+               self.hook_end = endpos;
+       }
+}
+
+// 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);
+       }
 
-       pointparticles(particleeffectnum("laser_gauntletmuzzleflash"), w_shotorg, w_shotdir * 1000, 1);
-       pointparticles(particleeffectnum("laser_gauntlet"), w_shotorg + w_shotdir * (cvar("g_balance_laser_primary_radius") + vlen(eX * self.velocity_x + eY * self.velocity_y)/5), w_shotdir * 1000, 1);
-       pointparticles(particleeffectnum("laser_gauntlet"), w_shotorg + w_shotdir * (cvar("g_balance_laser_primary_radius") + vlen(eX * self.velocity_x + eY * self.velocity_y)/5) * 0.5, w_shotdir * 1000, 1);
+       entity beam, oldself;
 
-       if (trace_fraction < 1)
-               Damage(trace_ent, self, self, cvar("g_balance_laser_primary_damage"), WEP_LASER | HITTYPE_SECONDARY, trace_endpos, cvar("g_balance_laser_primary_force") * w_shotdir);
+       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;
+       Net_LinkEntity(beam, FALSE, 0, gauntletbeam_send);
+
+       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)
@@ -143,8 +258,8 @@ float w_laser(float req)
                if (self.BUTTON_ATCK)
                if (weapon_prepareattack(0, cvar("g_balance_laser_primary_refire")))
                {
-                       if(cvar("g_balance_laser_gauntlet"))
-                               W_Laser_Attack2();
+                       if(cvar("g_balance_laser_primary_gauntlet"))
+                               W_Laser_Attack2(0);
                        else
                                W_Laser_Attack(0);
                        weapon_thinkf(WFRAME_FIRE1, cvar("g_balance_laser_primary_animtime"), w_ready);
@@ -155,7 +270,10 @@ float w_laser(float req)
                        {
                                if (weapon_prepareattack(0, cvar("g_balance_laser_secondary_refire")))
                                {
-                                       W_Laser_Attack(1);
+                                       if(cvar("g_balance_laser_secondary_gauntlet"))
+                                               W_Laser_Attack2(1);
+                                       else
+                                               W_Laser_Attack(1);
                                        weapon_thinkf(WFRAME_FIRE2, cvar("g_balance_laser_secondary_animtime"), w_ready);
                                }
                        }