Additional state imps

This commit is contained in:
Jack Andersen 2016-07-23 18:46:32 -10:00
parent 9298ca7b99
commit f10168e824
8 changed files with 296 additions and 47 deletions

View File

@ -2,13 +2,41 @@
#define __URDE_CINGAMETWEAKMANAGERBASE_HPP__ #define __URDE_CINGAMETWEAKMANAGERBASE_HPP__
#include <string> #include <string>
#include <vector>
namespace urde namespace urde
{ {
struct CTweakValue
{
enum class EType
{
} x0_type;
std::string x4_key;
std::string x30_str;
};
class CInGameTweakManagerBase class CInGameTweakManagerBase
{ {
protected:
std::vector<CTweakValue> x0_values;
public: public:
bool HasTweakValue(const std::string& name) const
{
for (const CTweakValue& val : x0_values)
if (val.x4_key == name)
return true;
return false;
}
const CTweakValue* GetTweakValue(const std::string& name) const
{
for (const CTweakValue& val : x0_values)
if (val.x4_key == name)
return &val;
return nullptr;
}
bool ReadFromMemoryCard(const std::string& name) bool ReadFromMemoryCard(const std::string& name)
{ {
return true; return true;

View File

@ -356,6 +356,15 @@ void CStateManager::RecursiveDrawTree(TUniqueId) const
{ {
} }
void CStateManager::SendScriptMsg(TUniqueId dest, TUniqueId src, EScriptObjectMessage msg)
{
CEntity* ent = ObjectById(dest);
if (ent)
{
ent->AcceptScriptMsg(msg, src, *this);
}
}
void CStateManager::SendScriptMsg(TUniqueId uid, TEditorId eid, void CStateManager::SendScriptMsg(TUniqueId uid, TEditorId eid,
EScriptObjectMessage msg, EScriptObjectState state) EScriptObjectMessage msg, EScriptObjectState state)
{ {
@ -383,7 +392,7 @@ void CStateManager::GetIdListForScript(TEditorId) const
{ {
} }
void CStateManager::LoadScriptObjects(TAreaId, CInputStream& in, EScriptPersistence) void CStateManager::LoadScriptObjects(TAreaId, CInputStream& in, std::vector<TEditorId>& idsOut)
{ {
} }
@ -392,6 +401,18 @@ void CStateManager::LoadScriptObject(TAreaId, EScriptObjectType, u32,
{ {
} }
void CStateManager::InitScriptObjects(std::vector<TEditorId>& ids)
{
for (TEditorId id : ids)
{
if (id == kInvalidEditorId)
continue;
TUniqueId uid = GetIdForScript(id);
SendScriptMsg(uid, kInvalidUniqueId, EScriptObjectMessage::UNKM15);
}
MurderScriptInstanceNames();
}
void CStateManager::InformListeners(const zeus::CVector3f&, EListenNoiseType) void CStateManager::InformListeners(const zeus::CVector3f&, EListenNoiseType)
{ {
} }

View File

@ -174,14 +174,16 @@ public:
void PreRender(); void PreRender();
void GetVisSetForArea(TAreaId, TAreaId) const; void GetVisSetForArea(TAreaId, TAreaId) const;
void RecursiveDrawTree(TUniqueId) const; void RecursiveDrawTree(TUniqueId) const;
void SendScriptMsg(TUniqueId dest, TUniqueId src, EScriptObjectMessage msg);
void SendScriptMsg(TUniqueId uid, TEditorId eid, EScriptObjectMessage msg, EScriptObjectState state); void SendScriptMsg(TUniqueId uid, TEditorId eid, EScriptObjectMessage msg, EScriptObjectState state);
void FreeScriptObjects(TAreaId); void FreeScriptObjects(TAreaId);
void GetBuildForScript(TEditorId) const; void GetBuildForScript(TEditorId) const;
TEditorId GetEditorIdForUniqueId(TUniqueId) const; TEditorId GetEditorIdForUniqueId(TUniqueId) const;
TUniqueId GetIdForScript(TEditorId) const; TUniqueId GetIdForScript(TEditorId) const;
void GetIdListForScript(TEditorId) const; void GetIdListForScript(TEditorId) const;
void LoadScriptObjects(TAreaId, CInputStream& in, EScriptPersistence); void LoadScriptObjects(TAreaId, CInputStream& in, std::vector<TEditorId>& idsOut);
void LoadScriptObject(TAreaId, EScriptObjectType, u32, CInputStream& in, EScriptPersistence); void LoadScriptObject(TAreaId, EScriptObjectType, u32, CInputStream& in, EScriptPersistence);
void InitScriptObjects(std::vector<TEditorId>& ids);
void InformListeners(const zeus::CVector3f&, EListenNoiseType); void InformListeners(const zeus::CVector3f&, EListenNoiseType);
void ApplyKnockBack(CActor& actor, const CDamageInfo& info, void ApplyKnockBack(CActor& actor, const CDamageInfo& info,
const CDamageVulnerability&, const zeus::CVector3f&, float); const CDamageVulnerability&, const zeus::CVector3f&, float);

View File

@ -36,7 +36,7 @@ public:
void setColorC(const zeus::CColor& color) {m_uniform.m_colorRegs[2] = color;} void setColorC(const zeus::CColor& color) {m_uniform.m_colorRegs[2] = color;}
void setScale(float scale) void setScale(float scale)
{ {
scale = 0.1f * (1.f - scale); scale = 0.025f * (1.f - scale);
m_uniform.m_indMtx[0][0] = scale; m_uniform.m_indMtx[0][0] = scale;
m_uniform.m_indMtx[1][1] = scale; m_uniform.m_indMtx[1][1] = scale;
} }

View File

@ -103,8 +103,8 @@ static std::vector<SObjectTag> ReadDependencyList(CInputStream& in)
return ret; return ret;
} }
CGameArea::CGameArea(CInputStream& in, int mlvlVersion) CGameArea::CGameArea(CInputStream& in, int idx, int mlvlVersion)
: x4_mlvlVersion(mlvlVersion), xf0_25_active(true) : x4_selfIdx(idx), xf0_25_active(true)
{ {
x8_nameSTRG = in.readUint32Big(); x8_nameSTRG = in.readUint32Big();
xc_transform.read34RowMajor(in); xc_transform.read34RowMajor(in);

View File

@ -21,6 +21,8 @@ enum class ERglFogMode
class CDummyGameArea : public IGameArea class CDummyGameArea : public IGameArea
{ {
friend class CDummyWorld;
int x4_mlvlVersion; int x4_mlvlVersion;
ResId x8_nameSTRG; ResId x8_nameSTRG;
ResId xc_mrea; ResId xc_mrea;
@ -44,7 +46,9 @@ public:
class CGameArea : public IGameArea class CGameArea : public IGameArea
{ {
int x4_mlvlVersion; friend class CWorld;
int x4_selfIdx;
ResId x8_nameSTRG; ResId x8_nameSTRG;
zeus::CTransform xc_transform; zeus::CTransform xc_transform;
zeus::CTransform x3c_invTransform; zeus::CTransform x3c_invTransform;
@ -174,7 +178,7 @@ public:
void DisableFog(); void DisableFog();
}; };
CGameArea(CInputStream& in, int mlvlVersion); CGameArea(CInputStream& in, int idx, int mlvlVersion);
bool IsFinishedOccluding() const; bool IsFinishedOccluding() const;
void ReadDependencyList(); void ReadDependencyList();

View File

@ -2,6 +2,8 @@
#include "CGameArea.hpp" #include "CGameArea.hpp"
#include "GameGlobalObjects.hpp" #include "GameGlobalObjects.hpp"
#include "CSimplePool.hpp" #include "CSimplePool.hpp"
#include "CStateManager.hpp"
#include "CInGameTweakManagerBase.hpp"
#include "AutoMapper/CMapWorld.hpp" #include "AutoMapper/CMapWorld.hpp"
namespace urde namespace urde
@ -16,37 +18,54 @@ CDummyWorld::CDummyWorld(ResId mlvlId, bool loadMap)
ResId CDummyWorld::IGetWorldAssetId() const ResId CDummyWorld::IGetWorldAssetId() const
{ {
return xc_mlvlId;
} }
ResId CDummyWorld::IGetStringTableAssetId() const ResId CDummyWorld::IGetStringTableAssetId() const
{ {
return x10_strgId;
} }
ResId CDummyWorld::IGetSaveWorldAssetId() const ResId CDummyWorld::IGetSaveWorldAssetId() const
{ {
return x14_savwId;
} }
const CMapWorld* CDummyWorld::IGetMapWorld() const const CMapWorld* CDummyWorld::IGetMapWorld() const
{ {
return x2c_mapWorld.GetObj();
} }
CMapWorld* CDummyWorld::IMapWorld() CMapWorld* CDummyWorld::IMapWorld()
{ {
return x2c_mapWorld.GetObj();
} }
IGameArea* CDummyWorld::IGetAreaAlways(TAreaId id) const const IGameArea* CDummyWorld::IGetAreaAlways(TAreaId id) const
{ {
return &x18_areas.at(id);
} }
ResId CDummyWorld::IGetCurrentAreaId() const TAreaId CDummyWorld::IGetCurrentAreaId() const
{ {
return x3c_curAreaId;
} }
int CDummyWorld::IGetAreaIndex(TAreaId id) const TAreaId CDummyWorld::IGetAreaId(ResId id) const
{ {
int ret = 0;
if (id == -1)
return kInvalidAreaId;
for (const CDummyGameArea& area : x18_areas)
{
if (area.xc_mrea == id)
return ret;
++ret;
}
return kInvalidAreaId;
} }
std::vector<CWorld::CRelay> ReadMemoryRelays(athena::io::MemoryReader& r) std::vector<CWorld::CRelay> CWorld::CRelay::ReadMemoryRelays(athena::io::MemoryReader& r)
{ {
std::vector<CWorld::CRelay> ret; std::vector<CWorld::CRelay> ret;
u32 count = r.readUint32Big(); u32 count = r.readUint32Big();
@ -56,7 +75,7 @@ std::vector<CWorld::CRelay> ReadMemoryRelays(athena::io::MemoryReader& r)
return ret; return ret;
} }
CWorldLayers ReadWorldLayers(athena::io::MemoryReader& r) CWorldLayers CWorldLayers::ReadWorldLayers(athena::io::MemoryReader& r)
{ {
CWorldLayers ret; CWorldLayers ret;
@ -99,7 +118,7 @@ bool CDummyWorld::ICheckWorldComplete()
if (version >= 12) if (version >= 12)
r.readUint32Big(); r.readUint32Big();
if (version >= 17) if (version >= 17)
ReadMemoryRelays(r); CWorld::CRelay::ReadMemoryRelays(r);
u32 areaCount = r.readUint32Big(); u32 areaCount = r.readUint32Big();
r.readUint32Big(); r.readUint32Big();
@ -110,10 +129,7 @@ bool CDummyWorld::ICheckWorldComplete()
x28_mapWorldId = r.readUint32Big(); x28_mapWorldId = r.readUint32Big();
if (x4_loadMap) if (x4_loadMap)
{
x2c_mapWorld = g_SimplePool->GetObj(SObjectTag{FOURCC('MAPW'), x28_mapWorldId}); x2c_mapWorld = g_SimplePool->GetObj(SObjectTag{FOURCC('MAPW'), x28_mapWorldId});
x2c_mapWorld.Lock();
}
if (version > 10) if (version > 10)
{ {
@ -128,7 +144,7 @@ bool CDummyWorld::ICheckWorldComplete()
if (version > 12) if (version > 12)
r.readString(); r.readString();
ReadWorldLayers(r); CWorldLayers::ReadWorldLayers(r);
if (x4_loadMap) if (x4_loadMap)
x8_phase = Phase::LoadingMap; x8_phase = Phase::LoadingMap;
@ -164,54 +180,195 @@ bool CDummyWorld::ICheckWorldComplete()
std::string CDummyWorld::IGetDefaultAudioTrack() const std::string CDummyWorld::IGetDefaultAudioTrack() const
{ {
return {};
} }
int CDummyWorld::IGetAreaCount() const int CDummyWorld::IGetAreaCount() const
{ {
return x18_areas.size();
}
CWorld::CWorld(IObjectStore& objStore, IFactory& resFactory, ResId mlvlId)
: x60_objectStore(objStore), x64_resFactory(resFactory)
{
SObjectTag tag{FOURCC('MLVL'), mlvlId};
resFactory.LoadResourceAsync(tag, x40_loadBuf);
} }
ResId CWorld::IGetWorldAssetId() const ResId CWorld::IGetWorldAssetId() const
{ {
return x8_mlvlId;
} }
ResId CWorld::IGetStringTableAssetId() const ResId CWorld::IGetStringTableAssetId() const
{ {
return xc_strgId;
} }
ResId CWorld::IGetSaveWorldAssetId() const ResId CWorld::IGetSaveWorldAssetId() const
{ {
return x10_savwId;
} }
const CMapWorld* CWorld::IGetMapWorld() const const CMapWorld* CWorld::IGetMapWorld() const
{ {
return GetMapWorld();
} }
CMapWorld* CWorld::IMapWorld() CMapWorld* CWorld::IMapWorld()
{ {
return (CMapWorld*)GetMapWorld();
} }
IGameArea* CWorld::IGetAreaAlways(TAreaId id) const const IGameArea* CWorld::IGetAreaAlways(TAreaId id) const
{
return x18_areas.at(id).get();
}
TAreaId CWorld::IGetCurrentAreaId() const
{
return x68_curAreaId;
}
TAreaId CWorld::IGetAreaId(ResId id) const
{
int ret = 0;
if (id == -1)
return kInvalidAreaId;
for (const std::unique_ptr<CGameArea>& area : x18_areas)
{
if (area->x84_mrea == id)
return ret;
++ret;
}
return kInvalidAreaId;
}
void CWorld::MoveToChain(CGameArea* area, EChain chain)
{ {
} }
ResId CWorld::IGetCurrentAreaId() const bool CWorld::CheckWorldComplete(CStateManager* mgr, TAreaId id, ResId mreaId)
{ {
} if (mreaId != -1)
{
x68_curAreaId = 0;
TAreaId aid = 0;
for (const std::unique_ptr<CGameArea>& area : x18_areas)
{
if (area->x84_mrea == mreaId)
{
x68_curAreaId = aid;
break;
}
++aid;
}
}
else
x68_curAreaId = id;
switch (x4_phase)
{
case Phase::Loading:
{
if (!x40_loadBuf)
return false;
athena::io::MemoryReader r(x40_loadBuf.get(), UINT32_MAX, false);
r.readUint32Big();
int version = r.readUint32Big();
xc_strgId = r.readUint32Big();
if (version >= 15)
x10_savwId = r.readUint32Big();
if (version >= 12)
{
ResId skyboxId = r.readUint32Big();
if (skyboxId != -1 && mgr)
x84_skybox = g_SimplePool->GetObj(SObjectTag{FOURCC('CMDL'), skyboxId});
}
if (version >= 17)
x2c_relays = CWorld::CRelay::ReadMemoryRelays(r);
u32 areaCount = r.readUint32Big();
r.readUint32Big();
x18_areas.reserve(areaCount);
for (u32 i=0 ; i<areaCount ; ++i)
x18_areas.push_back(std::make_unique<CGameArea>(r, i, version));
if (x48_chainCount < 5)
{
for (int i=x48_chainCount ; i<5 ; ++i)
x4c_chainHeads[i] = nullptr;
x48_chainCount = 5;
}
for (std::unique_ptr<CGameArea>& area : x18_areas)
MoveToChain(area.get(), EChain::One);
x24_mapwId = r.readUint32Big();
x28_mapWorld = g_SimplePool->GetObj(SObjectTag{FOURCC('MAPW'), x24_mapwId});
if (mgr)
{
std::vector<TEditorId> ids;
mgr->LoadScriptObjects(kInvalidAreaId, r, ids);
mgr->InitScriptObjects(ids);
}
if (version > 10)
{
u32 audioGroupCount = r.readUint32Big();
x74_soundGroupData.reserve(audioGroupCount);
for (u32 i=0 ; i<audioGroupCount ; ++i)
{
int grpId = r.readUint32Big();
ResId agscId = r.readUint32Big();
x74_soundGroupData.emplace_back(grpId, agscId);
}
}
if (version > 12)
{
x84_defAudioTrack = r.readString();
std::string trackKey = hecl::Format("WorldDefault: %8.8x", u32(x8_mlvlId));
if (g_TweakManager->HasTweakValue(trackKey))
x84_defAudioTrack = g_TweakManager->GetTweakValue(trackKey)->x30_str;
}
CWorldLayers::ReadWorldLayers(r);
x4_phase = Phase::LoadingMap;
}
case Phase::LoadingMap:
{
x4_phase = Phase::LoadingMapAreas;
}
case Phase::LoadingMapAreas:
{
x4_phase = Phase::Done;
}
case Phase::Done:
return true;
default:
return false;
}
int CWorld::IGetAreaIndex(TAreaId id) const
{
} }
bool CWorld::ICheckWorldComplete() bool CWorld::ICheckWorldComplete()
{ {
return CheckWorldComplete(nullptr, kInvalidAreaId, -1);
} }
std::string CWorld::IGetDefaultAudioTrack() const std::string CWorld::IGetDefaultAudioTrack() const
{ {
return x84_defAudioTrack;
} }
int CWorld::IGetAreaCount() const int CWorld::IGetAreaCount() const
{ {
return x18_areas.size();
} }
bool CWorld::DoesAreaExist(TAreaId area) const bool CWorld::DoesAreaExist(TAreaId area) const

View File

@ -4,6 +4,7 @@
#include "RetroTypes.hpp" #include "RetroTypes.hpp"
#include "ScriptObjectSupport.hpp" #include "ScriptObjectSupport.hpp"
#include "CGameArea.hpp" #include "CGameArea.hpp"
#include "Graphics/CModel.hpp"
namespace urde namespace urde
{ {
@ -22,9 +23,9 @@ public:
virtual ResId IGetSaveWorldAssetId() const=0; virtual ResId IGetSaveWorldAssetId() const=0;
virtual const CMapWorld* IGetMapWorld() const=0; virtual const CMapWorld* IGetMapWorld() const=0;
virtual CMapWorld* IMapWorld()=0; virtual CMapWorld* IMapWorld()=0;
virtual IGameArea* IGetAreaAlways(TAreaId id) const=0; virtual const IGameArea* IGetAreaAlways(TAreaId id) const=0;
virtual ResId IGetCurrentAreaId() const=0; virtual TAreaId IGetCurrentAreaId() const=0;
virtual int IGetAreaIndex(TAreaId id) const=0; virtual TAreaId IGetAreaId(TAreaId id) const=0;
virtual bool ICheckWorldComplete()=0; virtual bool ICheckWorldComplete()=0;
virtual std::string IGetDefaultAudioTrack() const=0; virtual std::string IGetDefaultAudioTrack() const=0;
virtual int IGetAreaCount() const=0; virtual int IGetAreaCount() const=0;
@ -45,10 +46,11 @@ class CDummyWorld : public IWorld
ResId x14_savwId = -1; ResId x14_savwId = -1;
std::vector<CDummyGameArea> x18_areas; std::vector<CDummyGameArea> x18_areas;
ResId x28_mapWorldId = -1; ResId x28_mapWorldId = -1;
TCachedToken<CMapWorld> x2c_mapWorld; TLockedToken<CMapWorld> x2c_mapWorld;
//AsyncTask x30_loadToken; //AsyncTask x30_loadToken;
std::unique_ptr<uint8_t[]> x34_loadBuf; std::unique_ptr<uint8_t[]> x34_loadBuf;
//u32 x38_bufSz; //u32 x38_bufSz;
TAreaId x3c_curAreaId = kInvalidAreaId;
public: public:
CDummyWorld(ResId mlvlId, bool loadMap); CDummyWorld(ResId mlvlId, bool loadMap);
ResId IGetWorldAssetId() const; ResId IGetWorldAssetId() const;
@ -56,9 +58,9 @@ public:
ResId IGetSaveWorldAssetId() const; ResId IGetSaveWorldAssetId() const;
const CMapWorld* IGetMapWorld() const; const CMapWorld* IGetMapWorld() const;
CMapWorld* IMapWorld(); CMapWorld* IMapWorld();
IGameArea* IGetAreaAlways(TAreaId id) const; const IGameArea* IGetAreaAlways(TAreaId id) const;
ResId IGetCurrentAreaId() const; TAreaId IGetCurrentAreaId() const;
int IGetAreaIndex(TAreaId id) const; TAreaId IGetAreaId(ResId id) const;
bool ICheckWorldComplete(); bool ICheckWorldComplete();
std::string IGetDefaultAudioTrack() const; std::string IGetDefaultAudioTrack() const;
int IGetAreaCount() const; int IGetAreaCount() const;
@ -81,21 +83,43 @@ public:
TEditorId GetTargetId() const { return x4_target; } TEditorId GetTargetId() const { return x4_target; }
s16 GetMessage() const { return x8_msg; } s16 GetMessage() const { return x8_msg; }
bool GetActive() const { return xa_active; } bool GetActive() const { return xa_active; }
static std::vector<CWorld::CRelay> ReadMemoryRelays(athena::io::MemoryReader& r);
}; };
class CSoundGroupData
{
public:
CSoundGroupData(int grpId, ResId agsc);
};
private: private:
ResId xc_worldId = -1; enum class Phase
ResId x10_ = -1; {
Loading,
LoadingMap,
LoadingMapAreas,
Done,
} x4_phase = Phase::Loading;
ResId x8_mlvlId = -1;
ResId xc_strgId = -1;
ResId x10_savwId = -1;
std::vector<std::unique_ptr<CGameArea>> x18_areas; std::vector<std::unique_ptr<CGameArea>> x18_areas;
ResId x24_ = -1; ResId x24_mapwId = -1;
TLockedToken<CMapWorld> x28_mapWorld;
std::vector<CRelay> x2c_relays; std::vector<CRelay> x2c_relays;
//AsyncTask x3c_loadToken;
std::unique_ptr<uint8_t[]> x40_loadBuf;
//u32 x44_bufSz;
u32 x48_chainCount = 0;
CGameArea* x4c_chainHeads[5] = {};
std::unique_ptr<u8[]> x40_; IObjectStore& x60_objectStore;
std::unique_ptr<u8[]> x44_; IFactory& x64_resFactory;
TAreaId x68_curAreaId = kInvalidAreaId;
IObjectStore* x60_objectStore;
CResFactory* x64_resFactory;
TAreaId x68_ = kInvalidAreaId;
u32 x6c_ = 0; u32 x6c_ = 0;
union union
@ -108,30 +132,43 @@ private:
bool x70_27_ : 1; bool x70_27_ : 1;
}; };
}; };
u32 x78_; std::vector<CSoundGroupData> x74_soundGroupData;
u32 x7c_; std::string x84_defAudioTrack;
TLockedToken<CModel> x84_skybox;
public: public:
CWorld(IObjectStore& objStore, CResFactory& resFactory, ResId); enum class EChain
{
Zero,
One,
Two,
Three,
Four
};
void MoveToChain(CGameArea* area, EChain chain);
bool CheckWorldComplete(CStateManager* mgr, TAreaId id, ResId mreaId);
CWorld(IObjectStore& objStore, IFactory& resFactory, ResId mlvlId);
bool DoesAreaExist(TAreaId area) const; bool DoesAreaExist(TAreaId area) const;
std::vector<std::unique_ptr<CGameArea>>& GetGameAreas() {return x18_areas;} std::vector<std::unique_ptr<CGameArea>>& GetGameAreas() {return x18_areas;}
const CMapWorld* GetMapWorld() const {return x28_mapWorld.GetObj();}
ResId IGetWorldAssetId() const; ResId IGetWorldAssetId() const;
ResId IGetStringTableAssetId() const; ResId IGetStringTableAssetId() const;
ResId IGetSaveWorldAssetId() const; ResId IGetSaveWorldAssetId() const;
const CMapWorld* IGetMapWorld() const; const CMapWorld* IGetMapWorld() const;
CMapWorld* IMapWorld(); CMapWorld* IMapWorld();
IGameArea* IGetAreaAlways(TAreaId id) const; const IGameArea* IGetAreaAlways(TAreaId id) const;
ResId IGetCurrentAreaId() const; TAreaId IGetCurrentAreaId() const;
int IGetAreaIndex(TAreaId id) const; TAreaId IGetAreaId(ResId id) const;
bool ICheckWorldComplete(); bool ICheckWorldComplete();
std::string IGetDefaultAudioTrack() const; std::string IGetDefaultAudioTrack() const;
int IGetAreaCount() const; int IGetAreaCount() const;
}; };
std::vector<CWorld::CRelay> ReadMemoryRelays(athena::io::MemoryReader& r);
struct CWorldLayers struct CWorldLayers
{ {
struct Area struct Area
@ -142,8 +179,8 @@ struct CWorldLayers
}; };
std::vector<Area> m_areas; std::vector<Area> m_areas;
std::vector<std::string> m_names; std::vector<std::string> m_names;
static CWorldLayers ReadWorldLayers(athena::io::MemoryReader& r);
}; };
CWorldLayers ReadWorldLayers(athena::io::MemoryReader& r);
} }