1
0
Fork 0
spacetac/src/core/actions/DeployDroneAction.ts
2018-07-09 12:28:18 +02:00

112 lines
3.9 KiB
TypeScript

/// <reference path="ToggleAction.ts"/>
module TK.SpaceTac {
/**
* Configuration of a drone deployment action
*/
export interface DeployDroneActionConfig {
// Maximal distance the drone may be deployed
deploy_distance: number
// Effect radius of the deployed drone
drone_radius: number
// Effects applied to ships in range of the drone
drone_effects: BaseEffect[]
}
/**
* Action to deploy a drone in space
*
* This is a toggled action, meaning that deploying a drone requires a permanent power supply from the ship
*/
export class DeployDroneAction extends ToggleAction implements DeployDroneActionConfig {
deploy_distance = 0
drone_radius = 0
drone_effects: BaseEffect[] = []
constructor(name: string, toggle_config?: Partial<ToggleActionConfig>, drone_config?: Partial<DeployDroneActionConfig>, code?: string) {
super(name, toggle_config, code);
if (drone_config) {
this.configureDrone(drone_config);
}
}
/**
* Configure the deployed drone
*/
configureDrone(config: Partial<DeployDroneActionConfig>): void {
copyfields(config, this);
}
getVerb(ship: Ship): string {
return ship.actions.isToggled(this) ? "Recall" : "Deploy";
}
getTargettingMode(ship: Ship): ActionTargettingMode {
return ship.actions.isToggled(this) ? ActionTargettingMode.SELF : ActionTargettingMode.SPACE;
}
getDefaultTarget(ship: Ship): Target {
let harmful = any(this.effects, effect => !effect.isBeneficial());
let distance = this.drone_radius * (harmful ? 1.1 : 0.9);
return Target.newFromLocation(
ship.arena_x + Math.cos(ship.arena_angle) * distance,
ship.arena_y + Math.sin(ship.arena_angle) * distance
);
}
getRangeRadius(ship: Ship): number {
return ship.actions.isToggled(this) ? 0 : this.deploy_distance;
}
filterImpactedShips(ship: Ship, source: ArenaLocation, target: Target, ships: Ship[]): Ship[] {
let result = ships.filter(iship => arenaDistance(iship.location, target) <= this.radius);
result = BaseAction.filterTargets(ship, result, this.filter);
return result;
}
checkShipTarget(ship: Ship, target: Target): boolean {
return false;
}
checkLocationTarget(ship: Ship, target: Target): boolean {
return arenaInRange(ship.location, target, this.deploy_distance);
}
getSpecificDiffs(ship: Ship, battle: Battle, target: Target): BaseBattleDiff[] {
let result = super.getSpecificDiffs(ship, battle, target);
if (ship.actions.isToggled(this)) {
let drone = first(battle.drones.list(), idrone => this.is(idrone.parent));
if (drone) {
result.push(new DroneRecalledDiff(drone));
} else {
return [];
}
} else {
let drone = new Drone(ship, this.code);
drone.parent = this;
drone.x = target.x;
drone.y = target.y;
drone.radius = this.drone_radius;
drone.effects = this.drone_effects;
result.push(new DroneDeployedDiff(drone));
}
return result;
}
getEffectsDescription(): string {
let desc = `Deploy drone (power usage ${this.power}, max range ${this.deploy_distance}km)`;
let suffix = `on ${BaseAction.getFilterDesc(this.filter)} in ${this.drone_radius}km radius`;
let effects = this.drone_effects.map(effect => {
return "• " + effect.getDescription() + " " + suffix;
});
return `${desc}:\n${effects.join("\n")}`;
}
}
}