98 lines
3.1 KiB
TypeScript
98 lines
3.1 KiB
TypeScript
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
|
|
}
|
|
}
|