diff --git a/engine/src/main/java/org/destinationsol/game/screens/BuyItemsScreen.java b/engine/src/main/java/org/destinationsol/game/screens/BuyItemsScreen.java index 702ef2ebb..ec8bc9a7b 100644 --- a/engine/src/main/java/org/destinationsol/game/screens/BuyItemsScreen.java +++ b/engine/src/main/java/org/destinationsol/game/screens/BuyItemsScreen.java @@ -16,7 +16,6 @@ package org.destinationsol.game.screens; -import org.destinationsol.GameOptions; import org.destinationsol.SolApplication; import org.destinationsol.game.FactionInfo; import org.destinationsol.game.Hero; @@ -24,16 +23,37 @@ import org.destinationsol.game.item.ItemContainer; import org.destinationsol.game.item.SolItem; import org.destinationsol.game.ship.SolShip; -import org.destinationsol.ui.SolInputManager; -import org.destinationsol.ui.SolUiControl; +import org.destinationsol.ui.nui.screens.InventoryScreen; +import org.destinationsol.ui.nui.widgets.UIWarnButton; +import org.terasology.nui.backends.libgdx.GDXInputUtil; +import org.terasology.nui.widgets.UIButton; +/** + * This screen allows you to purchase items for the hero's ship. + * The purchased items are moved to the hero's inventory and the cost deducted from the hero's money. + */ public class BuyItemsScreen extends InventoryOperationsScreen { - public final SolUiControl buyControl; + private final UIButton[] actionButtons = new UIButton[1]; + + @Override + public void initialise(SolApplication solApplication, InventoryScreen inventoryScreen) { + UIWarnButton buyButton = new UIWarnButton("buyButton", "Buy"); + buyButton.setKey(GDXInputUtil.GDXToNuiKey(solApplication.getOptions().getKeyBuyItem())); + buyButton.subscribe(button -> { + SolGame game = solApplication.getGame(); + Hero hero = game.getHero(); + TalkScreen talkScreen = game.getScreens().talkScreen; + SolShip target = talkScreen.getTarget(); + SolItem selectedItem = inventoryScreen.getSelectedItem(); - BuyItemsScreen(InventoryScreen inventoryScreen, GameOptions gameOptions) { - buyControl = new SolUiControl(inventoryScreen.itemCtrl(0), true, gameOptions.getKeyBuyItem()); - buyControl.setDisplayName("Buy"); - controls.add(buyControl); + target.getTradeContainer().getItems().remove(selectedItem); + hero.getItemContainer().add(selectedItem); + hero.setMoney(hero.getMoney() - selectedItem.getPrice()); + FactionInfo.setDisposition(target.getFactionID(), 1); + + inventoryScreen.updateItemRows(); + }); + actionButtons[0] = buyButton; } @Override @@ -47,28 +67,27 @@ public String getHeader() { } @Override - public void updateCustom(SolApplication solApplication, SolInputManager.InputPointer[] inputPointers, boolean clickedOutside) { + public UIButton[] getActionButtons() { + return actionButtons; + } + + public UIWarnButton getBuyControl() { + return (UIWarnButton) actionButtons[0]; + } + + @Override + public void update(SolApplication solApplication, InventoryScreen inventoryScreen) { SolGame game = solApplication.getGame(); - InventoryScreen is = game.getScreens().inventoryScreen; Hero hero = game.getHero(); TalkScreen talkScreen = game.getScreens().talkScreen; - SolShip target = talkScreen.getTarget(); if (talkScreen.isTargetFar(hero)) { - solApplication.getInputManager().setScreen(solApplication, game.getScreens().mainGameScreen); + solApplication.getNuiManager().removeScreen(inventoryScreen); return; } - SolItem selItem = is.getSelectedItem(); + SolItem selItem = inventoryScreen.getSelectedItem(); boolean enabled = selItem != null && hero.getMoney() >= selItem.getPrice() && hero.getItemContainer().canAdd(selItem); - buyControl.setDisplayName(enabled ? "Buy" : "---"); - buyControl.setEnabled(enabled); - if (!enabled) { - return; - } - if (buyControl.isJustOff()) { - target.getTradeContainer().getItems().remove(selItem); - hero.getItemContainer().add(selItem); - hero.setMoney(hero.getMoney() - selItem.getPrice()); - FactionInfo.setDisposition(target.getFactionID(), 1); - } + UIButton buyButton = actionButtons[0]; + buyButton.setText(enabled ? "Buy" : "---"); + buyButton.setEnabled(enabled); } } diff --git a/engine/src/main/java/org/destinationsol/game/screens/ChangeShipScreen.java b/engine/src/main/java/org/destinationsol/game/screens/ChangeShipScreen.java index 049ec0ac6..c0bcff042 100644 --- a/engine/src/main/java/org/destinationsol/game/screens/ChangeShipScreen.java +++ b/engine/src/main/java/org/destinationsol/game/screens/ChangeShipScreen.java @@ -16,7 +16,6 @@ package org.destinationsol.game.screens; import com.badlogic.gdx.math.Vector2; -import org.destinationsol.GameOptions; import org.destinationsol.SolApplication; import org.destinationsol.game.Hero; import org.destinationsol.game.SolGame; @@ -29,16 +28,31 @@ import org.destinationsol.game.ship.SolShip; import org.destinationsol.game.ship.hulls.Hull; import org.destinationsol.game.ship.hulls.HullConfig; -import org.destinationsol.ui.SolInputManager; -import org.destinationsol.ui.SolUiControl; +import org.destinationsol.ui.nui.screens.InventoryScreen; +import org.destinationsol.ui.nui.widgets.KeyActivatedButton; +import org.terasology.nui.backends.libgdx.GDXInputUtil; +import org.terasology.nui.widgets.UIButton; +/** + * This screen allows you to purchase a new ship for the hero. + * The hero's previous ship will be replaced with the purchased ship and the cost deducted from the hero's money. + */ public class ChangeShipScreen extends InventoryOperationsScreen { - private final SolUiControl changeControl; + private final UIButton[] actionButtons = new UIButton[1]; + + @Override + public void initialise(SolApplication solApplication, InventoryScreen inventoryScreen) { + KeyActivatedButton changeButton = new KeyActivatedButton("changeButton", "Change"); + changeButton.setKey(GDXInputUtil.GDXToNuiKey(solApplication.getOptions().getKeyChangeShip())); + changeButton.subscribe(button -> { + SolGame game = solApplication.getGame(); + Hero hero = game.getHero(); + SolItem selectedItem = inventoryScreen.getSelectedItem(); - ChangeShipScreen(InventoryScreen inventoryScreen, GameOptions gameOptions) { - changeControl = new SolUiControl(inventoryScreen.itemCtrl(0), true, gameOptions.getKeyChangeShip()); - changeControl.setDisplayName("Change"); - controls.add(changeControl); + hero.setMoney(hero.getMoney() - selectedItem.getPrice()); + changeShip(game, hero, (ShipItem) selectedItem); + }); + actionButtons[0] = changeButton; } @Override @@ -52,38 +66,39 @@ public String getHeader() { } @Override - public void updateCustom(SolApplication solApplication, SolInputManager.InputPointer[] inputPointers, boolean clickedOutside) { + public UIButton[] getActionButtons() { + return actionButtons; + } + + @Override + public void update(SolApplication solApplication, InventoryScreen inventoryScreen) { SolGame game = solApplication.getGame(); - InventoryScreen is = game.getScreens().inventoryScreen; Hero hero = game.getHero(); TalkScreen talkScreen = game.getScreens().talkScreen; if (talkScreen.isTargetFar(hero)) { solApplication.getInputManager().setScreen(solApplication, game.getScreens().mainGameScreen); return; } - SolItem selItem = is.getSelectedItem(); + + UIButton changeButton = actionButtons[0]; + + SolItem selItem = inventoryScreen.getSelectedItem(); if (selItem == null) { - changeControl.setDisplayName("---"); - changeControl.setEnabled(false); + changeButton.setText("---"); + changeButton.setEnabled(false); return; } boolean enabled = hasMoneyToBuyShip(hero, selItem); boolean sameShip = isSameShip(hero, selItem); if (enabled && !sameShip) { - changeControl.setDisplayName("Change"); - changeControl.setEnabled(true); + changeButton.setText("Change"); + changeButton.setEnabled(true); } else if (enabled && sameShip) { - changeControl.setDisplayName("Have it"); - changeControl.setEnabled(false); - return; + changeButton.setText("Have it"); + changeButton.setEnabled(false); } else { - changeControl.setDisplayName("---"); - changeControl.setEnabled(false); - return; - } - if (changeControl.isJustOff()) { - hero.setMoney(hero.getMoney() - selItem.getPrice()); - changeShip(game, hero, (ShipItem) selItem); + changeButton.setText("---"); + changeButton.setEnabled(false); } } diff --git a/engine/src/main/java/org/destinationsol/game/screens/ChooseMercenaryScreen.java b/engine/src/main/java/org/destinationsol/game/screens/ChooseMercenaryScreen.java index 316021f2f..d18283521 100644 --- a/engine/src/main/java/org/destinationsol/game/screens/ChooseMercenaryScreen.java +++ b/engine/src/main/java/org/destinationsol/game/screens/ChooseMercenaryScreen.java @@ -15,7 +15,6 @@ */ package org.destinationsol.game.screens; -import org.destinationsol.GameOptions; import org.destinationsol.SolApplication; import org.destinationsol.game.SolGame; import org.destinationsol.game.item.ItemContainer; @@ -23,60 +22,85 @@ import org.destinationsol.game.item.SolItem; import org.destinationsol.game.ship.SolShip; import org.destinationsol.ui.SolInputManager; -import org.destinationsol.ui.SolUiControl; +import org.destinationsol.ui.nui.NUIManager; +import org.destinationsol.ui.nui.screens.InventoryScreen; +import org.destinationsol.ui.nui.widgets.KeyActivatedButton; +import org.terasology.nui.backends.libgdx.GDXInputUtil; +import org.terasology.nui.widgets.UIButton; +/** + * This screen shows an overview of all the mercenaries that the hero has hired. + * You can manage each mercenary's independent inventory from here, as well as selecting their equipped items. + */ public class ChooseMercenaryScreen extends InventoryOperationsScreen { - private final SolUiControl giveControl; - private final SolUiControl takeControl; - private final SolUiControl equipControl; + private final UIButton[] actionButtons = new UIButton[3]; private final ItemContainer EMPTY_ITEM_CONTAINER = new ItemContainer(); - ChooseMercenaryScreen(InventoryScreen inventoryScreen, GameOptions gameOptions) { - giveControl = new SolUiControl(inventoryScreen.itemCtrl(0), true, gameOptions.getKeyShoot()); - giveControl.setDisplayName("Give Items"); - controls.add(giveControl); + public ChooseMercenaryScreen() { + } + + @Override + public void initialise(SolApplication solApplication, InventoryScreen inventoryScreen) { + KeyActivatedButton giveButton = new KeyActivatedButton("giveButton", "Give Items"); + giveButton.setKey(GDXInputUtil.GDXToNuiKey(solApplication.getOptions().getKeyShoot())); + giveButton.subscribe(button -> { + SolItem selectedItem = inventoryScreen.getSelectedItem(); + SolInputManager inputManager = solApplication.getInputManager(); + NUIManager nuiManager = solApplication.getNuiManager(); + + SolShip solship = ((MercItem) selectedItem).getSolShip(); + inputManager.setScreen(solApplication, solApplication.getGame().getScreens().mainGameScreen); + nuiManager.removeScreen(inventoryScreen); + inventoryScreen.getGiveItems().setTarget(solship); + inventoryScreen.setOperations(inventoryScreen.getGiveItems()); + nuiManager.pushScreen(inventoryScreen); + }); + actionButtons[0] = giveButton; + + KeyActivatedButton takeButton = new KeyActivatedButton("takeButton", "Take Items"); + takeButton.setKey(GDXInputUtil.GDXToNuiKey(solApplication.getOptions().getKeyShoot2())); + takeButton.subscribe(button -> { + SolItem selectedItem = inventoryScreen.getSelectedItem(); + SolInputManager inputManager = solApplication.getInputManager(); + NUIManager nuiManager = solApplication.getNuiManager(); - takeControl = new SolUiControl(inventoryScreen.itemCtrl(1), true, gameOptions.getKeyShoot2()); - takeControl.setDisplayName("Take Items"); - controls.add(takeControl); - - equipControl = new SolUiControl(inventoryScreen.itemCtrl(2), true, gameOptions.getKeyDrop()); - equipControl.setDisplayName("Equip Items"); - controls.add(equipControl); + SolShip solship = ((MercItem) selectedItem).getSolShip(); + inputManager.setScreen(solApplication, solApplication.getGame().getScreens().mainGameScreen); + inventoryScreen.getTakeItems().setTarget(solship); + nuiManager.removeScreen(inventoryScreen); + inventoryScreen.setOperations(inventoryScreen.getTakeItems()); + nuiManager.pushScreen(inventoryScreen); + }); + actionButtons[1] = takeButton; + + KeyActivatedButton equipButton = new KeyActivatedButton("equipButton", "Equip Items"); + equipButton.setKey(GDXInputUtil.GDXToNuiKey(solApplication.getOptions().getKeyDrop())); + equipButton.subscribe(button -> { + SolItem selectedItem = inventoryScreen.getSelectedItem(); + SolInputManager inputManager = solApplication.getInputManager(); + NUIManager nuiManager = solApplication.getNuiManager(); + + SolShip solship = ((MercItem) selectedItem).getSolShip(); + inputManager.setScreen(solApplication, solApplication.getGame().getScreens().mainGameScreen); + nuiManager.removeScreen(inventoryScreen); + inventoryScreen.getShowInventory().setTarget(solship); + inventoryScreen.setOperations(inventoryScreen.getShowInventory()); + nuiManager.pushScreen(inventoryScreen); + }); + actionButtons[2] = equipButton; } @Override - public void updateCustom(SolApplication solApplication, SolInputManager.InputPointer[] inputPointers, boolean clickedOutside) { - SolGame game = solApplication.getGame(); - InventoryScreen is = game.getScreens().inventoryScreen; - SolInputManager inputMan = solApplication.getInputManager(); - GameScreens screens = game.getScreens(); - SolItem selItem = is.getSelectedItem(); - boolean selNull = selItem != null; + public void update(SolApplication solApplication, InventoryScreen inventoryScreen) { + boolean selNull = inventoryScreen.getSelectedItem() != null; - giveControl.setEnabled(selNull); - takeControl.setEnabled(selNull); - equipControl.setEnabled(selNull); + UIButton giveButton = actionButtons[0]; + UIButton takeButton = actionButtons[1]; + UIButton equipButton = actionButtons[2]; - if (giveControl.isJustOff() && selNull) { - SolShip solship = ((MercItem) selItem).getSolShip(); - inputMan.setScreen(solApplication, screens.mainGameScreen); - is.giveItemsScreen.setTarget(solship); - is.setOperations(is.giveItemsScreen); - inputMan.addScreen(solApplication, is); - } else if (takeControl.isJustOff() && selNull) { - SolShip solship = ((MercItem) selItem).getSolShip(); - inputMan.setScreen(solApplication, screens.mainGameScreen); - is.takeItems.setTarget(solship); - is.setOperations(is.takeItems); - inputMan.addScreen(solApplication, is); - } else if (equipControl.isJustOff() && selNull) { - SolShip solship = ((MercItem) selItem).getSolShip(); - inputMan.setScreen(solApplication, screens.mainGameScreen); - is.showInventory.setTarget(solship); - is.setOperations(is.showInventory); - inputMan.addScreen(solApplication, is); - } + giveButton.setEnabled(selNull); + takeButton.setEnabled(selNull); + equipButton.setEnabled(selNull); } @Override @@ -95,4 +119,8 @@ public String getHeader() { return "Mercenaries:"; } + @Override + public UIButton[] getActionButtons() { + return actionButtons; + } } diff --git a/engine/src/main/java/org/destinationsol/game/screens/GameScreens.java b/engine/src/main/java/org/destinationsol/game/screens/GameScreens.java index 8ea147dbd..c5178173a 100644 --- a/engine/src/main/java/org/destinationsol/game/screens/GameScreens.java +++ b/engine/src/main/java/org/destinationsol/game/screens/GameScreens.java @@ -18,6 +18,7 @@ import org.destinationsol.SolApplication; import org.destinationsol.game.context.Context; import org.destinationsol.ui.SolLayouts; +import org.destinationsol.ui.nui.screens.InventoryScreen; public class GameScreens { public final MainGameScreen mainGameScreen; @@ -34,7 +35,7 @@ public GameScreens(SolApplication cmp, Context context) { mainGameScreen = new MainGameScreen(rightPaneLayout, context); mapScreen = new MapScreen(rightPaneLayout, cmp.isMobile(), cmp.getOptions()); menuScreen = new MenuScreen(layouts.menuLayout, cmp.getOptions()); - inventoryScreen = new InventoryScreen(cmp.getOptions()); + inventoryScreen = (org.destinationsol.ui.nui.screens.InventoryScreen) cmp.getNuiManager().createScreen("engine:inventoryScreen"); talkScreen = new TalkScreen(layouts.menuLayout, cmp.getOptions()); waypointCreationScreen = new WaypointCreationScreen(layouts.menuLayout, cmp.getOptions(), mapScreen); consoleScreen = new ConsoleScreen(context); diff --git a/engine/src/main/java/org/destinationsol/game/screens/GiveItemsScreen.java b/engine/src/main/java/org/destinationsol/game/screens/GiveItemsScreen.java index b0862faa1..eb98224a9 100644 --- a/engine/src/main/java/org/destinationsol/game/screens/GiveItemsScreen.java +++ b/engine/src/main/java/org/destinationsol/game/screens/GiveItemsScreen.java @@ -22,17 +22,36 @@ import org.destinationsol.game.item.ItemContainer; import org.destinationsol.game.item.SolItem; import org.destinationsol.game.ship.SolShip; -import org.destinationsol.ui.SolInputManager; -import org.destinationsol.ui.SolUiControl; +import org.destinationsol.ui.nui.screens.InventoryScreen; +import org.destinationsol.ui.nui.widgets.KeyActivatedButton; +import org.terasology.nui.backends.libgdx.GDXInputUtil; +import org.terasology.nui.widgets.UIButton; +/** + * This screen allows the hero to gift items from their inventory to the targeted mercenary. + */ public class GiveItemsScreen extends InventoryOperationsScreen { - private final SolUiControl giveControl; + private final UIButton[] actionButtons = new UIButton[1]; private SolShip target; - GiveItemsScreen(InventoryScreen inventoryScreen, GameOptions gameOptions) { - giveControl = new SolUiControl(inventoryScreen.itemCtrl(0), true, gameOptions.getKeySellItem()); - giveControl.setDisplayName("Give"); - controls.add(giveControl); + public GiveItemsScreen() { + } + + @Override + public void initialise(SolApplication solApplication, InventoryScreen inventoryScreen) { + KeyActivatedButton giveButton = new KeyActivatedButton("giveButton", "Give"); + giveButton.setKey(GDXInputUtil.GDXToNuiKey(solApplication.getOptions().getKeySellItem())); + giveButton.subscribe(button -> { + Hero hero = solApplication.getGame().getHero(); + SolItem selectedItem = inventoryScreen.getSelectedItem(); + + ItemContainer itemContainer = hero.getItemContainer(); + inventoryScreen.setSelected(itemContainer.getSelectionAfterRemove(inventoryScreen.getSelected())); + itemContainer.remove(selectedItem); + target.getItemContainer().add(selectedItem); + inventoryScreen.updateItemRows(); + }); + actionButtons[0] = giveButton; } @Override @@ -53,40 +72,36 @@ public String getHeader() { } @Override - public void updateCustom(SolApplication solApplication, SolInputManager.InputPointer[] inputPointers, boolean clickedOutside) { + public UIButton[] getActionButtons() { + return actionButtons; + } + + @Override + public void update(SolApplication solApplication, InventoryScreen inventoryScreen) { SolGame game = solApplication.getGame(); - InventoryScreen inventoryScreen = game.getScreens().inventoryScreen; Hero hero = game.getHero(); - SolItem selItem = inventoryScreen.getSelectedItem(); - if (selItem == null) { - giveControl.setDisplayName("----"); - giveControl.setEnabled(false); + UIButton giveButton = actionButtons[0]; + + SolItem selectedItem = inventoryScreen.getSelectedItem(); + if (selectedItem == null) { + giveButton.setText("----"); + giveButton.setEnabled(false); return; } - boolean isWornAndCanBeGiven = isItemEquippedAndGiveable(selItem, solApplication.getOptions()); - boolean enabled = isItemGiveable(selItem, target); + boolean isWornAndCanBeGiven = isItemEquippedAndGiveable(selectedItem, solApplication.getOptions()); + boolean enabled = isItemGiveable(selectedItem, target); if (enabled && isWornAndCanBeGiven) { - giveControl.setDisplayName("Give"); - giveControl.setEnabled(true); + giveButton.setText("Give"); + giveButton.setEnabled(true); } else if (enabled) { - giveControl.setDisplayName("Unequip it!"); - giveControl.setEnabled(false); + giveButton.setText("Unequip it!"); + giveButton.setEnabled(false); } else { - giveControl.setDisplayName("----"); - giveControl.setEnabled(false); - } - - if (!enabled || !isWornAndCanBeGiven) { - return; - } - if (giveControl.isJustOff()) { - ItemContainer itemContainer = hero.getItemContainer(); - inventoryScreen.setSelected(itemContainer.getSelectionAfterRemove(inventoryScreen.getSelected())); - itemContainer.remove(selItem); - target.getItemContainer().add(selItem); + giveButton.setText("----"); + giveButton.setEnabled(false); } } diff --git a/engine/src/main/java/org/destinationsol/game/screens/HireShipsScreen.java b/engine/src/main/java/org/destinationsol/game/screens/HireShipsScreen.java index 613776671..e34745ab0 100644 --- a/engine/src/main/java/org/destinationsol/game/screens/HireShipsScreen.java +++ b/engine/src/main/java/org/destinationsol/game/screens/HireShipsScreen.java @@ -15,7 +15,6 @@ */ package org.destinationsol.game.screens; -import org.destinationsol.GameOptions; import org.destinationsol.SolApplication; import org.destinationsol.game.Hero; import org.destinationsol.game.SolGame; @@ -23,16 +22,32 @@ import org.destinationsol.game.item.MercItem; import org.destinationsol.game.item.SolItem; import org.destinationsol.mercenary.MercenaryUtils; -import org.destinationsol.ui.SolInputManager; -import org.destinationsol.ui.SolUiControl; +import org.destinationsol.ui.nui.screens.InventoryScreen; +import org.destinationsol.ui.nui.widgets.KeyActivatedButton; +import org.terasology.nui.backends.libgdx.GDXInputUtil; +import org.terasology.nui.widgets.UIButton; public class HireShipsScreen extends InventoryOperationsScreen { - private final SolUiControl hireControl; + private final UIButton[] actionButtons = new UIButton[1]; - HireShipsScreen(InventoryScreen inventoryScreen, GameOptions gameOptions) { - hireControl = new SolUiControl(inventoryScreen.itemCtrl(0), true, gameOptions.getKeyHireShip()); - hireControl.setDisplayName("Hire"); - controls.add(hireControl); + public HireShipsScreen() { + } + + @Override + public void initialise(SolApplication solApplication, InventoryScreen inventoryScreen) { + KeyActivatedButton hireButton = new KeyActivatedButton(); + hireButton.setKey(GDXInputUtil.GDXToNuiKey(solApplication.getOptions().getKeyHireShip())); + hireButton.subscribe(button -> { + SolGame game = solApplication.getGame(); + Hero hero = game.getHero(); + SolItem selectedItem = inventoryScreen.getSelectedItem(); + + boolean hired = MercenaryUtils.createMerc(game, hero, (MercItem) selectedItem); + if (hired) { + hero.setMoney(hero.getMoney() - selectedItem.getPrice()); + } + }); + actionButtons[0] = hireButton; } @Override @@ -46,27 +61,24 @@ public String getHeader() { } @Override - public void updateCustom(SolApplication solApplication, SolInputManager.InputPointer[] inputPointers, boolean clickedOutside) { + public UIButton[] getActionButtons() { + return actionButtons; + } + + @Override + public void update(SolApplication solApplication, InventoryScreen inventoryScreen) { SolGame game = solApplication.getGame(); - InventoryScreen is = game.getScreens().inventoryScreen; Hero hero = game.getHero(); TalkScreen talkScreen = game.getScreens().talkScreen; if (talkScreen.isTargetFar(hero)) { solApplication.getInputManager().setScreen(solApplication, game.getScreens().mainGameScreen); return; } - SolItem selItem = is.getSelectedItem(); + + UIButton hireButton = actionButtons[0]; + SolItem selItem = inventoryScreen.getSelectedItem(); boolean enabled = selItem != null && hero.getMoney() >= selItem.getPrice(); - hireControl.setDisplayName(enabled ? "Hire" : "---"); - hireControl.setEnabled(enabled); - if (!enabled) { - return; - } - if (hireControl.isJustOff()) { - boolean hired = MercenaryUtils.createMerc(game, hero, (MercItem) selItem); - if (hired) { - hero.setMoney(hero.getMoney() - selItem.getPrice()); - } - } + hireButton.setText(enabled ? "Hire" : "---"); + hireButton.setEnabled(enabled); } } diff --git a/engine/src/main/java/org/destinationsol/game/screens/InventoryOperationsScreen.java b/engine/src/main/java/org/destinationsol/game/screens/InventoryOperationsScreen.java index bffc7b70d..456994790 100644 --- a/engine/src/main/java/org/destinationsol/game/screens/InventoryOperationsScreen.java +++ b/engine/src/main/java/org/destinationsol/game/screens/InventoryOperationsScreen.java @@ -15,21 +15,35 @@ */ package org.destinationsol.game.screens; +import org.destinationsol.SolApplication; import org.destinationsol.game.SolGame; import org.destinationsol.game.item.ItemContainer; import org.destinationsol.game.item.SolItem; import org.destinationsol.ui.SolUiBaseScreen; +import org.destinationsol.ui.nui.screens.InventoryScreen; +import org.terasology.nui.widgets.UIButton; +/** + * This is the base class for all inventory operations. + */ public abstract class InventoryOperationsScreen extends SolUiBaseScreen { - abstract ItemContainer getItems(SolGame game); + public abstract ItemContainer getItems(SolGame game); - boolean isUsing(SolGame game, SolItem item) { + public boolean isUsing(SolGame game, SolItem item) { return false; } - float getPriceMul() { + public float getPriceMul() { return 1; } - abstract String getHeader(); + public abstract String getHeader(); + + public abstract UIButton[] getActionButtons(); + + public void initialise(SolApplication solApplication, InventoryScreen inventoryScreen) { + } + + public void update(SolApplication solApplication, InventoryScreen inventoryScreen) { + } } diff --git a/engine/src/main/java/org/destinationsol/game/screens/InventoryScreen.java b/engine/src/main/java/org/destinationsol/game/screens/InventoryScreen.java deleted file mode 100644 index cddbe0686..000000000 --- a/engine/src/main/java/org/destinationsol/game/screens/InventoryScreen.java +++ /dev/null @@ -1,410 +0,0 @@ -/* - * Copyright 2018 MovingBlocks - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.destinationsol.game.screens; - -import com.badlogic.gdx.graphics.g2d.TextureAtlas; -import com.badlogic.gdx.math.Rectangle; -import com.badlogic.gdx.math.Vector2; -import org.destinationsol.Const; -import org.destinationsol.GameOptions; -import org.destinationsol.SolApplication; -import org.destinationsol.common.SolColor; -import org.destinationsol.game.SolGame; -import org.destinationsol.game.item.ItemContainer; -import org.destinationsol.game.item.SolItem; -import org.destinationsol.menu.MenuLayout; -import org.destinationsol.ui.DisplayDimensions; -import org.destinationsol.ui.FontSize; -import org.destinationsol.ui.SolInputManager; -import org.destinationsol.ui.SolUiBaseScreen; -import org.destinationsol.ui.SolUiControl; -import org.destinationsol.ui.UiDrawer; - -import java.util.ArrayList; -import java.util.List; - -public class InventoryScreen extends SolUiBaseScreen { - // TODO: Rename! - private static final ItemContainer EMPTY_CONTAINER = new ItemContainer(); - private static final float HEADER_TEXT_OFFSET = .005f; - private static final float SMALL_GAP = .004f; - private static final int BUTTON_ROWS = 4; - private static final float IMG_COL_PERC = .1f; - private static final float EQUI_COL_PERC = .1f; - private static final float PRICE_COL_PERC = .1f; - private static final float AMT_COL_PERC = .1f; - - public final ShowInventory showInventory; - public final BuyItemsScreen buyItemsScreen; - public final SellItems sellItems; - public final ChangeShipScreen changeShipScreen; - public final HireShipsScreen hireShipsScreen; - // The below screens deal with mercenaries - public final ChooseMercenaryScreen chooseMercenaryScreen; - public final GiveItemsScreen giveItemsScreen; - public final TakeItems takeItems; - - public final SolUiControl[] itemControls; - private final SolUiControl previousControl; - private final SolUiControl upControl; - public final SolUiControl nextControl; - public final SolUiControl closeControl; - public final SolUiControl downControl; - - private final Rectangle myArea; - private final Rectangle myListArea; - private final Rectangle myDetailArea; - private final Rectangle myItemCtrlArea; - private final Vector2 myDetailHeaderPos; - private final Vector2 myListHeaderPos; - - private int myPage; - private List mySelected; - private InventoryOperationsScreen myOperations; - - public InventoryScreen(GameOptions gameOptions) { - DisplayDimensions displayDimensions = SolApplication.displayDimensions; - - float contentW = .8f; - float col0 = displayDimensions.getRatio() / 2 - contentW / 2; - float row0 = .2f; - float row = row0; - float backgroundGap = MenuLayout.BG_BORDER; - float bigGap = SMALL_GAP * 6; - float headerH = .03f; - - // list header & controls - myListHeaderPos = new Vector2(col0 + HEADER_TEXT_OFFSET, row + HEADER_TEXT_OFFSET); // offset hack - float listCtrlW = contentW * .15f; - Rectangle nextArea = new Rectangle(col0 + contentW - listCtrlW, row, listCtrlW, headerH); - nextControl = new SolUiControl(nextArea, true, gameOptions.getKeyRight()); - nextControl.setDisplayName(">"); - controls.add(nextControl); - Rectangle prevArea = new Rectangle(nextArea.x - SMALL_GAP - listCtrlW, row, listCtrlW, headerH); - previousControl = new SolUiControl(prevArea, true, gameOptions.getKeyLeft()); - previousControl.setDisplayName("<"); - controls.add(previousControl); - row += headerH + SMALL_GAP; - - // list - float itemRowH = .04f; - float listRow0 = row; - itemControls = new SolUiControl[Const.ITEM_GROUPS_PER_PAGE]; - for (int i = 0; i < Const.ITEM_GROUPS_PER_PAGE; i++) { - Rectangle itemR = new Rectangle(col0, row, contentW, itemRowH); - SolUiControl itemCtrl = new SolUiControl(itemR, true); - itemControls[i] = itemCtrl; - controls.add(itemCtrl); - row += itemRowH + SMALL_GAP; - } - myListArea = new Rectangle(col0, row, contentW, row - SMALL_GAP - listRow0); - row += bigGap; - - // detail header & area - myDetailHeaderPos = new Vector2(col0 + HEADER_TEXT_OFFSET, row + HEADER_TEXT_OFFSET); // offset hack - row += headerH + SMALL_GAP; - float itemCtrlAreaW = contentW * .4f; - myItemCtrlArea = new Rectangle(col0 + contentW - itemCtrlAreaW, row, itemCtrlAreaW, .2f); - myDetailArea = new Rectangle(col0, row, contentW - itemCtrlAreaW - SMALL_GAP, myItemCtrlArea.height); - row += myDetailArea.height; - - // whole - myArea = new Rectangle(col0 - backgroundGap, row0 - backgroundGap, contentW + backgroundGap * 2, row - row0 + backgroundGap * 2); - - closeControl = new SolUiControl(itemCtrl(3), true, gameOptions.getKeyClose()); - closeControl.setDisplayName("Close"); - controls.add(closeControl); - - showInventory = new ShowInventory(this, gameOptions); - buyItemsScreen = new BuyItemsScreen(this, gameOptions); - sellItems = new SellItems(this, gameOptions); - changeShipScreen = new ChangeShipScreen(this, gameOptions); - hireShipsScreen = new HireShipsScreen(this, gameOptions); - chooseMercenaryScreen = new ChooseMercenaryScreen(this, gameOptions); - giveItemsScreen = new GiveItemsScreen(this, gameOptions); - takeItems = new TakeItems(this, gameOptions); - upControl = new SolUiControl(null, true, gameOptions.getKeyUp()); - controls.add(upControl); - downControl = new SolUiControl(null, true, gameOptions.getKeyDown()); - controls.add(downControl); - } - - @Override - public void updateCustom(SolApplication solApplication, SolInputManager.InputPointer[] inputPointers, boolean clickedOutside) { - if (clickedOutside) { - closeControl.maybeFlashPressed(solApplication.getOptions().getKeyClose()); - return; - } - if (closeControl.isJustOff()) { - - SolGame game = solApplication.getGame(); - // Make sure the ChooseMercenaryScreen screen comes back up when we exit a mercenary related screen - if (myOperations == giveItemsScreen || myOperations == takeItems || (myOperations == showInventory && showInventory.getTarget() != game.getHero().getShip())) { - SolInputManager inputMan = solApplication.getInputManager(); - GameScreens screens = game.getScreens(); - InventoryScreen is = screens.inventoryScreen; - - inputMan.setScreen(solApplication, screens.mainGameScreen); - is.setOperations(is.chooseMercenaryScreen); - inputMan.addScreen(solApplication, is); - } - solApplication.getInputManager().setScreen(solApplication, solApplication.getGame().getScreens().mainGameScreen); - return; - } - if (previousControl.isJustOff()) { - myPage--; - } - if (nextControl.isJustOff()) { - myPage++; - } - - ItemContainer itemContainer = myOperations.getItems(solApplication.getGame()); - if (itemContainer == null) { - itemContainer = EMPTY_CONTAINER; - } - int groupCount = itemContainer.groupCount(); - int pageCount = groupCount / Const.ITEM_GROUPS_PER_PAGE; - if (pageCount == 0 || pageCount * Const.ITEM_GROUPS_PER_PAGE < groupCount) { - pageCount += 1; - } - if (myPage < 0) { - myPage = 0; - } - if (myPage >= pageCount) { - myPage = pageCount - 1; - } - - previousControl.setEnabled(0 < myPage); - nextControl.setEnabled(myPage < pageCount - 1); - - if (!itemContainer.containsGroup(mySelected)) { - mySelected = null; - } - int selIdx = -1; - int offset = myPage * Const.ITEM_GROUPS_PER_PAGE; - boolean hNew = showingHeroItems(solApplication); - for (int i = 0; i < itemControls.length; i++) { - SolUiControl itemCtrl = itemControls[i]; - int groupIdx = offset + i; - boolean ctrlEnabled = groupIdx < groupCount; - itemCtrl.setEnabled(ctrlEnabled); - if (!ctrlEnabled) { - continue; - } - List group = itemContainer.getGroup(groupIdx); - if (hNew && itemContainer.isNew(group)) { - itemCtrl.enableWarn(); - } - if (itemCtrl.isJustOff()) { - mySelected = group; - } - if (mySelected == group) { - selIdx = groupIdx; - } - } - if (selIdx < 0 && groupCount > 0) { - mySelected = itemContainer.getGroup(offset); - } - if (upControl.isJustOff() && selIdx > 0) { - selIdx--; - mySelected = itemContainer.getGroup(selIdx); - if (selIdx < offset) { - myPage--; - } - } - if (downControl.isJustOff() && selIdx < groupCount - 1) { - selIdx++; - mySelected = itemContainer.getGroup(selIdx); - if (selIdx >= offset + Const.ITEM_GROUPS_PER_PAGE) { - myPage++; - } - } - if (mySelected != null) { - itemContainer.seen(mySelected); - } - } - - @Override - public boolean isCursorOnBackground(SolInputManager.InputPointer inputPointer) { - return myArea.contains(inputPointer.x, inputPointer.y); - } - - @Override - public void onAdd(SolApplication solApplication) { - if (myOperations != null) { - solApplication.getInputManager().addScreen(solApplication, myOperations); - } - myPage = 0; - mySelected = null; - } - - @Override - public void drawBackground(UiDrawer uiDrawer, SolApplication solApplication) { - uiDrawer.draw(myArea, SolColor.UI_BG); - } - - @Override - public void drawImages(UiDrawer uiDrawer, SolApplication solApplication) { - SolGame game = solApplication.getGame(); - ItemContainer itemContainer = myOperations.getItems(game); - if (itemContainer == null) { - itemContainer = EMPTY_CONTAINER; - } - - float imgColW = myListArea.width * IMG_COL_PERC; - float rowH = itemControls[0].getScreenArea().height; - float imgSz = imgColW < rowH ? imgColW : rowH; - - uiDrawer.draw(myDetailArea, SolColor.UI_INACTIVE); - for (int i = 0; i < itemControls.length; i++) { - int groupIdx = myPage * Const.ITEM_GROUPS_PER_PAGE + i; - int groupCount = itemContainer.groupCount(); - if (groupCount <= groupIdx) { - continue; - } - SolUiControl itemCtrl = itemControls[i]; - List group = itemContainer.getGroup(groupIdx); - SolItem item = group.get(0); - TextureAtlas.AtlasRegion tex = item.getIcon(game); - Rectangle rect = itemCtrl.getScreenArea(); - float rowCenterY = rect.y + rect.height / 2; - uiDrawer.draw(uiDrawer.whiteTexture, imgSz, imgSz, imgSz / 2, imgSz / 2, rect.x + imgColW / 2, rowCenterY, 0, item.getItemType().uiColor); - uiDrawer.draw(tex, imgSz, imgSz, imgSz / 2, imgSz / 2, rect.x + imgColW / 2, rowCenterY, 0, SolColor.WHITE); - } - } - - @Override - public void drawText(UiDrawer uiDrawer, SolApplication solApplication) { - SolGame game = solApplication.getGame(); - ItemContainer itemContainer = myOperations.getItems(game); - if (itemContainer == null) { - itemContainer = EMPTY_CONTAINER; - } - - float imgColW = myListArea.width * IMG_COL_PERC; - float equiColW = myListArea.width * EQUI_COL_PERC; - float priceWidth = myListArea.width * PRICE_COL_PERC; - float amtWidth = myListArea.width * AMT_COL_PERC; - float nameWidth = myListArea.width - imgColW - equiColW - priceWidth - amtWidth; - for (int i = 0; i < itemControls.length; i++) { - int groupIdx = myPage * Const.ITEM_GROUPS_PER_PAGE + i; - int groupCount = itemContainer.groupCount(); - if (groupCount <= groupIdx) { - continue; - } - SolUiControl itemCtrl = itemControls[i]; - List group = itemContainer.getGroup(groupIdx); - SolItem item = group.get(0); - Rectangle rect = itemCtrl.getScreenArea(); - float rowCenterY = rect.y + rect.height / 2; - if (myOperations.isUsing(game, item)) { - uiDrawer.drawString("using", rect.x + imgColW + equiColW / 2, rowCenterY, FontSize.WINDOW, true, SolColor.WHITE); - } - uiDrawer.drawString(item.getDisplayName(), rect.x + equiColW + imgColW + nameWidth / 2, rowCenterY, FontSize.WINDOW, true, - mySelected == group ? SolColor.WHITE : SolColor.G); - int count = itemContainer.getCount(groupIdx); - if (count > 1) { - uiDrawer.drawString("x" + count, rect.x + rect.width - amtWidth / 2, rowCenterY, FontSize.WINDOW, true, SolColor.WHITE); - } - float mul = myOperations.getPriceMul(); - if (mul > 0) { - float price = item.getPrice() * mul; - uiDrawer.drawString("$" + (int) price, rect.x + rect.width - amtWidth - priceWidth / 2, rowCenterY, FontSize.WINDOW, true, SolColor.LG); - } - } - - uiDrawer.drawString(myOperations.getHeader(), myListHeaderPos.x, myListHeaderPos.y, FontSize.WINDOW, UiDrawer.TextAlignment.LEFT, false, SolColor.WHITE); - uiDrawer.drawString("Selected Item:", myDetailHeaderPos.x, myDetailHeaderPos.y, FontSize.WINDOW, UiDrawer.TextAlignment.LEFT, false, SolColor.WHITE); - if (mySelected != null && !mySelected.isEmpty()) { - SolItem selItem = mySelected.get(0); - String desc = selItem.getDisplayName() + "\n" + selItem.getDescription(); - uiDrawer.drawString(desc, myDetailArea.x + .015f, myDetailArea.y + .015f, FontSize.WINDOW, UiDrawer.TextAlignment.LEFT, false, SolColor.WHITE); - } - } - - @Override - public boolean reactsToClickOutside() { - return true; - } - - @Override - public void blurCustom(SolApplication solApplication) { - if (!showingHeroItems(solApplication)) { - return; - } - SolGame game = solApplication.getGame(); - ItemContainer items = myOperations.getItems(game); - if (items != null) { - items.markAllAsSeen(); - } - } - - private boolean showingHeroItems(SolApplication application) { - return application.getGame().getHero().getShip() == showInventory.getTarget() || myOperations == sellItems; - } - - public Rectangle itemCtrl(int row) { - float h = (myItemCtrlArea.height - SMALL_GAP * (BUTTON_ROWS - 1)) / BUTTON_ROWS; - return new Rectangle(myItemCtrlArea.x, myItemCtrlArea.y + (h + SMALL_GAP) * row, myItemCtrlArea.width, h); - } - - public List getSelected() { - return mySelected; - } - - public void setSelected(List selected) { - mySelected = selected; - } - - public SolItem getSelectedItem() { - return mySelected == null || mySelected.isEmpty() ? null : mySelected.get(0); - } - - public InventoryOperationsScreen getOperations() { - return myOperations; - } - - public void setOperations(InventoryOperationsScreen operations) { - myOperations = operations; - } - - public int getPage() { - return myPage; - } - - public List getEquippedItemUIControlsForTutorial(SolGame game) { - List controls = new ArrayList<>(); - ItemContainer itemContainer = myOperations.getItems(game); - if (itemContainer == null) { - return controls; - } - - for (int i = 0; i < itemControls.length; i++) { - int groupIdx = myPage * Const.ITEM_GROUPS_PER_PAGE + i; - int groupCount = itemContainer.groupCount(); - if (groupCount <= groupIdx) { - continue; - } - SolUiControl itemCtrl = itemControls[i]; - List group = itemContainer.getGroup(groupIdx); - SolItem item = group.get(0); - if (myOperations.isUsing(game, item)) { - controls.add(itemCtrl); - } - } - return controls; - } -} diff --git a/engine/src/main/java/org/destinationsol/game/screens/MainGameScreen.java b/engine/src/main/java/org/destinationsol/game/screens/MainGameScreen.java index f725a33c1..f662a82a8 100644 --- a/engine/src/main/java/org/destinationsol/game/screens/MainGameScreen.java +++ b/engine/src/main/java/org/destinationsol/game/screens/MainGameScreen.java @@ -48,6 +48,7 @@ import org.destinationsol.ui.SolUiControl; import org.destinationsol.ui.SolUiScreen; import org.destinationsol.ui.UiDrawer; +import org.destinationsol.ui.nui.NUIScreenLayer; import org.destinationsol.ui.nui.screens.ConsoleScreen; import org.destinationsol.ui.nui.screens.UIShipControlsScreen; import org.terasology.gestalt.assets.ResourceUrn; @@ -225,7 +226,9 @@ public void updateCustom(SolApplication solApplication, SolInputManager.InputPoi zoneNameAnnouncer.update(game, context); - boolean controlsEnabled = inputMan.getTopScreen() == this; + NUIScreenLayer topScreen = solApplication.getNuiManager().getTopScreen(); + boolean controlsEnabled = inputMan.getTopScreen() == this && + (topScreen instanceof org.destinationsol.ui.nui.screens.MainGameScreen || topScreen instanceof UIShipControlsScreen); shipControl.update(solApplication, controlsEnabled); SolCam.DIRECT_CAM_CONTROL = freeCamControl.isOn(); diff --git a/engine/src/main/java/org/destinationsol/game/screens/SellItems.java b/engine/src/main/java/org/destinationsol/game/screens/SellItems.java index bd02e33e6..60dc0cc9f 100644 --- a/engine/src/main/java/org/destinationsol/game/screens/SellItems.java +++ b/engine/src/main/java/org/destinationsol/game/screens/SellItems.java @@ -22,18 +22,43 @@ import org.destinationsol.game.item.ItemContainer; import org.destinationsol.game.item.SolItem; import org.destinationsol.game.ship.SolShip; -import org.destinationsol.ui.SolInputManager; -import org.destinationsol.ui.SolUiControl; +import org.destinationsol.ui.nui.screens.InventoryScreen; +import org.destinationsol.ui.nui.widgets.KeyActivatedButton; +import org.terasology.nui.backends.libgdx.GDXInputUtil; +import org.terasology.nui.widgets.UIButton; +/** + * This screen allows the hero to sell their items in exchange for in-game currency (money). + * The sold items are moved into the vendor's inventory. + */ public class SellItems extends InventoryOperationsScreen { private static float PERC = .8f; - private final SolUiControl sellControl; + private final UIButton[] actionButtons = new UIButton[1]; - SellItems(InventoryScreen inventoryScreen, GameOptions gameOptions) { - sellControl = new SolUiControl(inventoryScreen.itemCtrl(0), true, gameOptions.getKeySellItem()); - sellControl.setDisplayName("Sell"); - controls.add(sellControl); + public SellItems() { + } + + @Override + public void initialise(SolApplication solApplication, InventoryScreen inventoryScreen) { + KeyActivatedButton sellButton = new KeyActivatedButton("sellButton", "Sell"); + sellButton.setKey(GDXInputUtil.GDXToNuiKey(solApplication.getOptions().getKeySellItem())); + sellButton.subscribe(button -> { + SolGame game = solApplication.getGame(); + Hero hero = game.getHero(); + SolItem selectedItem = inventoryScreen.getSelectedItem(); + TalkScreen talkScreen = game.getScreens().talkScreen; + SolShip target = talkScreen.getTarget(); + + ItemContainer itemContainer = hero.getItemContainer(); + inventoryScreen.setSelected(itemContainer.getSelectionAfterRemove(inventoryScreen.getSelected())); + itemContainer.remove(selectedItem); + target.getTradeContainer().getItems().add(selectedItem); + hero.setMoney(hero.getMoney() + selectedItem.getPrice() * PERC); + + inventoryScreen.updateItemRows(); + }); + actionButtons[0] = sellButton; } @Override @@ -59,9 +84,15 @@ public String getHeader() { } @Override - public void updateCustom(SolApplication solApplication, SolInputManager.InputPointer[] inputPointers, boolean clickedOutside) { + public UIButton[] getActionButtons() { + return actionButtons; + } + + @Override + public void update(SolApplication solApplication, InventoryScreen inventoryScreen) { SolGame game = solApplication.getGame(); - InventoryScreen inventoryScreen = game.getScreens().inventoryScreen; + UIButton sellButton = actionButtons[0]; + TalkScreen talkScreen = game.getScreens().talkScreen; SolShip target = talkScreen.getTarget(); Hero hero = game.getHero(); @@ -71,8 +102,8 @@ public void updateCustom(SolApplication solApplication, SolInputManager.InputPoi } SolItem selItem = inventoryScreen.getSelectedItem(); if (selItem == null) { - sellControl.setDisplayName("----"); - sellControl.setEnabled(false); + sellButton.setText("----"); + sellButton.setEnabled(false); return; } @@ -80,25 +111,14 @@ public void updateCustom(SolApplication solApplication, SolInputManager.InputPoi boolean enabled = isItemSellable(selItem, target); if (enabled && isWornAndCanBeSold) { - sellControl.setDisplayName("Sell"); - sellControl.setEnabled(true); + sellButton.setText("Sell"); + sellButton.setEnabled(true); } else if (enabled) { - sellControl.setDisplayName("Unequip it!"); - sellControl.setEnabled(false); + sellButton.setText("Unequip it!"); + sellButton.setEnabled(false); } else { - sellControl.setDisplayName("----"); - sellControl.setEnabled(false); - } - - if (!enabled || !isWornAndCanBeSold) { - return; - } - if (sellControl.isJustOff()) { - ItemContainer itemContainer = hero.getItemContainer(); - inventoryScreen.setSelected(itemContainer.getSelectionAfterRemove(inventoryScreen.getSelected())); - itemContainer.remove(selItem); - target.getTradeContainer().getItems().add(selItem); - hero.setMoney(hero.getMoney() + selItem.getPrice() * PERC); + sellButton.setText("----"); + sellButton.setEnabled(false); } } diff --git a/engine/src/main/java/org/destinationsol/game/screens/ShowInventory.java b/engine/src/main/java/org/destinationsol/game/screens/ShowInventory.java index 07d8dba0a..6d56b4e2b 100644 --- a/engine/src/main/java/org/destinationsol/game/screens/ShowInventory.java +++ b/engine/src/main/java/org/destinationsol/game/screens/ShowInventory.java @@ -23,79 +23,76 @@ import org.destinationsol.game.ship.SolShip; import org.destinationsol.ui.SolInputManager; import org.destinationsol.ui.SolUiControl; +import org.destinationsol.ui.nui.screens.InventoryScreen; +import org.destinationsol.ui.nui.widgets.KeyActivatedButton; +import org.destinationsol.ui.nui.widgets.UIWarnButton; +import org.terasology.nui.backends.libgdx.GDXInputUtil; +import org.terasology.nui.widgets.UIButton; +import java.util.List; + +/** + * This screen shows the current inventory of the targeted ship. + * You can also equip and de-equip items here, as well as force the ship to drop those items out into space. + */ public class ShowInventory extends InventoryOperationsScreen { - public final SolUiControl eq1Control; - private final SolUiControl eq2Control; - public final SolUiControl dropControl; - + private final UIButton[] actionButtons = new UIButton[3]; + private SolShip target; - ShowInventory(InventoryScreen inventoryScreen, GameOptions gameOptions) { - eq1Control = new SolUiControl(inventoryScreen.itemCtrl(0), true, gameOptions.getKeyEquip()); - eq1Control.setDisplayName("Eq"); - controls.add(eq1Control); - - eq2Control = new SolUiControl(inventoryScreen.itemCtrl(1), true, gameOptions.getKeyEquip2()); - eq2Control.setDisplayName("Eq2"); - controls.add(eq2Control); - - dropControl = new SolUiControl(inventoryScreen.itemCtrl(2), true, gameOptions.getKeyDrop()); - dropControl.setDisplayName("Drop"); - controls.add(dropControl); + public ShowInventory() { } @Override - public void updateCustom(SolApplication solApplication, SolInputManager.InputPointer[] inputPointers, boolean clickedOutside) { - SolGame game = solApplication.getGame(); - InventoryScreen inventoryScreen = game.getScreens().inventoryScreen; - SolItem selItem = inventoryScreen.getSelectedItem(); - - eq1Control.setDisplayName("---"); - eq1Control.setEnabled(false); - eq2Control.setDisplayName("---"); - eq2Control.setEnabled(false); - dropControl.setEnabled(false); - - if (selItem == null || target == null) { - return; - } - - dropControl.setEnabled(true); - if (dropControl.isJustOff()) { - ItemContainer itemContainer = target.getItemContainer(); - inventoryScreen.setSelected(itemContainer.getSelectionAfterRemove(inventoryScreen.getSelected())); - target.dropItem(solApplication.getGame(), selItem); - return; - } + public void initialise(SolApplication solApplication, InventoryScreen inventoryScreen) { + GameOptions gameOptions = solApplication.getOptions(); - Boolean equipped1 = target.maybeUnequip(game, selItem, false, false); - boolean canEquip1 = target.maybeEquip(game, selItem, false, false); - Boolean equipped2 = target.maybeUnequip(game, selItem, true, false); - boolean canEquip2 = target.maybeEquip(game, selItem, true, false); + UIWarnButton equip1Button = new UIWarnButton("equip1Button", "Eq"); + equip1Button.setKey(GDXInputUtil.GDXToNuiKey(gameOptions.getKeyEquip())); + equip1Button.subscribe(button -> { + SolGame game = solApplication.getGame(); + SolItem selItem = inventoryScreen.getSelectedItem(); + if (selItem == null) { + button.setEnabled(false); + return; + } - if (equipped1 || canEquip1) { - eq1Control.setDisplayName(equipped1 ? "Unequip" : "Equip"); - eq1Control.setEnabled(true); - } - if (equipped2 || canEquip2) { - eq2Control.setDisplayName(equipped2 ? "Unequip" : "Set Gun 2"); - eq2Control.setEnabled(true); - } - if (eq1Control.isJustOff()) { - if (equipped1) { + if (target.maybeUnequip(game, selItem, false, false)) { target.maybeUnequip(game, selItem, false, true); } else { target.maybeEquip(game, selItem, false, true); } - } - if (eq2Control.isJustOff()) { - if (equipped2) { + inventoryScreen.updateItemRows(); + }); + + UIWarnButton equip2Button = new UIWarnButton("equip2Button", "Eq2"); + equip2Button.setKey(GDXInputUtil.GDXToNuiKey(gameOptions.getKeyEquip2())); + equip2Button.subscribe(button -> { + SolGame game = solApplication.getGame(); + SolItem selItem = inventoryScreen.getSelectedItem(); + if (target.maybeUnequip(game, selItem, true, false)) { target.maybeUnequip(game, selItem, true, true); } else { target.maybeEquip(game, selItem, true, true); } - } + inventoryScreen.updateItemRows(); + }); + + UIWarnButton dropButton = new UIWarnButton("dropButton", "Drop"); + dropButton.setKey(GDXInputUtil.GDXToNuiKey(gameOptions.getKeyDrop())); + dropButton.subscribe(button -> { + SolItem selItem = inventoryScreen.getSelectedItem(); + ItemContainer itemContainer = target.getItemContainer(); + List newSelection = itemContainer.getSelectionAfterRemove(inventoryScreen.getSelected()); + target.dropItem(solApplication.getGame(), selItem); + inventoryScreen.updateItemRows(); + + inventoryScreen.setSelected(newSelection); + }); + + actionButtons[0] = equip1Button; + actionButtons[1] = equip2Button; + actionButtons[2] = dropButton; } @Override @@ -117,7 +114,56 @@ public float getPriceMul() { public String getHeader() { return "Items:"; } - + + @Override + public UIButton[] getActionButtons() { + return actionButtons; + } + + public UIWarnButton getEq1Control() { + return (UIWarnButton) actionButtons[0]; + } + + public UIWarnButton getDropControl() { + return (UIWarnButton) actionButtons[2]; + } + + @Override + public void update(SolApplication solApplication, InventoryScreen inventoryScreen) { + SolGame game = solApplication.getGame(); + SolItem selItem = inventoryScreen.getSelectedItem(); + + UIButton equip1Button = actionButtons[0]; + UIButton equip2Button = actionButtons[1]; + UIButton dropButton = actionButtons[2]; + + equip1Button.setText("---"); + equip1Button.setEnabled(false); + equip2Button.setText("---"); + equip2Button.setEnabled(false); + dropButton.setEnabled(false); + + if (selItem == null || target == null) { + return; + } + + dropButton.setEnabled(true); + + boolean equipped1 = target.maybeUnequip(game, selItem, false, false); + boolean canEquip1 = target.maybeEquip(game, selItem, false, false); + boolean equipped2 = target.maybeUnequip(game, selItem, true, false); + boolean canEquip2 = target.maybeEquip(game, selItem, true, false); + + if (equipped1 || canEquip1) { + equip1Button.setText(equipped1 ? "Unequip" : "Equip"); + equip1Button.setEnabled(true); + } + if (equipped2 || canEquip2) { + equip2Button.setText(equipped2 ? "Unequip" : "Set Gun 2"); + equip2Button.setEnabled(true); + } + } + /** * Sets the ship whose inventory we're viewing. * @param solship The mercenary being interacted with diff --git a/engine/src/main/java/org/destinationsol/game/screens/TakeItems.java b/engine/src/main/java/org/destinationsol/game/screens/TakeItems.java index 00e32cd6f..639d1df3f 100644 --- a/engine/src/main/java/org/destinationsol/game/screens/TakeItems.java +++ b/engine/src/main/java/org/destinationsol/game/screens/TakeItems.java @@ -16,24 +16,41 @@ package org.destinationsol.game.screens; -import org.destinationsol.GameOptions; import org.destinationsol.SolApplication; import org.destinationsol.game.Hero; import org.destinationsol.game.SolGame; import org.destinationsol.game.item.ItemContainer; import org.destinationsol.game.item.SolItem; import org.destinationsol.game.ship.SolShip; -import org.destinationsol.ui.SolInputManager; -import org.destinationsol.ui.SolUiControl; +import org.destinationsol.ui.nui.screens.InventoryScreen; +import org.destinationsol.ui.nui.widgets.KeyActivatedButton; +import org.terasology.nui.backends.libgdx.GDXInputUtil; +import org.terasology.nui.widgets.UIButton; +/** + * This screen allows the hero to take items acquired by their hired mercenaries. + * The items taken will be transferred directly into the hero's inventory. + */ public class TakeItems extends InventoryOperationsScreen { - public final SolUiControl takeControl; + public final UIButton[] actionButtons = new UIButton[1]; private SolShip target; - TakeItems(InventoryScreen inventoryScreen, GameOptions gameOptions) { - takeControl = new SolUiControl(inventoryScreen.itemCtrl(0), true, gameOptions.getKeyShoot()); - takeControl.setDisplayName("Take"); - controls.add(takeControl); + public TakeItems() { + } + + @Override + public void initialise(SolApplication solApplication, InventoryScreen inventoryScreen) { + KeyActivatedButton takeButton = new KeyActivatedButton("takeButton", "Take"); + takeButton.setKey(GDXInputUtil.GDXToNuiKey(solApplication.getOptions().getKeyShoot())); + takeButton.subscribe(button -> { + SolItem selectedItem = inventoryScreen.getSelectedItem(); + Hero hero = solApplication.getGame().getHero(); + + target.getItemContainer().remove(selectedItem); + hero.getItemContainer().add(selectedItem); + inventoryScreen.updateItemRows(); + }); + actionButtons[0] = takeButton; } @Override @@ -47,24 +64,21 @@ public String getHeader() { } @Override - public void updateCustom(SolApplication solApplication, SolInputManager.InputPointer[] inputPointers, boolean clickedOutside) { + public UIButton[] getActionButtons() { + return actionButtons; + } + + @Override + public void update(SolApplication solApplication, InventoryScreen inventoryScreen) { SolGame game = solApplication.getGame(); - InventoryScreen is = game.getScreens().inventoryScreen; Hero hero = game.getHero(); - - SolItem selItem = is.getSelectedItem(); - boolean enabled = selItem != null && hero.getItemContainer().canAdd(selItem); - takeControl.setDisplayName(enabled ? "Take" : "---"); - takeControl.setEnabled(enabled); - - if (!enabled) { - return; - } - - if (takeControl.isJustOff()) { - target.getItemContainer().remove(selItem); - hero.getItemContainer().add(selItem); - } + + UIButton takeButton = actionButtons[0]; + + SolItem selectedItem = inventoryScreen.getSelectedItem(); + boolean enabled = selectedItem != null && hero.getItemContainer().canAdd(selectedItem); + takeButton.setText(enabled ? "Take" : "---"); + takeButton.setEnabled(enabled); } /** diff --git a/engine/src/main/java/org/destinationsol/game/screens/TalkScreen.java b/engine/src/main/java/org/destinationsol/game/screens/TalkScreen.java index 5aa7e8b9b..f8fb1e29d 100644 --- a/engine/src/main/java/org/destinationsol/game/screens/TalkScreen.java +++ b/engine/src/main/java/org/destinationsol/game/screens/TalkScreen.java @@ -28,6 +28,7 @@ import org.destinationsol.ui.SolUiBaseScreen; import org.destinationsol.ui.SolUiControl; import org.destinationsol.ui.UiDrawer; +import org.destinationsol.ui.nui.screens.InventoryScreen; public class TalkScreen extends SolUiBaseScreen { public static final float MAX_TALK_DIST = 1f; @@ -88,10 +89,21 @@ public void updateCustom(SolApplication solApplication, SolInputManager.InputPoi boolean buy = buyControl.isJustOff(); boolean sellShips = shipsControl.isJustOff(); boolean hire = hireControl.isJustOff(); - if (sell || buy || sellShips || hire) { - inventoryScreen.setOperations(sell ? inventoryScreen.sellItems : buy ? inventoryScreen.buyItemsScreen : sellShips ? inventoryScreen.changeShipScreen : inventoryScreen.hireShipsScreen); + InventoryOperationsScreen inventoryOperations = null; + if (buy) { + inventoryOperations = inventoryScreen.getBuyItemsScreen(); + } else if (sell) { + inventoryOperations = inventoryScreen.getSellItems(); + } else if (sellShips) { + inventoryOperations = inventoryScreen.getChangeShipScreen(); + } else if (hire) { + inventoryOperations = inventoryScreen.getHireShipsScreen(); + } + + if (inventoryOperations != null) { + inventoryScreen.setOperations(inventoryOperations); inputManager.setScreen(solApplication, game.getScreens().mainGameScreen); - inputManager.addScreen(solApplication, inventoryScreen); + solApplication.getNuiManager().pushScreen(inventoryScreen); } } diff --git a/engine/src/main/java/org/destinationsol/ui/TutorialManager.java b/engine/src/main/java/org/destinationsol/ui/TutorialManager.java index 49f114ad6..641523228 100644 --- a/engine/src/main/java/org/destinationsol/ui/TutorialManager.java +++ b/engine/src/main/java/org/destinationsol/ui/TutorialManager.java @@ -15,6 +15,8 @@ */ package org.destinationsol.ui; +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.Input; import com.badlogic.gdx.math.Rectangle; import org.destinationsol.GameOptions; import org.destinationsol.SolApplication; @@ -23,12 +25,10 @@ import org.destinationsol.game.UpdateAwareSystem; import org.destinationsol.game.item.SolItem; import org.destinationsol.game.screens.GameScreens; -import org.destinationsol.game.screens.InventoryScreen; import org.destinationsol.game.screens.MainGameScreen; import org.destinationsol.game.screens.ShipMixedControl; import org.destinationsol.ui.nui.screens.UIShipControlsScreen; import org.destinationsol.ui.nui.widgets.UIWarnButton; -import org.terasology.nui.widgets.UIButton; import java.util.ArrayList; import java.util.List; @@ -139,23 +139,22 @@ public void start() { } if (mouseCtrl || mobile) { - addStep("In the inventory,\nselect the second row", screens.inventoryScreen.itemControls[1]); + addStep("In the inventory,\nselect the second row", screens.inventoryScreen.getRowButton(1)); } else { - addStep("In the inventory,\nselect the next item (" + gameOptions.getKeyDownName() + " key)", - screens.inventoryScreen.downControl); + addStep("In the inventory,\nselect the next item (" + gameOptions.getKeyDownName() + " key)", gameOptions.getKeyDown()); } if (mouseCtrl || mobile) { - addStep("Go to the next page", screens.inventoryScreen.nextControl, true); + addStep("Go to the next page", screens.inventoryScreen.getNextButton(), true); } else { - addStep("Go to the next page\n(" + gameOptions.getKeyRightName() + " key)", screens.inventoryScreen.nextControl, true); + addStep("Go to the next page\n(" + gameOptions.getKeyRightName() + " key)", screens.inventoryScreen.getNextButton(), true); } if (mouseCtrl || mobile) { - addStep("Throw away some item\nyou don't use", screens.inventoryScreen.showInventory.dropControl); + addStep("Throw away some item\nyou don't use", screens.inventoryScreen.getShowInventory().getDropControl()); } else { addStep("Throw away some item\nyou don't use (" + gameOptions.getKeyDropName() + " key)", - screens.inventoryScreen.showInventory.dropControl); + screens.inventoryScreen.getShowInventory().getDropControl()); } // Extra step to make sure an equipped item is selected before asking player to unequip @@ -166,22 +165,22 @@ public void start() { } if (mobile) { - addStep("Unequip the item\nthat is used now", screens.inventoryScreen.showInventory.eq1Control); + addStep("Unequip the item\nthat is used now", screens.inventoryScreen.getShowInventory().getEq1Control()); } else { addStep("Unequip the item\nthat is used now (" + gameOptions.getKeyEquipName() + " key)", - screens.inventoryScreen.showInventory.eq1Control); + screens.inventoryScreen.getShowInventory().getEq1Control()); } if (mobile) { - addStep("Now equip it again", screens.inventoryScreen.showInventory.eq1Control); + addStep("Now equip it again", screens.inventoryScreen.getShowInventory().getEq1Control()); } else { - addStep("Now equip it again\n(" + gameOptions.getKeyEquipName() + " key)", screens.inventoryScreen.showInventory.eq1Control); + addStep("Now equip it again\n(" + gameOptions.getKeyEquipName() + " key)", screens.inventoryScreen.getShowInventory().getEq1Control()); } if (mobile) { - addStep("Close the inventory\n(Touch the screen outside inventory)", screens.inventoryScreen.closeControl, true); + addStep("Close the inventory\n(Touch the screen outside inventory)", screens.inventoryScreen.getCloseButton(), true); } else { - addStep("Close the inventory (" + gameOptions.getKeyCloseName() + " key)", screens.inventoryScreen.closeControl, true); + addStep("Close the inventory (" + gameOptions.getKeyCloseName() + " key)", screens.inventoryScreen.getCloseButton(), true); } if (mouseCtrl) { @@ -206,15 +205,15 @@ public void start() { } if (mobile) { - addStep("Buy some item", screens.inventoryScreen.buyItemsScreen.buyControl); + addStep("Buy some item", screens.inventoryScreen.getBuyItemsScreen().getBuyControl()); } else { - addStep("Buy some item\n(" + gameOptions.getKeyBuyItemName() + " key)", screens.inventoryScreen.buyItemsScreen.buyControl); + addStep("Buy some item\n(" + gameOptions.getKeyBuyItemName() + " key)", screens.inventoryScreen.getBuyItemsScreen().getBuyControl()); } if (mobile) { - addStep("Close the Buy screen\n(Touch the screen outside inventory)", screens.inventoryScreen.closeControl, true); + addStep("Close the Buy screen\n(Touch the screen outside inventory)", screens.inventoryScreen.getCloseButton(), true); } else { - addStep("Close the Buy screen\n(" + gameOptions.getKeyCloseName() + " key)", screens.inventoryScreen.closeControl, true); + addStep("Close the Buy screen\n(" + gameOptions.getKeyCloseName() + " key)", screens.inventoryScreen.getCloseButton(), true); } if (mouseCtrl) { @@ -253,6 +252,10 @@ private void addStep(String text, SolUiControl ctrl) { addStep(text, ctrl, false); } + private void addStep(String text, int key) { + steps.add(new KeyPressedStep(text, key)); + } + private void addStep(String text, UIWarnButton ctrl) { addStep(text, ctrl, false); } @@ -367,10 +370,10 @@ public boolean canProgressToNextStep() { } public static class SelectEquippedItemStep extends Step { - InventoryScreen inventoryScreen; + org.destinationsol.ui.nui.screens.InventoryScreen inventoryScreen; SolGame game; - public SelectEquippedItemStep(String text, InventoryScreen inventoryScreen, SolGame game) { + public SelectEquippedItemStep(String text, org.destinationsol.ui.nui.screens.InventoryScreen inventoryScreen, SolGame game) { super(text, null, true); this.inventoryScreen = inventoryScreen; this.game = game; @@ -388,10 +391,24 @@ public boolean canProgressToNextStep() { // Highlight all equipped items on opened inventory page @Override public void highlight() { - List equippedItemControls = inventoryScreen.getEquippedItemUIControlsForTutorial(game); - for (SolUiControl control : equippedItemControls) { + List equippedItemControls = inventoryScreen.getEquippedItemUIControlsForTutorial(); + for (UIWarnButton control : equippedItemControls) { control.enableWarn(); } } } + + public static class KeyPressedStep extends Step { + private final int key; + + public KeyPressedStep(String text, int key) { + super(text, null, false); + this.key = key; + } + + @Override + public boolean canProgressToNextStep() { + return Gdx.input.isKeyJustPressed(key); + } + } } diff --git a/engine/src/main/java/org/destinationsol/ui/nui/NUIManager.java b/engine/src/main/java/org/destinationsol/ui/nui/NUIManager.java index 669c2702d..b9d33d526 100644 --- a/engine/src/main/java/org/destinationsol/ui/nui/NUIManager.java +++ b/engine/src/main/java/org/destinationsol/ui/nui/NUIManager.java @@ -184,6 +184,8 @@ public NUIManager(SolApplication solApplication, Context context, CommonDrawer c * @param solApplication the application to use */ public void update(SolApplication solApplication) { + mouse.update(); + for (int pointer = 0; pointer < mouse.getMaxPointers(); pointer++) { canvas.processMousePosition(mouse.getPosition(pointer), pointer); } @@ -434,7 +436,7 @@ public boolean isMouseOnUi() { // TODO: Find better way of doing this. Vector2i mousePosition = mouse.getPosition(); for (Rectanglei interactionRegion : canvas.getInteractionRegions()) { - if (RectUtility.contains(interactionRegion, mousePosition)) { + if (!interactionRegion.equals(canvas.getRegion()) && interactionRegion.containsPoint(mousePosition)) { return true; } } diff --git a/engine/src/main/java/org/destinationsol/ui/nui/NUIScreenLayer.java b/engine/src/main/java/org/destinationsol/ui/nui/NUIScreenLayer.java index 84223b44e..39f32e4a0 100644 --- a/engine/src/main/java/org/destinationsol/ui/nui/NUIScreenLayer.java +++ b/engine/src/main/java/org/destinationsol/ui/nui/NUIScreenLayer.java @@ -122,15 +122,19 @@ public Iterator iterator() { */ @Override public boolean onKeyEvent(NUIKeyEvent event) { - if (escapeCloses() && event.getState() == ButtonState.UP && event.getKey() == Keyboard.Key.ESCAPE) { - nuiManager.removeScreen(this); - return true; - } - // Send key events to all KeyActivatedButton sub-widgets. These buttons are supposed to react to key events // even when they are not in-focus. for (UIWidget widget : contents.findAll(KeyActivatedButton.class)) { - widget.onKeyEvent(event); + if (widget.onKeyEvent(event)) { + return true; + } + } + + // Process escape key handling after KeyActivatedButton key events, since some screens might implement + // a close button bound to the escape key. + if (escapeCloses() && event.getState() == ButtonState.UP && event.getKey() == Keyboard.Key.ESCAPE) { + nuiManager.removeScreen(this); + return true; } return super.onKeyEvent(event); diff --git a/engine/src/main/java/org/destinationsol/ui/nui/screens/InventoryScreen.java b/engine/src/main/java/org/destinationsol/ui/nui/screens/InventoryScreen.java new file mode 100644 index 000000000..219aca8be --- /dev/null +++ b/engine/src/main/java/org/destinationsol/ui/nui/screens/InventoryScreen.java @@ -0,0 +1,578 @@ +/* + * Copyright 2021 The Terasology Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.destinationsol.ui.nui.screens; + +import com.badlogic.gdx.graphics.g2d.TextureAtlas; +import org.destinationsol.Const; +import org.destinationsol.SolApplication; +import org.destinationsol.assets.Assets; +import org.destinationsol.common.In; +import org.destinationsol.game.item.ItemContainer; +import org.destinationsol.game.item.SolItem; +import org.destinationsol.game.screens.BuyItemsScreen; +import org.destinationsol.game.screens.ChangeShipScreen; +import org.destinationsol.game.screens.ChooseMercenaryScreen; +import org.destinationsol.game.screens.GameScreens; +import org.destinationsol.game.screens.GiveItemsScreen; +import org.destinationsol.game.screens.HireShipsScreen; +import org.destinationsol.game.screens.InventoryOperationsScreen; +import org.destinationsol.game.screens.SellItems; +import org.destinationsol.game.screens.ShowInventory; +import org.destinationsol.game.screens.TakeItems; +import org.destinationsol.ui.SolInputManager; +import org.destinationsol.ui.nui.NUIScreenLayer; +import org.destinationsol.ui.nui.widgets.UIWarnButton; +import org.terasology.nui.Color; +import org.terasology.nui.HorizontalAlign; +import org.terasology.nui.UIWidget; +import org.terasology.nui.backends.libgdx.GDXInputUtil; +import org.terasology.nui.backends.libgdx.GdxColorUtil; +import org.terasology.nui.backends.libgdx.LibGDXTexture; +import org.terasology.nui.events.NUIKeyEvent; +import org.terasology.nui.layouts.ColumnLayout; +import org.terasology.nui.layouts.ScrollableArea; +import org.terasology.nui.layouts.relative.HorizontalHint; +import org.terasology.nui.layouts.relative.RelativeLayout; +import org.terasology.nui.layouts.relative.RelativeLayoutHint; +import org.terasology.nui.layouts.relative.VerticalHint; +import org.terasology.nui.widgets.UIButton; +import org.terasology.nui.widgets.UIImage; +import org.terasology.nui.widgets.UILabel; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * The Inventory screen displays a paginate-able list of {@link SolItem} that you can select and view information on. + * Specialised functionality and logic for the screen is implemented via an assigned {@link InventoryOperationsScreen}, + * which can provide up to 3 additional "action buttons" placed in the bottom-right corner of the screen. + */ +public class InventoryScreen extends NUIScreenLayer { + @In + private SolApplication solApplication; + private UILabel titleLabel; + private ColumnLayout inventoryRows; + private UIWarnButton nextButton; + private UIWarnButton previousButton; + private ScrollableArea descriptionScrollArea; + private UILabel descriptionBox; + private ColumnLayout inventoryActionButtons; + private UIWarnButton closeButton; + private InventoryOperationsScreen inventoryOperations; + private int selectedIndex; + private int page; + + private ShowInventory showInventory; + private BuyItemsScreen buyItemsScreen; + private SellItems sellItems; + private ChangeShipScreen changeShipScreen; + private HireShipsScreen hireShipsScreen; + // The below screens deal with mercenaries + private ChooseMercenaryScreen chooseMercenaryScreen; + private GiveItemsScreen giveItemsScreen; + private TakeItems takeItems; + + @Override + public void initialise() { + titleLabel = find("title", UILabel.class); + + inventoryRows = find("inventoryRows", ColumnLayout.class); + + nextButton = find("nextButton", UIWarnButton.class); + nextButton.setKey(GDXInputUtil.GDXToNuiKey(solApplication.getOptions().getKeyRight())); + nextButton.subscribe(button -> { + nextPage(button); + selectedIndex = 0; + updateItemRows(); + }); + + previousButton = find("previousButton", UIWarnButton.class); + previousButton.setKey(GDXInputUtil.GDXToNuiKey(solApplication.getOptions().getKeyLeft())); + previousButton.subscribe(button -> { + previousPage(button); + selectedIndex = 0; + updateItemRows(); + }); + + for (int rowNo = 0; rowNo < Const.ITEM_GROUPS_PER_PAGE; rowNo++) { + inventoryRows.addWidget(createItemRow(rowNo)); + } + + descriptionScrollArea = find("itemDescriptionScrollArea", ScrollableArea.class); + descriptionBox = find("itemDescription", UILabel.class); + + inventoryActionButtons = find("inventoryActionButtons", ColumnLayout.class); + + closeButton = new UIWarnButton("cancelButton", "Cancel"); + closeButton.setKey(GDXInputUtil.GDXToNuiKey(solApplication.getOptions().getKeyEscape())); + closeButton.subscribe(button -> { + // Go back to the "Choose Mercenaries" screen if it was probably the last one opened. + if (inventoryOperations == giveItemsScreen || inventoryOperations == takeItems || + (inventoryOperations == showInventory && showInventory.getTarget() != solApplication.getGame().getHero().getShip())) { + SolInputManager inputMan = solApplication.getInputManager(); + GameScreens screens = solApplication.getGame().getScreens(); + + inputMan.setScreen(solApplication, screens.mainGameScreen); + onRemoved(); + setOperations(chooseMercenaryScreen); + onAdded(); + } else { + nuiManager.removeScreen(this); + } + }); + + showInventory = new ShowInventory(); + showInventory.initialise(solApplication, this); + buyItemsScreen = new BuyItemsScreen(); + buyItemsScreen.initialise(solApplication, this); + sellItems = new SellItems(); + sellItems.initialise(solApplication, this); + changeShipScreen = new ChangeShipScreen(); + changeShipScreen.initialise(solApplication, this); + hireShipsScreen = new HireShipsScreen(); + hireShipsScreen.initialise(solApplication, this); + chooseMercenaryScreen = new ChooseMercenaryScreen(); + chooseMercenaryScreen.initialise(solApplication, this); + giveItemsScreen = new GiveItemsScreen(); + giveItemsScreen.initialise(solApplication, this); + takeItems = new TakeItems(); + takeItems.initialise(solApplication, this); + } + + @Override + public void onAdded() { + titleLabel.setText(inventoryOperations.getHeader()); + descriptionBox.setText(""); + + selectedIndex = 0; + page = 0; + inventoryOperations.onAdd(solApplication); + + ItemContainer items = inventoryOperations.getItems(solApplication.getGame()); + nextButton.setEnabled(Const.ITEM_GROUPS_PER_PAGE < items.groupCount()); + previousButton.setEnabled(false); + + for (UIButton actionButton : inventoryOperations.getActionButtons()) { + inventoryActionButtons.addWidget(actionButton); + } + + inventoryActionButtons.addWidget(closeButton); + + updateItemRows(); + } + + /** + * Assigns the specified {@link InventoryOperationsScreen operations screen} to this screen. + * @param operations the operations that can be performed + */ + public void setOperations(InventoryOperationsScreen operations) { + this.inventoryOperations = operations; + } + + @Override + public void update(float delta) { + super.update(delta); + + if (solApplication.getGame().getHero().getShip() == showInventory.getTarget() || inventoryOperations == sellItems) { + int itemNo = page * Const.ITEM_GROUPS_PER_PAGE; + ItemContainer items = inventoryOperations.getItems(solApplication.getGame()); + Iterator rowIterator = inventoryRows.iterator(); + rowIterator.next(); // Skip header + while (rowIterator.hasNext()) { + UIWidget row = rowIterator.next(); + if (itemNo >= items.groupCount()) { + break; + } + + UIWarnButton itemButton = row.find("itemButton", UIWarnButton.class); + if (itemButton != null && !itemButton.isWarning() && items.isNew(items.getGroup(itemNo))) { + itemButton.enableWarn(); + } + itemNo++; + } + } + + inventoryOperations.update(solApplication, this); + } + + @Override + public void onRemoved() { + super.onRemoved(); + + if (inventoryOperations != null) { + inventoryOperations.getItems(solApplication.getGame()).markAllAsSeen(); + inventoryActionButtons.removeAllWidgets(); + } + } + + @Override + public boolean onKeyEvent(NUIKeyEvent event) { + if (super.onKeyEvent(event)) { + return true; + } + + if (event.isDown()) { + ItemContainer items = inventoryOperations.getItems(solApplication.getGame()); + if (event.getKey() == GDXInputUtil.GDXToNuiKey(solApplication.getOptions().getKeyUp())) { + if (selectedIndex < 1 && previousButton.isEnabled()) { + selectedIndex = Const.ITEM_GROUPS_PER_PAGE - 1; + previousPage(previousButton); + previousButton.getClickSound().play(previousButton.getClickVolume()); + } else if (selectedIndex > 0) { + selectedIndex--; + previousButton.getClickSound().play(previousButton.getClickVolume()); + } + + items.seen(items.getGroup(selectedIndex + page * Const.ITEM_GROUPS_PER_PAGE)); + + updateItemRows(); + return true; + } + + if (event.getKey() == GDXInputUtil.GDXToNuiKey(solApplication.getOptions().getKeyDown())) { + int itemsMaxIndex = items.groupCount() - 1; + int maxIndex = Math.min(Const.ITEM_GROUPS_PER_PAGE - 1, itemsMaxIndex - (page * Const.ITEM_GROUPS_PER_PAGE)); + if (selectedIndex >= maxIndex && nextButton.isEnabled()) { + selectedIndex = 0; + nextPage(nextButton); + nextButton.getClickSound().play(nextButton.getClickVolume()); + } else if (selectedIndex < maxIndex) { + selectedIndex++; + nextButton.getClickSound().play(nextButton.getClickVolume()); + } + + items.seen(items.getGroup(selectedIndex + page * Const.ITEM_GROUPS_PER_PAGE)); + + updateItemRows(); + return true; + } + } + + return false; + } + + /** + * Returns the currently selected item group. + * @return the selected item group + */ + public List getSelected() { + if (inventoryOperations == null || selectedIndex < 0 || selectedIndex >= Const.ITEM_GROUPS_PER_PAGE) { + return null; + } + + int itemGroupIndex = selectedIndex + page * Const.ITEM_GROUPS_PER_PAGE; + ItemContainer items = inventoryOperations.getItems(solApplication.getGame()); + if (itemGroupIndex >= items.groupCount()) { + return null; + } + + return items.getGroup(itemGroupIndex); + } + + /** + * Retrieves the currently selected item. + * @return the current selected item + */ + public SolItem getSelectedItem() { + List itemGroup = getSelected(); + if (itemGroup == null) { + return null; + } + return itemGroup.isEmpty() ? null : itemGroup.get(0); + } + + /** + * Sets the selected item group. + * @param itemGroup the item group to select + */ + public void setSelected(List itemGroup) { + ItemContainer items = inventoryOperations.getItems(solApplication.getGame()); + if (!items.containsGroup(itemGroup)) { + selectedIndex = 0; + } else { + for (int groupNo = 0; groupNo < items.groupCount(); groupNo++) { + if (items.getGroup(groupNo) == itemGroup) { + page = groupNo / Const.ITEM_GROUPS_PER_PAGE; + selectedIndex = groupNo % Const.ITEM_GROUPS_PER_PAGE; + } + } + } + + updateItemRows(); + } + + /** + * Returns the button representing the specified row. + * @param index the row to retrieve + * @return the row's item button + */ + public UIWarnButton getRowButton(int index) { + Iterator rowIterator = inventoryRows.iterator(); + rowIterator.next(); // Skip header + for (int rowNo = 0; rowNo < index; rowNo++) { + rowIterator.next(); + } + return rowIterator.next().find("itemButton", UIWarnButton.class); + } + + /** + * This is an internal API used by the tutorial. It just returns the buttons representing equipped items. + * @return The buttons representing currently equipped items. + */ + public List getEquippedItemUIControlsForTutorial() { + List controls = new ArrayList<>(); + + Iterator rowsIterator = inventoryRows.iterator(); + rowsIterator.next(); // Skip header + UIWidget row = rowsIterator.next(); + int startIndex = page * Const.ITEM_GROUPS_PER_PAGE; + ItemContainer items = inventoryOperations.getItems(solApplication.getGame()); + for (int rowNo = 0; rowNo < Const.ITEM_GROUPS_PER_PAGE; rowNo++) { + int groupNo = startIndex + rowNo; + boolean emptyRow = groupNo >= items.groupCount(); + + UIWarnButton itemButton = row.find("itemButton", UIWarnButton.class); + if (emptyRow) { + break; + } else { + List itemGroup = items.getGroup(groupNo); + SolItem sample = itemGroup.get(0); + + if (inventoryOperations.isUsing(solApplication.getGame(), sample)) { + controls.add(itemButton); + } + } + + if (rowsIterator.hasNext()) { + row = rowsIterator.next(); + } + } + + return controls; + } + + /** + * @return the next button - used in the tutorial + */ + public UIWarnButton getNextButton() { + return nextButton; + } + + /** + * @return the previous button + */ + public UIWarnButton getPreviousButton() { + return previousButton; + } + + /** + * @return the close button - used in the tutorial + */ + public UIWarnButton getCloseButton() { + return closeButton; + } + + /** + * @return the {@link ShowInventory} inventory operations + */ + public ShowInventory getShowInventory() { + return showInventory; + } + + /** + * @return the {@link BuyItemsScreen} inventory operations + */ + public BuyItemsScreen getBuyItemsScreen() { + return buyItemsScreen; + } + + /** + * @return the {@link SellItems} inventory operations + */ + public SellItems getSellItems() { + return sellItems; + } + + /** + * @return the {@link ChangeShipScreen} inventory operations + */ + public ChangeShipScreen getChangeShipScreen() { + return changeShipScreen; + } + + /** + * @return the {@link HireShipsScreen} inventory operations + */ + public HireShipsScreen getHireShipsScreen() { + return hireShipsScreen; + } + + /** + * @return the {@link ChooseMercenaryScreen} inventory operations + */ + public ChooseMercenaryScreen getChooseMercenaryScreen() { + return chooseMercenaryScreen; + } + + /** + * @return the {@link GiveItemsScreen} inventory operations + */ + public GiveItemsScreen getGiveItems() { + return giveItemsScreen; + } + + /** + * @return the {@link TakeItems} inventory operations + */ + public TakeItems getTakeItems() { + return takeItems; + } + + private UIWidget createItemRow(int index) { + RelativeLayout itemRowLayout = new RelativeLayout(); + itemRowLayout.setFamily("inventoryRow"); + + UIWarnButton itemButton = new UIWarnButton("itemButton", ""); + itemButton.subscribe(button -> { + selectedIndex = index; + updateItemRows(); + }); + itemRowLayout.addWidget(itemButton, new RelativeLayoutHint()); + + UIImage itemIconBackground = new UIImage("itemIconBackground", Assets.getDSTexture("engine:whiteTex").getUiTexture()); + itemRowLayout.addWidget(itemIconBackground, new RelativeLayoutHint( + new HorizontalHint() + .alignLeftRelativeTo("itemIcon", HorizontalAlign.LEFT) + .alignRightRelativeTo("itemIcon", HorizontalAlign.RIGHT), + new VerticalHint() + )); + + UIImage itemIcon = new UIImage("itemIcon"); + itemRowLayout.addWidget(itemIcon, new RelativeLayoutHint( + new HorizontalHint().alignLeft(8), + new VerticalHint() + ).setUsingContentWidth(true)); + + itemRowLayout.addWidget(new UILabel("itemEquippedLabel", ""), new RelativeLayoutHint( + new HorizontalHint().alignLeftRelativeTo("itemIcon", HorizontalAlign.RIGHT, 8), + new VerticalHint() + ).setUsingContentWidth(true)); + + itemRowLayout.addWidget(new UILabel("itemQuantityLabel", ""), new RelativeLayoutHint( + new HorizontalHint().alignRight(8), + new VerticalHint() + ).setUsingContentWidth(true)); + + itemRowLayout.addWidget(new UILabel("itemPriceLabel", ""), new RelativeLayoutHint( + new HorizontalHint().alignRight(64), + new VerticalHint() + ).setUsingContentWidth(true)); + + return itemRowLayout; + } + + public void updateItemRows() { + ItemContainer items = inventoryOperations.getItems(solApplication.getGame()); + Iterator rowsIterator = inventoryRows.iterator(); + rowsIterator.next(); // Ignore the first row, since it's the header. + UIWidget row = rowsIterator.next(); + + int startIndex = page * Const.ITEM_GROUPS_PER_PAGE; + if (startIndex >= items.groupCount() && page > 0) { + // Empty page. This may have happened if the last item on a page was dropped from the inventory. + page = (items.groupCount() - 1) / Const.ITEM_GROUPS_PER_PAGE; + startIndex = page * Const.ITEM_GROUPS_PER_PAGE; + selectedIndex = 0; + } + + previousButton.setEnabled(page > 0); + nextButton.setEnabled(((page + 1) * Const.ITEM_GROUPS_PER_PAGE) < items.groupCount()); + + for (int rowNo = 0; rowNo < Const.ITEM_GROUPS_PER_PAGE; rowNo++) { + int groupNo = startIndex + rowNo; + boolean emptyRow = groupNo >= items.groupCount(); + + UIWarnButton itemButton = row.find("itemButton", UIWarnButton.class); + UIImage itemIconBackground = row.find("itemIconBackground", UIImage.class); + UIImage itemIcon = row.find("itemIcon", UIImage.class); + UILabel itemEquippedLabel = row.find("itemEquippedLabel", UILabel.class); + UILabel itemQuantityLabel = row.find("itemQuantityLabel", UILabel.class); + UILabel itemPriceLabel = row.find("itemPriceLabel", UILabel.class); + if (emptyRow) { + itemButton.setText(""); + itemIconBackground.setTint(new Color(Color.transparent)); + itemIcon.setImage(null); + itemEquippedLabel.setText(""); + itemQuantityLabel.setText(""); + itemPriceLabel.setText(""); + + itemButton.setEnabled(false); + } else { + List itemGroup = items.getGroup(groupNo); + SolItem sample = itemGroup.get(0); + + itemButton.setText(sample.getDisplayName()); + itemButton.setActive(selectedIndex == rowNo); + if (items.isNew(itemGroup)) { + itemButton.enableWarn(); + } + + itemIconBackground.setTint(GdxColorUtil.gdxToTerasologyColor(sample.getItemType().uiColor)); + + TextureAtlas.AtlasRegion iconTexture = sample.getIcon(solApplication.getGame()); + itemIcon.setImage(new LibGDXTexture(iconTexture)); + + itemEquippedLabel.setText(inventoryOperations.isUsing(solApplication.getGame(), sample) ? "using" : ""); + + itemQuantityLabel.setText(itemGroup.size() > 1 ? "x" + itemGroup.size() : ""); + + itemPriceLabel.setText(inventoryOperations.getPriceMul() > 0 ? "$" + sample.getPrice() * inventoryOperations.getPriceMul() : ""); + + itemButton.setEnabled(true); + } + + if (rowsIterator.hasNext()) { + row = rowsIterator.next(); + } + } + + int selectedGroup = (selectedIndex + page * Const.ITEM_GROUPS_PER_PAGE); + if (items.groupCount() > 0 && items.groupCount() > selectedGroup) { + List itemGroup = items.getGroup(selectedGroup); + items.seen(itemGroup); + SolItem sample = itemGroup.get(0); + // Add an extra newline to the end to ensure that the entire area is scrollable. + descriptionBox.setText(sample.getDisplayName() + "\n" + sample.getDescription() + "\n"); + // Scroll to top + descriptionScrollArea.setPosition(0); + } + } + + private void nextPage(UIWidget nextButton) { + int inputCount = inventoryOperations.getItems(solApplication.getGame()).groupCount(); + page++; + nextButton.setEnabled(((page + 1) * Const.ITEM_GROUPS_PER_PAGE) < inputCount); + previousButton.setEnabled(true); + } + + private void previousPage(UIWidget previousButton) { + page--; + previousButton.setEnabled(page > 0); + nextButton.setEnabled(true); + } +} diff --git a/engine/src/main/java/org/destinationsol/ui/nui/screens/MainGameScreen.java b/engine/src/main/java/org/destinationsol/ui/nui/screens/MainGameScreen.java index b72049d1d..a8b31260c 100644 --- a/engine/src/main/java/org/destinationsol/ui/nui/screens/MainGameScreen.java +++ b/engine/src/main/java/org/destinationsol/ui/nui/screens/MainGameScreen.java @@ -34,10 +34,14 @@ import org.terasology.input.ButtonState; import org.terasology.input.Keyboard; import org.terasology.nui.AbstractWidget; +import org.terasology.nui.BaseInteractionListener; +import org.terasology.nui.Canvas; +import org.terasology.nui.InteractionListener; import org.terasology.nui.UIWidget; import org.terasology.nui.asset.UIElement; import org.terasology.nui.backends.libgdx.GDXInputUtil; import org.terasology.nui.events.NUIKeyEvent; +import org.terasology.nui.events.NUIMouseClickEvent; import java.util.List; @@ -58,6 +62,18 @@ public class MainGameScreen extends NUIScreenLayer { @In private SolApplication solApplication; + private final InteractionListener interactionListener = new BaseInteractionListener() { + @Override + public boolean onMouseClick(NUIMouseClickEvent event) { + NUIScreenLayer topScreen = nuiManager.getTopScreen(); + if (topScreen != MainGameScreen.this && !(topScreen instanceof UIShipControlsScreen)) { + nuiManager.popScreen(); + return true; + } + return false; + } + }; + @Override public void initialise() { consoleScreen = (ConsoleScreen) nuiManager.createScreen("engine:console"); @@ -109,7 +125,7 @@ public void update(float delta) { SolGame game = solApplication.getGame(); Hero hero = game.getHero(); - if (hero.isNonTranscendent() && !solInputManager.isScreenOn(gameScreens.inventoryScreen)) { + if (hero.isNonTranscendent() && !nuiManager.hasScreen(gameScreens.inventoryScreen)) { if (hero.getItemContainer().hasNew()) { inventoryButton.enableWarn(); } @@ -158,6 +174,12 @@ public void update(float delta) { } } + @Override + public void onDraw(Canvas canvas) { + canvas.addInteractionRegion(interactionListener); + super.onDraw(canvas); + } + @Override protected boolean escapeCloses() { return false; @@ -256,10 +278,12 @@ private void onItemsButtonClicked(UIWidget widget) { GameScreens gameScreens = solApplication.getGame().getScreens(); solInputManager.setScreen(solApplication, gameScreens.mainGameScreen); - if (!solInputManager.isScreenOn(gameScreens.inventoryScreen)) { - gameScreens.inventoryScreen.showInventory.setTarget(solApplication.getGame().getHero().getShip()); - gameScreens.inventoryScreen.setOperations(gameScreens.inventoryScreen.showInventory); - solInputManager.addScreen(solApplication, gameScreens.inventoryScreen); + if (!nuiManager.hasScreen(gameScreens.inventoryScreen)) { + gameScreens.inventoryScreen.getShowInventory().setTarget(solApplication.getGame().getHero().getShip()); + gameScreens.inventoryScreen.setOperations(gameScreens.inventoryScreen.getShowInventory()); + nuiManager.pushScreen(gameScreens.inventoryScreen); + } else { + nuiManager.removeScreen(gameScreens.inventoryScreen); } } @@ -279,9 +303,9 @@ private void onMercsButtonClicked(UIWidget widget) { GameScreens gameScreens = solApplication.getGame().getScreens(); solInputManager.setScreen(solApplication, gameScreens.mainGameScreen); - if (!solInputManager.isScreenOn(gameScreens.inventoryScreen)) { - gameScreens.inventoryScreen.setOperations(gameScreens.inventoryScreen.chooseMercenaryScreen); - solInputManager.addScreen(solApplication, gameScreens.inventoryScreen); + if (!nuiManager.hasScreen(gameScreens.inventoryScreen)) { + gameScreens.inventoryScreen.setOperations(gameScreens.inventoryScreen.getChooseMercenaryScreen()); + nuiManager.pushScreen(gameScreens.inventoryScreen); solApplication.getGame().getHero().getMercs().markAllAsSeen(); } } diff --git a/engine/src/main/java/org/destinationsol/ui/nui/widgets/KeyActivatedButton.java b/engine/src/main/java/org/destinationsol/ui/nui/widgets/KeyActivatedButton.java index 539956cea..5b32e58a2 100644 --- a/engine/src/main/java/org/destinationsol/ui/nui/widgets/KeyActivatedButton.java +++ b/engine/src/main/java/org/destinationsol/ui/nui/widgets/KeyActivatedButton.java @@ -42,6 +42,17 @@ public class KeyActivatedButton extends UIButton { @LayoutConfig private Binding activateWhenInvisible = new DefaultBinding<>(false); + public KeyActivatedButton(){ + } + + public KeyActivatedButton(String id) { + super(id); + } + + public KeyActivatedButton(String id, String text) { + super(id, text); + } + /** * Binds the key used to activate this {@code KeyActivatedButton}. * @@ -104,6 +115,11 @@ public boolean onKeyEvent(NUIKeyEvent event) { return true; } + // WidgetWithOrder contains some logic that consumed all UP key and DOWN key events, even when it does nothing + // with them. This might be worthwhile for scrolling lists but shouldn't do anything otherwise. + if (parent == null) { + return false; + } return super.onKeyEvent(event); } } diff --git a/engine/src/main/java/org/destinationsol/ui/nui/widgets/UIBackingBox.java b/engine/src/main/java/org/destinationsol/ui/nui/widgets/UIBackingBox.java new file mode 100644 index 000000000..66efd1291 --- /dev/null +++ b/engine/src/main/java/org/destinationsol/ui/nui/widgets/UIBackingBox.java @@ -0,0 +1,48 @@ +/* + * Copyright 2021 The Terasology Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.destinationsol.ui.nui.widgets; + +import org.terasology.nui.BaseInteractionListener; +import org.terasology.nui.Canvas; +import org.terasology.nui.InteractionListener; +import org.terasology.nui.events.NUIMouseClickEvent; +import org.terasology.nui.events.NUIMouseDoubleClickEvent; +import org.terasology.nui.widgets.UIBox; + +/** + * A {@link UIBox} that is designed to back an existing group of widgets, acting effectively as the background + * but absorbing all click and double-click events to prevent event propagation to the screens behind it. + */ +public class UIBackingBox extends UIBox { + private static final InteractionListener BLOCKING_INTERACTION_LISTENER = new BaseInteractionListener() { + @Override + public boolean onMouseClick(NUIMouseClickEvent event) { + return true; + } + + @Override + public boolean onMouseDoubleClick(NUIMouseDoubleClickEvent event) { + return true; + } + }; + + @Override + public void onDraw(Canvas canvas) { + canvas.addInteractionRegion(BLOCKING_INTERACTION_LISTENER); + super.onDraw(canvas); + } +} diff --git a/engine/src/main/java/org/destinationsol/ui/nui/widgets/UIWarnButton.java b/engine/src/main/java/org/destinationsol/ui/nui/widgets/UIWarnButton.java index 24b4c900c..5d9cf2af5 100644 --- a/engine/src/main/java/org/destinationsol/ui/nui/widgets/UIWarnButton.java +++ b/engine/src/main/java/org/destinationsol/ui/nui/widgets/UIWarnButton.java @@ -38,6 +38,17 @@ public class UIWarnButton extends KeyActivatedButton { private boolean warnPercGrows; private float warnAlpha = 1f; + public UIWarnButton() { + } + + public UIWarnButton(String id) { + super(id); + } + + public UIWarnButton(String id, String text) { + super(id, text); + } + @Override public void onDraw(Canvas canvas) { if (warnCounter > 0) { @@ -80,6 +91,14 @@ public void enableWarn() { warnCounter = WARN_COUNTER_MAX; } + /** + * Returns true if the button is currently in a "warn" phase. + * @return true, if the button is currently in a "warn" phase, otherwise false. + */ + public boolean isWarning() { + return warnCounter > 0; + } + @Override public boolean isSkinAppliedByCanvas() { return false; diff --git a/engine/src/main/resources/org/destinationsol/assets/skins/inventoryScreen.skin b/engine/src/main/resources/org/destinationsol/assets/skins/inventoryScreen.skin new file mode 100644 index 000000000..aed32aa82 --- /dev/null +++ b/engine/src/main/resources/org/destinationsol/assets/skins/inventoryScreen.skin @@ -0,0 +1,24 @@ +{ + "inherit": "engine:mainGameScreen", + "families": { + "inventoryHeader": { + "text-align-vertical": "middle", + "text-align-horizontal": "left", + "min-height": 16 + }, + "inventoryRow": { + "font": "engine:main#0.675", + "text-align-vertical": "middle", + "text-align-horizontal": "center", + "min-height": 32, + "max-height": 64 + }, + "inventoryActionButtons": { + "font": "engine:main#0.4" + }, + "selectedItemLabel": { + "text-align-vertical": "middle", + "text-align-horizontal": "left" + } + } +} \ No newline at end of file diff --git a/engine/src/main/resources/org/destinationsol/assets/skins/mainGameScreen.skin b/engine/src/main/resources/org/destinationsol/assets/skins/mainGameScreen.skin index b3b4d1619..1cbc58ccd 100644 --- a/engine/src/main/resources/org/destinationsol/assets/skins/mainGameScreen.skin +++ b/engine/src/main/resources/org/destinationsol/assets/skins/mainGameScreen.skin @@ -12,6 +12,22 @@ }, "controlsUIButton": { "font": "engine:main#0.95" + }, + "menuBox": { + "max-width": 800, + "max-height": 600, + "elements": { + "UIBox": { + "background": "engine:background" + } + } + }, + "uiBoxDefault": { + "elements": { + "UIBox": { + "background": "engine:area" + } + } } } } diff --git a/engine/src/main/resources/org/destinationsol/assets/textures/ui/nui/background.png b/engine/src/main/resources/org/destinationsol/assets/textures/ui/nui/background.png new file mode 100644 index 000000000..5e7f2df69 Binary files /dev/null and b/engine/src/main/resources/org/destinationsol/assets/textures/ui/nui/background.png differ diff --git a/engine/src/main/resources/org/destinationsol/assets/ui/inventoryScreen.ui b/engine/src/main/resources/org/destinationsol/assets/ui/inventoryScreen.ui new file mode 100644 index 000000000..2be50a95b --- /dev/null +++ b/engine/src/main/resources/org/destinationsol/assets/ui/inventoryScreen.ui @@ -0,0 +1,150 @@ +{ + "type": "InventoryScreen", + "skin": "engine:inventoryScreen", + "contents": { + "type": "RelativeLayout", + "contents": [ + { + "type": "UIBackingBox", + "family": "menuBox", + "content": { + "type": "RelativeLayout", + "contents": [ + { + "type": "ColumnLayout", + "id": "inventoryRows", + "verticalSpacing": 8, + "contents": [ + { + "type": "RowLayout", + "id": "header", + "family": "inventoryHeader", + "horizontalSpacing": 8, + "contents": [ + { + "type": "UILabel", + "id": "title", + "text": "Inventory Screen", + "layoutInfo": { + "relativeWidth": 0.6 + } + }, + { + "type": "UIWarnButton", + "id": "previousButton", + "text": "<" + }, + { + "type": "UIWarnButton", + "id": "nextButton", + "text": ">" + } + ] + } + ], + "layoutInfo": { + "position-horizontal-center": {}, + "position-top": { + "offset": 8 + }, + "position-bottom": { + "widget": "selectedItemLabel", + "target": "TOP", + "offset": 8 + }, + "position-left": { + "offset": 8 + }, + "position-right": { + "offset": 8 + } + } + }, + { + "type": "UILabel", + "id": "selectedItemLabel", + "text": "Selected Item:", + "layoutInfo": { + "position-top": { + "target": "MIDDLE", + "offset": 64 + }, + "position-left": { + "offset": 8 + }, + "position-right": { + "offset": 8 + }, + "use-content-height": true + } + }, + { + "type": "RowLayout", + "id": "inventoryItemInfo", + "horizontalSpacing": 16, + "contents": [ + { + "type": "UIBox", + "id": "itemDescriptionBox", + "family": "uiBoxDefault", + "content": { + "type": "ScrollableArea", + "id": "itemDescriptionScrollArea", + "content": { + "type": "UILabel", + "id": "itemDescription", + "text": "This is a really long description. Longer than that. No, even longer!" + } + }, + "layoutInfo": { + "relativeWidth": 0.6 + } + }, + { + "type": "ColumnLayout", + "id": "inventoryActionButtons", + "family": "inputMapOptions", + "verticalSpacing": 8, + "contents": [ + ] + } + ], + "layoutInfo": { + "position-top": { + "widget": "selectedItemLabel", + "target": "BOTTOM", + "offset": 8 + }, + "position-bottom": { + "offset": 8 + }, + "position-left": { + "offset": 8 + }, + "position-right": { + "offset": 8 + } + } + } + ] + }, + "layoutInfo": { + "position-horizontal-center": {}, + "position-vertical-center": {}, + "position-top": { + "offset": 64 + }, + "position-bottom": { + "offset": 64 + }, + "position-left": { + "offset": 64 + }, + "position-right": { + "offset": 64 + } + } + } + ] + } +} \ No newline at end of file