diff options
| author | Jérémy Zurcher <jeremy@asynk.ch> | 2016-05-03 15:31:32 +0200 | 
|---|---|---|
| committer | Jérémy Zurcher <jeremy@asynk.ch> | 2016-05-03 15:31:32 +0200 | 
| commit | 79793cf2dd5cad2af5fa513a7213292d2ee53f86 (patch) | |
| tree | 306e849be86d992a543e42c8e8ddec80d24795a6 /core/src | |
| parent | cff800a98e8aec4e454c5dc84fd4249b7127a1fd (diff) | |
| download | RustAndDust-79793cf2dd5cad2af5fa513a7213292d2ee53f86.zip RustAndDust-79793cf2dd5cad2af5fa513a7213292d2ee53f86.tar.gz | |
OMG: add event queue, messages, replay, bounce animation, complete states rewrite ...
Diffstat (limited to 'core/src')
41 files changed, 1405 insertions, 1442 deletions
| diff --git a/core/src/ch/asynk/rustanddust/engine/Board.java b/core/src/ch/asynk/rustanddust/engine/Board.java index ace94d6..f7fed7e 100644 --- a/core/src/ch/asynk/rustanddust/engine/Board.java +++ b/core/src/ch/asynk/rustanddust/engine/Board.java @@ -18,9 +18,6 @@ import ch.asynk.rustanddust.engine.util.IterableSet;  import ch.asynk.rustanddust.engine.util.Collection;  import ch.asynk.rustanddust.engine.gfx.Moveable;  import ch.asynk.rustanddust.engine.gfx.Animation; -import ch.asynk.rustanddust.engine.gfx.animations.AnimationSequence; -import ch.asynk.rustanddust.engine.gfx.animations.RunnableAnimation; -import ch.asynk.rustanddust.engine.gfx.animations.MoveToAnimation.MoveToAnimationCb;  public abstract class Board implements Disposable, Animation  { @@ -404,7 +401,7 @@ public abstract class Board implements Disposable, Animation              }          } -        return entry.opposite(); +        return entry;      }      public int objectivesCount(Faction faction) @@ -491,7 +488,6 @@ public abstract class Board implements Disposable, Animation      public Pawn setPawnOnto(Pawn pawn, Move move)      { -        pawn.move(move);          return setPawnOnto(pawn, move.to, move.orientation);      } @@ -502,54 +498,6 @@ public abstract class Board implements Disposable, Animation          return pawn;      } -    private RunnableAnimation getSetPawnOntoAnimation(final Pawn pawn) -    { -        return RunnableAnimation.get(pawn, new Runnable() { -            @Override -            public void run() { -                Tile to = pawn.move.to; -                if (!to.isOffMap()) -                    setPawnOnto(pawn, to, pawn.move.orientation); -            } -        }); -    } - -    protected void movePawn(final Pawn pawn, Move move, MoveToAnimationCb cb) -    { -        pawn.move(move); -        removePawn(pawn); - -        AnimationSequence seq = pawn.getMoveAnimation(move.iterator(), (move.steps() + 1), cb); -        seq.addAnimation(getSetPawnOntoAnimation(pawn)); -        addAnimation(seq); -    } - -    protected void enterPawn(final Pawn pawn, Move move) -    { -        pawn.move(move); -        setPawnOnto(pawn, move.to, move.orientation); -    } - -    protected void revertLastPawnMove(final Pawn pawn, final Move move) -    { -        removePawn(pawn); - -        revertclaim(pawn, move.to); -        for (Tile tile : move.tiles) -            revertclaim(pawn, tile); -        claim(pawn, move.from); - -        AnimationSequence seq = pawn.getRevertLastMoveAnimation(1); -        seq.addAnimation(RunnableAnimation.get(pawn, new Runnable() { -            @Override -            public void run() { -                pushPawnOnto(pawn, pawn.getTile()); -            } -        })); -        addAnimation(seq); -        pawn.revertLastMove(); -    } -      public void attack(final Pawn pawn, final Pawn target, boolean clearVisibility)      {          if (!pawn.canEngage(target) || !searchBoard.canAttack(pawn, target, clearVisibility)) diff --git a/core/src/ch/asynk/rustanddust/engine/Move.java b/core/src/ch/asynk/rustanddust/engine/Move.java index 09e7330..ff927c0 100644 --- a/core/src/ch/asynk/rustanddust/engine/Move.java +++ b/core/src/ch/asynk/rustanddust/engine/Move.java @@ -49,11 +49,10 @@ public class Move extends Path implements Iterable<Vector3>, Iterator          movePool.clear();      } -    public static Move getEnter(Pawn pawn, Tile to, Orientation orientation) +    public static Move getEnter(Pawn pawn, Tile from, Tile to, Orientation orientation, Path path)      { -        Move m = get(pawn, null, to, orientation, null); +        Move m = get(pawn, from, to, orientation, path);          m.type = MoveType.ENTER; -        m.cost = to.costFrom(pawn, orientation);          return m;      } @@ -122,11 +121,6 @@ public class Move extends Path implements Iterable<Vector3>, Iterator          return (type == MoveType.REGULAR);      } -    public boolean isFinal() -    { -        return (type != MoveType.ENTER); -    } -      public int steps()      {          int steps = 0; diff --git a/core/src/ch/asynk/rustanddust/engine/PathBuilder.java b/core/src/ch/asynk/rustanddust/engine/PathBuilder.java index edac1c3..609fe8b 100644 --- a/core/src/ch/asynk/rustanddust/engine/PathBuilder.java +++ b/core/src/ch/asynk/rustanddust/engine/PathBuilder.java @@ -294,6 +294,18 @@ public class PathBuilder implements Disposable          return Move.get(pawn, from, to, orientation, getPath(0));      } +    public Move getEnterMove(Pawn pawn, Tile from) +    { +        // getPath(0).tiles.insert(this.from, 0); +        // this.from = from; +        int cost = pawn.getSpentMovementPoints(); +        pawn.reset(); +        Move move = getMove(); +        move.type = Move.MoveType.ENTER; +        move.cost = cost + ((this.from == this.to) ? 0 : move.cost); +        return move; +    } +      public Move getExitMove()      {          Move move = getMove(); diff --git a/core/src/ch/asynk/rustanddust/engine/Pawn.java b/core/src/ch/asynk/rustanddust/engine/Pawn.java index fc0323f..d7c8749 100644 --- a/core/src/ch/asynk/rustanddust/engine/Pawn.java +++ b/core/src/ch/asynk/rustanddust/engine/Pawn.java @@ -115,20 +115,14 @@ public abstract class Pawn implements Moveable, Disposable      {          switch(move.type)          { -            case REGULAR: -                if ((this.move != null) && (!this.move.isEnter())) -                    throw new RuntimeException("try to override an existing move instance"); +            case SET:                  break; +            case REGULAR:              case ENTER: -                if (this.move != null) -                    throw new RuntimeException("try to override an existing move instance"); -                break;              case EXIT:                  if (this.move != null)                      throw new RuntimeException("try to override an existing move instance");                  break; -            case SET: -                break;              default:                  throw new RuntimeException("unsupported MoveType");          } @@ -144,11 +138,6 @@ public abstract class Pawn implements Moveable, Disposable          attack.distance = distance;      } -    public boolean justEntered() -    { -        return ((move != null) && move.isEnter()); -    } -      public boolean is(Faction faction)      {          return (this.faction == faction); @@ -333,28 +322,17 @@ public abstract class Pawn implements Moveable, Disposable          return hasOverlayEnabled();      } -    public AnimationSequence getRotateAnimation(float z, int size) -    { -        prevPosition.set(position); -        AnimationSequence seq = AnimationSequence.get(1 + size); -        seq.addAnimation(MoveToAnimation.get(this, position.x, position.y, z, MOVE_TIME)); - -        return seq; -    } - -    public AnimationSequence getMoveAnimation(Iterator<Vector3> vectors, int size, MoveToAnimation.MoveToAnimationCb cb) +    public AnimationSequence getMoveAnimation(Iterator<Vector3> vectors, AnimationSequence seq, MoveToAnimation.MoveToAnimationCb cb)      {          prevPosition.set(position); -        AnimationSequence seq = AnimationSequence.get(size);          while (vectors.hasNext())              seq.addAnimation(MoveToAnimation.get(this, vectors.next(), MOVE_TIME, cb));          return seq;      } -    public AnimationSequence getRevertLastMoveAnimation(int size) +    public AnimationSequence getRevertLastMoveAnimation(AnimationSequence seq)      { -        AnimationSequence seq = AnimationSequence.get(2 + size);          seq.addAnimation(MoveToAnimation.get(this, prevPosition, MOVE_TIME));          seq.addAnimation(RunnableAnimation.get(this, new Runnable() {              @Override diff --git a/core/src/ch/asynk/rustanddust/game/Battle.java b/core/src/ch/asynk/rustanddust/game/Battle.java index 168f5ee..4ed139c 100644 --- a/core/src/ch/asynk/rustanddust/game/Battle.java +++ b/core/src/ch/asynk/rustanddust/game/Battle.java @@ -24,14 +24,12 @@ public interface Battle extends Marshal      public Player getOpponent(); -    public void init(); +    public Map init(Ctrl ctrl);      public void desinit();      public void initialDeployment(); -    public boolean actionDone(); -      public boolean turnDone();      public boolean isDeploymentDone(); diff --git a/core/src/ch/asynk/rustanddust/game/Config.java b/core/src/ch/asynk/rustanddust/game/Config.java index 318eae9..db7fb5c 100644 --- a/core/src/ch/asynk/rustanddust/game/Config.java +++ b/core/src/ch/asynk/rustanddust/game/Config.java @@ -37,9 +37,10 @@ public class Config      public enum LoadMode      { -        LOAD("Load", 0), -        REPLAY_LAST("Replay Last Turn", 1), -        REPLAY_ALL("Full Replay", 2); +        NEW("New", 0), +        RESUME("Resume", 1), +        REPLAY_CURRENT("Replay Current Turn", 2), +        REPLAY_ALL("Full Replay", 3);          public String s;          public int i;          LoadMode(String s, int i) @@ -101,9 +102,9 @@ public class Config      public Config()      {          this.gameMode = GameMode.SOLO; -        this.loadMode = LoadMode.LOAD; +        this.loadMode = LoadMode.NEW;          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..9ff5d53 100644 --- a/core/src/ch/asynk/rustanddust/game/Ctrl.java +++ b/core/src/ch/asynk/rustanddust/game/Ctrl.java @@ -18,32 +18,54 @@ 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 +    enum Mode      { -        STATE_CHANGE, -        HUD_ANSWER, +        LOADING, +        REPLAY, +        PLAY, +    } + +    private static final boolean debugCtrl = false; + +    public enum MsgType +    { +        OK, +        CANCEL, +        PROMOTE,          ANIMATIONS_DONE, +        UNIT_DOCK_SELECT,          UNIT_DOCK_TOGGLE, -        UNIT_DOCK_SELECT; +        UNIT_DEPLOYED, +        UNIT_UNDEPLOYED, +    } + +    public enum EventType +    { +        ORDER, +        ORDER_DONE, +        STATE_CHANGE, +        ANIMATION, +        REPLAY_DONE, +        TURN_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; @@ -55,39 +77,37 @@ public abstract class Ctrl implements Disposable      public Map map;      public Hud hud; +    private float blockEvents;      public boolean blockMap;      public boolean blockHud;      private Hex touchedHex; +    protected int gameId;      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 Mode mode;      private State state;      private StateType stateType;      private StateType stateAfterAnimation;      public abstract void init(); -    protected abstract void actionDoneCb(); -    protected abstract void turnDoneCb(); -    public abstract void orderProcessedCb();      public static Ctrl getCtrl(final RustAndDust game)      {          Ctrl ctrl = null; -        switch(game.config.gameMode) { +        switch(game.config.gameMode) +        {              case SOLO:                  ctrl = new Solo(game);                  break; @@ -102,57 +122,57 @@ public abstract class Ctrl implements Disposable          this.battle = game.config.battle;          this.hud = new Hud(game); -        this.blockMap = false; +        this.blockEvents = 0.5f; +        this.blockMap = true;          this.blockHud = false;          this.touchedHex = null; +        this.gameId = -1;          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; +        this.mode = Mode.LOADING; -        battle.init(); -        this.map = battle.getMap(); +        this.map = battle.init(this);          init();          StateCommon.set(game);          hud.update(); -        this.state = selectState; -        this.stateType = StateType.DONE; -        this.stateAfterAnimation = StateType.DONE; - -        setState(battle.getState()); +        this.stateType = StateType.WAIT_EVENT; +        this.stateAfterAnimation = battle.getState(); -        if (synched) { -            this.hud.notify(battle.toString(), 2, Position.MIDDLE_CENTER, false); -            return; -        } +        setState(StateType.ANIMATION); -        switch(game.config.loadMode) { -            case REPLAY_ALL: -                // TODO REPLAY_ALL +        switch(game.config.loadMode) +        { +            case NEW: +                this.hud.notify(battle.toString(), 2, Position.MIDDLE_CENTER, false);                  break; -            case REPLAY_LAST: -                map.prepareReplayLastTurn(); -                setState(StateType.REPLAY); +            case RESUME: +                if (!synched) { +                    map.prepareReplayLastAction(); +                    this.stateAfterAnimation = StateType.REPLAY; +                }                  break; -            case LOAD: -                map.prepareReplayLastAction(); -                setState(StateType.REPLAY); +            case REPLAY_CURRENT: +                map.prepareReplayCurrentTurn(); +                this.stateAfterAnimation = StateType.REPLAY; +                break; +            case REPLAY_ALL: +                // TODO REPLAY ALL +                this.stateAfterAnimation = StateType.REPLAY;                  break;          } -      }      @Override @@ -167,13 +187,9 @@ public abstract class Ctrl implements Disposable      // JSON -    protected boolean isLoading() -    { -        return (stateType == StateType.LOADING); -    } -      protected void load(Marshal.Mode mode, String payload)      { +        if (payload == null) return;          JsonValue root = new JsonReader().parse(payload);          battle.load(mode, root);      } @@ -188,6 +204,27 @@ public abstract class Ctrl implements Disposable          return writer.toString();      } +    // DB +    private void storeState() +    { +        game.db.storeGameState(gameId, battle.getTurnCount(), battle.getPlayer().id, unload(Marshal.Mode.PLAYERS), unload(Marshal.Mode.MAP)); +    } + +    private void storeOrders() +    { +        game.db.storeGameOrders(gameId, battle.getTurnCount(), battle.getPlayer().id, unload(Marshal.Mode.ORDERS)); +    } + +    private void clearOrders() +    { +        game.db.clearGameOrders(gameId); +    } + +    private void storeTurn() +    { +        game.db.storeCurrentTurn(gameId); +    } +      // INPUTS      public boolean drag(float x, float y, int dx, int dy) @@ -199,9 +236,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 +248,64 @@ 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) +    { +        RustAndDust.debug(String.format("Msg : %s %s", msgType, 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 postTurnDone() { postEvent(EventType.TURN_DONE); } +    public void postActionAborted() { postEvent(EventType.ACTION_ABORTED); } +    public void postReplayDone(StateType stateType) { postEvent(EventType.REPLAY_DONE, stateType); }      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 postAnswer(Hud.OkCancelAction what, boolean status) +    public void postOrder(Order order)      { -        Event evt = getEvent(); -        evt.type = EventType.HUD_ANSWER; -        evt.data = what; -        evt.status = status; -        events.enqueue(evt); +        postOrder(order, null); +    } + +    public void postInitOrder(Order order) +    { +        // postEvent(EventType.ORDER, order); +        // postEvent(EventType.ORDER_DONE, stateType); +        executeOrder(order); +        orderDone(null); +    } + +    public void postOrder(Order order, StateType stateType) +    { +        postEvent(EventType.ORDER, order); +        switch(order.type) +        { +            case END: +            case REVERT: +                break; +            default: +                postEvent(EventType.ANIMATION, StateType.WAIT_EVENT); +        } +        postEvent(EventType.ORDER_DONE, stateType);      }      public void postEvent(EventType type) @@ -250,33 +315,39 @@ 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);      } -    public void processEvent() +    public void processEvent(float delta)      { -        if (events.size() <= 0) +        if (blockEvents > 0f) { +            blockEvents -= delta; +            if (blockEvents > 0f) +                return; +        } +        if ((events.size() <= 0) || inAnimation())              return;          Event evt = events.dequeue(); -        switch(evt.type) { -            case STATE_CHANGE: -                setState((StateType) evt.data); -                break; -            case HUD_ANSWER: -                handleHudAnswer(evt); -                break; -            case ANIMATIONS_DONE: -                animationsDone(); -                break; -            case UNIT_DOCK_TOGGLE: -                unitDockToggle(); -                break; -            case UNIT_DOCK_SELECT: -                unitDockSelect((Unit) evt.data); +        RustAndDust.debug(evt.toString()); + +        switch(evt.type) +        { +            case ORDER:             executeOrder((Order) evt.data); break; +            case ORDER_DONE:        orderDone((StateType) evt.data); break; +            case STATE_CHANGE:      setState((StateType) evt.data); break; +            case REPLAY_DONE:       replayDone((StateType) evt.data); break; +            case TURN_DONE:         turnDone(); break; +            case ACTION_ABORTED:    abortAction(); break; +            case EXIT_BATTLE:       exitBattle(); break; +            case ANIMATION: +                stateAfterAnimation = (StateType) evt.data; +                setState(StateType.ANIMATION);                  break;              default:                  RustAndDust.error(String.format("Unhandled Event Type : %s %s", evt.type, evt.data)); @@ -284,243 +355,244 @@ public abstract class Ctrl implements Disposable          freeEvents.push(evt);      } -    // State callbacks - -    public void setAfterAnimationState(StateType after) +    private boolean inAnimation()      { -        stateAfterAnimation = after; -    } - -    // Event handlers - -    private void handleHudAnswer(Event evt) -    { -        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) { -            StateType tmp = stateAfterAnimation; -            stateAfterAnimation = StateType.DONE; -            setState(tmp); + +        if (mode == Mode.LOADING) { +            this.mode = ((stateAfterAnimation == StateType.REPLAY) ? Mode.REPLAY : Mode.PLAY); +            if (game.config.loadMode == Config.LoadMode.NEW) { +                storeState(); +                storeTurn(); +            } +            if (mode == Mode.PLAY) +                map.clear(true);          } +        this.blockMap = false; +        StateType tmp = stateAfterAnimation; +        stateAfterAnimation = StateType.WAIT_EVENT; +        setState(tmp);      } -    private void unitDockSelect(Unit unit) +    private void replayDone(StateType nextState)      { -        if ((stateType == StateType.DEPLOYMENT) || (stateType == StateType.REINFORCEMENT)) -            state.touch(null); +        if (debugCtrl) RustAndDust.debug("    REPLAY DONE"); +        hud.notify("Replay Done", Position.MIDDLE_CENTER); +        this.mode = Mode.PLAY; +        if (nextState != null) { +            setState(nextState); +        } else { +            if (!synched) { +                storeState(); +                synched = true; +            } +            if (battle.getPlayer().apExhausted()) +                postTurnDone(); +            else if (!battle.getPlayer().canDoSomething()) +                postTurnDone(); +            else +                setState(battle.getState()); +        }      } -    private void unitDockToggle() +    private void executeOrder(Order order)      { -        if (this.stateType == StateType.SELECT) -            setState(StateType.REINFORCEMENT); -        else if (this.stateType == StateType.REINFORCEMENT) -            setState(StateType.SELECT); +        if (debugCtrl) RustAndDust.debug("    EXECUTE ORDER"); +        lastOrder = order; +        map.execute(order); +        if ((order.type == Order.OrderType.ENGAGE) && !order.replay) { +            game.ctrl.hud.engagementSummary(order.engagement); +        } +        if (this.mode == Mode.PLAY) +            storeOrders(); +        hud.update();      } -    // - -    private void turnDone() +    private void orderDone(StateType nextState)      { -        if (battle.turnDone()) -            hud.victory(battle.getPlayer(), battle.getOpponent()); -        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()); -        } -    } +        if (debugCtrl) RustAndDust.debug("    ORDER DONE -> " + nextState); +        Order order = this.lastOrder; +        this.lastOrder = null; +        if (nextState == null) +            nextState = battle.getState(); -    // +        completeOrder(order); -    private void setState(StateType nextState) -    { -        depth += 1; -        if (depth > 1) -            RustAndDust.error(String.format("***!!!*** STATE DEPTH : %d", depth)); +        if (mode == Mode.LOADING) +            return; -        if (nextState == StateType.ABORT) -            nextState = abortAction(); -        else if (nextState == StateType.DONE) { -            nextState = complete(); +        if (mode == Mode.REPLAY) { +            if (order.cost > 0) +                battle.getPlayer().burnDownOneAp(); +            hud.update(); +            blockEvents = 0.2f; +            post(nextState); +            return;          } -        if (stateType == StateType.ANIMATION) { -            this.blockMap = hud.dialogActive(); -            if (nextState == StateType.REPLAY) -                completeReplayStep(); +        if (order.cost == 0) { +            post(nextState); +            return;          } -        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; +        battle.getPlayer().burnDownOneAp(); +        hud.notify("1 Action Point burnt"); +        hud.update(); -        this.state.enterFrom(tmp); +        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); +        } -        if (nextState == StateType.TURN_OVER) -            turnDone(); -        depth -= 1; +        storeState();      } -    private StateType complete() +    private void completeOrder(Order order)      { -        switch(stateType) { -            case DEPLOYMENT: -                return completeDeployment(); -            case REPLAY: -                return completeReplay(); -            default: -                return completeAction(); +        switch(order.type) +        { +            case MOVE:      completeMoveOrder(order, (Unit) order.move.pawn); break; +            case ENGAGE:    completeEngagementOrder(order, order.engagement.defender); break; +            case PROMOTE:   battle.getPlayer().promote(order.leader); break; +            case REVERT:    break; +            case END:       break; +            default:        break;          }      } -    private StateType completeDeployment() +    private void completeEngagementOrder(Order order, Unit unit)      { -        if (battle.isDeploymentDone()) -            hud.askEndDeployment(); -        battle.actionDone(); -        return StateType.DEPLOYMENT; +        if (order.engagement.success) { +            battle.getPlayer().engagementWon += 1; +            battle.getOpponent().casualty(unit); +        } else { +            battle.getPlayer().engagementLost += 1; +        }      } -    private StateType abortAction() +    private void completeMoveOrder(Order order, Unit unit)      { -        hud.notify("Action canceled"); -        StateType nextState = this.state.abort(); - -        if (nextState == StateType.ABORT) -            nextState = battle.getState(); - -        return nextState; +        switch(order.move.type) +        { +            case EXIT:      battle.getPlayer().unitWithdraw(unit); break; +            case SET:       battle.getPlayer().unitEntry(unit); break; +            case ENTER:     battle.getPlayer().unitEntry(unit); break; +            case REGULAR:   break; +            default:        break; +        }      } -    private StateType completeAction() +    private void turnDone()      { -        StateType nextState = this.state.execute(); +        if (debugCtrl) RustAndDust.debug("    TURN DONE"); -        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()) { +        setState(StateType.WAIT_EVENT); + +        if (battle.turnDone()) +            hud.victory(battle.getPlayer(), battle.getOpponent()); +        else { +            hud.update(); +            if (battle.getPlayer().hasReinforcement()) +                hud.notify("You have reinforcement", 2, Position.MIDDLE_CENTER, true); +            if (!battle.getPlayer().canDoSomething()) {                  hud.notify("No available Actions"); -                nextState = StateType.TURN_OVER; -            } else -                nextState = battle.getState(); +                postTurnDone(); +            } else { +                post(battle.getState()); +            }          } -        return nextState; +        storeState(); +        storeTurn(); +        map.clear(true); +        clearOrders();      } -    private StateType completeReplay() +    private void abortAction()      { -        if (battle.getPlayer().apExhausted()) { -            return StateType.TURN_OVER; -        } else if (!battle.getPlayer().canDoSomething()) { -            return StateType.TURN_OVER; -        } else -            return battle.getState(); +        if (debugCtrl) RustAndDust.debug("    ABORT ACTION"); +        post(battle.getState());      } -    private void completeReplayStep() +    private void exitBattle()      { -        StateType nextState = replayState.execute(); +        if (debugCtrl) RustAndDust.debug("    EXIT BATTLE"); +        game.switchToMenu(); +    } -        if (nextState == StateType.DONE) { -            battle.getPlayer().burnDownOneAp(); -            hud.update(); +    private void unitDockToggle() +    { +        if (this.stateType == StateType.SELECT) +            post(StateType.REINFORCEMENT); +        else if (this.stateType == StateType.REINFORCEMENT) { +            sendMsg(MsgType.OK); +            post(StateType.SELECT);          }      } -    private State getNextState(StateType nextState) +    // + +    private void setState(StateType nextState)      { -        RustAndDust.debug("Ctrl", String.format("  %s -> %s : %s", stateType, nextState, battle.getPlayer())); +        if (stateType == nextState) +            RustAndDust.error("***!!!*** STATE LOOP ********************************************************************** " + stateType); -        State state = this.state; +        if (nextState == StateType.WAIT_EVENT) { +            stateType = nextState; +            if (debugCtrl) RustAndDust.debug("    WAIT_EVENT"); +            return; +        } -        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; +        depth += 1; +        if (depth > 1) +            RustAndDust.error(String.format("***!!!*** STATE DEPTH : %d", depth)); + +        if (nextState == StateType.DEPLOYMENT) { +            if (battle.isDeploymentDone()) +                hud.askEndDeployment(); +        } + +        hud.playerInfo.blockEndOfTurn(nextState != StateType.SELECT); + +        this.state = getNextState(nextState); +        StateType tmp = stateType; +        stateType = nextState; +        this.state.enterFrom(tmp); + +        depth -= 1; +    } + +    private State getNextState(StateType nextState) +    { +        RustAndDust.debug("  State Change", String.format("%s -> %s", stateType, nextState)); + +        switch(nextState) +        { +            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/Engagement.java b/core/src/ch/asynk/rustanddust/game/Engagement.java index b9630b8..4c29c3d 100644 --- a/core/src/ch/asynk/rustanddust/game/Engagement.java +++ b/core/src/ch/asynk/rustanddust/game/Engagement.java @@ -35,6 +35,7 @@ public class Engagement implements Disposable, Pool.Poolable      public Unit defender;      public UnitList assists;      public boolean success; +    public int cost;      public int d1;      public int d2;      public int d3; diff --git a/core/src/ch/asynk/rustanddust/game/Hex.java b/core/src/ch/asynk/rustanddust/game/Hex.java index 34ccdb3..ea988be 100644 --- a/core/src/ch/asynk/rustanddust/game/Hex.java +++ b/core/src/ch/asynk/rustanddust/game/Hex.java @@ -103,10 +103,10 @@ public class Hex extends Tile      public int costFrom(Pawn pawn, Orientation side)      {          if (side == Orientation.KEEP) return 0; -        if (hasUnits()) return (Integer.MAX_VALUE / 2); +        if (hasUnits()) return Integer.MAX_VALUE;          if (roadFrom(side)) return 1; -        int c = 0; +        int c = Integer.MAX_VALUE;          switch(terrain) {              case CLEAR:              case HILLS: @@ -118,7 +118,6 @@ public class Hex extends Tile                  break;              case OFFMAP:              case BLOCKED: -                c = (Integer.MAX_VALUE / 2);                  break;          } diff --git a/core/src/ch/asynk/rustanddust/game/Hud.java b/core/src/ch/asynk/rustanddust/game/Hud.java index b58c8f1..936d8b0 100644 --- a/core/src/ch/asynk/rustanddust/game/Hud.java +++ b/core/src/ch/asynk/rustanddust/game/Hud.java @@ -218,12 +218,22 @@ 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); +            boolean ok = false; +            if (okCancel.ok) { +                ok = true; +                game.playEnter(); +            } else +                game.playType(); +            if (ok) { +                if (this.okCancelAction == OkCancelAction.EXIT_BATTLE) +                    ctrl.postEvent(Ctrl.EventType.EXIT_BATTLE); +                else +                    ctrl.sendMsg(Ctrl.MsgType.OK); +            } else +                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..6a0bb03 100644 --- a/core/src/ch/asynk/rustanddust/game/Map.java +++ b/core/src/ch/asynk/rustanddust/game/Map.java @@ -24,33 +24,17 @@ public abstract class Map extends Map5Marshal          meteorology = new Meteorology();      } -    public void clearAll() +    public void clear() { clear(false); } +    public void clear(boolean orders)      { +        if (orders) { +            RustAndDust.debug("  Map", String.format("Clearder Orders : %d", ordersSize())); +            ordersClear(); +        }          clearMoves();          clearUnits();      } -    public void actionDone() -    { -        incActionId(); -        game.ctrl.actionDoneCb(); -    } - -    public void turnDone() -    { -        RustAndDust.debug("TurnDone", String.format(" Processed Orders : %d", ordersSize())); -        game.ctrl.turnDoneCb(); -        ordersClear(); -    } - -    @Override -    protected int engagementCost(Engagement e) -    { -        if ((activatedUnits.size() == 1) && e.attacker.isA(Unit.UnitType.AT_GUN) && e.defender.isHardTarget()) -            return 0; -        return 1; -    } -      @Override      protected void resolveEngagement(Engagement e)      { @@ -116,6 +100,15 @@ public abstract class Map extends Map5Marshal              e.d4 = 0;          } +        activableUnits.clear(); +        if (success) { +            for (Unit unit : activatedUnits) { +                if (unit.canBreak()) +                    activableUnits.add(unit); +            } +        } + +        e.cost = (((cnt == 1) && e.attacker.isA(Unit.UnitType.AT_GUN) && e.defender.isHardTarget()) ? 0 : 1);          e.set(cnt, flk, def, tdf, wdf);          e.success = success;      } diff --git a/core/src/ch/asynk/rustanddust/game/Order.java b/core/src/ch/asynk/rustanddust/game/Order.java index b959628..528d4d7 100644 --- a/core/src/ch/asynk/rustanddust/game/Order.java +++ b/core/src/ch/asynk/rustanddust/game/Order.java @@ -10,6 +10,7 @@ public class Order implements Disposable, Pool.Poolable, Comparable<Unit>      public static int orderId = 1;      public static final Order END = new Order(OrderType.END); +    public static final Order REVERT = new Order(OrderType.REVERT);      public enum OrderType      { @@ -18,6 +19,7 @@ public class Order implements Disposable, Pool.Poolable, Comparable<Unit>          ENGAGE,          PROMOTE,          END, +        REVERT,      }      private static final Pool<Order> orderPool = new Pool<Order>() @@ -64,6 +66,8 @@ public class Order implements Disposable, Pool.Poolable, Comparable<Unit>      @Override      public void dispose()      { +        if ((type == OrderType.END) || (type == OrderType.REVERT)) +            throw new RuntimeException(String.format("call dispose() on a static Order %s", type));          orderPool.free(this);      } @@ -102,32 +106,44 @@ public class Order implements Disposable, Pool.Poolable, Comparable<Unit>      @Override      public String toString()      { -        if (type == OrderType.END) -            return String.format("[00] END"); -        else -            return String.format("[%d] %s(%d) : %s", id, type, cost, leader.code); +        switch (type) +        { +            case END: +                return String.format("[00] END"); +            case REVERT: +                return String.format("%s[%d]", type, id); +            default: +                return String.format("[%d] %s(%d) : %s", id, type, cost, leader.code); +        }      }      public void setMove(Unit unit, Move move)      { -        this.leader = unit;          this.type = OrderType.MOVE; +        this.leader = unit;          this.move = move;      }      public void setPromote(Unit unit)      { -        this.leader = unit;          this.type = OrderType.PROMOTE; +        this.leader = unit;      }      public void setEngage(Unit unit, Unit target)      { -        this.leader = unit;          this.type = OrderType.ENGAGE; +        this.leader = unit;          this.engagement = Engagement.get(unit, target);      } +    public void setRevert(int id) +    { +        this.type = OrderType.REVERT; +        this.id = id; +        this.cost = 0; +    } +      public void setActivables(UnitList l)      {          for(Unit u : l) diff --git a/core/src/ch/asynk/rustanddust/game/Player.java b/core/src/ch/asynk/rustanddust/game/Player.java index c5d3473..0018e1a 100644 --- a/core/src/ch/asynk/rustanddust/game/Player.java +++ b/core/src/ch/asynk/rustanddust/game/Player.java @@ -193,12 +193,12 @@ public class Player      public void turnEnd()      {          apSpent = ap; -        for (Unit unit : units) -            unit.reset();      }      public void turnStart(int aps)      { +        for (Unit unit : units) +            unit.reset();          if (isDeploymentDone()) {              ap = aps;              apSpent = 0; diff --git a/core/src/ch/asynk/rustanddust/game/State.java b/core/src/ch/asynk/rustanddust/game/State.java index a3a6fec..9ab1576 100644 --- a/core/src/ch/asynk/rustanddust/game/State.java +++ b/core/src/ch/asynk/rustanddust/game/State.java @@ -1,32 +1,25 @@  package ch.asynk.rustanddust.game; +import ch.asynk.rustanddust.game.Ctrl.MsgType; +  public interface State  { -    enum StateType { -        LOADING, +    enum StateType +    {          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/Unit.java b/core/src/ch/asynk/rustanddust/game/Unit.java index 7a9f2e2..4dd04ee 100644 --- a/core/src/ch/asynk/rustanddust/game/Unit.java +++ b/core/src/ch/asynk/rustanddust/game/Unit.java @@ -315,7 +315,7 @@ public class Unit extends HeadedPawn          if (cost > mpLeft)              RustAndDust.debug("ERROR: Movement point exceeded: " + cost + "/" + mpLeft + " please report"); -        if ((cost > 0) && move.isFinal()) +        if (cost > 0)              setMoved();          spendMovementPoints(cost); diff --git a/core/src/ch/asynk/rustanddust/game/battles/BattleCommon.java b/core/src/ch/asynk/rustanddust/game/battles/BattleCommon.java index e7bcac5..a70698b 100644 --- a/core/src/ch/asynk/rustanddust/game/battles/BattleCommon.java +++ b/core/src/ch/asynk/rustanddust/game/battles/BattleCommon.java @@ -6,6 +6,7 @@ import com.badlogic.gdx.utils.Json;  import com.badlogic.gdx.utils.JsonValue;  import ch.asynk.rustanddust.util.Marshal; +import ch.asynk.rustanddust.game.Ctrl;  import ch.asynk.rustanddust.game.Battle;  import ch.asynk.rustanddust.game.Player;  import ch.asynk.rustanddust.game.State; @@ -13,6 +14,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; @@ -21,6 +23,7 @@ public abstract class BattleCommon implements Battle  {      protected final static Random random = new Random(System.currentTimeMillis()); +    private Ctrl ctrl;      protected final Factory factory;      protected int _id; @@ -67,12 +70,14 @@ public abstract class BattleCommon implements Battle      @Override public Factory.MapType getMapType()   { return mapType; }      @Override -    public void init() +    public Map init(Ctrl ctrl)      { +        this.ctrl = ctrl;          this.map = factory.getMap(getMapType());          setup();          this.turnCount = 0;          this.currentPlayer = players[0]; +        return this.map;      }      @Override @@ -90,52 +95,49 @@ public abstract class BattleCommon implements Battle      {          this.currentPlayer = players[0];          deployPlayer(); -        currentPlayer.turnEnd();          this.currentPlayer = players[1];          deployPlayer(); -        currentPlayer.turnEnd();          this.currentPlayer = players[0]; -        map.turnDone();      }      public void load(Marshal.Mode mode, JsonValue value)      { -        map.load(mode, value); -        if((mode == Marshal.Mode.FULL) || (mode == Marshal.Mode.STATE)) { -            JsonValue v = value.get("battle"); -            this.turnCount = v.getInt("turnCount"); +        if (mode == Marshal.Mode.PLAYERS) {              map.loadPlayers(value, players); +            this.currentPlayer = players[0]; +        } else { +            if (mode == Marshal.Mode.MAP) { +                JsonValue v = value.get("battle"); +                this.turnCount = v.getInt("turnCount"); +                Unit.unitId = v.getInt("unitId"); +                Order.orderId = v.getInt("orderId"); +            } +            map.load(mode, value);          } -        this.currentPlayer = players[0];      }      @Override      public void unload(Marshal.Mode mode, Json json)      {          json.writeObjectStart(); -        if((mode == Marshal.Mode.FULL) || (mode == Marshal.Mode.STATE)) { -            json.writeObjectStart("battle"); -            json.writeValue("turnCount", turnCount); -            json.writeObjectEnd(); +        if (mode == Marshal.Mode.PLAYERS)              map.unloadPlayers(json, getPlayer(), getOpponent()); +        else { +            if (mode == Marshal.Mode.MAP) { +                json.writeObjectStart("battle"); +                json.writeValue("turnCount", this.turnCount); +                json.writeValue("unitId", Unit.unitId); +                json.writeValue("orderId", Order.orderId); +                json.writeObjectEnd(); +            } +            map.unload(mode, json);          } -        map.unload(mode, json);          json.writeObjectEnd();      }      @Override -    public boolean actionDone() -    { -        boolean burn = (map.unitsActivatedSize() > 0); -        if (burn) -            currentPlayer.burnDownOneAp(); -        map.actionDone(); -        return burn; -    } - -    @Override      public boolean turnDone()      {          boolean ret = false; @@ -150,7 +152,7 @@ public abstract class BattleCommon implements Battle          }          turnCount += 1;          setNextTurn(); -        map.turnDone(); +        map.clear();          return ret;      } @@ -260,7 +262,7 @@ 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); +        ctrl.postInitOrder(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..29a8755 100644 --- a/core/src/ch/asynk/rustanddust/game/ctrl/Solo.java +++ b/core/src/ch/asynk/rustanddust/game/ctrl/Solo.java @@ -7,8 +7,6 @@ import ch.asynk.rustanddust.game.Ctrl;  public class Solo extends Ctrl  { -    private int gameId; -      public Solo(final RustAndDust game)      {          super(game); @@ -17,8 +15,8 @@ public class Solo extends Ctrl      @Override      public void init()      { -        gameId = game.config.gameId; -        if (gameId == game.db.NO_RECORD) { +        GameRecord r = loadState(); +        if (r == null) {              int me = game.backend.getMyId();              int other = game.backend.getOpponentId();              gameId = game.db.storeGameGetId(other, battle.getId(), game.config.gameMode.i); @@ -27,68 +25,28 @@ public class Solo extends Ctrl              battle.initialDeployment();              synched = true;          } else { -            GameRecord r = loadState(); -            if (r != null) { -                load(Marshal.Mode.STATE, r.state); -                load(Marshal.Mode.ORDERS, r.orders); -                battle.getMap().clearMarshalUnits(); -                synched = r.synched; -                r.dispose(); -            } else -                System.err.println("TODO : null GameRecord"); +            load(Marshal.Mode.MAP, r.map); +            load(Marshal.Mode.PLAYERS, r.players); +            load(Marshal.Mode.ORDERS, r.orders); +            battle.getMap().clearMarshalUnits(); +            synched = r.synched; +            r.dispose();          }      }      private GameRecord loadState()      {          GameRecord r = null; -        switch (game.config.loadMode) { -            case LOAD: -                r = game.db.loadGame(gameId); -                break; -            case REPLAY_LAST: -                r = game.db.loadLastTurn(gameId); -                break; +        gameId = game.config.gameId; +        switch (game.config.loadMode) +        { +            case NEW:               break; +            case RESUME:            r = game.db.loadGame(gameId); break; +            case REPLAY_CURRENT:    r = game.db.loadLastTurn(gameId); break;              case REPLAY_ALL:                  // TODO REPLAY_ALL                  break;          }          return r;      } - -    @Override -    public void orderProcessedCb() -    { -        if (!isLoading()) -            storeOrders(); -    } - -    @Override -    protected void actionDoneCb() -    { -        storeState(); -    } - -    @Override -    protected void turnDoneCb() -    { -        storeOrders(); -        storeState(); -        storeTurn(); -    } - -    private void storeState() -    { -        game.db.storeGameState(gameId, battle.getTurnCount(), battle.getPlayer().id, unload(Marshal.Mode.STATE)); -    } - -    private void storeOrders() -    { -        game.db.storeGameOrders(gameId, battle.getTurnCount(), battle.getPlayer().id, unload(Marshal.Mode.ORDERS)); -    } - -    private void storeTurn() -    { -        game.db.storeLastTurn(gameId); -    }  } 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..9f86b13 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.hud.notify(unitDock.selectedUnit.toString()); +            ctrl.sendMsg(Ctrl.MsgType.UNIT_DOCK_SELECT, unitDock.selectedUnit);              return true;          } diff --git a/core/src/ch/asynk/rustanddust/game/map/Map1Units.java b/core/src/ch/asynk/rustanddust/game/map/Map1Units.java index 3aa0c8d..b490042 100644 --- a/core/src/ch/asynk/rustanddust/game/map/Map1Units.java +++ b/core/src/ch/asynk/rustanddust/game/map/Map1Units.java @@ -79,13 +79,13 @@ public abstract class Map1Units extends Map0Hex          }      } -    public Unit unitsMoveableGet(int i) { return activableUnits.get(i); } +    public Unit getFirstActivable()     { return activableUnits.get(0); }      public void unitsTargetClear()      { targetUnits.clear(); }      public void unitsActivatedClear()   { activatedUnits.clear(); }      public int unitsActivatedSize()     { return activatedUnits.size(); } -    public int unitsActivableSize()      { return activableUnits.size(); } +    public int unitsActivableSize()     { return activableUnits.size(); }      public boolean unitsTargetContains(Unit unit)       { return targetUnits.contains(unit); }      public boolean unitsActivableContains(Unit unit)    { return activableUnits.contains(unit); } @@ -94,8 +94,8 @@ public abstract class Map1Units extends Map0Hex      public void unitsTargetHide()       { unitsShowOverlay(targetUnits, Unit.TARGET, false); }      public void unitsAssistShow()       { unitsShowOverlay(activableUnits, Unit.MAY_FIRE, true); }      public void unitsAssistHide()       { unitsShowOverlay(activableUnits, Unit.MAY_FIRE, false); unitsShowOverlay(activableUnits, Unit.FIRE, false); } -    public void unitsActivableShow()     { unitsShowOverlay(activableUnits, Unit.ACTIVEABLE, true); } -    public void unitsActivableHide()     { unitsShowOverlay(activableUnits, Unit.ACTIVEABLE, false); } +    public void unitsActivableShow()    { unitsShowOverlay(activableUnits, Unit.ACTIVEABLE, true); } +    public void unitsActivableHide()    { unitsShowOverlay(activableUnits, Unit.ACTIVEABLE, false); }      private void unitsShowOverlay(UnitList units, int overlay, boolean on)      { diff --git a/core/src/ch/asynk/rustanddust/game/map/Map2Moves.java b/core/src/ch/asynk/rustanddust/game/map/Map2Moves.java index e7ba8ce..e092fea 100644 --- a/core/src/ch/asynk/rustanddust/game/map/Map2Moves.java +++ b/core/src/ch/asynk/rustanddust/game/map/Map2Moves.java @@ -51,21 +51,10 @@ 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 void pathsInit(Unit unit, Hex from)      { paths.init(unit, from); }      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..d109366 100644 --- a/core/src/ch/asynk/rustanddust/game/map/Map3Animations.java +++ b/core/src/ch/asynk/rustanddust/game/map/Map3Animations.java @@ -4,6 +4,7 @@ import com.badlogic.gdx.audio.Sound;  import com.badlogic.gdx.graphics.Texture;  import ch.asynk.rustanddust.RustAndDust; +import ch.asynk.rustanddust.engine.Move;  import ch.asynk.rustanddust.engine.SelectedTile;  import ch.asynk.rustanddust.engine.gfx.Moveable;  import ch.asynk.rustanddust.engine.gfx.animations.AnimationSequence; @@ -21,7 +22,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  { @@ -31,6 +32,8 @@ public abstract class Map3Animations extends Map2Moves implements MoveToAnimatio      private Sound sound;      private long soundId = -1; +    protected static final float BOUNCE_DURATION = 0.3f; +      public Map3Animations(final RustAndDust game, Texture map, SelectedTile hex)      {          super(game, map, hex); @@ -92,18 +95,50 @@ public abstract class Map3Animations extends Map2Moves implements MoveToAnimatio      // <- implement MoveToAnimationCb -    protected void addBounceAnimation(final Unit unit, float duration) +    protected void moveUnit(final Unit unit, final Move move, MoveToAnimationCb cb, boolean bounce)      { -        addAnimation(BounceAnimation.get(unit, duration)); +        removePawn(unit); + +        AnimationSequence seq = AnimationSequence.get(move.steps() + (bounce ? 2 : 1)); +        if (bounce) seq.addAnimation(BounceAnimation.get(unit, BOUNCE_DURATION)); +        unit.getMoveAnimation(move.iterator(), seq, cb); +        seq.addAnimation(RunnableAnimation.get(unit, new Runnable() { +            @Override +            public void run() { +                unit.move(move); +                if (!move.to.isOffMap()) +                    setPawnOnto(unit, move.to, move.orientation); +            } +        })); +        addAnimation(seq);      } -    protected void addPromoteAnimation(final Unit unit, final Player player, final Runnable after) +    protected void revertLastUnitMove(final Unit unit, final Move move)      { -        Hex hex = unit.getHex(); -        AnimationSequence seq = AnimationSequence.get(2); -        seq.addAnimation(PromoteAnimation.get((unit.getArmy() == Army.US), hex.getX(), hex.getY(), game.config.fxVolume)); -        seq.addAnimation(RunnableAnimation.get(unit, after)); +        removePawn(unit); +        revertClaim(unit, move); + +        AnimationSequence seq = AnimationSequence.get(1); +        unit.getRevertLastMoveAnimation(seq); +        seq.addAnimation(RunnableAnimation.get(unit, new Runnable() { +            @Override +            public void run() { +                setPawnOnto(unit, move.to, move.orientation); +            } +        }));          addAnimation(seq); +        unit.revertLastMove(); +    } + +    protected void addBounceAnimation(final Unit unit) +    { +        addAnimation(BounceAnimation.get(unit, BOUNCE_DURATION)); +    } + +    protected void addPromoteAnimation(final Unit unit, final Player player) +    { +        Hex hex = unit.getHex(); +        addAnimation(PromoteAnimation.get((unit.getArmy() == Army.US), hex.getX(), hex.getY(), game.config.fxVolume));      }      protected void addDestroyAnimation(Unit unit) @@ -142,6 +177,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..05cc569 100644 --- a/core/src/ch/asynk/rustanddust/game/map/Map4Orders.java +++ b/core/src/ch/asynk/rustanddust/game/map/Map4Orders.java @@ -6,8 +6,10 @@ import ch.asynk.rustanddust.RustAndDust;  import ch.asynk.rustanddust.engine.Move;  import ch.asynk.rustanddust.engine.SelectedTile;  import ch.asynk.rustanddust.engine.Orientation; -import ch.asynk.rustanddust.game.Hex; +import ch.asynk.rustanddust.game.Ctrl.MsgType;  import ch.asynk.rustanddust.game.Unit; +import ch.asynk.rustanddust.game.Hex; +import ch.asynk.rustanddust.game.Zone;  import ch.asynk.rustanddust.game.Order;  import ch.asynk.rustanddust.game.OrderList;  import ch.asynk.rustanddust.game.Engagement; @@ -17,15 +19,12 @@ 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);      public Map4Orders(final RustAndDust game, Texture map, SelectedTile hex)      {          super(game, map, hex); -        this.orderId = 0;          this.orders = new OrderList(10);          this.replayOrders = new OrderList(10);      } @@ -39,78 +38,126 @@ public abstract class Map4Orders extends Map3Animations          Engagement.clearPool();      } -    protected void incOrderId() { orderId += 1; }      protected int ordersSize() { return orders.size(); }      protected void ordersClear() { orders.dispose(); }      // STATES ENTRY -> -    public void showOnBoard(final Unit unit, Hex to, Orientation o) +    public void setOnBoard(final Unit unit, Move move)      { -        setPawnOnto(unit, to, o); +        setPawnOnto(unit, move); +        addBounceAnimation(unit);      } -    public boolean setOnBoard(final Unit unit, Hex to, Orientation entry) +    public void setOnBoard(final Unit unit, Hex to, Orientation o)      { -        orders.dispose(unit); -        return process(getMoveOrder(unit, Move.getSet(unit, to, entry))); +        setPawnOnto(unit, to, o); +        addBounceAnimation(unit);      } -    public boolean enterBoard(final Unit unit, Hex to, int allowedMoves) +    public boolean enterBoard(final Unit unit, Hex to, Zone entryZone)      { -        Orientation entry = findBestEntry(unit, to, allowedMoves); +        Orientation entry = findBestEntry(unit, to, entryZone.allowedMoves);          if (entry == Orientation.KEEP)              return false; - -        return process(getMoveOrder(unit, Move.getEnter(unit, to, entry))); +        unit.spendMovementPoints(to.costFrom(unit, entry)); +        setOnBoard(unit, to, entry.opposite()); +        return true;      } -    public boolean exitBoard(final Unit unit) +    public void revertEnter(final Unit unit)      { -        return process(getMoveOrder(unit, paths.getExitMove())); +        removePawn(unit); +        unit.reset();      } -    public boolean moveUnit(final Unit unit) +    public Order getSetOrder(final Unit unit, final Hex to, final Orientation o)      { -        return process(getMoveOrder(unit, paths.getMove())); +        Order order = getMoveOrder(unit, Move.getSet(unit, to, o), false); +        order.cost = 0; + +        return order;      } -    public void revertMoves() +    public Order getRevertSetOrder(Unit unit)      { -        for (Unit unit: activatedUnits) { -            RustAndDust.debug("    revertMove() " + unit); -            revertLastPawnMove(unit, ((Order) orders.get(unit, Order.OrderType.MOVE)).move); -            orders.dispose(unit, Order.OrderType.MOVE); +        Order o = orders.get(unit, Order.OrderType.MOVE); +        if (o == null) { +            RustAndDust.error(String.format("can't revert order : %s %s", Order.OrderType.MOVE, unit)); +            return null;          } -        activatedUnits.clear(); +        Order order = Order.REVERT; +        order.setRevert(o.id); + +        return order;      } -    public void revertEnter(final Unit unit) +    public Order getExitOrder(final Unit unit, boolean hqMode)      { -        RustAndDust.debug("    revertEnter() "+ unit); +        Order order = getMoveOrder(unit, paths.getExitMove(), hqMode); -        revertclaim(unit, unit.getHex()); -        removePawn(unit); -        game.ctrl.battle.getPlayer().revertUnitEntry(unit); -        orders.dispose(unit); -        unit.reset(); +        return order;      } -    public boolean engageUnit(final Unit unit, final Unit target) +    public Order getEnterOrder(final Unit unit, boolean hqMode)      { -        attack(unit, target, true); +        Order order = getMoveOrder(unit, paths.getEnterMove(unit, getAdjTileAt(unit.getTile(), unit.getOrientation().opposite())), hqMode); + +        return order; +    } + +    public Order getMoveOrder(final Unit unit, boolean hqMode) +    { +        Order order = getMoveOrder(unit, paths.getMove(), hqMode); +        return order; +    } + +    // FIXME revertMoves(...) +    // public void revertMoves() +    // { +    //     for (Unit unit: activatedUnits) { +    //         RustAndDust.debug("    revertMove() " + unit); +    //         revertLastPawnMove(unit, ((Order) orders.get(unit, Order.OrderType.MOVE)).move); +    //         orders.dispose(unit, Order.OrderType.MOVE); +    //     } +    //     activatedUnits.clear(); +    // } + +    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.setActivables(activableUnits); +        if ((e.cost > 0) && order.activables.size() > 0) +            order.cost = 0; + +        return order;      } -    public boolean promoteUnit(final Unit unit) +    public Order getPromoteOrder(final Unit unit)      {          Order order = Order.get();          order.setPromote(unit); -        return process(order); + +        return order; +    } + +    private Order getMoveOrder(Unit leader, Move move, boolean hqMode) +    { +        Order order = Order.get(); +        order.setMove(leader, move); +        activableUnits.remove((Unit) move.pawn); +        activatedUnits.add((Unit) move.pawn); +        order.setActivables(activableUnits); +        if (hqMode && order.activables.size() > 0) +            order.cost = 0; + +        return order;      }      // STATES ENTRY <- @@ -120,22 +167,36 @@ public abstract class Map4Orders extends Map3Animations      public void prepareReplayLastAction()      {          int s = orders.size(); -        int a = orders.get(s - 1).id; -        while (s > 0) { +        if (s == 0) return; + +        boolean more = true; +        // int a = orders.get(s - 1).id; +        while (more) {              s -= 1;              Order o = orders.get(s); -            if (o.id != a) -                break; +            o.replay = true;              replayOrders.add(o); +            if (s == 0) { +                more = false; +            } else { +                Order prev = orders.get(s - 1); +                // first order cost=1 part of a group action +                if ((o.cost > 0) && (s > 0) && replayOrders.size() == 1) +                    more = ((prev.cost == 0) && (prev.type == o.type)); +                else // part of a group action +                    more = ((o.cost == 0) && (prev.cost == 0) && (prev.type == o.type)); +            }          }      } -    public void prepareReplayLastTurn() +    public void prepareReplayCurrentTurn()      {          int s = orders.size();          while (s > 0) {              s -= 1; -            replayOrders.add(orders.get(s)); +            Order o = orders.get(s); +            o.replay = true; +            replayOrders.add(o);          }      } @@ -147,154 +208,129 @@ public abstract class Map4Orders extends Map3Animations          return replayOrders.remove(s - 1);      } -    public boolean replay(Order order) -    { -        return process(order, true); -    } -      // REPLAY <- -    private Order getMoveOrder(Unit unit, Move move) +    // EXECUTE -> + +    public void execute(final Order order)      { -        Order order = Order.get(); -        order.setMove(unit, move); -        return order; +        RustAndDust.debug("  Order", order.toString()); + +        switch(order.type) +        { +            case MOVE:      executeMove(order); break; +            case ENGAGE:    executeEngage(order); break; +            case PROMOTE:   executePromote(order); break; +            case END:       executeEnd(order); return; +            case REVERT:    executeRevert(order); return; +            default: +                RustAndDust.error(String.format("Unhandled Order Type %s", order.type)); +                break; +        } + +        if (order.replay) { +            activableUnits.clear(); +            for (Unit u : order.activables) +                activableUnits.add(u); +        } else +            orders.add(order);      } -    private boolean process(Order order) +    private void executePromote(final Order order)      { -        return process(order, false); +        addPromoteAnimation(order.leader, game.ctrl.battle.getPlayer());      } -    private boolean process(Order order, boolean replay) +    private void executeEngage(final Order order)      { -        RustAndDust.debug("Order", order.toString()); +        Engagement e = order.engagement; -        boolean r = false; +        e.attacker.engage(); +        for (Unit u : e.assists) +            u.engage(); -        switch(order.type) { -            case MOVE: -                r = doMove(order.unit, order.move, replay); -                break; -            case PROMOTE: -                r = doPromote(order.unit, replay); -                break; -            case ENGAGE: -                r = doEngagement(order.engagement, replay); -                break; -            default: -                RustAndDust.error(String.format("Unhandled Order Type %s", order.type)); -                break; -        } - -        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(); +        if (order.replay) { +            activatedUnits.clear(); +            activatedUnits.add(e.attacker); +            addBounceAnimation(e.attacker); +            for (Unit u : e.assists) { +                activatedUnits.add(u); +                addBounceAnimation(u); +            }          } -        if (replay) { -            activableUnits.clear(); -            for (Unit u : order.activable) -                activableUnits.add(u); -            orderId = order.id; +        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 leader = order.leader; +        final Unit unit = (Unit) order.move.pawn; +        final Move move = order.move; -        switch(move.type) { +        switch(move.type) +        {              case REGULAR: -                initMove(unit); -                movePawn(unit, move, this); -                break; -            case EXIT: -                initMove(unit); -                movePawn(unit, move, this); -                game.ctrl.battle.getPlayer().unitWithdraw(unit); +                playMoveSound(unit); +                moveUnit(unit, move, this, order.replay);                  break;              case SET: -                setPawnOnto(unit, move); -                game.ctrl.battle.getPlayer().unitEntry(unit);                  claim(unit, move.to); -                addBounceAnimation(unit, 0.3f); +                if (!order.replay) +                    orders.dispose(unit, Order.OrderType.MOVE); +                setOnBoard(unit, move);                  break;              case ENTER: -                enterPawn(unit, move); -                game.ctrl.battle.getPlayer().unitEntry(unit); -                claim(unit, move.to); -                addBounceAnimation(unit, 0.3f); +                claim(unit, move.from); +                if (order.replay) +                    unit.setOnTile(move.from, Orientation.NORTH.r()); +                playMoveSound(unit); +                moveUnit(unit, move, this, order.replay); +                break; +            case EXIT: +                playMoveSound(unit); +                moveUnit(unit, move, this, order.replay);                  break;              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 void initMove(Unit unit) -    { -        activableUnits.remove(unit); -        activatedUnits.add(unit); -        playMoveSound(unit);      } -    private boolean doPromote(final Unit unit, boolean replay) +    private void executeRevert(Order order)      { -        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; -    } +        int id = order.id; +        order = orders.getId(id); +        orders.remove(order); -    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 (order.type != Order.OrderType.MOVE) { +            RustAndDust.error(String.format("Unhandled Revert for Order Type %s", order.type)); +            return;          } -        if (e.success) { -            unclaim(e.defender, e.defender.getHex()); -            removePawn(e.defender); -            addDestroyAnimation(e.defender); +        Unit unit = (Unit) order.move.pawn; +        switch(order.move.type) +        { +            case SET: +                removePawn(unit); +                unclaim(unit, order.move.to); +                game.ctrl.sendMsg(MsgType.UNIT_UNDEPLOYED, unit); +                break; +            case REGULAR: +            case EXIT: +            case ENTER: +            default: +                RustAndDust.error(String.format("Unhandled Move Type %s", order.move.type));          } - -        if (!replay) -            game.ctrl.hud.engagementSummary(e); -        addEngagementAnimation(e.defender); - -        if (engagementCost(e) == 0) -            activatedUnits.clear(); - -        return true; +        order.dispose();      } +    private void executeEnd(Order order) +    { +        orders.get(orders.size() - 1).cost = 1; +    }  } diff --git a/core/src/ch/asynk/rustanddust/game/map/Map5Marshal.java b/core/src/ch/asynk/rustanddust/game/map/Map5Marshal.java index 9447c38..b291062 100644 --- a/core/src/ch/asynk/rustanddust/game/map/Map5Marshal.java +++ b/core/src/ch/asynk/rustanddust/game/map/Map5Marshal.java @@ -37,10 +37,11 @@ public abstract class Map5Marshal extends Map4Orders implements Marshal      @Override      public void unload(Marshal.Mode mode, Json json)      { -        if((mode == Marshal.Mode.FULL) || (mode == Marshal.Mode.STATE)) -            unloadMap(json); -        else if(mode == Marshal.Mode.ORDERS) -            unloadOrders(json, orders); +        switch(mode) +        { +            case MAP: unloadMap(json); break; +            case ORDERS: unloadOrders(json, orders); break; +        }      }      public void unloadPlayers(Json json, Player a, Player b) @@ -160,20 +161,15 @@ public abstract class Map5Marshal extends Map4Orders implements Marshal              json.writeValue("id", o.id);              json.writeValue("type", o.type);              json.writeValue("cost", o.cost); -            switch(o.type) { -                case MOVE: -                    unloadMoveOrder(json, o.move); -                    break; -                case ENGAGE: -                    unloadEngageOrder(json, o.engagement); -                    break; -                case PROMOTE: -                    unloadPromoteOrder(json, o.unit); -                    break; +            switch(o.type) +            { +                case MOVE:      unloadMoveOrder(json, o.leader, o.move); break; +                case ENGAGE:    unloadEngageOrder(json, o.engagement); break; +                case PROMOTE:   unloadPromoteOrder(json, o.leader); break;              } -            if (o.activable.size() > 0) { +            if (o.activables.size() > 0) {                  json.writeArrayStart("a"); -                for(Unit u : o.activable) +                for(Unit u : o.activables)                      json.writeValue(u.id());                  json.writeArrayEnd();              } @@ -182,9 +178,11 @@ public abstract class Map5Marshal extends Map4Orders implements Marshal          json.writeArrayEnd();      } -    private void unloadMoveOrder(Json json, Move m) +    private void unloadMoveOrder(Json json, Unit leader, Move m)      {          json.writeValue("mType", m.type); +        json.writeValue("mCost", m.cost); +        json.writeValue("l", leader.id());          json.writeValue("u", ((Unit) m.pawn).id());          if (m.from != null) {              json.writeArrayStart("from"); @@ -267,10 +265,10 @@ public abstract class Map5Marshal extends Map4Orders implements Marshal      @Override      public void load(Marshal.Mode mode, JsonValue v)      { -        if((mode == Marshal.Mode.FULL) || (mode == Marshal.Mode.STATE)) -            loadMap(v.get("map")); -        else if(mode == Marshal.Mode.ORDERS) -            loadOrders(v.get("orders")); +        switch(mode) { +            case MAP: loadMap(v.get("map")); break; +            case ORDERS: loadOrders(v.get("orders")); break; +        }      }      public void loadPlayers(JsonValue v, Player[] players) @@ -323,8 +321,7 @@ public abstract class Map5Marshal extends Map4Orders implements Marshal          if (pos) {              a = v.get("p");              Hex h = getHex(a.getInt(0), a.getInt(1)); -            u.setRotation(a.getInt(2)); -            showOnBoard(u, h, Orientation.fromRotation(a.getInt(2))); +            setOnBoard(u, h, Orientation.fromRotation(a.getInt(2)));          }          units.add(u);          return u; @@ -366,23 +363,18 @@ public abstract class Map5Marshal extends Map4Orders implements Marshal          for (int i = 0; i < v.size; i++) {              JsonValue o = v.get(i);              Order order = null; -            switch(Order.OrderType.valueOf(o.getString("type"))) { -                case MOVE: -                    order = loadMoveOrder(o); -                    break; -                case ENGAGE: -                    order = loadEngageOrder(o); -                    break; -                case PROMOTE: -                    order = loadPromoteOrder(o); -                    break; +            switch(Order.OrderType.valueOf(o.getString("type"))) +            { +                case MOVE:      order = loadMoveOrder(o); break; +                case ENGAGE:    order = loadEngageOrder(o); break; +                case PROMOTE:   order = loadPromoteOrder(o); break;              }              order.id = o.getInt("id");              order.cost = o.getInt("cost");              JsonValue a = o.get("a");              if (a != null) {                  for (int j = 0; j < a.size; j++) { -                    order.activable.add(findById(a.getInt(j))); +                    order.activables.add(findById(a.getInt(j)));                  }              }              orders.add(order); @@ -391,6 +383,7 @@ public abstract class Map5Marshal extends Map4Orders implements Marshal      private Order loadMoveOrder(JsonValue v)      { +        Unit leader = findById(v.getInt("l"));          Unit unit = findById(v.getInt("u"));          if (unit == null) return null;          Hex from = loadHex(v, "from"); @@ -408,24 +401,20 @@ public abstract class Map5Marshal extends Map4Orders implements Marshal          }          Move m = null; -        switch(Move.MoveType.valueOf(v.getString("mType"))) { -            case REGULAR: -                m = Move.get(unit, from, to, orientation, path); -                break; -            case ENTER: -                m = Move.getEnter(unit, to, orientation); -                break; -            case SET: -                m = Move.getSet(unit, to, orientation); -                break; +        switch(Move.MoveType.valueOf(v.getString("mType"))) +        { +            case REGULAR:   m = Move.get(unit, from, to, orientation, path); break; +            case ENTER:     m = Move.getEnter(unit, from, to, orientation, path); break; +            case SET:       m = Move.getSet(unit, to, orientation); break;              case EXIT:                  m = Move.get(unit, from, to, orientation, path);                  m.type = Move.MoveType.EXIT;                  break;          } +        m.cost = v.getInt("mCost");          Order o = Order.get(); -        o.setMove(unit, m); +        o.setMove(leader, m);          return o;      } diff --git a/core/src/ch/asynk/rustanddust/game/states/StateAnimation.java b/core/src/ch/asynk/rustanddust/game/states/StateAnimation.java index c19f16b..4c6a965 100644 --- a/core/src/ch/asynk/rustanddust/game/states/StateAnimation.java +++ b/core/src/ch/asynk/rustanddust/game/states/StateAnimation.java @@ -5,23 +5,7 @@ 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() -    { -        return StateType.ABORT; -    } - -    @Override -    public StateType execute() -    { -        return StateType.DONE; -    }  } 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..27ed7b8 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,48 @@ 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) -    { -        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() +    public boolean processMsg(MsgType msg, Object data)      { -        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; +            case UNIT_UNDEPLOYED: +                ctrl.battle.getPlayer().revertUnitEntry((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,28 +65,19 @@ 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); +        map.setOnBoard(unit, hex, entryZone.orientation);          deployedUnits.add(unit);          entryZone.enable(Hex.AREA, false);          showRotation(unit, hex); @@ -102,7 +87,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 +97,29 @@ 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(); +        ctrl.postOrder(map.getSetOrder(activeUnit, selectedHex, o), StateType.DEPLOYMENT); +        clear(); +    } -        entryZone = null; +    private void undeployUnit() +    { +        ctrl.postOrder(map.getRevertSetOrder(activeUnit), StateType.DEPLOYMENT); +        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..ccd79c7 100644 --- a/core/src/ch/asynk/rustanddust/game/states/StateEngage.java +++ b/core/src/ch/asynk/rustanddust/game/states/StateEngage.java @@ -1,89 +1,158 @@  package ch.asynk.rustanddust.game.states; +import ch.asynk.rustanddust.engine.Orientation; +import ch.asynk.rustanddust.ui.Position;  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", Position.MIDDLE_CENTER); +            map.unitsActivableShow(); +            map.hexUnselect(selectedHex);          }      }      @Override -    public void leaveFor(StateType nextState) +    public boolean processMsg(MsgType msg, Object data) +    { +        switch(msg) +        { +            case OK: +                if (breakMove) +                    abortBreakMove(); +                return true; +        } + +        return false; +    } + +    @Override +    public void touch(Hex hex) +    { +        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); +            } + +        } +    } + +    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(); -        map.unitsTargetHide();          map.hexUnselect(selectedHex); -        if (to != null) -            map.hexUnselect(to); +        Order order = map.getEngageOrder(selectedUnit, activeUnit); + +        if (order.cost == 0) +            ctrl.postOrder(order, StateType.ENGAGE); +        else { +            order.cost = order.engagement.cost; +            ctrl.postOrder(order); +        }      } -    @Override -    public StateType abort() +    private void abort()      { +        map.unitsAssistHide(); +        map.unitsTargetHide(); +        activeUnit.hideTarget(); +        selectedUnit.hideAttack(); +        map.hexUnselect(selectedHex);          map.unitsActivatedClear(); -        return StateType.ABORT; +        ctrl.postActionAborted();      } -    @Override -    public StateType execute() +    private void selectBreakUnit(Unit unit)      { -        map.unitsAssistHide(); -        StateType nextState = StateType.DONE; -        if (map.engageUnit(selectedUnit, activeUnit)) { -            ctrl.battle.getPlayer().engagementWon += 1; -            ctrl.battle.getOpponent().casualty(activeUnit); -            if (map.unitsActivableSize() > 0) { -                nextState = StateType.BREAK; -            } -        } else { -            ctrl.battle.getPlayer().engagementLost += 1; -        } +        activeUnit = unit; +        map.hexMoveShow(to); +        map.hexMoveShow(unit.getHex()); +        map.hexDirectionsShow(to); +        map.unitsActivableHide(); +    } -        activeUnit.showTarget(); -        ctrl.setAfterAnimationState(nextState); -        return StateType.ANIMATION; +    private void unselectBreakUnit() +    { +        map.hexMoveHide(to); +        map.hexMoveHide(activeUnit.getHex()); +        map.hexDirectionsHide(to); +        map.unitsActivableShow(); +        activeUnit = null;      } -    @Override -    public void touch(Hex hex) +    private void doRotation(Orientation o)      { -        Unit unit = hex.getUnit(); +        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)); +    } -        // 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 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..ae0c751 100644 --- a/core/src/ch/asynk/rustanddust/game/states/StateMove.java +++ b/core/src/ch/asynk/rustanddust/game/states/StateMove.java @@ -1,103 +1,125 @@  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 enter; +    private boolean hqMode; +    private boolean notFirst; +      @Override      public void enterFrom(StateType prevState)      { -        ctrl.hud.actionButtons.show( -                ((map.unitsActivatedSize() > 0) ? Buttons.DONE.b : 0) -                ); +        state = State.SHOW; -        if (prevState == StateType.WITHDRAW) { -            completePath(map.pathsSize()); -            return; -        } +        enter = false; +        hqMode = false; +        notFirst = 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 { +                collectPaths(to); +            } +        } else if (prevState == StateType.REINFORCEMENT) { +            enter = true; +            map.hexSelect(selectedHex); +            map.pathsInit(selectedUnit); +            if (selectedUnit.getMovementPoints() > 0) { +                map.movesCollect(selectedUnit); +                map.movesShow();              } else { -                changeUnit(map.unitsMoveableGet(0)); +                to = selectedHex; +                showRotation(to); +                collectPaths(to);              } +        } else { +            notFirst = hqMode = true; +            selectNextUnit();          } -        map.unitsActivableShow(); +        if (hqMode) +            map.unitsActivableShow();          activeUnit.hideActiveable(); +        int n = (notFirst ? Buttons.DONE.b : 0); +        n |= (enter ? Buttons.ABORT.b : 0); +        ctrl.hud.actionButtons.show(n);      }      @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(); -        } -    } - -    @Override -    public StateType abort() -    { -        hideActivable(); -        if (activeUnit.justEntered()) { -            map.revertEnter(activeUnit); -            return StateType.ABORT; +        switch(msg) +        { +            case OK: +                if (state == State.EXIT) { +                    exit(); +                    return true; +                } +                if (hqMode) { +                    endHqMode(); +                    return true; +                } +                break; +            case CANCEL: +                if (enter || (state == State.PATH) || (state == State.ROTATE)) { +                    abortMove(); +                    return true; +                } +                if (state == State.EXIT) { +                    abortExit(); +                    return true; +                } +                break;          } -        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 +129,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.getFirstActivable());      } -    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 +160,170 @@ 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());      }      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 (enter)              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); +        if (enter) +            completeMove(map.getEnterOrder(selectedUnit, hqMode)); +        else +            completeMove(map.getMoveOrder(selectedUnit, 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(selectedUnit, 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 (enter) { +            map.revertEnter(activeUnit); +            ctrl.battle.getPlayer().revertUnitEntry(activeUnit); +            ctrl.hud.update(); +        } +        clear(); +        if (notFirst) { +            // 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; +            map.hexMoveShow(to); +            completePath(); +        } +        abortCompleted(); +    } + +    private void abortCompleted() +    { +        if (hqMode) +            map.unitsActivableShow(); +        activeUnit.hideActiveable(); +        ctrl.hud.actionButtons.show((notFirst ? 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..774b1a9 100644 --- a/core/src/ch/asynk/rustanddust/game/states/StatePromote.java +++ b/core/src/ch/asynk/rustanddust/game/states/StatePromote.java @@ -5,26 +5,6 @@ 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));      }  } diff --git a/core/src/ch/asynk/rustanddust/game/states/StateReinforcement.java b/core/src/ch/asynk/rustanddust/game/states/StateReinforcement.java index e118924..ffb1f24 100644 --- a/core/src/ch/asynk/rustanddust/game/states/StateReinforcement.java +++ b/core/src/ch/asynk/rustanddust/game/states/StateReinforcement.java @@ -3,6 +3,7 @@ package ch.asynk.rustanddust.game.states;  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;  public class StateReinforcement extends StateCommon  { @@ -11,70 +12,53 @@ public class StateReinforcement extends StateCommon      @Override      public void enterFrom(StateType prevState)      { -        map.clearAll(); -        if (selectedHex != null) -            map.hexUnselect(selectedHex); +        map.clear();          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; +        } -    @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 ((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); +        map.enterBoard(unit, hex, entryZone);          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"); -        } +        ctrl.battle.getPlayer().reinforcement.remove(unit); +        ctrl.hud.playerInfo.unitDock.hide(); +        ctrl.hud.update(); +        ctrl.post(StateType.MOVE); +        entryZone = 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..22105fb 100644 --- a/core/src/ch/asynk/rustanddust/game/states/StateReplay.java +++ b/core/src/ch/asynk/rustanddust/game/states/StateReplay.java @@ -1,87 +1,111 @@  package ch.asynk.rustanddust.game.states;  import ch.asynk.rustanddust.game.Order; +import ch.asynk.rustanddust.game.Ctrl.MsgType;  public class StateReplay extends StateCommon  { -    private Order order; +    private Order order = null;      @Override      public void enterFrom(StateType prevState)      { +        if (this.order != null) +            replayStep(); +          Order o = map.stepReplay();          if (o == null) { -            StateType nextState = nextState(); +            ctrl.postReplayDone(replayDone());              order = null; -            ctrl.post(nextState);          } else {              this.order = o;              setup(); -            map.replay(order); -            ctrl.setAfterAnimationState(StateType.REPLAY); -            ctrl.post(StateType.ANIMATION); +            ctrl.postOrder(o, StateType.REPLAY);          }      }      private void setup()      { -        int s = order.activable.size(); +        int s = order.activables.size(); -        switch (order.type) { +        switch (order.type) +        {              case MOVE: -                selectedUnit = ((s > 0) ? order.activable.get(s - 1) : order.unit); +                selectedUnit = order.leader;                  break;              case ENGAGE:                  to = order.engagement.defender.getHex(); -                if (order.engagement.success) { -                    ctrl.battle.getPlayer().engagementWon += 1; -                    ctrl.battle.getOpponent().casualty(order.engagement.defender); -                } else { -                    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) { +        switch (order.type) +        {              case MOVE: -                next = StateType.MOVE; +                moveReplayStep();                  break;              case ENGAGE: -                next = StateType.BREAK; -                break; +            case PROMOTE:              default: -                next = StateType.DONE;                  break;          } - -        return next;      } -    @Override -    public void leaveFor(StateType nextState) +    private void moveReplayStep()      { +        switch(order.move.type) +        { +            case SET: +                ctrl.sendMsg(MsgType.UNIT_DEPLOYED, order.move.pawn); +                break; +            case REGULAR: +            case EXIT: +            case ENTER: +                break; +        }      } -    @Override -    public StateType abort() +    private StateType replayDone()      { -        return StateType.ABORT; +        if (order == null) return null; + +        boolean more = (order.activables.size() > 0); +        StateType nextState = null; +        switch (order.type) +        { +            case MOVE: +                nextState = moveReplayDone(more); +                break; +            case ENGAGE: +                if (more) nextState = StateType.ENGAGE; +                break; +            case PROMOTE: +            default: +                break; +        } +        return nextState;      } -    @Override -    public StateType execute() +    private StateType moveReplayDone(boolean more)      { -        // called at the end of animation DONE -> burn 1 AP -        return ((order.cost == 0) ? StateType.REPLAY : StateType.DONE); +        StateType nextState = null; +        switch(order.move.type) +        { +            case REGULAR: +            case EXIT: +                if (more) nextState = StateType.MOVE; +                break; +            case SET: +                nextState = StateType.DEPLOYMENT; +                break; +            case ENTER: +                break; +        } +        return nextState;      }  } 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..f6c42c3 100644 --- a/core/src/ch/asynk/rustanddust/game/states/StateSelect.java +++ b/core/src/ch/asynk/rustanddust/game/states/StateSelect.java @@ -1,120 +1,131 @@  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); +        hide(); -        hidePossibilities(); -        if (hex.isOffMap()) { -            selectedUnit = null; -            return; -        } - -        Unit unit = hex.getUnit(); - -        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 +                ctrl.hud.notify("HQ activation", Position.MIDDLE_CENTER); +                to = null; +            } else                  to = hex; -                ctrl.post(StateType.ROTATE); -            } +            changeTo(StateType.MOVE);          } else { -            select(hex, unit, isEnemy); -            ctrl.hud.notify(selectedUnit.toString(), Position.TOP_CENTER); +            select(hex, unit); +            ctrl.hud.notify(selectedUnit.toString());          }      } -    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.clear(); +        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/menu/PlayMenu.java b/core/src/ch/asynk/rustanddust/menu/PlayMenu.java index 78fbe85..3fd0d4e 100644 --- a/core/src/ch/asynk/rustanddust/menu/PlayMenu.java +++ b/core/src/ch/asynk/rustanddust/menu/PlayMenu.java @@ -142,11 +142,11 @@ public class PlayMenu extends Patch implements MenuCtrl.Panel              return MenuCtrl.MenuType.OKKO;          } else if (resumeBtn.hit(x, y)) {              game.playType(); -            return setConfig(Config.LoadMode.LOAD); +            return setConfig(Config.LoadMode.RESUME);          } else if (replayBtn.hit(x, y)) {              game.playType(); -            // TODO chose between : REPLAY_LAST / REPLAY_ALL -            return setConfig(Config.LoadMode.REPLAY_LAST); +            // TODO chose between : REPLAY_CURRENT / REPLAY_ALL +            return setConfig(Config.LoadMode.REPLAY_CURRENT);          } else if (list.hit(x, y)) {              if (i != getList().getIdx())                  game.playType(); diff --git a/core/src/ch/asynk/rustanddust/screens/GameScreen.java b/core/src/ch/asynk/rustanddust/screens/GameScreen.java index e2aa8a2..b3d2457 100644 --- a/core/src/ch/asynk/rustanddust/screens/GameScreen.java +++ b/core/src/ch/asynk/rustanddust/screens/GameScreen.java @@ -149,7 +149,7 @@ public class GameScreen implements Screen                  blocked = false;          } -        ctrl.processEvent(); +        ctrl.processEvent(delta);          ctrl.hud.animate(delta);          ctrl.map.animate(delta); diff --git a/core/src/ch/asynk/rustanddust/util/DB.java b/core/src/ch/asynk/rustanddust/util/DB.java index 994e5d3..c5c68c3 100644 --- a/core/src/ch/asynk/rustanddust/util/DB.java +++ b/core/src/ch/asynk/rustanddust/util/DB.java @@ -42,7 +42,8 @@ public class DB          + " ,mode integer not null, battle integer not null, opponent integer not null"          + " ,turn integer not null, currentPlayer integer default null"          + " ,ts datetime default current_timestamp, synched integer default 0" -        + " ,state text default null, stateH text default null" +        + " ,players text default null, playersH text default null" +        + " ,map text default null, mapH text default null"          + " ,orders text default null, ordersH text default null"          + " ,foreign key (battle) references battles(_id)"          + " ,foreign key (opponent) references players(_id)" @@ -53,7 +54,8 @@ public class DB      private static final String TBL_TURNS_CRT = "create table if not exists"          + " turns ( _id integer primary key autoincrement"          + " ,game integer not null, turn integer not null, currentPlayer integer not null" -        + " ,state text default null, stateH text default null" +        + " ,players text default null, playersH text default null" +        + " ,map text default null, mapH text default null"          + " ,orders text default null, ordersH text default null"          + " ,foreign key (game) references games(_id)"          + " ,foreign key (currentPlayer) references players(_id)" @@ -126,6 +128,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)); @@ -258,15 +261,18 @@ public class DB          return getGameId(opponent, battle, mode);      } -    private static final String STORE_GAME_STATE = "update games set ts=current_timestamp, turn=%d, currentPlayer=%d, state='%s', stateH='%s', synched=1 where _id=%d;"; +    private static final String STORE_GAME_STATE = "update games set ts=current_timestamp, turn=%d, currentPlayer=%d," +        + " players='%s', playersH='%s', map='%s', mapH='%s', synched=1 where _id=%d;"; -    public boolean storeGameState(int game, int turn, int player, String state) +    public boolean storeGameState(int game, int turn, int player, String players, String map)      {          RustAndDust.debug("storeGameState");          try { -            String hash = getDigest(state); -            if (hash == null) return false; -            exec(String.format(STORE_GAME_STATE, turn, player, state, hash, game)); +            String playersH = getDigest(players); +            if (playersH == null) return false; +            String mapH = getDigest(map); +            if (mapH == null) return false; +            exec(String.format(STORE_GAME_STATE, turn, player, players, playersH, map, mapH, game));          } catch (SQLiteGdxException e) {              RustAndDust.error("storeGameState");              return false; @@ -280,9 +286,9 @@ public class DB      {          RustAndDust.debug("storeGameOrders");          try { -            String hash = getDigest(orders); -            if (hash == null) return false; -            exec(String.format(STORE_GAME_ORDERS, turn, player, orders, hash, game)); +            String ordersH = getDigest(orders); +            if (ordersH == null) return false; +            exec(String.format(STORE_GAME_ORDERS, turn, player, orders, ordersH, game));          } catch (SQLiteGdxException e) {              RustAndDust.error("storeGameOrders");              return false; @@ -290,15 +296,28 @@ public class DB          return true;      } -    private static final String COPY_TURN = "insert into turns(game, turn, currentPlayer, state, stateH, orders, ordersH)" -        + " select _id, turn, currentPlayer, state, stateH, orders, ordersH from games where _id=%d;"; +    private static final String COPY_TURN = "insert into turns(game, turn, currentPlayer, players, playersH, map, mapH, orders, ordersH)" +        + " select _id, turn, currentPlayer, players, playersH, map, mapH, orders, ordersH from games where _id=%d;"; -    public boolean storeLastTurn(int game) +    public boolean storeCurrentTurn(int game)      { +        RustAndDust.debug("storeCurrentTurn");          try {              exec(String.format(COPY_TURN, game));          } catch (SQLiteGdxException e) { -            RustAndDust.error("storeLastTurn"); +            RustAndDust.error("storeCurrentTurn"); +            return false; +        } +        return true; +    } + +    public boolean clearGameOrders(int game) +    { +        RustAndDust.debug("clearGameOrders"); +        try { +            exec(String.format("update games set orders=null, ordersH=null, synched=1 where _id=%d;", game)); +        } catch (SQLiteGdxException e) { +            RustAndDust.error("clearGameOrders");              return false;          }          return true; @@ -306,7 +325,7 @@ public class DB      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" +    private static final String LOAD_GAMES = LOAD_BASE + ", null, null, null, null, null, null, p.name, b.name"          + " from games g inner join players p on (p._id=g.opponent) inner join battles b on (b._id=g.battle);";      public void loadGames() @@ -325,46 +344,40 @@ public class DB          } catch (SQLiteGdxException e) { RustAndDust.error("loadGames"); }      } -    private static final String LOAD_GAME = LOAD_BASE + ", g.state, g.stateH, g.orders, g.ordersH, null, null from games g where g._id=%d;"; +    private static final String LOAD_GAME = LOAD_BASE + ", g.players, g.playersH, g.map, g.mapH, g.orders, g.ordersH, null, null from games g where g._id=%d;";      public GameRecord loadGame(int game)      {          RustAndDust.debug("loadGame"); -        GameRecord r = null; -        try { -            DatabaseCursor cursor = query(String.format(LOAD_GAME, game)); -            if (cursor.getCount() > 0) { -                cursor.next(); -                r = gameRecordFrom(cursor); -                if (!checkDigest("GameState", game, r.state, r.stateH)) -                    r = null; -                else if(!checkDigest("GameOrders", game, r.orders, r.ordersH)) -                    r = null; -            } -        } catch (SQLiteGdxException e) { RustAndDust.error("loadGame"); } -        if (r == null) -            deleteGame(game); -        return r; +        return loadGame(game, LOAD_GAME, "loadGAME");      } -    private static final String LOAD_LAST_TURN = "select g._id, g.mode, g.battle, g.opponent, t.turn, t.currentPlayer, g.ts, g.synched" -        + ", 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;"; +    private static final String LOAD_LAST_TURN = "select g._id, g.mode, g.battle, g.opponent, g.turn, g.currentPlayer, g.ts, g.synched" +        + ", t.players, t.playersH, t.map, t.mapH, 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)      {          RustAndDust.debug("loadLastTurn"); +        return loadGame(game, LOAD_LAST_TURN, "loadLastTurn"); +    } + +    private GameRecord loadGame(int game, String sql, String errMsg) +    {          GameRecord r = null;          try { -            DatabaseCursor cursor = query(String.format(LOAD_LAST_TURN, game)); +            DatabaseCursor cursor = query(String.format(sql, game));              if (cursor.getCount() > 0) {                  cursor.next();                  r = gameRecordFrom(cursor); -                if (!checkDigest("GameState", game, r.state, r.stateH)) +                if (!checkDigest("GameState", game, r.players, r.playersH)) +                    r = null; +                if (!checkDigest("GameState", game, r.map, r.mapH))                      r = null;                  else if(!checkDigest("GameOrders", game, r.orders, r.ordersH))                      r = null;              } -        } catch (SQLiteGdxException e) { RustAndDust.error("loadLastTurn"); } +        } catch (SQLiteGdxException e) { RustAndDust.error(errMsg); }          if (r == null)              deleteGame(game);          return r; @@ -404,13 +417,15 @@ public class DB                  RustAndDust.error(String.format("can't parse", cursor.getString(6)));              }              r.synched = ((cursor.getInt(7) == 1) ? true : false); -            r.state = cursor.getString(8); -            r.stateH = cursor.getString(9); -            r.orders = cursor.getString(10); -            r.ordersH = cursor.getString(11); +            r.players = cursor.getString(8); +            r.playersH = cursor.getString(9); +            r.map = cursor.getString(10); +            r.mapH = cursor.getString(11); +            r.orders = cursor.getString(12); +            r.ordersH = cursor.getString(13);              // -            r.oName = cursor.getString(12); -            r.bName = cursor.getString(13); +            r.oName = cursor.getString(14); +            r.bName = cursor.getString(15);          } catch (Exception e) {              r.dispose(); RustAndDust.error("GameRecord from cursor");          } diff --git a/core/src/ch/asynk/rustanddust/util/GameRecord.java b/core/src/ch/asynk/rustanddust/util/GameRecord.java index 5693a3e..4a540ba 100644 --- a/core/src/ch/asynk/rustanddust/util/GameRecord.java +++ b/core/src/ch/asynk/rustanddust/util/GameRecord.java @@ -21,8 +21,10 @@ public class GameRecord implements List.ListElement, Disposable, Pool.Poolable      public int currentPlayer;      public Date ts;      public boolean synched; -    public String state; -    public String stateH; +    public String players; +    public String playersH; +    public String map; +    public String mapH;      public String orders;      public String ordersH;      // diff --git a/core/src/ch/asynk/rustanddust/util/Marshal.java b/core/src/ch/asynk/rustanddust/util/Marshal.java index 513c87b..f805fa1 100644 --- a/core/src/ch/asynk/rustanddust/util/Marshal.java +++ b/core/src/ch/asynk/rustanddust/util/Marshal.java @@ -7,9 +7,9 @@ public interface Marshal  {      public enum Mode      { -        FULL, -        STATE, -        ORDERS +        PLAYERS, +        MAP, +        ORDERS,      }      public void unload(Mode mode, Json json); | 
