From 53af029e17e0334a5990f5436ad877c54d5a5d25 Mon Sep 17 00:00:00 2001 From: sruon Date: Sun, 19 Jan 2025 16:56:20 -0700 Subject: [PATCH 1/5] Automaton LEVEL_RESTRICTION fix Resolves over/underflow with automatons when applying LEVEL_RESTRICTION. - Force onUnequip on attachments before applying restriction - Rerun onEquip and the maneuvers after automaton stats are restricted - Enables the Truesights attachment --- .../abilities/pets/attachments/truesights.lua | 27 +++++ .../abilities/pets/attachments/volt_gun.lua | 35 +++--- scripts/globals/automaton.lua | 12 +- scripts/specs/core/CBaseEntity.lua | 19 +++ src/map/lua/lua_baseentity.cpp | 112 ++++++++++++++++++ src/map/lua/lua_baseentity.h | 4 + src/map/utils/puppetutils.cpp | 46 +++++++ src/map/utils/puppetutils.h | 2 + 8 files changed, 237 insertions(+), 20 deletions(-) create mode 100644 scripts/actions/abilities/pets/attachments/truesights.lua diff --git a/scripts/actions/abilities/pets/attachments/truesights.lua b/scripts/actions/abilities/pets/attachments/truesights.lua new file mode 100644 index 00000000000..a764193fd7d --- /dev/null +++ b/scripts/actions/abilities/pets/attachments/truesights.lua @@ -0,0 +1,27 @@ +----------------------------------- +-- Attachment: Truesights +----------------------------------- +---@type TAttachment +local attachmentObject = {} + +attachmentObject.onEquip = function(pet, attachment) + xi.automaton.onAttachmentEquip(pet, attachment) +end + +attachmentObject.onUnequip = function(pet, attachment) + xi.automaton.onAttachmentUnequip(pet, attachment) +end + +attachmentObject.onManeuverGain = function(pet, attachment, maneuvers) + xi.automaton.onManeuverGain(pet, attachment, maneuvers) +end + +attachmentObject.onManeuverLose = function(pet, attachment, maneuvers) + xi.automaton.onManeuverLose(pet, attachment, maneuvers) +end + +attachmentObject.onUpdate = function(pet, attachment, maneuvers) + xi.automaton.updateAttachmentModifier(pet, attachment, maneuvers) +end + +return attachmentObject diff --git a/scripts/actions/abilities/pets/attachments/volt_gun.lua b/scripts/actions/abilities/pets/attachments/volt_gun.lua index 49052beb83e..beffa77185d 100644 --- a/scripts/actions/abilities/pets/attachments/volt_gun.lua +++ b/scripts/actions/abilities/pets/attachments/volt_gun.lua @@ -4,37 +4,34 @@ ---@type TAttachment local attachmentObject = {} -attachmentObject.onEquip = function(pet, attachment) +local function calcEnspellDmg(pet, maneuvers) local skill = math.max(pet:getSkillLevel(xi.skill.AUTOMATON_MELEE), pet:getSkillLevel(xi.skill.AUTOMATON_RANGED), pet:getSkillLevel(xi.skill.AUTOMATON_MAGIC)) - pet:addMod(xi.mod.ENSPELL, xi.element.THUNDER) - pet:addMod(xi.mod.ENSPELL_DMG, skill * 0.1) - pet:addMod(xi.mod.ENSPELL_CHANCE, 20) + return (skill * 0.1) + ((skill * 0.05) * maneuvers) +end + +attachmentObject.onEquip = function(pet, attachment) + pet:setMod(xi.mod.ENSPELL_DMG, calcEnspellDmg(pet, 0)) + xi.automaton.onAttachmentEquip(pet, attachment) end attachmentObject.onUnequip = function(pet, attachment) - pet:delMod(xi.mod.ENSPELL, xi.element.THUNDER) pet:delMod(xi.mod.ENSPELL_DMG, pet:getMod(xi.mod.ENSPELL_DMG)) - pet:delMod(xi.mod.ENSPELL_CHANCE, 20) + xi.automaton.onAttachmentUnequip(pet, attachment) end attachmentObject.onManeuverGain = function(pet, attachment, maneuvers) - local skill = math.max(pet:getSkillLevel(xi.skill.AUTOMATON_MELEE), pet:getSkillLevel(xi.skill.AUTOMATON_RANGED), pet:getSkillLevel(xi.skill.AUTOMATON_MAGIC)) - pet:addMod(xi.mod.ENSPELL_DMG, skill * 0.05) - pet:addMod(xi.mod.ENSPELL_CHANCE, 15) + pet:setMod(xi.mod.ENSPELL_DMG, calcEnspellDmg(pet, maneuvers)) + xi.automaton.onManeuverGain(pet, attachment, maneuvers) end attachmentObject.onManeuverLose = function(pet, attachment, maneuvers) - local skill = math.max(pet:getSkillLevel(xi.skill.AUTOMATON_MELEE), pet:getSkillLevel(xi.skill.AUTOMATON_RANGED), pet:getSkillLevel(xi.skill.AUTOMATON_MAGIC)) - pet:delMod(xi.mod.ENSPELL_DMG, skill * 0.05) - pet:delMod(xi.mod.ENSPELL_CHANCE, 15) + pet:setMod(xi.mod.ENSPELL_DMG, calcEnspellDmg(pet, maneuvers)) + xi.automaton.onManeuverLose(pet, attachment, maneuvers) +end - -- Hacky way of keeping xi.mod.ENSPELL_DMG from going negative by simply resetting it - if maneuvers == 1 and pet:getMod(xi.mod.ENSPELL_DMG) < 0 then - pet:delMod(xi.mod.ENSPELL, pet:getMod(xi.mod.ENSPELL)) - pet:delMod(xi.mod.ENSPELL_DMG, pet:getMod(xi.mod.ENSPELL_DMG)) - pet:delMod(xi.mod.ENSPELL_CHANCE, pet:getMod(xi.mod.ENSPELL_CHANCE)) - attachmentObject.onEquip(pet, attachment) - end +attachmentObject.onUpdate = function(pet, attachment, maneuvers) + attachmentObject.onManeuverGain(pet, attachment, maneuvers) + xi.automaton.updateAttachmentModifier(pet, attachment, maneuvers) end return attachmentObject diff --git a/scripts/globals/automaton.lua b/scripts/globals/automaton.lua index 9c785fc7682..1d50585da30 100644 --- a/scripts/globals/automaton.lua +++ b/scripts/globals/automaton.lua @@ -158,6 +158,8 @@ local attachmentModifiers = ['turbo_charger_ii'] = { { xi.mod.HASTE_MAGIC, { 700, 1700, 2800, 4375 }, true }, }, ['vivi-valve'] = { { xi.mod.CURE_POTENCY, { 5, 15, 30, 45 }, true }, }, ['vivi-valve_ii'] = { { xi.mod.CURE_POTENCY, { 10, 20, 35, 50 }, true }, }, + ['volt_gun'] = { { xi.mod.ENSPELL, { 5, 5, 5, 5 }, false }, + { xi.mod.ENSPELL_CHANCE, { 20, 35, 50, 65 }, false }, }, } -- Auto Repair Kits and Mana Tanks use a formula based on Max HP/MP in the form of @@ -226,8 +228,14 @@ xi.automaton.onAttachmentUnequip = function(pet, attachment) local modTable = attachmentModifiers[attachment:getName()] for k, modList in ipairs(modTable) do - pet:delMod(modList[1], modList[2][1]) + if modList[2][1] then + pet:delMod(modList[1], modList[2][1]) + else + pet:setMod(modList[1], 0) + end end + + pet:clearLocalVarsWithPrefix(attachment:getName()) end xi.automaton.onManeuverGain = function(pet, attachment, maneuvers) @@ -269,6 +277,8 @@ xi.automaton.updateAttachmentModifier = function(pet, attachment, maneuvers) if modValue ~= previousMod then if previousMod ~= 0 then + -- If the automaton was reset to a blank state (LEVEL_RESTRICTION) + -- and the local variables were not cleared, this will under/overflow pet:delMod(modList[1], previousMod) end diff --git a/scripts/specs/core/CBaseEntity.lua b/scripts/specs/core/CBaseEntity.lua index 91b38af357b..c2648cdee3c 100644 --- a/scripts/specs/core/CBaseEntity.lua +++ b/scripts/specs/core/CBaseEntity.lua @@ -3428,11 +3428,23 @@ end function CBaseEntity:getAutomatonFrame() end +---@nodiscard +---@param itemId integer +---@return nil +function CBaseEntity:setAutomatonFrame(itemId) +end + ---@nodiscard ---@return integer function CBaseEntity:getAutomatonHead() end +---@nodiscard +---@param itemId integer +---@return nil +function CBaseEntity:setAutomatonHead(itemId) +end + ---@param itemID integer ---@return boolean function CBaseEntity:unlockAttachment(itemID) @@ -3457,6 +3469,13 @@ end function CBaseEntity:getAttachment(slotId) end +---@nodiscard +---@param itemId integer +---@param slotId integer +---@return nil +function CBaseEntity:setAttachment(itemId, slotId) +end + ---@nodiscard ---@return CItem[] function CBaseEntity:getAttachments() diff --git a/src/map/lua/lua_baseentity.cpp b/src/map/lua/lua_baseentity.cpp index d41d5d2d8ae..be6b6cb3259 100644 --- a/src/map/lua/lua_baseentity.cpp +++ b/src/map/lua/lua_baseentity.cpp @@ -711,6 +711,30 @@ void CLuaBaseEntity::setLocalVar(std::string const& var, uint32 val) m_PBaseEntity->SetLocalVar(var.c_str(), val); } +/************************************************************************ + * Function: clearLocalVarsWithPrefix() + * Purpose : Deletes all local variables with the given prefix. + * Example : pet:clearLocalVarsWithPrefix("volt"); + * Notes : + ************************************************************************/ + +void CLuaBaseEntity::clearLocalVarsWithPrefix(std::string const& prefix) +{ + auto& localVars = m_PBaseEntity->GetLocalVars(); + + auto iter = localVars.begin(); + while (iter != localVars.end()) + { + if (iter->first.rfind(prefix, 0) == 0) + { + m_PBaseEntity->SetLocalVar(iter->first.c_str(), 0); + } + ++iter; + } + + return; +} + /************************************************************************ * Function: resetLocalVars() * Purpose : Reset local variables back to default (ex: on Mob disengage) @@ -6615,6 +6639,11 @@ uint8 CLuaBaseEntity::levelRestriction(sol::object const& level) if (PChar->GetMLevel() != NewMLevel) { + if (PChar->PAutomaton) + { + // Call each attachment onUnequip handler and zero out localVars tracking applied buffs + puppetutils::PreLevelRestriction(PChar); + } charutils::RemoveAllEquipMods(PChar); PChar->SetMLevel(NewMLevel); PChar->SetSLevel(PChar->jobs.job[PChar->GetSJob()]); @@ -6697,6 +6726,9 @@ uint8 CLuaBaseEntity::levelRestriction(sol::object const& level) return PChar->m_LevelRestriction; } petutils::CalculateAutomatonStats(PChar, PPet); + + // Call each attachment onEquip handler and replay maneuvers against the new stats + puppetutils::PostLevelRestriction(PChar); break; case PET_TYPE::LUOPAN: petutils::CalculateLuopanStats(PChar, PPet); @@ -15703,6 +15735,32 @@ uint8 CLuaBaseEntity::getAutomatonFrame() return static_cast(PAutomaton->getFrame()); } +/************************************************************************ + * Function: setAutomatonFrame(frameItemID) + * Purpose : Sets the provided frame on the automaton + * Example : player:setAutomatonFrame(xi.item.VALOREDGE_FRAME) + * Notes : + ************************************************************************/ + +void CLuaBaseEntity::setAutomatonFrame(uint8 frameItemID) +{ + auto* PChar = dynamic_cast(m_PBaseEntity); + + if (PChar == nullptr) + { + ShowWarning("Invalid entity type calling function (%s).", m_PBaseEntity->getName()); + return; + } + + if (PChar->PAutomaton) + { + puppetutils::setFrame(PChar, frameItemID - 0x2000); + PChar->pushPacket(PChar, true); + PChar->pushPacket(PChar, false); + puppetutils::SaveAutomaton(PChar); + } +} + /************************************************************************ * Function: getAutomatonHead() * Purpose : Returns the integer value of the (active?) automation head @@ -15722,6 +15780,32 @@ uint8 CLuaBaseEntity::getAutomatonHead() return static_cast(PAutomaton->getHead()); } +/************************************************************************ + * Function: setAutomatonHead(headItemID) + * Purpose : Sets the automaton head to the specified item + * Example : player:setAutomatonHead(xi.item.VALOREDGE_HEAD) + * Notes : + ************************************************************************/ + +void CLuaBaseEntity::setAutomatonHead(uint8 headItemID) +{ + auto* PChar = dynamic_cast(m_PBaseEntity); + + if (PChar == nullptr) + { + ShowWarning("Invalid entity type calling function (%s).", m_PBaseEntity->getName()); + return; + } + + if (PChar->PAutomaton) + { + puppetutils::setHead(PChar, headItemID - 0x2000); + PChar->pushPacket(PChar, true); + PChar->pushPacket(PChar, false); + puppetutils::SaveAutomaton(PChar); + } +} + /************************************************************************ * Function: unlockAttachment() * Purpose : Makes new attachment frames available to the Puppetmaster @@ -15823,6 +15907,30 @@ std::optional CLuaBaseEntity::getAttachment(uint8 slotId) return std::nullopt; } +/************************************************************************ + * Function: setAttachment(attachmentItemID, slotID) + * Purpose : Sets the attachment of an automaton in the slot specified + * Example : player:setAttachment(8465, 0) + ************************************************************************/ + +void CLuaBaseEntity::setAttachment(uint8 attachmentItemID, uint8 slotID) +{ + auto* PChar = dynamic_cast(m_PBaseEntity); + + if (PChar == nullptr) + { + ShowWarning("Invalid entity type calling function (%s).", m_PBaseEntity->getName()); + return; + } + if (PChar->PAutomaton) + { + puppetutils::setAttachment(PChar, slotID, attachmentItemID - 0x2100); + PChar->pushPacket(PChar, true); + PChar->pushPacket(PChar, false); + puppetutils::SaveAutomaton(PChar); + } +} + /************************************************************************ * Function: getAttachments() * Purpose : Returns a table of attachment items equipped by an Automaton @@ -18485,6 +18593,7 @@ void CLuaBaseEntity::Register() SOL_REGISTER("getLocalVars", CLuaBaseEntity::getLocalVars); SOL_REGISTER("getLocalVar", CLuaBaseEntity::getLocalVar); SOL_REGISTER("setLocalVar", CLuaBaseEntity::setLocalVar); + SOL_REGISTER("clearLocalVarsWithPrefix", CLuaBaseEntity::clearLocalVarsWithPrefix); SOL_REGISTER("resetLocalVars", CLuaBaseEntity::resetLocalVars); SOL_REGISTER("clearVarsWithPrefix", CLuaBaseEntity::clearVarsWithPrefix); SOL_REGISTER("getLastOnline", CLuaBaseEntity::getLastOnline); @@ -19159,13 +19268,16 @@ void CLuaBaseEntity::Register() SOL_REGISTER("hasAttachment", CLuaBaseEntity::hasAttachment); SOL_REGISTER("getAutomatonName", CLuaBaseEntity::getAutomatonName); SOL_REGISTER("getAutomatonFrame", CLuaBaseEntity::getAutomatonFrame); + SOL_REGISTER("setAutomatonFrame", CLuaBaseEntity::setAutomatonFrame); SOL_REGISTER("getAutomatonHead", CLuaBaseEntity::getAutomatonHead); + SOL_REGISTER("setAutomatonHead", CLuaBaseEntity::setAutomatonHead); SOL_REGISTER("unlockAttachment", CLuaBaseEntity::unlockAttachment); SOL_REGISTER("getActiveManeuverCount", CLuaBaseEntity::getActiveManeuverCount); SOL_REGISTER("removeOldestManeuver", CLuaBaseEntity::removeOldestManeuver); SOL_REGISTER("removeAllManeuvers", CLuaBaseEntity::removeAllManeuvers); SOL_REGISTER("getAttachment", CLuaBaseEntity::getAttachment); + SOL_REGISTER("setAttachment", CLuaBaseEntity::setAttachment); SOL_REGISTER("getAttachments", CLuaBaseEntity::getAttachments); SOL_REGISTER("updateAttachments", CLuaBaseEntity::updateAttachments); SOL_REGISTER("reduceBurden", CLuaBaseEntity::reduceBurden); diff --git a/src/map/lua/lua_baseentity.h b/src/map/lua/lua_baseentity.h index 6a2ce651205..da119b4d59d 100644 --- a/src/map/lua/lua_baseentity.h +++ b/src/map/lua/lua_baseentity.h @@ -75,6 +75,7 @@ class CLuaBaseEntity auto getLocalVars() -> sol::table; uint32 getLocalVar(std::string const& var); void setLocalVar(std::string const& var, uint32 val); + void clearLocalVarsWithPrefix(std::string const& prefix); void resetLocalVars(); void clearVarsWithPrefix(std::string const& prefix); uint32 getLastOnline(); // Returns the unix timestamp of last time the player logged out or zoned @@ -782,13 +783,16 @@ class CLuaBaseEntity bool hasAttachment(uint16 itemID); auto getAutomatonName() -> std::string; uint8 getAutomatonFrame(); + void setAutomatonFrame(uint8 frameItemID); uint8 getAutomatonHead(); + void setAutomatonHead(uint8 headItemID); bool unlockAttachment(uint16 itemID); uint8 getActiveManeuverCount(); void removeOldestManeuver(); void removeAllManeuvers(); auto getAttachment(uint8 slotId) -> std::optional; auto getAttachments() -> sol::table; + void setAttachment(uint8 attachmentItemID, uint8 slotID); void updateAttachments(); void reduceBurden(float percentReduction, sol::object const& intReductionObj); bool isExceedingElementalCapacity(); diff --git a/src/map/utils/puppetutils.cpp b/src/map/utils/puppetutils.cpp index 9d5f4909b6f..be9173fa258 100644 --- a/src/map/utils/puppetutils.cpp +++ b/src/map/utils/puppetutils.cpp @@ -778,4 +778,50 @@ namespace puppetutils } } + void PreLevelRestriction(CCharEntity* PChar) + { + CAutomatonEntity* PAutomaton = PChar->PAutomaton; + if (PAutomaton) + { + for (int i = 0; i < 12; i++) + { + uint8 attachment = PAutomaton->getAttachment(i); + + if (attachment != 0) + { + CItemPuppet* PAttachment = (CItemPuppet*)itemutils::GetItemPointer(0x2100 + attachment); + + // Attachment scripts may have custom unequip logic that needs to run before the restriction is applied + // If they were to delMod after the restriction is applied, under/overflow may occur. + // This will also clear the localVars holding previously applied modifiers + luautils::OnAttachmentUnequip(PAutomaton, PAttachment); + } + } + } + } + + void PostLevelRestriction(CCharEntity* PChar) + { + CAutomatonEntity* PAutomaton = PChar->PAutomaton; + + if (PAutomaton) + { + for (int i = 0; i < 12; i++) + { + uint8 attachment = PAutomaton->getAttachment(i); + + if (attachment != 0) + { + CItemPuppet* PAttachment = (CItemPuppet*)itemutils::GetItemPointer(0x2100 + attachment); + + // Attachment scripts may have custom equip logic that needs to be computed against the LvRestricted puppet stats + luautils::OnAttachmentEquip(PAutomaton, PAttachment); + } + } + + // Now re-run the maneuvers apply logic on all attachments + UpdateAttachments(PChar); + } + } + } // namespace puppetutils diff --git a/src/map/utils/puppetutils.h b/src/map/utils/puppetutils.h index 9bfcf1ad9d0..0bddbf85b24 100644 --- a/src/map/utils/puppetutils.h +++ b/src/map/utils/puppetutils.h @@ -41,6 +41,8 @@ namespace puppetutils void LoadAutomatonStats(CCharEntity* PChar); void CheckAttachmentsForManeuver(CCharEntity* PChar, EFFECT maneuver, bool gain); void UpdateAttachments(CCharEntity* PChar); + void PreLevelRestriction(CCharEntity* PChar); + void PostLevelRestriction(CCharEntity* PChar); }; // namespace puppetutils #endif From 1a2be8458392892361735ba7cb0ae415c590db03 Mon Sep 17 00:00:00 2001 From: sruon Date: Mon, 20 Jan 2025 13:09:58 -0700 Subject: [PATCH 2/5] dynamic_cast PAttachment Co-Authored-By: WinterSolstice8 <60417494+WinterSolstice8@users.noreply.github.com> --- src/map/utils/puppetutils.cpp | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/map/utils/puppetutils.cpp b/src/map/utils/puppetutils.cpp index be9173fa258..a36fefa6a1c 100644 --- a/src/map/utils/puppetutils.cpp +++ b/src/map/utils/puppetutils.cpp @@ -789,12 +789,15 @@ namespace puppetutils if (attachment != 0) { - CItemPuppet* PAttachment = (CItemPuppet*)itemutils::GetItemPointer(0x2100 + attachment); + CItemPuppet* PAttachment = dynamic_cast(itemutils::GetItemPointer(0x2100 + attachment)); - // Attachment scripts may have custom unequip logic that needs to run before the restriction is applied - // If they were to delMod after the restriction is applied, under/overflow may occur. - // This will also clear the localVars holding previously applied modifiers - luautils::OnAttachmentUnequip(PAutomaton, PAttachment); + if (PAttachment) + { + // Attachment scripts may have custom unequip logic that needs to run before the restriction is applied + // If they were to delMod after the restriction is applied, under/overflow may occur. + // This will also clear the localVars holding previously applied modifiers + luautils::OnAttachmentUnequip(PAutomaton, PAttachment); + } } } } @@ -812,10 +815,12 @@ namespace puppetutils if (attachment != 0) { - CItemPuppet* PAttachment = (CItemPuppet*)itemutils::GetItemPointer(0x2100 + attachment); - - // Attachment scripts may have custom equip logic that needs to be computed against the LvRestricted puppet stats - luautils::OnAttachmentEquip(PAutomaton, PAttachment); + CItemPuppet* PAttachment = dynamic_cast(itemutils::GetItemPointer(0x2100 + attachment)); + if (PAttachment) + { + // Attachment scripts may have custom equip logic that needs to be computed against the LvRestricted puppet stats + luautils::OnAttachmentEquip(PAutomaton, PAttachment); + } } } From 7724dd49ad15be9aed69e44519a2895103319a23 Mon Sep 17 00:00:00 2001 From: sruon Date: Mon, 20 Jan 2025 13:26:12 -0700 Subject: [PATCH 3/5] Enspell damage calculation refactor Co-Authored-By: Xaver-DaRed <60053999+Xaver-DaRed@users.noreply.github.com> --- scripts/actions/abilities/pets/attachments/volt_gun.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/actions/abilities/pets/attachments/volt_gun.lua b/scripts/actions/abilities/pets/attachments/volt_gun.lua index beffa77185d..ecc11b640a2 100644 --- a/scripts/actions/abilities/pets/attachments/volt_gun.lua +++ b/scripts/actions/abilities/pets/attachments/volt_gun.lua @@ -6,7 +6,7 @@ local attachmentObject = {} local function calcEnspellDmg(pet, maneuvers) local skill = math.max(pet:getSkillLevel(xi.skill.AUTOMATON_MELEE), pet:getSkillLevel(xi.skill.AUTOMATON_RANGED), pet:getSkillLevel(xi.skill.AUTOMATON_MAGIC)) - return (skill * 0.1) + ((skill * 0.05) * maneuvers) + return math.floor(skill / 10 + skill * maneuvers / 20) end attachmentObject.onEquip = function(pet, attachment) From 598b162cd28488d4783a2c9ad4847ce116208473 Mon Sep 17 00:00:00 2001 From: sruon Date: Tue, 21 Jan 2025 22:04:20 -0700 Subject: [PATCH 4/5] Refactor localVars iterator Co-Authored-By: Zach Toogood <1389729+zach2good@users.noreply.github.com> --- src/map/lua/lua_baseentity.cpp | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/map/lua/lua_baseentity.cpp b/src/map/lua/lua_baseentity.cpp index be6b6cb3259..5ae6b2f983f 100644 --- a/src/map/lua/lua_baseentity.cpp +++ b/src/map/lua/lua_baseentity.cpp @@ -720,16 +720,12 @@ void CLuaBaseEntity::setLocalVar(std::string const& var, uint32 val) void CLuaBaseEntity::clearLocalVarsWithPrefix(std::string const& prefix) { - auto& localVars = m_PBaseEntity->GetLocalVars(); - - auto iter = localVars.begin(); - while (iter != localVars.end()) + for (const auto& localVar : m_PBaseEntity->GetLocalVars()) { - if (iter->first.rfind(prefix, 0) == 0) + if (starts_with(localVar.first, prefix)) { - m_PBaseEntity->SetLocalVar(iter->first.c_str(), 0); + m_PBaseEntity->SetLocalVar(localVar.first, 0); } - ++iter; } return; From 5cd5f40d2dbe17fec3bb31ae69c27ebdd0d6b652 Mon Sep 17 00:00:00 2001 From: Zach Toogood Date: Wed, 22 Jan 2025 15:56:29 +0000 Subject: [PATCH 5/5] Core: Use structured bindings in clearLocalVarsWithPrefix --- src/map/lua/lua_baseentity.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/map/lua/lua_baseentity.cpp b/src/map/lua/lua_baseentity.cpp index 5ae6b2f983f..2d435e81604 100644 --- a/src/map/lua/lua_baseentity.cpp +++ b/src/map/lua/lua_baseentity.cpp @@ -720,15 +720,13 @@ void CLuaBaseEntity::setLocalVar(std::string const& var, uint32 val) void CLuaBaseEntity::clearLocalVarsWithPrefix(std::string const& prefix) { - for (const auto& localVar : m_PBaseEntity->GetLocalVars()) + for (const auto& [localVar, _] : m_PBaseEntity->GetLocalVars()) { - if (starts_with(localVar.first, prefix)) + if (starts_with(localVar, prefix)) { - m_PBaseEntity->SetLocalVar(localVar.first, 0); + m_PBaseEntity->SetLocalVar(localVar, 0); } } - - return; } /************************************************************************