]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/damage.qc
Merge branch 'Mario/resource_registry' into 'master'
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / damage.qc
index b983cdb8aa2e11c26e002a4438a487983c3ef99c..969423bfb83f8b0e55ae1e6add6f25b5bdebefcc 100644 (file)
@@ -1,42 +1,45 @@
 #include "damage.qh"
 
+#include <common/constants.qh>
+#include <common/deathtypes/all.qh>
 #include <common/effects/all.qh>
-#include "bot/api.qh"
-#include "hook.qh"
+#include <common/gamemodes/_mod.qh>
+#include <common/gamemodes/rules.qh>
+#include <common/items/_mod.qh>
+#include <common/mapobjects/defs.qh>
+#include <common/mapobjects/triggers.qh>
+#include <common/mutators/mutator/buffs/buffs.qh>
+#include <common/mutators/mutator/buffs/sv_buffs.qh>
+#include <common/mutators/mutator/instagib/sv_instagib.qh>
+#include <common/mutators/mutator/status_effects/_mod.qh>
+#include <common/mutators/mutator/waypoints/waypointsprites.qh>
+#include <common/notifications/all.qh>
+#include <common/physics/movetypes/movetypes.qh>
+#include <common/physics/player.qh>
+#include <common/playerstats.qh>
+#include <common/resources/sv_resources.qh>
+#include <common/state.qh>
+#include <common/teams.qh>
+#include <common/util.qh>
+#include <common/vehicles/all.qh>
+#include <common/weapons/_all.qh>
+#include <lib/csqcmodel/sv_model.qh>
+#include <lib/warpzone/common.qh>
+#include <server/bot/api.qh>
 #include <server/client.qh>
 #include <server/gamelog.qh>
+#include <server/hook.qh>
 #include <server/items/items.qh>
-#include <server/mutators/_mod.qh>
 #include <server/main.qh>
+#include <server/mutators/_mod.qh>
+#include <server/scores.qh>
+#include <server/spawnpoints.qh>
+#include <server/teamplay.qh>
+#include <server/weapons/accuracy.qh>
+#include <server/weapons/csqcprojectile.qh>
+#include <server/weapons/selection.qh>
+#include <server/weapons/weaponsystem.qh>
 #include <server/world.qh>
-#include "teamplay.qh"
-#include "scores.qh"
-#include "spawnpoints.qh"
-#include "../common/state.qh"
-#include "../common/physics/player.qh"
-#include "resources.qh"
-#include "../common/vehicles/all.qh"
-#include "../common/items/_mod.qh"
-#include "../common/mutators/mutator/waypoints/waypointsprites.qh"
-#include "../common/mutators/mutator/instagib/sv_instagib.qh"
-#include "../common/mutators/mutator/buffs/buffs.qh"
-#include "weapons/accuracy.qh"
-#include "weapons/csqcprojectile.qh"
-#include "weapons/selection.qh"
-#include "../common/constants.qh"
-#include "../common/deathtypes/all.qh"
-#include <common/mapobjects/defs.qh>
-#include <common/mapobjects/triggers.qh>
-#include "../common/notifications/all.qh"
-#include "../common/physics/movetypes/movetypes.qh"
-#include "../common/playerstats.qh"
-#include "../common/teams.qh"
-#include "../common/util.qh"
-#include <common/gamemodes/_mod.qh>
-#include <common/gamemodes/rules.qh>
-#include <common/weapons/_all.qh>
-#include "../lib/csqcmodel/sv_model.qh"
-#include "../lib/warpzone/common.qh"
 
 void UpdateFrags(entity player, int f)
 {
@@ -92,10 +95,6 @@ string AppendItemcodes(string s, entity player)
                if(w != 0 || slot == 0)
                        s = strcat(s, ftos(w));
        }
-       if(time < STAT(STRENGTH_FINISHED, player))
-               s = strcat(s, "S");
-       if(time < STAT(INVINCIBLE_FINISHED, player))
-               s = strcat(s, "I");
        if(PHYS_INPUT_BUTTON_CHAT(player))
                s = strcat(s, "T");
        // TODO: include these codes as a flag on the item itself
@@ -282,7 +281,9 @@ void Obituary(entity attacker, entity inflictor, entity targ, int deathtype, .en
                                                Obituary_SpecialDeath(targ, false, deathtype, targ.netname, deathlocation, "", CS(targ).killcount, 0, 0);
                                                break;
                                        }
-
+                                       case DEATH_HURTTRIGGER:
+                                               Obituary_SpecialDeath(targ, false, deathtype, targ.netname, inflictor.message, deathlocation, CS(targ).killcount, 0, 0);
+                                               break;
                                        default:
                                        {
                                                Obituary_SpecialDeath(targ, false, deathtype, targ.netname, deathlocation, "", CS(targ).killcount, 0, 0);
@@ -412,7 +413,7 @@ void Obituary(entity attacker, entity inflictor, entity targ, int deathtype, .en
 
                        int f3 = 0;
                        if(deathtype == DEATH_BUFF.m_id)
-                               f3 = buff_FirstFromFlags(STAT(BUFFS, attacker)).m_id;
+                               f3 = buff_FirstFromFlags(attacker).m_id;
 
                        if (!Obituary_WeaponDeath(targ, true, deathtype, targ.netname, attacker_name, deathlocation, CS(targ).killcount, kill_count_to_attacker))
                                Obituary_SpecialDeath(targ, true, deathtype, targ.netname, attacker_name, deathlocation, CS(targ).killcount, kill_count_to_attacker, f3);
@@ -608,9 +609,12 @@ void Damage(entity targ, entity inflictor, entity attacker, float damage, int de
                // These are ALWAYS lethal
                // No damage modification here
                // Instead, prepare the victim for his death...
-               SetResourceExplicit(targ, RES_ARMOR, 0);
-               targ.spawnshieldtime = 0;
-               SetResourceExplicit(targ, RES_HEALTH, 0.9); // this is < 1
+               if(deathtype == DEATH_TEAMCHANGE.m_id || deathtype == DEATH_AUTOTEAMCHANGE.m_id)
+               {
+                       SetResourceExplicit(targ, RES_ARMOR, 0);
+                       SetResourceExplicit(targ, RES_HEALTH, 0.9); // this is < 1
+               }
+               StatusEffects_remove(STATUSEFFECT_SpawnShield, targ, STATUSEFFECT_REMOVE_CLEAR);
                targ.flags -= targ.flags & FL_GODMODE;
                damage = 100000;
        }
@@ -759,34 +763,6 @@ void Damage(entity targ, entity inflictor, entity attacker, float damage, int de
                        }
                }
 
-               if(!MUTATOR_IS_ENABLED(mutator_instagib))
-               {
-                       // apply strength multiplier
-                       if (attacker.items & ITEM_Strength.m_itemid)
-                       {
-                               if(targ == attacker)
-                               {
-                                       damage = damage * autocvar_g_balance_powerup_strength_selfdamage;
-                                       force = force * autocvar_g_balance_powerup_strength_selfforce;
-                               }
-                               else
-                               {
-                                       damage = damage * autocvar_g_balance_powerup_strength_damage;
-                                       force = force * autocvar_g_balance_powerup_strength_force;
-                               }
-                       }
-
-                       // apply invincibility multiplier
-                       if (targ.items & ITEM_Shield.m_itemid)
-                       {
-                               damage = damage * autocvar_g_balance_powerup_invincible_takedamage;
-                               if (targ != attacker)
-                               {
-                                       force = force * autocvar_g_balance_powerup_invincible_takeforce;
-                               }
-                       }
-               }
-
                if (targ == attacker)
                        damage = damage * autocvar_g_balance_selfdamagepercent; // Partial damage if the attacker hits himself
 
@@ -814,11 +790,10 @@ void Damage(entity targ, entity inflictor, entity attacker, float damage, int de
                                                        if(PHYS_INPUT_BUTTON_CHAT(victim))
                                                                attacker.typehitsound += 1;
                                                        else
-                                                               attacker.damage_dealt += damage;
+                                                               attacker.hitsound_damage_dealt += damage;
                                                }
 
-                                               damage_goodhits += 1;
-                                               damage_gooddamage += damage;
+                                               impressive_hits += 1;
 
                                                if (!DEATH_ISSPECIAL(deathtype))
                                                {
@@ -849,7 +824,7 @@ void Damage(entity targ, entity inflictor, entity attacker, float damage, int de
        // apply push
        if (targ.damageforcescale)
        if (force)
-       if (!IS_PLAYER(targ) || time >= targ.spawnshieldtime || targ == attacker)
+       if (!IS_PLAYER(targ) || !StatusEffects_active(STATUSEFFECT_SpawnShield, targ) || targ == attacker)
        {
                vector farce = damage_explosion_calcpush(targ.damageforcescale * force, targ.velocity, autocvar_g_balance_damagepush_speedfactor);
                if(targ.move_movetype == MOVETYPE_PHYSICS)
@@ -887,9 +862,9 @@ void Damage(entity targ, entity inflictor, entity attacker, float damage, int de
        }
 }
 
+// Returns total damage applies to creatures
 float RadiusDamageForSource (entity inflictor, vector inflictororigin, vector inflictorvelocity, entity attacker, float coredamage, float edgedamage, float rad, entity cantbe, entity mustbe,
                                                                float inflictorselfdamage, float forceintensity, float forcezscale, int deathtype, .entity weaponentity, entity directhitentity)
-       // Returns total damage applies to creatures
 {
        entity  targ;
        vector  force;
@@ -1099,11 +1074,6 @@ bool Heal(entity targ, entity inflictor, float amount, float limit)
        return healed;
 }
 
-float Fire_IsBurning(entity e)
-{
-       return (time < e.fire_endtime);
-}
-
 float Fire_AddDamage(entity e, entity o, float d, float t, float dt)
 {
        float dps;
@@ -1114,23 +1084,14 @@ float Fire_AddDamage(entity e, entity o, float d, float t, float dt)
                if(IS_DEAD(e))
                        return -1;
        }
-       else
-       {
-               if(!e.fire_burner)
-               {
-                       // print("adding a fire burner to ", e.classname, "\n");
-                       e.fire_burner = new(fireburner);
-                       setthink(e.fire_burner, fireburner_think);
-                       e.fire_burner.nextthink = time;
-                       e.fire_burner.owner = e;
-               }
-       }
 
        t = max(t, 0.1);
        dps = d / t;
-       if(Fire_IsBurning(e))
+       if(StatusEffects_active(STATUSEFFECT_Burning, e))
        {
-               mintime = e.fire_endtime - time;
+               float fireendtime = StatusEffects_gettime(STATUSEFFECT_Burning, e);
+
+               mintime = fireendtime - time;
                maxtime = max(mintime, t);
 
                mindps = e.fire_damagepersec;
@@ -1193,7 +1154,7 @@ float Fire_AddDamage(entity e, entity o, float d, float t, float dt)
                        // b) totaltime = min(maxtime, totaldamage / mindps) = totaldamage / maxdps
 
                        e.fire_damagepersec = totaldamage / totaltime;
-                       e.fire_endtime = time + totaltime;
+                       StatusEffects_apply(STATUSEFFECT_Burning, e, time + totaltime, 0);
                        if(totaldamage > 1.2 * mindamage)
                        {
                                e.fire_deathtype = dt;
@@ -1213,7 +1174,7 @@ float Fire_AddDamage(entity e, entity o, float d, float t, float dt)
        else
        {
                e.fire_damagepersec = dps;
-               e.fire_endtime = time + t;
+               StatusEffects_apply(STATUSEFFECT_Burning, e, time + t, 0);
                e.fire_deathtype = dt;
                e.fire_owner = o;
                e.fire_hitsound = false;
@@ -1228,31 +1189,20 @@ void Fire_ApplyDamage(entity e)
        float t, d, hi, ty;
        entity o;
 
-       if (!Fire_IsBurning(e))
-               return;
-
        for(t = 0, o = e.owner; o.owner && t < 16; o = o.owner, ++t);
        if(IS_NOT_A_CLIENT(o))
                o = e.fire_owner;
 
-       // water and slime stop fire
-       if(e.waterlevel)
-       if(e.watertype != CONTENT_LAVA)
-               e.fire_endtime = 0;
-
-       // ice stops fire
-       if(STAT(FROZEN, e))
-               e.fire_endtime = 0;
-
-       t = min(frametime, e.fire_endtime - time);
+       float fireendtime = StatusEffects_gettime(STATUSEFFECT_Burning, e);
+       t = min(frametime, fireendtime - time);
        d = e.fire_damagepersec * t;
 
-       hi = e.fire_owner.damage_dealt;
+       hi = e.fire_owner.hitsound_damage_dealt;
        ty = e.fire_owner.typehitsound;
        Damage(e, e, e.fire_owner, d, e.fire_deathtype, DMG_NOWEP, e.origin, '0 0 0');
        if(e.fire_hitsound && e.fire_owner)
        {
-               e.fire_owner.damage_dealt = hi;
+               e.fire_owner.hitsound_damage_dealt = hi;
                e.fire_owner.typehitsound = ty;
        }
        e.fire_hitsound = true;
@@ -1264,37 +1214,10 @@ void Fire_ApplyDamage(entity e)
                        if(!IS_DEAD(it) && it.takedamage && !IS_INDEPENDENT_PLAYER(it))
                        if(boxesoverlap(e.absmin, e.absmax, it.absmin, it.absmax))
                        {
-                               t = autocvar_g_balance_firetransfer_time * (e.fire_endtime - time);
+                               t = autocvar_g_balance_firetransfer_time * (fireendtime - time);
                                d = autocvar_g_balance_firetransfer_damage * e.fire_damagepersec * t;
                                Fire_AddDamage(it, o, d, t, DEATH_FIRE.m_id);
                        }
                });
        }
 }
-
-void Fire_ApplyEffect(entity e)
-{
-       if(Fire_IsBurning(e))
-               e.effects |= EF_FLAME;
-       else
-               e.effects &= ~EF_FLAME;
-}
-
-void fireburner_think(entity this)
-{
-       // for players, this is done in the regular loop
-       if(wasfreed(this.owner))
-       {
-               delete(this);
-               return;
-       }
-       Fire_ApplyEffect(this.owner);
-       if(!Fire_IsBurning(this.owner))
-       {
-               this.owner.fire_burner = NULL;
-               delete(this);
-               return;
-       }
-       Fire_ApplyDamage(this.owner);
-       this.nextthink = time;
-}