2022-10-09 05:13:17 +00:00
|
|
|
#ifndef _CWORLD
|
|
|
|
#define _CWORLD
|
2022-08-16 02:14:28 +00:00
|
|
|
|
2024-10-17 05:02:14 +00:00
|
|
|
#include "Kyoto/SObjectTag.hpp"
|
2022-08-16 02:14:28 +00:00
|
|
|
#include "types.h"
|
|
|
|
|
2022-10-02 10:13:35 +00:00
|
|
|
#include "MetroidPrime/CGameArea.hpp"
|
2022-08-16 02:14:28 +00:00
|
|
|
#include "MetroidPrime/TGameTypes.hpp"
|
|
|
|
|
2022-10-17 19:19:07 +00:00
|
|
|
#include "Kyoto/Audio/CSfxHandle.hpp"
|
2022-11-03 14:21:47 +00:00
|
|
|
#include "Kyoto/IObjectStore.hpp"
|
2022-12-05 15:43:31 +00:00
|
|
|
#include "Kyoto/TToken.hpp"
|
2022-08-16 02:14:28 +00:00
|
|
|
|
2022-12-05 15:43:31 +00:00
|
|
|
#include "rstl/reserved_vector.hpp"
|
2024-10-17 05:02:14 +00:00
|
|
|
#include "rstl/string.hpp"
|
|
|
|
#include "rstl/vector.hpp"
|
2022-08-16 02:14:28 +00:00
|
|
|
|
2024-10-17 05:02:14 +00:00
|
|
|
class CAudioGroupSet;
|
|
|
|
class CDvdRequest;
|
|
|
|
class CGameArea;
|
2022-08-16 02:14:28 +00:00
|
|
|
class CMapWorld;
|
2022-10-14 16:03:05 +00:00
|
|
|
class CModel;
|
2024-10-17 05:02:14 +00:00
|
|
|
class CRelay;
|
|
|
|
class CStateManager;
|
2022-08-16 02:14:28 +00:00
|
|
|
class IGameArea;
|
2024-10-17 05:02:14 +00:00
|
|
|
class CResFactory;
|
2022-08-16 02:14:28 +00:00
|
|
|
|
|
|
|
class IWorld {
|
|
|
|
public:
|
2024-10-17 05:02:14 +00:00
|
|
|
virtual ~IWorld() {}
|
2022-08-16 02:14:28 +00:00
|
|
|
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;
|
2022-09-05 04:01:13 +00:00
|
|
|
virtual int IGetAreaCount() const = 0;
|
2022-08-16 02:14:28 +00:00
|
|
|
};
|
|
|
|
|
2024-10-17 05:02:14 +00:00
|
|
|
class CRelay /* name? */ {
|
2022-11-03 14:21:47 +00:00
|
|
|
public:
|
2024-10-17 05:02:14 +00:00
|
|
|
explicit CRelay(CInputStream& in);
|
2022-11-03 14:21:47 +00:00
|
|
|
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; }
|
|
|
|
|
2024-10-17 05:02:14 +00:00
|
|
|
static rstl::vector< CRelay > ReadMemoryRelays(CInputStream& in); // name?
|
|
|
|
|
2022-11-03 14:21:47 +00:00
|
|
|
private:
|
|
|
|
TEditorId x0_relay;
|
|
|
|
TEditorId x4_target;
|
|
|
|
ushort x8_msg;
|
|
|
|
bool xa_active;
|
|
|
|
};
|
|
|
|
|
2022-08-16 02:14:28 +00:00
|
|
|
// TODO move?
|
|
|
|
enum EEnvFxType {
|
|
|
|
kEFX_None,
|
|
|
|
kEFX_Snow,
|
|
|
|
kEFX_Rain,
|
|
|
|
kEFX_UnderwaterFlake,
|
|
|
|
};
|
|
|
|
|
2024-10-17 05:02:14 +00:00
|
|
|
class CWorld final : public IWorld {
|
2022-08-16 02:14:28 +00:00
|
|
|
public:
|
2024-10-17 05:02:14 +00:00
|
|
|
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);
|
2022-08-16 02:14:28 +00:00
|
|
|
~CWorld();
|
2023-02-06 17:01:01 +00:00
|
|
|
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;
|
2024-10-17 05:02:14 +00:00
|
|
|
bool CheckWorldComplete(CStateManager* mgr, TAreaId aid, CAssetId mreaId);
|
2022-08-16 02:14:28 +00:00
|
|
|
|
2022-11-08 23:04:51 +00:00
|
|
|
void SetLoadPauseState(bool);
|
2022-11-27 23:26:24 +00:00
|
|
|
void TouchSky() const;
|
2024-10-17 05:02:14 +00:00
|
|
|
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);
|
2022-11-08 23:04:51 +00:00
|
|
|
|
2022-09-18 06:05:46 +00:00
|
|
|
const CGameArea& GetAreaAlways(TAreaId id) const { return *x18_areas[id.Value()]; }
|
2022-10-14 16:03:05 +00:00
|
|
|
CGameArea* Area(TAreaId id) { return x18_areas[id.Value()].get(); }
|
2022-10-22 15:56:07 +00:00
|
|
|
const CGameArea* GetArea(TAreaId id) const { return x18_areas[id.Value()].get(); }
|
2023-10-17 21:36:08 +00:00
|
|
|
bool IsAreaValid(TAreaId id) const { return x18_areas[id.Value()]->IsLoaded(); }
|
2022-10-02 10:13:35 +00:00
|
|
|
CAssetId GetWorldAssetId() const { return x8_mlvlId; }
|
2022-11-11 00:26:17 +00:00
|
|
|
TAreaId GetCurrentAreaId() const { return x68_curAreaId; }
|
2022-10-09 05:37:23 +00:00
|
|
|
TAreaId GetAreaIdForSaveId(int saveId) const;
|
2022-11-03 14:21:47 +00:00
|
|
|
const rstl::vector< CRelay >& GetRelays() const { return x2c_relays; }
|
2023-01-07 22:59:28 +00:00
|
|
|
EEnvFxType GetNeededEnvFx() const { return xc4_neededFx; }
|
2022-08-16 02:14:28 +00:00
|
|
|
|
2022-11-03 14:21:47 +00:00
|
|
|
static void PropogateAreaChain(CGameArea::EOcclusionState occlusionState, CGameArea* area,
|
|
|
|
CWorld* world);
|
2022-10-17 19:19:07 +00:00
|
|
|
|
2022-12-05 15:43:31 +00:00
|
|
|
CGameArea::CConstChainIterator GetChainHead(EChain chain) const {
|
|
|
|
return CGameArea::CConstChainIterator(x4c_chainHeads[size_t(chain)]);
|
|
|
|
}
|
2022-11-27 23:26:24 +00:00
|
|
|
static CGameArea::CConstChainIterator GetAliveAreasEnd();
|
2024-10-15 23:45:15 +00:00
|
|
|
void StopGlobalSound(ushort soundId);
|
2022-11-27 23:26:24 +00:00
|
|
|
|
2022-08-16 02:14:28 +00:00
|
|
|
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;
|
2024-10-17 05:02:14 +00:00
|
|
|
rstl::single_ptr< TCachedToken< CMapWorld > > x28_mapWorld;
|
2022-08-16 02:14:28 +00:00
|
|
|
rstl::vector< CRelay > x2c_relays;
|
2024-10-17 05:02:14 +00:00
|
|
|
rstl::single_ptr< CDvdRequest > x3c_loadToken;
|
|
|
|
rstl::single_ptr< char > x40_loadBuf;
|
2022-09-05 04:01:13 +00:00
|
|
|
uint x44_bufSz;
|
|
|
|
uint x48_chainCount;
|
2022-08-16 02:14:28 +00:00
|
|
|
CGameArea* x4c_chainHeads[5];
|
|
|
|
IObjectStore* x60_objectStore;
|
|
|
|
IFactory* x64_resFactory;
|
|
|
|
TAreaId x68_curAreaId;
|
2022-09-05 04:01:13 +00:00
|
|
|
uint x6c_loadedAudioGrpCount;
|
2022-08-16 02:14:28 +00:00
|
|
|
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)
|
|
|
|
|
2024-10-17 05:02:14 +00:00
|
|
|
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;
|
|
|
|
};
|
|
|
|
|
2022-10-09 05:13:17 +00:00
|
|
|
#endif // _CWORLD
|