diff --git a/forge-gui-mobile/src/forge/adventure/stage/GameHUD.java b/forge-gui-mobile/src/forge/adventure/stage/GameHUD.java index 03b29869492..f312d7b4c72 100644 --- a/forge-gui-mobile/src/forge/adventure/stage/GameHUD.java +++ b/forge-gui-mobile/src/forge/adventure/stage/GameHUD.java @@ -11,23 +11,24 @@ import com.badlogic.gdx.scenes.scene2d.InputEvent; import com.badlogic.gdx.scenes.scene2d.Stage; import com.badlogic.gdx.scenes.scene2d.actions.Actions; import com.badlogic.gdx.scenes.scene2d.ui.Button; +import com.badlogic.gdx.scenes.scene2d.ui.Dialog; import com.badlogic.gdx.scenes.scene2d.ui.Image; import com.badlogic.gdx.scenes.scene2d.ui.Touchpad; import com.badlogic.gdx.scenes.scene2d.utils.ActorGestureListener; import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable; +import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.Scaling; import com.badlogic.gdx.utils.Timer; import com.badlogic.gdx.utils.viewport.ScalingViewport; import com.github.tommyettinger.textra.TextraButton; import com.github.tommyettinger.textra.TextraLabel; +import com.github.tommyettinger.textra.TypingAdapter; +import com.github.tommyettinger.textra.TypingLabel; import forge.Forge; import forge.adventure.player.AdventurePlayer; import forge.adventure.scene.*; -import forge.adventure.util.Config; -import forge.adventure.util.Controls; -import forge.adventure.util.Current; -import forge.adventure.util.UIActor; +import forge.adventure.util.*; import forge.adventure.world.WorldSave; import forge.deck.Deck; import forge.gui.FThreads; @@ -53,6 +54,7 @@ public class GameHUD extends Stage { private final TextraButton menuActor; private final TextraButton statsActor; private final TextraButton inventoryActor; + private final TextraButton exitToWorldMapActor; public final UIActor ui; private final Touchpad touchpad; private final Console console; @@ -61,6 +63,11 @@ public class GameHUD extends Stage { float opacity = 1f; private boolean debugMap; + private final Dialog dialog; + private boolean dialogOnlyInput; + private final Array dialogButtonMap = new Array<>(); + TextraButton selectedKey; + private GameHUD(GameStage gameStage) { super(new ScalingViewport(Scaling.stretch, Scene.getIntendedWidth(), Scene.getIntendedHeight()), gameStage.getBatch()); instance = this; @@ -70,6 +77,7 @@ public class GameHUD extends Stage { ? Forge.isLandscapeMode() ? "ui/hud_landscape.json" : "ui/hud_portrait.json" : Forge.isLandscapeMode() ? "ui/hud.json" : "ui/hud_portrait.json")); + blank = ui.findActor("blank"); miniMap = ui.findActor("map"); mapborder = ui.findActor("mapborder"); @@ -83,6 +91,8 @@ public class GameHUD extends Stage { statsActor = ui.findActor("statistic"); inventoryActor = ui.findActor("inventory"); gamehud = ui.findActor("gamehud"); + exitToWorldMapActor = ui.findActor("exittoworldmap"); + dialog = Controls.newDialog(""); miniMapPlayer = new Image(new Texture(Config.instance().getFile("ui/minimap_player.png"))); //create touchpad @@ -108,6 +118,7 @@ public class GameHUD extends Stage { ui.onButtonPress("inventory", () -> openInventory()); ui.onButtonPress("statistic", () -> statistic()); ui.onButtonPress("deck", () -> openDeck()); + ui.onButtonPress("exittoworldmap", () -> exitToWorldMap()); lifePoints = ui.findActor("lifePoints"); mana = ui.findActor("mana"); money = ui.findActor("money"); @@ -208,6 +219,7 @@ public class GameHUD extends Stage { && !(Controls.actorContainsVector(openMapActor, touch)) //not inside openmap button && !(Controls.actorContainsVector(statsActor, touch)) //not inside stats button && !(Controls.actorContainsVector(inventoryActor, touch)) //not inside inventory button + && !(Controls.actorContainsVector(exitToWorldMapActor, touch)) //not inside deck button && (Controls.actorContainsVector(ui, touch)) //inside display bounds && pointer < 1) { //not more than 1 pointer touchpad.setBounds(touch.x - TOUCHPAD_SCALE / 2, touch.y - TOUCHPAD_SCALE / 2, TOUCHPAD_SCALE, TOUCHPAD_SCALE); @@ -278,6 +290,39 @@ public class GameHUD extends Stage { Forge.switchScene(InventoryScene.instance()); } + private void exitToWorldMap(){ + dialog.getButtonTable().clear(); + dialog.getContentTable().clear(); + TextraButton YES = Controls.newTextButton("YES", this::exitDungeonCallback); + YES.setVisible(false); + TextraButton NO = Controls.newTextButton("NO", this::hideDialog); + NO.setVisible(false); + TypingLabel L = Controls.newTypingLabel("Exit to the World Map?"); + L.setWrap(true); + L.setTypingListener(new TypingAdapter() { + @Override + public void end() { + YES.setVisible(true); + NO.setVisible(true); + } + }); + + dialog.getButtonTable().add(YES).width(60f); + dialog.getButtonTable().add(NO).width(60f); + dialog.getContentTable().add(L).width(120f); + dialog.setKeepWithinStage(true); + showDialog(); + + } + private void exitDungeonCallback(){ + hideDialog(); + Forge.switchScene(GameScene.instance()); + WorldStage.getInstance().getPlayerSprite().setMovementDirection(Vector2.Zero); + MapStage.getInstance().getPlayerSprite().setMovementDirection(Vector2.Zero); + + gameStage.getPlayerSprite().stop(); + } + private void menu() { gameStage.openMenu(); } @@ -306,12 +351,14 @@ public class GameHUD extends Stage { setVisibility(mana, visible); setVisibility(money, visible); setVisibility(blank, visible); + setVisibility(exitToWorldMapActor, !visible); //hide when not in a dungeon setAlpha(avatarborder, visible); setAlpha(avatar, visible); setAlpha(deckActor, visible); setAlpha(menuActor, visible); setAlpha(statsActor, visible); setAlpha(inventoryActor, visible); + setAlpha(exitToWorldMapActor, visible); opacity = visible ? 1f : 0.4f; } @@ -323,6 +370,9 @@ public class GameHUD extends Stage { @Override public boolean keyDown(int keycode) { + if (dialogOnlyInput) { + return dialogInput(keycode); + } ui.pressDown(keycode); if (keycode == Input.Keys.F9 || keycode == Input.Keys.F10) { console.toggle(); @@ -347,6 +397,21 @@ public class GameHUD extends Stage { return super.keyDown(keycode); } + public boolean dialogInput(int keycode) { + if (dialogOnlyInput) { + if (KeyBinding.Up.isPressed(keycode)) { + selectPreviousDialogButton(); + } + if (KeyBinding.Down.isPressed(keycode)) { + selectNextDialogButton(); + } + if (KeyBinding.Use.isPressed(keycode)) { + performTouch(this.getKeyboardFocus()); + } + } + return true; + } + public void performTouch(Actor actor) { if (actor == null) return; @@ -369,6 +434,7 @@ public class GameHUD extends Stage { inventoryActor.addAction(Actions.sequence(Actions.fadeOut(0.15f), Actions.hide(), Actions.moveTo(inventoryActor.getX() + inventoryActor.getWidth(), inventoryActor.getY()))); statsActor.addAction(Actions.sequence(Actions.fadeOut(0.20f), Actions.hide(), Actions.moveTo(statsActor.getX() + statsActor.getWidth(), statsActor.getY()))); menuActor.addAction(Actions.sequence(Actions.fadeOut(0.25f), Actions.hide(), Actions.moveTo(menuActor.getX() + menuActor.getWidth(), menuActor.getY()))); + exitToWorldMapActor.addAction(Actions.sequence(Actions.fadeOut(0.2f), Actions.hide(), Actions.moveTo(exitToWorldMapActor.getX() + exitToWorldMapActor.getWidth(), exitToWorldMapActor.getY()))); FThreads.delayInEDT(300, () -> isHiding = false); } @@ -384,6 +450,7 @@ public class GameHUD extends Stage { statsActor.addAction(Actions.sequence(Actions.delay(0.15f), Actions.parallel(Actions.show(), Actions.alpha(opacity, 0.1f), Actions.moveTo(referenceX, statsActor.getY(), 0.25f)))); inventoryActor.addAction(Actions.sequence(Actions.delay(0.2f), Actions.parallel(Actions.show(), Actions.alpha(opacity, 0.1f), Actions.moveTo(referenceX, inventoryActor.getY(), 0.25f)))); deckActor.addAction(Actions.sequence(Actions.delay(0.25f), Actions.parallel(Actions.show(), Actions.alpha(opacity, 0.1f), Actions.moveTo(referenceX, deckActor.getY(), 0.25f)))); + exitToWorldMapActor.addAction(Actions.sequence(Actions.delay(0.25f), Actions.parallel(Actions.show(), Actions.alpha(opacity, 0.1f), Actions.moveTo(referenceX, exitToWorldMapActor.getY(), 0.25f)))); FThreads.delayInEDT(300, () -> isShowing = false); } @@ -391,6 +458,60 @@ public class GameHUD extends Stage { debugMap = b; } + public void showDialog() { + + dialogButtonMap.clear(); + for (int i = 0; i < dialog.getButtonTable().getCells().size; i++) { + dialogButtonMap.add((TextraButton) dialog.getButtonTable().getCells().get(i).getActor()); + } + dialog.show(this, Actions.show()); + dialog.setPosition((this.getWidth() - dialog.getWidth()) / 2, (this.getHeight() - dialog.getHeight()) / 2); + dialogOnlyInput = true; + if (Forge.hasGamepad() && !dialogButtonMap.isEmpty()) + this.setKeyboardFocus(dialogButtonMap.first()); + } + + public void hideDialog() { + dialog.hide(Actions.sequence(Actions.sizeTo(dialog.getOriginX(), dialog.getOriginY(), 0.3f), Actions.hide())); + dialogOnlyInput = false; + selectedKey = null; + } + + private void selectNextDialogButton() { + if (dialogButtonMap.size < 2) + return; + if (!(this.getKeyboardFocus() instanceof Button)) { + this.setKeyboardFocus(dialogButtonMap.first()); + return; + } + for (int i = 0; i < dialogButtonMap.size; i++) { + if (this.getKeyboardFocus() == dialogButtonMap.get(i)) { + i += 1; + i %= dialogButtonMap.size; + this.setKeyboardFocus(dialogButtonMap.get(i)); + return; + } + } + } + + private void selectPreviousDialogButton() { + if (dialogButtonMap.size < 2) + return; + if (!(this.getKeyboardFocus() instanceof Button)) { + this.setKeyboardFocus(dialogButtonMap.first()); + return; + } + for (int i = 0; i < dialogButtonMap.size; i++) { + if (this.getKeyboardFocus() == dialogButtonMap.get(i)) { + i -= 1; + if (i < 0) + i = dialogButtonMap.size - 1; + this.setKeyboardFocus(dialogButtonMap.get(i)); + return; + } + } + } + class ConsoleToggleListener extends ActorGestureListener { public ConsoleToggleListener() { getGestureDetector().setLongPressSeconds(0.6f); @@ -410,5 +531,7 @@ public class GameHUD extends Stage { if (count > 1) showButtons(); } + + } } diff --git a/forge-gui-mobile/src/forge/adventure/stage/WorldStage.java b/forge-gui-mobile/src/forge/adventure/stage/WorldStage.java index 35b44f11150..164e9ef42c5 100644 --- a/forge-gui-mobile/src/forge/adventure/stage/WorldStage.java +++ b/forge-gui-mobile/src/forge/adventure/stage/WorldStage.java @@ -181,6 +181,7 @@ public class WorldStage extends GameStage implements SaveFileContent { continue; } TileMapScene.instance().load(point.getPointOfInterest()); + stop(); Forge.switchScene(TileMapScene.instance()); } else { if (point == collidingPoint) { diff --git a/forge-gui-mobile/src/forge/adventure/util/KeyBinding.java b/forge-gui-mobile/src/forge/adventure/util/KeyBinding.java index 81fb2a57051..910400a7a79 100644 --- a/forge-gui-mobile/src/forge/adventure/util/KeyBinding.java +++ b/forge-gui-mobile/src/forge/adventure/util/KeyBinding.java @@ -17,6 +17,7 @@ public enum KeyBinding { Deck("Deck", Input.Keys.E,Input.Keys.BUTTON_A), Map("Map", Input.Keys.M,Input.Keys.BUTTON_SELECT), Equip("Equip", Input.Keys.E,Input.Keys.BUTTON_X), + ExitToWorldMap("ExitToWorldMap", Input.Keys.F4,Input.Keys.BUTTON_L2), Use("Use", Input.Keys.ENTER,Input.Keys.BUTTON_A), Back("Back", Input.Keys.ESCAPE,Input.Keys.BUTTON_B), ScrollUp("ScrollUp", Input.Keys.PAGE_UP,Input.Keys.BUTTON_L1), diff --git a/forge-gui/res/adventure/Shandalar/skin/keys.atlas b/forge-gui/res/adventure/Shandalar/skin/keys.atlas index 4dec2672f67..0273fe282c7 100644 --- a/forge-gui/res/adventure/Shandalar/skin/keys.atlas +++ b/forge-gui/res/adventure/Shandalar/skin/keys.atlas @@ -573,4 +573,76 @@ Switch_Up size: 16, 16 Switch_Up_pressed xy: 432, 96 - size: 16, 16 \ No newline at end of file + size: 16, 16 +F1 + xy: 0, 112 + size: 16, 16 +F1_pressed + xy: 16, 112 + size: 16, 16 +F2 + xy: 32, 112 + size: 16, 16 +F2_pressed + xy: 48, 112 + size: 16, 16 +F3 + xy: 64, 112 + size: 16, 16 +F3_pressed + xy: 80, 112 + size: 16, 16 +F4 + xy: 96, 112 + size: 16, 16 +F4_pressed + xy: 112, 112 + size: 16, 16 +F5 + xy: 128, 112 + size: 16, 16 +F5_pressed + xy: 144, 112 + size: 16, 16 +F6 + xy: 160, 112 + size: 16, 16 +F6_pressed + xy: 176, 112 + size: 16, 16 +F7 + xy: 192, 112 + size: 16, 16 +F7_pressed + xy: 208, 112 + size: 16, 16 +F8 + xy: 224, 112 + size: 16, 16 +F8_pressed + xy: 240, 112 + size: 16, 16 +F9 + xy: 256, 112 + size: 16, 16 +F9_pressed + xy: 272, 112 + size: 16, 16 +F10 + xy: 288, 112 + size: 16, 16 +F10_pressed + xy: 304, 112 + size: 16, 16 +F11 + xy: 320, 112 + size: 16, 16 +F11_pressed + xy: 336, 112 + size: 16, 16 +F12 + xy: 352, 112 + size: 16, 16 +F12_pressed + xy: 368, 112 + size: 16, 16 \ No newline at end of file diff --git a/forge-gui/res/adventure/Shandalar/skin/keys.png b/forge-gui/res/adventure/Shandalar/skin/keys.png index 457aa41082c..ee3db1a8966 100644 Binary files a/forge-gui/res/adventure/Shandalar/skin/keys.png and b/forge-gui/res/adventure/Shandalar/skin/keys.png differ diff --git a/forge-gui/res/adventure/Shandalar/sprites/items.atlas b/forge-gui/res/adventure/Shandalar/sprites/items.atlas index ac90e0bce0e..7b08f7c8dba 100644 --- a/forge-gui/res/adventure/Shandalar/sprites/items.atlas +++ b/forge-gui/res/adventure/Shandalar/sprites/items.atlas @@ -35,7 +35,10 @@ Mana size: 16, 16 Deck xy: 48, 48 - size: 16, 16 + size: 16, 16 +ExitToWorldMap + xy: 48, 64 + size: 16, 16 Item xy: 0, 64 size: 16, 16 diff --git a/forge-gui/res/adventure/Shandalar/sprites/items.png b/forge-gui/res/adventure/Shandalar/sprites/items.png index fd8975a817b..108810b84bd 100644 Binary files a/forge-gui/res/adventure/Shandalar/sprites/items.png and b/forge-gui/res/adventure/Shandalar/sprites/items.png differ diff --git a/forge-gui/res/adventure/Shandalar/ui/hud.json b/forge-gui/res/adventure/Shandalar/ui/hud.json index f146b816890..fcaaa2830f6 100644 --- a/forge-gui/res/adventure/Shandalar/ui/hud.json +++ b/forge-gui/res/adventure/Shandalar/ui/hud.json @@ -82,6 +82,17 @@ "x": 442, "y": 90 }, + { + "type": "TextButton", + "name": "exittoworldmap", + "style":"menu", + "text": "{Scale=200%}[+ExitToWorldMap]", + "binding": "ExitToWorldMap", + "width": 48, + "height": 36, + "x": 424, + "y": 66 + } { "type": "TextButton", "name": "deck", diff --git a/forge-gui/res/adventure/Shandalar/ui/hud_landscape.json b/forge-gui/res/adventure/Shandalar/ui/hud_landscape.json index a6c9dcb47a6..4279ecc129d 100644 --- a/forge-gui/res/adventure/Shandalar/ui/hud_landscape.json +++ b/forge-gui/res/adventure/Shandalar/ui/hud_landscape.json @@ -136,6 +136,17 @@ "height": 18, "x": 0, "y": 80 + }, + { + "type": "TextButton", + "name": "exittoworldmap", + "style":"menu", + "text": "{Scale=200%}[+ExitToWorldMap]", + "binding": "ExitToWorldMap", + "width": 64, + "height": 32, + "x": -128, + "y": -128 } ] } \ No newline at end of file diff --git a/forge-gui/res/adventure/Shandalar/ui/hud_portrait.json b/forge-gui/res/adventure/Shandalar/ui/hud_portrait.json index d8cda8c3385..5587168dc17 100644 --- a/forge-gui/res/adventure/Shandalar/ui/hud_portrait.json +++ b/forge-gui/res/adventure/Shandalar/ui/hud_portrait.json @@ -135,6 +135,17 @@ "height": 18, "x": 0, "y": 80 + }, + { + "type": "TextButton", + "name": "exittoworldmap", + "style":"menu", + "text": "{Scale=200%}[+ExitToWorldMap]", + "binding": "ExitToWorldMap", + "width": 64, + "height": 32, + "x": -128, + "y": -128 } ] } \ No newline at end of file