From 0f86267ff0eb993d8f379a0a9415b23c07c5a4a5 Mon Sep 17 00:00:00 2001 From: Benjamin Amos Date: Sun, 18 Sep 2022 15:45:13 +0100 Subject: [PATCH 1/3] feat(nui): convert the remaining visual aspects of MainGameScreen to NUI --- .../org/destinationsol/SolApplication.java | 2 +- .../destinationsol/game/PlayerCreator.java | 2 +- .../java/org/destinationsol/game/SolCam.java | 2 +- .../java/org/destinationsol/game/SolGame.java | 5 +- .../game/screens/BorderDrawer.java | 2 +- .../game/screens/BuyItemsScreen.java | 2 +- .../game/screens/ChangeShipScreen.java | 2 +- .../game/screens/ChooseMercenaryScreen.java | 6 +- .../game/screens/ConsoleScreen.java | 2 +- .../game/screens/GameScreens.java | 17 +- .../game/screens/HireShipsScreen.java | 2 +- .../game/screens/InventoryScreen.java | 4 +- .../game/screens/MainGameScreen.java | 398 ++-------- .../game/screens/MapScreen.java | 4 +- .../game/screens/MenuScreen.java | 4 +- .../game/screens/SellItems.java | 2 +- .../game/screens/TalkScreen.java | 4 +- .../game/screens/ZoneNameAnnouncer.java | 2 +- .../destinationsol/ui/SolInputManager.java | 2 +- .../destinationsol/ui/TutorialManager.java | 2 +- .../ui/nui/screens/MainGameScreen.java | 691 +++++++++++++++++- .../ui/nui/screens/UIShipControlsScreen.java | 2 +- .../ui/nui/widgets/UIWarnDrawer.java | 160 ++++ .../assets/skins/mainGameScreen.skin | 22 + .../assets/ui/mainGameScreen_desktop.ui | 49 +- .../assets/ui/mainGameScreen_mobile.ui | 57 +- 26 files changed, 1054 insertions(+), 393 deletions(-) create mode 100644 engine/src/main/java/org/destinationsol/ui/nui/widgets/UIWarnDrawer.java diff --git a/engine/src/main/java/org/destinationsol/SolApplication.java b/engine/src/main/java/org/destinationsol/SolApplication.java index aef9f9528..ec333f60c 100644 --- a/engine/src/main/java/org/destinationsol/SolApplication.java +++ b/engine/src/main/java/org/destinationsol/SolApplication.java @@ -362,7 +362,7 @@ public void play(boolean tut, String shipName, boolean isNewGame, WorldConfig wo factionDisplay = new FactionDisplay(gameContext.getBean(SolCam.class)); nuiManager.removeScreen(menuScreens.loading); - inputManager.setScreen(this, solGame.getScreens().mainGameScreen); + inputManager.setScreen(this, solGame.getScreens().oldMainGameScreen); } public SolInputManager getInputManager() { diff --git a/engine/src/main/java/org/destinationsol/game/PlayerCreator.java b/engine/src/main/java/org/destinationsol/game/PlayerCreator.java index 7756b48a2..0203ed8b8 100644 --- a/engine/src/main/java/org/destinationsol/game/PlayerCreator.java +++ b/engine/src/main/java/org/destinationsol/game/PlayerCreator.java @@ -185,7 +185,7 @@ private Pilot createPilot(SolGame game, boolean isMouseControl) { if (isMouseControl) { return new AiPilot(new BeaconDestProvider(), true, Faction.LAANI, false, "you", Const.AI_DET_DIST); } else { - return new UiControlledPilot(game.getScreens().getMainGameScreen().getShipControl()); + return new UiControlledPilot(game.getScreens().getOldMainGameScreen().getShipControl()); } } diff --git a/engine/src/main/java/org/destinationsol/game/SolCam.java b/engine/src/main/java/org/destinationsol/game/SolCam.java index 55211335c..5f39f9abe 100644 --- a/engine/src/main/java/org/destinationsol/game/SolCam.java +++ b/engine/src/main/java/org/destinationsol/game/SolCam.java @@ -177,7 +177,7 @@ public void applyPos(float posX, float posY) { } private void applyInput(SolGame game) { - MainGameScreen screen = game.getScreens().mainGameScreen; + MainGameScreen screen = game.getScreens().oldMainGameScreen; boolean d = screen.isCameraDown(); boolean u = screen.isCameraUp(); boolean l = screen.isCameraLeft(); diff --git a/engine/src/main/java/org/destinationsol/game/SolGame.java b/engine/src/main/java/org/destinationsol/game/SolGame.java index 7fe5d3b95..3b99edfd0 100644 --- a/engine/src/main/java/org/destinationsol/game/SolGame.java +++ b/engine/src/main/java/org/destinationsol/game/SolGame.java @@ -22,7 +22,6 @@ import org.destinationsol.ContextWrapper; import org.destinationsol.GameOptions; import org.destinationsol.SolApplication; -import org.destinationsol.assets.Assets; import org.destinationsol.assets.sound.OggSoundManager; import org.destinationsol.assets.sound.SpecialSounds; import org.destinationsol.common.DebugCol; @@ -68,10 +67,8 @@ import org.destinationsol.ui.nui.screens.MainGameScreen; import org.destinationsol.world.GalaxyBuilder; import org.terasology.context.exception.BeanNotFoundException; -import org.terasology.gestalt.assets.ResourceUrn; import org.terasology.gestalt.di.BeanContext; import org.terasology.gestalt.entitysystem.entity.EntityRef; -import org.terasology.nui.asset.UIElement; import javax.inject.Inject; import java.util.ArrayList; @@ -266,7 +263,7 @@ public void run() { } }, 0, 30); gameScreens.consoleScreen.init(this); - solApplication.getNuiManager().pushScreen(mainGameScreen); + solApplication.getNuiManager().pushScreen(gameScreens.mainGameScreen); tutorialManager.ifPresent(TutorialManager::start); } diff --git a/engine/src/main/java/org/destinationsol/game/screens/BorderDrawer.java b/engine/src/main/java/org/destinationsol/game/screens/BorderDrawer.java index b0e714d0a..182736b96 100644 --- a/engine/src/main/java/org/destinationsol/game/screens/BorderDrawer.java +++ b/engine/src/main/java/org/destinationsol/game/screens/BorderDrawer.java @@ -56,7 +56,7 @@ public class BorderDrawer { private final ArrayList planetProximityIndicators; private final Vector2 myTmpVec = new Vector2(); - BorderDrawer() { + public BorderDrawer() { displayDimensions = SolApplication.displayDimensions; TextureAtlas.AtlasRegion texture = Assets.getAtlasRegion("engine:uiPlanetProximityIndicator"); 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..ff03fddbb 100644 --- a/engine/src/main/java/org/destinationsol/game/screens/BuyItemsScreen.java +++ b/engine/src/main/java/org/destinationsol/game/screens/BuyItemsScreen.java @@ -54,7 +54,7 @@ public void updateCustom(SolApplication solApplication, SolInputManager.InputPoi TalkScreen talkScreen = game.getScreens().talkScreen; SolShip target = talkScreen.getTarget(); if (talkScreen.isTargetFar(hero)) { - solApplication.getInputManager().setScreen(solApplication, game.getScreens().mainGameScreen); + solApplication.getInputManager().setScreen(solApplication, game.getScreens().oldMainGameScreen); return; } SolItem selItem = is.getSelectedItem(); 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..811e9895d 100644 --- a/engine/src/main/java/org/destinationsol/game/screens/ChangeShipScreen.java +++ b/engine/src/main/java/org/destinationsol/game/screens/ChangeShipScreen.java @@ -58,7 +58,7 @@ public void updateCustom(SolApplication solApplication, SolInputManager.InputPoi Hero hero = game.getHero(); TalkScreen talkScreen = game.getScreens().talkScreen; if (talkScreen.isTargetFar(hero)) { - solApplication.getInputManager().setScreen(solApplication, game.getScreens().mainGameScreen); + solApplication.getInputManager().setScreen(solApplication, game.getScreens().oldMainGameScreen); return; } SolItem selItem = is.getSelectedItem(); 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..3995c9ee3 100644 --- a/engine/src/main/java/org/destinationsol/game/screens/ChooseMercenaryScreen.java +++ b/engine/src/main/java/org/destinationsol/game/screens/ChooseMercenaryScreen.java @@ -60,19 +60,19 @@ public void updateCustom(SolApplication solApplication, SolInputManager.InputPoi if (giveControl.isJustOff() && selNull) { SolShip solship = ((MercItem) selItem).getSolShip(); - inputMan.setScreen(solApplication, screens.mainGameScreen); + inputMan.setScreen(solApplication, screens.oldMainGameScreen); 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); + inputMan.setScreen(solApplication, screens.oldMainGameScreen); 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); + inputMan.setScreen(solApplication, screens.oldMainGameScreen); is.showInventory.setTarget(solship); is.setOperations(is.showInventory); inputMan.addScreen(solApplication, is); diff --git a/engine/src/main/java/org/destinationsol/game/screens/ConsoleScreen.java b/engine/src/main/java/org/destinationsol/game/screens/ConsoleScreen.java index d406300e4..f3d944509 100644 --- a/engine/src/main/java/org/destinationsol/game/screens/ConsoleScreen.java +++ b/engine/src/main/java/org/destinationsol/game/screens/ConsoleScreen.java @@ -162,7 +162,7 @@ public void onAdd(SolApplication solApplication) { @Override public void updateCustom(SolApplication solApplication, SolInputManager.InputPointer[] inputPointers, boolean clickedOutside) { if (exitControl.isJustOff()) { - solApplication.getInputManager().setScreen(solApplication, solApplication.getGame().getScreens().mainGameScreen); + solApplication.getInputManager().setScreen(solApplication, solApplication.getGame().getScreens().oldMainGameScreen); } if (commandHistoryUpControl.isJustOff()) { if (commandHistoryIndex > 0) { 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 5da379640..cda4b9a3d 100644 --- a/engine/src/main/java/org/destinationsol/game/screens/GameScreens.java +++ b/engine/src/main/java/org/destinationsol/game/screens/GameScreens.java @@ -23,7 +23,10 @@ import javax.inject.Inject; public class GameScreens { - public final MainGameScreen mainGameScreen; + private static final String NUI_MAIN_GAME_SCREEN_DESKTOP_URI = "engine:mainGameScreen_desktop"; + private static final String NUI_MAIN_GAME_SCREEN_MOBILE_URI = "engine:mainGameScreen_mobile"; + public final MainGameScreen oldMainGameScreen; + public final org.destinationsol.ui.nui.screens.MainGameScreen mainGameScreen; public final MapScreen mapScreen; public final MenuScreen menuScreen; public final InventoryScreen inventoryScreen; @@ -35,7 +38,13 @@ public class GameScreens { public GameScreens(SolApplication cmp, Context context) { SolLayouts layouts = cmp.getLayouts(); RightPaneLayout rightPaneLayout = layouts.rightPaneLayout; - mainGameScreen = new MainGameScreen(rightPaneLayout, context); + oldMainGameScreen = new MainGameScreen(rightPaneLayout, context); + boolean isMobile = cmp.isMobile(); + if (!isMobile) { + mainGameScreen = (org.destinationsol.ui.nui.screens.MainGameScreen) cmp.getNuiManager().createScreen(NUI_MAIN_GAME_SCREEN_DESKTOP_URI); + } else { + mainGameScreen = (org.destinationsol.ui.nui.screens.MainGameScreen) cmp.getNuiManager().createScreen(NUI_MAIN_GAME_SCREEN_MOBILE_URI); + } mapScreen = new MapScreen(rightPaneLayout, cmp.isMobile(), cmp.getOptions()); menuScreen = new MenuScreen(layouts.menuLayout, cmp.getOptions()); inventoryScreen = new InventoryScreen(cmp.getOptions()); @@ -46,7 +55,7 @@ public GameScreens(SolApplication cmp, Context context) { // This was added for PlayerCreatorTest.java (used in PlayerCreator) // so that it can successfully mock the returned result. - public MainGameScreen getMainGameScreen() { - return mainGameScreen; + public MainGameScreen getOldMainGameScreen() { + return oldMainGameScreen; } } 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..3e298bc43 100644 --- a/engine/src/main/java/org/destinationsol/game/screens/HireShipsScreen.java +++ b/engine/src/main/java/org/destinationsol/game/screens/HireShipsScreen.java @@ -52,7 +52,7 @@ public void updateCustom(SolApplication solApplication, SolInputManager.InputPoi Hero hero = game.getHero(); TalkScreen talkScreen = game.getScreens().talkScreen; if (talkScreen.isTargetFar(hero)) { - solApplication.getInputManager().setScreen(solApplication, game.getScreens().mainGameScreen); + solApplication.getInputManager().setScreen(solApplication, game.getScreens().oldMainGameScreen); return; } SolItem selItem = is.getSelectedItem(); diff --git a/engine/src/main/java/org/destinationsol/game/screens/InventoryScreen.java b/engine/src/main/java/org/destinationsol/game/screens/InventoryScreen.java index cddbe0686..f4fe55c8b 100644 --- a/engine/src/main/java/org/destinationsol/game/screens/InventoryScreen.java +++ b/engine/src/main/java/org/destinationsol/game/screens/InventoryScreen.java @@ -157,11 +157,11 @@ public void updateCustom(SolApplication solApplication, SolInputManager.InputPoi GameScreens screens = game.getScreens(); InventoryScreen is = screens.inventoryScreen; - inputMan.setScreen(solApplication, screens.mainGameScreen); + inputMan.setScreen(solApplication, screens.oldMainGameScreen); is.setOperations(is.chooseMercenaryScreen); inputMan.addScreen(solApplication, is); } - solApplication.getInputManager().setScreen(solApplication, solApplication.getGame().getScreens().mainGameScreen); + solApplication.getInputManager().setScreen(solApplication, solApplication.getGame().getScreens().oldMainGameScreen); return; } if (previousControl.isJustOff()) { 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..453da82e3 100644 --- a/engine/src/main/java/org/destinationsol/game/screens/MainGameScreen.java +++ b/engine/src/main/java/org/destinationsol/game/screens/MainGameScreen.java @@ -15,92 +15,44 @@ */ package org.destinationsol.game.screens; -import com.badlogic.gdx.graphics.Color; -import com.badlogic.gdx.graphics.g2d.TextureAtlas; -import com.badlogic.gdx.math.MathUtils; 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.assets.Assets; -import org.destinationsol.common.SolColor; -import org.destinationsol.common.SolMath; import org.destinationsol.game.DebugOptions; -import org.destinationsol.game.FactionManager; -import org.destinationsol.game.HardnessCalc; -import org.destinationsol.game.Hero; -import org.destinationsol.game.SolCam; import org.destinationsol.game.SolGame; -import org.destinationsol.game.SolObject; import org.destinationsol.game.context.Context; -import org.destinationsol.game.item.Gun; -import org.destinationsol.game.item.ItemManager; -import org.destinationsol.game.item.Shield; -import org.destinationsol.game.item.SolItem; -import org.destinationsol.game.planet.Planet; -import org.destinationsol.game.ship.ShipAbility; -import org.destinationsol.game.ship.SolShip; -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.SolUiScreen; import org.destinationsol.ui.UiDrawer; +import org.destinationsol.ui.nui.NUIManager; +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; -import org.terasology.nui.asset.UIElement; import java.util.ArrayList; import java.util.List; +/** + * @deprecated This class only exists for compatibility purposes whilst the rest of the code is + * transitions to the new NUI-based MainGameScreen. Almost all functionality is now implemented by the new screen. + * @see org.destinationsol.ui.nui.screens.MainGameScreen the new NUI-based MainGameScreen + */ +@Deprecated public class MainGameScreen extends SolUiBaseScreen { - // TODO: Rename! - private static final float ICON_SZ = .03f; - private static final float BAR_SZ = ICON_SZ * 5; - private static final int MAX_ICON_COUNT = 3; static final float CELL_SZ = .17f; - private static final float H_PAD = .005f; - private static final float V_PAD = H_PAD; static final float HELPER_ROW_1 = 1 - 3f * CELL_SZ; - private static final float HELPER_ROW_2 = HELPER_ROW_1 - .5f * CELL_SZ; - private static final float HELPER_ROW_3 = HELPER_ROW_2 - .5f * CELL_SZ; private final ShipUiControl shipControl; - private final SolUiControl freeCamControl; private final SolUiControl pauseControl; private final CameraKeyboardControl cameraControl; - - private final ZoneNameAnnouncer zoneNameAnnouncer; - private final BorderDrawer borderDrawer; - - private final TextureAtlas.AtlasRegion lifeTexture; - private final TextureAtlas.AtlasRegion infinityTexture; - private final TextureAtlas.AtlasRegion waitTexture; - private final TextureAtlas.AtlasRegion compassTexture; - - private final Color myCompassTint; - private final TextPlace myLifeTp; - private final TextPlace myRepairsExcessTp; - private final TextPlace myShieldLifeTp; - private final TextPlace myG1AmmoTp; - private final TextPlace myG1AmmoExcessTp; - private final TextPlace myG2AmmoTp; - private final TextPlace myG2AmmoExcessTp; - private final TextPlace myChargesExcessTp; - private final TextPlace myMoneyExcessTp; private final SolApplication solApplication; - private final Context context; private List gameOverlayScreens = new ArrayList<>(); private List warnDrawers = new ArrayList<>(); MainGameScreen(RightPaneLayout rightPaneLayout, Context context) { - DisplayDimensions displayDimensions = SolApplication.displayDimensions; - - this.context = context; solApplication = context.get(SolApplication.class); GameOptions gameOptions = solApplication.getOptions(); @@ -122,42 +74,9 @@ public class MainGameScreen extends SolUiBaseScreen { break; } - boolean mobile = solApplication.isMobile(); - float lastCol = displayDimensions.getRatio() - MainGameScreen.CELL_SZ; - // No button, since on mobile, it should be ideally controlled straightly by dragging. - freeCamControl = new SolUiControl(null, false, gameOptions.getKeyFreeCameraMovement()); - controls.add(freeCamControl); pauseControl = new SolUiControl(null, true, gameOptions.getKeyPause()); controls.add(pauseControl); cameraControl = new CameraKeyboardControl(gameOptions, controls); - - // possible warning messages in order of importance, so earlier one will be drawn on the center - warnDrawers.add(new SunWarnDrawer()); - warnDrawers.add(new DmgWarnDrawer()); - warnDrawers.add(new CollisionWarnDrawer()); - warnDrawers.add(new NoShieldWarn()); - warnDrawers.add(new NoArmorWarn()); - warnDrawers.add(new EnemyWarn()); - - zoneNameAnnouncer = new ZoneNameAnnouncer(); - borderDrawer = new BorderDrawer(); - - lifeTexture = Assets.getAtlasRegion("engine:iconLife"); - infinityTexture = Assets.getAtlasRegion("engine:iconInfinity"); - waitTexture = Assets.getAtlasRegion("engine:iconWait"); - - compassTexture = Assets.getAtlasRegion("engine:uiCompass"); - myCompassTint = SolColor.col(1, 0); - - myLifeTp = new TextPlace(SolColor.W50); - myRepairsExcessTp = new TextPlace(SolColor.WHITE); - myShieldLifeTp = new TextPlace(SolColor.W50); - myG1AmmoTp = new TextPlace(SolColor.W50); - myG1AmmoExcessTp = new TextPlace(SolColor.WHITE); - myG2AmmoTp = new TextPlace(SolColor.W50); - myG2AmmoExcessTp = new TextPlace(SolColor.WHITE); - myChargesExcessTp = new TextPlace(SolColor.WHITE); - myMoneyExcessTp = new TextPlace(SolColor.WHITE); } @Override @@ -180,34 +99,6 @@ public static Rectangle btn(float x, float y, boolean halfHeight) { return new Rectangle(x + gap, y + gap, CELL_SZ - gap * 2, cellH - gap * 2); } - private void maybeDrawHeight(UiDrawer drawer) { - SolGame game = solApplication.getGame(); - Planet np = game.getPlanetManager().getNearestPlanet(); - SolCam cam = context.get(SolCam.class); - Vector2 camPos = cam.getPosition(); - if (np != null && np.getPosition().dst(camPos) < np.getFullHeight()) { - drawHeight(drawer, np, camPos, cam.getAngle()); - } - } - - private void drawHeight(UiDrawer drawer, Planet np, Vector2 camPos, float camAngle) { - float toPlanet = camPos.dst(np.getPosition()); - toPlanet -= np.getGroundHeight(); - if (Const.ATM_HEIGHT < toPlanet) { - return; - } - float perc = toPlanet / Const.ATM_HEIGHT; - float sz = .08f; - float maxY = 1 - sz / 2; - float y = 1 - perc; - myCompassTint.a = SolMath.clamp(1.5f * y); - if (maxY < y) { - y = maxY; - } - float angle = np.getAngle() - camAngle; - drawer.draw(compassTexture, sz, sz, sz / 2, sz / 2, sz / 2, y, angle, myCompassTint); - } - @Override public void updateCustom(SolApplication solApplication, SolInputManager.InputPointer[] inputPointers, boolean clickedOutside) { if (DebugOptions.PRINT_BALANCE) { @@ -216,20 +107,19 @@ public void updateCustom(SolApplication solApplication, SolInputManager.InputPoi } SolGame game = solApplication.getGame(); SolInputManager inputMan = solApplication.getInputManager(); + NUIManager nuiManager = solApplication.getNuiManager(); GameScreens screens = game.getScreens(); - Hero hero = game.getHero(); for (WarnDrawer warnDrawer : warnDrawers) { warnDrawer.update(game); } - zoneNameAnnouncer.update(game, context); - - boolean controlsEnabled = inputMan.getTopScreen() == this; + NUIScreenLayer topScreen = nuiManager.getTopScreen(); + boolean controlsEnabled = inputMan.getTopScreen() == this && + (topScreen instanceof org.destinationsol.ui.nui.screens.MainGameScreen || + inputMan.getTopScreen() instanceof UIShipControlsScreen); shipControl.update(solApplication, controlsEnabled); - SolCam.DIRECT_CAM_CONTROL = freeCamControl.isOn(); - if (solApplication.getNuiManager().hasScreenOfType(ConsoleScreen.class)) { controls.forEach(x -> x.setEnabled(false)); } else if (!inputMan.isScreenOn(screens.menuScreen)) { @@ -246,136 +136,8 @@ public void updateCustom(SolApplication solApplication, SolInputManager.InputPoi } } - private boolean drawGunStat(UiDrawer uiDrawer, Hero hero, boolean secondary, float col0, float col1, - float col2, float y) { - Gun g = hero.getHull().getGun(secondary); - if (g == null) { - return false; - } - TextureAtlas.AtlasRegion tex = g.config.icon; - - uiDrawer.draw(tex, ICON_SZ, ICON_SZ, 0, 0, col0, y, 0, SolColor.WHITE); - float curr; - float max; - if (g.reloadAwait > 0) { - max = g.config.reloadTime; - curr = max - g.reloadAwait; - } else { - curr = g.ammo; - max = g.config.clipConf.size; - } - TextPlace ammoTp = g.reloadAwait > 0 ? null : secondary ? myG2AmmoTp : myG1AmmoTp; - drawBar(uiDrawer, col1, y, curr, max, ammoTp); - if (g.reloadAwait > 0) { - drawWait(uiDrawer, col1, y); - } - if (!g.config.clipConf.infinite) { - int clipCount = hero.getItemContainer().count(g.config.clipConf.example); - drawIcons(uiDrawer, col2, y, clipCount, g.config.clipConf.icon, secondary ? myG2AmmoExcessTp : myG1AmmoExcessTp); - } else { - uiDrawer.draw(infinityTexture, ICON_SZ, ICON_SZ, 0, 0, col2, y, 0, SolColor.WHITE); - } - return true; - } - - private void drawWait(UiDrawer uiDrawer, float x, float y) { - uiDrawer.draw(waitTexture, ICON_SZ, ICON_SZ, ICON_SZ / 2, ICON_SZ / 2, x + BAR_SZ / 2, y + ICON_SZ / 2, 0, SolColor.WHITE); - } - - private void drawBar(UiDrawer uiDrawer, float x, float y, float curr, float max, TextPlace tp) { - float perc = curr / max; - uiDrawer.draw(uiDrawer.whiteTexture, BAR_SZ, ICON_SZ, 0, 0, x, y, 0, SolColor.UI_DARK); - uiDrawer.draw(uiDrawer.whiteTexture, BAR_SZ * perc, ICON_SZ, 0, 0, x, y, 0, SolColor.UI_LIGHT); - if (tp != null && max > 1 && curr > 0) { - tp.text = (int) curr + "/" + (int) max; - tp.position.set(x + BAR_SZ / 2, y + ICON_SZ / 2); - } - } - - private void drawIcons(UiDrawer uiDrawer, float x, float y, int count, TextureAtlas.AtlasRegion tex, - TextPlace textPlace) { - int excess = count - MAX_ICON_COUNT; - int iconCount = excess > 0 ? MAX_ICON_COUNT : count; - for (int i = 0; i < iconCount; i++) { - uiDrawer.draw(tex, ICON_SZ, ICON_SZ, 0, 0, x, y, 0, SolColor.WHITE); - x += ICON_SZ + H_PAD; - } - if (excess > 0) { - updateTextPlace(x, y, "+" + excess, textPlace); - } - } - - private void updateTextPlace(float x, float y, String text, TextPlace textPlace) { - textPlace.text = text; - textPlace.position.set(x + ICON_SZ / 2, y + ICON_SZ / 2); - } - @Override public void drawImages(UiDrawer uiDrawer, SolApplication solApplication) { - myLifeTp.text = null; - myRepairsExcessTp.text = null; - myShieldLifeTp.text = null; - myG1AmmoTp.text = null; - myG1AmmoExcessTp.text = null; - myG2AmmoTp.text = null; - myG2AmmoExcessTp.text = null; - myChargesExcessTp.text = null; - myMoneyExcessTp.text = null; - - maybeDrawHeight(uiDrawer); - borderDrawer.draw(uiDrawer, solApplication, context); - - SolGame game = solApplication.getGame(); - Hero hero = game.getHero(); - if (hero.isNonTranscendent()) { - float row = BorderDrawer.PLANET_PROXIMITY_INDICATOR_SIZE + V_PAD; - float col0 = BorderDrawer.PLANET_PROXIMITY_INDICATOR_SIZE + H_PAD; - float col1 = col0 + ICON_SZ + H_PAD; - float col2 = col1 + BAR_SZ + H_PAD; - - Shield shield = hero.getShield(); - if (shield != null) { - uiDrawer.draw(shield.getIcon(game), ICON_SZ, ICON_SZ, 0, 0, col0, row, 0, SolColor.WHITE); - drawBar(uiDrawer, col1, row, MathUtils.floor(shield.getLife()), shield.getMaxLife(), myShieldLifeTp); - row += ICON_SZ + V_PAD; - } - - uiDrawer.draw(lifeTexture, ICON_SZ, ICON_SZ, 0, 0, col0, row, 0, SolColor.WHITE); - drawBar(uiDrawer, col1, row, MathUtils.floor(hero.getLife()), hero.getHull().config.getMaxLife(), myLifeTp); - int repairKitCount = hero.getItemContainer().count(game.getItemMan().getRepairExample()); - ItemManager itemManager = game.getItemMan(); - drawIcons(uiDrawer, col2, row, repairKitCount, itemManager.repairIcon, myRepairsExcessTp); - - row += ICON_SZ + V_PAD; - boolean consumed = drawGunStat(uiDrawer, hero, false, col0, col1, col2, row); - if (consumed) { - row += ICON_SZ + V_PAD; - } - consumed = drawGunStat(uiDrawer, hero, true, col0, col1, col2, row); - if (consumed) { - row += ICON_SZ + V_PAD; - } - - ShipAbility ability = hero.getAbility(); - SolItem abilityChargeEx = ability == null ? null : ability.getConfig().getChargeExample(); - if (abilityChargeEx != null) { - int abilityChargeCount = hero.getItemContainer().count(abilityChargeEx); - TextureAtlas.AtlasRegion icon = abilityChargeEx.getIcon(game); - uiDrawer.draw(icon, ICON_SZ, ICON_SZ, 0, 0, col0, row, 0, SolColor.WHITE); - float chargePercentage = 1 - SolMath.clamp(hero.getAbilityAwait() / ability.getConfig().getRechargeTime()); - drawBar(uiDrawer, col1, row, chargePercentage, 1, null); - if (chargePercentage < 1) { - drawWait(uiDrawer, col1, row); - } - drawIcons(uiDrawer, col2, row, abilityChargeCount, icon, myChargesExcessTp); - row += ICON_SZ + V_PAD; - } - uiDrawer.draw(game.getItemMan().moneyIcon, ICON_SZ, ICON_SZ, 0, 0, col0, row, 0, SolColor.WHITE); - myMoneyExcessTp.text = Integer.toString(Math.round(hero.getMoney())); - myMoneyExcessTp.position.set(col1, row + ICON_SZ / 2); - //updateTextPlace(col1, row, (int) hero.getMoney() + "", myMoneyExcessTp); - } - int drawPlace = 0; for (WarnDrawer wd : warnDrawers) { if (wd.drawPercentage > 0) { @@ -390,16 +152,6 @@ public void drawImages(UiDrawer uiDrawer, SolApplication solApplication) { @Override public void drawText(UiDrawer uiDrawer, SolApplication solApplication) { - myLifeTp.draw(uiDrawer); - myRepairsExcessTp.draw(uiDrawer); - myShieldLifeTp.draw(uiDrawer); - myG1AmmoTp.draw(uiDrawer); - myG1AmmoExcessTp.draw(uiDrawer); - myG2AmmoTp.draw(uiDrawer); - myG2AmmoExcessTp.draw(uiDrawer); - myChargesExcessTp.draw(uiDrawer); - myMoneyExcessTp.draw(uiDrawer, UiDrawer.TextAlignment.LEFT); - int drawPlace = 0; for (WarnDrawer warnDrawer : warnDrawers) { if (warnDrawer.drawPercentage > 0) { @@ -407,8 +159,6 @@ public void drawText(UiDrawer uiDrawer, SolApplication solApplication) { } } - zoneNameAnnouncer.drawText(uiDrawer); - for (SolUiScreen screen : gameOverlayScreens) { screen.drawText(uiDrawer, solApplication); } @@ -443,117 +193,71 @@ public boolean isCameraRight() { return cameraControl.isRight(); } + /** + * @deprecated Use NUI screens instead. All NUI screens are overlays. + * @see NUIScreenLayer + * @see NUIManager#createScreen(String) + * @see NUIManager#pushScreen(NUIScreenLayer) + */ + @Deprecated public void addOverlayScreen(SolUiScreen screen) { gameOverlayScreens.add(screen); screen.onAdd(solApplication); controls.addAll(screen.getControls()); } + /** + * @deprecated Use NUI screens instead. All NUI screens are overlays. + * @see NUIManager#removeScreen(NUIScreenLayer) + */ + @Deprecated public void removeOverlayScreen(SolUiScreen screen) { gameOverlayScreens.remove(screen); controls.removeAll(screen.getControls()); } + /** + * @deprecated Use NUI screens instead. All NUI screens are overlays. + * @see NUIManager#hasScreen(NUIScreenLayer) + */ + @Deprecated public boolean hasOverlay(SolUiScreen screen) { return gameOverlayScreens.contains(screen); } + /** + * @deprecated Use the new MainGameScreen and UIWarnDrawer instead. + * @see org.destinationsol.ui.nui.widgets.UIWarnDrawer + * @see org.destinationsol.ui.nui.screens.MainGameScreen#addWarnDrawer(String, org.terasology.nui.Color, String, org.terasology.nui.databinding.Binding) + * @see org.destinationsol.ui.nui.screens.MainGameScreen#addWarnDrawer(org.destinationsol.ui.nui.widgets.UIWarnDrawer) + */ + @Deprecated public void addWarnDrawer(WarnDrawer drawer) { if (!warnDrawers.contains(drawer)) { warnDrawers.add(drawer); } } + /** + * @deprecated Use the new MainGameScreen and UIWarnDrawer instead. + * @see org.destinationsol.ui.nui.widgets.UIWarnDrawer + * @see org.destinationsol.ui.nui.screens.MainGameScreen#removeWarnDrawer(String) + * @see org.destinationsol.ui.nui.screens.MainGameScreen#removeWarnDrawer(org.destinationsol.ui.nui.widgets.UIWarnDrawer) + */ + @Deprecated public void removeWarnDrawer(WarnDrawer drawer) { warnDrawers.remove(drawer); } + /** + * @deprecated Use the new MainGameScreen and UIWarnDrawer instead. + * @see org.destinationsol.ui.nui.widgets.UIWarnDrawer + * @see org.destinationsol.ui.nui.screens.MainGameScreen#hasWarnDrawer(String) + * @see org.destinationsol.ui.nui.screens.MainGameScreen#hasWarnDrawer(org.destinationsol.ui.nui.widgets.UIWarnDrawer) + */ + @Deprecated public boolean hasWarnDrawer(WarnDrawer drawer) { return warnDrawers.contains(drawer); } - - public static class TextPlace { - public final Color color; - public String text; - public Vector2 position = new Vector2(); - - TextPlace(Color col) { - color = new Color(col); - } - - public void draw(UiDrawer uiDrawer) { - uiDrawer.drawString(text, position.x, position.y, FontSize.HUD, true, color); - } - - public void draw(UiDrawer uiDrawer, UiDrawer.TextAlignment align) { - uiDrawer.drawString(text, position.x, position.y, FontSize.HUD, align, true, color); - } - } - - private static class NoShieldWarn extends WarnDrawer { - NoShieldWarn() { - super("No Shield"); - } - - protected boolean shouldWarn(SolGame game) { - Hero hero = game.getHero(); - return hero.isNonTranscendent() && hero.getShield() == null; - } - } - - private static class NoArmorWarn extends WarnDrawer { - NoArmorWarn() { - super("No Armor"); - } - - protected boolean shouldWarn(SolGame game) { - Hero hero = game.getHero(); - return hero.isNonTranscendent() && hero.getArmor() == null; - } - } - - private static class EnemyWarn extends WarnDrawer { - EnemyWarn() { - super("Dangerous\nEnemy"); - } - - protected boolean shouldWarn(SolGame game) { - Hero hero = game.getHero(); - if (hero.isTranscendent()) { - return false; - } - - float heroCap = HardnessCalc.getShipDmgCap(hero.getShip()); - List objs = game.getObjectManager().getObjects(); - FactionManager fm = game.getFactionMan(); - SolCam cam = game.getContext().get(SolCam.class); - float viewDist = cam.getViewDistance(); - float dps = 0; - - for (SolObject o : objs) { - if (!(o instanceof SolShip)) { - continue; - } - - SolShip ship = (SolShip) o; - - if (viewDist < ship.getPosition().dst(hero.getPosition())) { - continue; - } - - if (!fm.areEnemies(hero.getShip(), ship)) { - continue; - } - - dps += HardnessCalc.getShipDps(ship); - - if (HardnessCalc.isDangerous(heroCap, dps)) { - return true; - } - } - - return false; - } - } } diff --git a/engine/src/main/java/org/destinationsol/game/screens/MapScreen.java b/engine/src/main/java/org/destinationsol/game/screens/MapScreen.java index aaa9e60f2..ee71bf625 100644 --- a/engine/src/main/java/org/destinationsol/game/screens/MapScreen.java +++ b/engine/src/main/java/org/destinationsol/game/screens/MapScreen.java @@ -89,7 +89,7 @@ public void updateCustom(SolApplication solApplication, SolInputManager.InputPoi mapDrawer.getMapDrawPositionAdditive().set(0, 0); isPickingWaypointSpot = false; addWaypointControl.setDisplayName(NEW_WAYPOINT_TEXT); - im.setScreen(solApplication, game.getScreens().mainGameScreen); + im.setScreen(solApplication, game.getScreens().oldMainGameScreen); } boolean zoomIn = zoomInControl.isJustOff(); @@ -100,7 +100,7 @@ public void updateCustom(SolApplication solApplication, SolInputManager.InputPoi float mapZoom = mapDrawer.getZoom(); zoomInControl.setEnabled(mapZoom != MapDrawer.MIN_ZOOM); zoomOutControl.setEnabled(mapZoom != MapDrawer.MAX_ZOOM); - ShipUiControl shipControl = game.getScreens().mainGameScreen.getShipControl(); + ShipUiControl shipControl = game.getScreens().oldMainGameScreen.getShipControl(); if (shipControl instanceof ShipMouseControl) { shipControl.update(solApplication, true); } diff --git a/engine/src/main/java/org/destinationsol/game/screens/MenuScreen.java b/engine/src/main/java/org/destinationsol/game/screens/MenuScreen.java index 34e4c569a..a0f9e084c 100644 --- a/engine/src/main/java/org/destinationsol/game/screens/MenuScreen.java +++ b/engine/src/main/java/org/destinationsol/game/screens/MenuScreen.java @@ -71,7 +71,7 @@ public void updateCustom(SolApplication solApplication, SolInputManager.InputPoi } if (respawnControl.isJustOff()) { game.respawn(); - im.setScreen(solApplication, game.getScreens().mainGameScreen); + im.setScreen(solApplication, game.getScreens().oldMainGameScreen); game.setPaused(false); } if (exitControl.isJustOff()) { @@ -79,7 +79,7 @@ public void updateCustom(SolApplication solApplication, SolInputManager.InputPoi } if (closeControl.isJustOff()) { game.setPaused(false); - im.setScreen(solApplication, game.getScreens().mainGameScreen); + im.setScreen(solApplication, game.getScreens().oldMainGameScreen); } doNotSellEquippedControl.setDisplayName("Can sell used items: " + (options.canSellEquippedItems ? "Yes" : "No")); 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..0d6488886 100644 --- a/engine/src/main/java/org/destinationsol/game/screens/SellItems.java +++ b/engine/src/main/java/org/destinationsol/game/screens/SellItems.java @@ -66,7 +66,7 @@ public void updateCustom(SolApplication solApplication, SolInputManager.InputPoi SolShip target = talkScreen.getTarget(); Hero hero = game.getHero(); if (talkScreen.isTargetFar(hero)) { - solApplication.getInputManager().setScreen(solApplication, game.getScreens().mainGameScreen); + solApplication.getInputManager().setScreen(solApplication, game.getScreens().oldMainGameScreen); return; } SolItem selItem = inventoryScreen.getSelectedItem(); 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..f21d45205 100644 --- a/engine/src/main/java/org/destinationsol/game/screens/TalkScreen.java +++ b/engine/src/main/java/org/destinationsol/game/screens/TalkScreen.java @@ -75,7 +75,7 @@ public void updateCustom(SolApplication solApplication, SolInputManager.InputPoi Hero hero = game.getHero(); SolInputManager inputManager = solApplication.getInputManager(); if (closeControl.isJustOff() || isTargetFar(hero)) { - inputManager.setScreen(solApplication, game.getScreens().mainGameScreen); + inputManager.setScreen(solApplication, game.getScreens().oldMainGameScreen); return; } @@ -90,7 +90,7 @@ public void updateCustom(SolApplication solApplication, SolInputManager.InputPoi boolean hire = hireControl.isJustOff(); if (sell || buy || sellShips || hire) { inventoryScreen.setOperations(sell ? inventoryScreen.sellItems : buy ? inventoryScreen.buyItemsScreen : sellShips ? inventoryScreen.changeShipScreen : inventoryScreen.hireShipsScreen); - inputManager.setScreen(solApplication, game.getScreens().mainGameScreen); + inputManager.setScreen(solApplication, game.getScreens().oldMainGameScreen); inputManager.addScreen(solApplication, inventoryScreen); } } diff --git a/engine/src/main/java/org/destinationsol/game/screens/ZoneNameAnnouncer.java b/engine/src/main/java/org/destinationsol/game/screens/ZoneNameAnnouncer.java index f4c57a33e..f0e11878a 100644 --- a/engine/src/main/java/org/destinationsol/game/screens/ZoneNameAnnouncer.java +++ b/engine/src/main/java/org/destinationsol/game/screens/ZoneNameAnnouncer.java @@ -37,7 +37,7 @@ public class ZoneNameAnnouncer { private String zone; private String text; - ZoneNameAnnouncer() { + public ZoneNameAnnouncer() { displayDimensions = SolApplication.displayDimensions; } diff --git a/engine/src/main/java/org/destinationsol/ui/SolInputManager.java b/engine/src/main/java/org/destinationsol/ui/SolInputManager.java index 75b03aadf..9a3e2f678 100644 --- a/engine/src/main/java/org/destinationsol/ui/SolInputManager.java +++ b/engine/src/main/java/org/destinationsol/ui/SolInputManager.java @@ -301,7 +301,7 @@ private void updateCursor(SolApplication solApplication) { if (game == null || mouseOnUi || nuiManager.isMouseOnUi()) { currCursor = uiCursor; } else { - currCursor = game.getScreens().mainGameScreen.getShipControl().getInGameTex(); + currCursor = game.getScreens().oldMainGameScreen.getShipControl().getInGameTex(); if (currCursor == null) { currCursor = uiCursor; } diff --git a/engine/src/main/java/org/destinationsol/ui/TutorialManager.java b/engine/src/main/java/org/destinationsol/ui/TutorialManager.java index c50ec587f..fdeb7e26d 100644 --- a/engine/src/main/java/org/destinationsol/ui/TutorialManager.java +++ b/engine/src/main/java/org/destinationsol/ui/TutorialManager.java @@ -59,7 +59,7 @@ public TutorialManager(GameScreens screens, GameOptions gameOptions, Provider() { + @Override + public UITextureRegion get() { + SolGame game = solApplication.getGame(); + Hero hero = game.getHero(); + Shield shield = hero.getShield(); + if (shield != null) { + return Assets.getDSTexture(shield.getIcon(game).name).getUiTexture(); + } else { + return null; + } + } + }, + new ReadOnlyBinding() { + @Override + public Float get() { + Hero hero = solApplication.getGame().getHero(); + Shield heroShield = hero.getShield(); + if (heroShield != null) { + return heroShield.getLife() / heroShield.getMaxLife(); + } else { + return 0.0f; + } + } + }, new ReadOnlyBinding() { + @Override + public String get() { + Hero hero = solApplication.getGame().getHero(); + Shield heroShield = hero.getShield(); + if (heroShield != null) { + return (int) Math.floor(heroShield.getLife()) + "/" + (int) Math.floor(heroShield.getMaxLife()); + } else { + return ""; + } + } + }, new DefaultBinding<>(), null, new DefaultBinding<>(0.0f)); + statsBars.addWidget(shieldStats); + + hullStats = createStatsRow("health", new DefaultBinding<>(Assets.getDSTexture(LIFE_TEXTURE_URN).getUiTexture()), + new ReadOnlyBinding() { + @Override + public Float get() { + Hero hero = solApplication.getGame().getHero(); + if (hero.isNonTranscendent()) { + return hero.getLife() / hero.getHull().config.getMaxLife(); + } else { + // The HUD is hidden when the hero is transcendent, so the value here doesn't matter. + return 1.0f; + } + } + }, new ReadOnlyBinding() { + @Override + public String get() { + Hero hero = solApplication.getGame().getHero(); + if (hero.isNonTranscendent()) { + return (int) Math.floor(Math.max(0, hero.getLife())) + "/" + hero.getHull().config.getMaxLife(); + } else { + // The HUD is hidden when the hero is transcendent, so the value here doesn't matter. + return ""; + } + } + }, new DefaultBinding<>(), Assets.getDSTexture(REPAIR_ITEM_TEXTURE_URN).getUiTexture(), new ReadOnlyBinding() { + @Override + public Float get() { + SolGame game = solApplication.getGame(); + Hero hero = game.getHero(); + return (float) hero.getItemContainer().count(game.getItemMan().getRepairExample()); + } + }); + statsBars.addWidget(hullStats); + + gun1Stats = createStatsRow("gun1", createGunIconBinding(false), createGunValueBinding(false), + createGunValueLabelBinding(false), createGunBarIconBinding(false), + null, createGunClipValueBinding(false)); + statsBars.addWidget(gun1Stats); + + gun2Stats = createStatsRow("gun2", createGunIconBinding(true), createGunValueBinding(true), + createGunValueLabelBinding(true), createGunBarIconBinding(true), + null, createGunClipValueBinding(true)); + statsBars.addWidget(gun2Stats); + + abilityStats = createStatsRow("ability", new ReadOnlyBinding() { + @Override + public UITextureRegion get() { + Hero hero = solApplication.getGame().getHero(); + SolItem example = hero.getAbility().getConfig().getChargeExample(); + if (example != null) { + return Assets.getDSTexture(example.getIcon(solApplication.getGame()).name).getUiTexture(); + } + return null; + } + }, new ReadOnlyBinding() { + @Override + public Float get() { + Hero hero = solApplication.getGame().getHero(); + if (hero.getAbilityAwait() > 0) { + return 1.0f - hero.getAbilityAwait() / hero.getAbility().getConfig().getRechargeTime(); + } else { + return 1.0f; + } + } + }, new DefaultBinding<>(""), new ReadOnlyBinding() { + @Override + public UITextureRegion get() { + SolGame game = solApplication.getGame(); + Hero hero = game.getHero(); + return hero.getAbilityAwait() > 0 ? Assets.getDSTexture(WAIT_TEXTURE_URN).getUiTexture() : null; + } + }, null, new ReadOnlyBinding() { + @Override + public Float get() { + SolGame game = solApplication.getGame(); + Hero hero = game.getHero(); + SolItem example = hero.getAbility().getConfig().getChargeExample(); + if (example != null) { + return (float) hero.getItemContainer().count(example); + } + return 0.0f; + } + }); + statsBars.addWidget(abilityStats); + + moneyIcon = new UILabelledIcon("moneyIcon"); + moneyIcon.setSpacing(8); + moneyIcon.bindText(new ReadOnlyBinding() { + @Override + public String get() { + Hero hero = solApplication.getGame().getHero(); + return Integer.toString(Math.round(hero.getMoney())); + } + }); + statsBars.addWidget(moneyIcon); + + statsBars.bindVisible(new ReadOnlyBinding() { + @Override + public Boolean get() { + return solApplication.getGame().getHero().isNonTranscendent(); + } + }); + + Color warnColour = new Color(1.0f, 0.5f, 0.0f, 0.5f); + Color dangerColour = new Color(1.0f, 0.0f, 0.0f, 0.5f); + + warnDrawers = find("warnDrawers", FlowLayout.class); + addWarnDrawer("sunWarnDrawer", warnColour, "Sun Near", new ReadOnlyBinding() { + @Override + public Boolean get() { + SolGame game = solApplication.getGame(); + Hero hero = game.getHero(); + if (hero.isTranscendent()) { + return false; + } + Vector2 position = hero.getPosition(); + float toCenter = game.getPlanetManager().getNearestSystem(position).getPosition().dst(position); + return toCenter < SolarSystemGenerator.SUN_RADIUS; + } + }); + addWarnDrawer("damagedWarnDrawer", dangerColour, "Heavily Damaged", new ReadOnlyBinding() { + @Override + public Boolean get() { + Hero hero = solApplication.getGame().getHero(); + if (hero.isTranscendent()) { + return false; + } + float currentLife = hero.getLife(); + + // already dead + if (currentLife <= 0.0) { + return false; + } + + int maxLife = hero.getHull().config.getMaxLife(); + return currentLife < maxLife * .3f; + } + }); + addWarnDrawer("collisionWarnDrawer", warnColour, "Object Near", new ReadOnlyBinding() { + @Override + public Boolean get() { + SolGame game = solApplication.getGame(); + Hero hero = game.getHero(); + if (hero.isTranscendent()) { + return false; + } + Vector2 position = hero.getPosition(); + Vector2 velocity = hero.getVelocity(); + float acc = hero.getAcceleration(); + float speed = velocity.len(); + float velocityAngle = SolMath.angle(velocity); + if (acc <= 0 || speed < 2 * acc) { + return false; + } + // time = velocity/acceleration; + // speed = acceleration*time*time/2 = velocity*velocity/acceleration/2; + float breakWay = speed * speed / acc / 2; + breakWay += 2 * speed; + Vector2 finalPos = SolMath.getVec(0, 0); + SolMath.fromAl(finalPos, velocityAngle, breakWay); + finalPos.add(position); + warnCallback.show = false; + game.getObjectManager().getWorld().rayCast(warnCallback, position, finalPos); + SolMath.free(finalPos); + return warnCallback.show; + } + }); + addWarnDrawer("noShieldDrawer", warnColour, "No Shield", new ReadOnlyBinding() { + @Override + public Boolean get() { + Hero hero = solApplication.getGame().getHero(); + return hero.isNonTranscendent() && hero.getShield() == null; + } + }); + addWarnDrawer("noArmourDrawer", warnColour, "No Armor", new ReadOnlyBinding() { + @Override + public Boolean get() { + Hero hero = solApplication.getGame().getHero(); + return hero.isNonTranscendent() && hero.getArmor() == null; + } + }); + addWarnDrawer("enemyWarnDrawer", warnColour, "Dangerous Enemy", new ReadOnlyBinding() { + @Override + public Boolean get() { + SolGame game = solApplication.getGame(); + Hero hero = game.getHero(); + if (hero.isTranscendent()) { + return false; + } + + float heroCap = HardnessCalc.getShipDmgCap(hero.getShip()); + List objs = game.getObjectManager().getObjects(); + FactionManager fm = game.getFactionMan(); + SolCam cam = game.getContext().get(SolCam.class); + float viewDist = cam.getViewDistance(); + float dps = 0; + + for (SolObject o : objs) { + if (!(o instanceof SolShip)) { + continue; + } + + SolShip ship = (SolShip) o; + + if (viewDist < ship.getPosition().dst(hero.getPosition())) { + continue; + } + + if (!fm.areEnemies(hero.getShip(), ship)) { + continue; + } + + dps += HardnessCalc.getShipDps(ship); + + if (HardnessCalc.isDangerous(heroCap, dps)) { + return true; + } + } + + return false; + } + }); + + borderDrawer = new BorderDrawer(); + zoneNameAnnouncer = new ZoneNameAnnouncer(); + } + + @Override + public void onAdded() { + moneyIcon.setIcon(Assets.getDSTexture(solApplication.getGame().getItemMan().moneyIcon.name).getUiTexture()); } @Override @@ -97,7 +434,7 @@ public void update(float delta) { ((AbstractWidget) contents).setVisible(false); } - if (solInputManager.getTopScreen() != gameScreens.mainGameScreen) { + if (solInputManager.getTopScreen() != gameScreens.oldMainGameScreen) { // User is in an original UI menu, so disable the escape key toggling the pause menu. menuButton.setKey(Keyboard.Key.NONE); } else { @@ -156,6 +493,56 @@ public void update(float delta) { if (consoleScreen.isConsoleJustClosed()) { game.setPaused(false); } + + shieldStats.setVisible(hero.getShield() != null); + gun1Stats.setVisible(hero.getHull().getGun(false) != null); + gun2Stats.setVisible(hero.getHull().getGun(true) != null); + + Gun gun1 = hero.getHull().getGun(false); + if (gun1 != null) { + UITextureRegion gun1ClipIcon; + if (gun1.config.clipConf.infinite) { + gun1ClipIcon = Assets.getDSTexture(INFINITY_TEXTURE_URN).getUiTexture(); + } else { + gun1ClipIcon = Assets.getDSTexture(gun1.config.clipConf.icon.name).getUiTexture(); + } + // HACK: You can't bind to the icons of a UIIconBar, so we set them during an update instead. + gun1Stats.findAll(UIIconBar.class).iterator().next().setIcon(gun1ClipIcon); + } + + Gun gun2 = hero.getHull().getGun(true); + if (gun2 != null) { + UITextureRegion gun2ClipIcon; + if (gun2.config.clipConf.infinite) { + gun2ClipIcon = Assets.getDSTexture(INFINITY_TEXTURE_URN).getUiTexture(); + } else { + gun2ClipIcon = Assets.getDSTexture(gun2.config.clipConf.icon.name).getUiTexture(); + } + // HACK: You can't bind to the icons of a UIIconBar, so we set them during an update instead. + gun2Stats.findAll(UIIconBar.class).iterator().next().setIcon(gun2ClipIcon); + } + + SolItem example = hero.getAbility().getConfig().getChargeExample(); + if (example != null) { + UITextureRegion abilityIcon = Assets.getDSTexture(example.getIcon(solApplication.getGame()).name).getUiTexture(); + abilityStats.findAll(UIIconBar.class).iterator().next().setIcon(abilityIcon); + } + + zoneNameAnnouncer.update(solApplication.getGame(), solApplication.getGame().getContext()); + } + + @Override + public void onDraw(Canvas canvas) { + super.onDraw(canvas); + + // Don't render the borders on-top of the map screen. + if (!solApplication.getInputManager().isScreenOn(solApplication.getGame().getScreens().mapScreen)) { + try (NUIManager.LegacyUiDrawerWrapper wrapper = nuiManager.getLegacyUiDrawer()) { + borderDrawer.draw(wrapper.getUiDrawer(), solApplication, solApplication.getGame().getContext()); + zoneNameAnnouncer.drawText(wrapper.getUiDrawer()); + drawHeightCompass(wrapper); + } + } } @Override @@ -185,9 +572,32 @@ public boolean onKeyEvent(NUIKeyEvent event) { return true; } + GameOptions gameOptions = solApplication.getOptions(); + // TODO: How to handle free camera movement on Android? (note: this has never been supported) + if (event.getKey() == GDXInputUtil.GDXToNuiKey(gameOptions.getKeyFreeCameraMovement())) { + SolCam.DIRECT_CAM_CONTROL = event.isDown(); + } + + SolGame solGame = solApplication.getGame(); + if (event.getState() == ButtonState.UP && event.getKey() == GDXInputUtil.GDXToNuiKey(gameOptions.getKeyPause())) { + solGame.setPaused(!solGame.isPaused()); + } + return super.onKeyEvent(event); } + @Override + public void onMouseButtonEvent(NUIMouseButtonEvent event) { + if (event.getState() == ButtonState.UP) { + NUIScreenLayer topScreen = nuiManager.getTopScreen(); + if (!solApplication.getInputManager().isMouseOnUi() && + topScreen != MainGameScreen.this && !(topScreen instanceof UIShipControlsScreen)) { + nuiManager.popScreen(); + event.consume(); + } + } + } + @Override public void onRemoved() { menuButton.unsubscribe(this::onMenuButtonClicked); @@ -237,6 +647,259 @@ public UIWarnButton getMercsButton() { return mercsButton; } + /** + * Creates and adds a new warn drawer with the specified properties and activation condition. + * @param id the id used for the drawer widget + * @param tint the tint used for the warning background + * @param text the text to be shown in the warning + * @param warnBinding the condition for the warning to be shown + * @return the {@link UIWarnDrawer} created + */ + public UIWarnDrawer addWarnDrawer(String id, Color tint, String text, Binding warnBinding) { + UIWarnDrawer warnDrawer = new UIWarnDrawer(id, whiteTexture, tint, new UILabel(text)); + warnDrawer.bindWarn(warnBinding); + warnDrawers.addWidget(new EmptyIfInvisibleContainer(warnDrawer), new RelativeLayoutHint()); + return warnDrawer; + } + + /** + * Adds the provided warn drawer to be displayed when the condition {@link UIWarnDrawer#isWarning()} is true. + * @param warnDrawer the warn-drawer instance to use + * @return the warn-drawer instance used. + */ + public UIWarnDrawer addWarnDrawer(UIWarnDrawer warnDrawer) { + warnDrawers.addWidget(new EmptyIfInvisibleContainer(warnDrawer), new RelativeLayoutHint()); + return warnDrawer; + } + + /** + * Returns true if a warn-drawer with the specified id already exists, otherwise false. + * @param id the id to search for + * @return true, if the drawer exists, otherwise false. + */ + public boolean hasWarnDrawer(String id) { + return warnDrawers.find(id, UIWarnDrawer.class) != null; + } + + /** + * Returns true if the specified warn-drawer already exists, otherwise false. + * @param warnDrawerToFind the drawer to search for + * @return true, if the drawer exists, otherwise false. + */ + public boolean hasWarnDrawer(UIWarnDrawer warnDrawerToFind) { + for (UIWidget warnDrawerContainer : warnDrawers) { + if (warnDrawerContainer instanceof EmptyIfInvisibleContainer) { + EmptyIfInvisibleContainer container = (EmptyIfInvisibleContainer) warnDrawerContainer; + if (container.iterator().hasNext() && container.iterator().next() == warnDrawerToFind) { + return true; + } + } + } + + return false; + } + + /** + * Removes the warn-drawer with the specified id from use. + * @param id the id of the warn-drawer to remove + */ + public void removeWarnDrawer(String id) { + UIWarnDrawer warnDrawer = warnDrawers.find(id, UIWarnDrawer.class); + if (warnDrawer != null) { + warnDrawers.removeWidget(warnDrawer); + } + } + + /** + * Removes the specified warn drawer from use. + * @param warnDrawer the warn-drawer instance to remove + */ + public void removeWarnDrawer(UIWarnDrawer warnDrawer) { + warnDrawers.removeWidget(warnDrawer); + } + + private void drawHeightCompass(NUIManager.LegacyUiDrawerWrapper drawerWrapper) { + SolGame game = solApplication.getGame(); + Planet np = game.getPlanetManager().getNearestPlanet(); + SolCam cam = solApplication.getGame().getCam(); + Vector2 camPos = cam.getPosition(); + if (np != null && np.getPosition().dst(camPos) < np.getFullHeight()) { + UiDrawer drawer = drawerWrapper.getUiDrawer(); + + float toPlanet = camPos.dst(np.getPosition()); + toPlanet -= np.getGroundHeight(); + if (Const.ATM_HEIGHT < toPlanet) { + return; + } + + float perc = toPlanet / Const.ATM_HEIGHT; + float sz = .08f; + float maxY = 1 - sz / 2; + float y = 1 - perc; + compassTint.a = SolMath.clamp(1.5f * y); + if (maxY < y) { + y = maxY; + } + float angle = np.getAngle() - cam.getAngle(); + drawer.draw(compassTexture, sz, sz, sz / 2, sz / 2, sz / 2, y, angle, compassTint); + } + } + + private AbstractWidget createStatsRow(String name, Binding statIcon, Binding statBinding, + Binding statBarTextBinding, Binding statBarIconBinding, + UITextureRegion refillIcon, Binding refillBinding) { + String iconId = name + "Icon"; + String statsBarTextId = name + "statsBarText"; + String refillExtraTextId = name + "refillExtraText"; + VerticalHint iconHeightHint = new VerticalHint() + .alignTopRelativeTo(iconId, VerticalAlign.TOP) + .alignBottomRelativeTo(iconId, VerticalAlign.BOTTOM); + + RelativeLayout relativeLayout = new RelativeLayout(); + UIImage icon = new UIImage(iconId, null); + icon.bindTexture(statIcon); + relativeLayout.addWidget(icon, new RelativeLayoutHint( + new HorizontalHint().alignLeft(), + new VerticalHint() + ).setUsingContentWidth(true).setUsingContentHeight(true)); + UILoadBar statsBar = new UILoadBar(); + statsBar.setAnimate(false); + statsBar.setFillTexture(Assets.getDSTexture("engine:buttonDown").getUiTexture()); + statsBar.bindValue(statBinding); + relativeLayout.addWidget(statsBar, new RelativeLayoutHint( + new HorizontalHint().alignLeftRelativeTo(iconId, HorizontalAlign.RIGHT, 8).alignRight(134), + iconHeightHint + )); + UILabelledIcon statsValueText = new UILabelledIcon(statsBarTextId, ""); + statsValueText.setFamily("centerAlignedLabel"); + statsValueText.setSpacing(0); + statsValueText.setIconAlign(HorizontalAlign.CENTER); + statsValueText.bindText(statBarTextBinding); + statsValueText.bindIcon(statBarIconBinding); + relativeLayout.addWidget(statsValueText, new RelativeLayoutHint( + new HorizontalHint().alignLeftRelativeTo(iconId, HorizontalAlign.RIGHT, 8).alignRight(134), + iconHeightHint + )); + + UIIconBar refillIconsBar = new UIIconBar(); + refillIconsBar.setMaxIcons(3); + refillIconsBar.setMaxValue(3); + refillIconsBar.setHalfIconMode(UIIconBar.HalfIconMode.NONE); + // NOTE: UIIconBar doesn't support icon bindings. + refillIconsBar.setIcon(refillIcon); + refillIconsBar.bindValue(refillBinding); + relativeLayout.addWidget(refillIconsBar, new RelativeLayoutHint( + new HorizontalHint() + .alignLeftRelativeTo(statsBarTextId, HorizontalAlign.RIGHT, 8) + .alignRightRelativeTo(refillExtraTextId, HorizontalAlign.LEFT), + iconHeightHint + )); + + UILabelledIcon refillExtrasText = new UILabelledIcon(refillExtraTextId, " "); + refillExtrasText.setFamily("topLeftAlignedLabel"); + refillExtrasText.setSpacing(0); + refillExtrasText.bindText(new ReadOnlyBinding() { + @Override + public String get() { + float value = refillBinding.get(); + if (value <= 3) { + return " "; + } + return "+" + String.format(Locale.ENGLISH, "%-2d", ((int)value - 3)); + } + }); + relativeLayout.addWidget(refillExtrasText, new RelativeLayoutHint( + new HorizontalHint().alignRight(), + iconHeightHint + ).setUsingContentWidth(true)); + + return new EmptyIfInvisibleContainer(relativeLayout); + } + + private ReadOnlyBinding createGunIconBinding(boolean isSecondary) { + return new ReadOnlyBinding() { + @Override + public UITextureRegion get() { + Hero hero = solApplication.getGame().getHero(); + Gun gun = hero.getHull().getGun(isSecondary); + if (gun != null) { + return Assets.getDSTexture(gun.getIcon(solApplication.getGame()).name).getUiTexture(); + } + return null; + } + }; + } + + private ReadOnlyBinding createGunClipValueBinding(boolean isSecondary) { + return new ReadOnlyBinding() { + @Override + public Float get() { + SolGame game = solApplication.getGame(); + Hero hero = game.getHero(); + Gun gun = hero.getHull().getGun(isSecondary); + if (gun == null) { + return 0.0f; + } + if (gun.config.clipConf.infinite) { + return 1.0f; + } + return (float) hero.getItemContainer().count(gun.config.clipConf.example); + } + }; + } + + private ReadOnlyBinding createGunValueBinding(boolean isSecondary) { + return new ReadOnlyBinding() { + @Override + public Float get() { + Hero hero = solApplication.getGame().getHero(); + Gun gun = hero.getHull().getGun(isSecondary); + if (gun == null) { + return 0.0f; + } + if (gun.reloadAwait > 0) { + return 1.0f - (gun.reloadAwait / gun.config.reloadTime); + } else { + return (float)gun.ammo / gun.config.clipConf.size; + } + } + }; + } + + private ReadOnlyBinding createGunValueLabelBinding(boolean isSecondary) { + return new ReadOnlyBinding() { + @Override + public String get() { + SolGame game = solApplication.getGame(); + Hero hero = game.getHero(); + Gun gun = hero.getHull().getGun(isSecondary); + if (gun == null) { + return ""; + } + if (gun.reloadAwait > 0) { + return ""; + } else { + return gun.ammo + "/" + gun.config.clipConf.size; + } + } + }; + } + + private ReadOnlyBinding createGunBarIconBinding(boolean isSecondary) { + return new ReadOnlyBinding() { + @Override + public UITextureRegion get() { + SolGame game = solApplication.getGame(); + Hero hero = game.getHero(); + Gun gun = hero.getHull().getGun(isSecondary); + if (gun == null) { + return null; + } + return gun.reloadAwait > 0 ? Assets.getDSTexture("engine:iconWait").getUiTexture() : null; + } + }; + } + private void onMenuButtonClicked(UIWidget widget) { SolInputManager solInputManager = solApplication.getInputManager(); GameScreens gameScreens = solApplication.getGame().getScreens(); @@ -261,7 +924,7 @@ private void onItemsButtonClicked(UIWidget widget) { SolInputManager solInputManager = solApplication.getInputManager(); GameScreens gameScreens = game.getScreens(); - solInputManager.setScreen(solApplication, gameScreens.mainGameScreen); + solInputManager.setScreen(solApplication, gameScreens.oldMainGameScreen); if (!solInputManager.isScreenOn(gameScreens.inventoryScreen)) { gameScreens.inventoryScreen.showInventory.setTarget(hero.getShip()); gameScreens.inventoryScreen.setOperations(gameScreens.inventoryScreen.showInventory); @@ -278,7 +941,7 @@ private void onTalkButtonClicked(UIWidget widget) { SolInputManager solInputManager = solApplication.getInputManager(); GameScreens gameScreens = game.getScreens(); - solInputManager.setScreen(solApplication, gameScreens.mainGameScreen); + solInputManager.setScreen(solApplication, gameScreens.oldMainGameScreen); if (!solInputManager.isScreenOn(gameScreens.talkScreen)) { gameScreens.talkScreen.setTarget(talkTarget); solInputManager.addScreen(solApplication, gameScreens.talkScreen); @@ -295,11 +958,29 @@ private void onMercsButtonClicked(UIWidget widget) { SolInputManager solInputManager = solApplication.getInputManager(); GameScreens gameScreens = game.getScreens(); - solInputManager.setScreen(solApplication, gameScreens.mainGameScreen); + solInputManager.setScreen(solApplication, gameScreens.oldMainGameScreen); if (!solInputManager.isScreenOn(gameScreens.inventoryScreen)) { gameScreens.inventoryScreen.setOperations(gameScreens.inventoryScreen.chooseMercenaryScreen); solInputManager.addScreen(solApplication, gameScreens.inventoryScreen); hero.getMercs().markAllAsSeen(); } } + + private final class CollisionWarnDrawerRayCastCallback implements RayCastCallback { + private boolean show; + + //TODO code from era when hero was SolShip - does this still work? (what is it supposed to do?) + // TODO: Moved from the original MainGameScreen - still don't know what this does. + @Override + public float reportRayFixture(Fixture fixture, Vector2 point, Vector2 normal, float fraction) { + if (fixture.getBody().getUserData() instanceof SolObject) { + SolObject o = (SolObject) fixture.getBody().getUserData(); + if (solApplication.getGame().getHero().getShip() == o) { + return -1; + } + show = true; + } + return 0; + } + } } diff --git a/engine/src/main/java/org/destinationsol/ui/nui/screens/UIShipControlsScreen.java b/engine/src/main/java/org/destinationsol/ui/nui/screens/UIShipControlsScreen.java index 2d8c13bf0..e3f0641e4 100644 --- a/engine/src/main/java/org/destinationsol/ui/nui/screens/UIShipControlsScreen.java +++ b/engine/src/main/java/org/destinationsol/ui/nui/screens/UIShipControlsScreen.java @@ -96,7 +96,7 @@ public void initialise() { @Override public void update(float delta) { // Hide and disable controls if the main game screen is not visible. - boolean mainGameScreenVisible = solApplication.getInputManager().isScreenOn(solApplication.getGame().getScreens().mainGameScreen); + boolean mainGameScreenVisible = solApplication.getInputManager().isScreenOn(solApplication.getGame().getScreens().oldMainGameScreen); ((AbstractWidget)contents).setVisible(mainGameScreenVisible); contents.setEnabled(mainGameScreenVisible); diff --git a/engine/src/main/java/org/destinationsol/ui/nui/widgets/UIWarnDrawer.java b/engine/src/main/java/org/destinationsol/ui/nui/widgets/UIWarnDrawer.java new file mode 100644 index 000000000..37f33f642 --- /dev/null +++ b/engine/src/main/java/org/destinationsol/ui/nui/widgets/UIWarnDrawer.java @@ -0,0 +1,160 @@ +/* + * 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.destinationsol.Const; +import org.destinationsol.common.SolMath; +import org.terasology.nui.Canvas; +import org.terasology.nui.Color; +import org.terasology.nui.LayoutConfig; +import org.terasology.nui.UITextureRegion; +import org.terasology.nui.UIWidget; +import org.terasology.nui.databinding.Binding; +import org.terasology.nui.databinding.DefaultBinding; +import org.terasology.nui.widgets.UISpace; + +/** + * An informational box that appears in the screen to alert the user to a particular circumstance that has occurred. + * The background, background tint, box content and trigger conditions are all configurable. + */ +public class UIWarnDrawer extends EmptyIfInvisibleContainer { + private static final float FADE_TIME = 1f; + @LayoutConfig + private UITextureRegion background; + @LayoutConfig + private Color tint; + private float alpha; + private Binding shouldWarn = new DefaultBinding<>(false); + + public UIWarnDrawer(String id, UITextureRegion background, Color tint) { + super(id, new UISpace()); + this.background = background; + this.tint = tint; + this.alpha = 0.0f; + } + + public UIWarnDrawer(String id, UITextureRegion background, Color tint, UIWidget content) { + super(id, content); + this.background = background; + this.tint = tint; + this.alpha = 0.0f; + } + + @Override + public void onDraw(Canvas canvas) { + canvas.setAlpha(alpha); + canvas.drawTexture(background, tint); + super.onDraw(canvas); + } + + @Override + public void update(float delta) { + if (isWarning()) { + alpha = 1; + } else { + alpha = SolMath.approach(alpha, 0, Const.REAL_TIME_STEP / FADE_TIME); + } + + super.update(delta); + } + + /** + * Returns the current background tint. + * @return the current background tint. + */ + public Color getTint() { + return tint; + } + + /** + * Sets the new background tint. + * @param tint the new background tint. + */ + public void setTint(Color tint) { + this.tint = tint; + } + + /** + * Returns the current background texture. + * @return the current background texture. + */ + public UITextureRegion getBackground() { + return background; + } + + /** + * Sets the new background texture. + * @param background the new background texture. + */ + public void setBackground(UITextureRegion background) { + this.background = background; + } + + /** + * Returns the current transparency of the widget. This is additive relative to the canvas. + * @return the current widget transparency. + */ + public float getAlpha() { + return alpha; + } + + /** + * Sets the new widget transparency, relative to the canvas. + * The assigned value may be overridden if the widget is currently warning. + * @param alpha the new widget transparency. + */ + public void setAlpha(float alpha) { + this.alpha = alpha; + } + + /** + * Returns if the widget is currently warning (full opacity). + * @return true, if the widget is currently warning, otherwise false. + */ + public boolean isWarning() { + return shouldWarn.get(); + } + + /** + * Sets whether the widget should currently be warning. + * @param shouldWarn true, if the widget should currently be warning, otherwise false. + */ + public void setWarn(boolean shouldWarn) { + this.shouldWarn.set(shouldWarn); + } + + /** + * Assigns a binding to the widget's warning value to determine when it should warn. + * @param shouldWarn the new warning binding. + */ + public void bindWarn(Binding shouldWarn) { + this.shouldWarn = shouldWarn; + } + + /** + * Returns if the widget is visible. + * NOTE: This overridden version also returns true if the widget alpha is zero or less. + */ + @Override + public boolean isVisible() { + if (!super.isVisible()) { + return false; + } + + return alpha > 0.0f; + } +} 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..165cf09c4 100644 --- a/engine/src/main/resources/org/destinationsol/assets/skins/mainGameScreen.skin +++ b/engine/src/main/resources/org/destinationsol/assets/skins/mainGameScreen.skin @@ -10,8 +10,30 @@ }, "font": "engine:main#1" }, + "statsBars": { + "elements": { + "RelativeLayout": { + "fixed-height": 32 + }, + "UILabelledIcon": { + "fixed-height": 32, + "text-align-horizontal": "left", + "text-align-vertical": "center", + "font": "engine:main#0.75" + } + } + }, "controlsUIButton": { "font": "engine:main#0.95" + }, + "warnDrawers": { + "elements": { + "UIWarnDrawer": { + "min-width": 160, + "min-height": 96 + } + }, + "font": "engine:main#0.8" } } } diff --git a/engine/src/main/resources/org/destinationsol/assets/ui/mainGameScreen_desktop.ui b/engine/src/main/resources/org/destinationsol/assets/ui/mainGameScreen_desktop.ui index 7e11eb81c..05a2030f4 100644 --- a/engine/src/main/resources/org/destinationsol/assets/ui/mainGameScreen_desktop.ui +++ b/engine/src/main/resources/org/destinationsol/assets/ui/mainGameScreen_desktop.ui @@ -4,6 +4,49 @@ "contents": { "type": "relativeLayout", "contents": [ + { + "type": "ColumnLayout", + "id": "statsBars", + "family": "statsBars", + "layoutInfo": { + "position-left": { + "offset": 16 + }, + "position-top": { + "offset": 16 + }, + "width": 288 + }, + "verticalSpacing": 8, + "fillVerticalSpace": false, + "contents": [ + ] + }, + { + "type": "FlowLayout", + "id": "warnDrawers", + "family": "warnDrawers", + "horizontalSpacing": 8, + "verticalSpacing": 8, + "contents": [ + ], + "layoutInfo": { + "position-left": { + "widget": "statsBars", + "target": "RIGHT" + }, + "position-right": { + "widget": "menuList", + "target": "LEFT" + }, + "position-top": { + "offset": 16 + }, + "position-bottom": { + "target": "MIDDLE" + } + } + }, { "type": "ColumnLayout", "id": "menuList", @@ -20,9 +63,9 @@ "family": "sideUIButton", "contents": [ { - "type": "UIWarnButton", - "text": "Menu", - "id": "menuButton" + "type": "UIWarnButton", + "text": "Menu", + "id": "menuButton" }, { "type": "UIWarnButton", diff --git a/engine/src/main/resources/org/destinationsol/assets/ui/mainGameScreen_mobile.ui b/engine/src/main/resources/org/destinationsol/assets/ui/mainGameScreen_mobile.ui index 11ff594fc..885c0392b 100644 --- a/engine/src/main/resources/org/destinationsol/assets/ui/mainGameScreen_mobile.ui +++ b/engine/src/main/resources/org/destinationsol/assets/ui/mainGameScreen_mobile.ui @@ -4,6 +4,50 @@ "contents": { "type": "relativeLayout", "contents": [ + { + "type": "ColumnLayout", + "id": "statsBars", + "family": "statsBars", + "layoutInfo": { + "position-left": { + "offset": 16 + }, + "position-right": { + "target": "CENTER" + }, + "position-top": { + "offset": 16 + } + }, + "column-widths": [0.6], + "verticalSpacing": 8, + "fillVerticalSpace": false, + "contents": [ + ] + }, + { + "type": "FlowLayout", + "id": "warnDrawers", + "family": "warnDrawers", + "horizontalSpacing": 8, + "verticalSpacing": 8, + "contents": [ + ], + "layoutInfo": { + "position-left": { + "widget": "statsBars", + "target": "RIGHT" + }, + "position-right": { + "widget": "rightMenuList", + "target": "LEFT" + }, + "position-top": {}, + "position-bottom": { + "target": "MIDDLE" + } + } + }, { "type": "ColumnLayout", "id": "leftMenuList", @@ -11,7 +55,7 @@ "use-content-width": true, "use-content-height": true, "position-vertical-center": { - "offset": -100 + "offset": 16 }, "position-left": {} }, @@ -20,9 +64,9 @@ "family": "sideUIButton", "contents": [ { - "type": "UIWarnButton", - "text": "Menu", - "id": "menuButton" + "type": "UIWarnButton", + "text": "Menu", + "id": "menuButton" }, { "type": "UIWarnButton", @@ -37,8 +81,9 @@ "layoutInfo": { "use-content-width": true, "use-content-height": true, - "position-vertical-center": { - "offset": -100 + "position-bottom": { + "widget": "leftMenuList", + "target": "BOTTOM" }, "position-right": {} }, From f7e1feb48104c7259e53ee325c650c1b37acad54 Mon Sep 17 00:00:00 2001 From: Benjamin Amos Date: Sun, 18 Sep 2022 15:46:14 +0100 Subject: [PATCH 2/3] fix(ability): fix null item ability charge examples --- .../java/org/destinationsol/game/item/ItemManager.java | 8 ++++++++ .../org/destinationsol/game/screens/MainGameScreen.java | 2 +- .../main/java/org/destinationsol/game/ship/EmWave.java | 2 +- .../main/java/org/destinationsol/game/ship/KnockBack.java | 2 +- .../src/main/java/org/destinationsol/game/ship/SloMo.java | 2 +- .../main/java/org/destinationsol/game/ship/Teleport.java | 2 +- .../main/java/org/destinationsol/game/ship/UnShield.java | 2 +- .../org/destinationsol/assets/skins/mainGameScreen.skin | 4 ++++ 8 files changed, 18 insertions(+), 6 deletions(-) diff --git a/engine/src/main/java/org/destinationsol/game/item/ItemManager.java b/engine/src/main/java/org/destinationsol/game/item/ItemManager.java index caf4ff912..1b9787d9f 100644 --- a/engine/src/main/java/org/destinationsol/game/item/ItemManager.java +++ b/engine/src/main/java/org/destinationsol/game/item/ItemManager.java @@ -78,6 +78,14 @@ public void fillContainer(ItemContainer itemContainer, String items) { } } + public ItemConfig parseItem(String item) { + List items = parseItems(item); + if (items.isEmpty()) { + return null; + } + return items.get(0); + } + public List parseItems(String items) { ArrayList result = new ArrayList<>(); 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 453da82e3..d8b861745 100644 --- a/engine/src/main/java/org/destinationsol/game/screens/MainGameScreen.java +++ b/engine/src/main/java/org/destinationsol/game/screens/MainGameScreen.java @@ -117,7 +117,7 @@ public void updateCustom(SolApplication solApplication, SolInputManager.InputPoi NUIScreenLayer topScreen = nuiManager.getTopScreen(); boolean controlsEnabled = inputMan.getTopScreen() == this && (topScreen instanceof org.destinationsol.ui.nui.screens.MainGameScreen || - inputMan.getTopScreen() instanceof UIShipControlsScreen); + topScreen instanceof UIShipControlsScreen); shipControl.update(solApplication, controlsEnabled); if (solApplication.getNuiManager().hasScreenOfType(ConsoleScreen.class)) { diff --git a/engine/src/main/java/org/destinationsol/game/ship/EmWave.java b/engine/src/main/java/org/destinationsol/game/ship/EmWave.java index 3ae4a960f..bda72d27f 100644 --- a/engine/src/main/java/org/destinationsol/game/ship/EmWave.java +++ b/engine/src/main/java/org/destinationsol/game/ship/EmWave.java @@ -93,7 +93,7 @@ public EmWaveConfig(float rechargeTime, SolItem chargeExample, float duration, A public static AbilityConfig load(JSONObject abNode, ItemManager itemManager, AbilityCommonConfig cc) { float rechargeTime = (float) abNode.getDouble("rechargeTime"); float duration = (float) abNode.getDouble("duration"); - SolItem chargeExample = itemManager.getExample("emWaveCharge"); + SolItem chargeExample = itemManager.parseItem("core:emWaveCharge").examples.get(0); return new EmWaveConfig(rechargeTime, chargeExample, duration, cc); } diff --git a/engine/src/main/java/org/destinationsol/game/ship/KnockBack.java b/engine/src/main/java/org/destinationsol/game/ship/KnockBack.java index 9e692bbe8..410604ea1 100644 --- a/engine/src/main/java/org/destinationsol/game/ship/KnockBack.java +++ b/engine/src/main/java/org/destinationsol/game/ship/KnockBack.java @@ -107,7 +107,7 @@ public KnockBackConfig(float rechargeTime, SolItem chargeExample, float force, A public static AbilityConfig load(JSONObject abNode, ItemManager itemManager, AbilityCommonConfig cc) { float rechargeTime = (float) abNode.getDouble("rechargeTime"); float force = (float) abNode.getDouble("force"); - SolItem chargeExample = itemManager.getExample("knockBackCharge"); + SolItem chargeExample = itemManager.parseItem("core:knockBackCharge").examples.get(0); return new KnockBackConfig(rechargeTime, chargeExample, force, cc); } diff --git a/engine/src/main/java/org/destinationsol/game/ship/SloMo.java b/engine/src/main/java/org/destinationsol/game/ship/SloMo.java index 64b9b539a..e5ab7b096 100644 --- a/engine/src/main/java/org/destinationsol/game/ship/SloMo.java +++ b/engine/src/main/java/org/destinationsol/game/ship/SloMo.java @@ -86,7 +86,7 @@ public SloMoConfig(float factor, float rechargeTime, SolItem chargeExample, Abil public static AbilityConfig load(JSONObject abNode, ItemManager itemManager, AbilityCommonConfig cc) { float factor = (float) abNode.getDouble("factor"); float rechargeTime = (float) abNode.getDouble("rechargeTime"); - SolItem chargeExample = itemManager.getExample("sloMoCharge"); + SolItem chargeExample = itemManager.parseItem("core:sloMoCharge").examples.get(0); return new SloMoConfig(factor, rechargeTime, chargeExample, cc); } diff --git a/engine/src/main/java/org/destinationsol/game/ship/Teleport.java b/engine/src/main/java/org/destinationsol/game/ship/Teleport.java index 28da06254..66e972746 100644 --- a/engine/src/main/java/org/destinationsol/game/ship/Teleport.java +++ b/engine/src/main/java/org/destinationsol/game/ship/Teleport.java @@ -126,7 +126,7 @@ public TeleportConfig(float angle, SolItem chargeExample, float rechargeTime, Ab public static AbilityConfig load(JSONObject abNode, ItemManager itemManager, AbilityCommonConfig cc) { float angle = (float) abNode.getDouble("angle"); - SolItem chargeExample = itemManager.getExample("teleportCharge"); + SolItem chargeExample = itemManager.parseItem("core:teleportCharge").examples.get(0); float rechargeTime = (float) abNode.getDouble("rechargeTime"); return new TeleportConfig(angle, chargeExample, rechargeTime, cc); } diff --git a/engine/src/main/java/org/destinationsol/game/ship/UnShield.java b/engine/src/main/java/org/destinationsol/game/ship/UnShield.java index a70cecf66..798ec55a8 100644 --- a/engine/src/main/java/org/destinationsol/game/ship/UnShield.java +++ b/engine/src/main/java/org/destinationsol/game/ship/UnShield.java @@ -107,7 +107,7 @@ public UnShieldConfig(float rechargeTime, SolItem chargeExample, float amount, A public static AbilityConfig load(JSONObject abNode, ItemManager itemManager, AbilityCommonConfig cc) { float rechargeTime = (float) abNode.getDouble("rechargeTime"); float amount = (float) abNode.getDouble("amount"); - SolItem chargeExample = itemManager.getExample("unShieldCharge"); + SolItem chargeExample = itemManager.parseItem("core:unShieldCharge").examples.get(0); return new UnShieldConfig(rechargeTime, chargeExample, amount, cc); } 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 165cf09c4..2be7a828b 100644 --- a/engine/src/main/resources/org/destinationsol/assets/skins/mainGameScreen.skin +++ b/engine/src/main/resources/org/destinationsol/assets/skins/mainGameScreen.skin @@ -31,6 +31,10 @@ "UIWarnDrawer": { "min-width": 160, "min-height": 96 + }, + "UILabel": { + "text-align-horizontal": "center", + "text-align-vertical": "middle" } }, "font": "engine:main#0.8" From 72814181633ebe844669f85fb483bf8da932f5b5 Mon Sep 17 00:00:00 2001 From: Benjamin Amos Date: Wed, 19 Oct 2022 20:50:45 +0100 Subject: [PATCH 3/3] fix(nui): remove excess spacing in MainGameScreen HUD --- .../org/destinationsol/assets/skins/mainGameScreen.skin | 2 +- .../org/destinationsol/assets/ui/mainGameScreen_desktop.ui | 2 +- .../org/destinationsol/assets/ui/mainGameScreen_mobile.ui | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) 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 2be7a828b..5035d8223 100644 --- a/engine/src/main/resources/org/destinationsol/assets/skins/mainGameScreen.skin +++ b/engine/src/main/resources/org/destinationsol/assets/skins/mainGameScreen.skin @@ -13,7 +13,7 @@ "statsBars": { "elements": { "RelativeLayout": { - "fixed-height": 32 + "fixed-height": 36 }, "UILabelledIcon": { "fixed-height": 32, diff --git a/engine/src/main/resources/org/destinationsol/assets/ui/mainGameScreen_desktop.ui b/engine/src/main/resources/org/destinationsol/assets/ui/mainGameScreen_desktop.ui index 05a2030f4..6ef46d1d9 100644 --- a/engine/src/main/resources/org/destinationsol/assets/ui/mainGameScreen_desktop.ui +++ b/engine/src/main/resources/org/destinationsol/assets/ui/mainGameScreen_desktop.ui @@ -17,7 +17,7 @@ }, "width": 288 }, - "verticalSpacing": 8, + "verticalSpacing": 0, "fillVerticalSpace": false, "contents": [ ] diff --git a/engine/src/main/resources/org/destinationsol/assets/ui/mainGameScreen_mobile.ui b/engine/src/main/resources/org/destinationsol/assets/ui/mainGameScreen_mobile.ui index 885c0392b..62fd5900b 100644 --- a/engine/src/main/resources/org/destinationsol/assets/ui/mainGameScreen_mobile.ui +++ b/engine/src/main/resources/org/destinationsol/assets/ui/mainGameScreen_mobile.ui @@ -20,7 +20,7 @@ } }, "column-widths": [0.6], - "verticalSpacing": 8, + "verticalSpacing": 0, "fillVerticalSpace": false, "contents": [ ]