X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fclient%2Fdamage.qc;h=2ac4a01c138f4c7c1511a2985465ab7472350998;hb=d03bf59652dab079deef7cf35e5b80599b13df05;hp=ae7440500752c4d7af02eb93816609215dc181a2;hpb=22a9cf27830f1ced8fbf6c878b068b7d1a750a26;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/client/damage.qc b/qcsrc/client/damage.qc index ae7440500..2ac4a01c1 100644 --- a/qcsrc/client/damage.qc +++ b/qcsrc/client/damage.qc @@ -1,4 +1,4 @@ -void DamageEffect(vector hitorg, float dmg, float type, float specnum1, float entnumber); +void DamageEffect(vector hitorg, float dmg, float type, float specnum1); void Ent_DamageInfo(float isNew) { float dmg, rad, edge, thisdmg, forcemul, species; @@ -40,6 +40,8 @@ void Ent_DamageInfo(float isNew) thisdmg = ((vlen (nearest - w_org) - bound(MIN_DAMAGEEXTRARADIUS, self.damageextraradius, MAX_DAMAGEEXTRARADIUS)) / rad); if(thisdmg >= 1) continue; + if(thisdmg < 0) + thisdmg = 0; if(dmg) { thisdmg = dmg + (edge - dmg) * thisdmg; @@ -73,7 +75,7 @@ void Ent_DamageInfo(float isNew) if(self.event_damage) self.event_damage(thisdmg, w_deathtype, w_org, thisforce); - DamageEffect(w_org, thisdmg, w_deathtype, species, self.entnum - 1); + DamageEffect(w_org, thisdmg, w_deathtype, species); } self = oldself; @@ -236,86 +238,88 @@ void DamageInfo_Precache() (get_weaponinfo(i)).weapon_func(WR_PRECACHE); } -// damage effect - -.entity dmgent; -.float dmgpartnum, dmgtime; -.float lifetime; - void DamageEffect_Think() { - self.nextthink = time; - vector org; - - if(time >= self.lifetime) + if(time >= self.cnt || self.owner == world || self.owner.model == "" || !self.owner.drawmask) { + // time is up or the player got gibbed / disconnected remove(self); - self = world; return; } - if(self.dmgtime > time) - return; - if(!autocvar_cl_damageeffect) - return; // don't show effects on the invisible dead body if gibs exist - if(self.team == player_localentnum - 1 && !autocvar_chase_active) - return; // if we aren't in third person mode, hide own damage effect + if(self.owner.entnum == player_localentnum && !autocvar_chase_active) + return; // if we aren't using a third person view, hide our own effects - // Now apply the effect to the player - org = gettaginfo(self, 0); - pointparticles(self.dmgpartnum, org, '0 0 0', 1); - self.dmgtime = time + autocvar_cl_damageeffect; + // now generate the particles + vector org; + org = gettaginfo(self, 0); // origin at attached location + pointparticles(self.team, org, '0 0 0', 1); + self.nextthink = time + autocvar_cl_damageeffect_ticrate; } -void DamageEffect(vector hitorg, float dmg, float type, float specnum, float entnumber) +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, i; string specstr, effectnum; entity e; - if(!autocvar_cl_damageeffect || autocvar_cl_gentle || autocvar_cl_gentle_damage) + if(autocvar_cl_gentle || autocvar_cl_gentle_damage) return; - if(self.model == "" || !self.model) + if(self == world || self.model == "" || !self.drawmask) return; - // if we reached our damage count limit for this player, return + // return if we reached our damage effect limit for(e = world; (e = find(e, classname, "damageeffect")); ) - { - if(e.team == entnumber) + if(e.owner.entnum == self.entnum) i += 1; - } - if(i >= autocvar_cl_damageeffect_limit) - return; + if(autocvar_cl_damageeffect < 1 || (self.isplayermodel && i >= autocvar_cl_damageeffect_limit)) + return; // allow multiple damage effects on players + if(autocvar_cl_damageeffect < 2 || (!self.isplayermodel && i)) + return; // allow a single damage effect on objects specstr = species_prefix(specnum); - life = bound(0, dmg * autocvar_cl_damageeffect_lifetime, autocvar_cl_damageeffect_lifetime_max); - + life = bound(autocvar_cl_damageeffect_lifetime_min, dmg * autocvar_cl_damageeffect_lifetime, autocvar_cl_damageeffect_lifetime_max); + type = DEATH_WEAPONOF(type); e = get_weaponinfo(type); + effectnum = strcat("weapondamage_", e.netname); - // If the weapon is a bullet weapon, its damage effect is blood. - // Since blood is species dependent, we make this effect per-species. + // if the weapon is a bullet weapon, its damage effect is blood + // since blood is species dependent, use the species tag for this effect if(type == WEP_SHOTGUN || type == WEP_UZI || type == WEP_RIFLE) - if(specstr != "") { - effectnum = strcat(effectnum, "_", specstr); - effectnum = substring(effectnum, 0, strlen(effectnum) - 1); // remove the _ symbol at the end of the species name + if(self.isplayermodel) + { + effectnum = strcat(effectnum, "_", specstr); + effectnum = substring(effectnum, 0, strlen(effectnum) - 1); // remove the _ symbol at the end of the species tag + } + else + return; // objects don't bleed } - float closest; - for(i = 0; gettaginfo(self, i); i++) + // if this is a player, damage effects will show on the limb where damage was dealt + // we do this by choosing the skeletal bone closest to the impact, and attaching the effect there + if(self.isplayermodel) { - // go through all tags on the player model, choose the one closest to the damage origin - if(!closest || vlen(hitorg - gettaginfo(self, i)) <= vlen(hitorg - gettaginfo(self, closest))) - closest = i; + float closest; + FOR_EACH_TAG(self) + { + // go through all skeletal bones on the player, and choose the one closest to the damage origin + if(!closest || vlen(hitorg - gettaginfo(self, tagnum)) <= vlen(hitorg - gettaginfo(self, closest))) + closest = tagnum; + } + gettaginfo(self, closest); // set gettaginfo_name to our bone } - gettaginfo(self, closest); // set gettaginfo_name + else + gettaginfo(self, 0); // set gettaginfo_name to entity origin e = spawn(); - setmodel(e, "models/null.md3"); - setattachment(e, self, gettaginfo_name); + setmodel(e, "models/null.md3"); // necessary to attach and read origin + setattachment(e, self, gettaginfo_name); // attach to the given bone + e.owner = self; + e.cnt = time + life; e.classname = "damageeffect"; - e.team = entnumber; - e.dmgpartnum = particleeffectnum(effectnum); - e.lifetime = time + life; + e.team = particleeffectnum(effectnum); e.think = DamageEffect_Think; e.nextthink = time; }