package DamageHandler import public initlater DamageTypeList import initlater UnitData import initlater StatHandler import initlater CombatText import initlater ThreatHandler import initlater BuffHandler import initlater SpellIgnoreThePain import initlater TalentList trigger unitAttackTrigger boolean blockNext = false boolean blockDmgEvent = false unit currentKillingUnit = null public function xGetKillingUnit() returns unit return currentKillingUnit public function blockNextDamageEvent() blockNext = true public function blockDamageEvents(boolean flag) blockDmgEvent = flag // Wrapper for non-attack damage. public function unitDamageTarget(unit source, unit target, real damage, DamageType damageType) unitDamageTarget(source, target, damage, damageType, false) public function unitDamageTarget(unit source, unit target, real damage, DamageType damageType, boolean isAttack) var dmg = damage if not source.xIsCombatUnit() or not target.xIsCombatUnit() printWarning("DamageHandler.unitDamageTarget(..): damage dealt by or on non-combat units.") return if not source.xIsAlive() or not target.xIsAlive() printWarning("DamageHandler.unitDamageTarget(..): damage dealt by or on dead units.") return // Proccs, buffs, etc.: // boolean isCrit = false // if damage comes from autoattack if isAttack // Calc evasion if GetRandomInt(0, 99) < target.getStat(Stat.EVAS) // if evade ... combatTextEvade(source, target) return // Calc crit if GetRandomInt(0, 99) < source.getStat(Stat.CCHA) // if crit ... isCrit = true dmg = dmg * (1 + source.getStat(Stat.CMUL)*0.01) + source.getStat(Stat.CBON) // damage = damage * critmultiplier + critbonus // Proccs, buffs, etc.: if target.hasBuff(BuffIgnoreThePain.typeId) if isAttack and target.xHasTalent(TALENT_WARRIOR_IGNORE_REFLECT) and source.getPos().distToVecSquared(target.getPos()) <= 100*100 unitDamageTarget(target, source, target.getStat(Stat.DAMA) * 1., DamageType.PHYSICAL) // Reflected damage dmg *= 0.2 // // Calc damage modifieds from armor/resists switch damageType case PHYSICAL dmg -= target.getStat(Stat.ARMO) if dmg <= 0 dmg = 1 case MAGIC dmg *= 0.9 case FIRE dmg *= 0.9 case POISON dmg *= 0.9 // Apply damage if dmg > 0 target.setHP(target.getHP() - dmg) // Apply Threat if not target.xIsHero() // If target is creep/boss real threat = dmg threat *= (1+source.getStat(Stat.ATHR)*0.01) modifyThreat(source, target, threat, true) if target.getHP() < 0.405 currentKillingUnit = source unitDeath(target) // unit dies // Floating text if isCrit combatTextCrit(source, target, dmg) else combatTextDamage(source, target, dmg) // TODO: give every instance its own trigger public class UnitDamageHandler construct(unit u) unitAttackTrigger.registerUnitEvent(u, EVENT_UNIT_DAMAGED) ondestroy // TODO: recycle event / trigger function unitAttacked() if blockNext blockNext = false return if not blockDmgEvent unit source = GetEventDamageSource() // print("EVENT_UNIT_DAMAGED triggered. Source: " + source.getName() + ", TriggeringUnit: " + GetTriggerUnit().getName() + ", Damage: " + GetEventDamage().toString()) if source.getTypeId() != DUMMY_UNIT_ID real damage = 1.*source.xGetUnitData().unitStatBuffer.get(Stat.DAMA) unitDamageTarget(source, GetTriggerUnit(), damage, DamageType.PHYSICAL, true) init unitAttackTrigger = CreateTrigger() ..addAction(function unitAttacked)