Skip to content

Commit 88f2705

Browse files
authored
Merge pull request #10050 from Skold177/Automaton-WS-Refactor-2
[lua] Automaton Skill Rework
2 parents 6319e1f + 2700e15 commit 88f2705

20 files changed

Lines changed: 590 additions & 462 deletions

modules/soa/lua/flame_holder.lua

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
-----------------------------------
2+
-- Flame Holder
3+
-- Reverts Flame Holder to its pre-2019 functionality - Where it consumed Fire Maneuvers on skill execution.
4+
-- Source : https://wiki.ffo.jp/html/11183.html
5+
-----------------------------------
6+
require('modules/module_utils')
7+
-----------------------------------
8+
local m = Module:new('era_flame_holder')
9+
10+
local validSkills = set
11+
{
12+
xi.automaton.abilities.ARCUBALLISTA,
13+
xi.automaton.abilities.ARMOR_PIERCER,
14+
xi.automaton.abilities.ARMOR_SHATTERER,
15+
xi.automaton.abilities.BONE_CRUSHER,
16+
xi.automaton.abilities.CANNIBAL_BLADE,
17+
xi.automaton.abilities.CHIMERA_RIPPER,
18+
xi.automaton.abilities.DAZE,
19+
xi.automaton.abilities.KNOCKOUT,
20+
xi.automaton.abilities.MAGIC_MORTAR,
21+
xi.automaton.abilities.SLAPSTICK,
22+
xi.automaton.abilities.STRING_CLIPPER,
23+
xi.automaton.abilities.STRING_SHREDDER,
24+
}
25+
26+
m:addOverride('xi.actions.abilities.pets.attachments.flame_holder.onEquip', function(pet, attachment)
27+
pet:addListener('WEAPONSKILL_STATE_ENTER', 'AUTO_FLAME_HOLDER_START', function(automaton, skillId)
28+
-- Not a valid skill for Flame Holder
29+
if not validSkills[skillId] then
30+
return
31+
end
32+
33+
local master = automaton:getMaster()
34+
35+
if not master then
36+
return
37+
end
38+
39+
-- Fetch the amount of active Fire Maneuvers on weaponskill state entry.
40+
local fireManeuvers = master:countEffect(xi.effect.FIRE_MANEUVER)
41+
42+
-- No Fire Maneuvers
43+
if fireManeuvers == 0 then
44+
return
45+
end
46+
47+
-- Set the WEAPONSKILL_DAMAGE_BASE mod to 125% / 150% / 175% based on the number of Fire Maneuvers active.
48+
local flameHolderAmount = 100 + 25 * fireManeuvers
49+
50+
automaton:setLocalVar('fireManeuvers', fireManeuvers)
51+
automaton:setLocalVar('flameHolderAmount', flameHolderAmount)
52+
automaton:addMod(xi.mod.WEAPONSKILL_DAMAGE_BASE, flameHolderAmount)
53+
end)
54+
55+
pet:addListener('WEAPONSKILL_STATE_EXIT', 'AUTO_FLAME_HOLDER_END', function(automaton, skillId, wasExecuted)
56+
local flameHolderAmount = automaton:getLocalVar('flameHolderAmount')
57+
58+
-- If no Flame Holder bonus is active, do nothing.
59+
if flameHolderAmount == 0 then
60+
return
61+
end
62+
63+
local fireManeuvers = automaton:getLocalVar('fireManeuvers')
64+
local master = automaton:getMaster()
65+
66+
if not master then
67+
return
68+
end
69+
70+
-- Consume all Fire Maneuvers on execution.
71+
for i = 1, fireManeuvers do
72+
master:delStatusEffectSilent(xi.effect.FIRE_MANEUVER)
73+
end
74+
75+
-- Remove the Flame Holder bonus and reset local variables.
76+
automaton:delMod(xi.mod.WEAPONSKILL_DAMAGE_BASE, flameHolderAmount)
77+
automaton:setLocalVar('flameHolderAmount', 0)
78+
automaton:setLocalVar('fireManeuvers', 0)
79+
end)
80+
end)
81+
82+
m:addOverride('xi.actions.abilities.pets.attachments.flame_holder.onUnequip', function(pet, attachment)
83+
local amount = pet:getLocalVar('flameHolderAmount')
84+
85+
-- Should be nearly impossible, but just in case.
86+
if amount ~= 0 then
87+
pet:delMod(xi.mod.WEAPONSKILL_DAMAGE_BASE, amount)
88+
end
89+
90+
pet:setLocalVar('flameHolderAmount', 0)
91+
pet:setLocalVar('fireManeuvers', 0)
92+
pet:removeListener('AUTO_FLAME_HOLDER_START')
93+
pet:removeListener('AUTO_FLAME_HOLDER_END')
94+
end)
95+
96+
m:addOverride('xi.actions.abilities.pets.attachments.flame_holder.onManeuverGain', function(pet, attachment, maneuvers)
97+
end)
98+
99+
m:addOverride('xi.actions.abilities.pets.attachments.flame_holder.onManeuverLose', function(pet, attachment, maneuvers)
100+
end)
101+
102+
m:addOverride('xi.actions.abilities.pets.attachments.flame_holder.onUpdate', function(pet, attachment, maneuvers)
103+
end)
104+
105+
return m

scripts/actions/abilities/pets/attachments/barrage_turbine.lua

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,21 @@ attachmentObject.onEquip = function(pet)
88
pet:addListener('AUTOMATON_ATTACHMENT_CHECK', 'ATTACHMENT_BARRAGE_TURBINE', function(automaton, target)
99
local master = automaton:getMaster()
1010

11-
if
12-
not automaton:hasRecast(xi.recast.ABILITY, xi.automaton.abilities.BARRAGE_TURBINE) and
13-
master and
14-
master:countEffect(xi.effect.WIND_MANEUVER) > 0
15-
then
16-
automaton:useMobAbility(xi.automaton.abilities.BARRAGE_TURBINE, target)
11+
if not master then
12+
return
1713
end
14+
15+
-- If no Wind Maneuvers are active, do nothing.
16+
if master:countEffect(xi.effect.WIND_MANEUVER) == 0 then
17+
return
18+
end
19+
20+
-- If Barrage Turbine is still on cooldown, do nothing.
21+
if automaton:hasRecast(xi.recast.ABILITY, xi.automaton.abilities.BARRAGE_TURBINE) then
22+
return
23+
end
24+
25+
automaton:useMobAbility(xi.automaton.abilities.BARRAGE_TURBINE, target)
1826
end)
1927
end
2028

Lines changed: 13 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,70 +1,29 @@
11
-----------------------------------
22
-- Attachment: Flame Holder
3+
-- Description : Adds fire maneuver burden to increase weapon skill damage.
4+
-- 25% at 0, 100% at 1, 175% at 2, and 250% at 3. Ex. at 3 fire maneuvers, 10 fTP will be 25 fTP.
35
-----------------------------------
46
---@type TAttachment
57
local attachmentObject = {}
68

7-
local validskills = set{
8-
1940,
9-
1941,
10-
1942,
11-
1943,
12-
2065,
13-
2066,
14-
2067,
15-
2299,
16-
2300,
17-
2301,
18-
2743,
19-
2744,
20-
}
21-
22-
attachmentObject.onEquip = function(automaton)
23-
automaton:addListener('WEAPONSKILL_STATE_ENTER', 'AUTO_FLAME_HOLDER_START', function(pet, skill)
24-
if not validskills[skill] then
25-
return
26-
end
27-
28-
local master = pet:getMaster()
29-
local maneuvers = master:countEffect(xi.effect.FIRE_MANEUVER)
30-
31-
if maneuvers < 1 or maneuvers > 3 then
32-
return
33-
end
34-
35-
local amount = 25 * maneuvers
36-
pet:setLocalVar('flameholdermaneuvers', maneuvers)
37-
38-
pet:addMod(xi.mod.WEAPONSKILL_DAMAGE_BASE, amount)
39-
pet:setLocalVar('flameholder', amount)
40-
end)
41-
42-
automaton:addListener('WEAPONSKILL_STATE_EXIT', 'AUTO_FLAME_HOLDER_END', function(pet, skillId, wasExecuted)
43-
local master = pet:getMaster()
44-
local toremove = pet:getLocalVar('flameholdermaneuvers')
45-
if toremove == 0 then
46-
return
47-
end
48-
49-
for i = 1, toremove do
50-
master:delStatusEffectSilent(xi.effect.FIRE_MANEUVER)
51-
end
9+
attachmentObject.onEquip = function(pet, attachment)
10+
xi.automaton.onAttachmentEquip(pet, attachment)
11+
end
5212

53-
pet:delMod(xi.mod.WEAPONSKILL_DAMAGE_BASE, pet:getLocalVar('flameholder'))
54-
pet:setLocalVar('flameholder', 0)
55-
pet:setLocalVar('flameholdermaneuvers', 0)
56-
end)
13+
attachmentObject.onUnequip = function(pet, attachment)
14+
xi.automaton.onAttachmentUnequip(pet, attachment)
5715
end
5816

59-
attachmentObject.onUnequip = function(pet)
60-
pet:removeListener('AUTO_FLAME_HOLDER_START')
61-
pet:removeListener('AUTO_FLAME_HOLDER_END')
17+
attachmentObject.onManeuverGain = function(pet, attachment, maneuvers)
18+
xi.automaton.onManeuverGain(pet, attachment, maneuvers)
6219
end
6320

64-
attachmentObject.onManeuverGain = function(pet, maneuvers)
21+
attachmentObject.onManeuverLose = function(pet, attachment, maneuvers)
22+
xi.automaton.onManeuverLose(pet, attachment, maneuvers)
6523
end
6624

67-
attachmentObject.onManeuverLose = function(pet, maneuvers)
25+
attachmentObject.onUpdate = function(pet, attachment, maneuvers)
26+
xi.automaton.updateAttachmentModifier(pet, attachment, maneuvers)
6827
end
6928

7029
return attachmentObject
Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
-----------------------------------
22
-- Arcuballista
3+
-- Description: Delivers a single attack. Damage varies with TP.
34
-----------------------------------
45
---@type TAbilityAutomaton
56
local abilityObject = {}
67

78
abilityObject.onAutomatonAbilityCheck = function(target, automaton, skill)
89
local master = automaton:getMaster()
10+
911
if not master then
1012
return
1113
end
@@ -14,22 +16,42 @@ abilityObject.onAutomatonAbilityCheck = function(target, automaton, skill)
1416
end
1517

1618
abilityObject.onAutomatonAbility = function(target, automaton, skill, master, action)
17-
local params =
18-
{
19-
numHits = 1,
20-
atkmulti = 1,
21-
accBonus = 100,
22-
ftpMod = { 2.5, 3.0, 4.0 },
23-
dex_wsc = 0.5,
24-
}
19+
local params = {}
20+
21+
params.baseDamage = xi.automaton.getRangedBaseDamage(automaton)
22+
params.numHits = 1
23+
params.fTP = { 2.5, 3.0, 4.0 }
24+
params.dex_wSC = 0.60
25+
params.accuracyModifier = { 100, 100, 100 }
26+
params.attackType = xi.attackType.RANGED
27+
params.damageType = xi.damageType.PIERCING
28+
params.shadowBehavior = xi.mobskills.shadowBehavior.NUMSHADOWS_1
29+
params.skipParry = true
30+
params.skipGuard = true
31+
params.skipBlock = true
2532

2633
if xi.settings.main.USE_ADOULIN_WEAPON_SKILL_CHANGES then
27-
params.ftpMod = { 7.0, 10.0, 13.0 }
34+
params.fTP = { 7.0, 10.0, 13.0 }
35+
end
36+
37+
-- Flame Holder Adjustment
38+
local flameHolderfTP = automaton:getMod(xi.mod.WEAPONSKILL_DAMAGE_BASE) / 100
39+
if flameHolderfTP > 0 then
40+
params.fTP =
41+
{
42+
params.fTP[1] * flameHolderfTP,
43+
params.fTP[2] * flameHolderfTP,
44+
params.fTP[3] * flameHolderfTP,
45+
}
2846
end
2947

30-
local damage = xi.autows.doAutoRangedWeaponskill(automaton, target, 0, params, skill:getTP(), true, skill, action)
48+
local info = xi.mobskills.mobRangedMove(automaton, target, skill, action, params)
49+
50+
if xi.mobskills.processDamage(automaton, target, skill, action, info) then
51+
target:takeDamage(info.damage, automaton, info.attackType, info.damageType)
52+
end
3153

32-
return damage
54+
return info.damage
3355
end
3456

3557
return abilityObject
Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
-----------------------------------
22
-- Armor Piercer
3+
-- Description: Delivers a single hit attack. Damage varies with TP. Ignores 50% of targets defence during weapon skill.
34
-----------------------------------
45
---@type TAbilityAutomaton
56
local abilityObject = {}
67

78
abilityObject.onAutomatonAbilityCheck = function(target, automaton, skill)
89
local master = automaton:getMaster()
10+
911
if not master then
1012
return
1113
end
@@ -14,24 +16,43 @@ abilityObject.onAutomatonAbilityCheck = function(target, automaton, skill)
1416
end
1517

1618
abilityObject.onAutomatonAbility = function(target, automaton, skill, master, action)
17-
local params =
18-
{
19-
numHits = 1,
20-
atkmulti = 1.5,
21-
accBonus = 100,
22-
ftpMod = { 3.0, 3.0, 3.0 },
23-
ignoredDefense = { 0.4, 0.5, 0.7 },
24-
dex_wsc = 0.6,
25-
}
19+
local params = {}
20+
21+
params.baseDamage = xi.automaton.getRangedBaseDamage(automaton)
22+
params.numHits = 1
23+
params.fTP = { 3.0, 3.5, 4.0 }
24+
params.dex_wSC = 0.60
25+
params.ignoreDefense = { 0.5, 0.5, 0.5 }
26+
params.accuracyModifier = { 100, 100, 100 }
27+
params.attackType = xi.attackType.RANGED
28+
params.damageType = xi.damageType.PIERCING
29+
params.shadowBehavior = xi.mobskills.shadowBehavior.NUMSHADOWS_1
30+
params.skipParry = true
31+
params.skipGuard = true
32+
params.skipBlock = true
2633

2734
if xi.settings.main.USE_ADOULIN_WEAPON_SKILL_CHANGES then
28-
params.ftpMod = { 4.0, 5.5, 7.0 }
29-
params.ignoredDefense = { 0.5, 0.5, 0.5 }
35+
params.fTP = { 4.0, 5.5, 7.0 }
36+
end
37+
38+
-- Flame Holder Adjustment
39+
local flameHolderfTP = automaton:getMod(xi.mod.WEAPONSKILL_DAMAGE_BASE) / 100
40+
if flameHolderfTP > 0 then
41+
params.fTP =
42+
{
43+
params.fTP[1] * flameHolderfTP,
44+
params.fTP[2] * flameHolderfTP,
45+
params.fTP[3] * flameHolderfTP,
46+
}
3047
end
3148

32-
local damage = xi.autows.doAutoRangedWeaponskill(automaton, target, 0, params, skill:getTP(), true, skill, action)
49+
local info = xi.mobskills.mobRangedMove(automaton, target, skill, action, params)
50+
51+
if xi.mobskills.processDamage(automaton, target, skill, action, info) then
52+
target:takeDamage(info.damage, automaton, info.attackType, info.damageType)
53+
end
3354

34-
return damage
55+
return info.damage
3556
end
3657

3758
return abilityObject

0 commit comments

Comments
 (0)