package MGSpacey import Minigame import PlayerData import Assets import KeyUtils import ChannelAbilityPreset import Projectile import ReviveManager import Execute constant ARENA_POS = vec2(-2700, 7500) public class MGSpacey extends Minigame static constant ships = new LinkedList() static constant rocks = new LinkedList() EventListener listener EventListener klistener override function getGameRect() returns rect return gg_rct_spaceygamearea override function getCamBounds() returns rect return gg_rct_spaceygamebounds override function onBegin() for pd in escaperPlayers if pd.escaper != null if not pd.escaper.alive forceRevive(pd.escaper) printTimedToPlayer("Use ARROW KEYS and the ESC key to control your spacecraft.", 15., pd.p) ships.add(new Spaceship(ARENA_POS+vec2(ships.size()*64., -168), pd.escaper)) listener = EventListener.add(EVENT_PLAYER_END_CINEMATIC) -> for ship in ships if ship.owner == GetTriggerPlayer() ship.shoot() break klistener = addKeyListener() -> for ship in ships if ship.owner == GetTriggerPlayer() ship.update() break for i = 0 to 2 new SpaceRock(ARENA_POS.polarOffset((90+GetRandomReal(-45, 45)).fromDeg(), GetRandomReal(256, 480)), vec2(GetRandomReal(-1, 1), GetRandomReal(-1, 1)), 4) override function onEnd() if listener != null destroy listener if klistener != null removeKeyListener(klistener) execute() -> for rock in rocks if rock != null rock.terminate() rocks.clear() execute() -> for ship in ships if ship != null and not ship.done ship.terminate() ships.clear() override function getStartPosition() returns vec2 return getGameRect().getCenter() override function getName() returns string return "|cff3322e2Spacey Adventure" constant minigame = new MGSpacey() init minigames.add(minigame) constant SHIP_ID = compiletime(UNIT_ID_GEN.next()) class ShipProjectile extends Projectile Spaceship ship construct(Spaceship ship) super(ship.getPos().toVec2().polarOffset(ship.actor.getFacingAngle(), 16).withZ(64), 16., ship.owner, ship.actor.getFacingAngle(), Abilities.faerieDragonMissile) fx.setTintFromPlayer(owner) setSpeed(8) fx.eff.setScale(0.75) vel += ship.vel this.ship = ship override function update() super.update() if not gg_rct_spaceygamearea.contains(pos.toVec2()) terminate() else let itr = MGSpacey.rocks.staticItr() for rock from itr if this.pos.distanceTo2dSq(rock.pos.toVec2()) < (21.).squared() + rock.radiusSq rock.hp-- if rock.hp <= 0 rock.terminate() itr.remove() owner.addGold(rock.level div 2) flashEffect(Abilities.manaBurnTarget, getPos()) this.terminate() break ondestroy ship.projectiles.remove(this) public class Spaceship extends UnitEntity real maxSpeed = 8 real acc = 0 angle xyAngle = (90).fromDeg() var projectiles = new LinkedList Escaper mounter int hp = 2 construct(vec2 pos, Escaper mounter) super(createUnit(mounter.owner, SHIP_ID, pos, (90).fromDeg())) this.mounter = mounter this.mounter.alive = false actor.addAbility(LOCUST_ID) mounter.actor..pause()..hide() setPos(this.pos+vec3(0,0,32)) sleeps = false function shoot() if active and projectiles.size() < 4 actor.setAnimation("attack") projectiles.add(new ShipProjectile(this)) function foo() let downKeys = owner.getDownKeys() acc = acc.lerp(0,0.1) if downKeys.left xyAngle += angle(0.105) if downKeys.right xyAngle -= angle(0.105) xyAngle = (xyAngle.degrees() % 360.).fromDeg() actor.setFacing(xyAngle) if localPlayer == owner CameraSetupApplyForceDuration(gg_cam_spaceycam, true, 0.) if downKeys.up acc = acc.lerp(0.75, 0.125) if downKeys.down acc = acc.lerp(-0.2, 0.125) override function update() foo() vel += (xyAngle).toVec(acc) vel *= 0.995 let lgSq = vel.lengthSquared() if lgSq > maxSpeed.squared() vel = vel.setLength(maxSpeed) let tpos = pos + vel*6. if tpos.x < gg_rct_spaceygamearea.getMinX() vel.x = -0.8*vel.x else if tpos.x > gg_rct_spaceygamearea.getMaxX() vel.x = -0.8*vel.x if tpos.y < gg_rct_spaceygamearea.getMinY() vel.y = -0.8*vel.y else if tpos.y > gg_rct_spaceygamearea.getMaxY() vel.y = -0.8*vel.y super.update() let itr = MGSpacey.rocks.staticItr() for rock from itr if rock == null or rock.done itr.remove() else if this.pos.distanceTo2dSq(rock.pos.toVec2()) < 30*30 + rock.radiusSq rock.terminate() itr.remove() hp-- if hp < 0 actor.setAnimation("death") deactivate() var isEnd = true for ship in MGSpacey.ships if ship.active isEnd = false break if isEnd or MGSpacey.rocks.isEmpty() minigame.reset() break ondestroy if mounter != null and not mounter.done mounter.alive = true if mounter.actor.isAlive() mounter.actor..unpause()..show() function getRockAsset(int level) returns string switch level case 4 return Abilities.ancientProtectorMissile case 3 return Abilities.demolisherMissile case 2 return Abilities.rockBoltMissile case 1 return Abilities.makuraMissile return "" public class SpaceRock extends Fx2Entity int level int hp real radiusSq construct(vec2 position, vec2 velocity, int level) super(STAFF_PLAYER, position.withZ(48), velocity.getAngle(), getRockAsset(level)) fx.eff.setScale(1+level*0.25) radiusSq = (26 + level*6.).squared() this.vel = (velocity * ((5-level)*0.85)).toVec3() this.level = level hp = level sleeps = false MGSpacey.rocks.add(this) override function update() let tpos = pos + vel*6. if tpos.x < gg_rct_spaceygamearea.getMinX() vel.x = -vel.x vel *= 0.95 else if tpos.x > gg_rct_spaceygamearea.getMaxX() vel.x = -vel.x vel *= 0.95 if tpos.y < gg_rct_spaceygamearea.getMinY() vel.y = -vel.y vel *= 0.95 else if tpos.y > gg_rct_spaceygamearea.getMaxY() vel.y = -vel.y vel *= 0.95 pos += vel fx.setOrientation(vel.toVec2().getAngle().toQuat(vec3(0,0,1))) super.update() ondestroy if level > 1 for i = 0 to 2 new SpaceRock(pos.toVec2(), vec2(GetRandomReal(-2, 2), GetRandomReal(-2, 2)), level-1) @objectgen function genObjs() new UnitDefinition(SHIP_ID, 'hgry') ..setName("Spaceship") ..setModelFile("Onslaught.mdx") ..setMovementHeight(64) ..setMovementHeightMinimum(16) ..setNormalAbilities("") ..setHitPointsMaximumBase(100000000) ..setManaMaximum(0) ..setCollisionSize(0) ..setScalingValue(0.25) ..setAttacksEnabled(0) ..setSpeedBase(1)