package DestroyerSummoner import initlater EndBoss import Creep import Assets import Fx constant SUMMONER_ID = 'u016' constant DESTROYER_ID = 'n00Q' constant SUMMON_CASTING_EFFECT_ABIL = 'A02J' constant SUMMONER_BOUNTY = 99 constant DESTROYER_BOUNTY = 666 constant DESTROYER_SUMMON_TIME = 30. constant updatePeriod = .05 constant animationLoopPeriod = 45. public class FinalBossSummoning var castPercent = 0. var animationLoop = 0. var castingCount = 0 var summoners = new LinkedList() Fx summoningEffect = null CallbackPeriodic updateCb FText summonText = createFText(middle.toVec3(), "0%", 12.) EndBossFight endBossFightRef construct(EndBossFight endBossFightRef) this.endBossFightRef = endBossFightRef summonText.tt.setVisibility(false) updateCb = doPeriodically(updatePeriod, (CallbackPeriodic cb) -> this.update()) function update() var newCastingCount = 0 for summoner in summoners if summoner.actor.isAlive() if not summoner.casting if summoner.getPos().distanceTo2d(middle) < 220. startCasting(summoner) newCastingCount ++ else newCastingCount++ else summoners.remove(summoner) castingCount = newCastingCount castPercent += getSummonSpeed(castingCount) * 2. * ANIMATION_PERIOD if castPercent < 0 castPercent = 0 if castPercent >= 100 castPercent = 0 summonDestroyer() else this.updateAnimation() function updateAnimation() animationLoop = (animationLoop + updatePeriod / animationLoopPeriod) % 1. if (castingCount > 0 or castPercent > 0) let percentComp = PercentTo255(castPercent) if summoningEffect == null summoningEffect = new Fx(PLAYER_COLOR_LIGHT_GRAY, middle.toVec3(), angle(0), Abilities.voodooAura)..setColor(colorA(255, 255, 255, 0)) summoningEffect..setScale(1.2 + castPercent / 75.)..setColor(colorA(63 + (percentComp * 3. / 4.).toInt(), 0, 0, percentComp)) summonText.tt..setVisibility(true) ..setText(castPercent.toInt().toString() + "%", 12) ..setColor(percentComp, 155 - percentComp, 0, 255) else if summoningEffect != null destroy summoningEffect summoningEffect = null summonText.tt.setVisibility(false) var i = 0 for summoner in summoners if summoner.casting summoner.setPos(middle.polarOffset(angle((animationLoop + (i - castingCount) / castingCount) * 6.28), 200.).toVec3().add(0, 0, 120)) summoner.actor.setFacing(summoner.pos.angleTo2d(middle)) i++ function startCasting(DestroyerSummoner summoner) summoner.sleeps = true summoner.casting = true summoner.actor.addAbility(SUMMON_CASTING_EFFECT_ABIL) summoner.actor.queueAnimation("attack spell") function getSummonSpeed(int castingCount) returns real if castingCount <= 0 return -1 return castingCount / 4 + castingCount * castingCount / 4 function addSummoner(DestroyerSummoner summoner) summoners.add(summoner) function summonDestroyer() let summonPos = middle.polarOffset(angle(animationLoop * 6.28), 200.) let destroyerFx = new Fx(summonPos, angle(0), Abilities.markOfChaosTarget) let middleFx = new Fx(middle, angle(0), Abilities.markOfChaosTarget)..setScale(2) doAfter(2.) -> destroy destroyerFx destroy middleFx new Creep(summonPos.toVec3(), DESTROYER_ID, DESTROYER_BOUNTY, middle, summonPos.angleTo(middle)) endBossFightRef.endDestroyerSummoning() ondestroy for DestroyerSummoner s in summoners new Fx(s.pos, angle(0), Abilities.aIamTarget).hiddenDestroy() s.actor.kill() destroy summoners destroy updateCb destroy summonText if summoningEffect != null destroy summoningEffect public class DestroyerSummoner extends Creep boolean casting = false construct(vec3 pos) super(pos, SUMMONER_ID, SUMMONER_BOUNTY, middle, pos.angleTo2d(middle)) destroy new Fx(pos, angle(0), Abilities.feralspiritdone)..setZ(180)..setScale(1.5) override function onDeath() super.onDeath() casting = false