1
0
Fork 0
spacetac/src/ui/battle/TurnPlanDisplay.ts

155 lines
6.1 KiB
TypeScript

module TK.SpaceTac.UI {
const PLAN_COLOR = 0xa5b7da
const PLAN_COLOR_HL = 0xdde6f9
/**
* Displays and maintain a turn plan
*/
export class TurnPlanDisplay {
readonly container: UIContainer
private battle?: Battle
constructor(builder: UIBuilder) {
this.container = builder.container("battleplan");
}
update(plan: TurnPlan, battle?: Battle): void {
this.battle = battle;
this.updateBattle(plan, this.container);
}
private updateBattle(plan: TurnPlan, 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) {
const ship = this.battle ? this.battle.getShip(plan.ship) : null;
if (ship) {
const move = first(plan.actions, action => action.category === ActionCategory.MOVE);
const final_location = (move && move.distance) ? TurnPlanning.getTargetForAction(ship, move) : ship.location;
const active = first(plan.actions, action => action.category === ActionCategory.ACTIVE);
this.updateMoveAction(ship, move, active, parent);
this.updateActiveAction(ship, final_location, active, parent);
} else {
console.error("Ship not found to update actions", plan);
}
}
private updateMoveAction(ship: Ship, plan: ActionPlan | null, active: ActionPlan | null, parent: UIContainer) {
let builder = parent.getBuilder();
let child = parent.getByName("moveline");
const graphics = child ? as(UIGraphics, child) : builder.graphics("moveline");
const move_location = plan ? TurnPlanning.getTargetForAction(ship, plan) : undefined;
graphics.clear();
if (move_location) {
graphics.addLine({
start: ship.location,
end: move_location,
width: 5,
color: PLAN_COLOR
});
}
child = parent.getByName("moveghost");
const ghost = child ? as(UIImage, child) : builder.image(`ship-${ship.model.code}-sprite`, 0, 0, true);
ghost.setName("moveghost");
if (move_location) {
ghost.setVisible(true);
ghost.setPosition(move_location.x, move_location.y);
if (builder.view.isTintSupported()) {
ghost.setTintFill(PLAN_COLOR);
} else {
ghost.setAlpha(0.6);
}
ghost.setRotation((active && active.angle) ? active.angle : arenaAngle(ship.location, move_location));
} else {
ghost.setVisible(false);
}
}
private updateActiveAction(ship: Ship, from: IArenaLocation, plan: ActionPlan | null, parent: UIContainer) {
let child = parent.getByName("activearea");
const graphics = child ? as(UIGraphics, child) : parent.getBuilder().graphics("activearea");
graphics.clear();
const action = plan ? ship.actions.getById(plan.action) : null;
if (action && plan) {
let radius = 0;
let angle = 0;
if (action instanceof TriggerAction) {
if (action.angle) {
angle = (action.angle * 0.5) * Math.PI / 180;
radius = action.range;
} else {
radius = action.blast;
}
} else if (action instanceof DeployDroneAction) {
radius = action.drone_radius;
} else if (action instanceof ToggleAction) {
radius = action.radius;
}
if (radius) {
if (angle) {
const base_angle = plan.angle || 0;
graphics.addCircleArc({
center: from,
radius,
angle: { start: base_angle - angle, span: angle * 2 },
fill: { color: PLAN_COLOR, alpha: 0.2 },
border: { color: PLAN_COLOR_HL, alpha: 0.2, width: 4 },
});
} else {
const center = TurnPlanning.getTargetForAction(ship, plan);
if (arenaDistance(from, center) > 0.0) {
graphics.addLine({
start: from,
end: center,
width: 6,
alpha: 0.2,
color: PLAN_COLOR_HL
});
}
graphics.addCircle({
center,
radius,
fill: { color: PLAN_COLOR, alpha: 0.2 },
border: { color: PLAN_COLOR_HL, alpha: 0.2, width: 4 },
});
}
}
}
}
}
}