Xonotic QuakeC
The free, fast arena FPS with crisp movement and a wide array of weapons
player.qc
Go to the documentation of this file.
1#include "player.qh"
2
3#include <common/anim.qh>
18#include <common/playerstats.qh>
19#include <common/state.qh>
20#include <common/wepent.qh>
22#include <server/bot/api.qh>
23#include <server/cheats.qh>
24#include <server/client.qh>
25#include <server/clientkill.qh>
28#include <server/damage.qh>
29#include <server/handicap.qh>
30#include <server/hook.qh>
31#include <server/main.qh>
33#include <server/portals.qh>
34#include <server/teamplay.qh>
40#include <server/world.qh>
41
43{
44 // called when the player has become stuck or frozen
45 // so objective items aren't stuck with the player
46
47 MUTATOR_CALLHOOK(DropSpecialItems, player);
48}
49
51{
53 {
54 this.CopyBody_think(this);
55 if(wasfreed(this))
56 return;
57 this.CopyBody_nextthink = this.nextthink;
58 this.CopyBody_think = getthink(this);
60 }
62 this.nextthink = time;
63}
64void CopyBody(entity this, float keepvelocity)
65{
66 if (this.effects & EF_NODRAW)
67 return;
68 entity clone = new(body);
69 clone.enemy = this;
70 clone.lip = this.lip;
71 clone.colormap = this.colormap;
72 clone.iscreature = this.iscreature;
73 clone.teleportable = this.teleportable;
74 clone.damagedbycontents = this.damagedbycontents;
75 if(clone.damagedbycontents)
77 clone.angles = this.angles;
78 clone.v_angle = this.v_angle;
79 clone.avelocity = this.avelocity;
80 clone.damageforcescale = this.damageforcescale;
81 clone.effects = this.effects;
82 clone.glowmod = this.glowmod;
83 clone.event_damage = this.event_damage;
84 clone.event_heal = this.event_heal;
85 clone.anim_state = this.anim_state;
86 clone.anim_time = this.anim_time;
87 clone.anim_lower_action = this.anim_lower_action;
88 clone.anim_lower_time = this.anim_lower_time;
89 clone.anim_upper_action = this.anim_upper_action;
90 clone.anim_upper_time = this.anim_upper_time;
91 clone.anim_implicit_state = this.anim_implicit_state;
92 clone.anim_implicit_time = this.anim_implicit_time;
93 clone.anim_lower_implicit_action = this.anim_lower_implicit_action;
94 clone.anim_lower_implicit_time = this.anim_lower_implicit_time;
95 clone.anim_upper_implicit_action = this.anim_upper_implicit_action;
96 clone.anim_upper_implicit_time = this.anim_upper_implicit_time;
97 clone.dphitcontentsmask = this.dphitcontentsmask;
98 clone.death_time = this.death_time;
99 clone.pain_finished = this.pain_finished;
100 SetResourceExplicit(clone, RES_HEALTH, GetResource(this, RES_HEALTH));
102 clone.armortype = this.armortype;
103 clone.model = this.model;
104 clone.modelindex = this.modelindex;
105 clone.skin = this.skin;
106 clone.species = this.species;
107 clone.move_qcphysics = false; // don't run gamecode logic on clones, too many
108 set_movetype(clone, this.move_movetype);
109 clone.solid = this.solid;
110 clone.takedamage = this.takedamage;
111 setcefc(clone, getcefc(this));
112 clone.uncustomizeentityforclient = this.uncustomizeentityforclient;
113 clone.uncustomizeentityforclient_set = this.uncustomizeentityforclient_set;
114 if (keepvelocity == 1)
115 clone.velocity = this.velocity;
116 clone.oldvelocity = clone.velocity;
117 clone.alpha = this.alpha;
118 clone.fade_time = this.fade_time;
119 clone.fade_rate = this.fade_rate;
120 //clone.weapon = this.weapon;
121 setorigin(clone, this.origin);
122 setsize(clone, this.mins, this.maxs);
123 clone.reset = SUB_Remove;
124 clone._ps = this._ps;
125
126 Drag_MoveDrag(this, clone);
127
128 if(clone.colormap <= maxclients && clone.colormap > 0)
129 clone.colormap = 1024 + this.clientcolors;
130 clone.sv_entnum = etof(this); // sent to CSQC for color mapping purposes
131
132 CSQCMODEL_AUTOINIT(clone);
133 clone.CopyBody_nextthink = this.nextthink;
134 clone.CopyBody_think = getthink(this);
135 clone.nextthink = time;
136 setthink(clone, CopyBody_Think);
137 // "bake" the current animation frame for clones (they don't get clientside animation)
140
141 IL_PUSH(g_clones, clone);
142
143 MUTATOR_CALLHOOK(CopyBody, this, clone, keepvelocity);
144}
145
147{
148 // load animation info
150 animdecide_setstate(this, 0, false);
151}
152
154{
155 int deadbits = (this.anim_state & (ANIMSTATE_DEAD1 | ANIMSTATE_DEAD2));
156 if(IS_DEAD(this)) {
157 if (!deadbits) {
158 // Decide on which death animation to use.
159 if(random() < 0.5)
160 deadbits = ANIMSTATE_DEAD1;
161 else
162 deadbits = ANIMSTATE_DEAD2;
163 }
164 } else {
165 // Clear a previous death animation.
166 deadbits = 0;
167 }
168 int animbits = deadbits;
169 if(StatusEffects_active(STATUSEFFECT_Frozen, this))
170 animbits |= ANIMSTATE_FROZEN;
172 animbits |= ANIMSTATE_FOLLOW;
173 if(IS_DUCKED(this))
174 animbits |= ANIMSTATE_DUCK;
175
176 MUTATOR_CALLHOOK(PlayerAnim, this, animbits);
177 animbits = M_ARGV(1, int);
178
179 animdecide_setstate(this, animbits, false);
181}
182
183void PlayerCorpseDamage(entity this, entity inflictor, entity attacker, float damage, int deathtype, .entity weaponentity, vector hitloc, vector force)
184{
185 float take, save;
186 vector v;
187 Violence_GibSplash_At(hitloc, force, 2, bound(0, damage, 200) / 16, this, attacker);
188
190 take = v.x;
191 save = v.y;
192
193 if(sound_allowed(MSG_BROADCAST, attacker))
194 {
195 if (save > 10)
196 sound (this, CH_SHOTS, SND_ARMORIMPACT, VOL_BASE, ATTEN_NORM);
197 else if (take > 30)
198 sound (this, CH_SHOTS, SND_BODYIMPACT2, VOL_BASE, ATTEN_NORM);
199 else if (take > 10)
200 sound (this, CH_SHOTS, SND_BODYIMPACT1, VOL_BASE, ATTEN_NORM);
201 }
202
203 if (take > 50)
204 Violence_GibSplash_At(hitloc, force * -0.1, 3, 1, this, attacker);
205 if (take > 100)
206 Violence_GibSplash_At(hitloc, force * -0.2, 3, 1, this, attacker);
207
208 TakeResource(this, RES_ARMOR, save);
209 TakeResource(this, RES_HEALTH, take);
210 // pause regeneration for 5 seconds
212
213 this.dmg_save = this.dmg_save + save;//max(save - 10, 0);
214 this.dmg_take = this.dmg_take + take;//max(take - 10, 0);
215 this.dmg_inflictor = inflictor;
216
217 if (GetResource(this, RES_HEALTH) <= -autocvar_sv_gibhealth && this.alpha >= 0)
218 {
219 // don't use any animations as a gib
220 this.frame = 0;
221 // view just above the floor
222 this.view_ofs = '0 0 4';
223
224 Violence_GibSplash(this, 1, 1, attacker);
225 this.alpha = -1;
226 this.solid = SOLID_NOT; // restore later
227 this.takedamage = DAMAGE_NO; // restore later
228 if(this.damagedbycontents)
230 this.damagedbycontents = false;
231 }
232}
233
234void PlayerDamage(entity this, entity inflictor, entity attacker, float damage, int deathtype, .entity weaponentity, vector hitloc, vector force)
235{
236 vector v;
237 float initial_health = max(GetResource(this, RES_HEALTH), 0);
238 float initial_armor = max(GetResource(this, RES_ARMOR), 0);
239 float take = 0, save = 0;
240
241 if (damage)
242 {
243 if(!DEATH_ISSPECIAL(deathtype))
244 {
245 damage *= Handicap_GetTotalHandicap(this, true);
246 if (this != attacker && IS_PLAYER(attacker))
247 {
248 damage /= Handicap_GetTotalHandicap(attacker, false);
249 }
250 }
251
252 if (StatusEffects_active(STATUSEFFECT_SpawnShield, this) && autocvar_g_spawnshield_blockdamage < 1)
253 damage *= 1 - bound(0, autocvar_g_spawnshield_blockdamage, 1);
254
255 if(deathtype & HITTYPE_SOUND) // sound based attacks cause bleeding from the ears
256 {
257 vector ear1, ear2;
258 vector d;
259 float f;
260 ear1 = this.origin;
261 ear1_z += 0.125 * this.view_ofs.z + 0.875 * this.maxs.z; // 7/8
262 ear2 = ear1;
263 makevectors(this.angles);
264 ear1 += v_right * -10;
265 ear2 += v_right * +10;
266 d = inflictor.origin - this.origin;
267 if (d)
268 f = (d * v_right) / vlen(d); // this is cos of angle of d and v_right!
269 else
270 f = 0; // Assum ecenter.
271 force = v_right * vlen(force);
272 Violence_GibSplash_At(ear1, force * -1, 2, bound(0, damage, 25) / 2 * (0.5 - 0.5 * f), this, attacker);
273 Violence_GibSplash_At(ear2, force, 2, bound(0, damage, 25) / 2 * (0.5 + 0.5 * f), this, attacker);
274 if(f > 0)
275 {
276 hitloc = ear1;
277 force = force * -1;
278 }
279 else
280 {
281 hitloc = ear2;
282 // force is already good
283 }
284 }
285 else
286 Violence_GibSplash_At(hitloc, force, 2, bound(0, damage, 200) / 16, this, attacker);
287
289 take = v.x;
290 save = v.y;
291 }
292
293 if(attacker == this)
294 {
295 // don't reset pushltime for self damage as it may be an attempt to
296 // escape a lava pit or similar
297 //this.pushltime = 0;
298 this.istypefrag = 0;
299 }
300 else if(IS_PLAYER(attacker))
301 {
302 this.pusher = attacker;
305 }
306 else if(time < this.pushltime)
307 {
308 attacker = this.pusher;
309 this.pushltime = max(this.pushltime, time + 0.6);
310 }
311 else if(IS_MONSTER(attacker) && IS_PLAYER(attacker.realowner))
312 {
313 attacker = attacker.realowner;
314 this.istypefrag = 0;
315 }
316 else
317 {
318 this.pushltime = 0;
319 this.istypefrag = 0;
320 }
321
322 MUTATOR_CALLHOOK(PlayerDamage_SplitHealthArmor, inflictor, attacker, this, force, take, save, deathtype, damage);
323 take = bound(0, M_ARGV(4, float), GetResource(this, RES_HEALTH));
324 save = bound(0, M_ARGV(5, float), GetResource(this, RES_ARMOR));
325 float excess = max(0, damage - take - save);
326
327 if(sound_allowed(MSG_BROADCAST, attacker))
328 {
329 if (save > 10 && (initial_health - take) > 0) // don't play armor sound if the attack is fatal
330 sound (this, CH_SHOTS, SND_ARMORIMPACT, VOL_BASE, ATTEN_NORM);
331 else if (take > 30)
332 sound (this, CH_SHOTS, SND_BODYIMPACT2, VOL_BASE, ATTEN_NORM);
333 else if (take > 10)
334 sound (this, CH_SHOTS, SND_BODYIMPACT1, VOL_BASE, ATTEN_NORM); // FIXME possibly remove them?
335 }
336
337 if (take > 50)
338 Violence_GibSplash_At(hitloc, force * -0.1, 3, 1, this, attacker);
339 if (take > 100)
340 Violence_GibSplash_At(hitloc, force * -0.2, 3, 1, this, attacker);
341
342 if (!StatusEffects_active(STATUSEFFECT_SpawnShield, this) || autocvar_g_spawnshield_blockdamage < 1)
343 {
344 if (!(this.flags & FL_GODMODE))
345 {
346 TakeResource(this, RES_ARMOR, save);
347 TakeResource(this, RES_HEALTH, take);
348 // pause regeneration for 5 seconds
349 if(take)
351
352 if (time > this.pain_finished && !STAT(FROZEN, this) && !StatusEffects_active(STATUSEFFECT_Frozen, this)) // Don't switch pain sequences like crazy
353 {
354 this.pain_finished = time + 0.5; //Supajoe
355
356 if(autocvar_sv_gentle < 1) {
357 if(this.classname != "body") // pain anim is BORKED on our ZYMs, FIXME remove this once we have good models
358 {
359 if (!this.animstate_override)
360 {
361 if (random() > 0.5)
363 else
365 }
366 }
367 float myhp = GetResource(this, RES_HEALTH);
368 if(myhp > 1)
369 if(myhp < 25 || !(DEATH_WEAPONOF(deathtype).spawnflags & WEP_FLAG_CANCLIMB) || take > 20 || attacker != this)
370 if(sound_allowed(MSG_BROADCAST, attacker))
371 // exclude pain sounds for laserjumps as long as you aren't REALLY low on health and would die of the next two
372 {
373 if(deathtype == DEATH_FALL.m_id)
374 PlayerSound(this, playersound_fall, CH_PAIN, VOL_BASE, VOICETYPE_PLAYERSOUND);
375 else if(myhp > 75)
376 PlayerSound(this, playersound_pain100, CH_PAIN, VOL_BASE, VOICETYPE_PLAYERSOUND);
377 else if(myhp > 50)
378 PlayerSound(this, playersound_pain75, CH_PAIN, VOL_BASE, VOICETYPE_PLAYERSOUND);
379 else if(myhp > 25)
380 PlayerSound(this, playersound_pain50, CH_PAIN, VOL_BASE, VOICETYPE_PLAYERSOUND);
381 else
382 PlayerSound(this, playersound_pain25, CH_PAIN, VOL_BASE, VOICETYPE_PLAYERSOUND);
383 }
384 }
385 }
386
387 // throw off bot aim temporarily
388 float shake;
389 if(IS_BOT_CLIENT(this) && GetResource(this, RES_HEALTH) >= 1)
390 {
391 shake = damage * 5 / (bound(0,skill,100) + 1);
392 this.v_angle_x = this.v_angle.x + (random() * 2 - 1) * shake;
393 this.v_angle_y = this.v_angle.y + (random() * 2 - 1) * shake;
394 this.v_angle_x = bound(-90, this.v_angle.x, 90);
395 }
396 }
397 else
398 this.max_armorvalue += (save + take);
399 }
400 this.dmg_save = this.dmg_save + save;//max(save - 10, 0);
401 this.dmg_take = this.dmg_take + take;//max(take - 10, 0);
402 this.dmg_inflictor = inflictor;
403
404 bool abot = (IS_BOT_CLIENT(attacker));
405 bool vbot = (IS_BOT_CLIENT(this));
406
407 bool valid_damage_for_weaponstats = false;
408 Weapon awep = WEP_Null;
409
411 if(vbot || IS_REAL_CLIENT(this))
412 if(abot || IS_REAL_CLIENT(attacker))
413 if(attacker && this != attacker)
414 if (DIFF_TEAM(this, attacker) && (!STAT(FROZEN, this) || this.freeze_time > time))
415 {
416 if(DEATH_ISSPECIAL(deathtype))
417 awep = attacker.(weaponentity).m_weapon;
418 else
419 awep = DEATH_WEAPONOF(deathtype);
420 valid_damage_for_weaponstats = true;
421 }
422
423 float dh = initial_health - max(GetResource(this, RES_HEALTH), 0); // health difference
424 float da = initial_armor - max(GetResource(this, RES_ARMOR), 0); // armor difference
425 if(valid_damage_for_weaponstats)
426 {
427 WeaponStats_LogDamage(awep.m_id, abot, this.(weaponentity).m_weapon.m_id, vbot, dh + da);
428 }
429
430 bool forbid_logging_damage = MUTATOR_CALLHOOK(PlayerDamaged, attacker, this, dh, da, hitloc, deathtype, damage);
431
432 if ((dh || da) && !forbid_logging_damage)
433 {
434 float realdmg = damage - excess;
435 if ((this != attacker || deathtype == DEATH_KILL.m_id) && realdmg
437 {
438 // accumulate damage, it will be logged later in this frame
439 if (IS_PLAYER(attacker) && DIFF_TEAM(attacker, this) && deathtype != DEATH_KILL.m_id)
440 {
441 if (accuracy_isgooddamage(attacker, this))
442 accuracy_add(attacker, awep, 0, 0, realdmg); // add to real
443 attacker.score_frame_dmg += realdmg;
444 }
445 if (IS_PLAYER(this))
446 this.score_frame_dmgtaken += realdmg;
447 }
448 }
449
450 if (GetResource(this, RES_HEALTH) < 1)
451 {
452 bool defer_ClientKill_Now_TeamChange = false;
453
454 if(this.alivetime_start)
455 {
457 this.alivetime_start = 0;
458 }
459
460 if(valid_damage_for_weaponstats)
461 WeaponStats_LogKill(awep.m_id, abot, this.(weaponentity).m_weapon.m_id, vbot);
462
463 if(autocvar_sv_gentle < 1)
464 if(sound_allowed(MSG_BROADCAST, attacker))
465 {
466 if(deathtype == DEATH_DROWN.m_id)
467 PlayerSound(this, playersound_drown, CH_PAIN, VOL_BASE, VOICETYPE_PLAYERSOUND);
468 else
469 PlayerSound(this, playersound_death, CH_PAIN, VOL_BASE, VOICETYPE_PLAYERSOUND);
470 }
471
472 // get rid of kill indicator
473 if(this.killindicator)
474 {
475 delete(this.killindicator);
476 this.killindicator = NULL;
478 defer_ClientKill_Now_TeamChange = true;
479
480 if(this.classname == "body")
481 if(deathtype == DEATH_KILL.m_id)
482 {
483 // for the lemmings fans, a small harmless explosion
484 Send_Effect(EFFECT_ROCKET_EXPLODE, this.origin, '0 0 0', 1);
485 }
486 }
487
488 // print an obituary message
489 if(this.classname != "body")
490 Obituary(attacker, inflictor, this, deathtype, weaponentity);
491
492 // increment frag counter for used weapon type
493 Weapon w = DEATH_WEAPONOF(deathtype);
494 if(w != WEP_Null && accuracy_isgooddamage(attacker, this))
495 CS(attacker).accuracy.(accuracy_frags[w.m_id-1]) += 1;
496
497 this.respawn_time = 0;
498 MUTATOR_CALLHOOK(PlayerDies, inflictor, attacker, this, deathtype, damage);
499 damage = M_ARGV(4, float);
500 excess = max(0, damage - take - save);
501
502 //Weapon wep = this.(weaponentity).m_weapon;
503 for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
504 {
505 .entity went = weaponentities[slot];
506 if(!this.(went))
507 continue; // TODO: clones have no weapon, but we don't want to have to check this all the time
508 Weapon wep = this.(went).m_weapon;
509 wep.wr_playerdeath(wep, this, went);
510 }
511
513
515
516 this.fixangle = true;
517
518 if(defer_ClientKill_Now_TeamChange)
519 ClientKill_Now_TeamChange(this); // can turn player into spectator
520
521 // player could have been miraculously resuscitated ;)
522 if(GetResource(this, RES_HEALTH) >= 1 || !(IS_PLAYER(this) || this.classname == "body"))
523 return;
524
525 if (!this.respawn_time) // can be set in the mutator hook PlayerDies
527
528 // when we get here, player actually dies
529
530 // clear waypoints
532 // throw a weapon
533 for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
534 {
535 .entity went = weaponentities[slot];
536 SpawnThrownWeapon(this, this.origin + (this.mins + this.maxs) * 0.5, this.(went).m_weapon, went);
537 }
538
539 // become fully visible
541 // make the corpse upright (not tilted)
542 this.angles_x = 0;
543 this.angles_z = 0;
544 // don't spin
545 this.avelocity = '0 0 0';
546 // view from the floor
547 this.view_ofs = '0 0 -8';
549 {
550 // don't toss the corpse in this case, it can get stuck in solid (causing low fps)
551 // or fall indefinitely into the void if out of the map
552 this.velocity = '0 0 0';
553 }
554 else
555 {
556 // toss the corpse
558 }
559 // shootable corpse
560 this.solid = SOLID_CORPSE;
561 PS(this).ballistics_density = autocvar_g_ballistics_density_corpse;
562 // don't stick to the floor
563 UNSET_ONGROUND(this);
564 // dying animation
565 this.deadflag = DEAD_DYING;
566 // don't play teleportation sounds
568
569 STAT(AIR_FINISHED, this) = 0;
570
571 this.death_time = time;
572 if (random() < 0.5)
574 else
576
577 // set damage function to corpse damage
578 this.event_damage = PlayerCorpseDamage;
579 this.event_heal = func_null;
580 // call the corpse damage function just in case it wants to gib
581 this.event_damage(this, inflictor, attacker, excess, deathtype, weaponentity, hitloc, force);
582
583 // set up to fade out later
584 SUB_SetFade (this, time + 6 + random (), 1);
585 // reset body think wrapper broken by SUB_SetFade
586 if(this.classname == "body" && getthink(this) != CopyBody_Think) {
587 this.CopyBody_think = getthink(this);
588 this.CopyBody_nextthink = this.nextthink;
590 this.nextthink = time;
591 }
592
593 if(autocvar_sv_gentle > 0 || autocvar_ekg || this.classname == "body") {
594 // remove corpse
595 // clones don't run any animation code any more, so we must gib them when they die :(
596 this.event_damage(this, inflictor, attacker, autocvar_sv_gibhealth + 1, deathtype, weaponentity, hitloc, force);
597 }
598
599 // reset fields the weapons may use just in case
600 if(this.classname != "body")
601 {
602 FOREACH(Weapons, it != WEP_Null,
603 {
604 it.wr_resetplayer(it, this);
605 for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
606 {
607 ATTACK_FINISHED_FOR(this, it.m_id, slot) = 0;
608 }
609 });
610 }
611 MUTATOR_CALLHOOK(PlayerDied, this);
612 }
613}
614
615bool PlayerHeal(entity targ, entity inflictor, float amount, float limit)
616{
617 float hlth = GetResource(targ, RES_HEALTH);
618 if (hlth <= 0 || hlth >= limit)
619 return false;
620
621 GiveResourceWithLimit(targ, RES_HEALTH, amount, limit);
622 return true;
623}
624
626{
627 int globhandle, i, n;
628 string f;
629
630 // remove :<skinnumber> suffix
631 int j = strstrofs(m, ":", 0);
632 if(j >= 0)
633 m = substring(m, 0, j);
634
635 if(substring(m, -9, 5) == "_lod1")
636 return;
637 if(substring(m, -9, 5) == "_lod2")
638 return;
639 precache_model(m);
640 f = strcat(substring(m, 0, -5), "_lod1", substring(m, -4, -1));
641 if(fexists(f))
642 precache_model(f);
643 f = strcat(substring(m, 0, -5), "_lod2", substring(m, -4, -1));
644 if(fexists(f))
645 precache_model(f);
646
647 globhandle = search_begin(strcat(m, "_*.sounds"), true, false);
648 if (globhandle < 0)
649 return;
650 n = search_getsize(globhandle);
651 for (i = 0; i < n; ++i)
652 {
653 //print(search_getfilename(globhandle, i), "\n");
654 f = search_getfilename(globhandle, i);
656 }
657 search_end(globhandle);
658}
659void precache_all_playermodels(string pattern)
660{
661 int globhandle = search_begin(pattern, true, false);
662 if (globhandle < 0) return;
663 int n = search_getsize(globhandle);
664 for (int i = 0; i < n; ++i)
665 {
666 string s = search_getfilename(globhandle, i);
668 }
669 search_end(globhandle);
670}
671
673{
674 FOREACH_WORD(s, true, { precache_playermodel(it); });
675}
676
677PRECACHE(PlayerModels)
678{
679 // Precache all player models if desired
681 {
682 PrecachePlayerSounds("sound/player/default.sounds");
683 precache_all_playermodels("models/player/*.zym");
684 precache_all_playermodels("models/player/*.dpm");
685 precache_all_playermodels("models/player/*.md3");
686 precache_all_playermodels("models/player/*.psk");
687 precache_all_playermodels("models/player/*.iqm");
688 }
689
691 {
697 }
698}
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 frame1time
start time of framegroup animation
Definition anim.qh:22
bool animstate_override
true for one cycle, then changed to false
Definition anim.qh:42
float frame2time
start time of framegroup animation
Definition anim.qh:24
float frame2
secondary framegroup animation (strength = lerpfrac)
Definition anim.qh:8
float frame
primary framegroup animation (strength = 1 - lerpfrac - lerpfrac3 - lerpfrac4)
Definition anim.qh:6
void animdecide_setimplicitstate(entity e, float onground)
void animdecide_load_if_needed(entity e)
Definition animdecide.qc:53
void animdecide_setframes(entity e, float support_blending,.float fld_frame,.float fld_frame1time,.float fld_frame2,.float fld_frame2time)
void animdecide_setstate(entity e, int newstate, float restart)
void animdecide_setaction(entity e, float action, float restart)
const int ANIMSTATE_FROZEN
float anim_lower_implicit_time
const int ANIMSTATE_DEAD1
float anim_lower_time
float anim_implicit_time
float anim_upper_implicit_action
float anim_lower_implicit_action
float anim_upper_time
int anim_state
const int ANIMSTATE_FOLLOW
float anim_upper_action
float anim_time
const int ANIMACTION_PAIN2
int anim_implicit_state
const int ANIMSTATE_DEAD2
const int ANIMACTION_PAIN1
float anim_lower_action
const int ANIMSTATE_DUCK
float anim_upper_implicit_time
float skill
Definition api.qh:35
#define MUTATOR_CALLHOOK(id,...)
Definition base.qh:143
void Drag_MoveDrag(entity from, entity to)
Definition cheats.qc:1006
var entity(vector mins, vector maxs,.entity tofield) findbox_tofield_OrFallback
float pain_finished
float GetResource(entity e, Resource res_type)
Returns the current amount of resource the given entity has.
void TakeResource(entity receiver, Resource res_type, float amount)
Takes an entity some resource.
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...
Definition weapon.qh:44
virtual void wr_playerdeath()
(SERVER) called whenever a player dies
Definition weapon.qh:110
int m_id
Definition weapon.qh:45
float alpha
Definition items.qc:13
void ClientKill_Now_TeamChange(entity this)
Definition clientkill.qc:18
int killindicator_teamchange
Definition clientkill.qh:8
entity killindicator
Definition clientkill.qh:7
int spawnflags
Definition ammo.qh:15
#define M_ARGV(x, type)
Definition events.qh:17
#define IS_DEAD(s)
Definition player.qh:245
#define PHYS_INPUT_BUTTON_CHAT(s)
Definition player.qh:159
vector v_angle
Definition player.qh:237
#define IS_DUCKED(s)
Definition player.qh:210
#define IS_PLAYER(s)
Definition player.qh:243
float game_starttime
Definition stats.qh:82
vector healtharmor_applydamage(float a, float armorblock, int deathtype, float damage)
Definition util.qc:1313
const int FL_GODMODE
Definition constants.qh:75
string classname
float flags
float maxclients
float modelindex
vector avelocity
vector mins
const float SOLID_CORPSE
vector velocity
const float SOLID_NOT
float effects
float skin
float time
vector v_right
vector maxs
float nextthink
float colormap
vector origin
const float EF_NODRAW
float dphitcontentsmask
vector glowmod
float death_time
#define CSQCMODEL_AUTOUPDATE(e)
#define CSQCMODEL_AUTOINIT(e)
void Obituary(entity attacker, entity inflictor, entity targ, int deathtype,.entity weaponentity)
Definition damage.qc:228
float damagedbycontents
Definition damage.qh:45
float autocvar_g_balance_armor_blockpercent
Definition damage.qh:21
IntrusiveList g_damagedbycontents
Definition damage.qh:135
float autocvar_g_maxpushtime
Definition damage.qh:17
float damageforcescale
#define DEATH_ISSPECIAL(t)
Definition all.qh:39
#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
#define strstrofs
void Send_Effect(entity eff, vector eff_loc, vector eff_vel, int eff_cnt)
Definition all.qc:124
RES_ARMOR
Definition ent_cs.qc:130
ent angles
Definition ent_cs.qc:121
model
Definition ent_cs.qc:139
clientcolors
Definition ent_cs.qc:147
solid
Definition ent_cs.qc:165
ERASEABLE bool fexists(string f)
Definition file.qh:4
void Violence_GibSplash(entity source, float type, float amount, entity attacker)
Definition gibs.qc:53
void Violence_GibSplash_At(vector org, vector dir, float type, float amount, entity gibowner, entity attacker)
Definition gibs.qc:23
int autocvar_ekg
Definition gibs.qh:4
void PrecachePlayerSounds(string f)
#define PlayerSound(this, def, chan, vol, voicetype)
const int VOICETYPE_PLAYERSOUND
Weapons
Definition guide.qh:113
float Handicap_GetTotalHandicap(entity player, bool receiving)
Returns the total handicap of the player.
Definition handicap.qc:96
Header file that describes the handicap system.
ERASEABLE void IL_REMOVE(IntrusiveList this, entity it)
Remove any element, anywhere in the list.
ERASEABLE entity IL_PUSH(IntrusiveList this, entity it)
Push to tail.
#define FOREACH_WORD(words, cond, body)
Definition iter.qh:33
#define FOREACH(list, cond, body)
Definition iter.qh:19
float pushltime
Definition jumppads.qh:21
bool istypefrag
Definition jumppads.qh:22
entity pusher
Definition laser.qc:57
float uncustomizeentityforclient_set
Definition net.qh:157
#define STAT(...)
Definition stats.qh:82
float bound(float min, float value, float max)
string substring(string s, float start, float length)
string search_getfilename(float handle, float num)
float random(void)
float search_getsize(float handle)
float vlen(vector v)
float search_begin(string pattern, float caseinsensitive, float quiet)
float MSG_BROADCAST
Definition menudefs.qc:55
void search_end(float handle)
float max(float f,...)
#define etof(e)
Definition misc.qh:25
void set_movetype(entity this, int mt)
Definition movetypes.qc:4
const int MOVETYPE_FOLLOW
Definition movetypes.qh:141
float move_movetype
Definition movetypes.qh:76
#define UNSET_ONGROUND(s)
Definition movetypes.qh:18
const int MOVETYPE_NOCLIP
Definition movetypes.qh:137
const int MOVETYPE_TOSS
Definition movetypes.qh:135
#define IS_ONGROUND(s)
Definition movetypes.qh:16
var void func_null()
strcat(_("^F4Countdown stopped!"), "\n^BG", _("Teams are too unbalanced."))
const string PLAYERSTATS_ALIVETIME
#define PlayerStats_GameReport_Event_Player(ent, eventid, val)
void Portal_ClearAllLater(entity own)
Definition portals.qc:611
#define NULL
Definition post.qh:14
#define makevectors
Definition post.qh:21
float DEAD_DYING
Definition progsdefs.qc:275
vector view_ofs
Definition progsdefs.qc:151
float fixangle
Definition progsdefs.qc:160
float deadflag
Definition progsdefs.qc:149
float dmg_save
Definition progsdefs.qc:199
float armortype
Definition progsdefs.qc:178
entity dmg_inflictor
Definition progsdefs.qc:200
fade_rate
Definition projectile.qh:14
#define round_handler_IsActive()
#define round_handler_IsRoundStarted()
#define setthink(e, f)
#define getthink(e)
vector
Definition self.qh:92
#define getcefc(e)
#define setcefc(e, f)
void calculate_player_respawn_time(entity this)
Definition client.qc:1392
float respawn_time
Definition client.qh:321
float pauseregen_finished
Definition client.qh:337
float alivetime_start
Definition client.qh:68
void RemoveGrapplingHooks(entity pl)
Definition hook.qc:30
float max_armorvalue
Definition items.qh:25
float species
Definition main.qh:47
bool iscreature
Definition main.qh:46
void PlayerDamage(entity this, entity inflictor, entity attacker, float damage, int deathtype,.entity weaponentity, vector hitloc, vector force)
Definition player.qc:234
void player_anim(entity this)
Definition player.qc:153
void precache_all_playermodels(string pattern)
Definition player.qc:659
void PlayerCorpseDamage(entity this, entity inflictor, entity attacker, float damage, int deathtype,.entity weaponentity, vector hitloc, vector force)
Definition player.qc:183
void Drop_Special_Items(entity player)
Definition player.qc:42
void precache_playermodels(string s)
Definition player.qc:672
void precache_playermodel(string m)
Definition player.qc:625
bool PlayerHeal(entity targ, entity inflictor, float amount, float limit)
Definition player.qc:615
void CopyBody_Think(entity this)
Definition player.qc:50
void player_setupanimsformodel(entity this)
Definition player.qc:146
void CopyBody(entity this, float keepvelocity)
Definition player.qc:64
string autocvar_sv_defaultplayermodel_blue
Definition player.qh:14
IntrusiveList g_clones
Definition player.qh:45
float score_frame_dmgtaken
Definition player.qh:26
string autocvar_sv_defaultplayermodel_yellow
Definition player.qh:17
string autocvar_sv_defaultplayermodel_red
Definition player.qh:16
bool autocvar_sv_precacheplayermodels
Definition player.qh:5
bool autocvar_sv_defaultcharacter
Definition player.qh:6
float autocvar_g_spawnshield_blockdamage
Definition player.qh:4
string autocvar_sv_defaultplayermodel
Definition player.qh:13
float CopyBody_nextthink
Definition player.qh:28
float autocvar_sv_gibhealth
Definition player.qh:19
string autocvar_sv_defaultplayermodel_pink
Definition player.qh:15
float fade_time
Definition common.qh:23
const int CH_PAIN
Definition sound.qh:18
const float VOL_BASE
Definition sound.qh:36
const int CH_SHOTS
Definition sound.qh:14
const float ATTEN_NORM
Definition sound.qh:30
#define sound(e, c, s, v, a)
Definition sound.qh:52
bool sound_allowed(int to, entity e)
Definition all.qc:9
#define PS(this)
Definition state.qh:18
PlayerState _ps
Definition state.qh:17
ClientState CS(Client this)
Definition state.qh:47
#define PRECACHE(func)
directly after STATIC_INIT_LATE
Definition static.qh:42
bool StatusEffects_active(StatusEffect this, entity actor)
void SUB_SetFade(entity ent, float vanish_time, float fading_time)
Definition subs.qc:77
const int DAMAGE_NO
Definition subs.qh:79
float lip
Definition subs.qh:40
float takedamage
Definition subs.qh:78
float freeze_time
void GiveResourceWithLimit(entity receiver, Resource res_type, float amount, float limit)
Gives an entity some resource but not more than a limit.
float autocvar_g_balance_pause_health_regen
#define DIFF_TEAM(a, b)
Definition teams.qh:242
float teleportable
const int TELEPORT_SIMPLE
void SpawnThrownWeapon(entity this, vector org, Weapon wep,.entity weaponentity)
Definition throwing.qc:160
float autocvar_g_ballistics_density_corpse
Definition tracing.qh:6
#define IS_REAL_CLIENT(v)
Definition utils.qh:17
#define IS_MONSTER(v)
Definition utils.qh:21
#define IS_BOT_CLIENT(v)
want: (IS_CLIENT(v) && !IS_REAL_CLIENT(v))
Definition utils.qh:15
float dmg_take
Definition view.qh:123
void WaypointSprite_PlayerDead(entity this)
const int WEP_FLAG_CANCLIMB
Definition weapon.qh:214
const int MAX_WEAPONSLOTS
Definition weapon.qh:16
entity weaponentities[MAX_WEAPONSLOTS]
Definition weapon.qh:17
void WeaponStats_LogKill(float awep, float abot, float vwep, float vbot)
void WeaponStats_LogDamage(float awep, float abot, float vwep, float vbot, float damage)
#define ATTACK_FINISHED_FOR(ent, w, slot)
Weapon m_weapon
Definition wepent.qh:26
float default_player_alpha
Definition world.qh:72