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