]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/g_damage.qc
Merge branch 'master' into martin-t/rpc-acc
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / g_damage.qc
index 74a0e4df6c4cc97078bb2adcb83ea319245a3bf2..c2db32650dd851c363ca44ed123641dcdbf8d5d6 100644 (file)
@@ -3,7 +3,7 @@
 #include <common/effects/all.qh>
 #include "bot/api.qh"
 #include "g_hook.qh"
-#include "mutators/_mod.qh"
+#include <server/mutators/_mod.qh>
 #include "scores.qh"
 #include "spawnpoints.qh"
 #include "../common/state.qh"
@@ -13,6 +13,8 @@
 #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"
@@ -23,6 +25,7 @@
 #include "../common/playerstats.qh"
 #include "../common/teams.qh"
 #include "../common/util.qh"
+#include <common/gamemodes/rules.qh>
 #include <common/weapons/_all.qh>
 #include "../lib/csqcmodel/sv_model.qh"
 #include "../lib/warpzone/common.qh"
@@ -32,7 +35,7 @@ void UpdateFrags(entity player, int f)
        GameRules_scoring_add_team(player, SCORE, f);
 }
 
-void GiveFrags (entity attacker, entity targ, float f, int deathtype)
+void GiveFrags(entity attacker, entity targ, float f, int deathtype, .entity weaponentity)
 {
        // TODO route through PlayerScores instead
        if(game_stopped) return;
@@ -54,59 +57,14 @@ void GiveFrags (entity attacker, entity targ, float f, int deathtype)
        {
                // regular frag
                GameRules_scoring_add(attacker, KILLS, 1);
-               if(targ.playerid)
-                       PS_GR_P_ADDVAL(attacker, sprintf("kills-%d", targ.playerid), 1);
+               if(!warmup_stage && targ.playerid)
+                       PlayerStats_GameReport_Event_Player(attacker, sprintf("kills-%d", targ.playerid), 1);
        }
 
        GameRules_scoring_add(targ, DEATHS, 1);
 
-       .entity weaponentity = weaponentities[0]; // TODO: unhardcode
-
-       if(targ != attacker) // not for suicides
-       if(g_weaponarena_random)
-       {
-               // after a frag, exchange the current weapon (or the culprit, if detectable) by a new random weapon
-               Weapon culprit = DEATH_WEAPONOF(deathtype);
-               if(!culprit) culprit = attacker.(weaponentity).m_weapon;
-               else if(!(attacker.weapons & (culprit.m_wepset))) culprit = attacker.(weaponentity).m_weapon;
-
-               if(g_weaponarena_random_with_blaster && culprit == WEP_BLASTER) // WEAPONTODO: Shouldn't this be in a mutator?
-               {
-                       // no exchange
-               }
-               else
-               {
-                       if(!GiveFrags_randomweapons)
-                       {
-                               GiveFrags_randomweapons = new(GiveFrags_randomweapons);
-                       }
-
-                       if(warmup_stage)
-                               GiveFrags_randomweapons.weapons = WARMUP_START_WEAPONS;
-                       else
-                               GiveFrags_randomweapons.weapons = start_weapons;
-
-                       // all others (including the culprit): remove
-                       GiveFrags_randomweapons.weapons &= ~attacker.weapons;
-                       GiveFrags_randomweapons.weapons &= ~(culprit.m_wepset);
-
-                       // among the remaining ones, choose one by random
-                       W_RandomWeapons(GiveFrags_randomweapons, 1);
-
-                       if(GiveFrags_randomweapons.weapons)
-                       {
-                               attacker.weapons |= GiveFrags_randomweapons.weapons;
-                               attacker.weapons &= ~(culprit.m_wepset);
-                       }
-               }
-
-               // after a frag, choose another random weapon set
-               if (!(attacker.weapons & WepSet_FromWeapon(attacker.(weaponentity).m_weapon)))
-                       W_SwitchWeapon_Force(attacker, w_getbestweapon(attacker, weaponentity), weaponentity);
-       }
-
        // FIXME fix the mess this is (we have REAL points now!)
-       if(MUTATOR_CALLHOOK(GiveFragsForKill, attacker, targ, f))
+       if(MUTATOR_CALLHOOK(GiveFragsForKill, attacker, targ, f, deathtype, attacker.(weaponentity)))
                f = M_ARGV(2, float);
 
        attacker.totalfrags += f;
@@ -167,60 +125,42 @@ void Obituary_SpecialDeath(
        string s1, string s2, string s3,
        float f1, float f2, float f3)
 {
-       if(DEATH_ISSPECIAL(deathtype))
+       if(!DEATH_ISSPECIAL(deathtype))
        {
-               entity deathent = Deathtypes_from(deathtype - DT_FIRST);
-               if (!deathent) { backtrace("Obituary_SpecialDeath: Could not find deathtype entity!\n"); return; }
+               backtrace("Obituary_SpecialDeath called without a special deathtype?\n");
+               return;
+       }
 
-               if(g_cts && deathtype == DEATH_KILL.m_id)
-                       return; // TODO: somehow put this in CTS gamemode file!
+       entity deathent = Deathtypes_from(deathtype - DT_FIRST);
+       if (!deathent)
+       {
+               backtrace("Obituary_SpecialDeath: Could not find deathtype entity!\n");
+               return;
+       }
 
-               if(murder)
-               {
-                       if(deathent.death_msgmurder)
-                       {
-                               Send_Notification_WOCOVA(
-                                       NOTIF_ONE,
-                                       notif_target,
-                                       MSG_MULTI,
-                                       deathent.death_msgmurder,
-                                       s1, s2, s3, "",
-                                       f1, f2, f3, 0
-                               );
-                               Send_Notification_WOCOVA(
-                                       NOTIF_ALL_EXCEPT,
-                                       notif_target,
-                                       MSG_INFO,
-                                       deathent.death_msgmurder.nent_msginfo,
-                                       s1, s2, s3, "",
-                                       f1, f2, f3, 0
-                               );
-                       }
-               }
-               else
-               {
-                       if(deathent.death_msgself)
-                       {
-                               Send_Notification_WOCOVA(
-                                       NOTIF_ONE,
-                                       notif_target,
-                                       MSG_MULTI,
-                                       deathent.death_msgself,
-                                       s1, s2, s3, "",
-                                       f1, f2, f3, 0
-                               );
-                               Send_Notification_WOCOVA(
-                                       NOTIF_ALL_EXCEPT,
-                                       notif_target,
-                                       MSG_INFO,
-                                       deathent.death_msgself.nent_msginfo,
-                                       s1, s2, s3, "",
-                                       f1, f2, f3, 0
-                               );
-                       }
-               }
+       if(g_cts && deathtype == DEATH_KILL.m_id)
+               return; // TODO: somehow put this in CTS gamemode file!
+
+       Notification death_message = (murder) ? deathent.death_msgmurder : deathent.death_msgself;
+       if(death_message)
+       {
+               Send_Notification_WOCOVA(
+                       NOTIF_ONE,
+                       notif_target,
+                       MSG_MULTI,
+                       death_message,
+                       s1, s2, s3, "",
+                       f1, f2, f3, 0
+               );
+               Send_Notification_WOCOVA(
+                       NOTIF_ALL_EXCEPT,
+                       notif_target,
+                       MSG_INFO,
+                       death_message.nent_msginfo,
+                       s1, s2, s3, "",
+                       f1, f2, f3, 0
+               );
        }
-       else { backtrace("Obituary_SpecialDeath called without a special deathtype?\n"); return; }
 }
 
 float Obituary_WeaponDeath(
@@ -231,44 +171,43 @@ float Obituary_WeaponDeath(
        float f1, float f2)
 {
        Weapon death_weapon = DEATH_WEAPONOF(deathtype);
-       if (death_weapon != WEP_Null)
-       {
-               w_deathtype = deathtype;
-               Notification death_message = ((murder) ? death_weapon.wr_killmessage(death_weapon) : death_weapon.wr_suicidemessage(death_weapon));
-               w_deathtype = false;
+       if (death_weapon == WEP_Null)
+               return false;
 
-               if (death_message)
-               {
-                       Send_Notification_WOCOVA(
-                               NOTIF_ONE,
-                               notif_target,
-                               MSG_MULTI,
-                               death_message,
-                               s1, s2, s3, "",
-                               f1, f2, 0, 0
-                       );
-                       // send the info part to everyone
-                       Send_Notification_WOCOVA(
-                               NOTIF_ALL_EXCEPT,
-                               notif_target,
-                               MSG_INFO,
-                               death_message.nent_msginfo,
-                               s1, s2, s3, "",
-                               f1, f2, 0, 0
-                       );
-               }
-               else
-               {
-                       LOG_TRACEF(
-                               "Obituary_WeaponDeath(): ^1Deathtype ^7(%d)^1 has no notification for weapon %d!\n",
-                               deathtype,
-                               death_weapon
-                       );
-               }
+       w_deathtype = deathtype;
+       Notification death_message = ((murder) ? death_weapon.wr_killmessage(death_weapon) : death_weapon.wr_suicidemessage(death_weapon));
+       w_deathtype = false;
 
-               return true;
+       if (death_message)
+       {
+               Send_Notification_WOCOVA(
+                       NOTIF_ONE,
+                       notif_target,
+                       MSG_MULTI,
+                       death_message,
+                       s1, s2, s3, "",
+                       f1, f2, 0, 0
+               );
+               // send the info part to everyone
+               Send_Notification_WOCOVA(
+                       NOTIF_ALL_EXCEPT,
+                       notif_target,
+                       MSG_INFO,
+                       death_message.nent_msginfo,
+                       s1, s2, s3, "",
+                       f1, f2, 0, 0
+               );
        }
-       return false;
+       else
+       {
+               LOG_TRACEF(
+                       "Obituary_WeaponDeath(): ^1Deathtype ^7(%d)^1 has no notification for weapon %d!\n",
+                       deathtype,
+                       death_weapon
+               );
+       }
+
+       return true;
 }
 
 bool frag_centermessage_override(entity attacker, entity targ, int deathtype, int kill_count_to_attacker, int kill_count_to_target)
@@ -283,9 +222,7 @@ bool frag_centermessage_override(entity attacker, entity targ, int deathtype, in
        return MUTATOR_CALLHOOK(FragCenterMessage, attacker, targ, deathtype, kill_count_to_attacker, kill_count_to_target);
 }
 
-.int buffs = _STAT(BUFFS); // TODO: remove
-entity buff_FirstFromFlags(int _buffs);
-void Obituary(entity attacker, entity inflictor, entity targ, int deathtype)
+void Obituary(entity attacker, entity inflictor, entity targ, int deathtype, .entity weaponentity)
 {
        // Sanity check
        if (!IS_PLAYER(targ)) { backtrace("Obituary called on non-player?!\n"); return; }
@@ -347,7 +284,7 @@ void Obituary(entity attacker, entity inflictor, entity targ, int deathtype)
                }
                LogDeath("suicide", deathtype, targ, targ);
                if(deathtype != DEATH_AUTOTEAMCHANGE.m_id) // special case: don't negate frags if auto switched
-                       GiveFrags(attacker, targ, -1, deathtype);
+                       GiveFrags(attacker, targ, -1, deathtype, weaponentity);
        }
 
        // ======
@@ -358,7 +295,7 @@ void Obituary(entity attacker, entity inflictor, entity targ, int deathtype)
                if(SAME_TEAM(attacker, targ))
                {
                        LogDeath("tk", deathtype, attacker, targ);
-                       GiveFrags(attacker, targ, -1, deathtype);
+                       GiveFrags(attacker, targ, -1, deathtype, weaponentity);
 
                        CS(attacker).killcount = 0;
 
@@ -372,18 +309,23 @@ void Obituary(entity attacker, entity inflictor, entity targ, int deathtype)
                else
                {
                        LogDeath("frag", deathtype, attacker, targ);
-                       GiveFrags(attacker, targ, 1, deathtype);
+                       GiveFrags(attacker, targ, 1, deathtype, weaponentity);
 
                        CS(attacker).taunt_soundtime = time + 1;
                        CS(attacker).killcount = CS(attacker).killcount + 1;
 
                        attacker.killsound += 1;
 
+                       // TODO: improve SPREE_ITEM and KILL_SPREE_LIST
+                       // these 2 macros are spread over multiple files
                        #define SPREE_ITEM(counta,countb,center,normal,gentle) \
                                case counta: \
                                { \
                                        Send_Notification(NOTIF_ONE, attacker, MSG_ANNCE, ANNCE_KILLSTREAK_##countb); \
-                                       PS_GR_P_ADDVAL(attacker, PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_##counta, 1); \
+                                       if (!warmup_stage)\
+                                       {\
+                                               PlayerStats_GameReport_Event_Player(attacker, PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_##counta, 1); \
+                                       }\
                                        break; \
                                }
                        switch(CS(attacker).killcount)
@@ -393,12 +335,12 @@ void Obituary(entity attacker, entity inflictor, entity targ, int deathtype)
                        }
                        #undef SPREE_ITEM
 
-                       if(!checkrules_firstblood)
+                       if(!warmup_stage && !checkrules_firstblood)
                        {
                                checkrules_firstblood = true;
                                notif_firstblood = true; // modify the current messages so that they too show firstblood information
-                               PS_GR_P_ADDVAL(attacker, PLAYERSTATS_ACHIEVEMENT_FIRSTBLOOD, 1);
-                               PS_GR_P_ADDVAL(targ, PLAYERSTATS_ACHIEVEMENT_FIRSTVICTIM, 1);
+                               PlayerStats_GameReport_Event_Player(attacker, PLAYERSTATS_ACHIEVEMENT_FIRSTBLOOD, 1);
+                               PlayerStats_GameReport_Event_Player(targ, PLAYERSTATS_ACHIEVEMENT_FIRSTVICTIM, 1);
 
                                // tell spree_inf and spree_cen that this is a first-blood and first-victim event
                                kill_count_to_attacker = -1;
@@ -459,7 +401,7 @@ void Obituary(entity attacker, entity inflictor, entity targ, int deathtype)
 
                        int f3 = 0;
                        if(deathtype == DEATH_BUFF.m_id)
-                               f3 = buff_FirstFromFlags(attacker.buffs).m_id;
+                               f3 = buff_FirstFromFlags(STAT(BUFFS, attacker)).m_id;
 
                        if (!Obituary_WeaponDeath(targ, true, deathtype, targ.netname, attacker.netname, deathlocation, CS(targ).killcount, kill_count_to_attacker))
                                Obituary_SpecialDeath(targ, true, deathtype, targ.netname, attacker.netname, deathlocation, CS(targ).killcount, kill_count_to_attacker, f3);
@@ -508,12 +450,15 @@ void Obituary(entity attacker, entity inflictor, entity targ, int deathtype)
                }
 
                LogDeath("accident", deathtype, targ, targ);
-               GiveFrags(targ, targ, -1, deathtype);
+               GiveFrags(targ, targ, -1, deathtype, weaponentity);
 
                if(GameRules_scoring_add(targ, SCORE, 0) == -5)
                {
                        Send_Notification(NOTIF_ONE, targ, MSG_ANNCE, ANNCE_ACHIEVEMENT_BOTLIKE);
-                       PS_GR_P_ADDVAL(attacker, PLAYERSTATS_ACHIEVEMENT_BOTLIKE, 1);
+                       if (!warmup_stage)
+                       {
+                               PlayerStats_GameReport_Event_Player(attacker, PLAYERSTATS_ACHIEVEMENT_BOTLIKE, 1);
+                       }
                }
        }
 
@@ -532,7 +477,7 @@ void Ice_Think(entity this)
        this.nextthink = time;
 }
 
-void Freeze (entity targ, float freeze_time, float frozen_type, float show_waypoint)
+void Freeze (entity targ, float revivespeed, float frozen_type, float show_waypoint)
 {
        if(!IS_PLAYER(targ) && !IS_MONSTER(targ)) // only specified entities can be freezed
                return;
@@ -543,12 +488,13 @@ void Freeze (entity targ, float freeze_time, float frozen_type, float show_waypo
        float targ_maxhealth = ((IS_MONSTER(targ)) ? targ.max_health : start_health);
 
        STAT(FROZEN, targ) = frozen_type;
-       targ.revive_progress = ((frozen_type == 3) ? 1 : 0);
+       STAT(REVIVE_PROGRESS, targ) = ((frozen_type == 3) ? 1 : 0);
        SetResourceAmount(targ, RESOURCE_HEALTH, ((frozen_type == 3) ? targ_maxhealth : 1));
-       targ.revive_speed = freeze_time;
+       targ.revive_speed = revivespeed;
        if(targ.bot_attack)
                IL_REMOVE(g_bot_targets, targ);
        targ.bot_attack = false;
+       targ.freeze_time = time;
 
        entity ice = new(ice);
        ice.owner = targ;
@@ -582,7 +528,7 @@ void Freeze (entity targ, float freeze_time, float frozen_type, float show_waypo
                WaypointSprite_Spawn(WP_Frozen, 0, 0, targ, '0 0 64', NULL, targ.team, targ, waypointsprite_attached, true, RADARICON_WAYPOINT);
 }
 
-void Unfreeze (entity targ)
+void Unfreeze(entity targ)
 {
        if(!STAT(FROZEN, targ))
                return;
@@ -594,7 +540,7 @@ void Unfreeze (entity targ)
        }
 
        STAT(FROZEN, targ) = 0;
-       targ.revive_progress = 0;
+       STAT(REVIVE_PROGRESS, targ) = 0;
        targ.revival_time = time;
        if(!targ.bot_attack)
                IL_PUSH(g_bot_targets, targ);
@@ -618,7 +564,7 @@ void Unfreeze (entity targ)
        targ.iceblock = NULL;
 }
 
-void Damage (entity targ, entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force)
+void Damage(entity targ, entity inflictor, entity attacker, float damage, int deathtype, .entity weaponentity, vector hitloc, vector force)
 {
        float complainteamdamage = 0;
        float mirrordamage = 0;
@@ -709,7 +655,7 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, int d
                                                                        force = '0 0 0';
                                                        }
                                                }
-                                               else
+                                               else if(!targ.canteamdamage)
                                                        damage = 0;
                                        }
                                }
@@ -726,7 +672,7 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, int d
                }
 
                // should this be changed at all? If so, in what way?
-               MUTATOR_CALLHOOK(Damage_Calculate, inflictor, attacker, targ, deathtype, damage, mirrordamage, force);
+               MUTATOR_CALLHOOK(Damage_Calculate, inflictor, attacker, targ, deathtype, damage, mirrordamage, force, attacker.(weaponentity));
                damage = M_ARGV(4, float);
                mirrordamage = M_ARGV(5, float);
                force = M_ARGV(6, vector);
@@ -735,9 +681,9 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, int d
                {
                        for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
                    {
-                       .entity weaponentity = weaponentities[slot];
-                       if(targ.(weaponentity).hook && targ.(weaponentity).hook.aiment == attacker)
-                               RemoveHook(targ.(weaponentity).hook);
+                       .entity went = weaponentities[slot];
+                       if(targ.(went).hook && targ.(went).hook.aiment == attacker)
+                               RemoveHook(targ.(went).hook);
                    }
                }
 
@@ -792,7 +738,7 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, int d
                        }
                }
 
-               if(!g_instagib)
+               if(!MUTATOR_IS_ENABLED(mutator_instagib))
                {
                        // apply strength multiplier
                        if (attacker.items & ITEM_Strength.m_itemid)
@@ -811,7 +757,13 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, int d
 
                        // 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)
@@ -901,7 +853,7 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, int d
        // apply damage
        if (damage != 0 || (targ.damageforcescale && force))
        if (targ.event_damage)
-               targ.event_damage (targ, inflictor, attacker, damage, deathtype, hitloc, force);
+               targ.event_damage (targ, inflictor, attacker, damage, deathtype, weaponentity, hitloc, force);
 
        // apply mirror damage if any
        if(!autocvar_g_mirrordamage_onlyweapons || DEATH_WEAPONOF(deathtype) != WEP_Null)
@@ -910,11 +862,12 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, int d
                attacker = attacker_save;
 
                force = normalize(attacker.origin + attacker.view_ofs - hitloc) * mirrorforce;
-               Damage(attacker, inflictor, attacker, mirrordamage, DEATH_MIRRORDAMAGE.m_id, attacker.origin, force);
+               Damage(attacker, inflictor, attacker, mirrordamage, DEATH_MIRRORDAMAGE.m_id, weaponentity, attacker.origin, force);
        }
 }
 
-float RadiusDamageForSource (entity inflictor, vector inflictororigin, vector inflictorvelocity, entity attacker, float coredamage, float edgedamage, float rad, entity cantbe, entity mustbe, float inflictorselfdamage, float forceintensity, int deathtype, entity directhitentity)
+float RadiusDamageForSource (entity inflictor, vector inflictororigin, vector inflictorvelocity, entity attacker, float coredamage, float edgedamage, float rad, entity cantbe, entity mustbe,
+                                                               float inflictorselfdamage, float forceintensity, int deathtype, .entity weaponentity, entity directhitentity)
        // Returns total damage applies to creatures
 {
        entity  targ;
@@ -1085,9 +1038,9 @@ float RadiusDamageForSource (entity inflictor, vector inflictororigin, vector in
                                                }
 
                                                if(targ == directhitentity || DEATH_ISSPECIAL(deathtype))
-                                                       Damage (targ, inflictor, attacker, finaldmg, deathtype, nearest, force);
+                                                       Damage(targ, inflictor, attacker, finaldmg, deathtype, weaponentity, nearest, force);
                                                else
-                                                       Damage (targ, inflictor, attacker, finaldmg, deathtype | HITTYPE_SPLASH, nearest, force);
+                                                       Damage(targ, inflictor, attacker, finaldmg, deathtype | HITTYPE_SPLASH, weaponentity, nearest, force);
                                        }
                                }
                        }
@@ -1103,9 +1056,9 @@ float RadiusDamageForSource (entity inflictor, vector inflictororigin, vector in
        return total_damage_to_creatures;
 }
 
-float RadiusDamage (entity inflictor, entity attacker, float coredamage, float edgedamage, float rad, entity cantbe, entity mustbe, float forceintensity, int deathtype, entity directhitentity)
+float RadiusDamage(entity inflictor, entity attacker, float coredamage, float edgedamage, float rad, entity cantbe, entity mustbe, float forceintensity, int deathtype, .entity weaponentity, entity directhitentity)
 {
-       return RadiusDamageForSource (inflictor, (inflictor.origin + (inflictor.mins + inflictor.maxs) * 0.5), inflictor.velocity, attacker, coredamage, edgedamage, rad, cantbe, mustbe, false, forceintensity, deathtype, directhitentity);
+       return RadiusDamageForSource(inflictor, (inflictor.origin + (inflictor.mins + inflictor.maxs) * 0.5), inflictor.velocity, attacker, coredamage, edgedamage, rad, cantbe, mustbe, false, forceintensity, deathtype, weaponentity, directhitentity);
 }
 
 float Fire_IsBurning(entity e)
@@ -1258,7 +1211,7 @@ void Fire_ApplyDamage(entity e)
 
        hi = e.fire_owner.damage_dealt;
        ty = e.fire_owner.typehitsound;
-       Damage(e, e, e.fire_owner, d, e.fire_deathtype, e.origin, '0 0 0');
+       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;