Tweak loader for MP1

This commit is contained in:
Aruki
2018-12-27 20:16:39 -07:00
parent d6340dced9
commit 7588200c26
37 changed files with 3780 additions and 65 deletions

View File

@@ -388,7 +388,7 @@ void CResTypeInfo::CResTypeInfoFactory::InitTypes()
pType->mCanHaveDependencies = false;
}
{
CResTypeInfo *pType = new CResTypeInfo(EResourceType::Tweak, "Tweak Data", "ctwk");
CResTypeInfo *pType = new CResTypeInfo(EResourceType::Tweaks, "Tweak Data", "ctwk");
AddExtension(pType, "CTWK", EGame::PrimeDemo, EGame::Prime);
pType->mCanHaveDependencies = false;
}

View File

@@ -66,7 +66,7 @@ enum class EResourceType
StringList,
StringTable,
Texture,
Tweak,
Tweaks,
UserEvaluatorData,
Video,
World,

View File

@@ -22,6 +22,8 @@
#include "CUnsupportedParticleLoader.h"
#include "CWorldLoader.h"
#include "Core/Tweaks/CTweakLoader.h"
#include "Core/Resource/Resources.h"
// Static helper class to allow spawning resources based on an EResType
@@ -97,6 +99,7 @@ public:
case EResourceType::StringList: pRes = CAudioGroupLoader::LoadSTLC(rInput, pEntry); break;
case EResourceType::StringTable: pRes = CStringLoader::LoadSTRG(rInput, pEntry); break;
case EResourceType::Texture: pRes = CTextureDecoder::LoadTXTR(rInput, pEntry); break;
case EResourceType::Tweaks: pRes = CTweakLoader::LoadCTWK(rInput, pEntry); break;
case EResourceType::World: pRes = CWorldLoader::LoadMLVL(rInput, pEntry); break;
case EResourceType::StateMachine:

View File

@@ -15,13 +15,13 @@
CScriptLoader::CScriptLoader()
: mpObj(nullptr)
, mpArrayItemData(nullptr)
, mpCurrentData(nullptr)
{
}
void CScriptLoader::ReadProperty(IProperty *pProp, uint32 Size, IInputStream& rSCLY)
{
void* pData = (mpArrayItemData ? mpArrayItemData : mpObj->mPropertyData.data());
void* pData = (mpCurrentData ? mpCurrentData : mpObj->mPropertyData.data());
switch (pProp->Type())
{
@@ -237,7 +237,7 @@ void CScriptLoader::ReadProperty(IProperty *pProp, uint32 Size, IInputStream& rS
int Count = rSCLY.ReadLong();
pArray->Resize(pData, Count);
void* pOldArrayItemData = mpArrayItemData;
void* pOldData = mpCurrentData;
// Make sure the array archetype is atomic... non-atomic array archetypes is not supported
// because arrays can only have one possible archetype so having property IDs here wouldn't make sense
@@ -257,11 +257,11 @@ void CScriptLoader::ReadProperty(IProperty *pProp, uint32 Size, IInputStream& rS
* migrated to Sequence properties eventually, so there isn't really any good reason to spend a lot of effort refactoring
* things to make this cleaner
*/
mpArrayItemData = pArray->ItemPointer(pData, ElementIdx);
mpCurrentData = pArray->ItemPointer(pData, ElementIdx);
ReadProperty(pArray->ItemArchetype(), 0, rSCLY);
}
mpArrayItemData = pOldArrayItemData;
mpCurrentData = pOldData;
break;
}
@@ -505,3 +505,20 @@ CScriptObject* CScriptLoader::LoadInstance(IInputStream& rSCLY, CGameArea *pArea
else
return Loader.LoadObjectMP2(rSCLY);
}
void CScriptLoader::LoadStructData(IInputStream& rInput, CStructRef InStruct)
{
if (!rInput.IsValid()) return;
CScriptLoader Loader;
Loader.mVersion = InStruct.Property()->Game();
Loader.mpGameTemplate = NGameList::GetGameTemplate(Loader.mVersion);
Loader.mpArea = nullptr;
Loader.mpLayer = nullptr;
Loader.mpCurrentData = InStruct.DataPointer();
if (Loader.mVersion <= EGame::Prime)
Loader.LoadStructMP1(rInput, InStruct.Property());
else
Loader.LoadStructMP2(rInput, InStruct.Property());
}

View File

@@ -15,8 +15,8 @@ class CScriptLoader
CGameArea* mpArea;
CGameTemplate *mpGameTemplate;
// Current array item pointer
void* mpArrayItemData;
// Current data pointer
void* mpCurrentData;
CScriptLoader();
void ReadProperty(IProperty* pProp, uint32 Size, IInputStream& rSCLY);
@@ -32,6 +32,7 @@ class CScriptLoader
public:
static CScriptLayer* LoadLayer(IInputStream& rSCLY, CGameArea *pArea, EGame Version);
static CScriptObject* LoadInstance(IInputStream& rSCLY, CGameArea *pArea, CScriptLayer *pLayer, EGame Version, bool ForceReturnsFormat);
static void LoadStructData(IInputStream& rInput, CStructRef InStruct);
};
#endif // CSCRIPTLOADER_H

View File

@@ -13,6 +13,7 @@ void CGameTemplate::Serialize(IArchive& Arc)
{
Arc << SerialParameter("ScriptObjects", mScriptTemplates)
<< SerialParameter("PropertyArchetypes", mPropertyTemplates)
<< SerialParameter("MiscTemplates", mMiscTemplates)
<< SerialParameter("States", mStates)
<< SerialParameter("Messages", mMessages);
}
@@ -51,6 +52,13 @@ void CGameTemplate::Load(const TString& kFilePath)
Internal_LoadPropertyTemplate(Iter->second);
}
}
for (auto Iter = mMiscTemplates.begin(); Iter != mMiscTemplates.end(); Iter++)
{
SScriptTemplatePath& MiscPath = Iter->second;
TString AbsPath = gkGameRoot + MiscPath.Path;
MiscPath.pTemplate = std::make_shared<CScriptTemplate>(this, -1, AbsPath);
}
}
void CGameTemplate::Save()
@@ -118,6 +126,16 @@ void CGameTemplate::SaveGameTemplates(bool ForceAll /*= false*/)
}
}
}
for (auto Iter = mMiscTemplates.begin(); Iter != mMiscTemplates.end(); Iter++)
{
SScriptTemplatePath& Path = Iter->second;
if( Path.pTemplate )
{
Path.pTemplate->Save(ForceAll);
}
}
}
uint32 CGameTemplate::GameVersion(TString VersionName)
@@ -286,6 +304,21 @@ bool CGameTemplate::RenamePropertyArchetype(const TString& kTypeName, const TStr
return false;
}
CScriptTemplate* CGameTemplate::FindMiscTemplate(const TString& kTemplateName)
{
auto Iter = mMiscTemplates.find(kTemplateName);
if (Iter == mMiscTemplates.end())
{
return nullptr;
}
else
{
SScriptTemplatePath& Path = Iter->second;
return Path.pTemplate.get();
}
}
TString CGameTemplate::GetGameDirectory() const
{
return mSourceFile.GetFileDirectory();

View File

@@ -35,54 +35,23 @@ struct SObjId
}
};
/** Struct holding a reference to a script object template */
struct SScriptTemplatePath
/** Struct holding a reference to a template */
template<typename TemplateT>
struct TTemplatePath
{
/** File path to the template file, relative to the game directory */
TString Path;
/** Template in memory */
std::shared_ptr<CScriptTemplate> pTemplate;
std::shared_ptr<TemplateT> pTemplate;
/** Constructor */
SScriptTemplatePath()
TTemplatePath()
{}
SScriptTemplatePath(const TString& kInPath, CScriptTemplate* pInTemplate)
TTemplatePath(const TString& kInPath, TemplateT* pInTemplate)
: Path(kInPath)
, pTemplate( std::shared_ptr<CScriptTemplate>(pInTemplate) )
{}
/** Serializer */
void Serialize(IArchive& Arc)
{
if (Arc.FileVersion() == 0)
{
Arc << SerialParameter("Path", Path, SH_Attribute);
}
else
{
Arc.SerializePrimitive(Path, 0);
}
}
};
/** Struct holding a reference to a property template */
struct SPropertyTemplatePath
{
/** File path to the template file, relative to the game directory */
TString Path;
/** Template in memory */
std::shared_ptr<IProperty> pTemplate;
/** Constructor */
SPropertyTemplatePath()
{}
SPropertyTemplatePath(const TString& kInPath, IProperty* pInTemplate)
: Path(kInPath)
, pTemplate( std::shared_ptr<IProperty>(pInTemplate) )
, pTemplate( std::shared_ptr<TemplateT>(pInTemplate) )
{}
/** Serializer */
@@ -92,6 +61,9 @@ struct SPropertyTemplatePath
}
};
typedef TTemplatePath<CScriptTemplate> SScriptTemplatePath;
typedef TTemplatePath<IProperty> SPropertyTemplatePath;
/** CGameTemplate - Per-game template data */
class CGameTemplate
{
@@ -103,6 +75,7 @@ class CGameTemplate
/** Template arrays */
std::map<SObjId, SScriptTemplatePath> mScriptTemplates;
std::map<TString, SPropertyTemplatePath> mPropertyTemplates;
std::map<TString, SScriptTemplatePath> mMiscTemplates;
std::map<SObjId, TString> mStates;
std::map<SObjId, TString> mMessages;
@@ -130,6 +103,7 @@ public:
IProperty* FindPropertyArchetype(const TString& kTypeName);
TString GetPropertyArchetypeFilePath(const TString& kTypeName);
bool RenamePropertyArchetype(const TString& kTypeName, const TString& kNewTypeName);
CScriptTemplate* FindMiscTemplate(const TString& kTemplateName);
TString GetGameDirectory() const;
// Inline Accessors

View File

@@ -91,6 +91,7 @@ void IProperty::Serialize(IArchive& rArc)
// The archetype must exist, or else the template file is malformed.
ASSERT(pArchetype != nullptr);
ASSERT(pArchetype->Type() == Type());
InitFromArchetype(pArchetype);
}