]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/w_laser.qc
make weapon death messages translatable
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / w_laser.qc
index cdfdaa537c048af9fa45594d5334f35c256eda78..4ce1331931628366bfaf35037c429edfbbe7f3b4 100644 (file)
@@ -1,5 +1,5 @@
 #ifdef REGISTER_WEAPON
-REGISTER_WEAPON(LASER, w_laser, 0, 1, WEP_FLAG_NORMAL | WEP_FLAG_CANCLIMB | WEP_TYPE_SPLASH, 0, "laser", "laser", "Laser");
+REGISTER_WEAPON(LASER, w_laser, 0, 1, WEP_FLAG_NORMAL | WEP_FLAG_CANCLIMB | WEP_TYPE_SPLASH, 0, "laser", "laser", _("Laser"))
 #else
 #ifdef SVQC
 void(float imp) W_SwitchWeapon;
@@ -10,9 +10,9 @@ void W_Laser_Touch (void)
 
        self.event_damage = SUB_Null;
        if (self.dmg)
-               RadiusDamage (self, self.owner, cvar("g_balance_laser_secondary_damage"), cvar("g_balance_laser_secondary_edgedamage"), cvar("g_balance_laser_secondary_radius"), world, cvar("g_balance_laser_secondary_force"), self.projectiledeathtype, other);
+               RadiusDamage (self, self.owner, autocvar_g_balance_laser_secondary_damage, autocvar_g_balance_laser_secondary_edgedamage, autocvar_g_balance_laser_secondary_radius, world, autocvar_g_balance_laser_secondary_force, self.projectiledeathtype, other);
        else
-               RadiusDamage (self, self.owner, cvar("g_balance_laser_primary_damage"), cvar("g_balance_laser_primary_edgedamage"), cvar("g_balance_laser_primary_radius"), world, cvar("g_balance_laser_primary_force"), self.projectiledeathtype, other);
+               RadiusDamage (self, self.owner, autocvar_g_balance_laser_primary_damage, autocvar_g_balance_laser_primary_edgedamage, autocvar_g_balance_laser_primary_radius, world, autocvar_g_balance_laser_primary_force, self.projectiledeathtype, other);
 
        remove (self);
 }
@@ -22,9 +22,9 @@ void W_Laser_Think()
        self.movetype = MOVETYPE_FLY;
        self.think = SUB_Remove;
        if (self.dmg)
-               self.nextthink = time + cvar("g_balance_laser_secondary_lifetime");
+               self.nextthink = time + autocvar_g_balance_laser_secondary_lifetime;
        else
-               self.nextthink = time + cvar("g_balance_laser_primary_lifetime");
+               self.nextthink = time + autocvar_g_balance_laser_primary_lifetime;
        CSQCProjectile(self, TRUE, PROJECTILE_LASER, TRUE);
 }
 
@@ -40,45 +40,34 @@ void W_Laser_Attack (float issecondary)
        else
                nodamage = FALSE;
 
-       if (issecondary == 1)
-               a = cvar("g_balance_laser_secondary_shotangle");
-       else
-               a = cvar("g_balance_laser_primary_shotangle");
+       a = autocvar_g_balance_laser_primary_shotangle;
        s_forward = v_forward * cos(a * DEG2RAD) + v_up * sin(a * DEG2RAD);
 
        if(nodamage)
-               W_SetupShot_Dir (self, s_forward, FALSE, 3, "weapons/lasergun_fire.wav", 0);
+               W_SetupShot_Dir (self, s_forward, FALSE, 3, "weapons/lasergun_fire.wav", CHAN_WEAPON2, 0);
        else if(issecondary == 1)
-               W_SetupShot_Dir (self, s_forward, FALSE, 3, "weapons/lasergun_fire.wav", cvar("g_balance_laser_secondary_damage"));
+               W_SetupShot_Dir (self, s_forward, FALSE, 3, "weapons/lasergun_fire.wav", CHAN_WEAPON2, autocvar_g_balance_laser_secondary_damage);
        else
-               W_SetupShot_Dir (self, s_forward, FALSE, 3, "weapons/lasergun_fire.wav", cvar("g_balance_laser_primary_damage"));
+               W_SetupShot_Dir (self, s_forward, FALSE, 3, "weapons/lasergun_fire.wav", CHAN_WEAPON2, autocvar_g_balance_laser_primary_damage);
        pointparticles(particleeffectnum("laser_muzzleflash"), w_shotorg, w_shotdir * 1000, 1);
 
        missile = spawn ();
        missile.owner = self;
        missile.classname = "laserbolt";
-       missile.dmg = (issecondary == 1);
+       missile.dmg = 0;
        if(!nodamage)
        {
                missile.bot_dodge = TRUE;
-               if (issecondary == 1)
-                       missile.bot_dodgerating = cvar("g_balance_laser_secondary_damage");
-               else
-                       missile.bot_dodgerating = cvar("g_balance_laser_primary_damage");
+               missile.bot_dodgerating = autocvar_g_balance_laser_primary_damage;
        }
 
        PROJECTILE_MAKETRIGGER(missile);
        missile.projectiledeathtype = WEP_LASER;
-       if(issecondary == 1)
-               missile.projectiledeathtype |= HITTYPE_SECONDARY;
 
        setorigin (missile, w_shotorg);
        setsize(missile, '0 0 0', '0 0 0');
 
-       if (issecondary == 1)
-               W_SETUPPROJECTILEVELOCITY(missile, g_balance_laser_secondary);
-       else
-               W_SETUPPROJECTILEVELOCITY(missile, g_balance_laser_primary);
+       W_SETUPPROJECTILEVELOCITY(missile, g_balance_laser_primary);
        missile.angles = vectoangles (missile.velocity);
        //missile.glow_color = 250; // 244, 250
        //missile.glow_size = 120;
@@ -87,10 +76,10 @@ void W_Laser_Attack (float issecondary)
        missile.flags = FL_PROJECTILE;
 
        missile.think = W_Laser_Think;
-       if (issecondary == 1)
-               missile.nextthink = time + cvar("g_balance_laser_secondary_delay");
-       else
-               missile.nextthink = time + cvar("g_balance_laser_primary_delay");
+       missile.nextthink = time + autocvar_g_balance_laser_primary_delay;
+
+       other = missile; MUTATOR_CALLHOOK(EditProjectile);
+
        if(time >= missile.nextthink)
        {
                entity oldself;
@@ -101,16 +90,115 @@ void W_Laser_Attack (float issecondary)
        }
 }
 
-void W_Laser_Attack2 (void) // gauntlet
+.vector hook_start, hook_end;
+float gauntletbeam_send(entity to, float sf)
+{
+       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()
+{
+       float damage, myforce, myradius;
+       damage = autocvar_g_balance_laser_secondary_damage;
+       myforce = autocvar_g_balance_laser_secondary_force;
+       myradius = autocvar_g_balance_laser_secondary_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)
+       {
+               remove(self);
+               return;
+       }
+
+       self.nextthink = time;
+
+       makevectors(self.owner.v_angle);
+
+       float dt;
+       dt = frametime;
+
+       W_SetupShot_Range(self.owner, TRUE, 0, "", 0, damage * dt, myradius);
+       WarpZone_traceline_antilag(self.owner, w_shotorg, w_shotend, MOVE_NORMAL, self.owner, ANTILAG_LATENCY(self.owner));
+
+       // apply the damage
+       if(trace_ent)
+       {
+               vector force;
+               force = w_shotdir * myforce;
+               if(accuracy_isgooddamage(self.owner, trace_ent))
+                       accuracy_add(self.owner, WEP_LASER, 0, damage * dt);
+               Damage (trace_ent, self.owner, self.owner, damage * dt, WEP_LASER | HITTYPE_SECONDARY, trace_endpos, force * dt);
+       }
+
+       // draw effect
+       if(w_shotorg != self.hook_start)
+       {
+               self.SendFlags |= 2;
+               self.hook_start = w_shotorg;
+       }
+       if(w_shotend != self.hook_end)
+       {
+               self.SendFlags |= 4;
+               self.hook_end = w_shotend;
+       }
+}
+
+// experimental gauntlet
+void W_Laser_Attack2 ()
 {
-       W_SetupShot (self, TRUE, 0, "weapons/gauntlet_fire.wav", cvar("g_balance_laser_primary_damage"));
+       // 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 * cvar("g_balance_laser_primary_radius"), FALSE, self, ANTILAG_LATENCY(self));
+       entity beam, oldself;
 
-       pointparticles(particleeffectnum("laser_gauntlet"), w_shotorg + w_shotdir * cvar("g_balance_laser_primary_radius"), '0 0 0', 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 = autocvar_g_balance_laser_primary_damage;
+       Net_LinkEntity(beam, FALSE, 0, gauntletbeam_send);
 
-       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);
+       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)
@@ -124,37 +212,34 @@ float w_laser(float req)
        local float r2;
        if (req == WR_AIM)
        {
-               if(cvar("g_balance_laser_secondary"))
+               if(autocvar_g_balance_laser_secondary)
                {
-                       r1 = cvar("g_balance_laser_primary_damage");
-                       r2 = cvar("g_balance_laser_secondary_damage");
+                       r1 = autocvar_g_balance_laser_primary_damage;
+                       r2 = autocvar_g_balance_laser_secondary_damage;
                        if (random() * (r2 + r1) > r1)
-                               self.BUTTON_ATCK2 = bot_aim(cvar("g_balance_laser_secondary_speed"), 0, cvar("g_balance_laser_secondary_lifetime"), FALSE);
+                               self.BUTTON_ATCK2 = bot_aim(autocvar_g_balance_laser_secondary_speed, 0, autocvar_g_balance_laser_secondary_lifetime, FALSE);
                        else
-                               self.BUTTON_ATCK = bot_aim(cvar("g_balance_laser_primary_speed"), 0, cvar("g_balance_laser_primary_lifetime"), FALSE);
+                               self.BUTTON_ATCK = bot_aim(autocvar_g_balance_laser_primary_speed, 0, autocvar_g_balance_laser_primary_lifetime, FALSE);
                }
                else
-                       self.BUTTON_ATCK = bot_aim(cvar("g_balance_laser_primary_speed"), 0, cvar("g_balance_laser_primary_lifetime"), FALSE);
+                       self.BUTTON_ATCK = bot_aim(autocvar_g_balance_laser_primary_speed, 0, autocvar_g_balance_laser_primary_lifetime, FALSE);
        }
        else if (req == WR_THINK)
        {
                if (self.BUTTON_ATCK)
-               if (weapon_prepareattack(0, cvar("g_balance_laser_primary_refire")))
+               if (weapon_prepareattack(0, autocvar_g_balance_laser_primary_refire))
                {
-                       if(cvar("g_balance_laser_gauntlet"))
-                               W_Laser_Attack2();
-                       else
-                               W_Laser_Attack(0);
-                       weapon_thinkf(WFRAME_FIRE1, cvar("g_balance_laser_primary_animtime"), w_ready);
+                       W_Laser_Attack(0);
+                       weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_laser_primary_animtime, w_ready);
                }
                if (self.BUTTON_ATCK2)
                {
-                       if(cvar("g_balance_laser_secondary"))
+                       if(autocvar_g_balance_laser_secondary)
                        {
-                               if (weapon_prepareattack(0, cvar("g_balance_laser_secondary_refire")))
+                               if (weapon_prepareattack(0, 0))
                                {
-                                       W_Laser_Attack(1);
-                                       weapon_thinkf(WFRAME_FIRE2, cvar("g_balance_laser_secondary_animtime"), w_ready);
+                                       W_Laser_Attack2();
+                                       weapon_thinkf(WFRAME_FIRE2, autocvar_g_balance_laser_secondary_animtime, w_ready);
                                }
                        }
                        else
@@ -197,10 +282,13 @@ float w_laser(float req)
                precache_sound("weapons/laserimpact.wav");
        }
        else if (req == WR_SUICIDEMESSAGE)
-               w_deathtypestring = "lasered themself to hell";
+               w_deathtypestring = _("%s lasered themself to hell");
        else if (req == WR_KILLMESSAGE)
        {
-               w_deathtypestring = "was lasered to death by"; // unchecked: SPLASH
+               if(w_deathtype & HITTYPE_SECONDARY)
+                       w_deathtypestring = _("%s was cut in half by %s's gauntlet"); // unchecked: SPLASH
+               else
+                       w_deathtypestring = _("%s was lasered to death by %s"); // unchecked: SPLASH
        }
        return TRUE;
 }