From 95d0131cb9733d273b81bf63a8778dc2b8e0a414 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Zurcher?= Date: Wed, 13 Apr 2016 23:44:53 +0200 Subject: WIP --- TODO | 11 +- core/src/ch/asynk/rustanddust/game/Config.java | 2 +- core/src/ch/asynk/rustanddust/game/Ctrl.java | 480 +++++++++++---------- core/src/ch/asynk/rustanddust/game/Hud.java | 12 +- core/src/ch/asynk/rustanddust/game/Map.java | 5 +- core/src/ch/asynk/rustanddust/game/Order.java | 31 +- core/src/ch/asynk/rustanddust/game/State.java | 22 +- .../rustanddust/game/battles/BattleCommon.java | 11 +- core/src/ch/asynk/rustanddust/game/ctrl/Solo.java | 2 +- .../asynk/rustanddust/game/hud/ActionButtons.java | 14 +- .../ch/asynk/rustanddust/game/hud/PlayerInfo.java | 4 +- .../ch/asynk/rustanddust/game/map/Map2Moves.java | 12 - .../asynk/rustanddust/game/map/Map3Animations.java | 4 +- .../ch/asynk/rustanddust/game/map/Map4Orders.java | 389 ++++++++++++----- .../rustanddust/game/states/StateAnimation.java | 22 +- .../asynk/rustanddust/game/states/StateBreak.java | 76 ---- .../asynk/rustanddust/game/states/StateCommon.java | 28 +- .../rustanddust/game/states/StateDeployment.java | 107 +++-- .../asynk/rustanddust/game/states/StateEngage.java | 173 +++++--- .../asynk/rustanddust/game/states/StateMove.java | 313 +++++++++----- .../rustanddust/game/states/StatePromote.java | 24 +- .../game/states/StateReinforcement.java | 118 +++-- .../asynk/rustanddust/game/states/StateReplay.java | 80 ++-- .../asynk/rustanddust/game/states/StateRotate.java | 103 ----- .../asynk/rustanddust/game/states/StateSelect.java | 128 +++--- .../rustanddust/game/states/StateWithdraw.java | 64 --- core/src/ch/asynk/rustanddust/util/DB.java | 17 +- 27 files changed, 1217 insertions(+), 1035 deletions(-) delete mode 100644 core/src/ch/asynk/rustanddust/game/states/StateBreak.java delete mode 100644 core/src/ch/asynk/rustanddust/game/states/StateRotate.java delete mode 100644 core/src/ch/asynk/rustanddust/game/states/StateWithdraw.java diff --git a/TODO b/TODO index 74d09f8..57ff14e 100644 --- a/TODO +++ b/TODO @@ -1,8 +1,17 @@ FIX: + - Order.orderId ??? + - clean up Map4 from activated, activable stuff, maybe should stay in states !?!? + - check unitId (static) after reinforcement arrive !!! + - after JSON load Unit.unitId must be set to max() + - load last turn synched - fix shoot animations, quit -> resume + - Orders boolean:replay, [if needed : id->seq(hq activation->same seq)] + - public Order map.prepareYxzOrder( ) + - postOrder() + - ctrl set ANIMATION state + map.processOrder() -> save if not replay + - at ANIMATION END, pay AP if needed (order.cost) ... TODO: - - check revert - turret aiming sound - moving cloudy sky overlay - Rules diff --git a/core/src/ch/asynk/rustanddust/game/Config.java b/core/src/ch/asynk/rustanddust/game/Config.java index 318eae9..f730360 100644 --- a/core/src/ch/asynk/rustanddust/game/Config.java +++ b/core/src/ch/asynk/rustanddust/game/Config.java @@ -103,7 +103,7 @@ public class Config this.gameMode = GameMode.SOLO; this.loadMode = LoadMode.LOAD; this.debug = false; - this.autoPath = true; + this.autoPath = false; this.revertAllMoves = false; this.showMoves = true; this.showTargets = true; diff --git a/core/src/ch/asynk/rustanddust/game/Ctrl.java b/core/src/ch/asynk/rustanddust/game/Ctrl.java index 6ec7184..a5807d0 100644 --- a/core/src/ch/asynk/rustanddust/game/Ctrl.java +++ b/core/src/ch/asynk/rustanddust/game/Ctrl.java @@ -18,32 +18,49 @@ import ch.asynk.rustanddust.game.State.StateType; import ch.asynk.rustanddust.game.states.StateCommon; 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; +// import ch.asynk.rustanddust.game.states.StateReinforcement; import ch.asynk.rustanddust.game.states.StateReplay; public abstract class Ctrl implements Disposable { - public enum EventType + + private static final boolean debugCtrl = true; + + public enum MsgType { - STATE_CHANGE, - HUD_ANSWER, + OK, + CANCEL, + PROMOTE, ANIMATIONS_DONE, + UNIT_DOCK_SELECT, UNIT_DOCK_TOGGLE, - UNIT_DOCK_SELECT; + UNIT_DEPLOYED, + } + + public enum EventType + { + ORDER, + ORDER_DONE, + STATE_CHANGE, + ANIMATED_STATE_CHANGE, + REPLAY_STEP, + REPLAY_DONE, + TURN_DONE, + // ACTION_DONE, + ACTION_ABORTED, + EXIT_BATTLE, } class Event { public EventType type; public Object data; - public boolean status; + @Override + public String toString() { return String.format("Event : %s - %s", type, (data == null) ? "" : data); } } public final RustAndDust game; @@ -61,20 +78,17 @@ public abstract class Ctrl implements Disposable protected boolean synched; private int depth; + private Order lastOrder; + private final State selectState; - private final State pathState; - private final State rotateState; + private final State moveState; private final State promoteState; private final State engageState; - private final State breakState; private final State animationState; - private final State reinforcementState; private final State deploymentState; - private final State withdrawState; + // private final State reinforcementState; private final State replayState; - private int animationCount = 0; - private State state; private StateType stateType; private StateType stateAfterAnimation; @@ -108,16 +122,15 @@ public abstract class Ctrl implements Disposable this.synched = false; this.depth = 0; + this.lastOrder = null; + this.selectState = new StateSelect(); - this.pathState = new StateMove(); - this.rotateState = new StateRotate(); + this.moveState = new StateMove(); 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.reinforcementState = new StateReinforcement(); this.replayState = new StateReplay(); this.stateType = StateType.LOADING; @@ -129,12 +142,11 @@ public abstract class Ctrl implements Disposable hud.update(); this.state = selectState; - this.stateType = StateType.DONE; - this.stateAfterAnimation = StateType.DONE; - - setState(battle.getState()); + this.stateType = StateType.WAIT_EVENT; + this.stateAfterAnimation = StateType.WAIT_EVENT; if (synched) { + setState(battle.getState()); this.hud.notify(battle.toString(), 2, Position.MIDDLE_CENTER, false); return; } @@ -152,7 +164,6 @@ public abstract class Ctrl implements Disposable setState(StateType.REPLAY); break; } - } @Override @@ -174,6 +185,7 @@ public abstract class Ctrl implements Disposable protected void load(Marshal.Mode mode, String payload) { + if (payload == null) return; JsonValue root = new JsonReader().parse(payload); battle.load(mode, root); } @@ -199,9 +211,7 @@ public abstract class Ctrl implements Disposable public void touchDown(float hudX, float hudY, float mapX, float mapY) { - boolean inAnimation = (this.stateType == StateType.ANIMATION); - - if (!blockHud && hud.hit(hudX, hudY, inAnimation)) + if (!blockHud && hud.hit(hudX, hudY, inAnimation())) return; touchedHex = (blockMap ? null : map.getHexAt(mapX, mapY)); @@ -213,34 +223,73 @@ public abstract class Ctrl implements Disposable state.touch(touchedHex); } - // EVENTS + // MESSAGES - private Event getEvent() + public void sendMsg(MsgType msgType) { - Event evt = freeEvents.pop(); - if (evt == null) - evt = new Event(); - return evt; + sendMsg(msgType, null); } - public void postDone() { post(StateType.DONE); } - public void postAbort() { post(StateType.ABORT); } + public void sendMsg(MsgType msgType, Object data) + { + switch(msgType) { + case ANIMATIONS_DONE: + animationsDone(); + break; + case UNIT_DOCK_TOGGLE: + unitDockToggle(); + break; + case UNIT_DEPLOYED: + deploymentState.processMsg(msgType, data); + break; + default: + if (!this.state.processMsg(msgType, data)) + RustAndDust.error(String.format("%s does not handle msg : %s %s", this.state, msgType, data)); + break; + } + } + + // EVENTS + + public void postReplayDone() { postEvent(EventType.REPLAY_DONE); } + public void postTurnDone() { postEvent(EventType.TURN_DONE); } + // public void postActionDone() { postEvent(EventType.ACTION_DONE); } + public void postActionAborted() { postEvent(EventType.ACTION_ABORTED); } public void post(StateType stateType) { - Event evt = getEvent(); - evt.type = EventType.STATE_CHANGE; - evt.data = stateType; - events.enqueue(evt); + postEvent(EventType.STATE_CHANGE, stateType); + } + + // public void postTransitionTo(StateType stateType) + // { + // postEvent(EventType.ANIMATED_STATE_CHANGE, stateType); + // } + + // public void postTransitionToDone() + // { + // postEvent(EventType.ANIMATED_STATE_CHANGE, StateType.WAIT_EVENT); + // postEvent(EventType.ACTION_DONE); + // } + + // public void postTransitionToAborted() + // { + // postEvent(EventType.ANIMATED_STATE_CHANGE, StateType.WAIT_EVENT); + // postEvent(EventType.ACTION_ABORTED); + // } + + public void postOrder(Order order) + { + postOrder(order, null); } - public void postAnswer(Hud.OkCancelAction what, boolean status) + public void postOrder(Order order, StateType stateType) { - Event evt = getEvent(); - evt.type = EventType.HUD_ANSWER; - evt.data = what; - evt.status = status; - events.enqueue(evt); + postEvent(EventType.ORDER, order); + // FIXME maybe use postActionDone() + if (order.type != Order.OrderType.END) + postEvent(EventType.ANIMATED_STATE_CHANGE, StateType.WAIT_EVENT); + postEvent(EventType.ORDER_DONE, stateType); } public void postEvent(EventType type) @@ -250,7 +299,9 @@ public abstract class Ctrl implements Disposable public void postEvent(EventType type, Object data) { - Event evt = getEvent(); + Event evt = freeEvents.pop(); + if (evt == null) + evt = new Event(); evt.type = type; evt.data = data; events.enqueue(evt); @@ -258,25 +309,43 @@ public abstract class Ctrl implements Disposable public void processEvent() { - if (events.size() <= 0) + if ((events.size() <= 0) || inAnimation()) return; Event evt = events.dequeue(); + RustAndDust.debug(evt.toString()); switch(evt.type) { + case ORDER: + lastOrder = (Order) evt.data; + map.execute(lastOrder); + break; + case ORDER_DONE: + orderDone((StateType) evt.data); + break; case STATE_CHANGE: setState((StateType) evt.data); break; - case HUD_ANSWER: - handleHudAnswer(evt); + case ANIMATED_STATE_CHANGE: + stateAfterAnimation = (StateType) evt.data; + setState(StateType.ANIMATION); break; - case ANIMATIONS_DONE: - animationsDone(); + case REPLAY_STEP: + replayStep((boolean) evt.data); break; - case UNIT_DOCK_TOGGLE: - unitDockToggle(); + case REPLAY_DONE: + replayDone(); + break; + case TURN_DONE: + turnDone(); + break; + // case ACTION_DONE: + // actionDone(); + // break; + case ACTION_ABORTED: + abortAction(); break; - case UNIT_DOCK_SELECT: - unitDockSelect((Unit) evt.data); + case EXIT_BATTLE: + exitBattle(); break; default: RustAndDust.error(String.format("Unhandled Event Type : %s %s", evt.type, evt.data)); @@ -284,243 +353,186 @@ public abstract class Ctrl implements Disposable freeEvents.push(evt); } - // State callbacks - - public void setAfterAnimationState(StateType after) - { - stateAfterAnimation = after; - } - - // Event handlers - - private void handleHudAnswer(Event evt) + private boolean inAnimation() { - switch((Hud.OkCancelAction) evt.data) { - case EXIT_BOARD: - if (evt.status) setState(StateType.DONE); - else setState(StateType.ABORT); - break; - case ABORT_TURN: - if (evt.status) { - this.state.abort(); - turnDone(); - } - break; - case END_DEPLOYMENT: - if (evt.status) { - this.state.execute(); - turnDone(); - } - break; - case QUIT_BATTLE: - if (evt.status) - game.switchToMenu(); - break; - - } + return (this.stateType == StateType.ANIMATION); } private void animationsDone() { + if (debugCtrl) RustAndDust.debug("ANIMATIONS DONE"); if (hud.dialogActive()) hud.notifyAnimationsDone(); if (stateType == StateType.ANIMATION) { + sendMsg(MsgType.OK, null); StateType tmp = stateAfterAnimation; - stateAfterAnimation = StateType.DONE; + stateAfterAnimation = StateType.WAIT_EVENT; setState(tmp); } } - private void unitDockSelect(Unit unit) + private void replayStep(boolean burnAp) { - if ((stateType == StateType.DEPLOYMENT) || (stateType == StateType.REINFORCEMENT)) - state.touch(null); + if (debugCtrl) RustAndDust.debug("REPLAY STEP --> burn down 1 AP " + burnAp); + if (burnAp) + battle.getPlayer().burnDownOneAp(); + map.actionDone(); + hud.update(); } - private void unitDockToggle() + private void replayDone() { - if (this.stateType == StateType.SELECT) - setState(StateType.REINFORCEMENT); - else if (this.stateType == StateType.REINFORCEMENT) - setState(StateType.SELECT); + if (debugCtrl) RustAndDust.debug("REPLAY DONE --> check turn change"); + if (battle.getPlayer().apExhausted()) + postTurnDone(); + else if (!battle.getPlayer().canDoSomething()) + postTurnDone(); + else + post(battle.getState()); } - // + private void orderDone(StateType nextState) + { + if (debugCtrl) RustAndDust.debug("ORDER DONE"); + + if (lastOrder.cost == 0) { + post((nextState == null) ? battle.getState() : nextState); + return; + } + + battle.getPlayer().burnDownOneAp(); + hud.notify("1 Action Point burnt"); + hud.update(); + + if (battle.getPlayer().apExhausted()) { + hud.notify("No more Action Points"); + postTurnDone(); + } else if (!battle.getPlayer().canDoSomething()) { + hud.notify("No available Actions"); + postTurnDone(); + } else { + post((nextState == null) ? battle.getState() : nextState); + } + } + + // private void actionDone() + // { + // if (debugCtrl) RustAndDust.debug("ACTION DONE"); + // if (battle.actionDone()) { + // hud.notify("1 Action Point burnt"); + // hud.update(); + // } + + // if (battle.getPlayer().apExhausted()) { + // hud.notify("No more Action Points"); + // postTurnDone(); + // } else if (!battle.getPlayer().canDoSomething()) { + // hud.notify("No available Actions"); + // postTurnDone(); + // } else { + // post(battle.getState()); + // } + // } private void turnDone() { - if (battle.turnDone()) + if (debugCtrl) RustAndDust.debug("TURN DONE"); + if (battle.turnDone()) { hud.victory(battle.getPlayer(), battle.getOpponent()); + // FIXME BATTLE OVER + } else { if (battle.getPlayer().hasReinforcement()) hud.notify("You have reinforcement", 2, Position.MIDDLE_CENTER, true); hud.update(); if (!battle.getPlayer().canDoSomething()) { hud.notify("No available Actions"); - setState(StateType.TURN_OVER); - } else - setState(battle.getState()); + // FIXME DOUBLE TURN DONE + postTurnDone(); + } else { + post(battle.getState()); + } } } - // - - private void setState(StateType nextState) + private void abortAction() { - depth += 1; - if (depth > 1) - RustAndDust.error(String.format("***!!!*** STATE DEPTH : %d", depth)); - - if (nextState == StateType.ABORT) - nextState = abortAction(); - else if (nextState == StateType.DONE) { - nextState = complete(); - } - - if (stateType == StateType.ANIMATION) { - this.blockMap = hud.dialogActive(); - if (nextState == StateType.REPLAY) - completeReplayStep(); - } - - hud.playerInfo.blockEndOfTurn(nextState != StateType.SELECT); - - if (nextState == stateType) - RustAndDust.debug(String.format("***!!!*** STATE LOOP : %s", stateType)); - - this.state.leaveFor(nextState); - - this.state = getNextState(nextState); - - StateType tmp = stateType; - stateType = nextState; - - this.state.enterFrom(tmp); - - if (nextState == StateType.TURN_OVER) - turnDone(); - depth -= 1; + if (debugCtrl) RustAndDust.debug("ABORT ACTION"); + // sendMsg(MsgType.CANCEL); this will loop + post(battle.getState()); } - private StateType complete() + private void exitBattle() { - switch(stateType) { - case DEPLOYMENT: - return completeDeployment(); - case REPLAY: - return completeReplay(); - default: - return completeAction(); - } + if (debugCtrl) RustAndDust.debug("EXIT BATTLE"); + System.err.println("FIXME exitBattle NOT IMPLEMENTED YET"); } - private StateType completeDeployment() + private void unitDockToggle() { - if (battle.isDeploymentDone()) - hud.askEndDeployment(); - battle.actionDone(); - return StateType.DEPLOYMENT; + // if (this.stateType == StateType.SELECT) + // post(StateType.REINFORCEMENT); + // else if (this.stateType == StateType.REINFORCEMENT) { + // sendMsg(MsgType.OK); + // post(StateType.SELECT); + // } } - private StateType abortAction() + // + + private void setState(StateType nextState) { - hud.notify("Action canceled"); - StateType nextState = this.state.abort(); + if (stateType == nextState) { + RustAndDust.error(String.format("***!!!*** STATE LOOP : %d", depth)); + return; + } - if (nextState == StateType.ABORT) - nextState = battle.getState(); + if (nextState == StateType.WAIT_EVENT) { + stateType = nextState; + if (debugCtrl) RustAndDust.debug("WAIT_EVENT"); + return; + } - return nextState; - } + depth += 1; + if (depth > 1) + RustAndDust.error(String.format("***!!!*** STATE DEPTH : %d", depth)); - private StateType completeAction() - { - StateType nextState = this.state.execute(); + // FIXME handle corner cases (is ok here ?) - if (nextState == StateType.DONE) { - if (battle.actionDone()) { - hud.notify("1 Action Point burnt"); - hud.update(); - } - if (battle.getPlayer().apExhausted()) { - hud.notify("No more Action Points"); - nextState = StateType.TURN_OVER; - } else if (!battle.getPlayer().canDoSomething()) { - hud.notify("No available Actions"); - nextState = StateType.TURN_OVER; - } else - nextState = battle.getState(); + if (nextState == StateType.DEPLOYMENT) { + if (battle.isDeploymentDone()) + hud.askEndDeployment(); } - return nextState; - } + // - private StateType completeReplay() - { - if (battle.getPlayer().apExhausted()) { - return StateType.TURN_OVER; - } else if (!battle.getPlayer().canDoSomething()) { - return StateType.TURN_OVER; - } else - return battle.getState(); - } + hud.playerInfo.blockEndOfTurn(nextState != StateType.SELECT); - private void completeReplayStep() - { - StateType nextState = replayState.execute(); + this.state = getNextState(nextState); + StateType tmp = stateType; + stateType = nextState; + this.state.enterFrom(tmp); - if (nextState == StateType.DONE) { - battle.getPlayer().burnDownOneAp(); - hud.update(); - } + depth -= 1; } private State getNextState(StateType nextState) { - RustAndDust.debug("Ctrl", String.format(" %s -> %s : %s", stateType, nextState, battle.getPlayer())); - - State state = this.state; + RustAndDust.debug("Ctrl", String.format("%s -> %s : %s", stateType, nextState, battle.getPlayer())); switch(nextState) { - case SELECT: - state = selectState; - break; - case MOVE: - state = pathState; - break; - case ROTATE: - state = rotateState; - break; - case PROMOTE: - state = promoteState; - break; - case ENGAGE: - state = engageState; - break; - case BREAK: - state = breakState; - break; - case WITHDRAW: - state = withdrawState; - break; - case ANIMATION: - state = animationState; - this.blockMap = true; - break; - case REINFORCEMENT: - state = reinforcementState; - break; - case DEPLOYMENT: - state = deploymentState; - break; - case REPLAY: - state = replayState; - break; + case SELECT: return selectState; + case MOVE: return moveState; + case PROMOTE: return promoteState; + case ENGAGE: return engageState; + case ANIMATION: return animationState; + case DEPLOYMENT: return deploymentState; + // case REINFORCEMENT: return reinforcementState; + case REPLAY: return replayState; default: RustAndDust.error(String.format("Unhandled State : %s", nextState)); - break; } - return state; + return this.state; } } diff --git a/core/src/ch/asynk/rustanddust/game/Hud.java b/core/src/ch/asynk/rustanddust/game/Hud.java index d8c112c..f905af9 100644 --- a/core/src/ch/asynk/rustanddust/game/Hud.java +++ b/core/src/ch/asynk/rustanddust/game/Hud.java @@ -218,12 +218,16 @@ public class Hud implements Disposable, Animation dialog.visible = false; if (dialog == okCancel) { - if (okCancel.ok) game.playEnter(); - else game.playType(); - ctrl.postAnswer(okCancelAction, okCancel.ok); + if (okCancel.ok) { + game.playEnter(); + ctrl.sendMsg(Ctrl.MsgType.OK); + } else { + game.playType(); + ctrl.sendMsg(Ctrl.MsgType.CANCEL); + } } else if (dialog == stats) { game.playEnter(); - ctrl.postAnswer(OkCancelAction.EXIT_BATTLE, true); + ctrl.postEvent(Ctrl.EventType.EXIT_BATTLE); } else game.playType(); diff --git a/core/src/ch/asynk/rustanddust/game/Map.java b/core/src/ch/asynk/rustanddust/game/Map.java index f55b8fd..685a5b1 100644 --- a/core/src/ch/asynk/rustanddust/game/Map.java +++ b/core/src/ch/asynk/rustanddust/game/Map.java @@ -32,15 +32,16 @@ public abstract class Map extends Map5Marshal public void actionDone() { - incActionId(); game.ctrl.actionDoneCb(); + clearAll(); } public void turnDone() { RustAndDust.debug("TurnDone", String.format(" Processed Orders : %d", ordersSize())); - game.ctrl.turnDoneCb(); + clearAll(); ordersClear(); + game.ctrl.turnDoneCb(); } @Override diff --git a/core/src/ch/asynk/rustanddust/game/Order.java b/core/src/ch/asynk/rustanddust/game/Order.java index aac0825..96b2bb7 100644 --- a/core/src/ch/asynk/rustanddust/game/Order.java +++ b/core/src/ch/asynk/rustanddust/game/Order.java @@ -7,12 +7,17 @@ import ch.asynk.rustanddust.engine.Move; public class Order implements Disposable, Pool.Poolable, Comparable { + public static int orderId = 1; + + public static final Order END = new Order(OrderType.END); + public enum OrderType { NONE, MOVE, ENGAGE, - PROMOTE; + PROMOTE, + END, } private static final Pool orderPool = new Pool() @@ -36,6 +41,7 @@ public class Order implements Disposable, Pool.Poolable, Comparable public int id; public int cost; + public boolean replay; public Unit unit; public OrderType type; public Move move; @@ -47,6 +53,12 @@ public class Order implements Disposable, Pool.Poolable, Comparable reset(); } + private Order(OrderType type) + { + this(); + this.type = type; + } + @Override public void dispose() { @@ -56,8 +68,12 @@ public class Order implements Disposable, Pool.Poolable, Comparable @Override public void reset() { - this.type = OrderType.NONE; + this.id = orderId; + orderId += 1; + this.cost = 1; + this.replay = false; this.unit = null; + this.type = OrderType.NONE; this.activable.clear(); if (this.move != null) { this.move.dispose(); @@ -85,27 +101,30 @@ public class Order implements Disposable, Pool.Poolable, Comparable @Override public String toString() { - return String.format("[%d] %s : %s", id, type, unit.code); + if (type == OrderType.END) + return String.format("[00] END"); + else + return String.format("[%d] %s(%d) : %s", id, type, cost, unit.code); } public void setMove(Unit unit, Move move) { + this.unit = unit; this.type = OrderType.MOVE; this.move = move; - this.unit = unit; } public void setPromote(Unit unit) { - this.type = OrderType.PROMOTE; this.unit = unit; + this.type = OrderType.PROMOTE; } public void setEngage(Unit unit, Unit target) { + this.unit = unit; this.type = OrderType.ENGAGE; this.engagement = Engagement.get(unit, target); - this.unit = unit; } public void setActivable(UnitList l) diff --git a/core/src/ch/asynk/rustanddust/game/State.java b/core/src/ch/asynk/rustanddust/game/State.java index a3a6fec..fc22d72 100644 --- a/core/src/ch/asynk/rustanddust/game/State.java +++ b/core/src/ch/asynk/rustanddust/game/State.java @@ -1,32 +1,26 @@ package ch.asynk.rustanddust.game; +import ch.asynk.rustanddust.game.Ctrl.MsgType; + public interface State { - enum StateType { + enum StateType + { LOADING, REPLAY, + WAIT_EVENT, SELECT, MOVE, - ROTATE, ENGAGE, - BREAK, PROMOTE, ANIMATION, REINFORCEMENT, DEPLOYMENT, - WITHDRAW, - ABORT, - DONE, - TURN_OVER }; - public void enterFrom(StateType prevState); - - public void leaveFor(StateType nextState); - - public StateType abort(); + public void touch(Hex hex); - public StateType execute(); + public void enterFrom(StateType prevState); - public void touch(Hex hex); + public boolean processMsg(MsgType msg, Object data); } diff --git a/core/src/ch/asynk/rustanddust/game/battles/BattleCommon.java b/core/src/ch/asynk/rustanddust/game/battles/BattleCommon.java index e7bcac5..ed6f52f 100644 --- a/core/src/ch/asynk/rustanddust/game/battles/BattleCommon.java +++ b/core/src/ch/asynk/rustanddust/game/battles/BattleCommon.java @@ -13,6 +13,7 @@ import ch.asynk.rustanddust.game.Map; import ch.asynk.rustanddust.game.Zone; import ch.asynk.rustanddust.game.Unit; import ch.asynk.rustanddust.game.Unit.UnitCode; +import ch.asynk.rustanddust.game.Order; import ch.asynk.rustanddust.game.Factory; import ch.asynk.rustanddust.game.State.StateType; import ch.asynk.rustanddust.engine.Orientation; @@ -104,9 +105,12 @@ public abstract class BattleCommon implements Battle { map.load(mode, value); if((mode == Marshal.Mode.FULL) || (mode == Marshal.Mode.STATE)) { + map.loadPlayers(value, players); JsonValue v = value.get("battle"); this.turnCount = v.getInt("turnCount"); - map.loadPlayers(value, players); + Unit.unitId = v.getInt("unitId"); + Order.orderId = v.getInt("orderId"); + System.err.println(Unit.unitId); } this.currentPlayer = players[0]; } @@ -118,6 +122,8 @@ public abstract class BattleCommon implements Battle if((mode == Marshal.Mode.FULL) || (mode == Marshal.Mode.STATE)) { json.writeObjectStart("battle"); json.writeValue("turnCount", turnCount); + json.writeValue("unitId", Unit.unitId); + json.writeValue("orderId", Order.orderId); json.writeObjectEnd(); map.unloadPlayers(json, getPlayer(), getOpponent()); } @@ -260,7 +266,8 @@ public abstract class BattleCommon implements Battle { Unit unit = factory.getUnit(unitCode, hq, ace); if (exitZone != null) unit.exitZone = exitZone; - map.setOnBoard(unit, map.getHex(col, row), orientation); + // map.setOnBoard(unit, map.getHex(col, row), orientation); + map.execute(map.getSetOrder(unit, map.getHex(col, row), orientation)); return unit; } } diff --git a/core/src/ch/asynk/rustanddust/game/ctrl/Solo.java b/core/src/ch/asynk/rustanddust/game/ctrl/Solo.java index 54d2310..02b5ee6 100644 --- a/core/src/ch/asynk/rustanddust/game/ctrl/Solo.java +++ b/core/src/ch/asynk/rustanddust/game/ctrl/Solo.java @@ -72,9 +72,9 @@ public class Solo extends Ctrl @Override protected void turnDoneCb() { + storeTurn(); storeOrders(); storeState(); - storeTurn(); } private void storeState() diff --git a/core/src/ch/asynk/rustanddust/game/hud/ActionButtons.java b/core/src/ch/asynk/rustanddust/game/hud/ActionButtons.java index 90ec017..e992867 100644 --- a/core/src/ch/asynk/rustanddust/game/hud/ActionButtons.java +++ b/core/src/ch/asynk/rustanddust/game/hud/ActionButtons.java @@ -6,7 +6,7 @@ import com.badlogic.gdx.graphics.glutils.ShapeRenderer; import ch.asynk.rustanddust.RustAndDust; import ch.asynk.rustanddust.game.Ctrl; -import ch.asynk.rustanddust.game.State.StateType; +import ch.asynk.rustanddust.game.Ctrl.MsgType; import ch.asynk.rustanddust.ui.Widget; import ch.asynk.rustanddust.ui.Bg; import ch.asynk.rustanddust.ui.Position; @@ -36,7 +36,7 @@ public class ActionButtons extends Widget private Sprite bg; private Bg buttons []; - private StateType states []; + private MsgType msgs []; public ActionButtons(RustAndDust game) { @@ -50,10 +50,10 @@ public class ActionButtons extends Widget this.buttons[Buttons.ABORT.i] = new Bg(game.factory.getHudRegion(game.factory.ACT_ABORT)); this.buttons[Buttons.PROMOTE.i] = new Bg(game.factory.getHudRegion(game.factory.ACT_PROMOTE)); - this.states = new StateType[Buttons.LAST.i]; - this.states[Buttons.DONE.i] = StateType.DONE; - this.states[Buttons.ABORT.i] = StateType.ABORT; - this.states[Buttons.PROMOTE.i] = StateType.PROMOTE; + this.msgs = new MsgType[Buttons.LAST.i]; + this.msgs[Buttons.DONE.i] = MsgType.OK; + this.msgs[Buttons.ABORT.i] = MsgType.CANCEL; + this.msgs[Buttons.PROMOTE.i] = MsgType.PROMOTE; } @Override @@ -135,7 +135,7 @@ public class ActionButtons extends Widget for (int i = 0; i < Buttons.LAST.i; i++) { if (buttons[i].hit(x, y)) { - ctrl.post(states[i]); + ctrl.sendMsg(msgs[i]); return true; } } diff --git a/core/src/ch/asynk/rustanddust/game/hud/PlayerInfo.java b/core/src/ch/asynk/rustanddust/game/hud/PlayerInfo.java index e96856f..8b67fb6 100644 --- a/core/src/ch/asynk/rustanddust/game/hud/PlayerInfo.java +++ b/core/src/ch/asynk/rustanddust/game/hud/PlayerInfo.java @@ -141,12 +141,12 @@ public class PlayerInfo implements Disposable, Drawable, Animation return true; } else if (reinforcement.hit(x, y)) { - ctrl.postEvent(Ctrl.EventType.UNIT_DOCK_TOGGLE); + ctrl.sendMsg(Ctrl.MsgType.UNIT_DOCK_TOGGLE); return true; } else if (unitDock.hit(x, y)) { ctrl.hud.notify(unitDock.selectedUnit.toString(), Position.TOP_CENTER); - ctrl.postEvent(Ctrl.EventType.UNIT_DOCK_SELECT, unitDock.selectedUnit); + ctrl.sendMsg(Ctrl.MsgType.UNIT_DOCK_SELECT, unitDock.selectedUnit); return true; } diff --git a/core/src/ch/asynk/rustanddust/game/map/Map2Moves.java b/core/src/ch/asynk/rustanddust/game/map/Map2Moves.java index e7ba8ce..c447da3 100644 --- a/core/src/ch/asynk/rustanddust/game/map/Map2Moves.java +++ b/core/src/ch/asynk/rustanddust/game/map/Map2Moves.java @@ -51,21 +51,9 @@ public abstract class Map2Moves extends Map1Units return 0; } - public void collectUpdate(Unit unit) - { - movesHide(); - unitsActivableHide(); - movesCollect(unit); - collectMoveable(unit); - movesShow(); - unitsActivableShow(); - activatedUnits.clear(); - } - public int pathsSize() { return paths.size(); } public void pathsClear() { paths.clear(); } public void pathsInit(Unit unit) { paths.init(unit); } - public void pathsInit(Unit unit, Hex hex) { paths.init(unit, hex); } public int pathsBuild(Hex hex) { return paths.build(hex); } public Hex pathsTo() { return (Hex) paths.to; } public void pathsSetOrientation(Orientation o) { paths.orientation = o; } diff --git a/core/src/ch/asynk/rustanddust/game/map/Map3Animations.java b/core/src/ch/asynk/rustanddust/game/map/Map3Animations.java index eba741b..63b3391 100644 --- a/core/src/ch/asynk/rustanddust/game/map/Map3Animations.java +++ b/core/src/ch/asynk/rustanddust/game/map/Map3Animations.java @@ -21,7 +21,7 @@ import ch.asynk.rustanddust.game.Hex; import ch.asynk.rustanddust.game.Unit; import ch.asynk.rustanddust.game.Army; import ch.asynk.rustanddust.game.Player; -import ch.asynk.rustanddust.game.Ctrl.EventType; +import ch.asynk.rustanddust.game.Ctrl.MsgType; public abstract class Map3Animations extends Map2Moves implements MoveToAnimationCb { @@ -142,6 +142,6 @@ public abstract class Map3Animations extends Map2Moves implements MoveToAnimatio addAnimation( SoundAnimation.get(SoundAnimation.Action.FADE_OUT, sound, soundId, game.config.fxVolume, 0.5f)); soundId = -1; } else - game.ctrl.postEvent(EventType.ANIMATIONS_DONE); + game.ctrl.sendMsg(MsgType.ANIMATIONS_DONE); } } diff --git a/core/src/ch/asynk/rustanddust/game/map/Map4Orders.java b/core/src/ch/asynk/rustanddust/game/map/Map4Orders.java index e3662e2..10684cb 100644 --- a/core/src/ch/asynk/rustanddust/game/map/Map4Orders.java +++ b/core/src/ch/asynk/rustanddust/game/map/Map4Orders.java @@ -17,7 +17,6 @@ public abstract class Map4Orders extends Map3Animations protected final OrderList orders; protected final OrderList replayOrders; - protected int orderId; protected abstract int engagementCost(Engagement e); protected abstract void resolveEngagement(Engagement e); @@ -25,7 +24,6 @@ public abstract class Map4Orders extends Map3Animations { super(game, map, hex); - this.orderId = 0; this.orders = new OrderList(10); this.replayOrders = new OrderList(10); } @@ -39,7 +37,6 @@ public abstract class Map4Orders extends Map3Animations Engagement.clearPool(); } - protected void incOrderId() { orderId += 1; } protected int ordersSize() { return orders.size(); } protected void ordersClear() { orders.dispose(); } @@ -50,33 +47,59 @@ public abstract class Map4Orders extends Map3Animations setPawnOnto(unit, to, o); } - public boolean setOnBoard(final Unit unit, Hex to, Orientation entry) + public Order getSetOrder(final Unit unit, final Hex to, final Orientation o) { - orders.dispose(unit); - return process(getMoveOrder(unit, Move.getSet(unit, to, entry))); + Order order = getMoveOrder(unit, Move.getSet(unit, to, o), false); + order.cost = 0; + + return order; } + // public boolean setOnBoard(final Unit unit, Hex to, Orientation entry) + // { + // // need to remove orders first when changing orientation + // orders.dispose(unit); + // return process(getMoveOrder(unit, Move.getSet(unit, to, entry))); + // } + public boolean enterBoard(final Unit unit, Hex to, int allowedMoves) { - Orientation entry = findBestEntry(unit, to, allowedMoves); - if (entry == Orientation.KEEP) - return false; + // FIXME enterBoard(...) + // Orientation entry = findBestEntry(unit, to, allowedMoves); + // if (entry == Orientation.KEEP) + // return false; - return process(getMoveOrder(unit, Move.getEnter(unit, to, entry))); + // return process(getMoveOrder(unit, Move.getEnter(unit, to, entry))); + return false; } - public boolean exitBoard(final Unit unit) + public Order getExitOrder(final Unit unit, boolean hqMode) { - return process(getMoveOrder(unit, paths.getExitMove())); + Order order = getMoveOrder(unit, paths.getExitMove(), hqMode); + + return order; } - public boolean moveUnit(final Unit unit) + // public boolean exitBoard(final Unit unit) + // { + // return process(getMoveOrder(unit, paths.getExitMove())); + // } + + public Order getMoveOrder(final Unit unit, boolean hqMode) { - return process(getMoveOrder(unit, paths.getMove())); + Order order = getMoveOrder(unit, paths.getMove(), hqMode); + + return order; } + // public boolean moveUnit(final Unit unit) + // { + // return process(getMoveOrder(unit, paths.getMove())); + // } + public void revertMoves() { + // FIXME for (Unit unit: activatedUnits) { RustAndDust.debug(" revertMove() " + unit); revertLastPawnMove(unit, ((Order) orders.get(unit, Order.OrderType.MOVE)).move); @@ -87,8 +110,10 @@ public abstract class Map4Orders extends Map3Animations public void revertEnter(final Unit unit) { + // FIXME RustAndDust.debug(" revertEnter() "+ unit); + orders.dispose(unit); revertclaim(unit, unit.getHex()); removePawn(unit); game.ctrl.battle.getPlayer().revertUnitEntry(unit); @@ -96,25 +121,68 @@ public abstract class Map4Orders extends Map3Animations unit.reset(); } - public boolean engageUnit(final Unit unit, final Unit target) + public Order getEngageOrder(final Unit unit, final Unit target) { attack(unit, target, true); - Order order = Order.get(); order.setEngage(unit, target); - process(order); - return order.engagement.success; + + Engagement e = order.engagement; + resolveEngagement(e); + order.cost = engagementCost(e); + activableUnits.clear(); + for (Unit u : activatedUnits) { + // FIXME in ctrl at order resolution + u.engage(); + if (e.success && u.canBreak()) + activableUnits.add(u); + } + order.setActivable(activableUnits); + if (order.activable.size() > 0) + order.cost = 0; + + return order; } - public boolean promoteUnit(final Unit unit) + // public boolean engageUnit(final Unit unit, final Unit target) + // { + // attack(unit, target, true); + + // Order order = Order.get(); + // order.setEngage(unit, target); + // process(order); + // return order.engagement.success; + // } + + public Order getPromoteOrder(final Unit unit) { Order order = Order.get(); order.setPromote(unit); - return process(order); + // order.cost = 1; + + return order; } + // public boolean promoteUnit(final Unit unit) + // { + // Order order = Order.get(); + // order.setPromote(unit); + // return process(order); + // } + // STATES ENTRY <- + private Order getMoveOrder(Unit unit, Move move, boolean hqMode) + { + Order order = Order.get(); + order.setMove(unit, move); + if (hqMode && activableUnits.size() > 0) { + order.setActivable(activableUnits); + order.cost = 0; + } + return order; + } + // REPLAY -> public void prepareReplayLastAction() @@ -149,66 +217,112 @@ public abstract class Map4Orders extends Map3Animations public boolean replay(Order order) { - return process(order, true); + // FIMXE replay(Order) + // return process(order, true); + return true; } // REPLAY <- - private Order getMoveOrder(Unit unit, Move move) - { - Order order = Order.get(); - order.setMove(unit, move); - return order; - } - - private boolean process(Order order) - { - return process(order, false); - } - - private boolean process(Order order, boolean replay) + // private boolean process(Order order) + // { + // return process(order, false); + // } + + // private boolean process(Order order, boolean replay) + // { + // boolean r = false; + + // switch(order.type) { + // case MOVE: + // r = doMove(order, replay); + // break; + // case PROMOTE: + // r = doPromote(order, replay); + // break; + // case ENGAGE: + // r = doEngagement(order, replay); + // break; + // default: + // RustAndDust.error(String.format("Unhandled Order Type %s", order.type)); + // break; + // } + + // if (!r) + // throw new RuntimeException(String.format("Exectution failure : %s", order)); + + // if (replay) { + // activableUnits.clear(); + // for (Unit u : order.activable) + // activableUnits.add(u); + // orderId = order.id + 1; + // } else { + // if (order.cost > 0) + // orderId += 1; + // order.id = orderId; + // order.setActivable(activableUnits); + // orders.add(order); + // game.ctrl.orderProcessedCb(); + // } + + // RustAndDust.debug("Order", order.toString()); + + // return true; + // } + + public void execute(final Order order) { RustAndDust.debug("Order", order.toString()); - boolean r = false; - switch(order.type) { - case MOVE: - r = doMove(order.unit, order.move, replay); - break; case PROMOTE: - r = doPromote(order.unit, replay); + executePromote(order); break; case ENGAGE: - r = doEngagement(order.engagement, replay); + executeEngage(order); break; + case MOVE: + executeMove(order); + break; + case END: + orders.get(orders.size() - 1).cost = 1; + return; default: RustAndDust.error(String.format("Unhandled Order Type %s", order.type)); break; } + // FIXME not all + orders.add(order); + } - if (r && !replay) { - order.id = orderId; - order.setActivable(activableUnits); - order.cost = ((activatedUnits.size() > 0) ? ((activableUnits.size() > 0) ? 0 : 1) : 0); - orders.add(order); - game.ctrl.orderProcessedCb(); - } + private void executePromote(final Order order) + { + addPromoteAnimation(order.unit, game.ctrl.battle.getPlayer(), new Runnable() { + @Override + public void run() { + // FIXME Ctrl should do that !!! + game.ctrl.battle.getPlayer().promote(order.unit); + } + }); + } - if (replay) { - activableUnits.clear(); - for (Unit u : order.activable) - activableUnits.add(u); - orderId = order.id; + private void executeEngage(final Order order) + { + Engagement e = order.engagement; + if (!order.replay) + game.ctrl.hud.engagementSummary(e); + if (e.success) { + unclaim(e.defender, e.defender.getHex()); + removePawn(e.defender); + addDestroyAnimation(e.defender); } - - return r; + addEngagementAnimation(e.defender); } - private boolean doMove(Unit unit, Move move, boolean replay) + private void executeMove(final Order order) { - RustAndDust.debug(" Move", String.format("%s %s", move.type, move.toString())); - + final Unit unit = order.unit; + final Move move = order.move; switch(move.type) { case REGULAR: initMove(unit); @@ -220,25 +334,60 @@ public abstract class Map4Orders extends Map3Animations game.ctrl.battle.getPlayer().unitWithdraw(unit); break; case SET: + orders.dispose(unit); setPawnOnto(unit, move); - game.ctrl.battle.getPlayer().unitEntry(unit); + game.ctrl.battle.getPlayer().unitEntry(order.unit); claim(unit, move.to); addBounceAnimation(unit, 0.3f); break; case ENTER: - enterPawn(unit, move); - game.ctrl.battle.getPlayer().unitEntry(unit); - claim(unit, move.to); - addBounceAnimation(unit, 0.3f); - break; + // FIXME default: - RustAndDust.error(String.format("Unhandled Move Type %s", move.type)); - return false; + RustAndDust.error(String.format("Unhandled Move Type %s", order.move.type)); } - - return true; } + // private boolean doMove(Order order, boolean replay) + // { + // Unit unit = order.unit; + // Move move = order.move; + + // RustAndDust.debug(" Move", String.format("%s %s", move.type, move.toString())); + + // switch(move.type) { + // case REGULAR: + // initMove(unit); + // movePawn(unit, move, this); + // order.cost = ((activableUnits.size() > 0) ? 0 : 1); + // break; + // case EXIT: + // initMove(unit); + // movePawn(unit, move, this); + // game.ctrl.battle.getPlayer().unitWithdraw(unit); + // order.cost = 1; + // break; + // case SET: + // setPawnOnto(unit, move); + // game.ctrl.battle.getPlayer().unitEntry(unit); + // claim(unit, move.to); + // addBounceAnimation(unit, 0.3f); + // order.cost = 1; + // break; + // case ENTER: + // enterPawn(unit, move); + // game.ctrl.battle.getPlayer().unitEntry(unit); + // claim(unit, move.to); + // addBounceAnimation(unit, 0.3f); + // // FIXME : ENTER : order.cost = 1; + // break; + // default: + // RustAndDust.error(String.format("Unhandled Move Type %s", move.type)); + // return false; + // } + + // return true; + // } + private void initMove(Unit unit) { activableUnits.remove(unit); @@ -246,55 +395,59 @@ public abstract class Map4Orders extends Map3Animations playMoveSound(unit); } - private boolean doPromote(final Unit unit, boolean replay) - { - activableUnits.remove(unit); - activatedUnits.add(unit); - addPromoteAnimation(unit, game.ctrl.battle.getPlayer(), new Runnable() { - @Override - public void run() { - game.ctrl.battle.getPlayer().promote(unit); - } - }); - return true; - } - - private boolean doEngagement(Engagement e, boolean replay) - { - if (replay) { - activatedUnits.clear(); - for (Unit u : e.assists) { - u.engage(); - activatedUnits.add(u); - } - e.attacker.engage(); - activatedUnits.add(e.attacker); - } else { - resolveEngagement(e); - activableUnits.clear(); - if (e.success) { - for (Unit u : activatedUnits) { - u.engage(); - if (u.canBreak()) - activableUnits.add(u); - } - } - } - - if (e.success) { - unclaim(e.defender, e.defender.getHex()); - removePawn(e.defender); - addDestroyAnimation(e.defender); - } - - if (!replay) - game.ctrl.hud.engagementSummary(e); - addEngagementAnimation(e.defender); - - if (engagementCost(e) == 0) - activatedUnits.clear(); - - return true; - } + // private boolean doPromote(Order order, boolean replay) + // { + // final Unit unit = order.unit; + // order.cost = 1; + // activableUnits.remove(unit); + // activatedUnits.add(unit); + // addPromoteAnimation(unit, game.ctrl.battle.getPlayer(), new Runnable() { + // @Override + // public void run() { + // game.ctrl.battle.getPlayer().promote(unit); + // } + // }); + // return true; + // } + + // private boolean doEngagement(Order order, boolean replay) + // { + // Engagement e = order.engagement; + // if (replay) { + // activatedUnits.clear(); + // for (Unit u : e.assists) { + // u.engage(); + // activatedUnits.add(u); + // } + // e.attacker.engage(); + // activatedUnits.add(e.attacker); + // } else { + // resolveEngagement(e); + // activableUnits.clear(); + // if (e.success) { + // for (Unit u : activatedUnits) { + // u.engage(); + // if (u.canBreak()) + // activableUnits.add(u); + // } + // } + // } + + // if (e.success) { + // unclaim(e.defender, e.defender.getHex()); + // removePawn(e.defender); + // addDestroyAnimation(e.defender); + // } + + // if (!replay) + // game.ctrl.hud.engagementSummary(e); + // addEngagementAnimation(e.defender); + + // order.cost = engagementCost(e); + // if (order.cost == 0) + // activatedUnits.clear(); + + // return true; + // } } diff --git a/core/src/ch/asynk/rustanddust/game/states/StateAnimation.java b/core/src/ch/asynk/rustanddust/game/states/StateAnimation.java index c19f16b..db55039 100644 --- a/core/src/ch/asynk/rustanddust/game/states/StateAnimation.java +++ b/core/src/ch/asynk/rustanddust/game/states/StateAnimation.java @@ -1,27 +1,25 @@ package ch.asynk.rustanddust.game.states; +import ch.asynk.rustanddust.game.Ctrl.MsgType; + public class StateAnimation extends StateCommon { @Override public void enterFrom(StateType prevState) { + ctrl.blockMap = true; ctrl.hud.actionButtons.hide(); } @Override - public void leaveFor(StateType nextState) - { - } - - @Override - public StateType abort() + public boolean processMsg(MsgType msg, Object data) { - return StateType.ABORT; - } + switch(msg) { + case OK: + ctrl.blockMap = false; + return true; + } - @Override - public StateType execute() - { - return StateType.DONE; + return false; } } diff --git a/core/src/ch/asynk/rustanddust/game/states/StateBreak.java b/core/src/ch/asynk/rustanddust/game/states/StateBreak.java deleted file mode 100644 index 1dab40b..0000000 --- a/core/src/ch/asynk/rustanddust/game/states/StateBreak.java +++ /dev/null @@ -1,76 +0,0 @@ -package ch.asynk.rustanddust.game.states; - -import ch.asynk.rustanddust.engine.Orientation; -import ch.asynk.rustanddust.game.Hex; -import ch.asynk.rustanddust.game.Unit; -import ch.asynk.rustanddust.game.hud.ActionButtons.Buttons; - -public class StateBreak extends StateCommon -{ - private Orientation o = Orientation.KEEP; - - @Override - public void enterFrom(StateType prevState) - { - activeUnit = null; - ctrl.hud.actionButtons.show(Buttons.DONE.b); - ctrl.hud.notify("Break Through possible"); - map.unitsActivableShow(); - } - - @Override - public void leaveFor(StateType nextState) - { - map.unitsActivableHide(); - map.hexMoveHide(to); - map.hexDirectionsHide(to); - if (activeUnit != null) map.hexMoveHide(activeUnit.getHex()); - } - - @Override - public StateType abort() - { - return StateType.ABORT; - } - - @Override - public StateType execute() - { - return StateType.DONE; - } - - @Override - public void touch(Hex hex) - { - // TODO : cancel preview move before showing rotation - if (activeUnit == null) { - Unit unit = hex.getUnit(); - if (map.unitsActivableContains(unit)) { - activeUnit = unit; - map.hexMoveShow(hex); - map.hexMoveShow(to); - map.hexDirectionsShow(to); - map.unitsActivableHide(); - } - } else { - o = Orientation.fromAdj(to, hex); - - if (o == Orientation.KEEP) return; - - doRotation(o); - ctrl.post(StateType.ANIMATION); - } - } - - private void doRotation(Orientation o) - { - if (activeUnit == null) return; - - map.pathsInit(activeUnit); - map.pathsBuild(to); - map.pathsChooseShortest(); - map.pathsSetOrientation(o); - map.moveUnit(activeUnit); - ctrl.setAfterAnimationState(StateType.DONE); - } -} diff --git a/core/src/ch/asynk/rustanddust/game/states/StateCommon.java b/core/src/ch/asynk/rustanddust/game/states/StateCommon.java index b894c0f..1614465 100644 --- a/core/src/ch/asynk/rustanddust/game/states/StateCommon.java +++ b/core/src/ch/asynk/rustanddust/game/states/StateCommon.java @@ -1,12 +1,13 @@ package ch.asynk.rustanddust.game.states; +import ch.asynk.rustanddust.RustAndDust; import ch.asynk.rustanddust.game.Map; import ch.asynk.rustanddust.game.Hex; import ch.asynk.rustanddust.game.Unit; import ch.asynk.rustanddust.game.Ctrl; +import ch.asynk.rustanddust.game.Ctrl.MsgType; import ch.asynk.rustanddust.game.State; import ch.asynk.rustanddust.game.Config; -import ch.asynk.rustanddust.RustAndDust; public abstract class StateCommon implements State { @@ -17,7 +18,6 @@ public abstract class StateCommon implements State protected static Hex selectedHex = null; protected static Hex to = null; - protected boolean isEnemy; protected static Unit activeUnit; protected static Unit selectedUnit; @@ -28,26 +28,12 @@ public abstract class StateCommon implements State map = game.ctrl.map; } - protected boolean hasUnit() - { - return (selectedUnit != null); - } - - protected void showPossibilities(Unit unit) - { - if (cfg.showMoves && unit.canMove()) map.movesShow(); - if (cfg.showTargets && unit.canEngage()) map.unitsTargetShow(); - if (cfg.showMoveAssists && unit.canMove()) map.unitsActivableShow(); - unit.hideActiveable(); - } + @Override + public void touch(Hex hex) { } - protected void hidePossibilities() + @Override + public boolean processMsg(MsgType state, Object data) { - map.movesHide(); - map.unitsTargetHide(); - map.unitsActivableHide(); + return false; } - - @Override - public void touch(Hex hex) { } } diff --git a/core/src/ch/asynk/rustanddust/game/states/StateDeployment.java b/core/src/ch/asynk/rustanddust/game/states/StateDeployment.java index f967917..bd99bd9 100644 --- a/core/src/ch/asynk/rustanddust/game/states/StateDeployment.java +++ b/core/src/ch/asynk/rustanddust/game/states/StateDeployment.java @@ -5,6 +5,7 @@ import ch.asynk.rustanddust.game.Hex; import ch.asynk.rustanddust.game.Zone; import ch.asynk.rustanddust.game.Unit; import ch.asynk.rustanddust.game.UnitList; +import ch.asynk.rustanddust.game.Ctrl.MsgType; import ch.asynk.rustanddust.game.hud.ActionButtons.Buttons; public class StateDeployment extends StateCommon @@ -15,55 +16,44 @@ public class StateDeployment extends StateCommon @Override public void enterFrom(StateType prevState) { - if (selectedHex != null) - map.hexUnselect(selectedHex); - entryZone = null; - selectedHex = null; - selectedUnit = null; - ctrl.hud.actionButtons.hide(); + clear(); ctrl.hud.playerInfo.unitDock.show(); } @Override - public void leaveFor(StateType nextState) + public boolean processMsg(MsgType msg, Object data) { - selectedUnit = null; - if (selectedHex != null) - map.hexUnselect(selectedHex); - if (entryZone != null) - entryZone.enable(Hex.AREA, false); - ctrl.hud.playerInfo.unitDock.hide(); - } - - @Override - public StateType abort() - { - if (activeUnit != null) - undo(); - return StateType.DEPLOYMENT; - } + switch(msg) { + case UNIT_DOCK_SELECT: + showEntryZone((Unit) data); + return true; + case CANCEL: + if (activeUnit != null) + undeployUnit(); + return true; + case OK: + deployedUnits.clear(); + ctrl.postTurnDone(); + return true; + case UNIT_DEPLOYED: + deployedUnits.add((Unit) data); + return true; + } - @Override - public StateType execute() - { - deployedUnits.clear(); - return StateType.DONE; + return false; } @Override public void touch(Hex hex) { - Unit unit = ctrl.hud.playerInfo.unitDock.selectedUnit; - if (hex == null) { - showEntryZone(unit); - } else if (selectedUnit != null) { + if (activeUnit != null) { deployUnit(Orientation.fromAdj(selectedHex, hex)); - } else if (!ctrl.battle.isDeploymentDone() && (entryZone != null) && (hex != null)) { + } else if ((selectedUnit != null) && (entryZone != null)) { if (hex.isEmpty() && entryZone.contains(hex)) { - showUnit(activeUnit, hex); + showUnit(selectedUnit, hex); } } else { - unit = hex.getUnit(); + Unit unit = hex.getUnit(); if (deployedUnits.contains(unit)) showRotation(unit, hex); } @@ -71,25 +61,16 @@ public class StateDeployment extends StateCommon private void showEntryZone(Unit unit) { - activeUnit = unit; - if (entryZone != null) entryZone.enable(Hex.AREA, false); - entryZone = activeUnit.entryZone; + selectedUnit = unit; + if (entryZone != null) + entryZone.enable(Hex.AREA, false); + entryZone = unit.entryZone; entryZone.enable(Hex.AREA, true); } - private void undo() - { - map.hexUnselect(selectedHex); - map.hexDirectionsHide(selectedHex); - map.revertEnter(activeUnit); - activeUnit = null; - selectedUnit = null; - ctrl.hud.update(); - } - private void showUnit(Unit unit, Hex hex) { - selectedUnit = unit; + activeUnit = unit; selectedHex = hex; ctrl.battle.getPlayer().reinforcement.remove(unit); map.showOnBoard(unit, hex, entryZone.orientation); @@ -102,7 +83,6 @@ public class StateDeployment extends StateCommon private void showRotation(Unit unit, Hex hex) { activeUnit = unit; - selectedUnit = unit; selectedHex = hex; map.hexSelect(selectedHex); map.hexDirectionsShow(selectedHex); @@ -113,16 +93,31 @@ public class StateDeployment extends StateCommon private void deployUnit(Orientation o) { if (o == Orientation.KEEP) - o = selectedUnit.getOrientation(); - map.setOnBoard(selectedUnit, selectedHex, o); + o = activeUnit.getOrientation(); + // map.setOnBoard(activeUnit, selectedHex, o); + ctrl.postOrder(map.getSetOrder(activeUnit, selectedHex, o), StateType.DEPLOYMENT); + clear(); + // ctrl.postTransitionTo(StateType.DEPLOYMENT); + } - entryZone = null; + private void undeployUnit() + { + map.revertEnter(activeUnit); + ctrl.hud.update(); + clear(); + ctrl.hud.playerInfo.unitDock.show(); + } + + private void clear() + { + if (selectedHex != null) { + map.hexUnselect(selectedHex); + map.hexDirectionsHide(selectedHex); + } activeUnit = null; + entryZone = null; + selectedHex = null; selectedUnit = null; - map.hexUnselect(selectedHex); - map.hexDirectionsHide(selectedHex); ctrl.hud.actionButtons.hide(); - ctrl.hud.playerInfo.unitDock.show(); - ctrl.post(StateType.DONE); } } diff --git a/core/src/ch/asynk/rustanddust/game/states/StateEngage.java b/core/src/ch/asynk/rustanddust/game/states/StateEngage.java index bfeced8..3405538 100644 --- a/core/src/ch/asynk/rustanddust/game/states/StateEngage.java +++ b/core/src/ch/asynk/rustanddust/game/states/StateEngage.java @@ -1,89 +1,162 @@ package ch.asynk.rustanddust.game.states; +import ch.asynk.rustanddust.engine.Orientation; import ch.asynk.rustanddust.game.Hex; import ch.asynk.rustanddust.game.Unit; +import ch.asynk.rustanddust.game.Order; +import ch.asynk.rustanddust.game.Ctrl.MsgType; +import ch.asynk.rustanddust.game.hud.ActionButtons.Buttons; public class StateEngage extends StateCommon { + // selectedUnit -> fire leader + // activeUnit -> target / break + + private boolean breakMove = false; + @Override public void enterFrom(StateType prevState) { if (prevState == StateType.SELECT) { - // activeUnit will be target - activeUnit = null; - if (to != null) { - // quick fire -> replay touchUp - touch(to); + breakMove = false; + if ((to != null) && (activeUnit != null)) { + // quick fire + selectTarget(activeUnit, to); } selectedUnit.showAttack(); map.hexSelect(selectedHex); + } else { + breakMove = true; + activeUnit = null; + ctrl.hud.actionButtons.show(Buttons.DONE.b); + ctrl.hud.notify("Break Through possible"); + map.unitsActivableShow(); + map.hexUnselect(selectedHex); } } @Override - public void leaveFor(StateType nextState) + public boolean processMsg(MsgType msg, Object data) { - selectedUnit.hideAttack(); - map.unitsAssistHide(); - map.unitsTargetHide(); - map.hexUnselect(selectedHex); - if (to != null) - map.hexUnselect(to); + switch(msg) { + case OK: + if (breakMove) + abortBreakMove(); + return true; + } + + return false; } @Override - public StateType abort() + public void touch(Hex hex) { - map.unitsActivatedClear(); - return StateType.ABORT; + Unit unit = hex.getUnit(); + + if (!breakMove) { + if (unit == selectedUnit) + abort(); + else if ((activeUnit == null) && map.unitsTargetContains(unit)) + selectTarget(unit, hex); + else if (unit == activeUnit) + engage(); + else if ((activeUnit != null) && map.unitsActivableContains(unit)) + map.toggleAssist(unit); + } else { + if (activeUnit == null) { + if (map.unitsActivableContains(unit)) + selectBreakUnit(unit); + } else { + Orientation o = Orientation.fromAdj(to, hex); + if (o == Orientation.KEEP) + unselectBreakUnit(); + else + doRotation(o); + } + + } } - @Override - public StateType execute() + private void selectTarget(Unit unit, Hex hex) { + to = hex; + activeUnit = unit; + map.unitsTargetHide(); + activeUnit.showTarget(); + map.collectAssists(selectedUnit, activeUnit, ctrl.battle.getPlayer().units); + map.unitsAssistShow(); + } + + private void engage() + { + activeUnit.hideTarget(); + selectedUnit.hideAttack(); map.unitsAssistHide(); - StateType nextState = StateType.DONE; - if (map.engageUnit(selectedUnit, activeUnit)) { + map.hexUnselect(selectedHex); + Order order = map.getEngageOrder(selectedUnit, activeUnit); + + // FIXME maybe do that in Ctrl at order resolution !!!! + if (order.engagement.success) { ctrl.battle.getPlayer().engagementWon += 1; ctrl.battle.getOpponent().casualty(activeUnit); - if (map.unitsActivableSize() > 0) { - nextState = StateType.BREAK; - } } else { ctrl.battle.getPlayer().engagementLost += 1; } - activeUnit.showTarget(); - ctrl.setAfterAnimationState(nextState); - return StateType.ANIMATION; + if (order.cost == 0) + ctrl.postOrder(order, StateType.ENGAGE); + else + ctrl.postOrder(order); } - @Override - public void touch(Hex hex) + private void abort() { - Unit unit = hex.getUnit(); + map.unitsAssistHide(); + map.unitsTargetHide(); + activeUnit.hideTarget(); + selectedUnit.hideAttack(); + map.hexUnselect(selectedHex); + map.unitsActivatedClear(); + ctrl.postActionAborted(); + } - // activeUnit is the target, selectedTarget is the engagement leader - if (unit == selectedUnit) { - ctrl.post(StateType.ABORT); - } else if ((activeUnit == null) && map.unitsTargetContains(unit)) { - // ctrl.hud.notify("Engage " + unit); - map.unitsTargetHide(); - to = hex; - activeUnit = unit; - activeUnit.showTarget(); - map.collectAssists(selectedUnit, activeUnit, ctrl.battle.getPlayer().units); - map.unitsAssistShow(); - } - else if (unit == activeUnit) { - ctrl.post(StateType.DONE); - } - else if ((activeUnit != null) && map.unitsActivableContains(unit)) { - map.toggleAssist(unit); - // if (map.toggleAssist(unit)) - // ctrl.hud.notify(unit + " will fire"); - // else - // ctrl.hud.notify(unit + " wont fire"); - } + private void selectBreakUnit(Unit unit) + { + activeUnit = unit; + map.hexMoveShow(to); + map.hexMoveShow(unit.getHex()); + map.hexDirectionsShow(to); + map.unitsActivableHide(); + } + + private void unselectBreakUnit() + { + map.hexMoveHide(to); + map.hexMoveHide(activeUnit.getHex()); + map.hexDirectionsHide(to); + map.unitsActivableShow(); + activeUnit = null; + } + + private void doRotation(Orientation o) + { + map.hexMoveHide(to); + map.hexMoveHide(activeUnit.getHex()); + map.hexDirectionsHide(to); + map.pathsInit(activeUnit); + map.pathsBuild(to); + map.pathsChooseShortest(); + map.pathsSetOrientation(o); + ctrl.postOrder(map.getMoveOrder(activeUnit, false)); + } + + private void abortBreakMove() + { + if (activeUnit != null) + map.hexMoveHide(activeUnit.getHex()); + map.hexMoveHide(to); + map.hexDirectionsHide(to); + map.unitsActivableHide(); + ctrl.postOrder(Order.END); } } diff --git a/core/src/ch/asynk/rustanddust/game/states/StateMove.java b/core/src/ch/asynk/rustanddust/game/states/StateMove.java index 3aa684d..4d10560 100644 --- a/core/src/ch/asynk/rustanddust/game/states/StateMove.java +++ b/core/src/ch/asynk/rustanddust/game/states/StateMove.java @@ -1,103 +1,106 @@ package ch.asynk.rustanddust.game.states; -import ch.asynk.rustanddust.ui.Position; +import ch.asynk.rustanddust.engine.Orientation; import ch.asynk.rustanddust.game.Hex; import ch.asynk.rustanddust.game.Unit; +import ch.asynk.rustanddust.game.Order; +import ch.asynk.rustanddust.game.Ctrl.MsgType; import ch.asynk.rustanddust.game.hud.ActionButtons.Buttons; public class StateMove extends StateCommon { + enum State + { + SHOW, + PATH, + ROTATE, + EXIT + } + + private State state; + private boolean hqMode; + @Override public void enterFrom(StateType prevState) { - ctrl.hud.actionButtons.show( - ((map.unitsActivatedSize() > 0) ? Buttons.DONE.b : 0) - ); - - if (prevState == StateType.WITHDRAW) { - completePath(map.pathsSize()); - return; - } + state = State.SHOW; + hqMode = false; map.pathsClear(); - if (prevState == StateType.SELECT) { - // use selectedHex and selectedUnit + map.hexSelect(selectedHex); + map.pathsInit(selectedUnit); activeUnit = selectedUnit; - map.pathsInit(activeUnit); - map.collectUpdate(activeUnit); - if (to != null) { - // quick move -> replay touchUp - touch(to); - } else - checkExit(activeUnit); - } else { - // back from rotation -> chose next Pawn - if (selectedUnit.canMove()) { - changeUnit(selectedUnit); + if (to == null) { + hqMode = true; + map.movesShow(); } else { - changeUnit(map.unitsMoveableGet(0)); + collectPaths(to); } + } else { + if (prevState == StateType.WAIT_EVENT) + hqMode = true; + selectNextUnit(); } - map.unitsActivableShow(); + if (hqMode) + map.unitsActivableShow(); activeUnit.hideActiveable(); + ctrl.hud.actionButtons.show(((map.unitsActivatedSize() > 0) ? Buttons.DONE.b : 0)); } @Override - public void leaveFor(StateType nextState) + public boolean processMsg(MsgType msg, Object data) { - if (nextState == StateType.WITHDRAW) - return; - - // hide all but assists : want them when in rotation - activeUnit.hideActiveable(); - map.movesHide(); - map.hexUnselect(activeUnit.getHex()); - if (to != null) - map.pathHide(to); - - if (nextState != StateType.SELECT) { - if (to == null) - to = activeUnit.getHex(); + switch(msg) { + case OK: + if (state == State.EXIT) { + exit(); + return true; + } + if (hqMode) { + endHqMode(); + return true; + } + break; + case CANCEL: + if ((state == State.PATH) || (state == State.ROTATE)) { + abortMove(); + return true; + } + if (state == State.EXIT) { + abortExit(); + return true; + } + break; } - } - @Override - public StateType abort() - { - hideActivable(); - if (activeUnit.justEntered()) { - map.revertEnter(activeUnit); - return StateType.ABORT; - } - int n = map.unitsActivatedSize(); - if (n == 0) - return StateType.ABORT; - map.revertMoves(); - return StateType.ANIMATION; - } - - @Override - public StateType execute() - { - hideActivable(); - // be sure that the hq is activated - if (selectedUnit.canMove() && (map.unitsActivatedSize() > 0)) - selectedUnit.setMoved(); - - return StateType.DONE; + return false; } @Override public void touch(Hex hex) { + if (state == State.ROTATE) { + if (hex == to) + abortMove(); + else { + Orientation o = Orientation.fromAdj(to, hex); + if (o != Orientation.KEEP) + move(o); + else if (hex == activeUnit.getHex()) + abortMove(); + } + return; + } + if (hex == activeUnit.getHex()) { if (to != null) map.pathHide(to); - to = null; + map.pathsHide(); map.pathsClear(); - ctrl.post(StateType.ROTATE); + map.pathsInit(activeUnit); + collectPaths(hex); return; } @@ -107,21 +110,29 @@ public class StateMove extends StateCommon if (map.unitsActivableContains(unit)) { if (unit != activeUnit) - changeUnit(unit); + selectUnit(unit); } else if ((s == 0) && map.movesContains(hex)) { collectPaths(hex); + } else if ((s > 1) && hex == to) { + s = map.pathsChooseBest(); + if (s == 1) + showRotation(to); } else if (map.pathsContains(hex)) { togglePoint(hex, s); } } - private void hideActivable() + private void selectNextUnit() { - map.unitsActivableHide(); + if (selectedUnit.canMove()) + selectUnit(selectedUnit); + else + selectUnit(map.unitsMoveableGet(0)); } - private void changeUnit(Unit unit) + private void selectUnit(Unit unit) { + state = State.SHOW; if (activeUnit != null ) { map.hexUnselect(activeUnit.getHex()); if (activeUnit.canMove()) @@ -130,70 +141,164 @@ public class StateMove extends StateCommon to = null; activeUnit = unit; activeUnit.hideActiveable(); - Hex hex = activeUnit.getHex(); - map.pathsInit(activeUnit, hex); + map.hexSelect(activeUnit.getHex()); + map.pathsClear(); + map.pathsInit(activeUnit); map.movesHide(); map.movesCollect(activeUnit); map.movesShow(); - map.hexSelect(hex); - ctrl.hud.notify(activeUnit.toString(), Position.TOP_CENTER); - checkExit(activeUnit); + ctrl.hud.notify(activeUnit.toString()); + // checkExit(activeUnit.getHex()); } private void collectPaths(Hex hex) { + state = State.PATH; to = hex; map.movesHide(); map.hexMoveShow(to); - int s = map.pathsBuild(to); - if (!checkExit(activeUnit, hex)) - completePath(s); + if (!checkExit(to)) + completePath(); + ctrl.hud.actionButtons.show(Buttons.ABORT.b); } - private void completePath(int s) + private void completePath() { + int s = map.pathsBuild(to); if (cfg.autoPath && (s > 1)) s = map.pathsChooseBest(); map.pathsShow(); if (s == 1) - ctrl.post(StateType.ROTATE); + showRotation(to); } private void togglePoint(Hex hex, int s) { - if (hex == activeUnit.getHex()) { - // - } else if (hex == to) { - // - } else { - map.pathsHide(); - s = map.pathsToggleHex(hex); - map.pathsShow(); - } - - if (s == 1) { - if (!checkExit(activeUnit, hex)) - ctrl.post(StateType.ROTATE); - } + map.pathsHide(); + s = map.pathsToggleHex(hex); + map.pathsShow(); + if (s == 1) + showRotation(to); } - private boolean checkExit(Unit unit) + private boolean checkExit(Hex hex) { - if (unit.justEntered()) + if (activeUnit.justEntered()) return false; - if ((unit.exitZone == null) || !unit.exitZone.contains(unit.getHex())) + if ((activeUnit.exitZone == null) || !activeUnit.exitZone.contains(hex)) return false; - ctrl.post(StateType.WITHDRAW); + + int s = map.pathsBuild(to); + + if (!map.pathsCanExit(activeUnit.exitZone.orientation)) + return false; + + if (map.pathsChooseExit(activeUnit.exitZone.orientation) > 1) + throw new RuntimeException(String.format("pathsChooseExit() -> %d", map.pathsSize())); + map.pathShow(hex); + + state = State.EXIT; + ctrl.hud.askExitBoard(); return true; } - private boolean checkExit(Unit unit, Hex hex) + private void showRotation(Hex hex) { - if ((unit.exitZone == null) || !unit.exitZone.contains(hex)) - return false; - if (!map.pathsCanExit(unit.exitZone.orientation)) - return false; - ctrl.post(StateType.WITHDRAW); - return true; + state = State.ROTATE; + map.movesHide(); + map.pathsHide(); + map.pathShow(hex); + map.hexDirectionsShow(hex); + ctrl.hud.actionButtons.show(Buttons.ABORT.b); + } + + private void move(Orientation o) + { + map.pathsSetOrientation(o); + completeMove(map.getMoveOrder(activeUnit, hqMode)); + } + + private void exit() + { + if (map.pathsTo() == null) { + map.pathsBuild(to); + if (map.pathsChooseExit(activeUnit.exitZone.orientation) > 1) + throw new RuntimeException(String.format("pathsChooseExit() -> %d", map.pathsSize())); + } + + completeMove(map.getExitOrder(activeUnit, hqMode)); + } + + private void completeMove(Order order) + { + map.pathHide(to); + map.hexDirectionsHide(to); + map.hexUnselect(selectedHex); + if (order.cost == 0) + ctrl.postOrder(order, StateType.MOVE); + else + ctrl.postOrder(order); + } + + private void endHqMode() + { + if (selectedUnit.canMove()) + selectedUnit.setMoved(); + clear(); + ctrl.postOrder(Order.END); + } + + private void abortMove() + { + if (activeUnit.justEntered()) + map.revertEnter(activeUnit); + clear(); + if (map.unitsActivatedSize() > 0) { + // FIXME abortMove : cfg.revertAllMoves + // if (cfg.revertAllMoves) { + // map.revertMoves(); + // ctrl.postTransitionToAborted(); + // } else { + selectUnit(activeUnit); + abortCompleted(); + // } + } + else + ctrl.postActionAborted(); + } + + private void abortExit() + { + map.pathHide(to); + if (to == null) { + state = State.SHOW; + } else { + state = State.PATH; + completePath(); + } + abortCompleted(); + } + + private void abortCompleted() + { + if (hqMode) + map.unitsActivableShow(); + activeUnit.hideActiveable(); + ctrl.hud.actionButtons.show(((map.unitsActivatedSize() > 0) ? Buttons.DONE.b : 0)); + } + + private void clear() + { + state = State.SHOW; + map.movesHide(); + map.pathsHide(); + activeUnit.hideActiveable(); + map.hexUnselect(activeUnit.getHex()); + map.unitsActivableHide(); + if (to != null) { + map.pathHide(to); + map.hexDirectionsHide(to); + } + map.pathsClear(); } } diff --git a/core/src/ch/asynk/rustanddust/game/states/StatePromote.java b/core/src/ch/asynk/rustanddust/game/states/StatePromote.java index bfec208..875834c 100644 --- a/core/src/ch/asynk/rustanddust/game/states/StatePromote.java +++ b/core/src/ch/asynk/rustanddust/game/states/StatePromote.java @@ -5,26 +5,8 @@ public class StatePromote extends StateCommon @Override public void enterFrom(StateType prevState) { - ctrl.setAfterAnimationState(StateType.DONE); - ctrl.post(StateType.ANIMATION); - map.promoteUnit(selectedUnit); - } - - @Override - public void leaveFor(StateType nextState) - { - map.hexUnselect(selectedHex); - } - - @Override - public StateType abort() - { - return StateType.ABORT; - } - - @Override - public StateType execute() - { - return StateType.DONE; + ctrl.postOrder(map.getPromoteOrder(selectedUnit)); + // map.promoteUnit(selectedUnit); + // ctrl.postTransitionToDone(); } } diff --git a/core/src/ch/asynk/rustanddust/game/states/StateReinforcement.java b/core/src/ch/asynk/rustanddust/game/states/StateReinforcement.java index e118924..a32af37 100644 --- a/core/src/ch/asynk/rustanddust/game/states/StateReinforcement.java +++ b/core/src/ch/asynk/rustanddust/game/states/StateReinforcement.java @@ -1,8 +1,11 @@ package ch.asynk.rustanddust.game.states; +import ch.asynk.rustanddust.engine.Orientation; import ch.asynk.rustanddust.game.Hex; import ch.asynk.rustanddust.game.Zone; import ch.asynk.rustanddust.game.Unit; +import ch.asynk.rustanddust.game.Ctrl.MsgType; +import ch.asynk.rustanddust.game.hud.ActionButtons.Buttons; public class StateReinforcement extends StateCommon { @@ -15,66 +18,111 @@ public class StateReinforcement extends StateCommon if (selectedHex != null) map.hexUnselect(selectedHex); entryZone = null; + activeUnit = null; selectedHex = null; + selectedUnit = null; ctrl.hud.playerInfo.unitDock.show(); } @Override - public void leaveFor(StateType nextState) + public boolean processMsg(MsgType msg, Object data) { - if (selectedHex != null) - map.hexUnselect(selectedHex); - if (entryZone != null) - entryZone.enable(Hex.AREA, false); - ctrl.hud.playerInfo.unitDock.hide(); - } - - @Override - public StateType abort() - { - return StateType.ABORT; - } + switch(msg) { + case UNIT_DOCK_SELECT: + showEntryZone((Unit) data); + return true; + case CANCEL: + undeployUnit(); + return true; + case OK: + abort(); + return true; + } - @Override - public StateType execute() - { - return StateType.DONE; + return false; } @Override public void touch(Hex hex) { - Unit unit = ctrl.hud.playerInfo.unitDock.selectedUnit; - if (hex == null) - changeUnit(unit); - else if ((entryZone != null) && hex.isEmpty() && entryZone.contains(hex)) - unitEnter(activeUnit, hex); - else - ctrl.post(StateType.SELECT); + if (activeUnit != null) + deployUnit(Orientation.fromAdj(selectedHex, hex)); + if ((entryZone != null) && hex.isEmpty() && entryZone.contains(hex)) + unitEnter(selectedUnit, hex); } - private void changeUnit(Unit unit) + private void showEntryZone(Unit unit) { - activeUnit = unit; + selectedUnit = unit; if (entryZone != null) entryZone.enable(Hex.AREA, false); - entryZone = activeUnit.entryZone; + entryZone = unit.entryZone; entryZone.enable(Hex.AREA, true); } private void unitEnter(Unit unit, Hex hex) { - selectedUnit = unit; + activeUnit = unit; selectedHex = hex; map.hexSelect(selectedHex); entryZone.enable(Hex.AREA, false); - if (map.enterBoard(unit, hex, entryZone.allowedMoves)) { - if (unit.getMovementPoints() > 0) - ctrl.post(StateType.MOVE); - else - ctrl.post(StateType.ROTATE); - } else { - ctrl.hud.notify("Can not enter the map at that position"); + map.showOnBoard(unit, hex, entryZone.orientation); + // FIXME compute enter cost && road + // if (unit.getMovementPoints() > 1) + // ctrl.post(StateType.MOVE); + // else { + map.hexSelect(selectedHex); + map.hexDirectionsShow(selectedHex); + // } + ctrl.battle.getPlayer().reinforcement.remove(unit); + ctrl.hud.playerInfo.unitDock.hide(); + ctrl.hud.actionButtons.show(Buttons.ABORT.b); + } + + private void deployUnit(Orientation o) + { + if (o == Orientation.KEEP) + o = activeUnit.getOrientation(); + // map.enterBoard(activeUnit, selectedHex, o, activeUnit.entryZone.allowedMoves); + // map.setOnBoard(activeUnit, selectedHex, o); + clear(); + // ctrl.postTransitionToDone(); + ctrl.hud.update(); + ctrl.hud.playerInfo.unitDock.hide(); + } + + private void undeployUnit() + { + if (activeUnit == null) + return; + activeUnit.reset(); + map.revertEnter(activeUnit); + clear(); + ctrl.hud.playerInfo.unitDock.show(); + } + + private void abort() + { + if (activeUnit != null) { + activeUnit.reset(); + map.revertEnter(activeUnit); } + clear(); + ctrl.hud.actionButtons.hide(); + ctrl.hud.playerInfo.unitDock.hide(); + } + + private void clear() + { + if (entryZone != null) + entryZone.enable(Hex.AREA, false); + if (selectedHex != null) { + map.hexUnselect(selectedHex); + map.hexDirectionsHide(selectedHex); + } + entryZone = null; + activeUnit = null; + selectedHex = null; + selectedUnit = null; } } diff --git a/core/src/ch/asynk/rustanddust/game/states/StateReplay.java b/core/src/ch/asynk/rustanddust/game/states/StateReplay.java index ec8295d..03d8465 100644 --- a/core/src/ch/asynk/rustanddust/game/states/StateReplay.java +++ b/core/src/ch/asynk/rustanddust/game/states/StateReplay.java @@ -1,25 +1,30 @@ package ch.asynk.rustanddust.game.states; import ch.asynk.rustanddust.game.Order; +import ch.asynk.rustanddust.game.Ctrl.MsgType; +import ch.asynk.rustanddust.game.Ctrl.EventType; public class StateReplay extends StateCommon { - private Order order; + private Order order = null; @Override public void enterFrom(StateType prevState) { + if (this.order != null) { + replayStep(); + ctrl.postEvent(EventType.REPLAY_STEP, (order.cost > 0)); + } + Order o = map.stepReplay(); if (o == null) { - StateType nextState = nextState(); + replayDone(); order = null; - ctrl.post(nextState); } else { this.order = o; setup(); map.replay(order); - ctrl.setAfterAnimationState(StateType.REPLAY); - ctrl.post(StateType.ANIMATION); + // ctrl.postTransitionTo(StateType.REPLAY); } } @@ -40,48 +45,69 @@ public class StateReplay extends StateCommon ctrl.battle.getPlayer().engagementLost += 1; } break; + case PROMOTE: default: break; } } - private StateType nextState() + private void replayStep() { - if (map.unitsActivableSize() <= 0) - return StateType.DONE; - - StateType next = null; - switch (order.type) { case MOVE: - next = StateType.MOVE; + moveReplayStep(); break; case ENGAGE: - next = StateType.BREAK; - break; + case PROMOTE: default: - next = StateType.DONE; - break; + ctrl.postReplayDone(); } - - return next; } - @Override - public void leaveFor(StateType nextState) + private void moveReplayStep() { + switch(order.move.type) { + case SET: + ctrl.sendMsg(MsgType.UNIT_DEPLOYED, order.unit); + break; + case REGULAR: + case EXIT: + case ENTER: + break; + } } - @Override - public StateType abort() + private void replayDone() { - return StateType.ABORT; + boolean more = (map.unitsActivableSize() > 0); + switch (order.type) { + case MOVE: + moveReplayDone(more); + break; + case ENGAGE: + if (more) ctrl.post(StateType.ENGAGE); + else ctrl.postReplayDone(); + break; + case PROMOTE: + default: + ctrl.postReplayDone(); + } } - @Override - public StateType execute() + private void moveReplayDone(boolean more) { - // called at the end of animation DONE -> burn 1 AP - return ((order.cost == 0) ? StateType.REPLAY : StateType.DONE); + switch(order.move.type) { + case REGULAR: + case EXIT: + if (more) ctrl.post(StateType.MOVE); + else ctrl.postReplayDone(); + break; + case SET: + ctrl.post(StateType.DEPLOYMENT); + break; + case ENTER: + System.err.println("FIXME ENTER ???????"); + break; + } } } diff --git a/core/src/ch/asynk/rustanddust/game/states/StateRotate.java b/core/src/ch/asynk/rustanddust/game/states/StateRotate.java deleted file mode 100644 index 4aa9608..0000000 --- a/core/src/ch/asynk/rustanddust/game/states/StateRotate.java +++ /dev/null @@ -1,103 +0,0 @@ -package ch.asynk.rustanddust.game.states; - -import ch.asynk.rustanddust.engine.Orientation; -import ch.asynk.rustanddust.game.Hex; -import ch.asynk.rustanddust.RustAndDust; - -public class StateRotate extends StateCommon -{ - private boolean rotateOnly; - private boolean rotationSet; - - @Override - public void enterFrom(StateType prevState) - { - if (!cfg.showMoveAssists) map.unitsActivableHide(); - - if (activeUnit == null) - activeUnit = selectedUnit; - if (to == null) - to = activeUnit.getHex(); - - if (!map.pathsIsSet()) { - map.pathsInit(activeUnit); - map.pathsBuild(to); - } - - if (map.pathsSize() > 1) - RustAndDust.debug("ERROR: Rotate pathsSize() == " + map.pathsSize()); - - rotateOnly = (to == activeUnit.getHex()); - - if (!rotateOnly) - map.pathShow(to); - map.hexSelect(activeUnit.getHex()); - map.hexDirectionsShow(to); - - rotationSet = false; - } - - @Override - public void leaveFor(StateType nextState) - { - map.hexUnselect(activeUnit.getHex()); - map.pathHide(to); - map.hexDirectionsHide(to); - map.pathsClear(); - to = null; - } - - @Override - public StateType abort() - { - StateType nextState = StateType.ABORT; - ctrl.hud.actionButtons.hide(); - if (activeUnit.justEntered()) { - map.revertEnter(activeUnit); - nextState = StateType.ABORT; - } else if (map.unitsActivatedSize() == 0) { - map.unitsActivableHide(); - } else { - nextState = StateType.MOVE; - } - return nextState; - } - - @Override - public StateType execute() - { - if (!rotationSet) - return StateType.DONE; - - StateType whenDone = StateType.DONE; - - if (map.moveUnit(activeUnit)) { - if (map.unitsActivableSize() > 0) - whenDone = StateType.MOVE; - } else - RustAndDust.debug("rotate failed"); - - ctrl.setAfterAnimationState(whenDone); - return StateType.ANIMATION; - } - - @Override - public void touch(Hex hex) - { - if (rotationSet) return; - - Orientation o = Orientation.fromAdj(to, hex); - if (o == Orientation.KEEP) { - ctrl.post(StateType.ABORT); - return; - } - - if (!activeUnit.justEntered() && rotateOnly && (o == activeUnit.getOrientation())) - return; - - map.pathsSetOrientation(o); - rotationSet = true; - execute(); - ctrl.post(StateType.ANIMATION); - } -} diff --git a/core/src/ch/asynk/rustanddust/game/states/StateSelect.java b/core/src/ch/asynk/rustanddust/game/states/StateSelect.java index 518258f..1f60ce7 100644 --- a/core/src/ch/asynk/rustanddust/game/states/StateSelect.java +++ b/core/src/ch/asynk/rustanddust/game/states/StateSelect.java @@ -1,120 +1,130 @@ package ch.asynk.rustanddust.game.states; +import ch.asynk.rustanddust.RustAndDust; import ch.asynk.rustanddust.ui.Position; import ch.asynk.rustanddust.game.Hex; import ch.asynk.rustanddust.game.Unit; +import ch.asynk.rustanddust.game.Ctrl.MsgType; import ch.asynk.rustanddust.game.hud.ActionButtons.Buttons; -import ch.asynk.rustanddust.RustAndDust; public class StateSelect extends StateCommon { - @Override - public void enterFrom(StateType prevState) - { - to = null; - selectedHex = null; - selectedUnit = null; - activeUnit = null; - map.clearAll(); - ctrl.hud.actionButtons.hide(); - } + private boolean isEnemy; @Override - public void leaveFor(StateType nextState) + public void enterFrom(StateType prevState) { - hidePossibilities(); + clear(); } @Override - public StateType abort() + public boolean processMsg(MsgType msg, Object data) { - if (selectedHex != null) - map.hexUnselect(selectedHex); - hidePossibilities(); - map.clearAll(); - return StateType.ABORT; - } + switch(msg) { + case OK: + ctrl.postTurnDone(); + return true; + case PROMOTE: + changeTo(StateType.PROMOTE); + return true; + } - @Override - public StateType execute() - { - return StateType.DONE; + return false; } @Override public void touch(Hex hex) { - if (!isEnemy) { + Unit unit = hex.getUnit(); + + if (!isEnemy && (selectedUnit != null)) { if (map.movesContains(hex)) { // quick move to = hex; - ctrl.post(StateType.MOVE); + changeTo(StateType.MOVE); return; } - if (map.unitsTargetContains(hex.getUnit())) { + if (map.unitsTargetContains(unit)) { // quick fire to = hex; - ctrl.post(StateType.ENGAGE); + activeUnit = unit; + changeTo(StateType.ENGAGE); return; } } - if (selectedHex != null) - map.hexUnselect(selectedHex); - - hidePossibilities(); - if (hex.isOffMap()) { - selectedUnit = null; - return; - } - - Unit unit = hex.getUnit(); + hide(); - if (unit == null) { - isEnemy = false; - ctrl.hud.actionButtons.hide(); - map.clearAll(); + if ((unit == null) || hex.isOffMap()) { selectedUnit = null; return; } isEnemy = ctrl.battle.getPlayer().isEnemy(unit); - if (!isEnemy && (unit == selectedUnit) && unit.canMove()) { + + if (!isEnemy && (selectedUnit == unit) && unit.canMove()) { if (unit.isHq() && (map.unitsActivableSize() > 1)) { ctrl.hud.notify("HQ activation"); - select(hex, unit, isEnemy); - ctrl.post(StateType.MOVE); - } else { - // quick rotate + to = null; + } else to = hex; - ctrl.post(StateType.ROTATE); - } + changeTo(StateType.MOVE); } else { - select(hex, unit, isEnemy); + select(hex, unit); ctrl.hud.notify(selectedUnit.toString(), Position.TOP_CENTER); } } - private void select(Hex hex, Unit unit, boolean isEnemy) + private void select(Hex hex, Unit unit) { selectedHex = hex; selectedUnit = unit; + RustAndDust.debug(String.format(" %s - %s", selectedUnit, selectedHex)); + + map.hexSelect(selectedHex); if (isEnemy && !cfg.showEnemyPossibilities) return; - int moves = map.movesCollect(selectedUnit); - int targets = map.collectTargets(selectedUnit, (isEnemy ? ctrl.battle.getPlayer() : ctrl.battle.getOpponent()).units); - - if (moves > 0) + if(map.movesCollect(selectedUnit) > 0) { map.collectMoveable(selectedUnit); + if (cfg.showMoves) map.movesShow(); + if (cfg.showMoveAssists) map.unitsActivableShow(); + unit.hideActiveable(); + } - if ((moves > 0) || (targets > 0)) { - map.hexSelect(selectedHex); - showPossibilities(selectedUnit); + if (map.collectTargets(selectedUnit, (isEnemy ? ctrl.battle.getPlayer() : ctrl.battle.getOpponent()).units) > 0) { + if (cfg.showTargets) map.unitsTargetShow(); + unit.hideActiveable(); } ctrl.hud.actionButtons.show((ctrl.battle.getPlayer().canPromote(selectedUnit)) ? Buttons.PROMOTE.b : 0 ); - RustAndDust.debug("Select", selectedHex.toString() + " " + selectedUnit + (isEnemy ? " enemy " : " friend ")); + } + + private void changeTo(StateType nextState) + { + hide(); + ctrl.post(nextState); + } + + private void hide() + { + if (selectedHex != null) + map.hexUnselect(selectedHex); + map.movesHide(); + map.unitsTargetHide(); + map.unitsActivableHide(); + ctrl.hud.actionButtons.hide(); + } + + private void clear() + { + hide(); + map.clearAll(); + to = null; + isEnemy = false; + selectedHex = null; + selectedUnit = null; + activeUnit = null; } } diff --git a/core/src/ch/asynk/rustanddust/game/states/StateWithdraw.java b/core/src/ch/asynk/rustanddust/game/states/StateWithdraw.java deleted file mode 100644 index f21fbed..0000000 --- a/core/src/ch/asynk/rustanddust/game/states/StateWithdraw.java +++ /dev/null @@ -1,64 +0,0 @@ -package ch.asynk.rustanddust.game.states; - -import ch.asynk.rustanddust.game.Hex; -import ch.asynk.rustanddust.game.Unit; -import ch.asynk.rustanddust.RustAndDust; - -public class StateWithdraw extends StateCommon -{ - @Override - public void enterFrom(StateType prevState) - { - ctrl.hud.askExitBoard(); - } - - @Override - public void leaveFor(StateType nextState) - { - } - - @Override - public StateType abort() - { - return StateType.MOVE; - } - - @Override - public StateType execute() - { - if (activeUnit == null) - activeUnit = selectedUnit; - - ctrl.setAfterAnimationState(withdraw(activeUnit)); - return StateType.ANIMATION; - } - - private StateType withdraw(Unit unit) - { - Hex hex = unit.getHex(); - - // rotation - if (map.pathsTo() == null) - map.pathsBuild(hex); - - Hex exitHex = (Hex) map.pathsTo(); - if (!unit.exitZone.contains(exitHex)) - throw new RuntimeException(String.format("%s not in exitZone", exitHex)); - - if (map.pathsChooseExit(unit.exitZone.orientation) > 1) - RustAndDust.debug("ERROR: Withdraw pathsSize() == " + map.pathsSize()); - - unit.hideActiveable(); - if (to != null) - map.pathHide(to); - map.movesHide(); - map.hexUnselect(hex); - - if (map.exitBoard(unit)) { - if (map.unitsActivableSize() > 0) - return StateType.MOVE; - } else - RustAndDust.debug("exit failed"); - return StateType.DONE; - } -} diff --git a/core/src/ch/asynk/rustanddust/util/DB.java b/core/src/ch/asynk/rustanddust/util/DB.java index 994e5d3..70767cf 100644 --- a/core/src/ch/asynk/rustanddust/util/DB.java +++ b/core/src/ch/asynk/rustanddust/util/DB.java @@ -67,6 +67,7 @@ public class DB this.db = DatabaseFactory.getNewDatabase(dbPath, DB_SCHEMA_VERSION, null, null); this.db.setupDatabase(); this.debug = debug; + this.debug = true; } public void setup() @@ -126,6 +127,7 @@ public class DB private boolean checkDigest(String what, int id, String payload, String digest) { + if (payload == null) return true; if (digest.equals(getDigest(payload))) return true; RustAndDust.error(String.format("corrupted %s(%d)", what, id)); @@ -295,6 +297,7 @@ public class DB public boolean storeLastTurn(int game) { + RustAndDust.debug("storeLastTurn"); try { exec(String.format(COPY_TURN, game)); } catch (SQLiteGdxException e) { @@ -304,6 +307,18 @@ public class DB return true; } + public boolean clearOrders(int game) + { + RustAndDust.debug("clearOrders"); + try { + exec(String.format("update games set orders=null, ordersH=null where _id=%d;", game)); + } catch (SQLiteGdxException e) { + RustAndDust.error("clearOrders"); + return false; + } + return true; + } + private static final String LOAD_BASE = "select g._id, g.mode, g.battle, g.opponent, g.turn, g.currentPlayer, g.ts, g.synched"; private static final String LOAD_GAMES = LOAD_BASE + ", null, null, null, null, p.name, b.name" @@ -347,7 +362,7 @@ public class DB return r; } - private static final String LOAD_LAST_TURN = "select g._id, g.mode, g.battle, g.opponent, t.turn, t.currentPlayer, g.ts, g.synched" + private static final String LOAD_LAST_TURN = "select g._id, g.mode, g.battle, g.opponent, t.turn, t.currentPlayer, g.ts, 0" + ", t.state, t.stateH, g.orders, g.ordersH, null, null from games g inner join turns t on (g._id = t.game) where g._id=%d order by t.turn desc limit 1;"; public GameRecord loadLastTurn(int game) -- cgit v1.1-2-g2b99