package Waypoint import BaseObject import Escaper import ObjectTarget import Builder import WaypointObjects import ClosureTimers import HashSet constant INCREMENT = .25 constant EVENT_RADIUS = 32. public class Waypoint extends StaticBaseObject let delay = new ConfigValue(0., INCREMENT, "Delay") boolean wisps = true HashSet linked = null boolean ready = false construct(vec2 pos, player owner) super(pos, CreateUnit(owner, WAYPOINT_ID, pos.x, pos.y, 0.), EVENT_RADIUS, function Waypoint.onInRange, () -> GetTriggerUnit().getFlyHeight() < 64 and (GetTriggeringTrigger().getSource().getEntity() castTo StaticBaseObject).enabled) construct(unit existing) super(existing.getPos(), existing, EVENT_RADIUS, function Waypoint.onInRange, () -> true) function orderLogicMove() let rallyPos = getRallyPoint() + vec2(0.001,0) forUnitsInRange(pos.toVec2(), radius + 48.) u -> let data = u.getEntity() if owner == data.owner and not data instanceof Escaper and not data instanceof Builder and not data instanceof StaticBaseObject if data instanceof SetupObject (data castTo SetupObject).setup.issuePointOrder("move", rallyPos.toVec2()) else data.actor.issuePointOrder("move", rallyPos.toVec2()) function onEnter(unit entry) let entity = entry.getEntity() let rallyPos = getRallyPoint() + vec2(0.001,0) if owner == entity.owner and not entity instanceof Escaper and not entity instanceof Builder if entity instanceof SetupObject if not (entity castTo SetupObject).setup.hasAbility(REMOVE_OBJECT_ID) return if not wisps and entity instanceof ObjectTarget return if linked != null and not linked.isEmpty() if not ready ready = true var allReady = true for andPartner in linked if not andPartner.ready allReady = false break if allReady for andPartner in linked andPartner.orderLogicMove() andPartner.ready = false orderLogicMove() ready = false else if delay.get() < INCREMENT if entity instanceof SetupObject and (entity castTo SetupObject).setup != (entity castTo SetupObject).actor (entity castTo SetupObject).setup.issuePointOrder("move", rallyPos.toVec2()) else entity.actor.issuePointOrder("move", rallyPos.toVec2()) else doAfter(delay.get(), () -> delayMove(entity, rallyPos.toVec2())) override function onCast() super.onCast() let id = GetSpellAbilityId() switch id case INCREASE_DELAY_ID delay.increment(this, 5.) case DECREASE_DELAY_ID delay.decrement(this, 0.) case NO_WISPS_ID if wisps wisps = false createFText(pos, vec2(0,0.05), "Wisps |cffAD0821inactive", 10, 2., COLOR_WHITE, owner) else wisps = true createFText(pos, vec2(0,0.05), "Wisps |cff08BD52active", 10, 2., COLOR_WHITE, owner) case AND_CONNECTION_ID if linked == null linked = new HashSet() let target = GetSpellTargetUnit().getEntity() if target != null and target instanceof Waypoint let twp = (target castTo Waypoint) if linked.has(twp) createFText(target.getPos(), vec2(0,0.08), "|cff0873C5Unlinked", 9., 1.75, COLOR_WHITE, owner) linked.remove(twp) else if twp.linked == null twp.linked = new HashSet() twp.linked.addAll(linked) for link in linked link.linked.add(twp) linked.add(twp) twp.linked.add(this) createFText(target.getPos(), vec2(0,0.08), "|cff0873C5Linked", 9., 1.75, COLOR_WHITE, owner) case CLEAR_CONNECTION_ID if linked != null linked.forEach() waypoint -> if waypoint != null waypoint.linked.remove(this) linked.clear() static function delayMove(UnitEntity entity, vec2 pos) if entity instanceof SetupObject (entity castTo SetupObject).setup.issuePointOrder("move", pos) else entity.actor.issuePointOrder("move", pos) static function onInRange() let source = GetTriggeringTrigger().getSource() let obj = source.getEntity() castTo thistype obj.onEnter(GetTriggerUnit()) override function serialize() returns Json let json = super.serialize() json..addProperty(new Property(KEY_TYPE, WAYPOINT_INDEX.toString())) return json ondestroy if linked != null for link in linked if link.linked != null link.linked.remove(this) destroy linked linked = null