Skip to content

Commit d246d36

Browse files
committed
"Fixed" a crash when mods set actors to non-existent teams
1 parent 2cc2842 commit d246d36

File tree

2 files changed

+20
-29
lines changed

2 files changed

+20
-29
lines changed

Source/Entities/Scene.cpp

Lines changed: 18 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2313,17 +2313,17 @@ int Scene::SetOwnerOfAllDoors(int team, int player) {
23132313
}
23142314

23152315
void Scene::ResetPathFinding() {
2316-
GetPathFinder(Activity::Teams::NoTeam)->RecalculateAllCosts();
2316+
GetPathFinder(Activity::Teams::NoTeam).RecalculateAllCosts();
23172317
for (int team = Activity::Teams::TeamOne; team < Activity::Teams::MaxTeamCount; ++team) {
23182318
g_MovableMan.OverrideMaterialDoors(true, team);
2319-
GetPathFinder(static_cast<Activity::Teams>(team))->RecalculateAllCosts();
2319+
GetPathFinder(static_cast<Activity::Teams>(team)).RecalculateAllCosts();
23202320
g_MovableMan.OverrideMaterialDoors(false, team);
23212321
}
23222322
}
23232323

23242324
void Scene::BlockUntilAllPathingRequestsComplete() {
23252325
for (int team = Activity::Teams::NoTeam; team < Activity::Teams::MaxTeamCount; ++team) {
2326-
while (GetPathFinder(static_cast<Activity::Teams>(team))->GetCurrentPathingRequests() != 0) {};
2326+
while (GetPathFinder(static_cast<Activity::Teams>(team)).GetCurrentPathingRequests() != 0) {};
23272327
}
23282328
}
23292329

@@ -2337,7 +2337,7 @@ void Scene::UpdatePathFinding() {
23372337
// TODO: this can indefinitely block updates if pathing requests are made every frame. Figure out a solution for this
23382338
// Either force-complete pathing requests occasionally, or delay starting new pathing requests if we've not updated in a while
23392339
for (int team = Activity::Teams::NoTeam; team < Activity::Teams::MaxTeamCount; ++team) {
2340-
if (GetPathFinder(static_cast<Activity::Teams>(team))->GetCurrentPathingRequests() != 0) {
2340+
if (GetPathFinder(static_cast<Activity::Teams>(team)).GetCurrentPathingRequests() != 0) {
23412341
return;
23422342
};
23432343
}
@@ -2349,7 +2349,7 @@ void Scene::UpdatePathFinding() {
23492349
}
23502350

23512351
// Update our shared pathFinder
2352-
std::vector<int> updatedNodes = GetPathFinder(Activity::Teams::NoTeam)->RecalculateAreaCosts(m_pTerrain->GetUpdatedMaterialAreas(), nodesToUpdate);
2352+
std::vector<int> updatedNodes = GetPathFinder(Activity::Teams::NoTeam).RecalculateAreaCosts(m_pTerrain->GetUpdatedMaterialAreas(), nodesToUpdate);
23532353
if (!updatedNodes.empty()) {
23542354
// Update each team's pathFinder
23552355
for (int team = Activity::Teams::TeamOne; team < Activity::Teams::MaxTeamCount; ++team) {
@@ -2360,7 +2360,7 @@ void Scene::UpdatePathFinding() {
23602360
// Remove the material representation of all doors of this team so we can navigate through them (they'll open for us).
23612361
g_MovableMan.OverrideMaterialDoors(true, team);
23622362

2363-
GetPathFinder(static_cast<Activity::Teams>(team))->UpdateNodeList(updatedNodes);
2363+
GetPathFinder(static_cast<Activity::Teams>(team)).UpdateNodeList(updatedNodes);
23642364

23652365
// Place back the material representation of all doors of this team so they are as we found them.
23662366
g_MovableMan.OverrideMaterialDoors(false, team);
@@ -2373,23 +2373,14 @@ void Scene::UpdatePathFinding() {
23732373

23742374
float Scene::CalculatePath(const Vector& start, const Vector& end, std::list<Vector>& pathResult, float digStrength, Activity::Teams team) {
23752375
float totalCostResult = -1;
2376+
int result = GetPathFinder(team).CalculatePath(start, end, pathResult, totalCostResult, digStrength);
23762377

2377-
if (const std::unique_ptr<PathFinder>& pathFinder = GetPathFinder(team)) {
2378-
int result = pathFinder->CalculatePath(start, end, pathResult, totalCostResult, digStrength);
2379-
2380-
// It's ok if start and end nodes happen to be the same, the exact pixel locations are added at the front and end of the result regardless
2381-
return (result == micropather::MicroPather::SOLVED || result == micropather::MicroPather::START_END_SAME) ? totalCostResult : -1;
2382-
}
2383-
2384-
return false;
2378+
// It's ok if start and end nodes happen to be the same, the exact pixel locations are added at the front and end of the result regardless
2379+
return (result == micropather::MicroPather::SOLVED || result == micropather::MicroPather::START_END_SAME) ? totalCostResult : -1;
23852380
}
23862381

23872382
std::shared_ptr<volatile PathRequest> Scene::CalculatePathAsync(const Vector& start, const Vector& end, float digStrength, Activity::Teams team, PathCompleteCallback callback) {
2388-
if (const std::unique_ptr<PathFinder>& pathFinder = GetPathFinder(team)) {
2389-
return pathFinder->CalculatePathAsync(start, end, digStrength, callback);
2390-
}
2391-
2392-
return nullptr;
2383+
return GetPathFinder(team).CalculatePathAsync(start, end, digStrength, callback);
23932384
}
23942385

23952386
int Scene::GetScenePathSize() const {
@@ -2401,11 +2392,7 @@ std::list<Vector>& Scene::GetScenePath() {
24012392
}
24022393

24032394
bool Scene::PositionsAreTheSamePathNode(const Vector& pos1, const Vector& pos2) const {
2404-
if (const std::unique_ptr<PathFinder>& pathFinder = const_cast<Scene*>(this)->GetPathFinder(Activity::Teams::NoTeam)) {
2405-
return pathFinder->PositionsAreTheSamePathNode(pos1, pos2);
2406-
}
2407-
2408-
return false;
2395+
return const_cast<Scene*>(this)->GetPathFinder(Activity::Teams::NoTeam).PositionsAreTheSamePathNode(pos1, pos2);
24092396
}
24102397

24112398
void Scene::Lock() {
@@ -2447,7 +2434,7 @@ void Scene::Update() {
24472434

24482435
m_NavigatableAreasUpToDate = true;
24492436
for (int team = Activity::Teams::NoTeam; team < Activity::Teams::MaxTeamCount; ++team) {
2450-
PathFinder& pathFinder = *GetPathFinder(static_cast<Activity::Teams>(team));
2437+
PathFinder& pathFinder = GetPathFinder(static_cast<Activity::Teams>(team));
24512438

24522439
pathFinder.MarkAllNodesNavigatable(m_NavigatableAreas.empty());
24532440

@@ -2467,7 +2454,11 @@ void Scene::Update() {
24672454
}
24682455
}
24692456

2470-
std::unique_ptr<PathFinder>& Scene::GetPathFinder(Activity::Teams team) {
2457+
PathFinder& Scene::GetPathFinder(Activity::Teams team) {
2458+
if (team < Activity::NoTeam || team >= Activity::MaxTeamCount) {
2459+
return *m_pPathFinders[0]; // Use NoTeam if a mod does something insane like applying an actor to team 6 (yes this actually happens)
2460+
}
2461+
24712462
// Note - we use + 1 when getting pathfinders by index, because our shared NoTeam pathfinder occupies index 0, and the rest come after that.
2472-
return m_pPathFinders[static_cast<int>(team) + 1];
2463+
return *m_pPathFinders[static_cast<int>(team) + 1];
24732464
}

Source/Entities/Scene.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -810,8 +810,8 @@ namespace RTE {
810810
private:
811811
/// Gets the pathfinder for a given team.
812812
/// @param team The team to get the pathfinder for. NoTeam is valid, and will give a shared pathfinder.
813-
/// @return A pointer to the pathfinder for the given team.
814-
std::unique_ptr<PathFinder>& GetPathFinder(Activity::Teams team);
813+
/// @return A reference to the pathfinder for the given team.
814+
PathFinder& GetPathFinder(Activity::Teams team);
815815

816816
/// Serializes the SceneObject via the Writer. Necessary because full serialization doesn't know how to deal with duplicate properties.
817817
/// @param writer The Writer being used for serialization.

0 commit comments

Comments
 (0)