From f06946c01b2c8f210b398a16610c260eca093a8b Mon Sep 17 00:00:00 2001 From: Wyvest <45589059+Wyvest@users.noreply.github.com> Date: Thu, 21 Jul 2022 04:04:48 +0900 Subject: HUD Improvements, 1.16 port, fix NanoVG with ARM (#52) * egg 1 * separate Hud from background stuff * 1984 This reverts commit 9ae517d57bbd495d30d35cb1cbfe81a03556e6bd. * hitboxes woo!!!!! * Revert "hitboxes woo!!!!!" This reverts commit 405d32d17df3c83f2e79eddf0de853f7279767a6. * padding * allow position to go slightly off the screen * stop using ints for ABSOLUTELY EVERYTHING, DIAMOND ... fix vigilance compat not setting color * start on new pos system * some stuff * finish new position system * api momento * 1.16.2 fabric port * start on hud gui * temp remove 1.16.2 fabric since it doesn't compile * fix fabric build * hud gui stuff * apiDump * fix fabric build 2 * so true * selecting stuff * scaling + other small things * More protecting * fix nanovg not working with macOS ARM move OneConfig.preLaunch to OneConfigInit * clean up OneUIScreen make kotlin version of TestNanoVGGui * make keybinds have runnable by default * rollback keybind things * merge master into hud-improvements (#55) * Release workflow (#53) * release workflow * update normal version to hash * fix * fix naming * fix some stuff * fix version thing * switch to number from hash * Release workflow (#54) * release workflow * update normal version to hash * fix * fix naming * fix some stuff * fix version thing * switch to number from hash * Maybe epic fixo * gotta love those Java principles * Revert "gotta love those Java principles", wrong branch This reverts commit 333d8b2ad8941790c13c4bfe0777fbd203d463e5. * start on snapping * Finish snapping * stop including mixin by default on legacy versions this breaks builds if the mod itself does not use mixin * merge draw and drawExample * fix gradle publish * Some fixes * Api DUmpidy * Help subcommand impovments (#59) * Made the overall look of the "help" subcommand better + added the ability to change the colour for the command overall + each individual SubCommand * Made the alliases show batter + added support for to show subcommand aliasses * mr deliverer didnt reply but whatever, added a space between command/subcommand and alliasses Co-authored-by: pinkulu * fix file not overwriting toJavaColor * Fix full shadow not scaling correctly Co-authored-by: DeDiamondPro <67508414+DeDiamondPro@users.noreply.github.com> Co-authored-by: nxtdaydelivery <12willettsh@gmail.com> Co-authored-by: pinkulu <56201697+pinkulu@users.noreply.github.com> Co-authored-by: pinkulu --- .../java/cc/polyfrost/oneconfig/config/Config.java | 5 +- .../oneconfig/config/core/OneKeyBind.java | 1 - .../java/cc/polyfrost/oneconfig/gui/GuiPause.java | 1 + .../java/cc/polyfrost/oneconfig/gui/HudGui.java | 292 --------------------- .../cc/polyfrost/oneconfig/gui/OneConfigGui.java | 14 +- .../java/cc/polyfrost/oneconfig/gui/SideBar.java | 3 +- .../oneconfig/gui/elements/BasicButton.java | 6 +- .../oneconfig/gui/elements/BasicElement.java | 6 +- .../oneconfig/gui/elements/ColorSelector.java | 46 ++-- .../polyfrost/oneconfig/gui/elements/ModCard.java | 2 +- .../polyfrost/oneconfig/gui/elements/Slider.java | 8 +- .../gui/elements/text/NumberInputField.java | 2 +- .../gui/elements/text/TextInputField.java | 14 +- .../cc/polyfrost/oneconfig/gui/pages/Page.java | 2 +- .../java/cc/polyfrost/oneconfig/hud/BasicHud.java | 116 ++++++++ .../java/cc/polyfrost/oneconfig/hud/HUDUtils.java | 48 ++-- src/main/java/cc/polyfrost/oneconfig/hud/Hud.java | 208 +++++---------- .../java/cc/polyfrost/oneconfig/hud/Position.java | 279 ++++++++++++++++++++ .../cc/polyfrost/oneconfig/hud/SingleTextHud.java | 49 +--- .../java/cc/polyfrost/oneconfig/hud/TextHud.java | 71 ++--- .../oneconfig/internal/assets/Colors.java | 5 - .../internal/command/OneConfigCommand.java | 4 +- .../oneconfig/internal/config/Preferences.java | 7 +- .../compatibility/vigilance/VigilanceConfig.java | 11 +- .../polyfrost/oneconfig/internal/gui/HudGui.java | 269 +++++++++++++++++++ .../polyfrost/oneconfig/internal/hud/HudCore.java | 2 +- .../oneconfig/internal/hud/utils/GrabOffset.java | 27 ++ .../oneconfig/internal/hud/utils/SnappingLine.java | 49 ++++ .../oneconfig/internal/init/OneConfigInit.java | 5 + .../oneconfig/platform/NanoVGPlatform.java | 42 +++ .../cc/polyfrost/oneconfig/platform/Platform.java | 13 + .../oneconfig/renderer/RenderManager.java | 28 +- .../polyfrost/oneconfig/renderer/TextRenderer.java | 4 +- .../oneconfig/renderer/scissor/Scissor.java | 2 +- .../cc/polyfrost/oneconfig/utils/InputUtils.java | 32 +-- .../oneconfig/utils/commands/CommandManager.java | 10 +- .../utils/commands/PlatformCommandManager.java | 31 ++- .../utils/commands/annotations/Command.java | 8 + .../utils/commands/annotations/SubCommand.java | 9 + .../cc/polyfrost/oneconfig/utils/gui/GuiUtils.java | 1 - .../polyfrost/oneconfig/utils/gui/OneUIScreen.java | 39 +-- 41 files changed, 1083 insertions(+), 688 deletions(-) delete mode 100644 src/main/java/cc/polyfrost/oneconfig/gui/HudGui.java create mode 100644 src/main/java/cc/polyfrost/oneconfig/hud/BasicHud.java create mode 100644 src/main/java/cc/polyfrost/oneconfig/hud/Position.java create mode 100644 src/main/java/cc/polyfrost/oneconfig/internal/gui/HudGui.java create mode 100644 src/main/java/cc/polyfrost/oneconfig/internal/hud/utils/GrabOffset.java create mode 100644 src/main/java/cc/polyfrost/oneconfig/internal/hud/utils/SnappingLine.java create mode 100644 src/main/java/cc/polyfrost/oneconfig/platform/NanoVGPlatform.java (limited to 'src/main/java/cc/polyfrost') diff --git a/src/main/java/cc/polyfrost/oneconfig/config/Config.java b/src/main/java/cc/polyfrost/oneconfig/config/Config.java index 8a5608e..1b5c5e6 100644 --- a/src/main/java/cc/polyfrost/oneconfig/config/Config.java +++ b/src/main/java/cc/polyfrost/oneconfig/config/Config.java @@ -24,7 +24,10 @@ import cc.polyfrost.oneconfig.utils.JsonUtils; import cc.polyfrost.oneconfig.utils.gui.GuiUtils; import com.google.gson.*; -import java.io.*; +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.nio.charset.StandardCharsets; diff --git a/src/main/java/cc/polyfrost/oneconfig/config/core/OneKeyBind.java b/src/main/java/cc/polyfrost/oneconfig/config/core/OneKeyBind.java index 791bc4a..7e844f0 100644 --- a/src/main/java/cc/polyfrost/oneconfig/config/core/OneKeyBind.java +++ b/src/main/java/cc/polyfrost/oneconfig/config/core/OneKeyBind.java @@ -14,7 +14,6 @@ public class OneKeyBind { keyBinds.add(key); } } - public boolean isActive() { if (keyBinds.size() == 0) return false; for (int keyBind : keyBinds) { diff --git a/src/main/java/cc/polyfrost/oneconfig/gui/GuiPause.java b/src/main/java/cc/polyfrost/oneconfig/gui/GuiPause.java index 44b2b5c..344f7bb 100644 --- a/src/main/java/cc/polyfrost/oneconfig/gui/GuiPause.java +++ b/src/main/java/cc/polyfrost/oneconfig/gui/GuiPause.java @@ -5,5 +5,6 @@ package cc.polyfrost.oneconfig.gui; * Minecraft itself. */ public interface GuiPause { + @SuppressWarnings("unused") boolean doesGuiPauseGame(); } diff --git a/src/main/java/cc/polyfrost/oneconfig/gui/HudGui.java b/src/main/java/cc/polyfrost/oneconfig/gui/HudGui.java deleted file mode 100644 index fc90c01..0000000 --- a/src/main/java/cc/polyfrost/oneconfig/gui/HudGui.java +++ /dev/null @@ -1,292 +0,0 @@ -package cc.polyfrost.oneconfig.gui; - -import cc.polyfrost.oneconfig.hud.Hud; -import cc.polyfrost.oneconfig.internal.config.core.ConfigCore; -import cc.polyfrost.oneconfig.internal.hud.HudCore; -import cc.polyfrost.oneconfig.libs.universal.UKeyboard; -import cc.polyfrost.oneconfig.libs.universal.UMatrixStack; -import cc.polyfrost.oneconfig.libs.universal.UResolution; -import cc.polyfrost.oneconfig.libs.universal.UScreen; -import cc.polyfrost.oneconfig.renderer.RenderManager; -import cc.polyfrost.oneconfig.utils.gui.GuiUtils; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.awt.*; -import java.util.ArrayList; - -public class HudGui extends UScreen implements GuiPause { - private Hud editingHud; - private boolean isDragging; - private boolean isScaling; - private final boolean openOneConfigOnClose; - private int xOffset; - private int yOffset; - - public HudGui(boolean openOneConfigOnClose) { - super(); - this.openOneConfigOnClose = openOneConfigOnClose; - } - - @Override - public void initScreen(int width, int height) { - HudCore.editing = true; - UKeyboard.allowRepeatEvents(true); - super.initScreen(width, height); - } - - @Override - public void onDrawScreen(@NotNull UMatrixStack matrixStack, int mouseX, int mouseY, float partialTicks) { - RenderManager.drawGlRect(0, 0, UResolution.getScaledWidth(), UResolution.getScaledHeight(), new Color(80, 80, 80, 50).getRGB()); - - if (isDragging) { - setPosition(mouseX - xOffset, mouseY - yOffset, true); - } - - for (Hud hud : HudCore.huds) { - if (hud.isEnabled()) processHud(matrixStack, hud, mouseX); - } - } - - private void processHud(UMatrixStack matrixStack, Hud hud, int mouseX) { - if (hud == editingHud && isScaling) { - float xFloat = hud.getXScaled(UResolution.getScaledWidth()); - float yFloat = hud.getYScaled(UResolution.getScaledHeight()); - float pos = getXSnapping(mouseX, true); - float newWidth = pos - xFloat; - float newScale = newWidth / ((hud.getWidth(hud.scale) + hud.paddingX * hud.scale) / hud.scale); - if (newScale > 20) - newScale = 20; - else if (newScale < 0.3) - newScale = 0.3f; - hud.scale = newScale; - - if (xFloat / UResolution.getScaledWidth() > 0.5) - editingHud.xUnscaled = (xFloat + (hud.getWidth(hud.scale) + hud.paddingX * hud.scale)) / (double) UResolution.getScaledWidth(); - if (yFloat / UResolution.getScaledHeight() > 0.5) - editingHud.yUnscaled = (yFloat + (hud.getHeight(hud.scale) + hud.paddingY * hud.scale)) / (double) UResolution.getScaledHeight(); - } - - int width = (int) (hud.getExampleWidth(hud.scale) + hud.paddingX * hud.scale); - int height = (int) (hud.getExampleHeight(hud.scale) + hud.paddingY * hud.scale); - int x = (int) hud.getXScaled(UResolution.getScaledWidth()); - int y = (int) hud.getYScaled(UResolution.getScaledHeight()); - - hud.drawExampleAll(matrixStack, x, y, hud.scale, true); - int color = new Color(215, 224, 235).getRGB(); - if (editingHud == hud) { - color = new Color(43, 159, 235).getRGB(); - if (isDragging) - RenderManager.drawGlRect(x, y, width, height, new Color(108, 176, 255, 60).getRGB()); - } - int finalColor = color; - RenderManager.setupAndDraw(true, (vg) -> { - RenderManager.drawLine(vg, x - 2 / 4f, y, x + width + 2 / 4f, y, 1, finalColor); - RenderManager.drawLine(vg, x, y, x, y + height, 1, finalColor); - RenderManager.drawLine(vg, x + width, y, x + width, y + height, 1, finalColor); - RenderManager.drawLine(vg, x - 2 / 4f, y + height, x + width + 2 / 4f, y + height, 1, finalColor); - }); - - if (hud == editingHud && !isDragging) { - RenderManager.setupAndDraw(true, (vg) -> RenderManager.drawCircle(vg, x + width, y + height, 3, new Color(43, 159, 235).getRGB())); - } - } - - private void setPosition(float newX, float newY, boolean snap) { - float width = editingHud.getWidth(editingHud.scale) + editingHud.paddingX * editingHud.scale; - float height = editingHud.getHeight(editingHud.scale) + editingHud.paddingY * editingHud.scale; - - if (newX < 0) - newX = 0; - else if (newX + width > UResolution.getScaledWidth()) - newX = UResolution.getScaledWidth() - width; - if (newY < 0) - newY = 0; - else if (newY + height > UResolution.getScaledHeight()) - newY = UResolution.getScaledHeight() - height; - - if (snap) { - float snapX = getXSnapping(newX, false); - float snapY = getYSnapping(newY); - if (snapX != newX || snapY != newY) { - newX = snapX; - newY = snapY; - } - } - - if (newX / UResolution.getScaledWidth() <= 0.5) - editingHud.xUnscaled = newX / (double) UResolution.getScaledWidth(); - else - editingHud.xUnscaled = (newX + width) / (double) UResolution.getScaledWidth(); - if (newY / UResolution.getScaledHeight() <= 0.5) - editingHud.yUnscaled = newY / (double) UResolution.getScaledHeight(); - else - editingHud.yUnscaled = (newY + height) / (double) UResolution.getScaledHeight(); - } - - private float getXSnapping(float pos, boolean rightOnly) { - float width = editingHud.getWidth(editingHud.scale) + editingHud.paddingX * editingHud.scale; - ArrayList verticalLines = new ArrayList<>(); - for (Hud hud : HudCore.huds) { - if (!hud.isEnabled()) continue; - verticalLines.addAll(getXSnappingHud(hud)); - } - getSpaceSnapping(verticalLines); - verticalLines.add(UResolution.getScaledWidth() / 2f); - float smallestDiff = -1; - float smallestLine = 0; - float smallestOffset = 0; - for (float lineX : verticalLines) { - for (float offset = 0; offset <= (rightOnly ? 0 : width); offset += width / 2f) { - if (Math.abs(lineX - pos - offset) < 5 && (Math.abs(lineX - pos - offset) < smallestDiff || smallestDiff == -1)) { - smallestDiff = Math.abs(lineX - pos); - smallestLine = lineX; - smallestOffset = offset; - } - } - } - if (smallestDiff != -1) { - float finalSmallestLine = smallestLine; - RenderManager.setupAndDraw(true, (vg) -> RenderManager.drawLine(vg, finalSmallestLine, 0, finalSmallestLine, UResolution.getScaledHeight(), 1, new Color(255, 255, 255).getRGB())); - return smallestLine - smallestOffset; - } - return pos; - } - - private ArrayList getXSnappingHud(Hud hud) { - ArrayList verticalLines = new ArrayList<>(); - if (hud == editingHud) return verticalLines; - int hudWidth = (int) (hud.getWidth(hud.scale) + hud.paddingX * hud.scale); - int hudX = (int) hud.getXScaled(UResolution.getScaledWidth()); - verticalLines.add((float) hudX); - verticalLines.add((float) (hudX + hudWidth)); - return verticalLines; - } - - private float getYSnapping(float pos) { - float height = editingHud.getHeight(editingHud.scale) + editingHud.paddingY * editingHud.scale; - ArrayList horizontalLines = new ArrayList<>(); - for (Hud hud : HudCore.huds) { - if (!hud.isEnabled()) continue; - horizontalLines.addAll(getYSnappingHud(hud)); - } - getSpaceSnapping(horizontalLines); - horizontalLines.add(UResolution.getScaledHeight() / 2f); - float smallestDiff = -1; - float smallestLine = 0; - float smallestOffset = 0; - for (float lineY : horizontalLines) { - for (float offset = 0; offset <= height; offset += height / 2f) { - if (Math.abs(lineY - pos - offset) < 5 && (Math.abs(lineY - pos - offset) < smallestDiff || smallestDiff == -1)) { - smallestDiff = Math.abs(lineY - pos); - smallestLine = lineY; - smallestOffset = offset; - } - } - } - if (smallestDiff != -1) { - float finalSmallestLine = smallestLine; - RenderManager.setupAndDraw(true, (vg) -> RenderManager.drawLine(vg, 0, finalSmallestLine, UResolution.getScaledWidth(), finalSmallestLine, 1, new Color(255, 255, 255).getRGB())); - return smallestLine - smallestOffset; - } - return pos; - } - - private ArrayList getYSnappingHud(Hud hud) { - ArrayList horizontalLines = new ArrayList<>(); - if (hud == editingHud) return horizontalLines; - int hudHeight = (int) (hud.getHeight(hud.scale) + hud.paddingY * hud.scale); - int hudY = (int) hud.getYScaled(UResolution.getScaledHeight()); - horizontalLines.add((float) hudY); - horizontalLines.add((float) (hudY + hudHeight)); - return horizontalLines; - } - - private void getSpaceSnapping(ArrayList lines) { - ArrayList newLines = new ArrayList<>(); - for (int i = 0; i < lines.size(); i++) { - for (int l = i + 1; l < lines.size(); l++) { - newLines.add(Math.max(lines.get(i), lines.get(l)) + Math.abs(lines.get(i) - lines.get(l))); - newLines.add(Math.min(lines.get(i), lines.get(l)) - Math.abs(lines.get(i) - lines.get(l))); - } - } - lines.addAll(newLines); - } - - @Override - public void onMouseClicked(double mouseX, double mouseY, int mouseButton) { - super.onMouseClicked(mouseX, mouseY, mouseButton); - if (mouseButton == 0) { - if (editingHud != null) { - int width = (int) (editingHud.getWidth(editingHud.scale) + editingHud.paddingX * editingHud.scale); - int height = (int) (editingHud.getHeight(editingHud.scale) + editingHud.paddingY * editingHud.scale); - float x = editingHud.getXScaled(UResolution.getScaledWidth()); - float y = editingHud.getYScaled(UResolution.getScaledHeight()); - if (mouseX >= x + width - 3 && mouseX <= x + width + 3 && mouseY >= y + height - 3 && mouseY <= y + height + 3) { - isScaling = true; - return; - } - } - editingHud = null; - for (Hud hud : HudCore.huds) { - if (!hud.isEnabled()) continue; - if (mouseClickedHud(hud, (int) mouseX, (int) mouseY)) - break; - } - } - } - - private boolean mouseClickedHud(Hud hud, int mouseX, int mouseY) { - int width = (int) (hud.getWidth(hud.scale) + hud.paddingX * hud.scale); - int height = (int) (hud.getHeight(hud.scale) + hud.paddingY * hud.scale); - float x = hud.getXScaled(UResolution.getScaledWidth()); - float y = hud.getYScaled(UResolution.getScaledHeight()); - if (mouseX >= x && mouseX <= x + width && mouseY >= y && mouseY <= y + height) { - editingHud = hud; - xOffset = (int) (mouseX - x); - yOffset = (int) (mouseY - y); - isDragging = true; - return true; - } - return false; - } - - @Override - public void onMouseReleased(double mouseX, double mouseY, int state) { - super.onMouseReleased(mouseX, mouseY, state); - isDragging = false; - isScaling = false; - } - - @Override - public void onKeyPressed(int keyCode, char typedChar, @Nullable UKeyboard.Modifiers modifiers) { - if (editingHud != null) { - float x = editingHud.getXScaled(UResolution.getScaledWidth()); - float y = editingHud.getYScaled(UResolution.getScaledHeight()); - if (keyCode == UKeyboard.KEY_UP) { - setPosition(x, y - 1, false); - } else if (keyCode == UKeyboard.KEY_DOWN) { - setPosition(x, y + 1, false); - } else if (keyCode == UKeyboard.KEY_LEFT) { - setPosition(x - 1, y, false); - } else if (keyCode == UKeyboard.KEY_RIGHT) { - setPosition(x + 1, y, false); - } - } - super.onKeyPressed(keyCode, typedChar, modifiers); - } - - @Override - public void onScreenClose() { - super.onScreenClose(); - HudCore.editing = false; - UKeyboard.allowRepeatEvents(false); - ConfigCore.saveAll(); - if(openOneConfigOnClose) GuiUtils.displayScreen(OneConfigGui.create()); - } - - @Override - public boolean doesGuiPauseGame() { - return false; - } -} \ No newline at end of file diff --git a/src/main/java/cc/polyfrost/oneconfig/gui/OneConfigGui.java b/src/main/java/cc/polyfrost/oneconfig/gui/OneConfigGui.java index 41d0b4f..1d40d0a 100644 --- a/src/main/java/cc/polyfrost/oneconfig/gui/OneConfigGui.java +++ b/src/main/java/cc/polyfrost/oneconfig/gui/OneConfigGui.java @@ -85,13 +85,13 @@ public class OneConfigGui extends UScreen implements GuiPause { int x = (int) ((UResolution.getWindowWidth() - 1280 * scale) / 2f / scale); int y = (int) ((UResolution.getWindowHeight() - 800 * scale) / 2f / scale); RenderManager.scale(vg, scale, scale); - if (Colors.ROUNDED_CORNERS) { - RenderManager.drawDropShadow(vg, x, y, 1280, 800, 32, 0, 20); - RenderManager.drawRoundedRect(vg, x + 224, y, 1056, 800, Colors.GRAY_800, Colors.CORNER_RADIUS_WIN); - RenderManager.drawRoundedRect(vg, x, y, 244, 800, Colors.GRAY_800_95, Colors.CORNER_RADIUS_WIN); - RenderManager.drawRect(vg, x + 224, y, 20, 800, Colors.GRAY_800); - RenderManager.drawHollowRoundRect(vg, x - 1, y - 1, 1282, 802, 0x4DCCCCCC, 20, scale < 1 ? 1 / scale : 1); - } + + RenderManager.drawDropShadow(vg, x, y, 1280, 800, 32, 0, 20); + RenderManager.drawRoundedRect(vg, x + 224, y, 1056, 800, Colors.GRAY_800, 20f); + RenderManager.drawRoundedRect(vg, x, y, 244, 800, Colors.GRAY_800_95, 20f); + RenderManager.drawRect(vg, x + 224, y, 20, 800, Colors.GRAY_800); + RenderManager.drawHollowRoundRect(vg, x - 1, y - 1, 1282, 802, 0x4DCCCCCC, 20, scale < 1 ? 1 / scale : 1); + RenderManager.drawLine(vg, x + 224, y + 72, x + 1280, y + 72, 1, Colors.GRAY_700); RenderManager.drawLine(vg, x + 224, y, x + 222, y + 800, 1, Colors.GRAY_700); diff --git a/src/main/java/cc/polyfrost/oneconfig/gui/SideBar.java b/src/main/java/cc/polyfrost/oneconfig/gui/SideBar.java index d1b5532..ebfc8cb 100644 --- a/src/main/java/cc/polyfrost/oneconfig/gui/SideBar.java +++ b/src/main/java/cc/polyfrost/oneconfig/gui/SideBar.java @@ -10,6 +10,7 @@ import cc.polyfrost.oneconfig.gui.pages.ModsPage; import cc.polyfrost.oneconfig.internal.assets.Colors; import cc.polyfrost.oneconfig.internal.assets.SVGs; import cc.polyfrost.oneconfig.internal.config.Preferences; +import cc.polyfrost.oneconfig.internal.gui.HudGui; import cc.polyfrost.oneconfig.renderer.RenderManager; import cc.polyfrost.oneconfig.renderer.font.Fonts; import cc.polyfrost.oneconfig.utils.color.ColorPalette; @@ -43,7 +44,7 @@ public class SideBar { buttons.get(0).setClickAction(new CreditsPage()); buttons.get(2).setClickAction(new ModsPage()); buttons.get(8).setClickAction(new ModConfigPage(Preferences.getInstance().mod.defaultPage, true)); - HUDButton.setClickAction(() -> GuiUtils.displayScreen(new HudGui(true))); + HUDButton.setClickAction(() -> GuiUtils.displayScreen(new HudGui())); CloseButton.setClickAction(GuiUtils::closeScreen); for (BasicButton button : buttons) { if (button.hasClickAction()) continue; diff --git a/src/main/java/cc/polyfrost/oneconfig/gui/elements/BasicButton.java b/src/main/java/cc/polyfrost/oneconfig/gui/elements/BasicButton.java index 7869114..1691eca 100644 --- a/src/main/java/cc/polyfrost/oneconfig/gui/elements/BasicButton.java +++ b/src/main/java/cc/polyfrost/oneconfig/gui/elements/BasicButton.java @@ -16,9 +16,9 @@ public class BasicButton extends BasicElement { protected SVGs icon1, icon2; private final int alignment; private final float fontSize, cornerRadius; - private final int xSpacing, xPadding; + private final float xSpacing, xPadding; private final int iconSize; - public int x, y; + public float x, y; public static final int ALIGNMENT_LEFT = 0; public static final int ALIGNMENT_CENTER = 2; public static final int ALIGNMENT_JUSTIFIED = 3; @@ -57,7 +57,7 @@ public class BasicButton extends BasicElement { } @Override - public void draw(long vg, int x, int y) { + public void draw(long vg, float x, float y) { this.x = x; this.y = y; this.update(x, y); diff --git a/src/main/java/cc/polyfrost/oneconfig/gui/elements/BasicElement.java b/src/main/java/cc/polyfrost/oneconfig/gui/elements/BasicElement.java index 6f203c4..ef98120 100644 --- a/src/main/java/cc/polyfrost/oneconfig/gui/elements/BasicElement.java +++ b/src/main/java/cc/polyfrost/oneconfig/gui/elements/BasicElement.java @@ -72,13 +72,13 @@ public class BasicElement { /** * Draw script for the element. - *
Make sure to call {@link #update(int x, int y)} to update the elements states! + *
Make sure to call {@link #update(float, float)} to update the elements states! * * @param vg NanoVG context (see {@link RenderManager}) * @param x x position of the element * @param y y position of the element */ - public void draw(long vg, int x, int y) { + public void draw(long vg, float x, float y) { this.update(x, y); RenderManager.drawRoundedRect(vg, x, y, width, height, currentColor, radius); } @@ -86,7 +86,7 @@ public class BasicElement { /** * Update this element's clicked, hovered, toggled, and pressed states, invoke any necessary methods, and update the color animation. */ - public void update(int x, int y) { + public void update(float x, float y) { if (disabled) { hovered = false; pressed = false; diff --git a/src/main/java/cc/polyfrost/oneconfig/gui/elements/ColorSelector.java b/src/main/java/cc/polyfrost/oneconfig/gui/elements/ColorSelector.java index 1fed640..568567d 100644 --- a/src/main/java/cc/polyfrost/oneconfig/gui/elements/ColorSelector.java +++ b/src/main/java/cc/polyfrost/oneconfig/gui/elements/ColorSelector.java @@ -45,21 +45,21 @@ public class ColorSelector { private final ColorSlider topSlider = new ColorSlider(384, 0, 360, 127); private final ColorSlider bottomSlider = new ColorSlider(384, 0, 255, 100); private final Slider speedSlider = new Slider(296, 1, 32, 0); - private int x; - private int y; + private float x; + private float y; private Animation barMoveAnimation = new DummyAnimation(18); private Animation moveAnimation = new DummyAnimation(1); - private int mouseX, mouseY; + private float mouseX, mouseY; private int mode = 0; private boolean dragging, mouseWasDown; private final boolean hasAlpha; private Scissor inputScissor = null; - public ColorSelector(OneColor color, int mouseX, int mouseY) { + public ColorSelector(OneColor color, float mouseX, float mouseY) { this(color, mouseX, mouseY, true); } - public ColorSelector(OneColor color, int mouseX, int mouseY, boolean hasAlpha) { + public ColorSelector(OneColor color, float mouseX, float mouseY, boolean hasAlpha) { this.color = color; this.hasAlpha = hasAlpha; buttons.add(new BasicButton(124, 28, "HSB Box", BasicButton.ALIGNMENT_CENTER, ColorPalette.TERTIARY)); @@ -82,12 +82,12 @@ public class ColorSelector { this.y = Math.max(0, mouseY - 776); if (color.getDataBit() != -1) mode = 2; if (mode == 0 || mode == 2) { - this.mouseX = (int) (color.getSaturation() / 100f * 384 + x + 16); - this.mouseY = (int) (Math.abs(color.getBrightness() / 100f - 1f) * 288 + y + 120); + this.mouseX = (color.getSaturation() / 100f * 384 + x + 16); + this.mouseY = (Math.abs(color.getBrightness() / 100f - 1f) * 288 + y + 120); } else { topSlider.setValue(color.getBrightness() / 100f * 360f); - this.mouseX = (int) (Math.sin(Math.toRadians(-color.getHue()) + 1.5708) * (saturationInput.getCurrentValue() / 100 * 144) + x + 208); - this.mouseY = (int) (Math.cos(Math.toRadians(-color.getHue()) + 1.5708) * (saturationInput.getCurrentValue() / 100 * 144) + y + 264); + this.mouseX = (float) (Math.sin(Math.toRadians(-color.getHue()) + 1.5708) * (saturationInput.getCurrentValue() / 100 * 144) + x + 208); + this.mouseY = (float) (Math.cos(Math.toRadians(-color.getHue()) + 1.5708) * (saturationInput.getCurrentValue() / 100 * 144) + y + 264); } //for(OneColor color1 : OneConfigConfig.recentColors) { // recentColors.add(new ColorBox(color1)); @@ -178,7 +178,7 @@ public class ColorSelector { setColorFromXY(); if (mode != 2) color.setChromaSpeed(-1); - drawColorSelector(vg, mode, (int) (x * percentMoveMain), y); + drawColorSelector(vg, mode, (x * percentMoveMain), y); if (dragging && InputUtils.isClicked(true)) { dragging = false; } @@ -209,7 +209,7 @@ public class ColorSelector { } } - private void drawColorSelector(long vg, int mode, int x, int y) { + private void drawColorSelector(long vg, int mode, float x, float y) { switch (mode) { default: case 0: @@ -242,8 +242,8 @@ public class ColorSelector { private void doDrag() { if (InputUtils.isAreaHovered(x, y, 368, 64) && Platform.getMousePlatform().isButtonDown(0) && !dragging) { - int dx = (int) (Platform.getMousePlatform().getMouseDX() / (OneConfigGui.INSTANCE == null ? 1 : OneConfigGui.INSTANCE.getScaleFactor())); - int dy = (int) (Platform.getMousePlatform().getMouseDY() / (OneConfigGui.INSTANCE == null ? 1 : OneConfigGui.INSTANCE.getScaleFactor())); + float dx = (float) (Platform.getMousePlatform().getMouseDX() / (OneConfigGui.INSTANCE == null ? 1 : OneConfigGui.INSTANCE.getScaleFactor())); + float dy = (float) (Platform.getMousePlatform().getMouseDY() / (OneConfigGui.INSTANCE == null ? 1 : OneConfigGui.INSTANCE.getScaleFactor())); x += dx; mouseX += dx; y -= dy; @@ -279,8 +279,8 @@ public class ColorSelector { } break; case 1: - int circleCenterX = x + 208; - int circleCenterY = y + 264; + float circleCenterX = x + 208; + float circleCenterY = y + 264; double squareDist = Math.pow((circleCenterX - InputUtils.mouseX()), 2) + Math.pow((circleCenterY - InputUtils.mouseY()), 2); hovered = squareDist < 144 * 144 && Platform.getMousePlatform().isButtonDown(0); isMouseDown = Platform.getMousePlatform().isButtonDown(0); @@ -293,8 +293,8 @@ public class ColorSelector { if (angle < 0) angle += 360; if ((squareDist / (144 * 144) > 1f)) { saturation = 100; - mouseX = (int) (Math.sin(Math.toRadians(-angle) + 1.5708) * 144 + x + 208); - mouseY = (int) (Math.cos(Math.toRadians(-angle) + 1.5708) * 144 + y + 264); + mouseX = (float) (Math.sin(Math.toRadians(-angle) + 1.5708) * 144 + x + 208); + mouseY = (float) (Math.cos(Math.toRadians(-angle) + 1.5708) * 144 + y + 264); } else { saturation = (int) (squareDist / (144 * 144) * 100); mouseX = InputUtils.mouseX(); @@ -309,14 +309,14 @@ public class ColorSelector { private void setXYFromColor() { bottomSlider.setValue(color.getAlpha()); if (mode == 1) { - mouseX = (int) (Math.sin(Math.toRadians(-color.getHue()) + 1.5708) * (saturationInput.getCurrentValue() / 100 * 144) + x + 208); - mouseY = (int) (Math.cos(Math.toRadians(-color.getHue()) + 1.5708) * (saturationInput.getCurrentValue() / 100 * 144) + y + 264); + mouseX = (float) (Math.sin(Math.toRadians(-color.getHue()) + 1.5708) * (saturationInput.getCurrentValue() / 100 * 144) + x + 208); + mouseY = (float) (Math.cos(Math.toRadians(-color.getHue()) + 1.5708) * (saturationInput.getCurrentValue() / 100 * 144) + y + 264); topSlider.setValue(color.getBrightness() / 100f * 360f); } if (mode == 0 || mode == 2) { topSlider.setValue(color.getHue()); - mouseX = (int) (saturationInput.getCurrentValue() / 100f * 384 + x + 16); - mouseY = (int) (Math.abs(brightnessInput.getCurrentValue() / 100f - 1f) * 288 + y + 120); + mouseX = (saturationInput.getCurrentValue() / 100f * 384 + x + 16); + mouseY = (Math.abs(brightnessInput.getCurrentValue() / 100f - 1f) * 288 + y + 120); } } @@ -429,7 +429,7 @@ public class ColorSelector { } @Override - public void draw(long vg, int x, int y) { + public void draw(long vg, float x, float y) { if (!disabled) update(x, y); else RenderManager.setAlpha(vg, 0.5f); super.dragPointerSize = 15f; @@ -469,7 +469,7 @@ public class ColorSelector { } @Override - public void draw(long vg, int x, int y) { + public void draw(long vg, float x, float y) { RenderManager.drawRoundedRect(vg, x, y, 32, 32, toggled ? Colors.PRIMARY_600 : Colors.GRAY_300, 12f); RenderManager.drawRoundedRect(vg, x + 2, y + 2, 28, 28, Colors.GRAY_800, 10f); RenderManager.drawRoundedRect(vg, x + 4, y + 4, 24, 24, color.getRGB(), 8f); diff --git a/src/main/java/cc/polyfrost/oneconfig/gui/elements/ModCard.java b/src/main/java/cc/polyfrost/oneconfig/gui/elements/ModCard.java index eebdba1..ffac8e3 100644 --- a/src/main/java/cc/polyfrost/oneconfig/gui/elements/ModCard.java +++ b/src/main/java/cc/polyfrost/oneconfig/gui/elements/ModCard.java @@ -42,7 +42,7 @@ public class ModCard extends BasicElement { } @Override - public void draw(long vg, int x, int y) { + public void draw(long vg, float x, float y) { super.update(x, y); String cleanName = modData.name.replaceAll("ยง.", ""); Scissor scissor = ScissorManager.scissor(vg, x, y, width, height); diff --git a/src/main/java/cc/polyfrost/oneconfig/gui/elements/Slider.java b/src/main/java/cc/polyfrost/oneconfig/gui/elements/Slider.java index dda5621..a22064c 100644 --- a/src/main/java/cc/polyfrost/oneconfig/gui/elements/Slider.java +++ b/src/main/java/cc/polyfrost/oneconfig/gui/elements/Slider.java @@ -21,7 +21,7 @@ public class Slider extends BasicElement { } @Override - public void draw(long vg, int x, int y) { + public void draw(long vg, float x, float y) { if(!disabled) update(x, y); else RenderManager.setAlpha(vg, 0.5f); RenderManager.drawRoundedRect(vg, x, y + 2, width, height - 4, Colors.GRAY_300, 3f); @@ -32,18 +32,18 @@ public class Slider extends BasicElement { } - public void update(int x, int y) { + public void update(float x, float y) { super.update(x, y); boolean isMouseDown = Platform.getMousePlatform().isButtonDown(0); boolean hovered = InputUtils.isAreaHovered(x - 6, y - 3, width + 12, height + 6); if (hovered && isMouseDown && !mouseWasDown) dragging = true; mouseWasDown = isMouseDown; if (dragging) { - value = ((float) InputUtils.mouseX() - x) / width; + value = (InputUtils.mouseX() - x) / width; } if (dragging && InputUtils.isClicked(true)) { dragging = false; - value = ((float) InputUtils.mouseX() - x) / width; + value = (InputUtils.mouseX() - x) / width; } if (value < 0) value = 0; diff --git a/src/main/java/cc/polyfrost/oneconfig/gui/elements/text/NumberInputField.java b/src/main/java/cc/polyfrost/oneconfig/gui/elements/text/NumberInputField.java index d7e29f5..5162ecb 100644 --- a/src/main/java/cc/polyfrost/oneconfig/gui/elements/text/NumberInputField.java +++ b/src/main/java/cc/polyfrost/oneconfig/gui/elements/text/NumberInputField.java @@ -27,7 +27,7 @@ public class NumberInputField extends TextInputField { } @Override - public void draw(long vg, int x, int y) { + public void draw(long vg, float x, float y) { super.errored = false; if(disabled) RenderManager.setAlpha(vg, 0.5f); RenderManager.drawRoundedRect(vg, x + width + 4, y, 12, 28, Colors.GRAY_500, 6f); diff --git a/src/main/java/cc/polyfrost/oneconfig/gui/elements/text/TextInputField.java b/src/main/java/cc/polyfrost/oneconfig/gui/elements/text/TextInputField.java index 054915c..3c2cb1c 100644 --- a/src/main/java/cc/polyfrost/oneconfig/gui/elements/text/TextInputField.java +++ b/src/main/java/cc/polyfrost/oneconfig/gui/elements/text/TextInputField.java @@ -26,7 +26,7 @@ public class TextInputField extends BasicElement { protected boolean password; protected int caretPos; - protected int x, y; + protected float x, y; protected float start, end; protected int startLine, endLine; protected long vg; @@ -95,7 +95,7 @@ public class TextInputField extends BasicElement { } @Override - public void draw(long vg, int x, int y) { + public void draw(long vg, float x, float y) { this.x = x; this.y = y; this.vg = vg; @@ -206,12 +206,12 @@ public class TextInputField extends BasicElement { if(disabled) RenderManager.setAlpha(vg, 0.5f); if (toggled) { if (multiLine) { - int lineY = y + 20 + getCaretLine(caretPos) * 24; + float lineY = y + 20 + getCaretLine(caretPos) * 24; RenderManager.drawLine(vg, x + width + 12, lineY - 10, x + width + 12, lineY + 10, 1, Colors.WHITE); } else if (!centered) { - RenderManager.drawLine(vg, x + width + 12, (float) y + height / 2f - 10, x + width + 12, (float) y + height / 2f + 10, 1, Colors.WHITE); + RenderManager.drawLine(vg, x + width + 12, y + height / 2f - 10, x + width + 12, y + height / 2f + 10, 1, Colors.WHITE); } else { - RenderManager.drawLine(vg, x + this.width / 2f - halfTextWidth + width, (float) y + height / 2f - 10, x + this.width / 2f - halfTextWidth + width, (float) y + height / 2f + 10, 1, Colors.WHITE); + RenderManager.drawLine(vg, x + this.width / 2f - halfTextWidth + width, y + height / 2f - 10, x + this.width / 2f - halfTextWidth + width, y + height / 2f + 10, 1, Colors.WHITE); } } @@ -228,7 +228,7 @@ public class TextInputField extends BasicElement { if (!password) { if (multiLine) { - int textY = y + 20; + float textY = y + 20; for (String line : wrappedText) { RenderManager.drawText(vg, line, x + 12, textY, color, 14f, Fonts.REGULAR); textY += 24; @@ -453,7 +453,7 @@ public class TextInputField extends BasicElement { } } - private int calculatePos(int pos, String string) { + private int calculatePos(float pos, String string) { if (centered) pos -= 12; String s1 = ""; int i; diff --git a/src/main/java/cc/polyfrost/oneconfig/gui/pages/Page.java b/src/main/java/cc/polyfrost/oneconfig/gui/pages/Page.java index 028f098..5a5970a 100644 --- a/src/main/java/cc/polyfrost/oneconfig/gui/pages/Page.java +++ b/src/main/java/cc/polyfrost/oneconfig/gui/pages/Page.java @@ -52,7 +52,7 @@ public abstract class Page { final float scrollBarLength = (728f / maxScroll) * 728f; Scissor scissor = ScissorManager.scissor(vg, x, y + scissorOffset, x + 1056, y + 728 - scissorOffset); Scissor inputScissor = InputUtils.blockInputArea(x, y,1056, scissorOffset); - int dWheel = (int) Platform.getMousePlatform().getDWheel(); + float dWheel = (float) Platform.getMousePlatform().getDWheel(); if (dWheel != 0) { scrollTarget += dWheel; diff --git a/src/main/java/cc/polyfrost/oneconfig/hud/BasicHud.java b/src/main/java/cc/polyfrost/oneconfig/hud/BasicHud.java new file mode 100644 index 0000000..cb8a2d4 --- /dev/null +++ b/src/main/java/cc/polyfrost/oneconfig/hud/BasicHud.java @@ -0,0 +1,116 @@ +package cc.polyfrost.oneconfig.hud; + +import cc.polyfrost.oneconfig.config.core.OneColor; +import cc.polyfrost.oneconfig.libs.universal.UMatrixStack; +import cc.polyfrost.oneconfig.renderer.RenderManager; + +public abstract class BasicHud extends Hud { + protected boolean rounded; + protected boolean border; + protected OneColor bgColor; + protected OneColor borderColor; + protected float cornerRadius; + protected float borderSize; + protected float paddingX; + protected float paddingY; + + /** + * @param enabled If the hud is enabled + * @param x X-coordinate of hud on a 1080p display + * @param y Y-coordinate of hud on a 1080p display + * @param scale Scale of the hud + * @param rounded If the corner is rounded or not + * @param cornerRadius Radius of the corner + * @param paddingX Horizontal background padding + * @param paddingY Vertical background padding + * @param bgColor Background color + * @param border If the hud has a border or not + * @param borderSize Thickness of the border + * @param borderColor The color of the border + */ + public BasicHud(boolean enabled, float x, float y, float scale, boolean rounded, float cornerRadius, float paddingX, float paddingY, OneColor bgColor, boolean border, float borderSize, OneColor borderColor) { + super(enabled, x, y, scale); + this.rounded = rounded; + this.cornerRadius = cornerRadius; + this.paddingX = paddingX; + this.paddingY = paddingY; + this.bgColor = bgColor; + this.border = border; + this.borderSize = borderSize; + this.borderColor = borderColor; + position.setSize(getWidth(scale, true) + paddingX * scale * 2f, getHeight(scale, true) + paddingY * scale * 2f); + } + + /** + * @param enabled If the hud is enabled + * @param x X-coordinate of hud on a 1080p display + * @param y Y-coordinate of hud on a 1080p display + * @param scale Scale of the hud + */ + public BasicHud(boolean enabled, float x, float y, float scale) { + this(enabled, x, y, scale, false, 2, 5, 5, new OneColor(0, 0, 0, 120), false, 2, new OneColor(0, 0, 0)); + } + + /** + * @param enabled If the hud is enabled + * @param x X-coordinate of hud on a 1080p display + * @param y Y-coordinate of hud on a 1080p display + */ + public BasicHud(boolean enabled, float x, float y) { + this(enabled, x, y, 1, false, 2, 5, 5, new OneColor(0, 0, 0, 120), false, 2, new OneColor(0, 0, 0)); + } + + /** + * @param enabled If the hud is enabled + */ + public BasicHud(boolean enabled) { + this(enabled, 0, 0, 1, false, 2, 5, 5, new OneColor(0, 0, 0, 120), false, 2, new OneColor(0, 0, 0)); + } + + public BasicHud() { + this(false, 0, 0, 1, false, 2, 5, 5, new OneColor(0, 0, 0, 120), false, 2, new OneColor(0, 0, 0)); + } + + @Override + public void drawAll(UMatrixStack matrices, boolean example) { + if (!example && !shouldShow()) return; + preRender(example); + position.setSize(getWidth(scale, example) + paddingX * scale * 2f, getHeight(scale, example) + paddingY * scale * 2f); + if (shouldDrawBackground()) + drawBackground(position.getX(), position.getY(), position.getWidth(), position.getHeight(), scale); + draw(matrices, position.getX() + paddingX * scale, position.getY() + paddingY * scale, scale, example); + } + + /** + * Set a new scale value + * + * @param scale The new scale + * @param example If the HUD is being rendered in example form + */ + @Override + public void setScale(float scale, boolean example) { + this.scale = scale; + position.updateSizePosition(getWidth(scale, example) + paddingX * scale * 2f, getHeight(scale, example) + paddingY * scale * 2f); + } + + /** + * @return If the background should be drawn + */ + protected boolean shouldDrawBackground() { + return true; + } + + protected void drawBackground(float x, float y, float width, float height, float scale) { + RenderManager.setupAndDraw(true, (vg) -> { + if (rounded) { + RenderManager.drawRoundedRect(vg, x, y, width, height, bgColor.getRGB(), cornerRadius * scale); + if (border) + RenderManager.drawHollowRoundRect(vg, x - borderSize * scale, y - borderSize * scale, width + borderSize * scale, height + borderSize * scale, borderColor.getRGB(), cornerRadius * scale, borderSize * scale); + } else { + RenderManager.drawRect(vg, x, y, width, height, bgColor.getRGB()); + if (border) + RenderManager.drawHollowRoundRect(vg, x - borderSize * scale, y - borderSize * scale, width + borderSize * scale, height + borderSize * scale, borderColor.getRGB(), 0, borderSize * scale); + } + }); + } +} diff --git a/src/main/java/cc/polyfrost/oneconfig/hud/HUDUtils.java b/src/main/java/cc/polyfrost/oneconfig/hud/HUDUtils.java index a67177c..bff1b70 100644 --- a/src/main/java/cc/polyfrost/oneconfig/hud/HUDUtils.java +++ b/src/main/java/cc/polyfrost/oneconfig/hud/HUDUtils.java @@ -6,42 +6,52 @@ import cc.polyfrost.oneconfig.config.core.ConfigUtils; import cc.polyfrost.oneconfig.config.elements.BasicOption; import cc.polyfrost.oneconfig.config.elements.OptionPage; import cc.polyfrost.oneconfig.gui.elements.config.*; +import cc.polyfrost.oneconfig.hud.BasicHud; +import cc.polyfrost.oneconfig.hud.Hud; import cc.polyfrost.oneconfig.internal.hud.HudCore; import java.lang.reflect.Field; import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; public class HUDUtils { public static void addHudOptions(OptionPage page, Field field, Object instance, Config config) { HUD hudAnnotation = field.getAnnotation(HUD.class); + field.setAccessible(true); Hud hud = (Hud) ConfigUtils.getField(field, instance); if (hud == null) return; hud.setConfig(config); HudCore.huds.add(hud); String category = hudAnnotation.category(); String subcategory = hudAnnotation.subcategory(); - ArrayList options = ConfigUtils.getSubCategory(page, hudAnnotation.category(), hudAnnotation.subcategory()).options; + ArrayList options = new ArrayList<>(); try { + ArrayList fieldArrayList = ConfigUtils.getClassFields(hud.getClass()); + HashMap fields = new HashMap<>(); + for (Field f : fieldArrayList) fields.put(f.getName(), f); options.add(new ConfigHeader(field, hud, hudAnnotation.name(), category, subcategory, 2)); - options.add(new ConfigSwitch(hud.getClass().getField("enabled"), hud, "Enabled", category, subcategory, 2)); + options.add(new ConfigSwitch(fields.get("enabled"), hud, "Enabled", category, subcategory, 2)); options.addAll(ConfigUtils.getClassOptions(hud)); - options.add(new ConfigCheckbox(hud.getClass().getField("rounded"), hud, "Rounded corners", category, subcategory, 1)); - options.get(options.size() - 1).addDependency(hud::isEnabled); - options.add(new ConfigCheckbox(hud.getClass().getField("border"), hud, "Outline/border", category, subcategory, 1)); - options.get(options.size() - 1).addDependency(hud::isEnabled); - options.add(new ConfigColorElement(hud.getClass().getField("bgColor"), hud, "Background color:", category, subcategory, 1, true)); - options.get(options.size() - 1).addDependency(hud::isEnabled); - options.add(new ConfigColorElement(hud.getClass().getField("borderColor"), hud, "Border color:", category, subcategory, 1, true)); - options.get(options.size() - 1).addDependency(() -> hud.isEnabled() && hud.border); - options.add(new ConfigSlider(hud.getClass().getField("cornerRadius"), hud, "Corner radius:", category, subcategory, 0, 10, 0)); - options.get(options.size() - 1).addDependency(() -> hud.isEnabled() && hud.rounded); - options.add(new ConfigSlider(hud.getClass().getField("borderSize"), hud, "Border thickness:", category, subcategory, 0, 10, 0)); - options.get(options.size() - 1).addDependency(() -> hud.isEnabled() && hud.border); - options.add(new ConfigSlider(hud.getClass().getField("paddingX"), hud, "X-Padding", category, subcategory, 0, 50, 0)); - options.get(options.size() - 1).addDependency(hud::isEnabled); - options.add(new ConfigSlider(hud.getClass().getField("paddingY"), hud, "Y-Padding", category, subcategory, 0, 50, 0)); - options.get(options.size() - 1).addDependency(hud::isEnabled); - } catch (NoSuchFieldException ignored) { + if (hud instanceof BasicHud) { + options.add(new ConfigCheckbox(fields.get("rounded"), hud, "Rounded corners", category, subcategory, 1)); + options.add(new ConfigCheckbox(fields.get("border"), hud, "Outline/border", category, subcategory, 1)); + options.add(new ConfigColorElement(fields.get("bgColor"), hud, "Background color:", category, subcategory, 1, true)); + options.add(new ConfigColorElement(fields.get("borderColor"), hud, "Border color:", category, subcategory, 1, true)); + options.get(options.size() - 1).addDependency(() -> ((BasicHud) hud).border); + options.add(new ConfigSlider(fields.get("cornerRadius"), hud, "Corner radius:", category, subcategory, 0, 10, 0)); + options.get(options.size() - 1).addDependency(() -> ((BasicHud) hud).rounded); + options.add(new ConfigSlider(fields.get("borderSize"), hud, "Border thickness:", category, subcategory, 0, 10, 0)); + options.get(options.size() - 1).addDependency(() -> ((BasicHud) hud).border); + options.add(new ConfigSlider(fields.get("paddingX"), hud, "X-Padding", category, subcategory, 0, 50, 0)); + options.add(new ConfigSlider(fields.get("paddingY"), hud, "Y-Padding", category, subcategory, 0, 50, 0)); + } + for (BasicOption option : options) { + if (option.name.equals("Enabled")) continue; + option.addDependency(hud::isEnabled); + } + } catch (Exception ignored) { } + ConfigUtils.getSubCategory(page, hudAnnotation.category(), hudAnnotation.subcategory()).options.addAll(options); } } diff --git a/src/main/java/cc/polyfrost/oneconfig/hud/Hud.java b/src/main/java/cc/polyfrost/oneconfig/hud/Hud.java index 05a4f76..a8c51bd 100644 --- a/src/main/java/cc/polyfrost/oneconfig/hud/Hud.java +++ b/src/main/java/cc/polyfrost/oneconfig/hud/Hud.java @@ -2,11 +2,9 @@ package cc.polyfrost.oneconfig.hud; import cc.polyfrost.oneconfig.config.Config; import cc.polyfrost.oneconfig.config.annotations.Switch; -import cc.polyfrost.oneconfig.config.core.OneColor; import cc.polyfrost.oneconfig.gui.OneConfigGui; import cc.polyfrost.oneconfig.libs.universal.UMatrixStack; import cc.polyfrost.oneconfig.platform.Platform; -import cc.polyfrost.oneconfig.renderer.RenderManager; /** * Represents a HUD element in OneConfig. @@ -15,7 +13,7 @@ import cc.polyfrost.oneconfig.renderer.RenderManager; * If you simply want to display text, extend {@link TextHud} or {@link SingleTextHud}, * whichever applies to the use case. Then, override the required methods. *

- * If you want to display something else, extend this class and override {@link Hud#getWidth(float)}, {@link Hud#getHeight(float)}, and {@link Hud#draw(UMatrixStack, int, int, float)} with the width, height, and the drawing code respectively. + * If you want to display something else, extend this class and override {@link Hud#getWidth(float, boolean)}, {@link Hud#getHeight(float, boolean)}, and {@link Hud#draw(UMatrixStack, float, float, float, boolean)} with the width, height, and the drawing code respectively. *

*

* It should also be noted that additional options to the HUD can be added simply by declaring them. @@ -39,50 +37,10 @@ import cc.polyfrost.oneconfig.renderer.RenderManager; * * } */ public abstract class Hud { - public boolean enabled; + protected boolean enabled; transient private Config config; - public boolean rounded; - public boolean border; - public OneColor bgColor; - public OneColor borderColor; - public float cornerRadius; - public float borderSize; - public double xUnscaled; - public double yUnscaled; - public float scale; - public float paddingX; - public float paddingY; - - /** - * @param enabled If the hud is enabled - * @param x X-coordinate of hud on a 1080p display - * @param y Y-coordinate of hud on a 1080p display - * @param scale Scale of the hud - * @param rounded If the corner is rounded or not - * @param cornerRadius Radius of the corner - * @param paddingX Horizontal background padding - * @param paddingY Vertical background padding - * @param bgColor Background color - * @param border If the hud has a border or not - * @param borderSize Thickness of the border - * @param borderColor The color of the border - */ - public Hud(boolean enabled, int x, int y, float scale, boolean rounded, int cornerRadius, int paddingX, int paddingY, OneColor bgColor, boolean border, float borderSize, OneColor borderColor) { - this.enabled = enabled; - this.scale = scale; - this.rounded = rounded; - this.cornerRadius = cornerRadius; - this.paddingX = paddingX; - this.paddingY = paddingY; - this.bgColor = bgColor; - this.border = border; - this.borderSize = borderSize; - this.borderColor = borderColor; - if (x / 1920d <= 0.5d) xUnscaled = x / 1920d; - else xUnscaled = (x + getWidth(scale)) / 1920d; - if (y / 1080d <= 0.5d) yUnscaled = y / 1080d; - else yUnscaled = (y + getHeight(scale)) / 1090d; - } + public final Position position; + protected float scale; /** * @param enabled If the hud is enabled @@ -90,8 +48,10 @@ public abstract class Hud { * @param y Y-coordinate of hud on a 1080p display * @param scale Scale of the hud */ - public Hud(boolean enabled, int x, int y, int scale) { - this(enabled, x, y, scale, false, 2, 5, 5, new OneColor(0, 0, 0, 120), false, 2, new OneColor(0, 0, 0)); + public Hud(boolean enabled, float x, float y, float scale) { + this.enabled = enabled; + this.scale = scale; + position = new Position(x, y, getWidth(scale, true), getHeight(scale, true)); } /** @@ -99,153 +59,103 @@ public abstract class Hud { * @param x X-coordinate of hud on a 1080p display * @param y Y-coordinate of hud on a 1080p display */ - public Hud(boolean enabled, int x, int y) { - this(enabled, x, y, 1, false, 2, 5, 5, new OneColor(0, 0, 0, 120), false, 2, new OneColor(0, 0, 0)); + public Hud(boolean enabled, float x, float y) { + this(enabled, x, y, 1); } /** * @param enabled If the hud is enabled */ public Hud(boolean enabled) { - this(enabled, 0, 0, 1, false, 2, 5, 5, new OneColor(0, 0, 0, 120), false, 2, new OneColor(0, 0, 0)); + this(enabled, 0, 0, 1); } - /** - * Function called when drawing the hud - * - * @param x Top left x-coordinate of the hud - * @param y Top left y-coordinate of the hud - * @param scale Scale of the hud - */ - public abstract void draw(UMatrixStack matrices, int x, int y, float scale); + public Hud() { + this(false, 0, 0, 1); + } /** - * Function called when drawing the example version of the hud. - * This is used in for example, the hud editor gui. + * Function called when drawing the hud * - * @param x Top left x-coordinate of the hud - * @param y Top left y-coordinate of the hud - * @param scale Scale of the hud + * @param matrices The UMatrixStack used for rendering in higher versions + * @param x Top left x-coordinate of the hud + * @param y Top left y-coordinate of the hud + * @param scale Scale of the hud + * @param example If the HUD is being rendered in example form */ - public void drawExample(UMatrixStack matrices, int x, int y, float scale) { - draw(matrices, x, y, scale); - } + protected abstract void draw(UMatrixStack matrices, float x, float y, float scale, boolean example); /** - * @param scale Scale of the hud + * @param scale Scale of the hud + * @param example If the HUD is being rendered in example form * @return The width of the hud */ - public abstract int getWidth(float scale); + protected abstract float getWidth(float scale, boolean example); /** - * @param scale Scale of the hud + * @param scale Scale of the hud + * @param example If the HUD is being rendered in example form * @return The height of the hud */ - public abstract int getHeight(float scale); - - /** - * @param scale Scale of the hud - * @return The width of the example version of the hud - */ - public int getExampleWidth(float scale) { - return getWidth(scale); - } - - /** - * @param scale Scale of the hud - * @return The height of the example version of the hud - */ - public int getExampleHeight(float scale) { - return getHeight(scale); - } + protected abstract float getHeight(float scale, boolean example); /** - * @return If the background should be drawn + * Function to do things before rendering anything + * + * @param example If the HUD is being rendered in example form */ - public boolean drawBackground() { - return true; + protected void preRender(boolean example) { } /** * Draw the background, the hud and all childed huds, used by HudCore - * - * @param x X-coordinate - * @param y Y-coordinate - * @param scale Scale of the hud - * @param background If background should be drawn or not */ - public void drawAll(UMatrixStack matrices, float x, float y, float scale, boolean background) { - if (!showInGuis && Platform.getGuiPlatform().getCurrentScreen() != null && !(Platform.getGuiPlatform().getCurrentScreen() instanceof OneConfigGui)) return; - if (!showInChat && Platform.getGuiPlatform().isInChat()) return; - if (!showInDebug && Platform.getGuiPlatform().isInDebug()) return; - if (background && drawBackground()) drawBackground(x, y, getWidth(scale), getHeight(scale), scale); - draw(matrices, (int) (x + paddingX * scale / 2f), (int) (y + paddingY * scale / 2f), scale); + public void drawAll(UMatrixStack matrices, boolean example) { + if (!example && !shouldShow()) return; + preRender(example); + position.setSize(getWidth(scale, example), getHeight(scale, example)); + draw(matrices, position.getX(), position.getY(), scale, example); } - /** - * Draw example version of the background, the hud and all childed huds, used by HudGui - * - * @param x X-coordinate - * @param y Y-coordinate - * @param scale Scale of the hud - * @param background If background should be drawn or not - */ - public void drawExampleAll(UMatrixStack matrices, float x, float y, float scale, boolean background) { - if (background) drawBackground(x, y, getWidth(scale), getHeight(scale), scale); - drawExample(matrices, (int) (x + paddingX * scale / 2f), (int) (y + paddingY * scale / 2f), scale); + protected boolean shouldShow() { + if (!showInGuis && Platform.getGuiPlatform().getCurrentScreen() != null && !(Platform.getGuiPlatform().getCurrentScreen() instanceof OneConfigGui)) + return false; + if (!showInChat && Platform.getGuiPlatform().isInChat()) return false; + return showInDebug || !Platform.getGuiPlatform().isInDebug(); } /** - * Draw example version of the background, the hud and all childed huds, used by HudGui - * - * @param x X-coordinate - * @param y Y-coordinate - * @param width Width of the hud - * @param height Height of the hud - * @param scale Scale of the hud + * @return If the hud is enabled */ - private void drawBackground(float x, float y, float width, float height, float scale) { - RenderManager.setupAndDraw(true, (vg) -> { - if (rounded) { - RenderManager.drawRoundedRect(vg, x, y, (width + paddingX * scale), (height + paddingY * scale), bgColor.getRGB(), cornerRadius * scale); - if (border) - RenderManager.drawHollowRoundRect(vg, x - borderSize * scale, y - borderSize * scale, (width + paddingX * scale) + borderSize * scale, (height + paddingY * scale) + borderSize * scale, borderColor.getRGB(), cornerRadius * scale, borderSize * scale); - } else { - RenderManager.drawRect(vg, x, y, (width + paddingX * scale), (height + paddingY * scale), bgColor.getRGB()); - if (border) - RenderManager.drawHollowRoundRect(vg, x - borderSize * scale, y - borderSize * scale, (width + paddingX * scale) + borderSize * scale, (height + paddingY * scale) + borderSize * scale, borderColor.getRGB(), 0, borderSize * scale); - } - }); + public boolean isEnabled() { + return enabled && (config == null || config.enabled); } /** - * @param screenWidth width of the screen - * @return X-coordinate of the hud + * Set the config to disable accordingly, intended for internal use + * + * @param config The config instance */ - public float getXScaled(int screenWidth) { - if (xUnscaled <= 0.5) - return (int) (screenWidth * xUnscaled); - return (float) (screenWidth - (1d - xUnscaled) * screenWidth - (getWidth(scale) + paddingX * scale)); + public void setConfig(Config config) { + this.config = config; } /** - * @param screenHeight height of the screen - * @return Y-coordinate of the hud + * @return The scale of the Hud */ - public float getYScaled(int screenHeight) { - if (yUnscaled <= 0.5) return (int) (screenHeight * yUnscaled); - return (float) (screenHeight - (1d - yUnscaled) * screenHeight - (getHeight(scale) + paddingY * scale)); + public float getScale() { + return scale; } /** - * @return If the hud is enabled + * Set a new scale value + * + * @param scale The new scale + * @param example If the HUD is being rendered in example form */ - public boolean isEnabled() { - return enabled && (config == null || config.enabled); - } - - public void setConfig(Config config) { - this.config = config; + public void setScale(float scale, boolean example) { + this.scale = scale; + position.updateSizePosition(getWidth(scale, example), getHeight(scale, example)); } @Switch( diff --git a/src/main/java/cc/polyfrost/oneconfig/hud/Position.java b/src/main/java/cc/polyfrost/oneconfig/hud/Position.java new file mode 100644 index 0000000..1b3bbb7 --- /dev/null +++ b/src/main/java/cc/polyfrost/oneconfig/hud/Position.java @@ -0,0 +1,279 @@ +package cc.polyfrost.oneconfig.hud; + +import cc.polyfrost.oneconfig.config.annotations.Exclude; +import cc.polyfrost.oneconfig.libs.universal.UResolution; +import com.google.gson.annotations.SerializedName; + +public class Position { + private AnchorPosition anchor; + private float x; + private float y; + @Exclude + private float width; + @Exclude + private float height; + + /** + * Position object used for huds + * + * @param x The X coordinate + * @param y The Y coordinate + * @param width The width of the HUD + * @param height The height of the HUD + * @param screenWidth The width of the screen to initialize the position width + * @param screenHeight The height of the screen to initialize the position width + */ + public Position(float x, float y, float width, float height, float screenWidth, float screenHeight) { + setSize(width, height); + setPosition(x, y, screenWidth, screenHeight); + } + + /** + * Position object used for huds + * + * @param x The X coordinate + * @param y The Y coordinate + * @param width The width of the HUD + * @param height The height of the HUD + */ + public Position(float x, float y, float width, float height) { + this(x, y, width, height, 1920, 1080); + } + + /** + * Set the position + * + * @param x The X coordinate + * @param y The Y coordinate + * @param screenWidth The screen width + * @param screenHeight The screen height + */ + public void setPosition(float x, float y, float screenWidth, float screenHeight) { + float rightX = x + width; + float bottomY = y + height; + + if (x <= screenWidth / 3f && y <= screenHeight / 3f) + this.anchor = AnchorPosition.TOP_LEFT; + else if (rightX >= screenWidth / 3f * 2f && y <= screenHeight / 3f) + this.anchor = AnchorPosition.TOP_RIGHT; + else if (x <= screenWidth / 3f && bottomY >= screenHeight / 3f * 2f) + this.anchor = AnchorPosition.BOTTOM_LEFT; + else if (rightX >= screenWidth / 3f * 2f && bottomY >= screenHeight / 3f * 2f) + this.anchor = AnchorPosition.BOTTOM_RIGHT; + else if (y <= screenHeight / 3f) + this.anchor = AnchorPosition.TOP_CENTER; + else if (x <= screenWidth / 3f) + this.anchor = AnchorPosition.MIDDLE_LEFT; + else if (rightX >= screenWidth / 3f * 2f) + this.anchor = AnchorPosition.MIDDLE_RIGHT; + else if (bottomY >= screenHeight / 3f * 2f) + this.anchor = AnchorPosition.BOTTOM_CENTER; + else + this.anchor = AnchorPosition.MIDDLE_CENTER; + + this.x = x - getAnchorX(screenWidth) + getAnchorX(width); + this.y = y - getAnchorY(screenHeight) + getAnchorY(height); + } + + /** + * Set the position + * + * @param x The X coordinate + * @param y The Y coordinate + */ + public void setPosition(float x, float y) { + setPosition(x, y, UResolution.getScaledWidth(), UResolution.getScaledHeight()); + } + + /** + * Set the size of the position + * + * @param width The width + * @param height The height + */ + public void setSize(float width, float height) { + this.width = width; + this.height = height; + } + + /** + * Update the position so the top left corner stays in the same spot + * + * @param width The width + * @param height The height + */ + public void updateSizePosition(float width, float height) { + float x = getX(); + float y = getY(); + setSize(width, height); + setPosition(x, y); + } + + /** + * Get the X coordinate scaled to the size of the screen + * + * @param screenWidth The width of the screen + * @return The X coordinate + */ + public float getX(float screenWidth) { + return x + getAnchorX(screenWidth) - getAnchorX(width); + } + + /** + * Get the X coordinate scaled to the size of the screen + * + * @return The X coordinate + */ + public float getX() { + return getX(UResolution.getScaledWidth()); + } + + /** + * Get the Y coordinate scaled to the size of the screen + * + * @param screenHeight The height of the screen + * @return The Y coordinate + */ + public float getY(float screenHeight) { + return y + getAnchorY(screenHeight) - getAnchorY(height); + } + + /** + * Get the Y coordinate scaled to the size of the screen + * + * @return The Y coordinate + */ + public float getY() { + return getY(UResolution.getScaledHeight()); + } + + /** + * Get the X coordinate scaled to the size of the screen of the right corner + * + * @param screenWidth The width of the screen + * @return The X coordinate of the right corner + */ + public float getRightX(float screenWidth) { + return getX(screenWidth) + width; + } + + /** + * Get the X coordinate scaled to the size of the screen of the right corner + * + * @return The X coordinate of the right corner + */ + public float getRightX() { + return getRightX(UResolution.getScaledWidth()); + } + + /** + * Get the Y coordinate scaled to the size of the screen of the bottom corner + * + * @param screenHeight The width of the screen + * @return The Y coordinate of the bottom corner + */ + public float getBottomY(float screenHeight) { + return getY(screenHeight) + height; + } + + /** + * Get the Y coordinate scaled to the size of the screen of the bottom corner + * + * @return The Y coordinate of the bottom corner + */ + public float getBottomY() { + return getBottomY(UResolution.getScaledHeight()); + } + + /** + * Get the center X coordinate + * + * @param screenWidth The width of the screen + * @return The center X coordinate + */ + public float getCenterX(float screenWidth) { + return getX(screenWidth) + width / 2f; + } + + /** + * Get the center X coordinate + * + * @return The center X coordinate + */ + public float getCenterX() { + return getCenterX(UResolution.getScaledWidth()); + } + + /** + * Get the center Y coordinate + * + * @param screenHeight The width of the screen + * @return The center Y coordinate + */ + public float getCenterY(float screenHeight) { + return getY(screenHeight) + height / 2f; + } + + /** + * Get the center Y coordinate + * + * @return The center Y coordinate + */ + public float getCenterY() { + return getCenterY(UResolution.getScaledHeight()); + } + + /** + * @return The width of the position + */ + public float getWidth() { + return width; + } + + /** + * @return The height of the position + */ + public float getHeight() { + return height; + } + + private float getAnchorX(float value) { + return value * anchor.x; + } + + private float getAnchorY(float value) { + return value * anchor.y; + } + + /** + * Position of the anchors were the position is relative too + */ + public enum AnchorPosition { + @SerializedName("0") + TOP_LEFT(0f, 0f), + @SerializedName("1") + TOP_CENTER(0.5f, 0f), + @SerializedName("2") + TOP_RIGHT(1f, 0f), + @SerializedName("3") + MIDDLE_LEFT(0f, 0.5f), + @SerializedName("4") + MIDDLE_CENTER(0.5f, 0.5f), + @SerializedName("5") + MIDDLE_RIGHT(1f, 0.5f), + @SerializedName("6") + BOTTOM_LEFT(0f, 1f), + @SerializedName("7") + BOTTOM_CENTER(0.5f, 1f), + @SerializedName("8") + BOTTOM_RIGHT(1f, 1f); + + public final float x; + public final float y; + + AnchorPosition(float x, float y) { + this.x = x; + this.y = y; + } + } +} diff --git a/src/main/java/cc/polyfrost/oneconfig/hud/SingleTextHud.java b/src/main/java/cc/polyfrost/oneconfig/hud/SingleTextHud.java index d3ce8f2..5380be5 100644 --- a/src/main/java/cc/polyfrost/oneconfig/hud/SingleTextHud.java +++ b/src/main/java/cc/polyfrost/oneconfig/hud/SingleTextHud.java @@ -22,56 +22,25 @@ public abstract class SingleTextHud extends TextHud { * * @return The new text */ - protected abstract String getText(); + protected abstract String getText(boolean example); /** * This function is called every frame * * @return The new text, null to use the cached value */ - protected String getTextFrequent() { + protected String getTextFrequent(boolean example) { return null; } - /** - * This function is called every tick in the move GUI - * - * @return The new text - */ - protected String getExampleText() { - return getText(); - } - - /** - * This function is called every frame in the move GUI - * - * @return The new text, null to use the cached value - */ - protected String getExampleTextFrequent() { - return getTextFrequent(); - } - - @Override - protected void getLines(List lines) { - lines.add(getCompleteText(getText())); - } - - @Override - protected void getLinesFrequent(List lines) { - String text = getTextFrequent(); - if (text == null) return; - lines.clear(); - lines.add(getCompleteText(text)); - } - @Override - protected void getExampleLines(List lines) { - lines.add(getCompleteText(getExampleText())); + protected void getLines(List lines, boolean example) { + lines.add(getCompleteText(getText(example))); } @Override - protected void getExampleLinesFrequent(List lines) { - String text = getExampleTextFrequent(); + protected void getLinesFrequent(List lines, boolean example) { + String text = getTextFrequent(example); if (text == null) return; lines.clear(); lines.add(getCompleteText(text)); @@ -104,16 +73,16 @@ public abstract class SingleTextHud extends TextHud { @Switch( name = "Brackets" ) - public boolean brackets = false; + protected boolean brackets = false; @Text( name = "Title" ) - public String title; + protected String title; @Dropdown( name = "Title Location", options = {"Left", "Right"} ) - public int titleLocation = 0; + protected int titleLocation = 0; } \ No newline at end of file diff --git a/src/main/java/cc/polyfrost/oneconfig/hud/TextHud.java b/src/main/java/cc/polyfrost/oneconfig/hud/TextHud.java index 8dd8ac3..b4857d8 100644 --- a/src/main/java/cc/polyfrost/oneconfig/hud/TextHud.java +++ b/src/main/java/cc/polyfrost/oneconfig/hud/TextHud.java @@ -15,21 +15,20 @@ import cc.polyfrost.oneconfig.renderer.RenderManager; import java.util.ArrayList; import java.util.List; -public abstract class TextHud extends Hud { +public abstract class TextHud extends BasicHud { protected transient List lines = new ArrayList<>(); private transient int width; - private transient int height; @Color( name = "Text Color" ) - public OneColor color = new OneColor(255, 255, 255); + protected OneColor color = new OneColor(255, 255, 255); @Dropdown( name = "Text Type", options = {"No Shadow", "Shadow", "Full Shadow"} ) - public int textType = 0; + protected int textType = 0; public TextHud(boolean enabled, int x, int y) { super(enabled, x, y); @@ -45,59 +44,72 @@ public abstract class TextHud extends Hud { * * @param lines Empty ArrayList to add your hud text too */ - protected abstract void getLines(List lines); + protected abstract void getLines(List lines, boolean example); /** * This function is called every frame * * @param lines The current lines of the hud */ - protected void getLinesFrequent(List lines) { + protected void getLinesFrequent(List lines, boolean example) { + } + + @Override + public void draw(UMatrixStack matrices, float x, float y, float scale, boolean example) { + if (lines == null || lines.size() == 0) return; + float textY = y; + for (String line : lines) { + drawLine(line, x, textY, scale); + textY += 12 * scale; + } } /** - * This function is called every tick in the move GUI + * Function that can be overwritten to implement different behavior easily * - * @param lines Empty ArrayList to add your hud text too + * @param line The line + * @param x The X coordinate + * @param y The Y coordinate + * @param scale The scale */ - protected void getExampleLines(List lines) { - getLines(lines); + protected void drawLine(String line, float x, float y, float scale) { + RenderManager.drawScaledString(line, x, y, color.getRGB(), RenderManager.TextType.toType(textType), scale); } /** - * This function is called every frame in the move GUI + * Function that can be overwritten to implement different behavior easily * - * @param lines The current lines of the hud + * @param line The line + * @return The width of the line (scaled accordingly) */ - protected void getExampleLinesFrequent(List lines) { - getLinesFrequent(lines); + protected float getLineWidth(String line, float scale) { + return Platform.getGLPlatform().getStringWidth(line) * scale; } @Override - public void draw(UMatrixStack matrices, int x, int y, float scale) { - if (!HudCore.editing) getLinesFrequent(lines); - else getExampleLinesFrequent(lines); - if (lines == null) return; + protected void preRender(boolean example) { + getLinesFrequent(lines, example); + } - int textY = y; - width = 0; + @Override + protected float getWidth(float scale, boolean example) { + if (lines == null) return 0; + float width = 0; for (String line : lines) { - RenderManager.drawScaledString(line, x, textY, color.getRGB(), RenderManager.TextType.toType(textType), scale); - width = Math.max(width, Platform.getGLPlatform().getStringWidth(line)); - textY += 12 * scale; + width = Math.max(width, getLineWidth(line, scale)); } - height = (int) ((textY - y) / scale - 3); + return width; } @Override - public int getWidth(float scale) { - return (int) (width * scale); + protected float getHeight(float scale, boolean example) { + return lines == null ? 0 : (lines.size() * 12 - 4) * scale; } @Override - public int getHeight(float scale) { - return (int) (height * scale); + public boolean shouldDrawBackground() { + return super.shouldDrawBackground() && lines != null && lines.size() > 0; } private class TickHandler { @@ -105,8 +117,7 @@ public abstract class TextHud extends Hud { private void onTick(TickEvent event) { if (event.stage != Stage.START || !isEnabled()) return; lines.clear(); - if (!HudCore.editing) getLines(lines); - else getExampleLines(lines); + getLines(lines, HudCore.editing); } } } \ No newline at end of file diff --git a/src/main/java/cc/polyfrost/oneconfig/internal/assets/Colors.java b/src/main/java/cc/polyfrost/oneconfig/internal/assets/Colors.java index 84f766f..9362873 100644 --- a/src/main/java/cc/polyfrost/oneconfig/internal/assets/Colors.java +++ b/src/main/java/cc/polyfrost/oneconfig/internal/assets/Colors.java @@ -42,9 +42,6 @@ public class Colors { public static final int ERROR_800_80 = new Color(145, 24, 24, 204).getRGB(); // Red 800 public static final int ERROR_300 = new Color(253, 155, 155).getRGB(); public static final int ERROR_300_80 = new Color(253, 155, 155, 204).getRGB(); - public static boolean ROUNDED_CORNERS = true; - public static final float CORNER_RADIUS_WIN = 20f; - public static final float CORNER_RADIUS = 12f; /** List of all colors used by Minecraft in its code. * Source: Click Here @@ -71,7 +68,5 @@ public class Colors { public static final int GRAY = new Color(170, 170, 170).getRGB(); // Mapped to 7 public static final int DARK_GRAY = new Color(85, 85, 85).getRGB(); // Mapped to 8 public static final int BLACK = new Color(0, 0, 0).getRGB(); // Mapped to 0 - - } } diff --git a/src/main/java/cc/polyfrost/oneconfig/internal/command/OneConfigCommand.java b/src/main/java/cc/polyfrost/oneconfig/internal/command/OneConfigCommand.java index 93d3c42..8aca921 100644 --- a/src/main/java/cc/polyfrost/oneconfig/internal/command/OneConfigCommand.java +++ b/src/main/java/cc/polyfrost/oneconfig/internal/command/OneConfigCommand.java @@ -1,6 +1,6 @@ package cc.polyfrost.oneconfig.internal.command; -import cc.polyfrost.oneconfig.gui.HudGui; +import cc.polyfrost.oneconfig.internal.gui.HudGui; import cc.polyfrost.oneconfig.gui.OneConfigGui; import cc.polyfrost.oneconfig.utils.gui.GuiUtils; import cc.polyfrost.oneconfig.utils.InputUtils; @@ -23,7 +23,7 @@ public class OneConfigCommand { private static class HUDSubCommand { @Main private static void main() { - GuiUtils.displayScreen(new HudGui(false)); + GuiUtils.displayScreen(new HudGui()); } } diff --git a/src/main/java/cc/polyfrost/oneconfig/internal/config/Preferences.java b/src/main/java/cc/polyfrost/oneconfig/internal/config/Preferences.java index cb93f0a..bf290b7 100644 --- a/src/main/java/cc/polyfrost/oneconfig/internal/config/Preferences.java +++ b/src/main/java/cc/polyfrost/oneconfig/internal/config/Preferences.java @@ -1,5 +1,6 @@ package cc.polyfrost.oneconfig.internal.config; +import cc.polyfrost.oneconfig.config.annotations.Exclude; import cc.polyfrost.oneconfig.config.annotations.KeyBind; import cc.polyfrost.oneconfig.config.annotations.Slider; import cc.polyfrost.oneconfig.config.annotations.Switch; @@ -9,7 +10,6 @@ import cc.polyfrost.oneconfig.internal.gui.BlurHandler; import cc.polyfrost.oneconfig.libs.universal.UKeyboard; import cc.polyfrost.oneconfig.platform.Platform; import cc.polyfrost.oneconfig.utils.TickDelay; -import cc.polyfrost.oneconfig.utils.gui.GuiUtils; public class Preferences extends InternalConfig { @Switch( @@ -23,10 +23,6 @@ public class Preferences extends InternalConfig { ) public static OneKeyBind oneConfigKeyBind = new OneKeyBind(UKeyboard.KEY_RSHIFT); - @Switch( - name = "Easter Egg 1" - ) - public static boolean easterEgg1 = true; @Switch( name = "Use custom GUI scale", @@ -43,6 +39,7 @@ public class Preferences extends InternalConfig { ) public static float customScale = 1f; + @Exclude private static Preferences INSTANCE; public Preferences() { diff --git a/src/main/java/cc/polyfrost/oneconfig/internal/config/compatibility/vigilance/VigilanceConfig.java b/src/main/java/cc/polyfrost/oneconfig/internal/config/compatibility/vigilance/VigilanceConfig.java index 689bf25..87ffc47 100644 --- a/src/main/java/cc/polyfrost/oneconfig/internal/config/compatibility/vigilance/VigilanceConfig.java +++ b/src/main/java/cc/polyfrost/oneconfig/internal/config/compatibility/vigilance/VigilanceConfig.java @@ -184,13 +184,10 @@ public class VigilanceConfig extends Config { } @Override - protected void setColor(OneColor color) { - if (cachedColor != color) { - Color newColor = new Color(color.getRGB(), true); - try { - this.color.set(parent, newColor); - } catch (IllegalAccessException ignored) { - } + protected void set(Object color) throws IllegalAccessException { + if (color instanceof OneColor) { + Color newColor = ((OneColor) color).toJavaColor(); + this.color.set(parent, newColor); } } } diff --git a/src/main/java/cc/polyfrost/oneconfig/internal/gui/HudGui.java b/src/main/java/cc/polyfrost/oneconfig/internal/gui/HudGui.java new file mode 100644 index 0000000..1710832 --- /dev/null +++ b/src/main/java/cc/polyfrost/oneconfig/internal/gui/HudGui.java @@ -0,0 +1,269 @@ +package cc.polyfrost.oneconfig.internal.gui; + +import cc.polyfrost.oneconfig.gui.GuiPause; +import cc.polyfrost.oneconfig.gui.OneConfigGui; +import cc.polyfrost.oneconfig.hud.Hud; +import cc.polyfrost.oneconfig.hud.Position; +import cc.polyfrost.oneconfig.internal.hud.utils.GrabOffset; +import cc.polyfrost.oneconfig.internal.hud.utils.SnappingLine; +import cc.polyfrost.oneconfig.internal.config.core.ConfigCore; +import cc.polyfrost.oneconfig.internal.hud.HudCore; +import cc.polyfrost.oneconfig.libs.universal.UKeyboard; +import cc.polyfrost.oneconfig.libs.universal.UMatrixStack; +import cc.polyfrost.oneconfig.libs.universal.UResolution; +import cc.polyfrost.oneconfig.libs.universal.UScreen; +import cc.polyfrost.oneconfig.renderer.RenderManager; +import cc.polyfrost.oneconfig.utils.MathUtils; +import cc.polyfrost.oneconfig.utils.gui.GuiUtils; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.awt.*; +import java.util.ArrayList; +import java.util.HashMap; + +public class HudGui extends UScreen implements GuiPause { + private static final int SNAPPING_DISTANCE = 10; + private final HashMap editingHuds = new HashMap<>(); + private boolean isDragging; + private boolean isSelecting; + private float selectX; + private float selectY; + private boolean isScaling; + + public HudGui() { + super(); + } + + @Override + public void initScreen(int width, int height) { + HudCore.editing = true; + UKeyboard.allowRepeatEvents(true); + super.initScreen(width, height); + } + + @Override + public void onDrawScreen(@NotNull UMatrixStack matrixStack, int mouseX, int mouseY, float partialTicks) { + int lineWidth = Math.max(1, Math.round(Math.min(UResolution.getWindowWidth() / 1920f, UResolution.getWindowHeight() / 1080f))); + if (isDragging) { + RenderManager.setupAndDraw(vg -> setHudPositions(vg, mouseX, mouseY, true, true, lineWidth)); + } else if (isSelecting) { + getHudsInRegion(selectX, selectY, mouseX, mouseY); + } else if (isScaling && editingHuds.size() == 1) { + RenderManager.setupAndDraw(vg -> { + Hud hud = (Hud) editingHuds.keySet().toArray()[0]; + Position position = hud.position; + float scaleX = getXSnapping(vg, lineWidth, mouseX, position.getWidth(), false); + hud.setScale(MathUtils.clamp((scaleX - position.getX()) / (position.getWidth() / hud.getScale()), 0.3f, 10f), true); + }); + } + + float scaleFactor = (float) UResolution.getScaleFactor(); + for (Hud hud : HudCore.huds) { + if (!hud.isEnabled()) continue; + Position position = hud.position; + hud.drawAll(matrixStack, true); + if (editingHuds.containsKey(hud)) + RenderManager.setupAndDraw(true, vg -> RenderManager.drawRect(vg, position.getX(), position.getY(), position.getWidth(), position.getHeight(), new Color(0, 128, 128, 60).getRGB())); + RenderManager.setupAndDraw(vg -> { + RenderManager.drawLine(vg, position.getX() * scaleFactor - lineWidth / 2f, position.getY() * scaleFactor - lineWidth / 2f, position.getRightX() * scaleFactor + lineWidth / 2f, position.getY() * scaleFactor - lineWidth / 2f, lineWidth, new Color(255, 255, 255).getRGB()); + RenderManager.drawLine(vg, position.getX() * scaleFactor - lineWidth / 2f, position.getBottomY() * scaleFactor + lineWidth / 2f, position.getRightX() * scaleFactor + lineWidth / 2f, position.getBottomY() * scaleFactor + lineWidth / 2f, lineWidth, new Color(255, 255, 255).getRGB()); + RenderManager.drawLine(vg, position.getX() * scaleFactor - lineWidth / 2f, position.getY() * scaleFactor - lineWidth / 2f, position.getX() * scaleFactor - lineWidth / 2f, position.getBottomY() * scaleFactor + lineWidth / 2f, lineWidth, new Color(255, 255, 255).getRGB()); + RenderManager.drawLine(vg, position.getRightX() * scaleFactor + lineWidth / 2f, position.getY() * scaleFactor - lineWidth / 2f, position.getRightX() * scaleFactor + lineWidth / 2f, position.getBottomY() * scaleFactor + lineWidth / 2f, lineWidth, new Color(255, 255, 255).getRGB()); + }); + if (editingHuds.containsKey(hud) && editingHuds.size() == 1) + RenderManager.setupAndDraw(true, vg -> RenderManager.drawRect(vg, position.getRightX() - 4, position.getBottomY() - 4, 8, 8, new Color(0, 128, 128, 200).getRGB())); + } + + if (isSelecting) + RenderManager.setupAndDraw(true, vg -> RenderManager.drawRect(vg, selectX, selectY, mouseX - selectX, mouseY - selectY, new Color(0, 0, 255, 100).getRGB())); + } + + @Override + public void onMouseClicked(double mouseX, double mouseY, int mouseButton) { + super.onMouseClicked(mouseX, mouseY, mouseButton); + if (mouseButton != 0) return; + isDragging = false; + isSelecting = false; + isScaling = false; + if (editingHuds.size() == 1) { + Position position = ((Hud) editingHuds.keySet().toArray()[0]).position; + if (mouseX >= position.getRightX() - 7 && mouseX <= position.getRightX() + 7 && mouseY >= position.getBottomY() - 7 && mouseY <= position.getBottomY() + 7) { + isScaling = true; + return; + } + } + for (Hud hud : HudCore.huds) { + if (!hud.isEnabled() || !mouseClickedHud(hud, (float) mouseX, (float) mouseY)) continue; + if (!editingHuds.containsKey(hud)) { + if (!UKeyboard.isCtrlKeyDown()) editingHuds.clear(); + editingHuds.put(hud, new GrabOffset()); + } + isDragging = true; + editingHuds.forEach((hud2, grabOffset) -> grabOffset.setOffset((float) (mouseX - hud2.position.getX()), (float) (mouseY - hud2.position.getY()))); + return; + } + isSelecting = true; + selectX = (float) mouseX; + selectY = (float) mouseY; + } + + @Override + public void onMouseReleased(double mouseX, double mouseY, int state) { + isDragging = false; + isSelecting = false; + isScaling = false; + super.onMouseReleased(mouseX, mouseY, state); + } + + @Override + public void onKeyPressed(int keyCode, char typedChar, @Nullable UKeyboard.Modifiers modifiers) { + if (isDragging) return; + editingHuds.forEach((hud, grabOffset) -> grabOffset.setOffset(-hud.position.getX(), -hud.position.getY())); + if (keyCode == UKeyboard.KEY_UP) { + setHudPositions(0f, -1f, false); + } else if (keyCode == UKeyboard.KEY_DOWN) { + setHudPositions(0f, 1f, false); + } else if (keyCode == UKeyboard.KEY_LEFT) { + setHudPositions(-1f, 0f, false); + } else if (keyCode == UKeyboard.KEY_RIGHT) { + setHudPositions(1f, 0f, false); + } + super.onKeyPressed(keyCode, typedChar, modifiers); + } + + @Override + public void onScreenClose() { + super.onScreenClose(); + HudCore.editing = false; + UKeyboard.allowRepeatEvents(false); + ConfigCore.saveAll(); + GuiUtils.displayScreen(OneConfigGui.create()); + } + + @Override + public boolean doesGuiPauseGame() { + return false; + } + + private void getHudsInRegion(float x1, float y1, float x2, float y2) { + if (x1 > x2) { + float temp = x1; + x1 = x2; + x2 = temp; + } + if (y1 > y2) { + float temp = y1; + y1 = y2; + y2 = temp; + } + + editingHuds.clear(); + for (Hud hud : HudCore.huds) { + if (!hud.isEnabled()) continue; + Position pos = hud.position; + if ((x1 <= pos.getX() && x2 >= pos.getX() || x1 <= pos.getRightX() && x2 >= pos.getRightX()) + && (y1 <= pos.getY() && y2 >= pos.getY() || y1 <= pos.getBottomY() && y2 >= pos.getBottomY())) + editingHuds.put(hud, new GrabOffset()); + } + } + + private void setHudPositions(long vg, float mouseX, float mouseY, boolean snap, boolean locked, int lineWidth) { + for (Hud hud : editingHuds.keySet()) { + GrabOffset grabOffset = editingHuds.get(hud); + Position position = hud.position; + float x = mouseX - grabOffset.getX(); + float y = mouseY - grabOffset.getY(); + + if (editingHuds.size() == 1 && snap) { + x = getXSnapping(vg, lineWidth, x, position.getWidth(), true); + y = getYSnapping(vg, lineWidth, y, position.getHeight(), true); + } + + if (locked) { + if (x < 0) x = 0; + else if (x + position.getWidth() > UResolution.getScaledWidth()) + x = UResolution.getScaledWidth() - position.getWidth(); + if (y < 0) y = 0; + else if (y + position.getHeight() > UResolution.getScaledHeight()) + y = UResolution.getScaledHeight() - position.getHeight(); + } + + position.setPosition(x, y); + } + } + + private void setHudPositions(float mouseX, float mouseY, boolean locked) { + setHudPositions(0, mouseX, mouseY, false, locked, 0); + } + + private boolean mouseClickedHud(Hud hud, float mouseX, float mouseY) { + Position position = hud.position; + return mouseX >= position.getX() && mouseX <= position.getRightX() && + mouseY >= position.getY() && mouseY <= position.getBottomY(); + } + + private float getXSnapping(long vg, float lineWidth, float x, float width, boolean multipleSides) { + ArrayList lines = getXSnappingLines(); + ArrayList snappingLines = new ArrayList<>(); + float closest = (float) (SNAPPING_DISTANCE / UResolution.getScaleFactor()); + for (Float line : lines) { + SnappingLine snappingLine = new SnappingLine(line, x, width, multipleSides); + if (Math.round(snappingLine.getDistance()) == Math.round(closest)) snappingLines.add(snappingLine); + else if (snappingLine.getDistance() < closest) { + closest = snappingLine.getDistance(); + snappingLines.clear(); + snappingLines.add(snappingLine); + } + } + if (snappingLines.isEmpty()) return x; + for (SnappingLine snappingLine : snappingLines) { + snappingLine.drawLine(vg, lineWidth, true); + } + return snappingLines.get(0).getPosition(); + } + + private ArrayList getXSnappingLines() { + ArrayList lines = new ArrayList<>(); + lines.add(UResolution.getScaledWidth() / 2f); + for (Hud hud : HudCore.huds) { + if (!hud.isEnabled() || editingHuds.containsKey(hud)) continue; + lines.add(hud.position.getX()); + lines.add(hud.position.getCenterX()); + lines.add(hud.position.getRightX()); + } + return lines; + } + + private float getYSnapping(long vg, float lineWidth, float y, float height, boolean multipleSides) { + ArrayList lines = getYSnappingLines(); + ArrayList snappingLines = new ArrayList<>(); + float closest = (float) (SNAPPING_DISTANCE / UResolution.getScaleFactor()); + for (Float line : lines) { + SnappingLine snappingLine = new SnappingLine(line, y, height, multipleSides); + if (Math.round(snappingLine.getDistance()) == Math.round(closest)) snappingLines.add(snappingLine); + else if (snappingLine.getDistance() < closest) { + closest = snappingLine.getDistance(); + snappingLines.clear(); + snappingLines.add(snappingLine); + } + } + if (snappingLines.isEmpty()) return y; + for (SnappingLine snappingLine : snappingLines) { + snappingLine.drawLine(vg, lineWidth, false); + } + return snappingLines.get(0).getPosition(); + } + + private ArrayList getYSnappingLines() { + ArrayList lines = new ArrayList<>(); + lines.add(UResolution.getScaledHeight() / 2f); + for (Hud hud : HudCore.huds) { + if (!hud.isEnabled() || editingHuds.containsKey(hud)) continue; + lines.add(hud.position.getY()); + lines.add(hud.position.getCenterY()); + lines.add(hud.position.getBottomY()); + } + return lines; + } +} \ No newline at end of file diff --git a/src/main/java/cc/polyfrost/oneconfig/internal/hud/HudCore.java b/src/main/java/cc/polyfrost/oneconfig/internal/hud/HudCore.java index 31604ed..812a8e4 100644 --- a/src/main/java/cc/polyfrost/oneconfig/internal/hud/HudCore.java +++ b/src/main/java/cc/polyfrost/oneconfig/internal/hud/HudCore.java @@ -16,7 +16,7 @@ public class HudCore { if (editing) return; for (Hud hud : huds) { if (!hud.isEnabled()) continue; - hud.drawAll(event.matrices, hud.getXScaled(UResolution.getScaledWidth()), hud.getYScaled(UResolution.getScaledHeight()), hud.scale, true); + hud.drawAll(event.matrices, false); } } } diff --git a/src/main/java/cc/polyfrost/oneconfig/internal/hud/utils/GrabOffset.java b/src/main/java/cc/polyfrost/oneconfig/internal/hud/utils/GrabOffset.java new file mode 100644 index 0000000..122ff77 --- /dev/null +++ b/src/main/java/cc/polyfrost/oneconfig/internal/hud/utils/GrabOffset.java @@ -0,0 +1,27 @@ +package cc.polyfrost.oneconfig.internal.hud.utils; + +public class GrabOffset { + private float offsetX; + private float offsetY; + + public GrabOffset(float offsetX, float offsetY) { + setOffset(offsetX, offsetY); + } + + public GrabOffset() { + this(0, 0); + } + + public void setOffset(float offsetX, float offsetY) { + this.offsetX = offsetX; + this.offsetY = offsetY; + } + + public float getX() { + return offsetX; + } + + public float getY() { + return offsetY; + } +} diff --git a/src/main/java/cc/polyfrost/oneconfig/internal/hud/utils/SnappingLine.java b/src/main/java/cc/polyfrost/oneconfig/internal/hud/utils/SnappingLine.java new file mode 100644 index 0000000..2a89e1f --- /dev/null +++ b/src/main/java/cc/polyfrost/oneconfig/internal/hud/utils/SnappingLine.java @@ -0,0 +1,49 @@ +package cc.polyfrost.oneconfig.internal.hud.utils; + +import cc.polyfrost.oneconfig.libs.universal.UResolution; +import cc.polyfrost.oneconfig.renderer.RenderManager; + +import java.awt.*; + +public class SnappingLine { + private static final int COLOR = new Color(138, 43, 226).getRGB(); + private final float line; + private final float distance; + private final float position; + + public SnappingLine(float line, float left, float size, boolean multipleSides) { + this.line = line; + float center = left + size / 2f; + float right = left + size; + float leftDistance = Math.abs(line - left); + float centerDistance = Math.abs(line - center); + float rightDistance = Math.abs(line - right); + if (!multipleSides || leftDistance <= centerDistance && leftDistance <= rightDistance) { + distance = leftDistance; + position = line; + } else if (centerDistance <= rightDistance) { + distance = centerDistance; + position = line - size / 2f; + } else { + distance = rightDistance; + position = line - size; + } + } + + public void drawLine(long vg, float lineWidth, boolean isX) { + float pos = (float) (line * UResolution.getScaleFactor() - lineWidth / 2f); + if (isX) { + RenderManager.drawLine(vg, pos, 0, pos, UResolution.getWindowHeight(), lineWidth, COLOR); + } else { + RenderManager.drawLine(vg, 0, pos, UResolution.getWindowWidth(), pos, lineWidth, COLOR); + } + } + + public float getPosition() { + return position; + } + + public float getDistance() { + return distance; + } +} diff --git a/src/main/java/cc/polyfrost/oneconfig/internal/init/OneConfigInit.java b/src/main/java/cc/polyfrost/oneconfig/internal/init/OneConfigInit.java index 1f70815..60480a2 100644 --- a/src/main/java/cc/polyfrost/oneconfig/internal/init/OneConfigInit.java +++ b/src/main/java/cc/polyfrost/oneconfig/internal/init/OneConfigInit.java @@ -2,10 +2,15 @@ package cc.polyfrost.oneconfig.internal.init; import org.spongepowered.asm.mixin.Mixins; +import java.io.File; + @SuppressWarnings("unused") public class OneConfigInit { public static void initialize(String[] args) { Mixins.addConfiguration("mixins.oneconfig.json"); + final File oneConfigDir = new File("./OneConfig"); + oneConfigDir.mkdirs(); + new File(oneConfigDir, "profiles").mkdirs(); } } diff --git a/src/main/java/cc/polyfrost/oneconfig/platform/NanoVGPlatform.java b/src/main/java/cc/polyfrost/oneconfig/platform/NanoVGPlatform.java new file mode 100644 index 0000000..af269ce --- /dev/null +++ b/src/main/java/cc/polyfrost/oneconfig/platform/NanoVGPlatform.java @@ -0,0 +1,42 @@ +package cc.polyfrost.oneconfig.platform; + +import org.jetbrains.annotations.Nullable; +import org.lwjgl.nanovg.NVGLUFramebuffer; + +public interface NanoVGPlatform { + int NVG_ANTIALIAS = 1; + int NVG_STENCIL_STROKES = 2; + int NVG_DEBUG = 4; + int NVG_IMAGE_NODELETE = 65536; + + int nnvglCreateImageFromHandle(long var0, int var2, int var3, int var4, int var5); + + int nvglCreateImageFromHandle(long ctx, int textureId, int w, int h, int flags); + + int nnvglImageHandle(long var0, int var2); + + int nvglImageHandle(long ctx, int image); + + long nnvgCreate(int var0); + + long nvgCreate(int flags); + + void nnvgDelete(long var0); + + void nvgDelete(long ctx); + + long nnvgluCreateFramebuffer(long var0, int var2, int var3, int var4); + + @Nullable + NVGLUFramebuffer nvgluCreateFramebuffer(long ctx, int w, int h, int imageFlags); + + void nnvgluBindFramebuffer(long var0, long var2); + + void nvgluBindFramebuffer(long ctx, @Nullable NVGLUFramebuffer fb); + + void nnvgluDeleteFramebuffer(long var0, long var2); + + void nvgluDeleteFramebuffer(long ctx, NVGLUFramebuffer fb); + + void triggerStaticInitialization(); +} diff --git a/src/main/java/cc/polyfrost/oneconfig/platform/Platform.java b/src/main/java/cc/polyfrost/oneconfig/platform/Platform.java index 62e9e2a..0fc2626 100644 --- a/src/main/java/cc/polyfrost/oneconfig/platform/Platform.java +++ b/src/main/java/cc/polyfrost/oneconfig/platform/Platform.java @@ -37,10 +37,16 @@ public interface Platform { return PlatformHolder.INSTANCE.i18nPlatform; } + static NanoVGPlatform getNanoVGPlatform() { + return PlatformHolder.INSTANCE.nvgPlatform; + } + boolean isCallingFromMinecraftThread(); int getMinecraftVersion(); + Loader getLoader(); + class PlatformHolder { private PlatformHolder() { @@ -53,5 +59,12 @@ public interface Platform { GLPlatform glPlatform = ServiceLoader.load(GLPlatform.class, GLPlatform.class.getClassLoader()).iterator().next(); GuiPlatform guiPlatform = ServiceLoader.load(GuiPlatform.class, GuiPlatform.class.getClassLoader()).iterator().next(); I18nPlatform i18nPlatform = ServiceLoader.load(I18nPlatform.class, I18nPlatform.class.getClassLoader()).iterator().next(); + + NanoVGPlatform nvgPlatform = ServiceLoader.load(NanoVGPlatform.class, NanoVGPlatform.class.getClassLoader()).iterator().next(); + } + + enum Loader { + FORGE, + FABRIC } } diff --git a/src/main/java/cc/polyfrost/oneconfig/renderer/RenderManager.java b/src/main/java/cc/polyfrost/oneconfig/renderer/RenderManager.java index 93c3c94..5f8ea11 100644 --- a/src/main/java/cc/polyfrost/oneconfig/renderer/RenderManager.java +++ b/src/main/java/cc/polyfrost/oneconfig/renderer/RenderManager.java @@ -7,6 +7,7 @@ import cc.polyfrost.oneconfig.internal.assets.Images; import cc.polyfrost.oneconfig.internal.assets.SVGs; import cc.polyfrost.oneconfig.libs.universal.UGraphics; import cc.polyfrost.oneconfig.libs.universal.UResolution; +import cc.polyfrost.oneconfig.platform.NanoVGPlatform; import cc.polyfrost.oneconfig.platform.Platform; import cc.polyfrost.oneconfig.renderer.font.Font; import cc.polyfrost.oneconfig.renderer.font.FontManager; @@ -14,7 +15,6 @@ import cc.polyfrost.oneconfig.utils.InputUtils; import cc.polyfrost.oneconfig.utils.NetworkUtils; import org.lwjgl.nanovg.NVGColor; import org.lwjgl.nanovg.NVGPaint; -import org.lwjgl.nanovg.NanoVGGL2; import org.lwjgl.opengl.GL11; import java.util.function.LongConsumer; @@ -52,7 +52,7 @@ public final class RenderManager { */ public static void setupAndDraw(boolean mcScaling, LongConsumer consumer) { if (vg == -1) { - vg = NanoVGGL2.nvgCreate(NanoVGGL2.NVG_ANTIALIAS); + vg = Platform.getNanoVGPlatform().nvgCreate(NanoVGPlatform.NVG_ANTIALIAS); if (vg == -1) { throw new RuntimeException("Failed to create nvg context"); } @@ -76,24 +76,6 @@ public final class RenderManager { GL11.glPopAttrib(); } - /** - * Draws a rectangle with the given parameters. - * - * @param vg The NanoVG context. - * @param x The x position. - * @param y The y position. - * @param width The width. - * @param height The height. - * @param color The color. - */ - public static void drawRectangle(long vg, float x, float y, float width, float height, int color) { // TODO make everything use this one day - if (Colors.ROUNDED_CORNERS) { - drawRoundedRect(vg, x, y, width, height, color, Colors.CORNER_RADIUS); - } else { - drawRect(vg, x, y, width, height, color); - } - } - /** * Draws a rectangle with the given parameters. * @@ -330,12 +312,12 @@ public final class RenderManager { *

This does NOT scale to Minecraft's GUI scale!

* * @see RenderManager#drawText(long, String, float, float, int, float, Font) - * @see InputUtils#isAreaClicked(int, int, int, int) + * @see InputUtils#isAreaClicked(float, float, float, float) */ public static void drawURL(long vg, String url, float x, float y, float size, Font font) { drawText(vg, url, x, y, Colors.PRIMARY_500, size, font); float length = getTextWidth(vg, url, size, font); - drawRectangle(vg, x, y + size / 2, length, 1, Colors.PRIMARY_500); + drawRect(vg, x, y + size / 2, length, 1, Colors.PRIMARY_500); if (InputUtils.isAreaClicked((int) (x - 2), (int) (y - 1), (int) (length + 4), (int) (size / 2 + 3))) { NetworkUtils.browseLink(url); } @@ -723,7 +705,7 @@ public final class RenderManager { Platform.getGLPlatform().drawText(text, x * (1 / scale), y * (1 / scale), color, true); break; case FULL: - drawBorderedText(text, x, y, color, 100); + drawBorderedText(text, x * (1 / scale), y * (1 / scale), color, 100); break; } UGraphics.GL.popMatrix(); diff --git a/src/main/java/cc/polyfrost/oneconfig/renderer/TextRenderer.java b/src/main/java/cc/polyfrost/oneconfig/renderer/TextRenderer.java index 95071d1..ed77942 100644 --- a/src/main/java/cc/polyfrost/oneconfig/renderer/TextRenderer.java +++ b/src/main/java/cc/polyfrost/oneconfig/renderer/TextRenderer.java @@ -122,12 +122,12 @@ public class TextRenderer { *

This does NOT scale to Minecraft's GUI scale!

* * @see RenderManager#drawText(long, String, float, float, int, float, Font) - * @see InputUtils#isAreaClicked(int, int, int, int) + * @see InputUtils#isAreaClicked(float, float, float, float) */ public static void drawURL(long vg, String url, float x, float y, float size, Font font) { drawText(vg, url, x, y, Colors.PRIMARY_500, size, font); float length = getTextWidth(vg, url, size, font); - RenderManager.drawRectangle(vg, x, y + size / 2, length, 1, Colors.PRIMARY_500); + RenderManager.drawRect(vg, x, y + size / 2, length, 1, Colors.PRIMARY_500); if (InputUtils.isAreaClicked((int) (x - 2), (int) (y - 1), (int) (length + 4), (int) (size / 2 + 3))) { NetworkUtils.browseLink(url); } diff --git a/src/main/java/cc/polyfrost/oneconfig/renderer/scissor/Scissor.java b/src/main/java/cc/polyfrost/oneconfig/renderer/scissor/Scissor.java index 62854ef..7ced323 100644 --- a/src/main/java/cc/polyfrost/oneconfig/renderer/scissor/Scissor.java +++ b/src/main/java/cc/polyfrost/oneconfig/renderer/scissor/Scissor.java @@ -25,7 +25,7 @@ public class Scissor { this.height = scissor.height; } - public boolean isInScissor(int x, int y) { + public boolean isInScissor(float x, float y) { return x >= this.x && x <= this.x + this.width && y >= this.y && y <= this.y + this.height; } } diff --git a/src/main/java/cc/polyfrost/oneconfig/utils/InputUtils.java b/src/main/java/cc/polyfrost/oneconfig/utils/InputUtils.java index 6582eaa..9466841 100644 --- a/src/main/java/cc/polyfrost/oneconfig/utils/InputUtils.java +++ b/src/main/java/cc/polyfrost/oneconfig/utils/InputUtils.java @@ -22,9 +22,9 @@ public final class InputUtils { * * @return true if mouse is over region, false if not. */ - public static boolean isAreaHovered(int x, int y, int width, int height, boolean ignoreBlock) { - int mouseX = mouseX(); - int mouseY = mouseY(); + public static boolean isAreaHovered(float x, float y, float width, float height, boolean ignoreBlock) { + float mouseX = mouseX(); + float mouseY = mouseY(); return (ignoreBlock || blockScissors.size() == 0 || !shouldBlock(mouseX, mouseY)) && mouseX > x && mouseY > y && mouseX < x + width && mouseY < y + height; } @@ -33,7 +33,7 @@ public final class InputUtils { * * @return true if mouse is over region, false if not. */ - public static boolean isAreaHovered(int x, int y, int width, int height) { + public static boolean isAreaHovered(float x, float y, float width, float height) { return isAreaHovered(x, y, width, height, false); } @@ -46,9 +46,9 @@ public final class InputUtils { * @param height the height of the region * @param ignoreBlock if true, will ignore * @return true if the mouse is clicked and is over the region, false if not - * @see InputUtils#isAreaHovered(int, int, int, int) + * @see InputUtils#isAreaHovered(float, float, float, float) */ - public static boolean isAreaClicked(int x, int y, int width, int height, boolean ignoreBlock) { + public static boolean isAreaClicked(float x, float y, float width, float height, boolean ignoreBlock) { return isAreaHovered(x, y, width, height, ignoreBlock) && isClicked(false); } @@ -60,9 +60,9 @@ public final class InputUtils { * @param width the width of the region * @param height the height of the region * @return true if the mouse is clicked and is over the region, false if not - * @see InputUtils#isAreaClicked(int, int, int, int, boolean) + * @see InputUtils#isAreaClicked(float, float, float, float, boolean) */ - public static boolean isAreaClicked(int x, int y, int width, int height) { + public static boolean isAreaClicked(float x, float y, float width, float height) { return isAreaClicked(x, y, width, height, false); } @@ -95,9 +95,9 @@ public final class InputUtils { * * @return the current mouse X position */ - public static int mouseX() { - if (OneConfigGui.INSTANCE == null) return (int) Platform.getMousePlatform().getMouseX(); //todo stop casting and actually use doubles - return (int) (Platform.getMousePlatform().getMouseX() / OneConfigGui.INSTANCE.getScaleFactor()); + public static float mouseX() { + if (OneConfigGui.INSTANCE == null) return (float) Platform.getMousePlatform().getMouseX(); + return (float) (Platform.getMousePlatform().getMouseX() / OneConfigGui.INSTANCE.getScaleFactor()); } /** @@ -109,9 +109,9 @@ public final class InputUtils { * * @return the current mouse Y position */ - public static int mouseY() { - if (OneConfigGui.INSTANCE == null) return (int) (UResolution.getWindowHeight() - Math.abs(Platform.getMousePlatform().getMouseY())); - return (int) ((UResolution.getWindowHeight() - Math.abs(Platform.getMousePlatform().getMouseY())) / OneConfigGui.INSTANCE.getScaleFactor()); + public static float mouseY() { + if (OneConfigGui.INSTANCE == null) return (float) (UResolution.getWindowHeight() - Math.abs(Platform.getMousePlatform().getMouseY())); + return (float) ((UResolution.getWindowHeight() - Math.abs(Platform.getMousePlatform().getMouseY())) / OneConfigGui.INSTANCE.getScaleFactor()); } /** @@ -122,7 +122,7 @@ public final class InputUtils { * @param width Width * @param height Height */ - public static Scissor blockInputArea(int x, int y, int width, int height) { + public static Scissor blockInputArea(float x, float y, float width, float height) { Scissor scissor = new Scissor(new Scissor(x, y, width, height)); blockScissors.add(scissor); return scissor; @@ -160,7 +160,7 @@ public final class InputUtils { return blockScissors.size() > 0; } - private static boolean shouldBlock(int x, int y) { + private static boolean shouldBlock(float x, float y) { for (Scissor block : blockScissors) { if (block.isInScissor(x, y)) return true; } diff --git a/src/main/java/cc/polyfrost/oneconfig/utils/commands/CommandManager.java b/src/main/java/cc/polyfrost/oneconfig/utils/commands/CommandManager.java index 16a2f8d..14a40c1 100644 --- a/src/main/java/cc/polyfrost/oneconfig/utils/commands/CommandManager.java +++ b/src/main/java/cc/polyfrost/oneconfig/utils/commands/CommandManager.java @@ -1,5 +1,6 @@ package cc.polyfrost.oneconfig.utils.commands; +import cc.polyfrost.oneconfig.libs.universal.ChatColor; import cc.polyfrost.oneconfig.utils.commands.annotations.Command; import cc.polyfrost.oneconfig.utils.commands.annotations.Main; import cc.polyfrost.oneconfig.utils.commands.annotations.SubCommand; @@ -63,7 +64,8 @@ public class CommandManager { if (clazz.isAnnotationPresent(Command.class)) { final Command annotation = clazz.getAnnotation(Command.class); - final InternalCommand root = new InternalCommand(annotation.value(), annotation.aliases(), annotation.description().trim().isEmpty() ? "Main command for " + annotation.value() : annotation.description(), null); + final InternalCommand root = new InternalCommand(annotation.value(), annotation.aliases(), annotation.description().trim().isEmpty() + ? "Main command for " + annotation.value() : annotation.description(), annotation.color(), null); for (Method method : clazz.getDeclaredMethods()) { if (method.isAnnotationPresent(Main.class) && method.getParameterCount() == 0) { root.invokers.add(new InternalCommand.InternalCommandInvoker(annotation.value(), annotation.aliases(), method, root)); @@ -79,7 +81,7 @@ public class CommandManager { for (Class clazz : classes) { if (clazz.isAnnotationPresent(SubCommand.class)) { SubCommand annotation = clazz.getAnnotation(SubCommand.class); - InternalCommand command = new InternalCommand(annotation.value(), annotation.aliases(), annotation.description(), parent); + InternalCommand command = new InternalCommand(annotation.value(), annotation.aliases(), annotation.description(), annotation.color() == ChatColor.RESET ? parent.color : annotation.color(), parent); for (Method method : clazz.getDeclaredMethods()) { if (method.isAnnotationPresent(Main.class)) { command.invokers.add(new InternalCommand.InternalCommandInvoker(annotation.value(), annotation.aliases(), method, command)); @@ -103,15 +105,17 @@ public class CommandManager { public final String name; public final String[] aliases; public final String description; + public final ChatColor color; public final ArrayList invokers = new ArrayList<>(); public final InternalCommand parent; public final ArrayList children = new ArrayList<>(); - public InternalCommand(String name, String[] aliases, String description, InternalCommand parent) { + public InternalCommand(String name, String[] aliases, String description, ChatColor color, InternalCommand parent) { this.name = name; this.aliases = aliases; this.description = description; this.parent = parent; + this.color = color; } public boolean isValid(String name, boolean tabCompletion) { diff --git a/src/main/java/cc/polyfrost/oneconfig/utils/commands/PlatformCommandManager.java b/src/main/java/cc/polyfrost/oneconfig/utils/commands/PlatformCommandManager.java index 1ab356c..617694c 100644 --- a/src/main/java/cc/polyfrost/oneconfig/utils/commands/PlatformCommandManager.java +++ b/src/main/java/cc/polyfrost/oneconfig/utils/commands/PlatformCommandManager.java @@ -13,18 +13,19 @@ public abstract class PlatformCommandManager { //TODO: someone make the help command actually look nice lmao protected String sendHelpCommand(CommandManager.InternalCommand root) { StringBuilder builder = new StringBuilder(); - builder.append(ChatColor.GOLD).append("Help for ").append(ChatColor.BOLD).append(root.name).append(ChatColor.RESET).append(ChatColor.GOLD).append(":\n"); - if (!root.description.isEmpty()) { - builder.append("\n").append(ChatColor.GOLD).append("Description: ").append(ChatColor.BOLD).append(root.description); - } - for (CommandManager.InternalCommand command : root.children) { - runThroughCommandsHelp(root.name, command, builder); - } - builder.append("\n").append(ChatColor.GOLD).append("Aliases: ").append(ChatColor.BOLD); + builder.append(root.color).append("Help for ").append(ChatColor.BOLD).append(root.name).append(ChatColor.RESET).append(root.color); int index = 0; for (String alias : root.aliases) { + if(index == 0) builder.append(" ("); ++index; - builder.append(alias).append(index < root.aliases.length ? ", " : ""); + builder.append("/").append(alias).append(index < root.aliases.length ? ", " : ")"); + } + builder.append(":\n"); + if (!root.description.isEmpty()) { + builder.append("\n").append(root.color).append("/").append(root.name).append(": ").append(ChatColor.BOLD).append(root.description); + } + for (CommandManager.InternalCommand command : root.children) { + runThroughCommandsHelp(root.name, command, builder); } builder.append("\n"); return builder.toString(); @@ -36,12 +37,12 @@ public abstract class PlatformCommandManager { if (declaringClass.isAnnotationPresent(SubCommand.class)) { String description = declaringClass.getAnnotation(SubCommand.class).description(); if (!description.isEmpty()) { - builder.append("\n").append(ChatColor.GOLD).append("Description: ").append(ChatColor.BOLD).append(description); + builder.append("\n"); } } } for (CommandManager.InternalCommand.InternalCommandInvoker invoker : command.invokers) { - builder.append("\n").append(ChatColor.GOLD).append("/").append(append).append(" ").append(command.name); + builder.append("\n").append(command.color).append("/").append(append).append(" ").append(command.name); for (Parameter parameter : invoker.method.getParameters()) { String name = parameter.getName(); if (parameter.isAnnotationPresent(Name.class)) { @@ -49,8 +50,14 @@ public abstract class PlatformCommandManager { } builder.append(" <").append(name).append(">"); } + int index = 0; + for (String alias : command.aliases) { + if(index == 0) builder.append(" ("); + ++index; + builder.append(alias).append(index < command.aliases.length ? ", " : ")"); + } if (!command.description.trim().isEmpty()) { - builder.append(": ").append(ChatColor.BOLD).append(command.description); + builder.append(": ").append(ChatColor.BOLD).append(command.color).append(command.description); } } for (CommandManager.InternalCommand subCommand : command.children) { diff --git a/src/main/java/cc/polyfrost/oneconfig/utils/commands/annotations/Command.java b/src/main/java/cc/polyfrost/oneconfig/utils/commands/annotations/Command.java index 41909c0..2bbf0bd 100644 --- a/src/main/java/cc/polyfrost/oneconfig/utils/commands/annotations/Command.java +++ b/src/main/java/cc/polyfrost/oneconfig/utils/commands/annotations/Command.java @@ -1,6 +1,7 @@ package cc.polyfrost.oneconfig.utils.commands.annotations; import cc.polyfrost.oneconfig.internal.command.OneConfigCommand; +import cc.polyfrost.oneconfig.libs.universal.ChatColor; import cc.polyfrost.oneconfig.utils.commands.CommandManager; import cc.polyfrost.oneconfig.utils.commands.arguments.ArgumentParser; @@ -107,6 +108,13 @@ public @interface Command { */ String description() default ""; + /** + * The color of the command. + * + * @return The color of the command. + */ + ChatColor color() default ChatColor.GOLD; + /** * Whether the command generates a help command. */ diff --git a/src/main/java/cc/polyfrost/oneconfig/utils/commands/annotations/SubCommand.java b/src/main/java/cc/polyfrost/oneconfig/utils/commands/annotations/SubCommand.java index 1bfbd53..eddca3c 100644 --- a/src/main/java/cc/polyfrost/oneconfig/utils/commands/annotations/SubCommand.java +++ b/src/main/java/cc/polyfrost/oneconfig/utils/commands/annotations/SubCommand.java @@ -1,5 +1,7 @@ package cc.polyfrost.oneconfig.utils.commands.annotations; +import cc.polyfrost.oneconfig.libs.universal.ChatColor; + import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -34,4 +36,11 @@ public @interface SubCommand { * @return The description of the command. */ String description() default ""; + + /** + * The color of the command. + * + * @return The color of the command. + */ + ChatColor color() default ChatColor.RESET; } diff --git a/src/main/java/cc/polyfrost/oneconfig/utils/gui/GuiUtils.java b/src/main/java/cc/polyfrost/oneconfig/utils/gui/GuiUtils.java index 63203e4..969654e 100644 --- a/src/main/java/cc/polyfrost/oneconfig/utils/gui/GuiUtils.java +++ b/src/main/java/cc/polyfrost/oneconfig/utils/gui/GuiUtils.java @@ -24,7 +24,6 @@ public final class GuiUtils { * Displays a screen after a tick, preventing mouse sync issues. * * @param screen the screen to display. - * @deprecated Not actually deprecated, but should not be used. */ @Deprecated public static void displayScreen(Object screen) { diff --git a/src/main/java/cc/polyfrost/oneconfig/utils/gui/OneUIScreen.java b/src/main/java/cc/polyfrost/oneconfig/utils/gui/OneUIScreen.java index 2dd961e..6a64251 100644 --- a/src/main/java/cc/polyfrost/oneconfig/utils/gui/OneUIScreen.java +++ b/src/main/java/cc/polyfrost/oneconfig/utils/gui/OneUIScreen.java @@ -37,16 +37,12 @@ public abstract class OneUIScreen extends UScreen implements GuiPause { } @Override - public void onDrawScreen(@NotNull UMatrixStack matrixStack, int mouseX, int mouseY, float partialTicks) { + public final void onDrawScreen(@NotNull UMatrixStack matrixStack, int mouseX, int mouseY, float partialTicks) { super.onDrawScreen(matrixStack, mouseX, mouseY, partialTicks); RenderManager.setupAndDraw(ignoreMinecraftScale(), vg -> draw(vg, partialTicks)); mouseDown = Platform.getMousePlatform().isButtonDown(0); } - /** - * This method is called when the screen is first opened. You can use it to set variables, initialize things, etc. - */ - public abstract void onScreenOpen(); /** * Use this method to draw things on the screen. It is called every render tick, and has a handy vg (NanoVG context) that can be used with the {@link RenderManager} to draw things. @@ -59,18 +55,7 @@ public abstract class OneUIScreen extends UScreen implements GuiPause { public abstract void draw(long vg, float partialTicks); /** - * This method is called when the screen is closed. You can use it to clean up things, etc. - */ - @Override - public abstract void onScreenClose(); - - @Override - public void initScreen(int width, int height) { - onScreenOpen(); - } - - /** - * Use this method to set weather or not to use the Minecraft scale on the GUI. Its default is true, and that is recommended for the NanoVG rendering. + * Use this method to set whether to use the Minecraft scale on the GUI. Its default is true, and that is recommended for the NanoVG rendering. */ public boolean ignoreMinecraftScale() { return true; @@ -79,42 +64,37 @@ public abstract class OneUIScreen extends UScreen implements GuiPause { /** * Get the current x position of the mouse. */ - public int getMouseX() { + protected float getMouseX() { return InputUtils.mouseX(); } /** * Get the current y position of the mouse. */ - public int getMouseY() { + protected float getMouseY() { return InputUtils.mouseY(); } - @Override - public void onMouseClicked(double mouseX, double mouseY, int mouseButton) { - super.onMouseClicked(mouseX, mouseY, mouseButton); - } - /** * Retrieve the click status of the mouse. This method uses a boolean to store the status of the mouse, so it will only return true once per click. (very useful) * * @param ignoreBlockClicks whether to ignore the current click blocker. */ - public boolean isClicked(boolean ignoreBlockClicks) { + protected boolean isClicked(boolean ignoreBlockClicks) { return mouseDown && !Platform.getMousePlatform().isButtonDown(0) && (!blockClicks || ignoreBlockClicks); } /** * Retrieve the click status of the mouse. This method uses a boolean to store the status of the mouse, so it will only return true once per click. (very useful) */ - public boolean isClicked() { + protected boolean isClicked() { return isClicked(false); } /** * Retrieve weather or not the mouse is currently down. Will constantly return true if its clicked. See {@link #isClicked()} for a method that only executes once per tick. */ - public boolean isMouseDown() { + protected boolean isMouseDown() { return Platform.getMousePlatform().isButtonDown(0); } @@ -131,4 +111,9 @@ public abstract class OneUIScreen extends UScreen implements GuiPause { public boolean isBlockingClicks() { return blockClicks; } + + @Override + public boolean doesGuiPauseGame() { + return false; + } } -- cgit