1
0
Fork 0

Added sticky temporary effects, and EnergyDepleter weapon (WIP)

This commit is contained in:
Michaël Lemaire 2015-02-27 01:00:00 +01:00
parent f01a9059e9
commit b89c443f13
9 changed files with 195 additions and 2 deletions

View file

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

View file

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

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

View file

@ -8,6 +8,7 @@ module SpaceTac.Game {
}
protected customApply(battle: Battle, ship: Ship, target: Target): boolean {
ship.endTurn();
battle.advanceToNextShip();
return true;
}

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

View 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
}
}
}

View file

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

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

View 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();
});
});
}