]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/client/damage.qc
Merge remote branch 'origin/master' into samual/menu_updates
[xonotic/xonotic-data.pk3dir.git] / qcsrc / client / damage.qc
index 46ecf3aabe7571875d5e848a821d5788a55be944..34c15837acc26fe3e9cade3ce1430bd218b9da87 100644 (file)
@@ -1,5 +1,3 @@
-.float total_damages;
-
 void DamageEffect_Think()
 {
        // if particle distribution is enabled, slow ticrate by total number of damages
@@ -11,7 +9,7 @@ void DamageEffect_Think()
        if(time >= self.cnt || !self.owner || !self.owner.modelindex || !self.owner.drawmask)
        {
                // time is up or the player got gibbed / disconnected
-               self.owner.total_damages -= 1;
+               self.owner.total_damages = max(0, self.owner.total_damages - 1);
                remove(self);
                return;
        }
@@ -19,12 +17,16 @@ void DamageEffect_Think()
        {
                // if the player was dead but is now alive, it means he respawned
                // if so, clear his damage effects, or damages from his dead body will be copied back
-               self.owner.total_damages -= 1;
+               self.owner.total_damages = max(0, self.owner.total_damages - 1);
                remove(self);
                return;
        }
        self.state = self.owner.csqcmodel_isdead;
+#ifdef COMPAT_XON050_ENGINE
        if(self.owner.isplayermodel && (self.owner.entnum == player_localentnum || self.owner.entnum == spectatee_status) && !autocvar_chase_active)
+#else
+       if(self.owner.isplayermodel && (self.owner.entnum == player_localentnum) && !autocvar_chase_active)
+#endif
                return; // if we aren't using a third person camera, hide our own effects
 
        // now generate the particles
@@ -37,11 +39,11 @@ void DamageEffect(vector hitorg, float dmg, float type, float specnum)
 {
        // particle effects for players and objects damaged by weapons (eg: flames coming out of victims shot with rockets)
 
-       float life, skeletal;
-       string specstr, effectnum;
+       float life, nearestbone;
+       string specstr, effectname;
        entity e;
 
-       if(autocvar_cl_gentle || autocvar_cl_gentle_damage)
+       if(!autocvar_cl_damageeffect || autocvar_cl_gentle || autocvar_cl_gentle_damage)
                return;
        if(!self || !self.modelindex || !self.drawmask)
                return;
@@ -49,29 +51,26 @@ void DamageEffect(vector hitorg, float dmg, float type, float specnum)
        // if this is a rigged mesh, the effect will show on the bone where damage was dealt
        // we do this by choosing the skeletal bone closest to the impact, and attaching our entity to it
        // if there's no skeleton, object origin will automatically be selected
-       float closest;
        FOR_EACH_TAG(self)
        {
+               if(!tagnum)
+                       continue; // skip empty bones
                // blacklist bones positioned outside the mesh, or the effect will be floating
                // TODO: Do we have to do it this way? Why do these bones exist at all?
                if(gettaginfo_name == "master" || gettaginfo_name == "knee_L" || gettaginfo_name == "knee_R" || gettaginfo_name == "leg_L" || gettaginfo_name == "leg_R")
                        continue; // player model bone blacklist
-               if(gettaginfo_name == "")
-                       continue; // skip empty bones
 
                // now choose the bone closest to impact origin
-               if(!closest || vlen(hitorg - gettaginfo(self, tagnum)) <= vlen(hitorg - gettaginfo(self, closest)))
-               {
-                       closest = tagnum;
-                       skeletal = TRUE; // a bone was found, so this model is rigged
-               }
+               if(vlen(hitorg - gettaginfo(self, tagnum)) <= vlen(hitorg - gettaginfo(self, nearestbone)))
+                       nearestbone = tagnum;
        }
-       gettaginfo(self, closest); // set gettaginfo_name
+       gettaginfo(self, nearestbone); // set gettaginfo_name
 
        // return if we reached our damage effect limit or damages are disabled
-       if(skeletal)
+       // TODO: When the limit is reached, it would be better if the oldest damage was removed instead of not adding a new one
+       if(nearestbone)
        {
-               if(autocvar_cl_damageeffect < 1 || self.total_damages >= autocvar_cl_damageeffect_bones)
+               if(self.total_damages >= autocvar_cl_damageeffect_bones)
                        return; // allow multiple damages on skeletal models
        }
        else
@@ -85,7 +84,7 @@ void DamageEffect(vector hitorg, float dmg, float type, float specnum)
        type = DEATH_WEAPONOF(type);
        e = get_weaponinfo(type);
 
-       effectnum = strcat("damage_", e.netname);
+       effectname = strcat("damage_", e.netname);
        
        // if damage was dealt with a bullet weapon, our effect is blood
        // since blood is species dependent, include the species tag
@@ -93,20 +92,20 @@ void DamageEffect(vector hitorg, float dmg, float type, float specnum)
        {
                if(self.isplayermodel)
                {
-                       effectnum = strcat(effectnum, "_", specstr);
-                       effectnum = substring(effectnum, 0, strlen(effectnum) - 1); // remove the _ symbol at the end of the species tag
+                       effectname = strcat(effectname, "_", specstr);
+                       effectname = substring(effectname, 0, strlen(effectname) - 1); // remove the _ symbol at the end of the species tag
                }
                else
                        return; // objects don't bleed
        }
 
        e = spawn();
-       setmodel(e, "models/null.md3"); // necessary to attach and read origin // samual: FIXME: this is weird, is there some better way to do this?
+       setmodel(e, "null"); // necessary to attach and read origin // samual: FIXME: this is weird, is there some better way to do this?
        setattachment(e, self, gettaginfo_name); // attach to the given bone
        e.classname = "damage";
        e.owner = self;
        e.cnt = time + life;
-       e.team = particleeffectnum(effectnum);
+       e.team = particleeffectnum(effectname);
        e.think = DamageEffect_Think;
        e.nextthink = time;
        self.total_damages += 1;