Work on CStateManager::InitializeState flow

This commit is contained in:
Jack Andersen 2016-08-13 17:00:58 -10:00
parent abcb9c2424
commit 2a425b5a73
20 changed files with 403 additions and 80 deletions

View File

@ -2,12 +2,18 @@
#define __DNACOMMON_ITWEAKPLAYER_HPP__
#include "../DNACommon.hpp"
#include "zeus/CAABox.hpp"
namespace DataSpec
{
struct ITweakPlayer : BigYAML
{
virtual float GetPlayerHeight() const=0; // x26c
virtual float GetPlayerXYHalfExtent() const=0; // x270
virtual float GetPlayerSomething1() const=0; // x274
virtual float GetPlayerSomething2() const=0; // x278
virtual float GetPlayerSomething3() const=0; // x27c
virtual float GetLeftLogicalThreshold() const=0;
virtual float GetRightLogicalThreshold() const=0;
};

View File

@ -11,8 +11,18 @@ namespace DNAMP1
struct CTweakPlayer : ITweakPlayer
{
DECL_YAML
Value<float> m_playerHeight;
Value<float> m_playerXYHalfExtent;
Value<float> m_unk1;
Value<float> m_unk2;
Value<float> m_unk3;
Value<float> m_leftDiv;
Value<float> m_rightDiv;
float GetPlayerHeight() const { return m_playerHeight; }
float GetPlayerXYHalfExtent() const { return m_playerXYHalfExtent; }
float GetPlayerSomething1() const { return m_unk1; }
float GetPlayerSomething2() const { return m_unk2; }
float GetPlayerSomething3() const { return m_unk3; }
float GetLeftLogicalThreshold() const {return m_leftDiv;}
float GetRightLogicalThreshold() const {return m_rightDiv;}
CTweakPlayer(athena::io::IStreamReader& reader) {this->read(reader);}

View File

@ -8,4 +8,19 @@ void CMapWorldInfo::SetDoorVisited(TEditorId eid, bool visited)
x14_[eid] = visited;
}
bool CMapWorldInfo::IsAreaVisted(TAreaId aid)
{
x4_visitedAreas.resize((aid + 31) / 32);
return (x4_visitedAreas[aid / 32] >> (aid % 32)) & 0x1;
}
void CMapWorldInfo::SetAreaVisited(TAreaId aid, bool visited)
{
x4_visitedAreas.resize((aid + 31) / 32);
if (visited)
x4_visitedAreas[aid / 32] |= 1 << (aid % 32);
else
x4_visitedAreas[aid / 32] &= ~(1 << (aid % 32));
}
}

View File

@ -7,6 +7,7 @@ namespace urde
{
class CMapWorldInfo
{
std::vector<u32> x4_visitedAreas;
std::map<TEditorId, bool> x14_;
public:
CMapWorldInfo()=default;
@ -16,8 +17,8 @@ public:
void SetIsMapped(bool) const;
void SetDoorVisited(TEditorId eid, bool val);
bool IsDoorVisited() const;
bool IsAreaVisted(TAreaId) const;
void SetAreaVisited(TAreaId, bool) const;
bool IsAreaVisted(TAreaId);
void SetAreaVisited(TAreaId, bool);
};
}

View File

@ -59,16 +59,16 @@ zeus::CTransform CMappableObject::AdjustTransformForType()
void CMappableObject::PostConstruct(const void *)
{
#if __BYTE_ORDER__!= __ORDER_BIG_ENDIAN__
x0_type = EMappableObjectType(SBIG(u32(x0_type)));
x4_ = SBIG(x4_);
x8_ = SBIG(x8_);
xc_ = SBIG(xc_);
x0_type = EMappableObjectType(hecl::SBig(u32(x0_type)));
x4_ = hecl::SBig(x4_);
x8_.id = hecl::SBig(x8_.id);
xc_ = hecl::SBig(xc_);
for (u32 i = 0 ; i<3 ; i++)
{
for (u32 j = 0 ; j<4 ; j++)
{
u32* tmp = reinterpret_cast<u32*>(&x10_transform.basis.m[i][j]);
*tmp = SBIG(*tmp);
*tmp = hecl::SBig(*tmp);
}
}

View File

@ -33,4 +33,21 @@ void CGameState::SetTotalPlayTime(float time)
xa0_playTime = zeus::clamp<double>(0.0, time, 359999.0);
}
CWorldState& CGameState::StateForWorld(ResId mlvlId)
{
auto it = x88_worldStates.begin();
for (; it != x88_worldStates.end() ; ++it)
{
if (it->GetWorldAssetId() == mlvlId)
break;
}
if (it == x88_worldStates.end())
{
x88_worldStates.emplace_back(mlvlId);
return x88_worldStates.back();
}
return *it;
}
}

View File

@ -10,9 +10,21 @@
namespace urde
{
class CWorldState
{
ResId x0_mlvlId;
TAreaId x4_areaId;
public:
CWorldState(ResId id) : x0_mlvlId(id) {}
ResId GetWorldAssetId() const {return x0_mlvlId;}
void SetAreaId(TAreaId aid) { x4_areaId = aid; }
};
class CGameState
{
int m_stateFlag = -1;
ResId x84_mlvlId = -1;
std::vector<CWorldState> x88_worldStates;
CPlayerState x98_playerState;
CWorldTransManager x9c_transManager;
float m_gameTime = 0.0;
@ -24,6 +36,8 @@ public:
void SetCurrentWorldId(unsigned int id, const std::string& name);
CWorldTransManager& WorldTransitionManager() {return x9c_transManager;}
void SetTotalPlayTime(float time);
CWorldState& StateForWorld(ResId mlvlId);
CWorldState& CurrentWorldState() { return StateForWorld(x84_mlvlId); }
};
}

View File

@ -51,7 +51,7 @@ void CRelayTracker::SendMsgs(const TAreaId& areaId, CStateManager& stateMgr)
for (u32 i=0 ; i<relayCount ; ++i)
{
const CWorld::CRelay& relay = world->GetRelay(i);
if (((relay.GetTargetId() >> 16) & 0x3FF) != areaId)
if (relay.GetTargetId().AreaNum() != areaId)
continue;
if (!HasRelay(relay.GetRelayId()))
@ -69,7 +69,7 @@ void CRelayTracker::SendMsgs(const TAreaId& areaId, CStateManager& stateMgr)
for (u32 i=0 ; i<relayCount ; ++i)
{
const CWorld::CRelay& relay = world->GetRelay(i);
if (((relay.GetTargetId() >> 16) & 0x3FF) != areaId)
if (relay.GetTargetId().AreaNum() != areaId)
continue;
if (!HasRelay(relay.GetRelayId()) || !relay.GetActive())

View File

@ -12,8 +12,10 @@
#include "GameGlobalObjects.hpp"
#include "CSimplePool.hpp"
#include "CPlayerState.hpp"
#include "CGameState.hpp"
#include "World/CPlayer.hpp"
#include "World/CMorphBall.hpp"
#include "AutoMapper/CMapWorldInfo.hpp"
#include <cmath>
@ -31,16 +33,9 @@ CStateManager::CStateManager(const std::weak_ptr<CRelayTracker>&,
x82c_lightObjs(new CGameLightList()),
x834_listenAiObjs(new CListeningAiList()),
x83c_aiWaypointObjs(new CAiWaypointList()),
x844_platformAndDoorObjs(new CPlatformAndDoorList()),
x870_cameraManager(new CCameraManager(kInvalidUniqueId)),
x874_sortedListManager(new CSortedListManager()),
x878_weaponManager(new CWeaponMgr()),
x87c_fluidPlaneManager(new CFluidPlaneManager()),
x880_envFxManager(new CEnvFxManager()),
x884_actorModelParticles(new CActorModelParticles()),
x888_teamAiTypes(new CTeamAiTypes()),
x88c_rumbleManager(new CRumbleManager())
x844_platformAndDoorObjs(new CPlatformAndDoorList())
{
x86c_stateManagerContainer.emplace();
x904_loaderFuncs[int(EScriptObjectType::Actor)] = ScriptLoader::LoadActor;
x904_loaderFuncs[int(EScriptObjectType::Waypoint)] = ScriptLoader::LoadWaypoint;
x904_loaderFuncs[int(EScriptObjectType::Door)] = ScriptLoader::LoadDoor;
@ -168,7 +163,7 @@ CStateManager::CStateManager(const std::weak_ptr<CRelayTracker>&,
x904_loaderFuncs[int(EScriptObjectType::ShadowProjector)] = ScriptLoader::LoadShadowProjector;
x904_loaderFuncs[int(EScriptObjectType::EnergyBall)] = ScriptLoader::LoadEnergyBall;
x8ec_shadowTex = g_SimplePool->GetObj("DefaultShadow");
x8f0_shadowTex = g_SimplePool->GetObj("DefaultShadow");
}
void CStateManager::UpdateThermalVisor()
@ -356,18 +351,36 @@ void CStateManager::RecursiveDrawTree(TUniqueId) const
{
}
void CStateManager::SendScriptMsg(TUniqueId dest, TUniqueId src, EScriptObjectMessage msg)
void CStateManager::SendScriptMsg(CEntity* dest, TUniqueId src, EScriptObjectMessage msg)
{
CEntity* ent = ObjectById(dest);
if (ent)
if (dest && !dest->x30_26_messagesBlocked)
{
ent->AcceptScriptMsg(msg, src, *this);
dest->AcceptScriptMsg(msg, src, *this);
}
}
void CStateManager::SendScriptMsg(TUniqueId uid, TEditorId eid,
void CStateManager::SendScriptMsg(TUniqueId dest, TUniqueId src, EScriptObjectMessage msg)
{
CEntity* ent = ObjectById(dest);
SendScriptMsg(ent, src, msg);
}
void CStateManager::SendScriptMsg(TUniqueId src, TEditorId dest,
EScriptObjectMessage msg, EScriptObjectState state)
{
CEntity* ent = ObjectById(src);
auto search = GetIdListForScript(dest);
if (ent &&
search.first != x890_scriptIdMap.cend() &&
search.second != x890_scriptIdMap.cend())
{
for (auto it = search.first ; it != search.second ; ++it)
{
TUniqueId id = it->second;
CEntity* dobj = x80c_allObjs->GetObjectById(id);
SendScriptMsg(dobj, src, msg);
}
}
}
void CStateManager::FreeScriptObjects(TAreaId)
@ -388,8 +401,11 @@ TUniqueId CStateManager::GetIdForScript(TEditorId) const
return 0;
}
void CStateManager::GetIdListForScript(TEditorId) const
std::pair<std::multimap<TEditorId, TUniqueId>::const_iterator,
std::multimap<TEditorId, TUniqueId>::const_iterator>
CStateManager::GetIdListForScript(TEditorId id) const
{
return x890_scriptIdMap.equal_range(id);
}
void CStateManager::LoadScriptObjects(TAreaId, CInputStream& in, std::vector<TEditorId>& idsOut)
@ -475,12 +491,55 @@ void CStateManager::FrameBegin()
{
}
void CStateManager::InitializeState(u32, TAreaId, u32)
void CStateManager::InitializeState(ResId mlvlId, TAreaId aid, ResId mreaId)
{
if (xb3c_initPhase == InitPhase::LoadWorld)
{
CreateStandardGameObjects();
x850_world.reset(new CWorld(*g_SimplePool, *g_ResFactory, mlvlId));
xb3c_initPhase = InitPhase::LoadFirstArea;
}
if (xb3c_initPhase == InitPhase::LoadFirstArea)
{
if (!x8f0_shadowTex.IsLoaded())
return;
x8f0_shadowTex.GetObj();
if (!x850_world->CheckWorldComplete(this, aid, mreaId))
return;
x8cc_nextAreaId = x850_world->x68_curAreaId;
CGameArea* area = x850_world->x18_areas[x8cc_nextAreaId].get();
if (x850_world->ScheduleAreaToLoad(area, *this))
{
area->StartStreamIn(*this);
return;
}
xb3c_initPhase = InitPhase::Done;
}
SetCurrentAreaId(x8cc_nextAreaId);
g_GameState->CurrentWorldState().SetAreaId(x8cc_nextAreaId);
x850_world->TravelToArea(x8cc_nextAreaId, *this, true);
UpdateRoomAcoustics(x8cc_nextAreaId);
/* TODO: Finish */
}
void CStateManager::CreateStandardGameObjects()
{
float height = g_tweakPlayer->GetPlayerHeight();
float xyHe = g_tweakPlayer->GetPlayerXYHalfExtent();
float unk1 = g_tweakPlayer->GetPlayerSomething1();
float unk2 = g_tweakPlayer->GetPlayerSomething2();
float unk3 = g_tweakPlayer->GetPlayerSomething3();
zeus::CAABox pBounds = {{-xyHe, -xyHe, 0.f}, {xyHe, xyHe, height}};
auto q = zeus::CQuaternion::fromAxisAngle(zeus::CVector3f{0.f, 0.f, 1.f}, zeus::degToRad(129.6f));
x84c_player.reset(new CPlayer(AllocateUniqueId(), zeus::CTransform(q), pBounds, 0,
zeus::CVector3f{1.65f, 1.65f, 1.65f},
200.f, unk1, unk2, unk3, CMaterialList(EMaterialTypes::ThirtyTwo,
EMaterialTypes::Nineteen, EMaterialTypes::ThirtySeven)));
AddObject(*x84c_player);
}
CObjectList* CStateManager::ObjectListById(EGameObjectList type)
@ -503,8 +562,21 @@ void CStateManager::UpdateRoomAcoustics(TAreaId)
{
}
void CStateManager::SetCurrentAreaId(TAreaId)
void CStateManager::SetCurrentAreaId(TAreaId aid)
{
if (aid != x8cc_nextAreaId)
{
x8d0_prevAreaId = x8cc_nextAreaId;
UpdateRoomAcoustics(aid);
x8cc_nextAreaId = aid;
}
if (aid == kInvalidAreaId)
return;
if (x8c0_mapWorldInfo->IsAreaVisted(aid))
return;
x8c0_mapWorldInfo->SetAreaVisited(aid, true);
x850_world->GetMapWorld()->RecalculateWorldSphere(*x8c0_mapWorldInfo, *x850_world);
}
void CStateManager::ClearGraveyard()
@ -565,11 +637,11 @@ zeus::CAABox CStateManager::CalculateObjectBounds(const CActor&)
return {};
}
void CStateManager::AddObject(CEntity&, EScriptPersistence)
void CStateManager::AddObject(CEntity&)
{
}
void CStateManager::AddObject(CEntity*, EScriptPersistence)
void CStateManager::AddObject(CEntity*)
{
}

View File

@ -14,6 +14,12 @@
#include "World/CAi.hpp"
#include "CToken.hpp"
#include "World/ScriptLoader.hpp"
#include "Input/CFinalInput.hpp"
#include "CSortedLists.hpp"
#include "CFluidPlaneManager.hpp"
#include "World/CEnvFxManager.hpp"
#include "World/CActorModelParticles.hpp"
#include "Input/CRumbleManager.hpp"
namespace urde
{
@ -64,17 +70,29 @@ class CStateManager
/* Used to be a list of 32-element reserved_vectors */
std::vector<TUniqueId> x858_objectGraveyard;
// x86c_stateManagerContainer;
std::unique_ptr<CCameraManager> x870_cameraManager;
std::unique_ptr<CSortedListManager> x874_sortedListManager;
std::unique_ptr<CWeaponMgr> x878_weaponManager;
std::unique_ptr<CFluidPlaneManager> x87c_fluidPlaneManager;
std::unique_ptr<CEnvFxManager> x880_envFxManager;
std::unique_ptr<CActorModelParticles> x884_actorModelParticles;
std::unique_ptr<CTeamAiTypes> x888_teamAiTypes;
std::unique_ptr<CRumbleManager> x88c_rumbleManager;
struct CStateManagerContainer
{
CCameraManager x0_cameraManager;
CSortedListManager x3c0_sortedListManager;
CWeaponMgr xe3d8_weaponManager;
CFluidPlaneManager xe3ec_fluidPlaneManager;
CEnvFxManager xe510_envFxManager;
CActorModelParticles xf168_actorModelParticles;
CRumbleManager xf250_rumbleManager;
u32 xf344_ = 0;
u32 xf370_ = 0;
u32 xf39c_ = 0;
};
std::experimental::optional<CStateManagerContainer> x86c_stateManagerContainer;
CCameraManager* x870_cameraManager = nullptr;
CSortedListManager* x874_sortedListManager = nullptr;
CWeaponMgr* x878_weaponManager = nullptr;
CFluidPlaneManager* x87c_fluidPlaneManager = nullptr;
CEnvFxManager* x880_envFxManager = nullptr;
CActorModelParticles* x884_actorModelParticles = nullptr;
CRumbleManager* x88c_rumbleManager = nullptr;
std::map<TGameScriptId, TUniqueId> x890_scriptIdMap;
std::multimap<TEditorId, TUniqueId> x890_scriptIdMap;
std::map<TEditorId, SScriptObjectStream> x8a4_loadedScriptObjects;
std::shared_ptr<CPlayerState> x8b8_playerState;
@ -84,16 +102,15 @@ class CStateManager
TAreaId x8c8_currentAreaId;
TAreaId x8cc_nextAreaId;
u32 x8d0_extFrameIdx = 0;
u32 x8d4_updateFrameIdx = 0;
u32 x8d8_drawFrameIdx = 0;
TAreaId x8d0_prevAreaId;
//u32 x8d0_extFrameIdx = 0;
//u32 x8d4_updateFrameIdx = 0;
//u32 x8d8_drawFrameIdx = 0;
std::vector<CLight> x8dc_dynamicLights;
TLockedToken<CTexture> x8ec_shadowTex; /* DefaultShadow in MiscData */
CRandom16 x8f8_random;
CRandom16* x8fc_activeRandom = nullptr;
TLockedToken<CTexture> x8f0_shadowTex; /* DefaultShadow in MiscData */
CRandom16 x8fc_random;
FScriptLoader x904_loaderFuncs[int(EScriptObjectType::ScriptObjectTypeMAX)] = {};
@ -101,8 +118,16 @@ class CStateManager
std::set<std::string> xab4_uniqueInstanceNames;
CCameraFilterPass xaf8_camFilterPasses[9];
CCameraBlurPass xc88_camBlurPasses[9];
enum class InitPhase
{
LoadWorld,
LoadFirstArea,
Done
} xb3c_initPhase;
CFinalInput xb54_finalInput;
CCameraFilterPass xb84_camFilterPasses[9];
CCameraBlurPass xd14_camBlurPasses[9];
s32 xe60_ = -1;
zeus::CVector3f xe64_;
@ -178,13 +203,17 @@ public:
void PreRender();
void GetVisSetForArea(TAreaId, TAreaId) const;
void RecursiveDrawTree(TUniqueId) const;
void SendScriptMsg(CEntity* dest, TUniqueId src, EScriptObjectMessage msg);
void SendScriptMsg(TUniqueId dest, TUniqueId src, EScriptObjectMessage msg);
void SendScriptMsg(TUniqueId uid, TEditorId eid, EScriptObjectMessage msg, EScriptObjectState state);
void SendScriptMsg(TUniqueId src, TEditorId dest,
EScriptObjectMessage msg, EScriptObjectState state);
void FreeScriptObjects(TAreaId);
void GetBuildForScript(TEditorId) const;
TEditorId GetEditorIdForUniqueId(TUniqueId) const;
TUniqueId GetIdForScript(TEditorId) const;
void GetIdListForScript(TEditorId) const;
std::pair<std::multimap<TEditorId, TUniqueId>::const_iterator,
std::multimap<TEditorId, TUniqueId>::const_iterator>
GetIdListForScript(TEditorId) const;
void LoadScriptObjects(TAreaId, CInputStream& in, std::vector<TEditorId>& idsOut);
void LoadScriptObject(TAreaId, EScriptObjectType, u32, CInputStream& in, EScriptPersistence);
void InitScriptObjects(std::vector<TEditorId>& ids);
@ -208,7 +237,7 @@ public:
void Update(float dt);
void UpdateGameState();
void FrameBegin();
void InitializeState(u32, TAreaId, u32);
void InitializeState(ResId mlvlId, TAreaId aid, ResId mreaId);
void CreateStandardGameObjects();
const std::unique_ptr<CObjectList>& GetObjectList() const { return x80c_allObjs; }
CObjectList* ObjectListById(EGameObjectList type);
@ -233,8 +262,8 @@ public:
void UpdateActorInSortedLists(CActor&);
void UpdateSortedLists();
zeus::CAABox CalculateObjectBounds(const CActor&);
void AddObject(CEntity&, EScriptPersistence);
void AddObject(CEntity*, EScriptPersistence);
void AddObject(CEntity&);
void AddObject(CEntity*);
bool RayStaticIntersection(const zeus::CVector3f&, const zeus::CVector3f&, float,
const CMaterialFilter&) const;
bool RayWorldIntersection(TUniqueId, const zeus::CVector3f&, const zeus::CVector3f&,
@ -244,13 +273,13 @@ public:
TUniqueId AllocateUniqueId();
const std::shared_ptr<CPlayerState>& GetPlayerState() const {return x8b8_playerState;}
CRandom16* GetActiveRandom() {return x8fc_activeRandom;}
CRandom16& GetActiveRandom() {return x8fc_random;}
CRumbleManager& GetRumbleManager() {return *x88c_rumbleManager;}
CCameraFilterPass& GetCameraFilterPass(int idx) {return xaf8_camFilterPasses[idx];}
CCameraFilterPass& GetCameraFilterPass(int idx) {return xb84_camFilterPasses[idx];}
CWorld* GetWorld() {return x850_world.get();}
CRelayTracker* GetRelayTracker() { return x8bc_relayTracker.get(); }
CCameraManager* GetCameraManager() { return x870_cameraManager.get(); }
CCameraManager* GetCameraManager() { return x870_cameraManager; }
std::shared_ptr<CMapWorldInfo> MapWorldInfo() { return x8c0_mapWorldInfo; }

View File

@ -77,7 +77,7 @@ void CCameraManager::Update(float dt, CStateManager& stateMgr)
it = x18_shakers.erase(it);
continue;
}
x30_shakeOffset += it->GeneratePoint(dt, *stateMgr.GetActiveRandom());
x30_shakeOffset += it->GeneratePoint(dt, stateMgr.GetActiveRandom());
++it;
}

View File

@ -39,7 +39,7 @@ class CCameraManager
};
public:
CCameraManager(TUniqueId curCameraId);
CCameraManager(TUniqueId curCameraId=kInvalidUniqueId);
static float DefaultAspect() {return 1.42f;}
static float DefaultFarPlane() {return 750.0f;}

View File

@ -37,11 +37,23 @@ struct SObjectTag
};
using TUniqueId = s16;
using TEditorId = s32;
using TAreaId = s32;
using TGameScriptId = s32;
#define kInvalidEditorId TEditorId(-1)
struct TEditorId
{
TEditorId() = default;
TEditorId(u32 idin) : id(idin) {}
u32 id = -1;
u8 LayerNum() const { return (id >> 26) & 0x3f; }
u16 AreaNum() const { return (id >> 16) & 0x3ff; }
TUniqueId Id() const { return id & 0xffff; }
bool operator<(const TEditorId& other) const { return (id & 0x3ffffff) < (other.id & 0x3ffffff); }
bool operator!=(const TEditorId& other) const { return (id & 0x3ffffff) != (other.id & 0x3ffffff); }
bool operator==(const TEditorId& other) const { return (id & 0x3ffffff) == (other.id & 0x3ffffff); }
};
#define kInvalidEditorId TEditorId()
#define kInvalidUniqueId TUniqueId(-1)
#define kInvalidAreaId TAreaId(-1)

View File

@ -25,11 +25,12 @@ public:
: x0_areaId(aid), x4_conns(conns) {}
TAreaId GetAreaId() const {return x0_areaId;}
std::vector<SConnection> GetConnectionList() const { return x4_conns; }
ResId GetEditorId() const { return x14_editorId; }
TEditorId GetEditorId() const { return x14_editorId; }
};
class CEntity
{
friend class CStateManager;
protected:
TAreaId x4_areaId;
TUniqueId x8_uid;
@ -43,7 +44,7 @@ protected:
{
bool x30_24_active : 1;
bool x30_25_ : 1;
bool x30_26_ : 1;
bool x30_26_messagesBlocked : 1;
bool x30_27_ : 1;
};
u8 _dummy = 0;

View File

@ -556,8 +556,24 @@ void CGameArea::AddStaticGeometry()
}
}
void CGameArea::SetChain(CGameArea* other, int)
EChain CGameArea::SetChain(CGameArea* next, EChain setChain)
{
if (x138_curChain == setChain)
return x138_curChain;
if (x134_prev)
x134_prev->x130_next = x130_next;
if (x130_next)
x130_next->x134_prev = x134_prev;
x134_prev = nullptr;
x130_next = next;
if (next)
next->x134_prev = this;
EChain ret = x138_curChain;
x138_curChain = setChain;
return ret;
}
bool CGameArea::StartStreamingMainArea()
@ -653,7 +669,7 @@ void CGameArea::AllocNewAreaData(int offset, int size)
x110_mreaSecBufs.back().first));
}
void CGameArea::Invalidate(CStateManager& mgr)
bool CGameArea::Invalidate(CStateManager& mgr)
{
}

View File

@ -216,6 +216,10 @@ private:
u32 x128_mreaDataOffset = 0;
std::unique_ptr<CPostConstructed> x12c_postConstructed;
CGameArea* x130_next = nullptr;
CGameArea* x134_prev = nullptr;
EChain x138_curChain = EChain::Zero;
void UpdateFog(float dt);
void UpdateThermalVisor(float dt);
@ -274,14 +278,14 @@ public:
void AddStaticGeometry();
//void TransferTokensToARAM();
//void TransferARAMTokensOver();
void SetChain(CGameArea* other, int);
EChain SetChain(CGameArea* prev, EChain chain);
bool StartStreamingMainArea();
//void UnloadAllLoadedTextures();
//void ReloadAllLoadedTextures();
void ReloadAllUnloadedTextures();
u32 GetNumPartSizes() const;
void AllocNewAreaData(int, int);
void Invalidate(CStateManager& mgr);
bool Invalidate(CStateManager& mgr);
void CullDeadAreaRequests();
void StartStreamIn(CStateManager& mgr);
bool Validate(CStateManager& mgr);

View File

@ -12,7 +12,7 @@ static CModelData MakePlayerAnimRes(ResId resId, const zeus::CVector3f& scale)
CPlayer::CPlayer(TUniqueId uid, const zeus::CTransform& xf, const zeus::CAABox& aabb, unsigned int resId,
const zeus::CVector3f& playerScale, float f1, float f2, float f3, float f4, const CMaterialList& ml)
: CPhysicsActor(uid, true, "CPlayer", CEntityInfo(kInvalidAreaId, CEntity::NullConnectionList, kInvalidEditorId),
: CPhysicsActor(uid, true, "CPlayer", CEntityInfo(kInvalidAreaId, CEntity::NullConnectionList),
xf, MakePlayerAnimRes(resId, playerScale), ml, aabb, SMoverData(f1), CActorParameters::None(), f2, f3)
{
x768_morphball.reset(new CMorphBall(*this, f4));

View File

@ -227,7 +227,7 @@ ResId CWorld::IGetSaveWorldAssetId() const
const CMapWorld* CWorld::IGetMapWorld() const
{
return GetMapWorld();
return ((CWorld*)this)->GetMapWorld();
}
CMapWorld* CWorld::IMapWorld()
@ -271,6 +271,15 @@ TAreaId CWorld::IGetAreaId(ResId id) const
void CWorld::MoveToChain(CGameArea* area, EChain chain)
{
if (area->x138_curChain == chain)
return;
if (area->x138_curChain != EChain::Invalid)
if (x4c_chainHeads[int(chain)] == area)
x4c_chainHeads[int(chain)] = area->x130_next;
area->SetChain(x4c_chainHeads[int(chain)], chain);
x4c_chainHeads[int(chain)] = area;
}
void CWorld::LoadSoundGroup(int groupId, ResId agscId, CSoundGroupData& data)
@ -444,6 +453,117 @@ bool CWorld::CheckWorldComplete(CStateManager* mgr, TAreaId id, ResId mreaId)
return false;
}
bool CWorld::ScheduleAreaToLoad(CGameArea* area, CStateManager& mgr)
{
if (!area->xf0_24_postConstructed)
{
MoveToChain(area, EChain::Two);
return true;
}
else
{
if (area->x138_curChain != EChain::Three)
{
if (area->x138_curChain != EChain::Four)
{
x70_24_ = true;
}
MoveToChain(area, EChain::Three);
}
return false;
}
}
void CWorld::TravelToArea(TAreaId aid, CStateManager& mgr, bool skipLoadOther)
{
if (aid < 0 || aid >= x18_areas.size())
return;
x70_24_ = false;
x68_curAreaId = aid;
CGameArea* chain0 = x4c_chainHeads[0];
while (chain0)
{
if (chain0->Invalidate(mgr))
{
MoveToChain(chain0, EChain::One);
break;
}
chain0 = chain0->x130_next;
}
CGameArea* chain3 = x4c_chainHeads[3];
while (chain3)
{
MoveToChain(chain3, EChain::Four);
chain3 = chain3->x130_next;
}
CGameArea* chain2 = x4c_chainHeads[2];
while (chain2)
{
MoveToChain(chain2, EChain::Zero);
chain2 = chain2->x130_next;
}
CGameArea* area = x18_areas[aid].get();
if (area->x138_curChain != EChain::Four)
x70_24_ = true;
area->Validate(mgr);
MoveToChain(area, EChain::Three);
area->SetOcclusionState(CGameArea::EOcclusionState::Occluded);
CGameArea* otherLoadArea = nullptr;
if (!skipLoadOther)
{
bool otherLoading = false;
for (CGameArea::Dock& dock : area->xcc_docks)
{
u32 dockRefCount = dock.GetDockRefs().size();
for (u32 i=0 ; i<dockRefCount ; ++i)
{
if (!dock.ShouldLoadOtherArea(i))
continue;
TAreaId connArea = dock.GetConnectedAreaId(i);
CGameArea* cArea = x18_areas[connArea].get();
if (!cArea->xf0_25_active)
continue;
if (!otherLoading)
{
otherLoading = ScheduleAreaToLoad(cArea, mgr);
if (!otherLoading)
continue;
otherLoadArea = cArea;
}
else
ScheduleAreaToLoad(cArea, mgr);
}
}
}
CGameArea* chain4 = x4c_chainHeads[4];
while (chain4)
{
MoveToChain(chain4, EChain::Zero);
chain4 = chain4->x130_next;
}
size_t toStreamCount = 0;
chain0 = x4c_chainHeads[0];
while (chain0)
{
chain0->RemoveStaticGeometry();
chain0 = chain0->x130_next;
++toStreamCount;
}
if (!toStreamCount && otherLoadArea && !x70_25_)
otherLoadArea->StartStreamIn(mgr);
GetMapWorld()->SetWhichMapAreasLoaded(*this, aid, 3);
}
bool CWorld::ICheckWorldComplete()
{
return CheckWorldComplete(nullptr, kInvalidAreaId, -1);

View File

@ -27,7 +27,7 @@ public:
virtual CMapWorld* IMapWorld()=0;
virtual const IGameArea* IGetAreaAlways(TAreaId id) const=0;
virtual TAreaId IGetCurrentAreaId() const=0;
virtual TAreaId IGetAreaId(TAreaId id) const=0;
virtual TAreaId IGetAreaId(ResId id) const=0;
virtual bool ICheckWorldComplete()=0;
virtual std::string IGetDefaultAudioTrack() const=0;
virtual int IGetAreaCount() const=0;
@ -70,6 +70,7 @@ public:
class CWorld : public IWorld
{
friend class CStateManager;
public:
class CRelay
{
@ -149,23 +150,16 @@ private:
public:
enum class EChain
{
Zero,
One,
Two,
Three,
Four
};
void MoveToChain(CGameArea* area, EChain chain);
bool CheckWorldComplete(CStateManager* mgr, TAreaId id, ResId mreaId);
bool ScheduleAreaToLoad(CGameArea* area, CStateManager& mgr);
void TravelToArea(TAreaId aid, CStateManager& mgr, bool);
CWorld(IObjectStore& objStore, IFactory& resFactory, ResId mlvlId);
bool DoesAreaExist(TAreaId area) const;
std::vector<std::unique_ptr<CGameArea>>& GetGameAreas() {return x18_areas;}
const CMapWorld* GetMapWorld() const {return x28_mapWorld.GetObj();}
CMapWorld* GetMapWorld() {return x28_mapWorld.GetObj();}
u32 GetRelayCount() const { return x2c_relays.size(); }
CRelay GetRelay(u32 idx) const { return x2c_relays[idx]; }

View File

@ -37,6 +37,7 @@ public:
const rstl::reserved_vector<zeus::CVector3f, 4>& GetPlaneVertices() const {return x14_planeVertices;}
u32 GetReferenceCount() const { return x0_; }
const std::vector<SDockReference>& GetDockRefs() const { return x4_dockReferences; }
Dock(CInputStream& in, const zeus::CTransform& xf);
TAreaId GetConnectedAreaId(s32 other) const;
s16 GetOtherDockNumber(s32 other) const;
@ -60,6 +61,17 @@ public:
virtual ResId IGetStringTableAssetId() const=0;
virtual const zeus::CTransform& IGetTM() const=0;
};
enum class EChain
{
Invalid = -1,
Zero,
One,
Two,
Three,
Four
};
}
#endif // __URDE_IGAMEAREA_HPP__