From c6087ce77ac2222738aafdf68c23da81e0d1e606 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Mon, 9 Oct 2023 13:33:22 -0700 Subject: [PATCH] perf: Loot memory savings (#1165) * Move away from constructor queries Fix up other large tables to have proper backup lookups Revert "idk im just dumb ig" This reverts commit 5d5be5df53b8959b42b291613d7db749a65a3585. idk im just dumb ig * Fix slow components registry lookup * add define for cdclient cache all * Huge loot namespace rework - Remove all excess memory usage - do not cache components registry - cache loot matrices on startup of the destroyable component - convert loot singleton class to a namespace - rework loot cdclient tables to operate closer to how someone would actually use them (basically doing the previous LootGenerator::LootGenerator caching but in those tables) - Memory usage reduced by 10%+ across the board * cache rebuild matrix * Database: move reading to own function Also change name of cache to PascalCase * Database: Move common function rading --- dDatabase/CDClientManager.cpp | 6 +- dDatabase/Tables/CDLootMatrixTable.cpp | 58 +++-- dDatabase/Tables/CDLootMatrixTable.h | 16 +- dDatabase/Tables/CDLootTableTable.cpp | 55 ++-- dDatabase/Tables/CDLootTableTable.h | 11 +- dDatabase/Tables/CDRarityTableTable.cpp | 27 +- dDatabase/Tables/CDRarityTableTable.h | 27 +- dGame/Entity.cpp | 2 + dGame/dComponents/DestroyableComponent.cpp | 8 +- dGame/dComponents/RacingControlComponent.cpp | 2 +- dGame/dComponents/RebuildComponent.cpp | 2 +- .../dComponents/ScriptedActivityComponent.cpp | 2 +- dGame/dComponents/VendorComponent.cpp | 5 +- dGame/dInventory/Item.cpp | 4 +- dGame/dUtilities/Loot.cpp | 236 ++++++------------ dGame/dUtilities/Loot.h | 46 +--- dGame/dUtilities/SlashCommandHandler.cpp | 2 +- .../General/TreasureChestDragonServer.cpp | 4 +- .../02_server/Equipment/BootyDigServer.cpp | 2 +- .../General/BaseInteractDropLootServer.cpp | 2 +- .../02_server/Map/General/GrowingFlower.cpp | 2 +- .../Map/General/WishingWellServer.cpp | 2 +- .../02_server/Map/VE/VeMissionConsole.cpp | 2 +- .../Map/njhub/NjDragonEmblemChestServer.cpp | 2 +- .../General/MinigameTreasureChestServer.cpp | 4 +- dScripts/ActivityManager.cpp | 2 +- dScripts/ScriptedPowerupSpawner.cpp | 2 +- dScripts/ai/AG/AgPicnicBlanket.cpp | 2 +- .../ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp | 4 +- dWorldServer/WorldServer.cpp | 1 - 30 files changed, 201 insertions(+), 339 deletions(-) diff --git a/dDatabase/CDClientManager.cpp b/dDatabase/CDClientManager.cpp index 32a6a5b1..465fd4e6 100644 --- a/dDatabase/CDClientManager.cpp +++ b/dDatabase/CDClientManager.cpp @@ -55,7 +55,7 @@ CDClientManager::CDClientManager() { CDBehaviorParameterTable::Instance().LoadValuesFromDatabase(); CDBehaviorTemplateTable::Instance().LoadValuesFromDatabase(); CDBrickIDTableTable::Instance().LoadValuesFromDatabase(); - CDComponentsRegistryTable::Instance().LoadValuesFromDatabase(); + CDCLIENT_DONT_CACHE_TABLE(CDComponentsRegistryTable::Instance().LoadValuesFromDatabase()); CDCurrencyTableTable::Instance().LoadValuesFromDatabase(); CDDestructibleComponentTable::Instance().LoadValuesFromDatabase(); CDEmoteTableTable::Instance().LoadValuesFromDatabase(); @@ -65,8 +65,8 @@ CDClientManager::CDClientManager() { CDItemSetSkillsTable::Instance().LoadValuesFromDatabase(); CDItemSetsTable::Instance().LoadValuesFromDatabase(); CDLevelProgressionLookupTable::Instance().LoadValuesFromDatabase(); - CDLootMatrixTable::Instance().LoadValuesFromDatabase(); - CDLootTableTable::Instance().LoadValuesFromDatabase(); + CDCLIENT_DONT_CACHE_TABLE(CDLootMatrixTable::Instance().LoadValuesFromDatabase()); + CDCLIENT_DONT_CACHE_TABLE(CDLootTableTable::Instance().LoadValuesFromDatabase()); CDMissionEmailTable::Instance().LoadValuesFromDatabase(); CDMissionNPCComponentTable::Instance().LoadValuesFromDatabase(); CDMissionTasksTable::Instance().LoadValuesFromDatabase(); diff --git a/dDatabase/Tables/CDLootMatrixTable.cpp b/dDatabase/Tables/CDLootMatrixTable.cpp index 27c01b30..4755c116 100644 --- a/dDatabase/Tables/CDLootMatrixTable.cpp +++ b/dDatabase/Tables/CDLootMatrixTable.cpp @@ -1,5 +1,18 @@ #include "CDLootMatrixTable.h" +CDLootMatrix CDLootMatrixTable::ReadRow(CppSQLite3Query& tableData) const { + CDLootMatrix entry{}; + if (tableData.eof()) return entry; + entry.LootTableIndex = tableData.getIntField("LootTableIndex", -1); + entry.RarityTableIndex = tableData.getIntField("RarityTableIndex", -1); + entry.percent = tableData.getFloatField("percent", -1.0f); + entry.minToDrop = tableData.getIntField("minToDrop", -1); + entry.maxToDrop = tableData.getIntField("maxToDrop", -1); + entry.flagID = tableData.getIntField("flagID", -1); + UNUSED(entry.gate_version = tableData.getStringField("gate_version", "")); + return entry; +} + void CDLootMatrixTable::LoadValuesFromDatabase() { // First, get the size of the table @@ -11,8 +24,6 @@ void CDLootMatrixTable::LoadValuesFromDatabase() { tableSize.nextRow(); } - tableSize.finalize(); - // Reserve the size this->entries.reserve(size); @@ -20,33 +31,28 @@ void CDLootMatrixTable::LoadValuesFromDatabase() { auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM LootMatrix"); while (!tableData.eof()) { CDLootMatrix entry; - entry.LootMatrixIndex = tableData.getIntField("LootMatrixIndex", -1); - entry.LootTableIndex = tableData.getIntField("LootTableIndex", -1); - entry.RarityTableIndex = tableData.getIntField("RarityTableIndex", -1); - entry.percent = tableData.getFloatField("percent", -1.0f); - entry.minToDrop = tableData.getIntField("minToDrop", -1); - entry.maxToDrop = tableData.getIntField("maxToDrop", -1); - entry.id = tableData.getIntField("id", -1); - entry.flagID = tableData.getIntField("flagID", -1); - UNUSED(entry.gate_version = tableData.getStringField("gate_version", "")); + uint32_t lootMatrixIndex = tableData.getIntField("LootMatrixIndex", -1); - this->entries.push_back(entry); + this->entries[lootMatrixIndex].push_back(ReadRow(tableData)); + tableData.nextRow(); + } +} + +const LootMatrixEntries& CDLootMatrixTable::GetMatrix(uint32_t matrixId) { + auto itr = this->entries.find(matrixId); + if (itr != this->entries.end()) { + return itr->second; + } + + auto query = CDClientDatabase::CreatePreppedStmt("SELECT * FROM LootMatrix where LootMatrixIndex = ?;"); + query.bind(1, static_cast(matrixId)); + + auto tableData = query.execQuery(); + while (!tableData.eof()) { + this->entries[matrixId].push_back(ReadRow(tableData)); tableData.nextRow(); } - tableData.finalize(); -} - -std::vector CDLootMatrixTable::Query(std::function predicate) { - - std::vector data = cpplinq::from(this->entries) - >> cpplinq::where(predicate) - >> cpplinq::to_vector(); - - return data; -} - -const std::vector& CDLootMatrixTable::GetEntries() const { - return this->entries; + return this->entries[matrixId]; } diff --git a/dDatabase/Tables/CDLootMatrixTable.h b/dDatabase/Tables/CDLootMatrixTable.h index 6ea012cb..551583f6 100644 --- a/dDatabase/Tables/CDLootMatrixTable.h +++ b/dDatabase/Tables/CDLootMatrixTable.h @@ -4,26 +4,26 @@ #include "CDTable.h" struct CDLootMatrix { - unsigned int LootMatrixIndex; //!< The Loot Matrix Index unsigned int LootTableIndex; //!< The Loot Table Index unsigned int RarityTableIndex; //!< The Rarity Table Index float percent; //!< The percent that this matrix is used? unsigned int minToDrop; //!< The minimum amount of loot from this matrix to drop unsigned int maxToDrop; //!< The maximum amount of loot from this matrix to drop - unsigned int id; //!< The ID of the Loot Matrix unsigned int flagID; //!< ??? UNUSED(std::string gate_version); //!< The Gate Version }; -class CDLootMatrixTable : public CDTable { -private: - std::vector entries; +typedef uint32_t LootMatrixIndex; +typedef std::vector LootMatrixEntries; +class CDLootMatrixTable : public CDTable { public: void LoadValuesFromDatabase(); - // Queries the table with a custom "where" clause - std::vector Query(std::function predicate); - const std::vector& GetEntries() const; + // Gets a matrix by ID or inserts a blank one if none existed. + const LootMatrixEntries& GetMatrix(uint32_t matrixId); +private: + CDLootMatrix ReadRow(CppSQLite3Query& tableData) const; + std::unordered_map entries; }; diff --git a/dDatabase/Tables/CDLootTableTable.cpp b/dDatabase/Tables/CDLootTableTable.cpp index 17dfd641..cdad7dca 100644 --- a/dDatabase/Tables/CDLootTableTable.cpp +++ b/dDatabase/Tables/CDLootTableTable.cpp @@ -1,5 +1,14 @@ #include "CDLootTableTable.h" +CDLootTable CDLootTableTable::ReadRow(CppSQLite3Query& tableData) const { + CDLootTable entry{}; + if (tableData.eof()) return entry; + entry.itemid = tableData.getIntField("itemid", -1); + entry.MissionDrop = tableData.getIntField("MissionDrop", -1) == 1 ? true : false; + entry.sortPriority = tableData.getIntField("sortPriority", -1); + return entry; +} + void CDLootTableTable::LoadValuesFromDatabase() { // First, get the size of the table @@ -11,8 +20,6 @@ void CDLootTableTable::LoadValuesFromDatabase() { tableSize.nextRow(); } - tableSize.finalize(); - // Reserve the size this->entries.reserve(size); @@ -20,32 +27,28 @@ void CDLootTableTable::LoadValuesFromDatabase() { auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM LootTable"); while (!tableData.eof()) { CDLootTable entry; - entry.id = tableData.getIntField("id", -1); - entry.itemid = tableData.getIntField("itemid", -1); - entry.LootTableIndex = tableData.getIntField("LootTableIndex", -1); - entry.id = tableData.getIntField("id", -1); - entry.MissionDrop = tableData.getIntField("MissionDrop", -1) == 1 ? true : false; - entry.sortPriority = tableData.getIntField("sortPriority", -1); + uint32_t lootTableIndex = tableData.getIntField("LootTableIndex", -1); - this->entries.push_back(entry); + this->entries[lootTableIndex].push_back(ReadRow(tableData)); + tableData.nextRow(); + } +} + +const LootTableEntries& CDLootTableTable::GetTable(uint32_t tableId) { + auto itr = this->entries.find(tableId); + if (itr != this->entries.end()) { + return itr->second; + } + + auto query = CDClientDatabase::CreatePreppedStmt("SELECT * FROM LootTable WHERE LootTableIndex = ?;"); + query.bind(1, static_cast(tableId)); + auto tableData = query.execQuery(); + + while (!tableData.eof()) { + CDLootTable entry; + this->entries[tableId].push_back(ReadRow(tableData)); tableData.nextRow(); } - tableData.finalize(); + return this->entries[tableId]; } - -//! Queries the table with a custom "where" clause -std::vector CDLootTableTable::Query(std::function predicate) { - - std::vector data = cpplinq::from(this->entries) - >> cpplinq::where(predicate) - >> cpplinq::to_vector(); - - return data; -} - -//! Gets all the entries in the table -const std::vector& CDLootTableTable::GetEntries() const { - return this->entries; -} - diff --git a/dDatabase/Tables/CDLootTableTable.h b/dDatabase/Tables/CDLootTableTable.h index baa300b0..b8ac2066 100644 --- a/dDatabase/Tables/CDLootTableTable.h +++ b/dDatabase/Tables/CDLootTableTable.h @@ -6,20 +6,21 @@ struct CDLootTable { unsigned int itemid; //!< The LOT of the item unsigned int LootTableIndex; //!< The Loot Table Index - unsigned int id; //!< The ID bool MissionDrop; //!< Whether or not this loot table is a mission drop unsigned int sortPriority; //!< The sorting priority }; +typedef uint32_t LootTableIndex; +typedef std::vector LootTableEntries; + class CDLootTableTable : public CDTable { private: - std::vector entries; + CDLootTable ReadRow(CppSQLite3Query& tableData) const; + std::unordered_map entries; public: void LoadValuesFromDatabase(); // Queries the table with a custom "where" clause - std::vector Query(std::function predicate); - - const std::vector& GetEntries() const; + const LootTableEntries& GetTable(uint32_t tableId); }; diff --git a/dDatabase/Tables/CDRarityTableTable.cpp b/dDatabase/Tables/CDRarityTableTable.cpp index b0295a59..aa451ae3 100644 --- a/dDatabase/Tables/CDRarityTableTable.cpp +++ b/dDatabase/Tables/CDRarityTableTable.cpp @@ -17,33 +17,18 @@ void CDRarityTableTable::LoadValuesFromDatabase() { this->entries.reserve(size); // Now get the data - auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM RarityTable"); + auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM RarityTable order by randmax desc;"); while (!tableData.eof()) { + uint32_t rarityTableIndex = tableData.getIntField("RarityTableIndex", -1); + CDRarityTable entry; - entry.id = tableData.getIntField("id", -1); entry.randmax = tableData.getFloatField("randmax", -1); entry.rarity = tableData.getIntField("rarity", -1); - entry.RarityTableIndex = tableData.getIntField("RarityTableIndex", -1); - - this->entries.push_back(entry); + entries[rarityTableIndex].push_back(entry); tableData.nextRow(); } - - tableData.finalize(); } -//! Queries the table with a custom "where" clause -std::vector CDRarityTableTable::Query(std::function predicate) { - - std::vector data = cpplinq::from(this->entries) - >> cpplinq::where(predicate) - >> cpplinq::to_vector(); - - return data; +const std::vector& CDRarityTableTable::GetRarityTable(uint32_t id) { + return entries[id]; } - -//! Gets all the entries in the table -const std::vector& CDRarityTableTable::GetEntries() const { - return this->entries; -} - diff --git a/dDatabase/Tables/CDRarityTableTable.h b/dDatabase/Tables/CDRarityTableTable.h index 2d28e4a5..e2053da7 100644 --- a/dDatabase/Tables/CDRarityTableTable.h +++ b/dDatabase/Tables/CDRarityTableTable.h @@ -4,37 +4,20 @@ #include "CDTable.h" struct CDRarityTable { - unsigned int id; float randmax; unsigned int rarity; - unsigned int RarityTableIndex; - - friend bool operator> (const CDRarityTable& c1, const CDRarityTable& c2) { - return c1.rarity > c2.rarity; - } - - friend bool operator>= (const CDRarityTable& c1, const CDRarityTable& c2) { - return c1.rarity >= c2.rarity; - } - - friend bool operator< (const CDRarityTable& c1, const CDRarityTable& c2) { - return c1.rarity < c2.rarity; - } - - friend bool operator<= (const CDRarityTable& c1, const CDRarityTable& c2) { - return c1.rarity <= c2.rarity; - } }; +typedef std::vector RarityTable; + class CDRarityTableTable : public CDTable { private: - std::vector entries; + typedef uint32_t RarityTableIndex; + std::unordered_map> entries; public: void LoadValuesFromDatabase(); - // Queries the table with a custom "where" clause - std::vector Query(std::function predicate); - const std::vector& GetEntries() const; + const std::vector& GetRarityTable(uint32_t predicate); }; diff --git a/dGame/Entity.cpp b/dGame/Entity.cpp index b577d1f5..b3a0a3cc 100644 --- a/dGame/Entity.cpp +++ b/dGame/Entity.cpp @@ -377,6 +377,7 @@ void Entity::Initialize() { comp->SetIsSmashable(destCompData[0].isSmashable); comp->SetLootMatrixID(destCompData[0].LootMatrixIndex); + Loot::CacheMatrix(destCompData[0].LootMatrixIndex); // Now get currency information uint32_t npcMinLevel = destCompData[0].level; @@ -565,6 +566,7 @@ void Entity::Initialize() { if (activityID > 0) { comp->SetActivityId(activityID); + Loot::CacheMatrix(activityID); } const auto compTime = GetVar(u"compTime"); diff --git a/dGame/dComponents/DestroyableComponent.cpp b/dGame/dComponents/DestroyableComponent.cpp index 35884361..06fc8848 100644 --- a/dGame/dComponents/DestroyableComponent.cpp +++ b/dGame/dComponents/DestroyableComponent.cpp @@ -735,18 +735,18 @@ void DestroyableComponent::Smash(const LWOOBJID source, const eKillType killType auto* member = Game::entityManager->GetEntity(specificOwner); - if (member) LootGenerator::Instance().DropLoot(member, m_Parent, lootMatrixId, GetMinCoins(), GetMaxCoins()); + if (member) Loot::DropLoot(member, m_Parent, lootMatrixId, GetMinCoins(), GetMaxCoins()); } else { for (const auto memberId : team->members) { // Free for all auto* member = Game::entityManager->GetEntity(memberId); if (member == nullptr) continue; - LootGenerator::Instance().DropLoot(member, m_Parent, lootMatrixId, GetMinCoins(), GetMaxCoins()); + Loot::DropLoot(member, m_Parent, lootMatrixId, GetMinCoins(), GetMaxCoins()); } } } else { // drop loot for non team user - LootGenerator::Instance().DropLoot(owner, m_Parent, GetLootMatrixID(), GetMinCoins(), GetMaxCoins()); + Loot::DropLoot(owner, m_Parent, GetLootMatrixID(), GetMinCoins(), GetMaxCoins()); } } } else { @@ -764,7 +764,7 @@ void DestroyableComponent::Smash(const LWOOBJID source, const eKillType killType coinsTotal -= coinsToLose; - LootGenerator::Instance().DropLoot(m_Parent, m_Parent, -1, coinsToLose, coinsToLose); + Loot::DropLoot(m_Parent, m_Parent, -1, coinsToLose, coinsToLose); character->SetCoins(coinsTotal, eLootSourceType::PICKUP); } } diff --git a/dGame/dComponents/RacingControlComponent.cpp b/dGame/dComponents/RacingControlComponent.cpp index 12f4201a..cda1abd0 100644 --- a/dGame/dComponents/RacingControlComponent.cpp +++ b/dGame/dComponents/RacingControlComponent.cpp @@ -388,7 +388,7 @@ void RacingControlComponent::HandleMessageBoxResponse(Entity* player, int32_t bu } const auto score = playersRating * 10 + data->finished; - LootGenerator::Instance().GiveActivityLoot(player, m_Parent, m_ActivityID, score); + Loot::GiveActivityLoot(player, m_Parent, m_ActivityID, score); // Giving rewards GameMessages::SendNotifyRacingClient( diff --git a/dGame/dComponents/RebuildComponent.cpp b/dGame/dComponents/RebuildComponent.cpp index 3f38c275..da8a9a4b 100644 --- a/dGame/dComponents/RebuildComponent.cpp +++ b/dGame/dComponents/RebuildComponent.cpp @@ -486,7 +486,7 @@ void RebuildComponent::CompleteRebuild(Entity* user) { auto* missionComponent = builder->GetComponent(); if (missionComponent) missionComponent->Progress(eMissionTaskType::ACTIVITY, m_ActivityId); } - LootGenerator::Instance().DropActivityLoot(builder, m_Parent, m_ActivityId, 1); + Loot::DropActivityLoot(builder, m_Parent, m_ActivityId, 1); } // Notify scripts diff --git a/dGame/dComponents/ScriptedActivityComponent.cpp b/dGame/dComponents/ScriptedActivityComponent.cpp index 2aae6297..fa70139b 100644 --- a/dGame/dComponents/ScriptedActivityComponent.cpp +++ b/dGame/dComponents/ScriptedActivityComponent.cpp @@ -576,7 +576,7 @@ void ActivityInstance::RewardParticipant(Entity* participant) { maxCoins = currencyTable[0].maxvalue; } - LootGenerator::Instance().DropLoot(participant, m_Parent, activityRewards[0].LootMatrixIndex, minCoins, maxCoins); + Loot::DropLoot(participant, m_Parent, activityRewards[0].LootMatrixIndex, minCoins, maxCoins); } } diff --git a/dGame/dComponents/VendorComponent.cpp b/dGame/dComponents/VendorComponent.cpp index e5e0f3d8..e6f99245 100644 --- a/dGame/dComponents/VendorComponent.cpp +++ b/dGame/dComponents/VendorComponent.cpp @@ -42,7 +42,7 @@ void VendorComponent::RefreshInventory(bool isCreation) { } auto* lootMatrixTable = CDClientManager::Instance().GetTable(); - const auto lootMatrices = lootMatrixTable->Query([=](CDLootMatrix entry) { return (entry.LootMatrixIndex == m_LootMatrixID); }); + const auto& lootMatrices = lootMatrixTable->GetMatrix(m_LootMatrixID); if (lootMatrices.empty()) return; @@ -51,8 +51,7 @@ void VendorComponent::RefreshInventory(bool isCreation) { auto* compRegistryTable = CDClientManager::Instance().GetTable(); for (const auto& lootMatrix : lootMatrices) { - int lootTableID = lootMatrix.LootTableIndex; - auto vendorItems = lootTableTable->Query([=](CDLootTable entry) { return (entry.LootTableIndex == lootTableID); }); + auto vendorItems = lootTableTable->GetTable(lootMatrix.LootTableIndex); if (lootMatrix.maxToDrop == 0 || lootMatrix.minToDrop == 0) { for (const auto& item : vendorItems) { if (!m_HasStandardCostItems || !m_HasMultiCostItems) { diff --git a/dGame/dInventory/Item.cpp b/dGame/dInventory/Item.cpp index 64f1dfbd..e55df9d2 100644 --- a/dGame/dInventory/Item.cpp +++ b/dGame/dInventory/Item.cpp @@ -319,7 +319,7 @@ void Item::UseNonEquip(Item* item) { // Roll the loot for all the packages then see if it all fits. If it fits, give it to the player, otherwise don't. std::unordered_map rolledLoot{}; for (auto& pack : packages) { - auto thisPackage = LootGenerator::Instance().RollLootMatrix(entityParent, pack.LootMatrixIndex); + auto thisPackage = Loot::RollLootMatrix(entityParent, pack.LootMatrixIndex); for (auto& loot : thisPackage) { // If we already rolled this lot, add it to the existing one, otherwise create a new entry. auto existingLoot = rolledLoot.find(loot.first); @@ -331,7 +331,7 @@ void Item::UseNonEquip(Item* item) { } } if (playerInventoryComponent->HasSpaceForLoot(rolledLoot)) { - LootGenerator::Instance().GiveLoot(playerInventoryComponent->GetParent(), rolledLoot, eLootSourceType::CONSUMPTION); + Loot::GiveLoot(playerInventoryComponent->GetParent(), rolledLoot, eLootSourceType::CONSUMPTION); item->SetCount(item->GetCount() - 1); } else { success = false; diff --git a/dGame/dUtilities/Loot.cpp b/dGame/dUtilities/Loot.cpp index c788c016..09c465bf 100644 --- a/dGame/dUtilities/Loot.cpp +++ b/dGame/dUtilities/Loot.cpp @@ -1,7 +1,8 @@ -#include - #include "Loot.h" +#include +#include + #include "CDComponentsRegistryTable.h" #include "CDItemComponentTable.h" #include "CDLootMatrixTable.h" @@ -18,148 +19,60 @@ #include "eMissionState.h" #include "eReplicaComponentType.h" -LootGenerator::LootGenerator() { - CDLootTableTable* lootTableTable = CDClientManager::Instance().GetTable(); +namespace { + std::unordered_set CachedMatrices; +} + +void Loot::CacheMatrix(uint32_t matrixIndex) { + if (CachedMatrices.find(matrixIndex) != CachedMatrices.end()) { + return; + } + CachedMatrices.insert(matrixIndex); CDComponentsRegistryTable* componentsRegistryTable = CDClientManager::Instance().GetTable(); CDItemComponentTable* itemComponentTable = CDClientManager::Instance().GetTable(); CDLootMatrixTable* lootMatrixTable = CDClientManager::Instance().GetTable(); + CDLootTableTable* lootTableTable = CDClientManager::Instance().GetTable(); CDRarityTableTable* rarityTableTable = CDClientManager::Instance().GetTable(); - // ============================== - // Cache Item Rarities - // ============================== + const auto& matrix = lootMatrixTable->GetMatrix(matrixIndex); - std::vector uniqueItems; - - for (const CDLootTable& loot : lootTableTable->GetEntries()) { - uniqueItems.push_back(loot.itemid); - } - - // filter out duplicates - std::sort(uniqueItems.begin(), uniqueItems.end()); - uniqueItems.erase(std::unique(uniqueItems.begin(), uniqueItems.end()), uniqueItems.end()); - - for (const uint32_t itemID : uniqueItems) { - uint32_t itemComponentID = componentsRegistryTable->GetByIDAndType(itemID, eReplicaComponentType::ITEM); - const CDItemComponent& item = itemComponentTable->GetItemComponentByID(itemComponentID); - - m_ItemRarities.insert({ itemID, item.rarity }); - } - - // ============================== - // Cache Rarity Tables - // ============================== - - std::vector uniqueRarityIndices; - - for (const CDRarityTable& rarity : rarityTableTable->GetEntries()) { - uniqueRarityIndices.push_back(rarity.RarityTableIndex); - } - - // filter out duplicates - std::sort(uniqueRarityIndices.begin(), uniqueRarityIndices.end()); - uniqueRarityIndices.erase(std::unique(uniqueRarityIndices.begin(), uniqueRarityIndices.end()), uniqueRarityIndices.end()); - - for (const uint32_t index : uniqueRarityIndices) { - std::vector table = rarityTableTable->Query([index](const CDRarityTable& entry) { return entry.RarityTableIndex == index; }); - - RarityTable rarityTable; - - for (const CDRarityTable& entry : table) { - RarityTableEntry rarity{ entry.rarity, entry.randmax }; - rarityTable.push_back(rarity); + for (const auto& entry : matrix) { + const auto& lootTable = lootTableTable->GetTable(entry.LootTableIndex); + const auto& rarityTable = rarityTableTable->GetRarityTable(entry.RarityTableIndex); + for (const auto& loot : lootTable) { + uint32_t itemComponentId = componentsRegistryTable->GetByIDAndType(loot.itemid, eReplicaComponentType::ITEM); + uint32_t rarity = itemComponentTable->GetItemComponentByID(itemComponentId).rarity; } - - // sort in descending order based on randMax - std::sort(rarityTable.begin(), rarityTable.end(), [](const RarityTableEntry& x, const RarityTableEntry& y) { return x.randMax > y.randMax; }); - - m_RarityTables.insert({ index, rarityTable }); - } - - // ============================== - // Cache Loot Matrices - // ============================== - - std::vector uniqueMatrixIndices; - - for (const CDLootMatrix& matrix : lootMatrixTable->GetEntries()) { - uniqueMatrixIndices.push_back(matrix.LootMatrixIndex); - } - - // filter out duplicates - std::sort(uniqueMatrixIndices.begin(), uniqueMatrixIndices.end()); - uniqueMatrixIndices.erase(std::unique(uniqueMatrixIndices.begin(), uniqueMatrixIndices.end()), uniqueMatrixIndices.end()); - - for (const uint32_t index : uniqueMatrixIndices) { - std::vector matrix = lootMatrixTable->Query([index](const CDLootMatrix& entry) { return entry.LootMatrixIndex == index; }); - - LootMatrix lootMatrix; - - for (const CDLootMatrix& entry : matrix) { - LootMatrixEntry matrixEntry{ entry.LootTableIndex, entry.RarityTableIndex, entry.percent, entry.minToDrop, entry.maxToDrop }; - lootMatrix.push_back(matrixEntry); - } - - m_LootMatrices.insert({ index, lootMatrix }); - } - - // ============================== - // Cache Loot Tables - // ============================== - - std::vector uniqueTableIndices; - - for (const CDLootTable& entry : lootTableTable->GetEntries()) { - uniqueTableIndices.push_back(entry.LootTableIndex); - } - - // filter out duplicates - std::sort(uniqueTableIndices.begin(), uniqueTableIndices.end()); - uniqueTableIndices.erase(std::unique(uniqueTableIndices.begin(), uniqueTableIndices.end()), uniqueTableIndices.end()); - - for (const uint32_t index : uniqueTableIndices) { - std::vector entries = lootTableTable->Query([index](const CDLootTable& entry) { return entry.LootTableIndex == index; }); - - LootTable lootTable; - - for (const CDLootTable& entry : entries) { - LootTableEntry tableEntry{ (LOT)entry.itemid, entry.MissionDrop }; - lootTable.push_back(tableEntry); - } - - // sort by item rarity descending - std::sort(lootTable.begin(), lootTable.end(), [&](const LootTableEntry& x, const LootTableEntry& y) { - return m_ItemRarities[x.itemID] > m_ItemRarities[y.itemID]; - }); - - m_LootTables.insert({ index, lootTable }); } } -std::unordered_map LootGenerator::RollLootMatrix(Entity* player, uint32_t matrixIndex) { +std::unordered_map Loot::RollLootMatrix(Entity* player, uint32_t matrixIndex) { + CDComponentsRegistryTable* componentsRegistryTable = CDClientManager::Instance().GetTable(); + CDItemComponentTable* itemComponentTable = CDClientManager::Instance().GetTable(); + CDLootMatrixTable* lootMatrixTable = CDClientManager::Instance().GetTable(); + CDLootTableTable* lootTableTable = CDClientManager::Instance().GetTable(); + CDRarityTableTable* rarityTableTable = CDClientManager::Instance().GetTable(); auto* missionComponent = player->GetComponent(); std::unordered_map drops; - if (missionComponent == nullptr) { - return drops; - } + if (missionComponent == nullptr) return drops; - const LootMatrix& matrix = m_LootMatrices[matrixIndex]; + const auto& matrix = lootMatrixTable->GetMatrix(matrixIndex); - for (const LootMatrixEntry& entry : matrix) { - if (GeneralUtils::GenerateRandomNumber(0, 1) < entry.percent) { - const LootTable& lootTable = m_LootTables[entry.lootTableIndex]; - const RarityTable& rarityTable = m_RarityTables[entry.rarityTableIndex]; + for (const auto& entry : matrix) { + if (GeneralUtils::GenerateRandomNumber(0, 1) < entry.percent) { // GetTable + const auto& lootTable = lootTableTable->GetTable(entry.LootTableIndex); + const auto& rarityTable = rarityTableTable->GetRarityTable(entry.RarityTableIndex); - uint32_t dropCount = GeneralUtils::GenerateRandomNumber(entry.minDrop, entry.maxDrop); + uint32_t dropCount = GeneralUtils::GenerateRandomNumber(entry.minToDrop, entry.maxToDrop); for (uint32_t i = 0; i < dropCount; ++i) { uint32_t maxRarity = 1; float rarityRoll = GeneralUtils::GenerateRandomNumber(0, 1); - for (const RarityTableEntry& rarity : rarityTable) { - if (rarity.randMax >= rarityRoll) { + for (const auto& rarity : rarityTable) { + if (rarity.randmax >= rarityRoll) { maxRarity = rarity.rarity; } else { break; @@ -167,10 +80,11 @@ std::unordered_map LootGenerator::RollLootMatrix(Entity* player, u } bool rarityFound = false; - std::vector possibleDrops; + std::vector possibleDrops; - for (const LootTableEntry& loot : lootTable) { - uint32_t rarity = m_ItemRarities[loot.itemID]; + for (const auto& loot : lootTable) { + uint32_t itemComponentId = componentsRegistryTable->GetByIDAndType(loot.itemid, eReplicaComponentType::ITEM); + uint32_t rarity = itemComponentTable->GetItemComponentByID(itemComponentId).rarity; if (rarity == maxRarity) { possibleDrops.push_back(loot); @@ -182,32 +96,34 @@ std::unordered_map LootGenerator::RollLootMatrix(Entity* player, u } if (possibleDrops.size() > 0) { - LootTableEntry drop = possibleDrops[GeneralUtils::GenerateRandomNumber(0, possibleDrops.size() - 1)]; + const auto& drop = possibleDrops[GeneralUtils::GenerateRandomNumber(0, possibleDrops.size() - 1)]; // filter out uneeded mission items - if (drop.isMissionDrop && !missionComponent->RequiresItem(drop.itemID)) + if (drop.MissionDrop && !missionComponent->RequiresItem(drop.itemid)) continue; + LOT itemID = drop.itemid; // convert faction token proxy - if (drop.itemID == 13763) { + if (itemID == 13763) { if (missionComponent->GetMissionState(545) == eMissionState::COMPLETE) - drop.itemID = 8318; // "Assembly Token" + itemID = 8318; // "Assembly Token" else if (missionComponent->GetMissionState(556) == eMissionState::COMPLETE) - drop.itemID = 8321; // "Venture League Token" + itemID = 8321; // "Venture League Token" else if (missionComponent->GetMissionState(567) == eMissionState::COMPLETE) - drop.itemID = 8319; // "Sentinels Token" + itemID = 8319; // "Sentinels Token" else if (missionComponent->GetMissionState(578) == eMissionState::COMPLETE) - drop.itemID = 8320; // "Paradox Token" + itemID = 8320; // "Paradox Token" } - if (drop.itemID == 13763) { + if (itemID == 13763) { continue; } // check if we aren't in faction - if (drops.find(drop.itemID) == drops.end()) { - drops.insert({ drop.itemID, 1 }); + // drops[itemID]++; this should work? + if (drops.find(itemID) == drops.end()) { + drops.insert({ itemID, 1 }); } else { - ++drops[drop.itemID]; + ++drops[itemID]; } } } @@ -217,24 +133,29 @@ std::unordered_map LootGenerator::RollLootMatrix(Entity* player, u return drops; } -std::unordered_map LootGenerator::RollLootMatrix(uint32_t matrixIndex) { +std::unordered_map Loot::RollLootMatrix(uint32_t matrixIndex) { + CDComponentsRegistryTable* componentsRegistryTable = CDClientManager::Instance().GetTable(); + CDItemComponentTable* itemComponentTable = CDClientManager::Instance().GetTable(); + CDLootMatrixTable* lootMatrixTable = CDClientManager::Instance().GetTable(); + CDLootTableTable* lootTableTable = CDClientManager::Instance().GetTable(); + CDRarityTableTable* rarityTableTable = CDClientManager::Instance().GetTable(); std::unordered_map drops; - const LootMatrix& matrix = m_LootMatrices[matrixIndex]; + const auto& matrix = lootMatrixTable->GetMatrix(matrixIndex); - for (const LootMatrixEntry& entry : matrix) { + for (const auto& entry : matrix) { if (GeneralUtils::GenerateRandomNumber(0, 1) < entry.percent) { - const LootTable& lootTable = m_LootTables[entry.lootTableIndex]; - const RarityTable& rarityTable = m_RarityTables[entry.rarityTableIndex]; + const auto& lootTable = lootTableTable->GetTable(entry.LootTableIndex); + const auto& rarityTable = rarityTableTable->GetRarityTable(entry.RarityTableIndex); - uint32_t dropCount = GeneralUtils::GenerateRandomNumber(entry.minDrop, entry.maxDrop); + uint32_t dropCount = GeneralUtils::GenerateRandomNumber(entry.minToDrop, entry.maxToDrop); for (uint32_t i = 0; i < dropCount; ++i) { uint32_t maxRarity = 1; float rarityRoll = GeneralUtils::GenerateRandomNumber(0, 1); - for (const RarityTableEntry& rarity : rarityTable) { - if (rarity.randMax >= rarityRoll) { + for (const auto& rarity : rarityTable) { + if (rarity.randmax >= rarityRoll) { maxRarity = rarity.rarity; } else { break; @@ -242,10 +163,11 @@ std::unordered_map LootGenerator::RollLootMatrix(uint32_t matrixIn } bool rarityFound = false; - std::vector possibleDrops; + std::vector possibleDrops; - for (const LootTableEntry& loot : lootTable) { - uint32_t rarity = m_ItemRarities[loot.itemID]; + for (const auto& loot : lootTable) { + uint32_t itemComponentId = componentsRegistryTable->GetByIDAndType(loot.itemid, eReplicaComponentType::ITEM); + uint32_t rarity = itemComponentTable->GetItemComponentByID(itemComponentId).rarity; if (rarity == maxRarity) { possibleDrops.push_back(loot); @@ -257,12 +179,12 @@ std::unordered_map LootGenerator::RollLootMatrix(uint32_t matrixIn } if (possibleDrops.size() > 0) { - const LootTableEntry& drop = possibleDrops[GeneralUtils::GenerateRandomNumber(0, possibleDrops.size() - 1)]; + const auto& drop = possibleDrops[GeneralUtils::GenerateRandomNumber(0, possibleDrops.size() - 1)]; - if (drops.find(drop.itemID) == drops.end()) { - drops.insert({ drop.itemID, 1 }); + if (drops.find(drop.itemid) == drops.end()) { + drops.insert({ drop.itemid, 1 }); } else { - ++drops[drop.itemID]; + ++drops[drop.itemid]; } } } @@ -272,7 +194,7 @@ std::unordered_map LootGenerator::RollLootMatrix(uint32_t matrixIn return drops; } -void LootGenerator::GiveLoot(Entity* player, uint32_t matrixIndex, eLootSourceType lootSourceType) { +void Loot::GiveLoot(Entity* player, uint32_t matrixIndex, eLootSourceType lootSourceType) { player = player->GetOwner(); // If the owner is overwritten, we collect that here std::unordered_map result = RollLootMatrix(player, matrixIndex); @@ -280,7 +202,7 @@ void LootGenerator::GiveLoot(Entity* player, uint32_t matrixIndex, eLootSourceTy GiveLoot(player, result, lootSourceType); } -void LootGenerator::GiveLoot(Entity* player, std::unordered_map& result, eLootSourceType lootSourceType) { +void Loot::GiveLoot(Entity* player, std::unordered_map& result, eLootSourceType lootSourceType) { player = player->GetOwner(); // if the owner is overwritten, we collect that here auto* inventoryComponent = player->GetComponent(); @@ -293,7 +215,7 @@ void LootGenerator::GiveLoot(Entity* player, std::unordered_map& r } } -void LootGenerator::GiveActivityLoot(Entity* player, Entity* source, uint32_t activityID, int32_t rating) { +void Loot::GiveActivityLoot(Entity* player, Entity* source, uint32_t activityID, int32_t rating) { CDActivityRewardsTable* activityRewardsTable = CDClientManager::Instance().GetTable(); std::vector activityRewards = activityRewardsTable->Query([activityID](CDActivityRewards entry) { return (entry.objectTemplate == activityID); }); @@ -327,7 +249,7 @@ void LootGenerator::GiveActivityLoot(Entity* player, Entity* source, uint32_t ac character->SetCoins(character->GetCoins() + coins, eLootSourceType::ACTIVITY); } -void LootGenerator::DropLoot(Entity* player, Entity* killedObject, uint32_t matrixIndex, uint32_t minCoins, uint32_t maxCoins) { +void Loot::DropLoot(Entity* player, Entity* killedObject, uint32_t matrixIndex, uint32_t minCoins, uint32_t maxCoins) { player = player->GetOwner(); // if the owner is overwritten, we collect that here auto* inventoryComponent = player->GetComponent(); @@ -340,7 +262,7 @@ void LootGenerator::DropLoot(Entity* player, Entity* killedObject, uint32_t matr DropLoot(player, killedObject, result, minCoins, maxCoins); } -void LootGenerator::DropLoot(Entity* player, Entity* killedObject, std::unordered_map& result, uint32_t minCoins, uint32_t maxCoins) { +void Loot::DropLoot(Entity* player, Entity* killedObject, std::unordered_map& result, uint32_t minCoins, uint32_t maxCoins) { player = player->GetOwner(); // if the owner is overwritten, we collect that here auto* inventoryComponent = player->GetComponent(); @@ -363,7 +285,7 @@ void LootGenerator::DropLoot(Entity* player, Entity* killedObject, std::unordere GameMessages::SendDropClientLoot(player, source, LOT_NULL, coins, spawnPosition); } -void LootGenerator::DropActivityLoot(Entity* player, Entity* source, uint32_t activityID, int32_t rating) { +void Loot::DropActivityLoot(Entity* player, Entity* source, uint32_t activityID, int32_t rating) { CDActivityRewardsTable* activityRewardsTable = CDClientManager::Instance().GetTable(); std::vector activityRewards = activityRewardsTable->Query([activityID](CDActivityRewards entry) { return (entry.objectTemplate == activityID); }); diff --git a/dGame/dUtilities/Loot.h b/dGame/dUtilities/Loot.h index a1c52b63..dacd3dcd 100644 --- a/dGame/dUtilities/Loot.h +++ b/dGame/dUtilities/Loot.h @@ -2,61 +2,23 @@ #include "dCommonVars.h" #include -#include "Singleton.h" -#include class Entity; -struct RarityTableEntry { - uint32_t rarity; - float randMax; -}; - -typedef std::vector RarityTable; - -struct LootMatrixEntry { - uint32_t lootTableIndex; - uint32_t rarityTableIndex; - float percent; - uint32_t minDrop; - uint32_t maxDrop; -}; - -typedef std::vector LootMatrix; - -struct LootTableEntry { - LOT itemID; - bool isMissionDrop; -}; - -typedef std::vector LootTable; - -// used for glue code with Entity and Player classes namespace Loot { struct Info { - LWOOBJID id; - LOT lot; - uint32_t count; + LWOOBJID id = 0; + LOT lot = 0; + uint32_t count = 0; }; -} - - -class LootGenerator : public Singleton { -public: - LootGenerator(); std::unordered_map RollLootMatrix(Entity* player, uint32_t matrixIndex); std::unordered_map RollLootMatrix(uint32_t matrixIndex); + void CacheMatrix(const uint32_t matrixIndex); void GiveLoot(Entity* player, uint32_t matrixIndex, eLootSourceType lootSourceType = eLootSourceType::NONE); void GiveLoot(Entity* player, std::unordered_map& result, eLootSourceType lootSourceType = eLootSourceType::NONE); void GiveActivityLoot(Entity* player, Entity* source, uint32_t activityID, int32_t rating = 0); void DropLoot(Entity* player, Entity* killedObject, uint32_t matrixIndex, uint32_t minCoins, uint32_t maxCoins); void DropLoot(Entity* player, Entity* killedObject, std::unordered_map& result, uint32_t minCoins, uint32_t maxCoins); void DropActivityLoot(Entity* player, Entity* source, uint32_t activityID, int32_t rating = 0); - -private: - std::unordered_map m_ItemRarities; - std::unordered_map m_RarityTables; - std::unordered_map m_LootMatrices; - std::unordered_map m_LootTables; }; diff --git a/dGame/dUtilities/SlashCommandHandler.cpp b/dGame/dUtilities/SlashCommandHandler.cpp index a27b6278..17fd980c 100644 --- a/dGame/dUtilities/SlashCommandHandler.cpp +++ b/dGame/dUtilities/SlashCommandHandler.cpp @@ -1790,7 +1790,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit for (uint32_t i = 0; i < loops; i++) { while (true) { - auto lootRoll = LootGenerator::Instance().RollLootMatrix(lootMatrixIndex); + auto lootRoll = Loot::RollLootMatrix(lootMatrixIndex); totalRuns += 1; bool doBreak = false; for (const auto& kv : lootRoll) { diff --git a/dScripts/02_server/Enemy/General/TreasureChestDragonServer.cpp b/dScripts/02_server/Enemy/General/TreasureChestDragonServer.cpp index 87416b4d..fd227087 100644 --- a/dScripts/02_server/Enemy/General/TreasureChestDragonServer.cpp +++ b/dScripts/02_server/Enemy/General/TreasureChestDragonServer.cpp @@ -33,10 +33,10 @@ void TreasureChestDragonServer::OnUse(Entity* self, Entity* user) { if (memberObject == nullptr) continue; - LootGenerator::Instance().DropActivityLoot(memberObject, self, scriptedActivityComponent->GetActivityID(), rating); + Loot::DropActivityLoot(memberObject, self, scriptedActivityComponent->GetActivityID(), rating); } } else { - LootGenerator::Instance().DropActivityLoot(user, self, scriptedActivityComponent->GetActivityID(), rating); + Loot::DropActivityLoot(user, self, scriptedActivityComponent->GetActivityID(), rating); } self->Smash(self->GetObjectID()); diff --git a/dScripts/02_server/Equipment/BootyDigServer.cpp b/dScripts/02_server/Equipment/BootyDigServer.cpp index d27d1faa..0461047e 100644 --- a/dScripts/02_server/Equipment/BootyDigServer.cpp +++ b/dScripts/02_server/Equipment/BootyDigServer.cpp @@ -45,7 +45,7 @@ BootyDigServer::OnFireEventServerSide(Entity* self, Entity* sender, std::string if (renderComponent != nullptr) renderComponent->PlayEffect(7730, u"cast", "bootyshine"); - LootGenerator::Instance().DropLoot(player, self, 231, 75, 75); + Loot::DropLoot(player, self, 231, 75, 75); } } } else if (args == "ChestDead") { diff --git a/dScripts/02_server/Map/General/BaseInteractDropLootServer.cpp b/dScripts/02_server/Map/General/BaseInteractDropLootServer.cpp index 44698956..dd25868d 100644 --- a/dScripts/02_server/Map/General/BaseInteractDropLootServer.cpp +++ b/dScripts/02_server/Map/General/BaseInteractDropLootServer.cpp @@ -22,7 +22,7 @@ void BaseInteractDropLootServer::BaseUse(Entity* self, Entity* user) { self->SetNetworkVar(u"bInUse", true); - LootGenerator::Instance().DropLoot(user, self, lootMatrix, 0, 0); + Loot::DropLoot(user, self, lootMatrix, 0, 0); self->AddCallbackTimer(cooldownTime, [this, self]() { self->SetNetworkVar(u"bInUse", false); diff --git a/dScripts/02_server/Map/General/GrowingFlower.cpp b/dScripts/02_server/Map/General/GrowingFlower.cpp index ad88528f..e9891902 100644 --- a/dScripts/02_server/Map/General/GrowingFlower.cpp +++ b/dScripts/02_server/Map/General/GrowingFlower.cpp @@ -13,7 +13,7 @@ void GrowingFlower::OnSkillEventFired(Entity* self, Entity* target, const std::s const auto mission1 = self->GetVar(u"missionID"); const auto mission2 = self->GetVar(u"missionID2"); - LootGenerator::Instance().DropActivityLoot(target, self, self->GetLOT(), 0); + Loot::DropActivityLoot(target, self, self->GetLOT(), 0); auto* missionComponent = target->GetComponent(); if (missionComponent != nullptr) { diff --git a/dScripts/02_server/Map/General/WishingWellServer.cpp b/dScripts/02_server/Map/General/WishingWellServer.cpp index 51f742ec..86af5a9a 100644 --- a/dScripts/02_server/Map/General/WishingWellServer.cpp +++ b/dScripts/02_server/Map/General/WishingWellServer.cpp @@ -21,7 +21,7 @@ void WishingWellServer::OnUse(Entity* self, Entity* user) { GameMessages::SendPlayNDAudioEmitter(self, user->GetSystemAddress(), audio); } - LootGenerator::Instance().DropActivityLoot( + Loot::DropActivityLoot( user, self, static_cast(scriptedActivity->GetActivityID()), diff --git a/dScripts/02_server/Map/VE/VeMissionConsole.cpp b/dScripts/02_server/Map/VE/VeMissionConsole.cpp index 35061bdf..7a8a1439 100644 --- a/dScripts/02_server/Map/VE/VeMissionConsole.cpp +++ b/dScripts/02_server/Map/VE/VeMissionConsole.cpp @@ -6,7 +6,7 @@ #include "eTerminateType.h" void VeMissionConsole::OnUse(Entity* self, Entity* user) { - LootGenerator::Instance().DropActivityLoot(user, self, 12551); + Loot::DropActivityLoot(user, self, 12551); auto* inventoryComponent = user->GetComponent(); if (inventoryComponent != nullptr) { diff --git a/dScripts/02_server/Map/njhub/NjDragonEmblemChestServer.cpp b/dScripts/02_server/Map/njhub/NjDragonEmblemChestServer.cpp index 931cfe56..74e50b1c 100644 --- a/dScripts/02_server/Map/njhub/NjDragonEmblemChestServer.cpp +++ b/dScripts/02_server/Map/njhub/NjDragonEmblemChestServer.cpp @@ -14,6 +14,6 @@ void NjDragonEmblemChestServer::OnUse(Entity* self, Entity* user) { auto* destroyable = self->GetComponent(); if (destroyable != nullptr) { - LootGenerator::Instance().DropLoot(user, self, destroyable->GetLootMatrixID(), 0, 0); + Loot::DropLoot(user, self, destroyable->GetLootMatrixID(), 0, 0); } } diff --git a/dScripts/02_server/Minigame/General/MinigameTreasureChestServer.cpp b/dScripts/02_server/Minigame/General/MinigameTreasureChestServer.cpp index e06ed1d9..2e5645cd 100644 --- a/dScripts/02_server/Minigame/General/MinigameTreasureChestServer.cpp +++ b/dScripts/02_server/Minigame/General/MinigameTreasureChestServer.cpp @@ -27,7 +27,7 @@ void MinigameTreasureChestServer::OnUse(Entity* self, Entity* user) { if (self->GetLOT() == frakjawChestId) activityRating = team->members.size(); - LootGenerator::Instance().DropActivityLoot(teamMember, self, sac->GetActivityID(), activityRating); + Loot::DropActivityLoot(teamMember, self, sac->GetActivityID(), activityRating); } } } else { @@ -35,7 +35,7 @@ void MinigameTreasureChestServer::OnUse(Entity* self, Entity* user) { if (self->GetLOT() == frakjawChestId) activityRating = 1; - LootGenerator::Instance().DropActivityLoot(user, self, sac->GetActivityID(), activityRating); + Loot::DropActivityLoot(user, self, sac->GetActivityID(), activityRating); } sac->PlayerRemove(user->GetObjectID()); diff --git a/dScripts/ActivityManager.cpp b/dScripts/ActivityManager.cpp index 24e661e3..a5bc0d5b 100644 --- a/dScripts/ActivityManager.cpp +++ b/dScripts/ActivityManager.cpp @@ -71,7 +71,7 @@ void ActivityManager::StopActivity(Entity* self, const LWOOBJID playerID, const SetActivityValue(self, playerID, 1, value1); SetActivityValue(self, playerID, 2, value2); - LootGenerator::Instance().GiveActivityLoot(player, self, gameID, CalculateActivityRating(self, playerID)); + Loot::GiveActivityLoot(player, self, gameID, CalculateActivityRating(self, playerID)); if (sac != nullptr) { sac->PlayerRemove(player->GetObjectID()); diff --git a/dScripts/ScriptedPowerupSpawner.cpp b/dScripts/ScriptedPowerupSpawner.cpp index 2c502f26..0566a1fa 100644 --- a/dScripts/ScriptedPowerupSpawner.cpp +++ b/dScripts/ScriptedPowerupSpawner.cpp @@ -29,7 +29,7 @@ void ScriptedPowerupSpawner::OnTimerDone(Entity* self, std::string message) { renderComponent->PlayEffect(0, u"cast", "N_cast"); } - LootGenerator::Instance().DropLoot(owner, self, drops, 0, 0); + Loot::DropLoot(owner, self, drops, 0, 0); } // Increment the current cycle diff --git a/dScripts/ai/AG/AgPicnicBlanket.cpp b/dScripts/ai/AG/AgPicnicBlanket.cpp index bec5577c..a413fd21 100644 --- a/dScripts/ai/AG/AgPicnicBlanket.cpp +++ b/dScripts/ai/AG/AgPicnicBlanket.cpp @@ -11,7 +11,7 @@ void AgPicnicBlanket::OnUse(Entity* self, Entity* user) { self->SetVar(u"active", true); auto lootTable = std::unordered_map{ {935, 3} }; - LootGenerator::Instance().DropLoot(user, self, lootTable, 0, 0); + Loot::DropLoot(user, self, lootTable, 0, 0); self->AddCallbackTimer(5.0f, [self]() { self->SetVar(u"active", false); diff --git a/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp b/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp index 97798dc8..2208d5d7 100644 --- a/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp +++ b/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp @@ -442,7 +442,7 @@ void SGCannon::SpawnNewModel(Entity* self) { if (lootMatrix != 0) { std::unordered_map toDrop = {}; - toDrop = LootGenerator::Instance().RollLootMatrix(player, lootMatrix); + toDrop = Loot::RollLootMatrix(player, lootMatrix); for (auto drop : toDrop) { rewardModel->OnFireEventServerSide(self, ModelToBuildEvent, drop.first); @@ -594,7 +594,7 @@ void SGCannon::StopGame(Entity* self, bool cancel) { missionComponent->Progress(eMissionTaskType::ACTIVITY, m_CannonLot, 0, "", self->GetVar(TotalScoreVariable)); } - LootGenerator::Instance().GiveActivityLoot(player, self, GetGameID(self), self->GetVar(TotalScoreVariable)); + Loot::GiveActivityLoot(player, self, GetGameID(self), self->GetVar(TotalScoreVariable)); SaveScore(self, player->GetObjectID(), static_cast(self->GetVar(TotalScoreVariable)), static_cast(self->GetVar(MaxStreakVariable)), percentage); diff --git a/dWorldServer/WorldServer.cpp b/dWorldServer/WorldServer.cpp index 6e038b06..0803bbf7 100644 --- a/dWorldServer/WorldServer.cpp +++ b/dWorldServer/WorldServer.cpp @@ -214,7 +214,6 @@ int main(int argc, char** argv) { ObjectIDManager::Instance()->Initialize(); UserManager::Instance()->Initialize(); - LootGenerator::Instance(); Game::chatFilter = new dChatFilter(Game::assetManager->GetResPath().string() + "/chatplus_en_us", bool(std::stoi(Game::config->GetValue("dont_generate_dcf")))); Game::server = new dServer(masterIP, ourPort, instanceID, maxClients, false, true, Game::logger, masterIP, masterPort, ServerType::World, Game::config, &Game::shouldShutdown, zoneID);