Added permanent effects on attributes for equipement
This commit is contained in:
parent
135609002c
commit
5f1913da6d
|
@ -39,15 +39,25 @@ module SpaceTac.Game {
|
||||||
current: number;
|
current: number;
|
||||||
|
|
||||||
// Create an attribute
|
// Create an attribute
|
||||||
constructor(code: AttributeCode, maximal: number = 1, current: number = 0) {
|
constructor(code: AttributeCode = AttributeCode.Misc, maximal: number = null, current: number = 0) {
|
||||||
this.code = code;
|
this.code = code;
|
||||||
this.maximal = maximal;
|
this.maximal = maximal;
|
||||||
this.current = current;
|
this.current = current;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Iterator over each code
|
||||||
|
static forEachCode(callback: (code: AttributeCode) => void) {
|
||||||
|
for (var val in AttributeCode) {
|
||||||
|
if (!isNaN(val)) {
|
||||||
|
callback(<AttributeCode>parseInt(val, 10));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Set the maximal value
|
// Set the maximal value
|
||||||
setMaximal(value: number): void {
|
setMaximal(value: number): void {
|
||||||
this.maximal = value;
|
this.maximal = value;
|
||||||
|
this.fix();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set an absolute value
|
// Set an absolute value
|
||||||
|
@ -70,7 +80,7 @@ module SpaceTac.Game {
|
||||||
|
|
||||||
// Fix the value to remain lower than maximal, and positive
|
// Fix the value to remain lower than maximal, and positive
|
||||||
private fix(): void {
|
private fix(): void {
|
||||||
if (this.current > this.maximal) {
|
if (this.maximal !== null && this.current > this.maximal) {
|
||||||
this.current = this.maximal;
|
this.current = this.maximal;
|
||||||
}
|
}
|
||||||
if (this.current < 0.0001) {
|
if (this.current < 0.0001) {
|
||||||
|
|
57
src/scripts/game/AttributeCollection.ts
Normal file
57
src/scripts/game/AttributeCollection.ts
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
module SpaceTac.Game {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
// Collection of several attributes
|
||||||
|
export class AttributeCollection {
|
||||||
|
// Attributes
|
||||||
|
private attributes: Attribute[];
|
||||||
|
|
||||||
|
// Base constructor
|
||||||
|
constructor() {
|
||||||
|
this.attributes = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get or create an attribute by its code
|
||||||
|
getRawAttr(code: AttributeCode): Attribute {
|
||||||
|
var attr = this.attributes[code];
|
||||||
|
if (!attr) {
|
||||||
|
attr = new Attribute(code);
|
||||||
|
this.attributes[code] = attr;
|
||||||
|
}
|
||||||
|
return attr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get an attribute value
|
||||||
|
getValue(attrcode: AttributeCode): number {
|
||||||
|
var attr = this.getRawAttr(attrcode);
|
||||||
|
return attr.current;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set an attribute value
|
||||||
|
setValue(attrcode: AttributeCode, value: number): number {
|
||||||
|
var attr = this.getRawAttr(attrcode);
|
||||||
|
attr.set(value);
|
||||||
|
return attr.current;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add an offset to an attribute value
|
||||||
|
addValue(attrcode: AttributeCode, offset: number): number {
|
||||||
|
var attr = this.getRawAttr(attrcode);
|
||||||
|
attr.add(offset);
|
||||||
|
return attr.current;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get an attribute maximum
|
||||||
|
getMaximum(attrcode: AttributeCode): number {
|
||||||
|
var attr = this.getRawAttr(attrcode);
|
||||||
|
return attr.maximal;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set an attribute maximum
|
||||||
|
setMaximum(attrcode: AttributeCode, value: number): number {
|
||||||
|
var attr = this.getRawAttr(attrcode);
|
||||||
|
attr.setMaximal(value);
|
||||||
|
return attr.maximal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -26,5 +26,13 @@ module SpaceTac.Game {
|
||||||
|
|
||||||
// Action associated with this equipment
|
// Action associated with this equipment
|
||||||
action: BaseAction;
|
action: BaseAction;
|
||||||
|
|
||||||
|
// Permanent effects
|
||||||
|
permanent_effects: BaseEffect[];
|
||||||
|
|
||||||
|
// Basic constructor
|
||||||
|
constructor() {
|
||||||
|
this.permanent_effects = [];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,14 +46,18 @@ module SpaceTac.Game {
|
||||||
// List of slots, able to contain equipment
|
// List of slots, able to contain equipment
|
||||||
slots: Slot[];
|
slots: Slot[];
|
||||||
|
|
||||||
|
// Collection of available attributes
|
||||||
|
attributes: AttributeCollection;
|
||||||
|
|
||||||
// Create a new ship inside a fleet
|
// Create a new ship inside a fleet
|
||||||
constructor(fleet: Fleet = null, name: string = null) {
|
constructor(fleet: Fleet = null, name: string = null) {
|
||||||
|
this.attributes = new AttributeCollection();
|
||||||
this.fleet = fleet;
|
this.fleet = fleet;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.initiative_level = 1;
|
this.initiative_level = 1;
|
||||||
this.ap_current = new Attribute(AttributeCode.AP);
|
this.ap_current = this.newAttribute(AttributeCode.AP);
|
||||||
this.ap_initial = new Attribute(AttributeCode.AP_Initial);
|
this.ap_initial = this.newAttribute(AttributeCode.AP_Initial);
|
||||||
this.ap_recover = new Attribute(AttributeCode.AP_Recovery);
|
this.ap_recover = this.newAttribute(AttributeCode.AP_Recovery);
|
||||||
this.movement_cost = 0.1;
|
this.movement_cost = 0.1;
|
||||||
this.slots = [];
|
this.slots = [];
|
||||||
|
|
||||||
|
@ -62,6 +66,11 @@ module SpaceTac.Game {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create and register an attribute
|
||||||
|
newAttribute(code: AttributeCode): Attribute {
|
||||||
|
return this.attributes.getRawAttr(code);
|
||||||
|
}
|
||||||
|
|
||||||
// Set position in the arena
|
// Set position in the arena
|
||||||
// This does not consumes action points
|
// This does not consumes action points
|
||||||
setArenaPosition(x: number, y: number) {
|
setArenaPosition(x: number, y: number) {
|
||||||
|
@ -207,5 +216,38 @@ module SpaceTac.Game {
|
||||||
this.slots.push(result);
|
this.slots.push(result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update attributes, taking into account attached equipment and active effects
|
||||||
|
updateAttributes(): void {
|
||||||
|
// TODO Something more generic
|
||||||
|
|
||||||
|
// Compute new maximal values for all attributes
|
||||||
|
var new_attrs = new AttributeCollection();
|
||||||
|
this.collectEffects("attrmax").forEach((effect: AttributeMaxEffect) => {
|
||||||
|
new_attrs.addValue(effect.attrcode, effect.value);
|
||||||
|
});
|
||||||
|
var old_attrs = this.attributes;
|
||||||
|
Attribute.forEachCode((code: AttributeCode) => {
|
||||||
|
old_attrs.setMaximum(code, new_attrs.getValue(code));
|
||||||
|
});
|
||||||
|
console.log(old_attrs, new_attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Collect all effects to apply for updateAttributes
|
||||||
|
private collectEffects(code: string = null): BaseEffect[] {
|
||||||
|
var result: BaseEffect[] = [];
|
||||||
|
|
||||||
|
this.slots.forEach((slot: Slot) => {
|
||||||
|
if (slot.attached) {
|
||||||
|
slot.attached.permanent_effects.forEach((effect: BaseEffect) => {
|
||||||
|
if (effect.code === code) {
|
||||||
|
result.push(effect);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
22
src/scripts/game/effects/AttributeMaxEffect.ts
Normal file
22
src/scripts/game/effects/AttributeMaxEffect.ts
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
/// <reference path="BaseEffect.ts"/>
|
||||||
|
|
||||||
|
module SpaceTac.Game {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
// Effect on attribute maximum
|
||||||
|
// Typically, these effects are summed up to define an attribute maximum
|
||||||
|
export class AttributeMaxEffect extends BaseEffect {
|
||||||
|
// Affected attribute
|
||||||
|
attrcode: AttributeCode;
|
||||||
|
|
||||||
|
// Value to add to the maximum
|
||||||
|
value: number;
|
||||||
|
|
||||||
|
constructor(attrcode: AttributeCode, value: number) {
|
||||||
|
super("attrmax");
|
||||||
|
|
||||||
|
this.attrcode = attrcode;
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
15
src/scripts/game/effects/BaseEffect.ts
Normal file
15
src/scripts/game/effects/BaseEffect.ts
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
module SpaceTac.Game {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
// Base class for effects of actions
|
||||||
|
// Effects can be permanent or temporary (for a number of turns)
|
||||||
|
export class BaseEffect {
|
||||||
|
// Identifier code for the type of effect
|
||||||
|
code: string;
|
||||||
|
|
||||||
|
// Base constructor
|
||||||
|
constructor(code: string) {
|
||||||
|
this.code = code;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,6 +4,29 @@ module SpaceTac.Game {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
describe("Attribute", function () {
|
describe("Attribute", function () {
|
||||||
|
it("is initially not limited", function () {
|
||||||
|
var attr = new Attribute();
|
||||||
|
|
||||||
|
attr.set(8888888);
|
||||||
|
expect(attr.current).toBe(8888888);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("enumerates codes", function () {
|
||||||
|
var result = [];
|
||||||
|
Attribute.forEachCode((code: AttributeCode) => {
|
||||||
|
result.push(code);
|
||||||
|
});
|
||||||
|
expect(result).toEqual([
|
||||||
|
AttributeCode.Initiative,
|
||||||
|
AttributeCode.Hull,
|
||||||
|
AttributeCode.Shield,
|
||||||
|
AttributeCode.AP,
|
||||||
|
AttributeCode.AP_Recovery,
|
||||||
|
AttributeCode.AP_Initial,
|
||||||
|
AttributeCode.Misc
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
it("applies minimal and maximal value", function () {
|
it("applies minimal and maximal value", function () {
|
||||||
var attr = new Attribute(AttributeCode.Misc, 100, 50);
|
var attr = new Attribute(AttributeCode.Misc, 100, 50);
|
||||||
expect(attr.current).toBe(50);
|
expect(attr.current).toBe(50);
|
||||||
|
@ -28,6 +51,12 @@ module SpaceTac.Game {
|
||||||
|
|
||||||
attr.set(105);
|
attr.set(105);
|
||||||
expect(attr.current).toBe(100);
|
expect(attr.current).toBe(100);
|
||||||
|
|
||||||
|
attr.setMaximal(50);
|
||||||
|
expect(attr.current).toBe(50);
|
||||||
|
|
||||||
|
attr.setMaximal(80);
|
||||||
|
expect(attr.current).toBe(50);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("tells if value changed", function () {
|
it("tells if value changed", function () {
|
||||||
|
|
29
src/scripts/game/specs/AttributeCollection.spec.ts
Normal file
29
src/scripts/game/specs/AttributeCollection.spec.ts
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
/// <reference path="../../definitions/jasmine.d.ts"/>
|
||||||
|
|
||||||
|
module SpaceTac.Game {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
describe("AttributeCollection", function () {
|
||||||
|
it("sets and gets an attribute value", function () {
|
||||||
|
var coll = new AttributeCollection();
|
||||||
|
|
||||||
|
coll.setValue(AttributeCode.Initiative, 5);
|
||||||
|
expect(coll.getValue(AttributeCode.Initiative)).toBe(5);
|
||||||
|
|
||||||
|
expect(coll.getValue(AttributeCode.Hull)).toBe(0);
|
||||||
|
coll.setValue(AttributeCode.Hull, 2);
|
||||||
|
expect(coll.getValue(AttributeCode.Hull)).toBe(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("sets and gets an attribute maximal", function () {
|
||||||
|
var coll = new AttributeCollection();
|
||||||
|
|
||||||
|
coll.setMaximum(AttributeCode.Initiative, 5);
|
||||||
|
expect(coll.getMaximum(AttributeCode.Initiative)).toBe(5);
|
||||||
|
|
||||||
|
expect(coll.getMaximum(AttributeCode.Hull)).toBe(null);
|
||||||
|
coll.setMaximum(AttributeCode.Hull, 2);
|
||||||
|
expect(coll.getMaximum(AttributeCode.Hull)).toBe(2);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
|
@ -57,5 +57,24 @@ module SpaceTac.Game {
|
||||||
expect(actions[0].code).toEqual("move");
|
expect(actions[0].code).toEqual("move");
|
||||||
expect(actions[1].code).toEqual("endturn");
|
expect(actions[1].code).toEqual("endturn");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("applies permanent effects of equipments on attributes", function () {
|
||||||
|
var ship = new Ship(null, "Test");
|
||||||
|
var slot: Slot;
|
||||||
|
var equipment: Equipment;
|
||||||
|
|
||||||
|
slot = ship.addSlot(SlotType.Power);
|
||||||
|
equipment = new Equipment();
|
||||||
|
equipment.permanent_effects.push(new AttributeMaxEffect(AttributeCode.AP, 4));
|
||||||
|
slot.attach(equipment);
|
||||||
|
|
||||||
|
slot = ship.addSlot(SlotType.Power);
|
||||||
|
equipment = new Equipment();
|
||||||
|
equipment.permanent_effects.push(new AttributeMaxEffect(AttributeCode.AP, 5));
|
||||||
|
slot.attach(equipment);
|
||||||
|
|
||||||
|
ship.updateAttributes();
|
||||||
|
expect(ship.ap_current.maximal).toBe(9);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue