From bbcc6daecc1d636fe62b61899d9ed4d741a4bf25 Mon Sep 17 00:00:00 2001 From: Xaver-DaRed Date: Wed, 15 Apr 2026 20:56:49 +0200 Subject: [PATCH] Corrects Tantra Cyclas +1 functionality and cleanup Impetus --- scripts/effects/impetus.lua | 71 +++++++------ scripts/globals/job_utils/monk.lua | 153 ++++++++++++++++------------- 2 files changed, 122 insertions(+), 102 deletions(-) diff --git a/scripts/effects/impetus.lua b/scripts/effects/impetus.lua index 36220cef272..2e368c638e9 100644 --- a/scripts/effects/impetus.lua +++ b/scripts/effects/impetus.lua @@ -5,44 +5,51 @@ local effectObject = {} effectObject.onEffectGain = function(target, effect) - target:addListener('MELEE_SWING_MISS', 'IMPETUS_MISS', xi.job_utils.monk.impetusMissListener) - target:addListener('MELEE_SWING_HIT', 'IMPETUS_HIT', xi.job_utils.monk.impetusHitListener) - - -- For reload from the DB (/logout, login), add the effect power - local mainPower = effect:getPower() -- Stores Attack & Critical Hit Rate bonuses - local subPower = effect:getSubPower() -- Stores Critical Hit Damage & Accuracy bonuses - - if mainPower > 0 then - target:addMod(xi.mod.ATT, mainPower * 2) - target:addMod(xi.mod.CRITHITRATE, mainPower) - end - - if subPower > 0 then - target:addMod(xi.mod.ACC, subPower * 2) - target:addMod(xi.mod.CRIT_DMG_INCREASE, subPower) - end + target:addListener('MELEE_SWING_HIT', 'IMPETUS_HIT', function(actorArg, targetArg, attack) + local effectArg = actorArg:getStatusEffect(xi.effect.IMPETUS) + if not effectArg then + return + end + + local mainPower = effectArg:getPower() + 1 -- Tracks stacks. + if mainPower > 50 then + return + end + + -- Handle Attack & Critical Hit Rate bonuses + effectArg:setPower(mainPower) + effectArg:setMod(xi.mod.ATT, 2 * mainPower) + effectArg:setMod(xi.mod.CRITHITRATE, mainPower) + + -- Handle Critical Hit Damage & Accuracy bonuses + local subPower = effectArg:getSubPower() -- Subpower tracks if user had effect augment, and what quality, when effect was applied. + if subPower ~= 0 then + effectArg:setMod(xi.mod.ACC, 2 * mainPower) + effectArg:setMod(xi.mod.CRIT_DMG_INCREASE, math.floor(subPower / 2) * mainPower) + end + end) + + target:addListener('MELEE_SWING_MISS', 'IMPETUS_MISS', function(actorArg, targetArg, attack) + local effectArg = actorArg:getStatusEffect(xi.effect.IMPETUS) + if not effectArg then + return + end + + effectArg:setPower(0) + + effectArg:setMod(xi.mod.ATT, 0) + effectArg:setMod(xi.mod.CRITHITRATE, 0) + effectArg:setMod(xi.mod.ACC, 0) + effectArg:setMod(xi.mod.CRIT_DMG_INCREASE, 0) + end) end effectObject.onEffectTick = function(target, effect) end effectObject.onEffectLose = function(target, effect) - target:removeListener('MELEE_SWING_MISS') - target:removeListener('MELEE_SWING_HIT') - - -- TODO: Support Tantra Cyclas + 1 (does not give critical hit damage) - local mainPower = effect:getPower() -- Stores Attack & Critical Hit Rate bonuses - local subPower = effect:getSubPower() -- Stores Critical Hit Damage & Accuracy bonuses - - if mainPower > 0 then - target:delMod(xi.mod.ATT, mainPower * 2) - target:delMod(xi.mod.CRITHITRATE, mainPower) - end - - if subPower > 0 then - target:delMod(xi.mod.ACC, subPower * 2) - target:delMod(xi.mod.CRIT_DMG_INCREASE, subPower) - end + target:removeListener('IMPETUS_MISS') + target:removeListener('IMPETUS_HIT') end return effectObject diff --git a/scripts/globals/job_utils/monk.lua b/scripts/globals/job_utils/monk.lua index fcbdb58cd5a..9b903e68705 100644 --- a/scripts/globals/job_utils/monk.lua +++ b/scripts/globals/job_utils/monk.lua @@ -99,124 +99,137 @@ xi.job_utils.monk.useChiBlast = function(player, target, ability) end xi.job_utils.monk.useCounterstance = function(player, target, ability) - local power = 45 + player:getMod(xi.mod.COUNTERSTANCE_EFFECT) + target:delStatusEffect(xi.effect.COUNTERSTANCE) - target:delStatusEffect(xi.effect.COUNTERSTANCE) --if not found this will do nothing - target:addStatusEffect(xi.effect.COUNTERSTANCE, { power = power, duration = 300, origin = player }) + local pTable = + { + power = 45 + player:getMod(xi.mod.COUNTERSTANCE_EFFECT), + duration = 300, + origin = player, + } + + target:addStatusEffect(xi.effect.COUNTERSTANCE, pTable) return xi.effect.COUNTERSTANCE end xi.job_utils.monk.useDodge = function(player, target, ability) - local jpLevel = target:getJobPointLevel(xi.jp.DODGE_EFFECT) - local dodgeMod = target:getMod(xi.mod.DODGE_EFFECT) - player:addStatusEffect(xi.effect.DODGE, { power = jpLevel + dodgeMod, duration = 30, origin = player }) + local pTable = + { + power = target:getMod(xi.mod.DODGE_EFFECT) + target:getJobPointLevel(xi.jp.DODGE_EFFECT), + duration = 30, + origin = player, + } + + player:addStatusEffect(xi.effect.DODGE, pTable) return xi.effect.DODGE end xi.job_utils.monk.useFocus = function(player, target, ability) - local jpLevel = target:getJobPointLevel(xi.jp.FOCUS_EFFECT) - local focusMod = target:getMod(xi.mod.FOCUS_EFFECT) - player:addStatusEffect(xi.effect.FOCUS, { power = jpLevel + focusMod, duration = 30, origin = player }) + local pTable = + { + power = target:getMod(xi.mod.FOCUS_EFFECT) + target:getJobPointLevel(xi.jp.FOCUS_EFFECT), + duration = 30, + origin = player, + } + + player:addStatusEffect(xi.effect.FOCUS, pTable) return xi.effect.FOCUS end xi.job_utils.monk.useFootwork = function(player, target, ability) - local kickDmg = 20 + player:getWeaponDmg() - local kickAttPercent = 25 + player:getMod(xi.mod.FOOTWORK_ATT_BONUS) + local pTable = + { + power = 20 + player:getWeaponDmg(), + duration = 60, + subPower = 25 + player:getMod(xi.mod.FOOTWORK_ATT_BONUS), + origin = player, + } - player:addStatusEffect(xi.effect.FOOTWORK, { power = kickDmg, duration = 60, origin = player, subPower = kickAttPercent }) + player:addStatusEffect(xi.effect.FOOTWORK, pTable) return xi.effect.FOOTWORK end xi.job_utils.monk.useFormlessStrikes = function(player, target, ability) - player:addStatusEffect(xi.effect.FORMLESS_STRIKES, { power = 1, duration = 180, origin = player }) + local pTable = + { + power = 1, + duration = 180, + origin = player, + } + + player:addStatusEffect(xi.effect.FORMLESS_STRIKES, pTable) return xi.effect.FORMLESS_STRIKES end xi.job_utils.monk.useHundredFists = function(player, target, ability) - player:addStatusEffect(xi.effect.HUNDRED_FISTS, { power = 1, duration = 45, origin = player }) - - return xi.effect.HUNDRED_FISTS -end - --- TODO: Support Tantra Cyclas + 1 (does not give critical hit damage) --- Probably will be exceptionally jank, very low priority -xi.job_utils.monk.impetusMissListener = function(attacker, victim, attack) - local effect = attacker:getStatusEffect(xi.effect.IMPETUS) - - if effect then - local mainPower = effect:getPower() -- Stores Attack & Critical Hit Rate bonuses - local subPower = effect:getSubPower() -- Stores Critical Hit Damage & Accuracy bonuses - - if mainPower > 0 then - attacker:delMod(xi.mod.ATT, mainPower * 2) - attacker:delMod(xi.mod.CRITHITRATE, mainPower) - - effect:setPower(0) - end - - if subPower > 0 then - attacker:delMod(xi.mod.ACC, subPower * 2) - attacker:delMod(xi.mod.CRIT_DMG_INCREASE, subPower) - - effect:setSubPower(0) - end - end -end - --- TODO: Support Tantra Cyclas + 1 (does not give critical hit damage) --- Probably will be exceptionally jank, very low priority -xi.job_utils.monk.impetusHitListener = function(attacker, victim, attack) - local effect = attacker:getStatusEffect(xi.effect.IMPETUS) - - if effect then - local mainPower = effect:getPower() -- Stores Attack & Critical Hit Rate bonuses - local subPower = effect:getSubPower() -- Stores Critical Hit Damage & Accuracy bonuses + local pTable = + { + power = 1, + duration = 45, + origin = player, + } - if mainPower < 50 then - attacker:addMod(xi.mod.ATT, 2) - attacker:addMod(xi.mod.CRITHITRATE, 1) + player:addStatusEffect(xi.effect.HUNDRED_FISTS, pTable) - effect:setPower(mainPower + 1) - end - - if attacker:getMod(xi.mod.AUGMENTS_IMPETUS) > 0 and subPower < 50 then - attacker:addMod(xi.mod.ACC, 2) - attacker:addMod(xi.mod.CRIT_DMG_INCREASE, 1) - - effect:setSubPower(subPower + 1) - end - end + return xi.effect.HUNDRED_FISTS end xi.job_utils.monk.useImpetus = function(player, target, ability) - player:addStatusEffect(xi.effect.IMPETUS, { duration = 180, origin = player }) + local pTable = + { + power = 0, + subPower = player:getMod(xi.mod.AUGMENTS_IMPETUS), -- Determines what extra bonuses we get. + duration = 180, + origin = player, + } + + player:addStatusEffect(xi.effect.IMPETUS, pTable) return xi.effect.IMPETUS end xi.job_utils.monk.useInnerStrength = function(player, target, ability) - player:addStatusEffect(xi.effect.INNER_STRENGTH, { power = 2, duration = 30, origin = player }) + local pTable = + { + power = 2, + duration = 30, + origin = player, + } + + player:addStatusEffect(xi.effect.INNER_STRENGTH, pTable) return xi.effect.INNER_STRENGTH end xi.job_utils.monk.useMantra = function(player, target, ability) - local merits = player:getMerit(xi.merit.MANTRA) - target:delStatusEffect(xi.effect.MAX_HP_BOOST) -- TODO: confirm which versions of HP boost mantra can overwrite - target:addStatusEffect(xi.effect.MAX_HP_BOOST, { power = merits, duration = 180, origin = player }) + + local pTable = + { + power = player:getMerit(xi.merit.MANTRA), + duration = 180, + origin = player, + } + + target:addStatusEffect(xi.effect.MAX_HP_BOOST, pTable) return xi.effect.MAX_HP_BOOST end xi.job_utils.monk.usePerfectCounter = function(player, target, ability) - player:addStatusEffect(xi.effect.PERFECT_COUNTER, { power = 2, duration = 30, origin = player }) + local pTable = + { + power = 2, + duration = 30, + origin = player, + } + + player:addStatusEffect(xi.effect.PERFECT_COUNTER, pTable) return xi.effect.PERFECT_COUNTER end