From eed8b48112b10555ef44a9744fa9e9f0a65baf3e Mon Sep 17 00:00:00 2001 From: Skold <113406182+Skold177@users.noreply.github.com> Date: Mon, 15 Jun 2026 00:59:18 -0400 Subject: [PATCH] Implement Automaton Equalizer Implements the automaton attachment Equalizer --- scripts/globals/automaton.lua | 28 ++++++++++++++++++++++++++++ scripts/globals/mobskills.lua | 4 ++-- scripts/globals/pets/automaton.lua | 2 +- src/map/utils/battleutils.cpp | 10 ++++++---- 4 files changed, 37 insertions(+), 7 deletions(-) diff --git a/scripts/globals/automaton.lua b/scripts/globals/automaton.lua index 840c28b33db..d663329d3e2 100644 --- a/scripts/globals/automaton.lua +++ b/scripts/globals/automaton.lua @@ -539,3 +539,31 @@ xi.automaton.handleAttuner = function(actor, target) return 0 end + +---@param actor CBaseEntity +---@param damage integer +---@return integer +xi.automaton.handleEqualizer = function(actor, damage) + local equalizerModifier = actor:getMod(xi.mod.AUTO_EQUALIZER) + local maxHP = actor:getMaxHP() + + -- No Equalizer Equipped, return unmodified damage. + if equalizerModifier == 0 then + return damage + end + + -- No Damage to reduce, return unmodified damage. + if damage <= 0 then + return damage + end + + -- Equalizer damage reduction becomes more effective the higher the damage is in relation to the automatons max HP. + local reductionRate = damage / maxHP * (equalizerModifier / 100) + + reductionRate = math.floor(reductionRate * 100) / 100 + + -- Damage reduction is capped at 90%. + reductionRate = math.min(reductionRate, 0.90) + + return math.floor(damage * (1 - reductionRate)) +end diff --git a/scripts/globals/mobskills.lua b/scripts/globals/mobskills.lua index 2978bda384a..e65797078cc 100644 --- a/scripts/globals/mobskills.lua +++ b/scripts/globals/mobskills.lua @@ -392,7 +392,7 @@ local function handleSinglePhysicalHit(mob, target, baseHitDamage, params) hitDamage = math.floor(hitDamage * xi.combat.damage.physicalElementSDT(target, params.damageType)) hitDamage = math.floor(hitDamage * xi.combat.damage.calculateDamageAdjustment(target, true, false, false, false)) - -- TODO: Automaton Equalizer Reduction + hitDamage = xi.automaton.handleEqualizer(target, hitDamage) -- TODO: Need captures for different severe damage mechanics. Do they proc per hit or per skill hitDamage = math.floor(target:handleSevereDamage(hitDamage, true)) @@ -506,7 +506,7 @@ local function handleSingleRangedHit(mob, target, baseHitDamage, params) hitDamage = math.floor(hitDamage * xi.combat.damage.physicalElementSDT(target, params.damageType)) hitDamage = math.floor(hitDamage * xi.combat.damage.calculateDamageAdjustment(target, true, false, true, false)) - -- TODO: Automaton Equalizer Reduction + hitDamage = xi.automaton.handleEqualizer(target, hitDamage) -- TODO: Need captures for different severe damage mechanics. Do they proc per hit or per skill hitDamage = math.floor(target:handleSevereDamage(hitDamage, true)) diff --git a/scripts/globals/pets/automaton.lua b/scripts/globals/pets/automaton.lua index b1b8008443a..eb49026e360 100644 --- a/scripts/globals/pets/automaton.lua +++ b/scripts/globals/pets/automaton.lua @@ -553,7 +553,7 @@ local function applyAutomatonFrameMods(mob) end for _, modData in ipairs(frameData.mods or {}) do - mob:setMod(modData[1], modData[2]) + mob:addMod(modData[1], modData[2]) end end diff --git a/src/map/utils/battleutils.cpp b/src/map/utils/battleutils.cpp index 7124afb18c7..609d0e57e50 100644 --- a/src/map/utils/battleutils.cpp +++ b/src/map/utils/battleutils.cpp @@ -4680,9 +4680,10 @@ int32 PhysicalDmgTaken(CBattleEntity* PDefender, int32 damage, DAMAGE_TYPE damag resist += PDefender->getMod(Mod::DMGPHYS_II) / 10000.0f; // Add Burtgang reduction after 50% cap. Extends cap to -68% damage = (int32)(damage * resist); - if (damage > 0 && PDefender->objtype == TYPE_PET && PDefender->getMod(Mod::AUTO_EQUALIZER) > 0) + if (damage > 0 && PDefender->getMod(Mod::AUTO_EQUALIZER) > 0) { - damage -= (int32)(damage / float(PDefender->GetMaxHP()) * (PDefender->getMod(Mod::AUTO_EQUALIZER) / 100.0f)); + const auto reductionRate = std::floor(damage / static_cast(PDefender->GetMaxHP()) * PDefender->getMod(Mod::AUTO_EQUALIZER)) / 100.0f; + damage = static_cast(std::floor(damage * (1.0f - std::min(reductionRate, 0.90f)))); } // Handle damage absorption. @@ -4723,9 +4724,10 @@ int32 RangedDmgTaken(CBattleEntity* PDefender, int32 damage, DAMAGE_TYPE damageT resist = std::max(resist, 0.5f); damage = (int32)(damage * resist); - if (damage > 0 && PDefender->objtype == TYPE_PET && PDefender->getMod(Mod::AUTO_EQUALIZER) > 0) + if (damage > 0 && PDefender->getMod(Mod::AUTO_EQUALIZER) > 0) { - damage -= (int32)(damage / float(PDefender->GetMaxHP()) * (PDefender->getMod(Mod::AUTO_EQUALIZER) / 10000.0f)); + const auto reductionRate = std::floor(damage / static_cast(PDefender->GetMaxHP()) * PDefender->getMod(Mod::AUTO_EQUALIZER)) / 100.0f; + damage = static_cast(std::floor(damage * (1.0f - std::min(reductionRate, 0.90f)))); } // Handle damage absorption.