----------------------------------- -- 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