diff --git a/TODO.md b/TODO.md index ec62ad2..47e8dc5 100644 --- a/TODO.md +++ b/TODO.md @@ -54,8 +54,9 @@ Battle * Merge identical sticky effects * Allow to undo last moves * Add a battle log display -* Allow to target ships with number keys, using their play order -* Allow to validate the current targetting with enter +* Allow to move targetting indicator with arrow keys +* Trigger targetting mode for all actions (even for damage protector or shield transfer) +* Add targetting shortcuts for "previous target", "next enemy" and "next ally" Ships models and equipments --------------------------- diff --git a/out/assets/images/character/experience.png b/graphics/exported/character/experience.png similarity index 100% rename from out/assets/images/character/experience.png rename to graphics/exported/character/experience.png diff --git a/src/ui/BaseView.ts b/src/ui/BaseView.ts index 86a60ef..38e93f4 100644 --- a/src/ui/BaseView.ts +++ b/src/ui/BaseView.ts @@ -210,7 +210,7 @@ module TS.SpaceTac.UI { } i++; } - return { key: "default", frame: 0 }; + return { key: `-missing-${name}`, frame: 0 }; } /** @@ -218,7 +218,7 @@ module TS.SpaceTac.UI { */ getFirstImage(...names: string[]): { key: string, frame: number } { let infos = names.map(name => this.getImageInfo(name)); - return first(infos, info => info.key != "default") || infos[0]; + return first(infos, info => info.key.substr(0, 9) != "-missing-") || infos[0]; } } } diff --git a/src/ui/Preload.ts b/src/ui/Preload.ts index 8d98490..6c00523 100644 --- a/src/ui/Preload.ts +++ b/src/ui/Preload.ts @@ -59,7 +59,6 @@ module TS.SpaceTac.UI { this.loadSheet("character/slots.png", 52); this.loadImage("character/upgrade-available.png"); this.loadImage("character/price-tag.png"); - this.loadImage("character/experience.png"); // Load image atlases // TODO automatic range diff --git a/src/ui/battle/ActionBar.ts b/src/ui/battle/ActionBar.ts index 1916144..78bcb5b 100644 --- a/src/ui/battle/ActionBar.ts +++ b/src/ui/battle/ActionBar.ts @@ -57,26 +57,6 @@ module TS.SpaceTac.UI { // Key bindings battleview.inputs.bind("Escape", "Cancel action", () => this.actionEnded()); battleview.inputs.bind(" ", "End turn", () => this.keyActionPressed(-1)); - battleview.inputs.bind("Numpad1", "Action 1", () => this.keyActionPressed(0)); - battleview.inputs.bind("Numpad2", "Action 2", () => this.keyActionPressed(1)); - battleview.inputs.bind("Numpad3", "Action 3", () => this.keyActionPressed(2)); - battleview.inputs.bind("Numpad4", "Action 4", () => this.keyActionPressed(3)); - battleview.inputs.bind("Numpad5", "Action 5", () => this.keyActionPressed(4)); - battleview.inputs.bind("Numpad6", "Action 6", () => this.keyActionPressed(5)); - battleview.inputs.bind("Numpad7", "Action 7", () => this.keyActionPressed(6)); - battleview.inputs.bind("Numpad8", "Action 8", () => this.keyActionPressed(7)); - battleview.inputs.bind("Numpad9", "Action 9", () => this.keyActionPressed(8)); - battleview.inputs.bind("Numpad0", "Action 10", () => this.keyActionPressed(9)); - battleview.inputs.bind("Digit1", "Action 1", () => this.keyActionPressed(0)); - battleview.inputs.bind("Digit2", "Action 2", () => this.keyActionPressed(1)); - battleview.inputs.bind("Digit3", "Action 3", () => this.keyActionPressed(2)); - battleview.inputs.bind("Digit4", "Action 4", () => this.keyActionPressed(3)); - battleview.inputs.bind("Digit5", "Action 5", () => this.keyActionPressed(4)); - battleview.inputs.bind("Digit6", "Action 6", () => this.keyActionPressed(5)); - battleview.inputs.bind("Digit7", "Action 7", () => this.keyActionPressed(6)); - battleview.inputs.bind("Digit8", "Action 8", () => this.keyActionPressed(7)); - battleview.inputs.bind("Digit9", "Action 9", () => this.keyActionPressed(8)); - battleview.inputs.bind("Digit0", "Action 10", () => this.keyActionPressed(9)); // Log processing battleview.log_processor.register(event => { diff --git a/src/ui/battle/BattleView.spec.ts b/src/ui/battle/BattleView.spec.ts index 0b2feba..3b792da 100644 --- a/src/ui/battle/BattleView.spec.ts +++ b/src/ui/battle/BattleView.spec.ts @@ -71,5 +71,27 @@ module TS.SpaceTac.UI.Specs { // Quit twice don't do anything battleview.exitTargettingMode(); }); + + it("allows to choose an action and a target with shortcut keys", function () { + let battleview = testgame.battleview; + battleview.setInteractionEnabled(true); + let action_icon = nn(first(battleview.action_bar.action_icons, icon => icon.action.needs_target)); + + expect(battleview.targetting.active).toBe(false); + expect(battleview.action_bar.hasActionSelected()).toBe(false); + battleview.numberPressed(battleview.action_bar.action_icons.indexOf(action_icon) + 1); + expect(battleview.action_bar.hasActionSelected()).toBe(true); + expect(battleview.targetting.active).toBe(true); + expect(battleview.targetting.action).toBe(action_icon.action); + expect(battleview.targetting.target).toBe(null); + battleview.numberPressed(3); + expect(battleview.targetting.active).toBe(true); + expect(battleview.targetting.action).toBe(action_icon.action); + expect(battleview.targetting.target).toEqual(Target.newFromShip(battleview.battle.play_order[3])); + battleview.numberPressed(4); + expect(battleview.targetting.active).toBe(true); + expect(battleview.targetting.action).toBe(action_icon.action); + expect(battleview.targetting.target).toEqual(Target.newFromShip(battleview.battle.play_order[4])); + }); }); } diff --git a/src/ui/battle/BattleView.ts b/src/ui/battle/BattleView.ts index a45b2e3..74a6e88 100644 --- a/src/ui/battle/BattleView.ts +++ b/src/ui/battle/BattleView.ts @@ -79,6 +79,7 @@ module TS.SpaceTac.UI { super.create(); var game = this.game; + this.interacting = false; this.log_processor = new LogProcessor(this); // Add layers @@ -113,6 +114,9 @@ module TS.SpaceTac.UI { // Key mapping this.inputs.bind("t", "Show tactical view", () => this.toggle_tactical_mode.manipulate("keyboard")(3000)); + this.inputs.bind("Enter", "Validate action", () => this.targetting.validate()); + range(10).forEach(i => this.inputs.bind(`Numpad${i % 10}`, `Action/target ${i}`, () => this.numberPressed(i))); + range(10).forEach(i => this.inputs.bind(`Digit${i % 10}`, `Action/target ${i}`, () => this.numberPressed(i))); this.inputs.bindCheat("w", "Win current battle", () => this.battle.cheats.win()); this.inputs.bindCheat("x", "Lose current battle", () => this.battle.cheats.lose()); this.inputs.bindCheat("a", "Use AI to play", () => this.playAI()); @@ -156,6 +160,25 @@ module TS.SpaceTac.UI { return splash.start(); } + /** + * Handle the pressing of a number key + * + * It may first be used to select an action to play, then to select a target + */ + numberPressed(num: number): void { + if (this.interacting) { + if (this.targetting.active) { + let ship = ifirst(this.battle.iships(true), ship => this.battle.getTurnsBefore(ship) == num % 10); + if (ship) { + this.targetting.setTarget(Target.newFromShip(ship)); + } + } else { + console.log(num); + this.action_bar.keyActionPressed(num - 1); + } + } + } + // Method called when cursor starts hovering over a ship (or its icon) cursorOnShip(ship: Ship): void { if (!this.targetting.active || ship.alive) { diff --git a/src/ui/battle/Targetting.ts b/src/ui/battle/Targetting.ts index 24d2f6e..3090701 100644 --- a/src/ui/battle/Targetting.ts +++ b/src/ui/battle/Targetting.ts @@ -44,7 +44,7 @@ module TS.SpaceTac.UI { this.move_ghost.anchor.set(0.5, 0.5); this.move_ghost.alpha = 0.8; this.move_ghost.visible = false; - this.fire_arrow = new Phaser.Image(view.game, 0, 0, "battle-hud-simulator-ok"); + this.fire_arrow = this.view.newImage("battle-hud-simulator-ok"); this.fire_arrow.anchor.set(1, 0.5); this.fire_arrow.visible = false; this.fire_impact = new Phaser.Group(view.game); @@ -71,7 +71,7 @@ module TS.SpaceTac.UI { * Indicator that the targetting is currently active */ get active(): boolean { - return (this.ship && this.action) ? true : false; + return bool(this.ship && this.action); } /** @@ -254,16 +254,18 @@ module TS.SpaceTac.UI { * This will make the needed approach and apply the action. */ validate(): void { - this.simulate(); + if (this.active) { + this.simulate(); - if (this.ship && this.simulation.complete) { - let ship = this.ship; - this.simulation.parts.forEach(part => { - if (part.possible) { - part.action.apply(ship, part.target); - } - }); - this.actionbar.actionEnded(); + if (this.ship && this.simulation.complete) { + let ship = this.ship; + this.simulation.parts.forEach(part => { + if (part.possible) { + part.action.apply(ship, part.target); + } + }); + this.actionbar.actionEnded(); + } } } }