1 #include "Explosion_Control.h"
2 #include "Structure.h"
3 #include "TileDef.h"
4 #include "WorldDef.h"
5 #include "WorldMan.h"
6 #include "Structure_Wrap.h"
7 #include "Isometric_Utils.h"
8 #include "Overhead.h"
9 #include "RenderWorld.h"
10 #include "StrategicMap.h"
11 #include "Rotting_Corpses.h"
12
13
IsRoofPresentAtGridno(INT16 sGridNo)14 BOOLEAN IsRoofPresentAtGridno( INT16 sGridNo )
15 {
16 return FindStructure(sGridNo, STRUCTURE_ROOF) != NULL;
17 }
18
19
IsJumpableWindowPresentAtGridNo(INT32 sGridNo,INT8 bStartingDir)20 BOOLEAN IsJumpableWindowPresentAtGridNo( INT32 sGridNo, INT8 bStartingDir)
21 {
22 STRUCTURE const* pStructure = FindStructure( sGridNo, STRUCTURE_WALLNWINDOW );
23 const BOOLEAN fIntactWindowsAlso = false; // TODO
24
25 if ( pStructure )
26 {
27 if (!(pStructure->fFlags & STRUCTURE_WALLNWINDOW) || (pStructure->fFlags & STRUCTURE_SPECIAL)) return false;
28
29 switch(bStartingDir)
30 {
31 case SOUTH:
32 case NORTH:
33 if (pStructure->ubWallOrientation != OUTSIDE_TOP_LEFT &&
34 pStructure->ubWallOrientation != INSIDE_TOP_LEFT)
35 {
36 return false;
37 }
38 break;
39 case EAST:
40 case WEST:
41 if (pStructure->ubWallOrientation != OUTSIDE_TOP_RIGHT &&
42 pStructure->ubWallOrientation != INSIDE_TOP_RIGHT)
43 {
44 return false;
45 }
46 break;
47 }
48
49 // XXX left out 1.13 prison window check, hope STRUCTURE_OPEN is enough
50 if ( fIntactWindowsAlso || ( pStructure->fFlags & STRUCTURE_OPEN ) ) return true;
51 }
52
53 return( FALSE );
54 }
55
IsJumpableFencePresentAtGridno(INT16 sGridNo)56 BOOLEAN IsJumpableFencePresentAtGridno( INT16 sGridNo )
57 {
58 STRUCTURE * pStructure;
59
60 pStructure = FindStructure( sGridNo, STRUCTURE_OBSTACLE );
61
62 if ( pStructure )
63 {
64 if ( pStructure->fFlags & STRUCTURE_FENCE && !(pStructure->fFlags & STRUCTURE_SPECIAL) )
65 {
66 return( TRUE );
67 }
68 if ( pStructure->pDBStructureRef->pDBStructure->ubArmour == MATERIAL_SANDBAG &&
69 StructureHeight( pStructure ) < 2 )
70 {
71 return( TRUE );
72 }
73 }
74
75 return( FALSE );
76 }
77
GetWallStructOfSameOrientationAtGridno(GridNo const grid_no,INT8 const orientation)78 STRUCTURE* GetWallStructOfSameOrientationAtGridno(GridNo const grid_no, INT8 const orientation)
79 {
80 FOR_EACH_STRUCTURE(pStructure, grid_no, STRUCTURE_WALLSTUFF)
81 {
82 if (pStructure->ubWallOrientation != orientation) continue;
83
84 STRUCTURE* const base = FindBaseStructure(pStructure);
85 if (!base) continue;
86
87 return base;
88 }
89 return 0;
90 }
91
92
IsDoorVisibleAtGridNo(INT16 sGridNo)93 BOOLEAN IsDoorVisibleAtGridNo( INT16 sGridNo )
94 {
95 STRUCTURE *pStructure;
96 INT16 sNewGridNo;
97
98 pStructure = FindStructure( sGridNo, STRUCTURE_ANYDOOR );
99
100 if ( pStructure != NULL )
101 {
102 // Check around based on orientation
103 switch( pStructure->ubWallOrientation )
104 {
105 case INSIDE_TOP_LEFT:
106 case OUTSIDE_TOP_LEFT:
107
108 // Here, check north direction
109 sNewGridNo = NewGridNo( sGridNo, DirectionInc( NORTH ) );
110
111 if ( IsRoofVisible2( sNewGridNo ) )
112 {
113 // OK, now check south, if true, she's not visible
114 sNewGridNo = NewGridNo( sGridNo, DirectionInc( SOUTH ) );
115
116 if ( IsRoofVisible2( sNewGridNo ) )
117 {
118 return( FALSE );
119 }
120 }
121 break;
122
123 case INSIDE_TOP_RIGHT:
124 case OUTSIDE_TOP_RIGHT:
125
126 // Here, check west direction
127 sNewGridNo = NewGridNo( sGridNo, DirectionInc( WEST ) );
128
129 if ( IsRoofVisible2( sNewGridNo ) )
130 {
131 // OK, now check south, if true, she's not visible
132 sNewGridNo = NewGridNo( sGridNo, DirectionInc( EAST ) );
133
134 if ( IsRoofVisible2( sNewGridNo ) )
135 {
136 return( FALSE );
137 }
138 }
139 break;
140
141 }
142
143 }
144
145 // Return true here, even if she does not exist
146 return( TRUE );
147 }
148
149
WallExistsOfTopLeftOrientation(INT16 sGridNo)150 BOOLEAN WallExistsOfTopLeftOrientation( INT16 sGridNo )
151 {
152 // CJC: changing to search only for normal walls, July 16, 1998
153 FOR_EACH_STRUCTURE(pStructure, sGridNo, STRUCTURE_WALL)
154 {
155 // Check orientation
156 if ( pStructure->ubWallOrientation == INSIDE_TOP_LEFT ||
157 pStructure->ubWallOrientation == OUTSIDE_TOP_LEFT )
158 {
159 return( TRUE );
160 }
161 }
162
163 return( FALSE );
164 }
165
WallExistsOfTopRightOrientation(INT16 sGridNo)166 BOOLEAN WallExistsOfTopRightOrientation( INT16 sGridNo )
167 {
168 // CJC: changing to search only for normal walls, July 16, 1998
169 FOR_EACH_STRUCTURE(pStructure, sGridNo, STRUCTURE_WALL)
170 {
171 // Check orientation
172 if ( pStructure->ubWallOrientation == INSIDE_TOP_RIGHT ||
173 pStructure->ubWallOrientation == OUTSIDE_TOP_RIGHT )
174 {
175 return( TRUE );
176 }
177 }
178
179 return( FALSE );
180 }
181
WallOrClosedDoorExistsOfTopLeftOrientation(INT16 sGridNo)182 BOOLEAN WallOrClosedDoorExistsOfTopLeftOrientation( INT16 sGridNo )
183 {
184 FOR_EACH_STRUCTURE(pStructure, sGridNo, STRUCTURE_WALLSTUFF)
185 {
186 // skip it if it's an open door
187 if (!((pStructure->fFlags & STRUCTURE_ANYDOOR) &&
188 (pStructure->fFlags & STRUCTURE_OPEN )))
189 {
190 // Check orientation
191 if (pStructure->ubWallOrientation == INSIDE_TOP_LEFT ||
192 pStructure->ubWallOrientation == OUTSIDE_TOP_LEFT)
193 {
194 return( TRUE );
195 }
196 }
197 }
198
199 return( FALSE );
200 }
201
WallOrClosedDoorExistsOfTopRightOrientation(INT16 sGridNo)202 BOOLEAN WallOrClosedDoorExistsOfTopRightOrientation( INT16 sGridNo )
203 {
204 FOR_EACH_STRUCTURE(pStructure, sGridNo, STRUCTURE_WALLSTUFF)
205 {
206 // skip it if it's an open door
207 if (!((pStructure->fFlags & STRUCTURE_ANYDOOR) && (pStructure->fFlags & STRUCTURE_OPEN)))
208 {
209 // Check orientation
210 if (pStructure->ubWallOrientation == INSIDE_TOP_RIGHT ||
211 pStructure->ubWallOrientation == OUTSIDE_TOP_RIGHT)
212 {
213 return( TRUE );
214 }
215 }
216 }
217
218 return( FALSE );
219 }
220
OpenRightOrientedDoorWithDoorOnRightOfEdgeExists(INT16 sGridNo)221 BOOLEAN OpenRightOrientedDoorWithDoorOnRightOfEdgeExists( INT16 sGridNo )
222 {
223 FOR_EACH_STRUCTURE(pStructure, sGridNo, STRUCTURE_ANYDOOR)
224 {
225 if (!(pStructure->fFlags & STRUCTURE_OPEN)) break;
226 // Check orientation
227 if (pStructure->ubWallOrientation == INSIDE_TOP_RIGHT ||
228 pStructure->ubWallOrientation == OUTSIDE_TOP_RIGHT)
229 {
230 if ((pStructure->fFlags & STRUCTURE_DOOR) ||
231 (pStructure->fFlags & STRUCTURE_DDOOR_RIGHT))
232 {
233 return( TRUE );
234 }
235 }
236 }
237
238 return( FALSE );
239 }
240
OpenLeftOrientedDoorWithDoorOnLeftOfEdgeExists(INT16 sGridNo)241 BOOLEAN OpenLeftOrientedDoorWithDoorOnLeftOfEdgeExists( INT16 sGridNo )
242 {
243 FOR_EACH_STRUCTURE(pStructure, sGridNo, STRUCTURE_ANYDOOR)
244 {
245 if (!(pStructure->fFlags & STRUCTURE_OPEN)) break;
246 // Check orientation
247 if (pStructure->ubWallOrientation == INSIDE_TOP_LEFT ||
248 pStructure->ubWallOrientation == OUTSIDE_TOP_LEFT)
249 {
250 if ((pStructure->fFlags & STRUCTURE_DOOR) ||
251 (pStructure->fFlags & STRUCTURE_DDOOR_LEFT))
252 {
253 return( TRUE );
254 }
255 }
256 }
257
258 return( FALSE );
259 }
260
261
FindCuttableWireFenceAtGridNo(INT16 sGridNo)262 static STRUCTURE* FindCuttableWireFenceAtGridNo(INT16 sGridNo)
263 {
264 STRUCTURE * pStructure;
265
266 pStructure = FindStructure( sGridNo, STRUCTURE_WIREFENCE );
267 if (pStructure != NULL && pStructure->ubWallOrientation != NO_ORIENTATION &&
268 !(pStructure->fFlags & STRUCTURE_OPEN))
269 {
270 return( pStructure );
271 }
272 return( NULL );
273 }
274
CutWireFence(INT16 sGridNo)275 BOOLEAN CutWireFence( INT16 sGridNo )
276 {
277 STRUCTURE * pStructure;
278
279 pStructure = FindCuttableWireFenceAtGridNo( sGridNo );
280 if (pStructure)
281 {
282 pStructure = SwapStructureForPartnerAndStoreChangeInMap(pStructure);
283 if (pStructure)
284 {
285 RecompileLocalMovementCosts( sGridNo );
286 SetRenderFlags( RENDER_FLAG_FULL );
287 return( TRUE );
288 }
289 }
290 return( FALSE );
291 }
292
IsCuttableWireFenceAtGridNo(INT16 sGridNo)293 BOOLEAN IsCuttableWireFenceAtGridNo( INT16 sGridNo )
294 {
295 return( FindCuttableWireFenceAtGridNo( sGridNo ) != NULL );
296 }
297
298
IsRepairableStructAtGridNo(const INT16 sGridNo,SOLDIERTYPE ** const tgt)299 UINT8 IsRepairableStructAtGridNo(const INT16 sGridNo, SOLDIERTYPE** const tgt)
300 {
301 // OK, first look for a vehicle....
302 SOLDIERTYPE* const s = WhoIsThere2(sGridNo, 0);
303 if (tgt != NULL) *tgt = s;
304
305 if (s != NULL && s->uiStatusFlags & SOLDIER_VEHICLE) return 2;
306 // Then for over a robot....
307
308 return( FALSE );
309 }
310
311
GetRefuelableStructAtGridNo(INT16 sGridNo)312 SOLDIERTYPE* GetRefuelableStructAtGridNo(INT16 sGridNo)
313 {
314 // OK, first look for a vehicle....
315 SOLDIERTYPE* const tgt = WhoIsThere2(sGridNo, 0);
316 return tgt != NULL && tgt->uiStatusFlags & SOLDIER_VEHICLE ? tgt : NULL;
317 }
318
FindDoorAtGridNoOrAdjacent(INT16 sGridNo)319 INT16 FindDoorAtGridNoOrAdjacent( INT16 sGridNo )
320 {
321 STRUCTURE *pStructure;
322 STRUCTURE *pBaseStructure;
323 INT16 sTestGridNo;
324
325 sTestGridNo = sGridNo;
326 pStructure = FindStructure( sTestGridNo, STRUCTURE_ANYDOOR );
327 if (pStructure)
328 {
329 pBaseStructure = FindBaseStructure( pStructure );
330 return( pBaseStructure->sGridNo );
331 }
332
333 sTestGridNo = sGridNo + DirectionInc( NORTH );
334 pStructure = FindStructure( sTestGridNo, STRUCTURE_ANYDOOR );
335 if (pStructure)
336 {
337 pBaseStructure = FindBaseStructure( pStructure );
338 return( pBaseStructure->sGridNo );
339 }
340
341 sTestGridNo = sGridNo + DirectionInc( WEST );
342 pStructure = FindStructure( sTestGridNo, STRUCTURE_ANYDOOR );
343 if (pStructure)
344 {
345 pBaseStructure = FindBaseStructure( pStructure );
346 return( pBaseStructure->sGridNo );
347 }
348
349 return( NOWHERE );
350 }
351
352
353
IsCorpseAtGridNo(INT16 sGridNo,UINT8 ubLevel)354 BOOLEAN IsCorpseAtGridNo( INT16 sGridNo, UINT8 ubLevel )
355 {
356 if ( GetCorpseAtGridNo( sGridNo , ubLevel ) != NULL )
357 {
358 return( TRUE );
359 }
360 else
361 {
362 return( FALSE );
363 }
364 }
365
366
SetOpenableStructureToClosed(INT16 sGridNo,UINT8 ubLevel)367 BOOLEAN SetOpenableStructureToClosed( INT16 sGridNo, UINT8 ubLevel )
368 {
369 STRUCTURE *pStructure;
370 STRUCTURE *pNewStructure;
371
372 pStructure = FindStructure( sGridNo, STRUCTURE_OPENABLE );
373 if ( !pStructure )
374 {
375 return( FALSE );
376 }
377
378 if ( pStructure->fFlags & STRUCTURE_OPEN )
379 {
380 pNewStructure = SwapStructureForPartner(pStructure);
381 if ( pNewStructure != NULL)
382 {
383 RecompileLocalMovementCosts( sGridNo );
384 SetRenderFlags( RENDER_FLAG_FULL );
385 }
386 }
387 // else leave it as is!
388 return( TRUE );
389 }
390