Added sticky temporary effects, and EnergyDepleter weapon (WIP)
This commit is contained in:
parent
f01a9059e9
commit
b89c443f13
|
@ -147,6 +147,15 @@ module SpaceTac.Game {
|
|||
this.target_effects.push(template);
|
||||
}
|
||||
|
||||
// Convenience function to add a sticking effect on target
|
||||
addTemporaryEffectOnTarget(effect: TemporaryEffect, min_value: number, max_value: number = null,
|
||||
min_duration: number = 1, max_duration: number = null): void {
|
||||
var template = new EffectTemplate(effect);
|
||||
template.addModifier("value", new Range(min_value, max_value));
|
||||
template.addModifier("duration", new Range(min_duration, max_duration));
|
||||
this.target_effects.push(template);
|
||||
}
|
||||
|
||||
// Method to reimplement to assign an action to a generated equipment
|
||||
protected getActionForEquipment(equipment: Equipment): BaseAction {
|
||||
return null;
|
||||
|
|
|
@ -37,6 +37,9 @@ module SpaceTac.Game {
|
|||
// Number of shield points (a shield can absorb some damage to protect the hull)
|
||||
shield: Attribute;
|
||||
|
||||
// Sticky temporary effects
|
||||
temporary_effects: TemporaryEffect[];
|
||||
|
||||
// Capabilities level
|
||||
cap_material: Attribute;
|
||||
cap_energy: Attribute;
|
||||
|
@ -70,6 +73,7 @@ module SpaceTac.Game {
|
|||
this.cap_human = this.newAttribute(AttributeCode.Cap_Human);
|
||||
this.cap_time = this.newAttribute(AttributeCode.Cap_Time);
|
||||
this.cap_gravity = this.newAttribute(AttributeCode.Cap_Gravity);
|
||||
this.temporary_effects = [];
|
||||
this.slots = [];
|
||||
|
||||
this.arena_x = 0;
|
||||
|
@ -200,7 +204,7 @@ module SpaceTac.Game {
|
|||
}
|
||||
|
||||
// Method called at the start of this ship turn
|
||||
startTurn(first: boolean): void {
|
||||
startTurn(first: boolean = false): void {
|
||||
// Recompute attributes
|
||||
this.updateAttributes();
|
||||
|
||||
|
@ -210,6 +214,22 @@ module SpaceTac.Game {
|
|||
} else {
|
||||
this.recoverActionPoints();
|
||||
}
|
||||
|
||||
// Apply sticky effects
|
||||
this.temporary_effects.forEach((effect: TemporaryEffect) => {
|
||||
effect.singleApply(this, false);
|
||||
});
|
||||
}
|
||||
|
||||
// Method called at the end of this ship turn
|
||||
endTurn(): void {
|
||||
// Decrement sticky effects duration
|
||||
this.temporary_effects.forEach((effect: TemporaryEffect) => {
|
||||
effect.duration -= 1;
|
||||
});
|
||||
this.temporary_effects = this.temporary_effects.filter((effect: TemporaryEffect): boolean => {
|
||||
return effect.duration > 0;
|
||||
});
|
||||
}
|
||||
|
||||
// Move toward a location
|
||||
|
|
36
src/scripts/game/TestTools.ts
Normal file
36
src/scripts/game/TestTools.ts
Normal file
|
@ -0,0 +1,36 @@
|
|||
module SpaceTac.Game {
|
||||
"use strict";
|
||||
|
||||
// unit testing utilities
|
||||
export class TestTools {
|
||||
// Set a ship action points, adding/updating an equipment if needed
|
||||
static setShipAP(ship: Ship, points: number, recovery: number) {
|
||||
var powers = ship.listEquipment(SlotType.Power);
|
||||
var equipment: Equipment;
|
||||
if (powers.length === 0) {
|
||||
equipment = (new Equipments.BasicPowerCore()).generateFixed(0);
|
||||
ship.addSlot(SlotType.Power).attach(equipment);
|
||||
} else {
|
||||
equipment = powers[0];
|
||||
}
|
||||
|
||||
equipment.permanent_effects.forEach((effect: BaseEffect) => {
|
||||
if (effect.code === "attrmax") {
|
||||
var meffect = <AttributeMaxEffect>effect;
|
||||
if (meffect.attrcode === AttributeCode.AP) {
|
||||
meffect.value = points;
|
||||
}
|
||||
} else if (effect.code === "attr") {
|
||||
var veffect = <AttributeValueEffect>effect;
|
||||
if (veffect.attrcode === AttributeCode.AP_Recovery) {
|
||||
veffect.value = recovery;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
ship.ap_current.setMaximal(points);
|
||||
ship.ap_current.set(points);
|
||||
ship.ap_recover.set(recovery);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,6 +8,7 @@ module SpaceTac.Game {
|
|||
}
|
||||
|
||||
protected customApply(battle: Battle, ship: Ship, target: Target): boolean {
|
||||
ship.endTurn();
|
||||
battle.advanceToNextShip();
|
||||
return true;
|
||||
}
|
||||
|
|
29
src/scripts/game/effects/AttributeLimitEffect.ts
Normal file
29
src/scripts/game/effects/AttributeLimitEffect.ts
Normal file
|
@ -0,0 +1,29 @@
|
|||
/// <reference path="TemporaryEffect.ts"/>
|
||||
|
||||
module SpaceTac.Game {
|
||||
"use strict";
|
||||
|
||||
// Hard limitation on attribute value
|
||||
// For example, this could be used to slow a target by limiting its action points
|
||||
export class AttributeLimitEffect extends TemporaryEffect {
|
||||
// Affected attribute
|
||||
attrcode: AttributeCode;
|
||||
|
||||
// Limit of the attribute value
|
||||
value: number;
|
||||
|
||||
constructor(attrcode: AttributeCode, duration: number = 0, value: number = 0) {
|
||||
super("attrlimit", duration);
|
||||
|
||||
this.attrcode = attrcode;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
singleApply(ship: Ship, on_stick: boolean): void {
|
||||
var current = ship.attributes.getValue(this.attrcode);
|
||||
if (current > this.value) {
|
||||
ship.setAttribute(ship.attributes.getRawAttr(this.attrcode), this.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
30
src/scripts/game/effects/TemporaryEffect.ts
Normal file
30
src/scripts/game/effects/TemporaryEffect.ts
Normal file
|
@ -0,0 +1,30 @@
|
|||
/// <reference path="BaseEffect.ts"/>
|
||||
|
||||
module SpaceTac.Game {
|
||||
"use strict";
|
||||
|
||||
// Base class for actions that will stick to a target for a number of rounds
|
||||
export class TemporaryEffect extends BaseEffect {
|
||||
// Duration, in number of turns
|
||||
duration: number;
|
||||
|
||||
// Base constructor
|
||||
constructor(code: string, duration: number = 0) {
|
||||
super(code);
|
||||
|
||||
this.duration = duration;
|
||||
}
|
||||
|
||||
applyOnShip(ship: Ship): boolean {
|
||||
ship.temporary_effects.push(Tools.copyObject(this));
|
||||
this.singleApply(ship, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Method to implement to apply the effect ponctually
|
||||
// on_stick is true when this is called by applyOnShip, and false when called at turn start
|
||||
singleApply(ship: Ship, on_stick: boolean): void {
|
||||
// Abstract
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,7 +8,7 @@ module SpaceTac.Game.Equipments {
|
|||
// Boolean set to true if the weapon can target space
|
||||
can_target_space: boolean;
|
||||
|
||||
constructor(name: string, min_damage: number, max_damage: number = null) {
|
||||
constructor(name: string, min_damage: number = 0, max_damage: number = null) {
|
||||
super(SlotType.Weapon, name);
|
||||
|
||||
this.can_target_space = false;
|
||||
|
|
18
src/scripts/game/equipments/EnergyDepleter.ts
Normal file
18
src/scripts/game/equipments/EnergyDepleter.ts
Normal file
|
@ -0,0 +1,18 @@
|
|||
/// <reference path="AbstractWeapon.ts"/>
|
||||
|
||||
module SpaceTac.Game.Equipments {
|
||||
"use strict";
|
||||
|
||||
export class EnergyDepleter extends AbstractWeapon {
|
||||
constructor() {
|
||||
super("Energy Depleter");
|
||||
|
||||
this.setRange(200, 300, false);
|
||||
|
||||
this.ap_usage = new Range(4, 5);
|
||||
this.min_level = new IntegerRange(1, 3);
|
||||
|
||||
this.addTemporaryEffectOnTarget(new AttributeLimitEffect(AttributeCode.AP), 4, 3, 1, 2);
|
||||
}
|
||||
}
|
||||
}
|
50
src/scripts/game/equipments/specs/EnergyDepleter.spec.ts
Normal file
50
src/scripts/game/equipments/specs/EnergyDepleter.spec.ts
Normal file
|
@ -0,0 +1,50 @@
|
|||
/// <reference path="../../../definitions/jasmine.d.ts"/>
|
||||
/// <reference path="../EnergyDepleter.ts"/>
|
||||
|
||||
module SpaceTac.Game.Specs {
|
||||
"use strict";
|
||||
|
||||
describe("EnergyDepleter", () => {
|
||||
it("limits target's AP", () => {
|
||||
var template = new Equipments.EnergyDepleter();
|
||||
var equipment = template.generateFixed(0);
|
||||
|
||||
var ship = new Ship();
|
||||
var target = new Ship();
|
||||
TestTools.setShipAP(target, 7, 2);
|
||||
spyOn(equipment.action, "canBeUsed").and.returnValue(true);
|
||||
|
||||
expect(target.ap_current.current).toBe(7);
|
||||
expect(target.temporary_effects).toEqual([]);
|
||||
|
||||
// Attribute is immediately limited
|
||||
equipment.action.apply(null, ship, Target.newFromShip(target));
|
||||
|
||||
expect(target.ap_current.current).toBe(4);
|
||||
expect(target.temporary_effects).toEqual([
|
||||
new AttributeLimitEffect(AttributeCode.AP, 1, 4)
|
||||
]);
|
||||
|
||||
// Attribute is limited for one turn, and prevents AP recovery
|
||||
target.ap_current.set(6);
|
||||
target.startTurn();
|
||||
|
||||
expect(target.ap_current.current).toBe(4);
|
||||
expect(target.temporary_effects).toEqual([
|
||||
new AttributeLimitEffect(AttributeCode.AP, 1, 4)
|
||||
]);
|
||||
|
||||
target.endTurn();
|
||||
expect(target.ap_current.current).toBe(4);
|
||||
expect(target.temporary_effects).toEqual([]);
|
||||
|
||||
// Attribute vanishes before the start of next turn, so AP recovery happens
|
||||
target.startTurn();
|
||||
|
||||
expect(target.ap_current.current).toBe(6);
|
||||
expect(target.temporary_effects).toEqual([]);
|
||||
|
||||
target.endTurn();
|
||||
});
|
||||
});
|
||||
}
|
Loading…
Reference in a new issue