1
0
Fork 0
spacetac/src/core/TurnResolution.ts

72 lines
2.5 KiB
TypeScript

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) {
const target = TurnPlanning.getTargetForAction(ship, actionplan);
this.battle.applyOneAction(actionplan.action, target);
}
});
}
});
});
}
/**
* Log a turn end diff
*/
logEnd(): void {
this.battle.applyDiffs([new TurnEndDiff(this.battle.turncount)]);
}
}
}