1
0
Fork 0

Fixed sticky effects not fading

This commit is contained in:
Michaël Lemaire 2017-11-28 19:01:56 +01:00
parent 77f229c4d6
commit 3f268a3bff
11 changed files with 225 additions and 17 deletions

View file

@ -38,7 +38,6 @@ Battle
------
* Fix area effects not applying (Damage Protector)
* Fix sticky effects not fading (Power Depleter)
* 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

@ -1 +1 @@
Subproject commit c1aa0e6263e9202fefc839bd97cbf16563cdca51
Subproject commit 38c06700cfb3d03a1f7309a6200ab0ca7c0ee9d8

View file

@ -5,25 +5,43 @@ module TK.SpaceTac {
check.equals(attribute.get(), 0, "initial");
attribute.addModifier(4);
check.equals(attribute.get(), 4, "added 4");
check.in("+4", check => {
check.equals(attribute.get(), 4, "effective value");
});
attribute.addModifier(2);
check.equals(attribute.get(), 6, "added 6");
check.in("+4 +2", check => {
check.equals(attribute.get(), 6, "effective value");
});
attribute.addModifier(undefined, 20);
check.equals(attribute.get(), 7, "added 20%");
check.in("+4 +2 +20%", check => {
check.equals(attribute.get(), 7, "effective value");
});
attribute.addModifier(undefined, 5);
check.equals(attribute.get(), 8, "added 5%");
check.in("+4 +2 +20% +5%", check => {
check.equals(attribute.get(), 8, "effective value");
check.equals(attribute.getMaximal(), Infinity, "maximal value");
});
attribute.addModifier(undefined, undefined, 6);
check.equals(attribute.get(), 6, "limited to 6");
check.in("+4 +2 +20% +5% lim6", check => {
check.equals(attribute.get(), 6, "effective value");
check.equals(attribute.getMaximal(), 6, "maximal value");
});
attribute.addModifier(undefined, undefined, 4);
check.equals(attribute.get(), 4, "limited to 4");
check.in("+4 +2 +20% +5% lim6 lim4", check => {
check.equals(attribute.get(), 4, "effective value");
check.equals(attribute.getMaximal(), 4, "maximal value");
});
attribute.addModifier(undefined, undefined, 10);
check.equals(attribute.get(), 4, "limited to 10");
check.in("+4 +2 +20% +5% lim6 lim4 lim10", check => {
check.equals(attribute.get(), 4, "effective value");
check.equals(attribute.getMaximal(), 4, "maximal value");
});
});
});
}

View file

@ -58,6 +58,17 @@ module TK.SpaceTac {
return this.current;
}
/**
* Get the maximal value enforced by limit modifiers, Infinity for unlimited
*/
getMaximal(): number {
if (this.limits.length > 0) {
return min(this.limits);
} else {
return Infinity;
}
}
/**
* Reset all modifiers
*/

View file

@ -12,7 +12,7 @@ module TK.SpaceTac.Specs {
check.equals(action.checkCannotBeApplied(battle.play_order[1]), "ship not playing");
});
test.case("ends turn when applied", check => {
test.case("changes active ship", check => {
let battle = TestTools.createBattle(2, 0);
TestTools.actionChain(check, battle, [
@ -99,5 +99,46 @@ module TK.SpaceTac.Specs {
}
]);
});
test.case("fades sticky effects for previous ship", check => {
let battle = TestTools.createBattle(1, 0);
let ship = battle.play_order[0];
let effect1 = new BaseEffect("e1");
let effect2 = new StickyEffect(new AttributeLimitEffect("precision", 7), 2);
ship.active_effects.add(effect1);
ship.active_effects.add(effect2);
effect2.base.getOnDiffs(ship, ship).forEach(effect => effect.apply(battle));
TestTools.actionChain(check, battle, [
[ship, EndTurnAction.SINGLETON, Target.newFromShip(ship)],
[ship, EndTurnAction.SINGLETON, Target.newFromShip(ship)],
[ship, EndTurnAction.SINGLETON, Target.newFromShip(ship)],
], [
check => {
check.equals(ship.active_effects.count(), 2, "effect count");
check.contains(ship.active_effects.ids(), effect2.id, "sticky effect active");
check.equals((<StickyEffect>nn(ship.active_effects.get(effect2.id))).duration, 2, "duration sticky effect");
check.equals(ship.attributes.precision.getMaximal(), 7, "max precision");
},
check => {
check.equals(ship.active_effects.count(), 2, "effect count");
check.contains(ship.active_effects.ids(), effect2.id, "sticky effect active");
check.equals((<StickyEffect>nn(ship.active_effects.get(effect2.id))).duration, 1, "duration sticky effect");
check.equals(ship.attributes.precision.getMaximal(), 7, "max precision");
},
check => {
check.equals(ship.active_effects.count(), 1, "effect count");
check.notcontains(ship.active_effects.ids(), effect2.id, "sticky effect removed");
check.equals(ship.attributes.precision.getMaximal(), Infinity, "max precision");
},
check => {
check.equals(ship.active_effects.count(), 1, "effect count");
check.notcontains(ship.active_effects.ids(), effect2.id, "sticky effect removed");
check.equals(ship.attributes.precision.getMaximal(), Infinity, "max precision");
}
]);
});
});
}

View file

@ -27,8 +27,18 @@ module TK.SpaceTac {
result.push(new ShipCooldownDiff(ship, equ, 1));
});
// TODO sticky effects
// Fade sticky 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));
}
}
});
// 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));

View file

@ -11,11 +11,11 @@ module TK.SpaceTac {
constructor(ship: Ship | RObjectId, effect: BaseEffect) {
super(ship);
this.effect = effect;
this.effect = duplicate(effect, TK.SpaceTac);
}
protected applyOnShip(ship: Ship, battle: Battle): void {
ship.active_effects.add(this.effect);
ship.active_effects.add(duplicate(this.effect, TK.SpaceTac));
}
protected getReverse(): BaseBattleDiff {
@ -33,7 +33,7 @@ module TK.SpaceTac {
constructor(ship: Ship | RObjectId, effect: BaseEffect) {
super(ship);
this.effect = effect;
this.effect = duplicate(effect, TK.SpaceTac);
}
protected applyOnShip(ship: Ship, battle: Battle): void {

View file

@ -0,0 +1,76 @@
module TK.SpaceTac.Specs {
testing("ShipEffectChangedDiff", test => {
test.case("applies and reverts", check => {
let battle = TestTools.createBattle();
let ship = battle.play_order[0];
let effect1 = new BaseEffect("e1");
let effect2 = new StickyEffect(new BaseEffect("e2"), 2);
let effect3 = new StickyEffect(new BaseEffect("e3"), 3);
ship.active_effects.add(effect1);
ship.active_effects.add(effect2);
ship.active_effects.add(effect3);
TestTools.diffChain(check, battle, [
new ShipEffectChangedDiff(ship, effect1),
new ShipEffectChangedDiff(ship, effect2, -1),
new ShipEffectChangedDiff(ship, effect3, 1),
], [
check => {
check.equals(ship.active_effects.count(), 3, "effect count");
check.equals(effect2.duration, 2, "duration effect2");
check.equals(effect3.duration, 3, "duration effect3");
},
check => {
check.equals(ship.active_effects.count(), 3, "effect count");
check.equals(effect2.duration, 2, "duration effect2");
check.equals(effect3.duration, 3, "duration effect3");
},
check => {
check.equals(ship.active_effects.count(), 3, "effect count");
check.equals(effect2.duration, 1, "duration effect2");
check.equals(effect3.duration, 3, "duration effect3");
},
check => {
check.equals(ship.active_effects.count(), 3, "effect count");
check.equals(effect2.duration, 1, "duration effect2");
check.equals(effect3.duration, 4, "duration effect3");
},
]);
});
test.case("leaves original effect untouched", check => {
let battle = TestTools.createBattle();
let ship = battle.play_order[0];
let effect = new StickyEffect(new BaseEffect("effect"), 2);
let effect_at_removal = copy(effect);
effect_at_removal.duration = 1;
TestTools.diffChain(check, battle, [
new ShipEffectAddedDiff(ship, effect),
new ShipEffectChangedDiff(ship, effect, -1),
new ShipEffectRemovedDiff(ship, effect_at_removal),
], [
check => {
check.equals(ship.active_effects.count(), 0, "effect count");
check.equals(effect.duration, 2, "original duration");
},
check => {
check.equals(ship.active_effects.count(), 1, "effect count");
check.equals(effect.duration, 2, "original duration");
check.equals((<StickyEffect>nn(ship.active_effects.get(effect.id))).duration, 2, "active duration");
},
check => {
check.equals(ship.active_effects.count(), 1, "effect count");
check.equals(effect.duration, 2, "original duration");
check.equals((<StickyEffect>nn(ship.active_effects.get(effect.id))).duration, 1, "active duration");
},
check => {
check.equals(ship.active_effects.count(), 0, "effect count");
check.equals(effect.duration, 2, "original duration");
},
]);
});
});
}

View file

@ -0,0 +1,40 @@
/// <reference path="BaseBattleDiff.ts"/>
module TK.SpaceTac {
/**
* An effect attached to a ship changed
*/
export class ShipEffectChangedDiff extends BaseBattleShipDiff {
// Effect modified
effect: RObjectId
// Duration diff
duration: number
constructor(ship: Ship | RObjectId, effect: BaseEffect | RObjectId, duration = 0) {
super(ship);
this.effect = (effect instanceof BaseEffect) ? effect.id : effect;
this.duration = duration;
}
protected applyOnShip(ship: Ship, battle: Battle): void {
let effect = ship.active_effects.get(this.effect);
if (effect) {
if (this.duration) {
if (effect instanceof StickyEffect) {
effect.duration += this.duration;
} else {
console.error("Could not apply diff - not a sticky effect", this, ship);
}
}
} else {
console.error("Could not apply diff - effect not found on ship", this, ship);
}
}
protected getReverse(): BaseBattleDiff {
return new ShipEffectChangedDiff(this.ship_id, this.effect, -this.duration);
}
}
}

View file

@ -24,7 +24,7 @@ module TK.SpaceTac {
getOnDiffs(ship: Ship, source: Ship | Drone): BaseBattleDiff[] {
// TODO if already there, remove the previous one to replace it
let result: BaseBattleDiff[] = [
new ShipEffectAddedDiff(ship, new StickyEffect(this.base, this.duration)),
new ShipEffectAddedDiff(ship, this),
]
result = result.concat(this.base.getOnDiffs(ship, source));
@ -32,6 +32,16 @@ module TK.SpaceTac {
return result;
}
getOffDiffs(ship: Ship, source: Ship | Drone): BaseBattleDiff[] {
let result: BaseBattleDiff[] = [
new ShipEffectRemovedDiff(ship, this),
]
result = result.concat(this.base.getOffDiffs(ship, source));
return result;
}
isBeneficial(): boolean {
return this.base.isBeneficial();
}

View file

@ -14,8 +14,9 @@ module TK.SpaceTac.UI {
// Forward diffs to other subscribers
private forwarding: ((diff: BaseBattleDiff) => number)[] = []
// Indicator to debug the processed logs
// Debug indicators
private debug = false
private ai_disabled = false
// Time at which the last action was applied
private last_action: number
@ -210,8 +211,10 @@ module TK.SpaceTac.UI {
if (player) {
if (player.is(this.view.player)) {
this.view.setInteractionEnabled(true);
} else {
} else if (!this.ai_disabled) {
this.view.playAI();
} else {
this.view.applyAction(EndTurnAction.SINGLETON);
}
} else {
this.view.setInteractionEnabled(false);