Xonotic QuakeC
The free, fast arena FPS with crisp movement and a wide array of weapons
damage.qh File Reference
Include dependency graph for damage.qh:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define DMG_NOWEP   (weaponentities[0])

Functions

string AppendItemcodes (string s, entity player)
 bool (entity targ, entity inflictor, float amount, float limit) event_heal
void Damage (entity targ, entity inflictor, entity attacker, float damage, int deathtype,.entity weaponentity, vector hitloc, vector force)
void Damage_DamageInfo (vector org, float coredamage, float edgedamage, float rad, vector force, int deathtype, float bloodtype, entity dmgowner)
bool Damage_DamageInfo_SendEntity (entity this, entity to, int sf)
float Fire_AddDamage (entity e, entity o, float d, float t, float dt)
void Fire_ApplyDamage (entity e)
void GiveFrags (entity attacker, entity targ, float f, int deathtype,.entity weaponentity)
bool Heal (entity targ, entity inflictor, float amount, float limit)
float IsFlying (entity a)
void LogDeath (string mode, int deathtype, entity killer, entity killed)
void Obituary (entity attacker, entity inflictor, entity targ, int deathtype,.entity weaponentity)
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)
float Obituary_WeaponDeath (entity notif_target, float murder, int deathtype, string s1, string s2, string s3, float f1, float f2)
float RadiusDamage (entity inflictor, entity attacker, float coredamage, float edgedamage, float rad, entity cantbe, entity mustbe, float forceintensity, int deathtype,.entity weaponentity, entity directhitentity)
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)
 STATIC_INIT (g_damagedbycontents)
 void (entity this, entity inflictor, entity attacker, float damage, int deathtype,.entity weaponentity, vector hitloc, vector force) event_damage
void W_SwitchWeapon_Force (Player this, Weapon w,.entity weaponentity)

Variables

float autocvar_g_balance_armor_blockpercent
float autocvar_g_balance_damagepush_speedfactor
int autocvar_g_balance_firetransfer_damage
int autocvar_g_balance_firetransfer_time
float autocvar_g_balance_selfdamagepercent
float autocvar_g_friendlyfire
float autocvar_g_friendlyfire_virtual
float autocvar_g_friendlyfire_virtual_force
float autocvar_g_maxpushtime
float autocvar_g_mirrordamage
bool autocvar_g_mirrordamage_onlyweapons
bool autocvar_g_mirrordamage_virtual
int autocvar_g_player_damageplayercenter
float autocvar_g_teamdamage_resetspeed
float autocvar_g_teamdamage_threshold
bool autocvar_g_teamkill_punishing
float autocvar_g_throughfloor_damage
float autocvar_g_throughfloor_damage_max_stddev
bool autocvar_g_throughfloor_debug
float autocvar_g_throughfloor_force
float autocvar_g_throughfloor_force_max_stddev
float autocvar_g_throughfloor_max_steps_other
float autocvar_g_throughfloor_max_steps_player
float autocvar_g_throughfloor_min_steps_other
float autocvar_g_throughfloor_min_steps_player
bool canteamdamage
float checkrules_firstblood
float damagedbycontents
float damagedbytriggers
float damageextraradius
float damageforcescale
vector death_origin
string deathmessage
float dmg
float dmg_edge
float dmg_force
float dmg_radius
float dmg_team
float fire_damagepersec
float fire_deathtype
float fire_hitsound
entity fire_owner
IntrusiveList g_damagedbycontents
float hitsound_damage_dealt
int impressive_hits
bool istypefrag
int killsound
const float MAX_DAMAGEEXTRARADIUS = 16
const float MIN_DAMAGEEXTRARADIUS = 0.1
float pain_finished
entity pusher
bool RadiusDamage_running
float spawnshieldtime
float taunt_soundtime
float teamkill_complain
entity teamkill_soundsource
float teamkill_soundtime
int totalfrags
int typehitsound
float w_deathtype
float yoda

Macro Definition Documentation

◆ DMG_NOWEP

Function Documentation

◆ AppendItemcodes()

string AppendItemcodes ( string s,
entity player )

Definition at line 81 of file damage.qc.

82{
83 for (int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
84 {
85 .entity weaponentity = weaponentities[slot];
86 int w = player.(weaponentity).m_weapon.m_id;
87 if (w == 0)
88 w = player.(weaponentity).cnt; // previous weapon
89 if (w != 0 || slot == 0)
90 s = strcat(s, ftos(w));
91 }
92 if (PHYS_INPUT_BUTTON_CHAT(player))
93 s = strcat(s, "T");
94 // TODO: include these codes as a flag on the item itself
95 MUTATOR_CALLHOOK(LogDeath_AppendItemCodes, player, s);
96 s = M_ARGV(1, string);
97 return s;
98}
#define MUTATOR_CALLHOOK(id,...)
Definition base.qh:143
float cnt
Definition powerups.qc:24
#define M_ARGV(x, type)
Definition events.qh:17
#define PHYS_INPUT_BUTTON_CHAT(s)
Definition player.qh:161
string ftos(float f)
strcat(_("^F4Countdown stopped!"), "\n^BG", _("Teams are too unbalanced."))
const int MAX_WEAPONSLOTS
Definition weapon.qh:16
entity weaponentities[MAX_WEAPONSLOTS]
Definition weapon.qh:17
Weapon m_weapon
Definition wepent.qh:26

References cnt, entity(), ftos(), M_ARGV, m_weapon, MAX_WEAPONSLOTS, MUTATOR_CALLHOOK, PHYS_INPUT_BUTTON_CHAT, strcat(), and weaponentities.

Referenced by LogDeath().

◆ bool()

bool ( entity targ,
entity inflictor,
float amount,
float limit )

References entity().

◆ Damage()

void Damage ( entity targ,
entity inflictor,
entity attacker,
float damage,
int deathtype,
.entity weaponentity,
vector hitloc,
vector force )

Definition at line 493 of file damage.qc.

494{
495 if (game_stopped || (IS_CLIENT(targ) && CS(targ).killcount == FRAGS_SPECTATOR))
496 return;
497
498 // special rule: gravity bombs and sound-based attacks do not affect team mates (other than for disconnecting the hook)
499 if ((DEATH_ISWEAPON(deathtype, WEP_HOOK) || (deathtype & HITTYPE_SOUND))
500 && IS_PLAYER(targ) && SAME_TEAM(targ, attacker))
501 return;
502
503 entity attacker_save = attacker;
504
505 float complainteamdamage = 0;
506 float mirrordamage = 0;
507 float mirrorforce = 0;
508
509 if (deathtype == DEATH_KILL.m_id || deathtype == DEATH_TEAMCHANGE.m_id || deathtype == DEATH_AUTOTEAMCHANGE.m_id)
510 {
511 // exit the vehicle before killing (fixes a crash)
512 if (IS_PLAYER(targ) && targ.vehicle)
513 vehicles_exit(targ.vehicle, VHEF_RELEASE);
514
515 // These are ALWAYS lethal
516 // No damage modification here
517 // Instead, prepare the victim for their death...
518 if (deathtype == DEATH_TEAMCHANGE.m_id || deathtype == DEATH_AUTOTEAMCHANGE.m_id)
519 {
521 SetResourceExplicit(targ, RES_HEALTH, 0.9); // this is < 1
522 }
523 StatusEffects_remove(STATUSEFFECT_SpawnShield, targ, STATUSEFFECT_REMOVE_CLEAR);
524 targ.flags &= ~FL_GODMODE;
525 damage = 100000;
526 }
527 else if (deathtype == DEATH_MIRRORDAMAGE.m_id || deathtype == DEATH_NOAMMO.m_id)
528 {
529 // no processing
530 }
531 else
532 {
533 // nullify damage if teamplay is on
534 if (deathtype != DEATH_TELEFRAG.m_id
535 && IS_PLAYER(attacker))
536 {
537 // avoid dealing damage or force to other independent players
538 // and avoid dealing damage or force to things owned by other independent players
539 if ((IS_PLAYER(targ) && targ != attacker && (IS_INDEPENDENT_PLAYER(attacker) || IS_INDEPENDENT_PLAYER(targ)))
540 || (targ.realowner && IS_INDEPENDENT_PLAYER(targ.realowner) && attacker != targ.realowner))
541 {
542 damage = 0;
543 force = '0 0 0';
544 }
545 else if (!STAT(FROZEN, targ) && SAME_TEAM(attacker, targ))
546 {
547 if (autocvar_teamplay_mode == 1)
548 damage = 0;
549 else if (attacker != targ)
550 {
551 if (autocvar_teamplay_mode == 2)
552 {
553 if (IS_PLAYER(targ) && !IS_DEAD(targ))
554 {
555 attacker.dmg_team += damage;
556 complainteamdamage = attacker.dmg_team - autocvar_g_teamdamage_threshold;
557 }
558 }
559 else if (autocvar_teamplay_mode == 3)
560 damage = 0;
561 else if (autocvar_teamplay_mode == 4)
562 {
563 if (IS_PLAYER(targ) && !IS_DEAD(targ))
564 {
565 attacker.dmg_team += damage;
566 complainteamdamage = attacker.dmg_team - autocvar_g_teamdamage_threshold;
567 if (complainteamdamage > 0)
568 mirrordamage = autocvar_g_mirrordamage * complainteamdamage;
569 mirrorforce = autocvar_g_mirrordamage * vlen(force);
570 damage = autocvar_g_friendlyfire * damage;
571 // mirrordamage will be used LATER
572
574 {
576 attacker.dmg_take += v.x;
577 attacker.dmg_save += v.y;
578 attacker.dmg_inflictor = inflictor;
579 mirrordamage = v.z;
580 mirrorforce = 0;
581 }
582
584 {
586 targ.dmg_take += v.x;
587 targ.dmg_save += v.y;
588 targ.dmg_inflictor = inflictor;
589 damage = 0;
591 force = '0 0 0';
592 }
593 }
594 else if (!targ.canteamdamage)
595 damage = 0;
596 }
597 }
598 }
599 }
600
601 if (!DEATH_ISSPECIAL(deathtype))
602 {
604 mirrordamage *= autocvar_g_weapondamagefactor;
605 complainteamdamage *= autocvar_g_weapondamagefactor;
607 mirrorforce *= autocvar_g_weaponforcefactor;
608 }
609
610 // should this be changed at all? If so, in what way?
611 MUTATOR_CALLHOOK(Damage_Calculate, inflictor, attacker, targ, deathtype, damage, mirrordamage, force, attacker.(weaponentity));
612 damage = M_ARGV(4, float);
613 mirrordamage = M_ARGV(5, float);
614 force = M_ARGV(6, vector);
615
616 if (IS_PLAYER(targ) && damage > 0 && attacker)
617 for (int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
618 {
619 .entity went = weaponentities[slot];
620 if (targ.(went).hook && targ.(went).hook.aiment == attacker)
621 RemoveHook(targ.(went).hook);
622 }
623
624 if (targ == attacker)
625 damage *= autocvar_g_balance_selfdamagepercent; // Partial damage if the attacker hits himself
626
627 // count the damage
628 if (attacker && targ != attacker
629 && !IS_DEAD(targ)
630 && deathtype != DEATH_BUFF.m_id
631 && targ.takedamage == DAMAGE_AIM)
632 {
633 entity victim;
634 if (IS_VEHICLE(targ) && targ.owner)
635 victim = targ.owner;
636 else
637 victim = targ;
638
639 // TODO: allow the mutator hook to tell if the hit sound should be team or not
640 if (IS_PLAYER(victim) || (IS_TURRET(victim) && victim.active == ACTIVE_ACTIVE) || IS_MONSTER(victim)
641 || MUTATOR_CALLHOOK(PlayHitsound, victim, attacker))
642 {
643 if (DIFF_TEAM(victim, attacker))
644 {
645 if (damage > 0)
646 {
647 if (deathtype != DEATH_FIRE.m_id)
648 {
649 if (PHYS_INPUT_BUTTON_CHAT(victim))
650 ++attacker.typehitsound;
651 else
652 attacker.hitsound_damage_dealt += damage;
653 }
654
656
657 if (!DEATH_ISSPECIAL(deathtype)
658 && IS_PLAYER(targ) // don't do this for vehicles
659 && IsFlying(victim))
660 yoda = 1;
661 }
662 }
663 else if (IS_PLAYER(attacker) && !STAT(FROZEN, victim) && !(deathtype & HITTYPE_SPAM)) // same team
664 {
665 if (deathtype != DEATH_FIRE.m_id)
666 ++attacker.typehitsound;
667 if (complainteamdamage > 0
668 && time > CS(attacker).teamkill_complain)
669 {
670 CS(attacker).teamkill_complain = time + 5;
671 CS(attacker).teamkill_soundtime = time + 0.4;
672 CS(attacker).teamkill_soundsource = targ;
673 }
674 }
675 }
676 }
677 }
678
679 // apply push
680 if (targ.damageforcescale && force
681 && (!IS_PLAYER(targ) || !StatusEffects_active(STATUSEFFECT_SpawnShield, targ) || targ == attacker))
682 {
683 vector farce = damage_explosion_calcpush(targ.damageforcescale * force, targ.velocity, autocvar_g_balance_damagepush_speedfactor);
684 if (targ.move_movetype == MOVETYPE_PHYSICS)
685 {
686 entity farcent = new(farce);
687 farcent.enemy = targ;
688 farcent.movedir = farce * 10;
689 if (targ.mass)
690 farcent.movedir *= targ.mass;
691 farcent.origin = hitloc;
692 farcent.forcetype = FORCETYPE_FORCEATPOS;
693 farcent.nextthink = time + 0.1;
694 setthink(farcent, SUB_Remove);
695 }
696 else if (targ.move_movetype != MOVETYPE_NOCLIP)
697 targ.velocity += farce;
698 UNSET_ONGROUND(targ);
700 }
701 // apply damage
702 if ((damage != 0 || (targ.damageforcescale && force))
703 && targ.event_damage)
704 targ.event_damage(targ, inflictor, attacker, damage, deathtype, weaponentity, hitloc, force);
705
706 // apply mirror damage if any
707 if ((!autocvar_g_mirrordamage_onlyweapons || DEATH_WEAPONOF(deathtype) != WEP_Null)
708 && (mirrordamage > 0 || mirrorforce > 0))
709 {
710 attacker = attacker_save;
711
712 force = normalize(attacker.origin + attacker.view_ofs - hitloc) * mirrorforce;
713 Damage(attacker, inflictor, attacker, mirrordamage, DEATH_MIRRORDAMAGE.m_id, weaponentity, attacker.origin, force);
714 }
715}
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.
bool IsFlying(entity this)
Definition player.qc:843
#define IS_CLIENT(s)
Definition player.qh:241
#define IS_DEAD(s)
Definition player.qh:244
#define IS_PLAYER(s)
Definition player.qh:242
float game_stopped
Definition stats.qh:81
vector healtharmor_applydamage(float a, float armorblock, int deathtype, float damage)
Definition util.qc:1413
const int FL_GODMODE
Definition constants.qh:75
const int FRAGS_SPECTATOR
Definition constants.qh:4
float time
void UpdateCSQCProjectile(entity e)
void Damage(entity targ, entity inflictor, entity attacker, float damage, int deathtype,.entity weaponentity, vector hitloc, vector force)
Definition damage.qc:493
bool autocvar_g_mirrordamage_virtual
Definition damage.qh:15
bool autocvar_g_mirrordamage_onlyweapons
Definition damage.qh:16
float yoda
Definition damage.qh:48
float autocvar_g_friendlyfire_virtual_force
Definition damage.qh:28
float autocvar_g_balance_armor_blockpercent
Definition damage.qh:21
int impressive_hits
Definition damage.qh:49
float autocvar_g_balance_selfdamagepercent
Definition damage.qh:25
float autocvar_g_friendlyfire_virtual
Definition damage.qh:27
float autocvar_g_teamdamage_threshold
Definition damage.qh:23
float teamkill_complain
Definition damage.qh:54
float autocvar_g_friendlyfire
Definition damage.qh:26
float autocvar_g_balance_damagepush_speedfactor
Definition damage.qh:18
float autocvar_g_mirrordamage
Definition damage.qh:14
#define DEATH_ISWEAPON(t, w)
Definition all.qh:46
#define DEATH_ISSPECIAL(t)
Definition all.qh:39
const int HITTYPE_SPAM
Definition all.qh:34
#define DEATH_WEAPONOF(t)
Definition all.qh:45
const int HITTYPE_SOUND
Definition all.qh:33
void SUB_Remove(entity this)
Remove entity.
Definition defer.qh:13
const int ACTIVE_ACTIVE
Definition defs.qh:37
const float FORCETYPE_FORCEATPOS
RES_ARMOR
Definition ent_cs.qc:130
#define STAT(...)
Definition stats.qh:82
float vlen(vector v)
vector normalize(vector v)
#define UNSET_ONGROUND(s)
Definition movetypes.qh:18
const int MOVETYPE_PHYSICS
Definition movetypes.qh:142
const int MOVETYPE_NOCLIP
Definition movetypes.qh:137
@ STATUSEFFECT_REMOVE_CLEAR
Effect is being forcibly removed without calling any additional mechanics.
Definition all.qh:30
#define setthink(e, f)
vector
Definition self.qh:92
int killcount
Definition client.qh:315
#define IS_INDEPENDENT_PLAYER(e)
Definition client.qh:312
void RemoveHook(entity this)
Definition hook.qc:48
ClientState CS(Client this)
Definition state.qh:47
void StatusEffects_remove(StatusEffect this, entity actor, int removal_type)
bool StatusEffects_active(StatusEffect this, entity actor)
const int DAMAGE_AIM
Definition subs.qh:81
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
Definition teamplay.qh:3
#define SAME_TEAM(a, b)
Definition teams.qh:241
#define DIFF_TEAM(a, b)
Definition teams.qh:242
#define IS_TURRET(v)
Definition utils.qh:25
#define IS_MONSTER(v)
Definition utils.qh:23
#define IS_VEHICLE(v)
Definition utils.qh:24
float autocvar_g_weaponforcefactor
float autocvar_g_weapondamagefactor

References ACTIVE_ACTIVE, autocvar_g_balance_armor_blockpercent, autocvar_g_balance_damagepush_speedfactor, autocvar_g_balance_selfdamagepercent, autocvar_g_friendlyfire, autocvar_g_friendlyfire_virtual, autocvar_g_friendlyfire_virtual_force, autocvar_g_mirrordamage, autocvar_g_mirrordamage_onlyweapons, autocvar_g_mirrordamage_virtual, autocvar_g_teamdamage_threshold, autocvar_g_weapondamagefactor, autocvar_g_weaponforcefactor, autocvar_teamplay_mode, CS(), Damage(), DAMAGE_AIM, damage_explosion_calcpush(), DEATH_ISSPECIAL, DEATH_ISWEAPON, DEATH_WEAPONOF, DIFF_TEAM, entity(), FL_GODMODE, FORCETYPE_FORCEATPOS, FRAGS_SPECTATOR, game_stopped, GetResource(), healtharmor_applydamage(), HITTYPE_SOUND, HITTYPE_SPAM, impressive_hits, IS_CLIENT, IS_DEAD, IS_INDEPENDENT_PLAYER, IS_MONSTER, IS_PLAYER, IS_TURRET, IS_VEHICLE, IsFlying(), killcount, M_ARGV, MAX_WEAPONSLOTS, MOVETYPE_NOCLIP, MOVETYPE_PHYSICS, MUTATOR_CALLHOOK, normalize(), PHYS_INPUT_BUTTON_CHAT, RemoveHook(), RES_ARMOR, SAME_TEAM, SetResourceExplicit(), setthink, STAT, STATUSEFFECT_REMOVE_CLEAR, StatusEffects_active(), StatusEffects_remove(), SUB_Remove(), teamkill_complain, time, UNSET_ONGROUND, UpdateCSQCProjectile(), vector, vehicles_exit(), VHEF_RELEASE, vlen(), weaponentities, and yoda.

Referenced by buff_Vengeance_DelayedDamage(), bumblebee_pilot_frame(), ClientKill_Now(), CommonCommand_editmob(), CreatureFrame_FallDamage(), CreatureFrame_hotliquids(), ctf_CaptureShield_Touch(), Damage(), door_blocked(), door_generic_plat_blocked(), DrownPlayer(), Fire_ApplyDamage(), fireBullet_falloff(), generic_plat_blocked(), havocbot_role_ctf_carrier(), instagib_countdown(), KillPlayerForTeamChange(), M_Zombie_Attack_Leap_Touch(), misc_laser_think(), Monster_Attack_Melee(), Monster_Move(), Monster_Think(), MUTATOR_HOOKFUNCTION(), MUTATOR_HOOKFUNCTION(), MUTATOR_HOOKFUNCTION(), MUTATOR_HOOKFUNCTION(), nade_heal_touch(), nade_spawn_DestroyDamage(), nade_translocate_DestroyDamage(), ons_CaptureShield_Touch(), Onslaught_CheckWinner(), plat_crush(), RadiusDamageForSource(), target_kill_use(), tdeath(), trigger_hurt_touch(), vehicles_impact(), vehicles_touch(), W_Arc_Beam_Think(), W_Fireball_Explode(), W_OverkillRocketPropelledChainsaw_Think(), W_Shotgun_Melee_Think(), and walker_melee_do_dmg().

◆ Damage_DamageInfo()

void Damage_DamageInfo ( vector org,
float coredamage,
float edgedamage,
float rad,
vector force,
int deathtype,
float bloodtype,
entity dmgowner )

Definition at line 27 of file damageeffects.qc.

28{
29 // TODO maybe call this from non-edgedamage too?
30 // TODO maybe make the client do the particle effects for the weapons and the impact sounds using this info?
31
32 if(!sound_allowed(MSG_BROADCAST, dmgowner))
33 deathtype |= 0x8000;
34
35 entity e = new_pure(damageinfo);
36 // origin is just data to be sent
37 //setorigin(e, org);
38 e.origin = org;
39 e.projectiledeathtype = deathtype;
40 e.dmg = coredamage;
41 e.dmg_edge = edgedamage;
42 bool rad_negative = false;
43 if(rad < 0)
44 {
45 // make it positive (unsigned) so it can be sent as byte
46 rad_negative = true;
47 rad = -rad;
48 }
49 e.dmg_radius = rad;
50 e.dmg_force = vlen(force);
51 e.velocity = force;
52
53 e.species = bloodtype & BITS(4); // it only uses bits from 0 to 3, see SPECIES_* constants
54 if(rad_negative)
55 e.species |= BIT(7);
56
57 e.colormap = (teamplay) ? dmgowner.team : dmgowner.clientcolors; // NOTE: doesn't work on non-clients
58
60}
#define BIT(n)
Only ever assign into the first 24 bits in QC (so max is BIT(23)).
Definition bits.qh:8
#define BITS(n)
Definition bits.qh:9
bool Damage_DamageInfo_SendEntity(entity this, entity to, int sf)
clientcolors
Definition ent_cs.qc:147
void Net_LinkEntity(entity e, bool docull, float dt, bool(entity this, entity to, int sendflags) sendfunc)
Definition net.qh:167
float MSG_BROADCAST
Definition menudefs.qc:55
#define new_pure(class)
purely logical entities (not linked to the area grid)
Definition oo.qh:67
vector org
Definition self.qh:92
bool sound_allowed(int to, entity e)
Definition all.qc:9
bool teamplay
Definition teams.qh:59

References BIT, BITS, Damage_DamageInfo_SendEntity(), entity(), MSG_BROADCAST, Net_LinkEntity(), new_pure, org, sound_allowed(), teamplay, vector, and vlen().

Referenced by fireBullet_falloff(), FireRailgunBullet(), nade_normal_boom(), RadiusDamageForSource(), raptor_bomb_burst(), W_Seeker_Tag_Explode(), and W_Seeker_Tag_Touch().

◆ Damage_DamageInfo_SendEntity()

bool Damage_DamageInfo_SendEntity ( entity this,
entity to,
int sf )

Definition at line 7 of file damageeffects.qc.

8{
9 vector org = vec3(floor(this.origin.x), floor(this.origin.y), floor(this.origin.z));
10 WriteHeader(MSG_ENTITY, ENT_CLIENT_DAMAGEINFO);
12 WriteVector(MSG_ENTITY, org);
13 WriteByte(MSG_ENTITY, bound(1, this.dmg, 255));
14 WriteByte(MSG_ENTITY, bound(0, this.dmg_radius, 255));
15 WriteByte(MSG_ENTITY, bound(1, this.dmg_edge, 255));
16 // we can't send the force vector compressed with compressShortVector as it's too inaccurate
17 // it would break decals when hit angle on a surface is small
18 // (the traceline performed by the client to spawn a decal wouldn't hit the surface at all)
19 WriteShort(MSG_ENTITY, floor(this.velocity.x / 4));
20 WriteShort(MSG_ENTITY, floor(this.velocity.y / 4));
21 WriteShort(MSG_ENTITY, floor(this.velocity.z / 4));
24 return true;
25}
float dmg
Definition breakable.qc:12
float dmg_edge
Definition breakable.qc:13
float dmg_radius
Definition breakable.qc:14
vector velocity
float colormap
vector origin
const int MSG_ENTITY
Definition net.qh:156
#define WriteHeader(to, id)
Definition net.qh:265
float bound(float min, float value, float max)
void WriteShort(float data, float dest, float desto)
void WriteByte(float data, float dest, float desto)
float floor(float f)
float species
Definition main.qh:47
int projectiledeathtype
Definition common.qh:21
#define vec3(_x, _y, _z)
Definition vector.qh:95

References bound(), colormap, dmg, dmg_edge, dmg_radius, entity(), floor(), MSG_ENTITY, org, origin, projectiledeathtype, species, vec3, vector, velocity, WriteByte(), WriteHeader, and WriteShort().

Referenced by Damage_DamageInfo().

◆ Fire_AddDamage()

float Fire_AddDamage ( entity e,
entity o,
float d,
float t,
float dt )

Definition at line 974 of file damage.qc.

975{
976 if (d <= 0)
977 return -1;
978 if (IS_PLAYER(e) && IS_DEAD(e))
979 return -1;
980
981 t = max(t, 0.1);
982 float dps = d / t;
983
984 if (StatusEffects_active(STATUSEFFECT_Burning, e))
985 {
986 float fireendtime = StatusEffects_gettime(STATUSEFFECT_Burning, e);
987
988 float mintime = fireendtime - time;
989 float maxtime = max(mintime, t);
990
991 float mindps = e.fire_damagepersec;
992 float maxdps = max(mindps, dps);
993
994 if (maxtime > mintime || maxdps > mindps)
995 {
996 // Constraints:
997
998 // damage we have right now
999 float mindamage = mindps * mintime;
1000
1001 // damage we want to get
1002 float maxdamage = mindamage + d;
1003
1004 // but we can't exceed maxtime * maxdps!
1005 float totaldamage = min(maxdamage, maxtime * maxdps);
1006
1007 // LEMMA:
1008 // Look at:
1009 // totaldamage = min(mindamage + d, maxtime * maxdps)
1010 // We see:
1011 // totaldamage <= maxtime * maxdps
1012 // ==> totaldamage / maxdps <= maxtime.
1013 // We also see:
1014 // totaldamage / mindps = min(mindamage / mindps + d, maxtime * maxdps / mindps)
1015 // >= min(mintime, maxtime)
1016 // ==> totaldamage / maxdps >= mintime.
1017
1018 /*
1019 // how long do we damage then?
1020 // at least as long as before
1021 // but, never exceed maxdps
1022 totaltime = max(mintime, totaldamage / maxdps); // always <= maxtime due to lemma
1023 */
1024
1025 // alternate:
1026 // at most as long as maximum allowed
1027 // but, never below mindps
1028 float totaltime = min(maxtime, totaldamage / mindps); // always >= mintime due to lemma
1029
1030 // assuming t > mintime, dps > mindps:
1031 // we get d = t * dps = maxtime * maxdps
1032 // totaldamage = min(maxdamage, maxtime * maxdps) = min(... + d, maxtime * maxdps) = maxtime * maxdps
1033 // totaldamage / maxdps = maxtime
1034 // totaldamage / mindps > totaldamage / maxdps = maxtime
1035 // FROM THIS:
1036 // a) totaltime = max(mintime, maxtime) = maxtime
1037 // b) totaltime = min(maxtime, totaldamage / maxdps) = maxtime
1038
1039 // assuming t <= mintime:
1040 // we get maxtime = mintime
1041 // a) totaltime = max(mintime, ...) >= mintime, also totaltime <= maxtime by the lemma, therefore totaltime = mintime = maxtime
1042 // b) totaltime = min(maxtime, ...) <= maxtime, also totaltime >= mintime by the lemma, therefore totaltime = mintime = maxtime
1043
1044 // assuming dps <= mindps:
1045 // we get mindps = maxdps.
1046 // With this, the lemma says that mintime <= totaldamage / mindps = totaldamage / maxdps <= maxtime.
1047 // a) totaltime = max(mintime, totaldamage / maxdps) = totaldamage / maxdps
1048 // b) totaltime = min(maxtime, totaldamage / mindps) = totaldamage / maxdps
1049
1050 e.fire_damagepersec = totaldamage / totaltime;
1051 StatusEffects_apply(STATUSEFFECT_Burning, e, time + totaltime, 0);
1052 if (totaldamage > 1.2 * mindamage)
1053 {
1054 e.fire_deathtype = dt;
1055 if (e.fire_owner != o)
1056 {
1057 e.fire_owner = o;
1058 e.fire_hitsound = false;
1059 }
1060 }
1061 if (accuracy_isgooddamage(o, e))
1062 accuracy_add(o, DEATH_WEAPONOF(dt), 0, max(0, totaldamage - mindamage), 0); // add to hit
1063 return max(0, totaldamage - mindamage); // can never be negative, but to make sure
1064 }
1065 else
1066 return 0;
1067 }
1068 else
1069 {
1070 e.fire_damagepersec = dps;
1071 StatusEffects_apply(STATUSEFFECT_Burning, e, time + t, 0);
1072 e.fire_deathtype = dt;
1073 e.fire_owner = o;
1074 e.fire_hitsound = false;
1075 if (accuracy_isgooddamage(o, e))
1076 accuracy_add(o, DEATH_WEAPONOF(dt), 0, d, 0); // add to hit
1077 return d;
1078 }
1079}
void accuracy_add(entity this, Weapon w, float fired, float hit, float real)
update accuracy stats
Definition accuracy.qc:102
bool accuracy_isgooddamage(entity attacker, entity targ)
does this damage count towards accuracy stats?
Definition accuracy.qc:133
float min(float f,...)
float max(float f,...)
float StatusEffects_gettime(StatusEffect this, entity actor)
void StatusEffects_apply(StatusEffect this, entity actor, float eff_time, int eff_flags)

References accuracy_add(), accuracy_isgooddamage(), DEATH_WEAPONOF, entity(), IS_DEAD, IS_PLAYER, max(), min(), StatusEffects_active(), StatusEffects_apply(), StatusEffects_gettime(), and time.

Referenced by CreatureFrame_hotliquids(), M_Wyvern_Attack_Fireball_Explode(), MUTATOR_HOOKFUNCTION(), napalm_damage(), W_Fireball_Firemine_Touch(), and W_Fireball_LaserPlay().

◆ Fire_ApplyDamage()

void Fire_ApplyDamage ( entity e)

Definition at line 1081 of file damage.qc.

1082{
1083 entity o;
1084 float t;
1085 for (t = 0, o = e.owner; o.owner && t < 16; o = o.owner, ++t);
1086 if (IS_NOT_A_CLIENT(o))
1087 o = e.fire_owner;
1088
1089 float fireendtime = StatusEffects_gettime(STATUSEFFECT_Burning, e);
1090 t = min(frametime, fireendtime - time);
1091 float d = e.fire_damagepersec * t;
1092
1093 float hi = e.fire_owner.hitsound_damage_dealt;
1094 float ty = e.fire_owner.typehitsound;
1095 Damage(e, e, e.fire_owner, d, e.fire_deathtype, DMG_NOWEP, e.origin, '0 0 0');
1096 if (e.fire_hitsound && e.fire_owner)
1097 {
1098 e.fire_owner.hitsound_damage_dealt = hi;
1099 e.fire_owner.typehitsound = ty;
1100 }
1101 e.fire_hitsound = true;
1102
1103 if (!IS_INDEPENDENT_PLAYER(e) && !STAT(FROZEN, e) && !StatusEffects_active(STATUSEFFECT_Frozen, e))
1104 IL_EACH(g_damagedbycontents, it.damagedbycontents && it != e,
1105 {
1106 if (!IS_DEAD(it) && it.takedamage && !IS_INDEPENDENT_PLAYER(it)
1107 && boxesoverlap(e.absmin, e.absmax, it.absmin, it.absmax))
1108 {
1109 t = autocvar_g_balance_firetransfer_time * (fireendtime - time);
1110 d = autocvar_g_balance_firetransfer_damage * e.fire_damagepersec * t;
1111 Fire_AddDamage(it, o, d, t, DEATH_FIRE.m_id);
1112 }
1113 });
1114}
#define IS_NOT_A_CLIENT(s)
Definition player.qh:243
float frametime
IntrusiveList g_damagedbycontents
Definition damage.qh:143
#define DMG_NOWEP
Definition damage.qh:104
#define IL_EACH(this, cond, body)

◆ GiveFrags()

void GiveFrags ( entity attacker,
entity targ,
float f,
int deathtype,
.entity weaponentity )

Definition at line 43 of file damage.qc.

44{
45 // TODO route through PlayerScores instead
46 if (game_stopped)
47 return;
48
49 if (f < 0)
50 {
51 if (targ == attacker) // suicide
52 GameRules_scoring_add(attacker, SUICIDES, 1);
53 else
54 {
55 // teamkill
56 int teamkills = GameRules_scoring_add(attacker, TEAMKILLS, 1);
58 f -= (teamkills * (teamkills - 1)) * 0.5; // negative 1, 2, 4, 7, 11, 16, 22, etc.
59 }
60 }
61 else
62 {
63 // regular frag
64 GameRules_scoring_add(attacker, KILLS, 1);
65 if (!warmup_stage && targ.playerid)
66 PlayerStats_GameReport_Event_Player(attacker, sprintf("kills-%d", targ.playerid), 1);
67 }
68
69 GameRules_scoring_add(targ, DEATHS, 1);
70
71 // FIXME fix the mess this is (we have REAL points now!)
72 if (MUTATOR_CALLHOOK(GiveFragsForKill, attacker, targ, f, deathtype, attacker.(weaponentity)))
73 f = M_ARGV(2, float);
74
75 attacker.totalfrags += f;
76
77 if (f)
78 GameRules_scoring_add_team(attacker, SCORE, f);
79}
bool warmup_stage
Definition main.qh:120
bool autocvar_g_teamkill_punishing
Definition damage.qh:24
#define PlayerStats_GameReport_Event_Player(ent, eventid, val)
#define GameRules_scoring_add(client, fld, value)
Definition sv_rules.qh:85
#define GameRules_scoring_add_team(client, fld, value)
Definition sv_rules.qh:89

References autocvar_g_teamkill_punishing, entity(), game_stopped, GameRules_scoring_add, GameRules_scoring_add_team, M_ARGV, MUTATOR_CALLHOOK, PlayerStats_GameReport_Event_Player, and warmup_stage.

Referenced by MUTATOR_HOOKFUNCTION(), and Obituary().

◆ Heal()

bool Heal ( entity targ,
entity inflictor,
float amount,
float limit )

Definition at line 957 of file damage.qc.

958{
959 // TODO: mutator hook to control healing
960 if (game_stopped
961 || (IS_CLIENT(targ) && CS(targ).killcount == FRAGS_SPECTATOR)
962 || STAT(FROZEN, targ) || IS_DEAD(targ))
963 return false;
964
965 bool healed = (targ.event_heal)
966 ? targ.event_heal(targ, inflictor, amount, limit)
967 : false;
968 // TODO: additional handling? what if the healing kills them? should this abort if healing would do so etc
969 // TODO: healing fx!
970 // TODO: armor healing?
971 return healed;
972}

References CS(), entity(), FRAGS_SPECTATOR, game_stopped, IS_CLIENT, IS_DEAD, killcount, and STAT.

Referenced by bumblebee_pilot_frame(), M_Mage_Defend_Heal(), MUTATOR_HOOKFUNCTION(), trigger_heal_touch(), and W_Arc_Beam_Think().

◆ IsFlying()

float IsFlying ( entity a)

Definition at line 843 of file player.qc.

844{
845 if(IS_ONGROUND(this))
846 return false;
848 return false;
849 tracebox(this.origin, this.mins, this.maxs, this.origin - '0 0 24', MOVE_NORMAL, this);
850 //traceline(this.origin, this.origin - '0 0 48', MOVE_NORMAL, this);
851 if(trace_fraction < 1)
852 return false;
853 return true;
854}
float waterlevel
Definition player.qh:225
const float MOVE_NORMAL
vector mins
vector maxs
float trace_fraction
const int WATERLEVEL_SWIMMING
Definition movetypes.qh:13
#define IS_ONGROUND(s)
Definition movetypes.qh:16

References entity(), IS_ONGROUND, maxs, mins, MOVE_NORMAL, origin, trace_fraction, waterlevel, and WATERLEVEL_SWIMMING.

Referenced by Damage(), MUTATOR_HOOKABLE(), sys_phys_update(), W_Devastator_Explode(), W_Electro_Explode(), W_MineLayer_Explode(), W_Mortar_Grenade_Explode(), W_Mortar_Grenade_Explode2(), W_OverkillNex_Attack(), W_RocketMinsta_Laser_Explode(), W_Vaporizer_Attack(), and W_Vortex_Attack().

◆ LogDeath()

void LogDeath ( string mode,
int deathtype,
entity killer,
entity killed )

Definition at line 100 of file damage.qc.

101{
103 return;
104 string s = strcat(":kill:", mode,
105 ":", ftos(killer.playerid),
106 ":", ftos(killed.playerid));
107 s = strcat(s, ":type=", Deathtype_Name(deathtype), ":items=");
108 s = AppendItemcodes(s, killer);
109 if (killed != killer)
110 {
111 s = strcat(s, ":victimitems=");
112 s = AppendItemcodes(s, killed);
113 }
114 GameLogEcho(s);
115}
string AppendItemcodes(string s, entity player)
Definition damage.qc:81
string Deathtype_Name(int deathtype)
Definition all.qc:3
void GameLogEcho(string s)
Definition gamelog.qc:15
bool autocvar_sv_eventlog
Definition gamelog.qh:3

References AppendItemcodes(), autocvar_sv_eventlog, Deathtype_Name(), entity(), ftos(), GameLogEcho(), and strcat().

Referenced by Obituary().

◆ Obituary()

void Obituary ( entity attacker,
entity inflictor,
entity targ,
int deathtype,
.entity weaponentity )

Definition at line 222 of file damage.qc.

223{
224 // Sanity check
225 if (!IS_PLAYER(targ))
226 {
227 backtrace("Obituary called on non-player?!\n");
228 return;
229 }
230
231 // Declarations
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;
236
237 // Set final information for the death
238 targ.death_origin = targ.origin;
239 string deathlocation = (autocvar_notification_server_allows_location ? NearestLocation(targ.death_origin) : "");
240
241 // Abort now if a mutator requests it
242 if (MUTATOR_CALLHOOK(ClientObituary, inflictor, attacker, targ, deathtype, attacker.(weaponentity)))
243 {
244 CS(targ).killcount = 0;
245 return;
246 }
247 notif_anonymous = M_ARGV(5, bool);
248
249 // TODO: Replace "???" with a translatable "Anonymous player" string
250 // https://gitlab.com/xonotic/xonotic-data.pk3dir/-/issues/2839
251 if (notif_anonymous)
252 attacker_name = "???";
253
254 #ifdef NOTIFICATIONS_DEBUG
255 Debug_Notification(sprintf(
256 "Obituary(%s, %s, %s, %s = %d);\n",
257 attacker_name,
258 inflictor.netname,
259 targ.netname,
260 Deathtype_Name(deathtype),
261 deathtype
262 ));
263 #endif
264
265 // =======
266 // SUICIDE
267 // =======
268 if (targ == attacker)
269 {
270 if (DEATH_ISSPECIAL(deathtype))
271 {
272 if (deathtype == DEATH_TEAMCHANGE.m_id || deathtype == DEATH_AUTOTEAMCHANGE.m_id)
273 Obituary_SpecialDeath(targ, false, 0, deathtype, targ.netname, deathlocation, "", "", targ.team, 0, 0);
274 else
275 {
276 switch (DEATH_ENT(deathtype))
277 {
278 case DEATH_MIRRORDAMAGE:
279 Obituary_SpecialDeath(targ, false, 0, deathtype, targ.netname, deathlocation, "", "", CS(targ).killcount, 0, 0);
280 break;
281 case DEATH_HURTTRIGGER:
282 {
283 bool msg_from_ent = (inflictor && inflictor.message != "");
284 Obituary_SpecialDeath(targ, false, msg_from_ent, deathtype,
285 targ.netname,
286 (msg_from_ent ? inflictor.message : deathlocation),
287 (msg_from_ent ? deathlocation : ""),
288 "", CS(targ).killcount, 0, 0
289 );
290 break;
291 }
292 default:
293 Obituary_SpecialDeath(targ, false, 0, deathtype, targ.netname, deathlocation, "", "", CS(targ).killcount, 0, 0);
294 break;
295 }
296 }
297 }
298 else if (!Obituary_WeaponDeath(targ, false, deathtype, targ.netname, deathlocation, "", CS(targ).killcount, 0))
299 {
300 backtrace("SUICIDE: what the hell happened here?\n");
301 return;
302 }
303 LogDeath("suicide", deathtype, targ, targ);
304 if (deathtype != DEATH_AUTOTEAMCHANGE.m_id) // special case: don't negate frags if auto switched
305 GiveFrags(attacker, targ, -1, deathtype, weaponentity);
306 }
307
308 // ======
309 // MURDER
310 // ======
311 else if (IS_PLAYER(attacker))
312 {
313 if (SAME_TEAM(attacker, targ))
314 {
315 LogDeath("tk", deathtype, attacker, targ);
316 GiveFrags(attacker, targ, -1, deathtype, weaponentity);
317
318 CS(attacker).killcount = 0;
319
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);
322 Send_Notification(NOTIF_ALL, NULL, MSG_INFO, APP_TEAM_NUM(targ.team, INFO_DEATH_TEAMKILL), targ.netname, attacker_name, deathlocation, CS(targ).killcount);
323
324 // In this case, the death message will ALWAYS be "foo was betrayed by bar"
325 // No need for specific death/weapon messages...
326 }
327 else
328 {
329 LogDeath("frag", deathtype, attacker, targ);
330 GiveFrags(attacker, targ, 1, deathtype, weaponentity);
331
332 CS(attacker).taunt_soundtime = time + 1;
333 ++CS(attacker).killcount;
334
335 ++attacker.killsound;
336
337 // TODO: improve SPREE_ITEM and KILL_SPREE_LIST
338 // these 2 macros are spread over multiple files
339 #define SPREE_ITEM(counta,countb,center,normal,gentle) \
340 case counta: \
341 Send_Notification(NOTIF_ONE, attacker, MSG_ANNCE, ANNCE_KILLSTREAK_##countb); \
342 if (!warmup_stage) \
343 PlayerStats_GameReport_Event_Player(attacker, PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_##counta, 1); \
344 break;
345
346 switch (CS(attacker).killcount)
347 {
349 default:
350 break;
351 }
352 #undef SPREE_ITEM
353
355 {
357 notif_firstblood = true; // modify the current messages so that they too show firstblood information
360
361 // tell spree_inf and spree_cen that this is a first-blood and first-victim event
362 kill_count_to_attacker = -1;
363 kill_count_to_target = -2;
364 }
365 else
366 {
367 kill_count_to_attacker = CS(attacker).killcount;
368 kill_count_to_target = 0;
369 }
370
371 if (targ.istypefrag)
372 {
374 NOTIF_ONE,
375 attacker,
376 MSG_CHOICE,
377 CHOICE_TYPEFRAG,
378 targ.netname,
379 kill_count_to_attacker,
380 (IS_BOT_CLIENT(targ) ? -1 : CS(targ).ping)
381 );
383 NOTIF_ONE,
384 targ,
385 MSG_CHOICE,
386 CHOICE_TYPEFRAGGED,
387 attacker_name,
388 kill_count_to_target,
389 GetResource(attacker, RES_HEALTH),
390 GetResource(attacker, RES_ARMOR),
391 (IS_BOT_CLIENT(attacker) ? -1 : CS(attacker).ping)
392 );
393 }
394 else if (!frag_centermessage_override(attacker, targ, deathtype, kill_count_to_attacker, kill_count_to_target, attacker_name))
395 {
397 NOTIF_ONE,
398 attacker,
399 MSG_CHOICE,
400 CHOICE_FRAG,
401 targ.netname,
402 kill_count_to_attacker,
403 (IS_BOT_CLIENT(targ) ? -1 : CS(targ).ping)
404 );
406 NOTIF_ONE,
407 targ,
408 MSG_CHOICE,
409 CHOICE_FRAGGED,
410 attacker_name,
411 kill_count_to_target,
412 GetResource(attacker, RES_HEALTH),
413 GetResource(attacker, RES_ARMOR),
414 (IS_BOT_CLIENT(attacker) ? -1 : CS(attacker).ping)
415 );
416 }
417
418 if (!Obituary_WeaponDeath(targ, true, deathtype, targ.netname, attacker_name, deathlocation, CS(targ).killcount, kill_count_to_attacker))
419 {
420 int f3 = (deathtype == DEATH_BUFF.m_id) ? buff_FirstFromFlags(attacker).m_id : 0;
421 if (DEATH_ENT(deathtype) == DEATH_HURTTRIGGER)
422 {
423 bool msg_from_ent = (inflictor && inflictor.message2 != "");
424 Obituary_SpecialDeath(targ, true, msg_from_ent, deathtype,
425 targ.netname,
426 attacker_name,
427 (msg_from_ent ? inflictor.message2 : deathlocation),
428 (msg_from_ent ? deathlocation : ""),
429 CS(targ).killcount, kill_count_to_attacker, f3
430 );
431 }
432 else
433 Obituary_SpecialDeath(targ, true, 0, deathtype, targ.netname, attacker_name, deathlocation, "", CS(targ).killcount, kill_count_to_attacker, f3);
434 }
435 }
436 }
437
438 // =============
439 // ACCIDENT/TRAP
440 // =============
441 else
442 {
443 switch (DEATH_ENT(deathtype))
444 {
445 // For now, we're just forcing HURTTRIGGER to behave as "DEATH_VOID" and giving it no special options...
446 // Later on you will only be able to make custom messages using DEATH_CUSTOM,
447 // and there will be a REAL DEATH_VOID implementation which mappers will use.
448 case DEATH_HURTTRIGGER:
449 {
450 bool msg_from_ent = (inflictor && inflictor.message != "");
451 Obituary_SpecialDeath(targ, false, msg_from_ent, deathtype,
452 targ.netname,
453 (msg_from_ent ? inflictor.message : deathlocation),
454 (msg_from_ent ? deathlocation : ""),
455 "",
456 CS(targ).killcount,
457 0,
458 0
459 );
460 break;
461 }
462 case DEATH_CUSTOM:
463 Obituary_SpecialDeath(targ, false, 0, deathtype,
464 targ.netname,
465 ((strstrofs(deathmessage, "%", 0) < 0) ? strcat("%s ", deathmessage) : deathmessage),
466 deathlocation,
467 "",
468 CS(targ).killcount,
469 0,
470 0
471 );
472 break;
473 default:
474 Obituary_SpecialDeath(targ, false, 0, deathtype, targ.netname, deathlocation, "", "", CS(targ).killcount, 0, 0);
475 break;
476 }
477
478 LogDeath("accident", deathtype, targ, targ);
479 GiveFrags(targ, targ, -1, deathtype, weaponentity);
480
481 if (GameRules_scoring_add(targ, SCORE, 0) == -5)
482 {
483 Send_Notification(NOTIF_ONE, targ, MSG_ANNCE, ANNCE_ACHIEVEMENT_BOTLIKE);
484 if (!warmup_stage)
486 }
487 }
488
489 // reset target kill count
490 CS(targ).killcount = 0;
491}
float ping
Definition main.qh:169
void GiveFrags(entity attacker, entity targ, float f, int deathtype,.entity weaponentity)
Definition damage.qc:43
float Obituary_WeaponDeath(entity notif_target, float murder, int deathtype, string s1, string s2, string s3, float f1, float f2)
Definition damage.qc:165
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)
Definition damage.qc:117
bool frag_centermessage_override(entity attacker, entity targ, int deathtype, int kill_count_to_attacker, int kill_count_to_target, string attacker_name)
Definition damage.qc:210
void LogDeath(string mode, int deathtype, entity killer, entity killed)
Definition damage.qc:100
string deathmessage
Definition damage.qh:73
float checkrules_firstblood
Definition damage.qh:43
#define DEATH_ENT(t)
Definition all.qh:41
#define strstrofs
#define backtrace(msg)
Definition log.qh:99
void Send_Notification(NOTIF broadcast, entity client, MSG net_type, Notification net_name,...count)
Definition all.qc:1573
#define KILL_SPREE_LIST
Definition all.qh:491
#define APP_TEAM_NUM(num, prefix)
Definition all.qh:84
float autocvar_notification_server_allows_location
Definition all.qh:318
const string PLAYERSTATS_ACHIEVEMENT_FIRSTBLOOD
const string PLAYERSTATS_ACHIEVEMENT_FIRSTVICTIM
const string PLAYERSTATS_ACHIEVEMENT_BOTLIKE
#define NULL
Definition post.qh:14
string NearestLocation(vector p)
Definition chat.qc:446
entity buff_FirstFromFlags(entity actor)
Definition sv_buffs.qc:288
#define IS_BOT_CLIENT(v)
want: (IS_CLIENT(v) && !IS_REAL_CLIENT(v))
Definition utils.qh:15

References APP_TEAM_NUM, autocvar_notification_server_allows_location, backtrace, buff_FirstFromFlags(), checkrules_firstblood, CS(), DEATH_ENT, DEATH_ISSPECIAL, deathmessage, Deathtype_Name(), entity(), frag_centermessage_override(), GameRules_scoring_add, GetResource(), GiveFrags(), IS_BOT_CLIENT, IS_PLAYER, KILL_SPREE_LIST, killcount, LogDeath(), M_ARGV, MUTATOR_CALLHOOK, NearestLocation(), NULL, Obituary_SpecialDeath(), Obituary_WeaponDeath(), ping, PLAYERSTATS_ACHIEVEMENT_BOTLIKE, PLAYERSTATS_ACHIEVEMENT_FIRSTBLOOD, PLAYERSTATS_ACHIEVEMENT_FIRSTVICTIM, PlayerStats_GameReport_Event_Player, RES_ARMOR, SAME_TEAM, Send_Notification(), strcat(), strstrofs, time, and warmup_stage.

Referenced by PlayerDamage().

◆ Obituary_SpecialDeath()

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 )

References entity(), f1, f2, s1, and s2.

◆ Obituary_WeaponDeath()

float Obituary_WeaponDeath ( entity notif_target,
float murder,
int deathtype,
string s1,
string s2,
string s3,
float f1,
float f2 )

Definition at line 165 of file damage.qc.

171{
172 Weapon death_weapon = DEATH_WEAPONOF(deathtype);
173 if (death_weapon == WEP_Null)
174 return false;
175
176 w_deathtype = deathtype;
177 Notification death_message = (murder ? death_weapon.wr_killmessage(death_weapon) : death_weapon.wr_suicidemessage(death_weapon));
178 w_deathtype = false;
179
180 if (death_message)
181 {
183 NOTIF_ONE,
184 notif_target,
185 MSG_MULTI,
186 death_message,
187 s1, s2, s3, "",
188 f1, f2, 0, 0
189 );
190 // send the info part to everyone
192 NOTIF_ALL_EXCEPT,
193 notif_target,
194 MSG_INFO,
195 death_message.nent_msginfo,
196 s1, s2, s3, "",
197 f1, f2, 0, 0
198 );
199 }
200 else
202 "Obituary_WeaponDeath(): ^1Deathtype ^7(%d)^1 has no notification for weapon %s!\n",
203 deathtype,
204 death_weapon.netname
205 );
206
207 return true;
208}
fields which are explicitly/manually set are marked with "M", fields set automatically are marked wit...
Definition weapon.qh:42
virtual void wr_suicidemessage()
(SERVER) notification number for suicide message (may inspect w_deathtype for details)
Definition weapon.qh:118
string netname
M: refname : reference name name.
Definition weapon.qh:84
virtual void wr_killmessage()
(SERVER) notification number for kill message (may inspect w_deathtype for details)
Definition weapon.qh:123
int w_deathtype
#define LOG_TRACEF(...)
Definition log.qh:77
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
Definition all.inc:366
spree_inf s1 s2 s3loc s2 s1
Definition all.inc:281
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
Definition all.inc:471
f1
Definition all.inc:563
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)
Definition all.qc:1762
entity Notification
always last
Definition all.qh:81

References DEATH_WEAPONOF, entity(), f1, f2, LOG_TRACEF, Weapon::netname, s1, s2, Send_Notification_WOCOVA(), w_deathtype, Weapon::wr_killmessage(), and Weapon::wr_suicidemessage().

Referenced by Obituary().

◆ RadiusDamage()

float RadiusDamage ( entity inflictor,
entity attacker,
float coredamage,
float edgedamage,
float rad,
entity cantbe,
entity mustbe,
float forceintensity,
int deathtype,
.entity weaponentity,
entity directhitentity )

Definition at line 943 of file damage.qc.

948{
950 inflictor, (inflictor.origin + (inflictor.mins + inflictor.maxs) * 0.5), inflictor.velocity, attacker,
951 coredamage, edgedamage, rad, cantbe, mustbe,
952 false, forceintensity, '1 1 1',
953 deathtype, weaponentity, directhitentity
954 );
955}
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)
Definition damage.qc:718

References entity(), and RadiusDamageForSource().

Referenced by bumblebee_blowup(), CheatImpulse(), func_breakable_destroy(), M_Golem_Attack_Lightning_Explode(), M_Golem_Attack_Smash(), M_Mage_Attack_Push(), M_Mage_Attack_Spike_Explode(), M_Spider_Attack_Web_Explode(), M_Wyvern_Attack_Fireball_Explode(), nade_normal_boom(), PlayerTouchExplode(), racer_blowup(), raptor_blowup(), raptor_bomblet_boom(), spiderbot_blowup(), turret_flac_projectile_think_explode(), turret_projectile_explode(), vehicles_projectile_explode(), W_Arc_Bolt_Explode(), W_Arc_Bolt_Touch(), W_Crylink_LinkExplode(), W_Crylink_LinkJoinEffect_Think(), W_Crylink_Touch(), W_Devastator_DoRemoteExplode(), W_Electro_Explode(), W_Electro_ExplodeCombo(), W_Electro_ExplodeComboThink(), W_Fireball_Explode(), W_Hagar_Explode(), W_Hagar_Explode2(), W_HLAC_Touch(), W_Hook_ExplodeThink(), W_MineLayer_DoRemoteExplode(), W_MineLayer_Explode(), W_Mortar_Grenade_Explode(), W_Mortar_Grenade_Explode2(), W_OverkillRocketPropelledChainsaw_Explode(), W_RocketMinsta_Explosion(), W_RocketMinsta_Laser_Damage(), W_Seeker_Flac_Explode(), W_Seeker_Missile_Explode(), W_Tuba_NoteOn(), and walker_rocket_explode().

◆ RadiusDamageForSource()

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 )

Definition at line 718 of file damage.qc.

723{
725 {
726 backtrace("RadiusDamage called recursively! Expect stuff to go HORRIBLY wrong.");
727 return 0;
728 }
729
730 if (rad < 0)
731 rad = 0;
732
734
735 float tfloordmg = autocvar_g_throughfloor_damage;
736 float tfloorforce = autocvar_g_throughfloor_force;
737
738 float stat_damagedone = 0;
739 float total_damage_to_creatures = 0;
740
741 vector force;
742 if (!(deathtype & (HITTYPE_SOUND | HITTYPE_SPAM))) // do not send bandwidth-hogging radial spam attacks
743 {
744 force = inflictorvelocity;
745 if (force == '0 0 0')
746 force = '0 0 -1';
747 else
748 force = normalize(force);
749 if (forceintensity >= 0)
750 Damage_DamageInfo(inflictororigin, coredamage, edgedamage, rad, forceintensity * force, deathtype, 0, attacker);
751 else
752 Damage_DamageInfo(inflictororigin, coredamage, edgedamage, -rad, (-forceintensity) * force, deathtype, 0, attacker);
753 }
754
755 entity targ = WarpZone_FindRadius(inflictororigin, rad + MAX_DAMAGEEXTRARADIUS, false);
756 for (; targ; targ = targ.chain)
757 if ((targ != inflictor || inflictorselfdamage)
758 && (((cantbe != targ) && !mustbe) || mustbe == targ)
759 && targ.takedamage)
760 {
761 // calculate distance from nearest point on target to nearest point on inflictor
762 // instead of origin to ensure full damage on impacts
763
764 vector nearest = targ.WarpZone_findradius_nearest;
765
766 // optimize code by getting inflictororigin_wz from WarpZone_FindRadius calculations instead of
767 //vector inflictororigin_wz = WarpZone_TransformOrigin(targ, inflictororigin);
768
769 vector inflictororigin_wz = targ.WarpZone_findradius_nearest + targ.WarpZone_findradius_dist;
770 vector inflictornearest = NearestPointOnBoundingBox(
771 inflictororigin_wz + inflictor.mins, inflictororigin_wz + inflictor.maxs, nearest);
772 vector diff = inflictornearest - nearest;
773
774 // round up a little on the damage to ensure full damage on impacts
775 // and turn the distance into a fraction of the radius
776 float dist = max(0, vlen(diff) - bound(MIN_DAMAGEEXTRARADIUS, targ.damageextraradius, MAX_DAMAGEEXTRARADIUS));
777 if (dist <= rad)
778 {
779 float f = (rad > 0) ? 1 - (dist / rad) : 1;
780 // at this point f can't be < 0 or > 1
781 float finaldmg = coredamage * f + edgedamage * (1 - f);
782 if (finaldmg > 0)
783 {
784 vector hitloc;
785 float a, c;
786
787 // if it's a player, use the view origin as reference
788 vector center = CENTER_OR_VIEWOFS(targ);
789
791 {
792 if (targ != attacker) // always use target's bbox centerpoint
793 center = targ.origin + ((targ.mins + targ.maxs) * 0.5);
794 else // targ == attacker
795 {
796 #if 0
797 // code stolen from W_SetupShot_Dir_ProjectileSize_Range()
798 vector md = targ.(weaponentity).movedir;
799 vector dv = v_right * -md.y + v_up * md.z;
800 vector mi = '0 0 0', ma = '0 0 0';
801
802 if (IS_CLIENT(targ)) // no antilag for non-clients!
803 {
804 if (CS(targ).antilag_debug)
805 tracebox_antilag(targ, center, mi, ma, center + dv, MOVE_NORMAL, targ, CS(targ).antilag_debug);
806 else
807 tracebox_antilag(targ, center, mi, ma, center + dv, MOVE_NORMAL, targ, ANTILAG_LATENCY(targ));
808 }
809 else
810 tracebox(center, mi, ma, center + dv, MOVE_NORMAL, targ);
811
812 center.z = trace_endpos.z;
813 #else
814 // very cheap way but it skips move into solid checks which is fine most of the time for now AFAIK
815 // this should only really be an issue with some rare edge cases where
816 // shot origin was prevented from going into a ceiling but it still explodes at the ceiling
817 // shot origin wasn't raised as high as possible and the shooter gets upwards knockback
818 // TL;DR: no bugs if vertical shot origin is always within player bbox
819 center.z += targ.(weaponentity).movedir.z;
820 #endif
821 }
822 }
823
824 /* debug prints
825 print(sprintf("origin vec %v\n", targ.origin));
826 print(sprintf("movedir vec %v\n", targ.(weaponentity).movedir));
827 print(sprintf("old def vec %v\n", CENTER_OR_VIEWOFS(targ)));
828 print(sprintf("origin+vofs %v\n", targ.origin + targ.view_ofs));
829 print(sprintf("bbox center %v\n", (targ.origin + ((targ.mins + targ.maxs) * 0.5))));
830 print(sprintf("center vec %v\n", center));
831 print(sprintf("shotorg vec %v\n", w_shotorg));
832 print("\n");
833 */
834
835 force = normalize(center - inflictororigin_wz);
836 force *= (finaldmg / max(coredamage, edgedamage)) * forceintensity;
837 hitloc = nearest;
838
839 // apply special force scalings
840 if (forcexyzscale.x)
841 force.x *= forcexyzscale.x;
842 if (forcexyzscale.y)
843 force.y *= forcexyzscale.y;
844 if (forcexyzscale.z)
845 force.z *= forcexyzscale.z;
846
847 if (targ != directhitentity)
848 {
849 float hits;
850 float total;
851 float hitratio;
852 float mininv_f, mininv_d;
853
854 // test line of sight to multiple positions on box,
855 // and do damage if any of them hit
856 hits = 0;
857
858 // we know: max stddev of hitratio = 1 / (2 * sqrt(n))
859 // so for a given max stddev:
860 // n = (1 / (2 * max stddev of hitratio))^2
861
862 mininv_d = (finaldmg * (1-tfloordmg)) / autocvar_g_throughfloor_damage_max_stddev;
863 mininv_f = (vlen(force) * (1-tfloorforce)) / autocvar_g_throughfloor_force_max_stddev;
864
866 LOG_INFOF("THROUGHFLOOR: D=%f F=%f max(dD)=1/%f max(dF)=1/%f", finaldmg, vlen(force), mininv_d, mininv_f);
867
868 total = 0.25 * (max(mininv_f, mininv_d) ** 2);
869
871 LOG_INFOF(" steps=%f", total);
872
873 if (IS_PLAYER(targ))
875 else
877
879 LOG_INFOF(" steps=%f dD=%f dF=%f", total, finaldmg * (1-tfloordmg) / (2 * sqrt(total)), vlen(force) * (1-tfloorforce) / (2 * sqrt(total)));
880
881 for (c = 0; c < total; ++c)
882 {
883 //traceline(targ.WarpZone_findradius_findorigin, nearest, MOVE_NOMONSTERS, inflictor);
884 WarpZone_TraceLine(inflictororigin, WarpZone_UnTransformOrigin(targ, nearest), MOVE_NOMONSTERS, inflictor);
885 if (trace_fraction == 1 || trace_ent == targ)
886 {
887 ++hits;
888 if (hits > 1)
889 hitloc += nearest;
890 else
891 hitloc = nearest;
892 }
893 nearest.x = targ.origin.x + targ.mins.x + random() * targ.size.x;
894 nearest.y = targ.origin.y + targ.mins.y + random() * targ.size.y;
895 nearest.z = targ.origin.z + targ.mins.z + random() * targ.size.z;
896 }
897
898 nearest = hitloc * (1 / max(1, hits));
899 hitratio = hits / total;
900 a = bound(0, tfloordmg + (1 - tfloordmg) * hitratio, 1);
901 finaldmg *= a;
902 a = bound(0, tfloorforce + (1 - tfloorforce) * hitratio, 1);
903 force *= a;
904
906 LOG_INFOF(" D=%f F=%f", finaldmg, vlen(force));
907
908 /*if (targ == attacker)
909 {
910 print("hits ", ftos(hits), " / ", ftos(total));
911 print(" finaldmg ", ftos(finaldmg), " force ", ftos(vlen(force)));
912 print(" (", vtos(force), ") (", ftos(a), ")\n");
913 }*/
914 }
915
916 if (finaldmg || force)
917 {
918 if (targ.iscreature)
919 {
920 total_damage_to_creatures += finaldmg;
921
922 if (accuracy_isgooddamage(attacker, targ))
923 stat_damagedone += finaldmg;
924 }
925
926 if (targ == directhitentity || DEATH_ISSPECIAL(deathtype))
927 Damage(targ, inflictor, attacker, finaldmg, deathtype, weaponentity, nearest, force);
928 else
929 Damage(targ, inflictor, attacker, finaldmg, deathtype | HITTYPE_SPLASH, weaponentity, nearest, force);
930 }
931 }
932 }
933 }
934
935 RadiusDamage_running = false;
936
937 if (!DEATH_ISSPECIAL(deathtype))
938 accuracy_add(attacker, DEATH_WEAPONOF(deathtype), 0, min(max(coredamage, edgedamage), stat_damagedone), 0); // add to hit
939
940 return total_damage_to_creatures;
941}
void tracebox_antilag(entity source, vector v1, vector mi, vector ma, vector v2, float nomonst, entity forent, float lag)
Definition antilag.qc:210
float antilag_debug
Definition antilag.qc:19
#define ANTILAG_LATENCY(e)
Definition antilag.qh:19
vector v_up
const float MOVE_NOMONSTERS
entity trace_ent
vector v_right
vector trace_endpos
bool RadiusDamage_running
Definition damage.qh:111
int autocvar_g_player_damageplayercenter
Definition damage.qh:106
float autocvar_g_throughfloor_force_max_stddev
Definition damage.qh:9
float autocvar_g_throughfloor_damage_max_stddev
Definition damage.qh:8
float autocvar_g_throughfloor_force
Definition damage.qh:7
bool autocvar_g_throughfloor_debug
Definition damage.qh:5
float autocvar_g_throughfloor_min_steps_other
Definition damage.qh:12
float autocvar_g_throughfloor_min_steps_player
Definition damage.qh:10
float autocvar_g_throughfloor_damage
Definition damage.qh:6
float autocvar_g_throughfloor_max_steps_other
Definition damage.qh:13
float autocvar_g_throughfloor_max_steps_player
Definition damage.qh:11
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
const int HITTYPE_SPLASH
Definition all.qh:30
entity WarpZone_FindRadius(vector org, float rad, bool needlineofsight)
Definition common.qc:684
void WarpZone_TraceLine(vector org, vector end, float nomonsters, entity forent)
Definition common.qc:348
vector WarpZone_UnTransformOrigin(entity wz, vector v)
Definition common.qc:544
#define LOG_INFOF(...)
Definition log.qh:66
vector movedir
Definition viewloc.qh:18
float ceil(float f)
float random(void)
float sqrt(float f)
#define CENTER_OR_VIEWOFS(ent)
Definition utils.qh:31
ERASEABLE vector NearestPointOnBoundingBox(vector mi, vector ma, vector org)
Definition vector.qh:194

References accuracy_add(), accuracy_isgooddamage(), antilag_debug, ANTILAG_LATENCY, autocvar_g_player_damageplayercenter, autocvar_g_throughfloor_damage, autocvar_g_throughfloor_damage_max_stddev, autocvar_g_throughfloor_debug, autocvar_g_throughfloor_force, autocvar_g_throughfloor_force_max_stddev, autocvar_g_throughfloor_max_steps_other, autocvar_g_throughfloor_max_steps_player, autocvar_g_throughfloor_min_steps_other, autocvar_g_throughfloor_min_steps_player, backtrace, bound(), ceil(), CENTER_OR_VIEWOFS, CS(), Damage(), Damage_DamageInfo(), DEATH_ISSPECIAL, DEATH_WEAPONOF, entity(), HITTYPE_SOUND, HITTYPE_SPAM, HITTYPE_SPLASH, IS_CLIENT, IS_PLAYER, LOG_INFOF, max(), MAX_DAMAGEEXTRARADIUS, min(), MIN_DAMAGEEXTRARADIUS, MOVE_NOMONSTERS, MOVE_NORMAL, movedir, NearestPointOnBoundingBox(), normalize(), RadiusDamage_running, random(), sqrt(), trace_endpos, trace_ent, trace_fraction, tracebox_antilag(), v_right, v_up, vector, vlen(), WarpZone_FindRadius(), WarpZone_TraceLine(), and WarpZone_UnTransformOrigin().

Referenced by RadiusDamage(), W_Blaster_Touch(), and W_Devastator_Explode().

◆ STATIC_INIT()

STATIC_INIT ( g_damagedbycontents )

Definition at line 144 of file damage.qh.

145{
147}
#define IL_NEW()

References g_damagedbycontents, and IL_NEW.

◆ void()

void ( entity this,
entity inflictor,
entity attacker,
float damage,
int deathtype,
.entity weaponentity,
vector hitloc,
vector force )

References entity(), and vector.

◆ W_SwitchWeapon_Force()

void W_SwitchWeapon_Force ( Player this,
Weapon w,
.entity weaponentity )

Definition at line 237 of file selection.qc.

238{
239 TC(Weapon, wep);
240 entity w_ent = this.(weaponentity);
241 w_ent.cnt = w_ent.m_switchweapon.m_id;
242 w_ent.m_switchweapon = wep;
243 w_ent.selectweapon = wep.m_id;
244}
#define TC(T, sym)
Definition _all.inc:82

References entity(), Weapon::m_id, and TC.

Referenced by GiveItems(), Item_GiveTo(), MUTATOR_HOOKFUNCTION(), TEST(), W_Hagar_Attack_Auto(), W_HLAC_Attack_Frame(), W_MachineGun_Attack_Auto(), W_MachineGun_Attack_Frame(), W_OverkillHeavyMachineGun_Attack_Auto(), W_OverkillMachineGun_Attack_Auto(), W_Shotgun_Attack3_Frame1(), W_Shotgun_Attack3_Frame2(), W_ThrowWeapon(), and W_WeaponFrame().

Variable Documentation

◆ autocvar_g_balance_armor_blockpercent

◆ autocvar_g_balance_damagepush_speedfactor

float autocvar_g_balance_damagepush_speedfactor

Definition at line 18 of file damage.qh.

Referenced by ClientInit_CheckUpdate(), Damage(), and MUTATOR_HOOKFUNCTION().

◆ autocvar_g_balance_firetransfer_damage

int autocvar_g_balance_firetransfer_damage

Definition at line 19 of file damage.qh.

◆ autocvar_g_balance_firetransfer_time

int autocvar_g_balance_firetransfer_time

Definition at line 20 of file damage.qh.

◆ autocvar_g_balance_selfdamagepercent

float autocvar_g_balance_selfdamagepercent

Definition at line 25 of file damage.qh.

Referenced by Damage().

◆ autocvar_g_friendlyfire

float autocvar_g_friendlyfire

Definition at line 26 of file damage.qh.

Referenced by Damage(), MUTATOR_HOOKFUNCTION(), and turret_damage().

◆ autocvar_g_friendlyfire_virtual

float autocvar_g_friendlyfire_virtual

Definition at line 27 of file damage.qh.

Referenced by Damage().

◆ autocvar_g_friendlyfire_virtual_force

float autocvar_g_friendlyfire_virtual_force

Definition at line 28 of file damage.qh.

Referenced by Damage().

◆ autocvar_g_maxpushtime

◆ autocvar_g_mirrordamage

float autocvar_g_mirrordamage

Definition at line 14 of file damage.qh.

Referenced by Damage().

◆ autocvar_g_mirrordamage_onlyweapons

bool autocvar_g_mirrordamage_onlyweapons

Definition at line 16 of file damage.qh.

Referenced by Damage().

◆ autocvar_g_mirrordamage_virtual

bool autocvar_g_mirrordamage_virtual

Definition at line 15 of file damage.qh.

Referenced by Damage().

◆ autocvar_g_player_damageplayercenter

int autocvar_g_player_damageplayercenter

Definition at line 106 of file damage.qh.

Referenced by RadiusDamageForSource().

◆ autocvar_g_teamdamage_resetspeed

float autocvar_g_teamdamage_resetspeed

Definition at line 22 of file damage.qh.

Referenced by PlayerThink().

◆ autocvar_g_teamdamage_threshold

float autocvar_g_teamdamage_threshold

Definition at line 23 of file damage.qh.

Referenced by Damage().

◆ autocvar_g_teamkill_punishing

bool autocvar_g_teamkill_punishing

Definition at line 24 of file damage.qh.

Referenced by GiveFrags().

◆ autocvar_g_throughfloor_damage

float autocvar_g_throughfloor_damage

Definition at line 6 of file damage.qh.

Referenced by RadiusDamageForSource().

◆ autocvar_g_throughfloor_damage_max_stddev

float autocvar_g_throughfloor_damage_max_stddev

Definition at line 8 of file damage.qh.

Referenced by RadiusDamageForSource().

◆ autocvar_g_throughfloor_debug

bool autocvar_g_throughfloor_debug

Definition at line 5 of file damage.qh.

Referenced by RadiusDamageForSource().

◆ autocvar_g_throughfloor_force

float autocvar_g_throughfloor_force

Definition at line 7 of file damage.qh.

Referenced by RadiusDamageForSource().

◆ autocvar_g_throughfloor_force_max_stddev

float autocvar_g_throughfloor_force_max_stddev

Definition at line 9 of file damage.qh.

Referenced by RadiusDamageForSource().

◆ autocvar_g_throughfloor_max_steps_other

float autocvar_g_throughfloor_max_steps_other

Definition at line 13 of file damage.qh.

Referenced by RadiusDamageForSource().

◆ autocvar_g_throughfloor_max_steps_player

float autocvar_g_throughfloor_max_steps_player

Definition at line 11 of file damage.qh.

Referenced by RadiusDamageForSource().

◆ autocvar_g_throughfloor_min_steps_other

float autocvar_g_throughfloor_min_steps_other

Definition at line 12 of file damage.qh.

Referenced by RadiusDamageForSource().

◆ autocvar_g_throughfloor_min_steps_player

float autocvar_g_throughfloor_min_steps_player

Definition at line 10 of file damage.qh.

Referenced by RadiusDamageForSource().

◆ canteamdamage

bool canteamdamage

Definition at line 65 of file damage.qh.

Referenced by spawnfunc().

◆ checkrules_firstblood

float checkrules_firstblood

Definition at line 43 of file damage.qh.

Referenced by Obituary().

◆ damagedbycontents

◆ damagedbytriggers

float damagedbytriggers

Definition at line 46 of file damage.qh.

◆ damageextraradius

float damageextraradius

Definition at line 128 of file damage.qh.

◆ damageforcescale

float damageforcescale

Definition at line 125 of file damage.qh.

◆ death_origin

vector death_origin

Definition at line 67 of file damage.qh.

Referenced by formatmessage(), IMPULSE(), IMPULSE(), and IMPULSE().

◆ deathmessage

string deathmessage

Definition at line 73 of file damage.qh.

Referenced by Obituary().

◆ dmg

float dmg

Definition at line 34 of file damage.qh.

◆ dmg_edge

float dmg_edge

Definition at line 35 of file damage.qh.

◆ dmg_force

float dmg_force

Definition at line 36 of file damage.qh.

◆ dmg_radius

float dmg_radius

Definition at line 37 of file damage.qh.

◆ dmg_team

float dmg_team

Definition at line 53 of file damage.qh.

Referenced by PlayerThink(), and PutPlayerInServer().

◆ fire_damagepersec

float fire_damagepersec

Definition at line 134 of file damage.qh.

◆ fire_deathtype

float fire_deathtype

Definition at line 135 of file damage.qh.

◆ fire_hitsound

float fire_hitsound

Definition at line 137 of file damage.qh.

◆ fire_owner

entity fire_owner

Definition at line 136 of file damage.qh.

◆ g_damagedbycontents

◆ hitsound_damage_dealt

float hitsound_damage_dealt

Definition at line 69 of file damage.qh.

◆ impressive_hits

int impressive_hits

Definition at line 49 of file damage.qh.

Referenced by Damage(), W_OverkillNex_Attack(), W_Vaporizer_Attack(), and W_Vortex_Attack().

◆ istypefrag

bool istypefrag

Definition at line 58 of file damage.qh.

◆ killsound

int killsound

Definition at line 70 of file damage.qh.

◆ MAX_DAMAGEEXTRARADIUS

const float MAX_DAMAGEEXTRARADIUS = 16

Definition at line 127 of file damage.qh.

◆ MIN_DAMAGEEXTRARADIUS

const float MIN_DAMAGEEXTRARADIUS = 0.1

Definition at line 126 of file damage.qh.

◆ pain_finished

float pain_finished

Definition at line 51 of file damage.qh.

◆ pusher

entity pusher

Definition at line 57 of file damage.qh.

◆ RadiusDamage_running

bool RadiusDamage_running

Definition at line 111 of file damage.qh.

Referenced by RadiusDamageForSource().

◆ spawnshieldtime

◆ taunt_soundtime

float taunt_soundtime

Definition at line 59 of file damage.qh.

Referenced by PlayerPreThink().

◆ teamkill_complain

float teamkill_complain

Definition at line 54 of file damage.qh.

Referenced by Damage(), and W_Nexball_Touch().

◆ teamkill_soundsource

entity teamkill_soundsource

Definition at line 56 of file damage.qh.

◆ teamkill_soundtime

float teamkill_soundtime

Definition at line 55 of file damage.qh.

Referenced by PlayerPreThink().

◆ totalfrags

int totalfrags

Definition at line 63 of file damage.qh.

◆ typehitsound

int typehitsound

Definition at line 70 of file damage.qh.

◆ w_deathtype

float w_deathtype

Definition at line 93 of file damage.qh.

◆ yoda