@@ -7720,260 +7720,6 @@ void Pathfinder::clip( Coord3D *from, Coord3D *to )
77207720
77217721}
77227722
7723- Bool Pathfinder::pathDestination ( Object *obj, const LocomotorSet& locomotorSet, Coord3D *dest,
7724- PathfindLayerEnum layer, const Coord3D *groupDest)
7725- {
7726- // CRCDEBUG_LOG(("Pathfinder::pathDestination()"));
7727- if (m_isMapReady == false ) return false ;
7728-
7729- if (!obj) return false ;
7730-
7731- Int cellCount = 0 ;
7732-
7733- Coord3D adjustTo = *groupDest;
7734- Coord3D *to = &adjustTo;
7735- DEBUG_ASSERTCRASH (m_openList.empty () && m_closedList.empty (), (" Dangling lists." ));
7736- // create unique "mark" values for open and closed cells for this pathfind invocation
7737-
7738- Bool isCrusher = obj ? obj->getCrusherLevel () > 0 : false ;
7739-
7740- PathfindLayerEnum desiredLayer = TheTerrainLogic->getLayerForDestination (dest);
7741- // determine desired
7742- PathfindCell *desiredCell = getClippedCell ( desiredLayer, dest );
7743- if (desiredCell == nullptr )
7744- return FALSE ;
7745-
7746- PathfindLayerEnum goalLayer = TheTerrainLogic->getLayerForDestination (to);
7747- // determine goal cell
7748- PathfindCell *goalCell = getClippedCell ( goalLayer, to );
7749- if (goalCell == nullptr )
7750- return FALSE ;
7751-
7752-
7753- Bool isHuman = true ;
7754- if (obj && obj->getControllingPlayer () && (obj->getControllingPlayer ()->getPlayerType ()==PLAYER_COMPUTER)) {
7755- isHuman = false ; // computer gets to cheat.
7756- }
7757- Bool center;
7758- Int radius;
7759- getRadiusAndCenter (obj, radius, center);
7760-
7761- // determine start cell
7762- ICoord2D startCellNdx;
7763- worldToCell (dest, &startCellNdx);
7764- PathfindCell *parentCell = getCell ( layer, startCellNdx.x , startCellNdx.y );
7765- if (parentCell == nullptr )
7766- return FALSE ;
7767- ICoord2D pos2d;
7768- worldToCell (to, &pos2d);
7769- if (!goalCell->allocateInfo (pos2d)) {
7770- return FALSE ;
7771- }
7772-
7773- if (parentCell!=goalCell) {
7774- if (!parentCell->allocateInfo (startCellNdx)) {
7775- #if RETAIL_COMPATIBLE_PATHFINDING
7776- if (!s_useFixedPathfinding) {
7777- desiredCell->releaseInfo ();
7778- }
7779- #endif
7780- goalCell->releaseInfo ();
7781- return FALSE ;
7782- }
7783- }
7784-
7785- PathfindCell *closestCell = nullptr ;
7786- Real closestDistanceSqr = FLT_MAX;
7787- Coord3D closestPos;
7788-
7789- if (validMovementPosition ( isCrusher, locomotorSet.getValidSurfaces (), parentCell ) == false ) {
7790- parentCell->releaseInfo ();
7791- goalCell->releaseInfo ();
7792- return FALSE ;
7793- }
7794-
7795- parentCell->startPathfind (goalCell);
7796-
7797- // initialize "open" list to contain start cell
7798- #if RETAIL_COMPATIBLE_PATHFINDING
7799- if (!s_useFixedPathfinding) {
7800- m_openList.reset (parentCell);
7801- }
7802- else
7803- #endif
7804- {
7805- m_openList.reset ();
7806- parentCell->putOnSortedOpenList (m_openList);
7807- }
7808-
7809- // "closed" list is initially empty
7810- m_closedList.reset ();
7811-
7812- //
7813- // Continue search until "open" list is empty, or
7814- // until goal is found.
7815- //
7816- while ( !m_openList.empty () )
7817- {
7818- // take head cell off of open list - it has lowest estimated total path cost
7819- parentCell = m_openList.getHead ();
7820- parentCell->removeFromOpenList (m_openList);
7821-
7822- Coord3D pos;
7823- // put parent cell onto closed list - its evaluation is finished
7824- parentCell->putOnClosedList ( m_closedList );
7825- if (checkForAdjust (obj, locomotorSet, isHuman, parentCell->getXIndex (), parentCell->getYIndex (), parentCell->getLayer (),
7826- radius, center, &pos, groupDest)) {
7827- Int dx = IABS (goalCell->getXIndex ()-parentCell->getXIndex ());
7828- Int dy = IABS (goalCell->getYIndex ()-parentCell->getYIndex ());
7829- Real distSqr = dx*dx+dy*dy;
7830-
7831- if (distSqr < closestDistanceSqr) {
7832- closestCell = parentCell;
7833- closestDistanceSqr = distSqr;
7834- closestPos = pos;
7835- } else {
7836- continue ;
7837- }
7838- } else {
7839- continue ;
7840- }
7841-
7842- if (cellCount > MAX_CELL_COUNT) {
7843- continue ;
7844- }
7845- // Check to see if we can change layers in this cell.
7846- checkChangeLayers (parentCell);
7847-
7848- // expand search to neighboring orthogonal cells
7849- static ICoord2D delta[] =
7850- {
7851- { 1 , 0 }, { 0 , 1 }, { -1 , 0 }, { 0 , -1 },
7852- { 1 , 1 }, { -1 , 1 }, { -1 , -1 }, { 1 , -1 }
7853- };
7854- const Int numNeighbors = 8 ;
7855- const Int firstDiagonal = 4 ;
7856- ICoord2D newCellCoord;
7857- PathfindCell *newCell;
7858- const Int adjacent[5 ] = {0 , 1 , 2 , 3 , 0 };
7859- Bool neighborFlags[8 ] = { 0 };
7860-
7861- UnsignedInt newCostSoFar = 0 ;
7862-
7863- for ( int i=0 ; i<numNeighbors; i++ )
7864- {
7865- neighborFlags[i] = false ;
7866- // determine neighbor cell to try
7867- newCellCoord.x = parentCell->getXIndex () + delta[i].x ;
7868- newCellCoord.y = parentCell->getYIndex () + delta[i].y ;
7869-
7870- // get the neighboring cell
7871- newCell = getCell (parentCell->getLayer (), newCellCoord.x , newCellCoord.y );
7872-
7873- // check if cell is on the map
7874- if (newCell == nullptr )
7875- continue ;
7876-
7877- // check if this neighbor cell is already on the open (waiting to be tried)
7878- // or closed (already tried) lists
7879- Bool onList = false ;
7880- if (newCell->hasInfo ()) {
7881- if (newCell->getOpen () || newCell->getClosed ())
7882- {
7883- // already on one of the lists
7884- onList = true ;
7885- }
7886- }
7887- if (i>=firstDiagonal) {
7888- // make sure one of the adjacent sides is open.
7889- if (!neighborFlags[adjacent[i-4 ]] && !neighborFlags[adjacent[i-3 ]]) {
7890- continue ;
7891- }
7892- }
7893-
7894- if (!validMovementPosition ( isCrusher, locomotorSet.getValidSurfaces (), newCell, parentCell )) {
7895- continue ;
7896- }
7897-
7898- neighborFlags[i] = true ;
7899-
7900- if (!newCell->allocateInfo (newCellCoord)) {
7901- // Out of cells for pathing...
7902- #if RETAIL_COMPATIBLE_PATHFINDING
7903- if (s_useFixedPathfinding)
7904- #endif
7905- {
7906- cleanOpenAndClosedLists ();
7907- goalCell->releaseInfo ();
7908- }
7909- return cellCount;
7910- }
7911- cellCount++;
7912-
7913- newCostSoFar = newCell->costSoFar ( parentCell );
7914- newCell->setBlockedByAlly (false );
7915-
7916- // check if this neighbor cell is already on the open (waiting to be tried)
7917- // or closed (already tried) lists
7918- if (onList)
7919- {
7920- // already on one of the lists - if existing costSoFar is less,
7921- // the new cell is on a longer path, so skip it
7922- if (newCell->getCostSoFar () <= newCostSoFar)
7923- continue ;
7924- }
7925-
7926- // keep track of path we're building - point back to cell we moved here from
7927- newCell->setParentCell (parentCell) ;
7928-
7929- // store cost of this path
7930- newCell->setCostSoFar (newCostSoFar);
7931-
7932- Int costRemaining = 0 ;
7933- if (goalCell) {
7934- costRemaining = newCell->costToGoal ( goalCell );
7935- }
7936-
7937- newCell->setTotalCost (newCell->getCostSoFar () + costRemaining) ;
7938-
7939- // if newCell was on closed list, remove it from the list
7940- if (newCell->getClosed ())
7941- newCell->removeFromClosedList ( m_closedList );
7942-
7943- // if the newCell was already on the open list, remove it so it can be re-inserted in order
7944- if (newCell->getOpen ())
7945- newCell->removeFromOpenList ( m_openList );
7946-
7947- // insert newCell in open list such that open list is sorted, smallest total path cost first
7948- newCell->putOnSortedOpenList ( m_openList );
7949- }
7950- }
7951-
7952- #if defined(RTS_DEBUG)
7953- if (closestCell) {
7954- debugShowSearch (true );
7955- *dest = closestPos;
7956- } else {
7957- debugShowSearch (true );
7958- }
7959- #endif
7960- m_isTunneling = false ;
7961- #if RETAIL_COMPATIBLE_PATHFINDING
7962- if (!s_useFixedPathfinding) {
7963- cleanOpenAndClosedLists ();
7964- goalCell->releaseInfo ();
7965- }
7966- else
7967- #endif
7968- {
7969- cleanOpenAndClosedLists ();
7970- parentCell->releaseInfo ();
7971- goalCell->releaseInfo ();
7972- }
7973-
7974- return false ;
7975- }
7976-
79777723struct TightenPathStruct
79787724{
79797725 Object *obj;
0 commit comments