123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561 |
- //===========================================================================//
- // Copyright (C) Microsoft Corporation. All rights reserved. //
- //===========================================================================//
- #ifndef GOAL_H
- #include "goal.h"
- #endif
- #ifndef GAMEOBJ_H
- #include "gameobj.h"
- #endif
- #ifndef TERROBJ_H
- #include "terrobj.h"
- #endif
- #ifndef GATE_H
- #include "gate.h"
- #endif
- #ifndef OBJMGR_H
- #include "objmgr.h"
- #endif
- #ifndef BLDNG_H
- #include "bldng.h"
- #endif
- #include "heap.h"
- #include "mclib.h"
- extern UserHeapPtr missionHeap;
- //***************************************************************************
- long adjCell[4][2] = {
- {-1, 0},
- {0, 1},
- {1, 0},
- {0, -1}
- };
- long recurseCount = 0;
- //***************************************************************************
- void* GoalObject::operator new (size_t ourSize) {
- void *result = missionHeap->Malloc(ourSize);
- return(result);
- }
- //---------------------------------------------------------------------------
- void GoalObject::operator delete (void* us) {
- missionHeap->Free(us);
- }
- //---------------------------------------------------------------------------
- void GoalObject::init (void) {
- used = false;
- type = GOAL_OBJECT;
- id = -1;
- name[0] = NULL;
- links = NULL;
- controller = NULL;
- info.object.WID = 0;
- next = NULL;
- prev = NULL;
- }
- //---------------------------------------------------------------------------
- void GoalObject::initObject (char* name, GameObjectPtr obj) {
- }
- //---------------------------------------------------------------------------
- void GoalObject::initRegion (char* name, long minRow, long minCol, long maxRow, long maxCol) {
- init();
- used = true;
- type = GOAL_REGION;
- strcpy(name, "MAP");
- info.region.minRow = minRow;
- }
- //---------------------------------------------------------------------------
- void GoalObject::destroy (void) {
- }
- //---------------------------------------------------------------------------
- void GoalObject::addLink (GoalObjectPtr gobject, GoalLinkType type) {
- GoalLinkPtr newLink = (GoalLink*)missionHeap->Malloc(sizeof(GoalLink));
-
- }
- //---------------------------------------------------------------------------
- void GoalObject::addController (GoalObjectPtr gobject) {
- }
- //***************************************************************************
- // ACTION GOAL MANAGER
- //***************************************************************************
- //#ifdef USE_REGION_MAP
- void* GoalManager::operator new (size_t ourSize) {
- void *result = missionHeap->Malloc(ourSize);
- return(result);
- }
- //---------------------------------------------------------------------------
- void GoalManager::operator delete (void* us) {
- missionHeap->Free(us);
- }
- //---------------------------------------------------------------------------
- void GoalManager::init (void) {
- numGoalObjects = 0;
- goalObjectPoolSize = 0;
- goalObjects = NULL;
- goalObjectPool = NULL;
- #ifdef USE_REGION_MAP
- for (long r = 0; r < GameMap->height; r++)
- for (long c = 0; c < GameMap->width; c++)
- regionMap[r][c] = -1;
- #endif
- numRegions = 0;
- fillStack = NULL;
- fillStackIndex = 0;
- }
- //---------------------------------------------------------------------------
- void GoalManager::destroy (void) {
- if (goalObjectPool) {
- missionHeap->Free(goalObjectPool);
- goalObjectPool = NULL;
- }
- numGoalObjects = 0;
- goalObjectPoolSize = 0;
- }
- //---------------------------------------------------------------------------
- void GoalManager::clear (void) {
- goalObjects = NULL;
- numGoalObjects = 0;
- for (long i = 0; i < goalObjectPoolSize; i++)
- goalObjectPool[i].used = false;
- #ifdef USE_REGION_MAP
- for (long r = 0; r < GameMap->height; r++)
- for (long c = 0; c < GameMap->width; c++)
- regionMap[r][c] = -1;
- #endif
- numRegions = 0;
- }
- //---------------------------------------------------------------------------
- GoalObjectPtr GoalManager::newGoalObject (void) {
- GoalObjectPtr goalObject = NULL;
- for (long i = 0; i < goalObjectPoolSize; i++)
- if (!goalObjectPool[i].used) {
- goalObjectPool[i].used = true;
- goalObject = &goalObjectPool[i];
- break;
- }
- if (!goalObject)
- Fatal(0, " GoalManager.newGoalObject: no more GoalObjects allowed ");
- return(goalObject);
- }
- //---------------------------------------------------------------------------
- void GoalManager::setup (long poolSize) {
- goalObjectPoolSize = poolSize;
- if (goalObjectPoolSize < 10)
- Fatal(0, " GoalManager.setup: goalObjectPoolSize must be greater than 10 ");
- goalObjectPool = (GoalObjectPtr)missionHeap->Malloc(sizeof(GoalObject) * goalObjectPoolSize);
- clear();
- }
- //---------------------------------------------------------------------------
- #if 0
- bool GlobalMap::fillNorthSouthBridgeArea (long row, long col, long area) {
- //----------------------------------------------------------------------
- // It is assumed that the bridge is erected over non-passable terrain...
- if ((row < minRow) || (row >= maxRow) || (col < minCol) || (col >= maxCol))
- return(false);
- areaMap[row * width + col] = area;
- //----------------
- // Expand North...
- long adjR = row - 1;
- long adjC = col;
- if ((adjR >= minRow) && (adjR < maxRow) && (adjC >= minCol) && (adjC < maxCol))
- if (GameMap->getOverlay(adjR, adjC) == OVERLAY_WATER_BRIDGE_NS)
- if (areaMap[adjR * width + adjC] == -1)
- fillNorthSouthBridgeArea(adjR, adjC, area);
- //----------------
- // Expand South...
- adjR = row + 1;
- adjC = col;
- if ((adjR >= minRow) && (adjR < maxRow) && (adjC >= minCol) && (adjC < maxCol))
- if (GameMap->getOverlay(adjR, adjC) == OVERLAY_WATER_BRIDGE_NS)
- if (areaMap[adjR * width + adjC] == -1)
- fillNorthSouthBridgeArea(adjR, adjC, area);
-
- return(true);
- }
- //------------------------------------------------------------------------------------------
- bool GlobalMap::fillEastWestBridgeArea (long row, long col, long area) {
- //----------------------------------------------------------------------
- // It is assumed that the bridge is erected over non-passable terrain...
- if ((row < minRow) || (row >= maxRow) || (col < minCol) || (col >= maxCol))
- return(false);
- areaMap[row * width + col] = area;
- //---------------
- // Expand East...
- long adjR = row;
- long adjC = col + 1;
- if ((adjR >= minRow) && (adjR < maxRow) && (adjC >= minCol) && (adjC < maxCol)) {
- long overlay = GameMap->getOverlay(adjR, adjC);
- if (overlay == OVERLAY_WATER_BRIDGE_EW)
- if (areaMap[adjR * width + adjC] == -1)
- fillEastWestBridgeArea(adjR, adjC, area);
- }
- //---------------
- // Expand West...
- adjR = row;
- adjC = col - 1;
- if ((adjR >= minRow) && (adjR < maxRow) && (adjC >= minCol) && (adjC < maxCol)) {
- long overlay = GameMap->getOverlay(adjR, adjC);
- if (overlay == OVERLAY_WATER_BRIDGE_EW)
- if (areaMap[adjR * width + adjC] == -1)
- fillEastWestBridgeArea(adjR, adjC, area);
- }
-
- return(true);
- }
- //------------------------------------------------------------------------------------------
- #endif
- bool GoalManager::fillWallGateRegion (long row, long col, long region) {
- recurseCount++;
- //----------------------------------------------------------------------
- // It is assumed that the bridge is erected over non-passable terrain...
- if ((row < 0) || (row >= GameMap->height) || (col < 0) || (col >= GameMap->width))
- return(false);
- if (!GameMap->getWall(row, col) && !GameMap->getGate(row, col))
- return(false);
- regionMap[row][col] = region;
- for (long dir = 0; dir < 4; dir ++) {
- long adjR = row + adjCell[dir][0];
- long adjC = col + adjCell[dir][1];
- if ((adjR >= 0) && (adjR < GameMap->height) && (adjC >= 0) && (adjC < GameMap->width))
- if (regionMap[adjR][adjC] == -1)
- fillWallGateRegion(adjR, adjC, region);
- }
-
- return(true);
- }
- //------------------------------------------------------------------------------------------
- bool GoalManager::fillRegion (long row, long col, long region) {
- #if 1
- // long overlay = GameMap->getOverlay(row, col);
- // if ((overlay == OVERLAY_WATER_BRIDGE_EW) || (overlay == OVERLAY_WATER_BRIDGE_NS))
- // return(false);
-
- if (GameMap->getWall(row, col) || GameMap->getGate(row, col))
- return(false);
-
- if (!GameMap->getPassable(row, col)) {
- regionMap[row][col] = -2;
- return(false);
- }
- fillStack[fillStackIndex++] = row;
- fillStack[fillStackIndex++] = col;
- while (fillStackIndex > 0) {
- //--------------------------------
- // Pop 'em in the reverse order...
- long col = fillStack[--fillStackIndex];
- long row = fillStack[--fillStackIndex];
- bool filling = true;
-
- if ((row < 0) || (row >= GameMap->height) || (col < 0) || (col >= GameMap->width))
- filling = false;
-
- // long overlay = GameMap->getOverlay(row, col);
- // if ((overlay == OVERLAY_WATER_BRIDGE_EW) || (overlay == OVERLAY_WATER_BRIDGE_NS))
- // filling = false;
-
- if (GameMap->getWall(row, col) || GameMap->getGate(row, col))
- filling = false;
-
- if (!GameMap->getPassable(row, col)) {
- regionMap[row][col] = -2;
- filling = false;
- }
-
- if (filling) {
- regionMap[row][col] = region;
- for (long dir = 0; dir < 4; dir ++) {
- long adjR = row + adjCell[dir][0];
- long adjC = col + adjCell[dir][1];
- if ((adjR >= 0) && (adjR < GameMap->height) && (adjC >= 0) && (adjC < GameMap->width))
- if (regionMap[adjR][adjC] == -1) {
- //--------------------------------------------
- // Cell hasn't been visited yet, so push it...
- fillStack[fillStackIndex++] = adjR;
- fillStack[fillStackIndex++] = adjC;
- //----------------------------------------------------------------
- // Mark the cell as on the stack (so we do not push it again if we
- // hit it before popping it)...
- regionMap[adjR][adjC] = -3;
- }
- }
- }
- }
- return(true);
- #else
- if ((row < 0) || (row >= GameMap->height) || (col < 0) || (col >= GameMap->width))
- return(false);
- //----------------------------------------------------------------------
- // If we hit a bridge cell, politely stop expanding this area into it...
- long overlay = GameMap->getOverlay(row, col);
- if ((overlay == OVERLAY_WATER_BRIDGE_EW) || (overlay == OVERLAY_WATER_BRIDGE_NS))
- return(false);
- if (GameMap->getWall(row, col) || GameMap->getGate(row, col))
- return(false);
- if (!GameMap->getPassable(row, col)) {
- regionMap[row][col] = -2;
- return(false);
- }
- regionMap[row][col] = region;
- for (long dir = 0; dir < 4; dir ++) {
- long adjR = row + adjCell[dir][0];
- long adjC = col + adjCell[dir][1];
- if ((adjR >= 0) && (adjR < GameMap->height) && (adjC >= 0) && (adjC < GameMap->width))
- if (regionMap[adjR][adjC] == -1)
- fillRegion(adjR, adjC, region);
- }
-
- return(true);
- #endif
- }
- //------------------------------------------------------------------------------------------
- void GoalManager::calcRegions (void) {
- //----------------------------------------------------------------------
- // This is the same method used in GlobalMap::calcAreas, so see notes...
- for (long r = 0; r < GameMap->height; r++)
- for (long c = 0; c < GameMap->width; c++)
- if (regionMap[r][c] == -1) {
- recurseCount = 0;
- #ifdef USE_OVERLAYS
- long overlay = GameMap->getOverlay(r, c);
- if (overlay == OVERLAY_WATER_BRIDGE_NS) {
- if (fillNorthSouthBridgeArea(r, c, numAreas))
- numAreas++;
- }
- else if (overlay == OVERLAY_WATER_BRIDGE_EW) {
- if (fillEastWestBridgeArea(r, c, numAreas))
- numAreas++;
- }
- #endif
- if (GameMap->getWall(r, c) || GameMap->getGate(r, c)) {
- if (fillWallGateRegion(r, c, numRegions))
- numRegions++;
- }
- else if (fillRegion(r, c, numRegions))
- numRegions++;
- }
- }
- //------------------------------------------------------------------------------------------
- void GoalManager::build (void) {
-
- //For temps, pull 'em off the windows heap. IT can resize. OURS cannot!!!!
- fillStack = (short*)malloc(FILL_STACK_SIZE * sizeof(short));
- gosASSERT(fillStack != NULL);
- fillStackIndex = 0;
- //--------------------------------
- // First, get the list of walls...
- GameObjectPtr wallObjects[MAX_WALL_OBJECTS];
- long numWalls = ObjectManager->getSpecificObjects(BUILDING, BUILDING_SUBTYPE_WALL, wallObjects, MAX_WALL_OBJECTS);
- /* short cellList[MAX_CELL_COORDS];
- for (long i = 0; i < numWalls; i++) {
- cellList[0] = MAX_CELL_COORDS;
- long numCells = wallObjects[i]->appearance->markMoveMap(true, NULL, false, cellList);
- for (long j = 0; j < numCells; j++)
- GameMap->setWall(cellList[j*2], cellList[j*2+1], true);
- }
- //--------------------------------------------------
- // Close all gates, before calcing the region map...
- for (i = 0; i < ObjectManager->getNumGates(); i++) {
- GatePtr gate = ObjectManager->getGate(i);
- gate->getAppearance()->markMoveMap(false, NULL);
- }
- */
- // calcRegions();
- /*
- //--------------------------------------
- // Now, open the gates (for the game)...
- for (i = 0; i < ObjectManager->getNumGates(); i++) {
- GatePtr gate = ObjectManager->getGate(i);
- gate->getAppearance()->markMoveMap(true, NULL);
- }
- */
- free(fillStack);
- fillStack = NULL;
- fillStackIndex = 0;
- }
- //---------------------------------------------------------------------------
- /*
- long GoalManager::setControl (ObstaclePtr controller, ObstaclePtr controllee) {
- if (controller && controllee) {
- controllee->parent = controller;
- controllee->prev = NULL;
- controllee->next = controller->controls;
- controllee->controls = NULL;
- controller->controls->prev = controllee;
- controller->controls = controllee;
- }
- return(0);
- }
- */
- //---------------------------------------------------------------------------
- GoalObjectPtr GoalManager::addRegion (GoalObjectPtr parent, GoalLinkType linkType, char* name, long minRow, long minCol, long maxRow, long maxCol) {
- GoalObjectPtr newRegion = newGoalObject();
- newRegion->initRegion(name, minRow, minCol, maxRow, maxCol);
- if (parent)
- parent->addLink(newRegion, linkType);
- else
- goalObjects = newRegion;
- return(newRegion);
- }
- //---------------------------------------------------------------------------
- GoalObjectPtr GoalManager::addObject (GoalObjectPtr parent, GoalLinkType linkType, char* name, GameObjectPtr object) {
- GoalObjectPtr newObject = newGoalObject();
- newObject->initObject(name, object);
- if (parent)
- parent->addLink(newObject, linkType);
- else
- goalObjects = newObject;
- return(newObject);
- }
- //---------------------------------------------------------------------------
- /*
- void GoalManager::setControlMap (long row, long col, GoalObjectPtr controller) {
- controlMap[row][col] = controller->id;
- }
- */
- //---------------------------------------------------------------------------
- GoalObjectPtr GoalManager::calcGoal (long startCell[2], long goalCell[2]) {
- //No Warnings!
- //ObstaclePtr startObstacle = &obstaclePool[controlMap[startCell[0]][startCell[1]]];
- //ObstaclePtr goalObstacle = &obstaclePool[controlMap[goalCell[0]][goalCell[1]]];
- /* DO SEARCH HERE */
- return(NULL);
- }
- //---------------------------------------------------------------------------
- GoalObjectPtr GoalManager::calcGoal (GameObjectPtr attacker, GameObjectPtr target) {
- return(NULL);
- }
- //---------------------------------------------------------------------------
- GoalObjectPtr GoalManager::calcGoal (GameObjectPtr attacker, Stuff::Vector3D location) {
- return(NULL);
- }
- //---------------------------------------------------------------------------
- GoalObjectPtr GoalManager::calcGoal (Stuff::Vector3D start, Stuff::Vector3D location) {
- long startCell[2], locationCell[2];
- land->worldToCell(start, startCell[0], startCell[1]);
- land->worldToCell(location, locationCell[0], locationCell[1]);
- return(calcGoal(startCell, locationCell));
- }
- //***************************************************************************
|