130 lines
4.8 KiB
Lua
130 lines
4.8 KiB
Lua
-----------------------------------
|
|
-- ABILITIES
|
|
-----------------------------------
|
|
xi = xi or {}
|
|
xi.ability = xi.ability or {}
|
|
|
|
xi.ability.adjustDamage = function(dmg, attacker, skill, target, skilltype, skillparam, shadowbehav) -- seems to only be used for Wyvern breaths and chi blast
|
|
-- physical attack missed, skip rest
|
|
local msg = skill:getMsg()
|
|
if
|
|
msg == xi.msg.JA_MISS or
|
|
msg == xi.msg.SKILL_MISS or
|
|
msg == xi.msg.SHADOW_ABSORB or
|
|
msg == xi.msg.ANTICIPATE
|
|
then
|
|
return 0
|
|
end
|
|
|
|
-- Handle pd.
|
|
if
|
|
(target:hasStatusEffect(xi.effect.PERFECT_DODGE) or
|
|
target:hasStatusEffect(xi.effect.ALL_MISS)) and
|
|
skilltype == xi.attackType.PHYSICAL
|
|
then
|
|
skill:setMsg(xi.msg.basic.JA_MISS_2)
|
|
return 0
|
|
end
|
|
|
|
-- set message to damage
|
|
-- this is for AoE because its only set once
|
|
skill:setMsg(xi.msg.basic.USES_JA_TAKE_DAMAGE)
|
|
|
|
-- Handle shadows depending on shadow behavior / skilltype
|
|
if
|
|
shadowbehav ~= xi.mobskills.shadowBehavior.WIPE_SHADOWS and
|
|
shadowbehav ~= xi.mobskills.shadowBehavior.IGNORE_SHADOWS
|
|
then
|
|
--remove 'shadowbehav' shadows.
|
|
|
|
dmg = utils.takeShadows(target, dmg, shadowbehav)
|
|
|
|
-- dealt zero damage, so shadows took hit
|
|
if dmg == 0 then
|
|
skill:setMsg(xi.msg.basic.SHADOW_ABSORB)
|
|
return shadowbehav
|
|
end
|
|
|
|
elseif shadowbehav == xi.mobskills.shadowBehavior.WIPE_SHADOWS then --take em all!
|
|
target:delStatusEffect(xi.effect.COPY_IMAGE)
|
|
target:delStatusEffect(xi.effect.BLINK)
|
|
target:delStatusEffect(xi.effect.THIRD_EYE)
|
|
end
|
|
|
|
-- Handle Third Eye using shadowbehav as a guide.
|
|
if
|
|
(skilltype == xi.attackType.PHYSICAL or
|
|
skilltype == xi.attackType.RANGED) and
|
|
xi.combat.physicalHitRate.checkAnticipated(attacker, target)
|
|
then
|
|
skill:setMsg(xi.msg.basic.ANTICIPATE)
|
|
|
|
return 0
|
|
end
|
|
|
|
local element = utils.clamp(skillparam - 5, xi.element.NONE, xi.element.DARK) -- Transform damage type to element
|
|
if skilltype == xi.attackType.PHYSICAL then
|
|
dmg = target:physicalDmgTaken(dmg, skillparam)
|
|
elseif skilltype == xi.attackType.MAGICAL then
|
|
dmg = math.floor(dmg * xi.combat.damage.calculateDamageAdjustment(target, false, true, false, false))
|
|
dmg = math.floor(dmg * xi.spells.damage.calculateAbsorption(target, element, true))
|
|
dmg = math.floor(dmg * xi.spells.damage.calculateNullification(target, element, true, false))
|
|
dmg = math.floor(target:handleSevereDamage(dmg, false))
|
|
elseif skilltype == xi.attackType.BREATH then
|
|
dmg = math.floor(dmg * xi.combat.damage.calculateDamageAdjustment(target, false, false, false, true))
|
|
dmg = math.floor(dmg * xi.spells.damage.calculateAbsorption(target, element, false))
|
|
dmg = math.floor(dmg * xi.spells.damage.calculateNullification(target, element, false, true))
|
|
dmg = math.floor(target:handleSevereDamage(dmg, false))
|
|
elseif skilltype == xi.attackType.RANGED then
|
|
dmg = target:rangedDmgTaken(dmg)
|
|
end
|
|
|
|
if dmg < 0 then
|
|
return dmg
|
|
end
|
|
|
|
dmg = utils.handlePhalanx(target, dmg)
|
|
|
|
if skilltype == xi.attackType.MAGICAL then
|
|
dmg = utils.handleOneForAll(target, dmg)
|
|
end
|
|
|
|
dmg = utils.handleStoneskin(target, dmg)
|
|
|
|
if dmg > 0 then
|
|
target:wakeUp()
|
|
target:updateEnmityFromDamage(attacker, dmg)
|
|
end
|
|
|
|
return dmg
|
|
end
|
|
|
|
xi.ability.takeDamage = function(defender, attacker, params, primary, finaldmg, attackType, damageType, slot, tpHitsLanded, extraHitsLanded, shadowsAbsorbed, bonusTP, action, taChar)
|
|
if tpHitsLanded + extraHitsLanded > 0 then
|
|
if finaldmg < 0 then
|
|
-- TODO: ability absorb messages (if there are any)
|
|
-- action:messageID(defender:getID(), xi.msg.basic.WHATEVER)
|
|
end
|
|
elseif shadowsAbsorbed > 0 then
|
|
action:messageID(defender:getID(), xi.msg.basic.SHADOW_ABSORB)
|
|
action:param(defender:getID(), shadowsAbsorbed)
|
|
else
|
|
-- no abilities that use ability message can miss (the rest use ws messages)
|
|
end
|
|
|
|
local targetTPMult = params.targetTPMult or 1
|
|
finaldmg = defender:takeWeaponskillDamage(attacker, finaldmg, attackType, damageType, slot, primary, tpHitsLanded, (extraHitsLanded * 10) + bonusTP, targetTPMult)
|
|
if tpHitsLanded + extraHitsLanded > 0 then
|
|
action:recordDamage(defender, attackType, math.abs(finaldmg))
|
|
end
|
|
|
|
local enmityEntity = taChar or attacker
|
|
if params.overrideCE and params.overrideVE then
|
|
defender:addEnmity(enmityEntity, params.overrideCE, params.overrideVE)
|
|
else
|
|
local enmityMult = params.enmityMult or 1
|
|
defender:updateEnmityFromDamage(enmityEntity, finaldmg * enmityMult)
|
|
end
|
|
|
|
return finaldmg
|
|
end
|