58 f -= (teamkills * (teamkills - 1)) * 0.5;
72 if (
MUTATOR_CALLHOOK(GiveFragsForKill, attacker, targ, f, deathtype, attacker.(weaponentity)))
75 attacker.totalfrags += f;
86 int w = player.(weaponentity).
m_weapon.m_id;
88 w = player.(weaponentity).
cnt;
89 if (w != 0 || slot == 0)
104 string s =
strcat(
":kill:", mode,
105 ":",
ftos(killer.playerid),
106 ":",
ftos(killed.playerid));
109 if (killed != killer)
111 s =
strcat(s,
":victimitems=");
122 string s1,
string s2,
string s3,
string s4,
123 float f1,
float f2,
float f3)
127 backtrace(
"Obituary_SpecialDeath called without a special deathtype?\n");
134 backtrace(
"Obituary_SpecialDeath: Could not find deathtype entity!\n");
138 if (
g_cts && deathtype == DEATH_KILL.m_id)
142 ? (murder ? deathent.death_msg_ent_murder : deathent.death_msg_ent_self)
143 : (murder ? deathent.death_msgmurder : deathent.death_msgself);
158 death_message.nent_msginfo,
169 string s1,
string s2,
string s3,
173 if (death_weapon == WEP_Null)
195 death_message.nent_msginfo,
202 "Obituary_WeaponDeath(): ^1Deathtype ^7(%d)^1 has no notification for weapon %s!\n",
212 if (deathtype == DEATH_FIRE.m_id)
215 Send_Notification(NOTIF_ONE, targ, MSG_CHOICE, CHOICE_FRAGGED_FIRE, attacker_name, kill_count_to_target,
GetResource(attacker, RES_HEALTH),
GetResource(attacker,
RES_ARMOR), (
IS_BOT_CLIENT(attacker) ? -1 :
CS(attacker).
ping));
219 return MUTATOR_CALLHOOK(FragCenterMessage, attacker, targ, deathtype, kill_count_to_attacker, kill_count_to_target);
227 backtrace(
"Obituary called on non-player?!\n");
232 float notif_firstblood =
false;
233 float kill_count_to_attacker, kill_count_to_target;
234 bool notif_anonymous =
false;
235 string attacker_name = attacker.netname;
238 targ.death_origin = targ.origin;
242 if (
MUTATOR_CALLHOOK(ClientObituary, inflictor, attacker, targ, deathtype, attacker.(weaponentity)))
244 CS(targ).killcount = 0;
247 notif_anonymous =
M_ARGV(5,
bool);
252 attacker_name =
"???";
254 #ifdef NOTIFICATIONS_DEBUG
255 Debug_Notification(sprintf(
256 "Obituary(%s, %s, %s, %s = %d);\n",
268 if (targ == attacker)
272 if (deathtype == DEATH_TEAMCHANGE.m_id || deathtype == DEATH_AUTOTEAMCHANGE.m_id)
273 Obituary_SpecialDeath(targ,
false,
false, deathtype, targ.netname, deathlocation,
"",
"", targ.team, 0, 0);
278 case DEATH_MIRRORDAMAGE:
279 Obituary_SpecialDeath(targ,
false,
false, deathtype, targ.netname, deathlocation,
"",
"",
CS(targ).
killcount, 0, 0);
281 case DEATH_HURTTRIGGER:
283 bool msg_from_ent = (inflictor && inflictor.message !=
"");
286 (msg_from_ent ? inflictor.message : deathlocation),
287 (msg_from_ent ? deathlocation :
""),
293 Obituary_SpecialDeath(targ,
false,
false, deathtype, targ.netname, deathlocation,
"",
"",
CS(targ).
killcount, 0, 0);
300 backtrace(
"SUICIDE: what the hell happened here?\n");
303 LogDeath(
"suicide", deathtype, targ, targ);
304 if (deathtype != DEATH_AUTOTEAMCHANGE.m_id)
305 GiveFrags(attacker, targ, -1, deathtype, weaponentity);
315 LogDeath(
"tk", deathtype, attacker, targ);
316 GiveFrags(attacker, targ, -1, deathtype, weaponentity);
318 CS(attacker).killcount = 0;
320 Send_Notification(NOTIF_ONE, attacker, MSG_CENTER, CENTER_DEATH_TEAMKILL_FRAG, targ.netname);
321 Send_Notification(NOTIF_ONE, targ, MSG_CENTER, CENTER_DEATH_TEAMKILL_FRAGGED, attacker_name);
329 LogDeath(
"frag", deathtype, attacker, targ);
330 GiveFrags(attacker, targ, 1, deathtype, weaponentity);
332 CS(attacker).taunt_soundtime =
time + 1;
333 ++
CS(attacker).killcount;
335 ++attacker.killsound;
339 #define SPREE_ITEM(counta,countb,center,normal,gentle) \
341 Send_Notification(NOTIF_ONE, attacker, MSG_ANNCE, ANNCE_KILLSTREAK_##countb); \
343 PlayerStats_GameReport_Event_Player(attacker, PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_##counta, 1); \
357 notif_firstblood =
true;
362 kill_count_to_attacker = -1;
363 kill_count_to_target = -2;
367 kill_count_to_attacker =
CS(attacker).killcount;
368 kill_count_to_target = 0;
379 kill_count_to_attacker,
388 kill_count_to_target,
402 kill_count_to_attacker,
411 kill_count_to_target,
420 bool msg_from_ent = (
DEATH_ENT(deathtype) == DEATH_HURTTRIGGER && inflictor && inflictor.message2 !=
"");
424 (msg_from_ent ? inflictor.message2 : deathlocation),
425 (msg_from_ent ? deathlocation :
""),
442 case DEATH_HURTTRIGGER:
444 bool msg_from_ent = (inflictor && inflictor.message !=
"");
447 (msg_from_ent ? inflictor.message : deathlocation),
448 (msg_from_ent ? deathlocation :
""),
464 Obituary_SpecialDeath(targ,
false,
false, deathtype, targ.netname, deathlocation,
"",
"",
CS(targ).
killcount, 0, 0);
468 LogDeath(
"accident", deathtype, targ, targ);
469 GiveFrags(targ, targ, -1, deathtype, weaponentity);
480 CS(targ).killcount = 0;
493 entity attacker_save = attacker;
495 float complainteamdamage = 0;
496 float mirrordamage = 0;
497 float mirrorforce = 0;
499 if (deathtype == DEATH_KILL.m_id || deathtype == DEATH_TEAMCHANGE.m_id || deathtype == DEATH_AUTOTEAMCHANGE.m_id)
508 if (deathtype == DEATH_TEAMCHANGE.m_id || deathtype == DEATH_AUTOTEAMCHANGE.m_id)
517 else if (deathtype == DEATH_MIRRORDAMAGE.m_id || deathtype == DEATH_NOAMMO.m_id)
524 if (deathtype != DEATH_TELEFRAG.m_id
539 else if (attacker != targ)
545 attacker.dmg_team += damage;
555 attacker.dmg_team += damage;
557 if (complainteamdamage > 0)
566 attacker.dmg_take += v.x;
567 attacker.dmg_save += v.y;
568 attacker.dmg_inflictor = inflictor;
576 targ.dmg_take += v.x;
577 targ.dmg_save += v.y;
578 targ.dmg_inflictor = inflictor;
584 else if (!targ.canteamdamage)
601 MUTATOR_CALLHOOK(Damage_Calculate, inflictor, attacker, targ, deathtype, damage, mirrordamage, force, attacker.(weaponentity));
602 damage =
M_ARGV(4,
float);
603 mirrordamage =
M_ARGV(5,
float);
606 if (
IS_PLAYER(targ) && damage > 0 && attacker)
610 if (targ.(went).hook && targ.(went).hook.aiment == attacker)
614 if (targ == attacker)
618 if (attacker && targ != attacker
620 && deathtype != DEATH_BUFF_INFERNO.m_id
621 && deathtype != DEATH_BUFF_VENGEANCE.m_id
638 if (deathtype != DEATH_FIRE.m_id)
641 ++attacker.typehitsound;
643 attacker.hitsound_damage_dealt += damage;
656 if (deathtype != DEATH_FIRE.m_id)
657 ++attacker.typehitsound;
658 if (complainteamdamage > 0
661 CS(attacker).teamkill_complain =
time + 5;
662 CS(attacker).teamkill_soundtime =
time + 0.4;
663 CS(attacker).teamkill_soundsource = targ;
671 if (targ.damageforcescale && force
677 entity farcent =
new(farce);
678 farcent.enemy = targ;
679 farcent.movedir = farce * 10;
681 farcent.movedir *= targ.mass;
682 farcent.origin = hitloc;
684 farcent.nextthink =
time + 0.1;
688 targ.velocity += farce;
693 if ((damage != 0 || (targ.damageforcescale && force))
694 && targ.event_damage)
695 targ.event_damage(targ, inflictor, attacker, damage, deathtype, weaponentity, hitloc, force);
699 && (mirrordamage > 0 || mirrorforce > 0))
701 attacker = attacker_save;
703 force =
normalize(attacker.origin + attacker.view_ofs - hitloc) * mirrorforce;
704 Damage(attacker, inflictor, attacker, mirrordamage, DEATH_MIRRORDAMAGE.m_id, weaponentity, attacker.origin, force);
711 float coredamage,
float edgedamage,
float rad,
entity cantbe,
entity mustbe,
712 bool inflictorselfdamage,
float forceintensity,
vector forcexyzscale,
713 int deathtype, .
entity weaponentity,
entity directhitentity)
717 backtrace(
"RadiusDamage called recursively! Expect stuff to go HORRIBLY wrong.");
729 float stat_damagedone = 0;
730 float total_damage_to_creatures = 0;
735 force = inflictorvelocity;
736 if (force ==
'0 0 0')
740 if (forceintensity >= 0)
741 Damage_DamageInfo(inflictororigin, coredamage, edgedamage, rad, forceintensity * force, deathtype, 0, attacker);
743 Damage_DamageInfo(inflictororigin, coredamage, edgedamage, -rad, (-forceintensity) * force, deathtype, 0, attacker);
747 for (; targ; targ = targ.chain)
748 if ((targ != inflictor || inflictorselfdamage)
749 && (((cantbe != targ) && !mustbe) || mustbe == targ)
755 vector nearest = targ.WarpZone_findradius_nearest;
760 vector inflictororigin_wz = targ.WarpZone_findradius_nearest + targ.WarpZone_findradius_dist;
762 inflictororigin_wz + inflictor.mins, inflictororigin_wz + inflictor.maxs, nearest);
763 vector diff = inflictornearest - nearest;
770 float f = (rad > 0) ? 1 - (dist / rad) : 1;
772 float finaldmg = coredamage * f + edgedamage * (1 - f);
783 if (targ != attacker)
784 center = targ.origin + ((targ.mins + targ.maxs) * 0.5);
791 vector mi =
'0 0 0', ma =
'0 0 0';
801 tracebox(center, mi, ma, center + dv,
MOVE_NORMAL, targ);
810 center.z += targ.(weaponentity).
movedir.z;
826 force =
normalize(center - inflictororigin_wz);
827 force *= (finaldmg /
max(coredamage, edgedamage)) * forceintensity;
832 force.x *= forcexyzscale.x;
834 force.y *= forcexyzscale.y;
836 force.z *= forcexyzscale.z;
838 if (targ != directhitentity)
843 float mininv_f, mininv_d;
857 LOG_INFOF(
"THROUGHFLOOR: D=%f F=%f max(dD)=1/%f max(dF)=1/%f", finaldmg,
vlen(force), mininv_d, mininv_f);
859 total = 0.25 * (
max(mininv_f, mininv_d) ** 2);
870 LOG_INFOF(
" steps=%f dD=%f dF=%f", total, finaldmg * (1-tfloordmg) / (2 *
sqrt(total)),
vlen(force) * (1-tfloorforce) / (2 *
sqrt(total)));
872 for (c = 0; c < total; ++c)
884 nearest.x = targ.origin.x + targ.mins.x +
random() * targ.size.x;
885 nearest.y = targ.origin.y + targ.mins.y +
random() * targ.size.y;
886 nearest.z = targ.origin.z + targ.mins.z +
random() * targ.size.z;
889 nearest = hitloc * (1 /
max(1, hits));
890 hitratio = hits / total;
891 a =
bound(0, tfloordmg + (1 - tfloordmg) * hitratio, 1);
893 a =
bound(0, tfloorforce + (1 - tfloorforce) * hitratio, 1);
907 if (finaldmg || force)
911 total_damage_to_creatures += finaldmg;
914 stat_damagedone += finaldmg;
918 Damage(targ, inflictor, attacker, finaldmg, deathtype, weaponentity, nearest, force);
920 Damage(targ, inflictor, attacker, finaldmg, deathtype |
HITTYPE_SPLASH, weaponentity, nearest, force);
931 return total_damage_to_creatures;
936 float coredamage,
float edgedamage,
float rad,
entity cantbe,
entity mustbe,
937 float forceintensity,
938 int deathtype, .
entity weaponentity,
entity directhitentity)
941 inflictor, (inflictor.origin + (inflictor.mins + inflictor.maxs) * 0.5), inflictor.velocity, attacker,
942 coredamage, edgedamage, rad, cantbe, mustbe,
943 false, forceintensity,
'1 1 1',
944 deathtype, weaponentity, directhitentity
956 bool healed = (targ.event_heal)
957 ? targ.event_heal(targ, inflictor, amount, limit)
979 float mintime = fireendtime -
time;
980 float maxtime =
max(mintime, t);
982 float mindps = e.fire_damagepersec;
983 float maxdps =
max(mindps, dps);
985 if (maxtime > mintime || maxdps > mindps)
990 float mindamage = mindps * mintime;
993 float maxdamage = mindamage + d;
996 float totaldamage =
min(maxdamage, maxtime * maxdps);
1019 float totaltime =
min(maxtime, totaldamage / mindps);
1041 e.fire_damagepersec = totaldamage / totaltime;
1043 if (totaldamage > 1.2 * mindamage)
1045 e.fire_deathtype = dt;
1046 if (e.fire_owner != o)
1049 e.fire_hitsound =
false;
1054 return max(0, totaldamage - mindamage);
1061 e.fire_damagepersec = dps;
1063 e.fire_deathtype = dt;
1065 e.fire_hitsound =
false;
1076 for (t = 0, o = e.owner; o.owner && t < 16; o = o.owner, ++t);
1082 float d = e.fire_damagepersec * t;
1084 float hi = e.fire_owner.hitsound_damage_dealt;
1085 float ty = e.fire_owner.typehitsound;
1086 Damage(e, e, e.fire_owner, d, e.fire_deathtype,
DMG_NOWEP, e.origin,
'0 0 0');
1087 if (e.fire_hitsound && e.fire_owner)
1089 e.fire_owner.hitsound_damage_dealt = hi;
1090 e.fire_owner.typehitsound = ty;
1092 e.fire_hitsound =
true;
1097 if (!IS_DEAD(it) && it.takedamage && !IS_INDEPENDENT_PLAYER(it)
1098 && boxesoverlap(e.absmin, e.absmax, it.absmin, it.absmax))
1100 t = autocvar_g_balance_firetransfer_time * (fireendtime - time);
1101 d = autocvar_g_balance_firetransfer_damage * e.fire_damagepersec * t;
1102 Fire_AddDamage(it, o, d, t, DEATH_FIRE.m_id);
void accuracy_add(entity this, Weapon w, float fired, float hit, float real)
update accuracy stats
bool accuracy_isgooddamage(entity attacker, entity targ)
does this damage count towards accuracy stats?
void tracebox_antilag(entity source, vector v1, vector mi, vector ma, vector v2, float nomonst, entity forent, float lag)
#define ANTILAG_LATENCY(e)
#define MUTATOR_CALLHOOK(id,...)
vector damage_explosion_calcpush(vector explosion_f, vector target_v, float speedfactor)
var entity(vector mins, vector maxs,.entity tofield) findbox_tofield_OrFallback
float GetResource(entity e, Resource res_type)
Returns the current amount of resource the given entity has.
fields which are explicitly/manually set are marked with "M", fields set automatically are marked wit...
virtual void wr_suicidemessage()
(SERVER) notification number for suicide message (may inspect w_deathtype for details)
string netname
M: refname : reference name name.
virtual void wr_killmessage()
(SERVER) notification number for kill message (may inspect w_deathtype for details)
bool IsFlying(entity this)
#define IS_NOT_A_CLIENT(s)
#define PHYS_INPUT_BUTTON_CHAT(s)
vector healtharmor_applydamage(float a, float armorblock, int deathtype, float damage)
const int FRAGS_SPECTATOR
const float MOVE_NOMONSTERS
void UpdateCSQCProjectile(entity e)
void Damage(entity targ, entity inflictor, entity attacker, float damage, int deathtype,.entity weaponentity, vector hitloc, vector force)
bool Heal(entity targ, entity inflictor, float amount, float limit)
float RadiusDamage(entity inflictor, entity attacker, float coredamage, float edgedamage, float rad, entity cantbe, entity mustbe, float forceintensity, int deathtype,.entity weaponentity, entity directhitentity)
void GiveFrags(entity attacker, entity targ, float f, int deathtype,.entity weaponentity)
float Fire_AddDamage(entity e, entity o, float d, float t, float dt)
float Obituary_WeaponDeath(entity notif_target, bool murder, int deathtype, string s1, string s2, string s3, float f1, float f2)
bool frag_centermessage_override(entity attacker, entity targ, int deathtype, int kill_count_to_attacker, int kill_count_to_target, string attacker_name)
float RadiusDamageForSource(entity inflictor, vector inflictororigin, vector inflictorvelocity, entity attacker, float coredamage, float edgedamage, float rad, entity cantbe, entity mustbe, bool inflictorselfdamage, float forceintensity, vector forcexyzscale, int deathtype,.entity weaponentity, entity directhitentity)
void Fire_ApplyDamage(entity e)
void Obituary_SpecialDeath(entity notif_target, bool murder, bool msg_from_ent, int deathtype, string s1, string s2, string s3, string s4, float f1, float f2, float f3)
string AppendItemcodes(string s, entity player)
void Obituary(entity attacker, entity inflictor, entity targ, int deathtype,.entity weaponentity)
void LogDeath(string mode, int deathtype, entity killer, entity killed)
bool RadiusDamage_running
bool autocvar_g_mirrordamage_virtual
bool autocvar_g_mirrordamage_onlyweapons
int autocvar_g_player_damageplayercenter
float autocvar_g_throughfloor_force_max_stddev
float autocvar_g_friendlyfire_virtual_force
float autocvar_g_throughfloor_damage_max_stddev
float autocvar_g_balance_armor_blockpercent
IntrusiveList g_damagedbycontents
float autocvar_g_throughfloor_force
float autocvar_g_balance_selfdamagepercent
bool autocvar_g_throughfloor_debug
float checkrules_firstblood
float autocvar_g_friendlyfire_virtual
float autocvar_g_teamdamage_threshold
float autocvar_g_throughfloor_min_steps_other
float autocvar_g_friendlyfire
float autocvar_g_throughfloor_min_steps_player
float autocvar_g_balance_damagepush_speedfactor
float autocvar_g_throughfloor_damage
float autocvar_g_throughfloor_max_steps_other
float autocvar_g_throughfloor_max_steps_player
float autocvar_g_mirrordamage
bool autocvar_g_teamkill_punishing
void Damage_DamageInfo(vector org, float coredamage, float edgedamage, float rad, vector force, int deathtype, float bloodtype, entity dmgowner)
const float MAX_DAMAGEEXTRARADIUS
const float MIN_DAMAGEEXTRARADIUS
string Deathtype_Name(int deathtype)
#define DEATH_ISWEAPON(t, w)
#define DEATH_ISSPECIAL(t)
const int HITTYPE_SPAM
set manually after first RadiusDamage, stops effect spam
const int HITTYPE_SPLASH
automatically set by RadiusDamage
#define DEATH_WEAPONOF(t)
const int HITTYPE_SOUND
cause bleeding from ears
void SUB_Remove(entity this)
Remove entity.
const float FORCETYPE_FORCEATPOS
SetResourceExplicit(ent, RES_ARMOR, ReadByte() *DEC_FACTOR)) ENTCS_PROP(NAME
void GameLogEcho(string s)
bool autocvar_sv_eventlog
#define IL_EACH(this, cond, body)
entity WarpZone_FindRadius(vector org, float rad, bool needlineofsight)
void WarpZone_TraceLine(vector org, vector end, float nomonsters, entity forent)
vector WarpZone_UnTransformOrigin(entity wz, vector v)
#define UNSET_ONGROUND(s)
const int MOVETYPE_PHYSICS
const int MOVETYPE_NOCLIP
@ STATUSEFFECT_REMOVE_CLEAR
Effect is being forcibly removed without calling any additional mechanics.
spree_inf s1 s2 s3loc s2 spree_inf s1 s2 s3loc s2 spree_inf s1 s2 s3loc s2 s1 s2loc s1 s2loc s1 s2loc s1 s2loc s1 s2loc s1 s2loc s1 s2 f1points f2
spree_inf s1 s2 s3loc s2 s1
spree_inf s1 s2 s3loc s2 spree_inf s1 s2 s3loc s2 spree_inf s1 s2 s3loc s2 s1 s2loc s1 s2loc s1 s2loc s1 s2loc s1 s2loc s1 s2loc s1 s2 f1points s1 s2
strcat(_("^F4Countdown stopped!"), "\n^BG", _("Teams are too unbalanced."))
void Send_Notification_Core(NOTIF broadcast, entity client, MSG net_type, Notification net_name, string s1, string s2, string s3, string s4, float f1, float f2, float f3, float f4)
void Send_Notification(NOTIF broadcast, entity client, MSG net_type, Notification net_name,...count)
bool autocvar_notification_server_allows_location
entity Notification
always last
#define APP_TEAM_NUM(num, prefix)
const string PLAYERSTATS_ACHIEVEMENT_FIRSTBLOOD
const string PLAYERSTATS_ACHIEVEMENT_FIRSTVICTIM
const string PLAYERSTATS_ACHIEVEMENT_BOTLIKE
#define PlayerStats_GameReport_Event_Player(ent, eventid, val)
#define REGISTRY_GET(id, i)
string NearestLocation(vector p)
#define IS_INDEPENDENT_PLAYER(e)
void RemoveHook(entity this)
ClientState CS(Client this)
void StatusEffects_remove(StatusEffect this, entity actor, int removal_type)
float StatusEffects_gettime(StatusEffect this, entity actor)
bool StatusEffects_active(StatusEffect this, entity actor)
void StatusEffects_apply(StatusEffect this, entity actor, float eff_time, int eff_flags)
Header file that describes the resource system.
#define GameRules_scoring_add(client, fld, value)
#define GameRules_scoring_add_team(client, fld, value)
void vehicles_exit(entity vehic, bool eject)
const int VHEF_RELEASE
Release ownership, client possibly allready dissconnected / went spec / changed team / used "kill" (n...
int autocvar_teamplay_mode
#define CENTER_OR_VIEWOFS(ent)
#define IS_BOT_CLIENT(v)
want: (IS_CLIENT(v) && !IS_REAL_CLIENT(v))
ERASEABLE vector NearestPointOnBoundingBox(vector mi, vector ma, vector org)
const int MAX_WEAPONSLOTS
entity weaponentities[MAX_WEAPONSLOTS]
float autocvar_g_weaponforcefactor
float autocvar_g_weapondamagefactor