#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 <server/items/items.qh>
#include <server/main.qh>
#include <server/mutators/_mod.qh>
-#include <server/resources.qh>
#include <server/scores.qh>
#include <server/spawnpoints.qh>
#include <server/teamplay.qh>
if(w != 0 || slot == 0)
s = strcat(s, ftos(w));
}
- if(StatusEffects_active(STATUSEFFECT_Strength, player))
- s = strcat(s, "S");
- if(StatusEffects_active(STATUSEFFECT_Shield, 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
// 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;
}
if(deathtype != DEATH_TELEFRAG.m_id)
if(IS_PLAYER(attacker))
{
- if(IS_PLAYER(targ) && targ != attacker && (IS_INDEPENDENT_PLAYER(attacker) || IS_INDEPENDENT_PLAYER(targ)))
+ // avoid dealing damage or force to other independent players
+ // and avoid dealing damage or force to things owned by other independent players
+ if((IS_PLAYER(targ) && targ != attacker && (IS_INDEPENDENT_PLAYER(attacker) || IS_INDEPENDENT_PLAYER(targ))) ||
+ (targ.realowner && IS_INDEPENDENT_PLAYER(targ.realowner) && attacker != targ.realowner))
{
damage = 0;
force = '0 0 0';
}
}
- 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
if(PHYS_INPUT_BUTTON_CHAT(victim))
attacker.typehitsound += 1;
else
- attacker.damage_dealt += damage;
+ attacker.hitsound_damage_dealt += damage;
}
impressive_hits += 1;
// 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)
return 0;
}
+ if (rad < 0) rad = 0;
+
RadiusDamage_running = 1;
tfloordmg = autocvar_g_throughfloor_damage;
if (((cantbe != targ) && !mustbe) || (mustbe == targ))
if (targ.takedamage)
{
- vector nearest;
- vector diff;
- float power;
-
- // LordHavoc: measure distance to nearest point on target (not origin)
- // (this guarentees 100% damage on a touch impact)
- nearest = targ.WarpZone_findradius_nearest;
- diff = targ.WarpZone_findradius_dist;
+ // measure distance from nearest point on target (not origin)
+ // to nearest point on inflictor (not origin)
+ vector nearest = targ.WarpZone_findradius_nearest;
+ vector inflictornearest = NearestPointOnBoundingBox(
+ inflictororigin - (inflictor.maxs - inflictor.mins) * 0.5,
+ inflictororigin + (inflictor.maxs - inflictor.mins) * 0.5,
+ nearest);
+ vector diff = inflictornearest - nearest;
+
// round up a little on the damage to ensure full damage on impacts
// and turn the distance into a fraction of the radius
- power = 1 - ((vlen (diff) - bound(MIN_DAMAGEEXTRARADIUS, targ.damageextraradius, MAX_DAMAGEEXTRARADIUS)) / rad);
- //bprint(" ");
- //bprint(ftos(power));
- //if (targ == attacker)
- // print(ftos(power), "\n");
- if (power > 0)
+ float dist = max(0, vlen(diff) - bound(MIN_DAMAGEEXTRARADIUS, targ.damageextraradius, MAX_DAMAGEEXTRARADIUS));
+ if (dist <= rad)
{
- float finaldmg;
- if (power > 1)
- power = 1;
- finaldmg = coredamage * power + edgedamage * (1 - power);
+ float power = 1;
+ if (rad > 0)
+ power -= (dist / rad);
+ // at this point power can't be < 0 or > 1
+ float finaldmg = coredamage * power + edgedamage * (1 - power);
if (finaldmg > 0)
{
float a;
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;