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

172 lines
5.8 KiB
TypeScript
Raw Normal View History

2017-02-09 00:00:35 +00:00
module TS.SpaceTac {
/**
* Base class for a battle action.
*
* An action should be the only way to modify a battle state.
*/
export class BaseAction {
2014-12-31 00:00:00 +00:00
// Identifier code for the type of action
2017-05-16 23:12:05 +00:00
code: string
2014-12-31 00:00:00 +00:00
2017-01-08 22:42:53 +00:00
// Human-readable name
2017-05-16 23:12:05 +00:00
name: string
2017-01-08 22:42:53 +00:00
2015-01-06 00:00:00 +00:00
// Boolean at true if the action needs a target
2017-05-16 23:12:05 +00:00
needs_target: boolean
2015-01-06 00:00:00 +00:00
2015-01-28 00:00:00 +00:00
// Equipment that triggers this action
2017-05-16 23:12:05 +00:00
equipment: Equipment | null
2015-01-28 00:00:00 +00:00
2015-01-06 00:00:00 +00:00
// Create the action
2017-03-09 17:11:00 +00:00
constructor(code: string, name: string, needs_target: boolean, equipment: Equipment | null = null) {
2014-12-31 00:00:00 +00:00
this.code = code;
2017-01-08 22:42:53 +00:00
this.name = name;
2015-01-06 00:00:00 +00:00
this.needs_target = needs_target;
2015-01-28 00:00:00 +00:00
this.equipment = equipment;
2014-12-31 00:00:00 +00:00
}
2017-05-22 16:29:04 +00:00
/**
* Get the number of turns this action is unavailable, because of overheating
*/
getCooldownDuration(estimated = false): number {
if (this.equipment) {
return estimated ? this.equipment.cooldown.cooling : this.equipment.cooldown.heat;
} else {
return 0;
}
}
/**
* Get the number of remaining uses before overheat, infinity if there is no overheat
*/
getUsesBeforeOverheat(): number {
if (this.equipment) {
return this.equipment.cooldown.getRemainingUses();
} else {
return Infinity;
}
}
/**
* Check basic conditions to know if the ship can use this action at all
*
* Method to extend to set conditions
*
* Returns an informative message indicating why the action cannot be used, null otherwise
*/
2017-03-09 17:11:00 +00:00
checkCannotBeApplied(ship: Ship, remaining_ap: number | null = null): string | null {
let battle = ship.getBattle();
if (battle && battle.playing_ship !== ship) {
// Ship is not playing
return "ship not playing";
}
// Check AP usage
if (remaining_ap === null) {
remaining_ap = ship.values.power.get();
}
var ap_usage = this.getActionPointsUsage(ship, null);
2017-05-16 23:12:05 +00:00
if (remaining_ap < ap_usage) {
return "not enough power";
}
2017-05-16 23:12:05 +00:00
// Check cooldown
if (this.equipment && !this.equipment.cooldown.canUse()) {
return "overheated";
}
return null;
2014-12-31 00:00:00 +00:00
}
2015-02-26 00:00:00 +00:00
// Get the number of action points the action applied to a target would use
2017-03-09 17:11:00 +00:00
getActionPointsUsage(ship: Ship, target: Target | null): number {
return 0;
2015-02-26 00:00:00 +00:00
}
2015-03-03 00:00:00 +00:00
// Get the range of this action
getRangeRadius(ship: Ship): number {
return 0;
2015-03-03 00:00:00 +00:00
}
// Get the effect area radius of this action
getBlastRadius(ship: Ship): number {
return 0;
}
2014-12-31 00:00:00 +00:00
// Method to check if a target is applicable for this action
// Will call checkLocationTarget or checkShipTarget by default
2017-03-09 17:11:00 +00:00
checkTarget(ship: Ship, target: Target | null): Target | null {
if (this.checkCannotBeApplied(ship)) {
2014-12-31 00:00:00 +00:00
return null;
2015-01-06 00:00:00 +00:00
} else if (target) {
if (target.ship) {
return this.checkShipTarget(ship, target);
2015-01-06 00:00:00 +00:00
} else {
return this.checkLocationTarget(ship, target);
2015-01-06 00:00:00 +00:00
}
2014-12-31 00:00:00 +00:00
} else {
2015-01-06 00:00:00 +00:00
return null;
2014-12-31 00:00:00 +00:00
}
}
// Method to reimplement to check if a space target is applicable
// Must return null if the target can't be applied, an altered target, or the original target
2017-03-09 17:11:00 +00:00
checkLocationTarget(ship: Ship, target: Target): Target | null {
2014-12-31 00:00:00 +00:00
return null;
}
// Method to reimplement to check if a ship target is applicable
// Must return null if the target can't be applied, an altered target, or the original target
2017-03-09 17:11:00 +00:00
checkShipTarget(ship: Ship, target: Target): Target | null {
2014-12-31 00:00:00 +00:00
return null;
}
// Apply an action, returning true if it was successful
2017-03-09 17:11:00 +00:00
apply(ship: Ship, target: Target | null): boolean {
let reject = this.checkCannotBeApplied(ship);
if (reject == null) {
let checked_target = this.checkTarget(ship, target);
if (!checked_target && this.needs_target) {
console.warn("Action rejected - invalid target", ship, this, target);
2015-01-06 00:00:00 +00:00
return false;
}
let cost = this.getActionPointsUsage(ship, checked_target);
2017-02-19 21:52:11 +00:00
if (!ship.useActionPoints(cost)) {
console.warn("Action rejected - not enough power", ship, this, checked_target);
return false;
}
2017-02-19 21:52:11 +00:00
if (this.equipment) {
this.equipment.addWear(1);
ship.listEquipment(SlotType.Power).forEach(equipment => equipment.addWear(1));
2017-05-16 23:12:05 +00:00
this.equipment.cooldown.use();
}
let battle = ship.getBattle();
if (battle) {
2017-09-14 21:56:28 +00:00
battle.log.add(new ActionAppliedEvent(ship, this, checked_target, cost));
}
this.customApply(ship, checked_target);
2017-02-19 21:52:11 +00:00
return true;
2015-01-06 00:00:00 +00:00
} else {
console.warn(`Action rejected - ${reject}`, ship, this, target);
return false;
}
}
// Method to reimplement to apply a action
2017-03-09 17:11:00 +00:00
protected customApply(ship: Ship, target: Target | null) {
}
/**
* Get textual description of effects
*/
getEffectsDescription(): string {
return "";
}
2014-12-31 00:00:00 +00:00
}
2015-01-07 00:00:00 +00:00
}