#ifndef _CWORLD #define _CWORLD #include "Kyoto/SObjectTag.hpp" #include "types.h" #include "MetroidPrime/CGameArea.hpp" #include "MetroidPrime/TGameTypes.hpp" #include "Kyoto/Audio/CSfxHandle.hpp" #include "Kyoto/IObjectStore.hpp" #include "Kyoto/TToken.hpp" #include "rstl/reserved_vector.hpp" #include "rstl/string.hpp" #include "rstl/vector.hpp" class CAudioGroupSet; class CDvdRequest; class CGameArea; class CMapWorld; class CModel; class CRelay; class CStateManager; class IGameArea; class CResFactory; class IWorld { public: virtual ~IWorld() {} virtual CAssetId IGetWorldAssetId() const = 0; virtual CAssetId IGetStringTableAssetId() const = 0; virtual CAssetId IGetSaveWorldAssetId() const = 0; virtual const CMapWorld* IGetMapWorld() const = 0; virtual CMapWorld* IMapWorld() = 0; virtual const IGameArea* IGetAreaAlways(TAreaId id) const = 0; virtual TAreaId IGetCurrentAreaId() const = 0; virtual TAreaId IGetAreaId(CAssetId id) const = 0; virtual bool ICheckWorldComplete() = 0; virtual rstl::string IGetDefaultAudioTrack() const = 0; virtual int IGetAreaCount() const = 0; }; class CRelay /* name? */ { public: explicit CRelay(CInputStream& in); const TEditorId& GetRelayId() const { return x0_relay; } const TEditorId& GetTargetId() const { return x4_target; } ushort GetMessage() const { return x8_msg; } bool GetActive() const { return xa_active; } static rstl::vector< CRelay > ReadMemoryRelays(CInputStream& in); // name? private: TEditorId x0_relay; TEditorId x4_target; ushort x8_msg; bool xa_active; }; // TODO move? enum EEnvFxType { kEFX_None, kEFX_Snow, kEFX_Rain, kEFX_UnderwaterFlake, }; class CWorld final : public IWorld { public: struct CSoundGroupData { int x0_groupId; CAssetId x4_agscId; bool x8_24_loadedIntoAram : 1; bool x8_25_loaded : 1; rstl::string xc_name; TCachedToken< CAudioGroupSet > x1c_groupData; public: CSoundGroupData(int grpId, CAssetId agsc); }; enum EAreaTravelType { kATT_Zero, kATT_One, }; enum EChain { kC_Invalid = -1, kC_ToDeallocate, kC_Deallocated, kC_Loading, kC_Alive, kC_AliveJudgement, }; CWorld(IObjectStore& objStore, CResFactory& resFactory, CAssetId mlvlId); ~CWorld(); CAssetId IGetWorldAssetId() const override; CAssetId IGetStringTableAssetId() const override; CAssetId IGetSaveWorldAssetId() const override; const CMapWorld* IGetMapWorld() const override; CMapWorld* IMapWorld() override; const IGameArea* IGetAreaAlways(TAreaId id) const override; TAreaId IGetCurrentAreaId() const override; TAreaId IGetAreaId(CAssetId id) const override; bool ICheckWorldComplete() override; rstl::string IGetDefaultAudioTrack() const override; int IGetAreaCount() const override; bool CheckWorldComplete(CStateManager* mgr, TAreaId aid, CAssetId mreaId); void SetLoadPauseState(bool); void TouchSky() const; void StopSounds(); void UnloadSoundGroups(); bool ScheduleAreaToLoad(CGameArea* area, CStateManager& mgr); void MoveToChain(CGameArea* area, EChain chain); void TravelToArea(TAreaId aid, CStateManager& mgr, EAreaTravelType type); CMapWorld* GetMapWorld() const; void LoadSoundGroups(); void LoadSoundGroup(uchar groupId, CAssetId agscId, CSoundGroupData& data); const CGameArea& GetAreaAlways(TAreaId id) const { return *x18_areas[id.Value()]; } CGameArea* Area(TAreaId id) { return x18_areas[id.Value()].get(); } const CGameArea* GetArea(TAreaId id) const { return x18_areas[id.Value()].get(); } bool IsAreaValid(TAreaId id) const { return x18_areas[id.Value()]->IsLoaded(); } CAssetId GetWorldAssetId() const { return x8_mlvlId; } TAreaId GetCurrentAreaId() const { return x68_curAreaId; } TAreaId GetAreaIdForSaveId(int saveId) const; const rstl::vector< CRelay >& GetRelays() const { return x2c_relays; } EEnvFxType GetNeededEnvFx() const { return xc4_neededFx; } static void PropogateAreaChain(CGameArea::EOcclusionState occlusionState, CGameArea* area, CWorld* world); CGameArea::CConstChainIterator GetChainHead(EChain chain) const { return CGameArea::CConstChainIterator(x4c_chainHeads[size_t(chain)]); } static CGameArea::CConstChainIterator GetAliveAreasEnd(); void StopGlobalSound(ushort soundId); private: enum Phase { kP_Loading, kP_LoadingMap, kP_LoadingMapAreas, kP_LoadingSkyBox, kP_LoadingSoundGroups, kP_Done, }; Phase x4_phase; CAssetId x8_mlvlId; CAssetId xc_strgId; CAssetId x10_savwId; rstl::vector< rstl::auto_ptr< CGameArea > > x18_areas; CAssetId x24_mapwId; rstl::single_ptr< TCachedToken< CMapWorld > > x28_mapWorld; rstl::vector< CRelay > x2c_relays; rstl::single_ptr< CDvdRequest > x3c_loadToken; rstl::single_ptr< char > x40_loadBuf; uint x44_bufSz; uint x48_chainCount; CGameArea* x4c_chainHeads[5]; IObjectStore* x60_objectStore; IFactory* x64_resFactory; TAreaId x68_curAreaId; uint x6c_loadedAudioGrpCount; bool x70_24_currentAreaNeedsAllocation : 1; bool x70_25_loadPaused : 1; bool x70_26_skyboxActive : 1; bool x70_27_skyboxVisible : 1; rstl::vector< CSoundGroupData > x74_soundGroupData; rstl::string x84_defAudioTrack; rstl::optional_object< TLockedToken< CModel > > x94_skyboxWorld; rstl::optional_object< TLockedToken< CModel > > xa4_skyboxWorldLoaded; rstl::optional_object< TLockedToken< CModel > > xb4_skyboxOverride; EEnvFxType xc4_neededFx; rstl::reserved_vector< CSfxHandle, 10 > xc8_globalSfxHandles; }; CHECK_SIZEOF(CWorld, 0xf4) struct SWorldLayers /* name? */ { static SWorldLayers ReadWorldLayers(CInputStream& in, int version, CAssetId mlvlId); }; class CDummyWorld : public IWorld { enum Phase { kP_Loading, kP_LoadingMap, kP_LoadingMapAreas, kP_Done, }; bool x4_loadMap; Phase x8_phase; CAssetId xc_mlvlId; CAssetId x10_strgId; CAssetId x14_savwId; rstl::vector< rstl::auto_ptr< CDummyGameArea > > x18_areas; CAssetId x28_mapWorldId; rstl::single_ptr< TCachedToken< CMapWorld > > x2c_mapWorld; rstl::single_ptr< CDvdRequest > x30_loadToken; rstl::single_ptr< char > x34_loadBuf; uint x38_bufSz; TAreaId x3c_curAreaId; public: CDummyWorld(CAssetId mlvlId, bool loadMap); ~CDummyWorld() override; CAssetId IGetWorldAssetId() const override; CAssetId IGetStringTableAssetId() const override; CAssetId IGetSaveWorldAssetId() const override; const CMapWorld* IGetMapWorld() const override; CMapWorld* IMapWorld() override; const IGameArea* IGetAreaAlways(TAreaId id) const override; TAreaId IGetCurrentAreaId() const override; TAreaId IGetAreaId(CAssetId id) const override; bool ICheckWorldComplete() override; rstl::string IGetDefaultAudioTrack() const override; int IGetAreaCount() const override; }; #endif // _CWORLD