vkQuake2 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 = 0;
177  int damagePerCell;
178  int pa_te_type;
179  int power = 0;
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  }
204  else
205  return 0;
206 
207  if (power_armor_type == POWER_ARMOR_NONE)
208  return 0;
209  if (!power)
210  return 0;
211 
212  if (power_armor_type == POWER_ARMOR_SCREEN)
213  {
214  vec3_t vec;
215  float dot;
216  vec3_t forward;
217 
218  // only works if damage point is in front
219  AngleVectors (ent->s.angles, forward, NULL, NULL);
220  VectorSubtract (point, ent->s.origin, vec);
221  VectorNormalize (vec);
222  dot = DotProduct (vec, forward);
223  if (dot <= 0.3)
224  return 0;
225 
226  damagePerCell = 1;
227  pa_te_type = TE_SCREEN_SPARKS;
228  damage = damage / 3;
229  }
230  else
231  {
232  damagePerCell = 2;
233  pa_te_type = TE_SHIELD_SPARKS;
234  damage = (2 * damage) / 3;
235  }
236 
237  save = power * damagePerCell;
238  if (!save)
239  return 0;
240  if (save > damage)
241  save = damage;
242 
243  SpawnDamage (pa_te_type, point, normal, save);
244  ent->powerarmor_time = level.time + 0.2;
245 
246  power_used = save / damagePerCell;
247 
248  if (client)
249  client->pers.inventory[index] -= power_used;
250  else
251  ent->monsterinfo.power_armor_power -= power_used;
252  return save;
253 }
254 
255 static int CheckArmor (edict_t *ent, vec3_t point, vec3_t normal, int damage, int te_sparks, int dflags)
256 {
257  gclient_t *client;
258  int save;
259  int index;
260  gitem_t *armor;
261 
262  if (!damage)
263  return 0;
264 
265  client = ent->client;
266 
267  if (!client)
268  return 0;
269 
270  if (dflags & DAMAGE_NO_ARMOR)
271  return 0;
272 
273  index = ArmorIndex (ent);
274  if (!index)
275  return 0;
276 
277  armor = GetItemByIndex (index);
278 
279  if (dflags & DAMAGE_ENERGY)
280  save = ceil(((gitem_armor_t *)armor->info)->energy_protection*damage);
281  else
282  save = ceil(((gitem_armor_t *)armor->info)->normal_protection*damage);
283  if (save >= client->pers.inventory[index])
284  save = client->pers.inventory[index];
285 
286  if (!save)
287  return 0;
288 
289  client->pers.inventory[index] -= save;
290  SpawnDamage (te_sparks, point, normal, save);
291 
292  return save;
293 }
294 
295 void M_ReactToDamage (edict_t *targ, edict_t *attacker)
296 {
297  if (!(attacker->client) && !(attacker->svflags & SVF_MONSTER))
298  return;
299 
300  if (attacker == targ || attacker == targ->enemy)
301  return;
302 
303  // if we are a good guy monster and our attacker is a player
304  // or another good guy, do not get mad at them
305  if (targ->monsterinfo.aiflags & AI_GOOD_GUY)
306  {
307  if (attacker->client || (attacker->monsterinfo.aiflags & AI_GOOD_GUY))
308  return;
309  }
310 
311  // we now know that we are not both good guys
312 
313  // if attacker is a client, get mad at them because he's good and we're not
314  if (attacker->client)
315  {
317 
318  // this can only happen in coop (both new and old enemies are clients)
319  // only switch if can't see the current enemy
320  if (targ->enemy && targ->enemy->client)
321  {
322  if (visible(targ, targ->enemy))
323  {
324  targ->oldenemy = attacker;
325  return;
326  }
327  targ->oldenemy = targ->enemy;
328  }
329  targ->enemy = attacker;
330  if (!(targ->monsterinfo.aiflags & AI_DUCKED))
331  FoundTarget (targ);
332  return;
333  }
334 
335  // it's the same base (walk/swim/fly) type and a different classname and it's not a tank
336  // (they spray too much), get mad at them
337  if (((targ->flags & (FL_FLY|FL_SWIM)) == (attacker->flags & (FL_FLY|FL_SWIM))) &&
338  (strcmp (targ->classname, attacker->classname) != 0) &&
339  (strcmp(attacker->classname, "monster_tank") != 0) &&
340  (strcmp(attacker->classname, "monster_supertank") != 0) &&
341  (strcmp(attacker->classname, "monster_makron") != 0) &&
342  (strcmp(attacker->classname, "monster_jorg") != 0) )
343  {
344  if (targ->enemy && targ->enemy->client)
345  targ->oldenemy = targ->enemy;
346  targ->enemy = attacker;
347  if (!(targ->monsterinfo.aiflags & AI_DUCKED))
348  FoundTarget (targ);
349  }
350  // if they *meant* to shoot us, then shoot back
351  else if (attacker->enemy == targ)
352  {
353  if (targ->enemy && targ->enemy->client)
354  targ->oldenemy = targ->enemy;
355  targ->enemy = attacker;
356  if (!(targ->monsterinfo.aiflags & AI_DUCKED))
357  FoundTarget (targ);
358  }
359  // otherwise get mad at whoever they are mad at (help our buddy) unless it is us!
360  else if (attacker->enemy && attacker->enemy != targ)
361  {
362  if (targ->enemy && targ->enemy->client)
363  targ->oldenemy = targ->enemy;
364  targ->enemy = attacker->enemy;
365  if (!(targ->monsterinfo.aiflags & AI_DUCKED))
366  FoundTarget (targ);
367  }
368 }
369 
371 {
372  //FIXME make the next line real and uncomment this block
373  // if ((ability to damage a teammate == OFF) && (targ's team == attacker's team))
374  return false;
375 }
376 
377 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)
378 {
379  gclient_t *client;
380  int take;
381  int save;
382  int asave;
383  int psave;
384  int te_sparks;
385 
386  if (!targ->takedamage)
387  return;
388 
389  // friendly fire avoidance
390  // if enabled you can't hurt teammates (but you can hurt yourself)
391  // knockback still occurs
392  if ((targ != attacker) && ((deathmatch->value && ((int)(dmflags->value) & (DF_MODELTEAMS | DF_SKINTEAMS))) || coop->value))
393  {
394  if (OnSameTeam (targ, attacker))
395  {
396  if ((int)(dmflags->value) & DF_NO_FRIENDLY_FIRE)
397  damage = 0;
398  else
399  mod |= MOD_FRIENDLY_FIRE;
400  }
401  }
402  meansOfDeath = mod;
403 
404  // easy mode takes half damage
405  if (skill->value == 0 && deathmatch->value == 0 && targ->client)
406  {
407  damage *= 0.5;
408  if (!damage)
409  damage = 1;
410  }
411 
412  client = targ->client;
413 
414  if (dflags & DAMAGE_BULLET)
415  te_sparks = TE_BULLET_SPARKS;
416  else
417  te_sparks = TE_SPARKS;
418 
419  VectorNormalize(dir);
420 
421 // bonus damage for suprising a monster
422  if (!(dflags & DAMAGE_RADIUS) && (targ->svflags & SVF_MONSTER) && (attacker->client) && (!targ->enemy) && (targ->health > 0))
423  damage *= 2;
424 
425  if (targ->flags & FL_NO_KNOCKBACK)
426  knockback = 0;
427 
428 // figure momentum add
429  if (!(dflags & DAMAGE_NO_KNOCKBACK))
430  {
431  if ((knockback) && (targ->movetype != MOVETYPE_NONE) && (targ->movetype != MOVETYPE_BOUNCE) && (targ->movetype != MOVETYPE_PUSH) && (targ->movetype != MOVETYPE_STOP))
432  {
433  vec3_t kvel;
434  float mass;
435 
436  if (targ->mass < 50)
437  mass = 50;
438  else
439  mass = targ->mass;
440 
441  if (targ->client && attacker == targ)
442  VectorScale (dir, 1600.0 * (float)knockback / mass, kvel); // the rocket jump hack...
443  else
444  VectorScale (dir, 500.0 * (float)knockback / mass, kvel);
445 
446  VectorAdd (targ->velocity, kvel, targ->velocity);
447  }
448  }
449 
450  take = damage;
451  save = 0;
452 
453  // check for godmode
454  if ( (targ->flags & FL_GODMODE) && !(dflags & DAMAGE_NO_PROTECTION) )
455  {
456  take = 0;
457  save = damage;
458  SpawnDamage (te_sparks, point, normal, save);
459  }
460 
461  // check for invincibility
462  if ((client && client->invincible_framenum > level.framenum ) && !(dflags & DAMAGE_NO_PROTECTION))
463  {
464  if (targ->pain_debounce_time < level.time)
465  {
466  gi.sound(targ, CHAN_ITEM, gi.soundindex("items/protect4.wav"), 1, ATTN_NORM, 0);
467  targ->pain_debounce_time = level.time + 2;
468  }
469  take = 0;
470  save = damage;
471  }
472 
473  psave = CheckPowerArmor (targ, point, normal, take, dflags);
474  take -= psave;
475 
476  asave = CheckArmor (targ, point, normal, take, te_sparks, dflags);
477  take -= asave;
478 
479  //treat cheat/powerup savings the same as armor
480  asave += save;
481 
482  // team damage avoidance
483  if (!(dflags & DAMAGE_NO_PROTECTION) && CheckTeamDamage (targ, attacker))
484  return;
485 
486 // do the damage
487  if (take)
488  {
489  if ((targ->svflags & SVF_MONSTER) || (client))
490  SpawnDamage (TE_BLOOD, point, normal, take);
491  else
492  SpawnDamage (te_sparks, point, normal, take);
493 
494 
495  targ->health = targ->health - take;
496 
497  if (targ->health <= 0)
498  {
499  if ((targ->svflags & SVF_MONSTER) || (client))
500  targ->flags |= FL_NO_KNOCKBACK;
501  Killed (targ, inflictor, attacker, take, point);
502  return;
503  }
504  }
505 
506  if (targ->svflags & SVF_MONSTER)
507  {
508  M_ReactToDamage (targ, attacker);
509  if (!(targ->monsterinfo.aiflags & AI_DUCKED) && (take))
510  {
511  targ->pain (targ, attacker, knockback, take);
512  // nightmare mode monsters don't go into pain frames often
513  if (skill->value == 3)
514  targ->pain_debounce_time = level.time + 5;
515  }
516  }
517  else if (client)
518  {
519  if (!(targ->flags & FL_GODMODE) && (take))
520  targ->pain (targ, attacker, knockback, take);
521  }
522  else if (take)
523  {
524  if (targ->pain)
525  targ->pain (targ, attacker, knockback, take);
526  }
527 
528  // add to the damage inflicted on a player this frame
529  // the total will be turned into screen blends and view angle kicks
530  // at the end of the frame
531  if (client)
532  {
533  client->damage_parmor += psave;
534  client->damage_armor += asave;
535  client->damage_blood += take;
536  client->damage_knockback += knockback;
537  VectorCopy (point, client->damage_from);
538  }
539 }
540 
541 
542 /*
543 ============
544 T_RadiusDamage
545 ============
546 */
547 void T_RadiusDamage (edict_t *inflictor, edict_t *attacker, float damage, edict_t *ignore, float radius, int mod)
548 {
549  float points;
550  edict_t *ent = NULL;
551  vec3_t v;
552  vec3_t dir;
553 
554  while ((ent = findradius(ent, inflictor->s.origin, radius)) != NULL)
555  {
556  if (ent == ignore)
557  continue;
558  if (!ent->takedamage)
559  continue;
560 
561  VectorAdd (ent->mins, ent->maxs, v);
562  VectorMA (ent->s.origin, 0.5, v, v);
563  VectorSubtract (inflictor->s.origin, v, v);
564  points = damage - 0.5 * VectorLength (v);
565  if (ent == attacker)
566  points = points * 0.5;
567  if (points > 0)
568  {
569  if (CanDamage (ent, inflictor))
570  {
571  VectorSubtract (ent->s.origin, inflictor->s.origin, dir);
572  T_Damage (ent, inflictor, attacker, dir, inflictor->s.origin, vec3_origin, (int)points, (int)points, DAMAGE_RADIUS, mod);
573  }
574  }
575  }
576 }
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:970
gclient_s::damage_from
vec3_t damage_from
Definition: g_local.h:915
deathmatch
cvar_t * deathmatch
Definition: g_main.c:35
DEAD_DEAD
#define DEAD_DEAD
Definition: g_local.h:115
TE_SHIELD_SPARKS
@ TE_SHIELD_SPARKS
Definition: q_shared.h:924
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:457
VectorSubtract
#define VectorSubtract(a, b, c)
Definition: q_shared.h:163
CHAN_ITEM
#define CHAN_ITEM
Definition: q_shared.h:986
edict_s::absmax
vec3_t absmax
Definition: g_local.h:991
AI_GOOD_GUY
#define AI_GOOD_GUY
Definition: g_local.h:137
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:912
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:193
entity_state_s::origin
vec3_t origin
Definition: q_shared.h:1149
DAMAGE_ENERGY
#define DAMAGE_ENERGY
Definition: g_local.h:665
ITEM_INDEX
#define ITEM_INDEX(x)
Definition: g_local.h:616
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:63
DAMAGE_RADIUS
#define DAMAGE_RADIUS
Definition: g_local.h:663
edict_s::oldenemy
edict_t * oldenemy
Definition: g_local.h:1077
trace_t
Definition: q_shared.h:453
MOVETYPE_PUSH
@ MOVETYPE_PUSH
Definition: g_local.h:192
edict_s::client
struct gclient_s * client
Definition: g_local.h:971
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:70
edict_s::mins
vec3_t mins
Definition: g_local.h:990
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:995
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:377
edict_s::movetype
int movetype
Definition: g_local.h:1001
client_persistant_t::inventory
int inventory[MAX_ITEMS]
Definition: g_local.h:848
DAMAGE_NO_KNOCKBACK
#define DAMAGE_NO_KNOCKBACK
Definition: g_local.h:666
FL_SWIM
#define FL_SWIM
Definition: g_local.h:60
gclient_s::pers
client_persistant_t pers
Definition: g_local.h:890
MASK_SOLID
#define MASK_SOLID
Definition: q_shared.h:395
client_respawn_t::score
int score
Definition: g_local.h:875
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:160
edict_s::svflags
int svflags
Definition: g_local.h:989
DAMAGE_BULLET
#define DAMAGE_BULLET
Definition: g_local.h:667
DAMAGE_NO_PROTECTION
#define DAMAGE_NO_PROTECTION
Definition: g_local.h:668
gclient_s::damage_armor
int damage_armor
Definition: g_local.h:911
edict_s::classname
char * classname
Definition: g_local.h:1011
edict_s
Definition: g_local.h:968
edict_s::mass
int mass
Definition: g_local.h:1032
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:190
DF_SKINTEAMS
#define DF_SKINTEAMS
Definition: q_shared.h:1030
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:914
VectorLength
vec_t VectorLength(vec3_t v)
Definition: q_shared.c:762
FL_GODMODE
#define FL_GODMODE
Definition: g_local.h:63
edict_s::owner
edict_t * owner
Definition: g_local.h:994
TE_SPARKS
@ TE_SPARKS
Definition: q_shared.h:920
edict_s::deadflag
int deadflag
Definition: g_local.h:1060
DotProduct
#define DotProduct(x, y)
Definition: q_shared.h:162
OnSameTeam
qboolean OnSameTeam(edict_t *ent1, edict_t *ent2)
Definition: g_cmds.c:49
gitem_armor_t
Definition: g_local.h:205
cvar_s::value
float value
Definition: q_shared.h:331
CheckTeamDamage
qboolean CheckTeamDamage(edict_t *targ, edict_t *attacker)
Definition: g_combat.c:370
VectorNormalize
vec_t VectorNormalize(vec3_t v)
Definition: q_shared.c:681
NULL
#define NULL
Definition: q_shared.h:67
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:255
monsterinfo_t::aiflags
int aiflags
Definition: g_local.h:421
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:1048
TE_SCREEN_SPARKS
@ TE_SCREEN_SPARKS
Definition: q_shared.h:923
edict_s::velocity
vec3_t velocity
Definition: g_local.h:1030
VectorAdd
#define VectorAdd(a, b, c)
Definition: q_shared.h:164
svc_temp_entity
@ svc_temp_entity
Definition: qcommon.h:227
VectorCopy
#define VectorCopy(a, b)
Definition: q_shared.h:165
coop
cvar_t * coop
Definition: g_main.c:36
edict_s::pain_debounce_time
float pain_debounce_time
Definition: g_local.h:1052
AI_SOUND_TARGET
#define AI_SOUND_TARGET
Definition: g_local.h:131
edict_s::monsterinfo
monsterinfo_t monsterinfo
Definition: g_local.h:1114
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:295
monsterinfo_t::power_armor_power
int power_armor_power
Definition: g_local.h:449
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:1068
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:1002
gclient_s::invincible_framenum
float invincible_framenum
Definition: g_local.h:946
monsterinfo_t::power_armor_type
int power_armor_type
Definition: g_local.h:448
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:990
GetItemByIndex
gitem_t * GetItemByIndex(int index)
Definition: g_items.c:62
trace_t::ent
struct edict_s * ent
Definition: q_shared.h:462
FL_FLY
#define FL_FLY
Definition: g_local.h:59
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:1046
MOVETYPE_BOUNCE
@ MOVETYPE_BOUNCE
Definition: g_local.h:200
DF_MODELTEAMS
#define DF_MODELTEAMS
Definition: q_shared.h:1031
gclient_s::damage_parmor
int damage_parmor
Definition: g_local.h:912
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:664
points
GLdouble GLdouble GLint GLint const GLdouble * points
Definition: qgl_win.c:225
gclient_s
Definition: g_local.h:883
edict_s::enemy
edict_t * enemy
Definition: g_local.h:1076
AI_DUCKED
#define AI_DUCKED
Definition: g_local.h:140
entity_state_s::angles
vec3_t angles
Definition: q_shared.h:1150
edict_s::die
void(* die)(edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
Definition: g_local.h:1049
MULTICAST_PVS
@ MULTICAST_PVS
Definition: q_shared.h:118
TE_BULLET_SPARKS
@ TE_BULLET_SPARKS
Definition: q_shared.h:925
vec3_t
vec_t vec3_t[3]
Definition: q_shared.h:134
edict_s::absmin
vec3_t absmin
Definition: g_local.h:991
POWER_ARMOR_NONE
#define POWER_ARMOR_NONE
Definition: g_local.h:159
edict_s::powerarmor_time
float powerarmor_time
Definition: g_local.h:1063
MOD_FRIENDLY_FIRE
#define MOD_FRIENDLY_FIRE
Definition: g_local.h:503
gitem_s::info
void * info
Definition: g_local.h:259
DF_NO_FRIENDLY_FIRE
#define DF_NO_FRIENDLY_FIRE
Definition: q_shared.h:1032
gclient_s::resp
client_respawn_t resp
Definition: g_local.h:891
g_local.h
gclient_s::damage_blood
int damage_blood
Definition: g_local.h:913
T_RadiusDamage
void T_RadiusDamage(edict_t *inflictor, edict_t *attacker, float damage, edict_t *ignore, float radius, int mod)
Definition: g_combat.c:547
edict_s::health
int health
Definition: g_local.h:1057
gitem_s
Definition: g_local.h:236