UFO: Alien Invasion
Loading...
Searching...
No Matches
test_routing.cpp
Go to the documentation of this file.
1
4
5/*
6Copyright (C) 2002-2025 UFO: Alien Invasion.
7
8This program is free software; you can redistribute it and/or
9modify it under the terms of the GNU General Public License
10as published by the Free Software Foundation; either version 2
11of the License, or (at your option) any later version.
12
13This program is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16
17See the GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License
20along with this program; if not, write to the Free Software
21Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22
23*/
24
25#include "test_shared.h"
26
27#include "../common/common.h"
28#include "../common/cmodel.h"
29#include "../common/grid.h"
30#include "../game/g_local.h"
31#include "../game/g_edicts.h"
32#include "../game/g_utils.h"
33#include "../server/server.h"
34
35class RoutingTest: public ::testing::Test {
36protected:
37 static void SetUpTestCase() {
38 TEST_Init();
39 Com_ParseScripts(true);
40 }
41
42 static void TearDownTestCase() {
44 }
45};
46
49static const char* mapName = "test_routing";
50
51TEST_F(RoutingTest, MapLoading)
52{
53 ASSERT_NE(-1, FS_CheckFile("maps/%s.bsp", mapName)) << "Map resource '" << mapName << ".bsp' for test is missing.";
54 char entityString[MAX_TOKEN_CHARS];
55 CM_LoadMap(mapName, true, "", entityString, &mapData, &mapTiles);
56 CM_LoadMap(mapName, true, "", entityString, &mapData, &mapTiles);
57}
58
60{
61 vec3_t vec;
62 pos3_t pos;
63 pos_t gridPos;
64
65 ASSERT_NE(-1, FS_CheckFile("maps/%s.bsp", mapName)) << "Map resource '" << mapName << ".bsp' for test is missing.";
66 char entityString[MAX_TOKEN_CHARS];
67 CM_LoadMap(mapName, true, "", entityString, &mapData, &mapTiles);
68 CM_LoadMap(mapName, true, "", entityString, &mapData, &mapTiles);
69
70 VectorSet(vec, 16, 16, 48);
71 VecToPos(vec, pos);
72 ASSERT_EQ(pos[0], 128);
73 ASSERT_EQ(pos[1], 128);
74 ASSERT_EQ(pos[2], 0);
75
76 VectorSet(vec, 80, 16, 80);
77 VecToPos(vec, pos);
78 ASSERT_EQ(pos[0], 130);
79 ASSERT_EQ(pos[1], 128);
80 ASSERT_EQ(pos[2], 1);
81
82 gridPos = Grid_Fall(mapData.routing, ACTOR_SIZE_NORMAL, pos);
83 ASSERT_EQ(gridPos, 1);
84
85 {
86 const byte crouchingState = 0;
87 const int maxTUs = MAX_ROUTE_TUS;
88 int lengthStored;
89 pos3_t to;
91
92 VectorSet(vec, 80, 80, 32);
93 VecToPos(vec, pos);
94
95 Grid_CalcPathing(mapData.routing, ACTOR_SIZE_NORMAL, path, pos, maxTUs, nullptr);
96 Grid_MoveStore(path);
97
98 /* move downwards */
99 {
100 int lengthUnstored;
101 VectorSet(vec, 80, 48, 32);
102 VecToPos(vec, to);
103
104 lengthUnstored = Grid_MoveLength(path, to, crouchingState, false);
105 lengthStored = Grid_MoveLength(path, to, crouchingState, true);
106 ASSERT_EQ(lengthUnstored, lengthStored);
107 ASSERT_EQ(lengthStored, TU_MOVE_STRAIGHT);
108 }
109 /* try to move three steps upwards - there is a brush*/
110 {
111 VectorSet(vec, 80, 176, 32);
112 VecToPos(vec, to);
113
114 lengthStored = Grid_MoveLength(path, to, crouchingState, true);
115 ASSERT_EQ(lengthStored, ROUTING_NOT_REACHABLE);
116 }
117 /* try move into the nodraw */
118 {
119 VectorSet(vec, 48, 16, 32);
120 VecToPos(vec, to);
121
122 lengthStored = Grid_MoveLength(path, to, crouchingState, true);
123 ASSERT_EQ(lengthStored, ROUTING_NOT_REACHABLE);
124 }
125 /* move into the lightclip */
126 {
127 VectorSet(vec, 48, 48, 32);
128 VecToPos(vec, to);
129
130 lengthStored = Grid_MoveLength(path, to, crouchingState, true);
131 ASSERT_EQ(lengthStored, TU_MOVE_DIAGONAL);
132 }
133 /* move into the passable */
134 {
135 VectorSet(vec, 144, 48, 32);
136 VecToPos(vec, to);
137
138 lengthStored = Grid_MoveLength(path, to, crouchingState, true);
139 ASSERT_EQ(lengthStored, TU_MOVE_DIAGONAL + TU_MOVE_STRAIGHT);
140 }
141 /* go to the other side - diagonal, followed by six straight moves */
142 {
143 VectorSet(vec, -16, 48, 32);
144 VecToPos(vec, to);
145
146 lengthStored = Grid_MoveLength(path, to, crouchingState, true);
147 ASSERT_EQ(lengthStored, 6 * TU_MOVE_STRAIGHT + TU_MOVE_DIAGONAL);
148 }
149 /* try to walk out of the map */
150 {
151 VectorSet(vec, 48, 272, 32);
152 VecToPos(vec, to);
153
154 lengthStored = Grid_MoveLength(path, to, crouchingState, true);
155 ASSERT_EQ(lengthStored, ROUTING_NOT_REACHABLE);
156 }
157 /* walk to the map border */
158 {
159 VectorSet(vec, 48, 240, 32);
160 VecToPos(vec, to);
161
162 lengthStored = Grid_MoveLength(path, to, crouchingState, true);
163 ASSERT_EQ(lengthStored, 4 * TU_MOVE_STRAIGHT + TU_MOVE_DIAGONAL);
164 }
165 /* walk a level upwards */
166 {
167 VectorSet(vec, 240, 80, 96);
168 VecToPos(vec, to);
169
170 lengthStored = Grid_MoveLength(path, to, crouchingState, true);
171 ASSERT_EQ(lengthStored, 5 * TU_MOVE_STRAIGHT);
172 }
173 /* move to the door (not a func_door) */
174 {
175 VectorSet(vec, 176, -80, 32);
176 VecToPos(vec, to);
177
178 lengthStored = Grid_MoveLength(path, to, crouchingState, true);
179 ASSERT_EQ(lengthStored, 4 * TU_MOVE_STRAIGHT + 2 * TU_MOVE_DIAGONAL);
180 }
181 /* move into the trigger_touch */
182 {
183 VectorSet(vec, -48, -80, 32);
184 VecToPos(vec, to);
185
186 lengthStored = Grid_MoveLength(path, to, crouchingState, true);
187 ASSERT_EQ(lengthStored, 5 * TU_MOVE_STRAIGHT + 3 * TU_MOVE_DIAGONAL);
188 }
189 /* try to walk into the actorclip */
190 {
191 VectorSet(vec, -48, -48, 32);
192 VecToPos(vec, to);
193
194 lengthStored = Grid_MoveLength(path, to, crouchingState, true);
195 ASSERT_EQ(lengthStored, ROUTING_NOT_REACHABLE);
196 }
197 }
198}
199
200TEST_F(RoutingTest, MoveEntities)
201{
202 pos3_t pos;
203 vec3_t vec;
206 const byte crouchingState = 0;
207 const int maxTUs = MAX_ROUTE_TUS;
208 forbiddenList.reset();
209
210 SV_Map(true, mapName, nullptr);
211
212 /* starting point */
213 VectorSet(vec, 240, -144, 32);
214 VecToPos(vec, pos);
215
217
218 {
219 Edict* ent = nullptr;
220 while ((ent = G_EdictsGetNextInUse(ent))) {
221 /* Dead 2x2 unit will stop walking, too. */
222 if (ent->type == ET_SOLID) {
223 for (int j = 0; j < ent->forbiddenListSize; j++) {
224 forbiddenList.add(ent->forbiddenListPos[j], (byte*) &ent->fieldSize);
225 }
226 }
227 }
228 }
229
230 {
231 int lengthStored;
232 pos3_t to;
233
234 Grid_CalcPathing(sv->mapData.routing, ACTOR_SIZE_NORMAL, path, pos, maxTUs, &forbiddenList);
235 Grid_MoveStore(path);
236
237 /* walk onto the func_breakable */
238 {
239 VectorSet(vec, 112, -144, 32);
240 VecToPos(vec, to);
241
242 lengthStored = Grid_MoveLength(path, to, crouchingState, true);
243 ASSERT_EQ(lengthStored, 4 * TU_MOVE_STRAIGHT);
244 }
245 /* walk over the func_breakable */
246 {
247 VectorSet(vec, 80, -144, 32);
248 VecToPos(vec, to);
249
250 lengthStored = Grid_MoveLength(path, to, crouchingState, true);
251 ASSERT_EQ(lengthStored, 5 * TU_MOVE_STRAIGHT);
252 }
253 /* walk over the func_breakable */
254 {
255 VectorSet(vec, 16, -144, 32);
256 VecToPos(vec, to);
257
258 lengthStored = Grid_MoveLength(path, to, crouchingState, true);
259 ASSERT_EQ(lengthStored, 7 * TU_MOVE_STRAIGHT);
260 }
261 }
262
263 /* starting point */
264 VectorSet(vec, 144, 144, 32);
265 VecToPos(vec, pos);
266
267 {
268 int lengthStored;
269 pos3_t to;
270
271 Grid_CalcPathing(sv->mapData.routing, ACTOR_SIZE_NORMAL, path, pos, maxTUs, &forbiddenList);
272 Grid_MoveStore(path);
273
274 /* walk through the opened door */
275 {
276 VectorSet(vec, 112, 144, 32);
277 VecToPos(vec, to);
278
279 lengthStored = Grid_MoveLength(path, to, crouchingState, true);
280 ASSERT_EQ(lengthStored, TU_MOVE_STRAIGHT);
281 }
282
283 /* walk around the opened door */
284 {
285 VectorSet(vec, 144, 208, 32);
286 VecToPos(vec, to);
287
288 lengthStored = Grid_MoveLength(path, to, crouchingState, true);
289 ASSERT_EQ(lengthStored, 2 * TU_MOVE_STRAIGHT + TU_MOVE_DIAGONAL);
290 }
291 }
292
294}
295
296/* tests for the new dvec format */
298{
299 short dv1 = 0x0724;
300 ASSERT_EQ(getDVdir(dv1), 0x07);
301 ASSERT_EQ(getDVflags(dv1), 0x02);
302 ASSERT_EQ(getDVz(dv1), 0x04);
303
304 short dv2 = makeDV(6, 3);
305 ASSERT_EQ(dv2, 0x0603);
306
307 dv2 = setDVz(dv2, 4);
308 ASSERT_EQ(dv2, 0x0604);
309}
310
312{
313 ASSERT_EQ(Grid_GetTUsForDirection(0, 0), 2);
314 ASSERT_EQ(Grid_GetTUsForDirection(2, 0), 2);
315 ASSERT_EQ(Grid_GetTUsForDirection(5, 0), 3);
316 ASSERT_EQ(Grid_GetTUsForDirection(5, false), 3);
317 ASSERT_EQ(Grid_GetTUsForDirection(0, 1), 3); /* now crouching */
318 ASSERT_EQ(Grid_GetTUsForDirection(5, 1), 4);
319 ASSERT_EQ(Grid_GetTUsForDirection(5, true), 4);
320 ASSERT_EQ(Grid_GetTUsForDirection(16, 0), 4); /* flying takes twice as much */
321 ASSERT_EQ(Grid_GetTUsForDirection(16, 1), 4); /* flying & crouching is still the same */
322}
static forbiddenList_t forbiddenList
A list of locations that cannot be moved to.
Definition cl_actor.cpp:602
actorSizeEnum_t fieldSize
Definition g_edict.h:141
pos3_t * forbiddenListPos
Definition g_edict.h:173
entity_type_t type
Definition g_edict.h:81
int forbiddenListSize
Definition g_edict.h:175
static void TearDownTestCase()
static void SetUpTestCase()
Common model code header (for bsp and others).
void CM_LoadMap(const char *tiles, bool day, const char *pos, const char *entityString, mapData_t *mapData, mapTiles_t *mapTiles)
Loads in the map and all submodels.
Definition bsp.cpp:860
definitions common between client and server, but not game lib
#define TU_MOVE_DIAGONAL
Definition defines.h:75
#define MAX_ROUTE_TUS
Definition defines.h:83
#define ROUTING_NOT_REACHABLE
Definition defines.h:283
#define TU_MOVE_STRAIGHT
Definition defines.h:74
#define ACTOR_SIZE_NORMAL
Definition defines.h:302
#define MAX_TOKEN_CHARS
Definition defines.h:372
int FS_CheckFile(const char *fmt,...)
Just returns the filelength and -1 if the file wasn't found.
Definition files.cpp:298
Edict * G_EdictsGetNextInUse(Edict *lastEnt)
Iterate through the entities that are in use.
Definition g_edicts.cpp:166
functions to handle the storage and lifecycle of all edicts in the game module.
Local definitions for game module.
void G_CompleteRecalcRouting(void)
Definition g_utils.cpp:464
Misc utility functions for game module.
void Grid_CalcPathing(const Routing &routing, const actorSizeEnum_t actorSize, pathing_t *path, const pos3_t from, int maxTUs, forbiddenList_t *fb_list)
Recalculate the pathing table for the given actor(-position).
Definition grid.cpp:497
pos_t Grid_MoveLength(const pathing_t *path, const pos3_t to, byte crouchingState, bool stored)
Return the needed TUs to walk to a given position.
Definition grid.cpp:698
int Grid_GetTUsForDirection(const int dir, bool crouched)
Returns the amounts of TUs that are needed to perform one step into the given direction.
Definition grid.cpp:766
pos_t Grid_Fall(const Routing &routing, const actorSizeEnum_t actorSize, const pos3_t pos)
Calculated the new height level when something falls down from a certain position.
Definition grid.cpp:783
void Grid_MoveStore(pathing_t *path)
Caches the calculated move.
Definition grid.cpp:683
Battlescape grid functions.
#define getDVflags(dv)
Definition mathlib.h:250
#define makeDV(dir, z)
Definition mathlib.h:247
#define getDVz(dv)
Definition mathlib.h:251
#define setDVz(dv, z)
Definition mathlib.h:248
#define getDVdir(dv)
Definition mathlib.h:249
#define VecToPos(v, p)
Map boundary is +/- MAX_WORLD_WIDTH - to get into the positive area we add the possible max negative ...
Definition mathlib.h:100
#define Mem_AllocType(type)
Definition mem.h:39
@ ET_SOLID
Definition q_shared.h:166
void Com_ParseScripts(bool onlyServer)
Definition scripts.cpp:3619
Main server include file.
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:681
serverInstanceGame_t * sv
Definition sv_init.cpp:36
A list of locations that cannot be moved to.
Definition grid.h:35
static mapTiles_t mapTiles
static const char * mapName
static mapData_t mapData
TEST_F(RoutingTest, MapLoading)
void TEST_Shutdown(void)
void TEST_Init(void)
pos_t pos3_t[3]
Definition ufotypes.h:58
byte pos_t
Definition ufotypes.h:57
vec_t vec3_t[3]
Definition ufotypes.h:39
#define VectorSet(v, x, y, z)
Definition vector.h:59