UFO: Alien Invasion
Loading...
Searching...
No Matches
g_utils.cpp
Go to the documentation of this file.
1
5
6/*
7All original material Copyright (C) 2002-2025 UFO: Alien Invasion.
8
9Original file from Quake 2 v3.21: quake2-2.31/game/g_utils.c
10Copyright (C) 1997-2001 Id Software, Inc.
11
12This program is free software; you can redistribute it and/or
13modify it under the terms of the GNU General Public License
14as published by the Free Software Foundation; either version 2
15of the License, or (at your option) any later version.
16
17This program is distributed in the hope that it will be useful,
18but WITHOUT ANY WARRANTY; without even the implied warranty of
19MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
20
21See the GNU General Public License for more details.
22
23You should have received a copy of the GNU General Public License
24along with this program; if not, write to the Free Software
25Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26
27*/
28
29#include "g_utils.h"
30#include <time.h>
31#include "g_client.h"
32#include "g_actor.h"
33#include "g_edicts.h"
34#include "g_trigger.h"
35
41void G_FreeEdict (Edict* ent)
42{
44
45 /* unlink from world */
46 gi.UnlinkEdict(ent);
47
48 ent->nativeReset();
49 ent->classname = "freed";
50 ent->inuse = false;
51}
52
60{
61 Edict* ent = nullptr;
62
63 while ((ent = G_EdictsGetNextInUse(ent))) {
64 if (type > ET_NULL && ent->type != type)
65 continue;
66 if (!VectorCompare(pos, ent->pos))
67 continue;
68
69 return ent;
70 }
71 /* nothing found at this pos */
72 return nullptr;
73}
74
81Edict* G_GetEdictFromPosExcluding (const pos3_t pos, const int n, ...)
82{
83 entity_type_t types[ET_MAX];
84 va_list ap;
85
86 assert(n > 0);
87 assert(n < sizeof(types));
88
89 va_start(ap, n);
90
91 for (int i = 0; i < n; i++) {
92 types[i] = (entity_type_t)va_arg(ap, int);
93 }
94
95 Edict* ent = nullptr;
96 while ((ent = G_EdictsGetNextInUse(ent))) {
97 int i;
98 for (i = 0; i < n; i++)
99 if (ent->type == types[i])
100 break;
101 if (i != n)
102 continue;
103 if (VectorCompare(pos, ent->pos))
104 return ent;
105 }
106 /* nothing found at this pos */
107 return nullptr;
108}
109
117bool G_UseEdict (Edict* ent, Edict* activator)
118{
119 if (!ent)
120 return false;
121
122 if (ent->groupMaster)
123 ent = ent->groupMaster;
124
125 bool status = true;
126 /* no use function assigned */
127 if (!ent->use) {
128 status = false;
129 } else if (!ent->use(ent, activator)) {
130 status = false;
131 }
132
133 Edict* chain = ent->groupChain;
134 while (chain) {
135 if (chain->use)
136 chain->use(chain, activator);
137 chain = chain->groupChain;
138 }
139
140 return status;
141}
142
148static const objDef_t* G_GetObjectForFiredef (const fireDef_t* fd)
149{
150 /* For each object ... */
151 for (int i = 0; i < gi.csi->numODs; i++) {
152 const objDef_t* od = &gi.csi->ods[i];
153 /* For each weapon-entry in the object ... */
154 for (int j = 0; j < od->numWeapons; j++) {
155 /* For each fire-definition in the weapon entry ... */
156 for (int k = 0; k < od->numFiredefs[j]; k++) {
157 const fireDef_t* csiFD = &od->fd[j][k];
158 if (csiFD == fd)
159 return od;
160 }
161 }
162 }
163
164 return nullptr;
165}
166
174{
175 const objDef_t* obj = G_GetObjectForFiredef(fd);
176 if (!obj)
177 return "unknown";
178 else
179 return obj->id;
180}
181
188Player* G_GetPlayerForTeam (int team)
189{
190 /* search corresponding player (even ai players) */
191 Player* p = nullptr;
192 while ((p = G_PlayerGetNextActiveHuman(p)))
193 if (p->getTeam() == team)
194 /* found player */
195 return p;
196
197 p = nullptr;
198 while ((p = G_PlayerGetNextActiveAI(p)))
199 if (p->getTeam() == team)
200 /* found player */
201 return p;
202
203 return nullptr;
204}
205
215void G_TakeDamage (Edict* ent, int damage)
216{
217 if (G_IsBreakable(ent) || G_IsActor(ent))
218 ent->HP = std::max(ent->HP - damage, 0);
219}
220
225static inline void G_TraceDraw (const Line& traceLine)
226{
227 if (g_drawtraces->integer)
228 G_EventParticleSpawn(PM_ALL, "fadeTracerDebug", TRACE_ALL_LEVELS, traceLine.start, traceLine.stop, vec3_origin);
229}
230
237bool G_TestLineWithEnts (const vec3_t start, const vec3_t end)
238{
239 const char* entList[MAX_EDICTS];
240 /* generate entity list */
241 G_GenerateEntList(entList);
242 G_TraceDraw(Line(start, end));
243 /* test for visibility */
244 return gi.TestLineWithEnt(start, end, TL_FLAG_NONE, entList);
245}
246
253bool G_TestLine (const vec3_t start, const vec3_t end)
254{
255 G_TraceDraw(Line(start, end));
256 return gi.TestLine(start, end, TL_FLAG_NONE);
257}
258
265trace_t G_Trace (const Line& trLine, const Edict* passent, int contentmask)
266{
267 static const AABB box;
268 G_TraceDraw(trLine);
269 return gi.Trace(trLine, box, passent, contentmask);
270}
271
275const char* G_GetPlayerName (int pnum)
276{
277 if (pnum >= game.sv_maxplayersperteam)
278 return "";
279 return game.players[pnum].pers.netname;
280}
281
289{
290 playermask_t pm = 0;
291 Edict* closeActor = nullptr;
292 while ((closeActor = G_FindRadius(closeActor, origin, radius))) {
293 if (!G_IsLivingActor(closeActor))
294 continue;
295 pm |= G_TeamToPM(closeActor->getTeam());
296 }
297 return pm;
298}
299
304void G_PrintStats (const char* format, ...)
305{
306 char buffer[512];
307 va_list argptr;
308
309 va_start(argptr, format);
310 Q_vsnprintf(buffer, sizeof(buffer), format, argptr);
311 va_end(argptr);
312
313 gi.DPrintf("[STATS] %s\n", buffer);
314 if (logstatsfile) {
315 char tbuf[32];
316 time_t aclock;
317
318 time(&aclock);
319 const struct tm* t = localtime(&aclock);
320
321 Com_sprintf(tbuf, sizeof(tbuf), "%4i/%02i/%02i %02i:%02i:%02i", t->tm_year + 1900,
322 t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
323
324 fprintf(logstatsfile, "[STATS] %s - %s\n", tbuf, buffer);
325 }
326}
327
336void G_PrintActorStats (const Edict* victim, const Edict* attacker, const fireDef_t* fd)
337{
338 char buffer[512];
339
340 if (attacker != nullptr && fd != nullptr) {
341 if (victim->getPlayerNum() != attacker->getPlayerNum()) {
342 const char* victimName = G_GetPlayerName(victim->getPlayerNum());
343 const char* attackerName = G_GetPlayerName(attacker->getPlayerNum());
344 if (victimName[0] == '\0') { /* empty string */
345 switch (victim->getTeam()) {
346 case TEAM_CIVILIAN:
347 victimName = "civilian";
348 break;
349 case TEAM_ALIEN:
350 victimName = "alien";
351 break;
352 default:
353 victimName = "unknown";
354 break;
355 }
356 }
357 if (attackerName[0] == '\0') { /* empty string */
358 switch (attacker->getTeam()) {
359 case TEAM_CIVILIAN:
360 attackerName = "civilian";
361 break;
362 case TEAM_ALIEN:
363 attackerName = "alien";
364 break;
365 default:
366 attackerName = "unknown";
367 break;
368 }
369 }
370 if (!victim->isSameTeamAs(attacker)) {
371 Com_sprintf(buffer, sizeof(buffer), "%s (%s) %s %s (%s) with %s of %s (entnum: %i)",
372 attackerName, attacker->chr.name,
373 (victim->HP == 0 ? "kills" : "stuns"),
374 victimName, victim->chr.name, fd->name, G_GetWeaponNameForFiredef(fd), victim->getIdNum());
375 } else {
376 Com_sprintf(buffer, sizeof(buffer), "%s (%s) %s %s (%s) (teamkill) with %s of %s (entnum: %i)",
377 attackerName, attacker->chr.name,
378 (victim->HP == 0 ? "kills" : "stuns"),
379 victimName, victim->chr.name, fd->name, G_GetWeaponNameForFiredef(fd), victim->getIdNum());
380 }
381 } else {
382 const char* attackerName = G_GetPlayerName(attacker->getPlayerNum());
383 Com_sprintf(buffer, sizeof(buffer), "%s %s %s (own team) with %s of %s (entnum: %i)",
384 attackerName, (victim->HP == 0 ? "kills" : "stuns"),
385 victim->chr.name, fd->name, G_GetWeaponNameForFiredef(fd), victim->getIdNum());
386 }
387 } else {
388 const char* victimName = G_GetPlayerName(victim->getPlayerNum());
389 Com_sprintf(buffer, sizeof(buffer), "%s (%s) was %s (entnum: %i)",
390 victimName, victim->chr.name, (victim->HP == 0 ? "killed" : "stunned"), victim->getIdNum());
391 }
392 G_PrintStats("%s", buffer);
393}
394
408Edict* G_FindRadius (Edict* from, const vec3_t org, float rad, entity_type_t type)
409{
410 Edict* ent = from;
411
412 while ((ent = G_EdictsGetNextInUse(ent))) {
413 vec3_t eorg;
414 vec3_t center;
415 ent->entBox.getCenter(center);
416 for (int j = 0; j < 3; j++)
417 eorg[j] = org[j] - (ent->origin[j] + center[j]);
418 if (VectorLength(eorg) > rad)
419 continue;
420 if (type != ET_NULL && ent->type != type)
421 continue;
422 return ent;
423 }
424
425 return nullptr;
426}
427
428#define IS_BMODEL(ent) ((ent)->model && (ent)->model[0] == '*' && (ent)->solid == SOLID_BSP)
429
436void G_GenerateEntList (const char* entList[MAX_EDICTS])
437{
438 int i = 0;
439 Edict* ent = nullptr;
440
441 /* generate entity list */
442 while ((ent = G_EdictsGetNextInUse(ent)))
443 if (IS_BMODEL(ent))
444 entList[i++] = ent->model;
445 entList[i] = nullptr;
446}
447
452void G_RecalcRouting (const char* model, const GridBox& box)
453{
454 const char* entList[MAX_EDICTS];
455 /* generate entity list */
456 G_GenerateEntList(entList);
457 /* recalculate routing */
458 gi.GridRecalcRouting(model, box, entList);
459}
460
465{
466 double start = time(nullptr); /* stopwatch */
467
468 Edict* ent = nullptr;
469 int i = 0;
470 while ((ent = G_EdictsGetNextInUse(ent)))
471 if (IS_BMODEL(ent)) {
472 i++;
474 }
475
476 Com_Printf("Rerouted for %i Edicts in %5.2fs\n", i, time(nullptr) - start);
477}
478
485static void G_ResetTriggers (Edict* ent, Edict** touched, int num)
486{
487 Edict* trigger = nullptr;
488
489 /* check all edicts to find all triggers */
490 while ((trigger = G_EdictsGetNextInUse(trigger))) {
491 if (trigger->solid == SOLID_TRIGGER) {
492 /* check if our edict is among the known triggerers of this trigger */
493 if (G_TriggerIsInList(trigger, ent)) {
494 /* if so, check if it still touches it */
495 int i;
496 for (i = 0; i < num; i++) {
497 if (touched[i] == trigger)
498 break; /* Yes ! */
499 }
500 if (i == num) { /* No ! */
501 G_TriggerRemoveFromList(trigger, ent);
502 /* the ent left the trigger area */
503 if (trigger->reset != nullptr)
504 trigger->reset(trigger, ent);
505 }
506 }
507 }
508 }
509}
510
519static int G_GetTouchingEdicts (const AABB& aabb, Edict** list, int maxCount, Edict* skip)
520{
521 int num = 0;
522
523 /* skip the world */
524 Edict* ent = G_EdictsGetFirst();
525 while ((ent = G_EdictsGetNextInUse(ent))) {
526 /* deactivated */
527 if (ent->solid == SOLID_NOT)
528 continue;
529 if (ent == skip)
530 continue;
531 if (aabb.doesIntersect(ent->absBox)) {
532 list[num++] = ent;
533 if (num >= maxCount)
534 break;
535 }
536 }
537
538 return num;
539}
540
548{
549 Edict* touched[MAX_EDICTS];
550
551 if (!G_IsLivingActor(ent))
552 return 0;
553 Actor* actor = makeActor(ent);
554
555 const int num = G_GetTouchingEdicts(actor->absBox, touched, lengthof(touched), actor);
556
557 G_ResetTriggers(actor, touched, num);
558
559 /* be careful, it is possible to have an entity in this
560 * list removed before we get to it (killtriggered) */
561 int usedNum = 0;
562 for (int i = 0; i < num; i++) {
563 Edict* hit = touched[i];
564 if (hit->solid != SOLID_TRIGGER)
565 continue;
566 if (type != ET_NULL && hit->type != type)
567 continue;
568 if (!hit->hasTouch())
569 continue;
570 if (hit->dmg == 0 && actor->isStunned())
571 continue;
572 if (hit->callTouch(actor))
573 usedNum++;
574 /* now after the use function was executed, we can add the ent to
575 * the touched list of the trigger. We do this because we want to be
576 * able to check whether another call changes the triggered state for
577 * the added entity. We have to do this after the use function was
578 * called, because there are triggers that may only be triggered once
579 * if someone touches it. */
580 G_TriggerAddToList(hit, actor);
581 }
582 return usedNum;
583}
584
590int G_TouchSolids (Edict* ent, float extend)
591{
592 if (!G_IsLivingActor(ent))
593 return 0;
594 Actor* actor = makeActor(ent);
595
596 AABB absbox(actor->absBox);
597 absbox.expand(extend);
598
599 Edict* touched[MAX_EDICTS];
600 const int num = G_GetTouchingEdicts(absbox, touched, lengthof(touched), actor);
601
602 int usedNum = 0;
603 /* be careful, it is possible to have an entity in this
604 * list removed before we get to it (killtriggered) */
605 for (int i = 0; i < num; i++) {
606 Edict* hit = touched[i];
607 if (hit->solid == SOLID_TRIGGER)
608 continue;
609 if (!hit->inuse)
610 continue;
611 if (!hit->hasTouch())
612 continue;
613 hit->callTouch(actor);
614 usedNum++;
615 }
616 return usedNum;
617}
618
625void G_TouchEdicts (Edict* trigger, float extend)
626{
627 const char* entName = (trigger->model) ? trigger->model : trigger->chr.name;
628
629 AABB absbox(trigger->absBox);
630 absbox.expand(extend);
631
632 Edict* touched[MAX_EDICTS];
633 const int num = G_GetTouchingEdicts(absbox, touched, lengthof(touched), trigger);
634 Com_DPrintf(DEBUG_GAME, "G_TouchEdicts: Entities touching %s: %i (%f extent).\n", entName, num, extend);
635
636 /* be careful, it is possible to have an entity in this
637 * list removed before we get to it (killtriggered) */
638 for (int i = 0; i < num; i++) {
639 Edict* hit = touched[i];
640 if (!hit->inuse)
641 continue;
642 if (trigger->hasTouch())
643 trigger->callTouch(hit);
644 }
645}
646
650uint32_t G_GetLevelFlagsFromPos (const pos3_t pos)
651{
652 uint32_t levelflags = 0;
653 for (int i = 0; i < PATHFINDING_HEIGHT; i++) {
654 if (i >= pos[2]) {
655 levelflags |= (1 << i);
656 }
657 }
658
659 return levelflags;
660}
Definition aabb.h:42
void getCenter(vec3_t center) const
Calculates the center of the bounding box.
Definition aabb.h:155
void expand(const float byVal)
expand the box in all directions, but clip them to the maximum boundaries
Definition aabb.h:240
bool doesIntersect(const AABB &other) const
Checks if the aabb touches or intersects with the given aabb.
Definition aabb.h:183
An Edict of type Actor.
Definition g_edict.h:348
bool isStunned() const
Definition g_edict.h:355
int getPlayerNum() const
Definition g_edict.h:234
bool isSameTeamAs(const Edict *other) const
Definition g_edict.h:278
character_t chr
Definition g_edict.h:116
int getIdNum() const
Definition g_edict.h:231
const char * classname
Definition g_edict.h:67
vec3_t origin
Definition g_edict.h:53
pos3_t pos
Definition g_edict.h:55
int HP
Definition g_edict.h:89
Edict * groupChain
Definition g_edict.h:167
bool(* use)(Edict *self, Edict *activator)
Definition g_edict.h:154
bool inuse
Definition g_edict.h:47
int getTeam() const
Definition g_edict.h:269
AABB entBox
Definition g_edict.h:60
bool callTouch(Edict *activator)
Definition g_edict.h:329
void(* reset)(Edict *self, Edict *activator)
Definition g_edict.h:148
AABB absBox
Definition g_edict.h:61
int dmg
Definition g_edict.h:138
bool hasTouch() const
Definition g_edict.h:324
solid_t solid
Definition g_edict.h:58
entity_type_t type
Definition g_edict.h:81
void nativeReset()
Definition g_edict.h:195
Edict * groupMaster
Definition g_edict.h:168
const char * model
Definition g_edict.h:74
static const GridBox EMPTY
Definition mathlib.h:122
Definition line.h:31
vec3_t start
Definition line.h:54
vec3_t stop
Definition line.h:55
void Com_DPrintf(int level, const char *fmt,...)
A Com_Printf that only shows up if the "developer" cvar is set.
Definition common.cpp:440
void Com_Printf(const char *const fmt,...)
Definition common.cpp:428
#define TL_FLAG_NONE
Definition defines.h:357
#define MAX_EDICTS
Definition defines.h:99
#define DEBUG_GAME
Definition defines.h:61
#define PATHFINDING_HEIGHT
15 max, adjusting above 8 will require a rewrite to the DV code
Definition defines.h:294
bool G_IsLivingActor(const Edict *ent)
Checks whether the given edict is a living actor.
Definition g_actor.cpp:43
playermask_t G_TeamToPM(int team)
Generates the player bit mask for a given team.
Definition g_client.cpp:144
Player * G_PlayerGetNextActiveHuman(Player *lastPlayer)
Iterate through the list of players.
Definition g_client.cpp:110
Player * G_PlayerGetNextActiveAI(Player *lastPlayer)
Iterate through the list of players.
Definition g_client.cpp:126
Interface for g_client.cpp.
Actor * makeActor(Edict *ent)
Convert an Edict pointer into an Actor pointer.
Definition g_edicts.cpp:327
Edict * G_EdictsGetFirst(void)
Returns the first entity.
Definition g_edicts.cpp:98
Edict * G_EdictsGetNextInUse(Edict *lastEnt)
Iterate through the entities that are in use.
Definition g_edicts.cpp:166
functions to handle the storage and lifecycle of all edicts in the game module.
void G_EventDestroyEdict(const Edict &ent)
Unregister an edict at the client.
Definition g_events.cpp:167
void G_EventParticleSpawn(playermask_t playerMask, const char *name, int levelFlags, const vec3_t s, const vec3_t v, const vec3_t a)
Spawn a new particle for the client.
Definition g_events.cpp:334
#define PM_ALL
Definition g_events.h:36
unsigned int playermask_t
Definition g_events.h:34
game_locals_t game
Definition g_main.cpp:37
#define G_IsActor(ent)
Definition g_local.h:127
#define G_IsBreakable(ent)
Definition g_local.h:137
game_import_t gi
Definition g_main.cpp:39
FILE * logstatsfile
Definition g_main.cpp:49
cvar_t * g_drawtraces
Definition g_main.cpp:115
void G_TriggerAddToList(Edict *self, Edict *activator)
Adds the activator to the list of recognized edicts for this trigger_touch edict.
Definition g_trigger.cpp:67
bool G_TriggerIsInList(Edict *self, Edict *activator)
Checks whether the activator of this trigger_touch was already recognized.
Definition g_trigger.cpp:47
bool G_TriggerRemoveFromList(Edict *self, Edict *activator)
Removes an activator from the list of recognized edicts.
Definition g_trigger.cpp:87
Trigger functions.
void G_GenerateEntList(const char *entList[MAX_EDICTS])
creates an entity list
Definition g_utils.cpp:436
#define IS_BMODEL(ent)
Definition g_utils.cpp:428
void G_CompleteRecalcRouting(void)
Definition g_utils.cpp:464
void G_RecalcRouting(const char *model, const GridBox &box)
Definition g_utils.cpp:452
Edict * G_GetEdictFromPos(const pos3_t pos, const entity_type_t type)
Searches an edict of the given type at the given grid location.
Definition g_utils.cpp:59
bool G_UseEdict(Edict *ent, Edict *activator)
Call the 'use' function for the given edict and all its group members.
Definition g_utils.cpp:117
static int G_GetTouchingEdicts(const AABB &aabb, Edict **list, int maxCount, Edict *skip)
Fills a list with edicts that are in use and are touching the given bounding box.
Definition g_utils.cpp:519
trace_t G_Trace(const Line &trLine, const Edict *passent, int contentmask)
collision detection - this version is more accurate and includes entity tests
Definition g_utils.cpp:265
playermask_t G_GetClosePlayerMask(const vec3_t origin, float radius)
Assembles a player mask for those players that have a living team member close to the given location.
Definition g_utils.cpp:288
const char * G_GetPlayerName(int pnum)
Returns the player name for a give player number.
Definition g_utils.cpp:275
void G_TakeDamage(Edict *ent, int damage)
Applies the given damage value to an edict that is either an actor or has the FL_DESTROYABLE flag set...
Definition g_utils.cpp:215
void G_PrintStats(const char *format,...)
Prints stats to game console and stats log file.
Definition g_utils.cpp:304
bool G_TestLine(const vec3_t start, const vec3_t end)
fast version of a line trace but without including entities
Definition g_utils.cpp:253
uint32_t G_GetLevelFlagsFromPos(const pos3_t pos)
Calculates the level flags for a given grid position.
Definition g_utils.cpp:650
bool G_TestLineWithEnts(const vec3_t start, const vec3_t end)
fast version of a line trace including entities
Definition g_utils.cpp:237
void G_TouchEdicts(Edict *trigger, float extend)
Call after linking a new trigger in or destroying a bmodel during gameplay to force all entities it c...
Definition g_utils.cpp:625
void G_FreeEdict(Edict *ent)
Marks the edict as free.
Definition g_utils.cpp:41
int G_TouchSolids(Edict *ent, float extend)
Call after making a step to a new grid tile to immediately touch edicts whose bbox intersects with th...
Definition g_utils.cpp:590
static void G_TraceDraw(const Line &traceLine)
Renders all the traces on the client side if the cvar g_drawtraces is activated.
Definition g_utils.cpp:225
static const objDef_t * G_GetObjectForFiredef(const fireDef_t *fd)
Searches for the obj that has the given firedef.
Definition g_utils.cpp:148
const char * G_GetWeaponNameForFiredef(const fireDef_t *fd)
Returns the corresponding weapon name for a given fire definition.
Definition g_utils.cpp:173
int G_TouchTriggers(Edict *ent, const entity_type_t type)
Check the world against triggers for the current entity.
Definition g_utils.cpp:547
Player * G_GetPlayerForTeam(int team)
Gets player for given team.
Definition g_utils.cpp:188
static void G_ResetTriggers(Edict *ent, Edict **touched, int num)
Call the reset function for those triggers that are no longer touched (left the trigger zone).
Definition g_utils.cpp:485
void G_PrintActorStats(const Edict *victim, const Edict *attacker, const fireDef_t *fd)
Prints stats about who killed who with what and how.
Definition g_utils.cpp:336
Edict * G_GetEdictFromPosExcluding(const pos3_t pos, const int n,...)
Searches an edict that is not of the given types at the given grid location.
Definition g_utils.cpp:81
Edict * G_FindRadius(Edict *from, const vec3_t org, float rad, entity_type_t type)
Returns entities that have origins within a spherical area.
Definition g_utils.cpp:408
Misc utility functions for game module.
@ SOLID_TRIGGER
Definition game.h:155
@ SOLID_NOT
Definition game.h:154
voidpf uLong int origin
Definition ioapi.h:45
vec_t VectorLength(const vec3_t v)
Calculate the length of a vector.
Definition mathlib.cpp:434
const vec3_t vec3_origin
Definition mathlib.cpp:35
#define TEAM_ALIEN
Definition q_shared.h:63
entity_type_t
Definition q_shared.h:145
@ ET_NULL
Definition q_shared.h:146
@ ET_MAX
Definition q_shared.h:173
void format(__printf__, 1, 2)))
#define TEAM_CIVILIAN
Definition q_shared.h:61
QGL_EXTERN GLint i
Definition r_gl.h:113
QGL_EXTERN GLint GLenum type
Definition r_gl.h:94
#define lengthof(x)
Definition shared.h:105
int Q_vsnprintf(char *str, size_t size, const char *format, va_list ap)
Safe (null terminating) vsnprintf implementation.
Definition shared.cpp:535
bool Com_sprintf(char *dest, size_t size, const char *fmt,...)
copies formatted string with buffer-size checking
Definition shared.cpp:494
char name[MAX_VAR]
Definition chr_shared.h:390
this is a fire definition for our weapons/ammo
Definition inv_shared.h:110
const char * name
Definition inv_shared.h:111
Defines all attributes of objects used in the inventory.
Definition inv_shared.h:264
fireDef_t fd[MAX_WEAPONS_PER_OBJDEF][MAX_FIREDEFS_PER_WEAPON]
Definition inv_shared.h:314
fireDefIndex_t numFiredefs[MAX_WEAPONS_PER_OBJDEF]
Definition inv_shared.h:315
const char * id
Definition inv_shared.h:268
int numWeapons
Definition inv_shared.h:317
#define TRACE_ALL_LEVELS
Definition tracing.h:52
pos_t pos3_t[3]
Definition ufotypes.h:58
vec_t vec3_t[3]
Definition ufotypes.h:39
#define VectorCompare(a, b)
Definition vector.h:63