Started work on turn resolution
This commit is contained in:
parent
c3c88449fb
commit
906322003f
|
@ -61,6 +61,14 @@ module TK.SpaceTac {
|
|||
return bool(this.outcome);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply a turn plan through a resolution
|
||||
*/
|
||||
applyTurnPlan(plan: TurnPlan): void {
|
||||
const resolution = new TurnResolution(this, plan);
|
||||
resolution.resolve();
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply a list of diffs to the game state, and add them to the log.
|
||||
*
|
||||
|
|
|
@ -111,8 +111,9 @@ module TK.SpaceTac {
|
|||
}
|
||||
|
||||
// Make an initiative throw, to resolve play order in a battle
|
||||
throwInitiative(gen: RandomGenerator): void {
|
||||
throwInitiative(gen: RandomGenerator): number {
|
||||
this.play_priority = gen.random() * this.attributes.initiative.get();
|
||||
return this.play_priority;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
53
src/core/TurnResolution.spec.ts
Normal file
53
src/core/TurnResolution.spec.ts
Normal file
|
@ -0,0 +1,53 @@
|
|||
module TK.SpaceTac {
|
||||
testing("TurnResolution", test => {
|
||||
test.case("defines play order by initiative throws", check => {
|
||||
const fleet1 = new Fleet();
|
||||
const fleet2 = new Fleet();
|
||||
|
||||
const ship1 = new Ship(fleet1, "F1S1");
|
||||
TestTools.setAttribute(ship1, "initiative", 2);
|
||||
const ship2 = new Ship(fleet1, "F1S2");
|
||||
TestTools.setAttribute(ship2, "initiative", 4);
|
||||
const ship3 = new Ship(fleet1, "F1S3");
|
||||
TestTools.setAttribute(ship3, "initiative", 1);
|
||||
const ship4 = new Ship(fleet2, "F2S1");
|
||||
TestTools.setAttribute(ship4, "initiative", 8);
|
||||
const ship5 = new Ship(fleet2, "F2S2");
|
||||
TestTools.setAttribute(ship5, "initiative", 2);
|
||||
|
||||
const battle = new Battle(fleet1, fleet2);
|
||||
const random = new SkewedRandomGenerator([1.0, 0.1, 1.0, 0.2, 0.6]);
|
||||
const resolution = new TurnResolution(battle, { fleets: [] }, random);
|
||||
|
||||
check.equals(resolution.play_order, []);
|
||||
resolution.throwInitiative();
|
||||
check.equals(resolution.play_order, [ship1, ship4, ship5, ship3, ship2]);
|
||||
});
|
||||
|
||||
test.case("logs a turn start diff", check => {
|
||||
const battle = new Battle();
|
||||
const resolution = new TurnResolution(battle, { fleets: [] });
|
||||
const ships = [new Ship(), new Ship()]
|
||||
resolution.play_order = ships;
|
||||
|
||||
check.equals(battle.log.count(), 0);
|
||||
resolution.logStart();
|
||||
check.equals(battle.log.count(), 1);
|
||||
const diff = battle.log.get(0);
|
||||
if (check.instance(diff, TurnStartDiff, "diff should be a TurnStartDiff")) {
|
||||
check.equals(diff.play_order, [ships[0].id, ships[1].id]);
|
||||
}
|
||||
});
|
||||
|
||||
test.case("logs a turn end diff", check => {
|
||||
const battle = new Battle();
|
||||
const resolution = new TurnResolution(battle, { fleets: [] });
|
||||
|
||||
check.equals(battle.log.count(), 0);
|
||||
resolution.logEnd();
|
||||
check.equals(battle.log.count(), 1);
|
||||
const diff = battle.log.get(0);
|
||||
check.instance(diff, TurnEndDiff, "diff should be a TurnEndDiff");
|
||||
});
|
||||
});
|
||||
}
|
70
src/core/TurnResolution.ts
Normal file
70
src/core/TurnResolution.ts
Normal file
|
@ -0,0 +1,70 @@
|
|||
namespace TK.SpaceTac {
|
||||
/**
|
||||
* The machinery to apply a turn plan, in order to resolve the current turn
|
||||
*/
|
||||
export class TurnResolution {
|
||||
play_order: Ship[] = []
|
||||
|
||||
constructor(readonly battle: Battle, readonly plan: TurnPlan, readonly random = new RandomGenerator()) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform the whole resolution
|
||||
*/
|
||||
resolve(): void {
|
||||
this.throwInitiative();
|
||||
this.logStart();
|
||||
this.performActions(ActionCategory.PASSIVE);
|
||||
this.performActions(ActionCategory.MOVE);
|
||||
this.performActions(ActionCategory.ACTIVE);
|
||||
this.logEnd();
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform an initiative throw, to obtain an order in which the ships will play
|
||||
*/
|
||||
throwInitiative(): void {
|
||||
const with_thrown = this.battle.ships.list().map(ship => [ship, ship.throwInitiative(this.random)] as [Ship, number]);
|
||||
const sorted_by_thrown = sortedBy(with_thrown, ([_, thrown]) => thrown);
|
||||
this.play_order = sorted_by_thrown.reverse().map(([ship, _]) => ship);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log a turn start diff
|
||||
*/
|
||||
logStart(): void {
|
||||
this.battle.applyDiffs([new TurnStartDiff(this.play_order)]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform all actions of a given category, for all ships in the initiative order
|
||||
*/
|
||||
performActions(category: ActionCategory): void {
|
||||
this.play_order.forEach(ship => this.performActionsForShip(ship, category));
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform all actions of a given category, for one given ship
|
||||
*/
|
||||
performActionsForShip(ship: Ship, category: ActionCategory): void {
|
||||
this.plan.fleets.forEach(fleetplan => {
|
||||
fleetplan.ships.forEach(shipplan => {
|
||||
if (ship.is(shipplan.ship)) {
|
||||
shipplan.actions.forEach(actionplan => {
|
||||
if (actionplan.category === category) {
|
||||
this.battle.applyOneAction(actionplan.action, actionplan.target);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Log a turn end diff
|
||||
*/
|
||||
logEnd(): void {
|
||||
this.battle.applyDiffs([new TurnEndDiff()]);
|
||||
}
|
||||
}
|
||||
}
|
9
src/core/diffs/TurnEndDiff.ts
Normal file
9
src/core/diffs/TurnEndDiff.ts
Normal file
|
@ -0,0 +1,9 @@
|
|||
/// <reference path="BaseBattleDiff.ts"/>
|
||||
|
||||
module TK.SpaceTac {
|
||||
/**
|
||||
* A turn has ended
|
||||
*/
|
||||
export class TurnEndDiff extends BaseBattleDiff {
|
||||
}
|
||||
}
|
16
src/core/diffs/TurnStartDiff.ts
Normal file
16
src/core/diffs/TurnStartDiff.ts
Normal file
|
@ -0,0 +1,16 @@
|
|||
/// <reference path="BaseBattleDiff.ts"/>
|
||||
|
||||
module TK.SpaceTac {
|
||||
/**
|
||||
* A turn has started
|
||||
*/
|
||||
export class TurnStartDiff extends BaseBattleDiff {
|
||||
readonly play_order: RObjectId[]
|
||||
|
||||
constructor(play_order: Ship[]) {
|
||||
super();
|
||||
|
||||
this.play_order = play_order.map(ship => ship.id);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,7 +4,7 @@ module TK.SpaceTac.UI.Specs {
|
|||
|
||||
test.case("shows turn counter and current phase", check => {
|
||||
const parent = testgame.view.getLayer("test");
|
||||
const bar = new BattleInfoBar(parent.getBuilder());
|
||||
const bar = new BattleInfoBar(parent.getBuilder(), { startResolution: () => null });
|
||||
|
||||
expect(collectTexts(parent)).toEqual(["Battle"]);
|
||||
|
||||
|
|
|
@ -26,20 +26,7 @@ module TK.SpaceTac.UI {
|
|||
|
||||
this.title = builder.in(this.container).text("Battle", 0, 0, { center: true, size: 30, shadow: true, color: "#dbeff9" });
|
||||
|
||||
this.planning = new BattleInfoBarPlanning(this.container, () => {
|
||||
});
|
||||
}
|
||||
|
||||
startResolution(): void {
|
||||
const startResolution = this.config.startResolution;
|
||||
if (startResolution) {
|
||||
const message = "Validate all your ship's planning, and proceed to turn resolution?";
|
||||
UIConfirmDialog.ask(this.builder.view, message).then(ok => {
|
||||
if (ok) {
|
||||
startResolution();
|
||||
}
|
||||
});
|
||||
}
|
||||
this.planning = new BattleInfoBarPlanning(this.container, config.startResolution);
|
||||
}
|
||||
|
||||
setPhase(turn: number, phase: BattleInfoBarPhase): void {
|
||||
|
@ -60,16 +47,18 @@ module TK.SpaceTac.UI {
|
|||
container: UIContainer
|
||||
turns: UIText
|
||||
|
||||
constructor(parent: UIContainer, startResolution: Function) {
|
||||
constructor(parent: UIContainer, startResolution?: Function) {
|
||||
this.container = parent.getBuilder().container("planning", 0, 0, false);
|
||||
const builder = this.container.getBuilder();
|
||||
|
||||
if (startResolution) {
|
||||
builder.button("battle-buttons-medium", 604, 0, startResolution, "Confirm your planning and start the turn resolution", undefined, {
|
||||
center: true,
|
||||
text: "Ready",
|
||||
text_x: 12,
|
||||
text_style: { size: 24, color: "#9fc4d6" }
|
||||
});
|
||||
}
|
||||
|
||||
builder.image("battle-infobar-turncounter", 450, 0, true);
|
||||
this.turns = builder.text("Turn", 450, 0, { center: true, size: 24, color: "#9fc4d6" });
|
||||
|
|
|
@ -225,9 +225,15 @@ module TK.SpaceTac.UI {
|
|||
* Start the turn resolution
|
||||
*/
|
||||
startResolution(): void {
|
||||
const message = "Validate your whole fleet planning, and proceed to turn resolution?";
|
||||
UIConfirmDialog.ask(this, message).then(ok => {
|
||||
if (ok) {
|
||||
// TODO Check we are in planning phase
|
||||
// TODO Wait for AI
|
||||
// TODO
|
||||
// TODO Merge plans
|
||||
this.actual_battle.applyTurnPlan(this.turn_plannings[0].getTurnPlan());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -9,7 +9,7 @@ module TK.SpaceTac.UI {
|
|||
constructor(view: BaseView, message: string) {
|
||||
super(view);
|
||||
|
||||
this.content.text(message, this.width * 0.5, this.height * 0.4, { color: "#9FC4D6", size: 32, shadow: true });
|
||||
this.content.text(message, this.width * 0.5, this.height * 0.4, { color: "#9FC4D6", size: 32, shadow: true, width: 800 });
|
||||
|
||||
this.result = new Promise(resolve => {
|
||||
this.result_resolver = resolve;
|
||||
|
|
Loading…
Reference in a new issue