]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/w_grenadelauncher.qc
give grenades a size too (6x6x6) like rockets;
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / w_grenadelauncher.qc
index a6e4d0dc0fc1cad0013db7639dcca143359aaf2b..64a987047c0307d0380e671d32910396b1faa33b 100644 (file)
@@ -13,6 +13,10 @@ void W_Grenade_Explode (void)
 
        self.event_damage = SUB_Null;
        self.takedamage = DAMAGE_NO;
+
+       if(self.movetype == MOVETYPE_NONE)
+               self.velocity = self.oldvelocity;
+
        RadiusDamage (self, self.owner, cvar("g_balance_grenadelauncher_primary_damage"), cvar("g_balance_grenadelauncher_primary_edgedamage"), cvar("g_balance_grenadelauncher_primary_radius"), world, cvar("g_balance_grenadelauncher_primary_force"), self.projectiledeathtype, other);
 
        remove (self);
@@ -28,6 +32,10 @@ void W_Grenade_Explode2 (void)
 
        self.event_damage = SUB_Null;
        self.takedamage = DAMAGE_NO;
+
+       if(self.movetype == MOVETYPE_NONE)
+               self.velocity = self.oldvelocity;
+
        RadiusDamage (self, self.owner, cvar("g_balance_grenadelauncher_secondary_damage"), cvar("g_balance_grenadelauncher_secondary_edgedamage"), cvar("g_balance_grenadelauncher_secondary_radius"), world, cvar("g_balance_grenadelauncher_secondary_force"), self.projectiledeathtype, other);
 
        remove (self);
@@ -49,37 +57,19 @@ void W_Grenade_Touch1 (void)
        PROJECTILE_TOUCH;
        if(cvar("g_balance_grenadelauncher_primary_sticky") && other.takedamage != DAMAGE_AIM)
        {
-               entity oldowner;
-               oldowner = self.owner;
-
-               vector temporigin;
-               temporigin = self.origin;
-
-               remove(self);
-               local entity gren;
+               spamsound (self, CHAN_PROJECTILE, "weapons/grenade_stick.wav", VOL_BASE, ATTN_NORM);
 
-               gren = spawn ();
-               gren.owner = oldowner;
-               gren.classname = "grenade";
-               gren.bot_dodge = TRUE;
-               gren.bot_dodgerating = cvar("g_balance_grenadelauncher_primary_damage");
-               gren.movetype = MOVETYPE_NONE;
-               PROJECTILE_MAKETRIGGER(gren);
-               gren.projectiledeathtype = WEP_GRENADE_LAUNCHER;
-               setorigin(gren, temporigin);
-               setsize(gren, '0 0 -3', '0 0 -3');
+               // let it stick whereever it is
+               self.oldvelocity = self.velocity;
+               self.velocity = '0 0 0';
+               self.movetype = MOVETYPE_NONE; // also disables gravity
+               self.gravity = 0; // nope, it does NOT! maybe a bug in CSQC code? TODO
+               UpdateCSQCProjectile(self);
 
-               gren.nextthink = time + cvar("g_balance_grenadelauncher_primary_lifetime2");
-               gren.think = adaptor_think2use_hittype_splash;
-               gren.use = W_Grenade_Explode;
+               // do not respond to any more touches
+               self.solid = SOLID_NOT;
 
-               gren.flags = FL_PROJECTILE;
-
-               gren.takedamage = DAMAGE_YES;
-               gren.health = cvar("g_balance_grenadelauncher_primary_health");
-               gren.event_damage = W_Grenade_Damage;
-
-               CSQCProjectile(gren, TRUE, PROJECTILE_GRENADE, TRUE);   
+               self.nextthink = min(self.nextthink, time + cvar("g_balance_grenadelauncher_primary_lifetime2"));
        }
        else
                W_Grenade_Explode ();
@@ -88,27 +78,46 @@ void W_Grenade_Touch1 (void)
 void W_Grenade_Touch2 (void)
 {
        PROJECTILE_TOUCH;
-       if (other.takedamage == DAMAGE_AIM)
+       if(cvar("g_balance_grenadelauncher_secondary_sticky") && other.takedamage != DAMAGE_AIM)
        {
-               self.use ();
+               spamsound (self, CHAN_PROJECTILE, "weapons/grenade_stick.wav", VOL_BASE, ATTN_NORM);
+
+               // let it stick whereever it is
+               self.oldvelocity = self.velocity;
+               self.velocity = '0 0 0';
+               self.movetype = MOVETYPE_NONE; // also disables gravity
+               self.gravity = 0; // nope, it does NOT! maybe a bug in CSQC code? TODO
+               UpdateCSQCProjectile(self);
+
+               // do not respond to any more touches
+               self.solid = SOLID_NOT;
+
+               self.nextthink = min(self.nextthink, time + cvar("g_balance_grenadelauncher_secondary_lifetime2"));
        }
        else
        {
-               float r;
-               r = random() * 6;
-               if(r < 1)
-                       spamsound (self, CHAN_PROJECTILE, "weapons/grenade_bounce1.wav", VOL_BASE, ATTN_NORM);
-               else if(r < 2)
-                       spamsound (self, CHAN_PROJECTILE, "weapons/grenade_bounce2.wav", VOL_BASE, ATTN_NORM);
-               else if(r < 3)
-                       spamsound (self, CHAN_PROJECTILE, "weapons/grenade_bounce3.wav", VOL_BASE, ATTN_NORM);
-               else if(r < 4)
-                       spamsound (self, CHAN_PROJECTILE, "weapons/grenade_bounce4.wav", VOL_BASE, ATTN_NORM);
-               else if(r < 5)
-                       spamsound (self, CHAN_PROJECTILE, "weapons/grenade_bounce5.wav", VOL_BASE, ATTN_NORM);
+               if (other.takedamage == DAMAGE_AIM)
+               {
+                       self.use ();
+               }
                else
-                       spamsound (self, CHAN_PROJECTILE, "weapons/grenade_bounce6.wav", VOL_BASE, ATTN_NORM);
-               self.projectiledeathtype |= HITTYPE_BOUNCE;
+               {
+                       float r;
+                       r = random() * 6;
+                       if(r < 1)
+                               spamsound (self, CHAN_PROJECTILE, "weapons/grenade_bounce1.wav", VOL_BASE, ATTN_NORM);
+                       else if(r < 2)
+                               spamsound (self, CHAN_PROJECTILE, "weapons/grenade_bounce2.wav", VOL_BASE, ATTN_NORM);
+                       else if(r < 3)
+                               spamsound (self, CHAN_PROJECTILE, "weapons/grenade_bounce3.wav", VOL_BASE, ATTN_NORM);
+                       else if(r < 4)
+                               spamsound (self, CHAN_PROJECTILE, "weapons/grenade_bounce4.wav", VOL_BASE, ATTN_NORM);
+                       else if(r < 5)
+                               spamsound (self, CHAN_PROJECTILE, "weapons/grenade_bounce5.wav", VOL_BASE, ATTN_NORM);
+                       else
+                               spamsound (self, CHAN_PROJECTILE, "weapons/grenade_bounce6.wav", VOL_BASE, ATTN_NORM);
+                       self.projectiledeathtype |= HITTYPE_BOUNCE;
+               }
        }
 }
 
@@ -118,7 +127,7 @@ void W_Grenade_Attack (void)
 
        if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
                self.ammo_rockets = self.ammo_rockets - cvar("g_balance_grenadelauncher_primary_ammo");
-       W_SetupShot_ProjectileSize (self, '0 0 -3', '0 0 -3', FALSE, 4, "weapons/grenade_fire.wav", cvar("g_balance_grenadelauncher_primary_damage"));
+       W_SetupShot_ProjectileSize (self, '-3 -3 -3', '3 3 3', FALSE, 4, "weapons/grenade_fire.wav", cvar("g_balance_grenadelauncher_primary_damage"));
        w_shotdir = v_forward; // no TrueAim for grenades please
 
        pointparticles(particleeffectnum("grenadelauncher_muzzleflash"), w_shotorg, w_shotdir * 1000, 1);
@@ -132,12 +141,16 @@ void W_Grenade_Attack (void)
        PROJECTILE_MAKETRIGGER(gren);
        gren.projectiledeathtype = WEP_GRENADE_LAUNCHER;
        setorigin(gren, w_shotorg);
-       setsize(gren, '0 0 -3', '0 0 -3');
+       setsize(gren, '-3 -3 -3', '3 3 3');
 
        gren.nextthink = time + cvar("g_balance_grenadelauncher_primary_lifetime");
        gren.think = adaptor_think2use_hittype_splash;
        gren.use = W_Grenade_Explode;
        gren.touch = W_Grenade_Touch1;
+
+       gren.takedamage = DAMAGE_YES;
+       gren.health = cvar("g_balance_grenadelauncher_primary_health");
+       gren.event_damage = W_Grenade_Damage;
        W_SETUPPROJECTILEVELOCITY_UP(gren, g_balance_grenadelauncher_primary);
 
        gren.angles = vectoangles (gren.velocity);
@@ -167,13 +180,14 @@ void W_Grenade_Attack2 (void)
        gren.bouncestop = cvar("g_balance_grenadelauncher_secondary_bouncestop");
        PROJECTILE_MAKETRIGGER(gren);
        gren.projectiledeathtype = WEP_GRENADE_LAUNCHER | HITTYPE_SECONDARY;
-       setsize(gren, '0 0 -3', '0 0 -3');
        setorigin(gren, w_shotorg);
+       setsize(gren, '-3 -3 -3', '3 3 3');
 
        gren.nextthink = time + cvar("g_balance_grenadelauncher_secondary_lifetime");
        gren.think = adaptor_think2use_hittype_splash;
        gren.use = W_Grenade_Explode2;
        gren.touch = W_Grenade_Touch2;
+
        gren.takedamage = DAMAGE_YES;
        gren.health = cvar("g_balance_grenadelauncher_secondary_health");
        gren.damageforcescale = cvar("g_balance_grenadelauncher_secondary_damageforcescale");
@@ -183,7 +197,10 @@ void W_Grenade_Attack2 (void)
        gren.angles = vectoangles (gren.velocity);
        gren.flags = FL_PROJECTILE;
 
-       CSQCProjectile(gren, TRUE, PROJECTILE_GRENADE_BOUNCING, TRUE);
+       if(cvar("g_balance_grenadelauncher_secondary_sticky"))
+               CSQCProjectile(gren, TRUE, PROJECTILE_GRENADE, TRUE);
+       else
+               CSQCProjectile(gren, TRUE, PROJECTILE_GRENADE_BOUNCING, TRUE);
 }
 
 void spawnfunc_weapon_grenadelauncher (void)
@@ -244,6 +261,7 @@ float w_glauncher(float req)
                precache_sound ("weapons/grenade_bounce4.wav");
                precache_sound ("weapons/grenade_bounce5.wav");
                precache_sound ("weapons/grenade_bounce6.wav");
+               precache_sound ("weapons/grenade_stick.wav");
                precache_sound ("weapons/grenade_fire.wav");
        }
        else if (req == WR_SETUP)
@@ -273,19 +291,19 @@ float w_glauncher(float req)
        else if (req == WR_SUICIDEMESSAGE)
        {
                if(w_deathtype & HITTYPE_SECONDARY)
-                       w_deathtypestring = "tried out his own grenade";
+                       w_deathtypestring = "%s tried out his own grenade";
                else
-                       w_deathtypestring = "detonated";
+                       w_deathtypestring = "%s detonated";
        }
        else if (req == WR_KILLMESSAGE)
        {
                if(w_deathtype & HITTYPE_SPLASH)
                        if(w_deathtype & HITTYPE_BOUNCE) // (must be secondary then)
-                               w_deathtypestring = "didn't see #'s grenade";
+                               w_deathtypestring = "%s didn't see %s's grenade";
                        else // unchecked: SECONDARY
-                               w_deathtypestring = "almost dodged #'s grenade";
+                               w_deathtypestring = "%s almost dodged %s's grenade";
                else // unchecked: SECONDARY, BOUNCE
-                       w_deathtypestring = "ate #'s grenade";
+                       w_deathtypestring = "%s ate %s's grenade";
        }
        return TRUE;
 }