@@ -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
}
@@ -6652,8 +6658,8 @@ Path *Pathfinder::internalFindPath( Object *obj, const LocomotorSet& locomotorSe
6652
6658
m_isTunneling = false ;
6653
6659
// construct and return path
6654
6660
Path *path = buildActualPath ( obj, locomotorSet.getValidSurfaces (), from, goalCell, centerInCell, false );
6655
- parentCell->releaseInfo ();
6656
6661
cleanOpenAndClosedLists ();
6662
+ parentCell->releaseInfo ();
6657
6663
return path;
6658
6664
}
6659
6665
@@ -6730,8 +6736,8 @@ Path *Pathfinder::internalFindPath( Object *obj, const LocomotorSet& locomotorSe
6730
6736
#endif
6731
6737
6732
6738
m_isTunneling = false ;
6733
- parentCell->releaseInfo ();
6734
6739
cleanOpenAndClosedLists ();
6740
+ parentCell->releaseInfo ();
6735
6741
goalCell->releaseInfo ();
6736
6742
return NULL ;
6737
6743
}
@@ -7171,8 +7177,8 @@ Path *Pathfinder::findGroundPath( const Coord3D *from,
7171
7177
m_isTunneling = false ;
7172
7178
// construct and return path
7173
7179
Path *path = buildGroundPath (crusher, from, goalCell, centerInCell, pathDiameter );
7174
- parentCell->releaseInfo ();
7175
7180
cleanOpenAndClosedLists ();
7181
+ parentCell->releaseInfo ();
7176
7182
return path;
7177
7183
}
7178
7184
@@ -7377,8 +7383,8 @@ Path *Pathfinder::findGroundPath( const Coord3D *from,
7377
7383
TheGameLogic->incrementOverallFailedPathfinds ();
7378
7384
#endif
7379
7385
m_isTunneling = false ;
7380
- parentCell->releaseInfo ();
7381
7386
cleanOpenAndClosedLists ();
7387
+ parentCell->releaseInfo ();
7382
7388
goalCell->releaseInfo ();
7383
7389
return NULL ;
7384
7390
}
@@ -7757,8 +7763,8 @@ Path *Pathfinder::internal_findHierarchicalPath( Bool isHuman, const LocomotorSu
7757
7763
#endif
7758
7764
}
7759
7765
#endif
7760
- parentCell->releaseInfo ();
7761
7766
cleanOpenAndClosedLists ();
7767
+ parentCell->releaseInfo ();
7762
7768
goalCell->releaseInfo ();
7763
7769
return path;
7764
7770
}
@@ -7956,8 +7962,8 @@ Path *Pathfinder::internal_findHierarchicalPath( Bool isHuman, const LocomotorSu
7956
7962
}
7957
7963
#endif
7958
7964
#endif
7959
- parentCell->releaseInfo ();
7960
7965
cleanOpenAndClosedLists ();
7966
+ parentCell->releaseInfo ();
7961
7967
goalCell->releaseInfo ();
7962
7968
return path;
7963
7969
}
@@ -8005,8 +8011,8 @@ Path *Pathfinder::internal_findHierarchicalPath( Bool isHuman, const LocomotorSu
8005
8011
TheGameLogic->incrementOverallFailedPathfinds ();
8006
8012
#endif
8007
8013
m_isTunneling = false ;
8008
- parentCell->releaseInfo ();
8009
8014
cleanOpenAndClosedLists ();
8015
+ parentCell->releaseInfo ();
8010
8016
goalCell->releaseInfo ();
8011
8017
return NULL ;
8012
8018
}
@@ -8443,8 +8449,8 @@ Bool Pathfinder::pathDestination( Object *obj, const LocomotorSet& locomotorSet
8443
8449
}
8444
8450
#endif
8445
8451
m_isTunneling = false ;
8446
- parentCell->releaseInfo ();
8447
8452
cleanOpenAndClosedLists ();
8453
+ parentCell->releaseInfo ();
8448
8454
goalCell->releaseInfo ();
8449
8455
return false ;
8450
8456
}
@@ -8574,8 +8580,8 @@ Int Pathfinder::checkPathCost(Object *obj, const LocomotorSet& locomotorSet, con
8574
8580
if (parentCell==goalCell) {
8575
8581
Int cost = parentCell->getTotalCost ();
8576
8582
m_isTunneling = false ;
8577
- parentCell->releaseInfo ();
8578
8583
cleanOpenAndClosedLists ();
8584
+ parentCell->releaseInfo ();
8579
8585
return cost;
8580
8586
}
8581
8587
@@ -8642,8 +8648,8 @@ Int Pathfinder::checkPathCost(Object *obj, const LocomotorSet& locomotorSet, con
8642
8648
8643
8649
if (!newCell->allocateInfo (newCellCoord)) {
8644
8650
// Out of cells for pathing...
8645
- parentCell->releaseInfo ();
8646
8651
cleanOpenAndClosedLists ();
8652
+ parentCell->releaseInfo ();
8647
8653
goalCell->releaseInfo ();
8648
8654
return cellCount;
8649
8655
}
@@ -8693,8 +8699,8 @@ Int Pathfinder::checkPathCost(Object *obj, const LocomotorSet& locomotorSet, con
8693
8699
}
8694
8700
8695
8701
m_isTunneling = false ;
8696
- parentCell->releaseInfo ();
8697
8702
cleanOpenAndClosedLists ();
8703
+ parentCell->releaseInfo ();
8698
8704
goalCell->releaseInfo ();
8699
8705
return MAX_COST;
8700
8706
}
@@ -8898,8 +8904,8 @@ Path *Pathfinder::findClosestPath( Object *obj, const LocomotorSet& locomotorSet
8898
8904
m_isTunneling = false ;
8899
8905
// construct and return path
8900
8906
Path *path = buildActualPath ( obj, locomotorSet.getValidSurfaces (), from, goalCell, centerInCell, blocked);
8901
- parentCell->releaseInfo ();
8902
8907
cleanOpenAndClosedLists ();
8908
+ parentCell->releaseInfo ();
8903
8909
goalCell->releaseInfo ();
8904
8910
return path;
8905
8911
}
@@ -8980,8 +8986,8 @@ Path *Pathfinder::findClosestPath( Object *obj, const LocomotorSet& locomotorSet
8980
8986
rawTo->y = closesetCell->getYIndex ()*PATHFIND_CELL_SIZE_F + PATHFIND_CELL_SIZE_F/2 .0f ;
8981
8987
// construct and return path
8982
8988
Path *path = buildActualPath ( obj, locomotorSet.getValidSurfaces (), from, closesetCell, centerInCell, blocked );
8983
- parentCell->releaseInfo ();
8984
8989
cleanOpenAndClosedLists ();
8990
+ parentCell->releaseInfo ();
8985
8991
goalCell->releaseInfo ();
8986
8992
return path;
8987
8993
}
@@ -9003,8 +9009,8 @@ Path *Pathfinder::findClosestPath( Object *obj, const LocomotorSet& locomotorSet
9003
9009
TheGameLogic->incrementOverallFailedPathfinds ();
9004
9010
#endif
9005
9011
m_isTunneling = false ;
9006
- parentCell->releaseInfo ();
9007
9012
cleanOpenAndClosedLists ();
9013
+ parentCell->releaseInfo ();
9008
9014
goalCell->releaseInfo ();
9009
9015
return NULL ;
9010
9016
}
@@ -9127,14 +9133,12 @@ void Pathfinder::prependCells( Path *path, const Coord3D *fromPos,
9127
9133
}
9128
9134
prevCell = cell;
9129
9135
}
9130
-
9131
9136
m_zoneManager.setPassable (cell->getXIndex (), cell->getYIndex (), true );
9132
9137
if (goalCellNull) {
9133
9138
// Very short path.
9134
9139
adjustCoordToCell (cell->getXIndex (), cell->getYIndex (), center, pos, cell->getLayer ());
9135
9140
path->prependNode ( &pos, cell->getLayer () );
9136
9141
}
9137
-
9138
9142
// put actual start position as first node on the path, so it begins right at the unit's feet
9139
9143
if (fromPos->x != path->getFirstNode ()->getPosition ()->x || fromPos->y != path->getFirstNode ()->getPosition ()->y ) {
9140
9144
path->prependNode ( fromPos, cell->getLayer () );
@@ -10392,8 +10396,8 @@ Path *Pathfinder::getMoveAwayFromPath(Object* obj, Object *otherObj,
10392
10396
m_isTunneling = false ;
10393
10397
// construct and return path
10394
10398
Path *newPath = buildActualPath ( obj, locomotorSet.getValidSurfaces (), obj->getPosition (), parentCell, centerInCell, false );
10395
- parentCell->releaseInfo ();
10396
10399
cleanOpenAndClosedLists ();
10400
+ parentCell->releaseInfo ();
10397
10401
return newPath;
10398
10402
}
10399
10403
// put parent cell onto closed list - its evaluation is finished
@@ -10415,8 +10419,8 @@ Path *Pathfinder::getMoveAwayFromPath(Object* obj, Object *otherObj,
10415
10419
DEBUG_LOG ((" Unit '%s', time %f\n " , obj->getTemplate ()->getName ().str (), (::GetTickCount ()-startTimeMS)/1000 .0f ));
10416
10420
10417
10421
m_isTunneling = false ;
10418
- parentCell->releaseInfo ();
10419
10422
cleanOpenAndClosedLists ();
10423
+ parentCell->releaseInfo ();
10420
10424
return NULL ;
10421
10425
}
10422
10426
@@ -10575,8 +10579,8 @@ Path *Pathfinder::patchPath( const Object *obj, const LocomotorSet& locomotorSet
10575
10579
10576
10580
// cleanup the path by checking line of sight
10577
10581
path->optimize (obj, locomotorSet.getValidSurfaces (), blocked);
10578
- parentCell->releaseInfo ();
10579
10582
cleanOpenAndClosedLists ();
10583
+ parentCell->releaseInfo ();
10580
10584
candidateGoal->releaseInfo ();
10581
10585
10582
10586
return path;
@@ -10601,8 +10605,8 @@ Path *Pathfinder::patchPath( const Object *obj, const LocomotorSet& locomotorSet
10601
10605
}
10602
10606
#endif
10603
10607
m_isTunneling = false ;
10604
- parentCell->releaseInfo ();
10605
10608
cleanOpenAndClosedLists ();
10609
+ parentCell->releaseInfo ();
10606
10610
candidateGoal->releaseInfo ();
10607
10611
return NULL ;
10608
10612
}
@@ -10896,8 +10900,8 @@ Path *Pathfinder::findAttackPath( const Object *obj, const LocomotorSet& locomot
10896
10900
}
10897
10901
}
10898
10902
Path *path = buildActualPath ( obj, locomotorSet.getValidSurfaces (), obj->getPosition (), parentCell, centerInCell, false );
10899
- parentCell->releaseInfo ();
10900
10903
cleanOpenAndClosedLists ();
10904
+ parentCell->releaseInfo ();
10901
10905
goalCell->releaseInfo ();
10902
10906
return path;
10903
10907
}
@@ -10955,8 +10959,8 @@ Path *Pathfinder::findAttackPath( const Object *obj, const LocomotorSet& locomot
10955
10959
TheGameLogic->incrementOverallFailedPathfinds ();
10956
10960
#endif
10957
10961
m_isTunneling = false ;
10958
- parentCell->releaseInfo ();
10959
10962
cleanOpenAndClosedLists ();
10963
+ parentCell->releaseInfo ();
10960
10964
goalCell->releaseInfo ();
10961
10965
return NULL ;
10962
10966
}
@@ -11079,8 +11083,8 @@ Path *Pathfinder::findSafePath( const Object *obj, const LocomotorSet& locomotor
11079
11083
#endif
11080
11084
// construct and return path
11081
11085
Path *path = buildActualPath ( obj, locomotorSet.getValidSurfaces (), obj->getPosition (), parentCell, centerInCell, false );
11082
- parentCell->releaseInfo ();
11083
11086
cleanOpenAndClosedLists ();
11087
+ parentCell->releaseInfo ();
11084
11088
return path;
11085
11089
}
11086
11090
@@ -11115,8 +11119,8 @@ Path *Pathfinder::findSafePath( const Object *obj, const LocomotorSet& locomotor
11115
11119
TheGameLogic->incrementOverallFailedPathfinds ();
11116
11120
#endif
11117
11121
m_isTunneling = false ;
11118
- parentCell->releaseInfo ();
11119
11122
cleanOpenAndClosedLists ();
11123
+ parentCell->releaseInfo ();
11120
11124
return NULL ;
11121
11125
}
11122
11126
0 commit comments