class PlayDirector : AbstractDirector { static var instance : PlayDirector // UDLR or NSEW to move. // x to switch to the next player. // udlr or nsew to move, but do not wait for it to succeed (can be used as a 1 tick delay if next to a wall) @Attribute( rows=15 ) var cheatInstructions = "" @Attribute(rows=3) var sceneTitle = "" var cheat : Input var restart : Input var quit : Input var mainStage : GridStage var extraStage : GameStage var glassStage : GameStage var mainView : StageView var extraView : StageView var glassView : StageView var valuables = 0 var cheatEnabled = false var cheatParts = listOf() var players = listOf() var player : Player = null // Set by TestDirector, XORTestDirector, CQTestDirector var tester : Tester = null init { instance = this } override fun sceneLoaded() { super.sceneLoaded() val inputs = Resources.instance.inputs cheat = inputs.find( "cheat" ) restart = inputs.find( "restart" ) quit = inputs.find( "quit" ) mainStage = Game.instance.scene.findStage( "main" ) as GridStage extraStage = Game.instance.scene.findStage( "extra" ) as GameStage glassStage = Game.instance.scene.findStage( "glass" ) as GameStage mainView = Game.instance.scene.findStageView( "main" ) extraView = Game.instance.scene.findStageView( "extra" ) glassView = Game.instance.scene.findStageView( "glass" ) } override fun begin() { super.begin() Game.instance.mergeScene( glassScene() ) mainView.centerView() extraView.centerView() singlePlayer() } override fun activated() { super.activated() if ( (tester != null) || cheat.isPressed() ) { if ( cheatInstructions != "" ) { cheatEnabled = true cheatParts = cheatInstructions.replaceAll( "\n", "" ).splitTerminator( "x" ).toList() cheatPart() } } } // CQDirector overrides this to give a different glass when playing Cavern Quest. fun glassScene() = "glass" override fun tick() { if (cheatEnabled && player.autoInstructions == "" && !player.isMoving()) { wakeUpNextPlayer() cheatPart() } if ( player != null ) { scrollToPlayer( player, false ) } if ( tester != null ) { tester.tick() } super.tick() } fun cheatPart() { if (player == null) { cheatEnabled = false return } if (cheatParts.size() > 0) { player.autoInstructions = cheatParts[0].trim() cheatParts.remove(0) if ( cheatParts.size() == 0 ) { cheatEnabled = false } } } fun playerDied( player : Player ) { players.remove( player ) if ( players.size() > 0 ) { this.player = players[0] this.player.wakeUp() } else { val restartNotice = glassStage.findActorByName( "restartNotice" ) val escapeNotice = glassStage.findActorByName( "escapeNotice" ) if (restartNotice != null) { (restartNotice.role as Notice).show() } if (escapeNotice != null) { (escapeNotice.role as Notice).show() } } } fun wakeUpNextPlayer() { if ( players.size() > 1 ) { val i = ( players.indexOf( player ) + 1 ) % players.size() player.fallAsleep() player = players[i] player.wakeUp() } } fun singlePlayer() { if (extraStage.findRoleByClass( Test ) == null) { // This is a regular scene. Only one player is awake at a time players = mainStage.findRolesByClass( Player ) for ( p in players) { if (player == null) { player = p scrollToPlayer( player, true ) } else { p.fallAsleep() } } } else { // This is a "tests" scene, where all players are activated at the same time players = mainStage.findRolesByClass( Player ) player = mainStage.findRoleByClass( Player ) } } fun scrollToPlayer( player : Player, jump : boolean ) { scrollTo( player.actor.x + player.offsetX * player.gridSize(), player.actor.y + player.offsetY * player.gridSize(), jump ) } fun scrollTo( x : double, y : double , jump : boolean ) { if ( jump ) { mainView.worldFocal.x = x mainView.worldFocal.y = y } else { val dx = x - mainView.worldFocal.x val dy = y - mainView.worldFocal.y val delta = Math.sqrt( dx * dx + dy * dy ) val change = if (delta > 10) Math.sqrt(10 / delta) else 1 mainView.worldFocal.x += dx * change mainView.worldFocal.y += dy * change } extraView.worldFocal.x = mainView.worldFocal.x extraView.worldFocal.y = mainView.worldFocal.y } override fun onKey( event : KeyEvent ) { if ( tester != null ) { tester.onKey( event ) } if (restart.matches( event ) ) { Game.instance.startScene( Game.instance.sceneName ) } else if ( quit.matches( event ) ) { if ( Game.instance.sceneName == "hub" ) { Game.instance.quit() } else { Game.instance.startScene( "hub" ) } } } }