1
0
Fork 0

Added log when an action cannot be applied

This commit is contained in:
Michaël Lemaire 2017-03-07 20:27:46 +01:00
parent cd7334babf
commit 144eb56537
21 changed files with 181 additions and 128 deletions

2
TODO
View file

@ -1,3 +1,4 @@
* Enable strict null checking in typescript
* Ensure that tweens and particle emitters get destroyed once animation is done (or view changes)
* Highlight ships that will be included as target of current action
* Controls: Do not focus on ship while targetting for area effects (dissociate hover and target)
@ -27,7 +28,6 @@
* TacticalAI: allow to play several moves in the same turn
* TacticalAI: add pauses to not play too quickly
* TacticalAI: replace BullyAI
* AIDuel: fix first AI always winning when two identical AIs are selected
* Add a defeat screen (game over for now)
* Add a victory screen, with loot display
* Add retreat from battle

View file

@ -89,5 +89,14 @@ module TS.SpaceTac.Specs {
{ action: jasmine.objectContaining({ code: "fire-null" }), target: new Target(ship.arena_x + 18, ship.arena_y, null), ap: 2 }
]);
});
it("does nothing if trying to move in the same spot", function () {
let [ship, simulator, action] = simpleWeaponCase();
let result = simulator.simulateAction(ship.listEquipment(SlotType.Engine)[0].action, new Target(ship.arena_x, ship.arena_y, null));
expect(result.success).toBe(true);
expect(result.need_move).toBe(false);
expect(result.need_fire).toBe(false);
expect(result.parts).toEqual([]);
});
});
}

View file

@ -59,27 +59,32 @@ module TS.SpaceTac {
* Simulate a given action on a given valid target.
*/
simulateAction(action: BaseAction, target: Target): MoveFireResult {
let result = new MoveFireResult();
let dx = target.x - this.ship.arena_x;
let dy = target.y - this.ship.arena_y;
let distance = Math.sqrt(dx * dx + dy * dy);
let result = new MoveFireResult();
let ap = this.ship.values.power.get();
let action_radius = action.getRangeRadius(this.ship);
if (action instanceof MoveAction || distance > action_radius) {
result.need_move = true;
let move_distance = action instanceof MoveAction ? distance : distance - action_radius;
let move_target = new Target(this.ship.arena_x + dx * move_distance / distance, this.ship.arena_y + dy * move_distance / distance, null);
let engine = this.findBestEngine();
if (engine) {
result.total_move_ap = engine.action.getActionPointsUsage(this.ship.getBattle(), this.ship, move_target);
result.can_move = ap > 0;
result.can_end_move = result.total_move_ap <= ap;
result.move_location = move_target;
result.parts.push({ action: engine.action, target: move_target, ap: result.total_move_ap });
if (move_distance > 0.000001) {
result.need_move = true;
ap -= result.total_move_ap;
distance -= move_distance;
let move_target = new Target(this.ship.arena_x + dx * move_distance / distance, this.ship.arena_y + dy * move_distance / distance, null);
let engine = this.findBestEngine();
if (engine) {
result.total_move_ap = engine.action.getActionPointsUsage(this.ship, move_target);
result.can_move = ap > 0;
result.can_end_move = result.total_move_ap <= ap;
result.move_location = move_target;
result.parts.push({ action: engine.action, target: move_target, ap: result.total_move_ap });
ap -= result.total_move_ap;
distance -= move_distance;
}
}
}
@ -87,7 +92,7 @@ module TS.SpaceTac {
result.success = true;
if (!(action instanceof MoveAction)) {
result.need_fire = true;
result.total_fire_ap = action.getActionPointsUsage(this.ship.getBattle(), this.ship, target);
result.total_fire_ap = action.getActionPointsUsage(this.ship, target);
result.can_fire = result.total_fire_ap <= ap;
result.fire_location = target;
result.parts.push({ action: action, target: target, ap: result.total_fire_ap });

View file

@ -8,22 +8,22 @@ module TS.SpaceTac {
ship.addSlot(SlotType.Hull).attach(equipment);
ship.values.power.setMaximal(10);
expect(action.canBeUsed(null, ship)).toBe(false);
expect(action.checkCannotBeApplied(ship)).toBe("not enough power");
ship.values.power.set(5);
expect(action.canBeUsed(null, ship)).toBe(true);
expect(action.canBeUsed(null, ship, 4)).toBe(true);
expect(action.canBeUsed(null, ship, 3)).toBe(true);
expect(action.canBeUsed(null, ship, 2)).toBe(false);
expect(action.checkCannotBeApplied(ship)).toBe(null);
expect(action.checkCannotBeApplied(ship, 4)).toBe(null);
expect(action.checkCannotBeApplied(ship, 3)).toBe(null);
expect(action.checkCannotBeApplied(ship, 2)).toBe("not enough power");
ship.values.power.set(3);
expect(action.canBeUsed(null, ship)).toBe(true);
expect(action.checkCannotBeApplied(ship)).toBe(null);
ship.values.power.set(2);
expect(action.canBeUsed(null, ship)).toBe(false);
expect(action.checkCannotBeApplied(ship)).toBe("not enough power");
});
});
}

View file

@ -21,12 +21,18 @@ module TS.SpaceTac {
this.equipment = equipment;
}
// Check basic conditions to know if the ship can use this action at all
// Method to reimplement to set conditions
canBeUsed(battle: Battle, ship: Ship, remaining_ap: number = null): boolean {
/**
* 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
*/
checkCannotBeApplied(ship: Ship, remaining_ap: number = null): string | null {
let battle = ship.getBattle();
if (battle && battle.playing_ship !== ship) {
// Ship is not playing
return false;
return "ship not playing";
}
// Check AP usage
@ -34,11 +40,15 @@ module TS.SpaceTac {
remaining_ap = ship.values.power.get();
}
var ap_usage = this.equipment ? this.equipment.ap_usage : 0;
return remaining_ap >= ap_usage;
if (remaining_ap >= ap_usage) {
return null;
} else {
return "not enough power";
}
}
// Get the number of action points the action applied to a target would use
getActionPointsUsage(battle: Battle, ship: Ship, target: Target): number {
getActionPointsUsage(ship: Ship, target: Target): number {
if (this.equipment) {
return this.equipment.ap_usage;
} else {
@ -66,14 +76,14 @@ module TS.SpaceTac {
// Method to check if a target is applicable for this action
// Will call checkLocationTarget or checkShipTarget by default
checkTarget(battle: Battle, ship: Ship, target: Target): Target {
if (!this.canBeUsed(battle, ship)) {
checkTarget(ship: Ship, target: Target): Target {
if (this.checkCannotBeApplied(ship)) {
return null;
} else if (target) {
if (target.ship) {
return this.checkShipTarget(battle, ship, target);
return this.checkShipTarget(ship, target);
} else {
return this.checkLocationTarget(battle, ship, target);
return this.checkLocationTarget(ship, target);
}
} else {
return null;
@ -82,38 +92,42 @@ module TS.SpaceTac {
// 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
checkLocationTarget(battle: Battle, ship: Ship, target: Target): Target {
checkLocationTarget(ship: Ship, target: Target): Target {
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
checkShipTarget(battle: Battle, ship: Ship, target: Target): Target {
checkShipTarget(ship: Ship, target: Target): Target {
return null;
}
// Apply an action, returning true if it was successful
apply(battle: Battle, ship: Ship, target: Target): boolean {
if (this.canBeUsed(battle, ship)) {
target = this.checkTarget(battle, ship, target);
apply(ship: Ship, target: Target): boolean {
let reject = this.checkCannotBeApplied(ship);
if (reject == null) {
target = this.checkTarget(ship, target);
if (!target && this.needs_target) {
console.warn("Action rejected - no target selected", ship, this, target);
return false;
}
let cost = this.getActionPointsUsage(battle, ship, target);
let cost = this.getActionPointsUsage(ship, target);
if (!ship.useActionPoints(cost)) {
console.warn("Action rejected - not enough power", ship, this, target);
return false;
}
this.customApply(battle, ship, target);
this.customApply(ship, target);
return true;
} else {
console.warn(`Action rejected - ${reject}`, ship, this, target);
return false;
}
}
// Method to reimplement to apply a action
protected customApply(battle: Battle, ship: Ship, target: Target) {
protected customApply(ship: Ship, target: Target) {
}
}
}

View file

@ -20,18 +20,18 @@ module TS.SpaceTac {
equipment.ap_usage = 0;
let action = new DeployDroneAction(equipment);
expect(action.checkTarget(null, ship, new Target(8, 0, null))).toEqual(new Target(8, 0, null));
expect(action.checkTarget(null, ship, new Target(12, 0, null))).toEqual(new Target(8, 0, null));
expect(action.checkTarget(ship, new Target(8, 0, null))).toEqual(new Target(8, 0, null));
expect(action.checkTarget(ship, new Target(12, 0, null))).toEqual(new Target(8, 0, null));
let other = new Ship();
other.setArenaPosition(8, 0);
expect(action.checkTarget(null, ship, new Target(8, 0, other))).toBeNull();
expect(action.checkTarget(ship, new Target(8, 0, other))).toBeNull();
});
it("deploys a new drone", function () {
let ship = new Ship();
ship.setArenaPosition(0, 0);
let battle = new Battle();
let ship = battle.fleets[0].addShip();
ship.setArenaPosition(0, 0);
battle.playing_ship = ship;
TestTools.setShipAP(ship, 3);
let equipment = new Equipment();
@ -43,7 +43,9 @@ module TS.SpaceTac {
equipment.target_effects.push(new DamageEffect(50));
let action = new DeployDroneAction(equipment);
let result = action.apply(battle, ship, new Target(5, 0, null));
battle.log.clear();
battle.log.addFilter("value");
let result = action.apply(ship, new Target(5, 0, null));
expect(result).toBe(true);
expect(battle.drones.length).toBe(1);

View file

@ -9,20 +9,24 @@ module TS.SpaceTac {
super("deploy-" + equipment.code, "Deploy", true, equipment);
}
checkLocationTarget(battle: Battle, ship: Ship, target: Target): Target {
checkLocationTarget(ship: Ship, target: Target): Target {
// TODO Not too close to other ships and drones
target = target.constraintInRange(ship.arena_x, ship.arena_y, this.equipment.distance);
return target;
}
protected customApply(battle: Battle, ship: Ship, target: Target) {
protected customApply(ship: Ship, target: Target) {
let drone = new Drone(ship, this.equipment.code);
drone.x = target.x;
drone.y = target.y;
drone.radius = this.equipment.blast;
drone.effects = this.equipment.target_effects;
drone.duration = this.equipment.duration;
battle.addDrone(drone);
let battle = ship.getBattle();
if (battle) {
battle.addDrone(drone);
}
}
}
}

View file

@ -1,14 +1,18 @@
module TS.SpaceTac.Specs {
describe("EndTurnAction", () => {
it("can't be applied to non-playing ship", () => {
spyOn(console, "warn").and.stub();
var battle = Battle.newQuickRandom();
var action = new EndTurnAction();
expect(action.canBeUsed(battle, battle.play_order[0])).toBe(true);
expect(action.canBeUsed(battle, battle.play_order[1])).toBe(false);
expect(action.checkCannotBeApplied(battle.play_order[0])).toBe(null);
expect(action.checkCannotBeApplied(battle.play_order[1])).toBe("ship not playing");
var result = action.apply(battle, battle.play_order[1], null);
var result = action.apply(battle.play_order[1], null);
expect(result).toBe(false);
expect(console.warn).toHaveBeenCalledWith("Action rejected - ship not playing", battle.play_order[1], action, null);
});
it("ends turn when applied", () => {
@ -17,7 +21,7 @@ module TS.SpaceTac.Specs {
expect(battle.playing_ship_index).toBe(0);
var result = action.apply(battle, battle.play_order[0], null);
var result = action.apply(battle.play_order[0], null);
expect(result).toBe(true);
expect(battle.playing_ship_index).toBe(1);
});

View file

@ -5,9 +5,13 @@ module TS.SpaceTac {
super("endturn", "End ship's turn", false);
}
protected customApply(battle: Battle, ship: Ship, target: Target) {
protected customApply(ship: Ship, target: Target) {
ship.endTurn();
battle.advanceToNextShip();
let battle = ship.getBattle();
if (battle) {
battle.advanceToNextShip();
}
}
}
}

View file

@ -39,7 +39,7 @@ module TS.SpaceTac {
battle.playing_ship = ship;
fleet.setBattle(battle);
action.apply(battle, ship, Target.newFromLocation(50, 50));
action.apply(ship, Target.newFromLocation(50, 50));
expect(mock_apply).toHaveBeenCalledTimes(1);
expect(mock_apply).toHaveBeenCalledWith(ship2);
});

View file

@ -12,7 +12,7 @@ module TS.SpaceTac {
this.can_target_space = can_target_space;
}
checkLocationTarget(battle: Battle, ship: Ship, target: Target): Target {
checkLocationTarget(ship: Ship, target: Target): Target {
if (this.can_target_space) {
target = target.constraintInRange(ship.arena_x, ship.arena_y, this.equipment.distance);
return target;
@ -21,7 +21,7 @@ module TS.SpaceTac {
}
}
checkShipTarget(battle: Battle, ship: Ship, target: Target): Target {
checkShipTarget(ship: Ship, target: Target): Target {
if (ship.getPlayer() === target.ship.getPlayer()) {
// No friendly fire
return null;
@ -48,7 +48,7 @@ module TS.SpaceTac {
return result;
}
protected customApply(battle: Battle, ship: Ship, target: Target) {
protected customApply(ship: Ship, target: Target) {
// Face the target
ship.rotate(Target.newFromShip(ship).getAngleTo(target));
@ -56,7 +56,7 @@ module TS.SpaceTac {
ship.addBattleEvent(new FireEvent(ship, this.equipment, target));
// Apply effects
let effects = this.getEffects(battle, ship, target);
let effects = this.getEffects(ship.getBattle(), ship, target);
effects.forEach(([ship, effect]) => effect.applyOnShip(ship));
}
}

View file

@ -15,14 +15,14 @@ module TS.SpaceTac {
expect(action.getDistanceByActionPoint(ship)).toBe(0.5);
var result = action.checkTarget(battle, ship, Target.newFromLocation(0, 2));
var result = action.checkTarget(ship, Target.newFromLocation(0, 2));
expect(result).toEqual(Target.newFromLocation(0, 2));
result = action.checkTarget(battle, ship, Target.newFromLocation(0, 8));
result = action.checkTarget(ship, Target.newFromLocation(0, 8));
expect(result).toEqual(Target.newFromLocation(0, 3));
ship.values.power.set(0);
result = action.checkTarget(battle, ship, Target.newFromLocation(0, 8));
result = action.checkTarget(ship, Target.newFromLocation(0, 8));
expect(result).toBeNull();
});
@ -31,10 +31,10 @@ module TS.SpaceTac {
var ship2 = new Ship(null, "Test2");
var action = new MoveAction(null);
var result = action.checkTarget(null, ship1, Target.newFromShip(ship1));
var result = action.checkTarget(ship1, Target.newFromShip(ship1));
expect(result).toBeNull();
result = action.checkTarget(null, ship1, Target.newFromShip(ship2));
result = action.checkTarget(ship1, Target.newFromShip(ship2));
expect(result).toBeNull();
});
@ -51,13 +51,15 @@ module TS.SpaceTac {
var action = new MoveAction(engine);
battle.playing_ship = ship;
var result = action.apply(battle, ship, Target.newFromLocation(10, 10));
spyOn(console, "warn").and.stub();
var result = action.apply(ship, Target.newFromLocation(10, 10));
expect(result).toBe(true);
expect(ship.arena_x).toBeCloseTo(3.535533, 0.00001);
expect(ship.arena_y).toBeCloseTo(3.535533, 0.00001);
expect(ship.values.power.get()).toEqual(0);
result = action.apply(battle, ship, Target.newFromLocation(10, 10));
result = action.apply(ship, Target.newFromLocation(10, 10));
expect(result).toBe(false);
expect(ship.arena_x).toBeCloseTo(3.535533, 0.00001);
expect(ship.arena_y).toBeCloseTo(3.535533, 0.00001);
@ -89,19 +91,19 @@ module TS.SpaceTac {
var action = new MoveAction(engine);
action.safety_distance = 2;
var result = action.checkLocationTarget(battle, ship, Target.newFromLocation(7, 5));
var result = action.checkLocationTarget(ship, Target.newFromLocation(7, 5));
expect(result).toEqual(Target.newFromLocation(7, 5));
result = action.checkLocationTarget(battle, ship, Target.newFromLocation(8, 5));
result = action.checkLocationTarget(ship, Target.newFromLocation(8, 5));
expect(result).toEqual(Target.newFromLocation(8, 5));
result = action.checkLocationTarget(battle, ship, Target.newFromLocation(9, 5));
result = action.checkLocationTarget(ship, Target.newFromLocation(9, 5));
expect(result).toEqual(Target.newFromLocation(8, 5));
result = action.checkLocationTarget(battle, ship, Target.newFromLocation(10, 5));
result = action.checkLocationTarget(ship, Target.newFromLocation(10, 5));
expect(result).toEqual(Target.newFromLocation(8, 5));
result = action.checkLocationTarget(battle, ship, Target.newFromLocation(12, 5));
result = action.checkLocationTarget(ship, Target.newFromLocation(12, 5));
expect(result).toEqual(Target.newFromLocation(12, 5));
});
});

View file

@ -11,19 +11,24 @@ module TS.SpaceTac {
this.safety_distance = 50;
}
canBeUsed(battle: Battle, ship: Ship, remaining_ap: number = null): boolean {
if (battle && battle.playing_ship !== ship) {
return false;
checkCannotBeApplied(ship: Ship, remaining_ap: number = 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();
}
return remaining_ap > 0.0001;
if (remaining_ap > 0.0001) {
return null
} else {
return "not enough power";
}
}
getActionPointsUsage(battle: Battle, ship: Ship, target: Target): number {
getActionPointsUsage(ship: Ship, target: Target): number {
if (target === null) {
return 0;
}
@ -43,23 +48,26 @@ module TS.SpaceTac {
return this.equipment.distance / this.equipment.ap_usage;
}
checkLocationTarget(battle: Battle, ship: Ship, target: Target): Target {
checkLocationTarget(ship: Ship, target: Target): Target {
// Apply maximal distance
var max_distance = this.getRangeRadius(ship);
target = target.constraintInRange(ship.arena_x, ship.arena_y, max_distance);
// Apply collision prevention
battle.play_order.forEach((iship: Ship) => {
if (iship !== ship) {
target = target.moveOutOfCircle(iship.arena_x, iship.arena_y, this.safety_distance,
ship.arena_x, ship.arena_y);
}
});
let battle = ship.getBattle();
if (battle) {
battle.play_order.forEach((iship: Ship) => {
if (iship !== ship) {
target = target.moveOutOfCircle(iship.arena_x, iship.arena_y, this.safety_distance,
ship.arena_x, ship.arena_y);
}
});
}
return target;
}
protected customApply(battle: Battle, ship: Ship, target: Target) {
protected customApply(ship: Ship, target: Target) {
ship.moveTo(target.x, target.y);
}
}

View file

@ -44,14 +44,15 @@ module TS.SpaceTac {
/**
* Update the result of a single battle
*/
update(winner: AbstractAI | null) {
if (winner) {
if (winner == this.ai1) {
update(winner: number) {
if (winner >= 0) {
if (winner == 0) {
this.win1 += 1;
console.log(` => Player 1 wins (${this.ai1})`);
} else {
this.win2 += 1;
console.log(` => Player 2 wins (${this.ai2})`);
}
console.log(` => ${winner.name} wins`);
} else {
this.draw += 1;
console.log(" => draw");
@ -86,9 +87,9 @@ module TS.SpaceTac {
}
if (battle.ended && !battle.outcome.draw) {
this.update(battle.outcome.winner == battle.fleets[0] ? this.ai1 : this.ai2);
this.update(battle.fleets.indexOf(battle.outcome.winner));
} else {
this.update(null);
this.update(-1);
}
if (!this.stopped) {
this.scheduled = Timer.global.schedule(100, () => this.next());

View file

@ -153,7 +153,7 @@ module TS.SpaceTac {
if (distance > safety_distance) { // Don't move too close
target = target.constraintInRange(this.ship.arena_x, this.ship.arena_y,
(distance - safety_distance) * APPROACH_FACTOR);
target = engine.action.checkLocationTarget(this.ship.getBattle(), this.ship, target);
target = engine.action.checkLocationTarget(this.ship, target);
return new BullyManeuver(new Maneuver(this.ship, engine, target));
} else {
return null;

View file

@ -32,8 +32,8 @@ module TS.SpaceTac {
apply(): void {
if (this.simulation.success) {
this.simulation.parts.forEach(part => {
if (!part.action.apply(this.ship.getBattle(), this.ship, part.target)) {
console.error("AI cannot apply maneuver", this);
if (!part.action.apply(this.ship, part.target)) {
console.error("AI cannot apply maneuver", this, part);
}
});
}

View file

@ -38,15 +38,15 @@ module TS.SpaceTac.Specs {
weapon.ap_usage = new Range(2);
var equipment = weapon.generateFixed(0);
expect(equipment.action.canBeUsed(null, ship)).toBe(true);
expect(equipment.action.checkCannotBeApplied(ship)).toBe(null);
weapon.ap_usage = new Range(3);
equipment = weapon.generateFixed(0);
expect(equipment.action.canBeUsed(null, ship)).toBe(true);
expect(equipment.action.checkCannotBeApplied(ship)).toBe(null);
weapon.ap_usage = new Range(4);
equipment = weapon.generateFixed(0);
expect(equipment.action.canBeUsed(null, ship)).toBe(false);
expect(equipment.action.checkCannotBeApplied(ship)).toBe("not enough power");
});
it("can't friendly fire", function () {
@ -60,9 +60,9 @@ module TS.SpaceTac.Specs {
weapon.setRange(10, 10);
var equipment = weapon.generateFixed(0);
expect(equipment.action.checkShipTarget(null, ship1a, Target.newFromShip(ship2a))).toEqual(
expect(equipment.action.checkShipTarget(ship1a, Target.newFromShip(ship2a))).toEqual(
Target.newFromShip(ship2a));
expect(equipment.action.checkShipTarget(null, ship1a, Target.newFromShip(ship1b))).toBeNull();
expect(equipment.action.checkShipTarget(ship1a, Target.newFromShip(ship1b))).toBeNull();
});
it("can't fire farther than its range", function () {
@ -78,25 +78,25 @@ module TS.SpaceTac.Specs {
var equipment = weapon.generateFixed(0);
expect(equipment.distance).toEqual(10);
expect(equipment.action.checkLocationTarget(null, ship, Target.newFromLocation(15, 10))).toEqual(
expect(equipment.action.checkLocationTarget(ship, Target.newFromLocation(15, 10))).toEqual(
Target.newFromLocation(15, 10));
expect(equipment.action.checkLocationTarget(null, ship, Target.newFromLocation(30, 10))).toEqual(
expect(equipment.action.checkLocationTarget(ship, Target.newFromLocation(30, 10))).toEqual(
Target.newFromLocation(20, 10));
// Ship targetting
var ship2 = new Ship(fleet2);
ship2.setArenaPosition(10, 15);
expect(equipment.action.checkShipTarget(null, ship, Target.newFromShip(ship2))).toEqual(
expect(equipment.action.checkShipTarget(ship, Target.newFromShip(ship2))).toEqual(
Target.newFromShip(ship2));
ship2.setArenaPosition(10, 25);
expect(equipment.action.checkShipTarget(null, ship, Target.newFromShip(ship2))).toBeNull();
expect(equipment.action.checkShipTarget(ship, Target.newFromShip(ship2))).toBeNull();
// Forbid targetting in space
weapon.setRange(10, 10, false);
equipment = weapon.generateFixed(0);
expect(equipment.action.checkLocationTarget(null, ship, Target.newFromLocation(15, 10))).toBeNull();
expect(equipment.action.checkLocationTarget(ship, Target.newFromLocation(15, 10))).toBeNull();
});
it("can target an enemy ship and damage it", function () {
@ -119,17 +119,17 @@ module TS.SpaceTac.Specs {
var equipment = weapon.generateFixed(0);
equipment.action.apply(null, ship1, Target.newFromShip(ship2));
equipment.action.apply(ship1, Target.newFromShip(ship2));
expect(ship2.values.hull.get()).toEqual(100);
expect(ship2.values.shield.get()).toEqual(10);
expect(ship1.values.power.get()).toEqual(49);
equipment.action.apply(null, ship1, Target.newFromShip(ship2));
equipment.action.apply(ship1, Target.newFromShip(ship2));
expect(ship2.values.hull.get()).toEqual(90);
expect(ship2.values.shield.get()).toEqual(0);
expect(ship1.values.power.get()).toEqual(48);
equipment.action.apply(null, ship1, Target.newFromShip(ship2));
equipment.action.apply(ship1, Target.newFromShip(ship2));
expect(ship2.values.hull.get()).toEqual(70);
expect(ship2.values.shield.get()).toEqual(0);
expect(ship1.values.power.get()).toEqual(47);

View file

@ -13,7 +13,7 @@ module TS.SpaceTac.Specs {
expect(target.sticky_effects).toEqual([]);
// Attribute is immediately limited
equipment.action.apply(null, ship, Target.newFromShip(target));
equipment.action.apply(ship, Target.newFromShip(target));
expect(target.values.power.get()).toBe(4);
expect(target.sticky_effects).toEqual([

View file

@ -7,10 +7,10 @@ module TS.SpaceTac.Equipments {
expect(equipment.target_effects).toEqual([new ValueEffect("hull", 30)]);
let battle = new Battle();
let ship = new Ship();
let ship = battle.fleets[0].addShip();
battle.playing_ship = ship;
TestTools.setShipAP(ship, 10);
let result = equipment.action.apply(battle, ship, new Target(5, 5, null));
let result = equipment.action.apply(ship, new Target(5, 5, null));
expect(result).toBe(true);
expect(battle.drones.length).toBe(1);

View file

@ -34,12 +34,12 @@ module TS.SpaceTac.Specs {
battle.log.addFilter("value");
// Fire at a ship
var t = Target.newFromShip(enemy1);
expect(equipment.action.canBeUsed(battle, ship)).toBe(true);
equipment.action.apply(battle, ship, t);
var target = Target.newFromShip(enemy1);
expect(equipment.action.checkCannotBeApplied(ship)).toBe(null);
equipment.action.apply(ship, target);
checkHP(50, 10, 50, 10, 50, 10);
expect(battle.log.events.length).toBe(4);
expect(battle.log.events[0]).toEqual(new FireEvent(ship, equipment, t));
expect(battle.log.events[0]).toEqual(new FireEvent(ship, equipment, target));
expect(battle.log.events[1]).toEqual(new DamageEvent(ship, 0, 20));
expect(battle.log.events[2]).toEqual(new DamageEvent(enemy1, 0, 20));
expect(battle.log.events[3]).toEqual(new DamageEvent(enemy2, 0, 20));
@ -47,24 +47,24 @@ module TS.SpaceTac.Specs {
battle.log.clear();
// Fire in space
t = Target.newFromLocation(2.4, 0);
expect(equipment.action.canBeUsed(battle, ship)).toBe(true);
equipment.action.apply(battle, ship, t);
target = Target.newFromLocation(2.4, 0);
expect(equipment.action.checkCannotBeApplied(ship)).toBe(null);
equipment.action.apply(ship, target);
checkHP(50, 10, 40, 0, 40, 0);
expect(battle.log.events.length).toBe(3);
expect(battle.log.events[0]).toEqual(new FireEvent(ship, equipment, t));
expect(battle.log.events[0]).toEqual(new FireEvent(ship, equipment, target));
expect(battle.log.events[1]).toEqual(new DamageEvent(enemy1, 10, 10));
expect(battle.log.events[2]).toEqual(new DamageEvent(enemy2, 10, 10));
battle.log.clear();
// Fire far away
t = Target.newFromLocation(5, 0);
expect(equipment.action.canBeUsed(battle, ship)).toBe(true);
equipment.action.apply(battle, ship, t);
target = Target.newFromLocation(5, 0);
expect(equipment.action.checkCannotBeApplied(ship)).toBe(null);
equipment.action.apply(ship, target);
checkHP(50, 10, 40, 0, 40, 0);
expect(battle.log.events.length).toBe(1);
expect(battle.log.events[0]).toEqual(new FireEvent(ship, equipment, t));
expect(battle.log.events[0]).toEqual(new FireEvent(ship, equipment, target));
});
});
}

View file

@ -88,7 +88,7 @@ module TS.SpaceTac.UI {
if (!this.bar.interactive) {
return;
}
if (!this.action.canBeUsed(this.battleview.battle, this.ship)) {
if (this.action.checkCannotBeApplied(this.ship)) {
return;
}
if (this.selected) {
@ -104,7 +104,7 @@ module TS.SpaceTac.UI {
this.battleview.arena.range_hint.setPrimary(this.ship, this.action);
// Update fading statuses
this.bar.updateSelectedActionPower(this.action.getActionPointsUsage(this.battleview.battle, this.ship, null));
this.bar.updateSelectedActionPower(this.action.getActionPointsUsage(this.ship, null));
// Set the selected state
this.setSelected(true);
@ -127,14 +127,14 @@ module TS.SpaceTac.UI {
// Called when a target is hovered
// This will check the target against current action and adjust it if needed
processHover(target: Target): void {
target = this.action.checkTarget(this.battleview.battle, this.ship, target);
target = this.action.checkTarget(this.ship, target);
this.targetting.setTarget(target, false, this.action.getBlastRadius(this.ship));
this.bar.updateSelectedActionPower(this.action.getActionPointsUsage(this.battleview.battle, this.ship, target));
this.bar.updateSelectedActionPower(this.action.getActionPointsUsage(this.ship, target));
}
// Called when a target is selected
processSelection(target: Target): void {
if (this.action.apply(this.battleview.battle, this.ship, target)) {
if (this.action.apply(this.ship, target)) {
this.bar.actionEnded();
}
}
@ -159,7 +159,7 @@ module TS.SpaceTac.UI {
// Update the active status, from the action canBeUsed result
updateActiveStatus(force = false): void {
var old_active = this.active;
this.active = this.action.canBeUsed(this.battleview.battle, this.ship);
this.active = !this.action.checkCannotBeApplied(this.ship);
if (force || (this.active != old_active)) {
Animation.setVisibility(this.game, this.layer_active, this.active, 500);
this.game.tweens.create(this.layer_icon).to({ alpha: this.active ? 1 : 0.3 }, 500).start();
@ -170,7 +170,7 @@ module TS.SpaceTac.UI {
// Update the fading status, given an hypothetical remaining AP
updateFadingStatus(remaining_ap: number): void {
var old_fading = this.fading;
this.fading = this.active && !this.action.canBeUsed(this.battleview.battle, this.ship, remaining_ap);
this.fading = this.active && (this.action.checkCannotBeApplied(this.ship, remaining_ap) != null);
if (this.fading != old_fading) {
Animation.setVisibility(this.game, this.layer_active, this.active && !this.fading, 500);
}