From e5cd71f4e14aa43b9e216118814722137ba1c48e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Lemaire?= Date: Sun, 12 Feb 2017 23:18:36 +0100 Subject: [PATCH] Display ship values variations in arena --- README.md | 15 +++-- TODO | 3 +- .../battle/attributes/powercapacity.png | Bin 0 -> 9225 bytes src/core/Ship.spec.ts | 4 +- src/core/Ship.ts | 22 +++--- src/core/ShipValue.spec.ts | 20 +++--- src/core/ShipValue.ts | 10 +-- src/core/ai/BullyAI.spec.ts | 12 ++-- src/core/events/ValueChangeEvent.ts | 8 ++- src/ui/Preload.ts | 1 + src/ui/battle/Arena.ts | 11 +-- src/ui/battle/ArenaShip.spec.ts | 24 +++++++ src/ui/battle/ArenaShip.ts | 63 +++++++++--------- src/ui/battle/LogProcessor.ts | 8 +-- src/ui/battle/ShipTooltip.ts | 2 +- 15 files changed, 118 insertions(+), 85 deletions(-) create mode 100644 out/assets/images/battle/attributes/powercapacity.png create mode 100644 src/ui/battle/ArenaShip.spec.ts diff --git a/README.md b/README.md index c8e78f1..87edf2f 100644 --- a/README.md +++ b/README.md @@ -27,12 +27,17 @@ After making changes to sources, you need to recompile: In combat, a ship's vitals are represented by the HSP system (Hull-Shield-Power): -* **Hull** - Amout of damage that a ship can receive before having to shut down all its systems +* **Hull** - Amount of damage that a ship can sustain before having to engage emergency stasis * **Shield** - Amount of damage that the shield equipments may absorb to protect the Hull * **Power** - Available action points (some actions require more power than others) These values will be changed by various effects (usage of equipments, sustained damage...). +Once the Hull of a ship is fully damaged (Hull=0), the ship engages its ESP, or Emergency +Statis Protocol. This protocol activates a statis field that protects the ship for the +remaining of the battle, preventing any further damage, but rendering it fully inoperent. +For battle purpose, the ship is to be considered "dead". + ### Attributes Attributes represent a ship's ability to use its HSP system: @@ -67,11 +72,11 @@ Each equipment has minimal skill requirements to be used. For example, a weapon and "energy >= 3" to be equipped. A ship that does not meet these requirements will not be able to use the equipment. -As for attributes, skill values are controlled by equipments, effects and level up. +Like for attributes, skill values are controlled by equipments, effects and level up. -If an equipped item has a requirement of "time >= 2", that the ship has time skill of exactly 2, and that a -temporary effect of "time -1" is active, the requirement is no longer fulfilled and the equipped item -is then temporarily disabled (no more effects and cannot be used), until the "time -1" effect is lifted. +If an equipped item has a requirement of "time skill >= 2", that the ship has "time skill" of exactly 2, and +that a temporary effect of "time skill -1" is active, the requirement is no longer fulfilled and the equipped +item is then temporarily disabled (no more effects and cannot be used), until the "time skill -1" effect is lifted. ## Drones diff --git a/TODO b/TODO index 978706d..06f9b26 100644 --- a/TODO +++ b/TODO @@ -1,10 +1,11 @@ * Drones: add tooltip * Drones: add hull points and take area damage * Drones: change the sprite angle for deploy animation -* Better display of effects over ship sprite (repairs, sticky effects...) * Add a battle log display * Organize arena objects and information in layers +* Prevent arena effects information (eg. "shield -36") to overflow out of the arena * Allow to cancel last moves +* Identify ships in emergency stasis more clearly * Add more visual effects to weapons, hits and explosions * Effect should be random in a range (eg. "damage target 50-75") * Add an overload/cooling system diff --git a/out/assets/images/battle/attributes/powercapacity.png b/out/assets/images/battle/attributes/powercapacity.png new file mode 100644 index 0000000000000000000000000000000000000000..7247fe752458f3578e24e30f95422b7761fd35ab GIT binary patch literal 9225 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 { - var sprite = new ArenaShip(this.battleview, ship); + this.battleview.battle.play_order.forEach(ship => { + var sprite = new ArenaShip(this, ship); this.addChild(sprite); this.ship_sprites.push(sprite); }); @@ -92,6 +92,7 @@ module TS.SpaceTac.UI { var sprite = this.findShipSprite(ship); if (sprite) { sprite.alpha = 0.5; + sprite.displayEffect("Emergency Stasis", false); } } diff --git a/src/ui/battle/ArenaShip.spec.ts b/src/ui/battle/ArenaShip.spec.ts new file mode 100644 index 0000000..f964a4a --- /dev/null +++ b/src/ui/battle/ArenaShip.spec.ts @@ -0,0 +1,24 @@ +/// + +module TS.SpaceTac.UI.Specs { + describe("ArenaShip", () => { + inbattleview_it("adds effects display", (battleview: BattleView) => { + let ship = battleview.battle.playing_ship; + let sprite = battleview.arena.findShipSprite(ship); + + expect(sprite.effects.children.length).toBe(0); + + sprite.displayValueChanged(new ValueChangeEvent(ship, ship.attributes.power_recovery, -4)); + + expect(sprite.effects.children.length).toBe(1); + let t1 = sprite.effects.getChildAt(0); + expect(t1.text).toBe("power recovery -4"); + + sprite.displayValueChanged(new ValueChangeEvent(ship, ship.values.shield, 12)); + + expect(sprite.effects.children.length).toBe(2); + let t2 = sprite.effects.getChildAt(1); + expect(t2.text).toBe("shield +12"); + }); + }); +} diff --git a/src/ui/battle/ArenaShip.ts b/src/ui/battle/ArenaShip.ts index e9c628e..fe5f084 100644 --- a/src/ui/battle/ArenaShip.ts +++ b/src/ui/battle/ArenaShip.ts @@ -16,30 +16,38 @@ module TS.SpaceTac.UI { // Frame to indicate the owner of the ship, and if it is playing frame: Phaser.Image; + // Effects display + effects: Phaser.Group; + // Create a ship sprite usable in the Arena - constructor(battleview: BattleView, ship: Ship) { - super(battleview.game); + constructor(parent: Arena, ship: Ship) { + super(parent.game); + let battleview = parent.battleview; this.ship = ship; this.enemy = this.ship.getPlayer() != battleview.player; // Add ship sprite - this.sprite = new Phaser.Button(battleview.game, 0, 0, "ship-" + ship.model + "-sprite"); + this.sprite = new Phaser.Button(this.game, 0, 0, "ship-" + ship.model + "-sprite"); this.sprite.rotation = ship.arena_angle; this.sprite.anchor.set(0.5, 0.5); this.addChild(this.sprite); // Add playing effect - this.frame = new Phaser.Image(battleview.game, 0, 0, `battle-arena-ship-normal-${this.enemy ? "enemy" : "own"}`, 0); + this.frame = new Phaser.Image(this.game, 0, 0, `battle-arena-ship-normal-${this.enemy ? "enemy" : "own"}`, 0); this.frame.anchor.set(0.5, 0.5); this.addChild(this.frame); // Add hover effect - this.hover = new Phaser.Image(battleview.game, 0, 0, "battle-arena-ship-hover", 0); + this.hover = new Phaser.Image(this.game, 0, 0, "battle-arena-ship-hover", 0); this.hover.anchor.set(0.5, 0.5); this.hover.visible = false; this.addChild(this.hover); + // Effects display + this.effects = new Phaser.Group(this.game); + this.addChild(this.effects); + // Handle input on ship sprite Tools.setHoverClick(this.sprite, () => battleview.cursorOnShip(ship), () => battleview.cursorOffShip(ship), () => battleview.cursorClicked()); @@ -75,33 +83,28 @@ module TS.SpaceTac.UI { } } - // Briefly display the damage done to the ship - displayDamage(hull: number, shield: number) { - if (hull > 0) { - var hull_text = new Phaser.Text(this.game, -20, -20, Math.round(hull).toString(), - { font: "bold 16pt Arial", align: "center", fill: "#eb4e4a" }); - hull_text.anchor.set(0.5, 0.5); - this.addChild(hull_text); - this.animateDamageText(hull_text); - } - if (shield > 0) { - var shield_text = new Phaser.Text(this.game, 20, -20, Math.round(shield).toString(), - { font: "bold 16pt Arial", align: "center", fill: "#2ad8dc" }); - shield_text.anchor.set(0.5, 0.5); - this.addChild(shield_text); - this.animateDamageText(shield_text); - } + /** + * Briefly show an effect on this ship + */ + displayEffect(message: string, beneficial: boolean) { + let text = new Phaser.Text(this.game, 0, 20 * this.effects.children.length, message, { font: "14pt Arial", fill: beneficial ? "#afe9c6" : "#e9afaf" }); + this.effects.addChild(text); + + this.effects.position.set(-this.effects.width / 2, this.sprite.height * 0.7); + + this.game.tweens.removeFrom(this.effects); + this.effects.alpha = 1; + let tween = this.game.tweens.create(this.effects).to({ alpha: 0 }, 500).delay(1000).start(); + tween.onComplete.addOnce(() => this.effects.removeAll(true)); } - private animateDamageText(text: Phaser.Text) { - text.alpha = 0; - var tween = this.game.tweens.create(text); - tween.to({ alpha: 1 }, 100, Phaser.Easing.Circular.In, false, 400); - tween.to({ y: -50, alpha: 0 }, 1000, Phaser.Easing.Circular.In, false, 1000); - tween.onComplete.addOnce(() => { - text.destroy(); - }); - tween.start(); + /** + * Display interesting changes in ship values + */ + displayValueChanged(event: ValueChangeEvent) { + let diff = event.diff; + let name = event.value.name; + this.displayEffect(`${name} ${diff < 0 ? "-" : "+"}${Math.abs(diff)}`, diff >= 0); } } } diff --git a/src/ui/battle/LogProcessor.ts b/src/ui/battle/LogProcessor.ts index 1d90259..0789fcd 100644 --- a/src/ui/battle/LogProcessor.ts +++ b/src/ui/battle/LogProcessor.ts @@ -72,10 +72,6 @@ module TS.SpaceTac.UI { // Damage to ship private processDamageEvent(event: DamageEvent): void { - var sprite = this.view.arena.findShipSprite(event.ship); - if (sprite) { - sprite.displayDamage(event.hull, event.shield); - } var item = this.view.ship_list.findItem(event.ship); if (item) { item.setDamageHit(); @@ -92,10 +88,14 @@ module TS.SpaceTac.UI { // Ship value changed private processValueChangedEvent(event: ValueChangeEvent): void { + var sprite = this.view.arena.findShipSprite(event.ship); + sprite.displayValueChanged(event); + var item = this.view.ship_list.findItem(event.ship); if (item) { item.updateAttributes(); } + // TODO Update tooltip } diff --git a/src/ui/battle/ShipTooltip.ts b/src/ui/battle/ShipTooltip.ts index 6413822..668c9c1 100644 --- a/src/ui/battle/ShipTooltip.ts +++ b/src/ui/battle/ShipTooltip.ts @@ -136,7 +136,7 @@ module TS.SpaceTac.UI { } let text = `${effect.getDescription()} (${effect.duration} turns)`; - let color = effect.isBeneficial() ? "afe9c6" : "#e9afaf"; + let color = effect.isBeneficial() ? "#afe9c6" : "#e9afaf"; let effect_text = new Phaser.Text(this.game, 60, effect_group.height / 2, text, { font: "16pt Arial", fill: color }); effect_text.anchor.set(0, 0.5); effect_group.addChild(effect_text);