From 64056cd7c5304c00d353e8faaea0a6ca24e6f4a3 Mon Sep 17 00:00:00 2001 From: Skold <113406182+Skold177@users.noreply.github.com> Date: Fri, 22 May 2026 16:09:28 -0400 Subject: [PATCH] Implement DA for Automaton WS / Update Automaton Shield Bash Implements DA for Automaton WS Implements Automaton Shield Bash & Hammermill Updates Cannibal Blade formula --- .../abilities/pets/attachments/hammermill.lua | 2 + .../abilities/pets/automaton/arcuballista.lua | 11 +-- .../pets/automaton/armor_piercer.lua | 11 +-- .../pets/automaton/armor_shatterer.lua | 11 +-- .../abilities/pets/automaton/bone_crusher.lua | 15 +-- .../pets/automaton/cannibal_blade.lua | 34 ++++--- .../pets/automaton/chimera_ripper.lua | 15 +-- .../actions/abilities/pets/automaton/daze.lua | 11 +-- .../abilities/pets/automaton/knockout.lua | 15 +-- .../abilities/pets/automaton/shield_bash.lua | 93 +++++++++++-------- .../abilities/pets/automaton/slapstick.lua | 15 +-- .../pets/automaton/string_clipper.lua | 15 +-- .../pets/automaton/string_shredder.lua | 17 +--- scripts/globals/automaton.lua | 34 ++++++- 14 files changed, 125 insertions(+), 174 deletions(-) diff --git a/scripts/actions/abilities/pets/attachments/hammermill.lua b/scripts/actions/abilities/pets/attachments/hammermill.lua index d5fa822e129..38ad4a1b0ec 100644 --- a/scripts/actions/abilities/pets/attachments/hammermill.lua +++ b/scripts/actions/abilities/pets/attachments/hammermill.lua @@ -6,10 +6,12 @@ local attachmentObject = {} attachmentObject.onEquip = function(pet, attachment) xi.automaton.onAttachmentEquip(pet, attachment) + pet:setLocalVar('hammermill', 1) end attachmentObject.onUnequip = function(pet, attachment) xi.automaton.onAttachmentUnequip(pet, attachment) + pet:setLocalVar('hammermill', 0) end attachmentObject.onManeuverGain = function(pet, attachment, maneuvers) diff --git a/scripts/actions/abilities/pets/automaton/arcuballista.lua b/scripts/actions/abilities/pets/automaton/arcuballista.lua index 30ac34402ad..5974a18f2c1 100644 --- a/scripts/actions/abilities/pets/automaton/arcuballista.lua +++ b/scripts/actions/abilities/pets/automaton/arcuballista.lua @@ -34,16 +34,7 @@ abilityObject.onAutomatonAbility = function(target, automaton, skill, master, ac params.fTP = { 7.0, 10.0, 13.0 } end - -- Flame Holder Adjustment - local flameHolderfTP = automaton:getMod(xi.mod.WEAPONSKILL_DAMAGE_BASE) / 100 - if flameHolderfTP > 0 then - params.fTP = - { - params.fTP[1] * flameHolderfTP, - params.fTP[2] * flameHolderfTP, - params.fTP[3] * flameHolderfTP, - } - end + xi.automaton.applyFlameHolder(automaton, params.fTP) local info = xi.mobskills.mobRangedMove(automaton, target, skill, action, params) diff --git a/scripts/actions/abilities/pets/automaton/armor_piercer.lua b/scripts/actions/abilities/pets/automaton/armor_piercer.lua index 83d99258790..4f3ce6c4dac 100644 --- a/scripts/actions/abilities/pets/automaton/armor_piercer.lua +++ b/scripts/actions/abilities/pets/automaton/armor_piercer.lua @@ -35,16 +35,7 @@ abilityObject.onAutomatonAbility = function(target, automaton, skill, master, ac params.fTP = { 4.0, 5.5, 7.0 } end - -- Flame Holder Adjustment - local flameHolderfTP = automaton:getMod(xi.mod.WEAPONSKILL_DAMAGE_BASE) / 100 - if flameHolderfTP > 0 then - params.fTP = - { - params.fTP[1] * flameHolderfTP, - params.fTP[2] * flameHolderfTP, - params.fTP[3] * flameHolderfTP, - } - end + xi.automaton.applyFlameHolder(automaton, params.fTP) local info = xi.mobskills.mobRangedMove(automaton, target, skill, action, params) diff --git a/scripts/actions/abilities/pets/automaton/armor_shatterer.lua b/scripts/actions/abilities/pets/automaton/armor_shatterer.lua index fbdf665b91b..3c84b1657c4 100644 --- a/scripts/actions/abilities/pets/automaton/armor_shatterer.lua +++ b/scripts/actions/abilities/pets/automaton/armor_shatterer.lua @@ -33,16 +33,7 @@ abilityObject.onAutomatonAbility = function(target, automaton, skill, master, ac local duration = math.floor(60 + 3 * skill:getTP() / 100) - -- Flame Holder Adjustment - local flameHolderfTP = automaton:getMod(xi.mod.WEAPONSKILL_DAMAGE_BASE) / 100 - if flameHolderfTP > 0 then - params.fTP = - { - params.fTP[1] * flameHolderfTP, - params.fTP[2] * flameHolderfTP, - params.fTP[3] * flameHolderfTP, - } - end + xi.automaton.applyFlameHolder(automaton, params.fTP) local info = xi.mobskills.mobRangedMove(automaton, target, skill, action, params) diff --git a/scripts/actions/abilities/pets/automaton/bone_crusher.lua b/scripts/actions/abilities/pets/automaton/bone_crusher.lua index 10ec8524a2b..47e1b3f15eb 100644 --- a/scripts/actions/abilities/pets/automaton/bone_crusher.lua +++ b/scripts/actions/abilities/pets/automaton/bone_crusher.lua @@ -19,12 +19,12 @@ abilityObject.onAutomatonAbility = function(target, automaton, skill, master, ac local params = {} params.baseDamage = automaton:getWeaponDmg() - params.numHits = 3 + params.numHits = utils.clamp(3 + xi.automaton.getExtraHits(automaton, 3), 1, 8) params.fTP = { 1.5, 1.5, 1.5 } params.vit_wSC = 0.60 params.attackType = xi.attackType.PHYSICAL params.damageType = xi.damageType.BLUNT - params.shadowBehavior = xi.mobskills.shadowBehavior.NUMSHADOWS_3 + params.shadowBehavior = params.numHits if xi.settings.main.USE_ADOULIN_WEAPON_SKILL_CHANGES then params.fTP = { 2.66, 2.66, 2.66 } @@ -38,16 +38,7 @@ abilityObject.onAutomatonAbility = function(target, automaton, skill, master, ac end end - -- Flame Holder Adjustment - local flameHolderfTP = automaton:getMod(xi.mod.WEAPONSKILL_DAMAGE_BASE) / 100 - if flameHolderfTP > 0 then - params.fTP = - { - params.fTP[1] * flameHolderfTP, - params.fTP[2] * flameHolderfTP, - params.fTP[3] * flameHolderfTP, - } - end + xi.automaton.applyFlameHolder(automaton, params.fTP) local info = xi.mobskills.mobPhysicalMove(automaton, target, skill, action, params) diff --git a/scripts/actions/abilities/pets/automaton/cannibal_blade.lua b/scripts/actions/abilities/pets/automaton/cannibal_blade.lua index a65ae17bd6c..0b4f2185bd0 100644 --- a/scripts/actions/abilities/pets/automaton/cannibal_blade.lua +++ b/scripts/actions/abilities/pets/automaton/cannibal_blade.lua @@ -1,6 +1,12 @@ ----------------------------------- -- Cannibal Blade -- Description: Delivers a single hit attack. Additional Effect: Convert damage dealt to HP. +-- SE claims this has a 1.0 MND wSC modifier. At this time it does not appear to have any scaling outside of Automaton Skill. +-- Cannot miss, cannot double attack, ignores PDIF, but is affected by Slashing/Physical DT modifiers. +-- Despite behaving like a magic ability, does not go through shadows. +-- Returns 0 TP. +-- TODO: Refine formula if more retail data becomes available. +-- Automaton Skill / 9.2 is very close, but not exact. Retail appears to use non-linear scaling or hidden stepping. ----------------------------------- ---@type TAbilityAutomaton local abilityObject = {} @@ -18,31 +24,21 @@ end abilityObject.onAutomatonAbility = function(target, automaton, skill, master, action) local params = {} - params.baseDamage = (math.floor(automaton:getSkillLevel(xi.skill.AUTOMATON_MELEE) / 9 * 11)) + params.baseDamage = automaton:getSkillLevel(xi.skill.AUTOMATON_MELEE) / 9.2 params.numHits = 1 - params.fTP = { 1.0, 1.15, 1.3 } - params.skipPDIF = true - params.guaranteedFirstHit = true + params.fTP = { 11.0, 12.5, 14.0 } params.attackType = xi.attackType.PHYSICAL params.damageType = xi.damageType.SLASHING params.shadowBehavior = xi.mobskills.shadowBehavior.NUMSHADOWS_1 + params.guaranteedFirstHit = true + params.skipFSTR = true + params.skipPDIF = true if xi.settings.main.USE_ADOULIN_WEAPON_SKILL_CHANGES then - params.baseDamage = automaton:getWeaponDmg() - params.fTP = { 16.0, 23.5, 31.5 } - params.mnd_wSC = 1.0 + params.fTP = { 16.0, 23.5, 31.0 } end - -- Flame Holder Adjustment - local flameHolderfTP = automaton:getMod(xi.mod.WEAPONSKILL_DAMAGE_BASE) / 100 - if flameHolderfTP > 0 then - params.fTP = - { - params.fTP[1] * flameHolderfTP, - params.fTP[2] * flameHolderfTP, - params.fTP[3] * flameHolderfTP, - } - end + xi.automaton.applyFlameHolder(automaton, params.fTP) local info = xi.mobskills.mobPhysicalMove(automaton, target, skill, action, params) @@ -51,10 +47,12 @@ abilityObject.onAutomatonAbility = function(target, automaton, skill, master, ac if not target:isUndead() then automaton:addHP(info.damage) - skill:setMsg(xi.msg.basic.SKILL_DRAIN_HP) end end + -- Does not return TP. + automaton:setTP(0) + return info.damage end diff --git a/scripts/actions/abilities/pets/automaton/chimera_ripper.lua b/scripts/actions/abilities/pets/automaton/chimera_ripper.lua index 6a6d1e4b071..44b6b3eb16e 100644 --- a/scripts/actions/abilities/pets/automaton/chimera_ripper.lua +++ b/scripts/actions/abilities/pets/automaton/chimera_ripper.lua @@ -19,28 +19,19 @@ abilityObject.onAutomatonAbility = function(target, automaton, skill, master, ac local params = {} params.baseDamage = automaton:getWeaponDmg() - params.numHits = 1 + params.numHits = utils.clamp(1 + xi.automaton.getExtraHits(automaton, 1), 1, 8) params.fTP = { 1.5, 2.0, 3.0 } params.str_wSC = 0.50 params.accuracyModifier = { 100, 100, 100 } params.attackType = xi.attackType.PHYSICAL params.damageType = xi.damageType.SLASHING - params.shadowBehavior = xi.mobskills.shadowBehavior.NUMSHADOWS_1 + params.shadowBehavior = params.numHits if xi.settings.main.USE_ADOULIN_WEAPON_SKILL_CHANGES then params.fTP = { 6.0, 8.5, 11.0 } end - -- Flame Holder Adjustment - local flameHolderfTP = automaton:getMod(xi.mod.WEAPONSKILL_DAMAGE_BASE) / 100 - if flameHolderfTP > 0 then - params.fTP = - { - params.fTP[1] * flameHolderfTP, - params.fTP[2] * flameHolderfTP, - params.fTP[3] * flameHolderfTP, - } - end + xi.automaton.applyFlameHolder(automaton, params.fTP) local info = xi.mobskills.mobPhysicalMove(automaton, target, skill, action, params) diff --git a/scripts/actions/abilities/pets/automaton/daze.lua b/scripts/actions/abilities/pets/automaton/daze.lua index e236f7731d8..9fabfff0245 100644 --- a/scripts/actions/abilities/pets/automaton/daze.lua +++ b/scripts/actions/abilities/pets/automaton/daze.lua @@ -34,16 +34,7 @@ abilityObject.onAutomatonAbility = function(target, automaton, skill, master, ac params.fTP = { 6.0, 8.5, 11.0 } end - -- Flame Holder Adjustment - local flameHolderfTP = automaton:getMod(xi.mod.WEAPONSKILL_DAMAGE_BASE) / 100 - if flameHolderfTP > 0 then - params.fTP = - { - params.fTP[1] * flameHolderfTP, - params.fTP[2] * flameHolderfTP, - params.fTP[3] * flameHolderfTP, - } - end + xi.automaton.applyFlameHolder(automaton, params.fTP) local info = xi.mobskills.mobRangedMove(automaton, target, skill, action, params) diff --git a/scripts/actions/abilities/pets/automaton/knockout.lua b/scripts/actions/abilities/pets/automaton/knockout.lua index 24cca432fc1..e2246e981d5 100644 --- a/scripts/actions/abilities/pets/automaton/knockout.lua +++ b/scripts/actions/abilities/pets/automaton/knockout.lua @@ -21,29 +21,20 @@ end abilityObject.onAutomatonAbility = function(target, automaton, skill, master, action) local params = {} - params.numHits = 1 + params.numHits = utils.clamp(1 + xi.automaton.getExtraHits(automaton, 1), 1, 8) params.fTP = { 4.0, 4.5, 5.0 } params.agi_wSC = 0.85 params.accuracyModifier = { 50, 50, 50 } params.attackType = xi.attackType.PHYSICAL params.damageType = xi.damageType.BLUNT - params.shadowBehavior = xi.mobskills.shadowBehavior.NUMSHADOWS_1 + params.shadowBehavior = params.numHits if xi.settings.main.USE_ADOULIN_WEAPON_SKILL_CHANGES then params.agi_wSC = 1.0 params.fTP = { 6.0, 8.5, 11.0 } end - -- Flame Holder Adjustment - local flameHolderfTP = automaton:getMod(xi.mod.WEAPONSKILL_DAMAGE_BASE) / 100 - if flameHolderfTP > 0 then - params.fTP = - { - params.fTP[1] * flameHolderfTP, - params.fTP[2] * flameHolderfTP, - params.fTP[3] * flameHolderfTP, - } - end + xi.automaton.applyFlameHolder(automaton, params.fTP) local info = xi.mobskills.mobPhysicalMove(automaton, target, skill, action, params) diff --git a/scripts/actions/abilities/pets/automaton/shield_bash.lua b/scripts/actions/abilities/pets/automaton/shield_bash.lua index 904abd99108..04ff4d49374 100644 --- a/scripts/actions/abilities/pets/automaton/shield_bash.lua +++ b/scripts/actions/abilities/pets/automaton/shield_bash.lua @@ -1,62 +1,77 @@ ----------------------------------- --- Shield Bash +-- Shield Bash (Automaton) +-- Description: Deals damage and stuns the target. Additional effect: Slow - Based on Earth Maneuvers if Hammermill is equipped. +-- Hammermill Slow increases with tiers per Earth Maneuver, at 3, overrides Haste (tier 6) -- Confirmed in Brenner. +-- https://wiki.ffo.jp/html/12156.html ----------------------------------- ---@type TAbilityAutomaton local abilityObject = {} +-- Slow tier and duration based on Earth Maneuvers. +local slowTable = +{ + [1] = { tier = 4, duration = 30 }, + [2] = { tier = 5, duration = 50 }, + [3] = { tier = 6, duration = 70 }, +} + +local function applyHammermillSlow(automaton, target, skill, master) + local power = automaton:getMod(xi.mod.AUTO_SHIELD_BASH_SLOW) * 100 + if power <= 0 then + return + end + + local slowTier = slowTable[master and master:countEffect(xi.effect.EARTH_MANEUVER) or 0] + + local params = + { + [1] = { effectId = xi.effect.SLOW, power = power, duration = slowTier.duration, tier = slowTier.tier }, + } + + xi.combat.action.executeMobskillStatusEffect(automaton, target, skill, params, { messageBypass = true }) +end + abilityObject.onAutomatonAbilityCheck = function(target, automaton, skill) return 0 end abilityObject.onAutomatonAbility = function(target, automaton, skill, master, action) - local chance = 90 - local damage = (automaton:getSkillLevel(xi.skill.AUTOMATON_MELEE) / 2) * (1 + automaton:getMod(xi.mod.SHIELD_BASH) / 100) - - damage = math.floor(damage) + local params = {} - chance = chance + (automaton:getMainLvl() - target:getMainLvl()) * 5 + params.baseDamage = automaton:getWeaponDmg() + params.numHits = utils.clamp(1 + xi.automaton.getExtraHits(automaton, 1), 1, 8) + params.fTP = { 1.0, 1.0, 1.0 } + params.attackType = xi.attackType.PHYSICAL + params.damageType = xi.damageType.BLUNT + params.shadowBehavior = params.numHits - if math.random() * 100 < chance then - target:addStatusEffect(xi.effect.STUN, { power = 1, duration = 6, origin = automaton }) - end - - local slowPower = automaton:getMod(xi.mod.AUTO_SHIELD_BASH_SLOW) - if slowPower > 0 then - local duration = 20 - if slowPower == 12 then - duration = math.random(20, 35) - elseif slowPower == 19 then - duration = math.random(51, 57) - elseif slowPower == 25 then - duration = math.random(70, 75) - end - - target:addStatusEffect(xi.effect.SLOW, { power = slowPower * 100, duration = duration, origin = automaton, tier = 3 }) - end + if automaton:getLocalVar('hammermill') == 1 then + local shieldBashBonus = 1.0 + automaton:getMod(xi.mod.SHIELD_BASH) / 100 - -- randomize damage - -- TODO: Should this use our newer PDIF calcs located in physical_utilities.lua? - local ratio = automaton:getStat(xi.mod.ATT) / target:getStat(xi.mod.DEF) - if ratio > 1.3 then - ratio = 1.3 - end + params.fTP = + { + params.fTP[1] * shieldBashBonus, + params.fTP[2] * shieldBashBonus, + params.fTP[3] * shieldBashBonus, + } - if ratio < 0.2 then - ratio = 0.2 + params.guaranteedFirstHit = true end - local pdif = math.random(ratio * 0.8 * 1000, ratio * 1.2 * 1000) + local info = xi.mobskills.mobPhysicalMove(automaton, target, skill, action, params) - damage = damage * (pdif / 1000) + if xi.mobskills.processDamage(automaton, target, skill, action, info) then + target:takeDamage(info.damage, automaton, info.attackType, info.damageType) - -- TODO: Affected by Phalanx, Physical Damage % modifiers? + xi.mobskills.mobStatusEffectMove(automaton, target, xi.effect.STUN, 1, 0, 6) - damage = utils.handleStoneskin(target, damage) - target:takeDamage(damage, automaton, xi.attackType.PHYSICAL, xi.damageType.BLUNT) - target:updateEnmityFromDamage(automaton, damage) - target:addEnmity(automaton, 450, 900) + -- Check for Hammermill, if equipped, apply Slow based on Earth Maneuvers. + if automaton:getLocalVar('hammermill') == 1 then + applyHammermillSlow(automaton, target, skill, master) + end + end - return damage + return info.damage end return abilityObject diff --git a/scripts/actions/abilities/pets/automaton/slapstick.lua b/scripts/actions/abilities/pets/automaton/slapstick.lua index fee7c736741..b50eda45d61 100644 --- a/scripts/actions/abilities/pets/automaton/slapstick.lua +++ b/scripts/actions/abilities/pets/automaton/slapstick.lua @@ -21,14 +21,14 @@ end abilityObject.onAutomatonAbility = function(target, automaton, skill, master, action) local params = {} - params.numHits = 3 + params.numHits = utils.clamp(3 + xi.automaton.getExtraHits(automaton, 3), 1, 8) params.fTP = { 1.0, 1.0, 1.0 } params.str_wSC = 0.20 params.dex_wSC = 0.20 params.accuracyModifier = { 0, 30, 50 } params.attackType = xi.attackType.PHYSICAL params.damageType = xi.damageType.BLUNT - params.shadowBehavior = xi.mobskills.shadowBehavior.NUMSHADOWS_3 + params.shadowBehavior = params.numHits if xi.settings.main.USE_ADOULIN_WEAPON_SKILL_CHANGES then params.fTP = { 2.66, 2.66, 2.66 } @@ -37,16 +37,7 @@ abilityObject.onAutomatonAbility = function(target, automaton, skill, master, ac params.accuracyModifier = { 0, 40, 80 } end - -- Flame Holder Adjustment - local flameHolderfTP = automaton:getMod(xi.mod.WEAPONSKILL_DAMAGE_BASE) / 100 - if flameHolderfTP > 0 then - params.fTP = - { - params.fTP[1] * flameHolderfTP, - params.fTP[2] * flameHolderfTP, - params.fTP[3] * flameHolderfTP, - } - end + xi.automaton.applyFlameHolder(automaton, params.fTP) local info = xi.mobskills.mobPhysicalMove(automaton, target, skill, action, params) diff --git a/scripts/actions/abilities/pets/automaton/string_clipper.lua b/scripts/actions/abilities/pets/automaton/string_clipper.lua index b5b50bb1b8f..7aca17cff6a 100644 --- a/scripts/actions/abilities/pets/automaton/string_clipper.lua +++ b/scripts/actions/abilities/pets/automaton/string_clipper.lua @@ -19,7 +19,7 @@ abilityObject.onAutomatonAbility = function(target, automaton, skill, master, ac local params = {} params.baseDamage = automaton:getWeaponDmg() - params.numHits = 2 + params.numHits = utils.clamp(2 + xi.automaton.getExtraHits(automaton, 2), 1, 8) params.fTP = { 2.0, 2.0, 2.0 } params.str_wSC = 0.30 params.dex_wSC = 0.30 @@ -27,22 +27,13 @@ abilityObject.onAutomatonAbility = function(target, automaton, skill, master, ac params.accuracyModifier = { 0, 50, 100 } params.attackType = xi.attackType.PHYSICAL params.damageType = xi.damageType.SLASHING - params.shadowBehavior = xi.mobskills.shadowBehavior.NUMSHADOWS_2 + params.shadowBehavior = params.numHits if xi.settings.main.USE_ADOULIN_WEAPON_SKILL_CHANGES then params.fTP = { 3.5, 3.5, 3.5 } end - -- Flame Holder Adjustment - local flameHolderfTP = automaton:getMod(xi.mod.WEAPONSKILL_DAMAGE_BASE) / 100 - if flameHolderfTP > 0 then - params.fTP = - { - params.fTP[1] * flameHolderfTP, - params.fTP[2] * flameHolderfTP, - params.fTP[3] * flameHolderfTP, - } - end + xi.automaton.applyFlameHolder(automaton, params.fTP) local info = xi.mobskills.mobPhysicalMove(automaton, target, skill, action, params) diff --git a/scripts/actions/abilities/pets/automaton/string_shredder.lua b/scripts/actions/abilities/pets/automaton/string_shredder.lua index a93a85535fb..c088b5c19c3 100644 --- a/scripts/actions/abilities/pets/automaton/string_shredder.lua +++ b/scripts/actions/abilities/pets/automaton/string_shredder.lua @@ -19,7 +19,7 @@ abilityObject.onAutomatonAbility = function(target, automaton, skill, master, ac local params = {} params.baseDamage = automaton:getWeaponDmg() - params.numHits = 2 + params.numHits = utils.clamp(2 + xi.automaton.getExtraHits(automaton, 2), 1, 8) params.fTP = { 1.5, 1.5, 1.5 } params.vit_wSC = 0.50 params.attackMultiplier = { 1.36, 1.36, 1.36 } @@ -27,18 +27,9 @@ abilityObject.onAutomatonAbility = function(target, automaton, skill, master, ac params.criticalChance = { 0.2, 0.4, 0.7 } params.attackType = xi.attackType.PHYSICAL params.damageType = xi.damageType.SLASHING - params.shadowBehavior = xi.mobskills.shadowBehavior.NUMSHADOWS_2 - - -- Flame Holder Adjustment - local flameHolderfTP = automaton:getMod(xi.mod.WEAPONSKILL_DAMAGE_BASE) / 100 - if flameHolderfTP > 0 then - params.fTP = - { - params.fTP[1] * flameHolderfTP, - params.fTP[2] * flameHolderfTP, - params.fTP[3] * flameHolderfTP, - } - end + params.shadowBehavior = params.numHits + + xi.automaton.applyFlameHolder(automaton, params.fTP) local info = xi.mobskills.mobPhysicalMove(automaton, target, skill, action, params) diff --git a/scripts/globals/automaton.lua b/scripts/globals/automaton.lua index cbf77748b8a..59aa7c8eee1 100644 --- a/scripts/globals/automaton.lua +++ b/scripts/globals/automaton.lua @@ -232,10 +232,6 @@ local function getRefreshModValue(pet, attachmentName, numManeuvers) return regenRefreshFormulas[attachmentName][1][numManeuvers + 1] + petMaxMP * (regenRefreshFormulas[attachmentName][2][numManeuvers + 1] / 100) end -xi.automaton.getRangedBaseDamage = function(automaton) - return automaton:getRangedDmg() * (1 + automaton:getMod(xi.mod.AUTO_RANGED_DAMAGEP) / 100) -end - local function isOpticFiber(attachmentName) if string.find(attachmentName, 'optic_fiber') ~= nil then return true @@ -262,6 +258,36 @@ local function calculatePerformanceBoost(pet) return performanceBoost end +-- Return the base damage of an Automaton Ranged Attack, factoring in the AUTO_RANGED_DAMAGEP modifier. +xi.automaton.getRangedBaseDamage = function(automaton) + return automaton:getRangedDmg() * (1 + automaton:getMod(xi.mod.AUTO_RANGED_DAMAGEP) / 100) +end + +-- Returns the number of extra hits granted by the DOUBLE_ATTACK modifier based on the base number of hits. +xi.automaton.getExtraHits = function(automaton, numHits) + local doubleAttackRate = utils.clamp(automaton:getMod(xi.mod.DOUBLE_ATTACK), 0, 100) + local extraHits = 0 + if doubleAttackRate > 0 then + for _ = 1, numHits do + if math.random(1, 100) <= doubleAttackRate then + extraHits = extraHits + 1 + end + end + end + + return extraHits +end + +-- Applies the FTP multiplier for an Automaton Weapon Skill, factoring in the WEAPONSKILL_DAMAGE_BASE modifier from Flame Holder. +xi.automaton.applyFlameHolder = function(automaton, ftp) + local flameHolderFTP = automaton:getMod(xi.mod.WEAPONSKILL_DAMAGE_BASE) / 100 + if flameHolderFTP > 0 then + ftp[1] = ftp[1] * flameHolderFTP + ftp[2] = ftp[2] * flameHolderFTP + ftp[3] = ftp[3] * flameHolderFTP + end +end + -- Global functions to handle attachment equip, unequip, maneuver and performance changes -- NOTE: Core is 0-indexed for maneuvers, yet the table above is 1-indexed, and Maneuvers -- are updated in core before the appropriate function is called in Lua. This is why some