@@ -1297,6 +1297,12 @@ Bool PathfindCell::allocateInfo( const ICoord2D &pos )
1297
1297
*/
1298
1298
void PathfindCell::releaseInfo ( void )
1299
1299
{
1300
+ // TheSuperHackers @bugfix Mauller/SkyAero 05/06/2025 Parent cell links need clearing to prevent dangling pointers on starting points that can link them to an invalid parent cell.
1301
+ // Parent cells are only cleared within Pathfinder::prependCells, so cells that do not make it onto the final path do not get their parent cell cleared.
1302
+ // Cells with a special flags also do not get their pathfindinfo cleared and therefore can leave a parent cell set on a starting cell.
1303
+ if (m_info) {
1304
+ m_info->m_pathParent = NULL ;
1305
+ }
1300
1306
if (m_type==PathfindCell::CELL_OBSTACLE) {
1301
1307
return ;
1302
1308
}
@@ -6648,8 +6654,8 @@ Path *Pathfinder::internalFindPath( Object *obj, const LocomotorSet& locomotorSe
6648
6654
m_isTunneling = false ;
6649
6655
// construct and return path
6650
6656
Path *path = buildActualPath ( obj, locomotorSet.getValidSurfaces (), from, goalCell, centerInCell, false );
6651
- parentCell->releaseInfo ();
6652
6657
cleanOpenAndClosedLists ();
6658
+ parentCell->releaseInfo ();
6653
6659
return path;
6654
6660
}
6655
6661
@@ -6726,8 +6732,8 @@ Path *Pathfinder::internalFindPath( Object *obj, const LocomotorSet& locomotorSe
6726
6732
#endif
6727
6733
6728
6734
m_isTunneling = false ;
6729
- parentCell->releaseInfo ();
6730
6735
cleanOpenAndClosedLists ();
6736
+ parentCell->releaseInfo ();
6731
6737
goalCell->releaseInfo ();
6732
6738
return NULL ;
6733
6739
}
@@ -7167,8 +7173,8 @@ Path *Pathfinder::findGroundPath( const Coord3D *from,
7167
7173
m_isTunneling = false ;
7168
7174
// construct and return path
7169
7175
Path *path = buildGroundPath (crusher, from, goalCell, centerInCell, pathDiameter );
7170
- parentCell->releaseInfo ();
7171
7176
cleanOpenAndClosedLists ();
7177
+ parentCell->releaseInfo ();
7172
7178
return path;
7173
7179
}
7174
7180
@@ -7373,8 +7379,8 @@ Path *Pathfinder::findGroundPath( const Coord3D *from,
7373
7379
TheGameLogic->incrementOverallFailedPathfinds ();
7374
7380
#endif
7375
7381
m_isTunneling = false ;
7376
- parentCell->releaseInfo ();
7377
7382
cleanOpenAndClosedLists ();
7383
+ parentCell->releaseInfo ();
7378
7384
goalCell->releaseInfo ();
7379
7385
return NULL ;
7380
7386
}
@@ -7753,8 +7759,8 @@ Path *Pathfinder::internal_findHierarchicalPath( Bool isHuman, const LocomotorSu
7753
7759
#endif
7754
7760
}
7755
7761
#endif
7756
- parentCell->releaseInfo ();
7757
7762
cleanOpenAndClosedLists ();
7763
+ parentCell->releaseInfo ();
7758
7764
goalCell->releaseInfo ();
7759
7765
return path;
7760
7766
}
@@ -7952,8 +7958,8 @@ Path *Pathfinder::internal_findHierarchicalPath( Bool isHuman, const LocomotorSu
7952
7958
}
7953
7959
#endif
7954
7960
#endif
7955
- parentCell->releaseInfo ();
7956
7961
cleanOpenAndClosedLists ();
7962
+ parentCell->releaseInfo ();
7957
7963
goalCell->releaseInfo ();
7958
7964
return path;
7959
7965
}
@@ -8001,8 +8007,8 @@ Path *Pathfinder::internal_findHierarchicalPath( Bool isHuman, const LocomotorSu
8001
8007
TheGameLogic->incrementOverallFailedPathfinds ();
8002
8008
#endif
8003
8009
m_isTunneling = false ;
8004
- parentCell->releaseInfo ();
8005
8010
cleanOpenAndClosedLists ();
8011
+ parentCell->releaseInfo ();
8006
8012
goalCell->releaseInfo ();
8007
8013
return NULL ;
8008
8014
}
@@ -8439,8 +8445,8 @@ Bool Pathfinder::pathDestination( Object *obj, const LocomotorSet& locomotorSet
8439
8445
}
8440
8446
#endif
8441
8447
m_isTunneling = false ;
8442
- parentCell->releaseInfo ();
8443
8448
cleanOpenAndClosedLists ();
8449
+ parentCell->releaseInfo ();
8444
8450
goalCell->releaseInfo ();
8445
8451
return false ;
8446
8452
}
@@ -8570,8 +8576,8 @@ Int Pathfinder::checkPathCost(Object *obj, const LocomotorSet& locomotorSet, con
8570
8576
if (parentCell==goalCell) {
8571
8577
Int cost = parentCell->getTotalCost ();
8572
8578
m_isTunneling = false ;
8573
- parentCell->releaseInfo ();
8574
8579
cleanOpenAndClosedLists ();
8580
+ parentCell->releaseInfo ();
8575
8581
return cost;
8576
8582
}
8577
8583
@@ -8638,8 +8644,8 @@ Int Pathfinder::checkPathCost(Object *obj, const LocomotorSet& locomotorSet, con
8638
8644
8639
8645
if (!newCell->allocateInfo (newCellCoord)) {
8640
8646
// Out of cells for pathing...
8641
- parentCell->releaseInfo ();
8642
8647
cleanOpenAndClosedLists ();
8648
+ parentCell->releaseInfo ();
8643
8649
goalCell->releaseInfo ();
8644
8650
return cellCount;
8645
8651
}
@@ -8689,8 +8695,8 @@ Int Pathfinder::checkPathCost(Object *obj, const LocomotorSet& locomotorSet, con
8689
8695
}
8690
8696
8691
8697
m_isTunneling = false ;
8692
- parentCell->releaseInfo ();
8693
8698
cleanOpenAndClosedLists ();
8699
+ parentCell->releaseInfo ();
8694
8700
goalCell->releaseInfo ();
8695
8701
return MAX_COST;
8696
8702
}
@@ -8894,8 +8900,8 @@ Path *Pathfinder::findClosestPath( Object *obj, const LocomotorSet& locomotorSet
8894
8900
m_isTunneling = false ;
8895
8901
// construct and return path
8896
8902
Path *path = buildActualPath ( obj, locomotorSet.getValidSurfaces (), from, goalCell, centerInCell, blocked);
8897
- parentCell->releaseInfo ();
8898
8903
cleanOpenAndClosedLists ();
8904
+ parentCell->releaseInfo ();
8899
8905
goalCell->releaseInfo ();
8900
8906
return path;
8901
8907
}
@@ -8976,8 +8982,8 @@ Path *Pathfinder::findClosestPath( Object *obj, const LocomotorSet& locomotorSet
8976
8982
rawTo->y = closesetCell->getYIndex ()*PATHFIND_CELL_SIZE_F + PATHFIND_CELL_SIZE_F/2 .0f ;
8977
8983
// construct and return path
8978
8984
Path *path = buildActualPath ( obj, locomotorSet.getValidSurfaces (), from, closesetCell, centerInCell, blocked );
8979
- parentCell->releaseInfo ();
8980
8985
cleanOpenAndClosedLists ();
8986
+ parentCell->releaseInfo ();
8981
8987
goalCell->releaseInfo ();
8982
8988
return path;
8983
8989
}
@@ -8999,8 +9005,8 @@ Path *Pathfinder::findClosestPath( Object *obj, const LocomotorSet& locomotorSet
8999
9005
TheGameLogic->incrementOverallFailedPathfinds ();
9000
9006
#endif
9001
9007
m_isTunneling = false ;
9002
- parentCell->releaseInfo ();
9003
9008
cleanOpenAndClosedLists ();
9009
+ parentCell->releaseInfo ();
9004
9010
goalCell->releaseInfo ();
9005
9011
return NULL ;
9006
9012
}
@@ -9123,14 +9129,12 @@ void Pathfinder::prependCells( Path *path, const Coord3D *fromPos,
9123
9129
}
9124
9130
prevCell = cell;
9125
9131
}
9126
-
9127
9132
m_zoneManager.setPassable (cell->getXIndex (), cell->getYIndex (), true );
9128
9133
if (goalCellNull) {
9129
9134
// Very short path.
9130
9135
adjustCoordToCell (cell->getXIndex (), cell->getYIndex (), center, pos, cell->getLayer ());
9131
9136
path->prependNode ( &pos, cell->getLayer () );
9132
9137
}
9133
-
9134
9138
// put actual start position as first node on the path, so it begins right at the unit's feet
9135
9139
if (fromPos->x != path->getFirstNode ()->getPosition ()->x || fromPos->y != path->getFirstNode ()->getPosition ()->y ) {
9136
9140
path->prependNode ( fromPos, cell->getLayer () );
@@ -10388,8 +10392,8 @@ Path *Pathfinder::getMoveAwayFromPath(Object* obj, Object *otherObj,
10388
10392
m_isTunneling = false ;
10389
10393
// construct and return path
10390
10394
Path *newPath = buildActualPath ( obj, locomotorSet.getValidSurfaces (), obj->getPosition (), parentCell, centerInCell, false );
10391
- parentCell->releaseInfo ();
10392
10395
cleanOpenAndClosedLists ();
10396
+ parentCell->releaseInfo ();
10393
10397
return newPath;
10394
10398
}
10395
10399
// put parent cell onto closed list - its evaluation is finished
@@ -10411,8 +10415,8 @@ Path *Pathfinder::getMoveAwayFromPath(Object* obj, Object *otherObj,
10411
10415
DEBUG_LOG ((" Unit '%s', time %f\n " , obj->getTemplate ()->getName ().str (), (::GetTickCount ()-startTimeMS)/1000 .0f ));
10412
10416
10413
10417
m_isTunneling = false ;
10414
- parentCell->releaseInfo ();
10415
10418
cleanOpenAndClosedLists ();
10419
+ parentCell->releaseInfo ();
10416
10420
return NULL ;
10417
10421
}
10418
10422
@@ -10571,8 +10575,8 @@ Path *Pathfinder::patchPath( const Object *obj, const LocomotorSet& locomotorSet
10571
10575
10572
10576
// cleanup the path by checking line of sight
10573
10577
path->optimize (obj, locomotorSet.getValidSurfaces (), blocked);
10574
- parentCell->releaseInfo ();
10575
10578
cleanOpenAndClosedLists ();
10579
+ parentCell->releaseInfo ();
10576
10580
candidateGoal->releaseInfo ();
10577
10581
10578
10582
return path;
@@ -10597,8 +10601,8 @@ Path *Pathfinder::patchPath( const Object *obj, const LocomotorSet& locomotorSet
10597
10601
}
10598
10602
#endif
10599
10603
m_isTunneling = false ;
10600
- parentCell->releaseInfo ();
10601
10604
cleanOpenAndClosedLists ();
10605
+ parentCell->releaseInfo ();
10602
10606
candidateGoal->releaseInfo ();
10603
10607
return NULL ;
10604
10608
}
@@ -10892,8 +10896,8 @@ Path *Pathfinder::findAttackPath( const Object *obj, const LocomotorSet& locomot
10892
10896
}
10893
10897
}
10894
10898
Path *path = buildActualPath ( obj, locomotorSet.getValidSurfaces (), obj->getPosition (), parentCell, centerInCell, false );
10895
- parentCell->releaseInfo ();
10896
10899
cleanOpenAndClosedLists ();
10900
+ parentCell->releaseInfo ();
10897
10901
goalCell->releaseInfo ();
10898
10902
return path;
10899
10903
}
@@ -10951,8 +10955,8 @@ Path *Pathfinder::findAttackPath( const Object *obj, const LocomotorSet& locomot
10951
10955
TheGameLogic->incrementOverallFailedPathfinds ();
10952
10956
#endif
10953
10957
m_isTunneling = false ;
10954
- parentCell->releaseInfo ();
10955
10958
cleanOpenAndClosedLists ();
10959
+ parentCell->releaseInfo ();
10956
10960
goalCell->releaseInfo ();
10957
10961
return NULL ;
10958
10962
}
@@ -11075,8 +11079,8 @@ Path *Pathfinder::findSafePath( const Object *obj, const LocomotorSet& locomotor
11075
11079
#endif
11076
11080
// construct and return path
11077
11081
Path *path = buildActualPath ( obj, locomotorSet.getValidSurfaces (), obj->getPosition (), parentCell, centerInCell, false );
11078
- parentCell->releaseInfo ();
11079
11082
cleanOpenAndClosedLists ();
11083
+ parentCell->releaseInfo ();
11080
11084
return path;
11081
11085
}
11082
11086
@@ -11111,8 +11115,8 @@ Path *Pathfinder::findSafePath( const Object *obj, const LocomotorSet& locomotor
11111
11115
TheGameLogic->incrementOverallFailedPathfinds ();
11112
11116
#endif
11113
11117
m_isTunneling = false ;
11114
- parentCell->releaseInfo ();
11115
11118
cleanOpenAndClosedLists ();
11119
+ parentCell->releaseInfo ();
11116
11120
return NULL ;
11117
11121
}
11118
11122
0 commit comments