package ch.asynk.rustanddust.game; import com.badlogic.gdx.utils.Disposable; import com.badlogic.gdx.math.Vector3; import ch.asynk.rustanddust.RustAndDust; import ch.asynk.rustanddust.ui.Position; import ch.asynk.rustanddust.game.State.StateType; import ch.asynk.rustanddust.game.states.StateSelect; import ch.asynk.rustanddust.game.states.StateMove; import ch.asynk.rustanddust.game.states.StateRotate; import ch.asynk.rustanddust.game.states.StatePromote; import ch.asynk.rustanddust.game.states.StateEngage; import ch.asynk.rustanddust.game.states.StateBreak; import ch.asynk.rustanddust.game.states.StateAnimation; import ch.asynk.rustanddust.game.states.StateReinforcement; import ch.asynk.rustanddust.game.states.StateDeployment; import ch.asynk.rustanddust.game.states.StateWithdraw; public class Ctrl implements Disposable { private final RustAndDust game; public final Battle battle; public Map map; public Hud hud; public Config cfg; public Player player; public Player opponent; public boolean blockMap; public boolean blockHud; public Vector3 mapTouch = new Vector3(); public Vector3 hudTouch = new Vector3(); private State selectState; private State pathState; private State rotateState; private State promoteState; private State engageState; private State breakState; private State animationState; private State reinforcementState; private State deploymentState; private State withdrawState; private int animationCount = 0; private State state; private StateType stateType; private StateType stateAfterAnimation; public Ctrl(final RustAndDust game, final Battle battle) { this.game = game; this.battle = battle; this.cfg = game.config; game.ctrl = this; battle.init(); this.map = battle.getMap(); battle.setup(this, map); this.map.init(); this.player = battle.getPlayer(); this.opponent = battle.opponent(player); this.selectState = new StateSelect(this, map); this.pathState = new StateMove(); this.rotateState = new StateRotate(); this.promoteState = new StatePromote(); this.engageState = new StateEngage(); this.breakState = new StateBreak(); this.animationState = new StateAnimation(); this.reinforcementState = new StateReinforcement(); this.deploymentState = new StateDeployment(); this.withdrawState = new StateWithdraw(); this.state = selectState; this.stateType = StateType.DONE; this.hud = new Hud(this, game); this.blockMap = false; this.blockHud = false; hud.notify(battle.toString(), 2, Position.MIDDLE_CENTER, false); startPlayerTurn(); } @Override public void dispose() { hud.dispose(); map.dispose(); } public Player getPlayer(Army army) { return (player.is(army) ? player : opponent); } public boolean isInAction() { return (state != selectState); } public void animationsOver() { if (hud.dialogActive()) return; if (stateType == StateType.ANIMATION) leaveAnimationState(); } private void leaveAnimationState() { StateType tmp = stateAfterAnimation; stateAfterAnimation = StateType.DONE; setState(tmp); } private void startPlayerTurn() { player.turnStart(); // hud.notify(player.getName() + "'s turn", 2, Position.MIDDLE_CENTER, true); if (battle.getReinforcement(this, map)) hud.notify("You have reinforcement", 2, Position.MIDDLE_CENTER, true); hud.update(); setState(battle.getState(player)); } private void endPlayerTurn() { player.turnEnd(); Player winner = battle.checkVictory(this); if (winner != null) hud.victory(winner, ((winner == player) ? opponent : player)); } private StateType actionAborted() { hud.notify("Action canceled"); StateType nextState = this.state.abort(); if (nextState == StateType.ABORT) nextState = battle.getState(player); return nextState; } private void turnDone() { map.turnDone(); endPlayerTurn(); player = battle.getPlayer(); opponent = battle.opponent(player); startPlayerTurn(); } private StateType actionDone() { StateType nextState = this.state.execute(); if (nextState == StateType.DONE) { map.actionDone(); if (map.unitsActivatedSize() > 0) { RustAndDust.debug("Ctrl", "burn down 1AP"); hud.notify("1 Action Point burnt", 0.6f, Position.BOTTOM_CENTER, false); player.burnDownOneAp(); hud.update(); } if (player.apExhausted()) hud.notifyNoMoreAP(); } if (nextState == StateType.DONE) nextState = battle.getState(player); return nextState; } private StateType deploymentDone() { map.actionDone(); return this.state.execute(); } public void setState(StateType nextState) { if (nextState == StateType.ABORT) nextState = actionAborted(); else if (nextState == StateType.DONE) { if (stateType == StateType.DEPLOYMENT) nextState = deploymentDone(); else nextState = actionDone(); } if (stateType == StateType.ANIMATION) { this.blockMap = hud.dialogActive(); } hud.playerInfo.blockEndOfTurn(nextState != StateType.SELECT); this.state.leave(nextState); RustAndDust.debug("Ctrl", String.format(" %s -> %s : %s", stateType, nextState, player)); switch(nextState) { case SELECT: this.state = selectState; break; case MOVE: this.state = pathState; break; case ROTATE: this.state = rotateState; break; case PROMOTE: this.state = promoteState; break; case ENGAGE: this.state = engageState; break; case BREAK: this.state = breakState; break; case WITHDRAW: this.state = withdrawState; break; case ANIMATION: this.blockMap = true; this.state = animationState; break; case REINFORCEMENT: this.state = reinforcementState; break; case DEPLOYMENT: this.state = deploymentState; break; default: break; } StateType tmp = stateType; stateType = nextState; this.state.enter(tmp); } public boolean drag(int dx, int dy) { if (!blockHud && hud.drag(hudTouch.x, hudTouch.y, dx, dy)) return true; return false; } public void touchDown() { if (!blockHud && hud.touchDown(hudTouch.x, hudTouch.y)) return; if (!blockMap && state.downInMap(mapTouch.x, mapTouch.y)) state.touchDown(); } public void touchUp() { if (!blockHud && hud.touchUp(hudTouch.x, hudTouch.y)) return; if (!blockMap && state.upInMap(mapTouch.x, mapTouch.y)) state.touchUp(); } public void stateTouchUp() { state.downInMap(-1, -1); state.upInMap(-1, -1); state.touchUp(); } public boolean isInAnimation() { return (this.stateType == StateType.ANIMATION); } public void setAfterAnimationState(StateType after) { stateAfterAnimation = after; } public boolean checkDeploymentDone() { boolean done = battle.deploymentDone(player); if (done) hud.askEndDeployment(); return done; } public void reinforcementHit() { if (this.stateType == StateType.SELECT) setState(StateType.REINFORCEMENT); else if (this.stateType == StateType.REINFORCEMENT) setState(StateType.SELECT); } // Hud callbacks public void engagementPanelClosed() { if (animationCount == 0) leaveAnimationState(); } public void endDeployment() { setState(StateType.DONE); turnDone(); } public void endGame() { game.switchToMenu(); } public void endPlayerTurn(boolean abort) { if (abort) state.abort(); turnDone(); } public void exitBoard(boolean doit) { if (doit) setState(StateType.DONE); else setState(StateType.ABORT); } }