1
0
Fork 0

Fixed area effects not applying

This commit is contained in:
Michaël Lemaire 2017-11-29 01:36:07 +01:00
parent e34033c976
commit e13ee56581
9 changed files with 115 additions and 33 deletions

View file

@ -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"

View file

@ -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");
});
})
})
}

View file

@ -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;
}
}
}

View file

@ -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)
);
}

View file

@ -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");
},
]);
});

View file

@ -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 => {

View file

@ -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 {

View file

@ -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");

View file

@ -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));