UFO: Alien Invasion
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
g_edicts.cpp
Go to the documentation of this file.
1 
6 /*
7 All original material Copyright (C) 2002-2020 UFO: Alien Invasion.
8 
9 Original file from Quake 2 v3.21: quake2-2.31/game/g_utils.c
10 Copyright (C) 1997-2001 Id Software, Inc.
11 
12 This program is free software; you can redistribute it and/or
13 modify it under the terms of the GNU General Public License
14 as published by the Free Software Foundation; either version 2
15 of the License, or (at your option) any later version.
16 
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
20 
21 See the GNU General Public License for more details.
22 
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26 
27 */
28 
29 #include "g_edicts.h"
30 #include "g_actor.h"
31 
33 static Edict* g_edicts;
34 
40 {
41  g_edicts = static_cast<Edict*>(G_TagMalloc(game.sv_maxentities * sizeof(g_edicts[0]), TAG_GAME));
42  return g_edicts;
43 }
44 
48 void G_EdictsInit (void)
49 {
50  for (int i = 0; i < game.sv_maxentities; i++)
51  g_edicts[i].init(i);
52 }
53 
60 int G_EdictsGetNumber (const Edict* ent)
61 {
62  const int idx = ent - g_edicts;
63  assert(idx >= 0 && idx < globals.num_edicts);
64  return idx;
65 }
66 
72 bool G_EdictsIsValidNum (const int num)
73 {
74  if (num >= 0 && num < globals.num_edicts)
75  return true;
76  return false;
77 }
78 
83 Edict* G_EdictsGetByNum (const int num)
84 {
85  if (!G_EdictsIsValidNum(num)) {
86  gi.DPrintf("Invalid edict num %i\n", num);
87  return nullptr;
88  }
89 
90  return g_edicts + num;
91 }
92 
99 {
100  return &g_edicts[0];
101 }
102 
108 {
109  if (!globals.num_edicts)
110  return nullptr;
111 
112  if (!lastEnt)
113  return g_edicts;
114 
115  const Edict* endOfEnts = &g_edicts[globals.num_edicts];
116  assert(lastEnt >= g_edicts);
117  assert(lastEnt < endOfEnts);
118 
119  Edict* ent = lastEnt;
120 
121  ent++;
122  if (ent >= endOfEnts)
123  return nullptr;
124 
125  return ent;
126 }
127 
128 Edict* G_EdictDuplicate (const Edict* edict)
129 {
130  Edict* duplicate = G_EdictsGetNewEdict();
131  if (duplicate == nullptr)
132  return nullptr;
133  memcpy(duplicate, edict, sizeof(*edict));
134  duplicate->number = G_EdictsGetNumber(duplicate);
135  return duplicate;
136 }
137 
142 {
143  Edict* ent = nullptr;
144 
145  /* try to recycle an edict */
146  while ((ent = G_EdictsGetNext(ent))) {
147  if (!ent->inuse)
148  return ent;
149  }
150 
151  /* no unused edict found, create a new one */
152  ent = &g_edicts[globals.num_edicts];
155  return nullptr;
156 
157  return ent;
158 }
159 
167 {
168  Edict* ent = lastEnt;
169 
170  while ((ent = G_EdictsGetNext(ent))) {
171  if (ent->inuse)
172  break;
173  }
174  return ent;
175 }
176 
182 {
183  Edict* ent = lastEnt;
184 
185  while ((ent = G_EdictsGetNextInUse(ent))) {
186  if (G_IsTriggerNextMap(ent))
187  break;
188  }
189  return ent;
190 }
191 
197 {
198  Edict* ent = lastEnt;
199 
200  while ((ent = G_EdictsGetNextInUse(ent))) {
201  if (G_IsLivingActor(ent)) {
202  Actor* actor = static_cast<Actor*>(ent);
203  if (actor)
204  return actor;
205  Sys_Error("dynamic_cast to Actor failed.");
206  }
207  }
208  return nullptr;
209 }
210 
216 Actor* G_EdictsGetNextLivingActorOfTeam (Actor* lastEnt, const int team)
217 {
218  Actor* actor = lastEnt;
219 
220  while ((actor = G_EdictsGetNextLivingActor(actor))) {
221  if (actor->getTeam() == team)
222  break;
223  }
224  return actor;
225 }
226 
232 {
233  Edict* ent = lastEnt;
234 
235  assert(lastEnt < &g_edicts[globals.num_edicts]);
236 
237  while ((ent = G_EdictsGetNextInUse(ent))) {
238  if (G_IsActor(ent)) {
239  Actor* actor = static_cast<Actor*>(ent);
240  if (actor)
241  return actor;
242  Sys_Error("dynamic_cast to Actor failed.");
243  }
244  }
245  return nullptr;
246 }
247 
254 Actor* G_EdictsGetActorByUCN (const int ucn, const int team)
255 {
256  Actor* actor = nullptr;
257 
258  while ((actor = G_EdictsGetNextActor(actor)))
259  if (team == actor->getTeam() && actor->chr.ucn == ucn)
260  return actor;
261 
262  return nullptr;
263 }
264 
271 {
272  Actor* actor = nullptr;
273 
274  while ((actor = G_EdictsGetNextLivingActor(actor))) {
275  if (!VectorCompare(pos, actor->pos))
276  continue;
277 
278  return actor;
279  }
280  /* nothing found at this pos */
281  return nullptr;
282 }
283 
290 Edict* G_EdictsFindTargetEntity (const char* target)
291 {
292  Edict* ent = nullptr;
293 
294  while ((ent = G_EdictsGetNextInUse(ent))) {
295  const char* n = ent->targetname;
296  if (n && Q_streq(n, target))
297  return ent;
298  }
299 
300  return nullptr;
301 }
302 
306 void G_EdictsThink (void)
307 {
308  /* treat each object in turn */
309  /* even the world gets a chance to think */
310  Edict* ent = nullptr;
311  while ((ent = G_EdictsGetNextInUse(ent))) {
312  if (!ent->think)
313  continue;
314  if (ent->nextthink <= 0)
315  continue;
316  if (ent->nextthink > level.time + 0.001f)
317  continue;
318 
320  ent->think(ent);
321  }
322 }
323 
328 {
329  if (G_IsActor(ent)) {
330  /* should be a dynamic_cast one fine day */
331  Actor* actor = static_cast<Actor*>(ent);
332  if (actor)
333  return actor;
334  }
335  Sys_Error("Unexpected non-Actor Edict found.");
336  return nullptr;
337 }
338 
339 void Edict::init (int idx)
340 {
341  inuse = inRescueZone = hiding = active = false;
344  body = head = 0;
345  visflags = 0;
346  dir = dmgtype = 0;
347  angle = nextthink = 0.0f;
348  solid = SOLID_NOT;
349  type = ET_NULL;
354  link = nullptr;
356  group = nullptr;
357  _touch = nullptr;
358  reset = nullptr;
359  think = nullptr;
360  use = nullptr;
361  destroy = nullptr;
362  touchedList = nullptr;
363  forbiddenListPos = nullptr;
364 
367  VectorClear(pos);
368  VectorClear(size);
369  OBJZERO(camera);
370  OBJZERO(moveinfo);
371  OBJZERO(AI);
372 
373  number = idx;
374  chr.init();
375 }
383 bool Edict::isOpponent (const Actor* actor) const
384 {
385  const bool actControlled = actor->isState(STATE_XVI);
386  const bool selfControlled = G_IsState(this, STATE_XVI);
387  if (actor->isSameTeamAs(this))
388  return selfControlled ? !actControlled : actControlled;
389 
390  bool opponent = true;
391  switch (this->getTeam()) {
392  /* Aliens: hostile to everyone */
393  case TEAM_ALIEN:
394  opponent = !actControlled;
395  break;
396  /* Civilians: Only hostile to aliens */
397  case TEAM_CIVILIAN:
398  opponent = G_IsAlien(actor) || actControlled;
399  break;
400  /* PHALANX and MP teams: Hostile to aliens and rival teams
401  * (under AI control while under panic/rage or when g_aihumans is non-zero) */
402  default:
403  opponent = !G_IsCivilian(actor) || actControlled;
404  break;
405  }
406 
407  return selfControlled ? !opponent : opponent;
408 }
int number
Definition: g_edict.h:51
char * group
Definition: g_edict.h:104
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
bool isSameTeamAs(const Edict *other) const
Definition: g_edict.h:278
solid_t solid
Definition: g_edict.h:58
void Sys_Error(const char *error,...)
Definition: g_main.cpp:421
#define G_IsState(ent, s)
Definition: g_actor.h:29
const char * targetname
Definition: g_edict.h:126
Actor * G_EdictsGetActorByUCN(const int ucn, const int team)
Searches an actor by a unique character number.
Definition: g_edicts.cpp:254
unsigned int body
Definition: g_edict.h:99
Actor * G_EdictsGetNextLivingActor(Actor *lastEnt)
Iterate through the living actor entities.
Definition: g_edicts.cpp:196
bool hiding
Definition: g_edict.h:142
void init()
Definition: chr_shared.cpp:34
float nextthink
Definition: g_edict.h:149
#define TEAM_ALIEN
Definition: q_shared.h:63
byte dmgtype
Definition: g_edict.h:139
linkedList_t * touchedList
Definition: g_edict.h:157
int G_EdictsGetNumber(const Edict *ent)
Get an entity's ID number.
Definition: g_edicts.cpp:60
voidpf uLong int origin
Definition: ioapi.h:45
const char * description
Definition: g_edict.h:131
Actor * G_EdictsGetLivingActorFromPos(const pos3_t pos)
Searches an actor at the given grid location.
Definition: g_edicts.cpp:270
vec3_t angles
Definition: g_edict.h:54
const char * message
Definition: g_edict.h:130
character_t chr
Definition: g_edict.h:116
int doorState
Definition: g_edict.h:158
bool(* use)(Edict *self, Edict *activator)
Definition: g_edict.h:154
Actor * makeActor(Edict *ent)
Convert an Edict pointer into an Actor pointer.
Definition: g_edicts.cpp:327
static Edict * g_edicts
Definition: g_edicts.cpp:33
AABB entBox
Definition: g_edict.h:60
bool inuse
Definition: g_edict.h:47
bool active
Definition: g_edict.h:177
AABB absBox
Definition: g_edict.h:61
int mapNum
Definition: g_edict.h:73
const char * target
Definition: g_edict.h:125
#define TEAM_CIVILIAN
Definition: q_shared.h:61
int forbiddenListSize
Definition: g_edict.h:175
moveinfo_t moveinfo
Definition: g_edict.h:160
byte dir
Definition: g_edict.h:86
#define TAG_GAME
Definition: g_local.h:58
Edict * G_EdictDuplicate(const Edict *edict)
Definition: g_edicts.cpp:128
#define G_IsActor(ent)
Definition: g_local.h:127
bool G_IsLivingActor(const Edict *ent)
Checks whether the given edict is a living actor.
Definition: g_actor.cpp:43
Edict * G_EdictsFindTargetEntity(const char *target)
Searches the edict that has the given target as targetname set.
Definition: g_edicts.cpp:290
camera_edict_data_t camera
Definition: g_edict.h:134
Edict * G_EdictsGetNewEdict(void)
Find an entity that is not in use.
Definition: g_edicts.cpp:141
int speed
Definition: g_edict.h:124
const char * noise
Definition: g_edict.h:132
int spawnflags
Definition: g_edict.h:118
game_locals_t game
Definition: g_main.cpp:37
int getTeam() const
Definition: g_edict.h:269
unsigned int head
Definition: g_edict.h:100
int modelindex
Definition: g_edict.h:66
int sv_maxentities
Definition: g_local.h:74
GLsizei size
Definition: r_gl.h:152
game_import_t gi
Definition: g_main.cpp:39
const char * nextmap
Definition: g_edict.h:129
#define OBJZERO(obj)
Definition: shared.h:178
void(* think)(Edict *self)
Definition: g_edict.h:150
int dmg
Definition: g_edict.h:138
#define G_IsCivilian(ent)
Definition: g_local.h:148
int radius
Definition: g_edict.h:123
int TU
Definition: g_edict.h:88
teammask_t visflags
Definition: g_edict.h:82
bool isOpponent(const Actor *actor) const
Check if given actor is an enemy.
Definition: g_edicts.cpp:383
int linkcount
Definition: g_edict.h:48
pos3_t pos
Definition: g_edict.h:55
Edict * groupMaster
Definition: g_edict.h:168
int sounds
Definition: g_edict.h:137
float angle
Definition: g_edict.h:120
#define G_TagMalloc(size, tag)
Definition: g_local.h:64
int _STUN
Definition: g_edict.h:90
An Edict of type Actor.
Definition: g_edict.h:348
int frame
Definition: g_edict.h:102
void(* reset)(Edict *self, Edict *activator)
Definition: g_edict.h:148
Edict * clientAction
Definition: g_edict.h:113
bool inRescueZone
Definition: g_edict.h:109
#define G_IsTriggerNextMap(ent)
Definition: g_local.h:133
Edict * _child
Definition: g_edict.h:64
int time
Definition: g_edict.h:136
pos_t pos3_t[3]
Definition: ufotypes.h:58
int state
Definition: g_edict.h:93
int flags
Definition: g_edict.h:169
actorSizeEnum_t fieldSize
Definition: g_edict.h:141
#define VectorCompare(a, b)
Definition: vector.h:63
#define VectorClear(a)
Definition: vector.h:55
int count
Definition: g_edict.h:135
int team
Definition: g_edict.h:96
Edict * G_EdictsGetTriggerNextMaps(Edict *lastEnt)
Iterator through all the trigger_nextmap edicts.
Definition: g_edicts.cpp:181
int contentFlags
Definition: g_edict.h:84
bool G_EdictsIsValidNum(const int num)
Check if the given number could point to an existing entity.
Definition: g_edicts.cpp:72
Actor * G_EdictsGetNextLivingActorOfTeam(Actor *lastEnt, const int team)
Iterate through the living actor entities of the given team.
Definition: g_edicts.cpp:216
QGL_EXTERN GLint i
Definition: r_gl.h:113
Actor * G_EdictsGetNextActor(Actor *lastEnt)
Iterate through the actor entities (even the dead!)
Definition: g_edicts.cpp:231
#define G_IsAlien(ent)
Definition: g_local.h:149
entity_type_t type
Definition: g_edict.h:81
functions to handle the storage and lifecycle of all edicts in the game module.
edictMaterial_t material
Definition: g_edict.h:133
const Edict * link
Definition: g_edict.h:80
bool(* destroy)(Edict *self)
Definition: g_edict.h:155
const char * item
Definition: g_edict.h:127
void G_EdictsInit(void)
Reset the entity pointers for eg. a new game.
Definition: g_edicts.cpp:48
int morale
Definition: g_edict.h:91
const char * classname
Definition: g_edict.h:67
#define SERVER_FRAME_SECONDS
Definition: g_local.h:55
Edict * G_EdictsGetByNum(const int num)
Get an entity by it's number.
Definition: g_edicts.cpp:83
Edict * _owner
Definition: g_edict.h:65
#define Q_streq(a, b)
Definition: shared.h:136
AI_t AI
Definition: g_edict.h:171
Edict * G_EdictsConstruct(void)
Allocate space for the entity pointers.
Definition: g_edicts.cpp:39
void G_EdictsThink(void)
Called every frame to let the edicts tick.
Definition: g_edicts.cpp:306
Definition: g_edict.h:45
static const AABB EMPTY
Definition: aabb.h:44
int pnum
Definition: g_edict.h:97
#define ACTOR_SIZE_INVALID
Definition: defines.h:301
#define STATE_XVI
Definition: q_shared.h:274
bool isState(int flag) const
Definition: g_edict.h:353
const char * model
Definition: g_edict.h:74
void init(int idx)
Definition: g_edicts.cpp:339
const char * particle
Definition: g_edict.h:128
Edict * groupChain
Definition: g_edict.h:167
Edict * G_EdictsGetNext(Edict *lastEnt)
Iterate through the list of entities.
Definition: g_edicts.cpp:107
pos3_t * forbiddenListPos
Definition: g_edict.h:173
int num_edicts
Definition: game.h:362
Edict * particleLink
Definition: g_edict.h:79
level_locals_t level
Definition: g_main.cpp:38
int HP
Definition: g_edict.h:89
game_export_t globals
Definition: g_main.cpp:40
bool(* _touch)(Edict *self, Edict *activator)
Definition: g_edict.h:146
float time
Definition: g_local.h:82