Fix game crashing when touching a dock to an unloaded area

This commit is contained in:
Phillip Stephens 2017-12-03 18:26:17 -08:00
parent 2bb0a9687e
commit 5c7a03fb40
3 changed files with 21 additions and 13 deletions

View File

@ -434,16 +434,16 @@ void CStateManager::SetActorAreaId(CActor& actor, TAreaId aid)
{ {
CGameArea* area = x850_world->GetArea(actorAid); CGameArea* area = x850_world->GetArea(actorAid);
if (area->IsPostConstructed()) if (area->IsPostConstructed())
area->GetAreaObjects().RemoveObject(actor.GetUniqueId()); area->GetAreaObjects()->RemoveObject(actor.GetUniqueId());
} }
if (aid == kInvalidAreaId) if (aid == kInvalidAreaId)
return; return;
CGameArea* area = x850_world->GetArea(aid); CGameArea* area = x850_world->GetArea(aid);
if (!area->IsPostConstructed() || area->GetAreaObjects().GetValidObjectById(actor.GetUniqueId())) if (!area->IsPostConstructed() || area->GetAreaObjects()->GetValidObjectById(actor.GetUniqueId()))
return; return;
area->GetAreaObjects().AddObject(actor); area->GetAreaObjects()->AddObject(actor);
} }
void CStateManager::TouchSky() const void CStateManager::TouchSky() const
@ -2300,7 +2300,7 @@ void CStateManager::RemoveObject(TUniqueId uid)
{ {
CGameArea* area = x850_world->GetArea(ent->GetAreaIdAlways()); CGameArea* area = x850_world->GetArea(ent->GetAreaIdAlways());
if (area->IsPostConstructed()) if (area->IsPostConstructed())
area->GetAreaObjects().RemoveObject(uid); area->GetAreaObjects()->RemoveObject(uid);
} }
if (TCastToPtr<CActor> act = ent) if (TCastToPtr<CActor> act = ent)
x874_sortedListManager->Remove(act.GetPtr()); x874_sortedListManager->Remove(act.GetPtr());
@ -2470,7 +2470,7 @@ void CStateManager::AddObject(CEntity& ent)
{ {
CGameArea* area = x850_world->GetArea(ent.GetAreaIdAlways()); CGameArea* area = x850_world->GetArea(ent.GetAreaIdAlways());
if (area->IsPostConstructed()) if (area->IsPostConstructed())
area->GetAreaObjects().AddObject(ent); area->GetAreaObjects()->AddObject(ent);
} }
if (TCastToPtr<CActor> act = ent) if (TCastToPtr<CActor> act = ent)

View File

@ -360,15 +360,20 @@ public:
s32 GetDockCount() const { return xcc_docks.size(); } s32 GetDockCount() const { return xcc_docks.size(); }
Dock* DockNC(s32 dock) { return &xcc_docks[dock]; } Dock* DockNC(s32 dock) { return &xcc_docks[dock]; }
bool IsPostConstructed() const {return xf0_24_postConstructed;} bool IsPostConstructed() const { return xf0_24_postConstructed && x12c_postConstructed; }
const CPostConstructed* GetPostConstructed() const {return x12c_postConstructed.get();} const CPostConstructed* GetPostConstructed() const
{
if (!x12c_postConstructed)
return nullptr;
return x12c_postConstructed.get();
}
bool IsValidated() const { return xf0_28_validated; } bool IsValidated() const { return xf0_28_validated; }
void SetAreaAttributes(const CScriptAreaAttributes* areaAttributes); void SetAreaAttributes(const CScriptAreaAttributes* areaAttributes);
bool GetActive() const { return xf0_25_active; } bool GetActive() const { return xf0_25_active; }
void SetActive(bool active) { xf0_25_active = active; } void SetActive(bool active) { xf0_25_active = active; }
CObjectList& GetAreaObjects() const { return *GetPostConstructed()->x10c0_areaObjs.get(); } CObjectList* GetAreaObjects() const { return GetPostConstructed()->x10c0_areaObjs.get(); }
CGameArea* GetNext() const { return x130_next; } CGameArea* GetNext() const { return x130_next; }

View File

@ -72,8 +72,10 @@ void CScriptDock::Think(float dt, CStateManager& mgr)
mgr.SetCurrentAreaId(aid); mgr.SetCurrentAreaId(aid);
s32 otherDock = dock->GetOtherDockNumber(dock->GetReferenceCount()); s32 otherDock = dock->GetOtherDockNumber(dock->GetReferenceCount());
CObjectList& objs = mgr.WorldNC()->GetArea(aid)->GetAreaObjects(); CObjectList* objs = mgr.WorldNC()->GetArea(aid)->GetAreaObjects();
for (CEntity* ent : objs) if (objs)
{
for (CEntity* ent : *objs)
{ {
TCastToPtr<CScriptDock> dock(ent); TCastToPtr<CScriptDock> dock(ent);
if (dock && dock->GetDockId() == otherDock) if (dock && dock->GetDockId() == otherDock)
@ -81,6 +83,7 @@ void CScriptDock::Think(float dt, CStateManager& mgr)
} }
} }
} }
}
x264_dockState = EDockState::Idle; x264_dockState = EDockState::Idle;
} }