Tweak cooking for MP1

This commit is contained in:
Aruki 2018-12-30 16:41:43 -07:00
parent e67471c480
commit eb9236bbea
10 changed files with 83 additions and 27 deletions

View File

@ -251,7 +251,8 @@ HEADERS += \
Resource/StringTable/ELanguage.h \ Resource/StringTable/ELanguage.h \
Tweaks/CTweakManager.h \ Tweaks/CTweakManager.h \
Tweaks/CTweakData.h \ Tweaks/CTweakData.h \
Tweaks/CTweakLoader.h Tweaks/CTweakLoader.h \
Tweaks/CTweakCooker.h
# Source Files # Source Files
SOURCES += \ SOURCES += \
@ -365,7 +366,8 @@ SOURCES += \
Resource/Script/NGameList.cpp \ Resource/Script/NGameList.cpp \
Resource/StringTable/CStringTable.cpp \ Resource/StringTable/CStringTable.cpp \
Tweaks/CTweakManager.cpp \ Tweaks/CTweakManager.cpp \
Tweaks/CTweakLoader.cpp Tweaks/CTweakLoader.cpp \
Tweaks/CTweakCooker.cpp
# Codegen # Codegen
CODEGEN_DIR = $$EXTERNALS_DIR/CodeGen CODEGEN_DIR = $$EXTERNALS_DIR/CodeGen

View File

@ -321,15 +321,15 @@ bool CResourceEntry::Save(bool SkipCacheSave /*= false*/)
if (!SkipCacheSave) if (!SkipCacheSave)
{ {
mpStore->ConditionalSaveStore(); mpStore->ConditionalSaveStore();
}
// Flag dirty any packages that contain this resource. // Flag dirty any packages that contain this resource.
for (uint32 iPkg = 0; iPkg < mpStore->Project()->NumPackages(); iPkg++) for (uint32 iPkg = 0; iPkg < mpStore->Project()->NumPackages(); iPkg++)
{ {
CPackage *pPkg = mpStore->Project()->PackageByIndex(iPkg); CPackage *pPkg = mpStore->Project()->PackageByIndex(iPkg);
if (pPkg->ContainsAsset(ID())) if (pPkg->ContainsAsset(ID()))
pPkg->MarkDirty(); pPkg->MarkDirty();
}
} }
if (ShouldCollectGarbage) if (ShouldCollectGarbage)

View File

@ -6,6 +6,8 @@
#include "CPoiToWorldCooker.h" #include "CPoiToWorldCooker.h"
#include "CWorldCooker.h" #include "CWorldCooker.h"
#include "Core/Tweaks/CTweakCooker.h"
#include "Core/GameProject/CResourceEntry.h" #include "Core/GameProject/CResourceEntry.h"
class CResourceCooker class CResourceCooker
@ -23,6 +25,7 @@ public:
case EResourceType::Area: return CAreaCooker::CookMREA((CGameArea*) pRes, rOutput); case EResourceType::Area: return CAreaCooker::CookMREA((CGameArea*) pRes, rOutput);
case EResourceType::Model: return CModelCooker::CookCMDL((CModel*) pRes, rOutput); case EResourceType::Model: return CModelCooker::CookCMDL((CModel*) pRes, rOutput);
case EResourceType::StaticGeometryMap: return CPoiToWorldCooker::CookEGMC((CPoiToWorld*) pRes, rOutput); case EResourceType::StaticGeometryMap: return CPoiToWorldCooker::CookEGMC((CPoiToWorld*) pRes, rOutput);
case EResourceType::Tweaks: return CTweakCooker::CookCTWK((CTweakData*) pRes, rOutput);
case EResourceType::World: return CWorldCooker::CookMLVL((CWorld*) pRes, rOutput); case EResourceType::World: return CWorldCooker::CookMLVL((CWorld*) pRes, rOutput);
default: default:

View File

@ -5,10 +5,9 @@
#include <Core/Resource/Script/Property/CEnumProperty.h> #include <Core/Resource/Script/Property/CEnumProperty.h>
#include <Core/Resource/Script/Property/CFlagsProperty.h> #include <Core/Resource/Script/Property/CFlagsProperty.h>
void CScriptCooker::WriteProperty(IOutputStream& rOut, IProperty* pProperty, bool InAtomicStruct) void CScriptCooker::WriteProperty(IOutputStream& rOut, IProperty* pProperty, void* pData, bool InAtomicStruct)
{ {
uint32 SizeOffset = 0, PropStart = 0; uint32 SizeOffset = 0, PropStart = 0;
void* pData = (mpArrayItemData ? mpArrayItemData : mpObject->PropertyData());
if (mGame >= EGame::EchoesDemo && !InAtomicStruct) if (mGame >= EGame::EchoesDemo && !InAtomicStruct)
{ {
@ -197,7 +196,7 @@ void CScriptCooker::WriteProperty(IOutputStream& rOut, IProperty* pProperty, boo
} }
for (uint32 PropertyIdx = 0; PropertyIdx < PropertiesToWrite.size(); PropertyIdx++) for (uint32 PropertyIdx = 0; PropertyIdx < PropertiesToWrite.size(); PropertyIdx++)
WriteProperty(rOut, PropertiesToWrite[PropertyIdx], pStruct->IsAtomic()); WriteProperty(rOut, PropertiesToWrite[PropertyIdx], pData, pStruct->IsAtomic());
break; break;
} }
@ -208,15 +207,11 @@ void CScriptCooker::WriteProperty(IOutputStream& rOut, IProperty* pProperty, boo
uint32 Count = pArray->ArrayCount(pData); uint32 Count = pArray->ArrayCount(pData);
rOut.WriteLong(Count); rOut.WriteLong(Count);
void* pOldItemData = mpArrayItemData;
for (uint32 ElementIdx = 0; ElementIdx < pArray->ArrayCount(pData); ElementIdx++) for (uint32 ElementIdx = 0; ElementIdx < pArray->ArrayCount(pData); ElementIdx++)
{ {
mpArrayItemData = pArray->ItemPointer(pData, ElementIdx); WriteProperty(rOut, pArray->ItemArchetype(), pArray->ItemPointer(pData, ElementIdx), true);
WriteProperty(rOut, pArray->ItemArchetype(), true);
} }
mpArrayItemData = pOldItemData;
break; break;
} }
@ -231,7 +226,6 @@ void CScriptCooker::WriteProperty(IOutputStream& rOut, IProperty* pProperty, boo
} }
} }
// ************ PUBLIC ************
void CScriptCooker::WriteInstance(IOutputStream& rOut, CScriptObject *pInstance) void CScriptCooker::WriteInstance(IOutputStream& rOut, CScriptObject *pInstance)
{ {
ASSERT(pInstance->Area()->Game() == mGame); ASSERT(pInstance->Area()->Game() == mGame);
@ -261,8 +255,7 @@ void CScriptCooker::WriteInstance(IOutputStream& rOut, CScriptObject *pInstance)
rOut.WriteLong(pLink->ReceiverID()); rOut.WriteLong(pLink->ReceiverID());
} }
mpObject = pInstance; WriteProperty(rOut, pInstance->Template()->Properties(), pInstance->PropertyData(), false);
WriteProperty(rOut, pInstance->Template()->Properties(), false);
uint32 InstanceEnd = rOut.Tell(); uint32 InstanceEnd = rOut.Tell();
rOut.Seek(SizeOffset, SEEK_SET); rOut.Seek(SizeOffset, SEEK_SET);

View File

@ -10,21 +10,16 @@
class CScriptCooker class CScriptCooker
{ {
EGame mGame; EGame mGame;
CScriptObject* mpObject;
void* mpArrayItemData;
std::vector<CScriptObject*> mGeneratedObjects; std::vector<CScriptObject*> mGeneratedObjects;
bool mWriteGeneratedSeparately; bool mWriteGeneratedSeparately;
void WriteProperty(IOutputStream& rOut, IProperty* pProperty, bool InAtomicStruct);
public: public:
CScriptCooker(EGame Game, bool WriteGeneratedObjectsSeparately = true) CScriptCooker(EGame Game, bool WriteGeneratedObjectsSeparately = true)
: mGame(Game) : mGame(Game)
, mpObject(nullptr)
, mpArrayItemData(nullptr)
, mWriteGeneratedSeparately(WriteGeneratedObjectsSeparately && mGame >= EGame::EchoesDemo) , mWriteGeneratedSeparately(WriteGeneratedObjectsSeparately && mGame >= EGame::EchoesDemo)
{} {}
void WriteProperty(IOutputStream& rOut, IProperty* pProperty, void* pData, bool InAtomicStruct);
void WriteInstance(IOutputStream& rOut, CScriptObject *pInstance); void WriteInstance(IOutputStream& rOut, CScriptObject *pInstance);
void WriteLayer(IOutputStream& rOut, CScriptLayer *pLayer); void WriteLayer(IOutputStream& rOut, CScriptLayer *pLayer);
void WriteGeneratedLayer(IOutputStream& rOut); void WriteGeneratedLayer(IOutputStream& rOut);

View File

@ -0,0 +1,17 @@
#include "CTweakCooker.h"
#include "Core/Resource/Cooker/CScriptCooker.h"
/** Cooker entry point */
bool CTweakCooker::CookCTWK(CTweakData* pTweakData, IOutputStream& CTWK)
{
CStructRef TweakProperties = pTweakData->TweakData();
CScriptCooker ScriptCooker(pTweakData->Game());
ScriptCooker.WriteProperty(CTWK, TweakProperties.Property(), TweakProperties.DataPointer(), true);
return true;
}
bool CTweakCooker::CookNTWK(const std::vector<CTweakData*>& kTweaks, IOutputStream& NTWK)
{
// Unimplemented
return false;
}

View File

@ -0,0 +1,18 @@
#ifndef CTWEAKCOOKER_H
#define CTWEAKCOOKER_H
#include "CTweakData.h"
/** Class responsible for cooking tweak data */
class CTweakCooker
{
/** Private constructor */
CTweakCooker() {}
public:
/** Cooker entry point */
static bool CookCTWK(CTweakData* pTweakData, IOutputStream& CTWK);
static bool CookNTWK(const std::vector<CTweakData*>& kTweaks, IOutputStream& NTWK);
};
#endif // CTWEAKCOOKER_H

View File

@ -15,6 +15,8 @@ CTweakEditor::CTweakEditor(QWidget* pParent)
SET_WINDOWTITLE_APPVARS("%APP_FULL_NAME% - Tweak Editor[*]"); SET_WINDOWTITLE_APPVARS("%APP_FULL_NAME% - Tweak Editor[*]");
connect(mpUI->TweakTabs, SIGNAL(currentChanged(int)), this, SLOT(OnTweakTabClicked(int))); connect(mpUI->TweakTabs, SIGNAL(currentChanged(int)), this, SLOT(OnTweakTabClicked(int)));
connect(mpUI->ActionSave, SIGNAL(triggered(bool)), this, SLOT(Save()));
connect(mpUI->ActionSaveAndRepack, SIGNAL(triggered(bool)), this, SLOT(SaveAndRepack()));
} }
CTweakEditor::~CTweakEditor() CTweakEditor::~CTweakEditor()
@ -27,6 +29,31 @@ bool CTweakEditor::HasTweaks()
return !mTweakAssets.isEmpty(); return !mTweakAssets.isEmpty();
} }
bool CTweakEditor::Save()
{
bool SavedAll = true;
foreach (CTweakData* pData, mTweakAssets)
{
if (!pData->Entry()->Save())
{
SavedAll = false;
}
}
if (!SavedAll)
{
UICommon::ErrorMsg(this, "Tweaks failed to save!");
return false;
}
else
{
UndoStack().setClean();
setWindowModified(false);
return true;
}
}
void CTweakEditor::showEvent(QShowEvent* pEvent) void CTweakEditor::showEvent(QShowEvent* pEvent)
{ {
// Perform first-time UI initialization // Perform first-time UI initialization

View File

@ -28,6 +28,7 @@ public:
~CTweakEditor(); ~CTweakEditor();
bool HasTweaks(); bool HasTweaks();
virtual bool Save() override;
virtual void showEvent(QShowEvent* pEvent) override; virtual void showEvent(QShowEvent* pEvent) override;
public slots: public slots:

View File

@ -38,7 +38,7 @@ public slots:
{ {
// Default implementation for editor windows that do not support resaving assets. // Default implementation for editor windows that do not support resaving assets.
// This should not be called. // This should not be called.
warnf("Base IEditor::Save() implementation called. Changes will not be saved."); errorf("Base IEditor::Save() implementation called. Changes will not be saved.");
return true; return true;
} }