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

118 lines
4.2 KiB
TypeScript
Raw Normal View History

2017-02-09 00:00:35 +00:00
module TS.SpaceTac {
2014-12-31 00:00:00 +00:00
// Action to move to a given location
export class MoveAction extends BaseAction {
// Distance allowed for each power point (raw, without applying maneuvrability)
2017-05-29 18:12:57 +00:00
distance_per_power: number
// Safety distance from other ships
2017-05-29 18:12:57 +00:00
safety_distance: number
2017-03-09 17:11:00 +00:00
// Equipment cannot be null (engine)
2017-05-29 18:12:57 +00:00
equipment: Equipment
2017-03-09 17:11:00 +00:00
// Impact of maneuvrability (in % of distance)
maneuvrability_factor: number
constructor(equipment: Equipment, distance_per_power = 0, safety_distance = 120, maneuvrability_factor = 0) {
2017-01-08 22:42:53 +00:00
super("move", "Move", true, equipment);
this.distance_per_power = distance_per_power;
2017-07-31 22:49:00 +00:00
this.safety_distance = safety_distance;
this.maneuvrability_factor = maneuvrability_factor;
2014-12-31 00:00:00 +00:00
}
2017-03-09 17:11:00 +00:00
checkCannotBeApplied(ship: Ship, remaining_ap: number | null = null): string | null {
let base = super.checkCannotBeApplied(ship, Infinity);
if (base) {
return base;
}
// Check AP usage
if (remaining_ap === null) {
remaining_ap = ship.values.power.get();
}
if (remaining_ap > 0.0001) {
return null;
} else {
return "not enough power";
}
2014-12-31 00:00:00 +00:00
}
getActionPointsUsage(ship: Ship, target: Target): number {
2015-02-26 00:00:00 +00:00
if (target === null) {
return 0;
}
var distance = Target.newFromShip(ship).getDistanceTo(target);
return Math.ceil(distance / this.getDistanceByActionPoint(ship));
2015-02-26 00:00:00 +00:00
}
2015-03-03 00:00:00 +00:00
getRangeRadius(ship: Ship): number {
return ship.getValue("power") * this.getDistanceByActionPoint(ship);
2015-03-03 00:00:00 +00:00
}
/**
* Get the distance that may be traveled with 1 action point
*/
getDistanceByActionPoint(ship: Ship): number {
let maneuvrability = Math.max(ship.getAttribute("maneuvrability"), 0);
let factor = maneuvrability / (maneuvrability + 2);
return Math.ceil(this.distance_per_power * (1 - this.maneuvrability_factor * 0.01 * (1 - factor)));
}
/**
* Get an exclusion helper for this move action
*/
getExclusionAreas(ship: Ship): ExclusionAreas {
return ExclusionAreas.fromShip(ship, this.safety_distance);
}
/**
* Apply exclusion areas (neer arena borders, or other ships)
*/
applyExclusion(ship: Ship, target: Target): Target {
let exclusion = this.getExclusionAreas(ship);
let destination = exclusion.stopBefore(new ArenaLocation(target.x, target.y), ship.location);
target = Target.newFromLocation(destination.x, destination.y);
return target;
}
/**
* 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);
}
2017-07-31 22:49:00 +00:00
checkLocationTarget(ship: Ship, target: Target): Target | null {
target = this.applyReachableRange(ship, target);
target = this.applyExclusion(ship, target);
2017-07-31 22:49:00 +00:00
return target.getDistanceTo(ship.location) > 0 ? target : null;
2014-12-31 00:00:00 +00:00
}
protected customApply(ship: Ship, target: Target) {
ship.moveTo(target.x, target.y, this.equipment);
}
getEffectsDescription(): string {
let result = `Move: ${this.distance_per_power}km per power point`;
let precisions = [];
if (this.safety_distance) {
precisions.push(`safety: ${this.safety_distance}km`);
}
if (this.maneuvrability_factor) {
precisions.push(`maneuvrability influence: ${this.maneuvrability_factor}%`);
}
if (precisions.length) {
result += ` (${precisions.join(", ")})`;
}
return result;
}
2014-12-31 00:00:00 +00:00
}
2015-01-07 00:00:00 +00:00
}