1
0
Fork 0
spacetac/src/core/Drone.ts

95 lines
2.7 KiB
TypeScript

module TK.SpaceTac {
/**
* Drones are static objects that apply effects in a circular zone around themselves.
*/
export class Drone extends RObject {
// ID of the owning ship
owner: RObjectId
// Code of the drone
code: string
// Location in arena
x: number
y: number
radius: number
// Remaining lifetime in number of turns
duration: number
// Effects to apply
effects: BaseEffect[] = []
constructor(owner: Ship, code = "drone", base_duration = 1) {
super();
this.owner = owner.id;
this.code = code;
this.duration = base_duration;
}
/**
* Return the current location of the drone
*/
get location(): ArenaLocation {
return new ArenaLocation(this.x, this.y);
}
/**
* Get a textual description of this drone
*/
getDescription(): string {
let effects = this.effects.map(effect => "• " + effect.getDescription()).join("\n");
if (effects.length == 0) {
effects = "• do nothing";
}
return `For ${this.duration} activation${this.duration > 1 ? "s" : ""}:\n${effects}`;
}
/**
* Check if a location is in range
*/
isInRange(x: number, y: number): boolean {
return Target.newFromLocation(x, y).getDistanceTo(this) <= this.radius;
}
/**
* Get the list of affected ships.
*/
getAffectedShips(battle: Battle): Ship[] {
let ships = ifilter(battle.iships(), ship => ship.alive && ship.isInCircle(this.x, this.y, this.radius));
return imaterialize(ships);
}
/**
* Get the list of diffs needed to apply the drone effects on a list of ships.
*
* This does not check if the ships are in range.
*/
getDiffs(battle: Battle, ships: Ship[]): BaseBattleDiff[] {
let result: BaseBattleDiff[] = [];
if (this.duration >= 1 && ships.length > 0) {
result.push(new DroneAppliedDiff(this, ships));
ships.forEach(ship => {
result = result.concat(flatten(this.effects.map(effect => effect.getOnDiffs(ship, this))));
});
}
if (this.duration <= 1) {
result.push(new DroneDestroyedDiff(this));
}
return result;
}
/**
* Apply one drone "activation"
*/
activate(battle: Battle) {
let diffs = this.getDiffs(battle, this.getAffectedShips(battle));
battle.applyDiffs(diffs);
}
}
}