diff --git a/TODO b/TODO index 1a332ab..c9ee7ee 100644 --- a/TODO +++ b/TODO @@ -2,8 +2,8 @@ * Effect should be random in a range (eg. "damage target 50-75") * Add an overload/cooling system * Add auto-move to attack -* Add equipment info (or summary) in ship tooltip * Escape key should cancel selected action +* Merge identical sticky effects * Handle effects overflowing ship tooltip when too numerous * Proper arena scaling (not graphical, only space coordinates) * Mobile: think UI layout so that fingers do not block the view (right and left handed) diff --git a/graphics/ui/attributes.svg b/graphics/ui/attributes.svg new file mode 100644 index 0000000..532ebbb --- /dev/null +++ b/graphics/ui/attributes.svg @@ -0,0 +1,312 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/out/assets/images/battle/actions/fire-energydepleter.png b/out/assets/images/battle/actions/fire-powerdepleter.png similarity index 100% rename from out/assets/images/battle/actions/fire-energydepleter.png rename to out/assets/images/battle/actions/fire-powerdepleter.png diff --git a/out/assets/images/battle/attributes/effect-decrease.png b/out/assets/images/battle/attributes/effect-decrease.png new file mode 100644 index 0000000..5dba422 Binary files /dev/null and b/out/assets/images/battle/attributes/effect-decrease.png differ diff --git a/out/assets/images/battle/attributes/effect-increase.png b/out/assets/images/battle/attributes/effect-increase.png new file mode 100644 index 0000000..01b2587 Binary files /dev/null and b/out/assets/images/battle/attributes/effect-increase.png differ diff --git a/out/assets/images/battle/attributes/effect-limit.png b/out/assets/images/battle/attributes/effect-limit.png new file mode 100644 index 0000000..15d6657 Binary files /dev/null and b/out/assets/images/battle/attributes/effect-limit.png differ diff --git a/out/assets/images/battle/attributes/power.png b/out/assets/images/battle/attributes/power.png new file mode 100644 index 0000000..7247fe7 Binary files /dev/null and b/out/assets/images/battle/attributes/power.png differ diff --git a/src/game/Attribute.spec.ts b/src/game/Attribute.spec.ts index 345d935..4d4ec95 100644 --- a/src/game/Attribute.spec.ts +++ b/src/game/Attribute.spec.ts @@ -16,9 +16,9 @@ module TS.SpaceTac.Game { AttributeCode.Initiative, AttributeCode.Hull, AttributeCode.Shield, - AttributeCode.AP, - AttributeCode.AP_Recovery, - AttributeCode.AP_Initial, + AttributeCode.Power, + AttributeCode.Power_Recovery, + AttributeCode.Power_Initial, AttributeCode.Cap_Material, AttributeCode.Cap_Energy, AttributeCode.Cap_Electronics, @@ -31,7 +31,7 @@ module TS.SpaceTac.Game { it("gets human readable name", function () { expect(ATTRIBUTE_NAMES[AttributeCode.Initiative]).toEqual("initiative"); - expect(ATTRIBUTE_NAMES[AttributeCode.AP]).toEqual("power"); + expect(ATTRIBUTE_NAMES[AttributeCode.Power]).toEqual("power"); }); it("applies minimal and maximal value", function () { diff --git a/src/game/Attribute.ts b/src/game/Attribute.ts index 287aee6..df44205 100644 --- a/src/game/Attribute.ts +++ b/src/game/Attribute.ts @@ -6,20 +6,20 @@ module TS.SpaceTac.Game { // Initiative level Initiative, - // Hull points (similar to health points in other games) + // Hull points (similar to health points or HP in other games) Hull, // Damage the shield can take Shield, - // Current level of action points - AP, + // Power available to make actions (similar to action points or AP in other games) + Power, - // Action points recovered by turn - AP_Recovery, + // Power recovered each turn + Power_Recovery, - // Starting action points in a battle - AP_Initial, + // Starting power in a battle + Power_Initial, // Capability level in materials Cap_Material, @@ -61,7 +61,7 @@ module TS.SpaceTac.Game { // Value computed from equipment // This value can be altered by effects - // Example attributes are health points, action points recovery... + // Example attributes are health points, power recovery... export class Attribute extends Serializable { // Identifying code of this attribute code: AttributeCode; diff --git a/src/game/Ship.spec.ts b/src/game/Ship.spec.ts index 3be4e37..139d14a 100644 --- a/src/game/Ship.spec.ts +++ b/src/game/Ship.spec.ts @@ -65,13 +65,13 @@ module TS.SpaceTac.Game.Specs { slot = ship.addSlot(SlotType.Power); equipment = new Equipment(); equipment.slot = slot.type; - equipment.permanent_effects.push(new AttributeMaxEffect(AttributeCode.AP, 4)); + equipment.permanent_effects.push(new AttributeMaxEffect(AttributeCode.Power, 4)); slot.attach(equipment); slot = ship.addSlot(SlotType.Power); equipment = new Equipment(); equipment.slot = slot.type; - equipment.permanent_effects.push(new AttributeMaxEffect(AttributeCode.AP, 5)); + equipment.permanent_effects.push(new AttributeMaxEffect(AttributeCode.Power, 5)); slot.attach(equipment); ship.updateAttributes(); diff --git a/src/game/Ship.ts b/src/game/Ship.ts index f98a288..63aecd4 100644 --- a/src/game/Ship.ts +++ b/src/game/Ship.ts @@ -75,9 +75,9 @@ module TS.SpaceTac.Game { this.alive = true; this.initiative = this.newAttribute(AttributeCode.Initiative); this.initiative.setMaximal(1); - this.ap_current = this.newAttribute(AttributeCode.AP); - this.ap_initial = this.newAttribute(AttributeCode.AP_Initial); - this.ap_recover = this.newAttribute(AttributeCode.AP_Recovery); + this.ap_current = this.newAttribute(AttributeCode.Power); + this.ap_initial = this.newAttribute(AttributeCode.Power_Initial); + this.ap_recover = this.newAttribute(AttributeCode.Power_Recovery); this.hull = this.newAttribute(AttributeCode.Hull); this.shield = this.newAttribute(AttributeCode.Shield); this.cap_material = this.newAttribute(AttributeCode.Cap_Material); @@ -375,7 +375,7 @@ module TS.SpaceTac.Game { new_attrs.addValue(effect.attrcode, effect.value); }); this.initiative.setMaximal(new_attrs.getValue(AttributeCode.Initiative)); - this.ap_current.setMaximal(new_attrs.getValue(AttributeCode.AP)); + this.ap_current.setMaximal(new_attrs.getValue(AttributeCode.Power)); this.hull.setMaximal(new_attrs.getValue(AttributeCode.Hull)); this.shield.setMaximal(new_attrs.getValue(AttributeCode.Shield)); @@ -384,8 +384,8 @@ module TS.SpaceTac.Game { 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)); + this.ap_initial.set(new_attrs.getValue(AttributeCode.Power_Initial)); + this.ap_recover.set(new_attrs.getValue(AttributeCode.Power_Recovery)); } // Fully restore hull and shield diff --git a/src/game/TestTools.ts b/src/game/TestTools.ts index ed327d7..1a59a57 100644 --- a/src/game/TestTools.ts +++ b/src/game/TestTools.ts @@ -49,12 +49,12 @@ module TS.SpaceTac.Game { equipment.permanent_effects.forEach((effect: BaseEffect) => { if (effect.code === "attrmax") { var meffect = effect; - if (meffect.attrcode === AttributeCode.AP) { + if (meffect.attrcode === AttributeCode.Power) { meffect.value = points; } } else if (effect.code === "attr") { var veffect = effect; - if (veffect.attrcode === AttributeCode.AP_Recovery) { + if (veffect.attrcode === AttributeCode.Power_Recovery) { veffect.value = recovery; } } diff --git a/src/game/actions/MoveAction.spec.ts b/src/game/actions/MoveAction.spec.ts index cc0f7a8..7d6cf78 100644 --- a/src/game/actions/MoveAction.spec.ts +++ b/src/game/actions/MoveAction.spec.ts @@ -74,7 +74,7 @@ module TS.SpaceTac.Game { expect(battle.log.events[1].code).toEqual("attr"); expect(battle.log.events[1].ship).toBe(ship); expect((battle.log.events[1]).attribute).toEqual( - new Attribute(AttributeCode.AP, 0, 20)); + new Attribute(AttributeCode.Power, 0, 20)); }); it("can't move too much near another ship", function () { diff --git a/src/game/ai/BullyAI.spec.ts b/src/game/ai/BullyAI.spec.ts index 011e658..3f3c83b 100644 --- a/src/game/ai/BullyAI.spec.ts +++ b/src/game/ai/BullyAI.spec.ts @@ -236,7 +236,7 @@ module TS.SpaceTac.Game.AI.Specs { expect(battle.log.events[0]).toEqual(new MoveEvent(ship1, 2, 0)); expect(battle.log.events[1]).toEqual(new AttributeChangeEvent(ship1, - new Attribute(AttributeCode.AP, 2, 10))); + new Attribute(AttributeCode.Power, 2, 10))); expect(battle.log.events[2]).toEqual(new FireEvent(ship1, weapon, Target.newFromShip(ship2))); expect(battle.log.events[3]).toEqual(new AttributeChangeEvent(ship2, @@ -245,7 +245,7 @@ module TS.SpaceTac.Game.AI.Specs { new Attribute(AttributeCode.Hull, 5))); expect(battle.log.events[5]).toEqual(new DamageEvent(ship2, 10, 10)); expect(battle.log.events[6]).toEqual(new AttributeChangeEvent(ship1, - new Attribute(AttributeCode.AP, 1, 10))); + new Attribute(AttributeCode.Power, 1, 10))); }); }); } diff --git a/src/game/equipments/BasicPowerCore.ts b/src/game/equipments/BasicPowerCore.ts index ea4bbce..2dce0a7 100644 --- a/src/game/equipments/BasicPowerCore.ts +++ b/src/game/equipments/BasicPowerCore.ts @@ -8,9 +8,9 @@ module TS.SpaceTac.Game.Equipments { this.min_level = new IntegerRange(1, 1); this.addPermanentAttributeMaxEffect(AttributeCode.Initiative, 1); - this.addPermanentAttributeMaxEffect(AttributeCode.AP, 8); - this.addPermanentAttributeValueEffect(AttributeCode.AP_Initial, 5); - this.addPermanentAttributeValueEffect(AttributeCode.AP_Recovery, 4); + this.addPermanentAttributeMaxEffect(AttributeCode.Power, 8); + this.addPermanentAttributeValueEffect(AttributeCode.Power_Initial, 5); + this.addPermanentAttributeValueEffect(AttributeCode.Power_Recovery, 4); } } } diff --git a/src/game/equipments/EnergyDepleter.spec.ts b/src/game/equipments/PowerDepleter.spec.ts similarity index 90% rename from src/game/equipments/EnergyDepleter.spec.ts rename to src/game/equipments/PowerDepleter.spec.ts index ee24a31..119062b 100644 --- a/src/game/equipments/EnergyDepleter.spec.ts +++ b/src/game/equipments/PowerDepleter.spec.ts @@ -1,7 +1,7 @@ module TS.SpaceTac.Game.Specs { - describe("EnergyDepleter", () => { + describe("PowerDepleter", () => { it("limits target's AP", () => { - var template = new Equipments.EnergyDepleter(); + var template = new Equipments.PowerDepleter(); var equipment = template.generateFixed(0); var ship = new Ship(); @@ -17,7 +17,7 @@ module TS.SpaceTac.Game.Specs { expect(target.ap_current.current).toBe(4); expect(target.sticky_effects).toEqual([ - new StickyEffect(new AttributeLimitEffect(AttributeCode.AP, 4), 1, true, false) + new StickyEffect(new AttributeLimitEffect(AttributeCode.Power, 4), 1, true, false) ]); // Attribute is limited for one turn, and prevents AP recovery diff --git a/src/game/equipments/EnergyDepleter.ts b/src/game/equipments/PowerDepleter.ts similarity index 73% rename from src/game/equipments/EnergyDepleter.ts rename to src/game/equipments/PowerDepleter.ts index 090ea8e..f07e5f1 100644 --- a/src/game/equipments/EnergyDepleter.ts +++ b/src/game/equipments/PowerDepleter.ts @@ -1,16 +1,16 @@ /// module TS.SpaceTac.Game.Equipments { - export class EnergyDepleter extends AbstractWeapon { + export class PowerDepleter extends AbstractWeapon { constructor() { - super("Energy Depleter"); + super("Power Depleter"); this.setRange(200, 300, false); this.ap_usage = new IntegerRange(4, 5); this.min_level = new IntegerRange(1, 3); - this.addSticky(new AttributeLimitEffect(AttributeCode.AP), 4, 3, 1, 2, true); + this.addSticky(new AttributeLimitEffect(AttributeCode.Power), 4, 3, 1, 2, true); } } } diff --git a/src/view/Preload.ts b/src/view/Preload.ts index 103df46..4ea0fa4 100644 --- a/src/view/Preload.ts +++ b/src/view/Preload.ts @@ -51,9 +51,13 @@ module TS.SpaceTac.View { this.loadImage("battle/actions/move.png"); this.loadImage("battle/actions/endturn.png"); this.loadImage("battle/actions/fire-gatlinggun.png"); - this.loadImage("battle/actions/fire-energydepleter.png"); + this.loadImage("battle/actions/fire-powerdepleter.png"); this.loadImage("battle/actions/fire-submunitionmissile.png"); this.loadImage("battle/weapon/bullet.png"); + this.loadImage("battle/attributes/power.png"); + this.loadImage("battle/attributes/effect-increase.png"); + this.loadImage("battle/attributes/effect-decrease.png"); + this.loadImage("battle/attributes/effect-limit.png"); this.loadImage("common/standard-bar-background.png"); this.loadImage("common/standard-bar-foreground.png"); this.loadImage("map/starsystem-background.png"); diff --git a/src/view/battle/ShipListItem.ts b/src/view/battle/ShipListItem.ts index 99b1eec..cb67907 100644 --- a/src/view/battle/ShipListItem.ts +++ b/src/view/battle/ShipListItem.ts @@ -87,7 +87,7 @@ module TS.SpaceTac.View { this.hull.setValue(attribute.current, attribute.maximal); } else if (attribute.code === Game.AttributeCode.Shield) { this.shield.setValue(attribute.current, attribute.maximal); - } else if (attribute.code === Game.AttributeCode.AP) { + } else if (attribute.code === Game.AttributeCode.Power) { this.energy.setValue(attribute.current, attribute.maximal); } } diff --git a/src/view/battle/ShipTooltip.ts b/src/view/battle/ShipTooltip.ts index 0a6974c..9278d21 100644 --- a/src/view/battle/ShipTooltip.ts +++ b/src/view/battle/ShipTooltip.ts @@ -105,6 +105,9 @@ module TS.SpaceTac.View { ship.sticky_effects.forEach((effect, index) => { this.addEffect(effect, index); }); + ship.listEquipment(Game.SlotType.Weapon).forEach((equipment, index) => { + this.addEquipment(equipment, ship.sticky_effects.length + index); + }); Animation.fadeIn(this.game, this, 200, 0.9); } else { @@ -112,18 +115,46 @@ module TS.SpaceTac.View { } } - // Add a sticky effect display + /** + * Add a sticky effect display + */ addEffect(effect: Game.StickyEffect, index = 0) { - var effect_group = new Phaser.Image(this.game, 27, 243 + 60 * index, "battle-ship-tooltip-effect"); + let effect_group = new Phaser.Image(this.game, 27, 243 + 60 * index, "battle-ship-tooltip-effect"); this.active_effects.addChild(effect_group); - var effect_icon = new Phaser.Image(this.game, 30, effect_group.height / 2, `battle-effect-${effect.getFullCode()}`); + if (effect.base instanceof Game.AttributeLimitEffect) { + let attr_name = Game.AttributeCode[effect.base.attrcode].toLowerCase().replace('_', ''); + let attr_icon = new Phaser.Image(this.game, 30, effect_group.height / 2, `battle-attributes-${attr_name}`); + attr_icon.anchor.set(0.5, 0.5); + attr_icon.scale.set(0.17, 0.17); + effect_group.addChild(attr_icon); + + let effect_icon = new Phaser.Image(this.game, 30, effect_group.height / 2, "battle-attributes-effect-limit"); + effect_icon.anchor.set(0.5, 0.5); + effect_icon.scale.set(0.17, 0.17); + effect_group.addChild(effect_icon); + } + + let text = `${effect.getDescription()} (${effect.duration} turns)`; + 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); + } + + /** + * Add an equipment action display + */ + addEquipment(equipment: Game.Equipment, index = 0) { + let effect_group = new Phaser.Image(this.game, 27, 243 + 60 * index, "battle-ship-tooltip-effect"); + this.active_effects.addChild(effect_group); + + let effect_icon = new Phaser.Image(this.game, 30, effect_group.height / 2, `battle-actions-${equipment.action.code}`); effect_icon.anchor.set(0.5, 0.5); + effect_icon.scale.set(0.17, 0.17); effect_group.addChild(effect_icon); - var text = `${effect.getDescription()} (${effect.duration} turns)`; - var color = effect.isBeneficial() ? "afe9c6" : "#e9afaf"; - var effect_text = new Phaser.Text(this.game, 60, effect_group.height / 2, text, { font: "16pt Arial", fill: color }); + let effect_text = new Phaser.Text(this.game, 60, effect_group.height / 2, equipment.name, { font: "16pt Arial", fill: "#ffffff" }); effect_text.anchor.set(0, 0.5); effect_group.addChild(effect_text); }