UFO: Alien Invasion
test_game.cpp
Go to the documentation of this file.
1
6/*
7Copyright (C) 2002-2022 UFO: Alien Invasion.
8
9This program is free software; you can redistribute it and/or
10modify it under the terms of the GNU General Public License
11as published by the Free Software Foundation; either version 2
12of the License, or (at your option) any later version.
13
14This program is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17
18See the GNU General Public License for more details.
19
20You should have received a copy of the GNU General Public License
21along with this program; if not, write to the Free Software
22Foundation, 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
37static int mapCount = 0;
38
39class GameTest: public ::testing::Test {
40protected:
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() {
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);
67 int testCountSpawnpointsGetNum2x2ValueForAircraft(const char *aircraft);
68
69 void SetUp() {
70 OBJZERO(*sv);
71 }
72
73 void TearDown() {
75 }
76};
77
78TEST_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 */
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
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
180void 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
304void 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
406void 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
453void 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)) {
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) {
483 testCountSpawnpointsForMapWithAssemblyAndAircraftAndUfo(verbose, md, asmName, aircraft, ufo);
484 }
485 }
486}
487
488void 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
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
555TEST_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
576TEST_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
616TEST_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
643TEST_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
654static 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
666TEST_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
691TEST_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 */
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);
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
748TEST_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 */
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
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
821TEST_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}
#define INVDEF(containerID)
Definition: cl_shared.h:48
An Edict of type Actor.
Definition: g_edict.h:348
bool isDead() const
Definition: g_edict.h:362
int countItems() const
Count the number of items in the Container.
Definition: inv_shared.cpp:681
Definition: g_edict.h:45
teammask_t visflags
Definition: g_edict.h:82
character_t chr
Definition: g_edict.h:116
const char * classname
Definition: g_edict.h:67
pos3_t pos
Definition: g_edict.h:55
int HP
Definition: g_edict.h:89
int doorState
Definition: g_edict.h:158
int getTeam() const
Definition: g_edict.h:269
Player & getPlayer() const
Definition: g_edict.h:265
const char * targetname
Definition: g_edict.h:126
entity_type_t type
Definition: g_edict.h:81
Item * getContainer(const containerIndex_t idx) const
Definition: g_edict.h:243
Item * getFloor() const
Definition: g_edict.h:262
int testCountSpawnpointsGetNumteamValueForUFO(const char *ufo)
Definition: test_game.cpp:152
void testCountSpawnpointsForMapWithAssemblyAndAircraft(bool verbose, const mapDef_t *md, const char *asmName, const char *aircraft)
Definition: test_game.cpp:453
static void TearDownTestCase()
Definition: test_game.cpp:55
void SetUp()
Definition: test_game.cpp:69
static void SetUpTestCase()
Definition: test_game.cpp:41
void testCountSpawnpointsForMapWithAssemblyAndAircraftAndUfo(bool verbose, const mapDef_t *md, const char *asmName, const char *aircraft, const char *ufo)
Definition: test_game.cpp:406
int testCountSpawnpointsGetNumteamValueForAircraft(const char *aircraft)
Definition: test_game.cpp:134
void testCountSpawnpointsForMapInSingleplayerMode(bool verbose, const mapDef_t *md, const char *asmName, const char *aircraft, const char *ufo)
Definition: test_game.cpp:304
int testCountSpawnpointsGetNum2x2ValueForAircraft(const char *aircraft)
Definition: test_game.cpp:112
void testCountSpawnpointsForMap(bool verbose, const mapDef_t *md)
Definition: test_game.cpp:525
void testCountSpawnpointsForMapInMultiplayerMode(bool verbose, const mapDef_t *md, const char *asmName, const char *aircraft, const char *ufo)
Definition: test_game.cpp:180
void TearDown()
Definition: test_game.cpp:73
void testCountSpawnpointsForMapWithAssembly(bool verbose, const mapDef_t *md, const char *asmName)
Definition: test_game.cpp:488
void findSpace(const invDef_t *container, const Item *item, int *const px, int *const py, const Item *ignoredItem) const
Finds space for item in inv at container.
Definition: inv_shared.cpp:876
const Container * getNextCont(const Container *prev, bool inclTemp=false) const
Definition: inv_shared.cpp:722
item instance data, with linked list capability
Definition: inv_shared.h:402
int getAmount() const
Definition: inv_shared.h:463
const objDef_t * def(void) const
Definition: inv_shared.h:469
Item * getNext() const
Definition: inv_shared.h:451
Definition: game.h:46
csi_t csi
Definition: common.cpp:39
cvar_t * port
Definition: common.cpp:58
const char * Com_UnsignedIntToBinary(uint32_t x)
Definition: common.cpp:1021
void Com_Printf(const char *const fmt,...)
Definition: common.cpp:386
memPool_t * com_networkPool
Definition: common.cpp:74
cvar_t * masterserver_url
Definition: common.cpp:57
cvar_t * sv_maxclients
Definition: g_main.cpp:43
#define PORT_SERVER
Definition: common.h:137
#define MASTER_SERVER
Definition: common.h:124
cvar_t * Cvar_Set(const char *varName, const char *value,...)
Sets a cvar value.
Definition: cvar.cpp:615
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
#define CVAR_SERVERINFO
Definition: cvar.h:42
#define CVAR_ARCHIVE
Definition: cvar.h:40
#define CVAR_NOSET
Definition: cvar.h:43
#define NONE
Definition: defines.h:68
int FS_CheckFile(const char *fmt,...)
Just returns the filelength and -1 if the file wasn't found.
Definition: files.cpp:298
int FS_LoadFile(const char *path, byte **buffer)
Filenames are relative to the quake search path.
Definition: files.cpp:384
void FS_FreeFile(void *buffer)
Definition: files.cpp:411
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
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
Player * G_PlayerGetNextHuman(Player *lastPlayer)
Iterate through the list of players.
Definition: g_client.cpp:58
Actor * G_EdictsGetNextLivingActorOfTeam(Actor *lastEnt, const int team)
Iterate through the living actor entities of the given team.
Definition: g_edicts.cpp:216
Edict * G_EdictsGetNextInUse(Edict *lastEnt)
Iterate through the entities that are in use.
Definition: g_edicts.cpp:166
void G_InventoryToFloor(Edict *ent)
Move items to adjacent locations if the containers on the current floor edict are full.
Edict * G_GetFloorItems(Edict *ent)
Prepares a list of items on the floor at given entity position.
Definition: g_inventory.cpp:59
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
level_locals_t level
Definition: g_main.cpp:38
#define G_TeamToVisMask(team)
Definition: g_local.h:143
#define G_IsAIPlayer(player)
Definition: g_local.h:142
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
unsigned int teammask_t
Definition: g_vis.h:30
#define MAX_INFO_STRING
Definition: infostring.h:36
#define CID_BACKPACK
Definition: inv_shared.h:51
#define CID_ARMOUR
Definition: inv_shared.h:54
int32_t containerIndex_t
Definition: inv_shared.h:46
#define CID_FLOOR
Definition: inv_shared.h:55
voidpf void uLong size
Definition: ioapi.h:42
voidpf void * buf
Definition: ioapi.h:42
const char int mode
Definition: ioapi.h:41
bool LIST_IsEmpty(const linkedList_t *list)
Checks whether the given list is empty.
Definition: list.cpp:335
#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
#define Mem_Free(ptr)
Definition: mem.h:35
#define Mem_CreatePool(name)
Definition: mem.h:32
#define Mem_StrDup(in)
Definition: mem.h:48
#define MAX_CLIENTS
Definition: q_shared.h:299
#define TEAM_PHALANX
Definition: q_shared.h:62
#define TEAM_ALIEN
Definition: q_shared.h:63
#define MapDef_Foreach(var)
Definition: q_shared.h:505
@ ET_DOOR
Definition: q_shared.h:156
#define TEAM_MAX_HUMAN
Definition: q_shared.h:64
#define TEAM_CIVILIAN
Definition: q_shared.h:61
QGL_EXTERN GLuint count
Definition: r_gl.h:99
QGL_EXTERN GLint i
Definition: r_gl.h:113
QGL_EXTERN GLuint GLsizei GLsizei GLint GLenum GLchar * name
Definition: r_gl.h:110
rstate_t r_state
Definition: r_main.cpp:48
void Com_ParseScripts(bool onlyServer)
Definition: scripts.cpp:3619
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:3277
memPool_t * sv_genericPool
Definition: sv_main.cpp:55
void SV_ClearWorld(void)
Clear physics interaction links.
Definition: sv_world.cpp:81
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
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
void SV_InitGameProgs(void)
Init the game subsystem for a new map.
Definition: sv_game.cpp:769
serverInstanceGame_t * sv
Definition: sv_init.cpp:36
serverInstanceStatic_t svs
Definition: sv_init.cpp:35
#define Q_streq(a, b)
Definition: shared.h:136
bool Q_strnull(const char *string)
Definition: shared.h:138
#define DOUBLEQUOTE(x)
Definition: shared.h:90
#define OBJZERO(obj)
Definition: shared.h:178
Inventory inv
Definition: chr_shared.h:411
int numGTs
Definition: q_shared.h:568
gametype_t gts[MAX_GAMETYPES]
Definition: q_shared.h:567
char value[MAX_VAR]
Definition: q_shared.h:338
char name[MAX_VAR]
Definition: q_shared.h:337
cvarlist_t cvars[MAX_CVARLISTINGAMETYPE]
Definition: q_shared.h:344
int num_cvars
Definition: q_shared.h:345
char id[MAX_VAR]
Definition: q_shared.h:342
int activeTeam
Definition: g_local.h:101
byte num_2x2spawnpoints[MAX_TEAMS]
Definition: g_local.h:117
byte num_spawnpoints[MAX_TEAMS]
Definition: g_local.h:116
linkedList_t * gameTypes
Definition: q_shared.h:476
linkedList_t * aircraft
Definition: q_shared.h:492
int teams
Definition: q_shared.h:475
char * mapTheme
Definition: q_shared.h:464
linkedList_t * ufos
Definition: q_shared.h:491
char * id
Definition: q_shared.h:463
int maxAliens
Definition: q_shared.h:483
bool campaign
Definition: q_shared.h:480
linkedList_t * params
Definition: q_shared.h:465
bool multiplayer
Definition: q_shared.h:474
bool singleplayer
Definition: q_shared.h:481
const char * name
Definition: inv_shared.h:267
gltexunit_t * active_texunit
Definition: r_state.h:117
gltexunit_t texunits[MAX_GL_TEXUNITS]
Definition: r_state.h:114
game_export_t * ge
Definition: server.h:92
int Sys_Milliseconds(void)
Definition: unix_shared.cpp:41
static int mapCount
Definition: test_game.cpp:37
static int GAMETEST_GetItemCount(const Edict *ent, containerIndex_t container)
Definition: test_game.cpp:654
TEST_F(GameTest, SpawnAndConnect)
Definition: test_game.cpp:78
static const char * mapName
void TEST_Shutdown(void)
Definition: test_shared.cpp:34
bool TEST_ExistsProperty(const char *name)
const char * TEST_GetStringProperty(const char *name)
void TEST_Init(void)
Definition: test_shared.cpp:72
#define VectorCompare(a, b)
Definition: vector.h:63