]> git.rm.cloudns.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Implement TakeResource
authorMario <mario@smbclan.net>
Sat, 16 Jun 2018 18:06:30 +0000 (04:06 +1000)
committerMario <mario@smbclan.net>
Sat, 16 Jun 2018 18:06:30 +0000 (04:06 +1000)
31 files changed:
qcsrc/client/resources.qc
qcsrc/client/resources.qh
qcsrc/common/gamemodes/gamemode/assault/assault.qc
qcsrc/common/gamemodes/gamemode/ctf/ctf.qc
qcsrc/common/gamemodes/gamemode/onslaught/sv_onslaught.qc
qcsrc/common/mapobjects/func/breakable.qc
qcsrc/common/mapobjects/func/button.qc
qcsrc/common/mapobjects/func/door.qc
qcsrc/common/mapobjects/trigger/multi.qc
qcsrc/common/mapobjects/trigger/swamp.qc
qcsrc/common/monsters/monster/shambler.qc
qcsrc/common/monsters/sv_monsters.qc
qcsrc/common/mutators/mutator/overkill/okrpc.qc
qcsrc/common/turrets/sv_turrets.qc
qcsrc/common/turrets/turret/walker.qc
qcsrc/common/vehicles/sv_vehicles.qc
qcsrc/common/vehicles/vehicle/raptor_weapons.qc
qcsrc/common/weapons/weapon/arc.qc
qcsrc/common/weapons/weapon/devastator.qc
qcsrc/common/weapons/weapon/electro.qc
qcsrc/common/weapons/weapon/fireball.qc
qcsrc/common/weapons/weapon/hagar.qc
qcsrc/common/weapons/weapon/minelayer.qc
qcsrc/common/weapons/weapon/mortar.qc
qcsrc/common/weapons/weapon/seeker.qc
qcsrc/server/g_hook.qc
qcsrc/server/mutators/events.qh
qcsrc/server/player.qc
qcsrc/server/portals.qc
qcsrc/server/resources.qc
qcsrc/server/resources.qh

index 1dbbe6646a7f72873acc0f30077c862c22a5d6ff..29a9cae1bb2dc9145a5b10148485042de85e0e26 100644 (file)
@@ -26,6 +26,31 @@ void SetResourceAmount(entity e, int resource_type, float amount)
        SetResourceAmountExplicit(e, resource_type, amount);
 }
 
+void TakeResource(entity receiver, int resource_type, float amount)
+{
+       if (amount == 0)
+       {
+               return;
+       }
+       SetResourceAmount(receiver, resource_type,
+               GetResourceAmount(receiver, resource_type) - amount);
+}
+
+void TakeResourceWithLimit(entity receiver, int resource_type, float amount,
+       float limit)
+{
+       if (amount == 0)
+       {
+               return;
+       }
+       float current_amount = GetResourceAmount(receiver, resource_type);
+       if (current_amount - amount < limit)
+       {
+               amount = limit + current_amount;
+       }
+       TakeResource(receiver, resource_type, amount);
+}
+
 int GetResourceType(.float resource_field)
 {
        switch (resource_field)
index 196ccf05dbaa1c87b150edddcea48b6ec100a2a2..6d4f46ed2f44143acef17fcf3fc3a4452befe36a 100644 (file)
@@ -28,6 +28,22 @@ bool SetResourceAmountExplicit(entity e, int resource_type, float amount);
 /// \return No return.
 void SetResourceAmount(entity e, int resource_type, float amount);
 
+/// \brief Takes an entity some resource.
+/// \param[in,out] receiver Entity to take resource from.
+/// \param[in] resource_type Type of the resource (a RESOURCE_* constant).
+/// \param[in] amount Amount of resource to take.
+/// \return No return.
+void TakeResource(entity receiver, int resource_type, float amount);
+
+/// \brief Takes an entity some resource but not less than a limit.
+/// \param[in,out] receiver Entity to take resource from.
+/// \param[in] resource_type Type of the resource (a RESOURCE_* constant).
+/// \param[in] amount Amount of resource to take.
+/// \param[in] limit Limit of resources to take.
+/// \return No return.
+void TakeResourceWithLimit(entity receiver, int resource_type, float amount,
+       float limit);
+
 // ===================== Legacy and/or internal API ===========================
 
 /// \brief Converts an entity field to resource type.
index 43a4e302e86d30d776426345a8c4d5e6a3948099..97a7b4df28d0a77c03c3e0c04d489d7c244d5543 100644 (file)
@@ -66,7 +66,7 @@ void assault_objective_decrease_use(entity this, entity actor, entity trigger)
                if(GetResourceAmount(this.enemy, RESOURCE_HEALTH) - this.dmg > 0.5)
                {
                        GameRules_scoring_add_team(actor, SCORE, this.dmg);
-                       SetResourceAmountExplicit(this.enemy, RESOURCE_HEALTH, GetResourceAmount(this.enemy, RESOURCE_HEALTH) - this.dmg);
+                       TakeResource(this.enemy, RESOURCE_HEALTH, this.dmg);
                }
                else
                {
index 6c6cf86ae206d576c118676a25c5369fa5c58ede..3f96b41142f162360dac01cf770a52b24391653f 100644 (file)
@@ -883,7 +883,7 @@ void ctf_FlagDamage(entity this, entity inflictor, entity attacker, float damage
        if(autocvar_g_ctf_flag_return_damage)
        {
                // reduce health and check if it should be returned
-               SetResourceAmountExplicit(this, RESOURCE_HEALTH, GetResourceAmount(this, RESOURCE_HEALTH) - damage);
+               TakeResource(this, RESOURCE_HEALTH, damage);
                ctf_CheckFlagReturn(this, RETURN_DAMAGE);
                return;
        }
@@ -953,13 +953,13 @@ void ctf_FlagThink(entity this)
                        }
                        if(this.ctf_flagdamaged_byworld)
                        {
-                               SetResourceAmountExplicit(this, RESOURCE_HEALTH, GetResourceAmount(this, RESOURCE_HEALTH) - ((this.max_flag_health / autocvar_g_ctf_flag_return_damage_delay) * FLAG_THINKRATE));
+                               TakeResource(this, RESOURCE_HEALTH, ((this.max_flag_health / autocvar_g_ctf_flag_return_damage_delay) * FLAG_THINKRATE));
                                ctf_CheckFlagReturn(this, RETURN_NEEDKILL);
                                return;
                        }
                        else if(autocvar_g_ctf_flag_return_time)
                        {
-                               SetResourceAmountExplicit(this, RESOURCE_HEALTH, GetResourceAmount(this, RESOURCE_HEALTH) - ((this.max_flag_health / autocvar_g_ctf_flag_return_time) * FLAG_THINKRATE));
+                               TakeResource(this, RESOURCE_HEALTH, ((this.max_flag_health / autocvar_g_ctf_flag_return_time) * FLAG_THINKRATE));
                                ctf_CheckFlagReturn(this, RETURN_TIMEOUT);
                                return;
                        }
index 5436a49d84047da94436f59d31943568866cae08..2157770cf7a0670345d157bce2c2432da5d7a24a 100644 (file)
@@ -400,7 +400,7 @@ void ons_ControlPoint_Icon_Damage(entity this, entity inflictor, entity attacker
                ons_notification_time[this.team] = time;
        }
 
-       SetResourceAmountExplicit(this, RESOURCE_HEALTH, GetResourceAmount(this, RESOURCE_HEALTH) - damage);
+       TakeResource(this, RESOURCE_HEALTH, damage);
        if(this.owner.iscaptured)
                WaypointSprite_UpdateHealth(this.owner.sprite, GetResourceAmount(this, RESOURCE_HEALTH));
        else
@@ -482,9 +482,7 @@ void ons_ControlPoint_Icon_Think(entity this)
        {
                if(GetResourceAmount(this, RESOURCE_HEALTH) < this.max_health)
                {
-                       SetResourceAmountExplicit(this, RESOURCE_HEALTH, GetResourceAmount(this, RESOURCE_HEALTH) + this.count);
-                       if (GetResourceAmount(this, RESOURCE_HEALTH) >= this.max_health)
-                               SetResourceAmountExplicit(this, RESOURCE_HEALTH, this.max_health);
+                       GiveResourceWithLimit(this, RESOURCE_HEALTH, this.count, this.max_health);
                        WaypointSprite_UpdateHealth(this.owner.sprite, GetResourceAmount(this, RESOURCE_HEALTH));
                }
        }
@@ -889,7 +887,7 @@ void ons_GeneratorDamage(entity this, entity inflictor, entity attacker, float d
                        play2team(this.team, SND(ONS_GENERATOR_UNDERATTACK));
                }
        }
-       SetResourceAmountExplicit(this, RESOURCE_HEALTH, GetResourceAmount(this, RESOURCE_HEALTH) - damage);
+       TakeResource(this, RESOURCE_HEALTH, damage);
        WaypointSprite_UpdateHealth(this.sprite, GetResourceAmount(this, RESOURCE_HEALTH));
        // choose an animation frame based on health
        this.frame = 10 * bound(0, (1 - GetResourceAmount(this, RESOURCE_HEALTH) / this.max_health), 1);
index 05d643b464b465b2de8d33151f818c5247bc0815..cb17ac442cb4244aa71b708e6c7c27deaf220bb4 100644 (file)
@@ -272,7 +272,7 @@ void func_breakable_damage(entity this, entity inflictor, entity attacker, float
                if(attacker.team == this.team)
                        return;
        this.pain_finished = time;
-       SetResourceAmountExplicit(this, RESOURCE_HEALTH, GetResourceAmount(this, RESOURCE_HEALTH) - damage);
+       TakeResource(this, RESOURCE_HEALTH, damage);
        if(this.sprite)
        {
                WaypointSprite_Ping(this.sprite);
index 4d9c93fd0de76cfdceb0cc7bae24e23990008c9a..44e31284336aae99eb35f580dff390b5db98797b 100644 (file)
@@ -104,7 +104,7 @@ void button_damage(entity this, entity inflictor, entity attacker, float damage,
        }
        else
        {
-               SetResourceAmountExplicit(this, RESOURCE_HEALTH, GetResourceAmount(this, RESOURCE_HEALTH) - damage);
+               TakeResource(this, RESOURCE_HEALTH, damage);
                if (GetResourceAmount(this, RESOURCE_HEALTH) <= 0)
                {
                        this.enemy = attacker;
index 4cb924bd6ab9db9fc417f91702b3cb13ccf4605b..8d40a377be081fbc583f3adef2486a129530d694 100644 (file)
@@ -265,7 +265,7 @@ void door_damage(entity this, entity inflictor, entity attacker, float damage, i
        if(this.spawnflags & NOSPLASH)
                if(!(DEATH_ISSPECIAL(deathtype)) && (deathtype & HITTYPE_SPLASH))
                        return;
-       SetResourceAmountExplicit(this, RESOURCE_HEALTH, GetResourceAmount(this, RESOURCE_HEALTH) - damage);
+       TakeResource(this, RESOURCE_HEALTH, damage);
 
        if (this.itemkeys)
        {
index 31be111dbda8779516305b4fb0fcc8c0610c841f..5447b992c373e1c1694b7e5bacb926cd8953f2e9 100644 (file)
@@ -120,7 +120,7 @@ void multi_eventdamage(entity this, entity inflictor, entity attacker, float dam
        if(this.team)
                if(((this.spawnflags & INVERT_TEAMS) == 0) == (this.team != attacker.team))
                        return;
-       SetResourceAmountExplicit(this, RESOURCE_HEALTH, GetResourceAmount(this, RESOURCE_HEALTH) - damage);
+       TakeResource(this, RESOURCE_HEALTH, damage);
        if (GetResourceAmount(this, RESOURCE_HEALTH) <= 0)
        {
                this.enemy = attacker;
index fd40e2f34db29d4a04e88dd69074742da043cfd8..8e3fd739de5694b34dd563a999707de4544fc45f 100644 (file)
@@ -18,6 +18,7 @@
 
 .float swamp_interval; //Hurt players in swamp with this interval
 .float swamp_slowdown; //Players in swamp get slowd down by this mutch 0-1 is slowdown 1-~ is speedup (!?)
+.float swamp_lifetime;  // holds the points remaining until slug dies (not quite health!) 
 .entity swampslug;
 
 #ifdef SVQC
@@ -40,7 +41,7 @@ void swampslug_think(entity this);
 void swampslug_think(entity this)
 {
        //Slowly kill the slug
-       SetResourceAmountExplicit(this, RESOURCE_HEALTH, GetResourceAmount(this, RESOURCE_HEALTH) - 1);
+       this.swamp_lifetime -= 1;
 
        //Slug dead? then remove curses.
        if(GetResourceAmount(this, RESOURCE_HEALTH) <= 0)
@@ -76,7 +77,7 @@ void swamp_touch(entity this, entity toucher)
                // If not attach one.
                //centerprint(toucher,"Entering swamp!\n");
                toucher.swampslug = spawn();
-               SetResourceAmountExplicit(toucher.swampslug, RESOURCE_HEALTH, 2);
+               toucher.swampslug.swamp_lifetime = 2;
                setthink(toucher.swampslug, swampslug_think);
                toucher.swampslug.nextthink = time;
                toucher.swampslug.owner = toucher;
@@ -90,7 +91,7 @@ void swamp_touch(entity this, entity toucher)
        //toucher.in_swamp = 1;
 
        //Revitalize players swampslug
-       SetResourceAmountExplicit(toucher.swampslug, RESOURCE_HEALTH, 2);
+       toucher.swampslug.swamp_lifetime = 2;
 }
 
 REGISTER_NET_LINKED(ENT_CLIENT_SWAMP)
index 7eb78cb47b154c2a0af31d557f1a7360926713a2..9981474f9bc7ad92a696dc9f8792d01a88cb0d15 100644 (file)
@@ -91,7 +91,7 @@ void M_Shambler_Attack_Lightning_Damage(entity this, entity inflictor, entity at
        if (!W_CheckProjectileDamage(inflictor.realowner, this.realowner, deathtype, -1)) // no exceptions
                return; // g_projectiles_damage says to halt
 
-       SetResourceAmountExplicit(this, RESOURCE_HEALTH, GetResourceAmount(this, RESOURCE_HEALTH) - damage);
+       TakeResource(this, RESOURCE_HEALTH, damage);
 
        if (GetResourceAmount(this, RESOURCE_HEALTH) <= 0)
                W_PrepareExplosionByDamage(this, attacker, adaptor_think2use);
index a8666dd81f9eecaa1a60d5066689b795ddeea51c..8497bde05635172713919d0294da23937c01d30e 100644 (file)
@@ -486,7 +486,7 @@ void Monster_Miniboss_Check(entity this)
        // g_monsters_miniboss_chance cvar or spawnflags 64 causes a monster to be a miniboss
        if ((this.spawnflags & MONSTERFLAG_MINIBOSS) || (chance < autocvar_g_monsters_miniboss_chance))
        {
-               SetResourceAmountExplicit(this, RESOURCE_HEALTH, GetResourceAmount(this, RESOURCE_HEALTH) + autocvar_g_monsters_miniboss_healthboost);
+               GiveResource(this, RESOURCE_HEALTH, autocvar_g_monsters_miniboss_healthboost);
                this.effects |= EF_RED;
                if(!this.weapon)
                        this.weapon = WEP_VORTEX.m_id;
@@ -906,7 +906,7 @@ void Monster_Reset(entity this)
 
 void Monster_Dead_Damage(entity this, entity inflictor, entity attacker, float damage, int deathtype, .entity weaponentity, vector hitloc, vector force)
 {
-       SetResourceAmountExplicit(this, RESOURCE_HEALTH, GetResourceAmount(this, RESOURCE_HEALTH) - damage);
+       TakeResource(this, RESOURCE_HEALTH, damage);
 
        Violence_GibSplash_At(hitloc, force, 2, bound(0, damage, 200) / 16, this, attacker);
 
index c5c03640b3371bf1ad30b31efc3e692629f9477e..37d82e22ef72d9f1579d4056349bcf39f61d012a 100644 (file)
@@ -34,7 +34,7 @@ void W_OverkillRocketPropelledChainsaw_Damage(entity this, entity inflictor, ent
        if (!W_CheckProjectileDamage(inflictor.realowner, this.realowner, deathtype, -1)) // no exceptions
                return; // g_projectiles_damage says to halt
 
-       SetResourceAmountExplicit(this, RESOURCE_HEALTH, GetResourceAmount(this, RESOURCE_HEALTH) - damage);
+       TakeResource(this, RESOURCE_HEALTH, damage);
 
        if (GetResourceAmount(this, RESOURCE_HEALTH) <= 0)
                W_PrepareExplosionByDamage(this, attacker, W_OverkillRocketPropelledChainsaw_Explode_think);
index a064b5eee91c263b8acab54f9eab8450327501c3..a02ce07aca2454367cacbc86cea4242fb6bf05b5 100644 (file)
@@ -230,7 +230,7 @@ void turret_damage(entity this, entity inflictor, entity attacker, float damage,
                        return;
        }
 
-       SetResourceAmountExplicit(this, RESOURCE_HEALTH, GetResourceAmount(this, RESOURCE_HEALTH) - damage);
+       TakeResource(this, RESOURCE_HEALTH, damage);
 
        // thorw head slightly off aim when hit?
        if (this.damage_flags & TFL_DMG_HEADSHAKE)
@@ -451,7 +451,7 @@ void turret_projectile_touch(entity this, entity toucher)
 void turret_projectile_damage(entity this, entity inflictor, entity attacker, float damage, int deathtype, .entity weaponentity, vector hitloc, vector vforce)
 {
        this.velocity  += vforce;
-       SetResourceAmountExplicit(this, RESOURCE_HEALTH, GetResourceAmount(this, RESOURCE_HEALTH) - damage);
+       TakeResource(this, RESOURCE_HEALTH, damage);
        //this.realowner = attacker; // Dont change realowner, it does not make much sense for turrets
        if(GetResourceAmount(this, RESOURCE_HEALTH) <= 0)
                W_PrepareExplosionByDamage(this, this.owner, turret_projectile_explode);
index 02b5067470087a8e4a3d24f8a1e5414c3cdc6b79..6aa0865e69d1e4fac73d93ab9177f72278071985 100644 (file)
@@ -86,7 +86,7 @@ void walker_rocket_touch(entity this, entity toucher)
 
 void walker_rocket_damage(entity this, entity inflictor, entity attacker, float damage, float deathtype, .entity weaponentity, vector hitloc, vector vforce)
 {
-    SetResourceAmountExplicit(this, RESOURCE_HEALTH, GetResourceAmount(this, RESOURCE_HEALTH) - damage);
+    TakeResource(this, RESOURCE_HEALTH, damage);
     this.velocity = this.velocity + vforce;
 
     if (GetResourceAmount(this, RESOURCE_HEALTH) <= 0)
index 59235fc0fb876e709f7d9a0941c72ba1bb6485ac..6c34741cc710733fe7886c837dddf7859b5aacc8 100644 (file)
@@ -205,7 +205,7 @@ void vehicles_projectile_damage(entity this, entity inflictor, entity attacker,
        if(inflictor.owner == this.owner)
                return;
 
-       SetResourceAmountExplicit(this, RESOURCE_HEALTH, GetResourceAmount(this, RESOURCE_HEALTH) - damage);
+       TakeResource(this, RESOURCE_HEALTH, damage);
        this.velocity += force;
        if(GetResourceAmount(this, RESOURCE_HEALTH) < 1)
        {
index 0def8bded9d615d37ad2c06d5359037f20e1ca44..53475d6cfd382e6efe95ae50ae09642b6fe04a89 100644 (file)
@@ -191,7 +191,7 @@ void raptor_flare_touch(entity this, entity toucher)
 
 void raptor_flare_damage(entity this, entity inflictor, entity attacker, float damage, int deathtype, .entity weaponentity, vector hitloc, vector force)
 {
-    SetResourceAmountExplicit(this, RESOURCE_HEALTH, GetResourceAmount(this, RESOURCE_HEALTH) - damage);
+    TakeResource(this, RESOURCE_HEALTH, damage);
     if(GetResourceAmount(this, RESOURCE_HEALTH) <= 0)
         delete(this);
 }
index 3b71d9207580baa0542b6b1176907686e78d8747..d6604623d2615ae31467d9592e0d7037c8557c6e 100644 (file)
@@ -110,7 +110,7 @@ void W_Arc_Bolt_Damage(entity this, entity inflictor, entity attacker, float dam
        if(!W_CheckProjectileDamage(inflictor.realowner, this.realowner, deathtype, -1))
                return; // g_projectiles_damage says to halt
 
-       SetResourceAmountExplicit(this, RESOURCE_HEALTH, GetResourceAmount(this, RESOURCE_HEALTH) - damage);
+       TakeResource(this, RESOURCE_HEALTH, damage);
        this.angles = vectoangles(this.velocity);
 
        if(GetResourceAmount(this, RESOURCE_HEALTH) <= 0)
index d30569adf2e65d07508537901d055669997166c8..ab97e3d7f0b6c5c16ba538092b3ece2bd2aeb4df 100644 (file)
@@ -295,7 +295,7 @@ void W_Devastator_Damage(entity this, entity inflictor, entity attacker, float d
        if(!W_CheckProjectileDamage(inflictor.realowner, this.realowner, deathtype, -1)) // no exceptions
                return; // g_projectiles_damage says to halt
 
-       SetResourceAmountExplicit(this, RESOURCE_HEALTH, GetResourceAmount(this, RESOURCE_HEALTH) - damage);
+       TakeResource(this, RESOURCE_HEALTH, damage);
        this.angles = vectoangles(this.velocity);
 
        if(GetResourceAmount(this, RESOURCE_HEALTH) <= 0)
index 4e9469c24a0b41936c552cbaf75fa1c5fb0d3113..89738289f2b84b0205020e9ae0b4f33eeca05afb 100644 (file)
@@ -309,7 +309,7 @@ void W_Electro_Orb_Damage(entity this, entity inflictor, entity attacker, float
        if(!W_CheckProjectileDamage(inflictor.realowner, this.realowner, deathtype, (is_combo ? 1 : -1)))
                return; // g_projectiles_damage says to halt
 
-       SetResourceAmountExplicit(this, RESOURCE_HEALTH, GetResourceAmount(this, RESOURCE_HEALTH) - damage);
+       TakeResource(this, RESOURCE_HEALTH, damage);
        if(GetResourceAmount(this, RESOURCE_HEALTH) <= 0)
        {
                this.takedamage = DAMAGE_NO;
index 45a8c13d13981cd37bc317183747c409efd28203..84113b7020f210352d85360cfc5f6b0d6d488d61 100644 (file)
@@ -125,7 +125,7 @@ void W_Fireball_Damage(entity this, entity inflictor, entity attacker, float dam
        if(!W_CheckProjectileDamage(inflictor.realowner, this.realowner, deathtype, -1)) // no exceptions
                return; // g_projectiles_damage says to halt
 
-       SetResourceAmountExplicit(this, RESOURCE_HEALTH, GetResourceAmount(this, RESOURCE_HEALTH) - damage);
+       TakeResource(this, RESOURCE_HEALTH, damage);
        if(GetResourceAmount(this, RESOURCE_HEALTH) <= 0)
        {
                this.cnt = 1;
index cebf15fdcfd11337983b71f616a24f46e6e61485..e8bfa4ce7767be98814d0f1696cb87e9392dd29b 100644 (file)
@@ -47,7 +47,7 @@ void W_Hagar_Damage(entity this, entity inflictor, entity attacker, float damage
        if(!W_CheckProjectileDamage(inflictor.realowner, this.realowner, deathtype, is_linkexplode))
                return; // g_projectiles_damage says to halt
 
-       SetResourceAmountExplicit(this, RESOURCE_HEALTH, GetResourceAmount(this, RESOURCE_HEALTH) - damage);
+       TakeResource(this, RESOURCE_HEALTH, damage);
        this.angles = vectoangles(this.velocity);
 
        if(GetResourceAmount(this, RESOURCE_HEALTH) <= 0)
index a36f2f09681623827e2362b1c4012ea9c75a21c3..6d3270a2b22788e6539f82115f93d72a2ef8b18c 100644 (file)
@@ -257,7 +257,7 @@ void W_MineLayer_Damage(entity this, entity inflictor, entity attacker, float da
        if(!W_CheckProjectileDamage(inflictor.realowner, this.realowner, deathtype, (is_from_enemy ? 1 : -1)))
                return; // g_projectiles_damage says to halt
 
-       SetResourceAmountExplicit(this, RESOURCE_HEALTH, GetResourceAmount(this, RESOURCE_HEALTH) - damage);
+       TakeResource(this, RESOURCE_HEALTH, damage);
        this.angles = vectoangles(this.velocity);
 
        if(GetResourceAmount(this, RESOURCE_HEALTH) <= 0)
index 8a280132e517971cf6b8faea3df55b61a2852ead..51267e50d4f80ad7d2d1de58b156328a2bd967ca 100644 (file)
@@ -60,7 +60,7 @@ void W_Mortar_Grenade_Damage(entity this, entity inflictor, entity attacker, flo
        if(!W_CheckProjectileDamage(inflictor.realowner, this.realowner, deathtype, -1)) // no exceptions
                return; // g_projectiles_damage says to halt
 
-       SetResourceAmountExplicit(this, RESOURCE_HEALTH, GetResourceAmount(this, RESOURCE_HEALTH) - damage);
+       TakeResource(this, RESOURCE_HEALTH, damage);
 
        if(GetResourceAmount(this, RESOURCE_HEALTH) <= 0)
                W_PrepareExplosionByDamage(this, attacker, adaptor_think2use);
index a55ebc86d87b107a781828b0247d07e3501e1cc7..166255c26cfa915692b2b3afb24c9944fabbef8b 100644 (file)
@@ -133,7 +133,7 @@ void W_Seeker_Missile_Damage(entity this, entity inflictor, entity attacker, flo
        if(this.realowner == attacker)
                SetResourceAmountExplicit(this, RESOURCE_HEALTH, GetResourceAmount(this, RESOURCE_HEALTH) - (damage * 0.25));
        else
-               SetResourceAmountExplicit(this, RESOURCE_HEALTH, GetResourceAmount(this, RESOURCE_HEALTH) - damage);
+               TakeResource(this, RESOURCE_HEALTH, damage);
 
        if(GetResourceAmount(this, RESOURCE_HEALTH) <= 0)
                W_PrepareExplosionByDamage(this, attacker, W_Seeker_Missile_Explode_think);
@@ -417,7 +417,7 @@ void W_Seeker_Tag_Damage(entity this, entity inflictor, entity attacker, float d
 {
        if(GetResourceAmount(this, RESOURCE_HEALTH) <= 0)
                return;
-       SetResourceAmountExplicit(this, RESOURCE_HEALTH, GetResourceAmount(this, RESOURCE_HEALTH) - damage);
+       TakeResource(this, RESOURCE_HEALTH, damage);
        if(GetResourceAmount(this, RESOURCE_HEALTH) <= 0)
                W_Seeker_Tag_Explode(this);
 }
index 6ca20c182a2330f8496b8336f7bbe55793a54d16..68aa7154ecdc3928261ea584bd251be2c86d2c03 100644 (file)
@@ -344,7 +344,7 @@ void GrapplingHook_Damage(entity this, entity inflictor, entity attacker, float
        if (!W_CheckProjectileDamage(inflictor.realowner, this.realowner, deathtype, -1)) // no exceptions
                return; // g_balance_projectiledamage says to halt
 
-       SetResourceAmountExplicit(this, RESOURCE_HEALTH, GetResourceAmount(this, RESOURCE_HEALTH) - damage);
+       TakeResource(this, RESOURCE_HEALTH, damage);
 
        if (GetResourceAmount(this, RESOURCE_HEALTH) <= 0)
        {
index 98db7219d2c1dde7bd18ba1223624991e08d4a96..de21a59035a5d4d913ab3ba33aa9b2e1ffbbef14 100644 (file)
@@ -745,6 +745,30 @@ RESOURCE_* constants for resource types. Return true to forbid giving. */
        /**/
 MUTATOR_HOOKABLE(GiveResourceWithLimit, EV_GiveResourceWithLimit);
 
+/** Called when some resource is being taken from an entity. See RESOURCE_* constants
+for resource types. Return true to forbid giving. */
+#define EV_TakeResource(i, o) \
+    /** receiver */      i(entity, MUTATOR_ARGV_0_entity) \
+    /** resource type */ i(int, MUTATOR_ARGV_1_int) \
+    /**/                 o(int, MUTATOR_ARGV_1_int) \
+    /** amount */        i(float, MUTATOR_ARGV_2_float) \
+    /**/                 o(float, MUTATOR_ARGV_2_float) \
+    /**/
+MUTATOR_HOOKABLE(TakeResource, EV_TakeResource);
+
+/** Called when some resource is being taken from an entity, with a limit. See
+RESOURCE_* constants for resource types. Return true to forbid giving. */
+#define EV_TakeResourceWithLimit(i, o) \
+    /** receiver */      i(entity, MUTATOR_ARGV_0_entity) \
+    /** resource type */ i(int, MUTATOR_ARGV_1_int) \
+    /**/                 o(int, MUTATOR_ARGV_1_int) \
+    /** amount */        i(float, MUTATOR_ARGV_2_float) \
+    /**/                 o(float, MUTATOR_ARGV_2_float) \
+    /** limit */         i(float, MUTATOR_ARGV_3_float) \
+    /**/                 o(float, MUTATOR_ARGV_3_float) \
+    /**/
+MUTATOR_HOOKABLE(TakeResourceWithLimit, EV_TakeResourceWithLimit);
+
 /** called at when a player connect */
 #define EV_ClientConnect(i, o) \
     /** player */ i(entity, MUTATOR_ARGV_0_entity) \
index 353337425f54c6bf1f420d19039d0eda02901dd5..4e39cf6b779297478ec2d3ed55170e2e13cfc90c 100644 (file)
@@ -192,8 +192,8 @@ void PlayerCorpseDamage(entity this, entity inflictor, entity attacker, float da
        if (take > 100)
                Violence_GibSplash_At(hitloc, force * -0.2, 3, 1, this, attacker);
 
-       SetResourceAmountExplicit(this, RESOURCE_ARMOR, GetResourceAmount(this, RESOURCE_ARMOR) - save);
-       SetResourceAmountExplicit(this, RESOURCE_HEALTH, GetResourceAmount(this, RESOURCE_HEALTH) - take);
+       TakeResource(this, RESOURCE_ARMOR, save);
+       TakeResource(this, RESOURCE_HEALTH, take);
        // pause regeneration for 5 seconds
        this.pauseregen_finished = max(this.pauseregen_finished, time + autocvar_g_balance_pause_health_regen);
 
@@ -411,8 +411,8 @@ void PlayerDamage(entity this, entity inflictor, entity attacker, float damage,
        {
                if (!(this.flags & FL_GODMODE))
                {
-                       SetResourceAmountExplicit(this, RESOURCE_ARMOR, GetResourceAmount(this, RESOURCE_ARMOR) - save);
-                       SetResourceAmountExplicit(this, RESOURCE_HEALTH, GetResourceAmount(this, RESOURCE_HEALTH) - take);
+                       TakeResource(this, RESOURCE_ARMOR, save);
+                       TakeResource(this, RESOURCE_HEALTH, take);
                        // pause regeneration for 5 seconds
                        if(take)
                                this.pauseregen_finished = max(this.pauseregen_finished, time + autocvar_g_balance_pause_health_regen);
index 78ed758bbc79529bfa0c6e3c8c5c929474c0a734..162026a169e98843d259e2717228984fb06905b8 100644 (file)
@@ -435,7 +435,7 @@ void Portal_Damage(entity this, entity inflictor, entity attacker, float damage,
        if(attacker != this.aiment)
                if(IS_INDEPENDENT_PLAYER(attacker) || IS_INDEPENDENT_PLAYER(this.aiment))
                        return;
-       SetResourceAmountExplicit(this, RESOURCE_HEALTH, GetResourceAmount(this, RESOURCE_HEALTH) - damage);
+       TakeResource(this, RESOURCE_HEALTH, damage);
        if(GetResourceAmount(this, RESOURCE_HEALTH) < 0)
                Portal_Remove(this, 1);
 }
index 8d993bd7b87e3089c54a25f2399713d6a66ca766..2632af10ff5e6d3cd9d8a971b2ea323e25c1704a 100644 (file)
@@ -186,6 +186,56 @@ void GiveResourceWithLimit(entity receiver, int resource_type, float amount,
        GiveResource(receiver, resource_type, amount);
 }
 
+void TakeResource(entity receiver, int resource_type, float amount)
+{
+       if (amount == 0)
+       {
+               return;
+       }
+       bool forbid = MUTATOR_CALLHOOK(TakeResource, receiver, resource_type,
+               amount);
+       if (forbid)
+       {
+               return;
+       }
+       resource_type = M_ARGV(1, int);
+       amount = M_ARGV(2, float);
+       if (amount == 0)
+       {
+               return;
+       }
+       SetResourceAmount(receiver, resource_type,
+               GetResourceAmount(receiver, resource_type) - amount);
+}
+
+void TakeResourceWithLimit(entity receiver, int resource_type, float amount,
+       float limit)
+{
+       if (amount == 0)
+       {
+               return;
+       }
+       bool forbid = MUTATOR_CALLHOOK(TakeResourceWithLimit, receiver,
+               resource_type, amount, limit);
+       if (forbid)
+       {
+               return;
+       }
+       resource_type = M_ARGV(1, int);
+       amount = M_ARGV(2, float);
+       limit = M_ARGV(3, float);
+       if (amount == 0)
+       {
+               return;
+       }
+       float current_amount = GetResourceAmount(receiver, resource_type);
+       if (current_amount - amount < limit)
+       {
+               amount = limit + current_amount;
+       }
+       TakeResource(receiver, resource_type, amount);
+}
+
 int GetResourceType(.float resource_field)
 {
        switch (resource_field)
index e35346c19c8dbfd5359a15c3794841029cc6939d..e4631ab5605ad30d7953826cdaddf6ef78ea7bd7 100644 (file)
@@ -51,6 +51,22 @@ void GiveResource(entity receiver, int resource_type, float amount);
 void GiveResourceWithLimit(entity receiver, int resource_type, float amount,
        float limit);
 
+/// \brief Takes an entity some resource.
+/// \param[in,out] receiver Entity to take resource from.
+/// \param[in] resource_type Type of the resource (a RESOURCE_* constant).
+/// \param[in] amount Amount of resource to take.
+/// \return No return.
+void TakeResource(entity receiver, int resource_type, float amount);
+
+/// \brief Takes an entity some resource but not less than a limit.
+/// \param[in,out] receiver Entity to take resource from.
+/// \param[in] resource_type Type of the resource (a RESOURCE_* constant).
+/// \param[in] amount Amount of resource to take.
+/// \param[in] limit Limit of resources to take.
+/// \return No return.
+void TakeResourceWithLimit(entity receiver, int resource_type, float amount,
+       float limit);
+
 // ===================== Legacy and/or internal API ===========================
 
 /// \brief Converts an entity field to resource type.