From bed3acfa48cadad70125e48f7a2b4a9563197a5b Mon Sep 17 00:00:00 2001 From: Critical <48370698+CriticalXI@users.noreply.github.com> Date: Fri, 20 Feb 2026 16:25:12 -0700 Subject: [PATCH] [lua, sql, c++][module] DRG Era Audit --- modules/abyssea/lua/job_adjustments.lua | 269 ++++++++++++++++++- modules/abyssea/sql/job_adjustments.sql | 38 +++ modules/rov/lua/job_adjustments.lua | 177 ++++++++++++ modules/rov/sql/job_adjustments.sql | 13 + modules/soa/lua/job_adjustments.lua | 58 ++++ modules/soa/sql/job_adjustments.sql | 31 +++ modules/wotg/lua/job_adjustments.lua | 18 ++ scripts/actions/abilities/deep_breathing.lua | 4 +- scripts/effects/spirit_surge.lua | 31 +-- scripts/enum/mod.lua | 1 + scripts/enum/msg.lua | 1 + scripts/globals/job_utils/dragoon.lua | 106 ++++---- scripts/globals/pets/wyvern.lua | 6 +- sql/abilities.sql | 4 +- sql/traits.sql | 18 +- src/map/ai/states/petskill_state.cpp | 4 +- src/map/modifier.h | 3 +- 17 files changed, 692 insertions(+), 90 deletions(-) diff --git a/modules/abyssea/lua/job_adjustments.lua b/modules/abyssea/lua/job_adjustments.lua index 2deb110f37a..9e1554764c8 100644 --- a/modules/abyssea/lua/job_adjustments.lua +++ b/modules/abyssea/lua/job_adjustments.lua @@ -122,7 +122,7 @@ m:addOverride('xi.job_utils.dark_knight.useLastResort', function(player, target, end) -- Dark Seal: Remove extra duration and cast speed from merits -m:addOverride('xi.effects.warriors_charge.onEffectGain', function(target, effect) +m:addOverride('xi.effects.dark_seal.onEffectGain', function(target, effect) -- Overwrites target:delStatusEffectSilent(xi.effect.DIVINE_EMBLEM) target:delStatusEffectSilent(xi.effect.DIVINE_SEAL) @@ -326,4 +326,271 @@ m:addOverride('xi.effects.flashy_shot.onEffectGain', function(target, effect) effect:addMod(xi.mod.RA_IGNORE_LVL_DIFF, 1) end) +----------------------------------- +-- Dragoon +----------------------------------- + +-- Ancient 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.dragoon.useAncientCircle', function(player, target, ability) + local duration = 60 + player:getMod(xi.mod.ANCIENT_CIRCLE_DURATION) + local power = 15 + + if player:getMainJob() ~= xi.job.DRG then + power = 5 + end + + power = power + player:getMod(xi.mod.ANCIENT_CIRCLE_POTENCY) + + ability:setMsg(xi.msg.basic.USES_ABILITY_FORTIFIED_DRAGONS) + + target:addStatusEffect(xi.effect.ANCIENT_CIRCLE, { power = power, duration = duration, origin = player }) + + return xi.effect.ANCIENT_CIRCLE +end) + +-- Spirit Surge: Revert haste to be HASTE_MAGIC instead of HASTE_ABILITY +-- Also removes ATK and DEF bonuses which are removed in SoA module +-- Source: https://www.bg-wiki.com/ffxi/Version_Update_(02/13/2012) +m:addOverride('xi.effects.spirit_surge.onEffectGain', function(target, effect) + effect:addMod(xi.mod.HP, effect:getPower()) + target:updateHealth() + + effect:addMod(xi.mod.STR, effect:getSubPower()) + effect:addMod(xi.mod.ACC, 50) + effect:addMod(xi.mod.HASTE_MAGIC, 2500) + effect:addMod(xi.mod.MAIN_DMG_RATING, target:getJobPointLevel(xi.jp.SPIRIT_SURGE_EFFECT)) +end) + +-- Spirit Surge + Super Jump: Revert enmity reduction from 100% to 50% +-- Source: https://www.bg-wiki.com/ffxi/Version_Update_(03/26/2012) +m:addOverride('xi.job_utils.dragoon.superJumpSurgeEffect', function(player, target) + if player:hasStatusEffect(xi.effect.SPIRIT_SURGE) then + local minDistance = 9999 + local closestPartyMember = nil + + -- Find the closest party member + local party = player:getPartyWithTrusts() + for _, member in pairs(party) do + local distance = member:checkDistance(player) + if + member:getID() ~= player:getID() and + not member:isDead() and + (distance < minDistance or closestPartyMember == nil) + then + closestPartyMember = member + minDistance = distance + end + end + + -- TODO: verify conditions for how close the dragoon needs to be to the mob, if at all + if + closestPartyMember and + closestPartyMember:isBehind(player) and + (player:checkDistance(target) < closestPartyMember:checkDistance(target)) + then + if target:isMob() then + target:lowerEnmity(closestPartyMember, 50) + end + end + end +end) + +-- Deep Breathing: Apply merit recast reduction instead of breath power bonus +-- Source: https://www.bg-wiki.com/ffxi/Version_Update_(03/26/2012) +m:addOverride('xi.job_utils.dragoon.useDeepBreathing', function(player, target, ability, action) + local recastReduction = player:getMerit(xi.merit.DEEP_BREATHING) - 150 + action:setRecast(action:getRecast() - recastReduction) + + local wyvern = player:getPet() + + if wyvern and wyvern:getPetID() == xi.petId.WYVERN then + wyvern:addStatusEffect(xi.effect.MAGIC_ATK_BOOST, { duration = 180, origin = player }) + end +end) + +-- Deep Breathing Bonus: Remove merit scaling, use flat base bonus only +m:addOverride('xi.job_utils.dragoon.getDeepBreathingBonus', function(wyvern, master, isHealing) + local bonus = 0 + local hadEffect = wyvern:hasStatusEffect(xi.effect.MAGIC_ATK_BOOST) + + if hadEffect then + bonus = isHealing and 37.5 or 0.75 + + wyvern:delStatusEffect(xi.effect.MAGIC_ATK_BOOST) + end + + return bonus +end) + +-- Spirit Link: Revert TP transfer from wyvern to master and removes regen +-- TP Transfer Source: https://www.bg-wiki.com/ffxi/Version_Update_(06/21/2010) +-- Regen Source: https://www.bg-wiki.com/ffxi/Version_Update_(03/26/2012) +m:addOverride('xi.job_utils.dragoon.useSpiritLink', function(player, target, ability, action) + local wyvern = player:getPet() + local playerHP = player:getHP() + + xi.job_utils.dragoon.checkForRemovableEffectsOnSpiritLink(player, wyvern) + + -- Empathy: copy status effects and grant wyvern EXP + xi.job_utils.dragoon.applyEmpathyBonus(player, wyvern) + + -- Pre-Abyssea: No TP transfer from wyvern to master + + -- Calculate drain amount. + local drainAmount = 0 + + if wyvern:getHP() ~= wyvern:getMaxHP() then + drainAmount = (math.random(25, 35) / 100) * playerHP + drainAmount = drainAmount * (1 - (0.01 * player:getJobPointLevel(xi.jp.SPIRIT_LINK_EFFECT))) + end + + -- Handle Stoneskin. + local stoneskinPower = 0 + + if player:hasStatusEffect(xi.effect.STONESKIN) then + stoneskinPower = player:getMod(xi.mod.STONESKIN) + + -- If stoneskin is more powerfull than the amount to be drained. + if stoneskinPower > drainAmount then + local effect = player:getStatusEffect(xi.effect.STONESKIN) + effect:setPower(effect:getPower() - drainAmount) -- Fixes the status effect so when it ends it uses the new power instead of old. + player:delMod(xi.mod.STONESKIN, drainAmount) -- Removes the amount from the mod. + + -- If stoneskin is as powerful or less than the amount to be drained. + else + player:delStatusEffect(xi.effect.STONESKIN) + end + end + + -- Handle master damage and pet healing. + player:takeDamage(drainAmount - stoneskinPower) + + -- Pre-September 2015: Healing formula includes MND and wyvern level components. + -- Source: https://wiki.ffo.jp/html/1897.html https://www.bg-wiki.com/ffxi/Spirit_Link + local playerMND = player:getStat(xi.mod.MND) + local alpha = wyvern:getMainLvl() * 0.7 + local healPet = (drainAmount + playerMND + alpha) * 2 + + if player:getEquipID(xi.slot.HEAD) == xi.item.DRACHEN_ARMET_P1 then + healPet = healPet + 15 + end + + -- Spirit Link is self target but reports effect on Wyvern. + action:ID(player:getID(), wyvern:getID()) + + return wyvern:addHP(healPet) -- add the hp to wyvern +end) + +-- Empathy: Revert Spirit Link granting wyvern 200 EXP per Empathy merit level +-- Source: https://www.bg-wiki.com/ffxi/Version_Update_(05/15/2012) +m:addOverride('xi.job_utils.dragoon.applyEmpathyBonus', function(player, wyvern) + local empathyTotal = player:getMerit(xi.merit.EMPATHY) + + if empathyTotal > 0 then + local validEffects = {} + local i = 0 + local effects = player:getStatusEffects() + local copyi = 0 + + for _, effect in pairs(effects) do + if effect:hasEffectFlag(xi.effectFlag.EMPATHY) then + validEffects[i + 1] = effect + i = i + 1 + end + end + + if i < empathyTotal then + empathyTotal = i + elseif i > empathyTotal then + validEffects = xi.job_utils.dragoon.cutEmpathyEffectTable(validEffects, i, empathyTotal) + end + + local copyEffect = nil + while copyi < empathyTotal do + copyEffect = validEffects[copyi + 1] + if wyvern:hasStatusEffect(copyEffect:getEffectType()) then + wyvern:delStatusEffectSilent(copyEffect:getEffectType()) + end + + wyvern:copyStatusEffect(copyEffect) + copyi = copyi + 1 + end + end +end) + +-- Wyvern Spawn: Revert innate -40% DT and reduce status breath table +-- DT Source: https://www.bg-wiki.com/ffxi/Version_Update_(09/19/2011) +-- Status Breath Source: https://www.bg-wiki.com/ffxi/Version_Update_(02/13/2012) +m:addOverride('xi.pets.wyvern.onMobSpawn', function(mob) + super(mob) + + local master = mob:getMaster() + + -- Revert innate -40% DT + mob:addMod(xi.mod.DMG, 4000) + + -- Determine if wyvern is DEFENSIVE type (status breath on WS) + local defensiveJobs = + { + [xi.job.WHM] = true, + [xi.job.BLM] = true, + [xi.job.RDM] = true, + [xi.job.SMN] = true, + [xi.job.BLU] = true, + [xi.job.SCH] = true, + [xi.job.GEO] = true, + } + + if defensiveJobs[master:getSubJob()] then + -- Replace WS listener with pre-2012 status breath table + master:removeListener('PET_WYVERN_WS') + + local removeBreathTable = + { + { 40, xi.jobAbility.REMOVE_PARALYSIS, { xi.effect.PARALYSIS } }, + { 20, xi.jobAbility.REMOVE_BLINDNESS, { xi.effect.BLINDNESS } }, + { 1, xi.jobAbility.REMOVE_POISON, { xi.effect.POISON } }, + } + + local breathRange = 14 + + local function doStatusBreath(target, player) + local wyvern = player:getPet() + + for _, v in pairs(removeBreathTable) do + local minLevel = v[1] + local ability = v[2] + local statuses = v[3] + + if wyvern:getMainLvl() >= minLevel then + for _, effect in pairs(statuses) do + if + target:hasStatusEffect(effect) and + wyvern:checkDistance(target) <= breathRange + then + wyvern:usePetAbility(ability, target) + + return true + end + end + end + end + + return false + end + + master:addListener('WEAPONSKILL_USE', 'PET_WYVERN_WS', function(player, target, skillid) + if not doStatusBreath(player, player) then + local party = player:getParty() + for _, member in pairs(party) do + if doStatusBreath(member, player) then + break + end + end + end + end) + end +end) + return m diff --git a/modules/abyssea/sql/job_adjustments.sql b/modules/abyssea/sql/job_adjustments.sql index 3d6e79729f0..dff72cc8de2 100644 --- a/modules/abyssea/sql/job_adjustments.sql +++ b/modules/abyssea/sql/job_adjustments.sql @@ -187,3 +187,41 @@ UPDATE spell_list SET castTime = 4000 WHERE name = 'tonko_ichi'; -- Monomi: Ichi: Revert cast time from 1.5 to 4 seconds UPDATE spell_list SET castTime = 4000 WHERE name = 'monomi_ichi'; + +----------------------------------- +-- Dragoon +-- Source: https://www.bg-wiki.com/ffxi/Version_Update_(02/13/2012) +----------------------------------- + +-- Jump: Revert recast from 1 minute to 1.5 minutes +UPDATE abilities SET recastTime = 90 WHERE name = 'jump'; + +-- Jump merit: Revert value from 2 seconds per level to 3 seconds per level +UPDATE merits SET value = 3 WHERE name = 'jump_recast'; + +-- High Jump: Revert recast from 2 minutes to 3 minutes +UPDATE abilities SET recastTime = 180 WHERE name = 'high_jump'; + +-- High Jump merit: Revert value from 4 seconds per level to 6 seconds per level +UPDATE merits SET value = 6 WHERE name = 'high_jump_recast'; + +-- Super Jump: Revert range from 12.5 to 9.5 yalms +UPDATE abilities SET `range` = 9.5 WHERE name = 'super_jump'; + +-- Spirit Link: Revert recast from 1.5 minutes to 3 minutes +UPDATE abilities SET recastTime = 180 WHERE name = 'spirit_link'; + +-- Spirit Link merit: Revert value from 4 seconds per level to 6 seconds per level +UPDATE merits SET value = 6 WHERE name = 'spirit_link_recast'; + +-- Ancient Circle: Revert recast from 5 to 10 minutes +UPDATE abilities SET recastTime = 600 WHERE name = 'ancient_circle'; + +-- Ancient Circle merit: Revert value from 10 to 20 seconds per level +UPDATE merits SET value = 20 WHERE name = 'ancient_circle_recast'; + +-- Deep Breathing: Revert recast from 5 to 15 minutes +UPDATE abilities SET recastTime = 900 WHERE name = 'deep_breathing'; + +-- Deep Breathing merit: Revert value to 150 seconds per level +UPDATE merits SET value = 150 WHERE name = 'deep_breathing'; diff --git a/modules/rov/lua/job_adjustments.lua b/modules/rov/lua/job_adjustments.lua index e4799cb936e..e9457146eda 100644 --- a/modules/rov/lua/job_adjustments.lua +++ b/modules/rov/lua/job_adjustments.lua @@ -207,4 +207,181 @@ for _, entry in ipairs(sanSpellOverrides) do end) end +----------------------------------- +-- Dragoon +----------------------------------- + +-- Healing Breath: Revert to consume TP and formula based on TP usage +-- Source: https://forum.square-enix.com/ffxi/threads/52969 +m:addOverride('xi.job_utils.dragoon.useHealingBreath', function(wyvern, target, skill, action) + local healingBreathTable = + { + -- { base, multiplier } + [xi.jobAbility.HEALING_BREATH] = { 8, 25 }, + [xi.jobAbility.HEALING_BREATH_II] = { 24, 38 }, + [xi.jobAbility.HEALING_BREATH_III] = { 42, 45 }, + [xi.jobAbility.HEALING_BREATH_IV] = { 60, 53 }, + } + + local master = wyvern:getMaster() + local deepMult = xi.job_utils.dragoon.getDeepBreathingBonus(wyvern, master, true) + local jobPointBonus = master:getJobPointLevel(xi.jp.WYVERN_BREATH_EFFECT) * 10 + local breathAugmentsBonus = 1 + master:getMod(xi.mod.UNCAPPED_WYVERN_BREATH) / 100 + local gear = master:getMod(xi.mod.WYVERN_BREATH) -- Master gear that enhances breath + local base = healingBreathTable[skill:getID()][1] + local baseMultiplier = healingBreathTable[skill:getID()][2] + + -- TP bonus: wyvern TP enhances healing multiplier + local tpBonus = math.floor(wyvern:getTP() / 200) / 1.165 + + -- gear cap of 64/256 in multiplier + local multiplier = (baseMultiplier + math.min(gear, 64) + math.floor(deepMult) + tpBonus) / 256 + local curePower = math.floor(wyvern:getMaxHP() * multiplier) + base + jobPointBonus * breathAugmentsBonus + local totalHPRestored = target:addHP(curePower) + + -- Consume wyvern TP after calculating breath power + wyvern:setTP(0) + + skill:setMsg(xi.msg.basic.JA_RECOVERS_HP_2) + + -- Also cure the Wyvern if Spirit Bond is up + if master:hasStatusEffect(xi.effect.SPIRIT_BOND) then + local totalWyvernHPRestored = wyvern:addHP(curePower) + + action:addAdditionalTarget(wyvern:getID()) + action:setAnimation(wyvern:getID(), action:getAnimation(target:getID())) + action:messageID(wyvern:getID(), xi.msg.basic.SELF_HEAL_SECONDARY) + action:param(wyvern:getID(), totalWyvernHPRestored) + end + + if master:getMod(xi.mod.ENHANCES_STRAFE) > 0 then + local strafeTP = master:getMerit(xi.merit.STRAFE_EFFECT) * 50 + wyvern:addTP(strafeTP) -- add 50 TP per merit with augmented AF2 legs + end + + return totalHPRestored +end) + +-- Spirit Link: Revert to pre-September 2015 healing formula. +-- Source: https://forum.square-enix.com/ffxi/threads/48564-Sep-16-2015-%28JST%29-Version-Update +-- Formula taken from: https://wiki.ffo.jp/html/15079.html +m:addOverride('xi.job_utils.dragoon.useSpiritLink', function(player, target, ability, action) + local wyvern = player:getPet() + local playerHP = player:getHP() + local petTP = wyvern:getTP() + local regenAmount = player:getMainLvl() / 3 -- level/3 tic regen + + xi.job_utils.dragoon.checkForRemovableEffectsOnSpiritLink(player, wyvern) + + -- Empathy: copy status effects and grant wyvern EXP + xi.job_utils.dragoon.applyEmpathyBonus(player, wyvern) + + wyvern:addStatusEffect(xi.effect.REGEN, { power = regenAmount, duration = 90, origin = player, tick = 3 }) -- 90 seconds of regen + player:addTP(petTP / 2) -- add half wyvern tp to you + wyvern:delTP(petTP / 2) -- remove half tp from wyvern + + -- Calculate drain amount. + local drainamount = 0 + + if wyvern:getHP() ~= wyvern:getMaxHP() then + drainamount = (math.random(25, 35) / 100) * playerHP + drainamount = drainamount * (1 - (0.01 * player:getJobPointLevel(xi.jp.SPIRIT_LINK_EFFECT))) + end + + -- Handle Stoneskin. + local stoneskinPower = 0 + + if player:hasStatusEffect(xi.effect.STONESKIN) then + stoneskinPower = player:getMod(xi.mod.STONESKIN) + + -- If stoneskin is more powerfull than the amount to be drained. + if stoneskinPower > drainamount then + local effect = player:getStatusEffect(xi.effect.STONESKIN) + effect:setPower(effect:getPower() - drainamount) -- Fixes the status effect so when it ends it uses the new power instead of old. + player:delMod(xi.mod.STONESKIN, drainamount) -- Removes the amount from the mod. + + -- If stoneskin is as powerful or less than the amount to be drained. + else + player:delStatusEffect(xi.effect.STONESKIN) + end + end + + -- Handle master damage and pet healing. + player:takeDamage(drainamount - stoneskinPower) + + local playerMND = player:getStat(xi.mod.MND) + local alpha = wyvern:getMainLvl() * 0.7 + local healPet = (drainamount + playerMND + alpha) * 2 + + if player:getEquipID(xi.slot.HEAD) == xi.item.DRACHEN_ARMET_P1 then + healPet = healPet + 15 + end + + -- Spirit Link is self target but reports effect on Wyvern. + action:ID(player:getID(), wyvern:getID()) + + return wyvern:addHP(healPet) -- add the hp to wyvern +end) + +-- Wyvern EXP: Revert WS Damage bonus from wyvern level-ups +-- Source: https://forum.square-enix.com/ffxi/threads/55997-October.-10-2019-%28JST%29-Version-Update +m:addOverride('xi.job_utils.dragoon.addWyvernExp', function(player, exp) + local wyvern = player:getPet() + local prevExp = wyvern:getLocalVar('wyvern_exp') + local numLevelUps = 0 + + if prevExp < 1000 then + local currentExp = exp + if prevExp + currentExp > 1000 then + currentExp = 1000 - prevExp + end + + numLevelUps = math.floor((prevExp + currentExp) / 200) - math.floor(prevExp / 200) + + if numLevelUps ~= 0 then + local wyvernAttributeIncreaseEffectJP = player:getJobPointLevel(xi.jp.WYVERN_ATTR_BONUS) + local wyvernBonusDA = player:getMod(xi.mod.WYVERN_ATTRIBUTE_DA) + + wyvern:addMod(xi.mod.ACC, 6 * numLevelUps) + wyvern:addMod(xi.mod.HPP, 6 * numLevelUps) + wyvern:addMod(xi.mod.ATTP, 5 * numLevelUps) + + wyvern:updateHealth() + wyvern:setHP(wyvern:getMaxHP()) + + player:messageBasic(xi.msg.basic.STATUS_INCREASED, 0, 0, wyvern) + + player:addMod(xi.mod.ATT, wyvernAttributeIncreaseEffectJP * numLevelUps) + player:addMod(xi.mod.DEF, wyvernAttributeIncreaseEffectJP * numLevelUps) + player:addMod(xi.mod.ATTP, 4 * numLevelUps) + player:addMod(xi.mod.DEFP, 4 * numLevelUps) + player:addMod(xi.mod.HASTE_ABILITY, 200 * numLevelUps) + player:addMod(xi.mod.DOUBLE_ATTACK, wyvernBonusDA * numLevelUps) + end + + wyvern:setLocalVar('wyvern_exp', prevExp + exp) + wyvern:setLocalVar('level_Ups', wyvern:getLocalVar('level_Ups') + numLevelUps) + end + + return numLevelUps +end) + +-- Wyvern Level Removal: Match addWyvernExp by omitting ALL_WSDMG_ALL_HITS +m:addOverride('xi.pets.wyvern.removeWyvernLevels', function(mob) + local master = mob:getMaster() + local numLvls = mob:getLocalVar('level_Ups') + + if numLvls ~= 0 then + local wyvernAttributeIncreaseEffectJP = master:getJobPointLevel(xi.jp.WYVERN_ATTR_BONUS) + local wyvernBonusDA = master:getMod(xi.mod.WYVERN_ATTRIBUTE_DA) + + master:delMod(xi.mod.ATT, wyvernAttributeIncreaseEffectJP * numLvls) + master:delMod(xi.mod.DEF, wyvernAttributeIncreaseEffectJP * numLvls) + master:delMod(xi.mod.ATTP, 4 * numLvls) + master:delMod(xi.mod.DEFP, 4 * numLvls) + master:delMod(xi.mod.HASTE_ABILITY, 200 * numLvls) + master:delMod(xi.mod.DOUBLE_ATTACK, wyvernBonusDA * numLvls) + end +end) + return m diff --git a/modules/rov/sql/job_adjustments.sql b/modules/rov/sql/job_adjustments.sql index b1d2cd9f75f..767c9e32be9 100644 --- a/modules/rov/sql/job_adjustments.sql +++ b/modules/rov/sql/job_adjustments.sql @@ -65,3 +65,16 @@ UPDATE merits SET upgrade = 0 WHERE name = 'yonin_effect'; UPDATE merits SET upgrade = 0 WHERE name = 'innin_effect'; UPDATE merits SET upgrade = 0 WHERE name = 'nin_magic_accuracy'; UPDATE merits SET upgrade = 0 WHERE name = 'nin_magic_attack'; + +------------------------------------ +-- Dragoon +-- Source: https://forum.square-enix.com/ffxi/threads/54901-January.-10-2019-%28JST%29-Version-Update +------------------------------------ + +-- Jump / Spirit Jump: Revert to share a cooldown +UPDATE abilities SET recastId = 158 WHERE name = 'jump'; +UPDATE abilities SET recastId = 158 WHERE name = 'spirit_jump'; + +-- High Jump / Soul Jump: Revert to share a cooldown +UPDATE abilities SET recastId = 159 WHERE name = 'high_jump'; +UPDATE abilities SET recastId = 159 WHERE name = 'soul_jump'; diff --git a/modules/soa/lua/job_adjustments.lua b/modules/soa/lua/job_adjustments.lua index 6f390eecf2d..1aceda51400 100644 --- a/modules/soa/lua/job_adjustments.lua +++ b/modules/soa/lua/job_adjustments.lua @@ -123,4 +123,62 @@ end) -- Tonko Ni: 600 seconds -> 300 seconds -- Monomi Ichi: 420 seconds -> 180 seconds +----------------------------------- +-- Dragoon +----------------------------------- + +-- Spirit Surge: Removes ATK and DEF bonuses +-- Source: https://forum.square-enix.com/ffxi/threads/44090-Sep-9-2014-%28JST%29-Version-Update +m:addOverride('xi.effects.spirit_surge.onEffectGain', function(target, effect) + effect:addMod(xi.mod.HP, effect:getPower()) + target:updateHealth() + + effect:addMod(xi.mod.STR, effect:getSubPower()) + effect:addMod(xi.mod.ACC, 50) + effect:addMod(xi.mod.HASTE_ABILITY, 2500) + effect:addMod(xi.mod.MAIN_DMG_RATING, target:getJobPointLevel(xi.jp.SPIRIT_SURGE_EFFECT)) +end) + +-- Wyvern Breath: Show readying animation to match the reverted 3-second prepare time +-- Source: https://forum.square-enix.com/ffxi/threads/44090-Sep-9-2014-%28JST%29-Version-Update +m:addOverride('xi.pets.wyvern.onMobSpawn', function(mob) + super(mob) + + mob:addMod(xi.mod.WYVERN_SHOW_READYING, 1) +end) + +-- Wyvern Levelup: Remove player stat transfers from wyvern levelups +-- Source: https://www.bg-wiki.com/ffxi/Version_Update_(04/29/2013) +m:addOverride('xi.job_utils.dragoon.addWyvernExp', function(player, exp) + local wyvern = player:getPet() + local prevExp = wyvern:getLocalVar('wyvern_exp') + local numLevelUps = 0 + + if prevExp < 1000 then + -- cap exp at 1000 to prevent wyvern leveling up many times from large exp awards + local currentExp = exp + if prevExp + currentExp > 1000 then + currentExp = 1000 - prevExp + end + + numLevelUps = math.floor((prevExp + currentExp) / 200) - math.floor(prevExp / 200) + + if numLevelUps ~= 0 then + wyvern:addMod(xi.mod.ACC, 6 * numLevelUps) + wyvern:addMod(xi.mod.HPP, 6 * numLevelUps) + wyvern:addMod(xi.mod.ATTP, 5 * numLevelUps) + + wyvern:updateHealth() + wyvern:setHP(wyvern:getMaxHP()) + + player:messageBasic(xi.msg.basic.STATUS_INCREASED, 0, 0, wyvern) + end + + wyvern:setLocalVar('wyvern_exp', prevExp + exp) + wyvern:setLocalVar('level_Ups', wyvern:getLocalVar('level_Ups') + numLevelUps) + end + + return numLevelUps +end) + return m diff --git a/modules/soa/sql/job_adjustments.sql b/modules/soa/sql/job_adjustments.sql index ec37b186a43..a142140a2c5 100644 --- a/modules/soa/sql/job_adjustments.sql +++ b/modules/soa/sql/job_adjustments.sql @@ -54,3 +54,34 @@ UPDATE abilities SET recastTime = 900 WHERE name = 'sange'; -- Sange merit: Revert value from 25 ranged accuracy to 150 seconds recast reduction UPDATE merits SET value = 150 WHERE name = 'sange'; + +------------------------------------ +-- Dragoon +-- Source: https://forum.square-enix.com/ffxi/threads/44090-Sep-9-2014-%28JST%29-Version-Update +------------------------------------ + +-- Strafe: Revert from level based trait to merit unlocked at 75 +UPDATE traits SET meritid = 2886, level = 75, value = 0 WHERE name = 'strafe'; + +-- Strafe merit: Revert value from 10 to 5 per upgrade +UPDATE merits SET value = 5 WHERE name = 'strafe_effect'; + +-- Wyvern Breath: Revert activation time from 1 second to 3 seconds +-- TODO: Revert skill prepare animation to display skill ready spikes +UPDATE pet_skills SET pet_prepare_time = 3000 WHERE pet_skill_name IN ( + 'healing_breath', + 'healing_breath_ii', + 'healing_breath_iii', + 'healing_breath_iv', + 'remove_poison', + 'remove_blindness', + 'remove_paralysis', + 'remove_curse', + 'remove_disease', + 'flame_breath', + 'frost_breath', + 'gust_breath', + 'sand_breath', + 'lightning_breath', + 'hydro_breath' +); diff --git a/modules/wotg/lua/job_adjustments.lua b/modules/wotg/lua/job_adjustments.lua index 54795020a78..e2954539394 100644 --- a/modules/wotg/lua/job_adjustments.lua +++ b/modules/wotg/lua/job_adjustments.lua @@ -51,4 +51,22 @@ m:addOverride('xi.job_utils.ninja.useMijinGakure', function(player, target, abil return dmg end) +----------------------------------- +-- Dragoon +----------------------------------- + +-- Wyvern: Revert experience points Wyvern system +-- Source: https://www.bg-wiki.com/ffxi/Version_Update_(03/11/2008) +m:addOverride('xi.job_utils.dragoon.addWyvernExp', function(player, exp) + return 0 +end) + +-- Wyvern Spawn: Remove EXPERIENCE_POINTS listener that feeds wyvern EXP system +m:addOverride('xi.pets.wyvern.onMobSpawn', function(mob) + super(mob) + + local master = mob:getMaster() + master:removeListener('PET_WYVERN_EXP') +end) + return m diff --git a/scripts/actions/abilities/deep_breathing.lua b/scripts/actions/abilities/deep_breathing.lua index b1722b4df01..ed34542c91d 100644 --- a/scripts/actions/abilities/deep_breathing.lua +++ b/scripts/actions/abilities/deep_breathing.lua @@ -12,8 +12,8 @@ abilityObject.onAbilityCheck = function(player, target, ability) return xi.job_utils.dragoon.abilityCheckDeepBreathing(player, target, ability) end -abilityObject.onUseAbility = function(player, target, ability) - return xi.job_utils.dragoon.useDeepBreathing(player, target, ability) +abilityObject.onUseAbility = function(player, target, ability, action) + return xi.job_utils.dragoon.useDeepBreathing(player, target, ability, action) end return abilityObject diff --git a/scripts/effects/spirit_surge.lua b/scripts/effects/spirit_surge.lua index e90ed33433d..b3b7e156ff1 100644 --- a/scripts/effects/spirit_surge.lua +++ b/scripts/effects/spirit_surge.lua @@ -8,48 +8,31 @@ local effectObject = {} effectObject.onEffectGain = function(target, effect) -- The dragoon's MAX HP increases by % of wyvern MaxHP - target:addMod(xi.mod.HP, effect:getPower()) + effect:addMod(xi.mod.HP, effect:getPower()) target:updateHealth() -- The dragoon gets a Strength boost relative to his level - target:addMod(xi.mod.STR, effect:getSubPower()) + effect:addMod(xi.mod.STR, effect:getSubPower()) -- The dragoon gets a 50 Accuracy boost - target:addMod(xi.mod.ACC, 50) + effect:addMod(xi.mod.ACC, 50) -- Wyvern levelup bonuses appear to be transferred as if the wyvern was max level: -- Does this also give the 10% all hits WSD and the 15% DA with job point gifts? - target:addMod(xi.mod.ATTP, 25) - target:addMod(xi.mod.DEFP, 25) + effect:addMod(xi.mod.ATTP, 25) + effect:addMod(xi.mod.DEFP, 25) -- The dragoon gets 25% Haste (see http://wiki.bluegartr.com/bg/Job_Ability_Haste for haste calculation) - target:addMod(xi.mod.HASTE_ABILITY, 2500) + effect:addMod(xi.mod.HASTE_ABILITY, 2500) -- DMG + 1 * JP - target:addMod(xi.mod.MAIN_DMG_RATING, target:getJobPointLevel(xi.jp.SPIRIT_SURGE_EFFECT)) + effect:addMod(xi.mod.MAIN_DMG_RATING, target:getJobPointLevel(xi.jp.SPIRIT_SURGE_EFFECT)) end effectObject.onEffectTick = function(target, effect) end effectObject.onEffectLose = function(target, effect) - -- The dragoon's MAX HP returns to normal - target:delMod(xi.mod.HP, effect:getPower()) - - -- The dragoon loses the Strength boost - target:delMod(xi.mod.STR, effect:getSubPower()) - - -- The dragoon loses the 50 Accuracy boost - target:delMod(xi.mod.ACC, 50) - - -- The dragoon loses 25% Haste - target:delMod(xi.mod.HASTE_ABILITY, 2500) - - -- Remove wyvern levelup bonuses - target:delMod(xi.mod.ATTP, 25) - target:delMod(xi.mod.DEFP, 25) - - target:delMod(xi.mod.MAIN_DMG_RATING, target:getJobPointLevel(xi.jp.SPIRIT_SURGE_EFFECT)) end return effectObject diff --git a/scripts/enum/mod.lua b/scripts/enum/mod.lua index 84c47401b76..bb922421a9e 100644 --- a/scripts/enum/mod.lua +++ b/scripts/enum/mod.lua @@ -569,6 +569,7 @@ xi.mod = -- Dragoon WYVERN_LVL_BONUS = 1043, -- Wyvern: Lv.+ (Increases wyvern's base level above 99) + WYVERN_SHOW_READYING = 1195, -- Pet shows readying animation instead of suppressing it (e.g., wyvern breath) -- Summoner AVATAR_LVL_BONUS = 1040, -- Avatar: Lv. ###/+ (Increases all avatar's base level above 99) diff --git a/scripts/enum/msg.lua b/scripts/enum/msg.lua index b90459823bf..b3a76ce0fed 100644 --- a/scripts/enum/msg.lua +++ b/scripts/enum/msg.lua @@ -181,6 +181,7 @@ xi.msg.basic = -- "Fortified against" messages FORTIFIED_DEMONS = 149, -- is fortified against demons. + USES_ABILITY_FORTIFIED_DRAGONS = 150, -- uses . is fortified against dragons. FORTIFIED_DRAGONS = 151, -- is fortified against dragons. FORTIFIED_UNDEAD = 286, -- is fortified against undead. FORTIFIED_ARCANA = 287, -- is fortified against arcana. diff --git a/scripts/globals/job_utils/dragoon.lua b/scripts/globals/job_utils/dragoon.lua index 6b3805273b7..b9263471aec 100644 --- a/scripts/globals/job_utils/dragoon.lua +++ b/scripts/globals/job_utils/dragoon.lua @@ -94,7 +94,7 @@ local function performWSJump(player, target, action, params, abilityID) return damage, totalHits end -local function cutEmpathyEffectTable(validEffects, i, maxCount) +xi.job_utils.dragoon.cutEmpathyEffectTable = function(validEffects, i, maxCount) local delindex = 1 while maxCount < i do @@ -223,6 +223,8 @@ xi.job_utils.dragoon.useAncientCircle = function(player, target, ability) power = power + player:getMod(xi.mod.ANCIENT_CIRCLE_POTENCY) + ability:setMsg(xi.msg.basic.USES_ABILITY_FORTIFIED_DRAGONS) + target:addStatusEffect(xi.effect.ANCIENT_CIRCLE, { power = power, duration = duration, origin = player }) return xi.effect.ANCIENT_CIRCLE @@ -250,7 +252,7 @@ xi.job_utils.dragoon.useJump = function(player, target, ability, action) return damage end -local function checkForRemovableEffectsOnSpiritLink(player, wyvern) +xi.job_utils.dragoon.checkForRemovableEffectsOnSpiritLink = function(player, wyvern) -- Removes all DoTs, all at once. -- Would this be better as an DoT effect flag? -- https://www.ffxiah.com/forum/topic/44396/sigurds-descendants-the-art-of-dragon-slaying/108/#3646578 @@ -318,15 +320,7 @@ local function checkForRemovableEffectsOnSpiritLink(player, wyvern) end end -xi.job_utils.dragoon.useSpiritLink = function(player, target, ability, action) - local wyvern = player:getPet() - local playerHP = player:getHP() - local petTP = wyvern:getTP() - local regenAmount = player:getMainLvl() / 3 -- level/3 tic regen - - checkForRemovableEffectsOnSpiritLink(player, wyvern) - - -- Empathy copying +xi.job_utils.dragoon.applyEmpathyBonus = function(player, wyvern) local empathyTotal = player:getMerit(xi.merit.EMPATHY) -- Add wyvern levels to the tune of 200 per empathy merit @@ -348,7 +342,7 @@ xi.job_utils.dragoon.useSpiritLink = function(player, target, ability, action) if i < empathyTotal then empathyTotal = i elseif i > empathyTotal then - validEffects = cutEmpathyEffectTable(validEffects, i, empathyTotal) + validEffects = xi.job_utils.dragoon.cutEmpathyEffectTable(validEffects, i, empathyTotal) end local copyEffect = nil @@ -362,6 +356,18 @@ xi.job_utils.dragoon.useSpiritLink = function(player, target, ability, action) copyi = copyi + 1 end end +end + +xi.job_utils.dragoon.useSpiritLink = function(player, target, ability, action) + local wyvern = player:getPet() + local playerHP = player:getHP() + local petTP = wyvern:getTP() + local regenAmount = player:getMainLvl() / 3 -- level/3 tic regen + + xi.job_utils.dragoon.checkForRemovableEffectsOnSpiritLink(player, wyvern) + + -- Empathy: copy status effects and grant wyvern EXP + xi.job_utils.dragoon.applyEmpathyBonus(player, wyvern) wyvern:addStatusEffect(xi.effect.REGEN, { power = regenAmount, duration = 90, origin = player, tick = 3 }) -- 90 seconds of regen player:addTP(petTP / 2) -- add half wyvern tp to you @@ -460,7 +466,11 @@ xi.job_utils.dragoon.useSuperJump = function(player, target, ability) wyvern:usePetAbility(xi.jobAbility.SUPER_CLIMB, wyvern) end - -- Handle Spirit Surge -50% enmity reduction on super jump to closest party member behind the dragoon + -- Handle Spirit Surge enmity reduction on super jump + xi.job_utils.dragoon.superJumpSurgeEffect(player, target) +end + +xi.job_utils.dragoon.superJumpSurgeEffect = function(player, target) if player:hasStatusEffect(xi.effect.SPIRIT_SURGE) then local minDistance = 9999 local closestPartyMember = nil @@ -487,7 +497,7 @@ xi.job_utils.dragoon.useSuperJump = function(player, target, ability) (player:checkDistance(target) < closestPartyMember:checkDistance(target)) -- Verify dragoon is closer than the party member that we want to reduce the enmity of then if target:isMob() then - target:lowerEnmity(closestPartyMember, 50) + target:lowerEnmity(closestPartyMember, 100) end end end @@ -507,7 +517,7 @@ xi.job_utils.dragoon.useAngon = function(player, target, ability) return xi.effect.DEFENSE_DOWN end -xi.job_utils.dragoon.useDeepBreathing = function(player, target, ability) +xi.job_utils.dragoon.useDeepBreathing = function(player, target, ability, action) local wyvern = getWyvern(player) if wyvern then @@ -598,6 +608,36 @@ xi.job_utils.dragoon.useSteadyWing = function(player, target, ability, action) end end +xi.job_utils.dragoon.getDeepBreathingBonus = function(wyvern, master, isHealing) + local bonus = 0 + local hadEffect = wyvern:hasStatusEffect(xi.effect.MAGIC_ATK_BOOST) + + if hadEffect then + local deepBreathingMerits = master:getMerit(xi.merit.DEEP_BREATHING) + local enhanceDB = master:getMod(xi.mod.ENHANCE_DEEP_BREATHING) + + if isHealing then + bonus = 37.5 + (12.5 * deepBreathingMerits) + + -- add in augment power, +5 per merit level (including first) + if enhanceDB > 0 then + bonus = bonus + deepBreathingMerits * 5 + end + else + bonus = 0.75 + (0.25 * deepBreathingMerits) + + -- add in augment power, +0.1 per merit level (including first) + if enhanceDB > 0 then + bonus = bonus + deepBreathingMerits * 0.1 + end + end + + wyvern:delStatusEffect(xi.effect.MAGIC_ATK_BOOST) + end + + return bonus +end + -- Breath Formula: https://www.bg-wiki.com/ffxi/Wyvern_(Dragoon_Pet)#Healing_Breath xi.job_utils.dragoon.useHealingBreath = function(wyvern, target, skill, action) local healingBreathTable = @@ -610,20 +650,7 @@ xi.job_utils.dragoon.useHealingBreath = function(wyvern, target, skill, action) } local master = wyvern:getMaster() - local deepBreathingMerits = master:getMerit(xi.merit.DEEP_BREATHING) - local deepMult = 0 - - if wyvern:hasStatusEffect(xi.effect.MAGIC_ATK_BOOST) then - deepMult = 37.5 + (12.5 * deepBreathingMerits) - - -- add in augment power, +5 per merit level (including first) - if master:getMod(xi.mod.ENHANCE_DEEP_BREATHING) > 0 then - deepMult = deepMult + deepBreathingMerits * 5 - end - - wyvern:delStatusEffect(xi.effect.MAGIC_ATK_BOOST) - end - + local deepMult = xi.job_utils.dragoon.getDeepBreathingBonus(wyvern, master, true) local jobPointBonus = master:getJobPointLevel(xi.jp.WYVERN_BREATH_EFFECT) * 10 local breathAugmentsBonus = 1 + master:getMod(xi.mod.UNCAPPED_WYVERN_BREATH) / 100 local gear = master:getMod(xi.mod.WYVERN_BREATH) -- Master gear that enhances breath @@ -657,23 +684,10 @@ end -- https://www.bg-wiki.com/ffxi/Wyvern_(Dragoon_Pet)#Elemental_Breath xi.job_utils.dragoon.useDamageBreath = function(wyvern, target, skill, action, damageType) local master = wyvern:getMaster() - local deepBreathingMerits = master:getMerit(xi.merit.DEEP_BREATHING) - local deepBreathingMultiplier = 0 - - if wyvern:hasStatusEffect(xi.effect.MAGIC_ATK_BOOST) then - deepBreathingMultiplier = 0.75 + (0.25 * deepBreathingMerits) - - -- add in augment power, +0.1 per merit level (including first) - if master:getMod(xi.mod.ENHANCE_DEEP_BREATHING) > 0 then - deepBreathingMultiplier = deepBreathingMultiplier + deepBreathingMerits * 0.1 - end - - wyvern:delStatusEffect(xi.effect.MAGIC_ATK_BOOST) - end - - local jobPointBonus = master:getJobPointLevel(xi.jp.WYVERN_BREATH_EFFECT) * 10 - local breathAugmentsBonus = master:getMod(xi.mod.UNCAPPED_WYVERN_BREATH) / 100 - local gearMultiplier = master:getMod(xi.mod.WYVERN_BREATH) -- Master gear that enhances breath + local deepBreathingMultiplier = xi.job_utils.dragoon.getDeepBreathingBonus(wyvern, master, false) + local jobPointBonus = master:getJobPointLevel(xi.jp.WYVERN_BREATH_EFFECT) * 10 + local breathAugmentsBonus = master:getMod(xi.mod.UNCAPPED_WYVERN_BREATH) / 100 + local gearMultiplier = master:getMod(xi.mod.WYVERN_BREATH) -- Master gear that enhances breath -- gear cap of 64/256 in multiplier gearMultiplier = 1.0 + (math.min(gearMultiplier, 64)) / 256 diff --git a/scripts/globals/pets/wyvern.lua b/scripts/globals/pets/wyvern.lua index 9fb7b03aceb..3fe7738bb16 100644 --- a/scripts/globals/pets/wyvern.lua +++ b/scripts/globals/pets/wyvern.lua @@ -186,7 +186,7 @@ xi.pets.wyvern.onMobSpawn = function(mob) end) end -local function removeWyvernLevels(mob) +xi.pets.wyvern.removeWyvernLevels = function(mob) local master = mob:getMaster() local numLvls = mob:getLocalVar('level_Ups') @@ -205,7 +205,7 @@ local function removeWyvernLevels(mob) end xi.pets.wyvern.onMobDeath = function(mob, player) - removeWyvernLevels(mob) + xi.pets.wyvern.removeWyvernLevels(mob) local master = mob:getMaster() master:removeListener('PET_WYVERN_WS') @@ -216,7 +216,7 @@ xi.pets.wyvern.onMobDeath = function(mob, player) end xi.pets.wyvern.onPetLevelRestriction = function(pet) - removeWyvernLevels(pet) + xi.pets.wyvern.removeWyvernLevels(pet) pet:setLocalVar('wyvern_exp', 0) pet:setLocalVar('level_Ups', 0) end diff --git a/sql/abilities.sql b/sql/abilities.sql index 5c214147ed1..f0e2c5f27bf 100644 --- a/sql/abilities.sql +++ b/sql/abilities.sql @@ -82,7 +82,7 @@ INSERT INTO `abilities` VALUES (61,'call_wyvern',14,1,1,1200,163,0,0,94,2000,0,6 INSERT INTO `abilities` VALUES (62,'third_eye',12,15,1,60,133,0,0,24,2000,0,6,0,0,0,1,0,1088,0,NULL); INSERT INTO `abilities` VALUES (63,'meditate',12,30,1,180,134,0,0,25,2000,0,6,0,0,0,320,0,1094,0,NULL); INSERT INTO `abilities` VALUES (64,'warding_circle',12,5,1,300,135,148,0,31,2000,0,6,0,1,10,1,20,1090,0,NULL); -INSERT INTO `abilities` VALUES (65,'ancient_circle',14,5,1,300,157,0,0,32,2000,0,6,0,1,10,1,20,1216,0,NULL); +INSERT INTO `abilities` VALUES (65,'ancient_circle',14,5,1,300,157,150,0,32,2000,0,6,0,1,10,1,20,1216,0,NULL); INSERT INTO `abilities` VALUES (66,'jump',14,10,4,60,158,110,0,204,2000,0,3,8,0,0,0,0,1218,0,NULL); INSERT INTO `abilities` VALUES (67,'high_jump',14,35,4,120,159,110,0,209,2000,0,3,10,0,0,0,0,1220,0,NULL); INSERT INTO `abilities` VALUES (68,'super_jump',14,50,4,180,160,110,0,214,2000,0,3,12,0,0,0,0,1221,0,NULL); @@ -398,7 +398,7 @@ INSERT INTO `abilities` VALUES (389,'consume_mana',8,55,1,60,95,0,0,337,2000,0,6 INSERT INTO `abilities` VALUES (390,'naturalists_roll',17,67,1,60,193,420,0,328,2000,0,6,0,1,8,1,80,0,8,'SOA'); -- No Enhancing Magic Duration MOD, Empty PH effect exists INSERT INTO `abilities` VALUES (391,'runeists_roll',17,70,1,60,193,420,0,329,2000,0,6,0,1,8,1,80,0,8,'SOA'); INSERT INTO `abilities` VALUES (392,'crooked_cards',17,95,1,600,96,100,0,335,2000,0,6,0,0,0,0,0,0,0,NULL); -INSERT INTO `abilities` VALUES (393,'spirit_bond',14,65,257,60,149,100,0,86,2000,0,6,4,0,0,0,0,0,0,NULL); +INSERT INTO `abilities` VALUES (393,'spirit_bond',14,65,257,60,149,100,0,86,2000,0,6,4,0,0,0,0,0,0,'ROV'); INSERT INTO `abilities` VALUES (394,'majesty',7,70,1,60,150,100,0,338,2000,0,6,0,0,0,0,340,0,0,NULL); INSERT INTO `abilities` VALUES (512,'healing_ruby',15,1,3,60,174,0,0,94,2000,0,6,20,0,0,1,60,0,0,NULL); INSERT INTO `abilities` VALUES (513,'poison_nails',15,5,4,60,173,0,0,94,2000,0,6,3,0,0,1,60,0,0,NULL); diff --git a/sql/traits.sql b/sql/traits.sql index c070b1bf3be..0cdf6a54621 100644 --- a/sql/traits.sql +++ b/sql/traits.sql @@ -469,15 +469,15 @@ INSERT INTO `traits` VALUES (86,'overwhelm',12,75,1,0,0,'TOAU',2758); INSERT INTO `traits` VALUES (87,'ninja tool expert.',13,75,1,308,0,'TOAU',2818); INSERT INTO `traits` VALUES (88,'empathy',14,75,1,0,0,'TOAU',2884); INSERT INTO `traits` VALUES (89,'strafe',14,20,1,986,10,'TOAU',0); -INSERT INTO `traits` VALUES (89,'strafe',14,40,2,986,15,'TOAU',0); -INSERT INTO `traits` VALUES (89,'strafe',14,60,3,986,25,'TOAU',0); -INSERT INTO `traits` VALUES (89,'strafe',14,80,4,986,30,'TOAU',0); -INSERT INTO `traits` VALUES (90,'enchainment',16,75,1,0,0,'WOTG',3012); -INSERT INTO `traits` VALUES (91,'assimilation',16,75,1,0,0,'WOTG',3014); -INSERT INTO `traits` VALUES (92,'winning streak',17,75,1,0,0,'WOTG',3076); -INSERT INTO `traits` VALUES (93,'loaded deck',17,75,1,0,0,'WOTG',3078); -INSERT INTO `traits` VALUES (94,'fine-tuning',18,75,1,0,0,'WOTG',3140); -INSERT INTO `traits` VALUES (95,'optimization',18,75,1,0,0,'WOTG',3142); +INSERT INTO `traits` VALUES (89,'strafe',14,40,2,986,15,'SOA',0); +INSERT INTO `traits` VALUES (89,'strafe',14,60,3,986,25,'SOA',0); +INSERT INTO `traits` VALUES (89,'strafe',14,80,4,986,30,'SOA',0); +INSERT INTO `traits` VALUES (90,'enchainment',16,75,1,0,0,'TOAU',3012); +INSERT INTO `traits` VALUES (91,'assimilation',16,75,1,0,0,'TOAU',3014); +INSERT INTO `traits` VALUES (92,'winning streak',17,75,1,0,0,'TOAU',3076); +INSERT INTO `traits` VALUES (93,'loaded deck',17,75,1,0,0,'TOAU',3078); +INSERT INTO `traits` VALUES (94,'fine-tuning',18,75,1,0,0,'TOAU',3140); +INSERT INTO `traits` VALUES (95,'optimization',18,75,1,0,0,'TOAU',3142); INSERT INTO `traits` VALUES (96,'closed position',19,75,1,0,0,'WOTG',3206); INSERT INTO `traits` VALUES (97,'stormsurge',20,75,1,0,0,'WOTG',3274); INSERT INTO `traits` VALUES (98,'crit. atk. bonus',1,78,1,421,5,'ABYSSEA',0); diff --git a/src/map/ai/states/petskill_state.cpp b/src/map/ai/states/petskill_state.cpp index 48afd067578..074e6139335 100644 --- a/src/map/ai/states/petskill_state.cpp +++ b/src/map/ai/states/petskill_state.cpp @@ -87,8 +87,8 @@ CPetSkillState::CPetSkillState(CPetEntity* PEntity, uint16 targid, uint16 wsid) m_PEntity->loc.zone->PushPacket(m_PEntity, CHAR_INRANGE, std::make_unique(action)); // Wyverns immediately emit a skill interrupt packet. - // This looks like a hack but is retail accurate - if (PEntity->m_PetID == PETID_WYVERN) + // This looks like a hack but is retail accurate. + if (PEntity->m_PetID == PETID_WYVERN && PEntity->getMod(Mod::WYVERN_SHOW_READYING) == 0) { ActionInterrupts::WyvernSkillReady(PEntity); } diff --git a/src/map/modifier.h b/src/map/modifier.h index e91948aa34f..c4b29f63397 100644 --- a/src/map/modifier.h +++ b/src/map/modifier.h @@ -647,6 +647,7 @@ enum class Mod WYVERN_BREATH_MACC = 986, // Increases accuracy of wyvern's breath. adds 10 magic accuracy per merit to the trait Strafe WYVERN_LVL_BONUS = 1043, // Wyvern: Lv.+ (Increases wyvern's base level above 99) WYVERN_ATTRIBUTE_DA = 1056, // Adds an amount of Double Attack to Dragoon each time Wyverns Attributes Increase (percent) + WYVERN_SHOW_READYING = 1195, // Pet shows readying animation instead of suppressing it (e.g., wyvern breath) DRAGOON_BREATH_RECAST = 1057, // Restoring/Smithing Breath Recast Reduction (seconds) ENHANCE_DEEP_BREATHING = 283, // Add 5/256 to deep breathing bonus per merit level when calculating healing breath UNCAPPED_WYVERN_BREATH = 284, // Uncapped wyvern breath boost. Used on retail for augments, normal gear should use WYVERN_BREATH. @@ -1148,7 +1149,7 @@ enum class Mod // The spares take care of finding the next ID to use so long as we don't forget to list IDs that have been freed up by refactoring. // 570 through 825 used by WS DMG mods these are not spares. // - // SPARE IDs: 1195 and onward + // SPARE IDs: 1196 and onward }; // temporary workaround for using enum class as unordered_map key until compilers support it