namespace TK.SpaceTac { /** * A tool to manipulate the plans for a turn (action plans for all involved ships, for one turn) */ export class TurnPlanning { private plan: TurnPlan constructor(private battle: Battle, readonly player?: Player) { this.plan = { fleets: battle.fleets.map(fleet => ({ fleet: fleet.id, ships: fleet.ships.map(ship => ({ ship: ship.id, actions: [] })) })) }; } getTurnPlan(): TurnPlan { return this.plan; } getFleetPlan(fleet: Fleet): FleetPlan { const fplan = first(this.plan.fleets, ifleet => fleet.is(ifleet.fleet)); return fplan || { fleet: -1, ships: [] }; } getShipPlan(ship: Ship): ShipPlan { const fplan = this.getFleetPlan(ship.fleet); const splan = first(fplan.ships, iship => ship.is(iship.ship)); return splan || { ship: -1, actions: [] }; } /** * Add an action to a ship plan */ addAction(ship: Ship, action: BaseAction, distance?: number, angle?: number) { const plan = this.getShipPlan(ship); if (action.getCategory() == ActionCategory.PASSIVE) { plan.actions = plan.actions.filter(iaction => !action.is(iaction.action)); } else { plan.actions = plan.actions.filter(iaction => iaction.category != action.getCategory()); } plan.actions.push({ action: action.id, category: action.getCategory(), distance, angle }); } /** * Collect all planned actions for all ships */ collectAllActions(): ActionPlan[] { return flatten(flatten(this.plan.fleets.map(fleet => fleet.ships.map(ship => ship.actions)))); } /** * Get the target object for a given ship */ static getTargetForAction(ship: Ship, action: ActionPlan): Target { if (typeof action.angle != "undefined") { if (action.distance) { return Target.newFromLocation( ship.arena_x + action.distance * Math.cos(action.angle), ship.arena_y + action.distance * Math.sin(action.angle), ); } else { return Target.newFromLocation( ship.arena_x + Math.cos(action.angle), ship.arena_y + Math.sin(action.angle), ); } } else { return Target.newFromShip(ship); } } } export type TurnPlan = { fleets: FleetPlan[] } export type FleetPlan = { fleet: RObjectId, ships: ShipPlan[] } export type ShipPlan = { ship: RObjectId actions: ActionPlan[] } export type ActionPlan = { action: RObjectId category: ActionCategory distance?: number angle?: number } }