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");
|
||||
}
|
||||
|
||||
void CAreaDependencyTree::AddScriptLayer(CScriptLayer *pLayer)
|
||||
void CAreaDependencyTree::AddScriptLayer(CScriptLayer *pLayer, const std::vector<CAssetID>& rkExtraDeps)
|
||||
{
|
||||
if (!pLayer) return;
|
||||
mLayerOffsets.push_back(mChildren.size());
|
||||
std::set<CAssetID> UsedIDs;
|
||||
|
||||
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
|
||||
if (pTree->NumChildren() > 0 || pLayer->Area()->Game() >= eEchoesDemo)
|
||||
{
|
||||
mChildren.push_back(pTree);
|
||||
pTree->GetAllResourceReferences(UsedIDs);
|
||||
}
|
||||
else
|
||||
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
|
||||
|
@ -351,8 +358,10 @@ void CAreaDependencyTree::GetModuleDependencies(EGame Game, std::vector<TString>
|
|||
|
||||
for (u32 iInst = StartIdx; iInst < EndIdx; iInst++)
|
||||
{
|
||||
CScriptInstanceDependency *pInst = static_cast<CScriptInstanceDependency*>(mChildren[iInst]);
|
||||
ASSERT(pInst->Type() == eDNT_ScriptInstance);
|
||||
IDependencyNode *pNode = mChildren[iInst];
|
||||
if (pNode->Type() != eDNT_ScriptInstance) continue;
|
||||
|
||||
CScriptInstanceDependency *pInst = static_cast<CScriptInstanceDependency*>(pNode);
|
||||
u32 ObjType = pInst->ObjectType();
|
||||
|
||||
if (UsedObjectTypes.find(ObjType) == UsedObjectTypes.end())
|
||||
|
|
|
@ -215,7 +215,7 @@ public:
|
|||
virtual EDependencyNodeType Type() const;
|
||||
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;
|
||||
|
||||
// Accessors
|
||||
|
|
|
@ -405,31 +405,44 @@ void CAreaDependencyListBuilder::BuildDependencyList(std::list<CAssetID>& rAsset
|
|||
|
||||
for (u32 iChild = StartIdx; iChild < EndIdx; iChild++)
|
||||
{
|
||||
CScriptInstanceDependency *pInst = static_cast<CScriptInstanceDependency*>(pTree->ChildByIndex(iChild));
|
||||
ASSERT(pInst->Type() == eDNT_ScriptInstance);
|
||||
mIsPlayerActor = (pInst->ObjectType() == 0x4C || pInst->ObjectType() == FOURCC('PLAC'));
|
||||
IDependencyNode *pNode = pTree->ChildByIndex(iChild);
|
||||
|
||||
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
|
||||
if (mGame == eCorruption && mIsPlayerActor)
|
||||
for (u32 iDep = 0; iDep < pInst->NumChildren(); iDep++)
|
||||
{
|
||||
TString PropID = pDep->PropertyID();
|
||||
CPropertyDependency *pDep = static_cast<CPropertyDependency*>(pInst->ChildByIndex(iDep));
|
||||
|
||||
if ( PropID == "0x846397A8" || PropID == "0x685A4C01" ||
|
||||
PropID == "0x9834ECC9" || PropID == "0x188B8960" ||
|
||||
PropID == "0x134A81E3" || PropID == "0x4ABF030C" ||
|
||||
PropID == "0x9BF030DC" || PropID == "0x981263D3" ||
|
||||
PropID == "0x8A8D5AA5" || PropID == "0xE4734608" ||
|
||||
PropID == "0x3376814D" || PropID == "0x797CA77E" ||
|
||||
PropID == "0x0EBEC440" || PropID == "0xBC0952D8" ||
|
||||
PropID == "0xA8778E57" || PropID == "0x1CB10DBE" )
|
||||
continue;
|
||||
// For MP3, exclude the CMDL/CSKR properties for the suit assets - only include default character assets
|
||||
if (mGame == eCorruption && mIsPlayerActor)
|
||||
{
|
||||
TString PropID = pDep->PropertyID();
|
||||
|
||||
if ( PropID == "0x846397A8" || PropID == "0x685A4C01" ||
|
||||
PropID == "0x9834ECC9" || PropID == "0x188B8960" ||
|
||||
PropID == "0x134A81E3" || PropID == "0x4ABF030C" ||
|
||||
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)
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,9 +48,18 @@ CDependencyTree* CGameArea::BuildDependencyTree() const
|
|||
pTree->AddDependency(mpPoiToWorldMap);
|
||||
}
|
||||
|
||||
// Extra deps
|
||||
for (u32 iDep = 0; iDep < mExtraAreaDeps.size(); iDep++)
|
||||
pTree->AddDependency(mExtraAreaDeps[iDep]);
|
||||
|
||||
// Layer dependencies
|
||||
std::vector<CAssetID> DummyDeps;
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -242,3 +251,13 @@ void CGameArea::DeleteInstance(CScriptObject *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;
|
||||
// Object to Static Geometry Map
|
||||
TResPtr<CPoiToWorld> mpPoiToWorldMap;
|
||||
// Dependencies
|
||||
std::vector<CAssetID> mExtraAreaDeps;
|
||||
std::vector< std::vector<CAssetID> > mExtraLayerDeps;
|
||||
|
||||
public:
|
||||
CGameArea(CResourceEntry *pEntry = 0);
|
||||
|
@ -80,6 +83,7 @@ public:
|
|||
u32 SuggestedID = -1, u32 SuggestedLayerIndex = -1);
|
||||
void AddInstanceToArea(CScriptObject *pInstance);
|
||||
void DeleteInstance(CScriptObject *pInstance);
|
||||
void ClearExtraDependencies();
|
||||
|
||||
// Inline Accessors
|
||||
inline u32 WorldIndex() const { return mWorldIndex; }
|
||||
|
|
|
@ -412,6 +412,52 @@ void CAreaLoader::ReadGeometryCorruption()
|
|||
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()
|
||||
{
|
||||
mpSectionMgr->ToSection(mLightsBlockNum);
|
||||
|
@ -733,6 +779,7 @@ CGameArea* CAreaLoader::LoadMREA(IInputStream& MREA, CResourceEntry *pEntry)
|
|||
case eCorruptionProto:
|
||||
Loader.ReadHeaderCorruption();
|
||||
Loader.ReadGeometryPrime();
|
||||
Loader.ReadDependenciesCorruption();
|
||||
Loader.ReadSCLYEchoes();
|
||||
Loader.ReadCollision();
|
||||
Loader.ReadLightsCorruption();
|
||||
|
@ -744,6 +791,7 @@ CGameArea* CAreaLoader::LoadMREA(IInputStream& MREA, CResourceEntry *pEntry)
|
|||
case eReturns:
|
||||
Loader.ReadHeaderCorruption();
|
||||
Loader.ReadGeometryCorruption();
|
||||
Loader.ReadDependenciesCorruption();
|
||||
Loader.ReadSCLYEchoes();
|
||||
Loader.ReadCollision();
|
||||
if (Loader.mVersion == eCorruption)
|
||||
|
|
|
@ -67,6 +67,7 @@ class CAreaLoader
|
|||
// Corruption
|
||||
void ReadHeaderCorruption();
|
||||
void ReadGeometryCorruption();
|
||||
void ReadDependenciesCorruption();
|
||||
void ReadLightsCorruption();
|
||||
|
||||
// Common
|
||||
|
|
|
@ -439,6 +439,9 @@ bool CWorldEditor::Save()
|
|||
bool SaveEGMCSuccess = mpArea->PoiToWorldMap() ? mpArea->PoiToWorldMap()->Entry()->Save() : true;
|
||||
bool SaveWorldSuccess = mpWorld->Entry()->Save();
|
||||
|
||||
if (SaveAreaSuccess)
|
||||
mpArea->ClearExtraDependencies();
|
||||
|
||||
if (SaveAreaSuccess || SaveEGMCSuccess || SaveWorldSuccess)
|
||||
gpEdApp->NotifyAssetsModified();
|
||||
|
||||
|
|
Loading…
Reference in New Issue