Structure Wrap.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570
  1. #ifdef PRECOMPILEDHEADERS
  2. #include "Tactical All.h"
  3. #else
  4. #include <stdio.h>
  5. #include "debug.h"
  6. #include "wcheck.h"
  7. #include "worlddef.h"
  8. #include "worldman.h"
  9. #include "structure wrap.h"
  10. #include "isometric utils.h"
  11. #include "worldman.h"
  12. #include "overhead.h"
  13. #include "renderworld.h"
  14. #include "strategicmap.h"
  15. #include "rotting corpses.h"
  16. #endif
  17. extern BOOLEAN DoesSAMExistHere( INT16 sSectorX, INT16 sSectorY, INT16 sSectorZ, INT16 sGridNo );
  18. BOOLEAN IsFencePresentAtGridno( INT16 sGridNo )
  19. {
  20. if ( FindStructure( sGridNo, STRUCTURE_ANYFENCE ) != NULL )
  21. {
  22. return( TRUE );
  23. }
  24. return( FALSE );
  25. }
  26. BOOLEAN IsRoofPresentAtGridno( INT16 sGridNo )
  27. {
  28. if ( FindStructure( sGridNo, STRUCTURE_ROOF ) != NULL )
  29. {
  30. return( TRUE );
  31. }
  32. return( FALSE );
  33. }
  34. BOOLEAN IsJumpableFencePresentAtGridno( INT16 sGridNo )
  35. {
  36. STRUCTURE * pStructure;
  37. pStructure = FindStructure( sGridNo, STRUCTURE_OBSTACLE );
  38. if ( pStructure )
  39. {
  40. if ( pStructure->fFlags & STRUCTURE_FENCE && !(pStructure->fFlags & STRUCTURE_SPECIAL) )
  41. {
  42. return( TRUE );
  43. }
  44. if ( pStructure->pDBStructureRef->pDBStructure->ubArmour == MATERIAL_SANDBAG && StructureHeight( pStructure ) < 2 )
  45. {
  46. return( TRUE );
  47. }
  48. }
  49. return( FALSE );
  50. }
  51. BOOLEAN IsDoorPresentAtGridno( INT16 sGridNo )
  52. {
  53. if ( FindStructure( sGridNo, STRUCTURE_ANYDOOR ) != NULL )
  54. {
  55. return( TRUE );
  56. }
  57. return( FALSE );
  58. }
  59. BOOLEAN IsTreePresentAtGridno( INT16 sGridNo )
  60. {
  61. if ( FindStructure( sGridNo, STRUCTURE_TREE ) != NULL )
  62. {
  63. return( TRUE );
  64. }
  65. return( FALSE );
  66. }
  67. LEVELNODE *IsWallPresentAtGridno( INT16 sGridNo )
  68. {
  69. LEVELNODE *pNode = NULL;
  70. STRUCTURE * pStructure;
  71. pStructure = FindStructure( sGridNo, STRUCTURE_WALLSTUFF );
  72. if ( pStructure != NULL )
  73. {
  74. pNode = FindLevelNodeBasedOnStructure( sGridNo, pStructure );
  75. }
  76. return( pNode );
  77. }
  78. LEVELNODE *GetWallLevelNodeOfSameOrientationAtGridno( INT16 sGridNo, INT8 ubOrientation )
  79. {
  80. LEVELNODE *pNode = NULL;
  81. STRUCTURE * pStructure;
  82. pStructure = FindStructure( sGridNo, STRUCTURE_WALLSTUFF );
  83. while ( pStructure != NULL )
  84. {
  85. // Check orientation
  86. if ( pStructure->ubWallOrientation == ubOrientation )
  87. {
  88. pNode = FindLevelNodeBasedOnStructure( sGridNo, pStructure );
  89. return( pNode );
  90. }
  91. pStructure = FindNextStructure( pStructure, STRUCTURE_WALLSTUFF );
  92. }
  93. return( NULL );
  94. }
  95. LEVELNODE *GetWallLevelNodeAndStructOfSameOrientationAtGridno( INT16 sGridNo, INT8 ubOrientation, STRUCTURE **ppStructure )
  96. {
  97. LEVELNODE *pNode = NULL;
  98. STRUCTURE * pStructure, * pBaseStructure;
  99. (*ppStructure) = NULL;
  100. pStructure = FindStructure( sGridNo, STRUCTURE_WALLSTUFF );
  101. while ( pStructure != NULL )
  102. {
  103. // Check orientation
  104. if ( pStructure->ubWallOrientation == ubOrientation )
  105. {
  106. pBaseStructure = FindBaseStructure( pStructure );
  107. if (pBaseStructure)
  108. {
  109. pNode = FindLevelNodeBasedOnStructure( pBaseStructure->sGridNo, pBaseStructure );
  110. (*ppStructure) = pBaseStructure;
  111. return( pNode );
  112. }
  113. }
  114. pStructure = FindNextStructure( pStructure, STRUCTURE_WALLSTUFF );
  115. }
  116. return( NULL );
  117. }
  118. BOOLEAN IsDoorVisibleAtGridNo( INT16 sGridNo )
  119. {
  120. STRUCTURE * pStructure;
  121. INT16 sNewGridNo;
  122. pStructure = FindStructure( sGridNo, STRUCTURE_ANYDOOR );
  123. if ( pStructure != NULL )
  124. {
  125. // Check around based on orientation
  126. switch( pStructure->ubWallOrientation )
  127. {
  128. case INSIDE_TOP_LEFT:
  129. case OUTSIDE_TOP_LEFT:
  130. // Here, check north direction
  131. sNewGridNo = NewGridNo( sGridNo, DirectionInc( NORTH ) );
  132. if ( IsRoofVisible2( sNewGridNo ) )
  133. {
  134. // OK, now check south, if true, she's not visible
  135. sNewGridNo = NewGridNo( sGridNo, DirectionInc( SOUTH ) );
  136. if ( IsRoofVisible2( sNewGridNo ) )
  137. {
  138. return( FALSE );
  139. }
  140. }
  141. break;
  142. case INSIDE_TOP_RIGHT:
  143. case OUTSIDE_TOP_RIGHT:
  144. // Here, check west direction
  145. sNewGridNo = NewGridNo( sGridNo, DirectionInc( WEST ) );
  146. if ( IsRoofVisible2( sNewGridNo ) )
  147. {
  148. // OK, now check south, if true, she's not visible
  149. sNewGridNo = NewGridNo( sGridNo, DirectionInc( EAST ) );
  150. if ( IsRoofVisible2( sNewGridNo ) )
  151. {
  152. return( FALSE );
  153. }
  154. }
  155. break;
  156. }
  157. }
  158. // Return true here, even if she does not exist
  159. return( TRUE );
  160. }
  161. BOOLEAN DoesGridnoContainHiddenStruct( INT16 sGridNo, BOOLEAN *pfVisible )
  162. {
  163. // ATE: These are ignored now - always return false
  164. //STRUCTURE *pStructure;
  165. //pStructure = FindStructure( sGridNo, STRUCTURE_HIDDEN );
  166. //if ( pStructure != NULL )
  167. //{
  168. // if ( !(gpWorldLevelData[ sGridNo ].uiFlags & MAPELEMENT_REVEALED ) && !(gTacticalStatus.uiFlags&SHOW_ALL_MERCS) )
  169. // {
  170. // *pfVisible = FALSE;
  171. // }
  172. // else
  173. // {
  174. // *pfVisible = TRUE;
  175. // }//
  176. //
  177. // return( TRUE );
  178. //}
  179. return( FALSE );
  180. }
  181. BOOLEAN IsHiddenStructureVisible( INT16 sGridNo, UINT16 usIndex )
  182. {
  183. // Check if it's a hidden struct and we have not revealed anything!
  184. if ( gTileDatabase[ usIndex ].uiFlags & HIDDEN_TILE )
  185. {
  186. if ( !(gpWorldLevelData[ sGridNo ].uiFlags & MAPELEMENT_REVEALED ) && !(gTacticalStatus.uiFlags&SHOW_ALL_MERCS) )
  187. {
  188. // Return false
  189. return( FALSE );
  190. }
  191. }
  192. return( TRUE );
  193. }
  194. BOOLEAN WallExistsOfTopLeftOrientation( INT16 sGridNo )
  195. {
  196. // CJC: changing to search only for normal walls, July 16, 1998
  197. STRUCTURE * pStructure;
  198. pStructure = FindStructure( sGridNo, STRUCTURE_WALL );
  199. while ( pStructure != NULL )
  200. {
  201. // Check orientation
  202. if ( pStructure->ubWallOrientation == INSIDE_TOP_LEFT || pStructure->ubWallOrientation == OUTSIDE_TOP_LEFT )
  203. {
  204. return( TRUE );
  205. }
  206. pStructure = FindNextStructure( pStructure, STRUCTURE_WALL );
  207. }
  208. return( FALSE );
  209. }
  210. BOOLEAN WallExistsOfTopRightOrientation( INT16 sGridNo )
  211. {
  212. // CJC: changing to search only for normal walls, July 16, 1998
  213. STRUCTURE * pStructure;
  214. pStructure = FindStructure( sGridNo, STRUCTURE_WALL );
  215. while ( pStructure != NULL )
  216. {
  217. // Check orientation
  218. if ( pStructure->ubWallOrientation == INSIDE_TOP_RIGHT || pStructure->ubWallOrientation == OUTSIDE_TOP_RIGHT )
  219. {
  220. return( TRUE );
  221. }
  222. pStructure = FindNextStructure( pStructure, STRUCTURE_WALL );
  223. }
  224. return( FALSE );
  225. }
  226. BOOLEAN WallOrClosedDoorExistsOfTopLeftOrientation( INT16 sGridNo )
  227. {
  228. STRUCTURE * pStructure;
  229. pStructure = FindStructure( sGridNo, STRUCTURE_WALLSTUFF );
  230. while ( pStructure != NULL )
  231. {
  232. // skip it if it's an open door
  233. if ( ! ( ( pStructure->fFlags & STRUCTURE_ANYDOOR ) && ( pStructure->fFlags & STRUCTURE_OPEN ) ) )
  234. {
  235. // Check orientation
  236. if ( pStructure->ubWallOrientation == INSIDE_TOP_LEFT || pStructure->ubWallOrientation == OUTSIDE_TOP_LEFT )
  237. {
  238. return( TRUE );
  239. }
  240. }
  241. pStructure = FindNextStructure( pStructure, STRUCTURE_WALLSTUFF );
  242. }
  243. return( FALSE );
  244. }
  245. BOOLEAN WallOrClosedDoorExistsOfTopRightOrientation( INT16 sGridNo )
  246. {
  247. STRUCTURE * pStructure;
  248. pStructure = FindStructure( sGridNo, STRUCTURE_WALLSTUFF );
  249. while ( pStructure != NULL )
  250. {
  251. // skip it if it's an open door
  252. if ( ! ( ( pStructure->fFlags & STRUCTURE_ANYDOOR ) && ( pStructure->fFlags & STRUCTURE_OPEN ) ) )
  253. {
  254. // Check orientation
  255. if ( pStructure->ubWallOrientation == INSIDE_TOP_RIGHT || pStructure->ubWallOrientation == OUTSIDE_TOP_RIGHT )
  256. {
  257. return( TRUE );
  258. }
  259. }
  260. pStructure = FindNextStructure( pStructure, STRUCTURE_WALLSTUFF );
  261. }
  262. return( FALSE );
  263. }
  264. BOOLEAN OpenRightOrientedDoorWithDoorOnRightOfEdgeExists( INT16 sGridNo )
  265. {
  266. STRUCTURE * pStructure;
  267. pStructure = FindStructure( sGridNo, STRUCTURE_ANYDOOR );
  268. while ( pStructure != NULL && (pStructure->fFlags & STRUCTURE_OPEN) )
  269. {
  270. // Check orientation
  271. if ( pStructure->ubWallOrientation == INSIDE_TOP_RIGHT || pStructure->ubWallOrientation == OUTSIDE_TOP_RIGHT )
  272. {
  273. if ( (pStructure->fFlags & STRUCTURE_DOOR) || (pStructure->fFlags & STRUCTURE_DDOOR_RIGHT) )
  274. {
  275. return( TRUE );
  276. }
  277. }
  278. pStructure = FindNextStructure( pStructure, STRUCTURE_ANYDOOR );
  279. }
  280. return( FALSE );
  281. }
  282. BOOLEAN OpenLeftOrientedDoorWithDoorOnLeftOfEdgeExists( INT16 sGridNo )
  283. {
  284. STRUCTURE * pStructure;
  285. pStructure = FindStructure( sGridNo, STRUCTURE_ANYDOOR );
  286. while ( pStructure != NULL && (pStructure->fFlags & STRUCTURE_OPEN) )
  287. {
  288. // Check orientation
  289. if ( pStructure->ubWallOrientation == INSIDE_TOP_LEFT || pStructure->ubWallOrientation == OUTSIDE_TOP_LEFT )
  290. {
  291. if ( (pStructure->fFlags & STRUCTURE_DOOR) || (pStructure->fFlags & STRUCTURE_DDOOR_LEFT) )
  292. {
  293. return( TRUE );
  294. }
  295. }
  296. pStructure = FindNextStructure( pStructure, STRUCTURE_ANYDOOR );
  297. }
  298. return( FALSE );
  299. }
  300. STRUCTURE * FindCuttableWireFenceAtGridNo( INT16 sGridNo )
  301. {
  302. STRUCTURE * pStructure;
  303. pStructure = FindStructure( sGridNo, STRUCTURE_WIREFENCE );
  304. if (pStructure != NULL && pStructure->ubWallOrientation != NO_ORIENTATION && !(pStructure->fFlags & STRUCTURE_OPEN) )
  305. {
  306. return( pStructure );
  307. }
  308. return( NULL );
  309. }
  310. BOOLEAN CutWireFence( INT16 sGridNo )
  311. {
  312. STRUCTURE * pStructure;
  313. pStructure = FindCuttableWireFenceAtGridNo( sGridNo );
  314. if (pStructure)
  315. {
  316. pStructure = SwapStructureForPartnerAndStoreChangeInMap( sGridNo, pStructure );
  317. if (pStructure)
  318. {
  319. RecompileLocalMovementCosts( sGridNo );
  320. SetRenderFlags( RENDER_FLAG_FULL );
  321. return( TRUE );
  322. }
  323. }
  324. return( FALSE );
  325. }
  326. BOOLEAN IsCuttableWireFenceAtGridNo( INT16 sGridNo )
  327. {
  328. return( FindCuttableWireFenceAtGridNo( sGridNo ) != NULL );
  329. }
  330. BOOLEAN IsRepairableStructAtGridNo( INT16 sGridNo, UINT8 *pubID )
  331. {
  332. UINT8 ubMerc;
  333. // OK, first look for a vehicle....
  334. ubMerc = WhoIsThere2( sGridNo, 0 );
  335. if ( pubID != NULL )
  336. {
  337. (*pubID) = ubMerc;
  338. }
  339. if ( ubMerc != NOBODY )
  340. {
  341. if ( MercPtrs[ ubMerc ]->uiStatusFlags & SOLDIER_VEHICLE )
  342. {
  343. return( 2 );
  344. }
  345. }
  346. // Then for over a robot....
  347. // then for SAM site....
  348. if ( DoesSAMExistHere( gWorldSectorX, gWorldSectorY, gbWorldSectorZ, sGridNo ) )
  349. {
  350. return( 3 );
  351. }
  352. return( FALSE );
  353. }
  354. BOOLEAN IsRefuelableStructAtGridNo( INT16 sGridNo, UINT8 *pubID )
  355. {
  356. UINT8 ubMerc;
  357. // OK, first look for a vehicle....
  358. ubMerc = WhoIsThere2( sGridNo, 0 );
  359. if ( pubID != NULL )
  360. {
  361. (*pubID) = ubMerc;
  362. }
  363. if ( ubMerc != NOBODY )
  364. {
  365. if ( MercPtrs[ ubMerc ]->uiStatusFlags & SOLDIER_VEHICLE )
  366. {
  367. return( TRUE );
  368. }
  369. }
  370. return( FALSE );
  371. }
  372. BOOLEAN IsCutWireFenceAtGridNo( INT16 sGridNo )
  373. {
  374. STRUCTURE * pStructure;
  375. pStructure = FindStructure( sGridNo, STRUCTURE_WIREFENCE );
  376. if (pStructure != NULL && (pStructure->ubWallOrientation != NO_ORIENTATION) && (pStructure->fFlags & STRUCTURE_OPEN) )
  377. {
  378. return( TRUE );
  379. }
  380. return( FALSE );
  381. }
  382. INT16 FindDoorAtGridNoOrAdjacent( INT16 sGridNo )
  383. {
  384. STRUCTURE * pStructure;
  385. STRUCTURE * pBaseStructure;
  386. INT16 sTestGridNo;
  387. sTestGridNo = sGridNo;
  388. pStructure = FindStructure( sTestGridNo, STRUCTURE_ANYDOOR );
  389. if (pStructure)
  390. {
  391. pBaseStructure = FindBaseStructure( pStructure );
  392. return( pBaseStructure->sGridNo );
  393. }
  394. sTestGridNo = sGridNo + DirectionInc( NORTH );
  395. pStructure = FindStructure( sTestGridNo, STRUCTURE_ANYDOOR );
  396. if (pStructure)
  397. {
  398. pBaseStructure = FindBaseStructure( pStructure );
  399. return( pBaseStructure->sGridNo );
  400. }
  401. sTestGridNo = sGridNo + DirectionInc( WEST );
  402. pStructure = FindStructure( sTestGridNo, STRUCTURE_ANYDOOR );
  403. if (pStructure)
  404. {
  405. pBaseStructure = FindBaseStructure( pStructure );
  406. return( pBaseStructure->sGridNo );
  407. }
  408. return( NOWHERE );
  409. }
  410. BOOLEAN IsCorpseAtGridNo( INT16 sGridNo, UINT8 ubLevel )
  411. {
  412. if ( GetCorpseAtGridNo( sGridNo , ubLevel ) != NULL )
  413. {
  414. return( TRUE );
  415. }
  416. else
  417. {
  418. return( FALSE );
  419. }
  420. }
  421. BOOLEAN SetOpenableStructureToClosed( INT16 sGridNo, UINT8 ubLevel )
  422. {
  423. STRUCTURE * pStructure;
  424. STRUCTURE * pNewStructure;
  425. pStructure = FindStructure( sGridNo, STRUCTURE_OPENABLE );
  426. if ( !pStructure )
  427. {
  428. return( FALSE );
  429. }
  430. if ( pStructure->fFlags & STRUCTURE_OPEN )
  431. {
  432. pNewStructure = SwapStructureForPartner( sGridNo, pStructure );
  433. if ( pNewStructure != NULL)
  434. {
  435. RecompileLocalMovementCosts( sGridNo );
  436. SetRenderFlags( RENDER_FLAG_FULL );
  437. }
  438. }
  439. // else leave it as is!
  440. return( TRUE );
  441. }