Added support for tracking extra dependencies in Corruption areas (necessary to avoid crashes)
This commit is contained in:
parent
95d0279027
commit
f980bc7536
|
@ -314,10 +314,11 @@ void CAreaDependencyTree::Serialize(IArchive& rArc)
|
||||||
rArc << SERIAL_CONTAINER("LayerOffsets", mLayerOffsets, "Offset");
|
rArc << SERIAL_CONTAINER("LayerOffsets", mLayerOffsets, "Offset");
|
||||||
}
|
}
|
||||||
|
|
||||||
void CAreaDependencyTree::AddScriptLayer(CScriptLayer *pLayer)
|
void CAreaDependencyTree::AddScriptLayer(CScriptLayer *pLayer, const std::vector<CAssetID>& rkExtraDeps)
|
||||||
{
|
{
|
||||||
if (!pLayer) return;
|
if (!pLayer) return;
|
||||||
mLayerOffsets.push_back(mChildren.size());
|
mLayerOffsets.push_back(mChildren.size());
|
||||||
|
std::set<CAssetID> UsedIDs;
|
||||||
|
|
||||||
for (u32 iInst = 0; iInst < pLayer->NumInstances(); iInst++)
|
for (u32 iInst = 0; iInst < pLayer->NumInstances(); iInst++)
|
||||||
{
|
{
|
||||||
|
@ -326,10 +327,16 @@ void CAreaDependencyTree::AddScriptLayer(CScriptLayer *pLayer)
|
||||||
|
|
||||||
// Note: MP2+ need to track all instances (not just instances with dependencies) to be able to build the layer module list
|
// Note: MP2+ need to track all instances (not just instances with dependencies) to be able to build the layer module list
|
||||||
if (pTree->NumChildren() > 0 || pLayer->Area()->Game() >= eEchoesDemo)
|
if (pTree->NumChildren() > 0 || pLayer->Area()->Game() >= eEchoesDemo)
|
||||||
|
{
|
||||||
mChildren.push_back(pTree);
|
mChildren.push_back(pTree);
|
||||||
|
pTree->GetAllResourceReferences(UsedIDs);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
delete pTree;
|
delete pTree;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (u32 iDep = 0; iDep < rkExtraDeps.size(); iDep++)
|
||||||
|
AddDependency(rkExtraDeps[iDep]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CAreaDependencyTree::GetModuleDependencies(EGame Game, std::vector<TString>& rModuleDepsOut, std::vector<u32>& rModuleLayerOffsetsOut) const
|
void CAreaDependencyTree::GetModuleDependencies(EGame Game, std::vector<TString>& rModuleDepsOut, std::vector<u32>& rModuleLayerOffsetsOut) const
|
||||||
|
@ -351,8 +358,10 @@ void CAreaDependencyTree::GetModuleDependencies(EGame Game, std::vector<TString>
|
||||||
|
|
||||||
for (u32 iInst = StartIdx; iInst < EndIdx; iInst++)
|
for (u32 iInst = StartIdx; iInst < EndIdx; iInst++)
|
||||||
{
|
{
|
||||||
CScriptInstanceDependency *pInst = static_cast<CScriptInstanceDependency*>(mChildren[iInst]);
|
IDependencyNode *pNode = mChildren[iInst];
|
||||||
ASSERT(pInst->Type() == eDNT_ScriptInstance);
|
if (pNode->Type() != eDNT_ScriptInstance) continue;
|
||||||
|
|
||||||
|
CScriptInstanceDependency *pInst = static_cast<CScriptInstanceDependency*>(pNode);
|
||||||
u32 ObjType = pInst->ObjectType();
|
u32 ObjType = pInst->ObjectType();
|
||||||
|
|
||||||
if (UsedObjectTypes.find(ObjType) == UsedObjectTypes.end())
|
if (UsedObjectTypes.find(ObjType) == UsedObjectTypes.end())
|
||||||
|
|
|
@ -215,7 +215,7 @@ public:
|
||||||
virtual EDependencyNodeType Type() const;
|
virtual EDependencyNodeType Type() const;
|
||||||
virtual void Serialize(IArchive& rArc);
|
virtual void Serialize(IArchive& rArc);
|
||||||
|
|
||||||
void AddScriptLayer(CScriptLayer *pLayer);
|
void AddScriptLayer(CScriptLayer *pLayer, const std::vector<CAssetID>& rkExtraDeps);
|
||||||
void GetModuleDependencies(EGame Game, std::vector<TString>& rModuleDepsOut, std::vector<u32>& rModuleLayerOffsetsOut) const;
|
void GetModuleDependencies(EGame Game, std::vector<TString>& rModuleDepsOut, std::vector<u32>& rModuleLayerOffsetsOut) const;
|
||||||
|
|
||||||
// Accessors
|
// Accessors
|
||||||
|
|
|
@ -405,31 +405,44 @@ void CAreaDependencyListBuilder::BuildDependencyList(std::list<CAssetID>& rAsset
|
||||||
|
|
||||||
for (u32 iChild = StartIdx; iChild < EndIdx; iChild++)
|
for (u32 iChild = StartIdx; iChild < EndIdx; iChild++)
|
||||||
{
|
{
|
||||||
CScriptInstanceDependency *pInst = static_cast<CScriptInstanceDependency*>(pTree->ChildByIndex(iChild));
|
IDependencyNode *pNode = pTree->ChildByIndex(iChild);
|
||||||
ASSERT(pInst->Type() == eDNT_ScriptInstance);
|
|
||||||
mIsPlayerActor = (pInst->ObjectType() == 0x4C || pInst->ObjectType() == FOURCC('PLAC'));
|
|
||||||
|
|
||||||
for (u32 iDep = 0; iDep < pInst->NumChildren(); iDep++)
|
if (pNode->Type() == eDNT_ScriptInstance)
|
||||||
{
|
{
|
||||||
CPropertyDependency *pDep = static_cast<CPropertyDependency*>(pInst->ChildByIndex(iDep));
|
CScriptInstanceDependency *pInst = static_cast<CScriptInstanceDependency*>(pNode);
|
||||||
|
mIsPlayerActor = (pInst->ObjectType() == 0x4C || pInst->ObjectType() == FOURCC('PLAC'));
|
||||||
|
|
||||||
// For MP3, exclude the CMDL/CSKR properties for the suit assets - only include default character assets
|
for (u32 iDep = 0; iDep < pInst->NumChildren(); iDep++)
|
||||||
if (mGame == eCorruption && mIsPlayerActor)
|
|
||||||
{
|
{
|
||||||
TString PropID = pDep->PropertyID();
|
CPropertyDependency *pDep = static_cast<CPropertyDependency*>(pInst->ChildByIndex(iDep));
|
||||||
|
|
||||||
if ( PropID == "0x846397A8" || PropID == "0x685A4C01" ||
|
// For MP3, exclude the CMDL/CSKR properties for the suit assets - only include default character assets
|
||||||
PropID == "0x9834ECC9" || PropID == "0x188B8960" ||
|
if (mGame == eCorruption && mIsPlayerActor)
|
||||||
PropID == "0x134A81E3" || PropID == "0x4ABF030C" ||
|
{
|
||||||
PropID == "0x9BF030DC" || PropID == "0x981263D3" ||
|
TString PropID = pDep->PropertyID();
|
||||||
PropID == "0x8A8D5AA5" || PropID == "0xE4734608" ||
|
|
||||||
PropID == "0x3376814D" || PropID == "0x797CA77E" ||
|
if ( PropID == "0x846397A8" || PropID == "0x685A4C01" ||
|
||||||
PropID == "0x0EBEC440" || PropID == "0xBC0952D8" ||
|
PropID == "0x9834ECC9" || PropID == "0x188B8960" ||
|
||||||
PropID == "0xA8778E57" || PropID == "0x1CB10DBE" )
|
PropID == "0x134A81E3" || PropID == "0x4ABF030C" ||
|
||||||
continue;
|
PropID == "0x9BF030DC" || PropID == "0x981263D3" ||
|
||||||
|
PropID == "0x8A8D5AA5" || PropID == "0xE4734608" ||
|
||||||
|
PropID == "0x3376814D" || PropID == "0x797CA77E" ||
|
||||||
|
PropID == "0x0EBEC440" || PropID == "0xBC0952D8" ||
|
||||||
|
PropID == "0xA8778E57" || PropID == "0x1CB10DBE" )
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
AddDependency(pDep->ID(), rAssetsOut, pAudioGroupsOut);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
AddDependency(pDep->ID(), rAssetsOut, pAudioGroupsOut);
|
else if (pNode->Type() == eDNT_ResourceDependency)
|
||||||
|
{
|
||||||
|
CResourceDependency *pResDep = static_cast<CResourceDependency*>(pNode);
|
||||||
|
AddDependency(pResDep->ID(), rAssetsOut, pAudioGroupsOut);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ASSERT(false); // unhandled case!
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -195,7 +195,7 @@ void CAnimationParameters::SetResource(const CAssetID& rkID)
|
||||||
|
|
||||||
if (!pEntry)
|
if (!pEntry)
|
||||||
Log::Error("Invalid resource ID passed to CAnimationParameters: " + rkID.ToString());
|
Log::Error("Invalid resource ID passed to CAnimationParameters: " + rkID.ToString());
|
||||||
else if (pEntry->ResourceType() != eAnimSet)
|
else if (pEntry->ResourceType() != eAnimSet && pEntry->ResourceType() != eCharacter)
|
||||||
Log::Error("Resource with invalid type passed to CAnimationParameters: " + pEntry->CookedAssetPath().GetFileName());
|
Log::Error("Resource with invalid type passed to CAnimationParameters: " + pEntry->CookedAssetPath().GetFileName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,9 +48,18 @@ CDependencyTree* CGameArea::BuildDependencyTree() const
|
||||||
pTree->AddDependency(mpPoiToWorldMap);
|
pTree->AddDependency(mpPoiToWorldMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Extra deps
|
||||||
|
for (u32 iDep = 0; iDep < mExtraAreaDeps.size(); iDep++)
|
||||||
|
pTree->AddDependency(mExtraAreaDeps[iDep]);
|
||||||
|
|
||||||
// Layer dependencies
|
// Layer dependencies
|
||||||
|
std::vector<CAssetID> DummyDeps;
|
||||||
|
|
||||||
for (u32 iLayer = 0; iLayer < mScriptLayers.size(); iLayer++)
|
for (u32 iLayer = 0; iLayer < mScriptLayers.size(); iLayer++)
|
||||||
pTree->AddScriptLayer(mScriptLayers[iLayer]);
|
{
|
||||||
|
const std::vector<CAssetID>& rkExtras = (mExtraLayerDeps.size() > iLayer ? mExtraLayerDeps[iLayer] : DummyDeps);
|
||||||
|
pTree->AddScriptLayer(mScriptLayers[iLayer], rkExtras);
|
||||||
|
}
|
||||||
|
|
||||||
return pTree;
|
return pTree;
|
||||||
}
|
}
|
||||||
|
@ -242,3 +251,13 @@ void CGameArea::DeleteInstance(CScriptObject *pInstance)
|
||||||
|
|
||||||
delete pInstance;
|
delete pInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CGameArea::ClearExtraDependencies()
|
||||||
|
{
|
||||||
|
if (mExtraAreaDeps.empty() || !mExtraLayerDeps.empty())
|
||||||
|
{
|
||||||
|
mExtraAreaDeps.clear();
|
||||||
|
mExtraLayerDeps.clear();
|
||||||
|
Entry()->UpdateDependencies();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -60,6 +60,9 @@ class CGameArea : public CResource
|
||||||
CAssetID mPortalAreaID;
|
CAssetID mPortalAreaID;
|
||||||
// Object to Static Geometry Map
|
// Object to Static Geometry Map
|
||||||
TResPtr<CPoiToWorld> mpPoiToWorldMap;
|
TResPtr<CPoiToWorld> mpPoiToWorldMap;
|
||||||
|
// Dependencies
|
||||||
|
std::vector<CAssetID> mExtraAreaDeps;
|
||||||
|
std::vector< std::vector<CAssetID> > mExtraLayerDeps;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CGameArea(CResourceEntry *pEntry = 0);
|
CGameArea(CResourceEntry *pEntry = 0);
|
||||||
|
@ -80,6 +83,7 @@ public:
|
||||||
u32 SuggestedID = -1, u32 SuggestedLayerIndex = -1);
|
u32 SuggestedID = -1, u32 SuggestedLayerIndex = -1);
|
||||||
void AddInstanceToArea(CScriptObject *pInstance);
|
void AddInstanceToArea(CScriptObject *pInstance);
|
||||||
void DeleteInstance(CScriptObject *pInstance);
|
void DeleteInstance(CScriptObject *pInstance);
|
||||||
|
void ClearExtraDependencies();
|
||||||
|
|
||||||
// Inline Accessors
|
// Inline Accessors
|
||||||
inline u32 WorldIndex() const { return mWorldIndex; }
|
inline u32 WorldIndex() const { return mWorldIndex; }
|
||||||
|
|
|
@ -412,6 +412,52 @@ void CAreaLoader::ReadGeometryCorruption()
|
||||||
mpArea->MergeTerrain();
|
mpArea->MergeTerrain();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CAreaLoader::ReadDependenciesCorruption()
|
||||||
|
{
|
||||||
|
mpSectionMgr->ToSection(mDependenciesBlockNum);
|
||||||
|
|
||||||
|
// Read the offsets first so we can read the deps directly into their corresponding arrays
|
||||||
|
u32 NumDeps = mpMREA->ReadLong();
|
||||||
|
u32 DepsStart = mpMREA->Tell();
|
||||||
|
mpMREA->Skip(NumDeps * 0xC);
|
||||||
|
|
||||||
|
u32 NumOffsets = mpMREA->ReadLong();
|
||||||
|
std::vector<u32> Offsets(NumOffsets);
|
||||||
|
|
||||||
|
for (u32 OffsetIdx = 0; OffsetIdx < NumOffsets; OffsetIdx++)
|
||||||
|
Offsets[OffsetIdx] = mpMREA->ReadLong();
|
||||||
|
|
||||||
|
mpMREA->GoTo(DepsStart);
|
||||||
|
|
||||||
|
// Read layer dependencies
|
||||||
|
u32 NumLayers = NumOffsets - 1;
|
||||||
|
mpArea->mExtraLayerDeps.resize(NumLayers);
|
||||||
|
|
||||||
|
for (u32 LayerIdx = 0; LayerIdx < NumLayers; LayerIdx++)
|
||||||
|
{
|
||||||
|
u32 NumLayerDeps = Offsets[LayerIdx+1] - Offsets[LayerIdx];
|
||||||
|
mpArea->mExtraLayerDeps[LayerIdx].reserve(NumLayerDeps);
|
||||||
|
|
||||||
|
for (u32 DepIdx = 0; DepIdx < NumLayerDeps; DepIdx++)
|
||||||
|
{
|
||||||
|
CAssetID AssetID(*mpMREA, eCorruption);
|
||||||
|
mpMREA->Skip(4);
|
||||||
|
mpArea->mExtraLayerDeps[LayerIdx].push_back(AssetID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read area dependencies
|
||||||
|
u32 NumAreaDeps = NumDeps - Offsets[NumLayers];
|
||||||
|
mpArea->mExtraAreaDeps.reserve(NumAreaDeps);
|
||||||
|
|
||||||
|
for (u32 DepIdx = 0; DepIdx < NumAreaDeps; DepIdx++)
|
||||||
|
{
|
||||||
|
CAssetID AssetID(*mpMREA, eCorruption);
|
||||||
|
mpMREA->Skip(4);
|
||||||
|
mpArea->mExtraAreaDeps.push_back(AssetID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CAreaLoader::ReadLightsCorruption()
|
void CAreaLoader::ReadLightsCorruption()
|
||||||
{
|
{
|
||||||
mpSectionMgr->ToSection(mLightsBlockNum);
|
mpSectionMgr->ToSection(mLightsBlockNum);
|
||||||
|
@ -733,6 +779,7 @@ CGameArea* CAreaLoader::LoadMREA(IInputStream& MREA, CResourceEntry *pEntry)
|
||||||
case eCorruptionProto:
|
case eCorruptionProto:
|
||||||
Loader.ReadHeaderCorruption();
|
Loader.ReadHeaderCorruption();
|
||||||
Loader.ReadGeometryPrime();
|
Loader.ReadGeometryPrime();
|
||||||
|
Loader.ReadDependenciesCorruption();
|
||||||
Loader.ReadSCLYEchoes();
|
Loader.ReadSCLYEchoes();
|
||||||
Loader.ReadCollision();
|
Loader.ReadCollision();
|
||||||
Loader.ReadLightsCorruption();
|
Loader.ReadLightsCorruption();
|
||||||
|
@ -744,6 +791,7 @@ CGameArea* CAreaLoader::LoadMREA(IInputStream& MREA, CResourceEntry *pEntry)
|
||||||
case eReturns:
|
case eReturns:
|
||||||
Loader.ReadHeaderCorruption();
|
Loader.ReadHeaderCorruption();
|
||||||
Loader.ReadGeometryCorruption();
|
Loader.ReadGeometryCorruption();
|
||||||
|
Loader.ReadDependenciesCorruption();
|
||||||
Loader.ReadSCLYEchoes();
|
Loader.ReadSCLYEchoes();
|
||||||
Loader.ReadCollision();
|
Loader.ReadCollision();
|
||||||
if (Loader.mVersion == eCorruption)
|
if (Loader.mVersion == eCorruption)
|
||||||
|
|
|
@ -67,6 +67,7 @@ class CAreaLoader
|
||||||
// Corruption
|
// Corruption
|
||||||
void ReadHeaderCorruption();
|
void ReadHeaderCorruption();
|
||||||
void ReadGeometryCorruption();
|
void ReadGeometryCorruption();
|
||||||
|
void ReadDependenciesCorruption();
|
||||||
void ReadLightsCorruption();
|
void ReadLightsCorruption();
|
||||||
|
|
||||||
// Common
|
// Common
|
||||||
|
|
|
@ -439,6 +439,9 @@ bool CWorldEditor::Save()
|
||||||
bool SaveEGMCSuccess = mpArea->PoiToWorldMap() ? mpArea->PoiToWorldMap()->Entry()->Save() : true;
|
bool SaveEGMCSuccess = mpArea->PoiToWorldMap() ? mpArea->PoiToWorldMap()->Entry()->Save() : true;
|
||||||
bool SaveWorldSuccess = mpWorld->Entry()->Save();
|
bool SaveWorldSuccess = mpWorld->Entry()->Save();
|
||||||
|
|
||||||
|
if (SaveAreaSuccess)
|
||||||
|
mpArea->ClearExtraDependencies();
|
||||||
|
|
||||||
if (SaveAreaSuccess || SaveEGMCSuccess || SaveWorldSuccess)
|
if (SaveAreaSuccess || SaveEGMCSuccess || SaveWorldSuccess)
|
||||||
gpEdApp->NotifyAssetsModified();
|
gpEdApp->NotifyAssetsModified();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue