1
0
Fork 0

Added damage effect mode

This commit is contained in:
Michaël Lemaire 2018-03-22 00:52:13 +01:00
parent 6443f9afda
commit 9f81b4c992
9 changed files with 88 additions and 26 deletions

View File

@ -32,6 +32,7 @@ Battle
------
* Fix stats only filling for one fleet
* Display shield (and its (dis)appearance)
* Add a voluntary retreat option
* 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
@ -65,7 +66,6 @@ Ships models and actions
* Add damage on collisions (when two ships are moved to the same place)
* 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
* Add damage mode: shield / shield or hull / shield then hull / hull
* Add pinned effect (cannot be moved)
* Add a reflect damage effect
* Add untargettable effect (can only be targetted with area effects)

View File

@ -35,7 +35,7 @@ module TK.SpaceTac {
*/
static addWeapon(ship: Ship, damage = 100, power_usage = 1, max_distance = 100, blast = 0, angle = 0): TriggerAction {
let action = new TriggerAction("Weapon", {
effects: [new DamageEffect(damage)],
effects: [new DamageEffect(damage, DamageEffectMode.SHIELD_THEN_HULL)],
power: power_usage,
range: max_distance,
blast: blast,

View File

@ -1,5 +1,26 @@
module TK.SpaceTac.Specs {
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 => {
let battle = new Battle();
let ship = battle.fleets[0].addShip();
@ -14,21 +35,24 @@ module TK.SpaceTac.Specs {
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);
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);
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);
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);
});
test.case("gets a textual description", check => {
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 => {

View File

@ -1,19 +1,35 @@
/// <reference path="BaseEffect.ts"/>
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.
*
* Damage is applied on shield while there is some, then on the hull.
*/
export class DamageEffect extends BaseEffect {
// Base damage points
// Damage amount
value: number
constructor(value = 0) {
// Damage mode
mode: DamageEffectMode
constructor(value: number, mode = DamageEffectMode.SHIELD_OR_HULL) {
super("damage");
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)
*/
getEffectiveDamage(ship: Ship): ShipDamageDiff {
let shield = ship.getValue("shield");
let hull = ship.getValue("hull");
let dhull = 0;
let dshield = 0;
// Apply modifiers
let theoritical = Math.round(this.value * this.getFactor(ship));
let damage = theoritical;
let damage = Math.round(this.value * this.getFactor(ship));
// Apply on shields
let shield = (damage >= ship.getValue("shield")) ? ship.getValue("shield") : damage;
damage -= shield;
// Split in shield/hull damage
if (this.mode == DamageEffectMode.HULL_ONLY) {
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
let hull = (damage >= ship.getValue("hull")) ? ship.getValue("hull") : damage;
return new ShipDamageDiff(ship, hull, shield, theoritical);
return new ShipDamageDiff(ship, dhull, dshield, damage);
}
getOnDiffs(ship: Ship, source: Ship | Drone): BaseBattleDiff[] {
@ -68,7 +97,16 @@ module TK.SpaceTac {
}
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`;
}
}
}

View File

@ -19,7 +19,7 @@ module TK.SpaceTac {
engine.configureCooldown(2, 1);
let gatling = new TriggerAction("Gatling Gun", {
effects: [new DamageEffect(2)],
effects: [new DamageEffect(2, DamageEffectMode.SHIELD_THEN_HULL)],
power: 2,
range: 200,
}, "gatlinggun");

View File

@ -17,7 +17,7 @@ module TK.SpaceTac {
});
let laser = new TriggerAction("Wingspan Laser", {
effects: [new DamageEffect(1)],
effects: [new DamageEffect(2, DamageEffectMode.SHIELD_THEN_HULL)],
power: 4,
range: 250, angle: 140,
}, "prokhorovlaser");

View File

@ -36,8 +36,8 @@ module TK.SpaceTac {
effects: [
new AttributeEffect("precision", 8),
new AttributeEffect("maneuvrability", 4),
new AttributeEffect("hull_capacity", 50),
new AttributeEffect("shield_capacity", 50),
new AttributeEffect("hull_capacity", 2),
new AttributeEffect("shield_capacity", 2),
new AttributeEffect("power_capacity", 9),
]
},

View File

@ -17,7 +17,7 @@ module TK.SpaceTac {
});
let laser = new TriggerAction("Prokhorov Laser", {
effects: [new DamageEffect(2)],
effects: [new DamageEffect(2, DamageEffectMode.SHIELD_THEN_HULL)],
power: 3,
range: 250, angle: 80,
});

View File

@ -50,7 +50,7 @@ module TK.SpaceTac.UI.Specs {
let ship = nn(battleview.battle.playing_ship);
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]);
let dest = new Ship();