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
|
||||
------
|
||||
|
||||
* 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 arena's ship hovering happening even when the character sheet (or a dialog) is open on top
|
||||
* Add a voluntary retreat option
|
||||
|
@ -57,7 +55,6 @@ Battle
|
|||
* Allow to move targetting indicator with arrow keys
|
||||
* 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
|
||||
* 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
|
||||
* Fix delay of shield/hull impact effects (should depend on weapon animation, and ship location)
|
||||
* Indicate visually the power gain of "end turn"
|
||||
|
|
|
@ -44,5 +44,27 @@ module TK.SpaceTac.Specs {
|
|||
new ShipDeathDiff(battle, ship3),
|
||||
], "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.
|
||||
*/
|
||||
checkAll(): BaseBattleDiff[] {
|
||||
let diffs = this.checkVictory();
|
||||
let diffs: BaseBattleDiff[];
|
||||
|
||||
diffs = this.checkAreaEffects();
|
||||
if (diffs.length) {
|
||||
return diffs;
|
||||
}
|
||||
|
@ -55,6 +57,11 @@ module TK.SpaceTac {
|
|||
return diffs;
|
||||
}
|
||||
|
||||
diffs = this.checkVictory();
|
||||
if (diffs.length) {
|
||||
return diffs;
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
|
@ -112,5 +119,34 @@ module TK.SpaceTac {
|
|||
|
||||
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.
|
||||
*
|
||||
* This combines the permanent effects from equipment, with sticky and area effects.
|
||||
*/
|
||||
ieffects(): Iterator<BaseEffect> {
|
||||
let battle = this.getBattle();
|
||||
let area_effects = battle ? battle.iAreaEffects(this.arena_x, this.arena_y) : IEMPTY;
|
||||
return ichain(
|
||||
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),
|
||||
area_effects
|
||||
imap(this.active_effects.iterator(), effect => (effect instanceof StickyEffect) ? effect.base : effect)
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -37,25 +37,47 @@ module TK.SpaceTac.Specs {
|
|||
let battle = TestTools.createBattle(1, 0);
|
||||
let ship = battle.play_order[0];
|
||||
TestTools.setShipAP(ship, 10, 3);
|
||||
let weapon = TestTools.addWeapon(ship);
|
||||
weapon.action = new ToggleAction(weapon, 2);
|
||||
ship.setValue("power", 6);
|
||||
|
||||
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, weapon.action, Target.newFromShip(ship)],
|
||||
[ship, EndTurnAction.SINGLETON, Target.newFromShip(ship)],
|
||||
], [
|
||||
check => {
|
||||
check.equals(ship.getValue("power"), 6, "power=6");
|
||||
check.equals(ship.getValue("power"), 6, "power value");
|
||||
},
|
||||
check => {
|
||||
check.equals(ship.getValue("power"), 9, "power=9");
|
||||
check.equals(ship.getValue("power"), 4, "power value");
|
||||
},
|
||||
check => {
|
||||
check.equals(ship.getValue("power"), 10, "power=10");
|
||||
check.equals(ship.getValue("power"), 6, "power value");
|
||||
},
|
||||
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();
|
||||
|
||||
// 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
|
||||
ship.listEquipment().filter(equ => equ.cooldown.heat > 0).forEach(equ => {
|
||||
|
|
|
@ -3,9 +3,11 @@
|
|||
module TK.SpaceTac {
|
||||
/**
|
||||
* 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 {
|
||||
// Power consumption (activation only)
|
||||
// Power consumption (for activation)
|
||||
power: number
|
||||
|
||||
// Effect radius
|
||||
|
@ -37,7 +39,7 @@ module TK.SpaceTac {
|
|||
}
|
||||
|
||||
getActionPointsUsage(ship: Ship, target: Target | null): number {
|
||||
return this.activated ? 0 : this.power;
|
||||
return this.activated ? -this.power : this.power;
|
||||
}
|
||||
|
||||
getRangeRadius(ship: Ship): number {
|
||||
|
@ -52,23 +54,25 @@ module TK.SpaceTac {
|
|||
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[] {
|
||||
// TODO Add effects to ships in range
|
||||
return [
|
||||
let result: BaseBattleDiff[] = [
|
||||
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 {
|
||||
|
|
|
@ -140,7 +140,7 @@ module TK.SpaceTac.UI.Specs {
|
|||
|
||||
targetting.setAction(action, ActionTargettingMode.SURROUNDINGS);
|
||||
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 });
|
||||
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) {
|
||||
this.setTarget(Target.newFromShip(this.ship));
|
||||
} else {
|
||||
this.setTarget(Target.newFromLocation(location.x, location.y));
|
||||
this.setTarget(new Target(location.x, location.y, this.ship));
|
||||
}
|
||||
} else {
|
||||
this.setTarget(Target.newFromShip(this.ship));
|
||||
|
|
Loading…
Reference in a new issue