From 6b06adc9327732acbdba118290e1d6b1f2ceb593 Mon Sep 17 00:00:00 2001 From: Critical <48370698+CriticalXI@users.noreply.github.com> Date: Fri, 30 Jan 2026 19:16:03 -0700 Subject: [PATCH] [lua, sql, cpp] DRK era audit --- modules/abyssea/lua/job_adjustments.lua | 63 +++++++++++++++++++++- modules/abyssea/sql/job_adjustments.sql | 30 +++++++++++ modules/rov/lua/job_adjustments.lua | 19 ++++++- modules/soa/lua/job_adjustments.lua | 26 +++++++++ modules/soa/sql/job_adjustments.sql | 12 +++++ modules/wotg/lua/job_adjustments.lua | 19 +++++++ scripts/actions/abilities/dark_seal.lua | 4 +- scripts/actions/abilities/diabolic_eye.lua | 4 +- scripts/actions/abilities/weapon_bash.lua | 4 +- scripts/globals/job_utils/dark_knight.lua | 47 +++++++++++----- sql/status_effects.sql | 2 +- sql/traits.sql | 2 +- src/map/utils/battleutils.cpp | 2 + 13 files changed, 210 insertions(+), 24 deletions(-) create mode 100644 modules/soa/lua/job_adjustments.lua create mode 100644 modules/soa/sql/job_adjustments.sql create mode 100644 modules/wotg/lua/job_adjustments.lua diff --git a/modules/abyssea/lua/job_adjustments.lua b/modules/abyssea/lua/job_adjustments.lua index 3eedc02bf92..63a406af99e 100644 --- a/modules/abyssea/lua/job_adjustments.lua +++ b/modules/abyssea/lua/job_adjustments.lua @@ -7,7 +7,7 @@ require('modules/module_utils') ----------------------------------- -local m = Module:new('job_adjustments') +local m = Module:new('abyssea_job_adjustments') ----------------------------------- -- Warrior @@ -66,4 +66,65 @@ m:addOverride('xi.job_utils.white_mage.useDevotion', function(player, target, ab return healMP end) +----------------------------------- +-- Dark Knight +----------------------------------- + +-- Arcane Circle: Revert duration from 3 minutes to 1 minute +-- Source: https://www.bg-wiki.com/ffxi/Version_Update_(02/13/2012) +m:addOverride('xi.job_utils.dark_knight.useArcaneCircle', function(player, target, ability) + local duration = 60 + player:getMod(xi.mod.ARCANE_CIRCLE_DURATION) + local power = 15 + + if player:getMainJob() ~= xi.job.DRK then + power = 5 + end + + power = power + player:getMod(xi.mod.ARCANE_CIRCLE_POTENCY) + + -- Handle simplified message for other party members. + if player:getID() ~= target:getID() then + ability:setMsg(xi.msg.basic.FORTIFIED_ARCANA) + end + + target:addStatusEffect(xi.effect.ARCANE_CIRCLE, power, 0, duration) + + return xi.effect.ARCANE_CIRCLE +end) + +-- Last Resort: Revert duration from 3 minutes to 30 seconds +m:addOverride('xi.job_utils.dark_knight.useLastResort', function(player, target, ability) + player:addStatusEffect(xi.effect.LAST_RESORT, 0, 0, 30) + + return xi.effect.LAST_RESORT +end) + +-- Dark Seal: Remove extra duration and cast speed from merits +m:addOverride('xi.effects.warriors_charge.onEffectGain', function(target, effect) + -- Overwrites + target:delStatusEffectSilent(xi.effect.DIVINE_EMBLEM) + target:delStatusEffectSilent(xi.effect.DIVINE_SEAL) + target:delStatusEffectSilent(xi.effect.ELEMENTAL_SEAL) +end) + +-- Dark Seal: Apply merit recast reduction +m:addOverride('xi.job_utils.dark_knight.useDarkSeal', function(player, target, ability, action) + local recastReduction = player:getMerit(xi.merit.DARK_SEAL) - 150 + action:setRecast(action:getRecast() - recastReduction) + + player:addStatusEffect(xi.effect.DARK_SEAL, 1, 0, 60) + + return xi.effect.DARK_SEAL +end) + +-- Diabolic Eye: Remove extra duration and potency from merits and apply merit recast reduction +m:addOverride('xi.job_utils.dark_knight.useDiabolicEye', function(player, target, ability, action) + local recastReduction = player:getMerit(xi.merit.DIABOLIC_EYE) - 150 + action:setRecast(action:getRecast() - recastReduction) + + player:addStatusEffect(xi.effect.DIABOLIC_EYE, 20, 0, 180) + + return xi.effect.DIABOLIC_EYE +end) + return m diff --git a/modules/abyssea/sql/job_adjustments.sql b/modules/abyssea/sql/job_adjustments.sql index d52e6852fc1..a9a15a9c471 100644 --- a/modules/abyssea/sql/job_adjustments.sql +++ b/modules/abyssea/sql/job_adjustments.sql @@ -52,3 +52,33 @@ UPDATE spell_list SET castTime = 3000 WHERE name = 'blindna'; -- Cursna: Revert cast time from 1 to 3 seconds UPDATE spell_list SET castTime = 3000 WHERE name = 'cursna'; + +------------------------------------ +-- Dark Knight +-- Source: https://www.bg-wiki.com/ffxi/Version_Update_(02/13/2012) +------------------------------------ + +-- Arcane Circle: Revert recast from 5 to 10 minutes +UPDATE abilities SET recastTime = 600 WHERE name = 'arcane_circle'; + +-- Arcane Circle merit: Revert value to 20 seconds per level +UPDATE merits SET value = 20 WHERE name = 'arcane_circle_recast'; + +-- Weapon Bash: Revert recast from 3 to 5 minutes +UPDATE abilities SET recastTime = 300 WHERE name = 'weapon_bash'; + +-- Weapon Bash merit: Revert value to 10 seconds per level +UPDATE merits SET value = 10 WHERE name = 'weapon_bash_recast'; + +-- Dark Seal: Revert recast from 5 to 15 minutes +-- Source: https://www.bg-wiki.com/ffxi/Version_Update_(03/26/2012) +UPDATE abilities SET recastTime = 900 WHERE name = 'dark_seal'; + +-- Dark Seal merit: Revert value to 150 seconds per level +UPDATE merits SET value = 150 WHERE name = 'dark_seal'; + +-- Diabolic Eye: Revert recast from 5 to 15 minutes +UPDATE abilities SET recastTime = 900 WHERE name = 'diabolic_eye'; + +-- Diabolic Eye merit: Revert value to 150 seconds per level +UPDATE merits SET value = 150 WHERE name = 'diabolic_eye'; diff --git a/modules/rov/lua/job_adjustments.lua b/modules/rov/lua/job_adjustments.lua index cea0fd3ea2a..c74bac1fec4 100644 --- a/modules/rov/lua/job_adjustments.lua +++ b/modules/rov/lua/job_adjustments.lua @@ -6,7 +6,7 @@ ----------------------------------- require('modules/module_utils') ----------------------------------- -local m = Module:new('job_adjustments') +local m = Module:new('rov_job_adjustments') ----------------------------------- -- Monk @@ -105,4 +105,21 @@ end) -- effect:addMod(xi.mod.HASTE_MAGIC, -6000) -- end) +----------------------------------- +-- Dark Knight +----------------------------------- + +-- Dread Spikes: Revert duration from 3 minutes to 1 minute. +-- Source: https://forum.square-enix.com/ffxi/threads/48564-Sep-16-2015-%28JST%29-Version-Update +m:addOverride('xi.effects.dread_spikes.onEffectGain', function(target, effect) + super(target, effect) + effect:setDuration(60000) +end) + +-- TODO Absorb-STAT: Add decay tick and set 90 second duration to boost effects +-- TODO Drain II: Set duration of max HP boost to 60 seconds. +-- Source: +-- Decay Removal: http://forum.square-enix.com/ffxi/threads/46531-Mar-26-2015-%28JST%29-Version-Update +-- Duration Change: https://forum.square-enix.com/ffxi/threads/48564-Sep-16-2015-%28JST%29-Version-Update + return m diff --git a/modules/soa/lua/job_adjustments.lua b/modules/soa/lua/job_adjustments.lua new file mode 100644 index 00000000000..f88791fdb03 --- /dev/null +++ b/modules/soa/lua/job_adjustments.lua @@ -0,0 +1,26 @@ +----------------------------------- +-- Module: Job Adjustments (Seekers of Adoulin era) +-- Desc: Removes traits/abilities/effects that were added to jobs during the SoA era +----------------------------------- +require('modules/module_utils') +----------------------------------- +local m = Module:new('soa_job_adjustments') + +----------------------------------- +-- Dark Knight +----------------------------------- + +-- Last Resort: Reduces attack bonus from 25% to 15% +-- Source: https://forum.square-enix.com/ffxi/threads/46976-May-14-2015-%28JST%29-Version-Update +m:addOverride('xi.effects.last_resort.onEffectGain', function(target, effect) + local targetMerit = target:getMerit(xi.merit.LAST_RESORT_EFFECT) + + -- Merit effect + effect:addMod(xi.mod.ATTP, 15 + targetMerit) + effect:addMod(xi.mod.RATTP, 15 + targetMerit) + effect:addMod(xi.mod.DEFP, -15 - targetMerit) + + effect:addMod(xi.mod.TWOHAND_HASTE_ABILITY, target:getMod(xi.mod.DESPERATE_BLOWS) + target:getMerit(xi.merit.DESPERATE_BLOWS)) +end) + +return m diff --git a/modules/soa/sql/job_adjustments.sql b/modules/soa/sql/job_adjustments.sql new file mode 100644 index 00000000000..c7c6a9bd092 --- /dev/null +++ b/modules/soa/sql/job_adjustments.sql @@ -0,0 +1,12 @@ +------------------------------------ +-- Seekers of Adoulin Job SQL Adjustments +-- This module reverts relevant SQL tables for jobs to their pre-SoA values +------------------------------------ + +------------------------------------ +-- Dark Knight +-- Source: https://www.bg-wiki.com/ffxi/Version_Update_(04/29/2013) +------------------------------------ + +-- Desperate Blows: Revert job trait to be merit unlocked +UPDATE traits SET meritid = 2502, level = 75 WHERE name = 'desperate blows'; diff --git a/modules/wotg/lua/job_adjustments.lua b/modules/wotg/lua/job_adjustments.lua new file mode 100644 index 00000000000..326143ad29c --- /dev/null +++ b/modules/wotg/lua/job_adjustments.lua @@ -0,0 +1,19 @@ +----------------------------------- +-- Module: Job Adjustments (Wings of the Goddess Era) +-- Desc: Removes traits/abilities/effects that were added to jobs during the WotG era +----------------------------------- +require('modules/module_utils') +----------------------------------- +local m = Module:new('wotg_job_adjustments') + +----------------------------------- +-- Dark Knight +----------------------------------- + +-- Arcane Circle: Removes WotG resist/defense/attack circle mods +-- Source: https://www.bg-wiki.com/ffxi/Version_Update_(07/20/2009) +m:addOverride('xi.effects.arcane_circle.onEffectGain', function(target, effect) + effect:addMod(xi.mod.ARCANA_KILLER, effect:getPower()) +end) + +return m diff --git a/scripts/actions/abilities/dark_seal.lua b/scripts/actions/abilities/dark_seal.lua index b9d5736cb7c..c3f14a852a1 100644 --- a/scripts/actions/abilities/dark_seal.lua +++ b/scripts/actions/abilities/dark_seal.lua @@ -12,8 +12,8 @@ abilityObject.onAbilityCheck = function(player, target, ability) return 0, 0 end -abilityObject.onUseAbility = function(player, target, ability) - return xi.job_utils.dark_knight.useDarkSeal(player, target, ability) +abilityObject.onUseAbility = function(player, target, ability, action) + return xi.job_utils.dark_knight.useDarkSeal(player, target, ability, action) end return abilityObject diff --git a/scripts/actions/abilities/diabolic_eye.lua b/scripts/actions/abilities/diabolic_eye.lua index 1155a529d84..252bd66e158 100644 --- a/scripts/actions/abilities/diabolic_eye.lua +++ b/scripts/actions/abilities/diabolic_eye.lua @@ -12,8 +12,8 @@ abilityObject.onAbilityCheck = function(player, target, ability) return 0, 0 end -abilityObject.onUseAbility = function(player, target, ability) - return xi.job_utils.dark_knight.useDiabolicEye(player, target, ability) +abilityObject.onUseAbility = function(player, target, ability, action) + return xi.job_utils.dark_knight.useDiabolicEye(player, target, ability, action) end return abilityObject diff --git a/scripts/actions/abilities/weapon_bash.lua b/scripts/actions/abilities/weapon_bash.lua index 6c4cc01601a..64c6aae7141 100644 --- a/scripts/actions/abilities/weapon_bash.lua +++ b/scripts/actions/abilities/weapon_bash.lua @@ -12,8 +12,8 @@ abilityObject.onAbilityCheck = function(player, target, ability) return xi.job_utils.dark_knight.checkWeaponBash(player, target, ability) end -abilityObject.onUseAbility = function(player, target, ability) - return xi.job_utils.dark_knight.useWeaponBash(player, target, ability) +abilityObject.onUseAbility = function(player, target, ability, action) + return xi.job_utils.dark_knight.useWeaponBash(player, target, ability, action) end return abilityObject diff --git a/scripts/globals/job_utils/dark_knight.lua b/scripts/globals/job_utils/dark_knight.lua index cea84a43f31..bef4b2a0615 100644 --- a/scripts/globals/job_utils/dark_knight.lua +++ b/scripts/globals/job_utils/dark_knight.lua @@ -92,7 +92,7 @@ xi.job_utils.dark_knight.useConsumeMana = function(player, target, ability) return xi.effect.CONSUME_MANA end -xi.job_utils.dark_knight.useDarkSeal = function(player, target, ability) +xi.job_utils.dark_knight.useDarkSeal = function(player, target, ability, action) -- Power: Each merit level after the first reduces Dark Magic casting time by -10% (total of -40% bonus). -- Sub Power: Enhances Dark Seal effect by increasing duration of Dark Magic by 10% per merit level (total of 50% bonus). local power = player:getMerit(xi.merit.DARK_SEAL) - 10 @@ -103,7 +103,7 @@ xi.job_utils.dark_knight.useDarkSeal = function(player, target, ability) return xi.effect.DARK_SEAL end -xi.job_utils.dark_knight.useDiabolicEye = function(player, target, ability) +xi.job_utils.dark_knight.useDiabolicEye = function(player, target, ability, action) local power = 15 + player:getMerit(xi.merit.DIABOLIC_EYE) * 5 local duration = 180 + player:getMerit(xi.merit.DIABOLIC_EYE) * player:getMod(xi.mod.ENHANCES_DIABOLIC_EYE) @@ -150,21 +150,40 @@ xi.job_utils.dark_knight.useSouleater = function(player, target, ability) return xi.effect.SOULEATER end -xi.job_utils.dark_knight.useWeaponBash = function(player, target, ability) - -- Applying Weapon Bash stun. Rate is said to be near 100%, so let's say 99%. - if math.random(1, 100) <= 99 then - target:addStatusEffect(xi.effect.STUN, 1, 0, 6) - end - - -- Weapon Bash deals damage dependant of Dark Knight level +xi.job_utils.dark_knight.useWeaponBash = function(player, target, ability, action) + -- Damage local darkKnightLvl = utils.getActiveJobLevel(player, xi.job.DRK) - - -- Calculating and applying Weapon Bash damage - local jpValue = target:getJobPointLevel(xi.jp.WEAPON_BASH_EFFECT) - local damage = math.floor((darkKnightLvl + 11) / 4 + player:getMod(xi.mod.WEAPON_BASH) + jpValue * 10) - + local jpValue = target:getJobPointLevel(xi.jp.WEAPON_BASH_EFFECT) + local damage = math.floor((darkKnightLvl + 11) / 4 + player:getMod(xi.mod.WEAPON_BASH) + jpValue * 10) target:takeDamage(damage, player, xi.attackType.PHYSICAL, xi.damageType.BLUNT) target:updateEnmityFromDamage(player, damage) + -- Stun. + if + not xi.data.statusEffect.isTargetImmune(target, xi.effect.STUN, xi.element.THUNDER) and + not xi.data.statusEffect.isTargetResistant(player, target, xi.effect.STUN) and + not xi.data.statusEffect.isEffectNullified(target, xi.effect.STUN, 0) + then + local resistanceRate = xi.combat.magicHitRate.calculateResistRate(player, target, 0, 0, xi.skillRank.A_PLUS, xi.element.THUNDER, xi.mod.INT, xi.effect.STUN, 0) + if xi.data.statusEffect.isResistRateSuccessfull(xi.effect.STUN, resistanceRate, 0) then + target:addStatusEffect(xi.effect.STUN, 1, 0, math.random(2, 8) * resistanceRate) + end + end + + -- Animation. + local animationTable = + { + -- [weapon type] = animation ID, + [xi.skill.GREAT_SWORD ] = 201, + [xi.skill.GREAT_KATANA] = 201, + [xi.skill.GREAT_AXE ] = 202, + [xi.skill.SCYTHE ] = 202, + [xi.skill.STAFF ] = 202, + [xi.skill.POLEARM ] = 203, + } + + local animation = animationTable[player:getWeaponSkillType(xi.slot.MAIN)] or 0 + action:setAnimation(target:getID(), animation) + return damage end diff --git a/sql/status_effects.sql b/sql/status_effects.sql index 0900982edba..5ab22e5578d 100644 --- a/sql/status_effects.sql +++ b/sql/status_effects.sql @@ -374,7 +374,7 @@ INSERT INTO `status_effects` VALUES (341,'formless_strikes',4194336,0,0,0,0,0,0, INSERT INTO `status_effects` VALUES (342,'assassins_charge',4194340,0,0,0,0,0,0,0,0); INSERT INTO `status_effects` VALUES (343,'feint',4194336,0,0,0,0,0,0,0,0); INSERT INTO `status_effects` VALUES (344,'fealty',4194337,0,0,0,0,0,0,0,0); -INSERT INTO `status_effects` VALUES (345,'dark_seal',33,0,0,0,0,0,0,0,0); +INSERT INTO `status_effects` VALUES (345,'dark_seal',161,0,0,0,0,0,0,0,0); INSERT INTO `status_effects` VALUES (346,'diabolic_eye',4194336,0,0,0,0,0,0,0,0); INSERT INTO `status_effects` VALUES (347,'nightingale',4194336,0,0,0,0,0,0,0,0); INSERT INTO `status_effects` VALUES (348,'troubadour',4194336,0,0,0,0,0,0,0,0); diff --git a/sql/traits.sql b/sql/traits.sql index e0c4d20714b..c070b1bf3be 100644 --- a/sql/traits.sql +++ b/sql/traits.sql @@ -452,7 +452,7 @@ INSERT INTO `traits` VALUES (76,'ambush',6,75,1,0,0,'TOAU',2374); INSERT INTO `traits` VALUES (77,'iron will',7,75,1,0,0,'TOAU',2436); INSERT INTO `traits` VALUES (78,'guardian',7,75,1,0,0,'TOAU',2438); INSERT INTO `traits` VALUES (79,'muted soul',8,75,1,0,0,'TOAU',2500); -INSERT INTO `traits` VALUES (80,'desperate blows',8,15,1,906,500,'SOA',0); +INSERT INTO `traits` VALUES (80,'desperate blows',8,15,1,906,500,'TOAU',0); INSERT INTO `traits` VALUES (80,'desperate blows',8,30,2,906,1000,'SOA',0); INSERT INTO `traits` VALUES (80,'desperate blows',8,45,3,906,1500,'SOA',0); INSERT INTO `traits` VALUES (81,'beast affinity ',9,75,1,0,0,'TOAU',2564); diff --git a/src/map/utils/battleutils.cpp b/src/map/utils/battleutils.cpp index b3913cba55d..5c7b8a7dd8c 100644 --- a/src/map/utils/battleutils.cpp +++ b/src/map/utils/battleutils.cpp @@ -895,6 +895,8 @@ auto HandleSpikesDamage(CBattleEntity* PAttacker, CBattleEntity* PDefender, acti const int remainingDrain = PEffect->GetSubPower(); if (remainingDrain - abs(damage) <= 0) // power absorbed from Dread Spikes takes pre-MDT etc values { + spikesDamage = std::min(spikesDamage, remainingDrain); + Action->spikesParam = static_cast(spikesDamage); PDefender->StatusEffectContainer->DelStatusEffect(EFFECT_DREAD_SPIKES); } else