60 f -= (teamkills * (teamkills - 1)) * 0.5;
74 if(
MUTATOR_CALLHOOK(GiveFragsForKill, attacker, targ, f, deathtype, attacker.(weaponentity)))
77 attacker.totalfrags += f;
88 int w = player.(weaponentity).
m_weapon.m_id;
90 w = player.(weaponentity).
cnt;
91 if(w != 0 || slot == 0)
107 s =
strcat(
":kill:", mode);
115 s =
strcat(s,
":victimitems=");
126 string s1,
string s2,
string s3,
string s4,
127 float f1,
float f2,
float f3)
131 backtrace(
"Obituary_SpecialDeath called without a special deathtype?\n");
138 backtrace(
"Obituary_SpecialDeath: Could not find deathtype entity!\n");
142 if(
g_cts && deathtype == DEATH_KILL.m_id)
145 Notification death_message = (murder) ? deathent.death_msgmurder : deathent.death_msgself;
147 death_message = (murder) ? deathent.death_msg_ent_murder : deathent.death_msg_ent_self;
162 death_message.nent_msginfo,
173 string s1,
string s2,
string s3,
177 if (death_weapon == WEP_Null)
199 death_message.nent_msginfo,
207 "Obituary_WeaponDeath(): ^1Deathtype ^7(%d)^1 has no notification for weapon %s!\n",
218 if(deathtype == DEATH_FIRE.m_id)
221 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));
225 return MUTATOR_CALLHOOK(FragCenterMessage, attacker, targ, deathtype, kill_count_to_attacker, kill_count_to_target);
234 float notif_firstblood =
false;
235 float kill_count_to_attacker, kill_count_to_target;
236 bool notif_anonymous =
false;
237 string attacker_name = attacker.netname;
240 targ.death_origin = targ.origin;
244 if (
MUTATOR_CALLHOOK(ClientObituary, inflictor, attacker, targ, deathtype, attacker.(weaponentity))) {
CS(targ).killcount = 0;
return; }
245 notif_anonymous =
M_ARGV(5,
bool);
250 attacker_name =
"???";
252 #ifdef NOTIFICATIONS_DEBUG
255 "Obituary(%s, %s, %s, %s = %d);\n",
272 if(deathtype == DEATH_TEAMCHANGE.m_id || deathtype == DEATH_AUTOTEAMCHANGE.m_id)
274 Obituary_SpecialDeath(targ,
false, 0, deathtype, targ.netname, deathlocation,
"",
"", targ.team, 0, 0);
280 case DEATH_MIRRORDAMAGE:
282 Obituary_SpecialDeath(targ,
false, 0, deathtype, targ.netname, deathlocation,
"",
"",
CS(targ).
killcount, 0, 0);
285 case DEATH_HURTTRIGGER:
286 bool msg_from_ent = (inflictor && inflictor.message !=
"");
289 (msg_from_ent ? inflictor.message : deathlocation),
290 (msg_from_ent ? deathlocation :
""),
295 Obituary_SpecialDeath(targ,
false, 0, deathtype, targ.netname, deathlocation,
"",
"",
CS(targ).
killcount, 0, 0);
303 backtrace(
"SUICIDE: what the hell happened here?\n");
306 LogDeath(
"suicide", deathtype, targ, targ);
307 if(deathtype != DEATH_AUTOTEAMCHANGE.m_id)
308 GiveFrags(attacker, targ, -1, deathtype, weaponentity);
318 LogDeath(
"tk", deathtype, attacker, targ);
319 GiveFrags(attacker, targ, -1, deathtype, weaponentity);
321 CS(attacker).killcount = 0;
323 Send_Notification(NOTIF_ONE, attacker, MSG_CENTER, CENTER_DEATH_TEAMKILL_FRAG, targ.netname);
324 Send_Notification(NOTIF_ONE, targ, MSG_CENTER, CENTER_DEATH_TEAMKILL_FRAGGED, attacker_name);
332 LogDeath(
"frag", deathtype, attacker, targ);
333 GiveFrags(attacker, targ, 1, deathtype, weaponentity);
335 CS(attacker).taunt_soundtime =
time + 1;
336 CS(attacker).killcount =
CS(attacker).killcount + 1;
338 attacker.killsound += 1;
342 #define SPREE_ITEM(counta,countb,center,normal,gentle) \
344 Send_Notification(NOTIF_ONE, attacker, MSG_ANNCE, ANNCE_KILLSTREAK_##countb); \
346 PlayerStats_GameReport_Event_Player(attacker, PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_##counta, 1); \
359 notif_firstblood =
true;
364 kill_count_to_attacker = -1;
365 kill_count_to_target = -2;
369 kill_count_to_attacker =
CS(attacker).killcount;
370 kill_count_to_target = 0;
381 kill_count_to_attacker,
390 kill_count_to_target,
404 kill_count_to_attacker,
413 kill_count_to_target,
421 if(deathtype == DEATH_BUFF.m_id)
426 if (
DEATH_ENT(deathtype) == DEATH_HURTTRIGGER)
428 bool msg_from_ent = (inflictor && inflictor.message2 !=
"");
432 (msg_from_ent ? inflictor.message2 : deathlocation),
433 (msg_from_ent ? deathlocation :
""),
437 Obituary_SpecialDeath(targ,
true, 0, deathtype, targ.netname, attacker_name, deathlocation,
"",
CS(targ).
killcount, kill_count_to_attacker, f3);
452 case DEATH_HURTTRIGGER:
454 bool msg_from_ent = (inflictor && inflictor.message !=
"");
457 (msg_from_ent ? inflictor.message : deathlocation),
458 (msg_from_ent ? deathlocation :
""),
481 Obituary_SpecialDeath(targ,
false, 0, deathtype, targ.netname, deathlocation,
"",
"",
CS(targ).
killcount, 0, 0);
486 LogDeath(
"accident", deathtype, targ, targ);
487 GiveFrags(targ, targ, -1, deathtype, weaponentity);
500 CS(targ).killcount = 0;
505 float complainteamdamage = 0;
506 float mirrordamage = 0;
507 float mirrorforce = 0;
512 entity attacker_save = attacker;
523 if(deathtype == DEATH_KILL.m_id || deathtype == DEATH_TEAMCHANGE.m_id || deathtype == DEATH_AUTOTEAMCHANGE.m_id)
532 if(deathtype == DEATH_TEAMCHANGE.m_id || deathtype == DEATH_AUTOTEAMCHANGE.m_id)
541 else if(deathtype == DEATH_MIRRORDAMAGE.m_id || deathtype == DEATH_NOAMMO.m_id)
548 if(deathtype != DEATH_TELEFRAG.m_id)
563 else if(attacker != targ)
569 attacker.dmg_team = attacker.dmg_team + damage;
579 attacker.dmg_team = attacker.dmg_team + damage;
581 if(complainteamdamage > 0)
590 attacker.dmg_take += v.x;
591 attacker.dmg_save += v.y;
592 attacker.dmg_inflictor = inflictor;
600 targ.dmg_take += v.x;
601 targ.dmg_save += v.y;
602 targ.dmg_inflictor = inflictor;
608 else if(!targ.canteamdamage)
625 MUTATOR_CALLHOOK(Damage_Calculate, inflictor, attacker, targ, deathtype, damage, mirrordamage, force, attacker.(weaponentity));
626 damage =
M_ARGV(4,
float);
627 mirrordamage =
M_ARGV(5,
float);
630 if(
IS_PLAYER(targ) && damage > 0 && attacker)
635 if(targ.(went).hook && targ.(went).hook.aiment == attacker)
640 if (targ == attacker)
646 if(deathtype != DEATH_BUFF.m_id)
663 if(deathtype != DEATH_FIRE.m_id)
666 attacker.typehitsound += 1;
668 attacker.hitsound_damage_dealt += damage;
683 if (deathtype != DEATH_FIRE.m_id)
685 attacker.typehitsound += 1;
687 if(complainteamdamage > 0)
690 CS(attacker).teamkill_complain =
time + 5;
691 CS(attacker).teamkill_soundtime =
time + 0.4;
692 CS(attacker).teamkill_soundsource = targ;
700 if (targ.damageforcescale)
707 entity farcent =
new(farce);
708 farcent.enemy = targ;
709 farcent.movedir = farce * 10;
711 farcent.movedir = farcent.movedir * targ.mass;
712 farcent.origin = hitloc;
714 farcent.nextthink =
time + 0.1;
719 targ.velocity = targ.velocity + farce;
725 if (damage != 0 || (targ.damageforcescale && force))
726 if (targ.event_damage)
727 targ.event_damage (targ, inflictor, attacker, damage, deathtype, weaponentity, hitloc, force);
731 if(mirrordamage > 0 || mirrorforce > 0)
733 attacker = attacker_save;
735 force =
normalize(attacker.origin + attacker.view_ofs - hitloc) * mirrorforce;
736 Damage(attacker, inflictor, attacker, mirrordamage, DEATH_MIRRORDAMAGE.m_id, weaponentity, attacker.origin, force);
742 float inflictorselfdamage,
float forceintensity,
vector forcexyzscale,
int deathtype, .
entity weaponentity,
entity directhitentity)
746 float total_damage_to_creatures;
751 float stat_damagedone;
755 backtrace(
"RadiusDamage called recursively! Expect stuff to go HORRIBLY wrong.");
759 if (rad < 0) rad = 0;
766 total_damage_to_creatures = 0;
770 force = inflictorvelocity;
775 if(forceintensity >= 0)
776 Damage_DamageInfo(inflictororigin, coredamage, edgedamage, rad, forceintensity * force, deathtype, 0, attacker);
778 Damage_DamageInfo(inflictororigin, coredamage, edgedamage, -rad, (-forceintensity) * force, deathtype, 0, attacker);
787 if ((targ != inflictor) || inflictorselfdamage)
788 if (((cantbe != targ) && !mustbe) || (mustbe == targ))
794 vector nearest = targ.WarpZone_findradius_nearest;
799 vector inflictororigin_wz = targ.WarpZone_findradius_nearest + targ.WarpZone_findradius_dist;
801 inflictororigin_wz + inflictor.mins, inflictororigin_wz + inflictor.maxs, nearest);
802 vector diff = inflictornearest - nearest;
809 float f = (rad > 0) ? 1 - (dist / rad) : 1;
811 float finaldmg = coredamage * f + edgedamage * (1 - f);
823 if (targ != attacker)
826 center = targ.origin + ((targ.mins + targ.maxs) * 0.5);
834 vector mi =
'0 0 0', ma =
'0 0 0';
844 tracebox(center, mi, ma, center + dv,
MOVE_NORMAL, targ);
853 center.z = center.z + targ.(weaponentity).
movedir.z;
869 force =
normalize(center - inflictororigin_wz);
870 force = force * (finaldmg /
max(coredamage, edgedamage)) * forceintensity;
875 force.x *= forcexyzscale.x;
877 force.y *= forcexyzscale.y;
879 force.z *= forcexyzscale.z;
881 if(targ != directhitentity)
886 float mininv_f, mininv_d;
900 LOG_INFOF(
"THROUGHFLOOR: D=%f F=%f max(dD)=1/%f max(dF)=1/%f", finaldmg,
vlen(force), mininv_d, mininv_f);
903 total = 0.25 * (
max(mininv_f, mininv_d) ** 2);
915 LOG_INFOF(
" steps=%f dD=%f dF=%f", total, finaldmg * (1-tfloordmg) / (2 *
sqrt(total)),
vlen(force) * (1-tfloorforce) / (2 *
sqrt(total)));
917 for(c = 0; c < total; ++c)
925 hitloc = hitloc + nearest;
929 nearest.x = targ.origin.x + targ.mins.x +
random() * targ.size.x;
930 nearest.y = targ.origin.y + targ.mins.y +
random() * targ.size.y;
931 nearest.z = targ.origin.z + targ.mins.z +
random() * targ.size.z;
934 nearest = hitloc * (1 /
max(1, hits));
935 hitratio = (hits / total);
936 a =
bound(0, tfloordmg + (1-tfloordmg) * hitratio, 1);
937 finaldmg = finaldmg * a;
938 a =
bound(0, tfloorforce + (1-tfloorforce) * hitratio, 1);
952 if(finaldmg || force)
956 total_damage_to_creatures += finaldmg;
959 stat_damagedone += finaldmg;
963 Damage(targ, inflictor, attacker, finaldmg, deathtype, weaponentity, nearest, force);
965 Damage(targ, inflictor, attacker, finaldmg, deathtype |
HITTYPE_SPLASH, weaponentity, nearest, force);
978 return total_damage_to_creatures;
981float RadiusDamage(
entity inflictor,
entity attacker,
float coredamage,
float edgedamage,
float rad,
entity cantbe,
entity mustbe,
float forceintensity,
int deathtype, .
entity weaponentity,
entity directhitentity)
983 return RadiusDamageForSource(inflictor, (inflictor.origin + (inflictor.mins + inflictor.maxs) * 0.5), inflictor.velocity, attacker, coredamage, edgedamage, rad,
984 cantbe, mustbe,
false, forceintensity,
'1 1 1', deathtype, weaponentity, directhitentity);
995 healed = targ.event_heal(targ, inflictor, amount, limit);
1004 float maxtime, mintime, maxdamage, mindamage, maxdps, mindps, totaldamage, totaltime;
1021 mintime = fireendtime -
time;
1022 maxtime =
max(mintime, t);
1024 mindps = e.fire_damagepersec;
1025 maxdps =
max(mindps, dps);
1027 if(maxtime > mintime || maxdps > mindps)
1032 mindamage = mindps * mintime;
1035 maxdamage = mindamage + d;
1038 totaldamage =
min(maxdamage, maxtime * maxdps);
1061 totaltime =
min(maxtime, totaldamage / mindps);
1083 e.fire_damagepersec = totaldamage / totaltime;
1085 if(totaldamage > 1.2 * mindamage)
1087 e.fire_deathtype = dt;
1088 if(e.fire_owner != o)
1091 e.fire_hitsound =
false;
1096 return max(0, totaldamage - mindamage);
1103 e.fire_damagepersec = dps;
1105 e.fire_deathtype = dt;
1107 e.fire_hitsound =
false;
1119 for(t = 0, o = e.owner; o.owner && t < 16; o = o.owner, ++t);
1125 d = e.fire_damagepersec * t;
1127 hi = e.fire_owner.hitsound_damage_dealt;
1128 ty = e.fire_owner.typehitsound;
1129 Damage(e, e, e.fire_owner, d, e.fire_deathtype,
DMG_NOWEP, e.origin,
'0 0 0');
1130 if(e.fire_hitsound && e.fire_owner)
1132 e.fire_owner.hitsound_damage_dealt = hi;
1133 e.fire_owner.typehitsound = ty;
1135 e.fire_hitsound =
true;
1141 if(!IS_DEAD(it) && it.takedamage && !IS_INDEPENDENT_PLAYER(it))
1142 if(boxesoverlap(e.absmin, e.absmax, it.absmin, it.absmax))
1144 t = autocvar_g_balance_firetransfer_time * (fireendtime - time);
1145 d = autocvar_g_balance_firetransfer_damage * e.fire_damagepersec * t;
1146 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.
bool SetResourceExplicit(entity e, Resource res_type, float amount)
Sets the resource amount of an entity without calling any hooks.
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 Obituary_WeaponDeath(entity notif_target, float murder, int deathtype, string s1, string s2, string s3, float f1, float f2)
void Obituary_SpecialDeath(entity notif_target, float murder, bool msg_from_ent, int deathtype, string s1, string s2, string s3, string s4, float f1, float f2, float f3)
float Fire_AddDamage(entity e, entity o, float d, float t, float dt)
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, float inflictorselfdamage, float forceintensity, vector forcexyzscale, int deathtype,.entity weaponentity, entity directhitentity)
void Fire_ApplyDamage(entity e)
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 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 RadiusDamage_running
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)
#define DEATH_WEAPONOF(t)
void SUB_Remove(entity this)
Remove entity.
const float FORCETYPE_FORCEATPOS
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(NOTIF broadcast, entity client, MSG net_type, Notification net_name,...count)
void Send_Notification_WOCOVA(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)
entity Notification
always last
#define APP_TEAM_NUM(num, prefix)
float autocvar_notification_server_allows_location
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)
entity buff_FirstFromFlags(entity actor)
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
User pressed exit key 3 times fast (not implemented) or vehicle is dying.
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