From 1d2ad2e6f865544a50b6bce49577ae8efb2050d2 Mon Sep 17 00:00:00 2001 From: Zach Toogood Date: Tue, 19 Nov 2024 12:38:00 +0000 Subject: [PATCH] Core: Cache augment data on startup --- src/map/items/item_equipment.cpp | 94 ++++++++++++++++++++++++-------- src/map/items/item_equipment.h | 4 ++ src/map/map.cpp | 24 ++++---- 3 files changed, 88 insertions(+), 34 deletions(-) diff --git a/src/map/items/item_equipment.cpp b/src/map/items/item_equipment.cpp index 12b79abe2ac..f162e671181 100644 --- a/src/map/items/item_equipment.cpp +++ b/src/map/items/item_equipment.cpp @@ -24,6 +24,52 @@ #include "map.h" #include +namespace +{ + /* + From augments.sql: + + `augmentId` smallint(5) unsigned NOT NULL, + `multiplier` smallint(2) NOT NULL DEFAULT 0, + `modId` smallint(5) unsigned NOT NULL DEFAULT 0, + `value` smallint(5) NOT NULL DEFAULT 0, + `isPet` tinyint(1) NOT NULL DEFAULT 0, + `petType` tinyint(3) unsigned NOT NULL DEFAULT 0, + */ + struct AugmentDataRow + { + uint16 augmentId; + uint16 multiplier; + uint16 modId; + int16 value; // Can be negative + uint8 isPet; + uint8 petType; + }; + + std::unordered_map sAugmentData; +} // namespace + +void CItemEquipment::LoadAugmentData() +{ + const auto rset = db::preparedStmt("SELECT `augmentId`, `multiplier`, `modId`, `value`, `isPet`, `petType` FROM `augments`"); + if (rset) + { + while (rset->next()) + { + const auto augmentId = rset->getUInt("augmentId"); + + sAugmentData[augmentId] = AugmentDataRow{ + .augmentId = static_cast(augmentId), + .multiplier = static_cast(rset->getUInt("multiplier")), + .modId = static_cast(rset->getUInt("modId")), + .value = static_cast(rset->getInt("value")), + .isPet = static_cast(rset->getUInt("isPet")), + .petType = static_cast(rset->getUInt("petType")), + }; + } + } +} + CItemEquipment::CItemEquipment(uint16 id) : CItemUsable(id) { @@ -367,6 +413,12 @@ void CItemEquipment::setAugment(uint8 slot, uint16 type, uint8 value) void CItemEquipment::SetAugmentMod(uint16 type, uint8 value) { + if (sAugmentData.find(type) == sAugmentData.end()) + { + ShowErrorFmt("Invalid augment type {} requested for item {}", type, this->getID()); + return; + } + if (type != 0) { setSubType(ITEM_AUGMENTED); @@ -374,34 +426,28 @@ void CItemEquipment::SetAugmentMod(uint16 type, uint8 value) ref(m_extra, 0x01) |= 0x03; } - // obtain augment info by querying the db - const char* fmtQuery = "SELECT augmentId, multiplier, modId, `value`, `isPet`, `petType` FROM augments WHERE augmentId = %u"; - - int32 ret = _sql->Query(fmtQuery, type); + const auto& augmentData = sAugmentData[type]; - while (ret != SQL_ERROR && _sql->NumRows() != 0 && _sql->NextRow() == SQL_SUCCESS) - { - uint8 multiplier = (uint8)_sql->GetUIntData(1); - Mod modId = static_cast(_sql->GetUIntData(2)); - int16 modValue = (int16)_sql->GetIntData(3); + uint8 multiplier = augmentData.multiplier; + Mod modId = static_cast(augmentData.modId); + int16 modValue = augmentData.value; - // type is 0 unless mod is for pets - uint8 isPet = (uint8)_sql->GetUIntData(4); - PetModType petType = static_cast(_sql->GetIntData(5)); + // type is 0 unless mod is for pets + uint8 isPet = augmentData.isPet; + PetModType petType = static_cast(augmentData.petType); - // apply modifier to item. increase modifier power by 'value' (default magnitude 1 for most augments) if multiplier isn't specified - // otherwise increase modifier power using the multiplier - // check if we should be adding to or taking away from the mod power (handle scripted augments properly) - modValue = (modValue > 0 ? modValue + value : modValue - value) * (multiplier > 1 ? multiplier : 1); + // apply modifier to item. increase modifier power by 'value' (default magnitude 1 for most augments) if multiplier isn't specified + // otherwise increase modifier power using the multiplier + // check if we should be adding to or taking away from the mod power (handle scripted augments properly) + modValue = (modValue > 0 ? modValue + value : modValue - value) * (multiplier > 1 ? multiplier : 1); - if (!isPet) - { - addModifier(CModifier(modId, modValue)); - } - else - { - addPetModifier(CPetModifier(modId, petType, modValue)); - } + if (!isPet) + { + addModifier(CModifier(modId, modValue)); + } + else + { + addPetModifier(CPetModifier(modId, petType, modValue)); } } diff --git a/src/map/items/item_equipment.h b/src/map/items/item_equipment.h index abde8385563..a3e667410ab 100644 --- a/src/map/items/item_equipment.h +++ b/src/map/items/item_equipment.h @@ -121,6 +121,10 @@ class CItemEquipment : public CItemUsable std::vector petModList; std::vector latentList; + // static + // TODO: Move this to itemutils + static void LoadAugmentData(); + private: uint8 m_reqLvl; uint8 m_iLvl; diff --git a/src/map/map.cpp b/src/map/map.cpp index 3fef58b996e..a64f2fefd95 100755 --- a/src/map/map.cpp +++ b/src/map/map.cpp @@ -25,6 +25,7 @@ #include "common/blowfish.h" #include "common/console_service.h" #include "common/database.h" +#include "common/debug.h" #include "common/logging.h" #include "common/md52.h" #include "common/timer.h" @@ -33,16 +34,10 @@ #include "common/version.h" #include "common/zlib.h" -#include -#include -#include -#include -#include - #include "ability.h" -#include "common/debug.h" -#include "common/vana_time.h" +#include "daily_system.h" #include "job_points.h" +#include "latent_effect_container.h" #include "linkshell.h" #include "message.h" #include "mob_spell_list.h" @@ -58,11 +53,13 @@ #include "zone_entities.h" #include "ai/controllers/automaton_controller.h" -#include "daily_system.h" -#include "latent_effect_container.h" + +#include "items/item_equipment.h" + #include "packets/basic.h" #include "packets/chat_message.h" #include "packets/server_ip.h" + #include "utils/battleutils.h" #include "utils/charutils.h" #include "utils/fishingutils.h" @@ -78,6 +75,12 @@ #include "utils/trustutils.h" #include "utils/zoneutils.h" +#include +#include +#include +#include +#include + #include #ifdef WIN32 @@ -291,6 +294,7 @@ int32 do_init(int32 argc, char** argv) daily::LoadDailyItems(); roeutils::UpdateUnityRankings(); synergyutils::LoadSynergyRecipes(); + CItemEquipment::LoadAugmentData(); // TODO: Move to itemutils if (!std::filesystem::exists("./navmeshes/") || std::filesystem::is_empty("./navmeshes/")) {