1
0
Fork 0
spacetac/src/ui/battle/ActionBar.ts
2018-07-12 16:51:30 +02:00

251 lines
9 KiB
TypeScript

/// <reference path="../common/UIContainer.ts" />
module TK.SpaceTac.UI {
/**
* Bar on the border of screen to display all available action icons
*/
export class ActionBar extends UIContainer {
// Link to the parent battleview
battleview: BattleView
// List of action icons
actions: UIContainer
action_icons: ActionIcon[]
// Power indicator
power: UIContainer
power_icons!: UIContainer
// Indicator of interaction disabled
icon_waiting: UIAwaiter
// Current ship, whose actions are displayed
ship: Ship | null
// Interactivity
interactive = true;
// Create an empty action bar
constructor(battleview: BattleView) {
super(battleview);
this.battleview = battleview;
this.action_icons = [];
this.ship = null;
battleview.layer_borders.add(this);
let builder = new UIBuilder(battleview, this);
// Background
let base = builder.image("battle-actionbar-background");
// Group for actions
this.actions = builder.container("actions", 86, 6);
builder.in(this.actions).image("battle-actionbar-actions-background");
// Power bar
this.power = builder.container("power", 1466, 0);
builder.in(this.power, builder => {
builder.image("battle-actionbar-power-background", 0, 6);
this.power_icons = builder.container("power icons", 50, 14);
});
// Playing ship
builder.image("battle-actionbar-ship", 1735);
// Waiting icon
this.icon_waiting = builder.awaiter(base.width / 2, base.height / 2, true, 0.5);
// Options button
builder.button("battle-actionbar-button-menu", 0, 0, () => battleview.showOptions(), "Game options");
// Log processing
battleview.log_processor.register(diff => {
if (!(diff instanceof BaseBattleShipDiff) || !this.ship || !this.ship.is(diff.ship_id)) {
return {};
}
if (diff instanceof ShipValueDiff && diff.code == "power") {
return {
background: async () => {
this.updatePower();
this.action_icons.forEach(action => action.refresh());
}
}
} else if (diff instanceof ShipAttributeDiff && diff.code == "power_capacity") {
return {
background: async () => this.updatePower()
}
} else if (diff instanceof ShipActionUsedDiff || diff instanceof ShipActionToggleDiff) {
return {
background: async () => this.action_icons.forEach(action => action.refresh())
}
} else if (diff instanceof ShipCooldownDiff) {
return {
background: async () => {
let icons = this.action_icons.filter(icon => icon.action.is(diff.action));
icons.forEach(icon => icon.refresh());
}
}
} else if (diff instanceof ShipChangeDiff) {
return {
background: async () => {
this.setShip(null);
}
}
} else {
return {}
}
});
battleview.log_processor.watchForShipChange(ship => {
return {
background: async () => {
this.setShip(ship);
}
}
});
this.setInteractivity(false);
}
/**
* Check if an action is selected
*/
hasActionSelected(): boolean {
return any(this.action_icons, icon => icon.selected);
}
/**
* Set the interactivity state
*/
setInteractivity(interactive: boolean) {
if (this.interactive != interactive) {
this.interactive = interactive;
this.battleview.animations.setVisible(this.icon_waiting, !this.interactive, 100);
this.battleview.animations.setVisible(this.power, interactive, 100, 1, 0.3);
this.battleview.animations.setVisible(this.actions, interactive, 100, 1, 0.3);
}
}
/**
* Called when an action shortcut key is pressed
*/
keyActionPressed(position: number) {
if (this.interactive) {
if (position < 0) {
this.action_icons[this.action_icons.length - 1].processClick();
} else if (position < this.action_icons.length - 1) {
this.action_icons[position].processClick();
}
}
}
/**
* Remove all the action icons
*/
clearAll(): void {
this.action_icons.forEach(action => action.destroy());
this.action_icons = [];
}
/**
* Add an action icon
*/
addAction(ship: Ship, action: BaseAction): ActionIcon {
var icon = new ActionIcon(this, ship, action, this.action_icons.length);
icon.moveTo(this.actions, 74 + this.action_icons.length * 138, 58);
this.action_icons.push(icon);
return icon;
}
/**
* Update the power indicator
*/
updatePower(move_power = 0, fire_power = 0): void {
let power_capacity = this.ship ? this.ship.getAttribute("power_capacity") : 0;
let power_value = this.ship ? this.ship.getValue("power") : 0;
let current_power = this.power_icons.length;
if (current_power > power_capacity) {
destroyChildren(this.power_icons, power_capacity, current_power);
} else if (power_capacity > current_power) {
range(power_capacity - current_power).forEach(i => {
let x = (current_power + i) % 5;
let y = ((current_power + i) - x) / 5;
let image = new UIBuilder(this.battleview, this.power_icons).image("battle-actionbar-power-used", x * 43, y * 22);
});
}
let remaining_power = power_value - move_power - fire_power;
this.power_icons.list.forEach((obj, idx) => {
let img = <UIImage>obj;
if (idx < remaining_power) {
this.battleview.changeImage(img, "battle-actionbar-power-available");
} else if (idx < remaining_power + move_power) {
this.battleview.changeImage(img, "battle-actionbar-power-move");
} else if (idx < power_value) {
this.battleview.changeImage(img, "battle-actionbar-power-fire");
} else {
this.battleview.changeImage(img, "battle-actionbar-power-used");
}
});
}
/**
* Temporarily set current action power usage.
*
* When an action is selected, this will fade the icons not available after the action would be done.
* This will also highlight power usage in the power bar.
*
* *move_power* and *fire_power* is the consumption of currently selected action/target.
*/
updateSelectedActionPower(move_power: number, fire_power: number, action: BaseAction): void {
this.action_icons.forEach(icon => icon.refresh(action, move_power + fire_power));
this.updatePower(move_power, fire_power);
}
/**
* Temporarily set power status for a given move-fire simulation
*/
updateFromSimulation(action: BaseAction, simulation: MoveFireResult) {
if (simulation.status == MoveFireStatus.OK) {
this.updateSelectedActionPower(simulation.total_move_ap, simulation.total_fire_ap, action);
} else {
this.updateSelectedActionPower(0, 0, action);
}
}
/**
* Set the bar to display a given ship
*/
setShip(ship: Ship | null): void {
this.clearAll();
if (ship && this.battleview.player.is(ship.fleet.player) && ship.alive) {
ship.actions.listAll().forEach(action => this.addAction(ship, action));
this.ship = ship;
} else {
this.ship = null;
}
this.updatePower();
}
// Called by an action icon when the action is selected
actionStarted(): void {
}
// Called by an action icon when the action has been applied
actionEnded(): void {
this.battleview.exitTargettingMode();
this.updatePower();
this.action_icons.forEach(action => action.refresh());
}
}
}