mirror of
https://github.com/AxioDL/PrimeWorldEditor.git
synced 2025-12-17 17:05:37 +00:00
Updated to Script Template V4
This commit is contained in:
@@ -58,8 +58,9 @@ public:
|
||||
}
|
||||
|
||||
TBasicString(const CharType* pkText)
|
||||
: mInternalString(pkText)
|
||||
{
|
||||
if (pkText)
|
||||
mInternalString = pkText;
|
||||
}
|
||||
|
||||
TBasicString(const CharType* pkText, u32 length)
|
||||
@@ -731,6 +732,20 @@ public:
|
||||
return sstream.str();
|
||||
}
|
||||
|
||||
static TBasicString<CharType> FromFloat(float value, int MinDecimals = 1)
|
||||
{
|
||||
TString Out = std::to_string(value);
|
||||
int NumZeroes = Out.Size() - (Out.IndexOf(".") + 1);
|
||||
|
||||
while (Out.Back() == '\0' && NumZeroes > MinDecimals)
|
||||
{
|
||||
Out = Out.ChopBack(1);
|
||||
NumZeroes--;
|
||||
}
|
||||
|
||||
return Out;
|
||||
}
|
||||
|
||||
static TBasicString<CharType> HexString(unsigned char num, bool addPrefix = true, bool uppercase = false, int width = 0)
|
||||
{
|
||||
return HexString((unsigned long) num, addPrefix, uppercase, width);
|
||||
|
||||
@@ -10,6 +10,4 @@ typedef signed short s16;
|
||||
typedef signed long s32;
|
||||
typedef signed long long s64;
|
||||
|
||||
|
||||
|
||||
#endif // TYPES_H
|
||||
|
||||
@@ -29,9 +29,11 @@ bool CAreaAttributes::IsSkyEnabled()
|
||||
switch (mGame)
|
||||
{
|
||||
case ePrime:
|
||||
case eEchoesDemo:
|
||||
case eEchoes:
|
||||
case eCorruptionProto:
|
||||
case eCorruption:
|
||||
return static_cast<CBoolProperty*>(pBaseStruct->PropertyByIndex(1))->Get();
|
||||
return static_cast<TBoolProperty*>(pBaseStruct->PropertyByIndex(1))->Get();
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
@@ -44,10 +46,12 @@ CModel* CAreaAttributes::SkyModel()
|
||||
switch (mGame)
|
||||
{
|
||||
case ePrime:
|
||||
case eEchoesDemo:
|
||||
case eEchoes:
|
||||
return (CModel*) static_cast<CFileProperty*>(pBaseStruct->PropertyByIndex(7))->Get().RawPointer();
|
||||
return (CModel*) static_cast<TFileProperty*>(pBaseStruct->PropertyByID(0xD208C9FA))->Get().RawPointer();
|
||||
case eCorruptionProto:
|
||||
case eCorruption:
|
||||
return (CModel*) static_cast<CFileProperty*>(pBaseStruct->PropertyByIndex(8))->Get().RawPointer();
|
||||
return (CModel*) static_cast<TFileProperty*>(pBaseStruct->PropertyByIndex(8))->Get().RawPointer();
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -13,12 +13,12 @@ int CLightParameters::LightLayerIndex()
|
||||
{
|
||||
if (!mpStruct) return 0;
|
||||
|
||||
CLongProperty *pParam;
|
||||
TLongProperty *pParam;
|
||||
|
||||
if (mGame <= ePrime)
|
||||
pParam = (CLongProperty*) mpStruct->PropertyByIndex(0xD);
|
||||
pParam = (TLongProperty*) mpStruct->PropertyByIndex(0xD);
|
||||
else
|
||||
pParam = (CLongProperty*) mpStruct->PropertyByID(0x1F715FD3);
|
||||
pParam = (TLongProperty*) mpStruct->PropertyByID(0x1F715FD3);
|
||||
|
||||
if (!pParam) return 0;
|
||||
else return pParam->Get();
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#define CLIGHTPARAMETERS_H
|
||||
|
||||
#include "Core/Resource/CGameArea.h"
|
||||
#include "Core/Resource/Script/CProperty.h"
|
||||
#include "Core/Resource/Script/IProperty.h"
|
||||
|
||||
class CLightParameters
|
||||
{
|
||||
|
||||
@@ -113,8 +113,6 @@ HEADERS += \
|
||||
Resource/Model/EVertexDescription.h \
|
||||
Resource/Model/SSurface.h \
|
||||
Resource/Script/CMasterTemplate.h \
|
||||
Resource/Script/CProperty.h \
|
||||
Resource/Script/CPropertyTemplate.h \
|
||||
Resource/Script/CScriptLayer.h \
|
||||
Resource/Script/CScriptObject.h \
|
||||
Resource/Script/CScriptTemplate.h \
|
||||
@@ -139,7 +137,6 @@ HEADERS += \
|
||||
Resource/CStringTable.h \
|
||||
Resource/CTexture.h \
|
||||
Resource/CWorld.h \
|
||||
Resource/EFormatVersion.h \
|
||||
Resource/EResType.h \
|
||||
Resource/ETevEnums.h \
|
||||
Resource/ETexelFormat.h \
|
||||
@@ -178,7 +175,12 @@ HEADERS += \
|
||||
OpenGL/CVertexArrayManager.h \
|
||||
OpenGL/CVertexBuffer.h \
|
||||
OpenGL/GLCommon.h \
|
||||
ScriptExtra/CRadiusSphereExtra.h
|
||||
ScriptExtra/CRadiusSphereExtra.h \
|
||||
Resource/EGame.h \
|
||||
Resource/Cooker/CAreaCooker.h \
|
||||
Resource/Script/IPropertyValue.h \
|
||||
Resource/Script/IPropertyTemplate.h \
|
||||
Resource/Script/IProperty.h
|
||||
|
||||
# Source Files
|
||||
SOURCES += \
|
||||
@@ -211,8 +213,6 @@ SOURCES += \
|
||||
Resource/Model/CStaticModel.cpp \
|
||||
Resource/Model/SSurface.cpp \
|
||||
Resource/Script/CMasterTemplate.cpp \
|
||||
Resource/Script/CProperty.cpp \
|
||||
Resource/Script/CPropertyTemplate.cpp \
|
||||
Resource/Script/CScriptLayer.cpp \
|
||||
Resource/Script/CScriptObject.cpp \
|
||||
Resource/Script/CScriptTemplate.cpp \
|
||||
@@ -261,4 +261,7 @@ SOURCES += \
|
||||
OpenGL/CVertexArrayManager.cpp \
|
||||
OpenGL/CVertexBuffer.cpp \
|
||||
OpenGL/GLCommon.cpp \
|
||||
ScriptExtra/CRadiusSphereExtra.cpp
|
||||
ScriptExtra/CRadiusSphereExtra.cpp \
|
||||
Resource/Cooker/CAreaCooker.cpp \
|
||||
Resource/Script/IPropertyTemplate.cpp \
|
||||
Resource/Script/IProperty.cpp
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include "CResource.h"
|
||||
#include "TResPtr.h"
|
||||
#include "EFormatVersion.h"
|
||||
#include "EGame.h"
|
||||
#include "Core/Resource/Model/CModel.h"
|
||||
|
||||
class CAnimationParameters
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include "CMaterialPass.h"
|
||||
#include "CTexture.h"
|
||||
#include "EFormatVersion.h"
|
||||
#include "EGame.h"
|
||||
#include "TResPtr.h"
|
||||
#include "Core/Resource/Model/EVertexDescription.h"
|
||||
#include "Core/Render/ERenderOptions.h"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include "CMaterial.h"
|
||||
#include "CTexture.h"
|
||||
#include "EFormatVersion.h"
|
||||
#include "EGame.h"
|
||||
#include <FileIO/IInputStream.h>
|
||||
|
||||
class CMaterialSet
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include "CResource.h"
|
||||
#include "CStringTable.h"
|
||||
#include "EFormatVersion.h"
|
||||
#include "EGame.h"
|
||||
#include "TResPtr.h"
|
||||
|
||||
class CScan : public CResource
|
||||
|
||||
20
src/Core/Resource/Cooker/CAreaCooker.cpp
Normal file
20
src/Core/Resource/Cooker/CAreaCooker.cpp
Normal file
@@ -0,0 +1,20 @@
|
||||
#include "CAreaCooker.h"
|
||||
|
||||
CAreaCooker::CAreaCooker()
|
||||
{
|
||||
}
|
||||
|
||||
u32 CAreaCooker::GetMREAVersion(EGame version)
|
||||
{
|
||||
switch (version)
|
||||
{
|
||||
case ePrimeDemo: return 0xC;
|
||||
case ePrime: return 0xF;
|
||||
case eEchoesDemo: return 0x15;
|
||||
case eEchoes: return 0x19;
|
||||
case eCorruptionProto: return 0x1D;
|
||||
case eCorruption: return 0x1E;
|
||||
case eReturns: return 0x20;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
14
src/Core/Resource/Cooker/CAreaCooker.h
Normal file
14
src/Core/Resource/Cooker/CAreaCooker.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#ifndef CAREACOOKER_H
|
||||
#define CAREACOOKER_H
|
||||
|
||||
#include "Core/Resource/EGame.h"
|
||||
#include <Common/types.h>
|
||||
|
||||
class CAreaCooker
|
||||
{
|
||||
CAreaCooker();
|
||||
public:
|
||||
static u32 GetMREAVersion(EGame version);
|
||||
};
|
||||
|
||||
#endif // CAREACOOKER_H
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include "Core/Resource/CMaterial.h"
|
||||
#include "Core/Resource/CMaterialSet.h"
|
||||
#include "Core/Resource/EFormatVersion.h"
|
||||
#include "Core/Resource/EGame.h"
|
||||
|
||||
class CMaterialCooker
|
||||
{
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#define CMODELCOOKER_H
|
||||
|
||||
#include "Core/Resource/Model/CModel.h"
|
||||
#include "Core/Resource/EFormatVersion.h"
|
||||
#include "Core/Resource/EGame.h"
|
||||
#include <FileIO/FileIO.h>
|
||||
|
||||
class CModelCooker
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include "CTemplateWriter.h"
|
||||
#include "CWorldCooker.h"
|
||||
#include "CAreaCooker.h"
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <tinyxml2.h>
|
||||
@@ -13,104 +13,121 @@ CTemplateWriter::CTemplateWriter()
|
||||
void CTemplateWriter::SaveAllTemplates()
|
||||
{
|
||||
// Create directory
|
||||
std::list<CMasterTemplate*> masterList = CMasterTemplate::GetMasterList();
|
||||
TString out = "../templates/";
|
||||
boost::filesystem::create_directory(out.ToStdString());
|
||||
std::list<CMasterTemplate*> MasterList = CMasterTemplate::GetMasterList();
|
||||
TString Out = "../templates/";
|
||||
boost::filesystem::create_directory(Out.ToStdString());
|
||||
|
||||
// Resave master templates
|
||||
for (auto it = masterList.begin(); it != masterList.end(); it++)
|
||||
SaveGameTemplates(*it, out);
|
||||
for (auto it = MasterList.begin(); it != MasterList.end(); it++)
|
||||
SaveGameTemplates(*it, Out);
|
||||
|
||||
// Resave game list
|
||||
XMLDocument gameList;
|
||||
XMLDocument GameList;
|
||||
|
||||
XMLDeclaration *pDecl = gameList.NewDeclaration();
|
||||
gameList.LinkEndChild(pDecl);
|
||||
XMLDeclaration *pDecl = GameList.NewDeclaration();
|
||||
GameList.LinkEndChild(pDecl);
|
||||
|
||||
XMLElement *pBase = gameList.NewElement("GameList");
|
||||
pBase->SetAttribute("version", 3);
|
||||
gameList.LinkEndChild(pBase);
|
||||
XMLElement *pBase = GameList.NewElement("GameList");
|
||||
pBase->SetAttribute("version", 4);
|
||||
GameList.LinkEndChild(pBase);
|
||||
|
||||
for (auto it = masterList.begin(); it != masterList.end(); it++)
|
||||
for (auto it = MasterList.begin(); it != MasterList.end(); it++)
|
||||
{
|
||||
CMasterTemplate *pMaster = *it;
|
||||
|
||||
XMLElement *pGame = gameList.NewElement("game");
|
||||
|
||||
XMLElement *pGameName = gameList.NewElement("name");
|
||||
pGameName->SetText(*pMaster->mGameName);
|
||||
|
||||
XMLElement *pWorldVersion = gameList.NewElement("mlvl");
|
||||
u32 versionNumber = CWorldCooker::GetMLVLVersion(pMaster->GetGame());
|
||||
pWorldVersion->SetText(*TString::HexString(versionNumber, true, true, 2));
|
||||
|
||||
XMLElement *pTempPath = gameList.NewElement("master");
|
||||
pTempPath->SetText(*pMaster->mSourceFile);
|
||||
|
||||
pGame->LinkEndChild(pGameName);
|
||||
pGame->LinkEndChild(pWorldVersion);
|
||||
pGame->LinkEndChild(pTempPath);
|
||||
XMLElement *pGame = GameList.NewElement("game");
|
||||
pBase->LinkEndChild(pGame);
|
||||
|
||||
XMLElement *pGameName = GameList.NewElement("name");
|
||||
pGameName->SetText(*pMaster->mGameName);
|
||||
pGame->LinkEndChild(pGameName);
|
||||
|
||||
XMLElement *pAreaVersion = GameList.NewElement("mrea");
|
||||
u32 VersionNumber = CAreaCooker::GetMREAVersion(pMaster->GetGame());
|
||||
pAreaVersion->SetText(*TString::HexString(VersionNumber, true, true, 2));
|
||||
pGame->LinkEndChild(pAreaVersion);
|
||||
|
||||
XMLElement *pTempPath = GameList.NewElement("master");
|
||||
pTempPath->SetText(*pMaster->mSourceFile);
|
||||
pGame->LinkEndChild(pTempPath);
|
||||
}
|
||||
|
||||
gameList.SaveFile(*(out + "GameList.xml"));
|
||||
TString GameListName = Out + "GameList.xml";
|
||||
GameList.SaveFile(*GameListName);
|
||||
}
|
||||
|
||||
void CTemplateWriter::SaveGameTemplates(CMasterTemplate *pMaster, const TString& dir)
|
||||
void CTemplateWriter::SaveGameTemplates(CMasterTemplate *pMaster, const TString& rkDir)
|
||||
{
|
||||
// Create directory
|
||||
TString outFile = dir + pMaster->mSourceFile;
|
||||
TString outDir = outFile.GetFileDirectory();
|
||||
boost::filesystem::create_directory(outDir.ToStdString());
|
||||
TString OutFile = rkDir + pMaster->mSourceFile;
|
||||
TString OutDir = OutFile.GetFileDirectory();
|
||||
boost::filesystem::create_directory(OutDir.ToStdString());
|
||||
|
||||
// Resave script templates
|
||||
for (auto it = pMaster->mTemplates.begin(); it != pMaster->mTemplates.end(); it++)
|
||||
SaveScriptTemplate(it->second, outDir);
|
||||
SaveScriptTemplate(it->second, OutDir);
|
||||
|
||||
// Resave master template
|
||||
XMLDocument master;
|
||||
XMLDocument Master;
|
||||
|
||||
XMLDeclaration *pDecl = master.NewDeclaration();
|
||||
master.LinkEndChild(pDecl);
|
||||
XMLDeclaration *pDecl = Master.NewDeclaration();
|
||||
Master.LinkEndChild(pDecl);
|
||||
|
||||
XMLElement *pBase = master.NewElement("MasterTemplate");
|
||||
pBase->SetAttribute("version", 3);
|
||||
master.LinkEndChild(pBase);
|
||||
XMLElement *pBase = Master.NewElement("MasterTemplate");
|
||||
pBase->SetAttribute("version", 4);
|
||||
Master.LinkEndChild(pBase);
|
||||
|
||||
// Write property list
|
||||
if (!pMaster->mPropertyList.empty())
|
||||
if (!pMaster->mPropertyNames.empty())
|
||||
{
|
||||
SavePropertyList(pMaster, outDir);
|
||||
SavePropertyList(pMaster, OutDir);
|
||||
|
||||
XMLElement *pPropList = master.NewElement("properties");
|
||||
XMLElement *pPropList = Master.NewElement("properties");
|
||||
pPropList->SetText("Properties.xml");
|
||||
pBase->LinkEndChild(pPropList);
|
||||
}
|
||||
|
||||
// Write versions
|
||||
if (!pMaster->mGameVersions.empty())
|
||||
{
|
||||
XMLElement *pVersionsBlock = Master.NewElement("versions");
|
||||
pBase->LinkEndChild(pVersionsBlock);
|
||||
|
||||
for (auto it = pMaster->mGameVersions.begin(); it != pMaster->mGameVersions.end(); it++)
|
||||
{
|
||||
XMLElement *pVersion = Master.NewElement("version");
|
||||
pVersion->SetText(*(*it));
|
||||
pBase->LinkEndChild(pVersion);
|
||||
}
|
||||
}
|
||||
|
||||
// Write script objects
|
||||
XMLElement *pObjects = master.NewElement("objects");
|
||||
XMLElement *pObjects = Master.NewElement("objects");
|
||||
pBase->LinkEndChild(pObjects);
|
||||
|
||||
for (auto it = pMaster->mTemplates.begin(); it != pMaster->mTemplates.end(); it++)
|
||||
{
|
||||
TString objID;
|
||||
u32 intID = (it->second)->ObjectID();
|
||||
if (intID <= 0xFF) objID = TString::HexString(intID, true, true, 2);
|
||||
else objID = CFourCC(intID).ToString();
|
||||
u32 ObjID = (it->second)->ObjectID();
|
||||
|
||||
XMLElement *pObj = master.NewElement("object");
|
||||
pObj->SetAttribute("ID", *objID);
|
||||
TString StrID;
|
||||
if (ObjID <= 0xFF)
|
||||
StrID = TString::HexString(ObjID, true, true, 2);
|
||||
else
|
||||
StrID = CFourCC(ObjID).ToString();
|
||||
|
||||
XMLElement *pObj = Master.NewElement("object");
|
||||
pObj->SetAttribute("ID", *StrID);
|
||||
pObj->SetAttribute("template", *(it->second)->mSourceFile);
|
||||
pObjects->LinkEndChild(pObj);
|
||||
}
|
||||
|
||||
// Write script states/messages
|
||||
std::map<u32, TString> *pMaps[2] = { &pMaster->mStates, &pMaster->mMessages };
|
||||
TString types[2] = { "state", "message" };
|
||||
TString Types[2] = { "state", "message" };
|
||||
|
||||
for (u32 iScr = 0; iScr < 2; iScr++)
|
||||
{
|
||||
XMLElement *pElem = master.NewElement(*(types[iScr] + "s"));
|
||||
XMLElement *pElem = Master.NewElement(*(Types[iScr] + "s"));
|
||||
pBase->LinkEndChild(pElem);
|
||||
|
||||
for (auto it = pMaps[iScr]->begin(); it != pMaps[iScr]->end(); it++)
|
||||
@@ -119,7 +136,7 @@ void CTemplateWriter::SaveGameTemplates(CMasterTemplate *pMaster, const TString&
|
||||
if (it->first <= 0xFF) ID = TString::HexString(it->first, true, true, 2);
|
||||
else ID = CFourCC(it->first).ToString();
|
||||
|
||||
XMLElement *pSubElem = master.NewElement(*types[iScr]);
|
||||
XMLElement *pSubElem = Master.NewElement(*Types[iScr]);
|
||||
pSubElem->SetAttribute("ID", *ID);
|
||||
pSubElem->SetAttribute("name", *(it->second));
|
||||
pElem->LinkEndChild(pSubElem);
|
||||
@@ -127,113 +144,69 @@ void CTemplateWriter::SaveGameTemplates(CMasterTemplate *pMaster, const TString&
|
||||
}
|
||||
|
||||
// Save file
|
||||
master.SaveFile(*outFile);
|
||||
Master.SaveFile(*OutFile);
|
||||
}
|
||||
|
||||
void CTemplateWriter::SavePropertyList(CMasterTemplate *pMaster, const TString& dir)
|
||||
void CTemplateWriter::SavePropertyList(CMasterTemplate *pMaster, const TString& rkDir)
|
||||
{
|
||||
// Create XML
|
||||
XMLDocument list;
|
||||
XMLDocument List;
|
||||
|
||||
XMLDeclaration *pDecl = list.NewDeclaration();
|
||||
list.LinkEndChild(pDecl);
|
||||
XMLDeclaration *pDecl = List.NewDeclaration();
|
||||
List.LinkEndChild(pDecl);
|
||||
|
||||
XMLElement *pBase = list.NewElement("Properties");
|
||||
pBase->SetAttribute("version", 3);
|
||||
list.LinkEndChild(pBase);
|
||||
XMLElement *pBase = List.NewElement("Properties");
|
||||
pBase->SetAttribute("version", 4);
|
||||
List.LinkEndChild(pBase);
|
||||
|
||||
// Write properties
|
||||
for (auto it = pMaster->mPropertyList.begin(); it != pMaster->mPropertyList.end(); it++)
|
||||
for (auto it = pMaster->mPropertyNames.begin(); it != pMaster->mPropertyNames.end(); it++)
|
||||
{
|
||||
CPropertyTemplate *pTemp = it->second;
|
||||
u32 ID = it->first;
|
||||
TString Name = it->second;
|
||||
|
||||
if (pTemp->Type() == eStructProperty)
|
||||
{
|
||||
CStructTemplate *pStructTemp = static_cast<CStructTemplate*>(pTemp);
|
||||
|
||||
XMLElement *pElem = list.NewElement("struct");
|
||||
pElem->SetAttribute("ID", *TString::HexString(pTemp->PropertyID(), true, true, 8));
|
||||
pElem->SetAttribute("name", *pTemp->Name());
|
||||
|
||||
if (!pStructTemp->mSourceFile.IsEmpty())
|
||||
{
|
||||
SaveStructTemplate(pStructTemp, pMaster, dir);
|
||||
pElem->SetAttribute("template", *pStructTemp->mSourceFile);
|
||||
}
|
||||
|
||||
pBase->LinkEndChild(pElem);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
XMLElement *pElem = list.NewElement("property");
|
||||
pElem->SetAttribute("ID", *TString::HexString(pTemp->PropertyID(), true, true, 8));
|
||||
pElem->SetAttribute("name", *pTemp->Name());
|
||||
pElem->SetAttribute("type", *PropEnumToPropString(pTemp->Type()));
|
||||
|
||||
if (pTemp->Type() == eFileProperty)
|
||||
{
|
||||
// Construct extension list string
|
||||
CFileTemplate *pFileProp = static_cast<CFileTemplate*>(pTemp);
|
||||
const TStringList& extensions = pFileProp->Extensions();
|
||||
|
||||
TString strList = "";
|
||||
|
||||
for (auto it = extensions.begin(); it != extensions.end();)
|
||||
{
|
||||
strList += *it;
|
||||
it++;
|
||||
if (it != extensions.end()) strList += ",";
|
||||
}
|
||||
|
||||
pElem->SetAttribute("ext", *strList);
|
||||
}
|
||||
|
||||
pBase->LinkEndChild(pElem);
|
||||
}
|
||||
XMLElement *pElem = List.NewElement("property");
|
||||
pElem->SetAttribute("ID", *TString::HexString(ID, true, true, 8));
|
||||
pElem->SetAttribute("name", *Name);
|
||||
pBase->LinkEndChild(pElem);
|
||||
}
|
||||
|
||||
list.SaveFile(*(dir + "Properties.xml"));
|
||||
TString OutFile = rkDir + "Properties.xml";
|
||||
List.SaveFile(*OutFile);
|
||||
}
|
||||
|
||||
void CTemplateWriter::SaveScriptTemplate(CScriptTemplate *pTemp, const TString& dir)
|
||||
void CTemplateWriter::SaveScriptTemplate(CScriptTemplate *pTemp, const TString& rkDir)
|
||||
{
|
||||
// Create directory
|
||||
TString outFile = dir + pTemp->mSourceFile;
|
||||
TString outDir = outFile.GetFileDirectory();
|
||||
TString OutFile = rkDir + pTemp->mSourceFile;
|
||||
TString outDir = OutFile.GetFileDirectory();
|
||||
boost::filesystem::create_directory(*outDir);
|
||||
|
||||
// Create new document
|
||||
XMLDocument scriptXML;
|
||||
XMLDocument ScriptXML;
|
||||
|
||||
XMLDeclaration *pDecl = scriptXML.NewDeclaration();
|
||||
scriptXML.LinkEndChild(pDecl);
|
||||
XMLDeclaration *pDecl = ScriptXML.NewDeclaration();
|
||||
ScriptXML.LinkEndChild(pDecl);
|
||||
|
||||
// Base element
|
||||
XMLElement *pBase = scriptXML.NewElement("ScriptTemplate");
|
||||
pBase->SetAttribute("version", 3.0f);
|
||||
scriptXML.LinkEndChild(pBase);
|
||||
XMLElement *pRoot = ScriptXML.NewElement("ScriptTemplate");
|
||||
pRoot->SetAttribute("version", 4);
|
||||
ScriptXML.LinkEndChild(pRoot);
|
||||
|
||||
// Write object name
|
||||
XMLElement *pName = scriptXML.NewElement("name");
|
||||
XMLElement *pName = ScriptXML.NewElement("name");
|
||||
pName->SetText(*pTemp->TemplateName());
|
||||
pBase->LinkEndChild(pName);
|
||||
pRoot->LinkEndChild(pName);
|
||||
|
||||
// Write properties
|
||||
for (auto it = pTemp->mPropertySets.begin(); it != pTemp->mPropertySets.end(); it++)
|
||||
{
|
||||
XMLElement *pProperties = scriptXML.NewElement("properties");
|
||||
pProperties->SetAttribute("version", *it->SetName);
|
||||
SaveProperties(&scriptXML, pProperties, it->pBaseStruct, pTemp->MasterTemplate(), dir);
|
||||
pBase->LinkEndChild(pProperties);
|
||||
}
|
||||
SaveProperties(&ScriptXML, pRoot, pTemp->mpBaseStruct, pTemp->MasterTemplate(), rkDir);
|
||||
|
||||
// Write editor properties
|
||||
XMLElement *pEditor = scriptXML.NewElement("editor");
|
||||
pBase->LinkEndChild(pEditor);
|
||||
XMLElement *pEditor = ScriptXML.NewElement("editor");
|
||||
pRoot->LinkEndChild(pEditor);
|
||||
|
||||
// Editor Properties
|
||||
XMLElement *pEditorProperties = scriptXML.NewElement("properties");
|
||||
XMLElement *pEditorProperties = ScriptXML.NewElement("properties");
|
||||
pEditor->LinkEndChild(pEditorProperties);
|
||||
|
||||
TString propNames[6] = {
|
||||
@@ -250,7 +223,7 @@ void CTemplateWriter::SaveScriptTemplate(CScriptTemplate *pTemp, const TString&
|
||||
{
|
||||
if (!pPropStrings[iProp]->IsEmpty())
|
||||
{
|
||||
XMLElement *pProperty = scriptXML.NewElement("property");
|
||||
XMLElement *pProperty = ScriptXML.NewElement("property");
|
||||
pProperty->SetAttribute("name", *propNames[iProp]);
|
||||
pProperty->SetAttribute("ID", **pPropStrings[iProp]);
|
||||
pEditorProperties->LinkEndChild(pProperty);
|
||||
@@ -258,28 +231,29 @@ void CTemplateWriter::SaveScriptTemplate(CScriptTemplate *pTemp, const TString&
|
||||
}
|
||||
|
||||
// Editor Assets
|
||||
XMLElement *pAssets = scriptXML.NewElement("assets");
|
||||
XMLElement *pAssets = ScriptXML.NewElement("assets");
|
||||
pEditor->LinkEndChild(pAssets);
|
||||
|
||||
for (auto it = pTemp->mAssets.begin(); it != pTemp->mAssets.end(); it++)
|
||||
{
|
||||
TString source = (it->AssetSource == CScriptTemplate::SEditorAsset::eFile ? "file" : "property");
|
||||
TString type;
|
||||
TString Source = (it->AssetSource == CScriptTemplate::SEditorAsset::eFile ? "file" : "property");
|
||||
TString Type;
|
||||
|
||||
switch (it->AssetType)
|
||||
{
|
||||
case CScriptTemplate::SEditorAsset::eModel: type = "model"; break;
|
||||
case CScriptTemplate::SEditorAsset::eAnimParams: type = "animparams"; break;
|
||||
case CScriptTemplate::SEditorAsset::eBillboard: type = "billboard"; break;
|
||||
case CScriptTemplate::SEditorAsset::eCollision: type = "collision"; break;
|
||||
case CScriptTemplate::SEditorAsset::eModel: Type = "model"; break;
|
||||
case CScriptTemplate::SEditorAsset::eAnimParams: Type = "animparams"; break;
|
||||
case CScriptTemplate::SEditorAsset::eBillboard: Type = "billboard"; break;
|
||||
case CScriptTemplate::SEditorAsset::eCollision: Type = "collision"; break;
|
||||
}
|
||||
|
||||
s32 force = -1;
|
||||
if (it->AssetSource == CScriptTemplate::SEditorAsset::eAnimParams) force = it->ForceNodeIndex;
|
||||
s32 Force = -1;
|
||||
if (it->AssetSource == CScriptTemplate::SEditorAsset::eAnimParams)
|
||||
Force = it->ForceNodeIndex;
|
||||
|
||||
XMLElement *pAsset = scriptXML.NewElement(*type);
|
||||
pAsset->SetAttribute("source", *source);
|
||||
if (force >= 0) pAsset->SetAttribute("force", std::to_string(force).c_str());
|
||||
XMLElement *pAsset = ScriptXML.NewElement(*Type);
|
||||
pAsset->SetAttribute("source", *Source);
|
||||
if (Force >= 0) pAsset->SetAttribute("force", std::to_string(Force).c_str());
|
||||
pAsset->SetText(*it->AssetLocation);
|
||||
pAssets->LinkEndChild(pAsset);
|
||||
}
|
||||
@@ -287,17 +261,17 @@ void CTemplateWriter::SaveScriptTemplate(CScriptTemplate *pTemp, const TString&
|
||||
// Preview Scale
|
||||
if (pTemp->mPreviewScale != 1.f)
|
||||
{
|
||||
XMLElement *pPreviewScale = scriptXML.NewElement("preview_scale");
|
||||
XMLElement *pPreviewScale = ScriptXML.NewElement("preview_scale");
|
||||
pPreviewScale->SetText(*TString::FromFloat(pTemp->mPreviewScale));
|
||||
pEditor->LinkEndChild(pPreviewScale);
|
||||
pPreviewScale->SetText(pTemp->mPreviewScale);
|
||||
}
|
||||
|
||||
// Rot/Scale Type
|
||||
XMLElement *pRotType = scriptXML.NewElement("rotation_type");
|
||||
XMLElement *pRotType = ScriptXML.NewElement("rotation_type");
|
||||
pEditor->LinkEndChild(pRotType);
|
||||
pRotType->SetText(pTemp->mRotationType == CScriptTemplate::eRotationEnabled ? "enabled" : "disabled");
|
||||
|
||||
XMLElement *pScaleType = scriptXML.NewElement("scale_type");
|
||||
XMLElement *pScaleType = ScriptXML.NewElement("scale_type");
|
||||
pEditor->LinkEndChild(pScaleType);
|
||||
|
||||
if (pTemp->mScaleType != CScriptTemplate::eScaleVolume)
|
||||
@@ -308,7 +282,7 @@ void CTemplateWriter::SaveScriptTemplate(CScriptTemplate *pTemp, const TString&
|
||||
pScaleType->SetText("volume");
|
||||
|
||||
// Volume Preview
|
||||
XMLElement *pVolume = scriptXML.NewElement("preview_volume");
|
||||
XMLElement *pVolume = ScriptXML.NewElement("preview_volume");
|
||||
pEditor->LinkEndChild(pVolume);
|
||||
|
||||
// Enum -> String conversion lambda to avoid redundant code
|
||||
@@ -335,27 +309,21 @@ void CTemplateWriter::SaveScriptTemplate(CScriptTemplate *pTemp, const TString&
|
||||
pVolume->SetAttribute("propertyID", *pTemp->mVolumeConditionIDString);
|
||||
|
||||
// Find conditional test property
|
||||
CPropertyTemplate *pProp;
|
||||
|
||||
for (auto it = pTemp->mPropertySets.begin(); it != pTemp->mPropertySets.end(); it++)
|
||||
{
|
||||
pProp = it->pBaseStruct->PropertyByIDString(pTemp->mVolumeConditionIDString);
|
||||
if (pProp) break;
|
||||
}
|
||||
IPropertyTemplate *pProp = pTemp->mpBaseStruct->PropertyByIDString(pTemp->mVolumeConditionIDString);
|
||||
|
||||
// Write conditions
|
||||
for (auto it = pTemp->mVolumeConditions.begin(); it != pTemp->mVolumeConditions.end(); it++)
|
||||
{
|
||||
// Value should be an integer, or a boolean condition?
|
||||
TString strVal;
|
||||
TString StrVal;
|
||||
|
||||
if (pProp->Type() == eBoolProperty)
|
||||
strVal = (it->Value == 1 ? "true" : "false");
|
||||
StrVal = (it->Value == 1 ? "true" : "false");
|
||||
else
|
||||
strVal = TString::HexString((u32) it->Value, true, true, (it->Value > 0xFF ? 8 : 2));
|
||||
StrVal = TString::HexString((u32) it->Value, true, true, (it->Value > 0xFF ? 8 : 2));
|
||||
|
||||
XMLElement *pCondition = scriptXML.NewElement("condition");
|
||||
pCondition->SetAttribute("value", *strVal);
|
||||
XMLElement *pCondition = ScriptXML.NewElement("condition");
|
||||
pCondition->SetAttribute("value", *StrVal);
|
||||
pCondition->SetAttribute("shape", *GetVolumeString(it->Shape));
|
||||
if (it->Scale != 1.f) pCondition->SetAttribute("scale", it->Scale);
|
||||
pVolume->LinkEndChild(pCondition);
|
||||
@@ -364,221 +332,239 @@ void CTemplateWriter::SaveScriptTemplate(CScriptTemplate *pTemp, const TString&
|
||||
}
|
||||
|
||||
// Write to file
|
||||
scriptXML.SaveFile(*outFile);
|
||||
ScriptXML.SaveFile(*OutFile);
|
||||
}
|
||||
|
||||
void CTemplateWriter::SaveStructTemplate(CStructTemplate *pTemp, CMasterTemplate *pMaster, const TString& dir)
|
||||
void CTemplateWriter::SaveStructTemplate(CStructTemplate *pTemp, CMasterTemplate *pMaster, const TString& rkDir)
|
||||
{
|
||||
// Create directory
|
||||
TString outFile = dir + pTemp->mSourceFile;
|
||||
TString outDir = outFile.GetFileDirectory();
|
||||
TString name = pTemp->mSourceFile.GetFileName();
|
||||
boost::filesystem::create_directory(outDir.ToStdString());
|
||||
TString OutFile = rkDir + pTemp->mSourceFile;
|
||||
TString OutDir = OutFile.GetFileDirectory();
|
||||
TString Name = OutFile.GetFileName(false);
|
||||
boost::filesystem::create_directory(OutDir.ToStdString());
|
||||
|
||||
// Create new document and write struct properties to it
|
||||
XMLDocument structXML;
|
||||
XMLDocument StructXML;
|
||||
|
||||
XMLDeclaration *pDecl = structXML.NewDeclaration();
|
||||
structXML.LinkEndChild(pDecl);
|
||||
XMLDeclaration *pDecl = StructXML.NewDeclaration();
|
||||
StructXML.LinkEndChild(pDecl);
|
||||
|
||||
XMLElement *pBase = structXML.NewElement("struct");
|
||||
pBase->SetAttribute("name", *name);
|
||||
pBase->SetAttribute("type", (pTemp->IsSingleProperty() ? "single" : "multi"));
|
||||
SaveProperties(&structXML, pBase, pTemp, pMaster, dir);
|
||||
structXML.LinkEndChild(pBase);
|
||||
XMLElement *pRoot = StructXML.NewElement("struct");
|
||||
pRoot->SetAttribute("name", *Name);
|
||||
pRoot->SetAttribute("type", (pTemp->IsSingleProperty() ? "single" : "multi"));
|
||||
StructXML.LinkEndChild(pRoot);
|
||||
|
||||
structXML.SaveFile(*outFile);
|
||||
SaveProperties(&StructXML, pRoot, pTemp, pMaster, rkDir);
|
||||
StructXML.SaveFile(*OutFile);
|
||||
}
|
||||
|
||||
void CTemplateWriter::SaveEnumTemplate(CEnumTemplate *pTemp, const TString& dir)
|
||||
void CTemplateWriter::SaveEnumTemplate(CEnumTemplate *pTemp, const TString& rkDir)
|
||||
{
|
||||
// Create directory
|
||||
TString outFile = dir + pTemp->mSourceFile;
|
||||
TString outDir = outFile.GetFileDirectory();
|
||||
TString name = pTemp->mSourceFile.GetFileName(false);
|
||||
boost::filesystem::create_directory(*outDir);
|
||||
TString OutFile = rkDir + pTemp->mSourceFile;
|
||||
TString OutDir = OutFile.GetFileDirectory();
|
||||
TString Name = OutFile.GetFileName(false);
|
||||
boost::filesystem::create_directory(*OutDir);
|
||||
|
||||
// Create new document and write enumerators to it
|
||||
XMLDocument enumXML;
|
||||
XMLDocument EnumXML;
|
||||
|
||||
XMLDeclaration *pDecl = enumXML.NewDeclaration();
|
||||
enumXML.LinkEndChild(pDecl);
|
||||
XMLDeclaration *pDecl = EnumXML.NewDeclaration();
|
||||
EnumXML.LinkEndChild(pDecl);
|
||||
|
||||
XMLElement *pBase = enumXML.NewElement("enum");
|
||||
pBase->SetAttribute("name", *name);
|
||||
SaveEnumerators(&enumXML, pBase, pTemp);
|
||||
enumXML.LinkEndChild(pBase);
|
||||
XMLElement *pRoot = EnumXML.NewElement("enum");
|
||||
pRoot->SetAttribute("name", *Name);
|
||||
EnumXML.LinkEndChild(pRoot);
|
||||
|
||||
enumXML.SaveFile(*outFile);
|
||||
SaveEnumerators(&EnumXML, pRoot, pTemp);
|
||||
EnumXML.SaveFile(*OutFile);
|
||||
}
|
||||
|
||||
void CTemplateWriter::SaveBitfieldTemplate(CBitfieldTemplate *pTemp, const TString& dir)
|
||||
void CTemplateWriter::SaveBitfieldTemplate(CBitfieldTemplate *pTemp, const TString& rkDir)
|
||||
{
|
||||
// Create directory
|
||||
TString outFile = dir + pTemp->mSourceFile;
|
||||
TString outDir = outFile.GetFileDirectory();
|
||||
TString name = pTemp->mSourceFile.GetFileName();
|
||||
boost::filesystem::create_directory(*outDir);
|
||||
TString OutFile = rkDir + pTemp->mSourceFile;
|
||||
TString OutDir = OutFile.GetFileDirectory();
|
||||
TString Name = pTemp->mSourceFile.GetFileName(false);
|
||||
boost::filesystem::create_directory(*OutDir);
|
||||
|
||||
// Create new document and write enumerators to it
|
||||
XMLDocument bitfieldXML;
|
||||
XMLDocument BitfieldXML;
|
||||
|
||||
XMLDeclaration *pDecl = bitfieldXML.NewDeclaration();
|
||||
bitfieldXML.LinkEndChild(pDecl);
|
||||
XMLDeclaration *pDecl = BitfieldXML.NewDeclaration();
|
||||
BitfieldXML.LinkEndChild(pDecl);
|
||||
|
||||
XMLElement *pBase = bitfieldXML.NewElement("bitfield");
|
||||
pBase->SetAttribute("name", *name);
|
||||
SaveBitFlags(&bitfieldXML, pBase, pTemp);
|
||||
bitfieldXML.LinkEndChild(pBase);
|
||||
XMLElement *pRoot = BitfieldXML.NewElement("bitfield");
|
||||
pRoot->SetAttribute("name", *Name);
|
||||
BitfieldXML.LinkEndChild(pRoot);
|
||||
|
||||
bitfieldXML.SaveFile(*outFile);
|
||||
SaveBitFlags(&BitfieldXML, pRoot, pTemp);
|
||||
BitfieldXML.SaveFile(*OutFile);
|
||||
}
|
||||
|
||||
void CTemplateWriter::SaveProperties(XMLDocument *pDoc, XMLElement *pParent, CStructTemplate *pTemp, CMasterTemplate *pMaster, const TString& dir)
|
||||
void CTemplateWriter::SaveProperties(XMLDocument *pDoc, XMLElement *pParent, CStructTemplate *pTemp, CMasterTemplate *pMaster, const TString& rkDir)
|
||||
{
|
||||
// Create base element
|
||||
XMLElement *pPropsBlock = pDoc->NewElement("properties");
|
||||
pParent->LinkEndChild(pPropsBlock);
|
||||
|
||||
for (u32 iProp = 0; iProp < pTemp->Count(); iProp++)
|
||||
{
|
||||
CPropertyTemplate *pProp = pTemp->PropertyByIndex(iProp);
|
||||
u32 propID = (pProp->PropertyID() == 0xFFFFFFFF ? iProp : pProp->PropertyID());
|
||||
TString strID = TString::HexString(propID, true, true, (propID > 0xFF ? 8 : 2));
|
||||
// Get ID
|
||||
IPropertyTemplate *pProp = pTemp->PropertyByIndex(iProp);
|
||||
u32 ID = pProp->PropertyID();
|
||||
TString StrID = TString::HexString(ID, true, true, (ID > 0xFF ? 8 : 2));
|
||||
|
||||
// Create element
|
||||
XMLElement *pElem;
|
||||
|
||||
if (pProp->Type() == eStructProperty)
|
||||
pElem = pDoc->NewElement("struct");
|
||||
else if (pProp->Type() == eEnumProperty)
|
||||
pElem = pDoc->NewElement("enum");
|
||||
else if (pProp->Type() == eBitfieldProperty)
|
||||
pElem = pDoc->NewElement("bitfield");
|
||||
else if (pProp->Type() == eArrayProperty)
|
||||
pElem = pDoc->NewElement("array");
|
||||
else
|
||||
pElem = pDoc->NewElement("property");
|
||||
|
||||
// Set common property parameters, starting with ID
|
||||
pElem->SetAttribute("ID", *StrID);
|
||||
|
||||
// Type
|
||||
if (pProp->Type() == eStructProperty)
|
||||
pElem->SetAttribute("type", (static_cast<CStructTemplate*>(pProp)->mIsSingleProperty ? "single" : "multi"));
|
||||
|
||||
else if (TString(pElem->Name()) == "property")
|
||||
pElem->SetAttribute("type", *PropEnumToPropString(pProp->Type()));
|
||||
|
||||
// Name
|
||||
TString Name = pProp->Name();
|
||||
|
||||
if (pMaster->HasPropertyList())
|
||||
{
|
||||
CStructTemplate *pStructTemp = static_cast<CStructTemplate*>(pProp);
|
||||
bool isExternal = (!pStructTemp->mSourceFile.IsEmpty());
|
||||
TString MasterName = pMaster->PropertyName(ID);
|
||||
|
||||
XMLElement *pElem = pDoc->NewElement("struct");
|
||||
pElem->SetAttribute("ID", *strID);
|
||||
|
||||
if ((!pMaster->HasPropertyList()) || (pProp->PropertyID() == -1) || pTemp->IsSingleProperty())
|
||||
{
|
||||
pElem->SetAttribute("name", *pProp->Name());
|
||||
}
|
||||
|
||||
if (!isExternal) {
|
||||
TString type = pStructTemp->IsSingleProperty() ? "single" : "multi";
|
||||
pElem->SetAttribute("type", *type);
|
||||
}
|
||||
|
||||
// Only save properties if this is a multi struct, or if there is no master property list
|
||||
if (!pMaster->HasPropertyList() || !pStructTemp->IsSingleProperty())
|
||||
{
|
||||
// Embed struct or save to external XML?
|
||||
if (!pStructTemp->mSourceFile.IsEmpty())
|
||||
{
|
||||
SaveStructTemplate(pStructTemp, pMaster, dir);
|
||||
pElem->SetAttribute("template", *pStructTemp->mSourceFile);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
SaveProperties(pDoc, pElem, pStructTemp, pMaster, dir);
|
||||
}
|
||||
}
|
||||
|
||||
pParent->LinkEndChild(pElem);
|
||||
if (Name != MasterName)
|
||||
pElem->SetAttribute("name", *Name);
|
||||
}
|
||||
|
||||
else
|
||||
pElem->SetAttribute("name", *Name);
|
||||
|
||||
// Default
|
||||
if (pProp->CanHaveDefault())
|
||||
{
|
||||
XMLElement *pDefault = pDoc->NewElement("default");
|
||||
pDefault->SetText(*pProp->DefaultToString());
|
||||
pElem->LinkEndChild(pDefault);
|
||||
}
|
||||
|
||||
// Range
|
||||
if (pProp->IsNumerical() && pProp->HasValidRange())
|
||||
{
|
||||
XMLElement *pRange = pDoc->NewElement("range");
|
||||
pRange->SetText(*pProp->RangeToString());
|
||||
pElem->LinkEndChild(pRange);
|
||||
}
|
||||
|
||||
// Cook Pref
|
||||
ECookPreference CookPref = pProp->CookPreference();
|
||||
|
||||
if (CookPref != eNoCookPreference)
|
||||
{
|
||||
XMLElement *pCookPref = pDoc->NewElement("should_cook");
|
||||
pCookPref->SetText(CookPref == eAlwaysCook ? "always" : "never");
|
||||
pElem->LinkEndChild(pCookPref);
|
||||
}
|
||||
|
||||
// File-specific parameters
|
||||
if (pProp->Type() == eFileProperty)
|
||||
{
|
||||
CFileTemplate *pFile = static_cast<CFileTemplate*>(pProp);
|
||||
const TStringList& rkExtensions = pFile->Extensions();
|
||||
TString ExtensionsString;
|
||||
|
||||
for (auto it = rkExtensions.begin(); it != rkExtensions.end(); it++)
|
||||
ExtensionsString += *it + ",";
|
||||
|
||||
ExtensionsString.ChopBack(1); // Remove extra comma
|
||||
pElem->SetAttribute("extensions", *ExtensionsString);
|
||||
}
|
||||
|
||||
// Enum-specific parameters
|
||||
else if (pProp->Type() == eEnumProperty)
|
||||
{
|
||||
CEnumTemplate *pEnumTemp = static_cast<CEnumTemplate*>(pProp);
|
||||
bool isExternal = (!pEnumTemp->mSourceFile.IsEmpty());
|
||||
CEnumTemplate *pEnum = static_cast<CEnumTemplate*>(pProp);
|
||||
|
||||
XMLElement *pElem = pDoc->NewElement("enum");
|
||||
pElem->SetAttribute("ID", *strID);
|
||||
|
||||
if ((!pMaster->HasPropertyList()) || (pProp->PropertyID() == -1))
|
||||
pElem->SetAttribute("name", *pProp->Name());
|
||||
|
||||
if (isExternal)
|
||||
{
|
||||
SaveEnumTemplate(pEnumTemp, dir);
|
||||
pElem->SetAttribute("template", *pEnumTemp->mSourceFile);
|
||||
}
|
||||
if (pEnum->mSourceFile.IsEmpty())
|
||||
SaveEnumerators(pDoc, pElem, pEnum);
|
||||
|
||||
else
|
||||
{
|
||||
SaveEnumerators(pDoc, pElem, pEnumTemp);
|
||||
SaveEnumTemplate(pEnum, rkDir);
|
||||
pElem->SetAttribute("template", *pEnum->mSourceFile);
|
||||
}
|
||||
|
||||
pParent->LinkEndChild(pElem);
|
||||
}
|
||||
|
||||
// Bitfield-specific parameters
|
||||
else if (pProp->Type() == eBitfieldProperty)
|
||||
{
|
||||
CBitfieldTemplate *pBitfieldTemp = static_cast<CBitfieldTemplate*>(pProp);
|
||||
bool isExternal = (!pBitfieldTemp->mSourceFile.IsEmpty());
|
||||
CBitfieldTemplate *pBitfield = static_cast<CBitfieldTemplate*>(pProp);
|
||||
|
||||
XMLElement *pElem = pDoc->NewElement("bitfield");
|
||||
pElem->SetAttribute("ID", *strID);
|
||||
|
||||
if ((!pMaster->HasPropertyList()) || (pProp->PropertyID() == -1))
|
||||
pElem->SetAttribute("name", *pProp->Name());
|
||||
|
||||
if (isExternal)
|
||||
{
|
||||
SaveBitfieldTemplate(pBitfieldTemp, dir);
|
||||
pElem->SetAttribute("template", *pBitfieldTemp->mSourceFile);
|
||||
}
|
||||
if (pBitfield->mSourceFile.IsEmpty())
|
||||
SaveBitFlags(pDoc, pElem, pBitfield);
|
||||
|
||||
else
|
||||
{
|
||||
SaveBitFlags(pDoc, pElem, pBitfieldTemp);
|
||||
SaveBitfieldTemplate(pBitfield, rkDir);
|
||||
pElem->SetAttribute("template", *pBitfield->mSourceFile);
|
||||
}
|
||||
|
||||
pParent->LinkEndChild(pElem);
|
||||
}
|
||||
else
|
||||
|
||||
// Struct/array-specific parameters
|
||||
if (pProp->Type() == eStructProperty || pProp->Type() == eArrayProperty)
|
||||
{
|
||||
XMLElement *pElem = pDoc->NewElement("property");
|
||||
pElem->SetAttribute("ID", *strID);
|
||||
CStructTemplate *pStruct = static_cast<CStructTemplate*>(pProp);
|
||||
|
||||
if ((!pMaster->HasPropertyList()) || (pProp->PropertyID() == -1) || pTemp->IsSingleProperty())
|
||||
if (pStruct->mSourceFile.IsEmpty())
|
||||
SaveProperties(pDoc, pElem, pStruct, pMaster, rkDir);
|
||||
|
||||
else
|
||||
{
|
||||
pElem->SetAttribute("name", *pProp->Name());
|
||||
pElem->SetAttribute("type", *PropEnumToPropString(pProp->Type()));
|
||||
|
||||
if (pProp->Type() == eFileProperty)
|
||||
{
|
||||
// Construct extension list string
|
||||
CFileTemplate *pFileProp = static_cast<CFileTemplate*>(pProp);
|
||||
const TStringList& extensions = pFileProp->Extensions();
|
||||
|
||||
TString strList = "";
|
||||
|
||||
for (auto it = extensions.begin(); it != extensions.end();)
|
||||
{
|
||||
strList += *it;
|
||||
it++;
|
||||
if (it != extensions.end()) strList += ",";
|
||||
}
|
||||
|
||||
pElem->SetAttribute("ext", *strList);
|
||||
}
|
||||
SaveStructTemplate(pStruct, pMaster, rkDir);
|
||||
pElem->SetAttribute("template", *pStruct->mSourceFile);
|
||||
}
|
||||
|
||||
pParent->LinkEndChild(pElem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CTemplateWriter::SaveEnumerators(XMLDocument *pDoc, XMLElement *pParent, CEnumTemplate *pTemp)
|
||||
{
|
||||
XMLElement *pEnumerators = pDoc->NewElement("enumerators");
|
||||
pParent->LinkEndChild(pEnumerators);
|
||||
|
||||
for (u32 iEnum = 0; iEnum < pTemp->NumEnumerators(); iEnum++)
|
||||
{
|
||||
XMLElement *pElem = pDoc->NewElement("enumerator");
|
||||
pElem->SetAttribute("ID", *TString::HexString(pTemp->EnumeratorID(iEnum), true, true, 8));
|
||||
u32 EnumerID = pTemp->EnumeratorID(iEnum);
|
||||
pElem->SetAttribute("ID", *TString::HexString(EnumerID, true, true, (EnumerID > 0xFF ? 8 : 0)));
|
||||
pElem->SetAttribute("name", *pTemp->EnumeratorName(iEnum));
|
||||
pParent->LinkEndChild(pElem);
|
||||
pEnumerators->LinkEndChild(pElem);
|
||||
}
|
||||
}
|
||||
|
||||
void CTemplateWriter::SaveBitFlags(tinyxml2::XMLDocument *pDoc, tinyxml2::XMLElement *pParent, CBitfieldTemplate *pTemp)
|
||||
void CTemplateWriter::SaveBitFlags(XMLDocument *pDoc, XMLElement *pParent, CBitfieldTemplate *pTemp)
|
||||
{
|
||||
XMLElement *pFlags = pDoc->NewElement("flags");
|
||||
pParent->LinkEndChild(pFlags);
|
||||
|
||||
for (u32 iFlag = 0; iFlag < pTemp->NumFlags(); iFlag++)
|
||||
{
|
||||
XMLElement *pElem = pDoc->NewElement("bitflag");
|
||||
XMLElement *pElem = pDoc->NewElement("flag");
|
||||
pElem->SetAttribute("mask", *TString::HexString(pTemp->FlagMask(iFlag), true, true, 8));
|
||||
pElem->SetAttribute("name", *pTemp->FlagName(iFlag));
|
||||
pParent->LinkEndChild(pElem);
|
||||
pFlags->LinkEndChild(pElem);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,13 +11,13 @@ class CTemplateWriter
|
||||
|
||||
public:
|
||||
static void SaveAllTemplates();
|
||||
static void SaveGameTemplates(CMasterTemplate *pMaster, const TString& dir);
|
||||
static void SavePropertyList(CMasterTemplate *pMaster, const TString& dir);
|
||||
static void SaveScriptTemplate(CScriptTemplate *pTemp, const TString& dir);
|
||||
static void SaveStructTemplate(CStructTemplate *pTemp, CMasterTemplate *pMaster, const TString& dir);
|
||||
static void SaveEnumTemplate(CEnumTemplate *pTemp, const TString& dir);
|
||||
static void SaveBitfieldTemplate(CBitfieldTemplate *pTemp, const TString& dir);
|
||||
static void SaveProperties(tinyxml2::XMLDocument *pDoc, tinyxml2::XMLElement *pParent, CStructTemplate *pTemp, CMasterTemplate *pMaster, const TString& dir);
|
||||
static void SaveGameTemplates(CMasterTemplate *pMaster, const TString& rkDir);
|
||||
static void SavePropertyList(CMasterTemplate *pMaster, const TString& rkDir);
|
||||
static void SaveScriptTemplate(CScriptTemplate *pTemp, const TString& rkDir);
|
||||
static void SaveStructTemplate(CStructTemplate *pTemp, CMasterTemplate *pMaster, const TString& rkDir);
|
||||
static void SaveEnumTemplate(CEnumTemplate *pTemp, const TString& rkDir);
|
||||
static void SaveBitfieldTemplate(CBitfieldTemplate *pTemp, const TString& rkDir);
|
||||
static void SaveProperties(tinyxml2::XMLDocument *pDoc, tinyxml2::XMLElement *pParent, CStructTemplate *pTemp, CMasterTemplate *pMaster, const TString& rkDir);
|
||||
static void SaveEnumerators(tinyxml2::XMLDocument *pDoc, tinyxml2::XMLElement *pParent, CEnumTemplate *pTemp);
|
||||
static void SaveBitFlags(tinyxml2::XMLDocument *pDoc, tinyxml2::XMLElement *pParent, CBitfieldTemplate *pTemp);
|
||||
};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef CWORLDCOOKER_H
|
||||
#define CWORLDCOOKER_H
|
||||
|
||||
#include "Core/Resource/EFormatVersion.h"
|
||||
#include "Core/Resource/EGame.h"
|
||||
#include <Common/types.h>
|
||||
|
||||
class CWorldCooker
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef EFORMATVERSION_H
|
||||
#define EFORMATVERSION_H
|
||||
#ifndef EGAME_H
|
||||
#define EGAME_H
|
||||
|
||||
// Global version enum that can be easily shared between loaders
|
||||
enum EGame
|
||||
@@ -11,8 +11,7 @@ enum EGame
|
||||
eCorruptionProto = 4,
|
||||
eCorruption = 5,
|
||||
eReturns = 6,
|
||||
TropicalFreeze = 7,
|
||||
eUnknownVersion = -1
|
||||
};
|
||||
|
||||
#endif // EFORMATVERSION_H
|
||||
#endif // EGAME_H
|
||||
@@ -2,7 +2,7 @@
|
||||
#define CCHARACTERLOADER_H
|
||||
|
||||
#include "Core/Resource/CAnimSet.h"
|
||||
#include "Core/Resource/EFormatVersion.h"
|
||||
#include "Core/Resource/EGame.h"
|
||||
#include "Core/Resource/CResCache.h"
|
||||
|
||||
class CAnimSetLoader
|
||||
|
||||
@@ -101,23 +101,27 @@ void CAreaLoader::ReadSCLYPrime()
|
||||
return;
|
||||
}
|
||||
|
||||
mpMREA->Seek(0x4, SEEK_CUR);
|
||||
if (mVersion <= ePrime)
|
||||
mpMREA->Seek(0x4, SEEK_CUR);
|
||||
else
|
||||
mpMREA->Seek(0x1, SEEK_CUR);
|
||||
|
||||
mNumLayers = mpMREA->ReadLong();
|
||||
mpArea->mScriptLayers.reserve(mNumLayers);
|
||||
|
||||
std::vector<u32> LayerSizes(mNumLayers);
|
||||
for (u32 l = 0; l < mNumLayers; l++)
|
||||
LayerSizes[l] = mpMREA->ReadLong();
|
||||
for (u32 iLayer = 0; iLayer < mNumLayers; iLayer++)
|
||||
LayerSizes[iLayer] = mpMREA->ReadLong();
|
||||
|
||||
for (u32 l = 0; l < mNumLayers; l++)
|
||||
for (u32 iLayer = 0; iLayer < mNumLayers; iLayer++)
|
||||
{
|
||||
u32 next = mpMREA->Tell() + LayerSizes[l];
|
||||
u32 Next = mpMREA->Tell() + LayerSizes[iLayer];
|
||||
|
||||
CScriptLayer *layer = CScriptLoader::LoadLayer(*mpMREA, mpArea, mVersion);
|
||||
if (layer)
|
||||
mpArea->mScriptLayers.push_back(layer);
|
||||
CScriptLayer *pLayer = CScriptLoader::LoadLayer(*mpMREA, mpArea, mVersion);
|
||||
if (pLayer)
|
||||
mpArea->mScriptLayers.push_back(pLayer);
|
||||
|
||||
mpMREA->Seek(next, SEEK_SET);
|
||||
mpMREA->Seek(Next, SEEK_SET);
|
||||
}
|
||||
|
||||
SetUpObjects();
|
||||
@@ -572,6 +576,12 @@ CGameArea* CAreaLoader::LoadMREA(IInputStream& MREA)
|
||||
Loader.ReadLightsPrime();
|
||||
break;
|
||||
case eEchoesDemo:
|
||||
Loader.ReadHeaderEchoes();
|
||||
Loader.ReadGeometryPrime();
|
||||
Loader.ReadSCLYPrime();
|
||||
Loader.ReadCollision();
|
||||
Loader.ReadLightsPrime();
|
||||
break;
|
||||
case eEchoes:
|
||||
Loader.ReadHeaderEchoes();
|
||||
Loader.ReadGeometryPrime();
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include "CBlockMgrIn.h"
|
||||
#include "Core/Resource/Script/SConnection.h"
|
||||
#include "Core/Resource/CGameArea.h"
|
||||
#include "Core/Resource/EFormatVersion.h"
|
||||
#include "Core/Resource/EGame.h"
|
||||
#include "Core/Resource/CResCache.h"
|
||||
|
||||
#include <FileIO/FileIO.h>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include "Core/Resource/CCollisionMesh.h"
|
||||
#include "Core/Resource/CCollisionMeshGroup.h"
|
||||
#include "Core/Resource/EFormatVersion.h"
|
||||
#include "Core/Resource/EGame.h"
|
||||
|
||||
class CCollisionLoader
|
||||
{
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#define CFONTLOADER_H
|
||||
|
||||
#include "Core/Resource/CFont.h"
|
||||
#include "Core/Resource/EFormatVersion.h"
|
||||
#include "Core/Resource/EGame.h"
|
||||
#include "Core/Resource/CResCache.h"
|
||||
|
||||
class CFontLoader
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#define CMATERIALLOADER_H
|
||||
|
||||
#include "Core/Resource/CMaterialSet.h"
|
||||
#include "Core/Resource/EFormatVersion.h"
|
||||
#include "Core/Resource/EGame.h"
|
||||
#include "Core/Resource/CResCache.h"
|
||||
|
||||
#include <FileIO/FileIO.h>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include "Core/Resource/Model/CBasicModel.h"
|
||||
#include "Core/Resource/Model/CModel.h"
|
||||
#include "Core/Resource/CResCache.h"
|
||||
#include "Core/Resource/EFormatVersion.h"
|
||||
#include "Core/Resource/EGame.h"
|
||||
#include <Common/EnumUtil.h>
|
||||
|
||||
#include <FileIO/FileIO.h>
|
||||
|
||||
@@ -51,21 +51,21 @@ CScan* CScanLoader::LoadScanMP2(IInputStream& SCAN)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
mpScan = new CScan();
|
||||
SCAN.Seek(0x2, SEEK_CUR);
|
||||
u16 NumProperties = SCAN.ReadShort();
|
||||
|
||||
switch (NumProperties)
|
||||
{
|
||||
case 0x14:
|
||||
mpScan = new CScan();
|
||||
LoadParamsMP2(SCAN);
|
||||
break;
|
||||
case 0x16:
|
||||
mpScan = new CScan();
|
||||
LoadParamsMP3(SCAN);
|
||||
break;
|
||||
default:
|
||||
Log::FileError(SCAN.GetSourceString(), SCAN.Tell() - 2, "Invalid SNFO property count: " + TString::HexString(NumProperties));
|
||||
delete mpScan;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#define CSCANLOADER_H
|
||||
|
||||
#include "Core/Resource/CScan.h"
|
||||
#include "Core/Resource/EFormatVersion.h"
|
||||
#include "Core/Resource/EGame.h"
|
||||
|
||||
class CScanLoader
|
||||
{
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "CScriptLoader.h"
|
||||
#include "CTemplateLoader.h"
|
||||
#include "Core/Resource/Script/CMasterTemplate.h"
|
||||
#include "Core/Resource/CResCache.h"
|
||||
#include "Core/Log.h"
|
||||
@@ -10,152 +11,215 @@ CScriptLoader::CScriptLoader()
|
||||
mpObj = nullptr;
|
||||
}
|
||||
|
||||
CPropertyStruct* CScriptLoader::LoadStructMP1(IInputStream& SCLY, CStructTemplate *pTemp)
|
||||
void CScriptLoader::ReadProperty(IProperty *pProp, u32 Size, IInputStream& SCLY)
|
||||
{
|
||||
u32 structStart = SCLY.Tell();
|
||||
CPropertyStruct *propStruct = new CPropertyStruct();
|
||||
propStruct->mpTemplate = pTemp;
|
||||
IPropertyTemplate *pTemp = pProp->Template();
|
||||
|
||||
// Verify property count
|
||||
u32 propCount = pTemp->Count();
|
||||
|
||||
if (!pTemp->IsSingleProperty())
|
||||
switch (pTemp->Type())
|
||||
{
|
||||
u32 filePropCount = SCLY.ReadLong();
|
||||
if (propCount != filePropCount)
|
||||
Log::FileWarning(SCLY.GetSourceString(), structStart, "Struct \"" + pTemp->Name() + "\" template prop count doesn't match file");
|
||||
|
||||
case eBoolProperty: {
|
||||
TBoolProperty *pBoolCast = static_cast<TBoolProperty*>(pProp);
|
||||
pBoolCast->Set( (SCLY.ReadByte() != 0) );
|
||||
break;
|
||||
}
|
||||
|
||||
// Parse properties
|
||||
propStruct->Reserve(propCount);
|
||||
case eByteProperty: {
|
||||
TByteProperty *pByteCast = static_cast<TByteProperty*>(pProp);
|
||||
pByteCast->Set(SCLY.ReadByte());
|
||||
break;
|
||||
}
|
||||
|
||||
for (u32 iProp = 0; iProp < propCount; iProp++)
|
||||
{
|
||||
CPropertyBase *pProp = nullptr;
|
||||
CPropertyTemplate *pPropTmp = pTemp->PropertyByIndex(iProp);
|
||||
EPropertyType type = pPropTmp->Type();
|
||||
case eShortProperty: {
|
||||
TShortProperty *pShortCast = static_cast<TShortProperty*>(pProp);
|
||||
pShortCast->Set(SCLY.ReadShort());
|
||||
break;
|
||||
}
|
||||
|
||||
switch (type)
|
||||
case eLongProperty: {
|
||||
TLongProperty *pLongCast = static_cast<TLongProperty*>(pProp);
|
||||
pLongCast->Set(SCLY.ReadLong());
|
||||
break;
|
||||
}
|
||||
|
||||
case eBitfieldProperty: {
|
||||
TBitfieldProperty *pBitfieldCast = static_cast<TBitfieldProperty*>(pProp);
|
||||
pBitfieldCast->Set(SCLY.ReadLong());
|
||||
|
||||
// Validate
|
||||
u32 mask = 0;
|
||||
CBitfieldTemplate *pBitfieldTemp = static_cast<CBitfieldTemplate*>(pTemp);
|
||||
for (u32 iMask = 0; iMask < pBitfieldTemp->NumFlags(); iMask++)
|
||||
mask |= pBitfieldTemp->FlagMask(iMask);
|
||||
|
||||
u32 check = pBitfieldCast->Get() & ~mask;
|
||||
if (check != 0)
|
||||
Log::FileWarning(SCLY.GetSourceString(), SCLY.Tell() - 4, "Bitfield property \"" + pBitfieldTemp->Name() + "\" in struct \"" + pTemp->Name() + "\" has flags set that aren't in the template: " + TString::HexString(check, true, true, 8));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case eEnumProperty: {
|
||||
TEnumProperty *pEnumCast = static_cast<TEnumProperty*>(pProp);
|
||||
CEnumTemplate *pEnumTemp = static_cast<CEnumTemplate*>(pTemp);
|
||||
u32 ID = SCLY.ReadLong();
|
||||
u32 index = pEnumTemp->EnumeratorIndex(ID);
|
||||
if (index == -1) Log::FileError(SCLY.GetSourceString(), SCLY.Tell() - 4, "Enum property \"" + pEnumTemp->Name() + "\" in struct \"" + pTemp->Name() + "\" has invalid enumerator value: " + TString::HexString(ID, true, true, 8));
|
||||
pEnumCast->Set(index);
|
||||
break;
|
||||
}
|
||||
|
||||
case eFloatProperty: {
|
||||
TFloatProperty *pFloatCast = static_cast<TFloatProperty*>(pProp);
|
||||
pFloatCast->Set(SCLY.ReadFloat());
|
||||
break;
|
||||
}
|
||||
|
||||
case eStringProperty: {
|
||||
TStringProperty *pStringCast = static_cast<TStringProperty*>(pProp);
|
||||
pStringCast->Set(SCLY.ReadString());
|
||||
break;
|
||||
}
|
||||
|
||||
case eVector3Property: {
|
||||
TVector3Property *pVector3Cast = static_cast<TVector3Property*>(pProp);
|
||||
pVector3Cast->Set(CVector3f(SCLY));
|
||||
break;
|
||||
}
|
||||
|
||||
case eColorProperty: {
|
||||
TColorProperty *pColorCast = static_cast<TColorProperty*>(pProp);
|
||||
pColorCast->Set(CColor(SCLY));
|
||||
break;
|
||||
}
|
||||
|
||||
case eFileProperty: {
|
||||
TFileProperty *pFileCast = static_cast<TFileProperty*>(pProp);
|
||||
|
||||
CUniqueID ResID = (mVersion < eCorruptionProto ? SCLY.ReadLong() : SCLY.ReadLongLong());
|
||||
const TStringList& Extensions = static_cast<CFileTemplate*>(pTemp)->Extensions();
|
||||
|
||||
CResource *pRes = nullptr;
|
||||
|
||||
// Check for each extension individually until we find a match
|
||||
// This could be done better with a function to fetch the extension given the resource ID
|
||||
// and a "does resource exist" function, but this will do for now
|
||||
bool hasIgnoredExt = false;
|
||||
|
||||
if (ResID.IsValid())
|
||||
{
|
||||
|
||||
case eBoolProperty: {
|
||||
bool v = (SCLY.ReadByte() == 1);
|
||||
pProp = new CBoolProperty(v);
|
||||
break;
|
||||
}
|
||||
case eByteProperty: {
|
||||
char v = SCLY.ReadByte();
|
||||
pProp = new CByteProperty(v);
|
||||
break;
|
||||
}
|
||||
case eShortProperty: {
|
||||
short v = SCLY.ReadShort();
|
||||
pProp = new CShortProperty(v);
|
||||
break;
|
||||
}
|
||||
case eLongProperty: {
|
||||
long v = SCLY.ReadLong();
|
||||
pProp = new CLongProperty(v);
|
||||
break;
|
||||
}
|
||||
case eBitfieldProperty: {
|
||||
long v = SCLY.ReadLong();
|
||||
pProp = new CBitfieldProperty(v);
|
||||
|
||||
// Validate
|
||||
u32 mask = 0;
|
||||
CBitfieldTemplate *pBitfieldTemp = static_cast<CBitfieldTemplate*>(pPropTmp);
|
||||
for (u32 iMask = 0; iMask < pBitfieldTemp->NumFlags(); iMask++)
|
||||
mask |= pBitfieldTemp->FlagMask(iMask);
|
||||
|
||||
u32 check = v & ~mask;
|
||||
if (check != 0) Log::FileWarning(SCLY.GetSourceString(), SCLY.Tell() - 4, "Bitfield property \"" + pBitfieldTemp->Name() + "\" in struct \"" + pTemp->Name() + "\" has flags set that aren't in the template: " + TString::HexString(check, true, true, 8));
|
||||
|
||||
break;
|
||||
}
|
||||
case eEnumProperty: {
|
||||
CEnumTemplate *pEnumTemp = static_cast<CEnumTemplate*>(pPropTmp);
|
||||
u32 ID = SCLY.ReadLong();
|
||||
u32 index = pEnumTemp->EnumeratorIndex(ID);
|
||||
if (index == -1) Log::FileError(SCLY.GetSourceString(), SCLY.Tell() - 4, "Enum property \"" + pEnumTemp->Name() + "\" in struct \"" + pTemp->Name() + "\" has invalid enumerator value: " + TString::HexString(ID, true, true, 8));
|
||||
pProp = new CEnumProperty(index);
|
||||
break;
|
||||
}
|
||||
case eFloatProperty: {
|
||||
float v = SCLY.ReadFloat();
|
||||
pProp = new CFloatProperty(v);
|
||||
break;
|
||||
}
|
||||
case eStringProperty: {
|
||||
TString v = SCLY.ReadString();
|
||||
pProp = new CStringProperty(v);
|
||||
break;
|
||||
}
|
||||
case eVector3Property: {
|
||||
CVector3f v(SCLY);
|
||||
pProp = new CVector3Property(v);
|
||||
break;
|
||||
}
|
||||
case eColorProperty: {
|
||||
CColor v(SCLY);
|
||||
pProp = new CColorProperty(v);
|
||||
break;
|
||||
}
|
||||
case eFileProperty: {
|
||||
u32 ResID = SCLY.ReadLong();
|
||||
const TStringList& Extensions = static_cast<CFileTemplate*>(pPropTmp)->Extensions();
|
||||
|
||||
CResource *pRes = nullptr;
|
||||
|
||||
for (auto it = Extensions.begin(); it != Extensions.end(); it++)
|
||||
{
|
||||
const TString& ext = *it;
|
||||
if ((ext != "MREA") && (ext != "MLVL")) // Let's avoid recursion please
|
||||
|
||||
if ((ext != "MREA") && (ext != "MLVL")) {
|
||||
pRes = gResCache.GetResource(ResID, ext);
|
||||
if (pRes) break;
|
||||
}
|
||||
|
||||
if (pRes) break;
|
||||
else
|
||||
hasIgnoredExt = true;
|
||||
}
|
||||
|
||||
pProp = new CFileProperty(pRes);
|
||||
break;
|
||||
}
|
||||
case eStructProperty: {
|
||||
CStructTemplate *StructTmp = pTemp->StructByIndex(iProp);
|
||||
pProp = LoadStructMP1(SCLY, StructTmp);
|
||||
break;
|
||||
}
|
||||
case eAnimParamsProperty: {
|
||||
pProp = new CAnimParamsProperty(CAnimationParameters(SCLY, mVersion));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
pProp = new CUnknownProperty();
|
||||
break;
|
||||
}
|
||||
|
||||
if (pProp)
|
||||
// Property may have an incorrect extension listed - print error
|
||||
if ((!pRes) && (CUniqueID(ResID).IsValid()) && (!hasIgnoredExt))
|
||||
{
|
||||
pProp->mpTemplate = pPropTmp;
|
||||
propStruct->mProperties.push_back(pProp);
|
||||
TString ExtList;
|
||||
for (auto it = Extensions.begin(); it != Extensions.end(); it++)
|
||||
{
|
||||
if (it != Extensions.begin()) ExtList += "/";
|
||||
ExtList += *it;
|
||||
}
|
||||
}
|
||||
|
||||
pFileCast->Set(pRes);
|
||||
break;
|
||||
}
|
||||
|
||||
return propStruct;
|
||||
case eStructProperty: {
|
||||
CPropertyStruct *pStructCast = static_cast<CPropertyStruct*>(pProp);
|
||||
|
||||
if (mVersion < eEchoesDemo)
|
||||
LoadStructMP1(SCLY, pStructCast, static_cast<CStructTemplate*>(pStructCast->Template()));
|
||||
else
|
||||
LoadStructMP2(SCLY, pStructCast, static_cast<CStructTemplate*>(pTemp));
|
||||
break;
|
||||
}
|
||||
|
||||
case eArrayProperty: {
|
||||
CArrayProperty *pArrayCast = static_cast<CArrayProperty*>(pProp);
|
||||
u32 Size = SCLY.ReadLong();
|
||||
|
||||
pArrayCast->Resize(Size);
|
||||
|
||||
for (u32 iElem = 0; iElem < Size; iElem++)
|
||||
{
|
||||
if (mVersion < eEchoesDemo)
|
||||
LoadStructMP1(SCLY, pArrayCast->ElementByIndex(iElem), pArrayCast->SubStructTemplate());
|
||||
else
|
||||
LoadStructMP2(SCLY, pArrayCast->ElementByIndex(iElem), pArrayCast->SubStructTemplate());
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case eCharacterProperty: {
|
||||
TAnimParamsProperty *pAnimCast = static_cast<TAnimParamsProperty*>(pProp);
|
||||
pAnimCast->Set(CAnimationParameters(SCLY, mVersion));
|
||||
break;
|
||||
}
|
||||
|
||||
case eUnknownProperty: {
|
||||
TUnknownProperty *pUnknownCast = static_cast<TUnknownProperty*>(pProp);
|
||||
std::vector<u8> Buffer(Size);
|
||||
SCLY.ReadBytes(Buffer.data(), Buffer.size());
|
||||
pUnknownCast->Set(Buffer);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CScriptLoader::LoadStructMP1(IInputStream& SCLY, CPropertyStruct *pStruct, CStructTemplate *pTemp)
|
||||
{
|
||||
u32 StructStart = SCLY.Tell();
|
||||
|
||||
// Verify property count
|
||||
u32 PropCount = pTemp->Count();
|
||||
u32 Version = 0;
|
||||
|
||||
if (!pTemp->IsSingleProperty())
|
||||
{
|
||||
u32 FilePropCount = SCLY.ReadLong();
|
||||
Version = pTemp->VersionForPropertyCount(FilePropCount);
|
||||
|
||||
if (Version == -1)
|
||||
Log::FileWarning(SCLY.GetSourceString(), StructStart, "Struct \"" + pTemp->Name() + "\" template prop count doesn't match file");
|
||||
}
|
||||
|
||||
// Parse properties
|
||||
for (u32 iProp = 0; iProp < PropCount; iProp++)
|
||||
{
|
||||
IPropertyTemplate *pPropTemp = pTemp->PropertyByIndex(iProp);
|
||||
IProperty *pProp = pStruct->PropertyByIndex(iProp);
|
||||
|
||||
if (pPropTemp->CookPreference() != eNeverCook && pPropTemp->IsInVersion(Version))
|
||||
ReadProperty(pProp, 0, SCLY);
|
||||
}
|
||||
}
|
||||
|
||||
CScriptObject* CScriptLoader::LoadObjectMP1(IInputStream& SCLY)
|
||||
{
|
||||
u32 objStart = SCLY.Tell();
|
||||
u8 type = SCLY.ReadByte();
|
||||
u32 size = SCLY.ReadLong();
|
||||
u32 end = SCLY.Tell() + size;
|
||||
u32 ObjStart = SCLY.Tell();
|
||||
u8 Type = SCLY.ReadByte();
|
||||
u32 Size = SCLY.ReadLong();
|
||||
u32 End = SCLY.Tell() + Size;
|
||||
|
||||
CScriptTemplate *pTemp = mpMaster->TemplateByID((u32) type);
|
||||
CScriptTemplate *pTemp = mpMaster->TemplateByID((u32) Type);
|
||||
if (!pTemp)
|
||||
{
|
||||
// No valid template for this object; can't load
|
||||
Log::FileError(SCLY.GetSourceString(), objStart, "Invalid object ID encountered: " + TString::HexString(type));
|
||||
SCLY.Seek(end, SEEK_SET);
|
||||
Log::FileError(SCLY.GetSourceString(), ObjStart, "Invalid object ID encountered: " + TString::HexString(Type));
|
||||
SCLY.Seek(End, SEEK_SET);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -163,30 +227,24 @@ CScriptObject* CScriptLoader::LoadObjectMP1(IInputStream& SCLY)
|
||||
mpObj->mInstanceID = SCLY.ReadLong();
|
||||
|
||||
// Load connections
|
||||
u32 numLinks = SCLY.ReadLong();
|
||||
mpObj->mOutConnections.reserve(numLinks);
|
||||
u32 NumLinks = SCLY.ReadLong();
|
||||
mpObj->mOutConnections.reserve(NumLinks);
|
||||
|
||||
for (u32 iLink = 0; iLink < numLinks; iLink++)
|
||||
for (u32 iLink = 0; iLink < NumLinks; iLink++)
|
||||
{
|
||||
SLink link;
|
||||
link.State = SCLY.ReadLong();
|
||||
link.Message = SCLY.ReadLong();
|
||||
link.ObjectID = SCLY.ReadLong();
|
||||
mpObj->mOutConnections.push_back(link);
|
||||
SLink Link;
|
||||
Link.State = SCLY.ReadLong();
|
||||
Link.Message = SCLY.ReadLong();
|
||||
Link.ObjectID = SCLY.ReadLong();
|
||||
mpObj->mOutConnections.push_back(Link);
|
||||
}
|
||||
|
||||
// Load object...
|
||||
u32 count = SCLY.PeekLong();
|
||||
CStructTemplate *pBase = pTemp->BaseStructByCount(count);
|
||||
|
||||
if (!pBase) {
|
||||
Log::Error(pTemp->TemplateName() + " template doesn't match file property count (" + TString::FromInt32(count) + ")");
|
||||
pBase = pTemp->BaseStructByIndex(0);
|
||||
}
|
||||
mpObj->mpProperties = LoadStructMP1(SCLY, pBase);
|
||||
CPropertyStruct *pBase = mpObj->mpProperties;
|
||||
LoadStructMP1(SCLY, pBase, static_cast<CStructTemplate*>(pBase->Template()));
|
||||
|
||||
// Cleanup and return
|
||||
SCLY.Seek(end, SEEK_SET);
|
||||
SCLY.Seek(End, SEEK_SET);
|
||||
|
||||
mpObj->EvaluateProperties();
|
||||
return mpObj;
|
||||
@@ -210,33 +268,37 @@ CScriptLayer* CScriptLoader::LoadLayerMP1(IInputStream &SCLY)
|
||||
}
|
||||
|
||||
// Layer sizes are always a multiple of 32 - skip end padding before returning
|
||||
u32 remaining = 32 - ((SCLY.Tell() - LayerStart) & 0x1F);
|
||||
SCLY.Seek(remaining, SEEK_CUR);
|
||||
u32 Remaining = 32 - ((SCLY.Tell() - LayerStart) & 0x1F);
|
||||
SCLY.Seek(Remaining, SEEK_CUR);
|
||||
return mpLayer;
|
||||
}
|
||||
|
||||
void CScriptLoader::LoadStructMP2(IInputStream& SCLY, CPropertyStruct *pStruct, CStructTemplate *pTemp)
|
||||
{
|
||||
// Verify property count
|
||||
u32 propCount = pTemp->Count();
|
||||
u32 StructStart = SCLY.Tell();
|
||||
StructStart += 0;
|
||||
u32 PropCount = pTemp->Count();
|
||||
u32 Version = 0;
|
||||
|
||||
if (!pTemp->IsSingleProperty())
|
||||
{
|
||||
u16 numProperties = SCLY.ReadShort();
|
||||
if ((numProperties != propCount) && (mVersion < eReturns))
|
||||
Log::FileWarning(SCLY.GetSourceString(), SCLY.Tell() - 2, "Struct \"" + pTemp->Name() + "\" template property count doesn't match file");
|
||||
propCount = numProperties;
|
||||
u16 NumProperties = SCLY.ReadShort();
|
||||
Version = pTemp->VersionForPropertyCount(NumProperties);
|
||||
|
||||
//if ((NumProperties != PropCount) && (mVersion < eReturns))
|
||||
// Log::FileWarning(SCLY.GetSourceString(), SCLY.Tell() - 2, "Struct \"" + pTemp->Name() + "\" template property count doesn't match file");
|
||||
|
||||
PropCount = NumProperties;
|
||||
}
|
||||
|
||||
// Parse properties
|
||||
pStruct->Reserve(propCount);
|
||||
|
||||
for (u32 iProp = 0; iProp < propCount; iProp++)
|
||||
for (u32 iProp = 0; iProp < PropCount; iProp++)
|
||||
{
|
||||
CPropertyBase *pProp;
|
||||
CPropertyTemplate *pPropTemp;
|
||||
u32 propertyStart = SCLY.Tell();
|
||||
u32 propertyID = -1;
|
||||
IProperty *pProp;
|
||||
IPropertyTemplate *pPropTemp;
|
||||
u32 PropertyStart = SCLY.Tell();
|
||||
u32 PropertyID = -1;
|
||||
u16 PropertyLength = 0;
|
||||
u32 NextProperty = 0;
|
||||
|
||||
@@ -247,170 +309,19 @@ void CScriptLoader::LoadStructMP2(IInputStream& SCLY, CPropertyStruct *pStruct,
|
||||
}
|
||||
else
|
||||
{
|
||||
propertyID = SCLY.ReadLong();
|
||||
PropertyID = SCLY.ReadLong();
|
||||
PropertyLength = SCLY.ReadShort();
|
||||
NextProperty = SCLY.Tell() + PropertyLength;
|
||||
|
||||
pProp = pStruct->PropertyByID(propertyID);
|
||||
pPropTemp = pTemp->PropertyByID(propertyID);
|
||||
pProp = pStruct->PropertyByID(PropertyID);
|
||||
pPropTemp = pTemp->PropertyByID(PropertyID);
|
||||
}
|
||||
|
||||
if (!pPropTemp)
|
||||
Log::FileError(SCLY.GetSourceString(), propertyStart, "Can't find template for property " + TString::HexString(propertyID) + " - skipping");
|
||||
Log::FileError(SCLY.GetSourceString(), PropertyStart, "Can't find template for property " + TString::HexString(PropertyID) + " - skipping");
|
||||
|
||||
else
|
||||
{
|
||||
switch (pPropTemp->Type())
|
||||
{
|
||||
|
||||
case eBoolProperty: {
|
||||
CBoolProperty *pBoolCast = static_cast<CBoolProperty*>(pProp);
|
||||
pBoolCast->Set( (SCLY.ReadByte() != 0) );
|
||||
break;
|
||||
}
|
||||
|
||||
case eByteProperty: {
|
||||
CByteProperty *pByteCast = static_cast<CByteProperty*>(pProp);
|
||||
pByteCast->Set(SCLY.ReadByte());
|
||||
break;
|
||||
}
|
||||
|
||||
case eShortProperty: {
|
||||
CShortProperty *pShortCast = static_cast<CShortProperty*>(pProp);
|
||||
pShortCast->Set(SCLY.ReadShort());
|
||||
break;
|
||||
}
|
||||
|
||||
case eLongProperty: {
|
||||
CLongProperty *pLongCast = static_cast<CLongProperty*>(pProp);
|
||||
pLongCast->Set(SCLY.ReadLong());
|
||||
break;
|
||||
}
|
||||
|
||||
case eBitfieldProperty: {
|
||||
CBitfieldProperty *pBitfieldCast = static_cast<CBitfieldProperty*>(pProp);
|
||||
pBitfieldCast->Set(SCLY.ReadLong());
|
||||
|
||||
// Validate
|
||||
u32 mask = 0;
|
||||
CBitfieldTemplate *pBitfieldTemp = static_cast<CBitfieldTemplate*>(pPropTemp);
|
||||
for (u32 iMask = 0; iMask < pBitfieldTemp->NumFlags(); iMask++)
|
||||
mask |= pBitfieldTemp->FlagMask(iMask);
|
||||
|
||||
u32 check = pBitfieldCast->Get() & ~mask;
|
||||
if (check != 0) Log::FileWarning(SCLY.GetSourceString(), SCLY.Tell() - 4, "Bitfield property \"" + pBitfieldTemp->Name() + "\" in struct \"" + pTemp->Name() + "\" has flags set that aren't in the template: " + TString::HexString(check, true, true, 8));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case eEnumProperty: {
|
||||
CEnumProperty *pEnumCast = static_cast<CEnumProperty*>(pProp);
|
||||
CEnumTemplate *pEnumTemp = static_cast<CEnumTemplate*>(pPropTemp);
|
||||
u32 ID = SCLY.ReadLong();
|
||||
u32 index = pEnumTemp->EnumeratorIndex(ID);
|
||||
if (index == -1) Log::FileError(SCLY.GetSourceString(), SCLY.Tell() - 4, "Enum property \"" + pEnumTemp->Name() + "\" in struct \"" + pTemp->Name() + "\" has invalid enumerator value: " + TString::HexString(ID, true, true, 8));
|
||||
pEnumCast->Set(index);
|
||||
break;
|
||||
}
|
||||
|
||||
case eFloatProperty: {
|
||||
CFloatProperty *pFloatCast = static_cast<CFloatProperty*>(pProp);
|
||||
pFloatCast->Set(SCLY.ReadFloat());
|
||||
break;
|
||||
}
|
||||
|
||||
case eStringProperty: {
|
||||
CStringProperty *pStringCast = static_cast<CStringProperty*>(pProp);
|
||||
pStringCast->Set(SCLY.ReadString());
|
||||
break;
|
||||
}
|
||||
|
||||
case eVector3Property: {
|
||||
CVector3Property *pVector3Cast = static_cast<CVector3Property*>(pProp);
|
||||
pVector3Cast->Set(CVector3f(SCLY));
|
||||
break;
|
||||
}
|
||||
|
||||
case eColorProperty: {
|
||||
CColorProperty *pColorCast = static_cast<CColorProperty*>(pProp);
|
||||
pColorCast->Set(CColor(SCLY));
|
||||
break;
|
||||
}
|
||||
|
||||
case eFileProperty: {
|
||||
CFileProperty *pFileCast = static_cast<CFileProperty*>(pProp);
|
||||
|
||||
CUniqueID ResID = (mVersion < eCorruptionProto ? SCLY.ReadLong() : SCLY.ReadLongLong());
|
||||
const TStringList& Extensions = static_cast<CFileTemplate*>(pPropTemp)->Extensions();
|
||||
|
||||
CResource *pRes = nullptr;
|
||||
|
||||
// Check for each extension individually until we find a match
|
||||
// This could be done better with a function to fetch the extension given the resource ID
|
||||
// and a "does resource exist" function, but this will do for now
|
||||
bool hasIgnoredExt = false;
|
||||
|
||||
if (ResID.IsValid())
|
||||
{
|
||||
for (auto it = Extensions.begin(); it != Extensions.end(); it++)
|
||||
{
|
||||
const TString& ext = *it;
|
||||
|
||||
if ((ext != "MREA") && (ext != "MLVL")) {
|
||||
pRes = gResCache.GetResource(ResID, ext);
|
||||
if (pRes) break;
|
||||
}
|
||||
|
||||
else
|
||||
hasIgnoredExt = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Property may have an incorrect extension listed - print error
|
||||
if ((!pRes) && (CUniqueID(ResID).IsValid()) && (!hasIgnoredExt))
|
||||
{
|
||||
TString ExtList;
|
||||
for (auto it = Extensions.begin(); it != Extensions.end(); it++)
|
||||
{
|
||||
if (it != Extensions.begin()) ExtList += "/";
|
||||
ExtList += *it;
|
||||
}
|
||||
Log::FileWarning(SCLY.GetSourceString(), "Incorrect resource type? " + ExtList + " " + TString::HexString(propertyID));
|
||||
}
|
||||
|
||||
pFileCast->Set(pRes);
|
||||
break;
|
||||
}
|
||||
|
||||
case eUnknownProperty: {
|
||||
CUnknownProperty *pUnknownCast = static_cast<CUnknownProperty*>(pProp);
|
||||
std::vector<u8> buf(PropertyLength);
|
||||
SCLY.ReadBytes(buf.data(), buf.size());
|
||||
pUnknownCast->Set(buf);
|
||||
break;
|
||||
}
|
||||
|
||||
case eStructProperty: {
|
||||
CPropertyStruct *pStructCast = static_cast<CPropertyStruct*>(pProp);
|
||||
LoadStructMP2(SCLY, pStructCast, static_cast<CStructTemplate*>(pPropTemp));
|
||||
break;
|
||||
}
|
||||
|
||||
case eArrayProperty: {
|
||||
CArrayProperty *pArrayCast = static_cast<CArrayProperty*>(pProp);
|
||||
std::vector<u8> buf(PropertyLength);
|
||||
SCLY.ReadBytes(buf.data(), buf.size());
|
||||
pArrayCast->Set(buf);
|
||||
break;
|
||||
}
|
||||
|
||||
case eAnimParamsProperty: {
|
||||
CAnimParamsProperty *pAnimCast = static_cast<CAnimParamsProperty*>(pProp);
|
||||
pAnimCast->Set(CAnimationParameters(SCLY, mVersion));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
ReadProperty(pProp, PropertyLength, SCLY);
|
||||
|
||||
if (NextProperty > 0)
|
||||
SCLY.Seek(NextProperty, SEEK_SET);
|
||||
@@ -443,20 +354,16 @@ CScriptObject* CScriptLoader::LoadObjectMP2(IInputStream& SCLY)
|
||||
|
||||
for (u32 iCon = 0; iCon < NumConnections; iCon++)
|
||||
{
|
||||
SLink con;
|
||||
con.State = SCLY.ReadLong();
|
||||
con.Message = SCLY.ReadLong();
|
||||
con.ObjectID = SCLY.ReadLong();
|
||||
mpObj->mOutConnections.push_back(con);
|
||||
SLink Link;
|
||||
Link.State = SCLY.ReadLong();
|
||||
Link.Message = SCLY.ReadLong();
|
||||
Link.ObjectID = SCLY.ReadLong();
|
||||
mpObj->mOutConnections.push_back(Link);
|
||||
}
|
||||
|
||||
// Load object
|
||||
SCLY.Seek(0x6, SEEK_CUR); // Skip base struct ID + size
|
||||
u16 numProps = SCLY.PeekShort();
|
||||
mpObj->CopyFromTemplate(pTemplate, (u32) numProps);
|
||||
|
||||
CStructTemplate *pBase = pTemplate->BaseStructByCount(numProps);
|
||||
LoadStructMP2(SCLY, mpObj->mpProperties, pBase);
|
||||
LoadStructMP2(SCLY, mpObj->mpProperties, mpObj->mpTemplate->BaseStruct());
|
||||
|
||||
// Cleanup and return
|
||||
SCLY.Seek(ObjEnd, SEEK_SET);
|
||||
@@ -466,14 +373,30 @@ CScriptObject* CScriptLoader::LoadObjectMP2(IInputStream& SCLY)
|
||||
|
||||
CScriptLayer* CScriptLoader::LoadLayerMP2(IInputStream& SCLY)
|
||||
{
|
||||
CFourCC SCLY_Magic(SCLY);
|
||||
bool IsSCGN = false;
|
||||
|
||||
if (SCLY_Magic == "SCLY") SCLY.Seek(0x6, SEEK_CUR);
|
||||
else if (SCLY_Magic == "SCGN") SCLY.Seek(0x2, SEEK_CUR);
|
||||
if (mVersion >= eEchoes)
|
||||
{
|
||||
CFourCC SCLY_Magic(SCLY);
|
||||
|
||||
if (SCLY_Magic == "SCLY")
|
||||
{
|
||||
SCLY.Seek(0x6, SEEK_CUR);
|
||||
}
|
||||
else if (SCLY_Magic == "SCGN")
|
||||
{
|
||||
SCLY.Seek(0x2, SEEK_CUR);
|
||||
IsSCGN = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Log::FileError(SCLY.GetSourceString(), SCLY.Tell() - 4, "Invalid script layer magic: " + TString::HexString((u32) SCLY_Magic.ToLong()));
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Log::FileError(SCLY.GetSourceString(), SCLY.Tell() - 4, "Invalid script layer magic: " + TString::HexString((u32) SCLY_Magic.ToLong()));
|
||||
return nullptr;
|
||||
SCLY.Seek(0x1, SEEK_CUR);
|
||||
}
|
||||
|
||||
u32 NumObjects = SCLY.ReadLong();
|
||||
@@ -488,7 +411,7 @@ CScriptLayer* CScriptLoader::LoadLayerMP2(IInputStream& SCLY)
|
||||
mpLayer->AddObject(pObj);
|
||||
}
|
||||
|
||||
if (SCLY_Magic == "SCGN")
|
||||
if (IsSCGN)
|
||||
{
|
||||
mpLayer->SetName("Generated");
|
||||
mpLayer->SetActive(true);
|
||||
@@ -496,13 +419,13 @@ CScriptLayer* CScriptLoader::LoadLayerMP2(IInputStream& SCLY)
|
||||
return mpLayer;
|
||||
}
|
||||
|
||||
CScriptLayer* CScriptLoader::LoadLayer(IInputStream &SCLY, CGameArea *pArea, EGame version)
|
||||
CScriptLayer* CScriptLoader::LoadLayer(IInputStream &SCLY, CGameArea *pArea, EGame Version)
|
||||
{
|
||||
if (!SCLY.IsValid()) return nullptr;
|
||||
|
||||
CScriptLoader Loader;
|
||||
Loader.mVersion = version;
|
||||
Loader.mpMaster = CMasterTemplate::GetMasterForGame(version);
|
||||
Loader.mVersion = Version;
|
||||
Loader.mpMaster = CMasterTemplate::GetMasterForGame(Version);
|
||||
Loader.mpArea = pArea;
|
||||
|
||||
if (!Loader.mpMaster)
|
||||
@@ -511,7 +434,10 @@ CScriptLayer* CScriptLoader::LoadLayer(IInputStream &SCLY, CGameArea *pArea, EGa
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (version <= ePrime)
|
||||
if (!Loader.mpMaster->IsLoadedSuccessfully())
|
||||
CTemplateLoader::LoadGameTemplates(Version);
|
||||
|
||||
if (Version <= ePrime)
|
||||
return Loader.LoadLayerMP1(SCLY);
|
||||
else
|
||||
return Loader.LoadLayerMP2(SCLY);
|
||||
|
||||
@@ -16,8 +16,9 @@ class CScriptLoader
|
||||
CMasterTemplate *mpMaster;
|
||||
|
||||
CScriptLoader();
|
||||
void ReadProperty(IProperty *pProp, u32 Size, IInputStream& SCLY);
|
||||
|
||||
CPropertyStruct* LoadStructMP1(IInputStream& SCLY, CStructTemplate *tmp);
|
||||
void LoadStructMP1(IInputStream& SCLY, CPropertyStruct *pStruct, CStructTemplate *pTemp);
|
||||
CScriptObject* LoadObjectMP1(IInputStream& SCLY);
|
||||
CScriptLayer* LoadLayerMP1(IInputStream& SCLY);
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include "Core/Resource/CStringTable.h"
|
||||
#include "Core/Resource/CResCache.h"
|
||||
#include "Core/Resource/EFormatVersion.h"
|
||||
#include "Core/Resource/EGame.h"
|
||||
#include "Core/Resource/TResPtr.h"
|
||||
|
||||
class CStringLoader
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,29 +7,44 @@
|
||||
|
||||
class CTemplateLoader
|
||||
{
|
||||
static const TString mskTemplatesDir;
|
||||
static const TString mskGameListPath;
|
||||
|
||||
CMasterTemplate *mpMaster;
|
||||
TString mTemplatesDir;
|
||||
TString mMasterDir;
|
||||
|
||||
// Constructor
|
||||
CTemplateLoader(const TString& templatesDir) : mTemplatesDir(templatesDir) {}
|
||||
CTemplateLoader(const TString& rkTemplatesDir)
|
||||
: mTemplatesDir(rkTemplatesDir) {}
|
||||
|
||||
// Load Property
|
||||
void LoadBitFlags(tinyxml2::XMLElement *pElem, CBitfieldTemplate *pTemp, const TString& templateName);
|
||||
void LoadEnumerators(tinyxml2::XMLElement *pElem, CEnumTemplate *pTemp, const TString& templateName);
|
||||
void LoadStructProperties(tinyxml2::XMLElement *pElem, CStructTemplate *pTemp, const TString& templateName);
|
||||
CPropertyTemplate* LoadPropertyTemplate(tinyxml2::XMLElement *pElem, const TString& templateName);
|
||||
IPropertyTemplate* LoadProperty(tinyxml2::XMLElement *pElem, CStructTemplate *pParentStruct, const TString& rkTemplateName);
|
||||
IPropertyTemplate* CreateProperty(u32 ID, EPropertyType Type, const TString& rkName, CStructTemplate *pStruct);
|
||||
|
||||
void LoadStructTemplate(const TString& rkTemplateFileName, CStructTemplate *pStruct);
|
||||
void LoadEnumTemplate(const TString& rkTemplateFileName, CEnumTemplate *pEnum);
|
||||
void LoadBitfieldTemplate(const TString& rkTemplateFileName, CBitfieldTemplate *pBitfield);
|
||||
|
||||
void LoadProperties(tinyxml2::XMLElement *pPropertiesElem, CStructTemplate *pStruct, const TString& rkTemplateName);
|
||||
void LoadEnumerators(tinyxml2::XMLElement *pEnumeratorsElem, CEnumTemplate *pEnum, const TString& rkTemplateName);
|
||||
void LoadBitFlags(tinyxml2::XMLElement *pFlagsElem, CBitfieldTemplate *pBitfield, const TString& rkTemplateName);
|
||||
|
||||
// Load Script Object
|
||||
CScriptTemplate* LoadScriptTemplate(tinyxml2::XMLDocument *pDoc, const TString& templateName, u32 objectID);
|
||||
CScriptTemplate* LoadScriptTemplate(tinyxml2::XMLDocument *pDoc, const TString& rkTemplateName, u32 ObjectID);
|
||||
|
||||
// Load Master
|
||||
void LoadMasterTemplate(tinyxml2::XMLDocument *pDoc);
|
||||
void LoadPropertyList(tinyxml2::XMLDocument *pDoc, const TString& listName);
|
||||
CMasterTemplate* LoadGame(tinyxml2::XMLNode *pNode);
|
||||
CMasterTemplate* LoadGameInfo(tinyxml2::XMLNode *pNode);
|
||||
void LoadMasterTemplate(tinyxml2::XMLDocument *pDoc, CMasterTemplate *pMaster);
|
||||
void LoadPropertyList(tinyxml2::XMLDocument *pDoc, const TString& rkListName);
|
||||
|
||||
// Utility
|
||||
static void OpenXML(const TString& rkPath, tinyxml2::XMLDocument& rDoc);
|
||||
static TString ErrorName(tinyxml2::XMLError Error);
|
||||
|
||||
public:
|
||||
static void LoadGameList();
|
||||
static void LoadGameTemplates(EGame Game);
|
||||
};
|
||||
|
||||
#endif // CTEMPLATELOADER_H
|
||||
|
||||
@@ -9,9 +9,8 @@ CWorldLoader::CWorldLoader()
|
||||
|
||||
void CWorldLoader::LoadPrimeMLVL(IInputStream& MLVL)
|
||||
{
|
||||
/**
|
||||
/*
|
||||
* This function loads MLVL files from Prime 1/2
|
||||
* Corruption isn't too different, but having to check for it on every file ID is obnoxious
|
||||
* We start immediately after the "version" value (0x8 in the file)
|
||||
*/
|
||||
// Header
|
||||
@@ -19,8 +18,8 @@ void CWorldLoader::LoadPrimeMLVL(IInputStream& MLVL)
|
||||
{
|
||||
mpWorld->mpWorldName = gResCache.GetResource(MLVL.ReadLong(), "STRG");
|
||||
if (mVersion == eEchoes) mpWorld->mpDarkWorldName = gResCache.GetResource(MLVL.ReadLong(), "STRG");
|
||||
if (mVersion > ePrime) mpWorld->mUnknown1 = MLVL.ReadLong();
|
||||
if (mVersion >= ePrime) mpWorld->mpSaveWorld = gResCache.GetResource(MLVL.ReadLong(), "SAVW");
|
||||
if (mVersion >= eEchoes) mpWorld->mUnknown1 = MLVL.ReadLong();
|
||||
if (mVersion >= ePrime) mpWorld->mpSaveWorld = gResCache.GetResource(MLVL.ReadLong(), "SAVW");
|
||||
mpWorld->mpDefaultSkybox = gResCache.GetResource(MLVL.ReadLong(), "CMDL");
|
||||
}
|
||||
|
||||
@@ -146,7 +145,7 @@ void CWorldLoader::LoadPrimeMLVL(IInputStream& MLVL)
|
||||
}
|
||||
|
||||
// Rels
|
||||
if (mVersion == eEchoes)
|
||||
if ( (mVersion == eEchoesDemo) || (mVersion == eEchoes) )
|
||||
{
|
||||
u32 NumRels = MLVL.ReadLong();
|
||||
pArea->RelFilenames.resize(NumRels);
|
||||
@@ -154,15 +153,18 @@ void CWorldLoader::LoadPrimeMLVL(IInputStream& MLVL)
|
||||
for (u32 iRel = 0; iRel < NumRels; iRel++)
|
||||
pArea->RelFilenames[iRel] = MLVL.ReadString();
|
||||
|
||||
u32 NumRelOffsets = MLVL.ReadLong(); // Don't know what these offsets correspond to
|
||||
pArea->RelOffsets.resize(NumRelOffsets);
|
||||
if (mVersion == eEchoes)
|
||||
{
|
||||
u32 NumRelOffsets = MLVL.ReadLong(); // Don't know what these offsets correspond to
|
||||
pArea->RelOffsets.resize(NumRelOffsets);
|
||||
|
||||
for (u32 iOff = 0; iOff < NumRelOffsets; iOff++)
|
||||
pArea->RelOffsets[iOff] = MLVL.ReadLong();
|
||||
for (u32 iOff = 0; iOff < NumRelOffsets; iOff++)
|
||||
pArea->RelOffsets[iOff] = MLVL.ReadLong();
|
||||
}
|
||||
}
|
||||
|
||||
// Footer
|
||||
if (mVersion >= eEchoes)
|
||||
if (mVersion >= eEchoesDemo)
|
||||
pArea->InternalName = MLVL.ReadString();
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include "Core/Resource/CWorld.h"
|
||||
#include "Core/Resource/CResCache.h"
|
||||
#include "Core/Resource/EFormatVersion.h"
|
||||
#include "Core/Resource/EGame.h"
|
||||
|
||||
#include <FileIO/FileIO.h>
|
||||
|
||||
|
||||
@@ -20,6 +20,23 @@ EGame CMasterTemplate::GetGame()
|
||||
return mGame;
|
||||
}
|
||||
|
||||
u32 CMasterTemplate::NumGameVersions()
|
||||
{
|
||||
if (mGameVersions.empty()) return 1;
|
||||
else return mGameVersions.size();
|
||||
}
|
||||
|
||||
u32 CMasterTemplate::GetGameVersion(TString VersionName)
|
||||
{
|
||||
VersionName = VersionName.ToLower();
|
||||
|
||||
for (u32 iVer = 0; iVer < mGameVersions.size(); iVer++)
|
||||
if (mGameVersions[iVer].ToLower() == VersionName)
|
||||
return iVer;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
CScriptTemplate* CMasterTemplate::TemplateByID(u32 ObjectID)
|
||||
{
|
||||
auto it = mTemplates.find(ObjectID);
|
||||
@@ -83,14 +100,14 @@ TString CMasterTemplate::MessageByIndex(u32 Index)
|
||||
return (std::next(it, Index))->second;
|
||||
}
|
||||
|
||||
CPropertyTemplate* CMasterTemplate::GetProperty(u32 PropertyID)
|
||||
TString CMasterTemplate::PropertyName(u32 PropertyID)
|
||||
{
|
||||
auto it = mPropertyList.find(PropertyID);
|
||||
auto it = mPropertyNames.find(PropertyID);
|
||||
|
||||
if (it != mPropertyList.end())
|
||||
if (it != mPropertyNames.end())
|
||||
return it->second;
|
||||
else
|
||||
return nullptr;
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
bool CMasterTemplate::HasPropertyList()
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#define CMASTERTEMPLATE_H
|
||||
|
||||
#include "CScriptTemplate.h"
|
||||
#include "Core/Resource/EFormatVersion.h"
|
||||
#include "Core/Resource/EGame.h"
|
||||
#include <Common/types.h>
|
||||
#include <map>
|
||||
|
||||
@@ -17,12 +17,13 @@ class CMasterTemplate
|
||||
u32 mVersion;
|
||||
bool mFullyLoaded;
|
||||
|
||||
std::vector<TString> mGameVersions;
|
||||
std::map<u32, CScriptTemplate*> mTemplates;
|
||||
std::map<u32, TString> mStates;
|
||||
std::map<u32, TString> mMessages;
|
||||
|
||||
bool mHasPropList;
|
||||
std::map<u32, CPropertyTemplate*> mPropertyList;
|
||||
std::map<u32, TString> mPropertyNames;
|
||||
|
||||
static std::map<EGame, CMasterTemplate*> smMasterMap;
|
||||
static u32 smGameListVersion;
|
||||
@@ -31,6 +32,8 @@ public:
|
||||
CMasterTemplate();
|
||||
~CMasterTemplate();
|
||||
EGame GetGame();
|
||||
u32 NumGameVersions();
|
||||
u32 GetGameVersion(TString VersionName);
|
||||
u32 NumScriptTemplates();
|
||||
u32 NumStates();
|
||||
u32 NumMessages();
|
||||
@@ -43,7 +46,7 @@ public:
|
||||
TString MessageByID(u32 MessageID);
|
||||
TString MessageByID(const CFourCC& MessageID);
|
||||
TString MessageByIndex(u32 Index);
|
||||
CPropertyTemplate* GetProperty(u32 PropertyID);
|
||||
TString PropertyName(u32 PropertyID);
|
||||
bool HasPropertyList();
|
||||
bool IsLoadedSuccessfully();
|
||||
|
||||
|
||||
@@ -1,123 +0,0 @@
|
||||
#include "CProperty.h"
|
||||
|
||||
// ************ CPropertyStruct ************
|
||||
CPropertyStruct::~CPropertyStruct()
|
||||
{
|
||||
for (auto it = mProperties.begin(); it != mProperties.end(); it++)
|
||||
delete *it;
|
||||
}
|
||||
|
||||
CPropertyBase* CPropertyStruct::PropertyByIndex(u32 index)
|
||||
{
|
||||
return mProperties[index];
|
||||
}
|
||||
|
||||
CPropertyBase* CPropertyStruct::PropertyByID(u32 ID)
|
||||
{
|
||||
for (auto it = mProperties.begin(); it != mProperties.end(); it++)
|
||||
{
|
||||
if ((*it)->ID() == ID)
|
||||
return *it;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CPropertyBase* CPropertyStruct::PropertyByIDString(const TIDString& str)
|
||||
{
|
||||
// Resolve namespace
|
||||
u32 nsStart = str.IndexOf(":");
|
||||
|
||||
// String has namespace; the requested property is within a struct
|
||||
if (nsStart != -1)
|
||||
{
|
||||
TString strStructID = str.Truncate(nsStart);
|
||||
if (!strStructID.IsHexString()) return nullptr;
|
||||
|
||||
u32 structID = strStructID.ToInt32();
|
||||
TString propName = str.ChopFront(nsStart + 1);
|
||||
|
||||
CPropertyStruct *pStruct = StructByID(structID);
|
||||
if (!pStruct) return nullptr;
|
||||
else return pStruct->PropertyByIDString(propName);
|
||||
}
|
||||
|
||||
// No namespace; fetch the property from this struct
|
||||
else
|
||||
{
|
||||
if (str.IsHexString())
|
||||
return PropertyByID(str.ToInt32());
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
CPropertyStruct* CPropertyStruct::StructByIndex(u32 index)
|
||||
{
|
||||
CPropertyBase *pProp = PropertyByIndex(index);
|
||||
|
||||
if (pProp->Type() == eStructProperty)
|
||||
return static_cast<CPropertyStruct*>(pProp);
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CPropertyStruct* CPropertyStruct::StructByID(u32 ID)
|
||||
{
|
||||
CPropertyBase *pProp = PropertyByID(ID);
|
||||
|
||||
if (pProp->Type() == eStructProperty)
|
||||
return static_cast<CPropertyStruct*>(pProp);
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CPropertyStruct* CPropertyStruct::StructByIDString(const TIDString& str)
|
||||
{
|
||||
CPropertyBase *pProp = PropertyByIDString(str);
|
||||
|
||||
if (pProp->Type() == eStructProperty)
|
||||
return static_cast<CPropertyStruct*>(pProp);
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// ************ STATIC ************
|
||||
CPropertyStruct* CPropertyStruct::CopyFromTemplate(CStructTemplate *pTemp)
|
||||
{
|
||||
CPropertyStruct *pStruct = new CPropertyStruct();
|
||||
pStruct->mpTemplate = pTemp;
|
||||
pStruct->Reserve(pTemp->Count());
|
||||
|
||||
for (u32 iProp = 0; iProp < pTemp->Count(); iProp++)
|
||||
{
|
||||
CPropertyTemplate *pPropTemp = pTemp->PropertyByIndex(iProp);
|
||||
CPropertyBase *pProp = nullptr;
|
||||
|
||||
switch (pPropTemp->Type())
|
||||
{
|
||||
case eBoolProperty: pProp = new CBoolProperty(false); break;
|
||||
case eByteProperty: pProp = new CByteProperty(0); break;
|
||||
case eShortProperty: pProp = new CShortProperty(0); break;
|
||||
case eLongProperty: pProp = new CLongProperty(0); break;
|
||||
case eEnumProperty: pProp = new CEnumProperty(0); break;
|
||||
case eBitfieldProperty: pProp = new CBitfieldProperty(0); break;
|
||||
case eFloatProperty: pProp = new CFloatProperty(0.f); break;
|
||||
case eStringProperty: pProp = new CStringProperty(""); break;
|
||||
case eVector3Property: pProp = new CVector3Property(CVector3f::skZero); break;
|
||||
case eColorProperty: pProp = new CColorProperty(CColor::skBlack); break;
|
||||
case eFileProperty: pProp = new CFileProperty(); break;
|
||||
case eArrayProperty: pProp = new CArrayProperty(); break;
|
||||
case eAnimParamsProperty: pProp = new CAnimParamsProperty(); break;
|
||||
case eUnknownProperty: pProp = new CUnknownProperty(); break;
|
||||
case eStructProperty: pProp = CPropertyStruct::CopyFromTemplate(static_cast<CStructTemplate*>(pPropTemp)); break;
|
||||
}
|
||||
|
||||
if (pProp)
|
||||
{
|
||||
pProp->SetTemplate(pPropTemp);
|
||||
pStruct->mProperties.push_back(pProp);
|
||||
}
|
||||
}
|
||||
|
||||
return pStruct;
|
||||
}
|
||||
@@ -1,101 +0,0 @@
|
||||
#ifndef CPROPERTY
|
||||
#define CPROPERTY
|
||||
|
||||
/* This header file declares some classes used to track script object properties
|
||||
* CPropertyBase, __CProperty (and typedefs), CPropertyStruct
|
||||
* It's a bit hard to read, should be reorganized at some point */
|
||||
#include "CPropertyTemplate.h"
|
||||
#include "EPropertyType.h"
|
||||
#include "Core/Resource/CResource.h"
|
||||
#include "Core/Resource/TResPtr.h"
|
||||
#include "Core/Resource/CAnimationParameters.h"
|
||||
#include <Common/CColor.h>
|
||||
#include <Common/TString.h>
|
||||
#include <Math/CVector3f.h>
|
||||
#include <list>
|
||||
|
||||
class CScriptTemplate;
|
||||
|
||||
typedef TString TIDString;
|
||||
|
||||
/*
|
||||
* CPropertyBase is the base class, containing just some virtual function definitions
|
||||
* Virtual destructor is mainly there to make cleanup easy; don't need to cast to delete
|
||||
*/
|
||||
class CPropertyBase
|
||||
{
|
||||
friend class CScriptLoader;
|
||||
protected:
|
||||
CPropertyTemplate *mpTemplate;
|
||||
public:
|
||||
virtual ~CPropertyBase() {}
|
||||
inline virtual EPropertyType Type() = 0;
|
||||
inline CPropertyTemplate *Template() { return mpTemplate; }
|
||||
inline void SetTemplate(CPropertyTemplate *_tmp) { mpTemplate = _tmp; }
|
||||
inline TString Name() { return mpTemplate->Name(); }
|
||||
inline u32 ID() { return mpTemplate->PropertyID(); }
|
||||
};
|
||||
|
||||
/*
|
||||
* __CProperty is a template subclass for actual properties.
|
||||
* Don't use this class directly. Typedefs are provided for every possible property type.
|
||||
*/
|
||||
template <typename t, EPropertyType type>
|
||||
class __CProperty : public CPropertyBase
|
||||
{
|
||||
friend class CScriptLoader;
|
||||
t mValue;
|
||||
public:
|
||||
__CProperty() {}
|
||||
__CProperty(t v) { Set(v); }
|
||||
~__CProperty() {}
|
||||
inline EPropertyType Type() { return type; }
|
||||
inline t Get() { return mValue; }
|
||||
inline void Set(t v) { mValue = v; }
|
||||
};
|
||||
typedef __CProperty<bool, eBoolProperty> CBoolProperty;
|
||||
typedef __CProperty<char, eByteProperty> CByteProperty;
|
||||
typedef __CProperty<short, eShortProperty> CShortProperty;
|
||||
typedef __CProperty<long, eLongProperty> CLongProperty;
|
||||
typedef __CProperty<long, eEnumProperty> CEnumProperty;
|
||||
typedef __CProperty<long, eBitfieldProperty> CBitfieldProperty;
|
||||
typedef __CProperty<float, eFloatProperty> CFloatProperty;
|
||||
typedef __CProperty<TString, eStringProperty> CStringProperty;
|
||||
typedef __CProperty<CVector3f, eVector3Property> CVector3Property;
|
||||
typedef __CProperty<CColor, eColorProperty> CColorProperty;
|
||||
typedef __CProperty<TResPtr<CResource>, eFileProperty> CFileProperty;
|
||||
typedef __CProperty<CAnimationParameters, eAnimParamsProperty> CAnimParamsProperty;
|
||||
typedef __CProperty<std::vector<u8>, eArrayProperty> CArrayProperty;
|
||||
typedef __CProperty<std::vector<u8>, eUnknownProperty> CUnknownProperty;
|
||||
|
||||
/*
|
||||
* CPropertyStruct is for defining structs of properties.
|
||||
*/
|
||||
class CPropertyStruct : public CPropertyBase
|
||||
{
|
||||
friend class CScriptLoader;
|
||||
std::vector<CPropertyBase*> mProperties;
|
||||
public:
|
||||
// Destructor simply iterates through the list and deletes them. Nothing complicated.
|
||||
~CPropertyStruct();
|
||||
|
||||
// Inline
|
||||
EPropertyType Type() { return eStructProperty; }
|
||||
inline u32 Count() { return mProperties.size(); }
|
||||
inline void Reserve(u32 amount) { mProperties.reserve(amount); }
|
||||
inline CPropertyBase* operator[](u32 index) { return mProperties[index]; }
|
||||
|
||||
// Functions
|
||||
CPropertyBase* PropertyByIndex(u32 index);
|
||||
CPropertyBase* PropertyByID(u32 ID);
|
||||
CPropertyBase* PropertyByIDString(const TIDString& str);
|
||||
CPropertyStruct* StructByIndex(u32 index);
|
||||
CPropertyStruct* StructByID(u32 ID);
|
||||
CPropertyStruct* StructByIDString(const TIDString& str);
|
||||
|
||||
// Static
|
||||
static CPropertyStruct* CopyFromTemplate(CStructTemplate *pTemp);
|
||||
};
|
||||
|
||||
#endif // CPROPERTY
|
||||
|
||||
@@ -1,175 +0,0 @@
|
||||
#include "CPropertyTemplate.h"
|
||||
#include <iostream>
|
||||
|
||||
EPropertyType PropStringToPropEnum(const TString& prop)
|
||||
{
|
||||
if (prop == "bool") return eBoolProperty;
|
||||
if (prop == "byte") return eByteProperty;
|
||||
if (prop == "short") return eShortProperty;
|
||||
if (prop == "long") return eLongProperty;
|
||||
if (prop == "enum") return eEnumProperty;
|
||||
if (prop == "bitfield") return eBitfieldProperty;
|
||||
if (prop == "float") return eFloatProperty;
|
||||
if (prop == "string") return eStringProperty;
|
||||
if (prop == "color") return eColorProperty;
|
||||
if (prop == "vector3f") return eVector3Property;
|
||||
if (prop == "file") return eFileProperty;
|
||||
if (prop == "struct") return eStructProperty;
|
||||
if (prop == "array") return eArrayProperty;
|
||||
if (prop == "animparams") return eAnimParamsProperty;
|
||||
if (prop == "unknown") return eUnknownProperty;
|
||||
return eInvalidProperty;
|
||||
}
|
||||
|
||||
TString PropEnumToPropString(EPropertyType prop)
|
||||
{
|
||||
switch (prop)
|
||||
{
|
||||
case eBoolProperty: return "bool";
|
||||
case eByteProperty: return "byte";
|
||||
case eShortProperty: return "short";
|
||||
case eLongProperty: return "long";
|
||||
case eEnumProperty: return "enum";
|
||||
case eBitfieldProperty: return "bitfield";
|
||||
case eFloatProperty: return "float";
|
||||
case eStringProperty: return "string";
|
||||
case eColorProperty: return "color";
|
||||
case eVector3Property: return "vector3f";
|
||||
case eFileProperty: return "file";
|
||||
case eStructProperty: return "struct";
|
||||
case eArrayProperty: return "array";
|
||||
case eAnimParamsProperty: return "animparams";
|
||||
case eUnknownProperty: return "unknown";
|
||||
|
||||
case eInvalidProperty:
|
||||
default:
|
||||
return "invalid";
|
||||
}
|
||||
}
|
||||
|
||||
/*******************
|
||||
* CStructTemplate *
|
||||
*******************/
|
||||
CStructTemplate::CStructTemplate() : CPropertyTemplate(-1)
|
||||
{
|
||||
mIsSingleProperty = false;
|
||||
mPropType = eStructProperty;
|
||||
}
|
||||
|
||||
CStructTemplate::~CStructTemplate()
|
||||
{
|
||||
for (auto it = mProperties.begin(); it != mProperties.end(); it++)
|
||||
delete *it;
|
||||
}
|
||||
|
||||
// ************ GETTERS ************
|
||||
EPropertyType CStructTemplate::Type() const
|
||||
{
|
||||
return eStructProperty;
|
||||
}
|
||||
|
||||
bool CStructTemplate::IsSingleProperty() const
|
||||
{
|
||||
return mIsSingleProperty;
|
||||
}
|
||||
|
||||
u32 CStructTemplate::Count() const
|
||||
{
|
||||
return mProperties.size();
|
||||
}
|
||||
|
||||
CPropertyTemplate* CStructTemplate::PropertyByIndex(u32 index)
|
||||
{
|
||||
if (mProperties.size() > index)
|
||||
return mProperties[index];
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CPropertyTemplate* CStructTemplate::PropertyByID(u32 ID)
|
||||
{
|
||||
for (auto it = mProperties.begin(); it != mProperties.end(); it++)
|
||||
{
|
||||
if ((*it)->PropertyID() == ID)
|
||||
return *it;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CPropertyTemplate* CStructTemplate::PropertyByIDString(const TIDString& str)
|
||||
{
|
||||
// Resolve namespace
|
||||
u32 nsStart = str.IndexOf(":");
|
||||
u32 propStart = nsStart + 1;
|
||||
|
||||
// String has namespace; the requested property is within a struct
|
||||
if (nsStart != -1)
|
||||
{
|
||||
TString strStructID = str.SubString(0, nsStart);
|
||||
if (!strStructID.IsHexString()) return nullptr;
|
||||
|
||||
u32 structID = strStructID.ToInt32();
|
||||
TString propName = str.SubString(propStart, str.Length() - propStart);
|
||||
|
||||
CStructTemplate *pStruct = StructByID(structID);
|
||||
if (!pStruct) return nullptr;
|
||||
else return pStruct->PropertyByIDString(propName);
|
||||
}
|
||||
|
||||
// No namespace; fetch the property from this struct
|
||||
else
|
||||
{
|
||||
// ID string lookup
|
||||
if (str.IsHexString())
|
||||
return PropertyByID(str.ToInt32());
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
CStructTemplate* CStructTemplate::StructByIndex(u32 index)
|
||||
{
|
||||
CPropertyTemplate *pProp = PropertyByIndex(index);
|
||||
|
||||
if (pProp->Type() == eStructProperty)
|
||||
return static_cast<CStructTemplate*>(pProp);
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CStructTemplate* CStructTemplate::StructByID(u32 ID)
|
||||
{
|
||||
CPropertyTemplate *pProp = PropertyByID(ID);
|
||||
|
||||
if (pProp && pProp->Type() == eStructProperty)
|
||||
return static_cast<CStructTemplate*>(pProp);
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CStructTemplate* CStructTemplate::StructByIDString(const TString& str)
|
||||
{
|
||||
CPropertyTemplate *pProp = PropertyByIDString(str);
|
||||
|
||||
if (pProp && pProp->Type() == eStructProperty)
|
||||
return static_cast<CStructTemplate*>(pProp);
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// ************ DEBUG ************
|
||||
void CStructTemplate::DebugPrintProperties(TString base)
|
||||
{
|
||||
base = base + Name() + "::";
|
||||
for (auto it = mProperties.begin(); it != mProperties.end(); it++)
|
||||
{
|
||||
CPropertyTemplate *tmp = *it;
|
||||
if (tmp->Type() == eStructProperty)
|
||||
{
|
||||
CStructTemplate *tmp2 = static_cast<CStructTemplate*>(tmp);
|
||||
tmp2->DebugPrintProperties(base);
|
||||
}
|
||||
else
|
||||
std::cout << base << tmp->Name() << "\n";
|
||||
}
|
||||
}
|
||||
@@ -1,219 +0,0 @@
|
||||
#ifndef CPROPERTYTEMPLATE
|
||||
#define CPROPERTYTEMPLATE
|
||||
|
||||
#include "EPropertyType.h"
|
||||
#include <Common/TString.h>
|
||||
#include <Common/types.h>
|
||||
#include <vector>
|
||||
|
||||
typedef TString TIDString;
|
||||
|
||||
class CPropertyTemplate
|
||||
{
|
||||
friend class CTemplateLoader;
|
||||
friend class CTemplateWriter;
|
||||
|
||||
protected:
|
||||
EPropertyType mPropType;
|
||||
TString mPropName;
|
||||
u32 mPropID;
|
||||
public:
|
||||
CPropertyTemplate(u32 ID)
|
||||
: mPropID(ID)
|
||||
{
|
||||
}
|
||||
|
||||
CPropertyTemplate(EPropertyType type, TString name, u32 ID)
|
||||
: mPropType(type),
|
||||
mPropName(name),
|
||||
mPropID(ID)
|
||||
{
|
||||
}
|
||||
|
||||
virtual EPropertyType Type() const
|
||||
{
|
||||
return mPropType;
|
||||
}
|
||||
|
||||
inline TString Name() const
|
||||
{
|
||||
return mPropName;
|
||||
}
|
||||
|
||||
inline u32 PropertyID() const
|
||||
{
|
||||
return mPropID;
|
||||
}
|
||||
|
||||
inline void SetName(const TString& Name)
|
||||
{
|
||||
mPropName = Name;
|
||||
}
|
||||
};
|
||||
|
||||
class CFileTemplate : public CPropertyTemplate
|
||||
{
|
||||
friend class CTemplateLoader;
|
||||
friend class CTemplateWriter;
|
||||
|
||||
TStringList mAcceptedExtensions;
|
||||
public:
|
||||
CFileTemplate(u32 ID) : CPropertyTemplate(ID) { mPropType = eFileProperty; }
|
||||
|
||||
CFileTemplate(const TString& name, u32 ID, const TStringList& extensions)
|
||||
: CPropertyTemplate(ID)
|
||||
{
|
||||
mPropType = eFileProperty;
|
||||
mPropName = name;
|
||||
mAcceptedExtensions = extensions;
|
||||
}
|
||||
|
||||
EPropertyType Type() const
|
||||
{
|
||||
return eFileProperty;
|
||||
}
|
||||
|
||||
const TStringList& Extensions() const
|
||||
{
|
||||
return mAcceptedExtensions;
|
||||
}
|
||||
};
|
||||
|
||||
class CEnumTemplate : public CPropertyTemplate
|
||||
{
|
||||
friend class CTemplateLoader;
|
||||
friend class CTemplateWriter;
|
||||
|
||||
struct SEnumerator
|
||||
{
|
||||
TString Name;
|
||||
u32 ID;
|
||||
|
||||
SEnumerator(const TString& _name, u32 _ID)
|
||||
: Name(_name), ID(_ID) {}
|
||||
};
|
||||
std::vector<SEnumerator> mEnumerators;
|
||||
TString mSourceFile;
|
||||
|
||||
public:
|
||||
CEnumTemplate(u32 ID)
|
||||
: CPropertyTemplate(ID)
|
||||
{
|
||||
mPropType = eEnumProperty;
|
||||
}
|
||||
|
||||
CEnumTemplate(const TString& name, u32 ID)
|
||||
: CPropertyTemplate(eEnumProperty, name, ID)
|
||||
{}
|
||||
|
||||
EPropertyType Type() const
|
||||
{
|
||||
return eEnumProperty;
|
||||
}
|
||||
|
||||
u32 NumEnumerators()
|
||||
{
|
||||
return mEnumerators.size();
|
||||
}
|
||||
|
||||
u32 EnumeratorIndex(u32 enumID)
|
||||
{
|
||||
for (u32 iEnum = 0; iEnum < mEnumerators.size(); iEnum++)
|
||||
{
|
||||
if (mEnumerators[iEnum].ID == enumID)
|
||||
return iEnum;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
u32 EnumeratorID(u32 enumIndex)
|
||||
{
|
||||
if (mEnumerators.size() > enumIndex)
|
||||
return mEnumerators[enumIndex].ID;
|
||||
|
||||
else return -1;
|
||||
}
|
||||
|
||||
TString EnumeratorName(u32 enumIndex)
|
||||
{
|
||||
if (mEnumerators.size() > enumIndex)
|
||||
return mEnumerators[enumIndex].Name;
|
||||
|
||||
else return "INVALID ENUM INDEX";
|
||||
}
|
||||
};
|
||||
|
||||
class CBitfieldTemplate : public CPropertyTemplate
|
||||
{
|
||||
friend class CTemplateLoader;
|
||||
friend class CTemplateWriter;
|
||||
|
||||
struct SBitFlag
|
||||
{
|
||||
TString Name;
|
||||
u32 Mask;
|
||||
|
||||
SBitFlag(const TString& _name, u32 _mask)
|
||||
: Name(_name), Mask(_mask) {}
|
||||
};
|
||||
std::vector<SBitFlag> mBitFlags;
|
||||
TString mSourceFile;
|
||||
|
||||
public:
|
||||
CBitfieldTemplate(u32 ID)
|
||||
: CPropertyTemplate(ID)
|
||||
{
|
||||
mPropType = eBitfieldProperty;
|
||||
}
|
||||
|
||||
CBitfieldTemplate(const TString& name, u32 ID)
|
||||
: CPropertyTemplate(eBitfieldProperty, name, ID)
|
||||
{}
|
||||
|
||||
EPropertyType Type() const
|
||||
{
|
||||
return eBitfieldProperty;
|
||||
}
|
||||
|
||||
u32 NumFlags()
|
||||
{
|
||||
return mBitFlags.size();
|
||||
}
|
||||
|
||||
TString FlagName(u32 index)
|
||||
{
|
||||
return mBitFlags[index].Name;
|
||||
}
|
||||
|
||||
u32 FlagMask(u32 index)
|
||||
{
|
||||
return mBitFlags[index].Mask;
|
||||
}
|
||||
};
|
||||
|
||||
class CStructTemplate : public CPropertyTemplate
|
||||
{
|
||||
friend class CTemplateLoader;
|
||||
friend class CTemplateWriter;
|
||||
|
||||
bool mIsSingleProperty;
|
||||
std::vector<CPropertyTemplate*> mProperties;
|
||||
TString mSourceFile;
|
||||
public:
|
||||
CStructTemplate();
|
||||
~CStructTemplate();
|
||||
|
||||
EPropertyType Type() const;
|
||||
bool IsSingleProperty() const;
|
||||
u32 Count() const;
|
||||
CPropertyTemplate* PropertyByIndex(u32 index);
|
||||
CPropertyTemplate* PropertyByID(u32 ID);
|
||||
CPropertyTemplate* PropertyByIDString(const TIDString& str);
|
||||
CStructTemplate* StructByIndex(u32 index);
|
||||
CStructTemplate* StructByID(u32 ID);
|
||||
CStructTemplate* StructByIDString(const TIDString& str);
|
||||
void DebugPrintProperties(TString base);
|
||||
};
|
||||
|
||||
#endif // CPROPERTYTEMPLATE
|
||||
|
||||
@@ -3,16 +3,16 @@
|
||||
#include "Core/Resource/CAnimSet.h"
|
||||
|
||||
CScriptObject::CScriptObject(CGameArea *pArea, CScriptLayer *pLayer, CScriptTemplate *pTemplate)
|
||||
: mpTemplate(pTemplate)
|
||||
, mpArea(pArea)
|
||||
, mpLayer(pLayer)
|
||||
, mVersion(0)
|
||||
, mpDisplayModel(nullptr)
|
||||
, mpCollision(nullptr)
|
||||
, mHasInGameModel(false)
|
||||
{
|
||||
mpTemplate = pTemplate;
|
||||
mpArea = pArea;
|
||||
mpLayer = pLayer;
|
||||
mpProperties = nullptr;
|
||||
mpTemplate->AddObject(this);
|
||||
mpDisplayModel = nullptr;
|
||||
mpBillboard = nullptr;
|
||||
mpCollision = nullptr;
|
||||
mHasInGameModel = false;
|
||||
mpProperties = (CPropertyStruct*) pTemplate->BaseStruct()->InstantiateProperty();
|
||||
}
|
||||
|
||||
CScriptObject::~CScriptObject()
|
||||
@@ -22,14 +22,7 @@ CScriptObject::~CScriptObject()
|
||||
}
|
||||
|
||||
// ************ DATA MANIPULATION ************
|
||||
void CScriptObject::CopyFromTemplate(CScriptTemplate *pTemp, u32 propCount)
|
||||
{
|
||||
CStructTemplate *pBaseStruct = pTemp->BaseStructByCount(propCount);
|
||||
delete mpProperties;
|
||||
mpProperties = CPropertyStruct::CopyFromTemplate(pBaseStruct);
|
||||
}
|
||||
|
||||
void CScriptObject::EvaluateProperties()
|
||||
void CScriptObject::EvaluateProperties()
|
||||
{
|
||||
mpInstanceName = mpTemplate->FindInstanceName(mpProperties);
|
||||
mpPosition = mpTemplate->FindPosition(mpProperties);
|
||||
@@ -61,12 +54,12 @@ void CScriptObject::EvaluateCollisionModel()
|
||||
}
|
||||
|
||||
// ************ GETTERS ************
|
||||
CPropertyBase* CScriptObject::PropertyByIndex(u32 index) const
|
||||
IProperty* CScriptObject::PropertyByIndex(u32 index) const
|
||||
{
|
||||
return mpProperties->PropertyByIndex(index);
|
||||
}
|
||||
|
||||
CPropertyBase* CScriptObject::PropertyByIDString(const TString& str) const
|
||||
IProperty* CScriptObject::PropertyByIDString(const TString& str) const
|
||||
{
|
||||
return mpProperties->PropertyByIDString(str);
|
||||
}
|
||||
@@ -91,6 +84,11 @@ CScriptLayer* CScriptObject::Layer() const
|
||||
return mpLayer;
|
||||
}
|
||||
|
||||
u32 CScriptObject::Version() const
|
||||
{
|
||||
return mVersion;
|
||||
}
|
||||
|
||||
CPropertyStruct* CScriptObject::Properties() const
|
||||
{
|
||||
return mpProperties;
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
#define CSCRIPTOBJECT_H
|
||||
|
||||
#include "SConnection.h"
|
||||
#include "CProperty.h"
|
||||
#include "CPropertyTemplate.h"
|
||||
#include "IProperty.h"
|
||||
#include "IPropertyTemplate.h"
|
||||
#include "CScriptTemplate.h"
|
||||
#include "Core/Resource/Model/CModel.h"
|
||||
#include "Core/Resource/CCollisionMeshGroup.h"
|
||||
@@ -19,17 +19,18 @@ class CScriptObject
|
||||
CScriptTemplate *mpTemplate;
|
||||
TResPtr<CGameArea> mpArea;
|
||||
CScriptLayer *mpLayer;
|
||||
u32 mVersion;
|
||||
|
||||
u32 mInstanceID;
|
||||
std::vector<SLink> mOutConnections;
|
||||
std::vector<SLink> mInConnections;
|
||||
CPropertyStruct *mpProperties;
|
||||
|
||||
CStringProperty *mpInstanceName;
|
||||
CVector3Property *mpPosition;
|
||||
CVector3Property *mpRotation;
|
||||
CVector3Property *mpScale;
|
||||
CBoolProperty *mpActive;
|
||||
TStringProperty *mpInstanceName;
|
||||
TVector3Property *mpPosition;
|
||||
TVector3Property *mpRotation;
|
||||
TVector3Property *mpScale;
|
||||
TBoolProperty *mpActive;
|
||||
CPropertyStruct *mpLightParameters;
|
||||
TResPtr<CModel> mpDisplayModel;
|
||||
TResPtr<CTexture> mpBillboard;
|
||||
@@ -43,7 +44,6 @@ public:
|
||||
CScriptObject(CGameArea *pArea, CScriptLayer *pLayer, CScriptTemplate *pTemplate);
|
||||
~CScriptObject();
|
||||
|
||||
void CopyFromTemplate(CScriptTemplate *pTemp, u32 propCount);
|
||||
void EvaluateProperties();
|
||||
void EvaluateDisplayModel();
|
||||
void EvaluateBillboard();
|
||||
@@ -53,10 +53,11 @@ public:
|
||||
CMasterTemplate* MasterTemplate() const;
|
||||
CGameArea* Area() const;
|
||||
CScriptLayer* Layer() const;
|
||||
u32 Version() const;
|
||||
CPropertyStruct* Properties() const;
|
||||
u32 NumProperties() const;
|
||||
CPropertyBase* PropertyByIndex(u32 index) const;
|
||||
CPropertyBase* PropertyByIDString(const TIDString& str) const;
|
||||
IProperty* PropertyByIndex(u32 index) const;
|
||||
IProperty* PropertyByIDString(const TIDString& str) const;
|
||||
u32 ObjectTypeID() const;
|
||||
u32 InstanceID() const;
|
||||
u32 NumInLinks() const;
|
||||
|
||||
@@ -9,18 +9,18 @@
|
||||
#include <string>
|
||||
|
||||
CScriptTemplate::CScriptTemplate(CMasterTemplate *pMaster)
|
||||
: mpMaster(pMaster)
|
||||
, mpBaseStruct(nullptr)
|
||||
, mVisible(true)
|
||||
, mPreviewScale(1.f)
|
||||
, mVolumeShape(eNoShape)
|
||||
, mVolumeScale(1.f)
|
||||
{
|
||||
mpMaster = pMaster;
|
||||
mVisible = true;
|
||||
mPreviewScale = 1.f;
|
||||
mVolumeScale = 1.f;
|
||||
mVolumeShape = eNoShape;
|
||||
}
|
||||
|
||||
CScriptTemplate::~CScriptTemplate()
|
||||
{
|
||||
for (u32 iSet = 0; iSet < mPropertySets.size(); iSet++)
|
||||
delete mPropertySets[iSet].pBaseStruct;
|
||||
delete mpBaseStruct;
|
||||
}
|
||||
|
||||
CMasterTemplate* CScriptTemplate::MasterTemplate()
|
||||
@@ -33,41 +33,9 @@ EGame CScriptTemplate::Game()
|
||||
return mpMaster->GetGame();
|
||||
}
|
||||
|
||||
TString CScriptTemplate::TemplateName(s32 propCount) const
|
||||
TString CScriptTemplate::TemplateName() const
|
||||
{
|
||||
// Return original name if there is only one property set
|
||||
// or if caller doesn't want to distinguish between sets
|
||||
if ((NumPropertySets() == 1) || (propCount == -1))
|
||||
return mTemplateName;
|
||||
|
||||
// Otherwise we return the template name with the set name appended
|
||||
for (auto it = mPropertySets.begin(); it != mPropertySets.end(); it++)
|
||||
if (it->pBaseStruct->Count() == propCount)
|
||||
return mTemplateName + " (" + it->SetName + ")";
|
||||
|
||||
return mTemplateName + " (Invalid)";
|
||||
}
|
||||
|
||||
TString CScriptTemplate::PropertySetNameByCount(s32 propCount) const
|
||||
{
|
||||
for (auto it = mPropertySets.begin(); it != mPropertySets.end(); it++)
|
||||
if (it->pBaseStruct->Count() == propCount)
|
||||
return it->SetName;
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
TString CScriptTemplate::PropertySetNameByIndex(u32 index) const
|
||||
{
|
||||
if (index < NumPropertySets())
|
||||
return mPropertySets[index].SetName;
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
||||
u32 CScriptTemplate::NumPropertySets() const
|
||||
{
|
||||
return mPropertySets.size();
|
||||
return mTemplateName;
|
||||
}
|
||||
|
||||
CScriptTemplate::ERotationType CScriptTemplate::RotationType() const
|
||||
@@ -100,10 +68,9 @@ bool CScriptTemplate::IsVisible() const
|
||||
return mVisible;
|
||||
}
|
||||
|
||||
void CScriptTemplate::DebugPrintProperties(int propCount)
|
||||
void CScriptTemplate::DebugPrintProperties()
|
||||
{
|
||||
CStructTemplate *pTemp = BaseStructByCount(propCount);
|
||||
if (pTemp) pTemp->DebugPrintProperties("");
|
||||
mpBaseStruct->DebugPrintProperties("");
|
||||
}
|
||||
|
||||
// ************ PROPERTY FETCHING ************
|
||||
@@ -111,7 +78,7 @@ template<typename t, EPropertyType propType>
|
||||
t TFetchProperty(CPropertyStruct *pProperties, const TIDString& ID)
|
||||
{
|
||||
if (ID.IsEmpty()) return nullptr;
|
||||
CPropertyBase *pProp = pProperties->PropertyByIDString(ID);
|
||||
IProperty *pProp = pProperties->PropertyByIDString(ID);
|
||||
|
||||
if (pProp && (pProp->Type() == propType))
|
||||
return static_cast<t>(pProp);
|
||||
@@ -119,23 +86,9 @@ t TFetchProperty(CPropertyStruct *pProperties, const TIDString& ID)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CStructTemplate* CScriptTemplate::BaseStructByCount(s32 propCount)
|
||||
CStructTemplate* CScriptTemplate::BaseStruct()
|
||||
{
|
||||
if (mPropertySets.size() == 1) return mPropertySets[0].pBaseStruct;
|
||||
|
||||
for (u32 iSet = 0; iSet < mPropertySets.size(); iSet++)
|
||||
if (mPropertySets[iSet].pBaseStruct->Count() == propCount)
|
||||
return mPropertySets[iSet].pBaseStruct;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CStructTemplate* CScriptTemplate::BaseStructByIndex(u32 index)
|
||||
{
|
||||
if (index < NumPropertySets())
|
||||
return mPropertySets[index].pBaseStruct;
|
||||
else
|
||||
return nullptr;
|
||||
return mpBaseStruct;
|
||||
}
|
||||
|
||||
EVolumeShape CScriptTemplate::VolumeShape(CScriptObject *pObj)
|
||||
@@ -177,32 +130,32 @@ s32 CScriptTemplate::CheckVolumeConditions(CScriptObject *pObj, bool LogErrors)
|
||||
// Private function
|
||||
if (mVolumeShape == eConditionalShape)
|
||||
{
|
||||
CPropertyBase *pProp = pObj->Properties()->PropertyByIDString(mVolumeConditionIDString);
|
||||
IProperty *pProp = pObj->Properties()->PropertyByIDString(mVolumeConditionIDString);
|
||||
|
||||
// Get value of the condition test property (only boolean, integral, and enum types supported)
|
||||
int v;
|
||||
switch (pProp->Type())
|
||||
{
|
||||
case eBoolProperty:
|
||||
v = (static_cast<CBoolProperty*>(pProp)->Get() ? 1 : 0);
|
||||
v = (static_cast<TBoolProperty*>(pProp)->Get() ? 1 : 0);
|
||||
break;
|
||||
|
||||
case eByteProperty:
|
||||
v = (int) static_cast<CByteProperty*>(pProp)->Get();
|
||||
v = (int) static_cast<TByteProperty*>(pProp)->Get();
|
||||
break;
|
||||
|
||||
case eShortProperty:
|
||||
v = (int) static_cast<CShortProperty*>(pProp)->Get();
|
||||
v = (int) static_cast<TShortProperty*>(pProp)->Get();
|
||||
break;
|
||||
|
||||
case eLongProperty:
|
||||
v = (int) static_cast<CLongProperty*>(pProp)->Get();
|
||||
v = (int) static_cast<TLongProperty*>(pProp)->Get();
|
||||
break;
|
||||
|
||||
case eEnumProperty: {
|
||||
CEnumProperty *pEnumCast = static_cast<CEnumProperty*>(pProp);
|
||||
TEnumProperty *pEnumCast = static_cast<TEnumProperty*>(pProp);
|
||||
CEnumTemplate *pEnumTemp = static_cast<CEnumTemplate*>(pEnumCast->Template());
|
||||
int index = static_cast<CEnumProperty*>(pProp)->Get();
|
||||
int index = static_cast<TEnumProperty*>(pProp)->Get();
|
||||
v = pEnumTemp->EnumeratorID(index);
|
||||
break;
|
||||
}
|
||||
@@ -222,29 +175,29 @@ s32 CScriptTemplate::CheckVolumeConditions(CScriptObject *pObj, bool LogErrors)
|
||||
return -1;
|
||||
}
|
||||
|
||||
CStringProperty* CScriptTemplate::FindInstanceName(CPropertyStruct *pProperties)
|
||||
TStringProperty* CScriptTemplate::FindInstanceName(CPropertyStruct *pProperties)
|
||||
{
|
||||
return TFetchProperty<CStringProperty*, eStringProperty>(pProperties, mNameIDString);
|
||||
return TFetchProperty<TStringProperty*, eStringProperty>(pProperties, mNameIDString);
|
||||
}
|
||||
|
||||
CVector3Property* CScriptTemplate::FindPosition(CPropertyStruct *pProperties)
|
||||
TVector3Property* CScriptTemplate::FindPosition(CPropertyStruct *pProperties)
|
||||
{
|
||||
return TFetchProperty<CVector3Property*, eVector3Property>(pProperties, mPositionIDString);
|
||||
return TFetchProperty<TVector3Property*, eVector3Property>(pProperties, mPositionIDString);
|
||||
}
|
||||
|
||||
CVector3Property* CScriptTemplate::FindRotation(CPropertyStruct *pProperties)
|
||||
TVector3Property* CScriptTemplate::FindRotation(CPropertyStruct *pProperties)
|
||||
{
|
||||
return TFetchProperty<CVector3Property*, eVector3Property>(pProperties, mRotationIDString);
|
||||
return TFetchProperty<TVector3Property*, eVector3Property>(pProperties, mRotationIDString);
|
||||
}
|
||||
|
||||
CVector3Property* CScriptTemplate::FindScale(CPropertyStruct *pProperties)
|
||||
TVector3Property* CScriptTemplate::FindScale(CPropertyStruct *pProperties)
|
||||
{
|
||||
return TFetchProperty<CVector3Property*, eVector3Property>(pProperties, mScaleIDString);
|
||||
return TFetchProperty<TVector3Property*, eVector3Property>(pProperties, mScaleIDString);
|
||||
}
|
||||
|
||||
CBoolProperty* CScriptTemplate::FindActive(CPropertyStruct *pProperties)
|
||||
TBoolProperty* CScriptTemplate::FindActive(CPropertyStruct *pProperties)
|
||||
{
|
||||
return TFetchProperty<CBoolProperty*, eBoolProperty>(pProperties, mActiveIDString);
|
||||
return TFetchProperty<TBoolProperty*, eBoolProperty>(pProperties, mActiveIDString);
|
||||
}
|
||||
|
||||
CPropertyStruct* CScriptTemplate::FindLightParameters(CPropertyStruct *pProperties)
|
||||
@@ -270,17 +223,17 @@ CModel* CScriptTemplate::FindDisplayModel(CPropertyStruct *pProperties)
|
||||
// Property
|
||||
else
|
||||
{
|
||||
CPropertyBase *pProp = pProperties->PropertyByIDString(it->AssetLocation);
|
||||
IProperty *pProp = pProperties->PropertyByIDString(it->AssetLocation);
|
||||
|
||||
if (pProp->Type() == eFileProperty)
|
||||
{
|
||||
CFileProperty *pFile = static_cast<CFileProperty*>(pProp);
|
||||
TFileProperty *pFile = static_cast<TFileProperty*>(pProp);
|
||||
pRes = pFile->Get();
|
||||
}
|
||||
|
||||
else if (pProp->Type() == eAnimParamsProperty)
|
||||
else if (pProp->Type() == eCharacterProperty)
|
||||
{
|
||||
CAnimParamsProperty *pParams = static_cast<CAnimParamsProperty*>(pProp);
|
||||
TAnimParamsProperty *pParams = static_cast<TAnimParamsProperty*>(pProp);
|
||||
pRes = pParams->Get().GetCurrentModel(it->ForceNodeIndex);
|
||||
}
|
||||
}
|
||||
@@ -310,11 +263,11 @@ CTexture* CScriptTemplate::FindBillboardTexture(CPropertyStruct *pProperties)
|
||||
// Property
|
||||
else
|
||||
{
|
||||
CPropertyBase *pProp = pProperties->PropertyByIDString(it->AssetLocation);
|
||||
IProperty *pProp = pProperties->PropertyByIDString(it->AssetLocation);
|
||||
|
||||
if (pProp->Type() == eFileProperty)
|
||||
{
|
||||
CFileProperty *pFile = static_cast<CFileProperty*>(pProp);
|
||||
TFileProperty *pFile = static_cast<TFileProperty*>(pProp);
|
||||
pRes = pFile->Get();
|
||||
}
|
||||
}
|
||||
@@ -344,11 +297,11 @@ CCollisionMeshGroup* CScriptTemplate::FindCollision(CPropertyStruct *pProperties
|
||||
// Property
|
||||
else
|
||||
{
|
||||
CPropertyBase *pProp = pProperties->PropertyByIDString(it->AssetLocation);
|
||||
IProperty *pProp = pProperties->PropertyByIDString(it->AssetLocation);
|
||||
|
||||
if (pProp->Type() == eFileProperty)
|
||||
{
|
||||
CFileProperty *pFile = static_cast<CFileProperty*>(pProp);
|
||||
TFileProperty *pFile = static_cast<TFileProperty*>(pProp);
|
||||
pRes = pFile->Get();
|
||||
}
|
||||
}
|
||||
@@ -369,17 +322,17 @@ bool CScriptTemplate::HasInGameModel(CPropertyStruct *pProperties)
|
||||
if (it->AssetSource == SEditorAsset::eFile) continue;
|
||||
CResource *pRes = nullptr;
|
||||
|
||||
CPropertyBase *pProp = pProperties->PropertyByIDString(it->AssetLocation);
|
||||
IProperty *pProp = pProperties->PropertyByIDString(it->AssetLocation);
|
||||
|
||||
if (pProp->Type() == eFileProperty)
|
||||
{
|
||||
CFileProperty *pFile = static_cast<CFileProperty*>(pProp);
|
||||
TFileProperty *pFile = static_cast<TFileProperty*>(pProp);
|
||||
pRes = pFile->Get();
|
||||
}
|
||||
|
||||
else if (pProp->Type() == eAnimParamsProperty)
|
||||
else if (pProp->Type() == eCharacterProperty)
|
||||
{
|
||||
CAnimParamsProperty *pParams = static_cast<CAnimParamsProperty*>(pProp);
|
||||
TAnimParamsProperty *pParams = static_cast<TAnimParamsProperty*>(pProp);
|
||||
pRes = pParams->Get().GetCurrentModel(it->ForceNodeIndex);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#ifndef CSCRIPTTEMPLATE_H
|
||||
#define CSCRIPTTEMPLATE_H
|
||||
|
||||
#include "CPropertyTemplate.h"
|
||||
#include "CProperty.h"
|
||||
#include "IPropertyTemplate.h"
|
||||
#include "IProperty.h"
|
||||
#include "EPropertyType.h"
|
||||
#include "EVolumeShape.h"
|
||||
#include "Core/Resource/Model/CModel.h"
|
||||
@@ -39,11 +39,6 @@ public:
|
||||
};
|
||||
|
||||
private:
|
||||
struct SPropertySet {
|
||||
TString SetName;
|
||||
CStructTemplate *pBaseStruct;
|
||||
};
|
||||
|
||||
struct SEditorAsset
|
||||
{
|
||||
enum {
|
||||
@@ -59,7 +54,7 @@ private:
|
||||
};
|
||||
|
||||
CMasterTemplate *mpMaster;
|
||||
std::vector<SPropertySet> mPropertySets;
|
||||
CStructTemplate *mpBaseStruct;
|
||||
std::list<CScriptObject*> mObjectList;
|
||||
TString mTemplateName;
|
||||
TString mSourceFile;
|
||||
@@ -75,9 +70,9 @@ private:
|
||||
TIDString mLightParametersIDString;
|
||||
std::vector<SEditorAsset> mAssets;
|
||||
|
||||
float mPreviewScale;
|
||||
ERotationType mRotationType;
|
||||
EScaleType mScaleType;
|
||||
float mPreviewScale;
|
||||
|
||||
// Preview Volume
|
||||
EVolumeShape mVolumeShape;
|
||||
@@ -97,9 +92,7 @@ public:
|
||||
|
||||
CMasterTemplate* MasterTemplate();
|
||||
EGame Game();
|
||||
TString TemplateName(s32 propCount = -1) const;
|
||||
TString PropertySetNameByCount(s32 propCount) const;
|
||||
TString PropertySetNameByIndex(u32 index) const;
|
||||
TString TemplateName() const;
|
||||
u32 NumPropertySets() const;
|
||||
ERotationType RotationType() const;
|
||||
EScaleType ScaleType() const;
|
||||
@@ -107,18 +100,17 @@ public:
|
||||
u32 ObjectID() const;
|
||||
void SetVisible(bool visible);
|
||||
bool IsVisible() const;
|
||||
void DebugPrintProperties(int propCount = -1);
|
||||
void DebugPrintProperties();
|
||||
|
||||
// Property Fetching
|
||||
CStructTemplate* BaseStructByCount(s32 propCount);
|
||||
CStructTemplate* BaseStructByIndex(u32 index);
|
||||
CStructTemplate* BaseStruct();
|
||||
EVolumeShape VolumeShape(CScriptObject *pObj);
|
||||
float VolumeScale(CScriptObject *pObj);
|
||||
CStringProperty* FindInstanceName(CPropertyStruct *pProperties);
|
||||
CVector3Property* FindPosition(CPropertyStruct *pProperties);
|
||||
CVector3Property* FindRotation(CPropertyStruct *pProperties);
|
||||
CVector3Property* FindScale(CPropertyStruct *pProperties);
|
||||
CBoolProperty* FindActive(CPropertyStruct *pProperties);
|
||||
TStringProperty* FindInstanceName(CPropertyStruct *pProperties);
|
||||
TVector3Property* FindPosition(CPropertyStruct *pProperties);
|
||||
TVector3Property* FindRotation(CPropertyStruct *pProperties);
|
||||
TVector3Property* FindScale(CPropertyStruct *pProperties);
|
||||
TBoolProperty* FindActive(CPropertyStruct *pProperties);
|
||||
CPropertyStruct* FindLightParameters(CPropertyStruct *pProperties);
|
||||
CModel* FindDisplayModel(CPropertyStruct *pProperties);
|
||||
CTexture* FindBillboardTexture(CPropertyStruct *pProperties);
|
||||
|
||||
@@ -18,7 +18,7 @@ enum EPropertyType
|
||||
eFileProperty,
|
||||
eStructProperty,
|
||||
eArrayProperty,
|
||||
eAnimParamsProperty,
|
||||
eCharacterProperty,
|
||||
eUnknownProperty,
|
||||
eInvalidProperty
|
||||
};
|
||||
|
||||
126
src/Core/Resource/Script/IProperty.cpp
Normal file
126
src/Core/Resource/Script/IProperty.cpp
Normal file
@@ -0,0 +1,126 @@
|
||||
#include "IProperty.h"
|
||||
#include "IPropertyTemplate.h"
|
||||
|
||||
// ************ IProperty ************
|
||||
IPropertyTemplate* IProperty::Template()
|
||||
{
|
||||
return mpTemplate;
|
||||
}
|
||||
|
||||
TString IProperty::Name()
|
||||
{
|
||||
return mpTemplate->Name();
|
||||
}
|
||||
|
||||
u32 IProperty::ID()
|
||||
{
|
||||
return mpTemplate->PropertyID();
|
||||
}
|
||||
|
||||
// ************ CPropertyStruct ************
|
||||
CPropertyStruct::~CPropertyStruct()
|
||||
{
|
||||
for (auto it = mProperties.begin(); it != mProperties.end(); it++)
|
||||
delete *it;
|
||||
}
|
||||
|
||||
IProperty* CPropertyStruct::PropertyByIndex(u32 index)
|
||||
{
|
||||
return mProperties[index];
|
||||
}
|
||||
|
||||
IProperty* CPropertyStruct::PropertyByID(u32 ID)
|
||||
{
|
||||
for (auto it = mProperties.begin(); it != mProperties.end(); it++)
|
||||
{
|
||||
if ((*it)->ID() == ID)
|
||||
return *it;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
IProperty* CPropertyStruct::PropertyByIDString(const TIDString& rkStr)
|
||||
{
|
||||
// Resolve namespace
|
||||
u32 NSStart = rkStr.IndexOf(":");
|
||||
|
||||
// String has namespace; the requested property is within a struct
|
||||
if (NSStart != -1)
|
||||
{
|
||||
TString StrStructID = rkStr.Truncate(NSStart);
|
||||
if (!StrStructID.IsHexString()) return nullptr;
|
||||
|
||||
u32 StructID = StrStructID.ToInt32();
|
||||
TString PropName = rkStr.ChopFront(NSStart + 1);
|
||||
|
||||
CPropertyStruct *pStruct = StructByID(StructID);
|
||||
if (!pStruct) return nullptr;
|
||||
else return pStruct->PropertyByIDString(PropName);
|
||||
}
|
||||
|
||||
// No namespace; fetch the property from this struct
|
||||
else
|
||||
{
|
||||
if (rkStr.IsHexString())
|
||||
return PropertyByID(rkStr.ToInt32());
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
CPropertyStruct* CPropertyStruct::StructByIndex(u32 index)
|
||||
{
|
||||
IProperty *pProp = PropertyByIndex(index);
|
||||
|
||||
if (pProp->Type() == eStructProperty)
|
||||
return static_cast<CPropertyStruct*>(pProp);
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CPropertyStruct* CPropertyStruct::StructByID(u32 ID)
|
||||
{
|
||||
IProperty *pProp = PropertyByID(ID);
|
||||
|
||||
if (pProp->Type() == eStructProperty)
|
||||
return static_cast<CPropertyStruct*>(pProp);
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CPropertyStruct* CPropertyStruct::StructByIDString(const TIDString& rkStr)
|
||||
{
|
||||
IProperty *pProp = PropertyByIDString(rkStr);
|
||||
|
||||
if (pProp->Type() == eStructProperty)
|
||||
return static_cast<CPropertyStruct*>(pProp);
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// ************ CArrayProperty ************
|
||||
void CArrayProperty::Resize(u32 Size)
|
||||
{
|
||||
u32 OldSize = mSubStructs.size();
|
||||
if (OldSize == Size) return;
|
||||
|
||||
if (Size < OldSize)
|
||||
{
|
||||
for (u32 i = mSubStructs.size() - 1; i >= Size; i--)
|
||||
delete mSubStructs[i];
|
||||
}
|
||||
|
||||
mSubStructs.resize(Size);
|
||||
|
||||
if (Size > OldSize)
|
||||
{
|
||||
for (u32 i = OldSize; i < Size; i++)
|
||||
mSubStructs[i] = static_cast<CArrayTemplate*>(mpTemplate)->CreateSubStruct();
|
||||
}
|
||||
}
|
||||
|
||||
CStructTemplate* CArrayProperty::SubStructTemplate()
|
||||
{
|
||||
// CArrayTemplate inherits from CStructTemplate. It defines the substruct structure.
|
||||
return static_cast<CStructTemplate*>(Template());
|
||||
}
|
||||
129
src/Core/Resource/Script/IProperty.h
Normal file
129
src/Core/Resource/Script/IProperty.h
Normal file
@@ -0,0 +1,129 @@
|
||||
#ifndef IPROPERTY
|
||||
#define IPROPERTY
|
||||
|
||||
/* This header file declares some classes used to track script object properties
|
||||
* IProperty, TTypedProperty (and typedefs), CPropertyStruct, and CArrayProperty */
|
||||
#include "EPropertyType.h"
|
||||
#include "IPropertyValue.h"
|
||||
#include "Core/Resource/CResource.h"
|
||||
#include "Core/Resource/TResPtr.h"
|
||||
#include "Core/Resource/CAnimationParameters.h"
|
||||
#include <Common/CColor.h>
|
||||
#include <Common/TString.h>
|
||||
#include <Math/CVector3f.h>
|
||||
#include <list>
|
||||
|
||||
class CScriptTemplate;
|
||||
class CStructTemplate;
|
||||
class IPropertyTemplate;
|
||||
typedef TString TIDString;
|
||||
|
||||
/*
|
||||
* IProperty is the base class, containing just some virtual function definitions
|
||||
* Virtual destructor is mainly there to make cleanup easy; don't need to cast to delete
|
||||
*/
|
||||
class IProperty
|
||||
{
|
||||
friend class CScriptLoader;
|
||||
protected:
|
||||
IPropertyTemplate *mpTemplate;
|
||||
public:
|
||||
IProperty(IPropertyTemplate *pTemp) : mpTemplate(pTemp) {}
|
||||
virtual ~IProperty() {}
|
||||
virtual EPropertyType Type() = 0;
|
||||
|
||||
IPropertyTemplate* Template();
|
||||
TString Name();
|
||||
u32 ID();
|
||||
};
|
||||
|
||||
/*
|
||||
* __CProperty is a template subclass for actual properties.
|
||||
*/
|
||||
template <typename PropType, EPropertyType TypeEnum, class ValueClass>
|
||||
class TTypedProperty : public IProperty
|
||||
{
|
||||
friend class CScriptLoader;
|
||||
ValueClass mValue;
|
||||
public:
|
||||
TTypedProperty(IPropertyTemplate *pTemp)
|
||||
: IProperty(pTemp) {}
|
||||
|
||||
TTypedProperty(IPropertyTemplate *pTemp, PropType v)
|
||||
: IProperty(pTemp), mValue(v) {}
|
||||
|
||||
~TTypedProperty() {}
|
||||
inline EPropertyType Type() { return TypeEnum; }
|
||||
inline PropType Get() { return mValue.Get(); }
|
||||
inline void Set(PropType v) { mValue.Set(v); }
|
||||
};
|
||||
typedef TTypedProperty<bool, eBoolProperty, CBoolValue> TBoolProperty;
|
||||
typedef TTypedProperty<char, eByteProperty, CByteValue> TByteProperty;
|
||||
typedef TTypedProperty<short, eShortProperty, CShortValue> TShortProperty;
|
||||
typedef TTypedProperty<long, eLongProperty, CLongValue> TLongProperty;
|
||||
typedef TTypedProperty<long, eEnumProperty, CLongValue> TEnumProperty;
|
||||
typedef TTypedProperty<long, eBitfieldProperty, CLongValue> TBitfieldProperty;
|
||||
typedef TTypedProperty<float, eFloatProperty, CFloatValue> TFloatProperty;
|
||||
typedef TTypedProperty<TString, eStringProperty, CStringValue> TStringProperty;
|
||||
typedef TTypedProperty<CVector3f, eVector3Property, CVector3Value> TVector3Property;
|
||||
typedef TTypedProperty<CColor, eColorProperty, CColorValue> TColorProperty;
|
||||
typedef TTypedProperty<TResPtr<CResource>, eFileProperty, CFileValue> TFileProperty;
|
||||
typedef TTypedProperty<CAnimationParameters, eCharacterProperty, CCharacterValue> TAnimParamsProperty;
|
||||
typedef TTypedProperty<std::vector<u8>, eUnknownProperty, CUnknownValue> TUnknownProperty;
|
||||
|
||||
/*
|
||||
* CPropertyStruct is for defining structs of properties.
|
||||
*/
|
||||
class CPropertyStruct : public IProperty
|
||||
{
|
||||
friend class CScriptLoader;
|
||||
std::vector<IProperty*> mProperties;
|
||||
public:
|
||||
CPropertyStruct(IPropertyTemplate *pTemp)
|
||||
: IProperty(pTemp) {}
|
||||
|
||||
~CPropertyStruct();
|
||||
|
||||
EPropertyType Type() { return eStructProperty; }
|
||||
|
||||
// Inline
|
||||
inline u32 Count() { return mProperties.size(); }
|
||||
inline void AddSubProperty(IProperty *pProp) { mProperties.push_back(pProp); }
|
||||
inline IProperty* operator[](u32 index) { return mProperties[index]; }
|
||||
|
||||
// Functions
|
||||
IProperty* PropertyByIndex(u32 index);
|
||||
IProperty* PropertyByID(u32 ID);
|
||||
IProperty* PropertyByIDString(const TIDString& rkStr);
|
||||
CPropertyStruct* StructByIndex(u32 index);
|
||||
CPropertyStruct* StructByID(u32 ID);
|
||||
CPropertyStruct* StructByIDString(const TIDString& rkStr);
|
||||
};
|
||||
|
||||
/*
|
||||
* CArrayProperty stores a repeated property struct.
|
||||
*/
|
||||
class CArrayProperty : public IProperty
|
||||
{
|
||||
friend class CScriptLoader;
|
||||
std::vector<CPropertyStruct*> mSubStructs;
|
||||
|
||||
public:
|
||||
CArrayProperty(IPropertyTemplate *pTemp)
|
||||
: IProperty(pTemp) {}
|
||||
|
||||
EPropertyType Type() { return eArrayProperty; }
|
||||
|
||||
// Inline
|
||||
inline u32 Count() { return mSubStructs.size(); }
|
||||
inline void Reserve(u32 amount) { mSubStructs.reserve(amount); }
|
||||
inline CPropertyStruct* ElementByIndex(u32 index) { return mSubStructs[index]; }
|
||||
inline CPropertyStruct* operator[](u32 index) { return ElementByIndex(index); }
|
||||
|
||||
// Functions
|
||||
void Resize(u32 Size);
|
||||
CStructTemplate* SubStructTemplate();
|
||||
};
|
||||
|
||||
#endif // IPROPERTY
|
||||
|
||||
224
src/Core/Resource/Script/IPropertyTemplate.cpp
Normal file
224
src/Core/Resource/Script/IPropertyTemplate.cpp
Normal file
@@ -0,0 +1,224 @@
|
||||
#include "IPropertyTemplate.h"
|
||||
#include <iostream>
|
||||
|
||||
// ************ IPropertyTemplate ************
|
||||
bool IPropertyTemplate::IsInVersion(u32 Version) const
|
||||
{
|
||||
if (mAllowedVersions.empty())
|
||||
return true;
|
||||
|
||||
for (u32 iVer = 0; iVer < mAllowedVersions.size(); iVer++)
|
||||
if (mAllowedVersions[iVer] == Version)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
TIDString IPropertyTemplate::IDString(bool FullPath) const
|
||||
{
|
||||
TIDString out;
|
||||
if (mpParent && FullPath) out = mpParent->IDString(true) + ":";
|
||||
out += TIDString::HexString(mID, true, true, 8);
|
||||
return out;
|
||||
}
|
||||
|
||||
CStructTemplate* IPropertyTemplate::RootStruct()
|
||||
{
|
||||
if (mpParent) return mpParent->RootStruct();
|
||||
else if (Type() == eStructProperty) return static_cast<CStructTemplate*>(this);
|
||||
else return nullptr;
|
||||
}
|
||||
|
||||
// ************ CStructTemplate ************
|
||||
bool CStructTemplate::IsSingleProperty() const
|
||||
{
|
||||
return mIsSingleProperty;
|
||||
}
|
||||
|
||||
u32 CStructTemplate::Count() const
|
||||
{
|
||||
return mSubProperties.size();
|
||||
}
|
||||
|
||||
u32 CStructTemplate::NumVersions()
|
||||
{
|
||||
return mVersionPropertyCounts.size();
|
||||
}
|
||||
|
||||
u32 CStructTemplate::PropertyCountForVersion(u32 Version)
|
||||
{
|
||||
if (Version == -1) Version = 0;
|
||||
return mVersionPropertyCounts[Version];
|
||||
}
|
||||
|
||||
u32 CStructTemplate::VersionForPropertyCount(u32 PropCount)
|
||||
{
|
||||
for (u32 iVer = 0; iVer < NumVersions(); iVer++)
|
||||
if (mVersionPropertyCounts[iVer] == PropCount)
|
||||
return iVer;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
IPropertyTemplate* CStructTemplate::PropertyByIndex(u32 index)
|
||||
{
|
||||
if (mSubProperties.size() > index)
|
||||
return mSubProperties[index];
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
IPropertyTemplate* CStructTemplate::PropertyByID(u32 ID)
|
||||
{
|
||||
for (auto it = mSubProperties.begin(); it != mSubProperties.end(); it++)
|
||||
{
|
||||
if ((*it)->PropertyID() == ID)
|
||||
return *it;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
IPropertyTemplate* CStructTemplate::PropertyByIDString(const TIDString& str)
|
||||
{
|
||||
// Resolve namespace
|
||||
u32 nsStart = str.IndexOf(":");
|
||||
u32 propStart = nsStart + 1;
|
||||
|
||||
// String has namespace; the requested property is within a struct
|
||||
if (nsStart != -1)
|
||||
{
|
||||
TString strStructID = str.SubString(0, nsStart);
|
||||
if (!strStructID.IsHexString()) return nullptr;
|
||||
|
||||
u32 structID = strStructID.ToInt32();
|
||||
TString propName = str.SubString(propStart, str.Length() - propStart);
|
||||
|
||||
CStructTemplate *pStruct = StructByID(structID);
|
||||
if (!pStruct) return nullptr;
|
||||
else return pStruct->PropertyByIDString(propName);
|
||||
}
|
||||
|
||||
// No namespace; fetch the property from this struct
|
||||
else
|
||||
{
|
||||
// ID string lookup
|
||||
if (str.IsHexString())
|
||||
return PropertyByID(str.ToInt32());
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
CStructTemplate* CStructTemplate::StructByIndex(u32 index)
|
||||
{
|
||||
IPropertyTemplate *pProp = PropertyByIndex(index);
|
||||
|
||||
if (pProp->Type() == eStructProperty)
|
||||
return static_cast<CStructTemplate*>(pProp);
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CStructTemplate* CStructTemplate::StructByID(u32 ID)
|
||||
{
|
||||
IPropertyTemplate *pProp = PropertyByID(ID);
|
||||
|
||||
if (pProp && pProp->Type() == eStructProperty)
|
||||
return static_cast<CStructTemplate*>(pProp);
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CStructTemplate* CStructTemplate::StructByIDString(const TString& str)
|
||||
{
|
||||
IPropertyTemplate *pProp = PropertyByIDString(str);
|
||||
|
||||
if (pProp && pProp->Type() == eStructProperty)
|
||||
return static_cast<CStructTemplate*>(pProp);
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool CStructTemplate::HasProperty(const TIDString& rkIdString)
|
||||
{
|
||||
IPropertyTemplate *pProperty = PropertyByIDString(rkIdString);
|
||||
return (pProperty != nullptr);
|
||||
}
|
||||
|
||||
void CStructTemplate::DetermineVersionPropertyCounts()
|
||||
{
|
||||
for (u32 iVer = 0; iVer < mVersionPropertyCounts.size(); iVer++)
|
||||
{
|
||||
mVersionPropertyCounts[iVer] = 0;
|
||||
|
||||
for (u32 iProp = 0; iProp < mSubProperties.size(); iProp++)
|
||||
{
|
||||
if (mSubProperties[iProp]->IsInVersion(iVer) && mSubProperties[iProp]->CookPreference() != eNeverCook)
|
||||
mVersionPropertyCounts[iVer]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ************ GLOBAL FUNCTIONS ************
|
||||
TString PropEnumToPropString(EPropertyType prop)
|
||||
{
|
||||
switch (prop)
|
||||
{
|
||||
case eBoolProperty: return "bool";
|
||||
case eByteProperty: return "byte";
|
||||
case eShortProperty: return "short";
|
||||
case eLongProperty: return "long";
|
||||
case eEnumProperty: return "enum";
|
||||
case eBitfieldProperty: return "bitfield";
|
||||
case eFloatProperty: return "float";
|
||||
case eStringProperty: return "string";
|
||||
case eColorProperty: return "color";
|
||||
case eVector3Property: return "vector3f";
|
||||
case eFileProperty: return "file";
|
||||
case eStructProperty: return "struct";
|
||||
case eArrayProperty: return "array";
|
||||
case eCharacterProperty: return "character";
|
||||
case eUnknownProperty: return "unknown";
|
||||
|
||||
case eInvalidProperty:
|
||||
default:
|
||||
return "invalid";
|
||||
}
|
||||
}
|
||||
|
||||
EPropertyType PropStringToPropEnum(const TString& rkProp)
|
||||
{
|
||||
if (rkProp == "bool") return eBoolProperty;
|
||||
if (rkProp == "byte") return eByteProperty;
|
||||
if (rkProp == "short") return eShortProperty;
|
||||
if (rkProp == "long") return eLongProperty;
|
||||
if (rkProp == "enum") return eEnumProperty;
|
||||
if (rkProp == "bitfield") return eBitfieldProperty;
|
||||
if (rkProp == "float") return eFloatProperty;
|
||||
if (rkProp == "string") return eStringProperty;
|
||||
if (rkProp == "color") return eColorProperty;
|
||||
if (rkProp == "vector3f") return eVector3Property;
|
||||
if (rkProp == "file") return eFileProperty;
|
||||
if (rkProp == "struct") return eStructProperty;
|
||||
if (rkProp == "array") return eArrayProperty;
|
||||
if (rkProp == "character") return eCharacterProperty;
|
||||
if (rkProp == "unknown") return eUnknownProperty;
|
||||
return eInvalidProperty;
|
||||
}
|
||||
|
||||
// ************ DEBUG ************
|
||||
void CStructTemplate::DebugPrintProperties(TString base)
|
||||
{
|
||||
base = base + Name() + "::";
|
||||
for (auto it = mSubProperties.begin(); it != mSubProperties.end(); it++)
|
||||
{
|
||||
IPropertyTemplate *tmp = *it;
|
||||
if (tmp->Type() == eStructProperty)
|
||||
{
|
||||
CStructTemplate *tmp2 = static_cast<CStructTemplate*>(tmp);
|
||||
tmp2->DebugPrintProperties(base);
|
||||
}
|
||||
else
|
||||
std::cout << base << tmp->Name() << "\n";
|
||||
}
|
||||
}
|
||||
517
src/Core/Resource/Script/IPropertyTemplate.h
Normal file
517
src/Core/Resource/Script/IPropertyTemplate.h
Normal file
@@ -0,0 +1,517 @@
|
||||
#ifndef IPROPERTYTEMPLATE
|
||||
#define IPROPERTYTEMPLATE
|
||||
|
||||
#include "EPropertyType.h"
|
||||
#include "IProperty.h"
|
||||
#include "IPropertyValue.h"
|
||||
#include "Core/Resource/CAnimationParameters.h"
|
||||
#include <Common/CColor.h>
|
||||
#include <Common/TString.h>
|
||||
#include <Common/types.h>
|
||||
#include <Math/CVector3f.h>
|
||||
#include <vector>
|
||||
|
||||
typedef TString TIDString;
|
||||
class CStructTemplate;
|
||||
class IProperty;
|
||||
|
||||
enum ECookPreference
|
||||
{
|
||||
eNoCookPreference,
|
||||
eAlwaysCook,
|
||||
eNeverCook
|
||||
};
|
||||
|
||||
// IPropertyTemplate - Base class. Contains basic info that every property has,
|
||||
// plus virtual functions for determining more specific property type.
|
||||
class IPropertyTemplate
|
||||
{
|
||||
friend class CTemplateLoader;
|
||||
friend class CTemplateWriter;
|
||||
|
||||
protected:
|
||||
CStructTemplate *mpParent;
|
||||
TString mName;
|
||||
u32 mID;
|
||||
ECookPreference mCookPreference;
|
||||
std::vector<u32> mAllowedVersions;
|
||||
|
||||
public:
|
||||
IPropertyTemplate(u32 ID, CStructTemplate *pParent = 0)
|
||||
: mID(ID)
|
||||
, mpParent(pParent)
|
||||
, mName("Unknown")
|
||||
, mCookPreference(eNoCookPreference)
|
||||
{
|
||||
}
|
||||
|
||||
IPropertyTemplate(u32 ID, const TString& rkName, ECookPreference CookPreference, CStructTemplate *pParent = 0)
|
||||
: mID(ID)
|
||||
, mpParent(pParent)
|
||||
, mName(rkName)
|
||||
, mCookPreference(CookPreference)
|
||||
{
|
||||
}
|
||||
|
||||
virtual EPropertyType Type() const = 0;
|
||||
virtual bool CanHaveDefault() const = 0;
|
||||
virtual bool IsNumerical() const = 0;
|
||||
|
||||
virtual bool HasValidRange() const { return false; }
|
||||
virtual TString DefaultToString() { return ""; }
|
||||
virtual TString RangeToString() { return ""; }
|
||||
|
||||
virtual void SetParam(const TString& rkParamName, const TString& rkValue)
|
||||
{
|
||||
if (rkParamName == "should_cook")
|
||||
{
|
||||
if (rkValue == "always")
|
||||
mCookPreference = eAlwaysCook;
|
||||
else if (rkValue == "never")
|
||||
mCookPreference = eNeverCook;
|
||||
else
|
||||
mCookPreference = eNoCookPreference;
|
||||
}
|
||||
}
|
||||
|
||||
virtual IProperty* InstantiateProperty() = 0;
|
||||
|
||||
inline TString Name() const
|
||||
{
|
||||
return mName;
|
||||
}
|
||||
|
||||
inline u32 PropertyID() const
|
||||
{
|
||||
return mID;
|
||||
}
|
||||
|
||||
inline ECookPreference CookPreference() const
|
||||
{
|
||||
return mCookPreference;
|
||||
}
|
||||
|
||||
inline void SetName(const TString& Name)
|
||||
{
|
||||
mName = Name;
|
||||
}
|
||||
|
||||
inline CStructTemplate* Parent() const
|
||||
{
|
||||
return mpParent;
|
||||
}
|
||||
|
||||
bool IsInVersion(u32 Version) const;
|
||||
TIDString IDString(bool FullPath) const;
|
||||
CStructTemplate* RootStruct();
|
||||
};
|
||||
|
||||
// TTypedPropertyTemplate - Template property class that allows for tracking
|
||||
// a default value. Typedefs are set up for a bunch of property types.
|
||||
template<typename PropType, EPropertyType PropTypeEnum, class ValueClass>
|
||||
class TTypedPropertyTemplate : public IPropertyTemplate
|
||||
{
|
||||
friend class CTemplateLoader;
|
||||
friend class CTemplateWriter;
|
||||
|
||||
protected:
|
||||
ValueClass mDefaultValue;
|
||||
|
||||
public:
|
||||
TTypedPropertyTemplate(u32 ID, CStructTemplate *pParent = 0)
|
||||
: IPropertyTemplate(ID, pParent) {}
|
||||
|
||||
TTypedPropertyTemplate(u32 ID, const TString& rkName, ECookPreference CookPreference, CStructTemplate *pParent = 0)
|
||||
: IPropertyTemplate(ID, rkName, CookPreference, pParent) {}
|
||||
|
||||
virtual EPropertyType Type() const { return PropTypeEnum; }
|
||||
virtual bool CanHaveDefault() const { return true; }
|
||||
virtual bool IsNumerical() const { return false; }
|
||||
|
||||
virtual TString DefaultToString()
|
||||
{
|
||||
return mDefaultValue.ToString();
|
||||
}
|
||||
|
||||
virtual void SetParam(const TString& rkParamName, const TString& rkValue)
|
||||
{
|
||||
IPropertyTemplate::SetParam(rkParamName, rkValue);
|
||||
|
||||
if (rkParamName == "default")
|
||||
mDefaultValue.FromString(rkValue);
|
||||
}
|
||||
|
||||
virtual IProperty* InstantiateProperty()
|
||||
{
|
||||
typedef TTypedProperty<PropType, PropTypeEnum, ValueClass> TPropertyType;
|
||||
|
||||
TPropertyType *pOut = new TPropertyType(this);
|
||||
pOut->Set(GetDefaultValue());
|
||||
return pOut;
|
||||
}
|
||||
|
||||
inline PropType GetDefaultValue() const
|
||||
{
|
||||
return mDefaultValue.Get();
|
||||
}
|
||||
|
||||
inline void SetDefaultValue(const PropType& rkIn)
|
||||
{
|
||||
mDefaultValue.Set(rkIn);
|
||||
}
|
||||
};
|
||||
|
||||
// TNumericalPropertyTemplate - Subclass of TTypedPropertyTemplate for numerical
|
||||
// property types, and allows a min/max value to be tracked.
|
||||
template<typename PropType, EPropertyType PropTypeEnum, class ValueClass>
|
||||
class TNumericalPropertyTemplate : public TTypedPropertyTemplate<PropType,PropTypeEnum,ValueClass>
|
||||
{
|
||||
friend class CTemplateLoader;
|
||||
friend class CTemplateWriter;
|
||||
|
||||
ValueClass mMin;
|
||||
ValueClass mMax;
|
||||
|
||||
public:
|
||||
TNumericalPropertyTemplate(u32 ID, CStructTemplate *pParent = 0)
|
||||
: TTypedPropertyTemplate(ID, pParent)
|
||||
{}
|
||||
|
||||
TNumericalPropertyTemplate(u32 ID, const TString& rkName, ECookPreference CookPreference, CStructTemplate *pParent = 0)
|
||||
: TTypedPropertyTemplate(ID, rkName, CookPreference, pParent)
|
||||
, mMin(0)
|
||||
, mMax(0)
|
||||
{}
|
||||
|
||||
virtual bool IsNumerical() const { return true; }
|
||||
|
||||
virtual bool HasValidRange() const
|
||||
{
|
||||
return (mMin != 0 || mMax != 0);
|
||||
}
|
||||
|
||||
virtual TString RangeToString() const
|
||||
{
|
||||
return mMin.ToString() + "," + mMax.ToString();
|
||||
}
|
||||
|
||||
virtual void SetParam(const TString& rkParamName, const TString& rkValue)
|
||||
{
|
||||
TTypedPropertyTemplate<PropType,PropTypeEnum,ValueClass>::SetParam(rkParamName, rkValue);
|
||||
|
||||
if (rkParamName == "range")
|
||||
{
|
||||
TStringList Components = rkValue.Split(", ");
|
||||
|
||||
if (Components.size() == 2)
|
||||
{
|
||||
mMin.FromString(Components.front());
|
||||
mMax.FromString(Components.back());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline PropType GetMin()
|
||||
{
|
||||
return mMin.Get();
|
||||
}
|
||||
|
||||
inline PropType GetMax()
|
||||
{
|
||||
return mMax.Get();
|
||||
}
|
||||
|
||||
inline void SetRange(const PropType& rkMin, const PropType& rkMax)
|
||||
{
|
||||
mMin.Set(rkMin);
|
||||
mMax.Set(rkMax);
|
||||
}
|
||||
};
|
||||
|
||||
// Typedefs for all property types that don't need further functionality.
|
||||
typedef TTypedPropertyTemplate<bool, eBoolProperty, CBoolValue> TBoolTemplate;
|
||||
typedef TNumericalPropertyTemplate<s8, eByteProperty, CByteValue> TByteTemplate;
|
||||
typedef TNumericalPropertyTemplate<s16, eShortProperty, CShortValue> TShortTemplate;
|
||||
typedef TNumericalPropertyTemplate<s32, eLongProperty, CLongValue> TLongTemplate;
|
||||
typedef TNumericalPropertyTemplate<float, eFloatProperty, CFloatValue> TFloatTemplate;
|
||||
typedef TTypedPropertyTemplate<TString, eStringProperty, CStringValue> TStringTemplate;
|
||||
typedef TTypedPropertyTemplate<CVector3f, eVector3Property, CVector3Value> TVector3Template;
|
||||
typedef TTypedPropertyTemplate<CColor, eColorProperty, CColorValue> TColorTemplate;
|
||||
|
||||
// CFileTemplate - Property template for files. Tracks a list of file types that
|
||||
// the property is allowed to accept.
|
||||
class CFileTemplate : public IPropertyTemplate
|
||||
{
|
||||
friend class CTemplateLoader;
|
||||
friend class CTemplateWriter;
|
||||
|
||||
TStringList mAcceptedExtensions;
|
||||
public:
|
||||
CFileTemplate(u32 ID, CStructTemplate *pParent = 0)
|
||||
: IPropertyTemplate(ID, pParent) {}
|
||||
|
||||
CFileTemplate(u32 ID, const TString& rkName, ECookPreference CookPreference, CStructTemplate *pParent = 0)
|
||||
: IPropertyTemplate(ID, rkName, CookPreference, pParent) {}
|
||||
|
||||
virtual EPropertyType Type() const { return eFileProperty; }
|
||||
virtual bool CanHaveDefault() const { return false; }
|
||||
virtual bool IsNumerical() const { return false; }
|
||||
|
||||
IProperty* InstantiateProperty()
|
||||
{
|
||||
return new TFileProperty(this);
|
||||
}
|
||||
|
||||
void SetAllowedExtensions(const TStringList& rkExtensions)
|
||||
{
|
||||
mAcceptedExtensions = rkExtensions;
|
||||
}
|
||||
|
||||
const TStringList& Extensions() const
|
||||
{
|
||||
return mAcceptedExtensions;
|
||||
}
|
||||
};
|
||||
|
||||
// CCharacterTemplate - Typed property that doesn't allow default values.
|
||||
class CCharacterTemplate : public TTypedPropertyTemplate<CAnimationParameters,
|
||||
eCharacterProperty,
|
||||
CCharacterValue>
|
||||
{
|
||||
friend class CTemplateLoader;
|
||||
friend class CTemplateWriter;
|
||||
|
||||
public:
|
||||
CCharacterTemplate(u32 ID, CStructTemplate *pParent = 0)
|
||||
: TTypedPropertyTemplate(ID, pParent) { }
|
||||
|
||||
CCharacterTemplate(u32 ID, const TString& rkName, ECookPreference CookPreference, CStructTemplate *pParent = 0)
|
||||
: TTypedPropertyTemplate(ID, rkName, CookPreference, pParent) { }
|
||||
|
||||
virtual bool CanHaveDefault() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
// CEnumTemplate - Property template for enums. Tracks a list of possible values (enumerators).
|
||||
class CEnumTemplate : public TLongTemplate
|
||||
{
|
||||
friend class CTemplateLoader;
|
||||
friend class CTemplateWriter;
|
||||
|
||||
struct SEnumerator
|
||||
{
|
||||
TString Name;
|
||||
u32 ID;
|
||||
|
||||
SEnumerator(const TString& rkName, u32 _ID)
|
||||
: Name(rkName), ID(_ID) {}
|
||||
};
|
||||
std::vector<SEnumerator> mEnumerators;
|
||||
TString mSourceFile;
|
||||
|
||||
public:
|
||||
CEnumTemplate(u32 ID, CStructTemplate *pParent = 0)
|
||||
: TLongTemplate(ID, pParent)
|
||||
{
|
||||
mDefaultValue.SetHexStringOutput(true);
|
||||
}
|
||||
|
||||
CEnumTemplate(u32 ID, const TString& rkName, ECookPreference CookPreference, CStructTemplate *pParent = 0)
|
||||
: TLongTemplate(ID, rkName, CookPreference, pParent)
|
||||
{
|
||||
mDefaultValue.SetHexStringOutput(true);
|
||||
}
|
||||
|
||||
virtual EPropertyType Type() const { return eEnumProperty; }
|
||||
virtual bool CanHaveDefault() const { return true; }
|
||||
virtual bool IsNumerical() const { return false; }
|
||||
|
||||
virtual IProperty* InstantiateProperty()
|
||||
{
|
||||
TEnumProperty *pEnum = new TEnumProperty(this);
|
||||
u32 Index = EnumeratorIndex(GetDefaultValue());
|
||||
pEnum->Set(Index);
|
||||
return pEnum;
|
||||
}
|
||||
|
||||
u32 NumEnumerators()
|
||||
{
|
||||
return mEnumerators.size();
|
||||
}
|
||||
|
||||
u32 EnumeratorIndex(u32 enumID)
|
||||
{
|
||||
for (u32 iEnum = 0; iEnum < mEnumerators.size(); iEnum++)
|
||||
{
|
||||
if (mEnumerators[iEnum].ID == enumID)
|
||||
return iEnum;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
u32 EnumeratorID(u32 enumIndex)
|
||||
{
|
||||
if (mEnumerators.size() > enumIndex)
|
||||
return mEnumerators[enumIndex].ID;
|
||||
|
||||
else return -1;
|
||||
}
|
||||
|
||||
TString EnumeratorName(u32 enumIndex)
|
||||
{
|
||||
if (mEnumerators.size() > enumIndex)
|
||||
return mEnumerators[enumIndex].Name;
|
||||
|
||||
else return "INVALID ENUM INDEX";
|
||||
}
|
||||
};
|
||||
|
||||
// CBitfieldTemplate - Property template for bitfields, which can have multiple
|
||||
// distinct boolean parameters packed into one property.
|
||||
class CBitfieldTemplate : public TLongTemplate
|
||||
{
|
||||
friend class CTemplateLoader;
|
||||
friend class CTemplateWriter;
|
||||
|
||||
struct SBitFlag
|
||||
{
|
||||
TString Name;
|
||||
u32 Mask;
|
||||
|
||||
SBitFlag(const TString& _name, u32 _mask)
|
||||
: Name(_name), Mask(_mask) {}
|
||||
};
|
||||
std::vector<SBitFlag> mBitFlags;
|
||||
TString mSourceFile;
|
||||
|
||||
public:
|
||||
CBitfieldTemplate(u32 ID, CStructTemplate *pParent = 0)
|
||||
: TLongTemplate(ID, pParent) {}
|
||||
|
||||
CBitfieldTemplate(u32 ID, const TString& rkName, ECookPreference CookPreference, CStructTemplate *pParent = 0)
|
||||
: TLongTemplate(ID, rkName, CookPreference, pParent) {}
|
||||
|
||||
virtual EPropertyType Type() const { return eBitfieldProperty; }
|
||||
virtual bool CanHaveDefault() const { return true; }
|
||||
virtual bool IsNumerical() const { return false; }
|
||||
|
||||
virtual IProperty* InstantiateProperty()
|
||||
{
|
||||
TBitfieldProperty *pBitfield = new TBitfieldProperty(this);
|
||||
pBitfield->Set(GetDefaultValue());
|
||||
return pBitfield;
|
||||
}
|
||||
|
||||
u32 NumFlags()
|
||||
{
|
||||
return mBitFlags.size();
|
||||
}
|
||||
|
||||
TString FlagName(u32 index)
|
||||
{
|
||||
return mBitFlags[index].Name;
|
||||
}
|
||||
|
||||
u32 FlagMask(u32 index)
|
||||
{
|
||||
return mBitFlags[index].Mask;
|
||||
}
|
||||
};
|
||||
|
||||
// CStructTemplate - Defines structs composed of multiple sub-properties.
|
||||
class CStructTemplate : public IPropertyTemplate
|
||||
{
|
||||
friend class CTemplateLoader;
|
||||
friend class CTemplateWriter;
|
||||
|
||||
protected:
|
||||
std::vector<IPropertyTemplate*> mSubProperties;
|
||||
std::vector<u32> mVersionPropertyCounts;
|
||||
bool mIsSingleProperty;
|
||||
TString mSourceFile;
|
||||
|
||||
void DetermineVersionPropertyCounts();
|
||||
public:
|
||||
CStructTemplate(u32 ID, CStructTemplate *pParent = 0)
|
||||
: IPropertyTemplate(ID, pParent)
|
||||
, mIsSingleProperty(false) {}
|
||||
|
||||
CStructTemplate(u32 ID, const TString& rkName, ECookPreference CookPreference, CStructTemplate *pParent = 0)
|
||||
: IPropertyTemplate(ID, rkName, CookPreference, pParent)
|
||||
, mIsSingleProperty(false) {}
|
||||
|
||||
~CStructTemplate()
|
||||
{
|
||||
for (auto it = mSubProperties.begin(); it != mSubProperties.end(); it++)
|
||||
delete *it;
|
||||
}
|
||||
|
||||
EPropertyType Type() const { return eStructProperty; }
|
||||
bool CanHaveDefault() const { return false; }
|
||||
bool IsNumerical() const { return false; }
|
||||
|
||||
IProperty* InstantiateProperty()
|
||||
{
|
||||
CPropertyStruct *pStruct = new CPropertyStruct(this);
|
||||
|
||||
for (u32 iSub = 0; iSub < mSubProperties.size(); iSub++)
|
||||
{
|
||||
IProperty *pSubProp = mSubProperties[iSub]->InstantiateProperty();
|
||||
pStruct->AddSubProperty(pSubProp);
|
||||
}
|
||||
|
||||
return pStruct;
|
||||
}
|
||||
|
||||
bool IsSingleProperty() const;
|
||||
u32 Count() const;
|
||||
u32 NumVersions();
|
||||
u32 PropertyCountForVersion(u32 Version);
|
||||
u32 VersionForPropertyCount(u32 PropCount);
|
||||
IPropertyTemplate* PropertyByIndex(u32 index);
|
||||
IPropertyTemplate* PropertyByID(u32 ID);
|
||||
IPropertyTemplate* PropertyByIDString(const TIDString& str);
|
||||
CStructTemplate* StructByIndex(u32 index);
|
||||
CStructTemplate* StructByID(u32 ID);
|
||||
CStructTemplate* StructByIDString(const TIDString& str);
|
||||
bool HasProperty(const TIDString& rkIdString);
|
||||
void DebugPrintProperties(TString base);
|
||||
};
|
||||
|
||||
// CArrayTemplate - Defines a repeating struct composed of multiple sub-properties.
|
||||
// Similar to CStructTemplate, but with new implementations of Type() and InstantiateProperty().
|
||||
class CArrayTemplate : public CStructTemplate
|
||||
{
|
||||
friend class CTemplateLoader;
|
||||
friend class CTemplateWriter;
|
||||
|
||||
public:
|
||||
CArrayTemplate(u32 ID, CStructTemplate *pParent = 0)
|
||||
: CStructTemplate(ID, pParent)
|
||||
{
|
||||
mIsSingleProperty = true;
|
||||
}
|
||||
|
||||
CArrayTemplate(u32 ID, const TString& rkName, ECookPreference CookPreference, CStructTemplate *pParent = 0)
|
||||
: CStructTemplate(ID, rkName, CookPreference, pParent)
|
||||
{
|
||||
mIsSingleProperty = true;
|
||||
}
|
||||
|
||||
EPropertyType Type() const { return eArrayProperty; }
|
||||
|
||||
IProperty* InstantiateProperty()
|
||||
{
|
||||
return new CArrayProperty(this);
|
||||
}
|
||||
|
||||
CPropertyStruct* CreateSubStruct()
|
||||
{
|
||||
return (CPropertyStruct*) CStructTemplate::InstantiateProperty();
|
||||
}
|
||||
};
|
||||
|
||||
#endif // IPROPERTYTEMPLATE
|
||||
|
||||
275
src/Core/Resource/Script/IPropertyValue.h
Normal file
275
src/Core/Resource/Script/IPropertyValue.h
Normal file
@@ -0,0 +1,275 @@
|
||||
#ifndef IPROPERTYVALUE_H
|
||||
#define IPROPERTYVALUE_H
|
||||
|
||||
#include "EPropertyType.h"
|
||||
#include "Core/Log.h"
|
||||
#include "Core/Resource/CAnimationParameters.h"
|
||||
#include "Core/Resource/CResource.h"
|
||||
#include "Core/Resource/TResPtr.h"
|
||||
|
||||
#include <Common/CColor.h>
|
||||
#include <Common/TString.h>
|
||||
#include <Math/CVector3f.h>
|
||||
|
||||
class IPropertyValue
|
||||
{
|
||||
public:
|
||||
virtual TString ToString() const = 0;
|
||||
virtual void FromString(const TString& rkString) = 0;
|
||||
};
|
||||
|
||||
template<typename PropType>
|
||||
class TTypedPropertyValue : public IPropertyValue
|
||||
{
|
||||
protected:
|
||||
PropType mValue;
|
||||
|
||||
public:
|
||||
TTypedPropertyValue() {}
|
||||
|
||||
TTypedPropertyValue(PropType Val)
|
||||
: mValue(Val) {}
|
||||
|
||||
PropType Get() const
|
||||
{
|
||||
return mValue;
|
||||
}
|
||||
|
||||
void Set(const PropType& rkIn)
|
||||
{
|
||||
mValue = rkIn;
|
||||
}
|
||||
|
||||
bool operator==(const TTypedPropertyValue& rkOther) const
|
||||
{
|
||||
return (mValue == rkOther.mValue);
|
||||
}
|
||||
|
||||
bool operator==(const PropType& rkOther) const { return (mValue == rkOther); }
|
||||
bool operator!=(const PropType& rkOther) const { return (mValue != rkOther); }
|
||||
bool operator< (const PropType& rkOther) const { return (mValue < rkOther); }
|
||||
bool operator<=(const PropType& rkOther) const { return (mValue <= rkOther); }
|
||||
bool operator> (const PropType& rkOther) const { return (mValue > rkOther); }
|
||||
bool operator>=(const PropType& rkOther) const { return (mValue >= rkOther); }
|
||||
};
|
||||
|
||||
class CBoolValue : public TTypedPropertyValue<bool>
|
||||
{
|
||||
public:
|
||||
CBoolValue() { mValue = false; }
|
||||
CBoolValue(bool Val) { mValue = Val; }
|
||||
|
||||
TString ToString() const
|
||||
{
|
||||
return (!mValue ? "false" : "true");
|
||||
}
|
||||
|
||||
void FromString(const TString& rkString)
|
||||
{
|
||||
mValue = (rkString == "true");
|
||||
}
|
||||
};
|
||||
|
||||
class CByteValue : public TTypedPropertyValue<s8>
|
||||
{
|
||||
public:
|
||||
CByteValue() { mValue = 0; }
|
||||
CByteValue(s8 Val) { mValue = Val; }
|
||||
|
||||
TString ToString() const
|
||||
{
|
||||
return TString::FromInt32(mValue, 0, 10);
|
||||
}
|
||||
|
||||
void FromString(const TString& rkString)
|
||||
{
|
||||
u32 base = (rkString.StartsWith("0x") ? 16 : 10);
|
||||
mValue = (s8) rkString.ToInt32(base);
|
||||
}
|
||||
};
|
||||
|
||||
class CShortValue : public TTypedPropertyValue<s16>
|
||||
{
|
||||
public:
|
||||
CShortValue() { mValue = 0; }
|
||||
CShortValue(s16 Val) { mValue = Val; }
|
||||
|
||||
TString ToString() const
|
||||
{
|
||||
return TString::FromInt32((s32) mValue, 0, 10);
|
||||
}
|
||||
|
||||
void FromString(const TString& rkString)
|
||||
{
|
||||
u32 base = (rkString.StartsWith("0x") ? 16 : 10);
|
||||
mValue = (s16) rkString.ToInt32(base);
|
||||
}
|
||||
};
|
||||
|
||||
class CLongValue : public TTypedPropertyValue<s32>
|
||||
{
|
||||
protected:
|
||||
bool mShouldOutputHex;
|
||||
|
||||
public:
|
||||
CLongValue() { mShouldOutputHex = false; mValue = 0; }
|
||||
CLongValue(s32 Val) { mShouldOutputHex = false; mValue = Val; }
|
||||
|
||||
void SetHexStringOutput(bool enable)
|
||||
{
|
||||
mShouldOutputHex = enable;
|
||||
}
|
||||
|
||||
TString ToString() const
|
||||
{
|
||||
if (mShouldOutputHex)
|
||||
return TString::HexString((u32) mValue, true, true, 8);
|
||||
else
|
||||
return TString::FromInt32(mValue, 0, 10);
|
||||
}
|
||||
|
||||
void FromString(const TString& rkString)
|
||||
{
|
||||
u32 base = (rkString.StartsWith("0x") ? 16 : 10);
|
||||
mValue = (s32) rkString.ToInt32(base);
|
||||
}
|
||||
};
|
||||
|
||||
class CFloatValue : public TTypedPropertyValue<float>
|
||||
{
|
||||
public:
|
||||
CFloatValue() { mValue = 0.0f; }
|
||||
CFloatValue(float Val) { mValue = Val; }
|
||||
|
||||
TString ToString() const
|
||||
{
|
||||
return TString::FromFloat(mValue);
|
||||
}
|
||||
|
||||
void FromString(const TString& rkString)
|
||||
{
|
||||
mValue = rkString.ToFloat();
|
||||
}
|
||||
};
|
||||
|
||||
class CStringValue : public TTypedPropertyValue<TString>
|
||||
{
|
||||
public:
|
||||
CStringValue() {}
|
||||
CStringValue(const TString& rkVal) { mValue = rkVal; }
|
||||
|
||||
// These functions are extremely complicated, but try to follow along
|
||||
TString ToString() const
|
||||
{
|
||||
return mValue;
|
||||
}
|
||||
|
||||
void FromString(const TString& rkString)
|
||||
{
|
||||
mValue = rkString;
|
||||
}
|
||||
};
|
||||
|
||||
class CColorValue : public TTypedPropertyValue<CColor>
|
||||
{
|
||||
public:
|
||||
CColorValue() {}
|
||||
CColorValue(const CColor& rkVal) { mValue = rkVal; }
|
||||
|
||||
TString ToString() const
|
||||
{
|
||||
TString out;
|
||||
out += TString::FromFloat(mValue.r) + ", ";
|
||||
out += TString::FromFloat(mValue.g) + ", ";
|
||||
out += TString::FromFloat(mValue.b) + ", ";
|
||||
out += TString::FromFloat(mValue.a);
|
||||
return out;
|
||||
}
|
||||
|
||||
void FromString(const TString& rkString)
|
||||
{
|
||||
TStringList Components = rkString.Split(", ");
|
||||
|
||||
if (Components.size() < 3 || Components.size() > 4)
|
||||
{
|
||||
Log::Error("CColorValue::FromString was passed a string with an invalid number of components");
|
||||
mValue = CColor::skTransparentBlack;
|
||||
return;
|
||||
}
|
||||
|
||||
float *pPtr = &mValue.r;
|
||||
mValue.a = 1.0f;
|
||||
|
||||
for (auto it = Components.begin(); it != Components.end(); it++)
|
||||
{
|
||||
*pPtr = it->ToFloat();
|
||||
pPtr++;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class CVector3Value : public TTypedPropertyValue<CVector3f>
|
||||
{
|
||||
public:
|
||||
CVector3Value() {}
|
||||
CVector3Value(const CVector3f& rkVal) { mValue = rkVal; }
|
||||
|
||||
TString ToString() const
|
||||
{
|
||||
TString out;
|
||||
out += TString::FromFloat(mValue.x) + ", ";
|
||||
out += TString::FromFloat(mValue.y) + ", ";
|
||||
out += TString::FromFloat(mValue.z);
|
||||
return out;
|
||||
}
|
||||
|
||||
void FromString(const TString& rkString)
|
||||
{
|
||||
TStringList Components = rkString.Split(", ");
|
||||
|
||||
if (Components.size() != 3)
|
||||
{
|
||||
Log::Error("CVector3Value::FromString was passed a string with an invalid number of components");
|
||||
mValue = CVector3f::skInfinite;
|
||||
return;
|
||||
}
|
||||
|
||||
float *pPtr = &mValue.x;
|
||||
|
||||
for (auto it = Components.begin(); it != Components.end(); it++)
|
||||
{
|
||||
*pPtr = it->ToFloat();
|
||||
pPtr++;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class CCharacterValue : public TTypedPropertyValue<CAnimationParameters>
|
||||
{
|
||||
public:
|
||||
CCharacterValue() {}
|
||||
|
||||
TString ToString() const { return ""; }
|
||||
void FromString(const TString&) { }
|
||||
};
|
||||
|
||||
class CFileValue : public TTypedPropertyValue<TResPtr<CResource>>
|
||||
{
|
||||
public:
|
||||
CFileValue() {}
|
||||
CFileValue(CResource *pRes) { mValue = pRes; }
|
||||
|
||||
TString ToString() const { return ""; }
|
||||
void FromString(const TString&) { }
|
||||
};
|
||||
|
||||
class CUnknownValue : public TTypedPropertyValue<std::vector<u8>>
|
||||
{
|
||||
public:
|
||||
CUnknownValue();
|
||||
|
||||
TString ToString() const { return ""; }
|
||||
void FromString(const TString&) {}
|
||||
};
|
||||
|
||||
#endif // IPROPERTYVALUE_H
|
||||
@@ -25,16 +25,15 @@ CScriptNode::CScriptNode(CSceneManager *pScene, CSceneNode *pParent, CScriptObje
|
||||
|
||||
if (mpInstance)
|
||||
{
|
||||
CScriptTemplate *pTemp = mpInstance->Template();
|
||||
CScriptTemplate *pTemp = Template();
|
||||
|
||||
// Determine transform
|
||||
mPosition = mpInstance->Position();
|
||||
mRotation = CQuaternion::FromEuler(mpInstance->Rotation());
|
||||
mScale = mpInstance->Scale();
|
||||
mScaleMultiplier = mpInstance->Template()->PreviewScale();
|
||||
MarkTransformChanged();
|
||||
|
||||
SetName("[" + pTemp->TemplateName(mpInstance->NumProperties()) + "] " + mpInstance->InstanceName());
|
||||
SetName("[" + pTemp->TemplateName() + "] " + mpInstance->InstanceName());
|
||||
|
||||
// Determine display assets
|
||||
mpActiveModel = mpInstance->GetDisplayModel();
|
||||
@@ -110,7 +109,7 @@ void CScriptNode::AddToRenderer(CRenderer *pRenderer, const SViewInfo& ViewInfo)
|
||||
// If we're in game mode, then override other visibility settings.
|
||||
if (ViewInfo.GameMode)
|
||||
{
|
||||
if (!mpInstance->IsActive() || !mpInstance->HasInGameModel())
|
||||
if ( (!mpInstance->IsActive() && Template()->Game() != eReturns) || !mpInstance->HasInGameModel())
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -163,9 +162,9 @@ void CScriptNode::Draw(ERenderOptions Options, int ComponentIndex, const SViewIn
|
||||
if (UsesModel())
|
||||
{
|
||||
CGraphics::SetupAmbientColor();
|
||||
CGraphics::UpdateVertexBlock();
|
||||
LoadModelMatrix();
|
||||
LoadLights(ViewInfo);
|
||||
CGraphics::UpdateVertexBlock();
|
||||
|
||||
// Draw model if possible!
|
||||
if (mpActiveModel)
|
||||
@@ -249,7 +248,7 @@ void CScriptNode::RayAABoxIntersectTest(CRayCollisionTester& Tester, const SView
|
||||
// If we're in game mode, then check whether we're visible before proceeding with the ray test.
|
||||
if (ViewInfo.GameMode)
|
||||
{
|
||||
if (!mpInstance->IsActive() || !mpInstance->HasInGameModel())
|
||||
if ( (!mpInstance->IsActive() && Template()->Game() != eReturns) || !mpInstance->HasInGameModel())
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -368,20 +367,18 @@ SRayIntersection CScriptNode::RayNodeIntersectTest(const CRay& Ray, u32 AssetID,
|
||||
|
||||
bool CScriptNode::AllowsRotate() const
|
||||
{
|
||||
CScriptTemplate *pTemp = mpInstance->Template();
|
||||
return (pTemp->RotationType() == CScriptTemplate::eRotationEnabled);
|
||||
return (Template()->RotationType() == CScriptTemplate::eRotationEnabled);
|
||||
}
|
||||
|
||||
bool CScriptNode::AllowsScale() const
|
||||
{
|
||||
CScriptTemplate *pTemp = mpInstance->Template();
|
||||
return (pTemp->ScaleType() != CScriptTemplate::eScaleDisabled);
|
||||
return (Template()->ScaleType() != CScriptTemplate::eScaleDisabled);
|
||||
}
|
||||
|
||||
bool CScriptNode::IsVisible() const
|
||||
{
|
||||
// Reimplementation of CSceneNode::IsVisible() to allow for layer and template visiblity to be taken into account
|
||||
return (mVisible && mpInstance->Layer()->IsVisible() && mpInstance->Template()->IsVisible());
|
||||
return (mVisible && mpInstance->Layer()->IsVisible() && Template()->IsVisible());
|
||||
}
|
||||
|
||||
CColor CScriptNode::TintColor(const SViewInfo &ViewInfo) const
|
||||
@@ -462,6 +459,11 @@ CScriptObject* CScriptNode::Object() const
|
||||
return mpInstance;
|
||||
}
|
||||
|
||||
CScriptTemplate* CScriptNode::Template() const
|
||||
{
|
||||
return mpInstance->Template();
|
||||
}
|
||||
|
||||
CModel* CScriptNode::ActiveModel() const
|
||||
{
|
||||
return mpActiveModel;
|
||||
@@ -487,19 +489,19 @@ CAABox CScriptNode::PreviewVolumeAABox() const
|
||||
|
||||
CVector2f CScriptNode::BillboardScale() const
|
||||
{
|
||||
CVector2f out = (mpInstance->Template()->ScaleType() == CScriptTemplate::eScaleEnabled ? AbsoluteScale().xz() : CVector2f(1.f));
|
||||
return out * 0.5f * mScaleMultiplier;
|
||||
CVector2f out = (Template()->ScaleType() == CScriptTemplate::eScaleEnabled ? AbsoluteScale().xz() : CVector2f(1.f));
|
||||
return out * 0.5f * Template()->PreviewScale();
|
||||
}
|
||||
|
||||
// ************ PROTECTED ************
|
||||
void CScriptNode::CalculateTransform(CTransform4f& rOut) const
|
||||
{
|
||||
CScriptTemplate *pTemp = mpInstance->Template();
|
||||
CScriptTemplate *pTemp = Template();
|
||||
|
||||
if (pTemp->ScaleType() != CScriptTemplate::eScaleDisabled)
|
||||
{
|
||||
CVector3f Scale = (HasPreviewVolume() ? CVector3f::skOne : AbsoluteScale());
|
||||
rOut.Scale(Scale * mScaleMultiplier);
|
||||
rOut.Scale(Scale * pTemp->PreviewScale());
|
||||
}
|
||||
|
||||
if (UsesModel() && pTemp->RotationType() == CScriptTemplate::eRotationEnabled)
|
||||
|
||||
@@ -18,7 +18,6 @@ class CScriptNode : public CSceneNode
|
||||
|
||||
bool mHasValidPosition;
|
||||
bool mHasVolumePreview;
|
||||
float mScaleMultiplier;
|
||||
CModelNode *mpVolumePreviewNode;
|
||||
|
||||
CLightParameters *mpLightParameters;
|
||||
@@ -39,6 +38,7 @@ public:
|
||||
|
||||
void GeneratePosition();
|
||||
CScriptObject* Object() const;
|
||||
CScriptTemplate* Template() const;
|
||||
CModel* ActiveModel() const;
|
||||
bool UsesModel() const;
|
||||
bool HasPreviewVolume() const;
|
||||
|
||||
@@ -16,7 +16,7 @@ CDamageableTriggerExtra::CDamageableTriggerExtra(CScriptObject *pInstance, CScen
|
||||
CPropertyStruct *pBaseStruct = pInstance->Properties();
|
||||
|
||||
// Fetch render side
|
||||
mpRenderSideProp = (CEnumProperty*) pBaseStruct->PropertyByIndex(0x5);
|
||||
mpRenderSideProp = (TEnumProperty*) pBaseStruct->PropertyByIndex(0x5);
|
||||
|
||||
if (mpRenderSideProp && mpRenderSideProp->Type() != eEnumProperty)
|
||||
mpRenderSideProp = nullptr;
|
||||
@@ -24,7 +24,7 @@ CDamageableTriggerExtra::CDamageableTriggerExtra(CScriptObject *pInstance, CScen
|
||||
if (mpRenderSideProp) PropertyModified(mpRenderSideProp);
|
||||
|
||||
// Fetch scale
|
||||
mpSizeProp = (CVector3Property*) pBaseStruct->PropertyByIndex(0x2);
|
||||
mpSizeProp = (TVector3Property*) pBaseStruct->PropertyByIndex(0x2);
|
||||
|
||||
if (mpSizeProp && mpSizeProp->Type() != eVector3Property)
|
||||
mpSizeProp = nullptr;
|
||||
@@ -34,7 +34,7 @@ CDamageableTriggerExtra::CDamageableTriggerExtra(CScriptObject *pInstance, CScen
|
||||
// Fetch textures
|
||||
for (u32 iTex = 0; iTex < 3; iTex++)
|
||||
{
|
||||
mpTextureProps[iTex] = (CFileProperty*) pBaseStruct->PropertyByIndex(0x6 + iTex);
|
||||
mpTextureProps[iTex] = (TFileProperty*) pBaseStruct->PropertyByIndex(0x6 + iTex);
|
||||
|
||||
if (mpTextureProps[iTex])
|
||||
{
|
||||
@@ -147,7 +147,7 @@ void CDamageableTriggerExtra::UpdatePlaneTransform()
|
||||
MarkTransformChanged();
|
||||
}
|
||||
|
||||
void CDamageableTriggerExtra::PropertyModified(CPropertyBase *pProperty)
|
||||
void CDamageableTriggerExtra::PropertyModified(IProperty *pProperty)
|
||||
{
|
||||
if (pProperty == mpRenderSideProp)
|
||||
{
|
||||
|
||||
@@ -17,9 +17,9 @@ class CDamageableTriggerExtra : public CScriptExtra
|
||||
eDown = 6
|
||||
};
|
||||
|
||||
CVector3Property *mpSizeProp;
|
||||
CEnumProperty *mpRenderSideProp;
|
||||
CFileProperty *mpTextureProps[3];
|
||||
TVector3Property *mpSizeProp;
|
||||
TEnumProperty *mpRenderSideProp;
|
||||
TFileProperty *mpTextureProps[3];
|
||||
|
||||
CVector3f mPlaneSize;
|
||||
ERenderSide mRenderSide;
|
||||
@@ -33,7 +33,7 @@ public:
|
||||
~CDamageableTriggerExtra();
|
||||
void CreateMaterial();
|
||||
void UpdatePlaneTransform();
|
||||
void PropertyModified(CPropertyBase *pProperty);
|
||||
void PropertyModified(IProperty *pProperty);
|
||||
bool ShouldDrawNormalAssets();
|
||||
void AddToRenderer(CRenderer *pRenderer, const SViewInfo& ViewInfo);
|
||||
void Draw(ERenderOptions Options, int ComponentIndex, const SViewInfo& ViewInfo);
|
||||
|
||||
@@ -9,19 +9,35 @@ CDoorExtra::CDoorExtra(CScriptObject *pInstance, CSceneManager *pScene, CSceneNo
|
||||
{
|
||||
CPropertyStruct *pBaseStruct = pInstance->Properties();
|
||||
|
||||
mpShieldModelProp = (CFileProperty*) pBaseStruct->PropertyByID(0xB20CC271);
|
||||
mpShieldModelProp = (TFileProperty*) pBaseStruct->PropertyByID(0xB20CC271);
|
||||
if (mpShieldModelProp && (mpShieldModelProp->Type() != eFileProperty))
|
||||
mpShieldModelProp = nullptr;
|
||||
|
||||
mpShieldColorProp = (CColorProperty*) pBaseStruct->PropertyByID(0x47B4E863);
|
||||
if (mpShieldColorProp && (mpShieldColorProp->Type() != eColorProperty))
|
||||
mpShieldColorProp = nullptr;
|
||||
|
||||
if (mpShieldModelProp)
|
||||
PropertyModified(mpShieldModelProp);
|
||||
|
||||
if (mGame >= eEchoes)
|
||||
{
|
||||
mpShieldColorProp = (TColorProperty*) pBaseStruct->PropertyByID(0x47B4E863);
|
||||
if (mpShieldColorProp && (mpShieldColorProp->Type() != eColorProperty))
|
||||
mpShieldColorProp = nullptr;
|
||||
|
||||
if (mpShieldColorProp)
|
||||
PropertyModified(mpShieldColorProp);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
mpDisabledProp = (TBoolProperty*) pBaseStruct->PropertyByID(0xDEE730F5);
|
||||
if (mpDisabledProp && (mpDisabledProp->Type() != eBoolProperty))
|
||||
mpDisabledProp = nullptr;
|
||||
|
||||
if (mpDisabledProp)
|
||||
PropertyModified(mpDisabledProp);
|
||||
}
|
||||
}
|
||||
|
||||
void CDoorExtra::PropertyModified(CPropertyBase *pProperty)
|
||||
void CDoorExtra::PropertyModified(IProperty *pProperty)
|
||||
{
|
||||
if (pProperty == mpShieldModelProp)
|
||||
{
|
||||
@@ -35,6 +51,21 @@ void CDoorExtra::PropertyModified(CPropertyBase *pProperty)
|
||||
|
||||
MarkTransformChanged();
|
||||
}
|
||||
|
||||
else if (pProperty == mpShieldColorProp)
|
||||
{
|
||||
mShieldColor = mpShieldColorProp->Get();
|
||||
}
|
||||
|
||||
else if (pProperty == mpDisabledProp)
|
||||
{
|
||||
// The Echoes demo doesn't have the shield color property. The color is
|
||||
// always cyan if the door is unlocked and always white if the door is locked.
|
||||
mShieldColor = CColor::skWhite;
|
||||
|
||||
if (!mpDisabledProp->Get())
|
||||
mShieldColor = CColor::skCyan;
|
||||
}
|
||||
}
|
||||
|
||||
void CDoorExtra::AddToRenderer(CRenderer *pRenderer, const SViewInfo& ViewInfo)
|
||||
@@ -62,10 +93,7 @@ void CDoorExtra::Draw(ERenderOptions Options, int ComponentIndex, const SViewInf
|
||||
CGraphics::SetupAmbientColor();
|
||||
CGraphics::UpdateVertexBlock();
|
||||
|
||||
CColor Tint = mpParent->TintColor(ViewInfo);
|
||||
|
||||
if (mpShieldColorProp)
|
||||
Tint *= mpShieldColorProp->Get();
|
||||
CColor Tint = mpParent->TintColor(ViewInfo) * mShieldColor;
|
||||
|
||||
CGraphics::sPixelBlock.TintColor = Tint;
|
||||
CGraphics::sPixelBlock.TevColor = CColor::skWhite;
|
||||
|
||||
@@ -6,13 +6,15 @@
|
||||
class CDoorExtra : public CScriptExtra
|
||||
{
|
||||
// Render colored door shield in MP2/3
|
||||
CFileProperty *mpShieldModelProp;
|
||||
CColorProperty *mpShieldColorProp;
|
||||
TFileProperty *mpShieldModelProp;
|
||||
TColorProperty *mpShieldColorProp;
|
||||
TBoolProperty *mpDisabledProp;
|
||||
TResPtr<CModel> mpShieldModel;
|
||||
CColor mShieldColor;
|
||||
|
||||
public:
|
||||
explicit CDoorExtra(CScriptObject *pInstance, CSceneManager *pScene, CSceneNode *pParent = 0);
|
||||
void PropertyModified(CPropertyBase *pProperty);
|
||||
void PropertyModified(IProperty *pProperty);
|
||||
void AddToRenderer(CRenderer *pRenderer, const SViewInfo& ViewInfo);
|
||||
void Draw(ERenderOptions Options, int ComponentIndex, const SViewInfo& ViewInfo);
|
||||
void DrawSelection();
|
||||
|
||||
@@ -15,14 +15,14 @@ CPointOfInterestExtra::CPointOfInterestExtra(CScriptObject *pInstance, CSceneMan
|
||||
{
|
||||
case ePrimeDemo:
|
||||
case ePrime:
|
||||
mpScanProperty = (CFileProperty*) pBaseProp->PropertyByIDString("0x04:0x00");
|
||||
mpScanProperty = (TFileProperty*) pBaseProp->PropertyByIDString("0x04:0x00");
|
||||
break;
|
||||
|
||||
case eEchoesDemo:
|
||||
case eEchoes:
|
||||
case eCorruptionProto:
|
||||
case eCorruption:
|
||||
mpScanProperty = (CFileProperty*) pBaseProp->PropertyByIDString("0xBDBEC295:0xB94E9BE7");
|
||||
mpScanProperty = (TFileProperty*) pBaseProp->PropertyByIDString("0xBDBEC295:0xB94E9BE7");
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -39,7 +39,7 @@ CPointOfInterestExtra::CPointOfInterestExtra(CScriptObject *pInstance, CSceneMan
|
||||
}
|
||||
}
|
||||
|
||||
void CPointOfInterestExtra::PropertyModified(CPropertyBase* pProperty)
|
||||
void CPointOfInterestExtra::PropertyModified(IProperty* pProperty)
|
||||
{
|
||||
if (mpScanProperty == pProperty)
|
||||
mpScanData = mpScanProperty->Get();
|
||||
|
||||
@@ -8,12 +8,12 @@
|
||||
class CPointOfInterestExtra : public CScriptExtra
|
||||
{
|
||||
// Tint POI billboard orange/red depending on scan importance
|
||||
CFileProperty *mpScanProperty;
|
||||
TFileProperty *mpScanProperty;
|
||||
TResPtr<CScan> mpScanData;
|
||||
|
||||
public:
|
||||
explicit CPointOfInterestExtra(CScriptObject *pInstance, CSceneManager *pScene, CSceneNode *pParent = 0);
|
||||
void PropertyModified(CPropertyBase* pProperty);
|
||||
void PropertyModified(IProperty* pProperty);
|
||||
void ModifyTintColor(CColor& Color);
|
||||
|
||||
static const CColor skRegularColor;
|
||||
|
||||
@@ -11,16 +11,16 @@ CRadiusSphereExtra::CRadiusSphereExtra(CScriptObject *pInstance, CSceneManager *
|
||||
switch (mObjectType)
|
||||
{
|
||||
case 0x63: // Repulsor (MP1)
|
||||
mpRadius = (CFloatProperty*) pInstance->Properties()->PropertyByID(0x3);
|
||||
mpRadius = (TFloatProperty*) pInstance->Properties()->PropertyByID(0x3);
|
||||
break;
|
||||
|
||||
case 0x68: // RadialDamage (MP1)
|
||||
mpRadius = (CFloatProperty*) pInstance->Properties()->PropertyByID(0x4);
|
||||
mpRadius = (TFloatProperty*) pInstance->Properties()->PropertyByID(0x4);
|
||||
break;
|
||||
|
||||
case 0x5245504C: // "REPL" Repulsor (MP2/MP3)
|
||||
case 0x52414444: // "RADD" RadialDamage (MP2/MP3/DKCR)
|
||||
mpRadius =(CFloatProperty*) pInstance->Properties()->PropertyByID(0x78C507EB);
|
||||
mpRadius = (TFloatProperty*) pInstance->Properties()->PropertyByID(0x78C507EB);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ class CRadiusSphereExtra : public CScriptExtra
|
||||
{
|
||||
// Sphere visualization for objects that have a float radius property.
|
||||
u32 mObjectType;
|
||||
CFloatProperty *mpRadius;
|
||||
TFloatProperty *mpRadius;
|
||||
|
||||
public:
|
||||
explicit CRadiusSphereExtra(CScriptObject *pInstance, CSceneManager *pScene, CSceneNode *pParent = 0);
|
||||
|
||||
@@ -40,7 +40,7 @@ public:
|
||||
|
||||
// Virtual CScriptExtra functions
|
||||
virtual void InstanceTransformed() {}
|
||||
virtual void PropertyModified(CPropertyBase* /*pProperty*/) {}
|
||||
virtual void PropertyModified(IProperty* /*pProperty*/) {}
|
||||
virtual void LinksModified() {}
|
||||
virtual bool ShouldDrawNormalAssets() { return true; }
|
||||
virtual bool ShouldDrawVolume() { return true; }
|
||||
|
||||
@@ -12,19 +12,19 @@ CSpacePirateExtra::CSpacePirateExtra(CScriptObject *pInstance, CSceneManager *pS
|
||||
|
||||
if (pVulns && pVulns->Type() == eStructProperty)
|
||||
{
|
||||
mpPowerVuln = (CLongProperty*) pVulns->PropertyByID(0x0);
|
||||
mpPowerVuln = (TLongProperty*) pVulns->PropertyByID(0x0);
|
||||
if (mpPowerVuln && mpPowerVuln->Type() != eLongProperty && mpPowerVuln->Type() != eEnumProperty)
|
||||
mpPowerVuln = nullptr;
|
||||
|
||||
mpWaveVuln = (CLongProperty*) pVulns->PropertyByID(0x2);
|
||||
mpWaveVuln = (TLongProperty*) pVulns->PropertyByID(0x2);
|
||||
if (mpWaveVuln && mpWaveVuln->Type() != eLongProperty && mpWaveVuln->Type() != eEnumProperty)
|
||||
mpWaveVuln = nullptr;
|
||||
|
||||
mpIceVuln = (CLongProperty*) pVulns->PropertyByID(0x1);
|
||||
mpIceVuln = (TLongProperty*) pVulns->PropertyByID(0x1);
|
||||
if (mpIceVuln && mpIceVuln->Type() != eLongProperty && mpIceVuln->Type() != eEnumProperty)
|
||||
mpIceVuln = nullptr;
|
||||
|
||||
mpPlasmaVuln = (CLongProperty*) pVulns->PropertyByID(0x3);
|
||||
mpPlasmaVuln = (TLongProperty*) pVulns->PropertyByID(0x3);
|
||||
if (mpPlasmaVuln && mpPlasmaVuln->Type() != eLongProperty && mpPlasmaVuln->Type() != eEnumProperty)
|
||||
mpPlasmaVuln = nullptr;
|
||||
}
|
||||
|
||||
@@ -2,15 +2,15 @@
|
||||
#define CSPACEPIRATEEXTRA_H
|
||||
|
||||
#include "CScriptExtra.h"
|
||||
#include "Core/Resource/Script/CProperty.h"
|
||||
#include "Core/Resource/Script/IProperty.h"
|
||||
|
||||
class CSpacePirateExtra : public CScriptExtra
|
||||
{
|
||||
// Render beam troopers with the correct color
|
||||
CLongProperty *mpPowerVuln;
|
||||
CLongProperty *mpWaveVuln;
|
||||
CLongProperty *mpIceVuln;
|
||||
CLongProperty *mpPlasmaVuln;
|
||||
TLongProperty *mpPowerVuln;
|
||||
TLongProperty *mpWaveVuln;
|
||||
TLongProperty *mpIceVuln;
|
||||
TLongProperty *mpPlasmaVuln;
|
||||
|
||||
public:
|
||||
explicit CSpacePirateExtra(CScriptObject *pInstance, CSceneManager *pScene, CSceneNode *pParent = 0);
|
||||
|
||||
@@ -28,6 +28,7 @@ CONFIG(debug, debug|release) {
|
||||
-L$$PWD/../../build/Math/ -lMathd \
|
||||
-L$$PWD/../../build/Core/ -lCored \
|
||||
-L$$PWD/../../externals/assimp/lib/ -lassimp-vc120-mtd \
|
||||
-L$$PWD/../../externals/boost_1_56_0/lib32-msvc-12.0 -llibboost_filesystem-vc120-mt-gd-1_56 \
|
||||
-L$$PWD/../../externals/tinyxml2/lib/ -ltinyxml2d
|
||||
|
||||
# Debug Target Dependencies
|
||||
@@ -52,6 +53,7 @@ CONFIG(release, debug|release) {
|
||||
-L$$PWD/../../build/Math/ -lMath \
|
||||
-L$$PWD/../../build/Core/ -lCore \
|
||||
-L$$PWD/../../externals/assimp/lib/ -lassimp-vc120-mt \
|
||||
-L$$PWD/../../externals/boost_1_56_0/lib32-msvc-12.0 -llibboost_filesystem-vc120-mt-1_56 \
|
||||
-L$$PWD/../../externals/tinyxml2/lib/ -ltinyxml2
|
||||
|
||||
# Release Target Dependencies
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
static const QString gskNullProperty = "[NULL]";
|
||||
static const QString gskUnsupportedType = "Invalid property type";
|
||||
|
||||
WPropertyEditor::WPropertyEditor(QWidget *pParent, CPropertyBase *pProperty)
|
||||
WPropertyEditor::WPropertyEditor(QWidget *pParent, IProperty *pProperty)
|
||||
: QWidget(pParent)
|
||||
{
|
||||
mUI.PropertyName = new QLabel(gskNullProperty, this);
|
||||
@@ -44,7 +44,7 @@ void WPropertyEditor::resizeEvent(QResizeEvent* /*pEvent*/)
|
||||
CreateLabelText();
|
||||
}
|
||||
|
||||
void WPropertyEditor::SetProperty(CPropertyBase *pProperty)
|
||||
void WPropertyEditor::SetProperty(IProperty *pProperty)
|
||||
{
|
||||
if (pProperty)
|
||||
{
|
||||
@@ -83,7 +83,7 @@ void WPropertyEditor::CreateEditor()
|
||||
// Bool - QCheckBox
|
||||
case eBoolProperty:
|
||||
{
|
||||
CBoolProperty *pBoolCast = static_cast<CBoolProperty*>(mpProperty);
|
||||
TBoolProperty *pBoolCast = static_cast<TBoolProperty*>(mpProperty);
|
||||
QCheckBox *pCheckBox = new QCheckBox(this);
|
||||
|
||||
pCheckBox->setChecked(pBoolCast->Get());
|
||||
@@ -95,7 +95,7 @@ void WPropertyEditor::CreateEditor()
|
||||
// Byte - WIntegralSpinBox
|
||||
case eByteProperty:
|
||||
{
|
||||
CByteProperty *pByteCast = static_cast<CByteProperty*>(mpProperty);
|
||||
TByteProperty *pByteCast = static_cast<TByteProperty*>(mpProperty);
|
||||
QSpinBox *pSpinBox = new WIntegralSpinBox(this);
|
||||
|
||||
pSpinBox->setRange(-128, 128);
|
||||
@@ -110,7 +110,7 @@ void WPropertyEditor::CreateEditor()
|
||||
// Short - WIntegralSpinBox
|
||||
case eShortProperty:
|
||||
{
|
||||
CShortProperty *pShortCast = static_cast<CShortProperty*>(mpProperty);
|
||||
TShortProperty *pShortCast = static_cast<TShortProperty*>(mpProperty);
|
||||
QSpinBox *pSpinBox = new WIntegralSpinBox(this);
|
||||
|
||||
pSpinBox->setRange(-32768, 32767);
|
||||
@@ -125,7 +125,7 @@ void WPropertyEditor::CreateEditor()
|
||||
// Long - WIntegralSpinBox
|
||||
case eLongProperty:
|
||||
{
|
||||
CLongProperty *pLongCast = static_cast<CLongProperty*>(mpProperty);
|
||||
TLongProperty *pLongCast = static_cast<TLongProperty*>(mpProperty);
|
||||
QSpinBox *pSpinBox = new WIntegralSpinBox(this);
|
||||
|
||||
pSpinBox->setRange(INT32_MIN, INT32_MAX);
|
||||
@@ -140,7 +140,7 @@ void WPropertyEditor::CreateEditor()
|
||||
// Enum - QComboBox
|
||||
case eEnumProperty:
|
||||
{
|
||||
CEnumProperty *pEnumCast = static_cast<CEnumProperty*>(mpProperty);
|
||||
TEnumProperty *pEnumCast = static_cast<TEnumProperty*>(mpProperty);
|
||||
CEnumTemplate *pTemplate = static_cast<CEnumTemplate*>(pEnumCast->Template());
|
||||
QComboBox *pComboBox = new QComboBox(this);
|
||||
|
||||
@@ -162,7 +162,7 @@ void WPropertyEditor::CreateEditor()
|
||||
// Bitfield - QGroupBox containing QCheckBoxes
|
||||
case eBitfieldProperty:
|
||||
{
|
||||
CBitfieldProperty *pBitfieldCast = static_cast<CBitfieldProperty*>(mpProperty);
|
||||
TBitfieldProperty *pBitfieldCast = static_cast<TBitfieldProperty*>(mpProperty);
|
||||
CBitfieldTemplate *pTemplate = static_cast<CBitfieldTemplate*>(pBitfieldCast->Template());
|
||||
long value = pBitfieldCast->Get();
|
||||
|
||||
@@ -190,7 +190,7 @@ void WPropertyEditor::CreateEditor()
|
||||
// Float - WDraggableSpinBox
|
||||
case eFloatProperty:
|
||||
{
|
||||
CFloatProperty *pFloatCast = static_cast<CFloatProperty*>(mpProperty);
|
||||
TFloatProperty *pFloatCast = static_cast<TFloatProperty*>(mpProperty);
|
||||
WDraggableSpinBox *pDraggableSpinBox = new WDraggableSpinBox(this);
|
||||
|
||||
pDraggableSpinBox->setDecimals(4);
|
||||
@@ -205,7 +205,7 @@ void WPropertyEditor::CreateEditor()
|
||||
// String - QLineEdit
|
||||
case eStringProperty:
|
||||
{
|
||||
CStringProperty *pStringCast = static_cast<CStringProperty*>(mpProperty);
|
||||
TStringProperty *pStringCast = static_cast<TStringProperty*>(mpProperty);
|
||||
QLineEdit *pLineEdit = new QLineEdit(this);
|
||||
|
||||
pLineEdit->setText(TO_QSTRING(pStringCast->Get()));
|
||||
@@ -219,7 +219,7 @@ void WPropertyEditor::CreateEditor()
|
||||
// Vector3 - WVectorEditor (inside QGroupBox)
|
||||
case eVector3Property:
|
||||
{
|
||||
CVector3Property *pVector3Cast = static_cast<CVector3Property*>(mpProperty);
|
||||
TVector3Property *pVector3Cast = static_cast<TVector3Property*>(mpProperty);
|
||||
QGroupBox *pGroupBox = new QGroupBox(this);
|
||||
WVectorEditor *pVectorEditor = new WVectorEditor(pGroupBox);
|
||||
|
||||
@@ -240,7 +240,7 @@ void WPropertyEditor::CreateEditor()
|
||||
// Color - WColorPicker
|
||||
case eColorProperty:
|
||||
{
|
||||
CColorProperty *pColorCast = static_cast<CColorProperty*>(mpProperty);
|
||||
TColorProperty *pColorCast = static_cast<TColorProperty*>(mpProperty);
|
||||
WColorPicker *pColorPicker = new WColorPicker(this);
|
||||
|
||||
CColor color = pColorCast->Get();
|
||||
@@ -254,7 +254,7 @@ void WPropertyEditor::CreateEditor()
|
||||
// File - WResourceSelector
|
||||
case eFileProperty:
|
||||
{
|
||||
CFileProperty *pFileCast = static_cast<CFileProperty*>(mpProperty);
|
||||
TFileProperty *pFileCast = static_cast<TFileProperty*>(mpProperty);
|
||||
CFileTemplate *pFileTemp = static_cast<CFileTemplate*>(pFileCast->Template());
|
||||
WResourceSelector *pResourceSelector = new WResourceSelector(this);
|
||||
|
||||
@@ -289,9 +289,9 @@ void WPropertyEditor::CreateEditor()
|
||||
}
|
||||
|
||||
// AnimParams - WAnimParamsEditor
|
||||
case eAnimParamsProperty:
|
||||
case eCharacterProperty:
|
||||
{
|
||||
CAnimParamsProperty *pAnimCast = static_cast<CAnimParamsProperty*>(mpProperty);
|
||||
TAnimParamsProperty *pAnimCast = static_cast<TAnimParamsProperty*>(mpProperty);
|
||||
CAnimationParameters params = pAnimCast->Get();
|
||||
|
||||
WAnimParamsEditor *pEditor = new WAnimParamsEditor(params, this);
|
||||
@@ -313,7 +313,7 @@ void WPropertyEditor::CreateEditor()
|
||||
if ((mpProperty->Type() != eStructProperty) &&
|
||||
(mpProperty->Type() != eBitfieldProperty) &&
|
||||
(mpProperty->Type() != eVector3Property) &&
|
||||
(mpProperty->Type() != eAnimParamsProperty))
|
||||
(mpProperty->Type() != eCharacterProperty))
|
||||
{
|
||||
mUI.EditorWidget->setMinimumHeight(21);
|
||||
mUI.EditorWidget->setMaximumHeight(21);
|
||||
@@ -330,7 +330,7 @@ void WPropertyEditor::UpdateEditor()
|
||||
|
||||
case eBoolProperty:
|
||||
{
|
||||
CBoolProperty *pBoolCast = static_cast<CBoolProperty*>(mpProperty);
|
||||
TBoolProperty *pBoolCast = static_cast<TBoolProperty*>(mpProperty);
|
||||
QCheckBox *pCheckBox = static_cast<QCheckBox*>(mUI.EditorWidget);
|
||||
pCheckBox->setChecked(pBoolCast->Get());
|
||||
break;
|
||||
@@ -338,7 +338,7 @@ void WPropertyEditor::UpdateEditor()
|
||||
|
||||
case eByteProperty:
|
||||
{
|
||||
CByteProperty *pByteCast = static_cast<CByteProperty*>(mpProperty);
|
||||
TByteProperty *pByteCast = static_cast<TByteProperty*>(mpProperty);
|
||||
QSpinBox *pSpinBox = static_cast<QSpinBox*>(mUI.EditorWidget);
|
||||
pSpinBox->setValue(pByteCast->Get());
|
||||
break;
|
||||
@@ -346,7 +346,7 @@ void WPropertyEditor::UpdateEditor()
|
||||
|
||||
case eShortProperty:
|
||||
{
|
||||
CShortProperty *pShortCast = static_cast<CShortProperty*>(mpProperty);
|
||||
TShortProperty *pShortCast = static_cast<TShortProperty*>(mpProperty);
|
||||
QSpinBox *pSpinBox = static_cast<QSpinBox*>(mUI.EditorWidget);
|
||||
pSpinBox->setValue(pShortCast->Get());
|
||||
break;
|
||||
@@ -354,7 +354,7 @@ void WPropertyEditor::UpdateEditor()
|
||||
|
||||
case eLongProperty:
|
||||
{
|
||||
CLongProperty *pLongCast = static_cast<CLongProperty*>(mpProperty);
|
||||
TLongProperty *pLongCast = static_cast<TLongProperty*>(mpProperty);
|
||||
QSpinBox *pSpinBox = static_cast<QSpinBox*>(mUI.EditorWidget);
|
||||
pSpinBox->setValue(pLongCast->Get());
|
||||
break;
|
||||
@@ -362,7 +362,7 @@ void WPropertyEditor::UpdateEditor()
|
||||
|
||||
case eEnumProperty:
|
||||
{
|
||||
CEnumProperty *pEnumCast = static_cast<CEnumProperty*>(mpProperty);
|
||||
TEnumProperty *pEnumCast = static_cast<TEnumProperty*>(mpProperty);
|
||||
QComboBox *pComboBox = static_cast<QComboBox*>(mUI.EditorWidget);
|
||||
pComboBox->setCurrentIndex(pEnumCast->Get());
|
||||
break;
|
||||
@@ -370,7 +370,7 @@ void WPropertyEditor::UpdateEditor()
|
||||
|
||||
case eBitfieldProperty:
|
||||
{
|
||||
CBitfieldProperty *pBitfieldCast = static_cast<CBitfieldProperty*>(mpProperty);
|
||||
TBitfieldProperty *pBitfieldCast = static_cast<TBitfieldProperty*>(mpProperty);
|
||||
CBitfieldTemplate *pTemplate = static_cast<CBitfieldTemplate*>(pBitfieldCast->Template());
|
||||
QGroupBox *pGroupBox = static_cast<QGroupBox*>(mUI.EditorWidget);
|
||||
|
||||
@@ -393,7 +393,7 @@ void WPropertyEditor::UpdateEditor()
|
||||
|
||||
case eFloatProperty:
|
||||
{
|
||||
CFloatProperty *pFloatCast = static_cast<CFloatProperty*>(mpProperty);
|
||||
TFloatProperty *pFloatCast = static_cast<TFloatProperty*>(mpProperty);
|
||||
WDraggableSpinBox *pDraggableSpinBox = static_cast<WDraggableSpinBox*>(mUI.EditorWidget);
|
||||
pDraggableSpinBox->setValue(pFloatCast->Get());
|
||||
break;
|
||||
@@ -401,7 +401,7 @@ void WPropertyEditor::UpdateEditor()
|
||||
|
||||
case eStringProperty:
|
||||
{
|
||||
CStringProperty *pStringCast = static_cast<CStringProperty*>(mpProperty);
|
||||
TStringProperty *pStringCast = static_cast<TStringProperty*>(mpProperty);
|
||||
QLineEdit *pLineEdit = static_cast<QLineEdit*>(mUI.EditorWidget);
|
||||
pLineEdit->setText(TO_QSTRING(pStringCast->Get()));
|
||||
pLineEdit->setCursorPosition(0);
|
||||
@@ -410,7 +410,7 @@ void WPropertyEditor::UpdateEditor()
|
||||
|
||||
case eVector3Property:
|
||||
{
|
||||
CVector3Property *pVector3Cast = static_cast<CVector3Property*>(mpProperty);
|
||||
TVector3Property *pVector3Cast = static_cast<TVector3Property*>(mpProperty);
|
||||
QGroupBox *pGroupBox = static_cast<QGroupBox*>(mUI.EditorWidget);
|
||||
|
||||
WVectorEditor *pVectorEditor = static_cast<WVectorEditor*>(pGroupBox->children().first());
|
||||
@@ -420,7 +420,7 @@ void WPropertyEditor::UpdateEditor()
|
||||
|
||||
case eColorProperty:
|
||||
{
|
||||
CColorProperty *pColorCast = static_cast<CColorProperty*>(mpProperty);
|
||||
TColorProperty *pColorCast = static_cast<TColorProperty*>(mpProperty);
|
||||
WColorPicker *pColorPicker = static_cast<WColorPicker*>(mUI.EditorWidget);
|
||||
|
||||
CColor color = pColorCast->Get();
|
||||
@@ -432,7 +432,7 @@ void WPropertyEditor::UpdateEditor()
|
||||
|
||||
case eFileProperty:
|
||||
{
|
||||
CFileProperty *pFileCast = static_cast<CFileProperty*>(mpProperty);
|
||||
TFileProperty *pFileCast = static_cast<TFileProperty*>(mpProperty);
|
||||
CFileTemplate *pFileTemp = static_cast<CFileTemplate*>(pFileCast->Template());
|
||||
WResourceSelector *pResourceSelector = static_cast<WResourceSelector*>(mUI.EditorWidget);
|
||||
pResourceSelector->SetAllowedExtensions(pFileTemp->Extensions());
|
||||
@@ -452,7 +452,7 @@ void WPropertyEditor::UpdateEditor()
|
||||
{
|
||||
if (pObj != pGroupBox->layout())
|
||||
{
|
||||
CPropertyBase *pProp = pStructCast->PropertyByIndex(PropNum);
|
||||
IProperty *pProp = pStructCast->PropertyByIndex(PropNum);
|
||||
static_cast<WPropertyEditor*>(pObj)->SetProperty(pProp);
|
||||
PropNum++;
|
||||
}
|
||||
@@ -460,9 +460,9 @@ void WPropertyEditor::UpdateEditor()
|
||||
break;
|
||||
}
|
||||
|
||||
case eAnimParamsProperty:
|
||||
case eCharacterProperty:
|
||||
{
|
||||
CAnimParamsProperty *pAnimCast = static_cast<CAnimParamsProperty*>(mpProperty);
|
||||
TAnimParamsProperty *pAnimCast = static_cast<TAnimParamsProperty*>(mpProperty);
|
||||
WAnimParamsEditor *pEditor = static_cast<WAnimParamsEditor*>(mUI.EditorWidget);
|
||||
pEditor->SetParameters(pAnimCast->Get());
|
||||
break;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef WPROPERTYEDITOR_H
|
||||
#define WPROPERTYEDITOR_H
|
||||
|
||||
#include <Core/Resource/Script/CProperty.h>
|
||||
#include <Core/Resource/Script/IProperty.h>
|
||||
#include <QWidget>
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
@@ -11,7 +11,7 @@ class WPropertyEditor : public QWidget
|
||||
Q_OBJECT
|
||||
|
||||
// Editor
|
||||
CPropertyBase *mpProperty;
|
||||
IProperty *mpProperty;
|
||||
|
||||
// UI
|
||||
struct {
|
||||
@@ -21,11 +21,11 @@ class WPropertyEditor : public QWidget
|
||||
} mUI;
|
||||
|
||||
public:
|
||||
explicit WPropertyEditor(QWidget *pParent = 0, CPropertyBase *pProperty = 0);
|
||||
explicit WPropertyEditor(QWidget *pParent = 0, IProperty *pProperty = 0);
|
||||
~WPropertyEditor();
|
||||
void resizeEvent(QResizeEvent *pEvent);
|
||||
|
||||
void SetProperty(CPropertyBase *pProperty);
|
||||
void SetProperty(IProperty *pProperty);
|
||||
|
||||
private:
|
||||
void CreateEditor();
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
#include "CDarkStyle.h"
|
||||
#include <Core/Resource/Factory/CTemplateLoader.h>
|
||||
|
||||
// temp
|
||||
#include <Core/Resource/Cooker/CTemplateWriter.h>
|
||||
|
||||
#include <QApplication>
|
||||
#include <QStyleFactory>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user