icculus quake2 doxygen  1.0 dev
g_combat.c
Go to the documentation of this file.
1 /*
2 Copyright (C) 1997-2001 Id Software, Inc.
3 
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8 
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 
13 See the GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 
19 */
20 // g_combat.c
21 
22 #include "g_local.h"
23 
24 /*
25 ============
26 CanDamage
27 
28 Returns true if the inflictor can directly damage the target. Used for
29 explosions and melee attacks.
30 ============
31 */
32 qboolean CanDamage (edict_t *targ, edict_t *inflictor)
33 {
34  vec3_t dest;
35  trace_t trace;
36 
37 // bmodels need special checking because their origin is 0,0,0
38  if (targ->movetype == MOVETYPE_PUSH)
39  {
40  VectorAdd (targ->absmin, targ->absmax, dest);
41  VectorScale (dest, 0.5, dest);
42  trace = gi.trace (inflictor->s.origin, vec3_origin, vec3_origin, dest, inflictor, MASK_SOLID);
43  if (trace.fraction == 1.0)
44  return true;
45  if (trace.ent == targ)
46  return true;
47  return false;
48  }
49 
50  trace = gi.trace (inflictor->s.origin, vec3_origin, vec3_origin, targ->s.origin, inflictor, MASK_SOLID);
51  if (trace.fraction == 1.0)
52  return true;
53 
54  VectorCopy (targ->s.origin, dest);
55  dest[0] += 15.0;
56  dest[1] += 15.0;
57  trace = gi.trace (inflictor->s.origin, vec3_origin, vec3_origin, dest, inflictor, MASK_SOLID);
58  if (trace.fraction == 1.0)
59  return true;
60 
61  VectorCopy (targ->s.origin, dest);
62  dest[0] += 15.0;
63  dest[1] -= 15.0;
64  trace = gi.trace (inflictor->s.origin, vec3_origin, vec3_origin, dest, inflictor, MASK_SOLID);
65  if (trace.fraction == 1.0)
66  return true;
67 
68  VectorCopy (targ->s.origin, dest);
69  dest[0] -= 15.0;
70  dest[1] += 15.0;
71  trace = gi.trace (inflictor->s.origin, vec3_origin, vec3_origin, dest, inflictor, MASK_SOLID);
72  if (trace.fraction == 1.0)
73  return true;
74 
75  VectorCopy (targ->s.origin, dest);
76  dest[0] -= 15.0;
77  dest[1] -= 15.0;
78  trace = gi.trace (inflictor->s.origin, vec3_origin, vec3_origin, dest, inflictor, MASK_SOLID);
79  if (trace.fraction == 1.0)
80  return true;
81 
82 
83  return false;
84 }
85 
86 
87 /*
88 ============
89 Killed
90 ============
91 */
92 void Killed (edict_t *targ, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
93 {
94  if (targ->health < -999)
95  targ->health = -999;
96 
97  targ->enemy = attacker;
98 
99  if ((targ->svflags & SVF_MONSTER) && (targ->deadflag != DEAD_DEAD))
100  {
101 // targ->svflags |= SVF_DEADMONSTER; // now treat as a different content type
102  if (!(targ->monsterinfo.aiflags & AI_GOOD_GUY))
103  {
104  level.killed_monsters++;
105  if (coop->value && attacker->client)
106  attacker->client->resp.score++;
107  // medics won't heal monsters that they kill themselves
108  if (strcmp(attacker->classname, "monster_medic") == 0)
109  targ->owner = attacker;
110  }
111  }
112 
113  if (targ->movetype == MOVETYPE_PUSH || targ->movetype == MOVETYPE_STOP || targ->movetype == MOVETYPE_NONE)
114  { // doors, triggers, etc
115  targ->die (targ, inflictor, attacker, damage, point);
116  return;
117  }
118 
119  if ((targ->svflags & SVF_MONSTER) && (targ->deadflag != DEAD_DEAD))
120  {
121  targ->touch = NULL;
122  monster_death_use (targ);
123  }
124 
125  targ->die (targ, inflictor, attacker, damage, point);
126 }
127 
128 
129 /*
130 ================
131 SpawnDamage
132 ================
133 */
134 void SpawnDamage (int type, vec3_t origin, vec3_t normal, int damage)
135 {
136  if (damage > 255)
137  damage = 255;
139  gi.WriteByte (type);
140 // gi.WriteByte (damage);
141  gi.WritePosition (origin);
142  gi.WriteDir (normal);
143  gi.multicast (origin, MULTICAST_PVS);
144 }
145 
146 
147 /*
148 ============
149 T_Damage
150 
151 targ entity that is being damaged
152 inflictor entity that is causing the damage
153 attacker entity that caused the inflictor to damage targ
154  example: targ=monster, inflictor=rocket, attacker=player
155 
156 dir direction of the attack
157 point point at which the damage is being inflicted
158 normal normal vector from that point
159 damage amount of damage being inflicted
160 knockback force to be applied against targ as a result of the damage
161 
162 dflags these flags are used to control how T_Damage works
163  DAMAGE_RADIUS damage was indirect (from a nearby explosion)
164  DAMAGE_NO_ARMOR armor does not protect from this damage
165  DAMAGE_ENERGY damage is from an energy based weapon
166  DAMAGE_NO_KNOCKBACK do not affect velocity, just view angles
167  DAMAGE_BULLET damage is from a bullet (used for ricochets)
168  DAMAGE_NO_PROTECTION kills godmode, armor, everything
169 ============
170 */
171 static int CheckPowerArmor (edict_t *ent, vec3_t point, vec3_t normal, int damage, int dflags)
172 {
173  gclient_t *client;
174  int save;
175  int power_armor_type;
176  int index;
177  int damagePerCell;
178  int pa_te_type;
179  int power;
180  int power_used;
181 
182  if (!damage)
183  return 0;
184 
185  client = ent->client;
186 
187  if (dflags & DAMAGE_NO_ARMOR)
188  return 0;
189 
190  if (client)
191  {
192  power_armor_type = PowerArmorType (ent);
193  if (power_armor_type != POWER_ARMOR_NONE)
194  {
195  index = ITEM_INDEX(FindItem("Cells"));
196  power = client->pers.inventory[index];
197  }
198  }
199  else if (ent->svflags & SVF_MONSTER)
200  {
201  power_armor_type = ent->monsterinfo.power_armor_type;
202  power = ent->monsterinfo.power_armor_power;
203  index = 0;
204  }
205  else
206  return 0;
207 
208  if (power_armor_type == POWER_ARMOR_NONE)
209  return 0;
210  if (!power)
211  return 0;
212 
213  if (power_armor_type == POWER_ARMOR_SCREEN)
214  {
215  vec3_t vec;
216  float dot;
217  vec3_t forward;
218 
219  // only works if damage point is in front
220  AngleVectors (ent->s.angles, forward, NULL, NULL);
221  VectorSubtract (point, ent->s.origin, vec);
222  VectorNormalize (vec);
223  dot = DotProduct (vec, forward);
224  if (dot <= 0.3)
225  return 0;
226 
227  damagePerCell = 1;
228  pa_te_type = TE_SCREEN_SPARKS;
229  damage = damage / 3;
230  }
231  else
232  {
233  damagePerCell = 2;
234  pa_te_type = TE_SHIELD_SPARKS;
235  damage = (2 * damage) / 3;
236  }
237 
238  save = power * damagePerCell;
239  if (!save)
240  return 0;
241  if (save > damage)
242  save = damage;
243 
244  SpawnDamage (pa_te_type, point, normal, save);
245  ent->powerarmor_time = level.time + 0.2;
246 
247  power_used = save / damagePerCell;
248 
249  if (client)
250  client->pers.inventory[index] -= power_used;
251  else
252  ent->monsterinfo.power_armor_power -= power_used;
253  return save;
254 }
255 
256 static int CheckArmor (edict_t *ent, vec3_t point, vec3_t normal, int damage, int te_sparks, int dflags)
257 {
258  gclient_t *client;
259  int save;
260  int index;
261  gitem_t *armor;
262 
263  if (!damage)
264  return 0;
265 
266  client = ent->client;
267 
268  if (!client)
269  return 0;
270 
271  if (dflags & DAMAGE_NO_ARMOR)
272  return 0;
273 
274  index = ArmorIndex (ent);
275  if (!index)
276  return 0;
277 
278  armor = GetItemByIndex (index);
279 
280  if (dflags & DAMAGE_ENERGY)
281  save = ceil(((gitem_armor_t *)armor->info)->energy_protection*damage);
282  else
283  save = ceil(((gitem_armor_t *)armor->info)->normal_protection*damage);
284  if (save >= client->pers.inventory[index])
285  save = client->pers.inventory[index];
286 
287  if (!save)
288  return 0;
289 
290  client->pers.inventory[index] -= save;
291  SpawnDamage (te_sparks, point, normal, save);
292 
293  return save;
294 }
295 
296 void M_ReactToDamage (edict_t *targ, edict_t *attacker)
297 {
298  if (!(attacker->client) && !(attacker->svflags & SVF_MONSTER))
299  return;
300 
301  if (attacker == targ || attacker == targ->enemy)
302  return;
303 
304  // if we are a good guy monster and our attacker is a player
305  // or another good guy, do not get mad at them
306  if (targ->monsterinfo.aiflags & AI_GOOD_GUY)
307  {
308  if (attacker->client || (attacker->monsterinfo.aiflags & AI_GOOD_GUY))
309  return;
310  }
311 
312  // we now know that we are not both good guys
313 
314  // if attacker is a client, get mad at them because he's good and we're not
315  if (attacker->client)
316  {
318 
319  // this can only happen in coop (both new and old enemies are clients)
320  // only switch if can't see the current enemy
321  if (targ->enemy && targ->enemy->client)
322  {
323  if (visible(targ, targ->enemy))
324  {
325  targ->oldenemy = attacker;
326  return;
327  }
328  targ->oldenemy = targ->enemy;
329  }
330  targ->enemy = attacker;
331  if (!(targ->monsterinfo.aiflags & AI_DUCKED))
332  FoundTarget (targ);
333  return;
334  }
335 
336  // it's the same base (walk/swim/fly) type and a different classname and it's not a tank
337  // (they spray too much), get mad at them
338  if (((targ->flags & (FL_FLY|FL_SWIM)) == (attacker->flags & (FL_FLY|FL_SWIM))) &&
339  (strcmp (targ->classname, attacker->classname) != 0) &&
340  (strcmp(attacker->classname, "monster_tank") != 0) &&
341  (strcmp(attacker->classname, "monster_supertank") != 0) &&
342  (strcmp(attacker->classname, "monster_makron") != 0) &&
343  (strcmp(attacker->classname, "monster_jorg") != 0) )
344  {
345  if (targ->enemy && targ->enemy->client)
346  targ->oldenemy = targ->enemy;
347  targ->enemy = attacker;
348  if (!(targ->monsterinfo.aiflags & AI_DUCKED))
349  FoundTarget (targ);
350  }
351  // if they *meant* to shoot us, then shoot back
352  else if (attacker->enemy == targ)
353  {
354  if (targ->enemy && targ->enemy->client)
355  targ->oldenemy = targ->enemy;
356  targ->enemy = attacker;
357  if (!(targ->monsterinfo.aiflags & AI_DUCKED))
358  FoundTarget (targ);
359  }
360  // otherwise get mad at whoever they are mad at (help our buddy) unless it is us!
361  else if (attacker->enemy && attacker->enemy != targ)
362  {
363  if (targ->enemy && targ->enemy->client)
364  targ->oldenemy = targ->enemy;
365  targ->enemy = attacker->enemy;
366  if (!(targ->monsterinfo.aiflags & AI_DUCKED))
367  FoundTarget (targ);
368  }
369 }
370 
372 {
373  //FIXME make the next line real and uncomment this block
374  // if ((ability to damage a teammate == OFF) && (targ's team == attacker's team))
375  return false;
376 }
377 
378 void T_Damage (edict_t *targ, edict_t *inflictor, edict_t *attacker, vec3_t dir, vec3_t point, vec3_t normal, int damage, int knockback, int dflags, int mod)
379 {
380  gclient_t *client;
381  int take;
382  int save;
383  int asave;
384  int psave;
385  int te_sparks;
386 
387  if (!targ->takedamage)
388  return;
389 
390  // friendly fire avoidance
391  // if enabled you can't hurt teammates (but you can hurt yourself)
392  // knockback still occurs
393  if ((targ != attacker) && ((deathmatch->value && ((int)(dmflags->value) & (DF_MODELTEAMS | DF_SKINTEAMS))) || coop->value))
394  {
395  if (OnSameTeam (targ, attacker))
396  {
397  if ((int)(dmflags->value) & DF_NO_FRIENDLY_FIRE)
398  damage = 0;
399  else
400  mod |= MOD_FRIENDLY_FIRE;
401  }
402  }
403  meansOfDeath = mod;
404 
405  // easy mode takes half damage
406  if (skill->value == 0 && deathmatch->value == 0 && targ->client)
407  {
408  damage *= 0.5;
409  if (!damage)
410  damage = 1;
411  }
412 
413  client = targ->client;
414 
415  if (dflags & DAMAGE_BULLET)
416  te_sparks = TE_BULLET_SPARKS;
417  else
418  te_sparks = TE_SPARKS;
419 
420  VectorNormalize(dir);
421 
422 // bonus damage for suprising a monster
423  if (!(dflags & DAMAGE_RADIUS) && (targ->svflags & SVF_MONSTER) && (attacker->client) && (!targ->enemy) && (targ->health > 0))
424  damage *= 2;
425 
426  if (targ->flags & FL_NO_KNOCKBACK)
427  knockback = 0;
428 
429 // figure momentum add
430  if (!(dflags & DAMAGE_NO_KNOCKBACK))
431  {
432  if ((knockback) && (targ->movetype != MOVETYPE_NONE) && (targ->movetype != MOVETYPE_BOUNCE) && (targ->movetype != MOVETYPE_PUSH) && (targ->movetype != MOVETYPE_STOP))
433  {
434  vec3_t kvel;
435  float mass;
436 
437  if (targ->mass < 50)
438  mass = 50;
439  else
440  mass = targ->mass;
441 
442  if (targ->client && attacker == targ)
443  VectorScale (dir, 1600.0 * (float)knockback / mass, kvel); // the rocket jump hack...
444  else
445  VectorScale (dir, 500.0 * (float)knockback / mass, kvel);
446 
447  VectorAdd (targ->velocity, kvel, targ->velocity);
448  }
449  }
450 
451  take = damage;
452  save = 0;
453 
454  // check for godmode
455  if ( (targ->flags & FL_GODMODE) && !(dflags & DAMAGE_NO_PROTECTION) )
456  {
457  take = 0;
458  save = damage;
459  SpawnDamage (te_sparks, point, normal, save);
460  }
461 
462  // check for invincibility
463  if ((client && client->invincible_framenum > level.framenum ) && !(dflags & DAMAGE_NO_PROTECTION))
464  {
465  if (targ->pain_debounce_time < level.time)
466  {
467  gi.sound(targ, CHAN_ITEM, gi.soundindex("items/protect4.wav"), 1, ATTN_NORM, 0);
468  targ->pain_debounce_time = level.time + 2;
469  }
470  take = 0;
471  save = damage;
472  }
473 
474  psave = CheckPowerArmor (targ, point, normal, take, dflags);
475  take -= psave;
476 
477  asave = CheckArmor (targ, point, normal, take, te_sparks, dflags);
478  take -= asave;
479 
480  //treat cheat/powerup savings the same as armor
481  asave += save;
482 
483  // team damage avoidance
484  if (!(dflags & DAMAGE_NO_PROTECTION) && CheckTeamDamage (targ, attacker))
485  return;
486 
487 // do the damage
488  if (take)
489  {
490  if ((targ->svflags & SVF_MONSTER) || (client))
491  SpawnDamage (TE_BLOOD, point, normal, take);
492  else
493  SpawnDamage (te_sparks, point, normal, take);
494 
495 
496  targ->health = targ->health - take;
497 
498  if (targ->health <= 0)
499  {
500  if ((targ->svflags & SVF_MONSTER) || (client))
501  targ->flags |= FL_NO_KNOCKBACK;
502  Killed (targ, inflictor, attacker, take, point);
503  return;
504  }
505  }
506 
507  if (targ->svflags & SVF_MONSTER)
508  {
509  M_ReactToDamage (targ, attacker);
510  if (!(targ->monsterinfo.aiflags & AI_DUCKED) && (take))
511  {
512  targ->pain (targ, attacker, knockback, take);
513  // nightmare mode monsters don't go into pain frames often
514  if (skill->value == 3)
515  targ->pain_debounce_time = level.time + 5;
516  }
517  }
518  else if (client)
519  {
520  if (!(targ->flags & FL_GODMODE) && (take))
521  targ->pain (targ, attacker, knockback, take);
522  }
523  else if (take)
524  {
525  if (targ->pain)
526  targ->pain (targ, attacker, knockback, take);
527  }
528 
529  // add to the damage inflicted on a player this frame
530  // the total will be turned into screen blends and view angle kicks
531  // at the end of the frame
532  if (client)
533  {
534  client->damage_parmor += psave;
535  client->damage_armor += asave;
536  client->damage_blood += take;
537  client->damage_knockback += knockback;
538  VectorCopy (point, client->damage_from);
539  }
540 }
541 
542 
543 /*
544 ============
545 T_RadiusDamage
546 ============
547 */
548 void T_RadiusDamage (edict_t *inflictor, edict_t *attacker, float damage, edict_t *ignore, float radius, int mod)
549 {
550  float points;
551  edict_t *ent = NULL;
552  vec3_t v;
553  vec3_t dir;
554 
555  while ((ent = findradius(ent, inflictor->s.origin, radius)) != NULL)
556  {
557  if (ent == ignore)
558  continue;
559  if (!ent->takedamage)
560  continue;
561 
562  VectorAdd (ent->mins, ent->maxs, v);
563  VectorMA (ent->s.origin, 0.5, v, v);
564  VectorSubtract (inflictor->s.origin, v, v);
565  points = damage - 0.5 * VectorLength (v);
566  if (ent == attacker)
567  points = points * 0.5;
568  if (points > 0)
569  {
570  if (CanDamage (ent, inflictor))
571  {
572  VectorSubtract (ent->s.origin, inflictor->s.origin, dir);
573  T_Damage (ent, inflictor, attacker, dir, inflictor->s.origin, vec3_origin, (int)points, (int)points, DAMAGE_RADIUS, mod);
574  }
575  }
576  }
577 }
FindItem
gitem_t * FindItem(char *pickup_name)
Definition: g_items.c:100
gi
game_import_t gi
Definition: g_main.c:25
edict_s::s
entity_state_t s
Definition: g_local.h:964
gclient_s::damage_from
vec3_t damage_from
Definition: g_local.h:909
deathmatch
cvar_t * deathmatch
Definition: g_main.c:35
DEAD_DEAD
#define DEAD_DEAD
Definition: g_local.h:113
TE_SHIELD_SPARKS
@ TE_SHIELD_SPARKS
Definition: q_shared.h:948
game_import_t::trace
trace_t(* trace)(vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, edict_t *passent, int contentmask)
Definition: game.h:128
trace_t::fraction
float fraction
Definition: q_shared.h:453
VectorSubtract
#define VectorSubtract(a, b, c)
Definition: q_shared.h:156
CHAN_ITEM
#define CHAN_ITEM
Definition: q_shared.h:1010
edict_s::absmax
vec3_t absmax
Definition: g_local.h:985
AI_GOOD_GUY
#define AI_GOOD_GUY
Definition: g_local.h:135
game_import_t::WritePosition
void(* WritePosition)(vec3_t pos)
Definition: game.h:152
game_import_t::multicast
void(* multicast)(vec3_t origin, multicast_t to)
Definition: game.h:144
TE_BLOOD
@ TE_BLOOD
Definition: q_shared.h:936
v
GLdouble v
Definition: qgl_win.c:143
PowerArmorType
int PowerArmorType(edict_t *ent)
Definition: g_items.c:688
MOVETYPE_STOP
@ MOVETYPE_STOP
Definition: g_local.h:191
entity_state_s::origin
vec3_t origin
Definition: q_shared.h:1173
DAMAGE_ENERGY
#define DAMAGE_ENERGY
Definition: g_local.h:659
ITEM_INDEX
#define ITEM_INDEX(x)
Definition: g_local.h:610
monster_death_use
void monster_death_use(edict_t *self)
Definition: g_monster.c:511
VectorScale
void VectorScale(vec3_t in, vec_t scale, vec3_t out)
Definition: q_shared.c:782
qboolean
qboolean
Definition: q_shared.h:56
DAMAGE_RADIUS
#define DAMAGE_RADIUS
Definition: g_local.h:657
edict_s::oldenemy
edict_t * oldenemy
Definition: g_local.h:1071
trace_t
Definition: q_shared.h:449
MOVETYPE_PUSH
@ MOVETYPE_PUSH
Definition: g_local.h:190
edict_s::client
struct gclient_s * client
Definition: g_local.h:965
game_import_t::sound
void(* sound)(edict_t *ent, int channel, int soundindex, float volume, float attenuation, float timeofs)
Definition: game.h:109
FL_NO_KNOCKBACK
#define FL_NO_KNOCKBACK
Definition: g_local.h:68
edict_s::mins
vec3_t mins
Definition: g_local.h:984
meansOfDeath
int meansOfDeath
Definition: g_main.c:31
ArmorIndex
int ArmorIndex(edict_t *ent)
Definition: g_items.c:590
type
GLenum type
Definition: qgl_win.c:72
ATTN_NORM
#define ATTN_NORM
Definition: q_shared.h:1019
T_Damage
void T_Damage(edict_t *targ, edict_t *inflictor, edict_t *attacker, vec3_t dir, vec3_t point, vec3_t normal, int damage, int knockback, int dflags, int mod)
Definition: g_combat.c:378
edict_s::movetype
int movetype
Definition: g_local.h:995
client_persistant_t::inventory
int inventory[MAX_ITEMS]
Definition: g_local.h:842
DAMAGE_NO_KNOCKBACK
#define DAMAGE_NO_KNOCKBACK
Definition: g_local.h:660
FL_SWIM
#define FL_SWIM
Definition: g_local.h:58
gclient_s::pers
client_persistant_t pers
Definition: g_local.h:884
MASK_SOLID
#define MASK_SOLID
Definition: q_shared.h:391
client_respawn_t::score
int score
Definition: g_local.h:869
AngleVectors
void AngleVectors(vec3_t angles, vec3_t forward, vec3_t right, vec3_t up)
Definition: q_shared.c:93
POWER_ARMOR_SCREEN
#define POWER_ARMOR_SCREEN
Definition: g_local.h:158
edict_s::svflags
int svflags
Definition: g_local.h:983
DAMAGE_BULLET
#define DAMAGE_BULLET
Definition: g_local.h:661
DAMAGE_NO_PROTECTION
#define DAMAGE_NO_PROTECTION
Definition: g_local.h:662
gclient_s::damage_armor
int damage_armor
Definition: g_local.h:905
edict_s::classname
char * classname
Definition: g_local.h:1005
edict_s
Definition: g_local.h:962
edict_s::mass
int mass
Definition: g_local.h:1026
findradius
edict_t * findradius(edict_t *from, vec3_t org, float rad)
Definition: g_utils.c:78
MOVETYPE_NONE
@ MOVETYPE_NONE
Definition: g_local.h:188
DF_SKINTEAMS
#define DF_SKINTEAMS
Definition: q_shared.h:1054
game_import_t::soundindex
int(* soundindex)(char *name)
Definition: game.h:122
forward
static vec3_t forward
Definition: p_view.c:29
gclient_s::damage_knockback
int damage_knockback
Definition: g_local.h:908
VectorLength
vec_t VectorLength(vec3_t v)
Definition: q_shared.c:762
FL_GODMODE
#define FL_GODMODE
Definition: g_local.h:61
edict_s::owner
edict_t * owner
Definition: g_local.h:988
TE_SPARKS
@ TE_SPARKS
Definition: q_shared.h:944
edict_s::deadflag
int deadflag
Definition: g_local.h:1054
DotProduct
#define DotProduct(x, y)
Definition: q_shared.h:155
OnSameTeam
qboolean OnSameTeam(edict_t *ent1, edict_t *ent2)
Definition: g_cmds.c:49
gitem_armor_t
Definition: g_local.h:203
cvar_s::value
float value
Definition: q_shared.h:324
CheckTeamDamage
qboolean CheckTeamDamage(edict_t *targ, edict_t *attacker)
Definition: g_combat.c:371
VectorNormalize
vec_t VectorNormalize(vec3_t v)
Definition: q_shared.c:681
NULL
#define NULL
Definition: q_shared.h:60
FoundTarget
void FoundTarget(edict_t *self)
Definition: g_ai.c:347
CheckArmor
static int CheckArmor(edict_t *ent, vec3_t point, vec3_t normal, int damage, int te_sparks, int dflags)
Definition: g_combat.c:256
monsterinfo_t::aiflags
int aiflags
Definition: g_local.h:419
CanDamage
qboolean CanDamage(edict_t *targ, edict_t *inflictor)
Definition: g_combat.c:32
skill
cvar_t * skill
Definition: g_main.c:38
edict_s::pain
void(* pain)(edict_t *self, edict_t *other, float kick, int damage)
Definition: g_local.h:1042
TE_SCREEN_SPARKS
@ TE_SCREEN_SPARKS
Definition: q_shared.h:947
edict_s::velocity
vec3_t velocity
Definition: g_local.h:1024
VectorAdd
#define VectorAdd(a, b, c)
Definition: q_shared.h:157
svc_temp_entity
@ svc_temp_entity
Definition: qcommon.h:210
VectorCopy
#define VectorCopy(a, b)
Definition: q_shared.h:158
coop
cvar_t * coop
Definition: g_main.c:36
edict_s::pain_debounce_time
float pain_debounce_time
Definition: g_local.h:1046
AI_SOUND_TARGET
#define AI_SOUND_TARGET
Definition: g_local.h:129
edict_s::monsterinfo
monsterinfo_t monsterinfo
Definition: g_local.h:1108
visible
qboolean visible(edict_t *self, edict_t *other)
Definition: g_ai.c:287
vec3_origin
vec3_t vec3_origin
Definition: q_shared.c:24
M_ReactToDamage
void M_ReactToDamage(edict_t *targ, edict_t *attacker)
Definition: g_combat.c:296
monsterinfo_t::power_armor_power
int power_armor_power
Definition: g_local.h:447
game_import_t::WriteDir
void(* WriteDir)(vec3_t pos)
Definition: game.h:153
game_import_t::WriteByte
void(* WriteByte)(int c)
Definition: game.h:147
edict_s::takedamage
int takedamage
Definition: g_local.h:1062
level
GLint level
Definition: qgl_win.c:116
Killed
void Killed(edict_t *targ, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
Definition: g_combat.c:92
SpawnDamage
void SpawnDamage(int type, vec3_t origin, vec3_t normal, int damage)
Definition: g_combat.c:134
edict_s::flags
int flags
Definition: g_local.h:996
gclient_s::invincible_framenum
float invincible_framenum
Definition: g_local.h:940
monsterinfo_t::power_armor_type
int power_armor_type
Definition: g_local.h:446
VectorMA
void VectorMA(vec3_t veca, float scale, vec3_t vecb, vec3_t vecc)
Definition: q_shared.c:719
edict_s::maxs
vec3_t maxs
Definition: g_local.h:984
GetItemByIndex
gitem_t * GetItemByIndex(int index)
Definition: g_items.c:62
trace_t::ent
struct edict_s * ent
Definition: q_shared.h:458
FL_FLY
#define FL_FLY
Definition: g_local.h:57
SVF_MONSTER
#define SVF_MONSTER
Definition: game.h:29
edict_s::touch
void(* touch)(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
Definition: g_local.h:1040
MOVETYPE_BOUNCE
@ MOVETYPE_BOUNCE
Definition: g_local.h:198
DF_MODELTEAMS
#define DF_MODELTEAMS
Definition: q_shared.h:1055
gclient_s::damage_parmor
int damage_parmor
Definition: g_local.h:906
dmflags
cvar_t * dmflags
Definition: g_main.c:37
CheckPowerArmor
static int CheckPowerArmor(edict_t *ent, vec3_t point, vec3_t normal, int damage, int dflags)
Definition: g_combat.c:171
DAMAGE_NO_ARMOR
#define DAMAGE_NO_ARMOR
Definition: g_local.h:658
points
GLdouble GLdouble GLint GLint const GLdouble * points
Definition: qgl_win.c:225
gclient_s
Definition: g_local.h:877
edict_s::enemy
edict_t * enemy
Definition: g_local.h:1070
AI_DUCKED
#define AI_DUCKED
Definition: g_local.h:138
entity_state_s::angles
vec3_t angles
Definition: q_shared.h:1174
edict_s::die
void(* die)(edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
Definition: g_local.h:1043
MULTICAST_PVS
@ MULTICAST_PVS
Definition: q_shared.h:111
TE_BULLET_SPARKS
@ TE_BULLET_SPARKS
Definition: q_shared.h:949
vec3_t
vec_t vec3_t[3]
Definition: q_shared.h:127
edict_s::absmin
vec3_t absmin
Definition: g_local.h:985
POWER_ARMOR_NONE
#define POWER_ARMOR_NONE
Definition: g_local.h:157
edict_s::powerarmor_time
float powerarmor_time
Definition: g_local.h:1057
MOD_FRIENDLY_FIRE
#define MOD_FRIENDLY_FIRE
Definition: g_local.h:497
gitem_s::info
void * info
Definition: g_local.h:257
DF_NO_FRIENDLY_FIRE
#define DF_NO_FRIENDLY_FIRE
Definition: q_shared.h:1056
gclient_s::resp
client_respawn_t resp
Definition: g_local.h:885
g_local.h
gclient_s::damage_blood
int damage_blood
Definition: g_local.h:907
T_RadiusDamage
void T_RadiusDamage(edict_t *inflictor, edict_t *attacker, float damage, edict_t *ignore, float radius, int mod)
Definition: g_combat.c:548
edict_s::health
int health
Definition: g_local.h:1051
gitem_s
Definition: g_local.h:234