package EscaperClasses import Sensor import FxEntity import Escaper import Assets import Key import EscaperSensor import EscaperObjects constant REINCARNATION_ID = 'A02X' constant PORTAL_CREATE_ID = 'A08K' constant SPEEDWAVE_ID = 'A06P' constant STAGNANCYSHIELD_ID = 'A008' constant SLOWWAVE_ID = 'A088' constant TEMP_REV_ID = 'A07Z' constant INNER_STRENGTH_ID = 'A08L' constant FIRE_RESISTANCE = 'A08Q' public class HolyEscaper extends Escaper construct(vec3 pos, player owner) super(pos, owner, ESC_HOLY_ID) override function onCast(int id) super.onCast(id) if id == REINCARNATION_ID if poisoned or not canCast() actor.resetAbilityCooldown(REINCARNATION_ID) createFText(pos, vec2(0,.08), "canceled!", 8.5, 2, colorA(255,0,0,255), owner) else if revivetomb != null revivetomb.remove() revivetomb = createUnit(owner, TOMB_DUMMY_ID, pos, angle(0)) else if id == TEMP_REV_ID if poisoned or not canCast() actor.resetAbilityCooldown(TEMP_REV_ID) createFText(pos, vec2(0,.08), "canceled!", 8.5, 2, colorA(255,0,0,255), owner) public class Portal extends FxEntity use Sensor vec2 destiny = ZERO2 FastEscaper es = null int duration real lerpy = 0. Fx targetFx = null construct(FastEscaper es, int duration) super(es.owner, es.getPos(), 28, angle(0), "PulseTC_fix4.mdx") silent = true this.duration = duration this.es = es deactivate() fx.setColor(colorA(145,145,145,145)) addSensorListener(this) (UnitEntity _source, UnitEntity target) -> if destiny != ZERO2 and target instanceof Escaper var teleport = true for i = 0 to 5 let ie = UnitItemInSlot(target.actor, i).getEntity() if ie != null and ie instanceof Key teleport = false break if teleport target.setPos(destiny.withZ(target.pos.z)) flashEffect(Abilities.blinkCaster, pos) flashEffect(Abilities.blinkTarget, destiny) if not (target castTo Escaper).camlock target.actor.getOwner().panCameraToTimed(destiny, 0.03) override function update() if destiny != ZERO2 and fx.getColor() != COLOR_WHITE lerpy = lerpy.lerp(1.05, 0.045) fx.setColor(colorA(145,145,145,145).mix(COLOR_WHITE, lerpy)) else deactivate() override function slowUpdate() if destiny != ZERO2 super.slowUpdate() if idleSeconds >= duration terminate() function setDestiny(vec2 tpos) this.destiny = tpos if tpos != ZERO2 if targetFx == null targetFx = new Fx(tpos.withZ(0),"PulseTC_tgt.mdx") targetFx.setScale(0.75) targetFx.setOwner(owner, true) targetFx.setXYZ(destiny.withZ(0)) activate() else targetFx.hiddenDestroy() targetFx = null fx.setColor(colorA(90,90,90,90)) ondestroy es.portal = null if targetFx != null targetFx.hiddenDestroy() targetFx = null public class FastEscaper extends Escaper Portal portal = null construct(vec3 pos, player owner) super(pos, owner, ESC_FAST_ID) override function onCPReach() super.onCPReach() if portal != null portal.terminate() Log.debug("portal Terminate") portal = null override function onCast(int id) super.onCast(id) if id == PORTAL_CREATE_ID if sliding or not canCast() actor.resetAbilityCooldown(PORTAL_CREATE_ID) createFText(pos, vec2(0,.08), "canceled!", 8.5, 2, colorA(255,0,0,255), owner) return if portal == null portal = new Portal(this, 20 + actor.getAbilityLevel(PORTAL_CREATE_ID) * 7) actor.resetAbilityCooldown(PORTAL_CREATE_ID) else if portal.destiny != ZERO2 portal..setPos(getPos())..setDestiny(ZERO2) actor.resetAbilityCooldown(PORTAL_CREATE_ID) else portal.setDestiny(getPos().toVec2()) public class IceEscaper extends Escaper construct(vec3 pos, player owner) super(pos, owner, ESC_ICE_ID) override function onCast(int id) super.onCast(id) if id == SPEEDWAVE_ID if sliding let angl = actor.getFacingAngle() let value = 10 + GetUnitAbilityLevel(actor,SPEEDWAVE_ID)*2.5 DestroyEffect(AddSpecialEffect("Abilities\\Spells\\Other\\CrushingWave\\CrushingWaveDamage.mdl", pos.x, pos.y)) addVel(vec3(value * angl.cos(),value * angl.sin(),0.)) else if id == SLOWWAVE_ID let lvl = actor.getAbilityLevel(id) / 4. if sliding speedFactor = 0.9 + lvl addEffect(Objects.impaleTargetDust, pos).destr() public class BlindEscaper extends Escaper construct(vec3 pos, player owner) super(pos, owner, ESC_BLIND_ID) override function onCast(int id) super.onCast(id) override function doLavaDamage() let hp = actor.getHP() let bias = 1 - (actor.getAbilityLevel(FIRE_RESISTANCE) * 0.1) if hp > .405 actor.setHP(hp-this.getCurrentRegion().lavaDmg * bias) else if alive kill(null) public class StrongEscaper extends Escaper boolean invulnerable = false effect shieldeffect = null vec2 shieldPos = vec2(0,0) real shieldtimer = 0. construct(vec3 pos, player owner) super(pos, owner, ESC_STRONG_ID) EventListener.add(actor, EVENT_PLAYER_HERO_SKILL, () -> onSkill()) function onSkill() let learnedId = GetLearnedSkill() let lvl = GetLearnedSkillLevel() if learnedId == INNER_STRENGTH_ID if lvl == 1 actor..addAbility(HP_GAIN_50) else if lvl == 2 actor..removeAbility(HP_GAIN_50)..addAbility(HP_GAIN_75) else if lvl == 3 actor..removeAbility(HP_GAIN_75)..addAbility(HP_GAIN_100) override function update() super.update() if invulnerable shieldtimer -= ANIMATION_PERIOD if getPos().distanceTo2dSq(shieldPos) > 16*16 or shieldtimer <= 0 or pos.getEBRTile().currentType == this.getCurrentRegion().getTypeSet().unwalkableId if shieldtimer > 0 createFText(pos, vec2(0,.08), "canceled!", 8.5, 2, colorA(255,0,0,255), owner) shieldtimer = 0 actor.removeAbility('Avul') invulnerable = false shieldeffect.destr() override function kill(UnitEntity entity, KillMode kmode) if not invulnerable or entity == null or entity instanceof StaticEscaperSensorSetup or kmode == KillMode.FORCE super.kill(null, KillMode.FORCE) else addEffect(Abilities.spellShieldCaster, pos).destr() override function onCast(int id) super.onCast(id) if id == STAGNANCYSHIELD_ID invulnerable = true shieldtimer = 1 + GetUnitAbilityLevel(actor, id)*2. if shieldtimer > 5 shieldtimer = 5 actor.addAbility('Avul') actor.setPos(pos.toVec2()) shieldPos = pos.toVec2() shieldeffect = addEffect("Abilities\\Spells\\Human\\DivineShield\\DivineShieldTarget.mdl", shieldPos)