void PlayerDamage(entity this, entity inflictor, entity attacker, float damage, int deathtype, .entity weaponentity, vector hitloc, vector force)
{
- float take, save, dh, da;
vector v;
- float excess;
+ float dh = max(GetResource(this, RES_HEALTH), 0);
+ float da = max(GetResource(this, RES_ARMOR), 0);
+ float take = 0, save = 0;
- dh = max(GetResource(this, RES_HEALTH), 0);
- da = max(GetResource(this, RES_ARMOR), 0);
-
- if(!DEATH_ISSPECIAL(deathtype))
+ if (damage)
{
- damage *= Handicap_GetTotalHandicap(this);
- if (this != attacker && IS_PLAYER(attacker))
+ if(!DEATH_ISSPECIAL(deathtype))
{
- damage /= Handicap_GetTotalHandicap(attacker);
+ damage *= Handicap_GetTotalHandicap(this);
+ if (this != attacker && IS_PLAYER(attacker))
+ {
+ damage /= Handicap_GetTotalHandicap(attacker);
+ }
}
- }
- if (time < this.spawnshieldtime && autocvar_g_spawnshield_blockdamage < 1)
- damage *= 1 - max(0, autocvar_g_spawnshield_blockdamage);
+ if (time < this.spawnshieldtime && autocvar_g_spawnshield_blockdamage < 1)
+ damage *= 1 - max(0, autocvar_g_spawnshield_blockdamage);
- if(DEATH_ISWEAPON(deathtype, WEP_TUBA))
- {
- // tuba causes blood to come out of the ears
- vector ear1, ear2;
- vector d;
- float f;
- ear1 = this.origin;
- ear1_z += 0.125 * this.view_ofs.z + 0.875 * this.maxs.z; // 7/8
- ear2 = ear1;
- makevectors(this.angles);
- ear1 += v_right * -10;
- ear2 += v_right * +10;
- d = inflictor.origin - this.origin;
- if (d)
- f = (d * v_right) / vlen(d); // this is cos of angle of d and v_right!
- else
- f = 0; // Assum ecenter.
- force = v_right * vlen(force);
- Violence_GibSplash_At(ear1, force * -1, 2, bound(0, damage, 25) / 2 * (0.5 - 0.5 * f), this, attacker);
- Violence_GibSplash_At(ear2, force, 2, bound(0, damage, 25) / 2 * (0.5 + 0.5 * f), this, attacker);
- if(f > 0)
+ if(deathtype & HITTYPE_SOUND) // sound based attacks cause bleeding from the ears
{
- hitloc = ear1;
- force = force * -1;
+ vector ear1, ear2;
+ vector d;
+ float f;
+ ear1 = this.origin;
+ ear1_z += 0.125 * this.view_ofs.z + 0.875 * this.maxs.z; // 7/8
+ ear2 = ear1;
+ makevectors(this.angles);
+ ear1 += v_right * -10;
+ ear2 += v_right * +10;
+ d = inflictor.origin - this.origin;
+ if (d)
+ f = (d * v_right) / vlen(d); // this is cos of angle of d and v_right!
+ else
+ f = 0; // Assum ecenter.
+ force = v_right * vlen(force);
+ Violence_GibSplash_At(ear1, force * -1, 2, bound(0, damage, 25) / 2 * (0.5 - 0.5 * f), this, attacker);
+ Violence_GibSplash_At(ear2, force, 2, bound(0, damage, 25) / 2 * (0.5 + 0.5 * f), this, attacker);
+ if(f > 0)
+ {
+ hitloc = ear1;
+ force = force * -1;
+ }
+ else
+ {
+ hitloc = ear2;
+ // force is already good
+ }
}
else
- {
- hitloc = ear2;
- // force is already good
- }
- }
- else
- Violence_GibSplash_At(hitloc, force, 2, bound(0, damage, 200) / 16, this, attacker);
+ Violence_GibSplash_At(hitloc, force, 2, bound(0, damage, 200) / 16, this, attacker);
- v = healtharmor_applydamage(GetResource(this, RES_ARMOR), autocvar_g_balance_armor_blockpercent, deathtype, damage);
- take = v.x;
- save = v.y;
+ v = healtharmor_applydamage(GetResource(this, RES_ARMOR), autocvar_g_balance_armor_blockpercent, deathtype, damage);
+ take = v.x;
+ save = v.y;
+ }
if(attacker == this)
{
- // don't reset pushltime for this damage as it may be an attempt to
+ // don't reset pushltime for self damage as it may be an attempt to
// escape a lava pit or similar
//this.pushltime = 0;
this.istypefrag = 0;
MUTATOR_CALLHOOK(PlayerDamage_SplitHealthArmor, inflictor, attacker, this, force, take, save, deathtype, damage);
take = bound(0, M_ARGV(4, float), GetResource(this, RES_HEALTH));
save = bound(0, M_ARGV(5, float), GetResource(this, RES_ARMOR));
- excess = max(0, damage - take - save);
+ float excess = max(0, damage - take - save);
if(sound_allowed(MSG_BROADCAST, attacker))
{
- if (save > 10)
+ if (save > 10 && (dh - take) > 0) // don't play armor sound if the attack is fatal
sound (this, CH_SHOTS, SND_ARMORIMPACT, VOL_BASE, ATTEN_NORM);
else if (take > 30)
sound (this, CH_SHOTS, SND_BODYIMPACT2, VOL_BASE, ATTEN_NORM);
this.v_angle_x = bound(-90, this.v_angle.x, 90);
}
- if (this != attacker) {
- float realdmg = damage - excess;
+ float realdmg = damage - excess;
+ if (this != attacker && realdmg)
+ if (!(round_handler_IsActive() && !round_handler_IsRoundStarted()) && time >= game_starttime)
+ {
if (IS_PLAYER(attacker) && DIFF_TEAM(attacker, this)) {
GameRules_scoring_add(attacker, DMG, realdmg);
}
bool valid_damage_for_weaponstats = false;
Weapon awep = WEP_Null;
+ if (!(round_handler_IsActive() && !round_handler_IsRoundStarted()) && time >= game_starttime)
if(vbot || IS_REAL_CLIENT(this))
if(abot || IS_REAL_CLIENT(attacker))
if(attacker && this != attacker)
// print an obituary message
if(this.classname != "body")
- Obituary (attacker, inflictor, this, deathtype, weaponentity);
+ Obituary(attacker, inflictor, this, deathtype, weaponentity);
// increment frag counter for used weapon type
Weapon w = DEATH_WEAPONOF(deathtype);
this.avelocity = '0 0 0';
// view from the floor
this.view_ofs = '0 0 -8';
- // toss the corpse
- set_movetype(this, MOVETYPE_TOSS);
+ if(this.move_movetype == MOVETYPE_NOCLIP)
+ {
+ // don't toss the corpse in this case, it can get stuck in solid (causing low fps)
+ // or fall indefinitely into the void if out of the map
+ this.velocity = '0 0 0';
+ }
+ else
+ {
+ // toss the corpse
+ set_movetype(this, MOVETYPE_TOSS);
+ }
// shootable corpse
this.solid = SOLID_CORPSE;
PS(this).ballistics_density = autocvar_g_ballistics_density_corpse;