@@ -3322,6 +3322,10 @@ void PathfindLayer::doDebugIcons() {
33223322 if (m_layer == LAYER_WALL ) {
33233323 bridgeHeight = TheAI->pathfinder ()->getWallHeight ();
33243324 }
3325+ static Int flash = 0 ;
3326+ flash--;
3327+ if (flash<1 ) flash = 20 ;
3328+ if (flash < 10 ) return ;
33253329 Bool showCells = TheGlobalData->m_debugAI ==AI_DEBUG_CELLS ;
33263330 // show the pathfind grid
33273331 for ( int j=0 ; j<m_height; j++ )
@@ -3333,8 +3337,8 @@ void PathfindLayer::doDebugIcons() {
33333337 topLeftCorner.x = (Real)(i+m_xOrigin) * PATHFIND_CELL_SIZE_F ;
33343338
33353339 color.red = color.green = color.blue = 0 ;
3336- Bool empty = true ;
3337-
3340+ Bool empty = false ;
3341+ Real size = 0 . 4f ;
33383342 const PathfindCell *cell = &m_layerCells[i][j];
33393343 if (cell)
33403344 {
@@ -3344,13 +3348,16 @@ void PathfindLayer::doDebugIcons() {
33443348 empty = false ;
33453349 } else if (cell->getType () == PathfindCell::CELL_IMPASSABLE ) {
33463350 color.red = color.green = color.blue = 1 ;
3351+ size = 0 .2f ;
33473352 empty = false ;
33483353 } else if (cell->getType () == PathfindCell::CELL_BRIDGE_IMPASSABLE ) {
33493354 color.blue = color.red = 1 ;
33503355 empty = false ;
33513356 } else if (cell->getType () == PathfindCell::CELL_CLIFF ) {
33523357 color.red = 1 ;
33533358 empty = false ;
3359+ } else {
3360+ size = 0 .2f ;
33543361 }
33553362 }
33563363 if (showCells) {
@@ -3376,7 +3383,7 @@ void PathfindLayer::doDebugIcons() {
33763383 loc.x = topLeftCorner.x + PATHFIND_CELL_SIZE_F /2 .0f ;
33773384 loc.y = topLeftCorner.y + PATHFIND_CELL_SIZE_F /2 .0f ;
33783385 loc.z = bridgeHeight;
3379- addIcon (&loc, PATHFIND_CELL_SIZE_F *0 . 8f , 99 , color);
3386+ addIcon (&loc, PATHFIND_CELL_SIZE_F *size , 99 , color);
33803387 }
33813388 }
33823389 }
@@ -3570,7 +3577,11 @@ void PathfindLayer::classifyCells()
35703577 groundCell->setConnectLayer (LAYER_INVALID ); // disconnect it.
35713578 }
35723579 }
3580+ #if RTS_GENERALS && RETAIL_COMPATIBLE_PATHFINDING
35733581 cell->setType (PathfindCell::CELL_IMPASSABLE );
3582+ #else
3583+ cell->setType (PathfindCell::CELL_BRIDGE_IMPASSABLE );
3584+ #endif
35743585 }
35753586 }
35763587 }
@@ -3735,7 +3746,11 @@ void PathfindLayer::classifyLayerMapCell( Int i, Int j , PathfindCell *cell, Bri
37353746 cell->setType (PathfindCell::CELL_CLEAR );
37363747 } else {
37373748 if (bridgeCount!=0 ) {
3749+ #if RTS_GENERALS && RETAIL_COMPATIBLE_PATHFINDING
37383750 cell->setType (PathfindCell::CELL_CLIFF ); // it's off the bridge.
3751+ #else
3752+ cell->setType (PathfindCell::CELL_BRIDGE_IMPASSABLE ); // it's off the bridge.
3753+ #endif
37393754 }
37403755
37413756 // check against the end lines.
@@ -3746,6 +3761,7 @@ void PathfindLayer::classifyLayerMapCell( Int i, Int j , PathfindCell *cell, Bri
37463761 cellBounds.hi .x = bottomRightCorner.x ;
37473762 cellBounds.hi .y = bottomRightCorner.y ;
37483763
3764+ #if RTS_GENERALS && RETAIL_COMPATIBLE_PATHFINDING
37493765 if (m_bridge->isCellOnEnd (&cellBounds)) {
37503766 cell->setType (PathfindCell::CELL_CLEAR );
37513767 }
@@ -3759,6 +3775,21 @@ void PathfindLayer::classifyLayerMapCell( Int i, Int j , PathfindCell *cell, Bri
37593775 groundCell->setConnectLayer (cell->getLayer ());
37603776 }
37613777 }
3778+ #else
3779+ if (m_bridge->isCellOnSide (&cellBounds)) {
3780+ cell->setType (PathfindCell::CELL_BRIDGE_IMPASSABLE );
3781+ } else {
3782+ if (m_bridge->isCellOnEnd (&cellBounds)) {
3783+ cell->setType (PathfindCell::CELL_CLEAR );
3784+ }
3785+ if (m_bridge->isCellEntryPoint (&cellBounds)) {
3786+ cell->setType (PathfindCell::CELL_CLEAR );
3787+ cell->setConnectLayer (LAYER_GROUND );
3788+ PathfindCell *groundCell = TheAI->pathfinder ()->getCell (LAYER_GROUND , i, j );
3789+ groundCell->setConnectLayer (cell->getLayer ());
3790+ }
3791+ }
3792+ #endif
37623793 }
37633794 Coord3D center = topLeftCorner;
37643795 center.x += PATHFIND_CELL_SIZE /2 ;
@@ -3771,7 +3802,11 @@ void PathfindLayer::classifyLayerMapCell( Int i, Int j , PathfindCell *cell, Bri
37713802 if (groundHeight+LAYER_Z_CLOSE_ENOUGH_F > bridgeHeight) {
37723803 PathfindCell *groundCell = TheAI->pathfinder ()->getCell (LAYER_GROUND ,i, j);
37733804 if (!(groundCell->getType ()==PathfindCell::CELL_OBSTACLE )) {
3805+ #if RTS_GENERALS && RETAIL_COMPATIBLE_PATHFINDING
37743806 groundCell->setType (PathfindCell::CELL_IMPASSABLE );
3807+ #else
3808+ groundCell->setType (PathfindCell::CELL_BRIDGE_IMPASSABLE );
3809+ #endif
37753810 }
37763811 }
37773812 }
@@ -3848,7 +3883,11 @@ void PathfindLayer::classifyWallMapCell( Int i, Int j , PathfindCell *cell, Obje
38483883 cell->setType (PathfindCell::CELL_CLEAR );
38493884 } else {
38503885 if (bridgeCount!=0 ) {
3886+ #if RTS_GENERALS && RETAIL_COMPATIBLE_PATHFINDING
38513887 cell->setType (PathfindCell::CELL_CLIFF ); // it's off the bridge.
3888+ #else
3889+ cell->setType (PathfindCell::CELL_BRIDGE_IMPASSABLE ); // it's off the bridge.
3890+ #endif
38523891 }
38533892
38543893 }
@@ -4038,7 +4077,9 @@ void Pathfinder::updateLayer(Object *obj, PathfindLayerEnum layer)
40384077 */
40394078void Pathfinder::classifyFence ( Object *obj, Bool insert )
40404079{
4080+ #if RTS_GENERALS && RETAIL_COMPATIBLE_PATHFINDING
40414081 m_zoneManager.markZonesDirty ();
4082+ #endif
40424083
40434084 const Coord3D *pos = obj->getPosition ();
40444085 Real angle = obj->getOrientation ();
@@ -4062,6 +4103,25 @@ void Pathfinder::classifyFence( Object *obj, Bool insert )
40624103 Real tl_x = pos->x - fenceOffset*c - halfsizeY*s;
40634104 Real tl_y = pos->y + halfsizeY*c - fenceOffset*s;
40644105
4106+ #if !(RTS_GENERALS && RETAIL_COMPATIBLE_PATHFINDING)
4107+ IRegion2D cellBounds;
4108+ cellBounds.lo .x = REAL_TO_INT_FLOOR ((pos->x + 0 .5f )/PATHFIND_CELL_SIZE_F );
4109+ cellBounds.lo .y = REAL_TO_INT_FLOOR ((pos->y + 0 .5f )/PATHFIND_CELL_SIZE_F );
4110+ // TheSuperHackers @fix Mauller 16/06/2025 Fixes uninitialized variables.
4111+ #if RETAIL_COMPATIBLE_CRC
4112+ // CRCDEBUG_LOG(("Pathfinder::classifyFence - (%d,%d)", cellBounds.hi.x, cellBounds.hi.y));
4113+
4114+ // In retail, the values in the stack often look like this. We set them
4115+ // to reduce the likelihood of mismatch.
4116+ cellBounds.hi .x = 253961804 ;
4117+ cellBounds.hi .y = 4202797 ;
4118+ #else
4119+ cellBounds.hi .x = REAL_TO_INT_CEIL ((pos->x + 0 .5f )/PATHFIND_CELL_SIZE_F );
4120+ cellBounds.hi .y = REAL_TO_INT_CEIL ((pos->y + 0 .5f )/PATHFIND_CELL_SIZE_F );
4121+ #endif
4122+ Bool didAnything = false ;
4123+ #endif // !(RTS_GENERALS && RETAIL_COMPATIBLE_PATHFINDING)
4124+
40654125 for (Int iy = 0 ; iy < numStepsY; ++iy, tl_x += ydx, tl_y += ydy)
40664126 {
40674127 Real x = tl_x;
@@ -4072,6 +4132,7 @@ void Pathfinder::classifyFence( Object *obj, Bool insert )
40724132 Int cy = REAL_TO_INT_FLOOR ((y + 0 .5f )/PATHFIND_CELL_SIZE_F );
40734133 if (cx >= 0 && cy >= 0 && cx < m_extent.hi .x && cy < m_extent.hi .y )
40744134 {
4135+ #if RTS_GENERALS && RETAIL_COMPATIBLE_PATHFINDING
40754136 if (insert) {
40764137 ICoord2D pos;
40774138 pos.x = cx;
@@ -4080,9 +4141,36 @@ void Pathfinder::classifyFence( Object *obj, Bool insert )
40804141 }
40814142 else
40824143 m_map[cx][cy].removeObstacle (obj);
4144+ #else
4145+ if (insert) {
4146+ ICoord2D pos;
4147+ pos.x = cx;
4148+ pos.y = cy;
4149+ if (m_map[cx][cy].setTypeAsObstacle ( obj, true , pos )) {
4150+ didAnything = true ;
4151+ m_map[cx][cy].setZone (PathfindZoneManager::UNINITIALIZED_ZONE );
4152+ }
4153+ }
4154+ else {
4155+ if (m_map[cx][cy].removeObstacle (obj)) {
4156+ didAnything = true ;
4157+ m_map[cx][cy].setZone (PathfindZoneManager::UNINITIALIZED_ZONE );
4158+ }
4159+ }
4160+ if (cellBounds.lo .x >cx) cellBounds.lo .x = cx;
4161+ if (cellBounds.lo .y >cy) cellBounds.lo .y = cy;
4162+ if (cellBounds.hi .x <cx) cellBounds.hi .x = cx;
4163+ if (cellBounds.hi .y <cy) cellBounds.hi .y = cy;
4164+ #endif
40834165 }
40844166 }
40854167 }
4168+ #if !(RTS_GENERALS && RETAIL_COMPATIBLE_PATHFINDING)
4169+ if (didAnything) {
4170+ m_zoneManager.markZonesDirty ();
4171+ m_zoneManager.updateZonesForModify (m_map, m_layers, cellBounds, m_extent);
4172+ }
4173+ #endif
40864174}
40874175
40884176/* *
@@ -4117,6 +4205,12 @@ void Pathfinder::classifyObjectFootprint( Object *obj, Bool insert )
41174205 // Just in case, remove the object. Remove checks that the object has been added before
41184206 // removing, so it's safer to just remove it, as by the time some units "die", they've become
41194207 // lifeless immobile husks of debris, but we still need to remove them. jba.
4208+
4209+ #if !RTS_GENERALS
4210+ if ( obj->isKindOf ( KINDOF_BLAST_CRATER ) ) // since these footprints are permanent, never remove them
4211+ return ;
4212+ #endif
4213+
41204214 removeUnitFromPathfindMap (obj);
41214215 if (obj->isKindOf (KINDOF_WALK_ON_TOP_OF_WALL )) {
41224216 if (!m_layers[LAYER_WALL ].isUnused ()) {
@@ -4160,20 +4254,35 @@ void Pathfinder::classifyObjectFootprint( Object *obj, Bool insert )
41604254 return ;
41614255 }
41624256
4257+ #if RTS_GENERALS
41634258 if (obj->getHeightAboveTerrain () > PATHFIND_CELL_SIZE_F ) {
41644259 return ; // Don't add bounds that are up in the air.
41654260 }
4261+ #else
4262+ if (obj->getHeightAboveTerrain () > PATHFIND_CELL_SIZE_F && ( ! obj->isKindOf ( KINDOF_BLAST_CRATER ) ) )
4263+ {
4264+ return ; // Don't add bounds that are up in the air.... unless a blast crater wants to do just that
4265+ }
4266+ #endif
41664267 internal_classifyObjectFootprint (obj, insert);
41674268}
41684269
41694270void Pathfinder::internal_classifyObjectFootprint ( Object *obj, Bool insert )
41704271{
4272+ const Coord3D *pos = obj->getPosition ();
4273+
4274+ #if !(RTS_GENERALS && RETAIL_COMPATIBLE_PATHFINDING)
4275+ IRegion2D cellBounds;
4276+ cellBounds.lo .x = REAL_TO_INT_FLOOR ((pos->x + 0 .5f )/PATHFIND_CELL_SIZE_F );
4277+ cellBounds.lo .y = REAL_TO_INT_FLOOR ((pos->y + 0 .5f )/PATHFIND_CELL_SIZE_F );
4278+ cellBounds.hi = cellBounds.lo ;
4279+ #endif
4280+
41714281 switch (obj->getGeometryInfo ().getGeomType ())
41724282 {
41734283 case GEOMETRY_BOX :
41744284 {
41754285 m_zoneManager.markZonesDirty ();
4176- const Coord3D *pos = obj->getPosition ();
41774286 Real angle = obj->getOrientation ();
41784287
41794288 Real halfsizeX = obj->getGeometryInfo ().getMajorRadius ();
@@ -4203,6 +4312,7 @@ void Pathfinder::internal_classifyObjectFootprint( Object *obj, Bool insert )
42034312 Int cx = REAL_TO_INT_FLOOR ((x + 0 .5f )/PATHFIND_CELL_SIZE_F );
42044313 Int cy = REAL_TO_INT_FLOOR ((y + 0 .5f )/PATHFIND_CELL_SIZE_F );
42054314
4315+ #if RTS_GENERALS && RETAIL_COMPATIBLE_PATHFINDING
42064316 if (cx >= 0 && cy >= 0 && cx < m_extent.hi .x && cy < m_extent.hi .y )
42074317 {
42084318 if (insert) {
@@ -4214,6 +4324,28 @@ void Pathfinder::internal_classifyObjectFootprint( Object *obj, Bool insert )
42144324 else
42154325 m_map[cx][cy].removeObstacle (obj);
42164326 }
4327+ #else
4328+ if (cx >= 0 && cy >= 0 && cx < m_extent.hi .x && cy < m_extent.hi .y )
4329+ {
4330+ if (insert) {
4331+ ICoord2D pos;
4332+ pos.x = cx;
4333+ pos.y = cy;
4334+ if (m_map[cx][cy].setTypeAsObstacle ( obj, false , pos )) {
4335+ m_map[cx][cy].setZone (PathfindZoneManager::UNINITIALIZED_ZONE );
4336+ }
4337+ }
4338+ else {
4339+ if (m_map[cx][cy].removeObstacle (obj)) {
4340+ m_map[cx][cy].setZone (PathfindZoneManager::UNINITIALIZED_ZONE );
4341+ }
4342+ }
4343+ if (cellBounds.lo .x >cx) cellBounds.lo .x = cx;
4344+ if (cellBounds.lo .y >cy) cellBounds.lo .y = cy;
4345+ if (cellBounds.hi .x <cx) cellBounds.hi .x = cx;
4346+ if (cellBounds.hi .y <cy) cellBounds.hi .y = cy;
4347+ }
4348+ #endif
42174349 }
42184350 }
42194351 }
@@ -4227,7 +4359,6 @@ void Pathfinder::internal_classifyObjectFootprint( Object *obj, Bool insert )
42274359 // / @todo This is a very inefficient circle-rasterizer
42284360 ICoord2D topLeft, bottomRight;
42294361 Coord2D center, delta;
4230- const Coord3D *pos = obj->getPosition ();
42314362 Real radius = obj->getGeometryInfo ().getMajorRadius ();
42324363 Real r2, size;
42334364
@@ -4252,6 +4383,7 @@ void Pathfinder::internal_classifyObjectFootprint( Object *obj, Bool insert )
42524383
42534384 if (delta.x *delta.x + delta.y *delta.y <= r2)
42544385 {
4386+ #if RTS_GENERALS && RETAIL_COMPATIBLE_PATHFINDING
42554387 if (i >= 0 && j >= 0 && i < m_extent.hi .x && j < m_extent.hi .y )
42564388 {
42574389 if (insert) {
@@ -4263,20 +4395,54 @@ void Pathfinder::internal_classifyObjectFootprint( Object *obj, Bool insert )
42634395 else
42644396 m_map[i][j].removeObstacle ( obj );
42654397 }
4398+ #else
4399+ if (i >= 0 && j >= 0 && i < m_extent.hi .x && j < m_extent.hi .y )
4400+ {
4401+ if (insert) {
4402+ ICoord2D pos;
4403+ pos.x = i;
4404+ pos.y = j;
4405+ if (m_map[i][j].setTypeAsObstacle ( obj, false , pos )) {
4406+ m_map[i][j].setZone (PathfindZoneManager::UNINITIALIZED_ZONE );
4407+ }
4408+ }
4409+ else {
4410+ if (m_map[i][j].removeObstacle (obj)) {
4411+ m_map[i][j].setZone (PathfindZoneManager::UNINITIALIZED_ZONE );
4412+ }
4413+ }
4414+ if (cellBounds.lo .x >i) cellBounds.lo .x = i;
4415+ if (cellBounds.lo .y >j) cellBounds.lo .y = j;
4416+ if (cellBounds.hi .x <i) cellBounds.hi .x = i;
4417+ if (cellBounds.hi .y <j) cellBounds.hi .y = j;
4418+ }
4419+ #endif
42664420 }
42674421 }
42684422 }
42694423 }
42704424 break ;
42714425 }
4426+
4427+ #if RTS_GENERALS && RETAIL_COMPATIBLE_PATHFINDING
42724428 Region2D bounds;
4273- Int i, j;
42744429 obj->getGeometryInfo ().get2DBounds (*obj->getPosition (), obj->getOrientation (), bounds);
42754430 IRegion2D cellBounds;
42764431 cellBounds.lo .x = REAL_TO_INT_FLOOR (bounds.lo .x /PATHFIND_CELL_SIZE_F )-1 ;
42774432 cellBounds.lo .y = REAL_TO_INT_FLOOR (bounds.lo .y /PATHFIND_CELL_SIZE_F )-1 ;
42784433 cellBounds.hi .x = REAL_TO_INT_CEIL (bounds.hi .x /PATHFIND_CELL_SIZE_F )+1 ;
42794434 cellBounds.hi .y = REAL_TO_INT_CEIL (bounds.hi .y /PATHFIND_CELL_SIZE_F )+1 ;
4435+ #else
4436+ m_zoneManager.updateZonesForModify (m_map, m_layers, cellBounds, m_extent);
4437+
4438+ cellBounds.lo .x -= 2 ;
4439+ cellBounds.lo .y -= 2 ;
4440+ cellBounds.hi .x += 2 ;
4441+ cellBounds.hi .y += 2 ;
4442+ #endif
4443+
4444+ Int i, j;
4445+
42804446 if (cellBounds.lo .x < m_extent.lo .x ) {
42814447 cellBounds.lo .x = m_extent.lo .x ;
42824448 }
@@ -4789,6 +4955,12 @@ Bool Pathfinder::checkDestination(const Object *obj, Int cellX, Int cellY, Pathf
47894955 return false ;
47904956 }
47914957
4958+ #if !(RTS_GENERALS && RETAIL_COMPATIBLE_PATHFINDING)
4959+ if (IS_IMPASSABLE (cell->getType ())) {
4960+ return false ;
4961+ }
4962+ #endif
4963+
47924964 if (cell->getFlags () == PathfindCell::NO_UNITS ) {
47934965 continue ; // Nobody is here, so it's ok.
47944966 }
@@ -4919,9 +5091,11 @@ Bool Pathfinder::checkForMovement(const Object *obj, TCheckMovementInfo &info)
49195091 if (!unit->getAIUpdateInterface ()) {
49205092 return false ; // can't path through not-idle units.
49215093 }
5094+ #if RTS_GENERALS && RETAIL_COMPATIBLE_PATHFINDING
49225095 if (!unit->getAIUpdateInterface ()->isIdle ()) {
49235096 return false ; // can't path through not-idle units.
49245097 }
5098+ #endif
49255099 Bool found = false ;
49265100 Int k;
49275101 for (k=0 ; k<numAlly; k++) {
0 commit comments