1
0
Fork 0
spacetac/src/core/actions/MoveAction.ts

110 lines
3.4 KiB
TypeScript

module TK.SpaceTac {
/**
* Configuration of a move action
*/
export interface MoveActionConfig {
// Power cost
power_cost: number
// Minimal distance to be used
min_distance: number
// Maximal distance reachable in one turn
max_distance: number
}
/**
* Action to move the ship to a specific location
*/
export class MoveAction extends BaseAction implements MoveActionConfig {
power_cost = 1
min_distance = 50
max_distance = 100
constructor(name = "Engine", config?: Partial<MoveActionConfig>, code = "move") {
super(name, code);
if (config) {
this.configureEngine(config);
}
}
getCategory(): ActionCategory {
return ActionCategory.MOVE;
}
/**
* Configure the engine
*/
configureEngine(config: Partial<MoveActionConfig>): void {
copyfields(config, this);
}
getVerb(ship: Ship): string {
return "Move";
}
getTitle(ship: Ship): string {
return `Use ${this.name}`;
}
getTargettingMode(ship: Ship): ActionTargettingMode {
return ActionTargettingMode.SPACE;
}
getDefaultTarget(ship: Ship): Target {
return Target.newFromLocation(ship.arena_x + Math.cos(ship.arena_angle) * 100, ship.arena_y + Math.sin(ship.arena_angle) * 100);
}
checkCannotBeApplied(ship: Ship, remaining_ap: number | null = null): ActionUnavailability | null {
let base = super.checkCannotBeApplied(ship, Infinity);
if (base) {
return base;
}
// Check vigilance actions
if (any(ship.getToggleActions(true), action => action instanceof VigilanceAction)) {
return ActionUnavailability.VIGILANCE;
}
// Check pinned status
if (any(ship.getEffects(), effect => effect instanceof PinnedEffect)) {
return ActionUnavailability.PINNED;
}
return null;
}
getPowerUsage(ship: Ship): number {
return this.power_cost;
}
getRangeRadius(ship: Ship): number {
return this.max_distance;
}
/**
* Apply reachable range, with remaining power
*/
applyReachableRange(ship: Ship, target: Target, margin = 0.1): Target {
let max_distance = this.getRangeRadius(ship);
max_distance = Math.max(0, max_distance - margin);
return target.constraintInRange(ship.arena_x, ship.arena_y, max_distance);
}
checkLocationTarget(ship: Ship, target: Target): Target | null {
target = this.applyReachableRange(ship, target);
return target.getDistanceTo(ship.location) > 0 ? target : null;
}
protected getSpecificDiffs(ship: Ship, battle: Battle, target: Target): BaseBattleDiff[] {
let angle = (arenaDistance(target, ship.location) < 0.00001) ? ship.arena_angle : arenaAngle(ship.location, target);
let destination = new ArenaLocationAngle(target.x, target.y, angle);
return [new ShipMoveDiff(ship, ship.location, destination, this)];
}
getEffectsDescription(): string {
let result = `Move: up to ${this.max_distance}km`;
return result;
}
}
}