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 \
Tweaks/CTweakManager.h \
Tweaks/CTweakData.h \
Tweaks/CTweakLoader.h
Tweaks/CTweakLoader.h \
Tweaks/CTweakCooker.h
# Source Files
SOURCES += \
@ -365,7 +366,8 @@ SOURCES += \
Resource/Script/NGameList.cpp \
Resource/StringTable/CStringTable.cpp \
Tweaks/CTweakManager.cpp \
Tweaks/CTweakLoader.cpp
Tweaks/CTweakLoader.cpp \
Tweaks/CTweakCooker.cpp
# Codegen
CODEGEN_DIR = $$EXTERNALS_DIR/CodeGen

View File

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

View File

@ -6,6 +6,8 @@
#include "CPoiToWorldCooker.h"
#include "CWorldCooker.h"
#include "Core/Tweaks/CTweakCooker.h"
#include "Core/GameProject/CResourceEntry.h"
class CResourceCooker
@ -23,6 +25,7 @@ public:
case EResourceType::Area: return CAreaCooker::CookMREA((CGameArea*) pRes, rOutput);
case EResourceType::Model: return CModelCooker::CookCMDL((CModel*) 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);
default:

View File

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

View File

@ -10,21 +10,16 @@
class CScriptCooker
{
EGame mGame;
CScriptObject* mpObject;
void* mpArrayItemData;
std::vector<CScriptObject*> mGeneratedObjects;
bool mWriteGeneratedSeparately;
void WriteProperty(IOutputStream& rOut, IProperty* pProperty, bool InAtomicStruct);
public:
CScriptCooker(EGame Game, bool WriteGeneratedObjectsSeparately = true)
: mGame(Game)
, mpObject(nullptr)
, mpArrayItemData(nullptr)
, mWriteGeneratedSeparately(WriteGeneratedObjectsSeparately && mGame >= EGame::EchoesDemo)
{}
void WriteProperty(IOutputStream& rOut, IProperty* pProperty, void* pData, bool InAtomicStruct);
void WriteInstance(IOutputStream& rOut, CScriptObject *pInstance);
void WriteLayer(IOutputStream& rOut, CScriptLayer *pLayer);
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[*]");
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()
@ -27,6 +29,31 @@ bool CTweakEditor::HasTweaks()
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)
{
// Perform first-time UI initialization

View File

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

View File

@ -38,7 +38,7 @@ public slots:
{
// Default implementation for editor windows that do not support resaving assets.
// 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;
}