Added damage effect mode
This commit is contained in:
parent
6443f9afda
commit
9f81b4c992
2
TODO.md
2
TODO.md
|
@ -32,6 +32,7 @@ Battle
|
||||||
------
|
------
|
||||||
|
|
||||||
* Fix stats only filling for one fleet
|
* Fix stats only filling for one fleet
|
||||||
|
* Display shield (and its (dis)appearance)
|
||||||
* Add a voluntary retreat option
|
* Add a voluntary retreat option
|
||||||
* Toggle bar/text display in power section of action bar
|
* Toggle bar/text display in power section of action bar
|
||||||
* Show a cooldown indicator on move action icon, if the simulation would cause the engine to overheat
|
* Show a cooldown indicator on move action icon, if the simulation would cause the engine to overheat
|
||||||
|
@ -65,7 +66,6 @@ Ships models and actions
|
||||||
* Add damage on collisions (when two ships are moved to the same place)
|
* Add damage on collisions (when two ships are moved to the same place)
|
||||||
* Add hull points to drones and make them take area damage
|
* Add hull points to drones and make them take area damage
|
||||||
* Allow to customize effects based on whether a target is enemy, allied or self
|
* Allow to customize effects based on whether a target is enemy, allied or self
|
||||||
* Add damage mode: shield / shield or hull / shield then hull / hull
|
|
||||||
* Add pinned effect (cannot be moved)
|
* Add pinned effect (cannot be moved)
|
||||||
* Add a reflect damage effect
|
* Add a reflect damage effect
|
||||||
* Add untargettable effect (can only be targetted with area effects)
|
* Add untargettable effect (can only be targetted with area effects)
|
||||||
|
|
|
@ -35,7 +35,7 @@ module TK.SpaceTac {
|
||||||
*/
|
*/
|
||||||
static addWeapon(ship: Ship, damage = 100, power_usage = 1, max_distance = 100, blast = 0, angle = 0): TriggerAction {
|
static addWeapon(ship: Ship, damage = 100, power_usage = 1, max_distance = 100, blast = 0, angle = 0): TriggerAction {
|
||||||
let action = new TriggerAction("Weapon", {
|
let action = new TriggerAction("Weapon", {
|
||||||
effects: [new DamageEffect(damage)],
|
effects: [new DamageEffect(damage, DamageEffectMode.SHIELD_THEN_HULL)],
|
||||||
power: power_usage,
|
power: power_usage,
|
||||||
range: max_distance,
|
range: max_distance,
|
||||||
blast: blast,
|
blast: blast,
|
||||||
|
|
|
@ -1,5 +1,26 @@
|
||||||
module TK.SpaceTac.Specs {
|
module TK.SpaceTac.Specs {
|
||||||
testing("DamageEffect", test => {
|
testing("DamageEffect", test => {
|
||||||
|
test.case("computes shield and hull damage, according to mode", check => {
|
||||||
|
let ship = new Ship();
|
||||||
|
TestTools.setShipModel(ship, 2, 3);
|
||||||
|
|
||||||
|
check.equals(new DamageEffect(1, DamageEffectMode.HULL_ONLY).getEffectiveDamage(ship), new ShipDamageDiff(ship, 1, 0, 1), "hull 1");
|
||||||
|
check.equals(new DamageEffect(3, DamageEffectMode.HULL_ONLY).getEffectiveDamage(ship), new ShipDamageDiff(ship, 2, 0, 3), "hull 3");
|
||||||
|
|
||||||
|
check.equals(new DamageEffect(1, DamageEffectMode.SHIELD_ONLY).getEffectiveDamage(ship), new ShipDamageDiff(ship, 0, 1, 1), "shield 1");
|
||||||
|
check.equals(new DamageEffect(4, DamageEffectMode.SHIELD_ONLY).getEffectiveDamage(ship), new ShipDamageDiff(ship, 0, 3, 4), "shield 4");
|
||||||
|
|
||||||
|
check.equals(new DamageEffect(1, DamageEffectMode.SHIELD_THEN_HULL).getEffectiveDamage(ship), new ShipDamageDiff(ship, 0, 1, 1), "piercing 1");
|
||||||
|
check.equals(new DamageEffect(4, DamageEffectMode.SHIELD_THEN_HULL).getEffectiveDamage(ship), new ShipDamageDiff(ship, 1, 3, 4), "piercing 4");
|
||||||
|
check.equals(new DamageEffect(8, DamageEffectMode.SHIELD_THEN_HULL).getEffectiveDamage(ship), new ShipDamageDiff(ship, 2, 3, 8), "piercing 8");
|
||||||
|
|
||||||
|
check.equals(new DamageEffect(1, DamageEffectMode.SHIELD_OR_HULL).getEffectiveDamage(ship), new ShipDamageDiff(ship, 0, 1, 1), "normal 1");
|
||||||
|
check.equals(new DamageEffect(4, DamageEffectMode.SHIELD_OR_HULL).getEffectiveDamage(ship), new ShipDamageDiff(ship, 0, 3, 4), "normal 4");
|
||||||
|
ship.setValue("shield", 0);
|
||||||
|
check.equals(new DamageEffect(1, DamageEffectMode.SHIELD_OR_HULL).getEffectiveDamage(ship), new ShipDamageDiff(ship, 1, 0, 1), "normal no shield 1");
|
||||||
|
check.equals(new DamageEffect(4, DamageEffectMode.SHIELD_OR_HULL).getEffectiveDamage(ship), new ShipDamageDiff(ship, 2, 0, 4), "normal no shield 4");
|
||||||
|
});
|
||||||
|
|
||||||
test.case("applies damage", check => {
|
test.case("applies damage", check => {
|
||||||
let battle = new Battle();
|
let battle = new Battle();
|
||||||
let ship = battle.fleets[0].addShip();
|
let ship = battle.fleets[0].addShip();
|
||||||
|
@ -14,21 +35,24 @@ module TK.SpaceTac.Specs {
|
||||||
|
|
||||||
checkValues("initial", 150, 400);
|
checkValues("initial", 150, 400);
|
||||||
|
|
||||||
battle.applyDiffs(new DamageEffect(50).getOnDiffs(ship, ship));
|
battle.applyDiffs(new DamageEffect(50, DamageEffectMode.SHIELD_THEN_HULL).getOnDiffs(ship, ship));
|
||||||
checkValues("after 50 damage", 150, 350);
|
checkValues("after 50 damage", 150, 350);
|
||||||
|
|
||||||
battle.applyDiffs(new DamageEffect(250).getOnDiffs(ship, ship));
|
battle.applyDiffs(new DamageEffect(250, DamageEffectMode.SHIELD_THEN_HULL).getOnDiffs(ship, ship));
|
||||||
checkValues("after 250 damage", 150, 100);
|
checkValues("after 250 damage", 150, 100);
|
||||||
|
|
||||||
battle.applyDiffs(new DamageEffect(201).getOnDiffs(ship, ship));
|
battle.applyDiffs(new DamageEffect(201, DamageEffectMode.SHIELD_THEN_HULL).getOnDiffs(ship, ship));
|
||||||
checkValues("after 201 damage", 49, 0);
|
checkValues("after 201 damage", 49, 0);
|
||||||
|
|
||||||
battle.applyDiffs(new DamageEffect(8000).getOnDiffs(ship, ship));
|
battle.applyDiffs(new DamageEffect(8000, DamageEffectMode.SHIELD_THEN_HULL).getOnDiffs(ship, ship));
|
||||||
checkValues("after 8000 damage", 0, 0);
|
checkValues("after 8000 damage", 0, 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
test.case("gets a textual description", check => {
|
test.case("gets a textual description", check => {
|
||||||
check.equals(new DamageEffect(10).getDescription(), "do 10 damage");
|
check.equals(new DamageEffect(10).getDescription(), "do 10 damage");
|
||||||
|
check.equals(new DamageEffect(10, DamageEffectMode.HULL_ONLY).getDescription(), "do 10 hull damage");
|
||||||
|
check.equals(new DamageEffect(10, DamageEffectMode.SHIELD_ONLY).getDescription(), "do 10 shield damage");
|
||||||
|
check.equals(new DamageEffect(10, DamageEffectMode.SHIELD_THEN_HULL).getDescription(), "do 10 piercing damage");
|
||||||
});
|
});
|
||||||
|
|
||||||
test.case("applies damage modifiers", check => {
|
test.case("applies damage modifiers", check => {
|
||||||
|
|
|
@ -1,19 +1,35 @@
|
||||||
/// <reference path="BaseEffect.ts"/>
|
/// <reference path="BaseEffect.ts"/>
|
||||||
|
|
||||||
module TK.SpaceTac {
|
module TK.SpaceTac {
|
||||||
|
/**
|
||||||
|
* Mode for damage effect
|
||||||
|
*/
|
||||||
|
export enum DamageEffectMode {
|
||||||
|
// Apply on shield only
|
||||||
|
SHIELD_ONLY,
|
||||||
|
// Apply on shield, then remaining value on hull
|
||||||
|
SHIELD_THEN_HULL,
|
||||||
|
// Apply on shield only if up, otherwise on hull
|
||||||
|
SHIELD_OR_HULL,
|
||||||
|
// Apply on hull only
|
||||||
|
HULL_ONLY
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Apply damage on a ship.
|
* Apply damage on a ship.
|
||||||
*
|
|
||||||
* Damage is applied on shield while there is some, then on the hull.
|
|
||||||
*/
|
*/
|
||||||
export class DamageEffect extends BaseEffect {
|
export class DamageEffect extends BaseEffect {
|
||||||
// Base damage points
|
// Damage amount
|
||||||
value: number
|
value: number
|
||||||
|
|
||||||
constructor(value = 0) {
|
// Damage mode
|
||||||
|
mode: DamageEffectMode
|
||||||
|
|
||||||
|
constructor(value: number, mode = DamageEffectMode.SHIELD_OR_HULL) {
|
||||||
super("damage");
|
super("damage");
|
||||||
|
|
||||||
this.value = value;
|
this.value = value;
|
||||||
|
this.mode = mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -33,18 +49,31 @@ module TK.SpaceTac {
|
||||||
* Get the effective damage done to both shield and hull (in this order)
|
* Get the effective damage done to both shield and hull (in this order)
|
||||||
*/
|
*/
|
||||||
getEffectiveDamage(ship: Ship): ShipDamageDiff {
|
getEffectiveDamage(ship: Ship): ShipDamageDiff {
|
||||||
|
let shield = ship.getValue("shield");
|
||||||
|
let hull = ship.getValue("hull");
|
||||||
|
let dhull = 0;
|
||||||
|
let dshield = 0;
|
||||||
|
|
||||||
// Apply modifiers
|
// Apply modifiers
|
||||||
let theoritical = Math.round(this.value * this.getFactor(ship));
|
let damage = Math.round(this.value * this.getFactor(ship));
|
||||||
let damage = theoritical;
|
|
||||||
|
|
||||||
// Apply on shields
|
// Split in shield/hull damage
|
||||||
let shield = (damage >= ship.getValue("shield")) ? ship.getValue("shield") : damage;
|
if (this.mode == DamageEffectMode.HULL_ONLY) {
|
||||||
damage -= shield;
|
dhull = Math.min(damage, hull);
|
||||||
|
} else if (this.mode == DamageEffectMode.SHIELD_ONLY) {
|
||||||
|
dshield = Math.min(damage, shield);
|
||||||
|
} else if (this.mode == DamageEffectMode.SHIELD_OR_HULL) {
|
||||||
|
if (shield) {
|
||||||
|
dshield = Math.min(damage, shield);
|
||||||
|
} else {
|
||||||
|
dhull = Math.min(damage, hull);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
dshield = Math.min(damage, shield);
|
||||||
|
dhull = Math.min(damage - dshield, hull);
|
||||||
|
}
|
||||||
|
|
||||||
// Apply on hull
|
return new ShipDamageDiff(ship, dhull, dshield, damage);
|
||||||
let hull = (damage >= ship.getValue("hull")) ? ship.getValue("hull") : damage;
|
|
||||||
|
|
||||||
return new ShipDamageDiff(ship, hull, shield, theoritical);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getOnDiffs(ship: Ship, source: Ship | Drone): BaseBattleDiff[] {
|
getOnDiffs(ship: Ship, source: Ship | Drone): BaseBattleDiff[] {
|
||||||
|
@ -68,7 +97,16 @@ module TK.SpaceTac {
|
||||||
}
|
}
|
||||||
|
|
||||||
getDescription(): string {
|
getDescription(): string {
|
||||||
return `do ${this.value} damage`;
|
let mode = "";
|
||||||
|
if (this.mode == DamageEffectMode.HULL_ONLY) {
|
||||||
|
mode = " hull";
|
||||||
|
} else if (this.mode == DamageEffectMode.SHIELD_ONLY) {
|
||||||
|
mode = " shield";
|
||||||
|
} else if (this.mode == DamageEffectMode.SHIELD_THEN_HULL) {
|
||||||
|
mode = " piercing";
|
||||||
|
}
|
||||||
|
|
||||||
|
return `do ${this.value}${mode} damage`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ module TK.SpaceTac {
|
||||||
engine.configureCooldown(2, 1);
|
engine.configureCooldown(2, 1);
|
||||||
|
|
||||||
let gatling = new TriggerAction("Gatling Gun", {
|
let gatling = new TriggerAction("Gatling Gun", {
|
||||||
effects: [new DamageEffect(2)],
|
effects: [new DamageEffect(2, DamageEffectMode.SHIELD_THEN_HULL)],
|
||||||
power: 2,
|
power: 2,
|
||||||
range: 200,
|
range: 200,
|
||||||
}, "gatlinggun");
|
}, "gatlinggun");
|
||||||
|
|
|
@ -17,7 +17,7 @@ module TK.SpaceTac {
|
||||||
});
|
});
|
||||||
|
|
||||||
let laser = new TriggerAction("Wingspan Laser", {
|
let laser = new TriggerAction("Wingspan Laser", {
|
||||||
effects: [new DamageEffect(1)],
|
effects: [new DamageEffect(2, DamageEffectMode.SHIELD_THEN_HULL)],
|
||||||
power: 4,
|
power: 4,
|
||||||
range: 250, angle: 140,
|
range: 250, angle: 140,
|
||||||
}, "prokhorovlaser");
|
}, "prokhorovlaser");
|
||||||
|
|
|
@ -36,8 +36,8 @@ module TK.SpaceTac {
|
||||||
effects: [
|
effects: [
|
||||||
new AttributeEffect("precision", 8),
|
new AttributeEffect("precision", 8),
|
||||||
new AttributeEffect("maneuvrability", 4),
|
new AttributeEffect("maneuvrability", 4),
|
||||||
new AttributeEffect("hull_capacity", 50),
|
new AttributeEffect("hull_capacity", 2),
|
||||||
new AttributeEffect("shield_capacity", 50),
|
new AttributeEffect("shield_capacity", 2),
|
||||||
new AttributeEffect("power_capacity", 9),
|
new AttributeEffect("power_capacity", 9),
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
|
@ -17,7 +17,7 @@ module TK.SpaceTac {
|
||||||
});
|
});
|
||||||
|
|
||||||
let laser = new TriggerAction("Prokhorov Laser", {
|
let laser = new TriggerAction("Prokhorov Laser", {
|
||||||
effects: [new DamageEffect(2)],
|
effects: [new DamageEffect(2, DamageEffectMode.SHIELD_THEN_HULL)],
|
||||||
power: 3,
|
power: 3,
|
||||||
range: 250, angle: 80,
|
range: 250, angle: 80,
|
||||||
});
|
});
|
||||||
|
|
|
@ -50,7 +50,7 @@ module TK.SpaceTac.UI.Specs {
|
||||||
let ship = nn(battleview.battle.playing_ship);
|
let ship = nn(battleview.battle.playing_ship);
|
||||||
ship.setArenaPosition(50, 30);
|
ship.setArenaPosition(50, 30);
|
||||||
|
|
||||||
let weapon = new TriggerAction("weapon", { effects: [new DamageEffect()], range: 500 });
|
let weapon = new TriggerAction("weapon", { effects: [new DamageEffect(1)], range: 500 });
|
||||||
check.patch(weapon, "getImpactedShips", () => [ship]);
|
check.patch(weapon, "getImpactedShips", () => [ship]);
|
||||||
|
|
||||||
let dest = new Ship();
|
let dest = new Ship();
|
||||||
|
|
Loading…
Reference in a new issue