diff --git a/scripts/actions/abilities/blade_bash.lua b/scripts/actions/abilities/blade_bash.lua index 137ad40f286..4b70a692546 100644 --- a/scripts/actions/abilities/blade_bash.lua +++ b/scripts/actions/abilities/blade_bash.lua @@ -26,7 +26,7 @@ abilityObject.onUseAbility = function(player, target, ability) local damage = math.floor(player:getMod(xi.mod.WEAPON_BASH) + (jobLevel + 11) / 4) -- Calculating and applying Blade Bash damage - damage = utils.stoneskin(target, damage) + damage = utils.stoneskin(target, damage, xi.attackType.PHYSICAL) target:takeDamage(damage, player, xi.attackType.PHYSICAL, xi.damageType.BLUNT) target:updateEnmityFromDamage(player, damage) diff --git a/scripts/actions/abilities/mijin_gakure.lua b/scripts/actions/abilities/mijin_gakure.lua index e1a5937bb6f..a850b1cb2ae 100644 --- a/scripts/actions/abilities/mijin_gakure.lua +++ b/scripts/actions/abilities/mijin_gakure.lua @@ -19,7 +19,7 @@ abilityObject.onUseAbility = function(player, target, ability) -- Job Point Bonus (3% per Level) dmg = dmg * (1 + (player:getJobPointLevel(xi.jp.MIJIN_GAKURE_EFFECT) * 0.03)) dmg = dmg * resist - dmg = utils.stoneskin(target, dmg) + dmg = utils.stoneskin(target, dmg, xi.attackType.SPECIAL) target:takeDamage(dmg, player, xi.attackType.SPECIAL, xi.damageType.ELEMENTAL) player:setLocalVar('MijinGakure', 1) diff --git a/scripts/actions/abilities/pets/automaton/shield_bash.lua b/scripts/actions/abilities/pets/automaton/shield_bash.lua index 93acd46caf9..3ef427b200f 100644 --- a/scripts/actions/abilities/pets/automaton/shield_bash.lua +++ b/scripts/actions/abilities/pets/automaton/shield_bash.lua @@ -47,7 +47,7 @@ abilityObject.onAutomatonAbility = function(target, automaton, skill, master, ac damage = damage * (pdif / 1000) - damage = utils.stoneskin(target, damage) + damage = utils.stoneskin(target, damage, xi.attackType.PHYSICAL) target:takeDamage(damage, automaton, xi.attackType.PHYSICAL, xi.damageType.BLUNT) target:updateEnmityFromDamage(automaton, damage) target:addEnmity(automaton, 450, 900) diff --git a/scripts/actions/abilities/pets/concentric_pulse.lua b/scripts/actions/abilities/pets/concentric_pulse.lua index b4dd91ae05e..5ce3a13c761 100644 --- a/scripts/actions/abilities/pets/concentric_pulse.lua +++ b/scripts/actions/abilities/pets/concentric_pulse.lua @@ -24,7 +24,7 @@ abilityObject.onPetAbility = function(target, pet, skill) dmg = dmg + (dmg * 0.01 * dmgBoost) end - dmg = utils.stoneskin(target, dmg) + dmg = utils.stoneskin(target, dmg, xi.attackType.MAGICAL) target:takeDamage(dmg, pet, xi.attackType.MAGICAL, xi.damageType.NONE) diff --git a/scripts/actions/mobskills/frozen_mist.lua b/scripts/actions/mobskills/frozen_mist.lua new file mode 100644 index 00000000000..89bc27c488c --- /dev/null +++ b/scripts/actions/mobskills/frozen_mist.lua @@ -0,0 +1,36 @@ +----------------------------------- +-- Frozen Mist +-- Description: Deals ice damage to enemies around the caster. Additional effect: Terror +-- Type: Magical (Ice) +----------------------------------- +local mobskillObject = {} + +mobskillObject.onMobSkillCheck = function(target, mob, skill) + return 0 +end + +mobskillObject.onMobWeaponSkill = function(target, mob, skill) + local duration = 30 + local resist = applyResistanceAddEffect(mob, target, xi.element.ICE, 0) + + xi.mobskills.mobStatusEffectMove(mob, target, xi.effect.TERROR, 30, 0, duration * resist) + + local dmgmod = 1.5 + local info = xi.mobskills.mobMagicalMove(mob, target, skill, mob:getWeaponDmg(), xi.element.ICE, dmgmod, xi.mobskills.magicalTpBonus.NO_EFFECT) + local dmg = xi.mobskills.mobFinalAdjustments(info.dmg, mob, skill, target, xi.attackType.MAGICAL, xi.damageType.ICE, xi.mobskills.shadowBehavior.WIPE_SHADOWS) + + target:takeDamage(dmg, mob, xi.attackType.MAGICAL, xi.damageType.ICE) + + mob:addStatusEffect(xi.effect.STONESKIN, 0, 0, 180, 1, 1000) + mob:setAnimationSub(1) + + local effect = mob:getStatusEffect(xi.effect.STONESKIN) + if effect then + mob:addMod(xi.mod.ICE_ABSORB, 100) + effect:addMod(xi.mod.ICE_ABSORB, 100) + end + + return dmg +end + +return mobskillObject diff --git a/scripts/actions/mobskills/fuscous_ooze.lua b/scripts/actions/mobskills/fuscous_ooze.lua index daf1155c85a..312b9fa8c07 100644 --- a/scripts/actions/mobskills/fuscous_ooze.lua +++ b/scripts/actions/mobskills/fuscous_ooze.lua @@ -1,7 +1,7 @@ ----------------------------------- -- Fuscous Ooze -- Family: Slugs --- Description: A dusky slime inflicts encumberance and weight. +-- Description: A dusky slime inflicts encumbrance and weight. -- Type: Magical -- Utsusemi/Blink absorb: Ignores shadows -- Range: Cone @@ -13,7 +13,7 @@ mobskillObject.onMobSkillCheck = function(target, mob, skill) end mobskillObject.onMobWeaponSkill = function(target, mob, skill) - -- TODO: Encumberance seems to do nothing? + -- TODO: Encumbrance seems to do nothing? xi.mobskills.mobStatusEffectMove(mob, target, xi.effect.WEIGHT, 50, 0, 45) local dmgmod = 1 diff --git a/scripts/actions/mobskills/hydro_wave.lua b/scripts/actions/mobskills/hydro_wave.lua new file mode 100644 index 00000000000..e84c4bb57ab --- /dev/null +++ b/scripts/actions/mobskills/hydro_wave.lua @@ -0,0 +1,36 @@ +----------------------------------- +-- Hydro Wave +-- Description: Deals water damage to enemies around the caster. +-- Type: Magical (Water) +----------------------------------- +local mobskillObject = {} + +mobskillObject.onMobSkillCheck = function(target, mob, skill) + return 0 +end + +mobskillObject.onMobWeaponSkill = function(target, mob, skill) + local duration = 30 + local resist = applyResistanceAddEffect(mob, target, xi.element.WATER, 0) + + xi.mobskills.mobStatusEffectMove(mob, target, xi.effect.ENCUMBRANCE_II, math.random(1,16), 0, (duration * resist)) + + local dmgmod = 2.5 + local info = xi.mobskills.mobMagicalMove(mob, target, skill, mob:getWeaponDmg(), xi.element.WATER, dmgmod, xi.mobskills.magicalTpBonus.NO_EFFECT) + local dmg = xi.mobskills.mobFinalAdjustments(info.dmg, mob, skill, target, xi.attackType.MAGICAL, xi.damageType.WATER, xi.mobskills.shadowBehavior.WIPE_SHADOWS) + + target:takeDamage(dmg, mob, xi.attackType.MAGICAL, xi.damageType.WATER) + + mob:addStatusEffect(xi.effect.STONESKIN, 0, 0, 180, 2, 1500) + mob:setAnimationSub(2) + + local effect = mob:getStatusEffect(xi.effect.STONESKIN) + if effect then + mob:addMod(xi.mod.WATER_ABSORB, 100) + effect:addMod(xi.mod.WATER_ABSORB, 100) + end + + return dmg +end + +return mobskillObject diff --git a/scripts/actions/mobskills/spirits_within.lua b/scripts/actions/mobskills/spirits_within.lua index 5d4f0ad04ec..077bf55fc1b 100644 --- a/scripts/actions/mobskills/spirits_within.lua +++ b/scripts/actions/mobskills/spirits_within.lua @@ -42,7 +42,7 @@ mobskillObject.onMobWeaponSkill = function(target, mob, skill) return 0 end - dmg = utils.stoneskin(target, dmg) + dmg = utils.stoneskin(target, dmg, xi.attackType.BREATH) if dmg > 0 then target:wakeUp() diff --git a/scripts/effects/bio.lua b/scripts/effects/bio.lua index 6bf1881f07d..ff9f3d0d672 100644 --- a/scripts/effects/bio.lua +++ b/scripts/effects/bio.lua @@ -19,7 +19,7 @@ effectObject.onEffectTick = function(target, effect) -- handle diabolos nightmare bio damage explicitly if effect:getTier() > 0 then -- re-using logic from helix effect processing - local dmg = utils.stoneskin(target, effect:getPower()) + local dmg = utils.stoneskin(target, effect:getPower(), xi.attackType.MAGICAL) if dmg > 0 then target:takeDamage(dmg, nil, nil, nil, { wakeUp = false, breakBind = false }) diff --git a/scripts/effects/encumbrance.lua b/scripts/effects/encumbrance.lua index 8c568c783a8..fadc0e90b51 100644 --- a/scripts/effects/encumbrance.lua +++ b/scripts/effects/encumbrance.lua @@ -1,5 +1,5 @@ ----------------------------------- --- xi.effect.ENCUMBERANCE +-- xi.effect.ENCUMBRANCE ----------------------------------- local effectObject = {} diff --git a/scripts/effects/helix.lua b/scripts/effects/helix.lua index 57d8fbd78f8..8fddc1dff22 100644 --- a/scripts/effects/helix.lua +++ b/scripts/effects/helix.lua @@ -7,7 +7,7 @@ effectObject.onEffectGain = function(target, effect) end effectObject.onEffectTick = function(target, effect) - local dmg = utils.stoneskin(target, effect:getPower()) + local dmg = utils.stoneskin(target, effect:getPower(), xi.attackType.MAGICAL) if dmg > 0 then target:takeDamage(dmg) diff --git a/scripts/globals/ability.lua b/scripts/globals/ability.lua index 203cef7fd1e..de0603450ac 100644 --- a/scripts/globals/ability.lua +++ b/scripts/globals/ability.lua @@ -85,7 +85,7 @@ xi.ability.adjustDamage = function(dmg, mob, skill, target, skilltype, skillpara dmg = utils.oneforall(target, dmg) end - dmg = utils.stoneskin(target, dmg) + dmg = utils.stoneskin(target, dmg, skilltype) if dmg > 0 then target:wakeUp() diff --git a/scripts/globals/bluemagic.lua b/scripts/globals/bluemagic.lua index 3ed05826e3f..b2c8ae3e39d 100644 --- a/scripts/globals/bluemagic.lua +++ b/scripts/globals/bluemagic.lua @@ -446,7 +446,7 @@ xi.spells.blue.applySpellDamage = function(caster, target, spell, dmg, params, t end -- handle stoneskin - dmg = utils.stoneskin(target, dmg) + dmg = utils.stoneskin(target, dmg, attackType) target:takeSpellDamage(caster, spell, dmg, attackType, damageType) diff --git a/scripts/globals/job_utils/dancer.lua b/scripts/globals/job_utils/dancer.lua index da36f3a2046..5c0692e0959 100644 --- a/scripts/globals/job_utils/dancer.lua +++ b/scripts/globals/job_utils/dancer.lua @@ -427,7 +427,7 @@ xi.job_utils.dancer.useViolentFlourishAbility = function(player, target, ability ability:setMsg(xi.msg.basic.JA_DAMAGE) end - dmg = utils.stoneskin(target, dmg) + dmg = utils.stoneskin(target, dmg, xi.attackType.PHYSICAL) target:takeDamage(dmg, player, xi.attackType.PHYSICAL, player:getWeaponDamageType(xi.slot.MAIN)) target:updateEnmityFromDamage(player, dmg) diff --git a/scripts/globals/job_utils/paladin.lua b/scripts/globals/job_utils/paladin.lua index 850474d9191..493cbf6c7ec 100644 --- a/scripts/globals/job_utils/paladin.lua +++ b/scripts/globals/job_utils/paladin.lua @@ -210,7 +210,7 @@ xi.job_utils.paladin.useShieldBash = function(player, target, ability) local randomizer = 1 + (math.random(1, 5) / 100) damage = damage * randomizer - damage = utils.stoneskin(target, damage) + damage = utils.stoneskin(target, damage, xi.attackType.PHYSICAL) target:takeDamage(damage, player, xi.attackType.PHYSICAL, xi.damageType.BLUNT) target:updateEnmityFromDamage(player, damage) diff --git a/scripts/globals/job_utils/rune_fencer.lua b/scripts/globals/job_utils/rune_fencer.lua index 3a7fad83d95..f79d03ac054 100644 --- a/scripts/globals/job_utils/rune_fencer.lua +++ b/scripts/globals/job_utils/rune_fencer.lua @@ -522,7 +522,7 @@ local function calculateSwipeLungeDamage(player, target, skillModifier, gearBonu -- Handle Stoneskin if damage > 0 then - damage = utils.clamp(utils.stoneskin(target, damage), -99999, 99999) + damage = utils.clamp(utils.stoneskin(target, damage, xi.attackType.MAGICAL), -99999, 99999) end return damage diff --git a/scripts/globals/job_utils/white_mage.lua b/scripts/globals/job_utils/white_mage.lua index 269be0047a9..637bb4865e5 100644 --- a/scripts/globals/job_utils/white_mage.lua +++ b/scripts/globals/job_utils/white_mage.lua @@ -110,12 +110,12 @@ xi.job_utils.white_mage.useDevotion = function(player, target, ability) local damageHP = math.floor(player:getHP() * 0.25) -- If stoneskin is present, it should absorb damage - damageHP = utils.stoneskin(player, damageHP) + damageHP = utils.stoneskin(player, damageHP, xi.attackType.MAGICAL) local healMP = player:getHP() * mpPercent healMP = utils.clamp(healMP, 0, target:getMaxMP() - target:getMP()) - damageHP = utils.stoneskin(player, damageHP) + damageHP = utils.stoneskin(player, damageHP, xi.attackType.MAGICAL) player:delHP(damageHP) target:addMP(healMP) @@ -143,7 +143,7 @@ xi.job_utils.white_mage.useMartyr = function(player, target, ability) healHP = utils.clamp(healHP, 0, target:getMaxHP() - target:getHP()) -- If stoneskin is present, it should absorb damage - damageHP = utils.stoneskin(player, damageHP) + damageHP = utils.stoneskin(player, damageHP, xi.attackType.MAGICAL) player:delHP(damageHP) target:addHP(healHP) diff --git a/scripts/globals/magic.lua b/scripts/globals/magic.lua index 967eb2ccbb3..97751a1df55 100644 --- a/scripts/globals/magic.lua +++ b/scripts/globals/magic.lua @@ -457,7 +457,7 @@ function finalMagicAdjustments(caster, target, spell, dmg) dmg = utils.oneforall(target, dmg) --handling stoneskin - dmg = utils.stoneskin(target, dmg) + dmg = utils.stoneskin(target, dmg, xi.attackType.MAGICAL) dmg = utils.clamp(dmg, -99999, 99999) if dmg < 0 then @@ -490,7 +490,7 @@ function finalMagicNonSpellAdjustments(caster, target, ele, dmg) dmg = utils.oneforall(target, dmg) -- handling stoneskin - dmg = utils.stoneskin(target, dmg) + dmg = utils.stoneskin(target, dmg, xi.attackType.MAGICAL) dmg = utils.clamp(dmg, -99999, 99999) diff --git a/scripts/globals/mobskills.lua b/scripts/globals/mobskills.lua index be02ea04829..b233e9aa376 100644 --- a/scripts/globals/mobskills.lua +++ b/scripts/globals/mobskills.lua @@ -471,7 +471,7 @@ xi.mobskills.mobBreathMove = function(mob, target, skill, percent, base, element -- Handle Stoneskin if damage > 0 then - damage = utils.clamp(utils.stoneskin(target, damage), -99999, 99999) + damage = utils.clamp(utils.stoneskin(target, damage, xi.attackType.BREATH), -99999, 99999) end -- breath mob skills are single hit so provide single Melee hit TP return if primary target @@ -601,7 +601,7 @@ xi.mobskills.mobFinalAdjustments = function(dmg, mob, skill, target, attackType, end end - dmg = utils.stoneskin(target, dmg) + dmg = utils.stoneskin(target, dmg, attackType) if dmg > 0 then target:updateEnmityFromDamage(mob, dmg) diff --git a/scripts/globals/spells/damage_spell.lua b/scripts/globals/spells/damage_spell.lua index 94320634b4f..7dac50a9a82 100644 --- a/scripts/globals/spells/damage_spell.lua +++ b/scripts/globals/spells/damage_spell.lua @@ -1001,7 +1001,7 @@ xi.spells.damage.useDamageSpell = function(caster, target, spell) -- Handle Stoneskin if finalDamage > 0 then - finalDamage = utils.clamp(utils.stoneskin(target, finalDamage), -99999, 99999) + finalDamage = utils.clamp(utils.stoneskin(target, finalDamage, xi.attackType.MAGICAL), -99999, 99999) end -- Handle Magic Absorb diff --git a/scripts/globals/summon.lua b/scripts/globals/summon.lua index dc3aed1f2a2..f9df3e34562 100644 --- a/scripts/globals/summon.lua +++ b/scripts/globals/summon.lua @@ -372,7 +372,7 @@ xi.summon.avatarFinalAdjustments = function(dmg, mob, skill, target, skilltype, end -- handling stoneskin - dmg = utils.stoneskin(target, dmg) + dmg = utils.stoneskin(target, dmg, skilltype) return dmg end diff --git a/scripts/globals/utils.lua b/scripts/globals/utils.lua index 6e4c4e4c7f2..21a7cd79923 100644 --- a/scripts/globals/utils.lua +++ b/scripts/globals/utils.lua @@ -354,7 +354,7 @@ function utils.counter(predicate) end -- returns unabsorbed damage -function utils.stoneskin(target, dmg) +function utils.stoneskin(target, dmg, attackType) --handling stoneskin if dmg > 0 then local skin = target:getMod(xi.mod.STONESKIN) @@ -365,7 +365,33 @@ function utils.stoneskin(target, dmg) else --absorbs some damage then wear target:delStatusEffect(xi.effect.STONESKIN) target:setMod(xi.mod.STONESKIN, 0) - return dmg - skin + dmg = dmg - skin + end + end + end + + local effect = target:getStatusEffect(xi.effect.STONESKIN) + + if effect ~= nil then + local subID = effect:getSubType() + + if subID == 1 and dmg > 0 then + local physicalSkin = effect:getSubPower() + + if physicalSkin > 0 and attackType == xi.attackType.PHYSICAL then + dmg = utils.stoneskinSubPower(target, effect, physicalSkin, dmg) + end + end + + if subID == 2 and dmg > 0 then + local magicSkin = effect:getSubPower() + + if + dmg > 0 and + magicSkin > 0 and + (attackType == xi.attackType.MAGICAL or attackType == xi.attackType.BREATH or attackType == xi.attackType.SPECIAL) + then + dmg = utils.stoneskinSubPower(target, effect, magicSkin, dmg) end end end @@ -373,6 +399,16 @@ function utils.stoneskin(target, dmg) return dmg end +function utils.stoneskinSubPower(target, effect, skin, dmg) + if skin > dmg then --absorb all damage + effect:setSubPower(skin - dmg) + return 0 + else --absorbs some damage then wear + target:delStatusEffect(xi.effect.STONESKIN) + return dmg - skin + end +end + -- returns reduced magic damage from RUN buff, 'One for All' function utils.oneforall(target, dmg) if dmg > 0 then diff --git a/scripts/globals/weaponskills.lua b/scripts/globals/weaponskills.lua index d28724a7375..502799708bd 100644 --- a/scripts/globals/weaponskills.lua +++ b/scripts/globals/weaponskills.lua @@ -92,7 +92,7 @@ local function souleaterBonus(attacker, wsParams) local bonusDamage = math.floor(attacker:getHP() * (0.1 + souleaterEffect + souleaterEffectII)) if bonusDamage >= 1 then - attacker:delHP(utils.stoneskin(attacker, bonusDamage * stalwartSoulBonus)) + attacker:delHP(utils.stoneskin(attacker, bonusDamage * stalwartSoulBonus, xi.attackType.PHYSICAL)) if attacker:getMainJob() ~= xi.job.DRK then return math.floor(bonusDamage / 2) @@ -349,7 +349,7 @@ local function getSingleHitDamage(attacker, target, dmg, ftp, wsParams, calcPara magicdmg = magicdmg - target:getMod(xi.mod.PHALANX) magicdmg = utils.clamp(magicdmg, 0, 99999) magicdmg = utils.oneforall(target, magicdmg) - magicdmg = utils.stoneskin(target, magicdmg) + magicdmg = utils.stoneskin(target, magicdmg, xi.attackType.MAGICAL) end finaldmg = finaldmg + magicdmg @@ -398,7 +398,7 @@ local function modifyMeleeHitDamage(attacker, target, attackTbl, wsParams, rawDa adjustedDamage = utils.clamp(adjustedDamage, 0, 99999) end - adjustedDamage = utils.stoneskin(target, adjustedDamage) + adjustedDamage = utils.stoneskin(target, adjustedDamage, xi.attackType.PHYSICAL) return adjustedDamage end @@ -937,7 +937,7 @@ xi.weaponskills.doMagicWeaponskill = function(attacker, target, wsID, wsParams, end dmg = utils.oneforall(target, dmg) - dmg = utils.stoneskin(target, dmg) + dmg = utils.stoneskin(target, dmg, xi.attackType.MAGICAL) dmg = dmg * xi.settings.main.WEAPON_SKILL_POWER -- Add server bonus else diff --git a/scripts/mixins/families/ruszor.lua b/scripts/mixins/families/ruszor.lua new file mode 100644 index 00000000000..d5d293ba15c --- /dev/null +++ b/scripts/mixins/families/ruszor.lua @@ -0,0 +1,13 @@ +require('scripts/globals/mixins') + +g_mixins = g_mixins or {} + +g_mixins.ruszor = function(ruszorMob) + ruszorMob:addListener('EFFECT_LOSE', 'STONESKIN', function(mob, effect) + if effect:getEffectType() == xi.effect.STONESKIN then + mob:setAnimationSub(0) + end + end) +end + +return g_mixins.ruszor diff --git a/scripts/zones/Beaucedine_Glacier_[S]/mobs/Ruszor.lua b/scripts/zones/Beaucedine_Glacier_[S]/mobs/Ruszor.lua new file mode 100644 index 00000000000..160e0aebbf7 --- /dev/null +++ b/scripts/zones/Beaucedine_Glacier_[S]/mobs/Ruszor.lua @@ -0,0 +1,12 @@ +----------------------------------- +-- Area: Beaucedine Glacier [S] +-- Mob: Ruszor +----------------------------------- +mixins = { require('scripts/mixins/families/ruszor') } +----------------------------------- +local entity = {} + +entity.onMobDeath = function(mob, player, optParams) +end + +return entity diff --git a/scripts/zones/Kamihr_Drifts/mobs/Slobbering_Ruszor.lua b/scripts/zones/Kamihr_Drifts/mobs/Slobbering_Ruszor.lua new file mode 100644 index 00000000000..35558325789 --- /dev/null +++ b/scripts/zones/Kamihr_Drifts/mobs/Slobbering_Ruszor.lua @@ -0,0 +1,12 @@ +----------------------------------- +-- Area: Kamihr Drifts +-- Mob: Slobbering Ruszor +----------------------------------- +mixins = { require('scripts/mixins/families/ruszor') } +----------------------------------- +local entity = {} + +entity.onMobDeath = function(mob, player, optParams) +end + +return entity diff --git a/scripts/zones/Xarcabard_[S]/mobs/Savage_Ruszor.lua b/scripts/zones/Xarcabard_[S]/mobs/Savage_Ruszor.lua new file mode 100644 index 00000000000..d054c848a77 --- /dev/null +++ b/scripts/zones/Xarcabard_[S]/mobs/Savage_Ruszor.lua @@ -0,0 +1,12 @@ +----------------------------------- +-- Area: Xarcabard [S] +-- Mob: Savage Ruszor +----------------------------------- +mixins = { require('scripts/mixins/families/ruszor') } +----------------------------------- +local entity = {} + +entity.onMobDeath = function(mob, player, optParams) +end + +return entity diff --git a/src/map/status_effect_container.cpp b/src/map/status_effect_container.cpp index 2cc2f8af8b4..8dce513203f 100644 --- a/src/map/status_effect_container.cpp +++ b/src/map/status_effect_container.cpp @@ -1941,7 +1941,7 @@ void CStatusEffectContainer::TickRegen(time_point tick) if (poison) { - int16 damage = battleutils::HandleStoneskin(m_POwner, poison); + int16 damage = battleutils::HandleStoneskin(m_POwner, poison, ATTACK_TYPE::MAGICAL); if (damage > 0) { diff --git a/src/map/utils/battleutils.cpp b/src/map/utils/battleutils.cpp index cc9ba1906fc..f3f84466bd3 100644 --- a/src/map/utils/battleutils.cpp +++ b/src/map/utils/battleutils.cpp @@ -732,7 +732,7 @@ namespace battleutils { damage = std::max(damage - PDefender->getMod(Mod::PHALANX), 0); damage = HandleOneForAll(PDefender, damage); - damage = HandleStoneskin(PDefender, damage); + damage = HandleStoneskin(PDefender, damage, ATTACK_TYPE::MAGICAL); } damage = std::clamp(damage, -99999, 99999); @@ -845,7 +845,7 @@ namespace battleutils { spikesDamage = std::max(spikesDamage - PAttacker->getMod(Mod::PHALANX), 0); spikesDamage = HandleOneForAll(PAttacker, spikesDamage); - spikesDamage = HandleStoneskin(PAttacker, spikesDamage); + spikesDamage = HandleStoneskin(PAttacker, spikesDamage, ATTACK_TYPE::MAGICAL); } if (spikesDamage < 0) // because spikes damage in action packet is uint16, we have to change the healed amount to a positive number and cast to uint16 @@ -991,7 +991,7 @@ namespace battleutils { spikesDamage = std::max(spikesDamage - PAttacker->getMod(Mod::PHALANX), 0); spikesDamage = HandleOneForAll(PAttacker, spikesDamage); - spikesDamage = HandleStoneskin(PAttacker, spikesDamage); + spikesDamage = HandleStoneskin(PAttacker, spikesDamage, ATTACK_TYPE::MAGICAL); } if (spikesDamage < 0) // fit healed spikes into uint16 @@ -1044,7 +1044,7 @@ namespace battleutils { spikesDamage = std::max(spikesDamage - PAttacker->getMod(Mod::PHALANX), 0); spikesDamage = HandleOneForAll(PAttacker, spikesDamage); - spikesDamage = HandleStoneskin(PAttacker, spikesDamage); + spikesDamage = HandleStoneskin(PAttacker, spikesDamage, ATTACK_TYPE::MAGICAL); } else if (spikesDamage < 0) // fit healed spikes into uint16 { @@ -2211,7 +2211,7 @@ namespace battleutils { damage = std::max(damage - PDefender->getMod(Mod::PHALANX), 0); - damage = HandleStoneskin(PDefender, damage); + damage = HandleStoneskin(PDefender, damage, ATTACK_TYPE::PHYSICAL); HandleAfflatusMiseryDamage(PDefender, damage); } damage = std::clamp(damage, -99999, 99999); @@ -2388,7 +2388,7 @@ namespace battleutils if (damage > 0) { damage = std::max(damage - PDefender->getMod(Mod::PHALANX), 0); - damage = HandleStoneskin(PDefender, damage); + damage = HandleStoneskin(PDefender, damage, attackType); } if (!isRanged) @@ -3918,7 +3918,7 @@ namespace battleutils { damage = std::max(damage - PDefender->getMod(Mod::PHALANX), 0); damage = HandleOneForAll(PDefender, damage); - damage = HandleStoneskin(PDefender, damage); + damage = HandleStoneskin(PDefender, damage, ATTACK_TYPE::SPECIAL); HandleAfflatusMiseryDamage(PDefender, damage); } damage = std::clamp(damage, -99999, 99999); @@ -4346,7 +4346,7 @@ namespace battleutils if (bonusDamage >= 1) { - m_PChar->addHP(-HandleStoneskin(m_PChar, (int32)(bonusDamage * stalwartSoulBonus))); + m_PChar->addHP(-HandleStoneskin(m_PChar, (int32)(bonusDamage * stalwartSoulBonus), ATTACK_TYPE::PHYSICAL)); if (m_PChar->GetMJob() == JOB_DRK) { @@ -5289,7 +5289,7 @@ namespace battleutils return damage; } - int32 HandleStoneskin(CBattleEntity* PDefender, int32 damage) + int32 HandleStoneskin(CBattleEntity* PDefender, int32 damage, ATTACK_TYPE attackType) { int16 skin = PDefender->getMod(Mod::STONESKIN); if (damage > 0 && skin > 0) @@ -5304,9 +5304,43 @@ namespace battleutils return damage - skin; } + CStatusEffect* PEffect = PDefender->StatusEffectContainer->GetStatusEffect(EFFECT_STONESKIN); + if (PEffect != nullptr) + { + uint32 subID = PEffect->GetSubID(); + skin = PEffect->GetSubPower(); + if (subID == 1) + { + if (damage > 0 && skin > 0 && attackType == ATTACK_TYPE::PHYSICAL) + { + damage = HandleStoneskinSubPower(PDefender, PEffect, damage, skin); + } + } + else if (subID == 2) + { + if (damage > 0 && skin > 0 && (attackType == ATTACK_TYPE::MAGICAL || attackType == ATTACK_TYPE::BREATH || attackType == ATTACK_TYPE::SPECIAL)) + { + damage = HandleStoneskinSubPower(PDefender, PEffect, damage, skin); + } + } + } + return damage; } + int32 HandleStoneskinSubPower(CBattleEntity* PDefender, CStatusEffect* PEffect, int32 damage, int16 skin) + { + if (skin > damage) + { + PEffect->SetSubPower(skin - damage); + return 0; + } + + PDefender->StatusEffectContainer->DelStatusEffect(EFFECT_STONESKIN); + + return damage - skin; + } + int32 HandleSevereDamage(CBattleEntity* PDefender, int32 damage, bool isPhysical) { damage = HandleSevereDamageEffect(PDefender, EFFECT_MIGAWARI, damage, true); diff --git a/src/map/utils/battleutils.h b/src/map/utils/battleutils.h index d6bf6a2b7d3..e825191eb38 100644 --- a/src/map/utils/battleutils.h +++ b/src/map/utils/battleutils.h @@ -226,7 +226,8 @@ namespace battleutils void BindBreakCheck(CBattleEntity* PAttacker, CBattleEntity* PDefender); // returns damage taken - int32 HandleStoneskin(CBattleEntity* PDefender, int32 damage); + int32 HandleStoneskin(CBattleEntity* PDefender, int32 damage, ATTACK_TYPE attackType); + int32 HandleStoneskinSubPower(CBattleEntity* PDefender, CStatusEffect* effect, int32 damage, int16 skin); int32 HandleOneForAll(CBattleEntity* PDefender, int32 damage); int32 HandleFanDance(CBattleEntity* PDefender, int32 damage); void HandleScarletDelirium(CBattleEntity* PDefender, int32 damage);