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

112 lines
3.1 KiB
TypeScript
Raw Normal View History

2017-02-09 00:00:35 +00:00
module TS.SpaceTac {
2017-02-06 21:46:55 +00:00
/**
* Drones are static objects that apply effects in a circular zone around themselves.
*/
export class Drone {
2017-02-08 18:54:02 +00:00
// Code of the drone
code: string;
2017-02-06 21:46:55 +00:00
// Ship that deployed the drone
owner: Ship;
// Location in arena
x: number;
y: number;
radius: number;
// Lifetime in number of turns (not including the initial effect on deployment)
duration: number = 1;
// Effects to apply
effects: BaseEffect[] = [];
// Ships registered inside the radius
inside: Ship[] = [];
// Ships starting their turn the radius
inside_at_start: Ship[] = [];
2017-02-08 18:54:02 +00:00
constructor(owner: Ship, code = "drone") {
2017-02-06 21:46:55 +00:00
this.owner = owner;
2017-02-08 18:54:02 +00:00
this.code = code;
2017-02-06 21:46:55 +00:00
}
/**
* Filter the list of ships in radius.
2017-02-06 21:46:55 +00:00
*/
filterShipsInRadius(ships: Ship[]): Ship[] {
return ships.filter(ship => ship.isInCircle(this.x, this.y, this.radius));
2017-02-06 21:46:55 +00:00
}
/**
* Apply the effects on a list of ships
2017-02-06 21:46:55 +00:00
*
* This does not check if the ships are in range.
2017-02-06 21:46:55 +00:00
*/
apply(ships: Ship[], log = true) {
2017-02-15 22:34:27 +00:00
ships = ships.filter(ship => ship.alive);
if (ships.length > 0) {
let battle = this.owner.getBattle();
if (battle && log) {
battle.log.add(new DroneAppliedEvent(this, ships));
}
ships.forEach(ship => this.effects.forEach(effect => effect.applyOnShip(ship)));
}
2017-02-06 21:46:55 +00:00
}
/**
* Called when the drone is first deployed.
*/
onDeploy(ships: Ship[]) {
this.apply(this.filterShipsInRadius(ships));
2017-02-06 21:46:55 +00:00
}
/**
* Called when a ship turn starts
*/
2017-02-08 18:54:02 +00:00
onTurnStart(ship: Ship) {
2017-02-06 21:46:55 +00:00
if (ship == this.owner) {
2017-02-08 18:54:02 +00:00
this.duration--;
}
if (this.duration <= 0) {
if (this.owner) {
let battle = this.owner.getBattle();
if (battle) {
battle.removeDrone(this);
}
2017-02-06 21:46:55 +00:00
}
2017-02-08 18:54:02 +00:00
return;
2017-02-06 21:46:55 +00:00
}
if (ship.isInCircle(this.x, this.y, this.radius)) {
add(this.inside, ship);
add(this.inside_at_start, ship);
} else {
remove(this.inside_at_start, ship);
}
}
/**
* Called when a ship turn ends
*/
onTurnEnd(ship: Ship) {
2017-02-08 18:54:02 +00:00
if (this.duration > 0 && ship.isInCircle(this.x, this.y, this.radius) && contains(this.inside_at_start, ship)) {
this.apply([ship]);
2017-02-06 21:46:55 +00:00
}
}
/**
* Called after a ship moved
*/
onShipMove(ship: Ship) {
2017-02-08 18:54:02 +00:00
if (this.duration > 0 && ship.isInCircle(this.x, this.y, this.radius)) {
2017-02-06 21:46:55 +00:00
if (add(this.inside, ship)) {
this.apply([ship]);
2017-02-06 21:46:55 +00:00
}
} else {
remove(this.inside, ship);
}
}
}
}