UFO: Alien Invasion
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
test_game.cpp
Go to the documentation of this file.
1 
6 /*
7 Copyright (C) 2002-2020 UFO: Alien Invasion.
8 
9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the GNU General Public License
11 as published by the Free Software Foundation; either version 2
12 of the License, or (at your option) any later version.
13 
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 
18 See the GNU General Public License for more details.
19 
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 
24 */
25 
26 #include "test_shared.h"
27 #include "../shared/ufotypes.h"
28 #include "../game/g_local.h"
29 #include "../game/g_actor.h"
30 #include "../game/g_client.h"
31 #include "../game/g_edicts.h"
32 #include "../game/g_inventory.h"
33 #include "../game/g_move.h"
34 #include "../server/server.h"
35 #include "../client/renderer/r_state.h"
36 
37 static int mapCount = 0;
38 
39 class GameTest: public ::testing::Test {
40 protected:
41  static void SetUpTestCase() {
42  TEST_Init();
43  /* we need the teamdefs for spawning ai actors */
44  Com_ParseScripts(true);
45  Cvar_Set("sv_threads", "0");
46  sv_maxclients = Cvar_Get("sv_maxclients", "1", CVAR_SERVERINFO, "Max. connected clients for test");
48  masterserver_url = Cvar_Get("masterserver_url", MASTER_SERVER, CVAR_ARCHIVE, "URL of UFO:AI masterserver");
49 
50  sv_genericPool = Mem_CreatePool("server-gametest");
51  com_networkPool = Mem_CreatePool("server-gametest-network");
53  }
54 
55  static void TearDownTestCase() {
56  TEST_Shutdown();
57  }
58 
59  void testCountSpawnpointsForMap(bool verbose, const mapDef_t *md);
60  void testCountSpawnpointsForMapWithAssembly(bool verbose, const mapDef_t *md, const char *asmName);
61  void testCountSpawnpointsForMapWithAssemblyAndAircraft(bool verbose, const mapDef_t *md, const char *asmName, const char *aircraft);
62  void testCountSpawnpointsForMapWithAssemblyAndAircraftAndUfo(bool verbose, const mapDef_t *md, const char *asmName, const char *aircraft, const char *ufo);
63  void testCountSpawnpointsForMapInSingleplayerMode(bool verbose, const mapDef_t *md, const char *asmName, const char *aircraft, const char *ufo);
64  void testCountSpawnpointsForMapInMultiplayerMode(bool verbose, const mapDef_t *md, const char *asmName, const char *aircraft, const char *ufo);
65  int testCountSpawnpointsGetNumteamValueForAircraft(const char *aircraft);
66  int testCountSpawnpointsGetNumteamValueForUFO(const char *ufo);
67  int testCountSpawnpointsGetNum2x2ValueForAircraft(const char *aircraft);
68 
69  void SetUp() {
70  OBJZERO(*sv);
71  }
72 
73  void TearDown() {
75  }
76 };
77 
78 TEST_F(GameTest, SpawnAndConnect)
79 {
80  char userinfo[MAX_INFO_STRING];
81  player_t* player;
82  const char* name = "name";
83  bool day = true;
84  byte* buf;
85  /* this entity string may not contain any inline models, we don't have the bsp tree loaded here */
86  const int size = FS_LoadFile("game/entity.txt", &buf);
87  Edict* e = nullptr;
88  int cnt = 0;
89 
90  ASSERT_NE(size, -1) << "could not load game/entity.txt.";
91  ASSERT_TRUE(size > 0) << "game/entity.txt is empty.";
92 
94  /* otherwise we can't link the entities */
95  SV_ClearWorld();
96 
97  player = G_PlayerGetNextHuman(0);
98  svs.ge->SpawnEntities(name, day, (const char*)buf);
99  ASSERT_TRUE(svs.ge->ClientConnect(player, userinfo, sizeof(userinfo))) << "Failed to connect the client";
100  ASSERT_FALSE(svs.ge->RunFrame()) << "Failed to run the server logic frame tick";
101 
102  while ((e = G_EdictsGetNextInUse(e))) {
103  Com_Printf("entity %i: %s\n", cnt, e->classname);
104  cnt++;
105  }
106 
107  ASSERT_EQ(cnt, 43);
108 
109  FS_FreeFile(buf);
110 }
111 
113 {
114  /* Right now, 2x2 units are not yet implemented. But if we start to, it will probably
115  be humans bringing UGVs into battle. So we should make sure there are at least some
116  2x2 spawnpoints for TEAM_HUMAN on each map.
117  The values are arbitrary, as they are not defined within the scripts yet. */
118 
119  if (Q_strnull(aircraft)) {
120  /* Could be any, so we return the max supported number. */
121  return 3;
122  } else if (Q_streq(aircraft, "craft_drop_firebird")) {
123  return 3;
124  } else if (Q_streq(aircraft, "craft_drop_raptor")) {
125  return 3;
126  } else if (Q_streq(aircraft, "craft_drop_herakles")) {
127  return 3;
128  } else {
129  ADD_FAILURE() << "Error: Mapdef defines unknown aircraft: " << aircraft;
130  return 0;
131  }
132 }
133 
135 {
136  // TODO: somehow fix these magic values here
137  if (Q_strnull(aircraft)) {
138  /* Could be any, so we return the max supported number. */
139  return 12;
140  } else if (Q_streq(aircraft, "craft_drop_firebird")) {
141  return 8;
142  } else if (Q_streq(aircraft, "craft_drop_raptor")) {
143  return 10;
144  } else if (Q_streq(aircraft, "craft_drop_herakles")) {
145  return 12;
146  } else {
147  ADD_FAILURE() << "Error: Mapdef defines unknown aircraft: " << aircraft;
148  return 0;
149  }
150 }
151 
153 {
154  // TODO: somehow fix these magic values here
155  if (Q_strnull(ufo)) {
156  /* Could be any, or none (ground based mission), so we return the max supported number. */
157  return 30;
158  } else if (Q_streq(ufo, "craft_ufo_scout") || Q_streq(ufo, "craft_crash_scout")) {
159  return 4;
160  } else if (Q_streq(ufo, "craft_ufo_fighter") || Q_streq(ufo, "craft_crash_fighter")) {
161  return 6;
162  } else if (Q_streq(ufo, "craft_ufo_harvester") || Q_streq(ufo, "craft_crash_harvester")) {
163  return 8;
164  } else if (Q_streq(ufo, "craft_ufo_corrupter") || Q_streq(ufo, "craft_crash_corrupter")) {
165  return 10;
166  } else if (Q_streq(ufo, "craft_ufo_supply") || Q_streq(ufo, "craft_crash_supply")) {
167  return 12;
168  } else if (Q_streq(ufo, "craft_ufo_gunboat") || Q_streq(ufo, "craft_crash_gunboat")) {
169  return 12;
170  } else if (Q_streq(ufo, "craft_ufo_bomber") || Q_streq(ufo, "craft_crash_bomber")) {
171  return 18;
172  } else if (Q_streq(ufo, "craft_ufo_ripper") || Q_streq(ufo, "craft_crash_ripper")) {
173  return 14;
174  } else {
175  ADD_FAILURE() << "Error: Mapdef defines unknown UFO: " << ufo;
176  return 0;
177  }
178 }
179 
180 void GameTest::testCountSpawnpointsForMapInMultiplayerMode(bool verbose, const mapDef_t *md, const char *asmName, const char *aircraft, const char *ufo)
181 {
182  if (verbose) {
183  std::cout << "[ ] adding test parameter: gamemode multiplayer" << std::endl;
184  Com_Printf("CountSpawnpoints - adding test parameter: gamemode multiplayer\n");
185  }
186 
187  if (LIST_IsEmpty(md->gameTypes)) {
188  ADD_FAILURE() << "Error: Multiplayer enabled, but no gametypes defined in mapdef " << md->id;
189  Com_Printf("CountSpawnpoints - error: Multiplayer enabled, but no gametypes defined in mapdef.\n");
190  return;
191  }
192 
193  if (md->teams < 1) {
194  ADD_FAILURE() << "Error: Multiplayer enabled, but number of teams is " << md->teams;
195  Com_Printf("CountSpawnpoints - error: Multiplayer enabled, but number of teams is %i.\n", md->teams);
196  return;
197  }
198 
199  /* Set initial values. */
200  /* Load map in multiplayer mode. */
201  Cvar_Set("sv_maxclients", DOUBLEQUOTE(MAX_CLIENTS));
202  /* It seems, because of reaction-fire limitations we cannot spawn more than 128 actors total. */
203  Cvar_Set("sv_maxsoldiersperteam", "12");
204  Cvar_Set("ai_multiplayeraliens", "64");
205  Cvar_Set("ai_numcivilians", "16");
206 
207  Com_Printf("CountSpawnpoints - loading map: mode multiplayer mapdef %s map %s assembly %s dropship %s ufo %s\n", md->id, md->mapTheme, asmName, aircraft, ufo);
208  long time = Sys_Milliseconds();
209 
210  try {
211  SV_Map(true, md->mapTheme, asmName, true);
212  } catch (comDrop_t&) {
213  ADD_FAILURE() << "Error: Failed to load assembly " << asmName << " from mapdef " << md->id << ", map "
214  << md->mapTheme << " aircraft: " << aircraft << ", ufo: " << ufo << " => multiplayer mode.";
215  Com_Printf("CountSpawnpoints - error: Multiplayer enabled, but no gametypes defined in mapdef.\n");
216  Com_Printf("CountSpawnpoints - error: Failed to load map.\n");
218  return;
219  }
220 
221  time = Sys_Milliseconds() - time;
222  Com_Printf("CountSpawnpoints - result: %li ms\n", time);
224  mapCount++;
225 
226  /* Print report to log. */
227  Com_Printf("CountSpawnpoints - map: mode multiplayer\n");
228  Com_Printf("CountSpawnpoints - map: mapdef %s\n", md->id);
229  Com_Printf("CountSpawnpoints - map: map %s\n", md->mapTheme);
230  Com_Printf("CountSpawnpoints - map: assembly %s\n", asmName);
231  Com_Printf("CountSpawnpoints - map: aircraft %s \n", aircraft);
232  Com_Printf("CountSpawnpoints - map: ufo %s\n", ufo);
233 
234  /* Check if one of the gametypes available in the mapdef defines a coop mode,
235  in which case we will need aliens on the map. */
236  int coop = 0;
237  /* The number of alien spawnpoints required on the map. In PvP gamemodes this is zero,
238  while in coop games we check for the number given as 'maxaliens' in the mapdef. */
239  int minAliens = 0;
240  /* The number of player spawnpoints required for each team is determined
241  by the value of sv_maxsoldiersperteam given in the gametype def. */
242  int minMP = 0;
243 
244  /* Count spawnpoints for TEAM_CIVILIAN. */
245  const int spawnCivs = static_cast<int>(level.num_spawnpoints[TEAM_CIVILIAN]);
246  Com_Printf("CountSpawnpoints - count spawnpoints: civilian %i\n", spawnCivs);
247 
248  /* Find the highest numbers for alien and player spawnpoints needed in the map. */
249  LIST_Foreach(md->gameTypes, const char, gameType) {
250  for (int i = 0; i < csi.numGTs; i++) {
251  const gametype_t* gt = &csi.gts[i];
252  if (!Q_streq(gt->id, gameType))
253  continue;
254  const cvarlist_t* list = gt->cvars;
255  for (int j = 0; j < gt->num_cvars; j++, list++) {
256  if (Q_streq(list->name, "ai_multiplayeraliens")) {
257  coop = std::max(coop, atoi(list->value));
258  } else if (Q_streq(list->name, "sv_maxsoldiersperteam")) {
259  minMP = std::max(minMP, atoi(list->value));
260  }
261  }
262  }
263  }
264 
265  /* If the mapdef does not define a coop mode, we do not need aliens. */
266  if (coop)
267  minAliens = std::min(md->maxAliens, testCountSpawnpointsGetNumteamValueForUFO(ufo));
268 
269  const int startTeam = TEAM_CIVILIAN + 1;
270  /* For every single mp team defined in the mapdef - check if there are enough spawnpoints available. */
271  for (int currTeamNum = startTeam; currTeamNum < startTeam + md->teams; ++currTeamNum) {
272  if (currTeamNum > TEAM_MAX_HUMAN) {
273  ADD_FAILURE() << "Error: Mapdef " << md->id << " has too many teams set.";
274  Com_Printf("CountSpawnpoints - error: Too many teams set.\n");
275  break;
276  }
277  const int spawnTeam = static_cast<int>(level.num_spawnpoints[currTeamNum]);
278  /* Make gtest report back in case there are not enough spawnpoints available for the team. */
279  EXPECT_GE(spawnTeam, minMP) << "Error: Assembly " << asmName << " from mapdef " << md->id << ", map " << md->mapTheme
280  << "(aircraft: " << aircraft << ", ufo: " << ufo << ") in multiplayer mode: Only " << spawnTeam
281  << " spawnpoints for team " << currTeamNum << " but " << minMP << " expected.";
282  /* Log the result. */
283  Com_Printf("CountSpawnpoints - count spawnpoints: player team/needs/found %i/%i/%i\n", currTeamNum, minMP, spawnTeam);
284  if (spawnTeam < minMP)
285  Com_Printf("CountSpawnpoints - error: missing spawnpoints - player team/needs/found %i/%i/%i\n", currTeamNum, minMP, spawnTeam);
286 
287  }
288  if (minAliens) {
289  const int spawnAliens = static_cast<int>(level.num_spawnpoints[TEAM_ALIEN]);
290  /* Make gtest report back in case there are not enough alien spawnpoints available. */
291  EXPECT_GE(spawnAliens, minAliens) << "Assembly " << asmName << " from mapdef " << md->id << ", map " << md->mapTheme
292  << "(aircraft: " << aircraft << ", ufo: " << ufo << ") in multiplayer mode defines at least one coop game mode,"
293  << " but does not have enough alien spawn positions for that. We expect at least " << minAliens
294  << " spawn positions for aliens, the map provides " << spawnAliens << ".";
295  /* Log the result. */
296  Com_Printf("CountSpawnpoints - count spawnpoints: alien needs/found %i/%i\n", minAliens, spawnAliens);
297  if (spawnAliens < minAliens)
298  Com_Printf("CountSpawnpoints - error: missing spawnpoints - alien needs/found %i/%i\n", minAliens, spawnAliens);
299  }
300 
302 }
303 
304 void GameTest::testCountSpawnpointsForMapInSingleplayerMode(bool verbose, const mapDef_t *md, const char *asmName, const char *aircraft, const char *ufo)
305 {
306  if (verbose) {
307  std::cout << "[ ] adding test parameter: gamemode singleplayer" << std::endl;
308  Com_Printf("CountSpawnpoints - adding test parameter: gamemode singleplayer\n");
309  }
310 
311  /* Set initial values. */
312  /* load singleplayer map */
313  Cvar_Set("sv_maxclients", "1");
314  /* It seems, because of reaction-fire limitations we cannot spawn more than 128 actors total. */
315  Cvar_Set("sv_maxsoldiersperteam", "12");
316  Cvar_Set("ai_singleplayeraliens", "64");
317  Cvar_Set("ai_numcivilians", "16");
318 
319  Com_Printf("CountSpawnpoints - loading map: mode singleplayer mapdef %s map %s assembly %s dropship %s ufo %s\n", md->id, md->mapTheme, asmName, aircraft, ufo);
320  long time = Sys_Milliseconds();
321 
322  try {
323  SV_Map(true, md->mapTheme, asmName, true);
324  } catch (comDrop_t&) {
325  ADD_FAILURE() << "Error: Failed to load assembly " << asmName << " from mapdef " << md->id << ", map "
326  << md->mapTheme << " aircraft: " << aircraft << ", ufo: " << ufo << " => singleplayer mode.";
327  Com_Printf("CountSpawnpoints - error: Failed to load map.\n");
329  return;
330  }
331  time = Sys_Milliseconds() - time;
332  Com_Printf("CountSpawnpoints - result: %li ms\n", time);
333  mapCount++;
334 
335  /* This is the max number of aliens the UFO can bring to the battlefield. */
336  const int numteamUFO = testCountSpawnpointsGetNumteamValueForUFO(ufo);
337 
338  /* The number of human spawnpoints required on the map depends on the 'numteam' value
339  of the used dropship, if any. */
340  const int minHumans = testCountSpawnpointsGetNumteamValueForAircraft(aircraft);
341 
342  /* The number of spawnpoints for 2x2 units required on the map depends on the number
343  of UGVs the aircraft can transport. */
344  const int minHuman2x2 = testCountSpawnpointsGetNum2x2ValueForAircraft(aircraft);
345 
346  /* How many aliens do we need to have on the map, at least?
347  The mapdef defines the map to support up to 'maxaliens' aliens, so the map should have
348  at least this number of spawnpoints available.
349  However, this number must not be higher than the 'numteam' value of the used UFO, if any. */
350  const int minAliens = std::min(md->maxAliens, numteamUFO);
351 
352  /* Count the spawnpoints available on the map. */
353  const int spawnCivs = static_cast<int>(level.num_spawnpoints[TEAM_CIVILIAN]);
354  const int spawnHumans = static_cast<int>(level.num_spawnpoints[TEAM_PHALANX]);
355  const int spawnAliens = static_cast<int>(level.num_spawnpoints[TEAM_ALIEN]);
356  const int spawnHuman2x2 = static_cast<int>(level.num_2x2spawnpoints[TEAM_PHALANX]);
357 
358  /* Make gtest report back in case there are not enough human spawnpoints. */
359  EXPECT_GE(spawnHumans, minHumans) << "Error: Assembly " << asmName << " in mapdef " << md->id
360  << " from map " << md->mapTheme << " in singleplayer mode (aircraft: " << aircraft
361  << " ufo: " << ufo << "): Only " << spawnHumans << " human spawnpoints but " << minHumans
362  << " expected.";
363  /* Make gtest report back in case there are not enough alien spawnpoints. */
364  EXPECT_GE(spawnAliens, minAliens) << "Error: Assembly " << asmName << " in mapdef " << md->id
365  << " from map " << md->mapTheme << " in singleplayer mode (aircraft: " << aircraft
366  << " ufo: " << ufo << "): Only " << spawnAliens << " alien spawnpoints but " << minAliens
367  << " expected.";
368  /* Make gtest report back in case there are not enough human 2x2 spawnpoints. */
369  EXPECT_GE(spawnHuman2x2, minHuman2x2) << "Error: Assembly " << asmName << " in mapdef " << md->id
370  << " from map " << md->mapTheme << " in singleplayer mode (aircraft: " << aircraft
371  << " ufo: " << ufo << "): Only " << spawnHuman2x2 << " human 2x2 spawnpoints but " << minHuman2x2
372  << " expected.";
373  /* Make gtest report back if the number of aliens allowed on the map is smaller than the crew number of the used UFO, if any. */
374  if (ufo) {
375  EXPECT_GE(md->maxAliens, numteamUFO) << "Error: Assembly " << asmName << " in mapdef " << md->id
376  << " from map " << md->mapTheme << " in singleplayer mode (aircraft: " << aircraft
377  << " ufo: " << ufo << "): The number of aliens allowed on the map is smaller than expected.";
378  }
379 
380  /* Print report to log. */
381  Com_Printf("CountSpawnpoints - map: mode singleplayer\n");
382  Com_Printf("CountSpawnpoints - map: mapdef %s\n", md->id);
383  Com_Printf("CountSpawnpoints - map: map %s\n", md->mapTheme);
384  Com_Printf("CountSpawnpoints - map: assembly %s\n", asmName);
385  Com_Printf("CountSpawnpoints - map: aircraft %s \n", aircraft);
386  Com_Printf("CountSpawnpoints - map: ufo %s\n", ufo);
387  Com_Printf("CountSpawnpoints - count spawnpoints: civilian %i\n", spawnCivs);
388  Com_Printf("CountSpawnpoints - count spawnpoints: singleplayer needs/found %i/%i\n", minHumans, spawnHumans);
389  Com_Printf("CountSpawnpoints - count spawnpoints: singleplayer_2x2 needs/found %i/%i\n", minHuman2x2, spawnHuman2x2);
390  Com_Printf("CountSpawnpoints - count spawnpoints: alien needs/found %i/%i\n", minAliens, spawnAliens);
391  if (spawnHumans < minHumans)
392  Com_Printf("CountSpawnpoints - error: missing spawnpoints - singleplayer needs/found %i/%i\n", minHumans, spawnHumans);
393  if (spawnHuman2x2 < minHuman2x2)
394  Com_Printf("CountSpawnpoints - error: missing spawnpoints - singleplayer_2x2 needs/found %i/%i\n", minHuman2x2, spawnHuman2x2);
395  if (spawnAliens < minAliens)
396  Com_Printf("CountSpawnpoints - error: missing spawnpoints - alien needs/found %i/%i\n", minAliens, spawnAliens);
397  if (ufo) {
398  if (md->maxAliens < numteamUFO) {
399  Com_Printf("CountSpawnpoints - error: mapdef parameter - maxaliens needs/found %i/%i\n", numteamUFO, md->maxAliens);
400  }
401  }
402 
404 }
405 
406 void GameTest::testCountSpawnpointsForMapWithAssemblyAndAircraftAndUfo(bool verbose, const mapDef_t *md, const char *asmName, const char *aircraft, const char *ufo)
407 {
408  if (verbose && ufo) {
409  std::cout << "[ ] adding test parameter: ufo " << ufo << std::endl;
410  Com_Printf("CountSpawnpoints - adding test parameter: ufo %s\n", ufo);
411  }
412 
413  /* The ufocrash map is a special one. The mapdef should not define single- nor
414  multiplayer mode. It uses one assembly for each ufo defined in the mapdef,
415  where the assembly name is equal the name of the UFO. */
416  if (Q_streq(md->id, "ufocrash")) {
417  testCountSpawnpointsForMapInSingleplayerMode(verbose, md, ufo, aircraft, ufo);
418  return;
419  }
420 
421  /* Check if we are manually testing a certain gamemode. */
422  if (TEST_ExistsProperty("mode")) {
423  const char *mode = TEST_GetStringProperty("mode");
424  if (Q_streq(mode, "sp")) {
425  if (md->singleplayer || md->campaign) {
426  testCountSpawnpointsForMapInSingleplayerMode(verbose, md, asmName, aircraft, ufo);
427  } else {
428  Com_Printf("CountSpawnpoints - error: Gamemode not defined in mapdef: %s\n", mode);
429  ADD_FAILURE() << "Error: Gamemode not defined in mapdef: " << mode;
430  }
431  } else if (Q_streq(mode, "mp")) {
432  if (md->multiplayer) {
433  testCountSpawnpointsForMapInMultiplayerMode(verbose, md, asmName, aircraft, ufo);
434  } else {
435  Com_Printf("CountSpawnpoints - error: Gamemode not defined in mapdef: %s\n", mode);
436  ADD_FAILURE() << "Error: Gamemode not defined in mapdef: " << mode;
437  }
438  } else {
439  Com_Printf("CountSpawnpoints - error: Not a valid gamemode: %s\n", mode);
440  ADD_FAILURE() << "Error: Not a valid gamemode: " << mode;
441  }
442  } else {
443  /* Test every gamemode defined in the mapdef. */
444  if (md->singleplayer || md->campaign) {
445  testCountSpawnpointsForMapInSingleplayerMode(verbose, md, asmName, aircraft, ufo);
446  }
447  if (md->multiplayer) {
448  testCountSpawnpointsForMapInMultiplayerMode(verbose, md, asmName, aircraft, ufo);
449  }
450  }
451 }
452 
453 void GameTest::testCountSpawnpointsForMapWithAssemblyAndAircraft(bool verbose, const mapDef_t *md, const char *asmName, const char *aircraft)
454 {
455  if (verbose && aircraft) {
456  std::cout << "[ ] adding test parameter: aircraft " << aircraft << std::endl;
457  Com_Printf("CountSpawnpoints - adding test parameter: aircraft %s\n", aircraft);
458  }
459 
460  /* Check if we are manually testing a certain UFO type. */
461  if (TEST_ExistsProperty("ufo")) {
462  const char *ufo = TEST_GetStringProperty("ufo");
463  int tested = 0;
464  LIST_Foreach(md->ufos, const char, s) {
465  if (Q_streq(ufo, s)) {
466  Cvar_Set("rm_ufo", "%s", Com_GetRandomMapAssemblyNameForCraft(ufo));
467  testCountSpawnpointsForMapWithAssemblyAndAircraftAndUfo(verbose, md, asmName, aircraft, ufo);
468  tested += 1;
469  }
470  }
471  if (tested < 1) {
472  Com_Printf("CountSpawnpoints - error: Not a valid UFO id: %s\n", ufo);
473  ADD_FAILURE() << "Error: Not a valid ufo id: " << ufo;
474  }
475  } else if (LIST_IsEmpty(md->ufos)) {
476  /* The mapdef defines no UFOs. */
477  Cvar_Set("rm_ufo", "");
478  testCountSpawnpointsForMapWithAssemblyAndAircraftAndUfo(verbose, md, asmName, aircraft, nullptr);
479  } else {
480  /* Test every UFO defined in the mapdef. */
481  LIST_Foreach(md->ufos, const char, ufo) {
482  Cvar_Set("rm_ufo", "%s", Com_GetRandomMapAssemblyNameForCraft(ufo));
483  testCountSpawnpointsForMapWithAssemblyAndAircraftAndUfo(verbose, md, asmName, aircraft, ufo);
484  }
485  }
486 }
487 
488 void GameTest::testCountSpawnpointsForMapWithAssembly(bool verbose, const mapDef_t *md, const char *asmName)
489 {
490  if (asmName) {
491  std::cout << "[ ] testing mapdef: " << md->id << " assembly: " << asmName << std::endl;
492  Com_Printf("CountSpawnpoints - adding test parameter: assembly %s\n", asmName);
493  } else {
494  std::cout << "[ ] testing mapdef: " << md->id << std::endl;
495  }
496 
497  /* Check if we are manually testing a certain aircraft. */
498  if (TEST_ExistsProperty("aircraft")) {
499  const char *aircraft = TEST_GetStringProperty("aircraft");
500  int tested = 0;
501  LIST_Foreach(md->aircraft, const char, s) {
502  if (Q_streq(aircraft, s)) {
503  Cvar_Set("rm_drop", "%s", Com_GetRandomMapAssemblyNameForCraft(aircraft));
504  testCountSpawnpointsForMapWithAssemblyAndAircraft(verbose, md, asmName, aircraft);
505  tested += 1;
506  }
507  }
508  if (tested < 1) {
509  Com_Printf("CountSpawnpoints - error: Not a valid aircraft id: %s\n", aircraft);
510  ADD_FAILURE() << "Error: Not a valid aircraft id: " << aircraft;
511  }
512  } else if (LIST_IsEmpty(md->aircraft)) {
513  /* There is no aircraft defined in the mapdef. */
514  Cvar_Set("rm_drop", "");
515  testCountSpawnpointsForMapWithAssemblyAndAircraft(verbose, md, asmName, nullptr);
516  } else {
517  /* Testing every aircraft defined in the mapdef. */
518  LIST_Foreach(md->aircraft, const char, aircraft) {
519  Cvar_Set("rm_drop", "%s", Com_GetRandomMapAssemblyNameForCraft(aircraft));
520  testCountSpawnpointsForMapWithAssemblyAndAircraft(verbose, md, asmName, aircraft);
521  }
522  }
523 }
524 
525 void GameTest::testCountSpawnpointsForMap(bool verbose, const mapDef_t *md)
526 {
527  Com_Printf("CountSpawnpoints - test start: mapdef %s\n", md->id);
528 
529  /* Check if we are manually testing a certain assembly. */
530  if (TEST_ExistsProperty("assembly")) {
531  const char *asmName = TEST_GetStringProperty("assembly");
532  int tested = 0;
533  LIST_Foreach(md->params, const char, s) {
534  if (Q_streq(asmName, s)) {
535  testCountSpawnpointsForMapWithAssembly(verbose, md, asmName);
536  tested += 1;
537  }
538  }
539  if (tested < 1) {
540  Com_Printf("CountSpawnpoints - error: Not a valid assembly: %s\n", asmName);
541  ADD_FAILURE() << "Error: Not a valid assembly: " << asmName;
542  }
543  } else if (LIST_IsEmpty(md->params)) {
544  /* This is for static maps. */
545  std::cout << "[ ] testing mapdef: " << md->id << std::endl;
546  testCountSpawnpointsForMapWithAssembly(verbose, md, nullptr);
547  } else {
548  /* This is for RMA. */
549  LIST_Foreach(md->params, const char, asmName) {
550  testCountSpawnpointsForMapWithAssembly(verbose, md, asmName);
551  }
552  }
553 }
554 
555 TEST_F(GameTest, CountSpawnpointsStatic)
556 {
557  bool verbose = false;
558  if (TEST_ExistsProperty("verbose"))
559  verbose = true;
560 
561  mapCount = 0;
562  const mapDef_t* md;
563  MapDef_Foreach(md) {
564  /* Exlude RMA maps. */
565  if (md->mapTheme[0] == '+')
566  continue;
567  /* Exclude .baseattack. */
568  if (md->mapTheme[0] == '.')
569  return;
570  testCountSpawnpointsForMap(verbose, md);
571  }
572  std::cout << "[ ] Static maps tested: " << mapCount << std::endl;
573  Com_Printf("CountSpawnpoints - static maps tested: %i\n", mapCount);
574 }
575 
576 TEST_F(GameTest, CountSpawnpointsRMA)
577 {
578  bool verbose = false;
579  if (TEST_ExistsProperty("verbose"))
580  verbose = true;
581 
582  mapCount = 0;
583  const mapDef_t* md;
584 
585  /* Check if we are manually testing a certain mapdef. */
586  if (TEST_ExistsProperty("mapdef-id")) {
587  const char* mapdefId = TEST_GetStringProperty("mapdef-id");
588  int tested = 0;
589  MapDef_Foreach(md) {
590  if (Q_streq(md->id, mapdefId)) {
591  testCountSpawnpointsForMap(verbose, md);
592  tested += 1;
593  }
594  }
595  if (tested < 1) {
596  Com_Printf("CountSpawnpoints - error: Not a valid mapdef: %s\n", mapdefId);
597  ADD_FAILURE() << "Error: Not a valid mapdef: " << mapdefId;
598  }
599  } else {
600  MapDef_Foreach(md) {
601  /* Exlude static maps. */
602  if (md->mapTheme[0] != '+')
603  continue;
604  /* Exclude .baseattack. */
605  if (md->mapTheme[0] == '.')
606  return;
607 
608  testCountSpawnpointsForMap(verbose, md);
609  }
610  }
611  Com_Printf("CountSpawnpoints - RMA combinations tested: RMA %i\n", mapCount);
612  std::cout << "[ ] RMA combinations tested: " << mapCount << std::endl;
614 }
615 
616 TEST_F(GameTest, DoorTrigger)
617 {
618  const char* mapName = "test_game";
619  ASSERT_NE(-1, FS_CheckFile("maps/%s.bsp", mapName)) << "Map resource '" << mapName << ".bsp' for test is missing.";
620  Edict* e = nullptr;
621  int cnt = 0;
622  int doors = 0;
623 
624  SV_Map(true, mapName, nullptr);
625  while ((e = G_EdictsGetNextInUse(e))) {
626  cnt++;
627  if (e->type != ET_DOOR)
628  continue;
629  if (Q_streq(e->targetname, "left-0")) {
630  ASSERT_TRUE(e->doorState) << "this one is triggered by an actor standing inside of a trigger_touch";
631  } else if (Q_streq(e->targetname, "right-0")) {
632  ASSERT_FALSE(e->doorState) << "this one has a trigger_touch, too - but nobody is touching that trigger yet";
633  } else {
634  ASSERT_TRUE(false) << "both of the used doors have a targetname set";
635  }
636  doors++;
637  }
638 
639  ASSERT_TRUE(cnt > 0);
640  ASSERT_TRUE(doors == 2);
641 }
642 
643 TEST_F(GameTest, Shooting)
644 {
645  const char* mapName = "test_game";
646  ASSERT_NE(-1, FS_CheckFile("maps/%s.bsp", mapName)) << "Map resource '" << mapName << ".bsp' for test is missing.";
647  SV_Map(true, mapName, nullptr);
652 }
653 
654 static int GAMETEST_GetItemCount (const Edict* ent, containerIndex_t container)
655 {
656  const Item* invlist = ent->getContainer(container);
657  int count = 0;
658  while (invlist != nullptr) {
659  count += invlist->getAmount();
660  invlist = invlist->getNext();
661  }
662 
663  return count;
664 }
665 
666 TEST_F(GameTest, VisFlags)
667 {
668  const char* mapName = "test_game";
669  ASSERT_NE(-1, FS_CheckFile("maps/%s.bsp", mapName)) << "Map resource '" << mapName << ".bsp' for test is missing.";
670  int num;
671 
672  SV_Map(true, mapName, nullptr);
673 
674  num = 0;
675  Actor* actor = nullptr;
676  while ((actor = G_EdictsGetNextLivingActorOfTeam(actor, TEAM_ALIEN))) {
677  const teammask_t teamMask = G_TeamToVisMask(actor->getTeam());
678  const bool visible = actor->visflags & teamMask;
679  char* visFlagsBuf = Mem_StrDup(Com_UnsignedIntToBinary(actor->visflags));
680  char* teamMaskBuf = Mem_StrDup(Com_UnsignedIntToBinary(teamMask));
681  ASSERT_EQ(actor->getTeam(), TEAM_ALIEN);
682  ASSERT_TRUE(visible) << "visflags: " << visFlagsBuf << ", teamMask: " << teamMaskBuf;
683  Mem_Free(visFlagsBuf);
684  Mem_Free(teamMaskBuf);
685  num++;
686  }
687 
688  ASSERT_TRUE(num > 0) << "No alien actors found";
689 }
690 
691 TEST_F(GameTest, InventoryForDiedAlien)
692 {
693  const char* mapName = "test_game";
694  ASSERT_NE(-1, FS_CheckFile("maps/%s.bsp", mapName)) << "Map resource '" << mapName << ".bsp' for test is missing.";
695  Actor* diedEnt;
696  Actor* actor;
697  Edict* floorItems;
698  Item* invlist;
699  int count;
700  SV_Map(true, mapName, nullptr);
702 
703  /* first alien that should die and drop its inventory */
704  diedEnt = G_EdictsGetNextLivingActorOfTeam(nullptr, TEAM_ALIEN);
705  ASSERT_TRUE(nullptr != diedEnt);
706  diedEnt->HP = 0;
707  ASSERT_TRUE(G_ActorDieOrStun(diedEnt, nullptr));
708  ASSERT_TRUE(diedEnt->isDead());
709 
710  /* now try to collect the inventory with a second alien */
712  ASSERT_TRUE(nullptr != actor);
713 
714  /* move to the location of the first died alien to drop the inventory into the same floor container */
715  Player& player = actor->getPlayer();
716  ASSERT_TRUE(G_IsAIPlayer(&player));
717  G_ClientMove(player, 0, actor, diedEnt->pos);
718  ASSERT_TRUE(VectorCompare(actor->pos, diedEnt->pos));
719 
720  floorItems = G_GetFloorItems(actor);
721  ASSERT_TRUE(nullptr != floorItems);
722  ASSERT_EQ(floorItems->getFloor(), actor->getFloor());
723 
724  /* drop everything to floor to make sure we have space in the backpack */
725  G_InventoryToFloor(actor);
726  ASSERT_EQ(0, GAMETEST_GetItemCount(actor, CID_BACKPACK));
727 
728  invlist = actor->getContainer(CID_BACKPACK);
729  ASSERT_TRUE(nullptr == invlist);
730  count = GAMETEST_GetItemCount(actor, CID_FLOOR);
731  if (count > 0) {
732  Item* entryToMove = actor->getFloor();
733  int tx, ty;
734  actor->chr.inv.findSpace(INVDEF(CID_BACKPACK), entryToMove, &tx, &ty, entryToMove);
735  if (tx == NONE)
736  return;
737  Com_Printf("trying to move item %s from floor into backpack to pos %i:%i\n", entryToMove->def()->name, tx, ty);
738  ASSERT_TRUE(G_ActorInvMove(actor, INVDEF(CID_FLOOR), entryToMove, INVDEF(CID_BACKPACK), tx, ty, false));
739  ASSERT_EQ(count - 1, GAMETEST_GetItemCount(actor, CID_FLOOR)) << "item " << entryToMove->def()->name << " could not get moved successfully from floor into backpack";
740  Com_Printf("item %s was removed from floor\n", entryToMove->def()->name);
741  ASSERT_EQ(1, GAMETEST_GetItemCount(actor, CID_BACKPACK)) << "item " << entryToMove->def()->name << " could not get moved successfully from floor into backpack";
742  Com_Printf("item %s was moved successfully into the backpack\n", entryToMove->def()->name);
743  invlist = actor->getContainer(CID_BACKPACK);
744  ASSERT_TRUE(nullptr != invlist);
745  }
746 }
747 
748 TEST_F(GameTest, InventoryWithTwoDiedAliensOnTheSameGridTile)
749 {
750  const char* mapName = "test_game";
751  ASSERT_NE(-1, FS_CheckFile("maps/%s.bsp", mapName)) << "Map resource '" << mapName << ".bsp' for test is missing.";
752  Actor* diedEnt;
753  Actor* diedEnt2;
754  Actor* actor;
755  Edict* floorItems;
756  Item* invlist;
757  int count;
758  SV_Map(true, mapName, nullptr);
760 
761  /* first alien that should die and drop its inventory */
762  diedEnt = G_EdictsGetNextLivingActorOfTeam(nullptr, TEAM_ALIEN);
763  ASSERT_TRUE(nullptr != diedEnt) << "No living actor in the alien team";
764  diedEnt->HP = 0;
765  G_ActorDieOrStun(diedEnt, nullptr);
766  ASSERT_TRUE(diedEnt->isDead()) << "Actor is not dead";
767 
768  /* second alien that should die and drop its inventory */
769  diedEnt2 = G_EdictsGetNextLivingActorOfTeam(nullptr, TEAM_ALIEN);
770  ASSERT_TRUE(nullptr != diedEnt2) << "No living actor in the alien team";
771 
772  /* move to the location of the first died alien to drop the inventory into the same floor container */
773  Player& player = diedEnt2->getPlayer();
774  ASSERT_TRUE(G_IsAIPlayer(&player));
775  G_ClientMove(player, 0, diedEnt2, diedEnt->pos);
776  ASSERT_TRUE(VectorCompare(diedEnt2->pos, diedEnt->pos));
777 
778  diedEnt2->HP = 0;
779  G_ActorDieOrStun(diedEnt2, nullptr);
780  ASSERT_TRUE(diedEnt2->isDead()) << "Actor is not dead";
781 
782  /* now try to collect the inventory with a third alien */
784  ASSERT_TRUE(nullptr != actor) << "No living actor in the alien team";
785 
786  player = actor->getPlayer();
787  ASSERT_TRUE(G_IsAIPlayer(&player)) << "Player is not ai controlled";
788 
789  G_ClientMove(player, 0, actor, diedEnt->pos);
790  ASSERT_TRUE(VectorCompare(actor->pos, diedEnt->pos)) << "Actor is not at the same position as the died entity";
791 
792  floorItems = G_GetFloorItems(actor);
793  ASSERT_TRUE(nullptr != floorItems);
794  ASSERT_EQ(floorItems->getFloor(), actor->getFloor());
795 
796  /* drop everything to floor to make sure we have space in the backpack */
797  G_InventoryToFloor(actor);
798  ASSERT_EQ(0, GAMETEST_GetItemCount(actor, CID_BACKPACK));
799 
800  invlist = actor->getContainer(CID_BACKPACK);
801  ASSERT_TRUE(nullptr == invlist);
802 
803  count = GAMETEST_GetItemCount(actor, CID_FLOOR);
804  if (count > 0) {
805  Item* entryToMove = actor->getFloor();
806  int tx, ty;
807  actor->chr.inv.findSpace(INVDEF(CID_BACKPACK), entryToMove, &tx, &ty, entryToMove);
808  if (tx == NONE)
809  return;
810  Com_Printf("trying to move item %s from floor into backpack to pos %i:%i\n", entryToMove->def()->name, tx, ty);
811  ASSERT_TRUE(G_ActorInvMove(actor, INVDEF(CID_FLOOR), entryToMove, INVDEF(CID_BACKPACK), tx, ty, false));
812  ASSERT_EQ(GAMETEST_GetItemCount(actor, CID_FLOOR), count - 1) << "item " << entryToMove->def()->name << " could not get moved successfully from floor into backpack";
813  Com_Printf("item %s was removed from floor\n", entryToMove->def()->name);
814  ASSERT_EQ(GAMETEST_GetItemCount(actor, CID_BACKPACK), 1) << "item " << entryToMove->def()->name << " could not get moved successfully from floor into backpack";
815  Com_Printf("item %s was moved successfully into the backpack\n", entryToMove->def()->name);
816  invlist = actor->getContainer(CID_BACKPACK);
817  ASSERT_TRUE(nullptr != invlist);
818  }
819 }
820 
821 TEST_F(GameTest, InventoryTempContainerLinks)
822 {
823  const char* mapName = "test_game";
824  ASSERT_NE(-1, FS_CheckFile("maps/%s.bsp", mapName)) << "Map resource '" << mapName << ".bsp' for test is missing.";
825  SV_Map(true, mapName, nullptr);
827 
828  /* first alien that should die and drop its inventory */
830  int nr = 0;
831  const Container* cont = nullptr;
832  while ((cont = actor->chr.inv.getNextCont(cont, true))) {
833  if (cont->id == CID_ARMOUR || cont->id == CID_FLOOR)
834  continue;
835  nr += cont->countItems();
836  }
837  ASSERT_TRUE(nr > 0) << "Could not find any items in the inventory of the actor";
838 
839  ASSERT_TRUE(nullptr == actor->getFloor());
840  G_InventoryToFloor(actor);
841  ASSERT_TRUE(nullptr != actor->getFloor());
842  ASSERT_EQ(G_GetFloorItemFromPos(actor->pos)->getFloor(), actor->getFloor());
843 
844  nr = 0;
845  cont = nullptr;
846  while ((cont = actor->chr.inv.getNextCont(cont, true))) {
847  if (cont->id == CID_ARMOUR || cont->id == CID_FLOOR)
848  continue;
849  nr += cont->countItems();
850  }
851  ASSERT_EQ(0, nr);
852 }
int numGTs
Definition: q_shared.h:568
bool Q_strnull(const char *string)
Definition: shared.h:138
char id[MAX_VAR]
Definition: q_shared.h:342
char name[MAX_VAR]
Definition: q_shared.h:337
Edict * G_EdictsGetNextInUse(Edict *lastEnt)
Iterate through the entities that are in use.
Definition: g_edicts.cpp:166
Item * getFloor() const
Definition: g_edict.h:262
int testCountSpawnpointsGetNum2x2ValueForAircraft(const char *aircraft)
Definition: test_game.cpp:112
const char * targetname
Definition: g_edict.h:126
int FS_CheckFile(const char *fmt,...)
Just returns the filelength and -1 if the file wasn't found.
Definition: files.cpp:298
#define TEAM_PHALANX
Definition: q_shared.h:62
static void TearDownTestCase()
Definition: test_game.cpp:55
char * id
Definition: q_shared.h:463
#define TEAM_ALIEN
Definition: q_shared.h:63
int teams
Definition: q_shared.h:475
static int GAMETEST_GetItemCount(const Edict *ent, containerIndex_t container)
Definition: test_game.cpp:654
cvar_t * sv_maxclients
Definition: g_main.cpp:43
Definition: game.h:45
csi_t csi
Definition: common.cpp:39
int activeTeam
Definition: g_local.h:101
bool isDead() const
Definition: g_edict.h:362
character_t chr
Definition: g_edict.h:116
static void SetUpTestCase()
Definition: test_game.cpp:41
int doorState
Definition: g_edict.h:158
void G_ClientMove(const Player &player, int visTeam, Actor *actor, const pos3_t to)
Generates the client events that are send over the netchannel to move an actor.
Definition: g_move.cpp:307
memPool_t * sv_genericPool
Definition: sv_main.cpp:55
void SetUp()
Definition: test_game.cpp:69
void SV_Map(bool day, const char *levelstring, const char *assembly, bool verbose=true)
Change the server to a new map, taking all connected clients along with it.
Definition: sv_init.cpp:113
const objDef_t * def(void) const
Definition: inv_shared.h:469
#define CID_ARMOUR
Definition: inv_shared.h:54
void Com_ParseScripts(bool onlyServer)
Definition: scripts.cpp:3641
int FS_LoadFile(const char *path, byte **buffer)
Filenames are relative to the quake search path.
Definition: files.cpp:384
#define TEAM_CIVILIAN
Definition: q_shared.h:61
void Com_Printf(const char *const fmt,...)
Definition: common.cpp:386
linkedList_t * gameTypes
Definition: q_shared.h:476
#define Mem_StrDup(in)
Definition: mem.h:48
Item * getNext() const
Definition: inv_shared.h:451
gltexunit_t texunits[MAX_GL_TEXUNITS]
Definition: r_state.h:114
void testCountSpawnpointsForMapInSingleplayerMode(bool verbose, const mapDef_t *md, const char *asmName, const char *aircraft, const char *ufo)
Definition: test_game.cpp:304
cvar_t * masterserver_url
Definition: common.cpp:57
void TearDown()
Definition: test_game.cpp:73
cvarlist_t cvars[MAX_CVARLISTINGAMETYPE]
Definition: q_shared.h:344
const char * Com_GetRandomMapAssemblyNameForCraft(const char *craftID)
Returns the name of an aircraft or an ufo that is used in the ump files for the random map assembly...
Definition: scripts.cpp:3299
voidpf void * buf
Definition: ioapi.h:42
#define CVAR_ARCHIVE
Definition: cvar.h:40
bool singleplayer
Definition: q_shared.h:481
#define TEAM_MAX_HUMAN
Definition: q_shared.h:64
Item * getContainer(const containerIndex_t idx) const
Definition: g_edict.h:243
#define MAX_CLIENTS
Definition: q_shared.h:299
int getTeam() const
Definition: g_edict.h:269
item instance data, with linked list capability
Definition: inv_shared.h:402
serverInstanceGame_t * sv
Definition: sv_init.cpp:36
int testCountSpawnpointsGetNumteamValueForAircraft(const char *aircraft)
Definition: test_game.cpp:134
void G_InventoryToFloor(Edict *ent)
Move items to adjacent locations if the containers on the current floor edict are full...
void testCountSpawnpointsForMapWithAssembly(bool verbose, const mapDef_t *md, const char *asmName)
Definition: test_game.cpp:488
#define MAX_INFO_STRING
Definition: infostring.h:36
gltexunit_t * active_texunit
Definition: r_state.h:117
cvar_t * Cvar_Get(const char *var_name, const char *var_value, int flags, const char *desc)
Init or return a cvar.
Definition: cvar.cpp:342
GLsizei size
Definition: r_gl.h:152
#define OBJZERO(obj)
Definition: shared.h:178
void TEST_Shutdown(void)
Definition: test_shared.cpp:34
byte num_spawnpoints[MAX_TEAMS]
Definition: g_local.h:116
void testCountSpawnpointsForMapWithAssemblyAndAircraftAndUfo(bool verbose, const mapDef_t *md, const char *asmName, const char *aircraft, const char *ufo)
Definition: test_game.cpp:406
teammask_t visflags
Definition: g_edict.h:82
TEST_F(GameTest, SpawnAndConnect)
Definition: test_game.cpp:78
bool multiplayer
Definition: q_shared.h:474
gametype_t gts[MAX_GAMETYPES]
Definition: q_shared.h:567
void testCountSpawnpointsForMapInMultiplayerMode(bool verbose, const mapDef_t *md, const char *asmName, const char *aircraft, const char *ufo)
Definition: test_game.cpp:180
pos3_t pos
Definition: g_edict.h:55
#define CVAR_NOSET
Definition: cvar.h:43
void testCountSpawnpointsForMapWithAssemblyAndAircraft(bool verbose, const mapDef_t *md, const char *asmName, const char *aircraft)
Definition: test_game.cpp:453
linkedList_t * aircraft
Definition: q_shared.h:492
int num_cvars
Definition: q_shared.h:345
#define Mem_CreatePool(name)
Definition: mem.h:32
An Edict of type Actor.
Definition: g_edict.h:348
#define CID_FLOOR
Definition: inv_shared.h:55
Edict * G_GetFloorItemFromPos(const pos3_t pos)
Callback to G_GetEdictFromPos() for given position, used to get items from position.
Definition: g_inventory.cpp:48
int getAmount() const
Definition: inv_shared.h:463
#define INVDEF(containerID)
Definition: cl_shared.h:47
int countItems() const
Count the number of items in the Container.
Definition: inv_shared.cpp:681
void testCountSpawnpointsForMap(bool verbose, const mapDef_t *md)
Definition: test_game.cpp:525
const char * name
Definition: inv_shared.h:267
bool G_ActorInvMove(Actor *actor, const invDef_t *fromContType, Item *fItem, const invDef_t *toContType, int tx, int ty, bool checkaction)
Moves an item inside an inventory. Floors are handled special.
Definition: g_actor.cpp:506
#define CID_BACKPACK
Definition: inv_shared.h:51
QGL_EXTERN GLuint count
Definition: r_gl.h:99
#define VectorCompare(a, b)
Definition: vector.h:63
#define G_TeamToVisMask(team)
Definition: g_local.h:143
int32_t containerIndex_t
Definition: inv_shared.h:46
const char * Com_UnsignedIntToBinary(uint32_t x)
Definition: common.cpp:1021
void SV_ClearWorld(void)
Clear physics interaction links.
Definition: sv_world.cpp:81
char * mapTheme
Definition: q_shared.h:464
bool TEST_ExistsProperty(const char *name)
static int mapCount
Definition: test_game.cpp:37
memPool_t * com_networkPool
Definition: common.cpp:74
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
const char * TEST_GetStringProperty(const char *name)
const Container * getNextCont(const Container *prev, bool inclTemp=false) const
Definition: inv_shared.cpp:722
void TEST_Init(void)
Definition: test_shared.cpp:72
void SV_InitGameProgs(void)
Init the game subsystem for a new map.
Definition: sv_game.cpp:769
QGL_EXTERN GLuint GLsizei GLsizei GLint GLenum GLchar * name
Definition: r_gl.h:110
entity_type_t type
Definition: g_edict.h:81
#define Mem_Free(ptr)
Definition: mem.h:35
const char int mode
Definition: ioapi.h:41
cvar_t * port
Definition: common.cpp:58
linkedList_t * ufos
Definition: q_shared.h:491
#define LIST_Foreach(list, type, var)
Iterates over a linked list, it's safe to delete the returned entry from the list while looping over ...
Definition: list.h:41
unsigned int teammask_t
Definition: g_vis.h:30
char value[MAX_VAR]
Definition: q_shared.h:338
Inventory inv
Definition: chr_shared.h:392
#define MASTER_SERVER
Definition: common.h:124
bool G_ActorDieOrStun(Actor *actor, Edict *attacker)
Reports and handles death or stun of an actor. If the HP of an actor is zero the actor will die...
Definition: g_actor.cpp:435
rstate_t r_state
Definition: r_main.cpp:48
byte num_2x2spawnpoints[MAX_TEAMS]
Definition: g_local.h:117
#define MapDef_Foreach(var)
Definition: q_shared.h:505
Edict * G_GetFloorItems(Edict *ent)
Prepares a list of items on the floor at given entity position.
Definition: g_inventory.cpp:59
const char * classname
Definition: g_edict.h:67
cvar_t * Cvar_Set(const char *varName, const char *value,...)
Sets a cvar value.
Definition: cvar.cpp:615
#define NONE
Definition: defines.h:68
#define Q_streq(a, b)
Definition: shared.h:136
bool LIST_IsEmpty(const linkedList_t *list)
Checks whether the given list is empty.
Definition: list.cpp:335
Player * G_PlayerGetNextHuman(Player *lastPlayer)
Iterate through the list of players.
Definition: g_client.cpp:58
Definition: g_edict.h:45
void SV_ShutdownGameProgs(void)
Called when either the entire server is being killed, or it is changing to a different game directory...
Definition: sv_game.cpp:703
uint8_t byte
Definition: ufotypes.h:34
#define G_IsAIPlayer(player)
Definition: g_local.h:142
bool campaign
Definition: q_shared.h:480
serverInstanceStatic_t svs
Definition: sv_init.cpp:35
#define DOUBLEQUOTE(x)
Definition: shared.h:90
#define CVAR_SERVERINFO
Definition: cvar.h:42
static const char * mapName
level_locals_t level
Definition: g_main.cpp:38
int maxAliens
Definition: q_shared.h:483
int HP
Definition: g_edict.h:89
void FS_FreeFile(void *buffer)
Definition: files.cpp:411
int Sys_Milliseconds(void)
Definition: unix_shared.cpp:41
int testCountSpawnpointsGetNumteamValueForUFO(const char *ufo)
Definition: test_game.cpp:152
#define PORT_SERVER
Definition: common.h:137
linkedList_t * params
Definition: q_shared.h:465
game_export_t * ge
Definition: server.h:92