Fixed property name generator/template edit dialog to work with new property system
This commit is contained in:
parent
803ea5788b
commit
22ab73883c
|
@ -11,9 +11,11 @@ using namespace std::experimental::filesystem::v1;
|
|||
namespace FileUtil
|
||||
{
|
||||
|
||||
#define ToPath(Path) u8path(Path)
|
||||
|
||||
bool Exists(const TString &rkFilePath)
|
||||
{
|
||||
return exists(*rkFilePath);
|
||||
return exists(ToPath(*rkFilePath));
|
||||
}
|
||||
|
||||
bool IsRoot(const TString& rkPath)
|
||||
|
@ -26,22 +28,22 @@ bool IsRoot(const TString& rkPath)
|
|||
|
||||
bool IsFile(const TString& rkFilePath)
|
||||
{
|
||||
return is_regular_file(*rkFilePath);
|
||||
return is_regular_file(ToPath(*rkFilePath));
|
||||
}
|
||||
|
||||
bool IsDirectory(const TString& rkDirPath)
|
||||
{
|
||||
return is_directory(*rkDirPath);
|
||||
return is_directory(ToPath(*rkDirPath));
|
||||
}
|
||||
|
||||
bool IsAbsolute(const TString& rkDirPath)
|
||||
{
|
||||
return path(*rkDirPath).is_absolute();
|
||||
return ToPath(*rkDirPath).is_absolute();
|
||||
}
|
||||
|
||||
bool IsRelative(const TString& rkDirPath)
|
||||
{
|
||||
return path(*rkDirPath).is_relative();
|
||||
return ToPath(*rkDirPath).is_relative();
|
||||
}
|
||||
|
||||
bool IsEmpty(const TString& rkDirPath)
|
||||
|
@ -52,7 +54,7 @@ bool IsEmpty(const TString& rkDirPath)
|
|||
return false;
|
||||
}
|
||||
|
||||
return is_empty(*rkDirPath);
|
||||
return is_empty(ToPath(*rkDirPath));
|
||||
}
|
||||
|
||||
bool MakeDirectory(const TString& rkNewDir)
|
||||
|
@ -63,7 +65,7 @@ bool MakeDirectory(const TString& rkNewDir)
|
|||
return false;
|
||||
}
|
||||
|
||||
return create_directories(*rkNewDir);
|
||||
return create_directories(ToPath(*rkNewDir));
|
||||
}
|
||||
|
||||
bool CopyFile(const TString& rkOrigPath, const TString& rkNewPath)
|
||||
|
@ -77,7 +79,7 @@ bool CopyFile(const TString& rkOrigPath, const TString& rkNewPath)
|
|||
MakeDirectory(rkNewPath.GetFileDirectory());
|
||||
std::error_code Error;
|
||||
// call std::filesystem::copy, not std::copy
|
||||
std::experimental::filesystem::copy(*rkOrigPath, *rkNewPath, Error);
|
||||
std::experimental::filesystem::copy(ToPath(*rkOrigPath), ToPath(*rkNewPath), Error);
|
||||
return (Error.value() == 0);
|
||||
}
|
||||
|
||||
|
@ -92,7 +94,7 @@ bool CopyDirectory(const TString& rkOrigPath, const TString& rkNewPath)
|
|||
MakeDirectory(rkNewPath.GetFileDirectory());
|
||||
std::error_code Error;
|
||||
// call std::filesystem::copy, not std::copy
|
||||
std::experimental::filesystem::copy(*rkOrigPath, *rkNewPath, Error);
|
||||
std::experimental::filesystem::copy(ToPath(*rkOrigPath), ToPath(*rkNewPath), Error);
|
||||
return (Error.value() == 0);
|
||||
}
|
||||
|
||||
|
@ -110,8 +112,9 @@ bool MoveFile(const TString& rkOldPath, const TString& rkNewPath)
|
|||
return false;
|
||||
}
|
||||
|
||||
int Result = rename(*rkOldPath, *rkNewPath);
|
||||
return (Result == 0);
|
||||
std::error_code Error;
|
||||
rename(ToPath(*rkOldPath), ToPath(*rkNewPath), Error);
|
||||
return Error.value() == 0;
|
||||
}
|
||||
|
||||
bool MoveDirectory(const TString& rkOldPath, const TString& rkNewPath)
|
||||
|
@ -128,14 +131,15 @@ bool MoveDirectory(const TString& rkOldPath, const TString& rkNewPath)
|
|||
return false;
|
||||
}
|
||||
|
||||
int Result = rename(*rkOldPath, *rkNewPath);
|
||||
return (Result == 0);
|
||||
std::error_code Error;
|
||||
rename(ToPath(*rkOldPath), ToPath(*rkNewPath), Error);
|
||||
return Error.value() == 0;
|
||||
}
|
||||
|
||||
bool DeleteFile(const TString& rkFilePath)
|
||||
{
|
||||
if (!IsFile(rkFilePath)) return false;
|
||||
return remove(*rkFilePath) == 1;
|
||||
return remove(ToPath(*rkFilePath)) == 1;
|
||||
}
|
||||
|
||||
bool DeleteDirectory(const TString& rkDirPath, bool FailIfNotEmpty)
|
||||
|
@ -159,7 +163,7 @@ bool DeleteDirectory(const TString& rkDirPath, bool FailIfNotEmpty)
|
|||
|
||||
// Delete directory
|
||||
std::error_code Error;
|
||||
remove_all(*rkDirPath, Error);
|
||||
remove_all(ToPath(*rkDirPath), Error);
|
||||
return (Error.value() == 0);
|
||||
}
|
||||
|
||||
|
@ -200,12 +204,12 @@ bool ClearDirectory(const TString& rkDirPath)
|
|||
|
||||
u64 FileSize(const TString &rkFilePath)
|
||||
{
|
||||
return (u64) (Exists(rkFilePath) ? file_size(*rkFilePath) : -1);
|
||||
return (u64) (Exists(rkFilePath) ? file_size(ToPath(*rkFilePath)) : -1);
|
||||
}
|
||||
|
||||
u64 LastModifiedTime(const TString& rkFilePath)
|
||||
{
|
||||
return (u64) last_write_time(*rkFilePath).time_since_epoch().count();
|
||||
return (u64) last_write_time(ToPath(*rkFilePath)).time_since_epoch().count();
|
||||
}
|
||||
|
||||
TString WorkingDirectory()
|
||||
|
@ -215,7 +219,7 @@ TString WorkingDirectory()
|
|||
|
||||
TString MakeAbsolute(TString Path)
|
||||
{
|
||||
if (!path(*Path).has_root_name())
|
||||
if (!ToPath(*Path).has_root_name())
|
||||
Path = WorkingDirectory() + "/" + Path;
|
||||
|
||||
TStringList Components = Path.Split("/\\");
|
||||
|
@ -481,7 +485,7 @@ void GetDirectoryContents(TString DirPath, TStringList& rOut, bool Recursive /*=
|
|||
|
||||
if (Recursive)
|
||||
{
|
||||
for (recursive_directory_iterator It(*DirPath); It != recursive_directory_iterator(); ++It)
|
||||
for (recursive_directory_iterator It(ToPath(*DirPath)); It != recursive_directory_iterator(); ++It)
|
||||
{
|
||||
AddFileLambda(It->path().string());
|
||||
}
|
||||
|
@ -489,7 +493,7 @@ void GetDirectoryContents(TString DirPath, TStringList& rOut, bool Recursive /*=
|
|||
|
||||
else
|
||||
{
|
||||
for (directory_iterator It(*DirPath); It != directory_iterator(); ++It)
|
||||
for (directory_iterator It(ToPath(*DirPath)); It != directory_iterator(); ++It)
|
||||
{
|
||||
AddFileLambda(It->path().string());
|
||||
}
|
||||
|
@ -499,7 +503,7 @@ void GetDirectoryContents(TString DirPath, TStringList& rOut, bool Recursive /*=
|
|||
|
||||
TString FindFileExtension(const TString& rkDir, const TString& rkName)
|
||||
{
|
||||
for (directory_iterator It(*rkDir); It != directory_iterator(); ++It)
|
||||
for (directory_iterator It(ToPath(*rkDir)); It != directory_iterator(); ++It)
|
||||
{
|
||||
TString Name = It->path().filename().string();
|
||||
if (Name.GetFileName(false) == rkName) return Name.GetFileExtension();
|
||||
|
|
|
@ -20,7 +20,7 @@ public:
|
|||
: IArchive()
|
||||
, mOwnsStream(true)
|
||||
{
|
||||
mArchiveFlags = AF_Binary | AF_Reader;
|
||||
mArchiveFlags = AF_Binary | AF_Reader | AF_NoSkipping;
|
||||
mpStream = new CFileInStream(rkFilename, IOUtil::eBigEndian);
|
||||
|
||||
if (mpStream->IsValid())
|
||||
|
@ -35,7 +35,7 @@ public:
|
|||
, mMagicValid(true)
|
||||
, mOwnsStream(false)
|
||||
{
|
||||
mArchiveFlags = AF_Binary | AF_Reader;
|
||||
mArchiveFlags = AF_Binary | AF_Reader | AF_NoSkipping;
|
||||
|
||||
ASSERT(pStream->IsValid());
|
||||
mpStream = pStream;
|
||||
|
@ -47,7 +47,7 @@ public:
|
|||
, mMagicValid(true)
|
||||
, mOwnsStream(true)
|
||||
{
|
||||
mArchiveFlags = AF_Binary | AF_Reader;
|
||||
mArchiveFlags = AF_Binary | AF_Reader | AF_NoSkipping;
|
||||
mpStream = new CMemoryInStream(pData, DataSize, Endian);
|
||||
SetVersion(rkVersion);
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ public:
|
|||
, mMagic(Magic)
|
||||
, mOwnsStream(true)
|
||||
{
|
||||
mArchiveFlags = AF_Binary | AF_Writer;
|
||||
mArchiveFlags = AF_Binary | AF_Writer | AF_NoSkipping;
|
||||
mpStream = new CFileOutStream(rkFilename, IOUtil::eBigEndian);
|
||||
|
||||
if (mpStream->IsValid())
|
||||
|
@ -36,7 +36,7 @@ public:
|
|||
, mOwnsStream(false)
|
||||
{
|
||||
ASSERT(pStream->IsValid());
|
||||
mArchiveFlags = AF_Binary | AF_Writer;
|
||||
mArchiveFlags = AF_Binary | AF_Writer | AF_NoSkipping;
|
||||
mpStream = pStream;
|
||||
SetVersion(skCurrentArchiveVersion, FileVersion, Game);
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ public:
|
|||
, mOwnsStream(false)
|
||||
{
|
||||
ASSERT(pStream->IsValid());
|
||||
mArchiveFlags = AF_Binary | AF_Writer;
|
||||
mArchiveFlags = AF_Binary | AF_Writer | AF_NoSkipping;
|
||||
mpStream = pStream;
|
||||
SetVersion(rkVersion);
|
||||
}
|
||||
|
|
|
@ -17,12 +17,6 @@ CResTypeInfo::CResTypeInfo(EResType Type, const TString& rkTypeName, const TStri
|
|||
smTypeMap[Type] = this;
|
||||
}
|
||||
|
||||
CResTypeInfo::~CResTypeInfo()
|
||||
{
|
||||
// shouldn't happen - we want to just create these at launch and keep them around forever
|
||||
ASSERT(false);
|
||||
}
|
||||
|
||||
bool CResTypeInfo::IsInGame(EGame Game) const
|
||||
{
|
||||
for (u32 iGame = 0; iGame < mCookedExtensions.size(); iGame++)
|
||||
|
|
|
@ -28,7 +28,7 @@ class CResTypeInfo
|
|||
|
||||
// Private Methods
|
||||
CResTypeInfo(EResType Type, const TString& rkTypeName, const TString& rkRetroExtension);
|
||||
~CResTypeInfo();
|
||||
~CResTypeInfo() {}
|
||||
|
||||
// Public Methods
|
||||
public:
|
||||
|
|
|
@ -55,6 +55,7 @@ void CGameTemplate::Load(const TString& kFilePath)
|
|||
|
||||
void CGameTemplate::Save()
|
||||
{
|
||||
Log::Write("Saving game template: " + mSourceFile);
|
||||
CXMLWriter Writer(mSourceFile, "Game", 0, mGame);
|
||||
ASSERT(Writer.IsValid());
|
||||
Serialize(Writer);
|
||||
|
@ -108,6 +109,7 @@ void CGameTemplate::SaveGameTemplates(bool ForceAll /*= false*/)
|
|||
const TString kOutPath = kGameDir + Path.Path;
|
||||
FileUtil::MakeDirectory( kOutPath.GetFileDirectory() );
|
||||
|
||||
Log::Write("Saving property template: " + kOutPath);
|
||||
CXMLWriter Writer(kOutPath, "PropertyTemplate", 0, Game());
|
||||
ASSERT(Writer.IsValid());
|
||||
|
||||
|
|
|
@ -96,8 +96,9 @@ void CScriptTemplate::Serialize(IArchive& Arc)
|
|||
|
||||
void CScriptTemplate::Save(bool Force)
|
||||
{
|
||||
if (mDirty || Force)
|
||||
if (IsDirty() || Force)
|
||||
{
|
||||
Log::Write("Saving script template: " + mSourceFile);
|
||||
CXMLWriter Writer(mSourceFile, "ScriptObject", 0, mpGame->Game());
|
||||
ASSERT(Writer.IsValid());
|
||||
Serialize(Writer);
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "NGameList.h"
|
||||
#include <Common/Log.h>
|
||||
|
||||
namespace NGameList
|
||||
{
|
||||
|
@ -85,6 +86,7 @@ inline void SerializeGameList(IArchive& Arc)
|
|||
void LoadGameList()
|
||||
{
|
||||
ASSERT(!gLoadedGameList);
|
||||
Log::Write("Loading game list");
|
||||
|
||||
CXMLReader Reader(gkGameListPath);
|
||||
ASSERT(Reader.IsValid());
|
||||
|
@ -97,6 +99,7 @@ void LoadGameList()
|
|||
void SaveGameList()
|
||||
{
|
||||
ASSERT(gLoadedGameList);
|
||||
Log::Write("Saving game list");
|
||||
|
||||
CXMLWriter Writer(gkGameListPath, "GameList");
|
||||
ASSERT(Writer.IsValid());
|
||||
|
|
|
@ -132,10 +132,16 @@ SNameKey CreateKey(IProperty* pProperty)
|
|||
return Key;
|
||||
}
|
||||
|
||||
SNameKey CreateKey(u32 ID, const char* pkTypeName)
|
||||
{
|
||||
return SNameKey( CCRC32::StaticHashString(pkTypeName), ID );
|
||||
}
|
||||
|
||||
/** Loads property names into memory */
|
||||
void LoadMap()
|
||||
{
|
||||
ASSERT( !gMapIsLoaded );
|
||||
Log::Write("Loading property map");
|
||||
|
||||
if ( gkUseLegacyMapForNameLookups )
|
||||
{
|
||||
|
@ -165,6 +171,7 @@ inline void ConditionalLoadMap()
|
|||
void SaveMap(bool Force /*= false*/)
|
||||
{
|
||||
ASSERT( gMapIsLoaded );
|
||||
Log::Write("Saving property map");
|
||||
|
||||
if( gMapIsDirty || Force )
|
||||
{
|
||||
|
@ -210,21 +217,67 @@ const char* GetPropertyName(u32 ID, const char* pkTypeName)
|
|||
// Does not support legacy map
|
||||
ConditionalLoadMap();
|
||||
|
||||
SNameKey Key( CCRC32::StaticHashString(pkTypeName), ID );
|
||||
SNameKey Key = CreateKey(ID, pkTypeName);
|
||||
auto MapFind = gNameMap.find(Key);
|
||||
return MapFind == gNameMap.end() ? "Unknown" : *MapFind->second.Name;
|
||||
}
|
||||
|
||||
|
||||
/** Returns whether the specified name is in the map. */
|
||||
bool IsValidPropertyName(u32 ID, const char* pkTypeName)
|
||||
{
|
||||
SNameKey Key = CreateKey(ID, pkTypeName);
|
||||
auto MapFind = gNameMap.find(Key);
|
||||
return MapFind != gNameMap.end();
|
||||
}
|
||||
|
||||
/** Retrieves a list of all properties that match the requested property ID. */
|
||||
void RetrievePropertiesWithID(u32 ID, const char* pkTypeName, std::list<IProperty*>& OutList)
|
||||
{
|
||||
SNameKey Key = CreateKey(ID, pkTypeName);
|
||||
auto MapFind = gNameMap.find(Key);
|
||||
|
||||
if (MapFind != gNameMap.end())
|
||||
{
|
||||
SNameValue& Value = MapFind->second;
|
||||
OutList = Value.PropertyList;
|
||||
}
|
||||
}
|
||||
|
||||
/** Retrieves a list of all XML templates that contain a given property ID. */
|
||||
void RetrieveXMLsWithProperty(u32 ID, const char* pkTypeName, std::set<TString>& OutSet)
|
||||
{
|
||||
SNameKey Key = CreateKey(ID, pkTypeName);
|
||||
auto MapFind = gNameMap.find(Key);
|
||||
|
||||
if (MapFind != gNameMap.end())
|
||||
{
|
||||
SNameValue& NameValue = MapFind->second;
|
||||
|
||||
for (auto ListIter = NameValue.PropertyList.begin(); ListIter != NameValue.PropertyList.end(); ListIter++)
|
||||
{
|
||||
IProperty* pProperty = *ListIter;
|
||||
OutSet.insert( pProperty->GetTemplateFileName() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Updates the name of a given property in the map */
|
||||
void SetPropertyName(IProperty* pProperty, const char* pkNewName)
|
||||
void SetPropertyName(u32 ID, const char* pkTypeName, const char* pkNewName)
|
||||
{
|
||||
if( gkUseLegacyMapForUpdates )
|
||||
{
|
||||
gLegacyNameMap[pProperty->ID()] = pkNewName;
|
||||
auto Iter = gLegacyNameMap.find(ID);
|
||||
|
||||
if (Iter == gLegacyNameMap.end() || Iter->second != pkNewName)
|
||||
{
|
||||
Iter->second = pkNewName;
|
||||
gMapIsDirty = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SNameKey Key = CreateKey(pProperty);
|
||||
SNameKey Key = CreateKey(ID, pkTypeName);
|
||||
auto MapFind = gNameMap.find(Key);
|
||||
|
||||
if (MapFind != gNameMap.end())
|
||||
|
@ -235,6 +288,7 @@ void SetPropertyName(IProperty* pProperty, const char* pkNewName)
|
|||
{
|
||||
TString OldName = Value.Name;
|
||||
Value.Name = pkNewName;
|
||||
gMapIsDirty = true;
|
||||
|
||||
// Update all properties with this ID with the new name
|
||||
for (auto Iter = Value.PropertyList.begin(); Iter != Value.PropertyList.end(); Iter++)
|
||||
|
@ -250,8 +304,6 @@ void SetPropertyName(IProperty* pProperty, const char* pkNewName)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
gMapIsDirty = true;
|
||||
}
|
||||
|
||||
/** Registers a property in the name map. Should be called on all properties that use the map */
|
||||
|
|
|
@ -22,8 +22,17 @@ const char* GetPropertyName(IProperty* pProperty);
|
|||
*/
|
||||
const char* GetPropertyName(u32 ID, const char* pkTypeName);
|
||||
|
||||
/** Returns whether the specified name is in the map. */
|
||||
bool IsValidPropertyName(u32 ID, const char* pkTypeName);
|
||||
|
||||
/** Retrieves a list of all properties that match the requested property ID. */
|
||||
void RetrievePropertiesWithID(u32 ID, const char* pkTypeName, std::list<IProperty*>& OutList);
|
||||
|
||||
/** Retrieves a list of all XML templates that contain a given property ID. */
|
||||
void RetrieveXMLsWithProperty(u32 ID, const char* pkTypeName, std::set<TString>& OutSet);
|
||||
|
||||
/** Updates the name of a given property in the map */
|
||||
void SetPropertyName(IProperty* pProperty, const char* pkNewName);
|
||||
void SetPropertyName(u32 ID, const char* pkTypeName, const char* pkNewName);
|
||||
|
||||
/** Registers a property in the name map. Should be called on all properties that use the map */
|
||||
void RegisterProperty(IProperty* pProperty);
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include "IUIRelay.h"
|
||||
#include "Core/Resource/Factory/CTemplateLoader.h"
|
||||
#include "Core/Resource/Script/CGameTemplate.h"
|
||||
#include "Core/Resource/Script/NPropertyMap.h"
|
||||
#include <Common/Hash/CCRC32.h>
|
||||
|
||||
/** Default constructor */
|
||||
|
@ -146,17 +147,16 @@ void CPropertyNameGenerator::Generate(const SPropertyNameGenerationParameters& r
|
|||
for (int TypeIdx = 0; TypeIdx < rkParams.TypeNames.size(); TypeIdx++)
|
||||
{
|
||||
CCRC32 FullHash = BaseHash;
|
||||
FullHash.Hash( *rkParams.TypeNames[TypeIdx] );
|
||||
const char* pkTypeName = *rkParams.TypeNames[TypeIdx];
|
||||
FullHash.Hash( pkTypeName );
|
||||
u32 PropertyID = FullHash.Digest();
|
||||
|
||||
//@FIXME
|
||||
#if 0
|
||||
// Check if this hash is a property ID - it's valid if there are any XMLs using this ID
|
||||
SGeneratedPropertyName PropertyName;
|
||||
CGameTemplate::XMLsUsingID(PropertyID, PropertyName.XmlList);
|
||||
|
||||
if (PropertyName.XmlList.size() > 0)
|
||||
// Check if this hash is a property ID
|
||||
if (NPropertyMap::IsValidPropertyName(PropertyID, pkTypeName))
|
||||
{
|
||||
SGeneratedPropertyName PropertyName;
|
||||
NPropertyMap::RetrieveXMLsWithProperty(PropertyID, pkTypeName, PropertyName.XmlList);
|
||||
|
||||
// Generate a string with the complete name. (We wait to do this until now to avoid needless string allocation)
|
||||
PropertyName.Name = rkParams.Prefix;
|
||||
|
||||
|
@ -195,16 +195,15 @@ void CPropertyNameGenerator::Generate(const SPropertyNameGenerationParameters& r
|
|||
{
|
||||
TString DelimitedXmlList;
|
||||
|
||||
for (int XmlIdx = 0; XmlIdx < PropertyName.XmlList.size(); XmlIdx++)
|
||||
for (auto Iter = PropertyName.XmlList.begin(); Iter != PropertyName.XmlList.end(); Iter++)
|
||||
{
|
||||
DelimitedXmlList += PropertyName.XmlList[XmlIdx] + "\n";
|
||||
DelimitedXmlList += *Iter + "\n";
|
||||
}
|
||||
|
||||
TString LogMsg = TString::Format("%s [%s] : 0x%08X\n", *PropertyName.Name, *PropertyName.Type, PropertyName.ID) + DelimitedXmlList;
|
||||
Log::Write(LogMsg);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Every 250 tests, check with the progress notifier. Update the progress
|
||||
|
|
|
@ -32,7 +32,7 @@ struct SGeneratedPropertyName
|
|||
TString Name;
|
||||
TString Type;
|
||||
u32 ID;
|
||||
std::vector<TString> XmlList;
|
||||
std::set<TString> XmlList;
|
||||
};
|
||||
|
||||
/** Generates property names and validates them against know property IDs. */
|
||||
|
|
|
@ -275,15 +275,35 @@ IProperty* IProperty::ChildByIDString(const TIDString& rkIdString)
|
|||
|
||||
TString IProperty::GetTemplateFileName()
|
||||
{
|
||||
if (mpScriptTemplate)
|
||||
// We want to return the path to the XML file that this property originally belongs to.
|
||||
// So, for example, if this is a property of a script template, we want to return that script template.
|
||||
// However, if this property was copied from a property archetype... If we are a direct instance of an
|
||||
// archetype property (for instance a DamageInfo struct instance), then we want to return the template
|
||||
// that contains the instance. However, if we are a sub-property of an archetype, then we want to return
|
||||
// the path to that archetype instead. Hopefully that makes sense!
|
||||
IProperty* pTemplateRoot = this;
|
||||
|
||||
// If our archetype has a parent, then our archetype is a sub-property of the main archetype, and we
|
||||
// need to go deeper to find the original source XML file.
|
||||
//
|
||||
// If our archetype doesn't have a parent, then we are an instance of the main archetype, and we stop here.
|
||||
while (pTemplateRoot->Archetype() && pTemplateRoot->Archetype()->Parent())
|
||||
{
|
||||
return mpScriptTemplate->SourceFile();
|
||||
pTemplateRoot = pTemplateRoot->Archetype();
|
||||
}
|
||||
pTemplateRoot = pTemplateRoot->RootParent();
|
||||
|
||||
// Now that we have the base property of our template, we can return the file path.
|
||||
static const u32 kChopAmount = strlen("../templates/");
|
||||
|
||||
if (pTemplateRoot->ScriptTemplate())
|
||||
{
|
||||
return pTemplateRoot->ScriptTemplate()->SourceFile().ChopFront(kChopAmount);
|
||||
}
|
||||
else
|
||||
{
|
||||
CGameTemplate* pGameTemplate = NGameList::GetGameTemplate(Game());
|
||||
IProperty* pTemplateRoot = (IsArchetype() ? RootParent() : mpArchetype);
|
||||
return pGameTemplate->GetPropertyArchetypeFilePath( pTemplateRoot->Name() );
|
||||
return pGameTemplate->GetPropertyArchetypeFilePath( pTemplateRoot->Name() ).ChopFront(kChopAmount);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -304,27 +324,36 @@ bool IProperty::ShouldCook(void* pPropertyData) const
|
|||
|
||||
void IProperty::SetName(const TString& rkNewName)
|
||||
{
|
||||
mName = rkNewName;
|
||||
mFlags.ClearFlag(EPropertyFlag::HasCachedNameCheck);
|
||||
|
||||
// in Echoes and on, since property names are referenced by ID, renaming a property
|
||||
// doesn't directly affect the serialized data, so it doesn't need to be flagged dirty
|
||||
if (mGame <= EGame::Prime)
|
||||
if (mName != rkNewName)
|
||||
{
|
||||
MarkDirty();
|
||||
mName = rkNewName;
|
||||
mFlags.ClearFlag(EPropertyFlag::HasCachedNameCheck);
|
||||
|
||||
// in Echoes and on, since property names are referenced by ID, renaming a property
|
||||
// doesn't directly affect the serialized data, so it doesn't need to be flagged dirty
|
||||
if (mGame <= EGame::Prime)
|
||||
{
|
||||
MarkDirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void IProperty::SetDescription(const TString& rkNewDescription)
|
||||
{
|
||||
mDescription = rkNewDescription;
|
||||
MarkDirty();
|
||||
if (mDescription != rkNewDescription)
|
||||
{
|
||||
mDescription = rkNewDescription;
|
||||
MarkDirty();
|
||||
}
|
||||
}
|
||||
|
||||
void IProperty::SetSuffix(const TString& rkNewSuffix)
|
||||
{
|
||||
mSuffix = rkNewSuffix;
|
||||
MarkDirty();
|
||||
if (mSuffix != rkNewSuffix)
|
||||
{
|
||||
mSuffix = rkNewSuffix;
|
||||
MarkDirty();
|
||||
}
|
||||
}
|
||||
|
||||
void IProperty::MarkDirty()
|
||||
|
|
|
@ -211,6 +211,7 @@ public:
|
|||
inline IProperty* Parent() const;
|
||||
inline IProperty* RootParent();
|
||||
inline IProperty* Archetype() const;
|
||||
inline IProperty* RootArchetype();
|
||||
inline CScriptTemplate* ScriptTemplate() const;
|
||||
inline TString Name() const;
|
||||
inline TString Description() const;
|
||||
|
@ -286,6 +287,20 @@ inline IProperty* IProperty::Archetype() const
|
|||
return mpArchetype;
|
||||
}
|
||||
|
||||
inline IProperty* IProperty::RootArchetype()
|
||||
{
|
||||
IProperty* pArchetype = Archetype();
|
||||
IProperty* pOut = this;
|
||||
|
||||
while (pArchetype)
|
||||
{
|
||||
pOut = pArchetype;
|
||||
pArchetype = pArchetype->Archetype();
|
||||
}
|
||||
|
||||
return pOut;
|
||||
}
|
||||
|
||||
inline CScriptTemplate* IProperty::ScriptTemplate() const
|
||||
{
|
||||
return mpScriptTemplate;
|
||||
|
|
|
@ -225,13 +225,11 @@ void CGeneratePropertyNamesDialog::ApplyChanges()
|
|||
{
|
||||
QTreeWidgetItem* pItem = mCheckedItems[ItemIdx];
|
||||
u32 ID = TO_TSTRING( pItem->text(2) ).ToInt32();
|
||||
TString Type = TO_TSTRING( pItem->text(1) );
|
||||
TString NewName = TO_TSTRING( pItem->text(0) );
|
||||
|
||||
//FIXME
|
||||
#if 0
|
||||
QString NewName = pItem->text(0);
|
||||
NPropertyMap::SetPropertyName(::RenameProperty( ID, TO_TSTRING(NewName) );
|
||||
pItem->setText(3, NewName);
|
||||
#endif
|
||||
NPropertyMap::SetPropertyName( ID, *Type, *NewName );
|
||||
pItem->setText( 3, TO_QSTRING(NewName) );
|
||||
}
|
||||
|
||||
NPropertyMap::SaveMap();
|
||||
|
@ -270,9 +268,9 @@ void CGeneratePropertyNamesDialog::CheckForNewResults()
|
|||
pItem->setCheckState(0, Qt::Unchecked);
|
||||
|
||||
// Add children items
|
||||
for (int XmlIdx = 0; XmlIdx < rkName.XmlList.size(); XmlIdx++)
|
||||
for (auto Iter = rkName.XmlList.begin(); Iter != rkName.XmlList.end(); Iter++)
|
||||
{
|
||||
QString XmlName = TO_QSTRING( rkName.XmlList[XmlIdx] );
|
||||
QString XmlName = TO_QSTRING( *Iter );
|
||||
ColumnText.clear();
|
||||
ColumnText << XmlName;
|
||||
|
||||
|
|
|
@ -36,14 +36,11 @@ CTemplateEditDialog::CTemplateEditDialog(IProperty *pProperty, QWidget *pParent)
|
|||
{
|
||||
NGameList::LoadAllGameTemplates();
|
||||
|
||||
//@FIXME
|
||||
#if 0
|
||||
std::vector<TString> TemplateList;
|
||||
CGameTemplate::XMLsUsingID(pProperty->ID(), TemplateList);
|
||||
std::set<TString> Templates;
|
||||
NPropertyMap::RetrieveXMLsWithProperty( pProperty->ID(), pProperty->HashableTypeName(), Templates );
|
||||
|
||||
for (u32 iTemp = 0; iTemp < TemplateList.size(); iTemp++)
|
||||
mpUI->TemplatesListWidget->addItem(TO_QSTRING(TemplateList[iTemp]));
|
||||
#endif
|
||||
for (auto Iter = Templates.begin(); Iter != Templates.end(); Iter++)
|
||||
mpUI->TemplatesListWidget->addItem(TO_QSTRING(*Iter));
|
||||
|
||||
mpUI->ValidityLabel->SetValidityText("Hash match! Property name is likely correct.", "Hash mismatch! Property name is likely wrong.");
|
||||
connect(mpUI->NameLineEdit, SIGNAL( SoftValidityChanged(bool) ), mpUI->ValidityLabel, SLOT( SetValid(bool) ) );
|
||||
|
@ -94,7 +91,7 @@ void CTemplateEditDialog::ApplyChanges()
|
|||
// Rename properties
|
||||
if (RenameAll && (mGame >= EGame::EchoesDemo || mpProperty->Archetype() != nullptr))
|
||||
{
|
||||
NPropertyMap::SetPropertyName(mpProperty, *NewName);
|
||||
NPropertyMap::SetPropertyName(mpProperty->ID(), mpProperty->HashableTypeName(), *NewName);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -102,10 +99,8 @@ void CTemplateEditDialog::ApplyChanges()
|
|||
UpdateDescription(NewDescription);
|
||||
|
||||
// Resave templates
|
||||
NGameList::SaveTemplates();
|
||||
NPropertyMap::SaveMap();
|
||||
CGameTemplate* pGameTemplate = NGameList::GetGameTemplate( mpProperty->Game() );
|
||||
pGameTemplate->SaveGameTemplates();
|
||||
|
||||
close();
|
||||
}
|
||||
|
||||
|
@ -115,23 +110,19 @@ void CTemplateEditDialog::UpdateDescription(const TString& rkNewDesc)
|
|||
mpProperty->SetDescription(rkNewDesc);
|
||||
|
||||
// Update all copies of this property in memory with the new description
|
||||
//@FIXME
|
||||
#if 0
|
||||
TString SourceFile = mpProperty->GetTemplateFileName();
|
||||
|
||||
if (!SourceFile.IsEmpty())
|
||||
{
|
||||
const std::vector<IProperty*>* pkTemplates = CGameTemplate::TemplatesWithMatchingID(mpProperty);
|
||||
std::list<IProperty*> Templates;
|
||||
NPropertyMap::RetrievePropertiesWithID(mpProperty->ID(), mpProperty->HashableTypeName(), Templates);
|
||||
|
||||
if (pkTemplates)
|
||||
for (auto Iter = Templates.begin(); Iter != Templates.end(); Iter++)
|
||||
{
|
||||
for (u32 TemplateIdx = 0; TemplateIdx < pkTemplates->size(); TemplateIdx++)
|
||||
{
|
||||
IProperty* pProp = pkTemplates->at(TemplateIdx);
|
||||
IProperty* pProperty = *Iter;
|
||||
|
||||
if (pProp->GetTemplateFileName() == SourceFile && pProp->Description() == mOriginalDescription)
|
||||
pProp->SetDescription(rkNewDesc);
|
||||
}
|
||||
if (pProperty->GetTemplateFileName() == SourceFile && pProperty->Description() == mOriginalDescription)
|
||||
pProperty->SetDescription(rkNewDesc);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -140,73 +131,60 @@ void CTemplateEditDialog::UpdateDescription(const TString& rkNewDesc)
|
|||
{
|
||||
pProperty->SetDescription(rkNewDesc);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void CTemplateEditDialog::FindEquivalentProperties(IProperty *pTemp)
|
||||
void CTemplateEditDialog::FindEquivalentProperties(IProperty* pProperty)
|
||||
{
|
||||
//FIXME
|
||||
/*
|
||||
// This function creates a list of properties in other games that are equivalent to this one.
|
||||
// In this case "equivalent" means same template file and same ID string.
|
||||
// Since MP1 doesn't have property IDs, we don't apply this to MP1.
|
||||
if (mGame <= EGame::Prime) return;
|
||||
|
||||
// Find the equivalent version of this property in other games.
|
||||
CScriptTemplate *pScript = pTemp->ScriptTemplate();
|
||||
TString Source = pTemp->FindStructSource();
|
||||
|
||||
// Determine struct-relative ID string
|
||||
TIDString IDString;
|
||||
|
||||
if (Source.IsEmpty())
|
||||
IDString = pTemp->IDString(true);
|
||||
|
||||
else
|
||||
// Find the lowest-level archetype and retrieve the ID string relative to that archetype's XML file.
|
||||
while (pProperty->Archetype())
|
||||
{
|
||||
IDString = pTemp->IDString(false);
|
||||
CStructTemplate *pParent = pTemp->Parent();
|
||||
|
||||
while (pParent)
|
||||
{
|
||||
if (!pParent->SourceFile().IsEmpty()) break;
|
||||
IDString.Prepend(pParent->IDString(false) + ":");
|
||||
pParent = pParent->Parent();
|
||||
}
|
||||
pProperty = pProperty->Archetype();
|
||||
}
|
||||
TString Name = pProperty->Name();
|
||||
TIDString IDString = pProperty->IDString(true);
|
||||
CScriptTemplate* pScript = pProperty->ScriptTemplate();
|
||||
|
||||
QList<CGameTemplate*> GameList = QList<CGameTemplate*>::fromStdList(CGameTemplate::GameList());
|
||||
|
||||
if (Source.IsEmpty())
|
||||
// Now iterate over all games, check for an equivalent property in an equivalent XML file.
|
||||
for (int GameIdx = 0; GameIdx < (int) EGame::Max; GameIdx++)
|
||||
{
|
||||
u32 ObjectID = pScript->ObjectID();
|
||||
EGame Game = (EGame) GameIdx;
|
||||
if (Game <= EGame::Prime || Game == mGame) continue;
|
||||
|
||||
foreach (CGameTemplate *pGame, GameList)
|
||||
CGameTemplate* pGame = NGameList::GetGameTemplate(Game);
|
||||
|
||||
// Check for equivalent properties in a script template
|
||||
CStructProperty* pStruct = nullptr;
|
||||
|
||||
if (pScript)
|
||||
{
|
||||
if (pGame == pTemp->GameTemplate() || pGame->Game() <= EGame::Prime) continue;
|
||||
CScriptTemplate *pNewScript = pGame->TemplateByID(ObjectID);
|
||||
u32 ObjectID = pScript->ObjectID();
|
||||
CScriptTemplate* pEquivalentScript = pGame->TemplateByID(ObjectID);
|
||||
|
||||
if (pNewScript)
|
||||
if (pEquivalentScript)
|
||||
{
|
||||
IPropertyTemplate *pNewTemp = pNewScript->BaseStruct()->PropertyByIDString(IDString);
|
||||
pStruct = pEquivalentScript->Properties();
|
||||
}
|
||||
}
|
||||
// Check for equivalent properties in a property template
|
||||
else
|
||||
{
|
||||
pStruct = TPropCast<CStructProperty>( pGame->FindPropertyArchetype(Name) );
|
||||
}
|
||||
|
||||
if (pNewTemp)
|
||||
mEquivalentProperties << pNewTemp;
|
||||
// If we have a struct, check if thestruct contains an equivalent property.
|
||||
if (pStruct)
|
||||
{
|
||||
IProperty* pEquivalentProperty = pStruct->ChildByIDString( IDString );
|
||||
|
||||
if (pEquivalentProperty)
|
||||
{
|
||||
mEquivalentProperties << pEquivalentProperty;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
foreach (CGameTemplate *pGame, GameList)
|
||||
{
|
||||
if (pGame == pTemp->GameTemplate() || pGame->Game() <= EGame::Prime) continue;
|
||||
CStructTemplate *pStruct = pGame->StructAtSource(Source);
|
||||
|
||||
if (pStruct)
|
||||
{
|
||||
IPropertyTemplate *pNewTemp = pStruct->PropertyByIDString(IDString);
|
||||
|
||||
if (pNewTemp)
|
||||
mEquivalentProperties << pNewTemp;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ public slots:
|
|||
|
||||
protected:
|
||||
void UpdateDescription(const TString& rkNewDesc);
|
||||
void FindEquivalentProperties(IProperty *pTemp);
|
||||
void FindEquivalentProperties(IProperty *pProperty);
|
||||
};
|
||||
|
||||
#endif // CTEMPLATEEDITDIALOG_H
|
||||
|
|
|
@ -23,58 +23,78 @@ void QtLogRedirect(QtMsgType Type, const QMessageLogContext& /*rkContext*/, cons
|
|||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
class CMain
|
||||
{
|
||||
// Create application
|
||||
QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
|
||||
CEditorApplication App(argc, argv);
|
||||
App.setApplicationName( APP_NAME );
|
||||
App.setApplicationVersion( APP_VERSION );
|
||||
App.setOrganizationName("Aruki");
|
||||
App.setWindowIcon(QIcon(":/icons/AppIcon.ico"));
|
||||
|
||||
// Create UI relay
|
||||
CUIRelay UIRelay(&App);
|
||||
gpUIRelay = &UIRelay;
|
||||
|
||||
// Set up dark theme
|
||||
qApp->setStyle(QStyleFactory::create("Fusion"));
|
||||
QPalette DarkPalette;
|
||||
DarkPalette.setColor(QPalette::Window, QColor(53,53,53));
|
||||
DarkPalette.setColor(QPalette::WindowText, Qt::white);
|
||||
DarkPalette.setColor(QPalette::Base, QColor(25,25,25));
|
||||
DarkPalette.setColor(QPalette::AlternateBase, QColor(35,35,35));
|
||||
DarkPalette.setColor(QPalette::ToolTipBase, Qt::white);
|
||||
DarkPalette.setColor(QPalette::ToolTipText, Qt::white);
|
||||
DarkPalette.setColor(QPalette::Text, Qt::white);
|
||||
DarkPalette.setColor(QPalette::Button, QColor(53,53,53));
|
||||
DarkPalette.setColor(QPalette::ButtonText, Qt::white);
|
||||
DarkPalette.setColor(QPalette::BrightText, Qt::red);
|
||||
DarkPalette.setColor(QPalette::Link, QColor(42, 130, 218));
|
||||
DarkPalette.setColor(QPalette::Highlight, QColor(42, 130, 218));
|
||||
DarkPalette.setColor(QPalette::HighlightedText, Qt::white);
|
||||
qApp->setPalette(DarkPalette);
|
||||
|
||||
// Init log
|
||||
bool Initialized = Log::InitLog("primeworldeditor.log");
|
||||
if (!Initialized) QMessageBox::warning(0, "Error", "Couldn't open log file. Logging will not work for this session.");
|
||||
qInstallMessageHandler(QtLogRedirect);
|
||||
|
||||
// Create editor resource store
|
||||
gpEditorStore = new CResourceStore("../resources/");
|
||||
|
||||
if (!gpEditorStore->AreAllEntriesValid())
|
||||
public:
|
||||
/** Main function */
|
||||
int Main(int argc, char *argv[])
|
||||
{
|
||||
Log::Write("Editor store has invalid entries. Rebuilding database...");
|
||||
gpEditorStore->RebuildFromDirectory();
|
||||
gpEditorStore->ConditionalSaveStore();
|
||||
// Create application
|
||||
QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
|
||||
CEditorApplication App(argc, argv);
|
||||
App.setApplicationName( APP_NAME );
|
||||
App.setApplicationVersion( APP_VERSION );
|
||||
App.setOrganizationName("Aruki");
|
||||
App.setWindowIcon(QIcon(":/icons/AppIcon.ico"));
|
||||
|
||||
// Create UI relay
|
||||
CUIRelay UIRelay(&App);
|
||||
gpUIRelay = &UIRelay;
|
||||
|
||||
// Set up dark theme
|
||||
qApp->setStyle(QStyleFactory::create("Fusion"));
|
||||
QPalette DarkPalette;
|
||||
DarkPalette.setColor(QPalette::Window, QColor(53,53,53));
|
||||
DarkPalette.setColor(QPalette::WindowText, Qt::white);
|
||||
DarkPalette.setColor(QPalette::Base, QColor(25,25,25));
|
||||
DarkPalette.setColor(QPalette::AlternateBase, QColor(35,35,35));
|
||||
DarkPalette.setColor(QPalette::ToolTipBase, Qt::white);
|
||||
DarkPalette.setColor(QPalette::ToolTipText, Qt::white);
|
||||
DarkPalette.setColor(QPalette::Text, Qt::white);
|
||||
DarkPalette.setColor(QPalette::Button, QColor(53,53,53));
|
||||
DarkPalette.setColor(QPalette::ButtonText, Qt::white);
|
||||
DarkPalette.setColor(QPalette::BrightText, Qt::red);
|
||||
DarkPalette.setColor(QPalette::Link, QColor(42, 130, 218));
|
||||
DarkPalette.setColor(QPalette::Highlight, QColor(42, 130, 218));
|
||||
DarkPalette.setColor(QPalette::HighlightedText, Qt::white);
|
||||
qApp->setPalette(DarkPalette);
|
||||
|
||||
// Init log
|
||||
bool Initialized = Log::InitLog("primeworldeditor.log");
|
||||
if (!Initialized) QMessageBox::warning(0, "Error", "Couldn't open log file. Logging will not work for this session.");
|
||||
qInstallMessageHandler(QtLogRedirect);
|
||||
|
||||
// Create editor resource store
|
||||
gpEditorStore = new CResourceStore("../resources/");
|
||||
|
||||
if (!gpEditorStore->AreAllEntriesValid())
|
||||
{
|
||||
Log::Write("Editor store has invalid entries. Rebuilding database...");
|
||||
gpEditorStore->RebuildFromDirectory();
|
||||
gpEditorStore->ConditionalSaveStore();
|
||||
}
|
||||
|
||||
for (int i = 0; i < (int) EGame::Max; i++)
|
||||
{
|
||||
CGameTemplate* pGame = NGameList::GetGameTemplate( (EGame) i );
|
||||
if (pGame) pGame->Save();
|
||||
}
|
||||
return 0;
|
||||
|
||||
// Execute application
|
||||
App.InitEditor();
|
||||
return App.exec();
|
||||
}
|
||||
|
||||
// Execute application
|
||||
App.InitEditor();
|
||||
int ReturnValue = App.exec();
|
||||
/** Clean up any resources at the end of application execution */
|
||||
~CMain()
|
||||
{
|
||||
NGameList::Shutdown();
|
||||
}
|
||||
};
|
||||
|
||||
// Clean up
|
||||
NGameList::Shutdown();
|
||||
return ReturnValue;
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
CMain Main;
|
||||
return Main.Main(argc, argv);
|
||||
}
|
||||
|
|
|
@ -659,6 +659,10 @@
|
|||
<Key>ActorMultiKeyframeStruct</Key>
|
||||
<Value Path="Structs/ActorMultiKeyframeStruct.xml"/>
|
||||
</Element>
|
||||
<Element>
|
||||
<Key>ActivationTime</Key>
|
||||
<Value Path="Structs/ActivationTime.xml"/>
|
||||
</Element>
|
||||
<Element>
|
||||
<Key>ActorParameters</Key>
|
||||
<Value Path="Structs/ActorParameters.xml"/>
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<PropertyTemplate ArchiveVer="4" Game="DKCReturns">
|
||||
<PropertyArchetype Type="Struct">
|
||||
<Name>ActivationTime</Name>
|
||||
<Atomic>true</Atomic>
|
||||
<SubProperties>
|
||||
<Element Type="Float" ID="0x0">
|
||||
<Name>Time</Name>
|
||||
<DefaultValue>0.0</DefaultValue>
|
||||
</Element>
|
||||
<Element Type="Int" ID="0x1">
|
||||
<Name>Unknown 1</Name>
|
||||
<DefaultValue>0</DefaultValue>
|
||||
</Element>
|
||||
<Element Type="Int" ID="0x2">
|
||||
<Name>Unknown 2</Name>
|
||||
<DefaultValue>0</DefaultValue>
|
||||
</Element>
|
||||
<Element Type="Int" ID="0x3">
|
||||
<Name>Unknown 3</Name>
|
||||
<DefaultValue>0</DefaultValue>
|
||||
</Element>
|
||||
</SubProperties>
|
||||
</PropertyArchetype>
|
||||
</PropertyTemplate>
|
|
@ -10,10 +10,7 @@
|
|||
</Element>
|
||||
<Element Type="Array" ID="0x1">
|
||||
<Name>Activation Times</Name>
|
||||
<ItemArchetype Type="Float" ID="0x0">
|
||||
<Name></Name>
|
||||
<DefaultValue>0.0</DefaultValue>
|
||||
</ItemArchetype>
|
||||
<ItemArchetype Type="Struct" Archetype="ActivationTime"/>
|
||||
</Element>
|
||||
</SubProperties>
|
||||
</PropertyArchetype>
|
||||
|
|
|
@ -839,6 +839,10 @@
|
|||
<Key>Abilities</Key>
|
||||
<Value Path="Structs/Abilities.xml"/>
|
||||
</Element>
|
||||
<Element>
|
||||
<Key>ActivationTime</Key>
|
||||
<Value Path="Structs/ActivationTime.xml"/>
|
||||
</Element>
|
||||
<Element>
|
||||
<Key>ActorParameters</Key>
|
||||
<Value Path="Structs/ActorParameters.xml"/>
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<PropertyTemplate ArchiveVer="4" Game="Corruption">
|
||||
<PropertyArchetype Type="Struct">
|
||||
<Name>ActivationTime</Name>
|
||||
<Atomic>true</Atomic>
|
||||
<SubProperties>
|
||||
<Element Type="Float" ID="0x0">
|
||||
<Name>Time</Name>
|
||||
<DefaultValue>0.0</DefaultValue>
|
||||
</Element>
|
||||
<Element Type="Int" ID="0x1">
|
||||
<Name>Unknown 1</Name>
|
||||
<DefaultValue>0</DefaultValue>
|
||||
</Element>
|
||||
<Element Type="Int" ID="0x2">
|
||||
<Name>Unknown 2</Name>
|
||||
<DefaultValue>0</DefaultValue>
|
||||
</Element>
|
||||
<Element Type="Int" ID="0x3">
|
||||
<Name>Unknown 3</Name>
|
||||
<DefaultValue>0</DefaultValue>
|
||||
</Element>
|
||||
</SubProperties>
|
||||
</PropertyArchetype>
|
||||
</PropertyTemplate>
|
|
@ -10,10 +10,7 @@
|
|||
</Element>
|
||||
<Element Type="Array" ID="0x1">
|
||||
<Name>Activation Times</Name>
|
||||
<ItemArchetype Type="Float" ID="0x0">
|
||||
<Name></Name>
|
||||
<DefaultValue>0.0</DefaultValue>
|
||||
</ItemArchetype>
|
||||
<ItemArchetype Type="Struct" Archetype="ActivationTime"/>
|
||||
</Element>
|
||||
</SubProperties>
|
||||
</PropertyArchetype>
|
||||
|
|
|
@ -623,6 +623,10 @@
|
|||
<Key>Abilities</Key>
|
||||
<Value Path="Structs/Abilities.xml"/>
|
||||
</Element>
|
||||
<Element>
|
||||
<Key>ActivationTime</Key>
|
||||
<Value Path="Structs/ActivationTime.xml"/>
|
||||
</Element>
|
||||
<Element>
|
||||
<Key>ActorParameters</Key>
|
||||
<Value Path="Structs/ActorParameters.xml"/>
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<PropertyTemplate ArchiveVer="4" Game="CorruptionProto">
|
||||
<PropertyArchetype Type="Struct">
|
||||
<Name>ActivationTime</Name>
|
||||
<Atomic>true</Atomic>
|
||||
<SubProperties>
|
||||
<Element Type="Float" ID="0x0">
|
||||
<Name>Time</Name>
|
||||
<DefaultValue>0.0</DefaultValue>
|
||||
</Element>
|
||||
<Element Type="Int" ID="0x1">
|
||||
<Name>Unknown 1</Name>
|
||||
<DefaultValue>0</DefaultValue>
|
||||
</Element>
|
||||
<Element Type="Int" ID="0x2">
|
||||
<Name>Unknown 2</Name>
|
||||
<DefaultValue>0</DefaultValue>
|
||||
</Element>
|
||||
<Element Type="Int" ID="0x3">
|
||||
<Name>Unknown 3</Name>
|
||||
<DefaultValue>0</DefaultValue>
|
||||
</Element>
|
||||
</SubProperties>
|
||||
</PropertyArchetype>
|
||||
</PropertyTemplate>
|
|
@ -10,10 +10,7 @@
|
|||
</Element>
|
||||
<Element Type="Array" ID="0x1">
|
||||
<Name>Activation Times</Name>
|
||||
<ItemArchetype Type="Float" ID="0x0">
|
||||
<Name></Name>
|
||||
<DefaultValue>0.0</DefaultValue>
|
||||
</ItemArchetype>
|
||||
<ItemArchetype Type="Struct" Archetype="ActivationTime"/>
|
||||
</Element>
|
||||
</SubProperties>
|
||||
</PropertyArchetype>
|
||||
|
|
Loading…
Reference in New Issue