From 89a5b2437e5caa7fbbb4845918cb031117b3a922 Mon Sep 17 00:00:00 2001 From: Leo dev Date: Mon, 23 Jun 2025 16:49:09 +0200 Subject: [PATCH] fully functional store --- .../saturnclient/saturnclient/auth/Auth.java | 8 ++ .../saturnclient/cosmetics/Hats.java | 1 + .../saturnclient/ui2/components/Sidebar.java | 13 +-- .../saturnclient/ui2/elements/TabMenu.java | 73 +++++++++++++++++ .../saturnclient/ui2/resources/Textures.java | 1 + .../saturnclient/ui2/screens/ShiftMenu.java | 1 + .../saturnclient/ui2/screens/TitleMenu.java | 1 + .../screens/{ => cosmetics}/CloakMenu.java | 12 ++- .../ui2/screens/{ => cosmetics}/HatMenu.java | 14 +++- .../{Store.java => store/CloakStore.java} | 23 ++++-- .../ui2/screens/store/HatStore.java | 75 ++++++++++++++++++ .../textures/gui/components/shirt.png | Bin 0 -> 884 bytes 12 files changed, 203 insertions(+), 19 deletions(-) create mode 100644 src/main/java/org/saturnclient/ui2/elements/TabMenu.java rename src/main/java/org/saturnclient/ui2/screens/{ => cosmetics}/CloakMenu.java (77%) rename src/main/java/org/saturnclient/ui2/screens/{ => cosmetics}/HatMenu.java (74%) rename src/main/java/org/saturnclient/ui2/screens/{Store.java => store/CloakStore.java} (74%) create mode 100644 src/main/java/org/saturnclient/ui2/screens/store/HatStore.java create mode 100644 src/main/resources/assets/saturnclient/textures/gui/components/shirt.png diff --git a/src/main/java/org/saturnclient/saturnclient/auth/Auth.java b/src/main/java/org/saturnclient/saturnclient/auth/Auth.java index bf21829..e035f50 100644 --- a/src/main/java/org/saturnclient/saturnclient/auth/Auth.java +++ b/src/main/java/org/saturnclient/saturnclient/auth/Auth.java @@ -236,4 +236,12 @@ public class Auth { SaturnClient.LOGGER.error("Request failed", e); } } + + public static void buyHat(String name) { + try { + Network.write("buy_hat@hat=" + name); + } catch (Exception e) { + SaturnClient.LOGGER.error("Request failed", e); + } + } } diff --git a/src/main/java/org/saturnclient/saturnclient/cosmetics/Hats.java b/src/main/java/org/saturnclient/saturnclient/cosmetics/Hats.java index 4302290..408da52 100644 --- a/src/main/java/org/saturnclient/saturnclient/cosmetics/Hats.java +++ b/src/main/java/org/saturnclient/saturnclient/cosmetics/Hats.java @@ -6,6 +6,7 @@ import org.saturnclient.saturnclient.auth.SaturnPlayer; import org.saturnclient.saturnclient.auth.Auth; public class Hats { + public static final String[] ALL_HATS = { "horns_black", "horns_white", "halo", "halo_black" }; public static List availableHats = new ArrayList<>(); public static void initialize() { diff --git a/src/main/java/org/saturnclient/ui2/components/Sidebar.java b/src/main/java/org/saturnclient/ui2/components/Sidebar.java index 93df017..37315b9 100644 --- a/src/main/java/org/saturnclient/ui2/components/Sidebar.java +++ b/src/main/java/org/saturnclient/ui2/components/Sidebar.java @@ -9,11 +9,10 @@ import org.saturnclient.ui2.Element; import org.saturnclient.ui2.ElementContext; import org.saturnclient.ui2.RenderScope; import org.saturnclient.ui2.Utils; -import org.saturnclient.ui2.screens.CloakMenu; import org.saturnclient.ui2.screens.ConfigEditor; -import org.saturnclient.ui2.screens.HatMenu; import org.saturnclient.ui2.screens.ModMenu; -import org.saturnclient.ui2.screens.Store; +import org.saturnclient.ui2.screens.cosmetics.CloakMenu; +import org.saturnclient.ui2.screens.store.CloakStore; import net.minecraft.client.render.RenderLayer; import net.minecraft.util.Identifier; @@ -53,20 +52,16 @@ public class Sidebar extends Element { SaturnClient.client.setScreen(new ConfigEditor(SaturnClientConfig.config)); }, false), - new Sidebar.SidebarComponent(Textures.CLOAK, () -> { + new Sidebar.SidebarComponent(Textures.SHIRT, () -> { SaturnClient.client.setScreen(new CloakMenu()); }, false), - new Sidebar.SidebarComponent(Textures.HAT, () -> { - SaturnClient.client.setScreen(new HatMenu()); - }, false), - new Sidebar.SidebarComponent(Textures.CLOSE, () -> { onClose.run(); }, true), new Sidebar.SidebarComponent(Textures.STORE, () -> { - SaturnClient.client.setScreen(new Store()); + SaturnClient.client.setScreen(new CloakStore()); }, true), }; int active = 0; diff --git a/src/main/java/org/saturnclient/ui2/elements/TabMenu.java b/src/main/java/org/saturnclient/ui2/elements/TabMenu.java new file mode 100644 index 0000000..e640106 --- /dev/null +++ b/src/main/java/org/saturnclient/ui2/elements/TabMenu.java @@ -0,0 +1,73 @@ +package org.saturnclient.ui2.elements; + +import org.saturnclient.saturnclient.config.Property; +import org.saturnclient.saturnclient.config.ThemeManager; +import org.saturnclient.ui2.Element; +import org.saturnclient.ui2.ElementContext; +import org.saturnclient.ui2.RenderScope; +import org.saturnclient.ui2.Utils; + +import net.minecraft.util.Identifier; + +public class TabMenu extends Element { + private static ThemeManager theme = new ThemeManager("TabMenu", "hovering", "selected"); + private static Property bgColor = theme.property("bg-color", Property.color(0x90000000)); + private static Property iconFg = theme.property("icon-fg", Property.color(0xFFFFFFFF)); + private static Property iconBg = theme.property("icon-bg", Property.color(0x00000000)); + private static Property cornerRadius = theme.property("corner-radius", Property.integer(10)); + + static { + theme.propertyStateDefault("hovering", "icon-bg", -7643914); + } + + public static class TabMenuComponent { + Runnable onClick; + Identifier sprite; + + public TabMenuComponent(Identifier sprite, Runnable onClick) { + this.onClick = onClick; + this.sprite = sprite; + } + } + + TabMenuComponent[] components; + public int selectedScreen = 0; + + public TabMenu(int active, TabMenuComponent... components) { + this.components = components; + width = 25 * components.length + 6; + height = 30; + this.selectedScreen = active; + } + + @Override + public void render(RenderScope renderScope, ElementContext ctx) { + renderScope.drawRoundedRectangle(0, 0, width, height, cornerRadius.value, bgColor.value); + + int col = 0; + for (TabMenuComponent component : components) { + int x = 25 * col + 5; + if (ctx.isHovering(x, 5, 20, 20) || selectedScreen == col) { + theme.setState("hovering"); + } + + renderScope.drawRoundedRectangle(x, 5, 20, 20, cornerRadius.value, iconBg.value); + renderScope.drawTexture(component.sprite, x + 5, 10, 0, 0, 10, 10, iconFg.value); + + theme.setState(null); + col++; + } + } + + @Override + public void click(int mouseX, int mouseY) { + int col = 0; + for (TabMenuComponent component : components) { + int x = 25 * col + 5; + if (Utils.isHovering(mouseX - x, mouseY - 5, 20, 20, 1.0f)) { + component.onClick.run(); + } + col++; + } + } +} diff --git a/src/main/java/org/saturnclient/ui2/resources/Textures.java b/src/main/java/org/saturnclient/ui2/resources/Textures.java index c7bbfb8..1f62aa9 100644 --- a/src/main/java/org/saturnclient/ui2/resources/Textures.java +++ b/src/main/java/org/saturnclient/ui2/resources/Textures.java @@ -19,6 +19,7 @@ public class Textures { public static final Identifier RIGHT = Identifier.of("saturnclient", "textures/gui/components/right.png"); public static final Identifier STORE = Identifier.of("saturnclient", "textures/gui/components/store.png"); public static final Identifier COINS = Identifier.of("saturnclient", "textures/gui/components/coins.png"); + public static final Identifier SHIRT = Identifier.of("saturnclient", "textures/gui/components/shirt.png"); public static final Identifier LOGO = Identifier.of("saturnclient", "textures/logo/logo.png"); public static final Identifier REALISTIC_LOGO = Identifier.of("saturnclient", "textures/logo/realistic.png"); diff --git a/src/main/java/org/saturnclient/ui2/screens/ShiftMenu.java b/src/main/java/org/saturnclient/ui2/screens/ShiftMenu.java index 0a4b29e..004308e 100644 --- a/src/main/java/org/saturnclient/ui2/screens/ShiftMenu.java +++ b/src/main/java/org/saturnclient/ui2/screens/ShiftMenu.java @@ -4,6 +4,7 @@ import org.saturnclient.saturnclient.SaturnClient; import org.saturnclient.saturnclient.SaturnClientConfig; import org.saturnclient.saturnclient.menus.HudEditor; import org.saturnclient.ui2.resources.Textures; +import org.saturnclient.ui2.screens.cosmetics.CloakMenu; import org.saturnclient.ui2.Element; import org.saturnclient.ui2.SaturnScreen; import org.saturnclient.ui2.elements.Button; diff --git a/src/main/java/org/saturnclient/ui2/screens/TitleMenu.java b/src/main/java/org/saturnclient/ui2/screens/TitleMenu.java index 05e99c0..8bcde8e 100644 --- a/src/main/java/org/saturnclient/ui2/screens/TitleMenu.java +++ b/src/main/java/org/saturnclient/ui2/screens/TitleMenu.java @@ -4,6 +4,7 @@ import org.saturnclient.saturnclient.SaturnClient; import org.saturnclient.saturnclient.SaturnClientConfig; import org.saturnclient.saturnclient.menus.HudEditor; import org.saturnclient.ui2.resources.Textures; +import org.saturnclient.ui2.screens.cosmetics.CloakMenu; import org.saturnclient.ui2.SaturnScreen; import org.saturnclient.ui2.anim.Fade; import org.saturnclient.ui2.anim.SlideY; diff --git a/src/main/java/org/saturnclient/ui2/screens/CloakMenu.java b/src/main/java/org/saturnclient/ui2/screens/cosmetics/CloakMenu.java similarity index 77% rename from src/main/java/org/saturnclient/ui2/screens/CloakMenu.java rename to src/main/java/org/saturnclient/ui2/screens/cosmetics/CloakMenu.java index 904bf6f..aae0b06 100644 --- a/src/main/java/org/saturnclient/ui2/screens/CloakMenu.java +++ b/src/main/java/org/saturnclient/ui2/screens/cosmetics/CloakMenu.java @@ -1,5 +1,6 @@ -package org.saturnclient.ui2.screens; +package org.saturnclient.ui2.screens.cosmetics; +import org.saturnclient.saturnclient.SaturnClient; import org.saturnclient.saturnclient.auth.Auth; import org.saturnclient.saturnclient.auth.SaturnPlayer; import org.saturnclient.saturnclient.cosmetics.cloaks.Cloaks; @@ -9,6 +10,8 @@ import org.saturnclient.ui2.components.CosmeticPreview; import org.saturnclient.ui2.components.Sidebar; import org.saturnclient.ui2.components.SkinPreview; import org.saturnclient.ui2.elements.Scroll; +import org.saturnclient.ui2.elements.TabMenu; +import org.saturnclient.ui2.elements.TabMenu.TabMenuComponent; public class CloakMenu extends SaturnScreen { public CloakMenu() { @@ -49,5 +52,12 @@ public class CloakMenu extends SaturnScreen { draw(new SkinPreview(-30.0f, false).scale(3.5f).position(scroll.x + (scrollWidth - 220), scroll.y+40)); draw(new Sidebar(2, this::close).centerOffset(width, height, -(scrollWidth / 2 + 20), 0)); + + draw(new TabMenu(0, + new TabMenuComponent(Textures.CLOAK, () -> {}), + new TabMenuComponent(Textures.HAT, () -> { + SaturnClient.client.setScreen(new HatMenu()); + }) + ).centerOffset(width, height, 0, -195)); } } diff --git a/src/main/java/org/saturnclient/ui2/screens/HatMenu.java b/src/main/java/org/saturnclient/ui2/screens/cosmetics/HatMenu.java similarity index 74% rename from src/main/java/org/saturnclient/ui2/screens/HatMenu.java rename to src/main/java/org/saturnclient/ui2/screens/cosmetics/HatMenu.java index 06e89bb..d81a9cb 100644 --- a/src/main/java/org/saturnclient/ui2/screens/HatMenu.java +++ b/src/main/java/org/saturnclient/ui2/screens/cosmetics/HatMenu.java @@ -1,5 +1,6 @@ -package org.saturnclient.ui2.screens; +package org.saturnclient.ui2.screens.cosmetics; +import org.saturnclient.saturnclient.SaturnClient; import org.saturnclient.saturnclient.auth.Auth; import org.saturnclient.saturnclient.auth.SaturnPlayer; import org.saturnclient.saturnclient.cosmetics.Hats; @@ -9,6 +10,8 @@ import org.saturnclient.ui2.components.CosmeticPreview; import org.saturnclient.ui2.components.Sidebar; import org.saturnclient.ui2.components.SkinPreview; import org.saturnclient.ui2.elements.Scroll; +import org.saturnclient.ui2.elements.TabMenu; +import org.saturnclient.ui2.elements.TabMenu.TabMenuComponent; public class HatMenu extends SaturnScreen { public HatMenu() { @@ -48,6 +51,13 @@ public class HatMenu extends SaturnScreen { draw(new SkinPreview(170f, true).scale(3.5f).position(scroll.x + (scrollWidth - 220), scroll.y+40)); - draw(new Sidebar(3, this::close).centerOffset(width, height, -(scrollWidth / 2 + 20), 0)); + draw(new Sidebar(2, this::close).centerOffset(width, height, -(scrollWidth / 2 + 20), 0)); + + draw(new TabMenu(1, + new TabMenuComponent(Textures.CLOAK, () -> { + SaturnClient.client.setScreen(new CloakMenu()); + }), + new TabMenuComponent(Textures.HAT, () -> {}) + ).centerOffset(width, height, 0, -195)); } } diff --git a/src/main/java/org/saturnclient/ui2/screens/Store.java b/src/main/java/org/saturnclient/ui2/screens/store/CloakStore.java similarity index 74% rename from src/main/java/org/saturnclient/ui2/screens/Store.java rename to src/main/java/org/saturnclient/ui2/screens/store/CloakStore.java index 84beb75..ff338eb 100644 --- a/src/main/java/org/saturnclient/ui2/screens/Store.java +++ b/src/main/java/org/saturnclient/ui2/screens/store/CloakStore.java @@ -1,5 +1,6 @@ -package org.saturnclient.ui2.screens; +package org.saturnclient.ui2.screens.store; +import org.saturnclient.saturnclient.SaturnClient; import org.saturnclient.saturnclient.auth.Auth; import org.saturnclient.saturnclient.auth.SaturnPlayer; import org.saturnclient.saturnclient.cosmetics.cloaks.Cloaks; @@ -8,13 +9,15 @@ import org.saturnclient.ui2.components.CosmeticPreview; import org.saturnclient.ui2.components.Sidebar; import org.saturnclient.ui2.elements.ImageTexture; import org.saturnclient.ui2.elements.Scroll; +import org.saturnclient.ui2.elements.TabMenu; +import org.saturnclient.ui2.elements.TabMenu.TabMenuComponent; import org.saturnclient.ui2.elements.Text; import org.saturnclient.ui2.resources.Fonts; import org.saturnclient.ui2.resources.Textures; -public class Store extends SaturnScreen { - public Store() { - super("Store"); +public class CloakStore extends SaturnScreen { + public CloakStore() { + super("Hat Store"); } @Override @@ -37,15 +40,14 @@ public class Store extends SaturnScreen { int y = (111 + gy) * row; scroll.draw(new CosmeticPreview(cloak == player.cloak, Textures.getCloakPreview(cloak), () -> { Auth.buyCloak(cloak); - // This is to refresh the screen to remove the cloak because it's in our inventory - resize(client, width, height); + SaturnClient.client.setScreen(new CloakStore()); }).position(x, y)); String t = "100"; scroll.draw(new Text(t).position(x + Fonts.centerX(50, t, Text.font.value), y + 113).scale(0.5f)); - scroll.draw(new ImageTexture(Textures.COINS).dimensions(16, 16).position(x + Fonts.getWidth(t, Text.font.value), y + 112).scale(0.5f)); + scroll.draw(new ImageTexture(Textures.COINS).dimensions(16, 16).position(x + Fonts.getWidth(t, Text.font.value) - 1, y + 112).scale(0.5f)); if (col == 8) { col = 0; @@ -62,5 +64,12 @@ public class Store extends SaturnScreen { draw(scroll.dimensions(scrollWidth, 350).centerOffset(width, height, 15, 0)); draw(new Sidebar(5, this::close).centerOffset(width, height, -((scrollWidth - 30) / 2 + 20), 0)); + + draw(new TabMenu(0, + new TabMenuComponent(Textures.CLOAK, () -> {}), + new TabMenuComponent(Textures.HAT, () -> { + SaturnClient.client.setScreen(new HatStore()); + }) + ).centerOffset(width, height, 0, -195)); } } diff --git a/src/main/java/org/saturnclient/ui2/screens/store/HatStore.java b/src/main/java/org/saturnclient/ui2/screens/store/HatStore.java new file mode 100644 index 0000000..01155e4 --- /dev/null +++ b/src/main/java/org/saturnclient/ui2/screens/store/HatStore.java @@ -0,0 +1,75 @@ +package org.saturnclient.ui2.screens.store; + +import org.saturnclient.saturnclient.SaturnClient; +import org.saturnclient.saturnclient.auth.Auth; +import org.saturnclient.saturnclient.auth.SaturnPlayer; +import org.saturnclient.saturnclient.cosmetics.Hats; +import org.saturnclient.ui2.SaturnScreen; +import org.saturnclient.ui2.components.CosmeticPreview; +import org.saturnclient.ui2.components.Sidebar; +import org.saturnclient.ui2.elements.ImageTexture; +import org.saturnclient.ui2.elements.Scroll; +import org.saturnclient.ui2.elements.TabMenu; +import org.saturnclient.ui2.elements.TabMenu.TabMenuComponent; +import org.saturnclient.ui2.elements.Text; +import org.saturnclient.ui2.resources.Fonts; +import org.saturnclient.ui2.resources.Textures; + +public class HatStore extends SaturnScreen { + public HatStore() { + super("Hat Store"); + } + + @Override + public void ui() { + int p = 10; + int gx = 10; + int gy = 20; + + Scroll scroll = new Scroll(p); + + int row = 0; + int col = 0; + + SaturnPlayer player = Auth.players.get(Auth.uuid); + + if (player != null) { + for (String hat : Hats.ALL_HATS) { + if (!Hats.availableHats.contains(hat)) { + int x = (50 + gx) * col; + int y = (50 + gy) * row; + scroll.draw(new CosmeticPreview(hat == player.hat, Textures.getHatPreview(hat), () -> { + Auth.buyHat(hat); + SaturnClient.client.setScreen(new HatStore()); + }).dimensions(50, 50).position(x, y)); + + String t = "50"; + + scroll.draw(new Text(t).position(x + Fonts.centerX(50, t, Text.font.value), y + 53).scale(0.5f)); + + scroll.draw(new ImageTexture(Textures.COINS).dimensions(16, 16).position(x + Fonts.getWidth(t, Text.font.value) + 4, y + 52).scale(0.5f)); + + if (col == 8) { + col = 0; + row++; + } else { + col++; + } + } + } + } + + int scrollWidth = 480 + 40 + (gx * 2) + (p * 2); + + draw(scroll.dimensions(scrollWidth, 350).centerOffset(width, height, 15, 0)); + + draw(new Sidebar(5, this::close).centerOffset(width, height, -((scrollWidth - 30) / 2 + 20), 0)); + + draw(new TabMenu(1, + new TabMenuComponent(Textures.CLOAK, () -> { + SaturnClient.client.setScreen(new CloakStore()); + }), + new TabMenuComponent(Textures.HAT, () -> {}) + ).centerOffset(width, height, 0, -195)); + } +} diff --git a/src/main/resources/assets/saturnclient/textures/gui/components/shirt.png b/src/main/resources/assets/saturnclient/textures/gui/components/shirt.png new file mode 100644 index 0000000000000000000000000000000000000000..96a85f1f843ba6c204dc8dd4f8fc7d703393b04a GIT binary patch literal 884 zcmV-)1B?8LP)Px#L}ge>W=%~1DgXcg2mk?xX#fNO00031000^Q000001E2u_0{{R30RRC20H6W@ z1ONa40RR91FrWhf1ONa40RR91FaQ7m0NXcg3;+NE-bqA3RA>e5SG#T$K@hwnaOBL8 zIB)tYQJWkUsG1;SqJ8hF4Ri-7*P0dgF`9Y|h`dEihsT%+tZv|BW zVnz|oGgEufUN7DNYjR9yRn2e>9Q=92vd8g_4v;ZaDNe7E;Y4>&J*|~$?J0eX!4UH`uksa z8zwmmZak_5;JSdd$104pWyrTGy;Y0;{;#U|8Y*#PCN1{1>@yTz0JbKvFy2WrMKGi$ zFk3;?01hB8Aip5)3L=UCxkWCW?18;Bzkk5r53NBii^X5k;9Q&6rccYSuhBOCKh~cI zSoG246UZl!xC8kLC2nAHdOm^VElecHCy=;-$?5q7lD9CCAfG_u1}3NfS10hpZWsQ8 zx@GMY9b7jhzgA0PH8bV}Ue+>uy}elsQ8d3N+^@t=H&N&z