Fixed area effects not applying
This commit is contained in:
parent
e34033c976
commit
e13ee56581
3
TODO.md
3
TODO.md
|
@ -37,8 +37,6 @@ Character sheet
|
||||||
Battle
|
Battle
|
||||||
------
|
------
|
||||||
|
|
||||||
* Fix area effects not applying (Damage Protector)
|
|
||||||
* Fix toggle actions not deactivating (Damage Protector)
|
|
||||||
* Fix drone effects not applying, and drone never disappearing (Repair Drone)
|
* 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
|
* Fix arena's ship hovering happening even when the character sheet (or a dialog) is open on top
|
||||||
* Add a voluntary retreat option
|
* Add a voluntary retreat option
|
||||||
|
@ -57,7 +55,6 @@ Battle
|
||||||
* Allow to move targetting indicator with arrow keys
|
* Allow to move targetting indicator with arrow keys
|
||||||
* Add targetting shortcuts for "previous target", "next enemy" and "next ally"
|
* Add targetting shortcuts for "previous target", "next enemy" and "next ally"
|
||||||
* Area targetting should include the hotkeyed ship at best (apply exclusion and power limit), not necessarily center on it
|
* Area targetting should include the hotkeyed ship at best (apply exclusion and power limit), not necessarily center on it
|
||||||
* Fix "toggle action" targetting with simulated move not activating the action after the move
|
|
||||||
* Add shortcut to perform only the "move" part of a move+fire simulation
|
* Add shortcut to perform only the "move" part of a move+fire simulation
|
||||||
* Fix delay of shield/hull impact effects (should depend on weapon animation, and ship location)
|
* Fix delay of shield/hull impact effects (should depend on weapon animation, and ship location)
|
||||||
* Indicate visually the power gain of "end turn"
|
* Indicate visually the power gain of "end turn"
|
||||||
|
|
|
@ -44,5 +44,27 @@ module TK.SpaceTac.Specs {
|
||||||
new ShipDeathDiff(battle, ship3),
|
new ShipDeathDiff(battle, ship3),
|
||||||
], "2 ships to mark as dead");
|
], "2 ships to mark as dead");
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test.case("fixes area effects", check => {
|
||||||
|
let battle = new Battle();
|
||||||
|
let ship1 = battle.fleets[0].addShip();
|
||||||
|
let ship2 = battle.fleets[1].addShip();
|
||||||
|
let checks = new BattleChecks(battle);
|
||||||
|
|
||||||
|
check.in("initial state", check => {
|
||||||
|
check.equals(checks.checkAreaEffects(), [], "effects diff");
|
||||||
|
});
|
||||||
|
|
||||||
|
let effect1 = ship1.active_effects.add(new StickyEffect(new BaseEffect("e1")));
|
||||||
|
let effect2 = ship1.active_effects.add(new BaseEffect("e2"));
|
||||||
|
let effect3 = ship1.active_effects.add(new BaseEffect("e3"));
|
||||||
|
check.patch(battle, "iAreaEffects", () => isingle(effect3));
|
||||||
|
check.in("sticky+obsolete+missing", check => {
|
||||||
|
check.equals(checks.checkAreaEffects(), [
|
||||||
|
new ShipEffectRemovedDiff(ship1, effect2),
|
||||||
|
new ShipEffectAddedDiff(ship2, effect3)
|
||||||
|
], "effects diff");
|
||||||
|
});
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,9 @@ module TK.SpaceTac {
|
||||||
* This may not contain ALL the diffs needed, and should be called again while it returns diffs.
|
* This may not contain ALL the diffs needed, and should be called again while it returns diffs.
|
||||||
*/
|
*/
|
||||||
checkAll(): BaseBattleDiff[] {
|
checkAll(): BaseBattleDiff[] {
|
||||||
let diffs = this.checkVictory();
|
let diffs: BaseBattleDiff[];
|
||||||
|
|
||||||
|
diffs = this.checkAreaEffects();
|
||||||
if (diffs.length) {
|
if (diffs.length) {
|
||||||
return diffs;
|
return diffs;
|
||||||
}
|
}
|
||||||
|
@ -55,6 +57,11 @@ module TK.SpaceTac {
|
||||||
return diffs;
|
return diffs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
diffs = this.checkVictory();
|
||||||
|
if (diffs.length) {
|
||||||
|
return diffs;
|
||||||
|
}
|
||||||
|
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,5 +119,34 @@ module TK.SpaceTac {
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check area effects (remove obsolete ones, and add missing ones)
|
||||||
|
*/
|
||||||
|
checkAreaEffects(): BaseBattleDiff[] {
|
||||||
|
let result: BaseBattleDiff[] = [];
|
||||||
|
|
||||||
|
iforeach(this.battle.iships(true), ship => {
|
||||||
|
let expected = new RObjectContainer(imaterialize(this.battle.iAreaEffects(ship.arena_x, ship.arena_y)));
|
||||||
|
|
||||||
|
// Remove obsolete effects
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add missing effects
|
||||||
|
expected.list().forEach(effect => {
|
||||||
|
if (!ship.active_effects.get(effect.id)) {
|
||||||
|
result.push(new ShipEffectAddedDiff(ship, effect));
|
||||||
|
result = result.concat(effect.getOnDiffs(ship, ship));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -524,14 +524,13 @@ module TK.SpaceTac {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Iterator over all effects active for this ship.
|
* Iterator over all effects active for this ship.
|
||||||
|
*
|
||||||
|
* This combines the permanent effects from equipment, with sticky and area effects.
|
||||||
*/
|
*/
|
||||||
ieffects(): Iterator<BaseEffect> {
|
ieffects(): Iterator<BaseEffect> {
|
||||||
let battle = this.getBattle();
|
|
||||||
let area_effects = battle ? battle.iAreaEffects(this.arena_x, this.arena_y) : IEMPTY;
|
|
||||||
return ichain(
|
return ichain(
|
||||||
ichainit(imap(iarray(this.slots), slot => slot.attached ? iarray(slot.attached.effects) : IEMPTY)),
|
ichainit(imap(iarray(this.slots), slot => slot.attached ? iarray(slot.attached.effects) : IEMPTY)),
|
||||||
imap(this.active_effects.iterator(), effect => (effect instanceof StickyEffect) ? effect.base : effect),
|
imap(this.active_effects.iterator(), effect => (effect instanceof StickyEffect) ? effect.base : effect)
|
||||||
area_effects
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,25 +37,47 @@ module TK.SpaceTac.Specs {
|
||||||
let battle = TestTools.createBattle(1, 0);
|
let battle = TestTools.createBattle(1, 0);
|
||||||
let ship = battle.play_order[0];
|
let ship = battle.play_order[0];
|
||||||
TestTools.setShipAP(ship, 10, 3);
|
TestTools.setShipAP(ship, 10, 3);
|
||||||
|
let weapon = TestTools.addWeapon(ship);
|
||||||
|
weapon.action = new ToggleAction(weapon, 2);
|
||||||
ship.setValue("power", 6);
|
ship.setValue("power", 6);
|
||||||
|
|
||||||
TestTools.actionChain(check, battle, [
|
TestTools.actionChain(check, battle, [
|
||||||
|
[ship, weapon.action, Target.newFromShip(ship)],
|
||||||
|
[ship, weapon.action, Target.newFromShip(ship)],
|
||||||
|
[ship, EndTurnAction.SINGLETON, Target.newFromShip(ship)],
|
||||||
|
[ship, weapon.action, Target.newFromShip(ship)],
|
||||||
[ship, EndTurnAction.SINGLETON, Target.newFromShip(ship)],
|
[ship, EndTurnAction.SINGLETON, Target.newFromShip(ship)],
|
||||||
[ship, EndTurnAction.SINGLETON, Target.newFromShip(ship)],
|
[ship, EndTurnAction.SINGLETON, Target.newFromShip(ship)],
|
||||||
|
[ship, weapon.action, Target.newFromShip(ship)],
|
||||||
[ship, EndTurnAction.SINGLETON, Target.newFromShip(ship)],
|
[ship, EndTurnAction.SINGLETON, Target.newFromShip(ship)],
|
||||||
], [
|
], [
|
||||||
check => {
|
check => {
|
||||||
check.equals(ship.getValue("power"), 6, "power=6");
|
check.equals(ship.getValue("power"), 6, "power value");
|
||||||
},
|
},
|
||||||
check => {
|
check => {
|
||||||
check.equals(ship.getValue("power"), 9, "power=9");
|
check.equals(ship.getValue("power"), 4, "power value");
|
||||||
},
|
},
|
||||||
check => {
|
check => {
|
||||||
check.equals(ship.getValue("power"), 10, "power=10");
|
check.equals(ship.getValue("power"), 6, "power value");
|
||||||
},
|
},
|
||||||
check => {
|
check => {
|
||||||
check.equals(ship.getValue("power"), 10, "power=10");
|
check.equals(ship.getValue("power"), 9, "power value");
|
||||||
}
|
},
|
||||||
|
check => {
|
||||||
|
check.equals(ship.getValue("power"), 7, "power value");
|
||||||
|
},
|
||||||
|
check => {
|
||||||
|
check.equals(ship.getValue("power"), 8, "power value");
|
||||||
|
},
|
||||||
|
check => {
|
||||||
|
check.equals(ship.getValue("power"), 9, "power value");
|
||||||
|
},
|
||||||
|
check => {
|
||||||
|
check.equals(ship.getValue("power"), 10, "power value");
|
||||||
|
},
|
||||||
|
check => {
|
||||||
|
check.equals(ship.getValue("power"), 10, "power value");
|
||||||
|
},
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,9 @@ module TK.SpaceTac {
|
||||||
let new_ship = battle.getNextShip();
|
let new_ship = battle.getNextShip();
|
||||||
|
|
||||||
// Generate power
|
// Generate power
|
||||||
result = result.concat(ship.getValueDiffs("power", ship.getAttribute("power_generation"), true));
|
let toggled_cost = isum(imap(ship.iToggleActions(true), action => action.power));
|
||||||
|
let power_diff = ship.getAttribute("power_generation") - toggled_cost;
|
||||||
|
result = result.concat(ship.getValueDiffs("power", power_diff, true));
|
||||||
|
|
||||||
// Cool down equipment
|
// Cool down equipment
|
||||||
ship.listEquipment().filter(equ => equ.cooldown.heat > 0).forEach(equ => {
|
ship.listEquipment().filter(equ => equ.cooldown.heat > 0).forEach(equ => {
|
||||||
|
|
|
@ -3,9 +3,11 @@
|
||||||
module TK.SpaceTac {
|
module TK.SpaceTac {
|
||||||
/**
|
/**
|
||||||
* Action to toggle some effects on the ship or around it, until next turn start
|
* Action to toggle some effects on the ship or around it, until next turn start
|
||||||
|
*
|
||||||
|
* Toggle actions consume power when activated, and restore it when deactivated
|
||||||
*/
|
*/
|
||||||
export class ToggleAction extends BaseAction {
|
export class ToggleAction extends BaseAction {
|
||||||
// Power consumption (activation only)
|
// Power consumption (for activation)
|
||||||
power: number
|
power: number
|
||||||
|
|
||||||
// Effect radius
|
// Effect radius
|
||||||
|
@ -37,7 +39,7 @@ module TK.SpaceTac {
|
||||||
}
|
}
|
||||||
|
|
||||||
getActionPointsUsage(ship: Ship, target: Target | null): number {
|
getActionPointsUsage(ship: Ship, target: Target | null): number {
|
||||||
return this.activated ? 0 : this.power;
|
return this.activated ? -this.power : this.power;
|
||||||
}
|
}
|
||||||
|
|
||||||
getRangeRadius(ship: Ship): number {
|
getRangeRadius(ship: Ship): number {
|
||||||
|
@ -52,23 +54,25 @@ module TK.SpaceTac {
|
||||||
return ship.is(target.ship_id) ? target : null;
|
return ship.is(target.ship_id) ? target : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Collect the effects applied by this action
|
|
||||||
*/
|
|
||||||
getEffects(ship: Ship, target: Target, source = ship.location): [Ship, BaseEffect][] {
|
|
||||||
let result: [Ship, BaseEffect][] = [];
|
|
||||||
let ships = this.getImpactedShips(ship, target, source);
|
|
||||||
ships.forEach(ship => {
|
|
||||||
this.effects.forEach(effect => result.push([ship, effect]));
|
|
||||||
});
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected getSpecificDiffs(ship: Ship, battle: Battle, target: Target): BaseBattleDiff[] {
|
protected getSpecificDiffs(ship: Ship, battle: Battle, target: Target): BaseBattleDiff[] {
|
||||||
// TODO Add effects to ships in range
|
let result: BaseBattleDiff[] = [
|
||||||
return [
|
|
||||||
new ShipActionToggleDiff(ship, this, !this.activated)
|
new ShipActionToggleDiff(ship, this, !this.activated)
|
||||||
]
|
];
|
||||||
|
|
||||||
|
let ships = this.getImpactedShips(ship, target, ship.location);
|
||||||
|
ships.forEach(iship => {
|
||||||
|
this.effects.forEach(effect => {
|
||||||
|
if (this.activated) {
|
||||||
|
result.push(new ShipEffectRemovedDiff(iship, effect));
|
||||||
|
result = result.concat(effect.getOffDiffs(iship, ship));
|
||||||
|
} else {
|
||||||
|
result.push(new ShipEffectAddedDiff(iship, effect));
|
||||||
|
result = result.concat(effect.getOnDiffs(iship, ship));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
getEffectsDescription(): string {
|
getEffectsDescription(): string {
|
||||||
|
|
|
@ -140,7 +140,7 @@ module TK.SpaceTac.UI.Specs {
|
||||||
|
|
||||||
targetting.setAction(action, ActionTargettingMode.SURROUNDINGS);
|
targetting.setAction(action, ActionTargettingMode.SURROUNDINGS);
|
||||||
targetting.setTargetFromLocation({ x: 8000, y: 60 });
|
targetting.setTargetFromLocation({ x: 8000, y: 60 });
|
||||||
check.equals(targetting.target, Target.newFromLocation(8000, 60), "surroundings 1");
|
check.equals(targetting.target, new Target(8000, 60, playing_ship), "surroundings 1");
|
||||||
targetting.setTargetFromLocation({ x: playing_ship.arena_x + 10, y: playing_ship.arena_y - 20 });
|
targetting.setTargetFromLocation({ x: playing_ship.arena_x + 10, y: playing_ship.arena_y - 20 });
|
||||||
check.equals(targetting.target, Target.newFromShip(playing_ship), "surroundings 2");
|
check.equals(targetting.target, Target.newFromShip(playing_ship), "surroundings 2");
|
||||||
|
|
||||||
|
|
|
@ -325,7 +325,7 @@ module TK.SpaceTac.UI {
|
||||||
if (arenaDistance(this.ship.location, location) < 50) {
|
if (arenaDistance(this.ship.location, location) < 50) {
|
||||||
this.setTarget(Target.newFromShip(this.ship));
|
this.setTarget(Target.newFromShip(this.ship));
|
||||||
} else {
|
} else {
|
||||||
this.setTarget(Target.newFromLocation(location.x, location.y));
|
this.setTarget(new Target(location.x, location.y, this.ship));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.setTarget(Target.newFromShip(this.ship));
|
this.setTarget(Target.newFromShip(this.ship));
|
||||||
|
|
Loading…
Reference in a new issue