From 43456aedbd009298734914f4ce0ae616e7416709 Mon Sep 17 00:00:00 2001 From: TheApadayo Date: Tue, 15 Jan 2019 19:40:57 -0500 Subject: [PATCH] [ZoneBuilder] Fix one small thing in weapon writing, change how we search for assets in common_mp as using DB_EnumXAssets was missing some of them, and allow the weapon loading function see zonebuilder assets --- src/Components/Modules/AssetHandler.cpp | 46 +++++++++++++++++-- src/Components/Modules/AssetHandler.hpp | 4 ++ .../Modules/AssetInterfaces/IWeapon.cpp | 8 +++- src/Components/Modules/ZoneBuilder.cpp | 25 +++++----- 4 files changed, 65 insertions(+), 18 deletions(-) diff --git a/src/Components/Modules/AssetHandler.cpp b/src/Components/Modules/AssetHandler.cpp index 731573e5..f116fb3f 100644 --- a/src/Components/Modules/AssetHandler.cpp +++ b/src/Components/Modules/AssetHandler.cpp @@ -3,6 +3,7 @@ namespace Components { thread_local int AssetHandler::BypassState = 0; + bool AssetHandler::ShouldSearchTempAssets = false; std::map AssetHandler::AssetInterfaces; std::map> AssetHandler::TypeCallbacks; Utils::Signal AssetHandler::RestrictSignal; @@ -69,6 +70,21 @@ namespace Components return header; } + Game::XAssetHeader AssetHandler::FindTemporaryAsset(Game::XAssetType type, const char* filename) + { + Game::XAssetHeader header = { nullptr }; + if (type >= Game::XAssetType::ASSET_TYPE_COUNT) return header; + + auto tempPool = &AssetHandler::TemporaryAssets[type]; + auto entry = tempPool->find(filename); + if (entry != tempPool->end()) + { + header = { entry->second }; + } + + return header; + } + int AssetHandler::HasThreadBypass() { return AssetHandler::BypassState > 0; @@ -116,7 +132,7 @@ namespace Components test al, al - jnz finishOriginal + jnz checkTempAssets mov ecx, [esp + 18h] // Asset type mov ebx, [esp + 1Ch] // Filename @@ -139,9 +155,28 @@ namespace Components test eax, eax jnz finishFound + + checkTempAssets: + mov al, AssetHandler::ShouldSearchTempAssets // check to see if enabled + test eax, eax + jz finishOriginal - finishOriginal: - // Asset not found using custom handlers, redirect to DB_FindXAssetHeader + mov ecx, [esp + 18h] // Asset type + mov ebx, [esp + 1Ch] // Filename + + push ebx + push ecx + + call AssetHandler::FindTemporaryAsset + + add esp, 8h + + test eax, eax + jnz finishFound + + finishOriginal: + // Asset not found using custom handlers or in temp assets or bypasses were enabled + // redirect to DB_FindXAssetHeader mov ebx, ds:6D7190h // InterlockedDecrement mov eax, 40793Bh jmp eax @@ -454,6 +489,11 @@ namespace Components Utils::Hook::Set(0x5BAEA2, entryPool + 1); } + void AssetHandler::ExposeTemporaryAssets(bool expose) + { + AssetHandler::ShouldSearchTempAssets = expose; + } + AssetHandler::AssetHandler() { this->reallocateEntryPool(); diff --git a/src/Components/Modules/AssetHandler.hpp b/src/Components/Modules/AssetHandler.hpp index 4abff29c..6f667bbb 100644 --- a/src/Components/Modules/AssetHandler.hpp +++ b/src/Components/Modules/AssetHandler.hpp @@ -39,8 +39,11 @@ namespace Components static void ResetBypassState(); + static void ExposeTemporaryAssets(bool expose); + private: static thread_local int BypassState; + static bool ShouldSearchTempAssets; static std::map TemporaryAssets[Game::XAssetType::ASSET_TYPE_COUNT]; @@ -55,6 +58,7 @@ namespace Components static void RegisterInterface(IAsset* iAsset); static Game::XAssetHeader FindAsset(Game::XAssetType type, const char* filename); + static Game::XAssetHeader FindTemporaryAsset(Game::XAssetType type, const char* filename); static bool IsAssetEligible(Game::XAssetType type, Game::XAssetHeader* asset); static void FindAssetStub(); static void AddAssetStub(); diff --git a/src/Components/Modules/AssetInterfaces/IWeapon.cpp b/src/Components/Modules/AssetInterfaces/IWeapon.cpp index cd2d05f2..0449d9aa 100644 --- a/src/Components/Modules/AssetInterfaces/IWeapon.cpp +++ b/src/Components/Modules/AssetInterfaces/IWeapon.cpp @@ -11,9 +11,13 @@ namespace Assets { // let the function see temporary assets when calling DB_FindXAssetHeader during the loading function // otherwise it fails to link things properly - Components::AssetHandler::ExposeTemporaryAssets(true); + Components::AssetHandler::ExposeTemporaryAssets(true); + IWeapon::CurrentBuilder = builder; + header->data = Game::BG_LoadWeaponDef_LoadObj(name.data()); + Components::AssetHandler::ExposeTemporaryAssets(false); + IWeapon::CurrentBuilder = nullptr; } } @@ -286,7 +290,7 @@ namespace Assets continue; } - buffer->saveMax(); + buffer->saveMax(sizeof(Game::snd_alias_list_t*)); buffer->saveString(def->bounceSound[i]->aliasName); } diff --git a/src/Components/Modules/ZoneBuilder.cpp b/src/Components/Modules/ZoneBuilder.cpp index babbc42a..dd2f5fc6 100644 --- a/src/Components/Modules/ZoneBuilder.cpp +++ b/src/Components/Modules/ZoneBuilder.cpp @@ -701,21 +701,20 @@ namespace Components if (zoneIndex > 0) { - Game::DB_EnumXAssetEntries(type, [&](Game::XAssetEntry* entry) - { - if (!header.data && entry->zoneIndex == zoneIndex && Game::DB_GetXAssetName(&entry->asset) == name) - { - // Allocate an empty asset (filled with zeros) - header.data = builder->getAllocator()->allocate(Game::DB_GetXAssetSizeHandlers[type]()); + Game::XAssetEntry* entry = Game::DB_FindXAssetEntry(type, name.data()); - // Set the name to the original name, so it can be stored - Game::DB_SetXAssetNameHandlers[type](&header, name.data()); - AssetHandler::StoreTemporaryAsset(type, header); + if (entry->zoneIndex == zoneIndex) + { + // Allocate an empty asset (filled with zeros) + header.data = builder->getAllocator()->allocate(Game::DB_GetXAssetSizeHandlers[type]()); - // Set the name to the empty name - Game::DB_SetXAssetNameHandlers[type](&header, builder->getAllocator()->duplicateString("," + name)); - } - }, true, true); + // Set the name to the original name, so it can be stored + Game::DB_SetXAssetNameHandlers[type](&header, name.data()); + AssetHandler::StoreTemporaryAsset(type, header); + + // Set the name to the empty name + Game::DB_SetXAssetNameHandlers[type](&header, builder->getAllocator()->duplicateString("," + name)); + } } }