1
0
Fork 0

Restored drones feature

This commit is contained in:
Michaël Lemaire 2017-11-29 23:03:58 +01:00
parent 1e681d6df3
commit 05a0607445
45 changed files with 422 additions and 376 deletions

View file

@ -37,7 +37,6 @@ Character sheet
Battle
------
* Fix drone effects not applying, and drone never disappearing (Repair Drone)
* Fix arena's ship hovering happening even when the character sheet (or a dialog) is open on top
* Add a voluntary retreat option
* Add scroll buttons when there are too many actions
@ -49,7 +48,6 @@ Battle
* Find incentives to move from starting position (permanent drones or anomalies?)
* Add a "loot all" button (on the character sheet or outcome dialog?)
* Mark targetting in error when target is refused by the action (there is already an arrow for this)
* Repair drone has its activation effect sometimes displayed as permanent effect on ships in the radius
* Allow to undo last moves
* Add a battle log display
* Allow to move targetting indicator with arrow keys
@ -76,7 +74,6 @@ Ships models and equipments
* RepelEffect should apply on ships in a good order (distance decreasing)
* Add hull points to drones and make them take area damage
* Quality modifiers should be based on an "quality difference" to reach
* Drones effects should be classified: permanent effects apply permanently, ponctual effects may be applied by an owner's action (if in range)
Artificial Intelligence
-----------------------

View file

@ -133,7 +133,7 @@ module TK.SpaceTac {
ship.active_effects.list().forEach(effect => {
if (!(effect instanceof StickyEffect) && !expected.get(effect.id)) {
result.push(new ShipEffectRemovedDiff(ship, effect));
result = result.concat(effect.getOffDiffs(ship, ship));
result = result.concat(effect.getOffDiffs(ship));
}
});
@ -141,7 +141,7 @@ module TK.SpaceTac {
expected.list().forEach(effect => {
if (!ship.active_effects.get(effect.id)) {
result.push(new ShipEffectAddedDiff(ship, effect));
result = result.concat(effect.getOnDiffs(ship, ship));
result = result.concat(effect.getOnDiffs(ship, ship)); // TODO correct source
}
});
});

View file

@ -1,132 +1,64 @@
/// <reference path="effects/BaseEffect.ts" />
module TK.SpaceTac {
/**
* Fake effect to capture apply requests
*/
class FakeEffect extends BaseEffect {
applied: Ship[] = []
constructor() {
super("fake");
}
getOnDiffs(ship: Ship, source: Ship | Drone): BaseBattleDiff[] {
this.applied.push(ship);
return [];
}
getApplyCalls() {
let result = acopy(this.applied);
this.applied = [];
return result;
}
}
function newTestDrone(x: number, y: number, radius: number, owner: Ship): [Drone, FakeEffect] {
let drone = new Drone(owner);
drone.x = x;
drone.y = y;
drone.radius = radius;
let effect = new FakeEffect();
drone.effects.push(effect);
let battle = owner.getBattle();
if (battle) {
battle.addDrone(drone);
}
return [drone, effect];
}
testing("Drone", test => {
test.case("applies effects on all ships inside the radius", check => {
let battle = new Battle();
let ship1 = new Ship(battle.fleets[0], "ship1");
ship1.setArenaPosition(0, 0);
let ship2 = new Ship(battle.fleets[0], "ship2");
ship2.setArenaPosition(5, 5);
let ship3 = new Ship(battle.fleets[0], "ship3");
ship3.setArenaPosition(10, 10);
let ship4 = new Ship(battle.fleets[0], "ship4");
ship4.setArenaPosition(0, 0);
ship4.setDead();
let [drone, effect] = newTestDrone(2, 2, 8, ship1);
test.case("applies area effects when deployed", check => {
let battle = TestTools.createBattle();
let ship = nn(battle.playing_ship);
TestTools.setShipAP(ship, 10);
let weapon = TestTools.addWeapon(ship);
weapon.action = new DeployDroneAction(weapon, 2, 300, 30, [new AttributeEffect("precision", 15)]);
let engine = TestTools.addEngine(ship, 1000);
check.equals(effect.getApplyCalls(), []);
drone.activate(battle);
check.equals(effect.getApplyCalls(), [ship1, ship2]);
});
test.case("signals the need for destruction after its lifetime", check => {
let battle = new Battle();
let owner = new Ship(battle.fleets[0]);
let [drone, effect] = newTestDrone(0, 0, 5, owner);
drone.duration = 3;
let removeDrone = check.patch(battle, "removeDrone", null);
drone.activate(battle);
check.equals(drone.duration, 2);
check.called(removeDrone, 0);
drone.activate(battle);
check.equals(drone.duration, 1);
check.called(removeDrone, 0);
drone.activate(battle);
check.equals(drone.duration, 0);
check.called(removeDrone, [[drone]]);
});
test.case("builds diffs on activation", check => {
let battle = new Battle();
let ship = new Ship();
ship.fleet.setBattle(battle);
let other = new Ship();
let drone = new Drone(ship);
drone.duration = 2;
check.in("duration=2", check => {
check.equals(drone.getDiffs(battle, [ship, other]), [
new DroneAppliedDiff(drone, [ship, other]),
], "two ships in range");
check.equals(drone.getDiffs(battle, []), [
], "no ship in range");
});
drone.duration = 1;
check.in("duration=1", check => {
check.equals(drone.getDiffs(battle, [ship, other]), [
new DroneAppliedDiff(drone, [ship, other]),
new DroneDestroyedDiff(drone),
], "two ships in range");
check.equals(drone.getDiffs(battle, []), [
new DroneDestroyedDiff(drone),
], "no ship in range");
});
drone.duration = 0;
check.in("duration=0", check => {
check.equals(drone.getDiffs(battle, [ship, other]), [
new DroneDestroyedDiff(drone),
], "two ships in range");
check.equals(drone.getDiffs(battle, []), [
new DroneDestroyedDiff(drone),
], "no ship in range");
});
TestTools.actionChain(check, battle, [
[ship, nn(weapon.action), Target.newFromLocation(150, 50)], // deploy out of effects radius
[ship, nn(engine.action), Target.newFromLocation(110, 50)], // move out of effects radius
[ship, nn(engine.action), Target.newFromLocation(130, 50)], // move in effects radius
[ship, nn(weapon.action), Target.newFromShip(ship)], // recall
[ship, nn(weapon.action), Target.newFromLocation(130, 70)], // deploy in effects radius
], [
check => {
check.equals(ship.active_effects.count(), 0, "active effects");
check.equals(ship.getValue("power"), 10, "power");
check.equals(battle.drones.count(), 0, "drone count");
},
check => {
check.equals(ship.active_effects.count(), 0, "active effects");
check.equals(ship.getValue("power"), 8, "power");
check.equals(battle.drones.count(), 1, "drone count");
},
check => {
check.equals(ship.active_effects.count(), 0, "active effects");
check.equals(ship.getValue("power"), 7, "power");
check.equals(battle.drones.count(), 1, "drone count");
},
check => {
check.equals(ship.active_effects.count(), 1, "active effects");
check.equals(ship.getValue("power"), 6, "power");
check.equals(battle.drones.count(), 1, "drone count");
},
check => {
check.equals(ship.active_effects.count(), 0, "active effects");
check.equals(ship.getValue("power"), 8, "power");
check.equals(battle.drones.count(), 0, "drone count");
},
check => {
check.equals(ship.active_effects.count(), 1, "active effects");
check.equals(ship.getValue("power"), 6, "power");
check.equals(battle.drones.count(), 1, "drone count");
},
]);
});
test.case("builds a textual description", check => {
let drone = new Drone(new Ship());
drone.duration = 1;
check.equals(drone.getDescription(), "For 1 activation:\n• do nothing");
check.equals(drone.getDescription(), "While deployed:\n• do nothing");
drone.duration = 3;
drone.effects = [
new DamageEffect(5),
new AttributeEffect("skill_quantum", 1)
]
check.equals(drone.getDescription(), "For 3 activations:\n• do 5 damage\n• quantum skill +1");
check.equals(drone.getDescription(), "While deployed:\n• do 5 damage\n• quantum skill +1");
});
});
}

View file

@ -14,18 +14,17 @@ module TK.SpaceTac {
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) {
// Action that triggered that drone
parent: DeployDroneAction | null = null;
constructor(owner: Ship, code = "drone") {
super();
this.owner = owner.id;
this.code = code;
this.duration = base_duration;
}
/**
@ -43,7 +42,7 @@ module TK.SpaceTac {
if (effects.length == 0) {
effects = "• do nothing";
}
return `For ${this.duration} activation${this.duration > 1 ? "s" : ""}:\n${effects}`;
return `While deployed:\n${effects}`;
}
/**
@ -60,36 +59,5 @@ module TK.SpaceTac {
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);
}
}
}

View file

@ -40,7 +40,12 @@ module TK.SpaceTac {
}
function effectFactor(effect: BaseEffect) {
if (effect instanceof ValueEffect || effect instanceof AttributeEffect) {
if (effect instanceof ValueEffect) {
simpleFactor(effect, 'value_on');
simpleFactor(effect, 'value_off');
simpleFactor(effect, 'value_start');
simpleFactor(effect, 'value_end');
} else if (effect instanceof AttributeEffect || effect instanceof AttributeMultiplyEffect) {
simpleFactor(effect, 'value');
} else if (effect instanceof AttributeLimitEffect) {
simpleFactor(effect, 'value', true);
@ -79,8 +84,8 @@ module TK.SpaceTac {
if (equipment.action instanceof DeployDroneAction) {
simpleFactor(equipment.action, 'deploy_distance');
simpleFactor(equipment.action, 'effect_radius');
equipment.action.effects.forEach(effectFactor);
simpleFactor(equipment.action, 'drone_radius');
equipment.action.drone_effects.forEach(effectFactor);
}
if (equipment.action instanceof MoveAction) {

View file

@ -55,12 +55,13 @@ module TK.SpaceTac.Specs {
compare_effects(check, action1.effects, action2.effects);
}
}
export function compare_drone_action(check: TestContext, action1: BaseAction | null, action2: DeployDroneAction | null): void {
if (action1 === null || action2 === null || !(action1 instanceof DeployDroneAction)) {
check.equals(action1, action2, "action");
} else {
check.equals(strip_id(strip(action1, "effects")), strip_id(strip(action2, "effects")), "action");
compare_effects(check, action1.effects, action2.effects);
check.equals(strip_id(strip(action1, "drone_effects")), strip_id(strip(action2, "drone_effects")), "action");
compare_effects(check, action1.drone_effects, action2.drone_effects);
}
}
@ -163,15 +164,15 @@ module TK.SpaceTac.Specs {
test.case("adds drone actions", check => {
let template = new LootTemplate(SlotType.Weapon, "Weapon");
template.addDroneAction(istep(1), istep(100), istep(2), istep(50), [
template.addDroneAction(istep(1), istep(100), istep(50), [
new EffectTemplate(new FakeEffect(3), { "fakevalue": istep(8) })
]);
let result = template.generate(1);
compare_drone_action(check, result.action, new DeployDroneAction(result, 1, 100, 2, 50, [new FakeEffect(8)]));
compare_drone_action(check, result.action, new DeployDroneAction(result, 1, 100, 50, [new FakeEffect(8)]));
result = template.generate(2);
compare_drone_action(check, result.action, new DeployDroneAction(result, 2, 101, 3, 51, [new FakeEffect(9)]));
compare_drone_action(check, result.action, new DeployDroneAction(result, 2, 101, 51, [new FakeEffect(9)]));
});
test.case("checks the presence of damaging effects", check => {

View file

@ -3,6 +3,7 @@ module TK.SpaceTac {
* A leveled value is an iterator yielding the desired value for each level (first item is for level 1, and so on)
*/
type LeveledValue = Iterator<number>;
type LeveledModifiers<T extends BaseEffect> = {[P in keyof T]?: LeveledValue }
/**
* Modifiers of generated equipment
@ -35,12 +36,12 @@ module TK.SpaceTac {
// Effect value modifiers
modifiers: [keyof T, LeveledValue][];
constructor(effect: T, modifiers: { [attr: string]: LeveledValue }) {
constructor(effect: T, modifiers: LeveledModifiers<T>) {
this.effect = effect;
this.modifiers = [];
iteritems(modifiers, (key, value) => {
if (effect.hasOwnProperty(key)) {
if (effect.hasOwnProperty(key) && value) {
this.addModifier(<keyof T>key, value);
}
});
@ -56,7 +57,7 @@ module TK.SpaceTac {
let result = copy(this.effect);
this.modifiers.forEach(modifier => {
let [name, value] = modifier;
(<any>result)[name] = resolveForLevel(value, level);
result[name] = resolveForLevel(value, level);
});
return result;
}
@ -215,10 +216,10 @@ module TK.SpaceTac {
/**
* Add a deploy drone action.
*/
addDroneAction(power: LeveledValue, range: LeveledValue, lifetime: LeveledValue, radius: LeveledValue, effects: EffectTemplate<any>[]): void {
addDroneAction(power: LeveledValue, range: LeveledValue, radius: LeveledValue, effects: EffectTemplate<any>[]): void {
this.base_modifiers.push((equipment, level) => {
let reffects = effects.map(effect => effect.generate(level));
equipment.action = new DeployDroneAction(equipment, resolveForLevel(power, level), resolveForLevel(range, level), resolveForLevel(lifetime, level), resolveForLevel(radius, level), reffects);
equipment.action = new DeployDroneAction(equipment, resolveForLevel(power, level), resolveForLevel(range, level), resolveForLevel(radius, level), reffects);
});
}

View file

@ -50,7 +50,7 @@ module TK.SpaceTac {
*/
static addWeapon(ship: Ship, damage = 100, power_usage = 1, max_distance = 100, blast = 0, angle = 0): Equipment {
var equipment = ship.addSlot(SlotType.Weapon).attach(new Equipment(SlotType.Weapon));
equipment.action = new TriggerAction(equipment, [new DamageEffect(damage)], power_usage, max_distance, blast, angle, "Test Weapon");
equipment.action = new TriggerAction(equipment, [new DamageEffect(damage)], power_usage, max_distance, blast, angle);
return equipment;
}

View file

@ -2,7 +2,7 @@ module TK.SpaceTac.Specs {
testing("BaseAction", test => {
test.case("check if equipment can be used with remaining AP", check => {
var equipment = new Equipment(SlotType.Hull);
var action = new BaseAction("test", "Test", equipment);
var action = new BaseAction("test", equipment);
check.patch(action, "getActionPointsUsage", () => 3);
var ship = new Ship();
ship.addSlot(SlotType.Hull).attach(equipment);
@ -27,7 +27,7 @@ module TK.SpaceTac.Specs {
test.case("check if equipment can be used with overheat", check => {
let equipment = new Equipment();
let action = new BaseAction("test", "Test", equipment);
let action = new BaseAction("test", equipment);
let ship = new Ship();
check.equals(action.checkCannotBeApplied(ship), null);
@ -71,7 +71,7 @@ module TK.SpaceTac.Specs {
TestTools.setShipAP(ship, 10);
let power = ship.listEquipment(SlotType.Power)[0];
let equipment = new Equipment(SlotType.Weapon);
let action = new BaseAction("test", "Test", equipment);
let action = new BaseAction("test", equipment);
equipment.action = action;
ship.addSlot(SlotType.Weapon).attach(equipment);

View file

@ -26,21 +26,24 @@ module TK.SpaceTac {
// Identifier code for the type of action
code: string
// Human-readable name
name: string
// Equipment that triggers this action
equipment: Equipment | null
// Create the action
constructor(code = "nothing", name = "Idle", equipment: Equipment | null = null) {
constructor(code = "nothing", equipment: Equipment | null = null) {
super();
this.code = code;
this.name = name;
this.equipment = equipment;
}
/**
* Get the verb for this action
*/
getVerb(): string {
return "Idle";
}
/**
* Get the relevent cooldown for this action
*/

View file

@ -5,7 +5,7 @@ module TK.SpaceTac.Specs {
let action = new DeployDroneAction(equipment);
check.equals(action.code, "deploy-testdrone");
check.equals(action.name, "Deploy");
check.equals(action.getVerb(), "Deploy");
check.same(action.equipment, equipment);
});
@ -29,7 +29,7 @@ module TK.SpaceTac.Specs {
TestTools.setShipAP(ship, 3);
let equipment = new Equipment(SlotType.Weapon, "testdrone");
let action = new DeployDroneAction(equipment, 2, 8, 2, 4, [new DamageEffect(50)]);
let action = new DeployDroneAction(equipment, 2, 8, 4, [new DamageEffect(50)]);
equipment.action = action;
ship.addSlot(SlotType.Weapon).attach(equipment);
@ -46,7 +46,6 @@ module TK.SpaceTac.Specs {
let drone = battle.drones.list()[0];
check.equals(drone.code, "testdrone");
check.equals(drone.duration, 2);
check.same(drone.owner, ship.id);
check.equals(drone.x, 5);
check.equals(drone.y, 0);

View file

@ -1,74 +1,78 @@
/// <reference path="BaseAction.ts"/>
/// <reference path="ToggleAction.ts"/>
module TK.SpaceTac {
/**
* Action to deploy a drone in space
*
* This is a toggled action, meaning that deploying a drone requires a permanent power supply from the ship
*/
export class DeployDroneAction extends BaseAction {
// Power usage
power: number;
export class DeployDroneAction extends ToggleAction {
// Maximal distance the drone may be deployed
deploy_distance: number;
deploy_distance: number
// Effect radius of the deployed drone
effect_radius: number;
// Duration of the drone in turns, before being destroyed
lifetime: number;
drone_radius: number
// Effects applied to ships in range of the drone
effects: BaseEffect[];
drone_effects: BaseEffect[]
// Source equipment
equipment: Equipment;
constructor(equipment: Equipment, power = 1, deploy_distance = 0, radius = 0, effects: BaseEffect[] = []) {
super(equipment, power, 0, [], `deploy-${equipment.code}`);
constructor(equipment: Equipment, power = 1, deploy_distance = 0, lifetime = 0, effect_radius = 0, effects: BaseEffect[] = []) {
super("deploy-" + equipment.code, "Deploy", equipment);
this.power = power;
this.deploy_distance = deploy_distance;
this.lifetime = lifetime;
this.effect_radius = effect_radius;
this.effects = effects;
this.drone_radius = radius;
this.drone_effects = effects;
}
getVerb(): string {
return this.activated ? "Recall" : "Deploy";
}
getTargettingMode(ship: Ship): ActionTargettingMode {
return ActionTargettingMode.SPACE;
}
getActionPointsUsage(ship: Ship, target: Target | null): number {
return this.power;
return this.activated ? ActionTargettingMode.SELF : ActionTargettingMode.SPACE;
}
getRangeRadius(ship: Ship): number {
return this.deploy_distance;
return this.activated ? 0 : this.deploy_distance;
}
filterImpactedShips(source: ArenaLocation, target: Target, ships: Ship[]): Ship[] {
return ships.filter(ship => arenaDistance(ship.location, target) <= this.effect_radius);
return ships.filter(ship => arenaDistance(ship.location, target) <= this.drone_radius);
}
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.deploy_distance);
return target;
}
protected getSpecificDiffs(ship: Ship, battle: Battle, target: Target): BaseBattleDiff[] {
let drone = new Drone(ship, this.equipment.code, this.lifetime);
drone.x = target.x;
drone.y = target.y;
drone.radius = this.effect_radius;
drone.effects = this.effects;
let result = super.getSpecificDiffs(ship, battle, target);
return [new DroneDeployedDiff(drone)];
if (this.activated) {
let drone = first(battle.drones.list(), drone => drone.parent == this);
if (drone) {
result.push(new DroneRecalledDiff(drone));
} else {
return [];
}
} else {
let drone = new Drone(ship, this.equipment.code);
drone.parent = this;
drone.x = target.x;
drone.y = target.y;
drone.radius = this.drone_radius;
drone.effects = this.drone_effects;
result.push(new DroneDeployedDiff(drone));
}
return result;
}
getEffectsDescription(): string {
let desc = `Deploy drone for ${this.lifetime} activation${this.lifetime > 1 ? "s" : ""} (power usage ${this.power}, max range ${this.deploy_distance}km)`;
let effects = this.effects.map(effect => {
let suffix = `for ships in ${this.effect_radius}km radius`;
let desc = `Deploy drone (power usage ${this.power}, max range ${this.deploy_distance}km)`;
let effects = this.drone_effects.map(effect => {
let suffix = `for ships in ${this.drone_radius}km radius`;
return "• " + effect.getDescription() + " " + suffix;
});
return `${desc}:\n${effects.join("\n")}`;

View file

@ -11,7 +11,11 @@ module TK.SpaceTac {
static SINGLETON = new EndTurnAction();
constructor() {
super("endturn", "End ship's turn");
super("endturn");
}
getVerb(): string {
return "End ship's turn";
}
protected getSpecificDiffs(ship: Ship, battle: Battle, target: Target): BaseBattleDiff[] {
@ -29,21 +33,20 @@ module TK.SpaceTac {
result.push(new ShipCooldownDiff(ship, equ, 1));
});
// Fade sticky effects
// "On turn end" effects
iforeach(ship.active_effects.iterator(), effect => {
if (effect instanceof StickyEffect) {
if (effect.duration > 1) {
result.push(new ShipEffectChangedDiff(ship, effect, -1));
} else {
result = result.concat(effect.getOffDiffs(ship, ship));
}
}
result = result.concat(effect.getTurnEndDiffs(ship));
});
// Change the active ship
let cycle_diff = (battle.play_order.indexOf(new_ship) == 0) ? 1 : 0;
result.push(new ShipChangeDiff(ship, new_ship, cycle_diff));
// "On turn start" effects
iforeach(new_ship.active_effects.iterator(), effect => {
result = result.concat(effect.getTurnStartDiffs(ship));
});
return result;
} else {
return [];

View file

@ -16,13 +16,17 @@ module TK.SpaceTac {
maneuvrability_factor: number
constructor(equipment: Equipment, distance_per_power = 0, safety_distance = 120, maneuvrability_factor = 0) {
super("move", "Move", equipment);
super("move", equipment);
this.distance_per_power = distance_per_power;
this.safety_distance = safety_distance;
this.maneuvrability_factor = maneuvrability_factor;
}
getVerb(): string {
return "Move";
}
getTargettingMode(ship: Ship): ActionTargettingMode {
return ActionTargettingMode.SPACE;
}

View file

@ -22,14 +22,18 @@ module TK.SpaceTac {
// Current activation status
activated = false
constructor(equipment: Equipment, power = 1, radius = 0, effects: BaseEffect[] = [], name = "(De)activate") {
super("toggle-" + equipment.code, name, equipment);
constructor(equipment: Equipment, power = 1, radius = 0, effects: BaseEffect[] = [], code = `toggle-${equipment.code}`) {
super(code, equipment);
this.power = power;
this.radius = radius;
this.effects = effects;
}
getVerb(): string {
return this.activated ? "Deactivate" : "Activate";
}
getTargettingMode(ship: Ship): ActionTargettingMode {
if (this.activated || !this.radius) {
return ActionTargettingMode.SELF_CONFIRM;
@ -64,7 +68,7 @@ module TK.SpaceTac {
this.effects.forEach(effect => {
if (this.activated) {
result.push(new ShipEffectRemovedDiff(iship, effect));
result = result.concat(effect.getOffDiffs(iship, ship));
result = result.concat(effect.getOffDiffs(iship));
} else {
result.push(new ShipEffectAddedDiff(iship, effect));
result = result.concat(effect.getOnDiffs(iship, ship));

View file

@ -5,7 +5,7 @@ module TK.SpaceTac.Specs {
let action = new TriggerAction(equipment, [], 4, 30, 10);
check.equals(action.code, "fire-testweapon");
check.equals(action.name, "Fire");
check.equals(action.getVerb(), "Fire");
check.same(action.equipment, equipment);
})

View file

@ -25,8 +25,8 @@ module TK.SpaceTac {
// Equipment cannot be null
equipment: Equipment
constructor(equipment: Equipment, effects: BaseEffect[] = [], power = 1, range = 0, blast = 0, angle = 0, name = range ? "Fire" : "Trigger") {
super("fire-" + equipment.code, name, equipment);
constructor(equipment: Equipment, effects: BaseEffect[] = [], power = 1, range = 0, blast = 0, angle = 0, code = `fire-${equipment.code}`) {
super(code, equipment);
this.power = power;
this.range = range;
@ -35,6 +35,10 @@ module TK.SpaceTac {
this.angle = angle;
}
getVerb(): string {
return this.range ? "Fire" : "Trigger";
}
getDefaultTarget(ship: Ship): Target {
if (this.range == 0) {
return Target.newFromShip(ship);
@ -175,7 +179,7 @@ module TK.SpaceTac {
info.push(`max range ${this.range}km`);
}
let desc = `${this.name} (${info.join(", ")})`;
let desc = `${this.getVerb()} (${info.join(", ")})`;
let effects = this.effects.map(effect => {
let suffix: string;
if (this.blast) {

View file

@ -32,7 +32,7 @@ module TK.SpaceTac.Specs {
let ship2 = battle.fleets[0].addShip();
let ship3 = battle.fleets[1].addShip();
let weapon = ship1.addSlot(SlotType.Weapon).attach(new Equipment(SlotType.Weapon));
weapon.action = new DeployDroneAction(weapon, 0, 100, 1, 10, [new ValueEffect("shield", 10)]);
weapon.action = new DeployDroneAction(weapon, 0, 100, 10, [new ValueEffect("shield", 10)]);
ship1.setArenaPosition(0, 0);
TestTools.setShipHP(ship1, 20, 20);
ship2.setArenaPosition(0, 5);

View file

@ -81,8 +81,8 @@ module TK.SpaceTac {
if (this.action instanceof TriggerAction) {
result = result.concat(this.action.getEffects(this.ship, this.target));
} else if (this.action instanceof DeployDroneAction) {
let ships = this.battle.collectShipsInCircle(this.target, this.action.effect_radius, true);
this.action.effects.forEach(effect => {
let ships = this.battle.collectShipsInCircle(this.target, this.action.drone_radius, true);
this.action.drone_effects.forEach(effect => {
result = result.concat(ships.map(ship => <[Ship, BaseEffect]>[ship, effect]));
});
}

View file

@ -7,7 +7,7 @@ module TK.SpaceTac.Specs {
constructor(score: number) {
let battle = new Battle();
let ship = battle.fleets[0].addShip();
super(ship, new BaseAction("nothing", "Do nothing"), new Target(0, 0));
super(ship, new BaseAction("nothing"), new Target(0, 0));
this.score = score;
}
}

View file

@ -89,7 +89,7 @@ module TK.SpaceTac.Specs {
let action = nn(weapon.action);
let engine = TestTools.addEngine(ship, 25);
let maneuver = new Maneuver(ship, new BaseAction("fake", "Nothing"), new Target(0, 0), 0);
let maneuver = new Maneuver(ship, new BaseAction("fake"), new Target(0, 0), 0);
check.same(TacticalAIHelpers.evaluateTurnCost(ship, battle, maneuver), -1);
maneuver = new Maneuver(ship, action, Target.newFromLocation(100, 0), 0);

View file

@ -37,9 +37,9 @@ module TK.SpaceTac {
dshield -= ds;
} else if (effect instanceof ValueEffect) {
if (effect.valuetype == "hull") {
dhull = clamp(hull + effect.value, 0, chull) - hull;
dhull = clamp(hull + effect.value_on, 0, chull) - hull;
} else if (effect.valuetype == "shield") {
dshield += clamp(shield + effect.value, 0, cshield) - shield;
dshield += clamp(shield + effect.value_on, 0, cshield) - shield;
}
}
}

View file

@ -1,39 +0,0 @@
/// <reference path="BaseBattleDiff.ts"/>
module TK.SpaceTac {
/**
* A drone applies its effect on ships around
*/
export class DroneAppliedDiff extends BaseBattleDiff {
// ID of the drone
drone: RObjectId
// IDs of impacted ships
ships: RObjectId[]
constructor(drone: Drone, ships: Ship[]) {
super();
this.drone = drone.id;
this.ships = ships.map(ship => ship.id);
}
apply(battle: Battle): void {
let drone = battle.drones.get(this.drone);
if (drone) {
drone.duration -= 1;
} else {
console.error("Cannot apply diff - Drone not found", this);
}
}
revert(battle: Battle): void {
let drone = battle.drones.get(this.drone);
if (drone) {
drone.duration += 1;
} else {
console.error("Cannot revert diff - Drone not found", this);
}
}
}
}

View file

@ -3,41 +3,25 @@ module TK.SpaceTac.Specs {
test.case("applies and reverts", check => {
let battle = TestTools.createBattle();
let drone1 = new Drone(battle.play_order[0]);
let drone2 = new Drone(battle.play_order[0], "test", 2);
let drone2 = new Drone(battle.play_order[0], "test");
TestTools.diffChain(check, battle, [
new DroneDeployedDiff(drone1, 3),
new DroneDeployedDiff(drone1),
new DroneDeployedDiff(drone2),
new DroneAppliedDiff(drone1, []),
new DroneAppliedDiff(drone1, []),
new DroneDestroyedDiff(drone1, 1),
new DroneDestroyedDiff(drone2),
new DroneRecalledDiff(drone1),
new DroneRecalledDiff(drone2),
], [
check => {
check.equals(battle.drones.count(), 0, "drone count");
},
check => {
check.equals(battle.drones.count(), 1, "drone count");
check.equals(nn(battle.drones.get(drone1.id)).duration, 3, "drone1 duration");
},
check => {
check.equals(battle.drones.count(), 2, "drone count");
check.equals(nn(battle.drones.get(drone1.id)).duration, 3, "drone1 duration");
check.equals(nn(battle.drones.get(drone2.id)).duration, 2, "drone2 duration");
},
check => {
check.equals(battle.drones.count(), 2, "drone count");
check.equals(nn(battle.drones.get(drone1.id)).duration, 2, "drone1 duration");
check.equals(nn(battle.drones.get(drone2.id)).duration, 2, "drone2 duration");
},
check => {
check.equals(battle.drones.count(), 2, "drone count");
check.equals(nn(battle.drones.get(drone1.id)).duration, 1, "drone1 duration");
check.equals(nn(battle.drones.get(drone2.id)).duration, 2, "drone2 duration");
},
check => {
check.equals(battle.drones.count(), 1, "drone count");
check.equals(nn(battle.drones.get(drone2.id)).duration, 2, "drone2 duration");
},
check => {
check.equals(battle.drones.count(), 0, "drone count");

View file

@ -8,41 +8,32 @@ module TK.SpaceTac {
// Drone object
drone: Drone
// Initial duration (number of activations)
duration: number
constructor(drone: Drone, duration = drone.duration) {
constructor(drone: Drone) {
super(drone.owner);
this.drone = drone;
this.duration = duration;
}
protected applyOnShip(ship: Ship, battle: Battle): void {
this.drone.duration = this.duration;
battle.addDrone(this.drone);
}
protected getReverse(): BaseBattleDiff {
return new DroneDestroyedDiff(this.drone, this.duration);
return new DroneRecalledDiff(this.drone);
}
}
/**
* A drone is destroyed
* A drone is recalled
*/
export class DroneDestroyedDiff extends BaseBattleShipDiff {
export class DroneRecalledDiff extends BaseBattleShipDiff {
// Drone object
drone: Drone
// Remaining duration
duration: number
constructor(drone: Drone, duration = drone.duration) {
constructor(drone: Drone) {
super(drone.owner);
this.drone = drone;
this.duration = duration;
}
protected applyOnShip(ship: Ship, battle: Battle): void {
@ -50,7 +41,7 @@ module TK.SpaceTac {
}
protected getReverse(): BaseBattleDiff {
return new DroneDeployedDiff(this.drone, this.duration);
return new DroneDeployedDiff(this.drone);
}
}
}

View file

@ -13,10 +13,10 @@ module TK.SpaceTac {
battle.applyDiffs(effect2.getOnDiffs(ship, ship));
check.equals(ship.getAttribute("maneuvrability"), 30, "applied 2");
battle.applyDiffs(effect1.getOffDiffs(ship, ship));
battle.applyDiffs(effect1.getOffDiffs(ship));
check.equals(ship.getAttribute("maneuvrability"), 10, "reverted 1");
battle.applyDiffs(effect2.getOffDiffs(ship, ship));
battle.applyDiffs(effect2.getOffDiffs(ship));
check.equals(ship.getAttribute("maneuvrability"), 0, "reverted 2");
});

View file

@ -26,7 +26,7 @@ module TK.SpaceTac {
];
}
getOffDiffs(ship: Ship, source: Ship | Drone): BaseBattleDiff[] {
getOffDiffs(ship: Ship): BaseBattleDiff[] {
return [
new ShipAttributeDiff(ship, this.attrcode, {}, { cumulative: this.value }),
];

View file

@ -14,10 +14,10 @@ module TK.SpaceTac {
battle.applyDiffs(effect2.getOnDiffs(ship, ship));
check.equals(ship.getAttribute("precision"), 3, "applied 2");
battle.applyDiffs(effect1.getOffDiffs(ship, ship));
battle.applyDiffs(effect1.getOffDiffs(ship));
check.equals(ship.getAttribute("precision"), 3, "reverted 1");
battle.applyDiffs(effect2.getOffDiffs(ship, ship));
battle.applyDiffs(effect2.getOffDiffs(ship));
check.equals(ship.getAttribute("precision"), 12, "reverted 2");
});

View file

@ -26,7 +26,7 @@ module TK.SpaceTac {
];
}
getOffDiffs(ship: Ship, source: Ship | Drone): BaseBattleDiff[] {
getOffDiffs(ship: Ship): BaseBattleDiff[] {
return [
new ShipAttributeDiff(ship, this.attrcode, {}, { limit: this.value }),
];

View file

@ -14,10 +14,10 @@ module TK.SpaceTac {
battle.applyDiffs(effect2.getOnDiffs(ship, ship));
check.equals(ship.getAttribute("hull_capacity"), 120, "applied 2");
battle.applyDiffs(effect1.getOffDiffs(ship, ship));
battle.applyDiffs(effect1.getOffDiffs(ship));
check.equals(ship.getAttribute("hull_capacity"), 90, "reverted 1");
battle.applyDiffs(effect2.getOffDiffs(ship, ship));
battle.applyDiffs(effect2.getOffDiffs(ship));
check.equals(ship.getAttribute("hull_capacity"), 100, "reverted 2");
});

View file

@ -27,7 +27,7 @@ module TK.SpaceTac {
];
}
getOffDiffs(ship: Ship, source: Ship | Drone): BaseBattleDiff[] {
getOffDiffs(ship: Ship): BaseBattleDiff[] {
return [
new ShipAttributeDiff(ship, this.attrcode, {}, { multiplier: this.value }),
];

View file

@ -28,7 +28,21 @@ module TK.SpaceTac {
/**
* Get the list of diffs needed to remove this effect on a ship
*/
getOffDiffs(ship: Ship, source: Ship | Drone): BaseBattleDiff[] {
getOffDiffs(ship: Ship): BaseBattleDiff[] {
return [];
}
/**
* Get the list of diffs to apply when this effect is active on a ship beginning its turn
*/
getTurnStartDiffs(ship: Ship): BaseBattleDiff[] {
return [];
}
/**
* Get the list of diffs to apply when this effect is active on a ship ending its turn
*/
getTurnEndDiffs(ship: Ship): BaseBattleDiff[] {
return [];
}

View file

@ -26,7 +26,7 @@ module TK.SpaceTac {
let previous = ship.active_effects.get(this.id);
if (previous) {
result = result.concat(previous.getOffDiffs(ship, source));
result = result.concat(previous.getOffDiffs(ship));
}
result.push(new ShipEffectAddedDiff(ship, this));
@ -35,17 +35,38 @@ module TK.SpaceTac {
return result;
}
getOffDiffs(ship: Ship, source: Ship | Drone): BaseBattleDiff[] {
getOffDiffs(ship: Ship): BaseBattleDiff[] {
let result: BaseBattleDiff[] = [];
if (ship.active_effects.get(this.id)) {
result.push(new ShipEffectRemovedDiff(ship, this));
result = result.concat(this.base.getOffDiffs(ship, source));
result = result.concat(this.base.getOffDiffs(ship));
}
return result;
}
getTurnStartDiffs(ship: Ship): BaseBattleDiff[] {
if (ship.active_effects.get(this.id)) {
return this.base.getTurnStartDiffs(ship);
} else {
return [];
}
}
getTurnEndDiffs(ship: Ship): BaseBattleDiff[] {
if (ship.active_effects.get(this.id)) {
if (this.duration > 1) {
let result: BaseBattleDiff[] = [new ShipEffectChangedDiff(ship, this, -1)];
return result.concat(this.base.getTurnEndDiffs(ship));
} else {
return this.getOffDiffs(ship);
}
} else {
return [];
}
}
isBeneficial(): boolean {
return this.base.isBeneficial();
}

View file

@ -15,12 +15,89 @@ module TK.SpaceTac {
check.equals(ship.getValue("shield"), 95);
});
test.case("estimates if the effect is beneficial", check => {
let effect = new ValueEffect("hull", 12);
check.equals(effect.isBeneficial(), true, "12");
effect = new ValueEffect("hull", -12);
check.equals(effect.isBeneficial(), false, "-12");
effect = new ValueEffect("hull", 0, 8);
check.equals(effect.isBeneficial(), true, "0 8");
effect = new ValueEffect("hull", 0, -8);
check.equals(effect.isBeneficial(), false, "0 -8");
effect = new ValueEffect("hull", 4, -3);
check.equals(effect.isBeneficial(), true, "4 -3");
effect = new ValueEffect("hull", 4, -4);
check.equals(effect.isBeneficial(), true, "4 -4");
effect = new ValueEffect("hull", 3, -4);
check.equals(effect.isBeneficial(), false, "3 -4");
effect = new ValueEffect("hull", -4, 4);
check.equals(effect.isBeneficial(), false, "-4 4");
effect = new ValueEffect("hull", 0, 0, 12);
check.equals(effect.isBeneficial(), true, "0 0 12");
effect = new ValueEffect("hull", 0, 0, -12);
check.equals(effect.isBeneficial(), false, "0 0 -12");
effect = new ValueEffect("hull", 0, 0, 0, 8);
check.equals(effect.isBeneficial(), true, "0 0 0 8");
effect = new ValueEffect("hull", 0, 0, 0, -8);
check.equals(effect.isBeneficial(), false, "0 0 0 -8");
effect = new ValueEffect("hull", 0, 0, 4, -3);
check.equals(effect.isBeneficial(), true, "0 0 4 -3");
effect = new ValueEffect("hull", 0, 0, 4, -4);
check.equals(effect.isBeneficial(), true, "0 0 4 -4");
effect = new ValueEffect("hull", 0, 0, 3, -4);
check.equals(effect.isBeneficial(), false, "0 0 3 -4");
effect = new ValueEffect("hull", 0, 0, -4, 4);
check.equals(effect.isBeneficial(), false, "0 0 -4 4");
});
test.case("has a description", check => {
let effect = new ValueEffect("power", 12);
check.equals(effect.getDescription(), "power +12");
effect = new ValueEffect("power", -4);
check.equals(effect.getDescription(), "power -4");
effect = new ValueEffect("power");
check.equals(effect.getDescription(), "no effect");
effect = new ValueEffect("power", 0, -5);
check.equals(effect.getDescription(), "power -5 when removed");
effect = new ValueEffect("power", 5, -5);
check.equals(effect.getDescription(), "power +5 while active");
effect = new ValueEffect("power", 5, -6);
check.equals(effect.getDescription(), "power +5 on, -6 off");
effect = new ValueEffect("power", 0, 0, 6);
check.equals(effect.getDescription(), "power +6 on turn start");
effect = new ValueEffect("power", 0, 0, 0, -3);
check.equals(effect.getDescription(), "power -3 on turn end");
effect = new ValueEffect("power", 0, 0, 3, -3);
check.equals(effect.getDescription(), "power +3 during turn");
effect = new ValueEffect("power", 0, 0, 4, -3);
check.equals(effect.getDescription(), "power +4 on turn start, -3 on turn end");
effect = new ValueEffect("power", 1, 2, 3, 4);
check.equals(effect.getDescription(), "power +1 on, +2 off, +3 on turn start, +4 on turn end");
});
});
}

View file

@ -1,6 +1,10 @@
/// <reference path="BaseEffect.ts"/>
module TK.SpaceTac {
function strval(value: number) {
return `${value > 0 ? "+" : "-"}${Math.abs(value)}`;
}
/**
* Effect to add (or subtract if negative) an amount to a ship value.
*
@ -10,22 +14,69 @@ module TK.SpaceTac {
// Affected value
valuetype: keyof ShipValues
// Value to add (or subtract if negative)
value: number
// Value to add (or subtract if negative), when the effect is applied to a ship
value_on: number
constructor(valuetype: keyof ShipValues, value: number = 0) {
// Value to add (or subtract if negative), when the effect is removed from a ship
value_off: number
// Value to add (or subtract if negative), when the effect is active on a ship starting its turn
value_start: number
// Value to add (or subtract if negative), when the effect is active on a ship ending its turn
value_end: number
constructor(valuetype: keyof ShipValues, value_on = 0, value_off = 0, value_start = 0, value_end = 0) {
super("value");
this.valuetype = valuetype;
this.value = value;
this.value_on = value_on;
this.value_off = value_off;
this.value_start = value_start;
this.value_end = value_end;
}
getOnDiffs(ship: Ship, source: Ship | Drone): BaseBattleDiff[] {
return ship.getValueDiffs(this.valuetype, this.value, true);
if (this.value_on) {
return ship.getValueDiffs(this.valuetype, this.value_on, true);
} else {
return [];
}
}
getOffDiffs(ship: Ship): BaseBattleDiff[] {
if (this.value_off) {
return ship.getValueDiffs(this.valuetype, this.value_off, true);
} else {
return [];
}
}
getTurnStartDiffs(ship: Ship): BaseBattleDiff[] {
if (this.value_start) {
return ship.getValueDiffs(this.valuetype, this.value_start, true);
} else {
return [];
}
}
getTurnEndDiffs(ship: Ship): BaseBattleDiff[] {
if (this.value_end) {
return ship.getValueDiffs(this.valuetype, this.value_end, true);
} else {
return [];
}
}
isBeneficial(): boolean {
return this.value >= 0;
if (this.value_off < -this.value_on || this.value_end < -this.value_start) {
// after value is lower than before
return false;
} else if ((this.value_off && this.value_off == -this.value_on) || (this.value_end && this.value_end == -this.value_start)) {
return this.value_on > 0 || this.value_start > 0;
} else {
return this.value_on > 0 || this.value_off > 0 || this.value_start > 0 || this.value_end > 0;
}
}
getFullCode(): string {
@ -34,7 +85,44 @@ module TK.SpaceTac {
getDescription(): string {
let attrname = SHIP_VALUES_NAMES[this.valuetype];
return `${attrname} ${this.value > 0 ? "+" : "-"}${Math.abs(this.value)}`;
let parts: string[] = [];
if (this.value_on) {
if (this.value_off == -this.value_on) {
parts.push(`${strval(this.value_on)} while active`);
} else {
if (this.value_off) {
parts.push(`${strval(this.value_on)} on`);
parts.push(`${strval(this.value_off)} off`);
} else {
parts.push(strval(this.value_on));
}
}
}
if (this.value_start) {
if (this.value_end == -this.value_start) {
parts.push(`${strval(this.value_start)} during turn`);
} else {
parts.push(`${strval(this.value_start)} on turn start`);
if (this.value_end) {
parts.push(`${strval(this.value_end)} on turn end`);
}
}
} else if (this.value_end) {
parts.push(`${strval(this.value_end)} on turn end`);
}
if (this.value_off && !this.value_on) {
parts.push(`${strval(this.value_off)} when removed`);
}
if (parts.length) {
return `${attrname} ${parts.join(', ')}`;
} else {
return "no effect";
}
}
}
}

View file

@ -28,7 +28,7 @@ module TK.SpaceTac.Equipments {
this.addAttributeEffect("hull_capacity", leveled(60));
this.addAttributeEffect("precision", leveled(2));
this.addTriggerAction(leveled(1, 0.1), [
new EffectTemplate(new ValueEffect("hull"), { value: leveled(60) })
new EffectTemplate(new ValueEffect("hull"), { value_on: leveled(60) })
])
this.setCooldown(irepeat(1), irepeat(4));
}

View file

@ -5,26 +5,26 @@ module TK.SpaceTac.Specs {
let equipment = template.generate(1);
check.equals(equipment.requirements, { "skill_quantum": 1 });
compare_drone_action(check, equipment.action, new DeployDroneAction(equipment, 4, 300, 10, 150, [
new ValueEffect("hull", 2)
compare_drone_action(check, equipment.action, new DeployDroneAction(equipment, 3, 300, 150, [
new ValueEffect("hull", 0, 0, 0, 30)
]));
equipment = template.generate(2);
check.equals(equipment.requirements, { "skill_quantum": 4 });
compare_drone_action(check, equipment.action, new DeployDroneAction(equipment, 4, 310, 11, 155, [
new ValueEffect("hull", 3)
compare_drone_action(check, equipment.action, new DeployDroneAction(equipment, 3, 310, 155, [
new ValueEffect("hull", 0, 0, 0, 42)
]));
equipment = template.generate(3);
check.equals(equipment.requirements, { "skill_quantum": 7 });
compare_drone_action(check, equipment.action, new DeployDroneAction(equipment, 4, 322, 12, 161, [
new ValueEffect("hull", 4)
compare_drone_action(check, equipment.action, new DeployDroneAction(equipment, 3, 322, 161, [
new ValueEffect("hull", 0, 0, 0, 56)
]));
equipment = template.generate(10);
check.equals(equipment.requirements, { "skill_quantum": 49 });
compare_drone_action(check, equipment.action, new DeployDroneAction(equipment, 10, 462, 26, 231, [
new ValueEffect("hull", 11)
compare_drone_action(check, equipment.action, new DeployDroneAction(equipment, 6, 462, 231, [
new ValueEffect("hull", 0, 0, 0, 224)
]));
});
});

View file

@ -9,9 +9,8 @@ module TK.SpaceTac.Equipments {
super(SlotType.Weapon, "Repair Drone", "Drone able to repair small hull breaches, using quantum patches", 190);
this.setSkillsRequirements({ "skill_quantum": leveled(1, 3) });
this.setCooldown(irepeat(1), leveled(3));
this.addDroneAction(leveled(4, 0.4), leveled(300, 10), leveled(10, 1), leveled(150, 5), [
new EffectTemplate(new ValueEffect("hull"), { "value": istep(2) })
this.addDroneAction(leveled(3, 0.2), leveled(300, 10), leveled(150, 5), [
new EffectTemplate(new ValueEffect("hull"), { "value_end": leveled(30) })
]);
}
}

View file

@ -104,7 +104,7 @@ module TK.SpaceTac.UI {
this.loadSound("battle/weapon-missile-explosion.wav");
this.loadSound("battle/drone-deploy.wav");
this.loadSound("battle/drone-destroy.wav");
this.loadSound("battle/drone-activate.wav");
// this.loadSound("battle/drone-activate.wav");
this.loadSound("music/mechanolith.mp3");
}

View file

@ -7,7 +7,7 @@ module TK.SpaceTac.UI.Specs {
test.case("displays power usage", check => {
let bar = testgame.view.action_bar;
let ship = new Ship();
let action = new BaseAction("something", "Do something");
let action = new BaseAction("something");
let icon = new ActionIcon(bar, ship, action, 0);
check.same(icon.img_power.visible, false, "initial state");
@ -124,7 +124,7 @@ module TK.SpaceTac.UI.Specs {
icon.refresh(action);
check.same(icon.img_targetting.visible, true, "selected");
icon.refresh(new BaseAction("other", "Other action"));
icon.refresh(new BaseAction("other"));
check.same(icon.img_targetting.visible, false, "other");
})
});

View file

@ -11,12 +11,12 @@ module TK.SpaceTac.UI.Specs {
let action1 = new MoveAction(new Equipment());
nn(action1.equipment).name = "Engine";
action1.name = "Move";
check.patch(action1, "getVerb", () => "Move");
let action2 = new TriggerAction(new Equipment(), [new DamageEffect(12)], 2, 50, 0);
nn(action2.equipment).name = "Weapon";
action2.name = "Fire";
check.patch(action2, "getVerb", () => "Fire");
let action3 = new EndTurnAction();
action3.name = "End turn";
check.patch(action3, "getVerb", () => "End turn");
ActionTooltip.fill(tooltip.getFiller(), ship, action1, 0);
checkText(check, (<any>tooltip).container.content.children[1], "Engine");

View file

@ -12,7 +12,7 @@ module TK.SpaceTac.UI {
let icon = builder.image([`equipment-${action.equipment ? action.equipment.code : "---"}`, `action-${action.code}`]);
icon.scale.set(0.5);
builder.text(action.equipment ? action.equipment.name : action.name, 150, 0, { size: 24 });
builder.text(action.equipment ? action.equipment.name : action.getVerb(), 150, 0, { size: 24 });
let cost = "";
if (action instanceof MoveAction) {

View file

@ -18,9 +18,6 @@ module TK.SpaceTac.UI {
// Activation effect
activation: Phaser.Graphics
// Duration info
duration: Phaser.Text
constructor(battleview: BattleView, drone: Drone) {
super(battleview.game);
@ -48,11 +45,6 @@ module TK.SpaceTac.UI {
this.sprite.scale.set(0.1, 0.1);
this.add(this.sprite);
this.duration = new Phaser.Text(this.game, 0, 40, "", { font: "bold 16pt SpaceTac", fill: "#ffdd4b" });
this.duration.anchor.set(0.5, 0.5);
this.duration.visible = false;
this.add(this.duration);
this.view.tooltip.bindDynamicText(this.sprite, () => {
return this.drone.getDescription();
});
@ -93,11 +85,7 @@ module TK.SpaceTac.UI {
* Set the tactical mode display
*/
setTacticalMode(active: boolean) {
if (active) {
this.duration.text = `${this.drone.duration}`;
}
this.sprite.scale.set(active ? 0.2 : 0.1);
this.view.animations.setVisible(this.duration, active, 200);
}
}
}

View file

@ -184,10 +184,8 @@ module TK.SpaceTac.UI {
durations.push(this.processEndBattleEvent(diff));
} else if (diff instanceof DroneDeployedDiff) {
durations.push(this.processDroneDeployedEvent(diff));
} else if (diff instanceof DroneDestroyedDiff) {
durations.push(this.processDroneDestroyedEvent(diff));
} else if (diff instanceof DroneAppliedDiff) {
durations.push(this.processDroneAppliedEvent(diff));
} else if (diff instanceof DroneRecalledDiff) {
durations.push(this.processDroneRecalledEvent(diff));
}
let delay = max([0].concat(durations));
@ -286,7 +284,7 @@ module TK.SpaceTac.UI {
}
// Drone destroyed
private processDroneDestroyedEvent(event: DroneDestroyedDiff): number {
private processDroneRecalledEvent(event: DroneRecalledDiff): number {
let duration = this.view.arena.removeDrone(event.drone);
if (duration) {
@ -297,7 +295,7 @@ module TK.SpaceTac.UI {
}
// Drone applied
private processDroneAppliedEvent(event: DroneAppliedDiff): number {
/*private processDroneAppliedEvent(event: DroneAppliedDiff): number {
let drone = this.view.arena.findDrone(event.drone);
if (drone) {
let duration = drone.setApplied();
@ -310,6 +308,6 @@ module TK.SpaceTac.UI {
} else {
return 0;
}
}
}*/
}
}

View file

@ -154,7 +154,7 @@ module TK.SpaceTac.UI {
}
} else if (action instanceof DeployDroneAction) {
color = 0xe9f2f9;
radius = action.effect_radius;
radius = action.drone_radius;
} else if (action instanceof ToggleAction) {
color = 0xd3e448;
radius = action.radius;