]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/mutators/mutator/mutator_nades.qc
Mutators: add hooks for overkill
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / mutators / mutator / mutator_nades.qc
index cc567d2b872ff5cd37198e2cb82e7127d3b418bc..9cfc2ec410ac1e5cc408148f739f4577e03a92ea 100644 (file)
@@ -26,6 +26,18 @@ void(entity player, float score) nades_GiveBonus;
 // Remove all bonus nades from a player
 void(entity player) nades_RemoveBonus;
 
+/**
+ * called to adjust nade damage and force on hit
+ */
+#define EV_Nade_Damage(i, o) \
+       /** weapon */ i(entity, MUTATOR_ARGV_0_entity) \
+    /** force */  i(vector, MUTATOR_ARGV_0_vector) \
+    /**/          o(vector, MUTATOR_ARGV_0_vector) \
+       /** damage */ i(float,  MUTATOR_ARGV_0_float) \
+    /**/          o(float,  MUTATOR_ARGV_0_float) \
+    /**/
+MUTATOR_HOOKABLE(Nade_Damage, EV_Nade_Damage);
+
 #endif
 #ifdef IMPLEMENTATION
 
@@ -64,15 +76,14 @@ void nade_timer_think()
 
 void nade_burn_spawn(entity _nade)
 {
-       CSQCProjectile(_nade, true, Nades[_nade.nade_type].m_projectile[true], true);
+       CSQCProjectile(_nade, true, Nades_from(_nade.nade_type).m_projectile[true], true);
 }
 
 void nade_spawn(entity _nade)
 {
-       entity timer = spawn();
+       entity timer = new(nade_timer);
        setmodel(timer, MDL_NADE_TIMER);
        setattachment(timer, _nade, "");
-       timer.classname = "nade_timer";
        timer.colormap = _nade.colormap;
        timer.glowmod = _nade.glowmod;
        timer.think = nade_timer_think;
@@ -83,7 +94,7 @@ void nade_spawn(entity _nade)
 
        _nade.effects |= EF_LOWPRECISION;
 
-       CSQCProjectile(_nade, true, Nades[_nade.nade_type].m_projectile[false], true);
+       CSQCProjectile(_nade, true, Nades_from(_nade.nade_type).m_projectile[false], true);
 }
 
 void napalm_damage(float dist, float damage, float edgedamage, float burntime)
@@ -164,11 +175,10 @@ void nade_napalm_ball()
 
        spamsound(self, CH_SHOTS, SND(FIREBALL_FIRE), VOL_BASE, ATTEN_NORM);
 
-       proj = spawn ();
+       proj = new(grenade);
        proj.owner = self.owner;
        proj.realowner = self.realowner;
        proj.team = self.owner.team;
-       proj.classname = "grenade";
        proj.bot_dodge = true;
        proj.bot_dodgerating = autocvar_g_nades_napalm_ball_damage;
        proj.movetype = MOVETYPE_BOUNCE;
@@ -360,10 +370,9 @@ void nade_ice_boom()
        if ( autocvar_g_nades_ice_explode )
        {
                setmodel(fountain, MDL_PROJECTILE_GRENADE);
-               entity timer = spawn();
+               entity timer = new(nade_timer);
                setmodel(timer, MDL_NADE_TIMER);
                setattachment(timer, fountain, "");
-               timer.classname = "nade_timer";
                timer.colormap = self.colormap;
                timer.glowmod = self.glowmod;
                timer.think = nade_timer_think;
@@ -513,7 +522,7 @@ void nade_boom()
        entity expef = NULL;
        bool nade_blast = true;
 
-       switch ( Nades[self.nade_type] )
+       switch ( Nades_from(self.nade_type) )
        {
                case NADE_TYPE_NAPALM:
                        nade_blast = autocvar_g_nades_napalm_blast;
@@ -565,7 +574,7 @@ void nade_boom()
        }
 
        if(self.takedamage)
-       switch ( Nades[self.nade_type] )
+       switch ( Nades_from(self.nade_type) )
        {
                case NADE_TYPE_NAPALM: nade_napalm_boom(); break;
                case NADE_TYPE_ICE: nade_ice_boom(); break;
@@ -633,35 +642,34 @@ void nade_damage(entity inflictor, entity attacker, float damage, int deathtype,
        if(self.nade_type == NADE_TYPE_TRANSLOCATE.m_id || self.nade_type == NADE_TYPE_SPAWN.m_id)
                return;
 
-       if(DEATH_ISWEAPON(deathtype, WEP_BLASTER))
+       if (MUTATOR_CALLHOOK(Nade_Damage, DEATH_WEAPONOF(deathtype), force, damage)) {}
+       else if(DEATH_ISWEAPON(deathtype, WEP_BLASTER))
        {
                force *= 1.5;
                damage = 0;
        }
-
-       if(DEATH_ISWEAPON(deathtype, WEP_VAPORIZER) && (deathtype & HITTYPE_SECONDARY))
+       else if(DEATH_ISWEAPON(deathtype, WEP_VAPORIZER) && (deathtype & HITTYPE_SECONDARY))
        {
                force *= 0.5; // too much
-               frag_damage = 0;
+               damage = 0;
        }
-
-       if(DEATH_ISWEAPON(deathtype, WEP_VORTEX) || DEATH_ISWEAPON(deathtype, WEP_VAPORIZER))
+       else if(DEATH_ISWEAPON(deathtype, WEP_VORTEX) || DEATH_ISWEAPON(deathtype, WEP_VAPORIZER))
        {
                force *= 6;
                damage = self.max_health * 0.55;
        }
-
-       if(DEATH_ISWEAPON(deathtype, WEP_MACHINEGUN) || DEATH_ISWEAPON(deathtype, WEP_HMG))
+       else if(DEATH_ISWEAPON(deathtype, WEP_MACHINEGUN))
                damage = self.max_health * 0.1;
-
-       if(DEATH_ISWEAPON(deathtype, WEP_SHOCKWAVE) || DEATH_ISWEAPON(deathtype, WEP_SHOTGUN)) // WEAPONTODO
-       if(deathtype & HITTYPE_SECONDARY)
+       else if(DEATH_ISWEAPON(deathtype, WEP_SHOCKWAVE) || DEATH_ISWEAPON(deathtype, WEP_SHOTGUN)) // WEAPONTODO
        {
-               damage = self.max_health * 0.1;
-               force *= 10;
+               if(deathtype & HITTYPE_SECONDARY)
+               {
+                       damage = self.max_health * 0.1;
+                       force *= 10;
+               }
+               else
+                       damage = self.max_health * 1.15;
        }
-       else
-               damage = self.max_health * 1.15;
 
        self.velocity += force;
        UpdateCSQCProjectile(self);
@@ -808,7 +816,7 @@ float nade_customize()
        {
                //self.effects = EF_ADDITIVE | EF_FULLBRIGHT | EF_LOWPRECISION;
                if(!self.traileffectnum)
-                       self.traileffectnum = _particleeffectnum(Nade_TrailEffect(Nades[self.nade_type].m_projectile[false], self.team).eent_eff_name);
+                       self.traileffectnum = _particleeffectnum(Nade_TrailEffect(Nades_from(self.nade_type).m_projectile[false], self.team).eent_eff_name);
                self.alpha = 1;
        }
 
@@ -827,10 +835,7 @@ void nade_prime()
        if(self.fake_nade)
                remove(self.fake_nade);
 
-       entity n = spawn(), fn = spawn();
-
-       n.classname = "nade";
-       fn.classname = "fake_nade";
+       entity n = new(nade), fn = new(fake_nade);
 
        if(self.items & ITEM_Strength.m_itemid && autocvar_g_nades_bonus_onstrength)
                n.nade_type = self.nade_type;
@@ -852,8 +857,8 @@ void nade_prime()
        //setattachment(n, self, "bip01 l hand");
        n.exteriormodeltoclient = self;
        n.customizeentityforclient = nade_customize;
-       n.traileffectnum = _particleeffectnum(Nade_TrailEffect(Nades[n.nade_type].m_projectile[false], self.team).eent_eff_name);
-       n.colormod = Nades[n.nade_type].m_color;
+       n.traileffectnum = _particleeffectnum(Nade_TrailEffect(Nades_from(n.nade_type).m_projectile[false], self.team).eent_eff_name);
+       n.colormod = Nades_from(n.nade_type).m_color;
        n.realowner = self;
        n.colormap = self.colormap;
        n.glowmod = self.glowmod;
@@ -864,10 +869,10 @@ void nade_prime()
        n.projectiledeathtype = DEATH_NADE.m_id;
 
        setmodel(fn, MDL_NADE_VIEW);
-       int slot = 0; // TODO: unhardcode
-       setattachment(fn, self.weaponentity[slot], "");
+       .entity weaponentity = weaponentities[0]; // TODO: unhardcode
+       setattachment(fn, self.(weaponentity), "");
        fn.realowner = fn.owner = self;
-       fn.colormod = Nades[n.nade_type].m_color;
+       fn.colormod = Nades_from(n.nade_type).m_color;
        fn.colormap = self.colormap;
        fn.glowmod = self.glowmod;
        fn.think = SUB_Remove;