diff --git a/src/core/BattlePlanning.spec.ts b/src/core/BattlePlanning.spec.ts index df8cab9..b4847d8 100644 --- a/src/core/BattlePlanning.spec.ts +++ b/src/core/BattlePlanning.spec.ts @@ -48,11 +48,15 @@ module TK.SpaceTac.Specs { const planning = new BattlePlanning(battle); check.equals(planning.getShipPlan(ship).actions, []); + check.equals(planning.collectAllActions(), []); planning.addAction(ship, action1, Target.newFromShip(ship)); check.equals(planning.getShipPlan(ship).actions, [ { action: action1.id, target: Target.newFromShip(ship) } ]); + check.equals(planning.collectAllActions(), [ + { action: action1.id, target: Target.newFromShip(ship) } + ]); }); }); } diff --git a/src/core/BattlePlanning.ts b/src/core/BattlePlanning.ts index f337b67..5109b6c 100644 --- a/src/core/BattlePlanning.ts +++ b/src/core/BattlePlanning.ts @@ -43,6 +43,13 @@ namespace TK.SpaceTac { plan.actions.push({ action: action.id, target }); } } + + /** + * Collect all planned actions for all ships + */ + collectAllActions(): ActionPlan[] { + return flatten(flatten(this.plan.fleets.map(fleet => fleet.ships.map(ship => ship.actions)))); + } } export type BattlePlan = { diff --git a/src/ui/TestGame.ts b/src/ui/TestGame.ts index 7b8ef2b..fd2282f 100644 --- a/src/ui/TestGame.ts +++ b/src/ui/TestGame.ts @@ -85,8 +85,11 @@ module TK.SpaceTac.UI.Specs { view.splash = false; let battle = Battle.newQuickRandom(); - let player = new Player(); - nn(battle.playing_ship).fleet.setPlayer(player); + if (nn(battle.playing_ship).fleet != battle.fleets[0]) { + // Ensure the player plays first (to not trigger AI) + battle.fleets.push(nn(battle.fleets.shift())); + } + let player = battle.fleets[0].player; return [view, { player, battle }]; }); diff --git a/src/ui/battle/BattleView.spec.ts b/src/ui/battle/BattleView.spec.ts index 597d8ac..da43313 100644 --- a/src/ui/battle/BattleView.spec.ts +++ b/src/ui/battle/BattleView.spec.ts @@ -87,5 +87,21 @@ module TK.SpaceTac.UI.Specs { check.same(battleview.targetting.action, action_icon.action); check.equals(battleview.targetting.target, Target.newFromShip(battleview.battle.play_order[4])); }); + + test.case("adds player actions to plan", check => { + let battleview = testgame.view; + let playing_ship = nn(battleview.battle.playing_ship); + check.equals(battleview.plannings.length, 2); + check.equals(battleview.plannings[0].collectAllActions(), []); + check.equals(battleview.plannings[1].collectAllActions(), []); + + let action = nn(first(playing_ship.actions.listAll(), action => action instanceof MoveAction)); + battleview.applyPlayerAction(action, Target.newFromLocation(0, 0)); + check.equals(battleview.plannings.length, 2); + check.equals(battleview.plannings[0].collectAllActions(), [ + { action: action.id, target: Target.newFromLocation(0, 0) } + ]); + check.equals(battleview.plannings[1].collectAllActions(), []); + }); }); } diff --git a/src/ui/battle/PlanDisplay.spec.ts b/src/ui/battle/PlanDisplay.spec.ts new file mode 100644 index 0000000..c1c8bb2 --- /dev/null +++ b/src/ui/battle/PlanDisplay.spec.ts @@ -0,0 +1,56 @@ +/// + +module TK.SpaceTac.UI.Specs { + testing("PlanDisplay", test => { + let testgame = setupEmptyView(test); + + function compareDisplay(check: TestContext, plan: BattlePlan, display: PlanDisplay): void { + const container = display.container; + const children = cfilter(container.list, UIContainer); + check.equals(children.length, plan.fleets.length, "fleet containers count"); + + zip(plan.fleets, children).forEach(([plan, container], idx) => { + check.in(`fleet ${idx}`, check => { + const children = cfilter(container.list, UIContainer); + check.equals(children.length, plan.ships.length, "ship containers count"); + + zip(plan.ships, children).forEach(([plan, container], idx) => { + }); + }); + }); + } + + test.case("updates from a battle plan", check => { + let battle = new Battle(); + battle.fleets[0].addShip(); + battle.fleets[1].addShip(); + battle.fleets[1].addShip(); + + const display = new PlanDisplay(testgame.view.getLayer("test").getBuilder()); + check.in("initial state", check => { + compareDisplay(check, { fleets: [] }, display); + }); + + let planning = new BattlePlanning(battle); + display.update(planning.getBattlePlan()); + check.in("initial update", check => { + compareDisplay(check, planning.getBattlePlan(), display); + }); + + display.update(planning.getBattlePlan()); + check.in("no change", check => { + // TODO Check that no object was added/removed + compareDisplay(check, planning.getBattlePlan(), display); + }); + + battle = new Battle(); + battle.fleets[0].addShip(); + battle.fleets[1].addShip(); + battle.fleets[1].addShip(); + display.update(planning.getBattlePlan()); + check.in("update whole", check => { + compareDisplay(check, planning.getBattlePlan(), display); + }); + }); + }); +} diff --git a/src/ui/battle/PlanDisplay.ts b/src/ui/battle/PlanDisplay.ts new file mode 100644 index 0000000..eba47e5 --- /dev/null +++ b/src/ui/battle/PlanDisplay.ts @@ -0,0 +1,51 @@ +module TK.SpaceTac.UI { + /** + * Displays and maintain a battle plan + */ + export class PlanDisplay { + readonly container: UIContainer + + constructor(builder: UIBuilder) { + this.container = builder.container("battleplan"); + } + + update(plan: BattlePlan): void { + this.updateBattle(plan, this.container); + } + + private updateBattle(plan: BattlePlan, parent: UIContainer) { + const builder = parent.getBuilder(); + + if (parent.list.length > plan.fleets.length) { + builder.clear(); + } + + while (parent.list.length < plan.fleets.length) { + builder.container("fleetplan"); + } + + iforeach(izip(plan.fleets, ifilterclass(parent.list, UIContainer)), ([fleetplan, child]) => { + this.updateFleet(fleetplan, child); + }); + } + + private updateFleet(plan: FleetPlan, parent: UIContainer) { + const builder = parent.getBuilder(); + + if (parent.list.length > plan.ships.length) { + builder.clear(); + } + + while (parent.list.length < plan.ships.length) { + builder.container("shipplan"); + } + + iforeach(izip(plan.ships, ifilterclass(parent.list, UIContainer)), ([shipplan, child]) => { + this.updateShip(shipplan, child); + }); + } + + private updateShip(plan: ShipPlan, parent: UIContainer) { + } + } +}