goal.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561
  1. //===========================================================================//
  2. // Copyright (C) Microsoft Corporation. All rights reserved. //
  3. //===========================================================================//
  4. #ifndef GOAL_H
  5. #include "goal.h"
  6. #endif
  7. #ifndef GAMEOBJ_H
  8. #include "gameobj.h"
  9. #endif
  10. #ifndef TERROBJ_H
  11. #include "terrobj.h"
  12. #endif
  13. #ifndef GATE_H
  14. #include "gate.h"
  15. #endif
  16. #ifndef OBJMGR_H
  17. #include "objmgr.h"
  18. #endif
  19. #ifndef BLDNG_H
  20. #include "bldng.h"
  21. #endif
  22. #include "heap.h"
  23. #include "mclib.h"
  24. extern UserHeapPtr missionHeap;
  25. //***************************************************************************
  26. long adjCell[4][2] = {
  27. {-1, 0},
  28. {0, 1},
  29. {1, 0},
  30. {0, -1}
  31. };
  32. long recurseCount = 0;
  33. //***************************************************************************
  34. void* GoalObject::operator new (size_t ourSize) {
  35. void *result = missionHeap->Malloc(ourSize);
  36. return(result);
  37. }
  38. //---------------------------------------------------------------------------
  39. void GoalObject::operator delete (void* us) {
  40. missionHeap->Free(us);
  41. }
  42. //---------------------------------------------------------------------------
  43. void GoalObject::init (void) {
  44. used = false;
  45. type = GOAL_OBJECT;
  46. id = -1;
  47. name[0] = NULL;
  48. links = NULL;
  49. controller = NULL;
  50. info.object.WID = 0;
  51. next = NULL;
  52. prev = NULL;
  53. }
  54. //---------------------------------------------------------------------------
  55. void GoalObject::initObject (char* name, GameObjectPtr obj) {
  56. }
  57. //---------------------------------------------------------------------------
  58. void GoalObject::initRegion (char* name, long minRow, long minCol, long maxRow, long maxCol) {
  59. init();
  60. used = true;
  61. type = GOAL_REGION;
  62. strcpy(name, "MAP");
  63. info.region.minRow = minRow;
  64. }
  65. //---------------------------------------------------------------------------
  66. void GoalObject::destroy (void) {
  67. }
  68. //---------------------------------------------------------------------------
  69. void GoalObject::addLink (GoalObjectPtr gobject, GoalLinkType type) {
  70. GoalLinkPtr newLink = (GoalLink*)missionHeap->Malloc(sizeof(GoalLink));
  71. }
  72. //---------------------------------------------------------------------------
  73. void GoalObject::addController (GoalObjectPtr gobject) {
  74. }
  75. //***************************************************************************
  76. // ACTION GOAL MANAGER
  77. //***************************************************************************
  78. //#ifdef USE_REGION_MAP
  79. void* GoalManager::operator new (size_t ourSize) {
  80. void *result = missionHeap->Malloc(ourSize);
  81. return(result);
  82. }
  83. //---------------------------------------------------------------------------
  84. void GoalManager::operator delete (void* us) {
  85. missionHeap->Free(us);
  86. }
  87. //---------------------------------------------------------------------------
  88. void GoalManager::init (void) {
  89. numGoalObjects = 0;
  90. goalObjectPoolSize = 0;
  91. goalObjects = NULL;
  92. goalObjectPool = NULL;
  93. #ifdef USE_REGION_MAP
  94. for (long r = 0; r < GameMap->height; r++)
  95. for (long c = 0; c < GameMap->width; c++)
  96. regionMap[r][c] = -1;
  97. #endif
  98. numRegions = 0;
  99. fillStack = NULL;
  100. fillStackIndex = 0;
  101. }
  102. //---------------------------------------------------------------------------
  103. void GoalManager::destroy (void) {
  104. if (goalObjectPool) {
  105. missionHeap->Free(goalObjectPool);
  106. goalObjectPool = NULL;
  107. }
  108. numGoalObjects = 0;
  109. goalObjectPoolSize = 0;
  110. }
  111. //---------------------------------------------------------------------------
  112. void GoalManager::clear (void) {
  113. goalObjects = NULL;
  114. numGoalObjects = 0;
  115. for (long i = 0; i < goalObjectPoolSize; i++)
  116. goalObjectPool[i].used = false;
  117. #ifdef USE_REGION_MAP
  118. for (long r = 0; r < GameMap->height; r++)
  119. for (long c = 0; c < GameMap->width; c++)
  120. regionMap[r][c] = -1;
  121. #endif
  122. numRegions = 0;
  123. }
  124. //---------------------------------------------------------------------------
  125. GoalObjectPtr GoalManager::newGoalObject (void) {
  126. GoalObjectPtr goalObject = NULL;
  127. for (long i = 0; i < goalObjectPoolSize; i++)
  128. if (!goalObjectPool[i].used) {
  129. goalObjectPool[i].used = true;
  130. goalObject = &goalObjectPool[i];
  131. break;
  132. }
  133. if (!goalObject)
  134. Fatal(0, " GoalManager.newGoalObject: no more GoalObjects allowed ");
  135. return(goalObject);
  136. }
  137. //---------------------------------------------------------------------------
  138. void GoalManager::setup (long poolSize) {
  139. goalObjectPoolSize = poolSize;
  140. if (goalObjectPoolSize < 10)
  141. Fatal(0, " GoalManager.setup: goalObjectPoolSize must be greater than 10 ");
  142. goalObjectPool = (GoalObjectPtr)missionHeap->Malloc(sizeof(GoalObject) * goalObjectPoolSize);
  143. clear();
  144. }
  145. //---------------------------------------------------------------------------
  146. #if 0
  147. bool GlobalMap::fillNorthSouthBridgeArea (long row, long col, long area) {
  148. //----------------------------------------------------------------------
  149. // It is assumed that the bridge is erected over non-passable terrain...
  150. if ((row < minRow) || (row >= maxRow) || (col < minCol) || (col >= maxCol))
  151. return(false);
  152. areaMap[row * width + col] = area;
  153. //----------------
  154. // Expand North...
  155. long adjR = row - 1;
  156. long adjC = col;
  157. if ((adjR >= minRow) && (adjR < maxRow) && (adjC >= minCol) && (adjC < maxCol))
  158. if (GameMap->getOverlay(adjR, adjC) == OVERLAY_WATER_BRIDGE_NS)
  159. if (areaMap[adjR * width + adjC] == -1)
  160. fillNorthSouthBridgeArea(adjR, adjC, area);
  161. //----------------
  162. // Expand South...
  163. adjR = row + 1;
  164. adjC = col;
  165. if ((adjR >= minRow) && (adjR < maxRow) && (adjC >= minCol) && (adjC < maxCol))
  166. if (GameMap->getOverlay(adjR, adjC) == OVERLAY_WATER_BRIDGE_NS)
  167. if (areaMap[adjR * width + adjC] == -1)
  168. fillNorthSouthBridgeArea(adjR, adjC, area);
  169. return(true);
  170. }
  171. //------------------------------------------------------------------------------------------
  172. bool GlobalMap::fillEastWestBridgeArea (long row, long col, long area) {
  173. //----------------------------------------------------------------------
  174. // It is assumed that the bridge is erected over non-passable terrain...
  175. if ((row < minRow) || (row >= maxRow) || (col < minCol) || (col >= maxCol))
  176. return(false);
  177. areaMap[row * width + col] = area;
  178. //---------------
  179. // Expand East...
  180. long adjR = row;
  181. long adjC = col + 1;
  182. if ((adjR >= minRow) && (adjR < maxRow) && (adjC >= minCol) && (adjC < maxCol)) {
  183. long overlay = GameMap->getOverlay(adjR, adjC);
  184. if (overlay == OVERLAY_WATER_BRIDGE_EW)
  185. if (areaMap[adjR * width + adjC] == -1)
  186. fillEastWestBridgeArea(adjR, adjC, area);
  187. }
  188. //---------------
  189. // Expand West...
  190. adjR = row;
  191. adjC = col - 1;
  192. if ((adjR >= minRow) && (adjR < maxRow) && (adjC >= minCol) && (adjC < maxCol)) {
  193. long overlay = GameMap->getOverlay(adjR, adjC);
  194. if (overlay == OVERLAY_WATER_BRIDGE_EW)
  195. if (areaMap[adjR * width + adjC] == -1)
  196. fillEastWestBridgeArea(adjR, adjC, area);
  197. }
  198. return(true);
  199. }
  200. //------------------------------------------------------------------------------------------
  201. #endif
  202. bool GoalManager::fillWallGateRegion (long row, long col, long region) {
  203. recurseCount++;
  204. //----------------------------------------------------------------------
  205. // It is assumed that the bridge is erected over non-passable terrain...
  206. if ((row < 0) || (row >= GameMap->height) || (col < 0) || (col >= GameMap->width))
  207. return(false);
  208. if (!GameMap->getWall(row, col) && !GameMap->getGate(row, col))
  209. return(false);
  210. regionMap[row][col] = region;
  211. for (long dir = 0; dir < 4; dir ++) {
  212. long adjR = row + adjCell[dir][0];
  213. long adjC = col + adjCell[dir][1];
  214. if ((adjR >= 0) && (adjR < GameMap->height) && (adjC >= 0) && (adjC < GameMap->width))
  215. if (regionMap[adjR][adjC] == -1)
  216. fillWallGateRegion(adjR, adjC, region);
  217. }
  218. return(true);
  219. }
  220. //------------------------------------------------------------------------------------------
  221. bool GoalManager::fillRegion (long row, long col, long region) {
  222. #if 1
  223. // long overlay = GameMap->getOverlay(row, col);
  224. // if ((overlay == OVERLAY_WATER_BRIDGE_EW) || (overlay == OVERLAY_WATER_BRIDGE_NS))
  225. // return(false);
  226. if (GameMap->getWall(row, col) || GameMap->getGate(row, col))
  227. return(false);
  228. if (!GameMap->getPassable(row, col)) {
  229. regionMap[row][col] = -2;
  230. return(false);
  231. }
  232. fillStack[fillStackIndex++] = row;
  233. fillStack[fillStackIndex++] = col;
  234. while (fillStackIndex > 0) {
  235. //--------------------------------
  236. // Pop 'em in the reverse order...
  237. long col = fillStack[--fillStackIndex];
  238. long row = fillStack[--fillStackIndex];
  239. bool filling = true;
  240. if ((row < 0) || (row >= GameMap->height) || (col < 0) || (col >= GameMap->width))
  241. filling = false;
  242. // long overlay = GameMap->getOverlay(row, col);
  243. // if ((overlay == OVERLAY_WATER_BRIDGE_EW) || (overlay == OVERLAY_WATER_BRIDGE_NS))
  244. // filling = false;
  245. if (GameMap->getWall(row, col) || GameMap->getGate(row, col))
  246. filling = false;
  247. if (!GameMap->getPassable(row, col)) {
  248. regionMap[row][col] = -2;
  249. filling = false;
  250. }
  251. if (filling) {
  252. regionMap[row][col] = region;
  253. for (long dir = 0; dir < 4; dir ++) {
  254. long adjR = row + adjCell[dir][0];
  255. long adjC = col + adjCell[dir][1];
  256. if ((adjR >= 0) && (adjR < GameMap->height) && (adjC >= 0) && (adjC < GameMap->width))
  257. if (regionMap[adjR][adjC] == -1) {
  258. //--------------------------------------------
  259. // Cell hasn't been visited yet, so push it...
  260. fillStack[fillStackIndex++] = adjR;
  261. fillStack[fillStackIndex++] = adjC;
  262. //----------------------------------------------------------------
  263. // Mark the cell as on the stack (so we do not push it again if we
  264. // hit it before popping it)...
  265. regionMap[adjR][adjC] = -3;
  266. }
  267. }
  268. }
  269. }
  270. return(true);
  271. #else
  272. if ((row < 0) || (row >= GameMap->height) || (col < 0) || (col >= GameMap->width))
  273. return(false);
  274. //----------------------------------------------------------------------
  275. // If we hit a bridge cell, politely stop expanding this area into it...
  276. long overlay = GameMap->getOverlay(row, col);
  277. if ((overlay == OVERLAY_WATER_BRIDGE_EW) || (overlay == OVERLAY_WATER_BRIDGE_NS))
  278. return(false);
  279. if (GameMap->getWall(row, col) || GameMap->getGate(row, col))
  280. return(false);
  281. if (!GameMap->getPassable(row, col)) {
  282. regionMap[row][col] = -2;
  283. return(false);
  284. }
  285. regionMap[row][col] = region;
  286. for (long dir = 0; dir < 4; dir ++) {
  287. long adjR = row + adjCell[dir][0];
  288. long adjC = col + adjCell[dir][1];
  289. if ((adjR >= 0) && (adjR < GameMap->height) && (adjC >= 0) && (adjC < GameMap->width))
  290. if (regionMap[adjR][adjC] == -1)
  291. fillRegion(adjR, adjC, region);
  292. }
  293. return(true);
  294. #endif
  295. }
  296. //------------------------------------------------------------------------------------------
  297. void GoalManager::calcRegions (void) {
  298. //----------------------------------------------------------------------
  299. // This is the same method used in GlobalMap::calcAreas, so see notes...
  300. for (long r = 0; r < GameMap->height; r++)
  301. for (long c = 0; c < GameMap->width; c++)
  302. if (regionMap[r][c] == -1) {
  303. recurseCount = 0;
  304. #ifdef USE_OVERLAYS
  305. long overlay = GameMap->getOverlay(r, c);
  306. if (overlay == OVERLAY_WATER_BRIDGE_NS) {
  307. if (fillNorthSouthBridgeArea(r, c, numAreas))
  308. numAreas++;
  309. }
  310. else if (overlay == OVERLAY_WATER_BRIDGE_EW) {
  311. if (fillEastWestBridgeArea(r, c, numAreas))
  312. numAreas++;
  313. }
  314. #endif
  315. if (GameMap->getWall(r, c) || GameMap->getGate(r, c)) {
  316. if (fillWallGateRegion(r, c, numRegions))
  317. numRegions++;
  318. }
  319. else if (fillRegion(r, c, numRegions))
  320. numRegions++;
  321. }
  322. }
  323. //------------------------------------------------------------------------------------------
  324. void GoalManager::build (void) {
  325. //For temps, pull 'em off the windows heap. IT can resize. OURS cannot!!!!
  326. fillStack = (short*)malloc(FILL_STACK_SIZE * sizeof(short));
  327. gosASSERT(fillStack != NULL);
  328. fillStackIndex = 0;
  329. //--------------------------------
  330. // First, get the list of walls...
  331. GameObjectPtr wallObjects[MAX_WALL_OBJECTS];
  332. long numWalls = ObjectManager->getSpecificObjects(BUILDING, BUILDING_SUBTYPE_WALL, wallObjects, MAX_WALL_OBJECTS);
  333. /* short cellList[MAX_CELL_COORDS];
  334. for (long i = 0; i < numWalls; i++) {
  335. cellList[0] = MAX_CELL_COORDS;
  336. long numCells = wallObjects[i]->appearance->markMoveMap(true, NULL, false, cellList);
  337. for (long j = 0; j < numCells; j++)
  338. GameMap->setWall(cellList[j*2], cellList[j*2+1], true);
  339. }
  340. //--------------------------------------------------
  341. // Close all gates, before calcing the region map...
  342. for (i = 0; i < ObjectManager->getNumGates(); i++) {
  343. GatePtr gate = ObjectManager->getGate(i);
  344. gate->getAppearance()->markMoveMap(false, NULL);
  345. }
  346. */
  347. // calcRegions();
  348. /*
  349. //--------------------------------------
  350. // Now, open the gates (for the game)...
  351. for (i = 0; i < ObjectManager->getNumGates(); i++) {
  352. GatePtr gate = ObjectManager->getGate(i);
  353. gate->getAppearance()->markMoveMap(true, NULL);
  354. }
  355. */
  356. free(fillStack);
  357. fillStack = NULL;
  358. fillStackIndex = 0;
  359. }
  360. //---------------------------------------------------------------------------
  361. /*
  362. long GoalManager::setControl (ObstaclePtr controller, ObstaclePtr controllee) {
  363. if (controller && controllee) {
  364. controllee->parent = controller;
  365. controllee->prev = NULL;
  366. controllee->next = controller->controls;
  367. controllee->controls = NULL;
  368. controller->controls->prev = controllee;
  369. controller->controls = controllee;
  370. }
  371. return(0);
  372. }
  373. */
  374. //---------------------------------------------------------------------------
  375. GoalObjectPtr GoalManager::addRegion (GoalObjectPtr parent, GoalLinkType linkType, char* name, long minRow, long minCol, long maxRow, long maxCol) {
  376. GoalObjectPtr newRegion = newGoalObject();
  377. newRegion->initRegion(name, minRow, minCol, maxRow, maxCol);
  378. if (parent)
  379. parent->addLink(newRegion, linkType);
  380. else
  381. goalObjects = newRegion;
  382. return(newRegion);
  383. }
  384. //---------------------------------------------------------------------------
  385. GoalObjectPtr GoalManager::addObject (GoalObjectPtr parent, GoalLinkType linkType, char* name, GameObjectPtr object) {
  386. GoalObjectPtr newObject = newGoalObject();
  387. newObject->initObject(name, object);
  388. if (parent)
  389. parent->addLink(newObject, linkType);
  390. else
  391. goalObjects = newObject;
  392. return(newObject);
  393. }
  394. //---------------------------------------------------------------------------
  395. /*
  396. void GoalManager::setControlMap (long row, long col, GoalObjectPtr controller) {
  397. controlMap[row][col] = controller->id;
  398. }
  399. */
  400. //---------------------------------------------------------------------------
  401. GoalObjectPtr GoalManager::calcGoal (long startCell[2], long goalCell[2]) {
  402. //No Warnings!
  403. //ObstaclePtr startObstacle = &obstaclePool[controlMap[startCell[0]][startCell[1]]];
  404. //ObstaclePtr goalObstacle = &obstaclePool[controlMap[goalCell[0]][goalCell[1]]];
  405. /* DO SEARCH HERE */
  406. return(NULL);
  407. }
  408. //---------------------------------------------------------------------------
  409. GoalObjectPtr GoalManager::calcGoal (GameObjectPtr attacker, GameObjectPtr target) {
  410. return(NULL);
  411. }
  412. //---------------------------------------------------------------------------
  413. GoalObjectPtr GoalManager::calcGoal (GameObjectPtr attacker, Stuff::Vector3D location) {
  414. return(NULL);
  415. }
  416. //---------------------------------------------------------------------------
  417. GoalObjectPtr GoalManager::calcGoal (Stuff::Vector3D start, Stuff::Vector3D location) {
  418. long startCell[2], locationCell[2];
  419. land->worldToCell(start, startCell[0], startCell[1]);
  420. land->worldToCell(location, locationCell[0], locationCell[1]);
  421. return(calcGoal(startCell, locationCell));
  422. }
  423. //***************************************************************************