From 3a5e963240cee75b2e0eb5bd186292568d0c4334 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Lemaire?= Date: Thu, 22 Jan 2015 01:00:00 +0100 Subject: [PATCH] Manage AP recovery and initial value with equipment effects --- src/scripts/game/Battle.ts | 10 ++++++ src/scripts/game/BattleLog.ts | 28 ++++++++++++++++- src/scripts/game/LootTemplate.ts | 7 +++++ src/scripts/game/Ship.ts | 18 +++++++---- .../game/effects/AttributeValueEffect.ts | 22 +++++++++++++ src/scripts/game/equipments/BasicPowerCore.ts | 3 ++ src/scripts/game/specs/Battle.spec.ts | 31 +++++++++++++++++++ src/scripts/game/specs/BattleLog.spec.ts | 5 ++- 8 files changed, 116 insertions(+), 8 deletions(-) create mode 100644 src/scripts/game/effects/AttributeValueEffect.ts diff --git a/src/scripts/game/Battle.ts b/src/scripts/game/Battle.ts index 484de19..c44eb85 100644 --- a/src/scripts/game/Battle.ts +++ b/src/scripts/game/Battle.ts @@ -16,6 +16,9 @@ module SpaceTac.Game { playing_ship_index: number; playing_ship: Ship; + // Boolean indicating if its the first turn + first_turn: boolean; + // Create a battle between two fleets constructor(fleet1: Fleet, fleet2: Fleet) { this.log = new BattleLog(); @@ -23,6 +26,7 @@ module SpaceTac.Game { this.play_order = []; this.playing_ship_index = null; this.playing_ship = null; + this.first_turn = true; } // Create a quick random battle, for testing purposes @@ -56,6 +60,7 @@ module SpaceTac.Game { // Defines the initial ship positions of all engaged fleets placeShips(): void { + this.first_turn = true; this.placeFleetShips(this.fleets[0], 100, 100, 0); this.placeFleetShips(this.fleets[1], 300, 100, Math.PI); } @@ -77,10 +82,15 @@ module SpaceTac.Game { } if (this.playing_ship_index >= this.play_order.length) { this.playing_ship_index = 0; + this.first_turn = false; } this.playing_ship = this.play_order[this.playing_ship_index]; } + if (this.playing_ship) { + this.playing_ship.startTurn(this.first_turn); + } + if (log) { this.log.add(new ShipChangeEvent(previous_ship, this.playing_ship)); } diff --git a/src/scripts/game/BattleLog.ts b/src/scripts/game/BattleLog.ts index f575542..45f59d3 100644 --- a/src/scripts/game/BattleLog.ts +++ b/src/scripts/game/BattleLog.ts @@ -11,14 +11,35 @@ module SpaceTac.Game { // List of subscribers private subscribers: Function[]; + // List of event codes to ignore + private filters: string[]; + // Create an initially empty log constructor() { this.events = []; this.subscribers = []; + this.filters = []; + } + + // Clear the stored events + clear(): void { + this.events = []; } // Add a battle event to the log - add(event: BaseLogEvent) { + add(event: BaseLogEvent): void { + // Apply filters + var filtered = false; + this.filters.forEach((code: string) => { + if (event.code === code) { + filtered = true; + return false; + } + }); + if (filtered) { + return; + } + this.events.push(event); this.subscribers.forEach((subscriber: Function) => { @@ -26,6 +47,11 @@ module SpaceTac.Game { }); } + // Filter out a type of event + addFilter(event_code: string): void { + this.filters.push(event_code); + } + // Subscribe a callback to receive further events subscribe(callback: (event: BaseLogEvent) => void): Function { this.subscribers.push(callback); diff --git a/src/scripts/game/LootTemplate.ts b/src/scripts/game/LootTemplate.ts index 94d18e9..bd796cd 100644 --- a/src/scripts/game/LootTemplate.ts +++ b/src/scripts/game/LootTemplate.ts @@ -109,6 +109,13 @@ module SpaceTac.Game { } } + // Convenience function to add a permanent attribute effect on equipment + addPermanentAttributeValueEffect(code: AttributeCode, min: number, max: number = null): void { + var template = new EffectTemplate(new AttributeValueEffect(code, 0)); + template.addModifier("value", new Range(min, max)); + this.permanent_effects.push(template); + } + // Convenience function to add a permanent attribute max effect on equipment addPermanentAttributeMaxEffect(code: AttributeCode, min: number, max: number = null): void { var template = new EffectTemplate(new AttributeMaxEffect(code, 0)); diff --git a/src/scripts/game/Ship.ts b/src/scripts/game/Ship.ts index 8fc833c..6f29cad 100644 --- a/src/scripts/game/Ship.ts +++ b/src/scripts/game/Ship.ts @@ -174,14 +174,15 @@ module SpaceTac.Game { // Method called at the start of this ship turn startTurn(first: boolean): void { + // Recompute attributes + this.updateAttributes(); + // Manage action points if (first) { this.initializeActionPoints(); } else { this.recoverActionPoints(); } - - // TODO Apply active effects } // Get the maximal position reachable in the arena with current action points @@ -221,15 +222,20 @@ module SpaceTac.Game { updateAttributes(): void { // TODO Something more generic - // Compute new maximal values for all attributes + // Compute new maximal values for 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)); + this.ap_current.setMaximal(new_attrs.getValue(AttributeCode.AP)); + + // Compute new current values for attributes + new_attrs = new AttributeCollection(); + this.collectEffects("attr").forEach((effect: AttributeMaxEffect) => { + new_attrs.addValue(effect.attrcode, effect.value); }); + this.ap_initial.set(new_attrs.getValue(AttributeCode.AP_Initial)); + this.ap_recover.set(new_attrs.getValue(AttributeCode.AP_Recovery)); } // Collect all effects to apply for updateAttributes diff --git a/src/scripts/game/effects/AttributeValueEffect.ts b/src/scripts/game/effects/AttributeValueEffect.ts new file mode 100644 index 0000000..86027d9 --- /dev/null +++ b/src/scripts/game/effects/AttributeValueEffect.ts @@ -0,0 +1,22 @@ +/// + +module SpaceTac.Game { + "use strict"; + + // Effect on attribute value + // Typically, these effects are summed up to define an attribute value + export class AttributeValueEffect extends BaseEffect { + // Affected attribute + attrcode: AttributeCode; + + // Value to contribute + value: number; + + constructor(attrcode: AttributeCode, value: number) { + super("attr"); + + this.attrcode = attrcode; + this.value = value; + } + } +} diff --git a/src/scripts/game/equipments/BasicPowerCore.ts b/src/scripts/game/equipments/BasicPowerCore.ts index e64684d..3df4f7e 100644 --- a/src/scripts/game/equipments/BasicPowerCore.ts +++ b/src/scripts/game/equipments/BasicPowerCore.ts @@ -8,7 +8,10 @@ module SpaceTac.Game.Equipments { super(SlotType.Power, "Basic Power Core"); this.min_level = new IntegerRange(1, 1); + this.addPermanentAttributeMaxEffect(AttributeCode.AP, 8); + this.addPermanentAttributeValueEffect(AttributeCode.AP_Initial, 5); + this.addPermanentAttributeValueEffect(AttributeCode.AP_Recovery, 4); } } } diff --git a/src/scripts/game/specs/Battle.spec.ts b/src/scripts/game/specs/Battle.spec.ts index f7cc4a6..9c48215 100644 --- a/src/scripts/game/specs/Battle.spec.ts +++ b/src/scripts/game/specs/Battle.spec.ts @@ -107,5 +107,36 @@ module SpaceTac.Game { expect(battle.playing_ship).toBe(ship2); expect(battle.playing_ship_index).toBe(0); }); + + it("calls startTurn on ships, with first turn indicator", function () { + var fleet1 = new Fleet(null); + var fleet2 = new Fleet(null); + + var ship1 = new Ship(fleet1, "F1S1"); + var ship2 = new Ship(fleet1, "F1S2"); + var ship3 = new Ship(fleet2, "F2S1"); + + var battle = new Battle(fleet1, fleet2); + + spyOn(ship1, "startTurn").and.callThrough(); + spyOn(ship2, "startTurn").and.callThrough(); + spyOn(ship3, "startTurn").and.callThrough(); + + // Force play order + var gen = new RandomGenerator(0.3, 0.2, 0.1); + battle.throwInitiative(gen); + + battle.advanceToNextShip(); + expect(ship1.startTurn).toHaveBeenCalledWith(true); + + battle.advanceToNextShip(); + expect(ship2.startTurn).toHaveBeenCalledWith(true); + + battle.advanceToNextShip(); + expect(ship3.startTurn).toHaveBeenCalledWith(true); + + battle.advanceToNextShip(); + expect(ship1.startTurn).toHaveBeenCalledWith(false); + }); }); } diff --git a/src/scripts/game/specs/BattleLog.spec.ts b/src/scripts/game/specs/BattleLog.spec.ts index 4b5b45f..7e5d1c8 100644 --- a/src/scripts/game/specs/BattleLog.spec.ts +++ b/src/scripts/game/specs/BattleLog.spec.ts @@ -61,6 +61,8 @@ module SpaceTac.Game { it("logs ship change events", function () { var battle = Battle.newQuickRandom(); + battle.log.clear(); + battle.log.addFilter("attr"); expect(battle.log.events.length).toBe(0); battle.advanceToNextShip(); @@ -70,7 +72,8 @@ module SpaceTac.Game { it("can receive simulated initial state events", function () { var battle = Battle.newQuickRandom(); - + battle.log.clear(); + battle.log.addFilter("attr"); expect(battle.log.events.length).toBe(0); battle.injectInitialEvents();