Reimplemented save & repack button to work in the project system
This commit is contained in:
parent
1b97cd459a
commit
a7b0a2480c
|
@ -62,6 +62,10 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// We couldn't find a matching element, so we can't load this parameter.
|
// We couldn't find a matching element, so we can't load this parameter.
|
||||||
|
// If we pushed a parent earlier, undo it.
|
||||||
|
if (!mJustEndedParam)
|
||||||
|
mpCurElem = mpCurElem->Parent()->ToElement();
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -276,7 +276,7 @@ void GenerateAssetNames(CGameProject *pProj)
|
||||||
{
|
{
|
||||||
TString Name = pInst->InstanceName();
|
TString Name = pInst->InstanceName();
|
||||||
|
|
||||||
if (Name.EndsWith(".SCAN", false))
|
if (Name.StartsWith("POI_", false))
|
||||||
{
|
{
|
||||||
TIDString ScanIDString = (pProj->Game() <= ePrime ? "0x4:0x0" : "0xBDBEC295:0xB94E9BE7");
|
TIDString ScanIDString = (pProj->Game() <= ePrime ? "0x4:0x0" : "0xBDBEC295:0xB94E9BE7");
|
||||||
TAssetProperty *pScanProperty = TPropCast<TAssetProperty>(pInst->PropertyByIDString(ScanIDString));
|
TAssetProperty *pScanProperty = TPropCast<TAssetProperty>(pInst->PropertyByIDString(ScanIDString));
|
||||||
|
@ -289,10 +289,10 @@ void GenerateAssetNames(CGameProject *pProj)
|
||||||
|
|
||||||
if (pEntry && !pEntry->IsNamed())
|
if (pEntry && !pEntry->IsNamed())
|
||||||
{
|
{
|
||||||
TWideString ScanName = Name.ToUTF16().ChopBack(5);
|
TWideString ScanName = Name.ToUTF16().ChopFront(4);
|
||||||
|
|
||||||
if (ScanName.StartsWith(L"POI_"))
|
if (ScanName.EndsWith(L".SCAN", false))
|
||||||
ScanName = ScanName.ChopFront(4);
|
ScanName = ScanName.ChopBack(5);
|
||||||
|
|
||||||
ApplyGeneratedName(pEntry, pEntry->DirectoryPath(), ScanName);
|
ApplyGeneratedName(pEntry, pEntry->DirectoryPath(), ScanName);
|
||||||
|
|
||||||
|
@ -419,7 +419,7 @@ void GenerateAssetNames(CGameProject *pProj)
|
||||||
{
|
{
|
||||||
CAudioGroup *pGroup = (CAudioGroup*) It->Load();
|
CAudioGroup *pGroup = (CAudioGroup*) It->Load();
|
||||||
TWideString GroupName = pGroup->GroupName().ToUTF16();
|
TWideString GroupName = pGroup->GroupName().ToUTF16();
|
||||||
ApplyGeneratedName(*It, L"AudioGrp\\", GroupName);
|
ApplyGeneratedName(*It, L"Audio\\", GroupName);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,24 @@ bool CAssetNameMap::GetNameInfo(CAssetID ID, TString& rOutDirectory, TString& rO
|
||||||
|
|
||||||
void CAssetNameMap::CopyFromStore(CResourceStore *pStore /*= gpResourceStore*/)
|
void CAssetNameMap::CopyFromStore(CResourceStore *pStore /*= gpResourceStore*/)
|
||||||
{
|
{
|
||||||
|
// Do a first pass to remove old paths from used set to prevent false positives from eg. if two resources switch places
|
||||||
|
for (CResourceIterator It(pStore); It; ++It)
|
||||||
|
{
|
||||||
|
if (It->IsCategorized() || It->IsNamed())
|
||||||
|
{
|
||||||
|
auto Find = mMap.find(It->ID());
|
||||||
|
|
||||||
|
if (Find != mMap.end())
|
||||||
|
{
|
||||||
|
SAssetNameInfo& rInfo = Find->second;
|
||||||
|
auto UsedFind = mUsedSet.find(rInfo);
|
||||||
|
ASSERT(UsedFind != mUsedSet.end());
|
||||||
|
mUsedSet.erase(UsedFind);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do a second pass to add the new paths to the map
|
||||||
for (CResourceIterator It(pStore); It; ++It)
|
for (CResourceIterator It(pStore); It; ++It)
|
||||||
{
|
{
|
||||||
if (It->IsCategorized() || It->IsNamed())
|
if (It->IsCategorized() || It->IsNamed())
|
||||||
|
@ -44,17 +62,6 @@ void CAssetNameMap::CopyFromStore(CResourceStore *pStore /*= gpResourceStore*/)
|
||||||
CFourCC Type = It->CookedExtension();
|
CFourCC Type = It->CookedExtension();
|
||||||
SAssetNameInfo NameInfo { Name, Directory, Type };
|
SAssetNameInfo NameInfo { Name, Directory, Type };
|
||||||
|
|
||||||
// Remove old path from used set
|
|
||||||
auto Find = mMap.find(ID);
|
|
||||||
|
|
||||||
if (Find != mMap.end())
|
|
||||||
{
|
|
||||||
SAssetNameInfo& rInfo = Find->second;
|
|
||||||
auto UsedFind = mUsedSet.find(rInfo);
|
|
||||||
ASSERT(UsedFind != mUsedSet.end());
|
|
||||||
mUsedSet.erase(UsedFind);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for conflicts with new name
|
// Check for conflicts with new name
|
||||||
if (mUsedSet.find(NameInfo) != mUsedSet.end())
|
if (mUsedSet.find(NameInfo) != mUsedSet.end())
|
||||||
{
|
{
|
||||||
|
|
|
@ -57,6 +57,12 @@ void CGameProject::Serialize(IArchive& rArc)
|
||||||
|
|
||||||
if (rArc.IsReader())
|
if (rArc.IsReader())
|
||||||
{
|
{
|
||||||
|
// Load resource store
|
||||||
|
ASSERT(mpResourceStore == nullptr);
|
||||||
|
mpResourceStore = new CResourceStore(this);
|
||||||
|
mpResourceStore->LoadResourceDatabase();
|
||||||
|
|
||||||
|
// Load packages
|
||||||
for (u32 iPkg = 0; iPkg < mPackages.size(); iPkg++)
|
for (u32 iPkg = 0; iPkg < mPackages.size(); iPkg++)
|
||||||
delete mPackages[iPkg];
|
delete mPackages[iPkg];
|
||||||
mPackages.clear();
|
mPackages.clear();
|
||||||
|
@ -169,8 +175,6 @@ CGameProject* CGameProject::LoadProject(const TWideString& rkProjPath)
|
||||||
pProj->Serialize(Reader);
|
pProj->Serialize(Reader);
|
||||||
CTemplateLoader::LoadGameTemplates(pProj->mGame);
|
CTemplateLoader::LoadGameTemplates(pProj->mGame);
|
||||||
|
|
||||||
pProj->mpResourceStore = new CResourceStore(pProj);
|
|
||||||
pProj->mpResourceStore->LoadResourceDatabase();
|
|
||||||
pProj->mpGameInfo->LoadGameInfo(pProj->mGame);
|
pProj->mpGameInfo->LoadGameInfo(pProj->mGame);
|
||||||
pProj->mpAudioManager->LoadAssets();
|
pProj->mpAudioManager->LoadAssets();
|
||||||
return pProj;
|
return pProj;
|
||||||
|
|
|
@ -15,6 +15,7 @@ void CPackage::Load()
|
||||||
TWideString DefPath = DefinitionPath(false);
|
TWideString DefPath = DefinitionPath(false);
|
||||||
CXMLReader Reader(DefPath.ToUTF8());
|
CXMLReader Reader(DefPath.ToUTF8());
|
||||||
Serialize(Reader);
|
Serialize(Reader);
|
||||||
|
UpdateDependencyCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPackage::Save()
|
void CPackage::Save()
|
||||||
|
@ -28,7 +29,18 @@ void CPackage::Save()
|
||||||
|
|
||||||
void CPackage::Serialize(IArchive& rArc)
|
void CPackage::Serialize(IArchive& rArc)
|
||||||
{
|
{
|
||||||
rArc << SERIAL_CONTAINER("Collections", mCollections, "ResourceCollection");
|
rArc << SERIAL("NeedsRecook", mNeedsRecook)
|
||||||
|
<< SERIAL_CONTAINER("Collections", mCollections, "ResourceCollection");
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPackage::UpdateDependencyCache()
|
||||||
|
{
|
||||||
|
CPackageDependencyListBuilder Builder(this);
|
||||||
|
std::list<CAssetID> AssetList;
|
||||||
|
Builder.BuildDependencyList(false, AssetList);
|
||||||
|
|
||||||
|
for (auto Iter = AssetList.begin(); Iter != AssetList.end(); Iter++)
|
||||||
|
mCachedDependencies.insert(*Iter);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPackage::Cook()
|
void CPackage::Cook()
|
||||||
|
@ -74,18 +86,6 @@ void CPackage::Cook()
|
||||||
pkRes->ID.Write(Pak);
|
pkRes->ID.Write(Pak);
|
||||||
Pak.WriteLong(pkRes->Name.Size());
|
Pak.WriteLong(pkRes->Name.Size());
|
||||||
Pak.WriteString(pkRes->Name.ToStdString(), pkRes->Name.Size()); // Note: Explicitly specifying size means we don't write the terminating 0
|
Pak.WriteString(pkRes->Name.ToStdString(), pkRes->Name.Size()); // Note: Explicitly specifying size means we don't write the terminating 0
|
||||||
|
|
||||||
// TEMP: recook world
|
|
||||||
if (pkRes->Type == "MLVL")
|
|
||||||
{
|
|
||||||
CResourceEntry *pEntry = gpResourceStore->FindEntry(pkRes->ID);
|
|
||||||
ASSERT(pEntry);
|
|
||||||
CWorld *pWorld = (CWorld*) pEntry->Load();
|
|
||||||
ASSERT(pWorld);
|
|
||||||
CFileOutStream MLVL(pEntry->CookedAssetPath().ToStdString(), IOUtil::eBigEndian);
|
|
||||||
ASSERT(MLVL.IsValid());
|
|
||||||
CWorldCooker::CookMLVL(pWorld, MLVL);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fill in table of contents with junk, write later
|
// Fill in table of contents with junk, write later
|
||||||
|
@ -114,10 +114,14 @@ void CPackage::Cook()
|
||||||
|
|
||||||
for (auto Iter = AssetList.begin(); Iter != AssetList.end(); Iter++, ResIdx++)
|
for (auto Iter = AssetList.begin(); Iter != AssetList.end(); Iter++, ResIdx++)
|
||||||
{
|
{
|
||||||
|
// Initialize entry, recook assets if needed
|
||||||
CAssetID ID = *Iter;
|
CAssetID ID = *Iter;
|
||||||
CResourceEntry *pEntry = gpResourceStore->FindEntry(ID);
|
CResourceEntry *pEntry = gpResourceStore->FindEntry(ID);
|
||||||
ASSERT(pEntry != nullptr);
|
ASSERT(pEntry != nullptr);
|
||||||
|
|
||||||
|
if (pEntry->NeedsRecook())
|
||||||
|
pEntry->Cook();
|
||||||
|
|
||||||
SResourceTocInfo& rTocInfo = ResourceTocData[ResIdx];
|
SResourceTocInfo& rTocInfo = ResourceTocData[ResIdx];
|
||||||
rTocInfo.pEntry = pEntry;
|
rTocInfo.pEntry = pEntry;
|
||||||
rTocInfo.Offset = Pak.Tell();
|
rTocInfo.Offset = Pak.Tell();
|
||||||
|
@ -200,6 +204,8 @@ void CPackage::Cook()
|
||||||
Pak.WriteLong(rkTocInfo.Offset);
|
Pak.WriteLong(rkTocInfo.Offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mNeedsRecook = false;
|
||||||
|
Save();
|
||||||
Log::Write("Finished writing " + PakPath.ToUTF8());
|
Log::Write("Finished writing " + PakPath.ToUTF8());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,6 +50,8 @@ class CPackage
|
||||||
TString mPakName;
|
TString mPakName;
|
||||||
TWideString mPakPath;
|
TWideString mPakPath;
|
||||||
std::vector<CResourceCollection*> mCollections;
|
std::vector<CResourceCollection*> mCollections;
|
||||||
|
std::set<CAssetID> mCachedDependencies;
|
||||||
|
bool mNeedsRecook;
|
||||||
|
|
||||||
enum EPackageDefinitionVersion
|
enum EPackageDefinitionVersion
|
||||||
{
|
{
|
||||||
|
@ -66,11 +68,13 @@ public:
|
||||||
: mpProject(pProj)
|
: mpProject(pProj)
|
||||||
, mPakName(rkName)
|
, mPakName(rkName)
|
||||||
, mPakPath(rkPath)
|
, mPakPath(rkPath)
|
||||||
|
, mNeedsRecook(false)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void Load();
|
void Load();
|
||||||
void Save();
|
void Save();
|
||||||
void Serialize(IArchive& rArc);
|
void Serialize(IArchive& rArc);
|
||||||
|
void UpdateDependencyCache();
|
||||||
|
|
||||||
void Cook();
|
void Cook();
|
||||||
void CompareOriginalAssetList(const std::list<CAssetID>& rkNewList);
|
void CompareOriginalAssetList(const std::list<CAssetID>& rkNewList);
|
||||||
|
@ -88,8 +92,11 @@ public:
|
||||||
inline CGameProject* Project() const { return mpProject; }
|
inline CGameProject* Project() const { return mpProject; }
|
||||||
inline u32 NumCollections() const { return mCollections.size(); }
|
inline u32 NumCollections() const { return mCollections.size(); }
|
||||||
inline CResourceCollection* CollectionByIndex(u32 Idx) const { return mCollections[Idx]; }
|
inline CResourceCollection* CollectionByIndex(u32 Idx) const { return mCollections[Idx]; }
|
||||||
|
inline bool ContainsAsset(const CAssetID& rkID) const { return mCachedDependencies.find(rkID) != mCachedDependencies.end(); }
|
||||||
|
inline bool NeedsRecook() const { return mNeedsRecook; }
|
||||||
|
|
||||||
inline void SetPakName(TString NewName) { mPakName = NewName; }
|
inline void SetPakName(TString NewName) { mPakName = NewName; }
|
||||||
|
inline void MarkDirty() { mNeedsRecook = true; Save(); UpdateDependencyCache(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CPACKAGE
|
#endif // CPACKAGE
|
||||||
|
|
|
@ -213,13 +213,24 @@ bool CResourceEntry::Save(bool SkipCacheSave /*= false*/)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resource has been saved, now update dependencies + cache file
|
// Resource has been saved; now make sure dependencies, cache data, and packages are all up to date
|
||||||
UpdateDependencies();
|
UpdateDependencies();
|
||||||
mpStore->SetCacheDataDirty();
|
mpStore->SetCacheDataDirty();
|
||||||
|
|
||||||
if (!SkipCacheSave)
|
if (!SkipCacheSave)
|
||||||
|
{
|
||||||
mpStore->ConditionalSaveStore();
|
mpStore->ConditionalSaveStore();
|
||||||
|
|
||||||
|
// Flag dirty any packages that contain this resource.
|
||||||
|
for (u32 iPkg = 0; iPkg < mpStore->Project()->NumPackages(); iPkg++)
|
||||||
|
{
|
||||||
|
CPackage *pPkg = mpStore->Project()->PackageByIndex(iPkg);
|
||||||
|
|
||||||
|
if (pPkg->ContainsAsset(ID()))
|
||||||
|
pPkg->MarkDirty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (ShouldCollectGarbage)
|
if (ShouldCollectGarbage)
|
||||||
mpStore->DestroyUnreferencedResources();
|
mpStore->DestroyUnreferencedResources();
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,7 @@ void CCharacterUsageMap::FindUsagesForArea(CWorld *pWorld, u32 AreaIndex)
|
||||||
mCurrentAreaAllowsDupes = pWorld->DoesAreaAllowPakDuplicates(iArea);
|
mCurrentAreaAllowsDupes = pWorld->DoesAreaAllowPakDuplicates(iArea);
|
||||||
|
|
||||||
CAssetID AreaID = pWorld->AreaResourceID(iArea);
|
CAssetID AreaID = pWorld->AreaResourceID(iArea);
|
||||||
CResourceEntry *pEntry = gpResourceStore->FindEntry(AreaID);
|
CResourceEntry *pEntry = mpStore->FindEntry(AreaID);
|
||||||
ASSERT(pEntry && pEntry->ResourceType() == eArea);
|
ASSERT(pEntry && pEntry->ResourceType() == eArea);
|
||||||
|
|
||||||
ParseDependencyNode(pEntry->Dependencies());
|
ParseDependencyNode(pEntry->Dependencies());
|
||||||
|
@ -98,7 +98,7 @@ void CCharacterUsageMap::DebugPrintContents()
|
||||||
{
|
{
|
||||||
CAssetID ID = Iter->first;
|
CAssetID ID = Iter->first;
|
||||||
std::vector<bool>& rUsedList = Iter->second;
|
std::vector<bool>& rUsedList = Iter->second;
|
||||||
CAnimSet *pSet = (CAnimSet*) gpResourceStore->LoadResource(ID, "ANCS");
|
CAnimSet *pSet = (CAnimSet*) mpStore->LoadResource(ID, "ANCS");
|
||||||
|
|
||||||
for (u32 iChar = 0; iChar < pSet->NumCharacters(); iChar++)
|
for (u32 iChar = 0; iChar < pSet->NumCharacters(); iChar++)
|
||||||
{
|
{
|
||||||
|
@ -152,7 +152,7 @@ void CCharacterUsageMap::ParseDependencyNode(IDependencyNode *pNode)
|
||||||
else if (Type == eDNT_ResourceDependency || Type == eDNT_ScriptProperty)
|
else if (Type == eDNT_ResourceDependency || Type == eDNT_ScriptProperty)
|
||||||
{
|
{
|
||||||
CResourceDependency *pDep = static_cast<CResourceDependency*>(pNode);
|
CResourceDependency *pDep = static_cast<CResourceDependency*>(pNode);
|
||||||
CResourceEntry *pEntry = gpResourceStore->FindEntry(pDep->ID());
|
CResourceEntry *pEntry = mpStore->FindEntry(pDep->ID());
|
||||||
|
|
||||||
if (pEntry)
|
if (pEntry)
|
||||||
{
|
{
|
||||||
|
@ -184,7 +184,7 @@ void CPackageDependencyListBuilder::BuildDependencyList(bool AllowDuplicates, st
|
||||||
for (u32 iRes = 0; iRes < pCollection->NumResources(); iRes++)
|
for (u32 iRes = 0; iRes < pCollection->NumResources(); iRes++)
|
||||||
{
|
{
|
||||||
const SNamedResource& rkRes = pCollection->ResourceByIndex(iRes);
|
const SNamedResource& rkRes = pCollection->ResourceByIndex(iRes);
|
||||||
CResourceEntry *pEntry = gpResourceStore->FindEntry(rkRes.ID);
|
CResourceEntry *pEntry = mpStore->FindEntry(rkRes.ID);
|
||||||
if (!pEntry) continue;
|
if (!pEntry) continue;
|
||||||
|
|
||||||
if (rkRes.Name.EndsWith("NODEPEND") || rkRes.Type == "CSNG")
|
if (rkRes.Name.EndsWith("NODEPEND") || rkRes.Type == "CSNG")
|
||||||
|
@ -211,7 +211,7 @@ void CPackageDependencyListBuilder::BuildDependencyList(bool AllowDuplicates, st
|
||||||
void CPackageDependencyListBuilder::AddDependency(CResourceEntry *pCurEntry, const CAssetID& rkID, std::list<CAssetID>& rOut)
|
void CPackageDependencyListBuilder::AddDependency(CResourceEntry *pCurEntry, const CAssetID& rkID, std::list<CAssetID>& rOut)
|
||||||
{
|
{
|
||||||
if (pCurEntry && pCurEntry->ResourceType() == eDependencyGroup) return;
|
if (pCurEntry && pCurEntry->ResourceType() == eDependencyGroup) return;
|
||||||
CResourceEntry *pEntry = gpResourceStore->FindEntry(rkID);
|
CResourceEntry *pEntry = mpStore->FindEntry(rkID);
|
||||||
if (!pEntry) return;
|
if (!pEntry) return;
|
||||||
|
|
||||||
EResType ResType = pEntry->ResourceType();
|
EResType ResType = pEntry->ResourceType();
|
||||||
|
@ -395,7 +395,7 @@ void CAreaDependencyListBuilder::BuildDependencyList(std::list<CAssetID>& rAsset
|
||||||
|
|
||||||
void CAreaDependencyListBuilder::AddDependency(const CAssetID& rkID, std::list<CAssetID>& rOut, std::set<CAssetID> *pAudioGroupsOut)
|
void CAreaDependencyListBuilder::AddDependency(const CAssetID& rkID, std::list<CAssetID>& rOut, std::set<CAssetID> *pAudioGroupsOut)
|
||||||
{
|
{
|
||||||
CResourceEntry *pEntry = gpResourceStore->FindEntry(rkID);
|
CResourceEntry *pEntry = mpStore->FindEntry(rkID);
|
||||||
if (!pEntry) return;
|
if (!pEntry) return;
|
||||||
|
|
||||||
EResType ResType = pEntry->ResourceType();
|
EResType ResType = pEntry->ResourceType();
|
||||||
|
|
|
@ -12,12 +12,16 @@ class CCharacterUsageMap
|
||||||
{
|
{
|
||||||
std::map<CAssetID, std::vector<bool>> mUsageMap;
|
std::map<CAssetID, std::vector<bool>> mUsageMap;
|
||||||
std::set<CAssetID> mStillLookingIDs;
|
std::set<CAssetID> mStillLookingIDs;
|
||||||
|
CResourceStore *mpStore;
|
||||||
u32 mLayerIndex;
|
u32 mLayerIndex;
|
||||||
bool mIsInitialArea;
|
bool mIsInitialArea;
|
||||||
bool mCurrentAreaAllowsDupes;
|
bool mCurrentAreaAllowsDupes;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CCharacterUsageMap() : mLayerIndex(-1), mIsInitialArea(true), mCurrentAreaAllowsDupes(false) {}
|
CCharacterUsageMap(CResourceStore *pStore)
|
||||||
|
: mpStore(pStore), mLayerIndex(-1), mIsInitialArea(true), mCurrentAreaAllowsDupes(false)
|
||||||
|
{}
|
||||||
|
|
||||||
bool IsCharacterUsed(const CAssetID& rkID, u32 CharacterIndex) const;
|
bool IsCharacterUsed(const CAssetID& rkID, u32 CharacterIndex) const;
|
||||||
bool IsAnimationUsed(const CAssetID& rkID, CSetAnimationDependency *pAnim) const;
|
bool IsAnimationUsed(const CAssetID& rkID, CSetAnimationDependency *pAnim) const;
|
||||||
void FindUsagesForAsset(CResourceEntry *pEntry);
|
void FindUsagesForAsset(CResourceEntry *pEntry);
|
||||||
|
@ -35,6 +39,7 @@ protected:
|
||||||
class CPackageDependencyListBuilder
|
class CPackageDependencyListBuilder
|
||||||
{
|
{
|
||||||
CPackage *mpPackage;
|
CPackage *mpPackage;
|
||||||
|
CResourceStore *mpStore;
|
||||||
EGame mGame;
|
EGame mGame;
|
||||||
TResPtr<CWorld> mpWorld;
|
TResPtr<CWorld> mpWorld;
|
||||||
CAssetID mCurrentAnimSetID;
|
CAssetID mCurrentAnimSetID;
|
||||||
|
@ -49,9 +54,12 @@ public:
|
||||||
CPackageDependencyListBuilder(CPackage *pPackage)
|
CPackageDependencyListBuilder(CPackage *pPackage)
|
||||||
: mpPackage(pPackage)
|
: mpPackage(pPackage)
|
||||||
, mGame(pPackage->Project()->Game())
|
, mGame(pPackage->Project()->Game())
|
||||||
|
, mpStore(pPackage->Project()->ResourceStore())
|
||||||
|
, mCharacterUsageMap(pPackage->Project()->ResourceStore())
|
||||||
, mCurrentAreaHasDuplicates(false)
|
, mCurrentAreaHasDuplicates(false)
|
||||||
, mIsPlayerActor(false)
|
, mIsPlayerActor(false)
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void BuildDependencyList(bool AllowDuplicates, std::list<CAssetID>& rOut);
|
void BuildDependencyList(bool AllowDuplicates, std::list<CAssetID>& rOut);
|
||||||
void AddDependency(CResourceEntry *pCurEntry, const CAssetID& rkID, std::list<CAssetID>& rOut);
|
void AddDependency(CResourceEntry *pCurEntry, const CAssetID& rkID, std::list<CAssetID>& rOut);
|
||||||
|
@ -62,6 +70,7 @@ public:
|
||||||
class CAreaDependencyListBuilder
|
class CAreaDependencyListBuilder
|
||||||
{
|
{
|
||||||
CResourceEntry *mpAreaEntry;
|
CResourceEntry *mpAreaEntry;
|
||||||
|
CResourceStore *mpStore;
|
||||||
EGame mGame;
|
EGame mGame;
|
||||||
CAssetID mCurrentAnimSetID;
|
CAssetID mCurrentAnimSetID;
|
||||||
CCharacterUsageMap mCharacterUsageMap;
|
CCharacterUsageMap mCharacterUsageMap;
|
||||||
|
@ -72,7 +81,9 @@ class CAreaDependencyListBuilder
|
||||||
public:
|
public:
|
||||||
CAreaDependencyListBuilder(CResourceEntry *pAreaEntry)
|
CAreaDependencyListBuilder(CResourceEntry *pAreaEntry)
|
||||||
: mpAreaEntry(pAreaEntry)
|
: mpAreaEntry(pAreaEntry)
|
||||||
|
, mpStore(pAreaEntry->ResourceStore())
|
||||||
, mGame(pAreaEntry->Game())
|
, mGame(pAreaEntry->Game())
|
||||||
|
, mCharacterUsageMap(pAreaEntry->ResourceStore())
|
||||||
{
|
{
|
||||||
ASSERT(mpAreaEntry->ResourceType() == eArea);
|
ASSERT(mpAreaEntry->ResourceType() == eArea);
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,6 +84,26 @@ void CEditorApplication::EditResource(CResourceEntry *pEntry)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CEditorApplication::NotifyAssetsModified()
|
||||||
|
{
|
||||||
|
emit AssetsModified();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CEditorApplication::CookAllDirtyPackages()
|
||||||
|
{
|
||||||
|
CGameProject *pProj = CGameProject::ActiveProject();
|
||||||
|
|
||||||
|
for (u32 iPkg = 0; iPkg < pProj->NumPackages(); iPkg++)
|
||||||
|
{
|
||||||
|
CPackage *pPackage = pProj->PackageByIndex(iPkg);
|
||||||
|
|
||||||
|
if (pPackage->NeedsRecook())
|
||||||
|
pPackage->Cook();
|
||||||
|
}
|
||||||
|
|
||||||
|
mpProjectDialog->SetupPackagesList();
|
||||||
|
}
|
||||||
|
|
||||||
void CEditorApplication::AddEditor(IEditor *pEditor)
|
void CEditorApplication::AddEditor(IEditor *pEditor)
|
||||||
{
|
{
|
||||||
mEditorWindows << pEditor;
|
mEditorWindows << pEditor;
|
||||||
|
|
|
@ -31,6 +31,8 @@ public:
|
||||||
~CEditorApplication();
|
~CEditorApplication();
|
||||||
void InitEditor();
|
void InitEditor();
|
||||||
void EditResource(CResourceEntry *pEntry);
|
void EditResource(CResourceEntry *pEntry);
|
||||||
|
void NotifyAssetsModified();
|
||||||
|
void CookAllDirtyPackages();
|
||||||
|
|
||||||
// Accessors
|
// Accessors
|
||||||
inline CWorldEditor* WorldEditor() const { return mpWorldEditor; }
|
inline CWorldEditor* WorldEditor() const { return mpWorldEditor; }
|
||||||
|
@ -44,6 +46,9 @@ public slots:
|
||||||
void AddEditor(IEditor *pEditor);
|
void AddEditor(IEditor *pEditor);
|
||||||
void TickEditors();
|
void TickEditors();
|
||||||
void OnEditorClose();
|
void OnEditorClose();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void AssetsModified();
|
||||||
};
|
};
|
||||||
|
|
||||||
#define gpEdApp static_cast<CEditorApplication*>(qApp)
|
#define gpEdApp static_cast<CEditorApplication*>(qApp)
|
||||||
|
|
|
@ -22,6 +22,8 @@ CProjectOverviewDialog::CProjectOverviewDialog(QWidget *pParent)
|
||||||
connect(mpUI->LaunchEditorButton, SIGNAL(clicked()), this, SLOT(LaunchEditor()));
|
connect(mpUI->LaunchEditorButton, SIGNAL(clicked()), this, SLOT(LaunchEditor()));
|
||||||
connect(mpUI->ViewResourcesButton, SIGNAL(clicked()), this, SLOT(LaunchResourceBrowser()));
|
connect(mpUI->ViewResourcesButton, SIGNAL(clicked()), this, SLOT(LaunchResourceBrowser()));
|
||||||
connect(mpUI->CookPackageButton, SIGNAL(clicked()), this, SLOT(CookPackage()));
|
connect(mpUI->CookPackageButton, SIGNAL(clicked()), this, SLOT(CookPackage()));
|
||||||
|
|
||||||
|
connect(gpEdApp, SIGNAL(AssetsModified()), this, SLOT(SetupPackagesList()));
|
||||||
}
|
}
|
||||||
|
|
||||||
CProjectOverviewDialog::~CProjectOverviewDialog()
|
CProjectOverviewDialog::~CProjectOverviewDialog()
|
||||||
|
@ -113,7 +115,10 @@ void CProjectOverviewDialog::SetupPackagesList()
|
||||||
{
|
{
|
||||||
CPackage *pPackage = mpProject->PackageByIndex(iPkg);
|
CPackage *pPackage = mpProject->PackageByIndex(iPkg);
|
||||||
ASSERT(pPackage != nullptr);
|
ASSERT(pPackage != nullptr);
|
||||||
mpUI->PackagesList->addItem(TO_QSTRING(pPackage->Name()));
|
|
||||||
|
QString PackageName = TO_QSTRING(pPackage->Name());
|
||||||
|
if (pPackage->NeedsRecook()) PackageName += '*';
|
||||||
|
mpUI->PackagesList->addItem(PackageName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include "Editor/Widgets/WVectorEditor.h"
|
#include "Editor/Widgets/WVectorEditor.h"
|
||||||
#include "Editor/Undo/UndoCommands.h"
|
#include "Editor/Undo/UndoCommands.h"
|
||||||
|
|
||||||
|
#include <Core/GameProject/CGameProject.h>
|
||||||
#include <Core/Render/CDrawUtil.h>
|
#include <Core/Render/CDrawUtil.h>
|
||||||
#include <Core/Scene/CSceneIterator.h>
|
#include <Core/Scene/CSceneIterator.h>
|
||||||
#include <Common/Log.h>
|
#include <Common/Log.h>
|
||||||
|
@ -360,6 +361,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 || SaveEGMCSuccess || SaveWorldSuccess)
|
||||||
|
gpEdApp->NotifyAssetsModified();
|
||||||
|
|
||||||
if (SaveAreaSuccess && SaveEGMCSuccess && SaveWorldSuccess)
|
if (SaveAreaSuccess && SaveEGMCSuccess && SaveWorldSuccess)
|
||||||
{
|
{
|
||||||
mUndoStack.setClean();
|
mUndoStack.setClean();
|
||||||
|
@ -376,32 +380,8 @@ bool CWorldEditor::Save()
|
||||||
bool CWorldEditor::SaveAndRepack()
|
bool CWorldEditor::SaveAndRepack()
|
||||||
{
|
{
|
||||||
if (!Save()) return false;
|
if (!Save()) return false;
|
||||||
|
gpEdApp->CookAllDirtyPackages();
|
||||||
if (!CanRepack())
|
return true;
|
||||||
{
|
|
||||||
CRepackInfoDialog Dialog(mWorldDir, mPakFileList, mPakTarget, this);
|
|
||||||
Dialog.exec();
|
|
||||||
|
|
||||||
if (Dialog.result() == QDialog::Accepted)
|
|
||||||
{
|
|
||||||
SetWorldDir(Dialog.TargetFolder());
|
|
||||||
SetPakFileList(Dialog.ListFile());
|
|
||||||
SetPakTarget(Dialog.OutputPak());
|
|
||||||
if (!CanRepack()) return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
else return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString PakOut;
|
|
||||||
CPakToolDialog::EResult Result = CPakToolDialog::Repack(CurrentGame(), mPakTarget, mPakFileList, mWorldDir, &PakOut, this);
|
|
||||||
|
|
||||||
if (Result == CPakToolDialog::eError)
|
|
||||||
QMessageBox::warning(this, "Error", "Failed to repack!");
|
|
||||||
else if (Result == CPakToolDialog::eSuccess)
|
|
||||||
QMessageBox::information(this, "Success", "Successfully saved pak: " + PakOut);
|
|
||||||
|
|
||||||
return (Result == CPakToolDialog::eSuccess);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWorldEditor::OnLinksModified(const QList<CScriptObject*>& rkInstances)
|
void CWorldEditor::OnLinksModified(const QList<CScriptObject*>& rkInstances)
|
||||||
|
|
Loading…
Reference in New Issue