2015-01-28 00:00:00 +00:00
|
|
|
/// <reference path="BaseAction.ts"/>
|
|
|
|
|
2017-02-09 00:00:35 +00:00
|
|
|
module TS.SpaceTac {
|
2017-04-18 19:51:23 +00:00
|
|
|
/**
|
|
|
|
* Action to fire a weapon on another ship, or in space
|
|
|
|
*/
|
2015-01-28 00:00:00 +00:00
|
|
|
export class FireWeaponAction extends BaseAction {
|
2017-04-18 19:51:23 +00:00
|
|
|
// Power consumption
|
|
|
|
power: number;
|
|
|
|
|
|
|
|
// Maximal range of the weapon
|
|
|
|
range: number
|
|
|
|
|
|
|
|
// Blast radius
|
|
|
|
blast: number;
|
|
|
|
|
|
|
|
// Effects applied on hit
|
|
|
|
effects: BaseEffect[];
|
2015-01-28 00:00:00 +00:00
|
|
|
|
2017-03-09 17:11:00 +00:00
|
|
|
// Equipment cannot be null
|
|
|
|
equipment: Equipment;
|
|
|
|
|
2017-04-18 19:51:23 +00:00
|
|
|
constructor(equipment: Equipment, power = 1, range = 0, blast = 0, effects: BaseEffect[] = [], name = "Fire") {
|
2017-01-08 22:42:53 +00:00
|
|
|
super("fire-" + equipment.code, name, true, equipment);
|
2015-01-28 00:00:00 +00:00
|
|
|
|
2017-04-18 19:51:23 +00:00
|
|
|
this.power = power;
|
|
|
|
this.range = range;
|
|
|
|
this.effects = effects;
|
|
|
|
this.blast = blast;
|
|
|
|
}
|
|
|
|
|
|
|
|
getActionPointsUsage(ship: Ship, target: Target | null): number {
|
|
|
|
return this.power;
|
|
|
|
}
|
|
|
|
|
|
|
|
getRangeRadius(ship: Ship): number {
|
|
|
|
return this.range;
|
|
|
|
}
|
|
|
|
|
|
|
|
getBlastRadius(ship: Ship): number {
|
|
|
|
return this.blast;
|
2015-01-28 00:00:00 +00:00
|
|
|
}
|
|
|
|
|
2017-03-09 17:11:00 +00:00
|
|
|
checkLocationTarget(ship: Ship, target: Target): Target | null {
|
2017-04-18 19:51:23 +00:00
|
|
|
if (target && this.blast > 0) {
|
|
|
|
target = target.constraintInRange(ship.arena_x, ship.arena_y, this.range);
|
2015-01-28 00:00:00 +00:00
|
|
|
return target;
|
|
|
|
} else {
|
|
|
|
return null;
|
|
|
|
}
|
2015-01-28 00:00:00 +00:00
|
|
|
}
|
|
|
|
|
2017-03-09 17:11:00 +00:00
|
|
|
checkShipTarget(ship: Ship, target: Target): Target | null {
|
|
|
|
if (target.ship && ship.getPlayer() === target.ship.getPlayer()) {
|
2015-01-28 00:00:00 +00:00
|
|
|
// No friendly fire
|
|
|
|
return null;
|
|
|
|
} else {
|
2015-01-28 00:00:00 +00:00
|
|
|
// Check if target is in range
|
2017-04-18 19:51:23 +00:00
|
|
|
if (this.blast > 0) {
|
2017-03-08 23:18:40 +00:00
|
|
|
return this.checkLocationTarget(ship, new Target(target.x, target.y));
|
2017-04-18 19:51:23 +00:00
|
|
|
} else if (target.isInRange(ship.arena_x, ship.arena_y, this.range)) {
|
2015-01-28 00:00:00 +00:00
|
|
|
return target;
|
|
|
|
} else {
|
|
|
|
return null;
|
|
|
|
}
|
2015-01-28 00:00:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-02-27 00:42:12 +00:00
|
|
|
/**
|
|
|
|
* Collect the effects applied by this action
|
|
|
|
*/
|
2017-03-09 17:11:00 +00:00
|
|
|
getEffects(ship: Ship, target: Target): [Ship, BaseEffect][] {
|
2017-02-27 00:42:12 +00:00
|
|
|
let result: [Ship, BaseEffect][] = [];
|
|
|
|
let blast = this.getBlastRadius(ship);
|
2017-03-09 17:11:00 +00:00
|
|
|
let battle = ship.getBattle();
|
|
|
|
let ships = (blast && battle) ? battle.collectShipsInCircle(target, blast, true) : ((target.ship && target.ship.alive) ? [target.ship] : []);
|
2017-02-27 00:42:12 +00:00
|
|
|
ships.forEach(ship => {
|
2017-04-18 19:51:23 +00:00
|
|
|
this.effects.forEach(effect => result.push([ship, effect]));
|
2017-02-27 00:42:12 +00:00
|
|
|
});
|
|
|
|
return result;
|
|
|
|
}
|
2015-02-20 00:00:00 +00:00
|
|
|
|
2017-03-07 19:27:46 +00:00
|
|
|
protected customApply(ship: Ship, target: Target) {
|
2017-02-14 00:30:50 +00:00
|
|
|
// Face the target
|
|
|
|
ship.rotate(Target.newFromShip(ship).getAngleTo(target));
|
|
|
|
|
2015-03-11 00:00:00 +00:00
|
|
|
// Fire event
|
|
|
|
ship.addBattleEvent(new FireEvent(ship, this.equipment, target));
|
|
|
|
|
2017-02-27 00:42:12 +00:00
|
|
|
// Apply effects
|
2017-03-09 17:11:00 +00:00
|
|
|
let effects = this.getEffects(ship, target);
|
2017-02-27 00:42:12 +00:00
|
|
|
effects.forEach(([ship, effect]) => effect.applyOnShip(ship));
|
2015-01-28 00:00:00 +00:00
|
|
|
}
|
2017-04-18 19:51:23 +00:00
|
|
|
|
2017-04-18 22:55:59 +00:00
|
|
|
getEffectsDescription(): string {
|
|
|
|
if (this.effects.length == 0) {
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
|
|
|
let desc = `${this.name} (power usage ${this.power}, max range ${this.range}km)`;
|
|
|
|
let effects = this.effects.map(effect => {
|
2017-04-18 19:51:23 +00:00
|
|
|
let suffix = this.blast ? `in ${this.blast}km radius` : "on target";
|
|
|
|
if (effect instanceof StickyEffect) {
|
|
|
|
suffix = `for ${effect.duration} turn${effect.duration > 1 ? "s" : ""} ${suffix}`;
|
|
|
|
}
|
2017-04-18 22:55:59 +00:00
|
|
|
return "- " + effect.getDescription() + " " + suffix;
|
2017-04-18 19:51:23 +00:00
|
|
|
});
|
2017-04-18 22:55:59 +00:00
|
|
|
return `${desc}:\n${effects.join("\n")}`;
|
2017-04-18 19:51:23 +00:00
|
|
|
}
|
2015-01-28 00:00:00 +00:00
|
|
|
}
|
|
|
|
}
|