From 9d6a8d5c296838aff18bfc4a84c33cb30dd4a4ac Mon Sep 17 00:00:00 2001 From: Gerbagel Date: Mon, 17 Nov 2025 17:50:43 +0100 Subject: [PATCH 01/55] [Cosmere] Stripped SpiritwebMenu bare --- .../cosmere/client/ClientForgeEvents.java | 6 + .../leaf/cosmere/client/ClientModEvents.java | 13 +- .../cosmere/client/gui/SpiritwebMenu.java | 985 +----------------- 3 files changed, 35 insertions(+), 969 deletions(-) diff --git a/src/main/java/leaf/cosmere/client/ClientForgeEvents.java b/src/main/java/leaf/cosmere/client/ClientForgeEvents.java index fbeee02e1..d0677638e 100644 --- a/src/main/java/leaf/cosmere/client/ClientForgeEvents.java +++ b/src/main/java/leaf/cosmere/client/ClientForgeEvents.java @@ -8,6 +8,7 @@ import com.mojang.blaze3d.platform.InputConstants; import leaf.cosmere.api.Activator; import leaf.cosmere.api.manifestation.Manifestation; +import leaf.cosmere.client.gui.SpiritwebMenu; import leaf.cosmere.common.Cosmere; import leaf.cosmere.common.cap.entity.SpiritwebCapability; import leaf.cosmere.common.fog.FogManager; @@ -67,6 +68,11 @@ public static void onKey(InputEvent.Key event) SpiritwebCapability.get(player).ifPresent(spiritweb -> { + if (Keybindings.MANIFESTATION_MENU.consumeClick()) + { + Minecraft.getInstance().setScreen(new SpiritwebMenu(Component.literal("Spiritweb Menu"), spiritweb)); + } + Manifestation selected = spiritweb.getSelectedManifestation(); if (isKeyPressed(event, Keybindings.MANIFESTATIONS_DEACTIVATE)) { diff --git a/src/main/java/leaf/cosmere/client/ClientModEvents.java b/src/main/java/leaf/cosmere/client/ClientModEvents.java index 700798726..3256c3846 100644 --- a/src/main/java/leaf/cosmere/client/ClientModEvents.java +++ b/src/main/java/leaf/cosmere/client/ClientModEvents.java @@ -4,17 +4,20 @@ package leaf.cosmere.client; +import com.mojang.blaze3d.vertex.PoseStack; import leaf.cosmere.api.CosmereAPI; -import leaf.cosmere.client.gui.ISyncSpiritweb; import leaf.cosmere.client.gui.SpiritwebMenu; import leaf.cosmere.client.render.CosmereRenderers; import leaf.cosmere.common.Cosmere; import leaf.cosmere.common.cap.entity.SpiritwebCapability; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.renderer.texture.TextureAtlas; +import net.minecraft.world.inventory.InventoryMenu; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.client.event.EntityRenderersEvent; import net.minecraftforge.client.event.RegisterGuiOverlaysEvent; +import net.minecraftforge.client.event.TextureStitchEvent; import net.minecraftforge.client.gui.overlay.VanillaGuiOverlay; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod; @@ -72,16 +75,14 @@ public static void renderSpiritwebHUD(final GuiGraphics guiGraphics) final Minecraft mc = Minecraft.getInstance(); SpiritwebCapability.get(mc.player).ifPresent(cap -> { - SpiritwebCapability spiritweb = (SpiritwebCapability) cap; - //normal hud stuff - if (!(mc.screen instanceof ISyncSpiritweb)) + if (!(mc.screen instanceof SpiritwebMenu)) { - spiritweb.renderSelectedHUD(guiGraphics); + //cap.renderSelectedHUD(guiGraphics); } //actual menu stuff - SpiritwebMenu.instance.postRender(spiritweb); + //SpiritwebMenu.instance.postRender(spiritweb); }); } diff --git a/src/main/java/leaf/cosmere/client/gui/SpiritwebMenu.java b/src/main/java/leaf/cosmere/client/gui/SpiritwebMenu.java index d6157b707..0db0cf666 100644 --- a/src/main/java/leaf/cosmere/client/gui/SpiritwebMenu.java +++ b/src/main/java/leaf/cosmere/client/gui/SpiritwebMenu.java @@ -9,13 +9,11 @@ import com.mojang.blaze3d.platform.Window; import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.*; -import leaf.cosmere.api.IHasMetalType; -import leaf.cosmere.api.ISpiritwebSubmodule; -import leaf.cosmere.api.Manifestations; -import leaf.cosmere.api.Metals; +import leaf.cosmere.api.*; import leaf.cosmere.api.manifestation.Manifestation; import leaf.cosmere.api.math.MathHelper; import leaf.cosmere.api.math.Vector2; +import leaf.cosmere.api.spiritweb.ISpiritweb; import leaf.cosmere.client.Keybindings; import leaf.cosmere.common.Cosmere; import leaf.cosmere.common.cap.entity.SpiritwebCapability; @@ -24,11 +22,14 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.screens.Screen; +import net.minecraft.client.gui.screens.recipebook.RecipeBookPage; import net.minecraft.client.renderer.GameRenderer; import net.minecraft.client.resources.language.I18n; import net.minecraft.core.Direction; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; +import net.minecraft.stats.RecipeBook; +import net.minecraft.world.inventory.RecipeBookMenu; import org.jetbrains.annotations.NotNull; import org.lwjgl.opengl.GL11; @@ -38,35 +39,16 @@ import java.util.Set; import java.util.concurrent.TimeUnit; -public class SpiritwebMenu extends Screen implements ISyncSpiritweb +public class SpiritwebMenu extends Screen { - final double TEXT_DISTANCE = 30; - - public static final SpiritwebMenu instance = new SpiritwebMenu(); - private SpiritwebCapability spiritweb = null; - private float visibility = 0.0f; private Stopwatch lastChange = Stopwatch.createStarted(); - public Manifestation selectedManifestation = null; - public SidedMenuButton doAction = null; - private Manifestations.ManifestationTypes selectedPowerType = Manifestations.ManifestationTypes.ALLOMANCY; - - protected ArrayList radialMenuButtons = new ArrayList<>(); - protected ArrayList sidedMenuButtons = new ArrayList<>(); - protected ArrayList metalQuadrants = new ArrayList<>(); + private ISpiritweb spiritweb; - private final List m_infoText = new ArrayList<>(); - - protected SpiritwebMenu() + public SpiritwebMenu(Component pTitle, ISpiritweb spiritweb) { - super(Component.literal("Menu")); - this.minecraft = getMinecraft(); - } - - @Override - public boolean isPauseScreen() - { - return false; + super(pTitle); + this.spiritweb = spiritweb; } public void raiseVisibility() @@ -76,43 +58,20 @@ public void raiseVisibility() lastChange = Stopwatch.createStarted(); } - public void setScaledResolution(final int scaledWidth, final int scaledHeight) + private void CloseScreen() { - width = scaledWidth; - height = scaledHeight; + this.minecraft.setScreen(null); } @Override - public Minecraft getMinecraft() - { - return Minecraft.getInstance(); - } - - - public void postRender(SpiritwebCapability spiritweb) + public void render(@NotNull GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) { - if (this.minecraft.screen != SpiritwebMenu.instance && this.minecraft.screen != null) - { - return; - } - if (Keybindings.MANIFESTATION_MENU.consumeClick()) - { - final Window window = this.minecraft.getWindow(); - init(this.minecraft, window.getGuiScaledWidth(), window.getGuiScaledHeight()); - setScaledResolution(window.getGuiScaledWidth(), window.getGuiScaledHeight()); - this.spiritweb = spiritweb; - this.minecraft.setScreen(SpiritwebMenu.instance); - visibility = 0; - lastChange = Stopwatch.createStarted(); - - selectedManifestation = spiritweb.getSelectedManifestation(); + super.render(pGuiGraphics, pMouseX, pMouseY, pPartialTick); + raiseVisibility(); + final int start = (int) (visibility * 98) << 24; + final int end = (int) (visibility * 128) << 24; - SetupButtons(); - } - if (this.minecraft.screen == SpiritwebMenu.instance) - { - raiseVisibility(); - } + pGuiGraphics.fillGradient(0, 0, width, height, start, end); } @Override @@ -120,916 +79,16 @@ public boolean keyReleased(int pKeyCode, int pScanCode, int pModifiers) { if (Keybindings.MANIFESTATION_MENU.matches(pKeyCode, pScanCode)) { - for (RadialMenuButton radialMenuButton : radialMenuButtons) - { - if (radialMenuButton.highlighted) - { - Cosmere.packetHandler().sendToServer(new SetSelectedManifestationMessage(radialMenuButton.manifestation)); - break; - } - } - CloseScreen(); } - return super.keyReleased(pKeyCode, pScanCode, pModifiers); - } - - @Override - public boolean mouseClicked(final double mouseX, final double mouseY, final int button) - { - for (RadialMenuButton radialMenuButton : radialMenuButtons) - { - if (radialMenuButton.highlighted) - { - //final ResourceLocation selectedPower = radialMenuButton.manifestation.getRegistryName(); - //if (selectedPower.getNamespace().equals("feruchemy") && selectedPower.getPath().equals("nicrosil")) - if (radialMenuButton.manifestation.hasMenu()) - { - radialMenuButton.manifestation.openMenu(); - } - else - { - if (button == 0) - { - Cosmere.packetHandler().sendToServer(new ChangeManifestationModeMessage(radialMenuButton.manifestation, 1)); - } - else - { - Cosmere.packetHandler().sendToServer(new ChangeManifestationModeMessage(radialMenuButton.manifestation, -1)); - } - return true; - } - } - } - for (SidedMenuButton sidedMenuButton : sidedMenuButtons) - { - if (sidedMenuButton.highlighted) - { - if (sidedMenuButton.powerType != -1) - { - selectedPowerType = Manifestations.ManifestationTypes.valueOf(sidedMenuButton.powerType).get(); - SetupButtons(); - } - else if (sidedMenuButton.action != null) - { - //do other action - } - - return true; - } - } - return true; - } - - private void CloseScreen() - { - this.minecraft.setScreen(null); - } - - private static class SidedMenuButton - { - public double x1, x2; - public double y1, y2; - public boolean highlighted; - - public final ButtonAction action; - public final int powerType; - public int color; - public String name; - public Direction textSide; - - // NEW: logical layout info - public final int index; - public final int size; - - // For "action" buttons (if you ever use them) - public SidedMenuButton( - final String name, - final ButtonAction action, - final int index, - final int size, - final Direction textSide) - { - this.name = name; - this.action = action; - this.powerType = -1; - this.color = 0xffffff; - this.textSide = textSide; - this.index = index; - this.size = size; - } - - // For "power type" buttons (current use) - public SidedMenuButton( - final String name, - final int powerType, - final int index, - final int size, - final Direction textSide) - { - this.name = name; - this.action = null; - this.powerType = powerType; - this.color = 0xffffff; - this.textSide = textSide; - this.index = index; - this.size = size; - } - } - - - static class RadialMenuButton - { - - public final Manifestation manifestation; - public double centerX; - public double centerY; - public boolean highlighted; - - public RadialMenuButton(final Manifestation manifestation) - { - this.manifestation = manifestation; - } - - } - - static class MetalQuadrant - { - public final Metals.MetalType metalType; - public double centerX; - public double centerY; - public static double width = 50; - public static double height = 40; - - public MetalQuadrant(final Metals.MetalType metalType, double centerX, double centerY) - { - this.metalType = metalType; - this.centerX = centerX; - this.centerY = centerY; - } - - } - - public void onSpiritwebUpdated(SpiritwebCapability cap) - { - this.spiritweb = cap; - // if you want the radial menu to reflect changes immediately: - SetupButtons(); - } - - protected void SetupButtons() - { - radialMenuButtons.clear(); - sidedMenuButtons.clear(); - metalQuadrants.clear(); - - if (selectedPowerType == Manifestations.ManifestationTypes.ALLOMANCY || selectedPowerType == Manifestations.ManifestationTypes.FERUCHEMY) - { - // adding manually one-by-one was better than a for loop, as there would have to be a switch case anyway - - // add physical metals - double quadCenterX = width / 2F - MetalQuadrant.width * 3; // these multiplications are kinda random, but if it works, it works - double quadCenterY = height / 2F - MetalQuadrant.height * 0.75; - metalQuadrants.add(new MetalQuadrant(Metals.MetalType.IRON, - quadCenterX - MetalQuadrant.width / 2, - quadCenterY - MetalQuadrant.height / 2)); - - metalQuadrants.add(new MetalQuadrant(Metals.MetalType.STEEL, - quadCenterX + 2 + MetalQuadrant.width / 2, - quadCenterY - MetalQuadrant.height / 2)); - - metalQuadrants.add(new MetalQuadrant(Metals.MetalType.TIN, - quadCenterX - MetalQuadrant.width / 2, - quadCenterY + 2 + MetalQuadrant.height / 2)); - - metalQuadrants.add(new MetalQuadrant(Metals.MetalType.PEWTER, - quadCenterX + 2 + MetalQuadrant.width / 2, - quadCenterY + 2 + MetalQuadrant.height / 2)); - - // add mental metals - quadCenterX = width / 2 + MetalQuadrant.width * 3; - metalQuadrants.add(new MetalQuadrant(Metals.MetalType.ZINC, - quadCenterX - MetalQuadrant.width / 2, - quadCenterY - MetalQuadrant.height / 2)); - - metalQuadrants.add(new MetalQuadrant(Metals.MetalType.BRASS, - quadCenterX + 2 + MetalQuadrant.width / 2, - quadCenterY - MetalQuadrant.height / 2)); - - metalQuadrants.add(new MetalQuadrant(Metals.MetalType.COPPER, - quadCenterX - MetalQuadrant.width / 2, - quadCenterY + 2 + MetalQuadrant.height / 2)); - - metalQuadrants.add(new MetalQuadrant(Metals.MetalType.BRONZE, - quadCenterX + 2 + MetalQuadrant.width / 2, - quadCenterY + 2 + MetalQuadrant.height / 2)); - - // add enhancement metals - quadCenterX = width / 2F - MetalQuadrant.width * 3; - quadCenterY = height / 2F + MetalQuadrant.height * 1.75; - metalQuadrants.add(new MetalQuadrant(Metals.MetalType.ALUMINUM, - quadCenterX - MetalQuadrant.width / 2, - quadCenterY - MetalQuadrant.height / 2)); - - metalQuadrants.add(new MetalQuadrant(Metals.MetalType.DURALUMIN, - quadCenterX + 2 + MetalQuadrant.width / 2, - quadCenterY - MetalQuadrant.height / 2)); - - metalQuadrants.add(new MetalQuadrant(Metals.MetalType.CHROMIUM, - quadCenterX - MetalQuadrant.width / 2, - quadCenterY + 2 + MetalQuadrant.height / 2)); - - metalQuadrants.add(new MetalQuadrant(Metals.MetalType.NICROSIL, - quadCenterX + 2 + MetalQuadrant.width / 2, - quadCenterY + 2 + MetalQuadrant.height / 2)); - - // add temporal metals - quadCenterX = width / 2 + MetalQuadrant.width * 3; - metalQuadrants.add(new MetalQuadrant(Metals.MetalType.GOLD, - quadCenterX - MetalQuadrant.width / 2, - quadCenterY - MetalQuadrant.height / 2)); - - metalQuadrants.add(new MetalQuadrant(Metals.MetalType.ELECTRUM, - quadCenterX + 2 + MetalQuadrant.width / 2, - quadCenterY - MetalQuadrant.height / 2)); - - metalQuadrants.add(new MetalQuadrant(Metals.MetalType.CADMIUM, - quadCenterX - MetalQuadrant.width / 2, - quadCenterY + 2 + MetalQuadrant.height / 2)); - - metalQuadrants.add(new MetalQuadrant(Metals.MetalType.BENDALLOY, - quadCenterX + 2 + MetalQuadrant.width / 2, - quadCenterY + 2 + MetalQuadrant.height / 2)); - - // add atium - metalQuadrants.add(new MetalQuadrant(Metals.MetalType.ATIUM, - width / 2D, - quadCenterY + MetalQuadrant.height / 2)); - } - - final List availableManifestations = spiritweb.getAvailableManifestations(); - - if (availableManifestations.size() <= 16) - { - for (Manifestation manifestation : availableManifestations) - { - radialMenuButtons.add(new RadialMenuButton(manifestation)); - } - } - else - { - Set foundPowerTypes = new HashSet<>(); - - for (Manifestation manifestation : availableManifestations) - { - if (manifestation.getManifestationType() == selectedPowerType) - { - radialMenuButtons.add(new RadialMenuButton(manifestation)); - } - foundPowerTypes.add(manifestation.getManifestationType()); - } - - int index = 0; - int size = foundPowerTypes.size(); - - for (Manifestations.ManifestationTypes foundPowerType : foundPowerTypes) - { - sidedMenuButtons.add( - new SidedMenuButton( - foundPowerType.getName(), - foundPowerType.getID(), - index++, - size, - Direction.UP) - ); - } - } + return super.keyReleased(pKeyCode, pScanCode, pModifiers); } @Override - public void render(final GuiGraphics guiGraphics, final int mouseX, final int mouseY, final float partialTicks) - { - PoseStack matrixStack = guiGraphics.pose(); - if (spiritweb == null) - { - return; - } - - matrixStack.pushPose(); - - final int start = (int) (visibility * 98) << 24; - final int end = (int) (visibility * 128) << 24; - - guiGraphics.fillGradient(0, 0, width, height, start, end); - - //RenderSystem.disableTexture(); - RenderSystem.enableBlend(); - RenderSystem.blendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, 1, 0); - final Tesselator tessellator = Tesselator.getInstance(); - final BufferBuilder buffer = tessellator.getBuilder(); - - buffer.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR); - - final double mouseVecX = mouseX - width / 2f; - final double mouseVecY = (mouseY - height / 2f); - - final double middle_x = width / 2f; - final double middle_y = height / 2f; - - selectedManifestation = null; - doAction = null; - - //render the button backgrounds - renderRadialButtons(buffer, mouseVecX, mouseVecY, middle_x, middle_y); - renderSidedButtons(buffer, mouseVecX, mouseVecY, middle_x, middle_y); - - //render the metal quadrant backgrounds - renderMetalQuadrants(buffer); - - //draw out what we've asked for - tessellator.end(); - - drawIcons(guiGraphics, buffer, middle_x, middle_y); - - - // draw radial button strings - // Removing radial button strings since its so cluttered with the metal submenu - //renderRadialButtonStrings(guiGraphics, (int) middle_x, (int) middle_y); - //draw sided button strings - renderSidedButtonStrings(guiGraphics, middle_x, middle_y); - //draw quadrant strings - renderMetalQuadrantsStrings(guiGraphics); - //do extra text info stuff - renderAnyExtraInfoTexts(guiGraphics, (int) middle_x, (int) middle_y); - - matrixStack.popPose(); - } - - private void drawIcons(@NotNull GuiGraphics guiGraphics, BufferBuilder buffer, double middle_x, double middle_y) - { - PoseStack matrixStack = guiGraphics.pose(); - matrixStack.pushPose(); - //RenderSystem.enableTexture(); - RenderSystem.enableBlend(); - - //then we switch to icons - RenderSystem.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA); - RenderSystem.setShader(GameRenderer::getPositionTexShader); - //RenderSystem.bindTexture(Minecraft.getInstance().getTextureManager().getTexture(InventoryMenu.BLOCK_ATLAS).getId()); - //buffer.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX_COLOR); - - //put the icons on the region buttons - renderRadialButtonIcons(guiGraphics, middle_x, middle_y); - //put the icons on the sided buttons - renderSidedButtonIcons(guiGraphics, middle_x, middle_y); - - matrixStack.popPose(); - } - - private void renderAnyExtraInfoTexts(GuiGraphics guiGraphics, int middle_x, int middle_y) - { - int leftSideX = 10; - final int[] y = {(int) middle_y / 2}; - - if (selectedPowerType == Manifestations.ManifestationTypes.SANDMASTERY) - { - m_infoText.clear(); - - for (ISpiritwebSubmodule spiritwebSubmodule : spiritweb.getSubmodules().values()) - { - spiritwebSubmodule.collectMenuInfo(m_infoText); - } - - for (String s : m_infoText) - { - if (s.toLowerCase().contains("hydration")) - { - guiGraphics.drawString(font, s, leftSideX, y[0], 0xffffffff); - y[0] += 10; - } - } - } - - if (selectedManifestation == null) - { - return; - } - - int sidedMenuX = !sidedMenuButtons.isEmpty() ? (int) sidedMenuButtons.get(sidedMenuButtons.size() - 1).x2 + 35 : 0; - int sidedMenuY = !sidedMenuButtons.isEmpty() ? (int) sidedMenuButtons.get(sidedMenuButtons.size() - 1).y1 : -85; - - sidedMenuX += middle_x; - sidedMenuY += middle_y; - - String displayString = "+" + (int) selectedManifestation.getStrength(spiritweb, false) + " " + I18n.get(selectedManifestation.getTranslationKey()); - guiGraphics.drawString(font, displayString, sidedMenuX, sidedMenuY, 0xffffffff); - //todo mode translation - guiGraphics.drawString(font, "Mode: " + spiritweb.getMode(selectedManifestation), sidedMenuX, sidedMenuY + 10, 0xffffffff); - - } - - private void renderMetalQuadrantsStrings(GuiGraphics guiGraphics) - { - PoseStack matrixStack = guiGraphics.pose(); - m_infoText.clear(); - - List maniList = spiritweb.getAvailableManifestations(); - int maniListSize = maniList.size(); - boolean manifestationNotNull = selectedManifestation != null; - boolean inMetalSubmenu = (selectedPowerType == Manifestations.ManifestationTypes.ALLOMANCY || selectedPowerType == Manifestations.ManifestationTypes.FERUCHEMY) && maniListSize > 16; - boolean shouldShowAllomancy = maniListSize <= 16 && manifestationNotNull && selectedManifestation.getManifestationType() == Manifestations.ManifestationTypes.ALLOMANCY; - boolean shouldShowFeruchemy = maniListSize <= 16 && manifestationNotNull && selectedManifestation.getManifestationType() == Manifestations.ManifestationTypes.FERUCHEMY; - boolean manifestationIsSelected = shouldShowAllomancy || shouldShowFeruchemy; - - for (ISpiritwebSubmodule submodule : spiritweb.getSubmodules().values()) - { - submodule.collectMenuInfo(m_infoText); - } - - for (MetalQuadrant quad : metalQuadrants) - { - boolean foundNumber = false; - boolean selectedAllomancyType = selectedPowerType == Manifestations.ManifestationTypes.ALLOMANCY || shouldShowAllomancy; - boolean selectedFeruchemyType = selectedPowerType == Manifestations.ManifestationTypes.FERUCHEMY || shouldShowFeruchemy; - - // if there are submenus, or if a manifestation is selected in the menu, proceed - if (inMetalSubmenu || manifestationIsSelected) - { - for (String s : m_infoText) - { - if (((inMetalSubmenu && selectedAllomancyType) || shouldShowAllomancy) && s.toLowerCase().contains("a. " + quad.metalType.getName()) && maniList.contains(Manifestations.ManifestationTypes.ALLOMANCY.getManifestation(quad.metalType.getID()))) - { - String displayString = s.split(":")[1].stripLeading(); - guiGraphics.drawString(font, displayString, (int) (quad.centerX - font.width(displayString) / 2F), (int) quad.centerY + font.lineHeight, 0xffffffff); - - displayString = quad.metalType.getName().substring(0, 1).toUpperCase() + quad.metalType.getName().substring(1); - guiGraphics.drawString(font, displayString, (int) (quad.centerX - font.width(displayString) / 2F), (int) (quad.centerY - font.lineHeight * 1.5F), 0xffffffff); - - foundNumber = true; - break; - } - else if (((inMetalSubmenu && selectedFeruchemyType) || shouldShowFeruchemy) && s.toLowerCase().contains("f. " + quad.metalType.getName()) && maniList.contains(Manifestations.ManifestationTypes.FERUCHEMY.getManifestation(quad.metalType.getID()))) - { - String displayString = s.split(":")[1].stripLeading(); - guiGraphics.drawString(font, displayString, (int) (quad.centerX - font.width(displayString) / 2F), (int) quad.centerY + font.lineHeight, 0xffffffff); - - displayString = quad.metalType.getName().substring(0, 1).toUpperCase() + quad.metalType.getName().substring(1); - guiGraphics.drawString(font, displayString, (int) (quad.centerX - font.width(displayString) / 2F), (int) (quad.centerY - font.lineHeight * 1.5F), 0xffffffff); - - foundNumber = true; - break; - } - } - } - - boolean alloManiListContains = maniList.contains(Manifestations.ManifestationTypes.ALLOMANCY.getManifestation(quad.metalType.getID())); - boolean feruManiListContains = maniList.contains(Manifestations.ManifestationTypes.FERUCHEMY.getManifestation(quad.metalType.getID())); - - boolean shouldDrawMetalNames = !foundNumber && ((inMetalSubmenu && ((selectedAllomancyType && alloManiListContains) || (selectedFeruchemyType && feruManiListContains))) - || (!inMetalSubmenu && ((shouldShowAllomancy && alloManiListContains) || (shouldShowFeruchemy && feruManiListContains)))); - if (shouldDrawMetalNames) - { - String displayString; - displayString = "0"; - guiGraphics.drawString(font, displayString, (int) (quad.centerX - font.width(displayString) / 2F), (int) (quad.centerY + font.lineHeight), 0xffffffff); - - displayString = quad.metalType.getName().substring(0, 1).toUpperCase() + quad.metalType.getName().substring(1); - guiGraphics.drawString(font, displayString, (int) (quad.centerX - font.width(displayString) / 2F), (int) (quad.centerY - font.lineHeight * 1.5F), 0xffffffff); - } - } - } - - private void renderSidedButtonStrings(GuiGraphics guiGraphics, double middle_x, double middle_y) - { - for (final SidedMenuButton sideButton : sidedMenuButtons) - { - //but only if that sided button is highlighted - if (sideButton.highlighted) - { - final String text = I18n.get(sideButton.name); - - switch (sideButton.textSide) - { - case WEST: - guiGraphics.drawString(font, text, (int) (middle_x + sideButton.x1 - 8) - font.width(text), (int) (middle_y + sideButton.y1 + 6), 0xffffffff); - break; - case EAST: - guiGraphics.drawString(font, text, (int) (middle_x + sideButton.x2 + 8), (int) (middle_y + sideButton.y1 + 6), 0xffffffff); - break; - case UP: - guiGraphics.drawString(font, text, (int) (middle_x + (sideButton.x1 + sideButton.x2) * 0.5 - font.width(text) * 0.5), (int) (middle_y + sideButton.y1 - 14), 0xffffffff); - break; - case DOWN: - guiGraphics.drawString(font, text, (int) (middle_x + (sideButton.x1 + sideButton.x2) * 0.5 - font.width(text) * 0.5), (int) (middle_y + sideButton.y1 + 24), 0xffffffff); - break; - } - - } - } - } - - private void renderRadialButtonStrings(GuiGraphics guiGraphics, int middle_x, int middle_y) - { - for (final RadialMenuButton button : radialMenuButtons) - { - //but only if that button is highlighted - if (button.highlighted) - { - final double x = button.centerX; - final double y = button.centerY; - - int fixed_x = (int) x;//(x + TEXT_DISTANCE); - final int fixed_y = (int) y;//(y + TEXT_DISTANCE); - - //todo localisation check - final String text = I18n.get(button.manifestation.getTranslationKey()); - - fixed_x = (int) (x < 0 - ? fixed_x - (font.width(text) + TEXT_DISTANCE) - : fixed_x + TEXT_DISTANCE); - - guiGraphics.drawString(font, text, middle_x + fixed_x, middle_y + fixed_y, 0xffffffff); - - //no need to keep searching, we only keep one highlighted at a time. - break; - } - } - } - - private void renderSidedButtonIcons(GuiGraphics guiGraphics, double middleX, double middleY) - { - final StringBuilder stringBuilder = new StringBuilder(); - for (final SidedMenuButton button : sidedMenuButtons) - { - stringBuilder.setLength(0); - final double x = (button.x1 + button.x2) / 2 + 0.01; - final double y = (button.y1 + button.y2) / 2 + 0.01; - - stringBuilder - .append("textures/icon/") - .append(button.name) - .append(".png"); - - //RenderSystem.setShaderTexture(0, new ResourceLocation(button.name, stringBuilder.toString())); - guiGraphics.blit(new ResourceLocation(button.name, stringBuilder.toString()), (int) (middleX + x - 8), (int) (middleY + y - 8), 16, 16, 0, 0, 18, 18, 18, 18); - - } - } - - private void renderRadialButtonIcons(GuiGraphics guiGraphics, double middleX, double middleY) - { - final StringBuilder stringBuilder = new StringBuilder(); - for (final RadialMenuButton menuRegion : radialMenuButtons) - { - stringBuilder.setLength(0); - final double x = menuRegion.centerX; - final double y = menuRegion.centerY; - - final double scalex = 15 * 0.5; - final double scaley = 15 * 0.5; - final double x1 = x - scalex; - final double y1 = y - scaley; - - Manifestation mani = menuRegion.manifestation; - final Manifestations.ManifestationTypes manifestationType = mani.getManifestationType(); - String manifestationTypeName = manifestationType.getName(); - stringBuilder - .append("textures/icon/") - .append(manifestationTypeName) - .append("/"); - - switch (manifestationType) - { - case ALLOMANCY: - case FERUCHEMY: - if (mani instanceof IHasMetalType metalType) - { - stringBuilder.append(metalType.getMetalType().getName()); - } - break; - case SURGEBINDING: - stringBuilder.append(mani.getName()); - break; - case AON_DOR: - break; - case AWAKENING: - break; - } - - stringBuilder.append(".png"); - final ResourceLocation textureLocation = new ResourceLocation(mani.getRegistryName().getNamespace(), stringBuilder.toString()); - RenderSystem.setShaderTexture(0, textureLocation); - guiGraphics.blit(textureLocation, - (int) (middleX + x1), - (int) (middleY + y1), - 16, - 16, - 0, - 0, - 18, - 18, - 18, - 18); - - } - } - - private void renderSidedButtons(BufferBuilder buffer, double mouseVecX, double mouseVecY, double middle_x, double middle_y) - { - if (sidedMenuButtons.isEmpty()) - { - return; - } - - // How many buttons in this row - final int size = sidedMenuButtons.size(); - - // Match Nicrosil-style spacing: distance between button centers - final double spacing = 25.0; - final double half = (size - 1) / 2.0; - - // Vertical offset relative to center (was hardcoded -90 in SetupButtons before) - final double rowYOffset = -90.0; - - for (int i = 0; i < size; i++) - { - final SidedMenuButton button = sidedMenuButtons.get(i); - - // Center offsets relative to screen center - double centerX = spacing * (i - half); - double centerY = rowYOffset; - - // Button is 18x18 → half-size = 9 - double halfSize = 9.0; - button.x1 = centerX - halfSize; - button.x2 = centerX + halfSize; - button.y1 = centerY - halfSize; - button.y2 = centerY + halfSize; - - final float a = 0.5f; - float f; - - // Mouse is also relative to center here (mouseVecX/mouseVecY) - boolean inside = (button.x1 <= mouseVecX && button.x2 >= mouseVecX - && button.y1 <= mouseVecY && button.y2 >= mouseVecY); - - if (inside) - { - f = 1; - button.highlighted = true; - doAction = button; - } - else - { - button.highlighted = false; - - // Highlight selected power type, even if not hovered - f = selectedPowerType.getID() == button.powerType - ? 1 - : 0; - } - - // Draw the quad at center-relative position - buffer.vertex(middle_x + button.x1, middle_y + button.y1, 0).color(f, f, f, a).endVertex(); - buffer.vertex(middle_x + button.x1, middle_y + button.y2, 0).color(f, f, f, a).endVertex(); - buffer.vertex(middle_x + button.x2, middle_y + button.y2, 0).color(f, f, f, a).endVertex(); - buffer.vertex(middle_x + button.x2, middle_y + button.y1, 0).color(f, f, f, a).endVertex(); - } - } - - - private void renderMetalQuadrants(BufferBuilder buffer) - { - List maniList = spiritweb.getAvailableManifestations(); - boolean manifestationIsSelected = selectedManifestation != null && maniList.size() <= 16 && (selectedManifestation.getManifestationType() == Manifestations.ManifestationTypes.ALLOMANCY || selectedManifestation.getManifestationType() == Manifestations.ManifestationTypes.FERUCHEMY); - boolean allomancySubmenuOpen = selectedPowerType == Manifestations.ManifestationTypes.ALLOMANCY && maniList.size() > 16; - boolean feruchemySubmenuOpen = selectedPowerType == Manifestations.ManifestationTypes.FERUCHEMY && maniList.size() > 16; - boolean hasSubmenu = allomancySubmenuOpen || feruchemySubmenuOpen; - boolean allomancySelected = !hasSubmenu && manifestationIsSelected && selectedManifestation.getManifestationType() == Manifestations.ManifestationTypes.ALLOMANCY; - boolean feruchemySelected = !hasSubmenu && manifestationIsSelected && selectedManifestation.getManifestationType() == Manifestations.ManifestationTypes.FERUCHEMY; - int r = 0, g = 0, b = 0, a = 127; // 127 is halfway between 0 and 255, so 0.5 transparency - - for (MetalQuadrant quadrant : metalQuadrants) - { - Manifestation alloMani = Manifestations.ManifestationTypes.ALLOMANCY.getManifestation(quadrant.metalType.getID()); - Manifestation feruMani = Manifestations.ManifestationTypes.FERUCHEMY.getManifestation(quadrant.metalType.getID()); - - // if player doesn't have the manifestation, skip it - if ((hasSubmenu && ((allomancySubmenuOpen && maniList.contains(alloMani)) || (feruchemySubmenuOpen && maniList.contains(feruMani)))) - || (!hasSubmenu && ((allomancySelected && maniList.contains(alloMani)) || (feruchemySelected && maniList.contains(feruMani))))) - { - buffer.vertex(quadrant.centerX - MetalQuadrant.width / 2, quadrant.centerY - MetalQuadrant.height / 2, 0).color(r, g, b, a).endVertex(); - buffer.vertex(quadrant.centerX - MetalQuadrant.width / 2, quadrant.centerY + MetalQuadrant.height / 2, 0).color(r, g, b, a).endVertex(); - buffer.vertex(quadrant.centerX + MetalQuadrant.width / 2, quadrant.centerY + MetalQuadrant.height / 2, 0).color(r, g, b, a).endVertex(); - buffer.vertex(quadrant.centerX + MetalQuadrant.width / 2, quadrant.centerY - MetalQuadrant.height / 2, 0).color(r, g, b, a).endVertex(); - } - } - } - - private void renderRadialButtons(BufferBuilder buffer, double mouseVecX, double mouseVecY, double middle_x, double middle_y) - { - if (!radialMenuButtons.isEmpty()) - { - final float ring_inner_edge = -20; - final float ring_outer_edge = -60; - - // todo test if I can get down to one button only - final int totalButtons = radialMenuButtons.size(); - - Vector2 innerEdge; - Vector2 outerEdge; - - int drawMode = radialMenuButtons.size(); - - innerEdge = new Vector2(0, ring_inner_edge); - outerEdge = new Vector2(0, ring_outer_edge); - - int i = radialMenuButtons.size() - 1; - while (i >= 0) - { - RadialMenuButton region = radialMenuButtons.get(i); - //left side inner point - double x1m1; - double y1m1; - - //left side outer point - double x2m1; - double y2m1; - - //right side inner point - double x1m2; - double y1m2; - //right side outer point - double x2m2; - double y2m2; - - if (drawMode == 1) - { - //1 - x1m1 = outerEdge.x; - y1m1 = outerEdge.y; - outerEdge.Rotate(90); - - //2 - x2m1 = outerEdge.x; - y2m1 = outerEdge.y; - outerEdge.Rotate(90); - - //3 - x1m2 = outerEdge.x; - y1m2 = outerEdge.y; - outerEdge.Rotate(90); - - } - else if (drawMode == 2) - { - //1 - x1m1 = outerEdge.x; - y1m1 = outerEdge.y; - outerEdge.Rotate(60); - - //2 - x2m1 = outerEdge.x; - y2m1 = outerEdge.y; - outerEdge.Rotate(60); - - //3 - x1m2 = outerEdge.x; - y1m2 = outerEdge.y; - outerEdge.Rotate(60); - - } - else - { - - //left side inner point - x1m1 = innerEdge.x; - y1m1 = innerEdge.y; - - //left side outer point - x2m1 = outerEdge.x; - y2m1 = outerEdge.y; - - //rotate vectors around the point - innerEdge.Rotate(-(360f / totalButtons)); - outerEdge.Rotate(-(360f / totalButtons)); - - //right side inner point - x1m2 = innerEdge.x; - y1m2 = innerEdge.y; - - } - //4 or right side outer point - x2m2 = outerEdge.x; - y2m2 = outerEdge.y; - - //the center of a regular polygon can be found by adding up - // all corner positions and divide by the total count - region.centerX = (x1m1 + x2m1 + x1m2 + x2m2) / 4; - region.centerY = (y1m1 + y2m1 + y1m2 + y2m2) / 4; - - - float a = 0.5f; - float f = 0f; - - final boolean showHighlight; - if (drawMode <= 2) - { - showHighlight = - MathHelper.inTriangle( - x1m1, y1m1, - x2m1, y2m1, - x1m2, y1m2, - mouseVecX, mouseVecY) - || MathHelper.inTriangle( - x1m2, y1m2, - x2m2, y2m2, - x1m1, y1m1, - mouseVecX, mouseVecY); - } - else - { - showHighlight = - MathHelper.inTriangle( - x1m1, y1m1, - x2m2, y2m2, - x2m1, y2m1, - mouseVecX, mouseVecY) - || MathHelper.inTriangle( - x1m1, y1m1, - x1m2, y1m2, - x2m2, y2m2, - mouseVecX, mouseVecY); - } - - //if mouse is within the region, as defined by the two triangles - //if (begin_rad <= mouseAngle && mouseAngle <= end_rad && showHighlight) - if (showHighlight) - { - f = 0.1f; - region.highlighted = true; - selectedManifestation = region.manifestation; - } - else - { - region.highlighted = false; - } - - float lerpPositive = 0; - float lerpNegative = 0; - float green = 0; - - if (region.manifestation != null) - { - int mode = region.manifestation.getMode(spiritweb); - int modeMin = region.manifestation.modeMin(spiritweb); - int modeMax = region.manifestation.modeMax(spiritweb); - - if (region.manifestation.hasMenu()) - { - lerpPositive = 0.25f; - green = 0.25f; - lerpNegative = 0.25f; - a = 0.75f; - } - else if (mode > 0) - { - lerpPositive = MathHelper.InverseLerp(0, modeMax, mode) - 0.1f; - } - else if (mode < 0) - { - lerpNegative = MathHelper.InverseLerp(0, Math.abs(modeMin), Math.abs(mode)) - 0.1f; - } - } - - float r = lerpPositive + f; - float g = f + green; - float b = lerpNegative + f; - - if (drawMode <= 2) - { - buffer.vertex(middle_x + x2m1, middle_y + y2m1, 0).color(r, g, b, a).endVertex(); - buffer.vertex(middle_x + x1m1, middle_y + y1m1, 0).color(r, g, b, a).endVertex(); - } - else - { - //set the square pos - buffer.vertex(middle_x + x1m1, middle_y + y1m1, 0).color(r, g, b, a).endVertex(); - buffer.vertex(middle_x + x2m1, middle_y + y2m1, 0).color(r, g, b, a).endVertex(); - } - - buffer.vertex(middle_x + x2m2, middle_y + y2m2, 0).color(r, g, b, a).endVertex(); - buffer.vertex(middle_x + x1m2, middle_y + y1m2, 0).color(r, g, b, a).endVertex(); - - i--; - } - } - } - - public SpiritwebCapability getSpiritweb() + public boolean isPauseScreen() { - return spiritweb; + // no pause >:( + return false; } - } \ No newline at end of file From 100e7e5cb99f3af1769a6d4584e2cbcfb1eac2a6 Mon Sep 17 00:00:00 2001 From: Gerbagel Date: Sun, 23 Nov 2025 13:46:27 +0100 Subject: [PATCH 02/55] [Cosmere] Added Submenu registry and render calls --- .../client/gui/AllomancySpiritwebMenu.java | 44 ++++ .../client/gui/InnerRadialButton.java | 12 + .../client/gui/OuterRadialButton.java | 228 ++++++++++++++++++ .../AllomancySpiritwebSubmodule.java | 7 + .../leaf/cosmere/api/ISpiritwebSubmodule.java | 3 + .../client/FeruchemyClientSetup.java | 3 + .../client/gui/FeruchemySpiritwebMenu.java | 26 ++ .../FeruchemySpiritwebSubmodule.java | 9 + .../cosmere/client/ClientForgeEvents.java | 6 + .../cosmere/client/gui/SpiritwebMenu.java | 74 ++++-- .../cosmere/client/gui/SpiritwebRegistry.java | 32 +++ .../leaf/cosmere/client/gui/TabButton.java | 59 +++++ .../cap/entity/SpiritwebCapability.java | 6 +- 13 files changed, 482 insertions(+), 27 deletions(-) create mode 100644 src/allomancy/java/leaf/cosmere/allomancy/client/gui/AllomancySpiritwebMenu.java create mode 100644 src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java create mode 100644 src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java create mode 100644 src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/FeruchemySpiritwebMenu.java create mode 100644 src/main/java/leaf/cosmere/client/gui/SpiritwebRegistry.java create mode 100644 src/main/java/leaf/cosmere/client/gui/TabButton.java diff --git a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/AllomancySpiritwebMenu.java b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/AllomancySpiritwebMenu.java new file mode 100644 index 000000000..747bac0f2 --- /dev/null +++ b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/AllomancySpiritwebMenu.java @@ -0,0 +1,44 @@ +package leaf.cosmere.allomancy.client.gui; + +import leaf.cosmere.api.CosmereAPI; +import leaf.cosmere.common.cap.entity.SpiritwebCapability; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.client.player.LocalPlayer; +import net.minecraft.network.chat.Component; + +public class AllomancySpiritwebMenu extends Screen +{ + LocalPlayer player; + public AllomancySpiritwebMenu() + { + super(Component.literal("Allomancy")); + player = Minecraft.getInstance().player; + init(); + } + + @Override + protected void init() + { + CosmereAPI.logger.info("wow"); + SpiritwebCapability.get(player).ifPresent( (iSpiritweb -> { + CosmereAPI.logger.info("wahoo"); + addRenderableWidget(new OuterRadialButton(width/2, height/2, 0, iSpiritweb.getAvailableManifestations().get(0))); + })); +// for (int i = 0; i < spiritweb.getAvailableManifestations().size(); i++) +// { +// if (i < 8) +// { +// addRenderableWidget(new OuterRadialButton(width / 2, height / 2, i, spiritweb.getAvailableManifestations().get(i))); +// } +// } + } + + @Override + public void render(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) + { + pGuiGraphics.drawCenteredString(Minecraft.getInstance().font, "wow", pMouseX, pMouseY, 0xFFFFFFFF); + super.render(pGuiGraphics, pMouseX, pMouseY, pPartialTick); + } +} diff --git a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java new file mode 100644 index 000000000..97c9433b8 --- /dev/null +++ b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java @@ -0,0 +1,12 @@ +package leaf.cosmere.allomancy.client.gui; + +import net.minecraft.client.gui.components.Button; +import net.minecraft.network.chat.Component; + +public class InnerRadialButton extends Button +{ + protected InnerRadialButton(int pX, int pY, int pWidth, int pHeight, Component pMessage, OnPress pOnPress, CreateNarration pCreateNarration) + { + super(pX, pY, pWidth, pHeight, pMessage, pOnPress, pCreateNarration); + } +} diff --git a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java new file mode 100644 index 000000000..a7580bb23 --- /dev/null +++ b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java @@ -0,0 +1,228 @@ +package leaf.cosmere.allomancy.client.gui; + +import com.mojang.blaze3d.systems.RenderSystem; +import com.mojang.blaze3d.vertex.*; +import leaf.cosmere.api.IHasMetalType; +import leaf.cosmere.api.manifestation.Manifestation; +import leaf.cosmere.common.Cosmere; +import leaf.cosmere.common.network.packets.ChangeManifestationModeMessage; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.components.Button; +import net.minecraft.client.renderer.GameRenderer; +import net.minecraft.client.sounds.SoundManager; +import net.minecraft.network.chat.CommonComponents; +import net.minecraft.resources.ResourceLocation; +import org.jetbrains.annotations.NotNull; + +public class OuterRadialButton extends Button +{ + private static final int OUTER_RADIUS = 100; + private static final int INNER_RADIUS = 60; + private final double startAngle; + private final double endAngle; + private Manifestation manifestation; + + protected OuterRadialButton(int centerX, int centerY, int segmentNr, Manifestation manifestation) + { + super(centerX, centerY, 16, 16, CommonComponents.EMPTY, (button) -> {}, DEFAULT_NARRATION); + this.manifestation = manifestation; + double eighthCircle = Math.toRadians(45.d); // a circle is 360 degrees, / by 8 for 45 degrees, converted to radians + startAngle = segmentNr * eighthCircle; // todo: decided by power ID + endAngle = startAngle + eighthCircle; + } + + @Override + protected void renderWidget(@NotNull GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) + { + //renderRingSegment(pGuiGraphics, getX(), getY(), 0xFFFFFFFF); + //renderSegment(pGuiGraphics, isMouseOver(pMouseX, pMouseY)); + //renderIcon(pGuiGraphics); + } + + @Override + public boolean isMouseOver(double mouseX, double mouseY) + { + double distanceX = mouseX - this.getX(); + double distanceY = mouseY - this.getY(); + double dSqr = distanceX * distanceX + distanceY * distanceY; + + if (dSqr < INNER_RADIUS * INNER_RADIUS || + dSqr > OUTER_RADIUS * OUTER_RADIUS) + { + return false; + } + + double angle = Math.atan2(distanceY, distanceX); + + if (angle < 0) { + angle += 2 * Math.PI; + } + + double start = normalizeAngle(startAngle); + double end = normalizeAngle(endAngle); + angle = normalizeAngle(angle); + + if (start <= end) { + return angle >= start && angle <= end; + } else { + return angle >= start || angle <= end; + } + } + + @Override + public boolean mouseClicked(double pMouseX, double pMouseY, int pButton) + { + if (pButton == 0) + Cosmere.packetHandler().sendToServer(new ChangeManifestationModeMessage(manifestation, 1)); + else + Cosmere.packetHandler().sendToServer(new ChangeManifestationModeMessage(manifestation, -1)); + return super.mouseClicked(pMouseX, pMouseY, pButton); + } + + @Override + public void playDownSound(SoundManager pHandler) + { + super.playDownSound(pHandler); + } + + private double normalizeAngle(double angle) + { + if (angle != 0) + { + angle = angle % (2 * Math.PI); + if (angle < 0) + { + angle += 2 * Math.PI; + } + } + return angle; + } + + private void renderSegment(@NotNull GuiGraphics pGuiGraphics, boolean isHovered) + { + final int color = isHovered ? 0xFFFFFFFF : 0xAAAAAAFF; + int segments = 32; + double angleRange = endAngle - startAngle; + + for (int i = 0; i < segments; i++) { + double angle1 = startAngle + angleRange * i / segments; + double angle2 = startAngle + angleRange * (i + 1) / segments; + + int x1Outer = getX() + (int)(Math.cos(angle1) * OUTER_RADIUS); + int y1Outer = getY() + (int)(Math.sin(angle1) * OUTER_RADIUS); + int x2Outer = getX() + (int)(Math.cos(angle2) * OUTER_RADIUS); + int y2Outer = getY() + (int)(Math.sin(angle2) * OUTER_RADIUS); + + int x1Inner = getX() + (int)(Math.cos(angle1) * INNER_RADIUS); + int y1Inner = getY() + (int)(Math.sin(angle1) * INNER_RADIUS); + int x2Inner = getX() + (int)(Math.cos(angle2) * INNER_RADIUS); + int y2Inner = getY() + (int)(Math.sin(angle2) * INNER_RADIUS); + + // Draw a quad (two triangles) to form the ring segment piece + // Triangle 1: outer1 -> outer2 -> inner1 + drawTriangle(pGuiGraphics, x1Outer, y1Outer, x2Outer, y2Outer, x1Inner, y1Inner, color); + // Triangle 2: outer2 -> inner2 -> inner1 + drawTriangle(pGuiGraphics, x2Outer, y2Outer, x2Inner, y2Inner, x1Inner, y1Inner, color); + +// pGuiGraphics.fill(x1Inner, y1Inner, x1Outer, y1Outer, color); +// pGuiGraphics.fill(x1Outer, y1Outer, x2Outer, y2Outer, color); + } + } + + private void renderRingSegment(GuiGraphics guiGraphics, int centerX, int centerY, int color) { + int segments = 32; + double angleRange = endAngle - startAngle; + + PoseStack poseStack = guiGraphics.pose(); + poseStack.pushPose(); + + RenderSystem.enableBlend(); + RenderSystem.defaultBlendFunc(); + RenderSystem.setShader(GameRenderer::getPositionColorShader); + + BufferBuilder bufferBuilder = Tesselator.getInstance().getBuilder(); + bufferBuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR); + + float r = ((color >> 16) & 0xFF) / 255f; + float g = ((color >> 8) & 0xFF) / 255f; + float b = (color & 0xFF) / 255f; + float a = ((color >> 24) & 0xFF) / 255f; + + for (int i = 0; i < segments; i++) { + double angle1 = startAngle + angleRange * i / segments; + double angle2 = startAngle + angleRange * (i + 1) / segments; + + float x1Outer = centerX + (float)(Math.cos(angle1) * OUTER_RADIUS); + float y1Outer = centerY + (float)(Math.sin(angle1) * OUTER_RADIUS); + float x2Outer = centerX + (float)(Math.cos(angle2) * OUTER_RADIUS); + float y2Outer = centerY + (float)(Math.sin(angle2) * OUTER_RADIUS); + + float x1Inner = centerX + (float)(Math.cos(angle1) * INNER_RADIUS); + float y1Inner = centerY + (float)(Math.sin(angle1) * INNER_RADIUS); + float x2Inner = centerX + (float)(Math.cos(angle2) * INNER_RADIUS); + float y2Inner = centerY + (float)(Math.sin(angle2) * INNER_RADIUS); + + bufferBuilder.vertex(poseStack.last().pose(), x1Inner, y1Inner, 0).color(r, g, b, a).endVertex(); + bufferBuilder.vertex(poseStack.last().pose(), x1Outer, y1Outer, 0).color(r, g, b, a).endVertex(); + bufferBuilder.vertex(poseStack.last().pose(), x2Outer, y2Outer, 0).color(r, g, b, a).endVertex(); + bufferBuilder.vertex(poseStack.last().pose(), x2Inner, y2Inner, 0).color(r, g, b, a).endVertex(); + } + + BufferUploader.drawWithShader(bufferBuilder.end()); + + poseStack.popPose(); + RenderSystem.disableBlend(); + } + + private void renderIcon(@NotNull GuiGraphics pGuiGraphics) + { + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.setLength(0); + stringBuilder.append("textures/icon/") + .append(manifestation.getManifestationType().getName()) + .append("/"); + + switch (manifestation.getManifestationType()) + { + case ALLOMANCY: + case FERUCHEMY: + if (manifestation instanceof IHasMetalType metalType) + { + stringBuilder.append(metalType.getMetalType().getName()); + } + break; + case SURGEBINDING: + stringBuilder.append(manifestation.getName()); + case AON_DOR: + case AWAKENING: + break; + } + + stringBuilder.append(".png"); + final ResourceLocation location = new ResourceLocation(manifestation.getRegistryName().getNamespace(), stringBuilder.toString()); + RenderSystem.setShaderTexture(0, location); + + double midAngle = (startAngle + endAngle) / 2; + double midRadius = (INNER_RADIUS + OUTER_RADIUS) / 2.0; + int posX = getX() + (int)(Math.cos(midAngle) * midRadius); + int posY = getY() + (int)(Math.sin(midAngle) * midRadius); + + pGuiGraphics.blit(location, + posX, + posY, + width-2, + height-2, + 0, + 0, + width, + height, + width, + height); + } + + private void drawTriangle(GuiGraphics guiGraphics, int x1, int y1, int x2, int y2, int x3, int y3, int color) { + // This is a simple approach - for proper rendering you'd want to use the actual vertex buffer + guiGraphics.fill(Math.min(x1, Math.min(x2, x3)), Math.min(y1, Math.min(y2, y3)), + Math.max(x1, Math.max(x2, x3)), Math.max(y1, Math.max(y2, y3)), color); + } +} diff --git a/src/allomancy/java/leaf/cosmere/allomancy/common/capabilities/AllomancySpiritwebSubmodule.java b/src/allomancy/java/leaf/cosmere/allomancy/common/capabilities/AllomancySpiritwebSubmodule.java index 665bfedae..6aba0cbd2 100644 --- a/src/allomancy/java/leaf/cosmere/allomancy/common/capabilities/AllomancySpiritwebSubmodule.java +++ b/src/allomancy/java/leaf/cosmere/allomancy/common/capabilities/AllomancySpiritwebSubmodule.java @@ -5,6 +5,7 @@ package leaf.cosmere.allomancy.common.capabilities; import com.mojang.blaze3d.vertex.PoseStack; +import leaf.cosmere.allomancy.client.gui.AllomancySpiritwebMenu; import leaf.cosmere.allomancy.client.metalScanning.IronSteelLinesThread; import leaf.cosmere.allomancy.client.metalScanning.ScanResult; import leaf.cosmere.allomancy.common.Allomancy; @@ -24,6 +25,7 @@ import leaf.cosmere.api.manifestation.Manifestation; import leaf.cosmere.api.spiritweb.ISpiritweb; import leaf.cosmere.common.registration.impl.AttributeRegistryObject; +import leaf.cosmere.client.gui.SpiritwebRegistry; import net.minecraft.client.Minecraft; import net.minecraft.nbt.CompoundTag; import net.minecraft.world.entity.ai.attributes.Attribute; @@ -353,6 +355,11 @@ public List getPowers() return AllomancyAttributes.ALLOMANCY_ATTRIBUTES.values().stream() .map((AttributeRegistryObject::getAttribute)).collect(Collectors.toList()); } + + public void registerMenu() + { + SpiritwebRegistry.getInstance().register(Manifestations.ManifestationTypes.ALLOMANCY, AllomancySpiritwebMenu::new); + } public int getIngestedMetal(Metals.MetalType metalType) { diff --git a/src/api/java/leaf/cosmere/api/ISpiritwebSubmodule.java b/src/api/java/leaf/cosmere/api/ISpiritwebSubmodule.java index f7dc690af..2d7b972a5 100644 --- a/src/api/java/leaf/cosmere/api/ISpiritwebSubmodule.java +++ b/src/api/java/leaf/cosmere/api/ISpiritwebSubmodule.java @@ -56,7 +56,10 @@ default void GiveStartingItem(Player player, Manifestation manifestation) default void resetOnDeath(ISpiritweb spiritweb) { + } + default void registerMenu() + { } void drainInvestiture(ISpiritweb data, double strength); diff --git a/src/feruchemy/java/leaf/cosmere/feruchemy/client/FeruchemyClientSetup.java b/src/feruchemy/java/leaf/cosmere/feruchemy/client/FeruchemyClientSetup.java index 382c3cc44..6e845fff3 100644 --- a/src/feruchemy/java/leaf/cosmere/feruchemy/client/FeruchemyClientSetup.java +++ b/src/feruchemy/java/leaf/cosmere/feruchemy/client/FeruchemyClientSetup.java @@ -5,6 +5,9 @@ package leaf.cosmere.feruchemy.client; import leaf.cosmere.api.CosmereAPI; +import leaf.cosmere.api.Manifestations; +import leaf.cosmere.client.gui.SpiritwebRegistry; +import leaf.cosmere.feruchemy.client.gui.FeruchemySpiritwebMenu; import leaf.cosmere.common.cap.entity.SpiritwebCapability; import leaf.cosmere.feruchemy.client.gui.NicrosilMenu; import leaf.cosmere.feruchemy.client.render.FeruchemyLayerDefinitions; diff --git a/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/FeruchemySpiritwebMenu.java b/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/FeruchemySpiritwebMenu.java new file mode 100644 index 000000000..4f9001138 --- /dev/null +++ b/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/FeruchemySpiritwebMenu.java @@ -0,0 +1,26 @@ +package leaf.cosmere.feruchemy.client.gui; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.network.chat.Component; + +public class FeruchemySpiritwebMenu extends Screen +{ + public FeruchemySpiritwebMenu() + { + super(Component.literal("Feruchemy")); + } + + @Override + protected void init() + { + + } + + @Override + public void render(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) + { + pGuiGraphics.drawCenteredString(Minecraft.getInstance().font, "feruchemy", pMouseX, pMouseY, 0xFFFFFFFF); + } +} diff --git a/src/feruchemy/java/leaf/cosmere/feruchemy/common/capabilities/FeruchemySpiritwebSubmodule.java b/src/feruchemy/java/leaf/cosmere/feruchemy/common/capabilities/FeruchemySpiritwebSubmodule.java index f09b5ad87..24f9bbf53 100644 --- a/src/feruchemy/java/leaf/cosmere/feruchemy/common/capabilities/FeruchemySpiritwebSubmodule.java +++ b/src/feruchemy/java/leaf/cosmere/feruchemy/common/capabilities/FeruchemySpiritwebSubmodule.java @@ -5,11 +5,14 @@ package leaf.cosmere.feruchemy.common.capabilities; import leaf.cosmere.api.ISpiritwebSubmodule; +import leaf.cosmere.api.Manifestations; import leaf.cosmere.api.Metals; import leaf.cosmere.api.helpers.PlayerHelper; import leaf.cosmere.api.manifestation.Manifestation; import leaf.cosmere.api.math.MathHelper; import leaf.cosmere.api.spiritweb.ISpiritweb; +import leaf.cosmere.client.gui.SpiritwebRegistry; +import leaf.cosmere.feruchemy.client.gui.FeruchemySpiritwebMenu; import leaf.cosmere.common.registration.impl.AttributeRegistryObject; import leaf.cosmere.feruchemy.client.utils.FeruchemyChargeThread; import leaf.cosmere.feruchemy.common.config.FeruchemyConfigs; @@ -97,6 +100,12 @@ public void collectMenuInfo(List m_infoText) ISpiritwebSubmodule.super.collectMenuInfo(m_infoText); } + @Override + public void registerMenu() + { + SpiritwebRegistry.getInstance().register(Manifestations.ManifestationTypes.FERUCHEMY, FeruchemySpiritwebMenu::new); + } + private static void GiveStartingItem(Player player, Metals.MetalType metalType, float fillAmount) { ItemStack itemStack; diff --git a/src/main/java/leaf/cosmere/client/ClientForgeEvents.java b/src/main/java/leaf/cosmere/client/ClientForgeEvents.java index d0677638e..97aa471d9 100644 --- a/src/main/java/leaf/cosmere/client/ClientForgeEvents.java +++ b/src/main/java/leaf/cosmere/client/ClientForgeEvents.java @@ -70,6 +70,12 @@ public static void onKey(InputEvent.Key event) { if (Keybindings.MANIFESTATION_MENU.consumeClick()) { + SpiritwebCapability.get(player).ifPresent( (iSpiritweb -> + { + iSpiritweb.getSubmodules().forEach( ((manifestationTypes, iSpiritwebSubmodule) -> { + iSpiritwebSubmodule.registerMenu(); + })); + })); Minecraft.getInstance().setScreen(new SpiritwebMenu(Component.literal("Spiritweb Menu"), spiritweb)); } diff --git a/src/main/java/leaf/cosmere/client/gui/SpiritwebMenu.java b/src/main/java/leaf/cosmere/client/gui/SpiritwebMenu.java index 0db0cf666..ce6532ab5 100644 --- a/src/main/java/leaf/cosmere/client/gui/SpiritwebMenu.java +++ b/src/main/java/leaf/cosmere/client/gui/SpiritwebMenu.java @@ -5,50 +5,32 @@ package leaf.cosmere.client.gui; import com.google.common.base.Stopwatch; -import com.mojang.blaze3d.platform.GlStateManager; -import com.mojang.blaze3d.platform.Window; -import com.mojang.blaze3d.systems.RenderSystem; -import com.mojang.blaze3d.vertex.*; -import leaf.cosmere.api.*; -import leaf.cosmere.api.manifestation.Manifestation; +import leaf.cosmere.api.Manifestations; import leaf.cosmere.api.math.MathHelper; -import leaf.cosmere.api.math.Vector2; import leaf.cosmere.api.spiritweb.ISpiritweb; import leaf.cosmere.client.Keybindings; -import leaf.cosmere.common.Cosmere; -import leaf.cosmere.common.cap.entity.SpiritwebCapability; -import leaf.cosmere.common.network.packets.ChangeManifestationModeMessage; -import leaf.cosmere.common.network.packets.SetSelectedManifestationMessage; -import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.screens.Screen; -import net.minecraft.client.gui.screens.recipebook.RecipeBookPage; -import net.minecraft.client.renderer.GameRenderer; -import net.minecraft.client.resources.language.I18n; -import net.minecraft.core.Direction; import net.minecraft.network.chat.Component; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.stats.RecipeBook; -import net.minecraft.world.inventory.RecipeBookMenu; import org.jetbrains.annotations.NotNull; -import org.lwjgl.opengl.GL11; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; public class SpiritwebMenu extends Screen { private float visibility = 0.0f; private Stopwatch lastChange = Stopwatch.createStarted(); - private ISpiritweb spiritweb; + private final ISpiritweb spiritweb; + private final SpiritwebRegistry registry; + private Manifestations.ManifestationTypes selectedManifestationType = Manifestations.ManifestationTypes.NONE; + private Screen selectedManifestationScreen = null; public SpiritwebMenu(Component pTitle, ISpiritweb spiritweb) { super(pTitle); this.spiritweb = spiritweb; + this.registry = SpiritwebRegistry.getInstance(); } public void raiseVisibility() @@ -63,6 +45,43 @@ private void CloseScreen() this.minecraft.setScreen(null); } + public void prepareClose() + { + // todo + // will need later + } + + @Override + protected void init() + { + AtomicInteger added = new AtomicInteger(0); + int count = registry.getManifestationScreenMap().size(); + for (int i = 0; i < Manifestations.ManifestationTypes.AVIAR.getID(); i++) + { + Manifestations.ManifestationTypes.valueOf(i).ifPresent( (maniType) -> + { + if (registry.getManifestationScreenMap().get(maniType) != null) + { + int x = (width / 2) - ((count * 32) / 2) + (added.get() * 32); + addRenderableWidget(new TabButton(x, (pButton -> + { + if (maniType != selectedManifestationType) + { + selectedManifestationType = maniType; + selectedManifestationScreen = registry.getManifestationScreenMap().get(maniType).get(); + } + }), maniType)); + added.set(added.get()+1); + if (added.get() == 1) + { + selectedManifestationType = maniType; + selectedManifestationScreen = registry.getManifestationScreenMap().get(maniType).get(); + } + } + }); + } + } + @Override public void render(@NotNull GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) { @@ -72,6 +91,11 @@ public void render(@NotNull GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, final int end = (int) (visibility * 128) << 24; pGuiGraphics.fillGradient(0, 0, width, height, start, end); + + if (selectedManifestationScreen != null) + { + selectedManifestationScreen.render(pGuiGraphics, pMouseX, pMouseY, pPartialTick); + } } @Override diff --git a/src/main/java/leaf/cosmere/client/gui/SpiritwebRegistry.java b/src/main/java/leaf/cosmere/client/gui/SpiritwebRegistry.java new file mode 100644 index 000000000..0334de17c --- /dev/null +++ b/src/main/java/leaf/cosmere/client/gui/SpiritwebRegistry.java @@ -0,0 +1,32 @@ +package leaf.cosmere.client.gui; + +import leaf.cosmere.api.Manifestations; +import net.minecraft.client.gui.screens.Screen; + +import java.util.HashMap; +import java.util.function.Supplier; + +public class SpiritwebRegistry +{ + private static SpiritwebRegistry INSTANCE; + private final HashMap> manifestationScreenMap = new HashMap<>(); + + public static SpiritwebRegistry getInstance() + { + if (INSTANCE == null) + { + INSTANCE = new SpiritwebRegistry(); + } + return INSTANCE; + } + + public void register(Manifestations.ManifestationTypes maniType, Supplier subScreen) + { + manifestationScreenMap.put(maniType, subScreen); + } + + public HashMap> getManifestationScreenMap() + { + return manifestationScreenMap; + } +} diff --git a/src/main/java/leaf/cosmere/client/gui/TabButton.java b/src/main/java/leaf/cosmere/client/gui/TabButton.java new file mode 100644 index 000000000..3ffa5e42a --- /dev/null +++ b/src/main/java/leaf/cosmere/client/gui/TabButton.java @@ -0,0 +1,59 @@ +package leaf.cosmere.client.gui; + +import com.mojang.blaze3d.systems.RenderSystem; +import leaf.cosmere.api.Manifestations; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.components.Button; +import net.minecraft.network.chat.CommonComponents; +import net.minecraft.resources.ResourceLocation; +import org.lwjgl.opengl.GL11; + +public class TabButton extends Button +{ + private static final int WIDTH = 32; + private static final int HEIGHT = 32; + private static final int START_Y = 10; + public Manifestations.ManifestationTypes manifestation; + + public TabButton(int x, Button.OnPress onPress, Manifestations.ManifestationTypes manifestation) + { + super(x, START_Y, WIDTH, HEIGHT, CommonComponents.EMPTY, onPress, DEFAULT_NARRATION); + this.manifestation = manifestation; + } + + @Override + protected void renderWidget(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) + { + renderBackground(pGuiGraphics, pMouseX, pMouseY); + renderIcon(pGuiGraphics); + } + + private void renderBackground(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY) + { + int color = isMouseOver(pMouseX, pMouseY) ? 0x00000077 : 0x00220077; + //int color = isMouseOver(pMouseX, pMouseY) ? 0xDDDDDDFF : 0x222222FF; + + int minX = this.getX(), minY = this.getY(), maxX = minX + this.width, maxY = minY + this.height; + pGuiGraphics.fill(minX, minY, maxX, maxY, color); + } + + private void renderIcon(GuiGraphics pGuiGraphics) + { + final ResourceLocation resourceLocation = new ResourceLocation(manifestation.getName(), "textures/icon/" + manifestation.getName() + ".png"); + RenderSystem.setShaderTexture(0, resourceLocation); + + RenderSystem.enableBlend(); + RenderSystem.blendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, 1, 0); + pGuiGraphics.blit( + resourceLocation, + getX(), + getY(), + 0, + 0, + width, + height, + width, + height + ); + } +} diff --git a/src/main/java/leaf/cosmere/common/cap/entity/SpiritwebCapability.java b/src/main/java/leaf/cosmere/common/cap/entity/SpiritwebCapability.java index be75795db..92867dcc2 100644 --- a/src/main/java/leaf/cosmere/common/cap/entity/SpiritwebCapability.java +++ b/src/main/java/leaf/cosmere/common/cap/entity/SpiritwebCapability.java @@ -7,7 +7,10 @@ import com.google.common.collect.Maps; import com.mojang.blaze3d.systems.RenderSystem; -import com.mojang.blaze3d.vertex.*; +import com.mojang.blaze3d.vertex.BufferBuilder; +import com.mojang.blaze3d.vertex.DefaultVertexFormat; +import com.mojang.blaze3d.vertex.Tesselator; +import com.mojang.blaze3d.vertex.VertexFormat; import leaf.cosmere.api.CosmereAPI; import leaf.cosmere.api.IHasMetalType; import leaf.cosmere.api.ISpiritwebSubmodule; @@ -54,7 +57,6 @@ import javax.annotation.Nullable; import java.io.FileNotFoundException; import java.util.*; -import java.util.List; /* "The actual outlet of the power is not chosen by the practitioner, but instead is hardwritten into their Spiritweb" From 9b5435e3ecf3a416a2541fd9c16b72ee01f0a509 Mon Sep 17 00:00:00 2001 From: Gerbagel Date: Mon, 24 Nov 2025 22:24:19 +0100 Subject: [PATCH 03/55] [Cosmere] Minor changes to TabButton layout, background, and highlighting --- .../client/gui/AllomancySpiritwebMenu.java | 5 +-- .../cosmere/client/gui/SpiritwebMenu.java | 4 +- .../leaf/cosmere/client/gui/TabButton.java | 37 ++++++++++++++----- 3 files changed, 30 insertions(+), 16 deletions(-) diff --git a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/AllomancySpiritwebMenu.java b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/AllomancySpiritwebMenu.java index 747bac0f2..3a50cbb02 100644 --- a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/AllomancySpiritwebMenu.java +++ b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/AllomancySpiritwebMenu.java @@ -1,6 +1,5 @@ package leaf.cosmere.allomancy.client.gui; -import leaf.cosmere.api.CosmereAPI; import leaf.cosmere.common.cap.entity.SpiritwebCapability; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; @@ -21,9 +20,7 @@ public AllomancySpiritwebMenu() @Override protected void init() { - CosmereAPI.logger.info("wow"); SpiritwebCapability.get(player).ifPresent( (iSpiritweb -> { - CosmereAPI.logger.info("wahoo"); addRenderableWidget(new OuterRadialButton(width/2, height/2, 0, iSpiritweb.getAvailableManifestations().get(0))); })); // for (int i = 0; i < spiritweb.getAvailableManifestations().size(); i++) @@ -38,7 +35,7 @@ protected void init() @Override public void render(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) { - pGuiGraphics.drawCenteredString(Minecraft.getInstance().font, "wow", pMouseX, pMouseY, 0xFFFFFFFF); + pGuiGraphics.drawCenteredString(Minecraft.getInstance().font, "allomancy", pMouseX, pMouseY, 0xFFFFFFFF); super.render(pGuiGraphics, pMouseX, pMouseY, pPartialTick); } } diff --git a/src/main/java/leaf/cosmere/client/gui/SpiritwebMenu.java b/src/main/java/leaf/cosmere/client/gui/SpiritwebMenu.java index ce6532ab5..6576b29ca 100644 --- a/src/main/java/leaf/cosmere/client/gui/SpiritwebMenu.java +++ b/src/main/java/leaf/cosmere/client/gui/SpiritwebMenu.java @@ -23,8 +23,8 @@ public class SpiritwebMenu extends Screen private Stopwatch lastChange = Stopwatch.createStarted(); private final ISpiritweb spiritweb; private final SpiritwebRegistry registry; - private Manifestations.ManifestationTypes selectedManifestationType = Manifestations.ManifestationTypes.NONE; private Screen selectedManifestationScreen = null; + public static Manifestations.ManifestationTypes selectedManifestationType = Manifestations.ManifestationTypes.NONE; public SpiritwebMenu(Component pTitle, ISpiritweb spiritweb) { @@ -62,7 +62,7 @@ protected void init() { if (registry.getManifestationScreenMap().get(maniType) != null) { - int x = (width / 2) - ((count * 32) / 2) + (added.get() * 32); + int x = (width / 2) - ((count * 32) / 2) + (added.get() * 37); addRenderableWidget(new TabButton(x, (pButton -> { if (maniType != selectedManifestationType) diff --git a/src/main/java/leaf/cosmere/client/gui/TabButton.java b/src/main/java/leaf/cosmere/client/gui/TabButton.java index 3ffa5e42a..27da08607 100644 --- a/src/main/java/leaf/cosmere/client/gui/TabButton.java +++ b/src/main/java/leaf/cosmere/client/gui/TabButton.java @@ -30,17 +30,12 @@ protected void renderWidget(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, private void renderBackground(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY) { - int color = isMouseOver(pMouseX, pMouseY) ? 0x00000077 : 0x00220077; - //int color = isMouseOver(pMouseX, pMouseY) ? 0xDDDDDDFF : 0x222222FF; - - int minX = this.getX(), minY = this.getY(), maxX = minX + this.width, maxY = minY + this.height; - pGuiGraphics.fill(minX, minY, maxX, maxY, color); - } - - private void renderIcon(GuiGraphics pGuiGraphics) - { - final ResourceLocation resourceLocation = new ResourceLocation(manifestation.getName(), "textures/icon/" + manifestation.getName() + ".png"); + float alpha = isMouseOver(pMouseX, pMouseY) ? 1.0f : 0.5f; + alpha = (SpiritwebMenu.selectedManifestationType == this.manifestation) ? 1.0f : alpha; + final ResourceLocation resourceLocation = new ResourceLocation(manifestation.getName(), "textures/gui/hud_background.png"); RenderSystem.setShaderTexture(0, resourceLocation); + float[] shaderColor = RenderSystem.getShaderColor(); + RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, alpha); RenderSystem.enableBlend(); RenderSystem.blendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, 1, 0); @@ -55,5 +50,27 @@ private void renderIcon(GuiGraphics pGuiGraphics) width, height ); + + RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f); + } + + private void renderIcon(GuiGraphics pGuiGraphics) + { + final ResourceLocation resourceLocation = new ResourceLocation(manifestation.getName(), "textures/icon/" + manifestation.getName() + ".png"); + RenderSystem.setShaderTexture(0, resourceLocation); + + RenderSystem.enableBlend(); + RenderSystem.blendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, 1, 0); + pGuiGraphics.blit( + resourceLocation, + getX()+1, + getY()+1, + 0, + 0, + width-2, + height-2, + width-2, + height-2 + ); } } From cedc5bbd09f12f563503869e5bd4080e3ab45747 Mon Sep 17 00:00:00 2001 From: Gerbagel Date: Tue, 27 Jan 2026 13:58:40 +0100 Subject: [PATCH 04/55] [Cosmere] Render internal and external circle segments --- .../client/gui/AllomancySpiritwebMenu.java | 28 ++-- .../client/gui/InnerRadialButton.java | 128 +++++++++++++++++- .../client/gui/OuterRadialButton.java | 111 +++++++-------- .../leaf/cosmere/client/gui/TabButton.java | 11 +- 4 files changed, 199 insertions(+), 79 deletions(-) diff --git a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/AllomancySpiritwebMenu.java b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/AllomancySpiritwebMenu.java index 3a50cbb02..dc2e76c1e 100644 --- a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/AllomancySpiritwebMenu.java +++ b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/AllomancySpiritwebMenu.java @@ -20,22 +20,34 @@ public AllomancySpiritwebMenu() @Override protected void init() { + super.init(); + this.width = Minecraft.getInstance().getWindow().getGuiScaledWidth(); + this.height = Minecraft.getInstance().getWindow().getGuiScaledHeight(); + SpiritwebCapability.get(player).ifPresent( (iSpiritweb -> { addRenderableWidget(new OuterRadialButton(width/2, height/2, 0, iSpiritweb.getAvailableManifestations().get(0))); + addRenderableWidget(new OuterRadialButton(width/2, height/2, 1, iSpiritweb.getAvailableManifestations().get(1))); + addRenderableWidget(new OuterRadialButton(width/2, height/2, 2, iSpiritweb.getAvailableManifestations().get(2))); + addRenderableWidget(new OuterRadialButton(width/2, height/2, 3, iSpiritweb.getAvailableManifestations().get(3))); + addRenderableWidget(new OuterRadialButton(width/2, height/2, 4, iSpiritweb.getAvailableManifestations().get(4))); + addRenderableWidget(new OuterRadialButton(width/2, height/2, 5, iSpiritweb.getAvailableManifestations().get(5))); + addRenderableWidget(new OuterRadialButton(width/2, height/2, 6, iSpiritweb.getAvailableManifestations().get(6))); + addRenderableWidget(new OuterRadialButton(width/2, height/2, 7, iSpiritweb.getAvailableManifestations().get(7))); + + addRenderableWidget(new InnerRadialButton(width/2, height/2, 0, iSpiritweb.getAvailableManifestations().get(0))); + addRenderableWidget(new InnerRadialButton(width/2, height/2, 1, iSpiritweb.getAvailableManifestations().get(1))); + addRenderableWidget(new InnerRadialButton(width/2, height/2, 2, iSpiritweb.getAvailableManifestations().get(2))); + addRenderableWidget(new InnerRadialButton(width/2, height/2, 3, iSpiritweb.getAvailableManifestations().get(3))); + addRenderableWidget(new InnerRadialButton(width/2, height/2, 4, iSpiritweb.getAvailableManifestations().get(4))); + addRenderableWidget(new InnerRadialButton(width/2, height/2, 5, iSpiritweb.getAvailableManifestations().get(5))); + addRenderableWidget(new InnerRadialButton(width/2, height/2, 6, iSpiritweb.getAvailableManifestations().get(6))); + addRenderableWidget(new InnerRadialButton(width/2, height/2, 7, iSpiritweb.getAvailableManifestations().get(7))); })); -// for (int i = 0; i < spiritweb.getAvailableManifestations().size(); i++) -// { -// if (i < 8) -// { -// addRenderableWidget(new OuterRadialButton(width / 2, height / 2, i, spiritweb.getAvailableManifestations().get(i))); -// } -// } } @Override public void render(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) { - pGuiGraphics.drawCenteredString(Minecraft.getInstance().font, "allomancy", pMouseX, pMouseY, 0xFFFFFFFF); super.render(pGuiGraphics, pMouseX, pMouseY, pPartialTick); } } diff --git a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java index 97c9433b8..2e2235a44 100644 --- a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java +++ b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java @@ -1,12 +1,134 @@ package leaf.cosmere.allomancy.client.gui; +import com.mojang.blaze3d.systems.RenderSystem; +import com.mojang.blaze3d.vertex.BufferBuilder; +import com.mojang.blaze3d.vertex.DefaultVertexFormat; +import com.mojang.blaze3d.vertex.Tesselator; +import com.mojang.blaze3d.vertex.VertexFormat; +import leaf.cosmere.api.manifestation.Manifestation; +import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.Button; -import net.minecraft.network.chat.Component; +import net.minecraft.client.renderer.GameRenderer; +import net.minecraft.network.chat.CommonComponents; +import net.minecraft.util.Mth; +import org.jetbrains.annotations.NotNull; +import org.joml.Matrix4f; public class InnerRadialButton extends Button { - protected InnerRadialButton(int pX, int pY, int pWidth, int pHeight, Component pMessage, OnPress pOnPress, CreateNarration pCreateNarration) + private static final int OUTER_RADIUS = 60; + private static final int INNER_RADIUS = 0; + private final double startAngle; + private final double endAngle; + private final int segmentNr; + private final int centerX; + private final int centerY; + private final Manifestation manifestation; + + protected InnerRadialButton(int centerX, int centerY, int segmentNr, Manifestation manifestation) + { + super(centerX, centerY, 16, 16, CommonComponents.EMPTY, (button) -> {}, DEFAULT_NARRATION); + this.manifestation = manifestation; + double eighthCircle = Math.toRadians(45.d); // a circle is 360 degrees, / by 8 for 45 degrees, converted to radians + this.segmentNr = segmentNr; + startAngle = segmentNr * eighthCircle; // todo: decided by power ID + endAngle = startAngle + eighthCircle; + this.centerX = centerX; + this.centerY = centerY; + } + + @Override + protected void renderWidget(@NotNull GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) + { + renderSegment(pGuiGraphics, isMouseOver(pMouseX, pMouseY)); + } + + @Override + public boolean isMouseOver(double mouseX, double mouseY) { - super(pX, pY, pWidth, pHeight, pMessage, pOnPress, pCreateNarration); + double distanceX = mouseX - centerX; + double distanceY = mouseY - centerY; + double dSqr = distanceX * distanceX + distanceY * distanceY; + + if (dSqr < INNER_RADIUS * INNER_RADIUS || + dSqr > OUTER_RADIUS * OUTER_RADIUS) + { + return false; + } + + double angle = Math.atan2(distanceY, distanceX); + + if (angle < 0) { + angle += 2 * Math.PI; + } + + double start = normalizeAngle(startAngle); + double end = normalizeAngle(endAngle); + angle = normalizeAngle(angle); + + if (start <= end) { + return angle >= start && angle <= end; + } else { + return angle >= start || angle <= end; + } + } + + private double normalizeAngle(double angle) + { + if (angle != 0) + { + angle = angle % (2 * Math.PI); + if (angle < 0) + { + angle += 2 * Math.PI; + } + } + return angle; + } + + private void renderSegment(GuiGraphics pGuiGraphics, boolean isHovered) + { + float r, g, b, a; + + if (isHovered) { + r = g = b = a = 1.0f; + } else { + r = g = 0.f; + b = 0.67f; + a = 1.0f; + } + + float radsPerSegment = (float) Math.PI * 2 / 8; + float step = (float) Math.PI / 180; + float radius = OUTER_RADIUS; + + RenderSystem.disableCull(); + RenderSystem.enableBlend(); + RenderSystem.defaultBlendFunc(); + RenderSystem.setShader(GameRenderer::getPositionColorShader); + + Matrix4f pose = pGuiGraphics.pose().last().pose(); + Tesselator tess = Tesselator.getInstance(); + BufferBuilder buf = tess.getBuilder(); + + buf.begin(VertexFormat.Mode.TRIANGLE_FAN, DefaultVertexFormat.POSITION_COLOR); + buf.vertex(pose, centerX, centerY, 0).color(r, g, b, a).endVertex(); + + for (float f = 0f; f < radsPerSegment + step/2; f += step) + { + float rad = f + segmentNr * radsPerSegment; + float x = centerX + Mth.cos(rad) * radius; + float y = centerY + Mth.sin(rad) * radius; + + if (f == 0) + { + buf.vertex(pose, x, y, 0).color(r,g,b,a).endVertex(); + } + buf.vertex(pose, x, y, 0).color(r,g,b,a).endVertex(); + } + + tess.end(); + + RenderSystem.disableBlend(); } } diff --git a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java index a7580bb23..d40ca3a8b 100644 --- a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java +++ b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java @@ -1,7 +1,10 @@ package leaf.cosmere.allomancy.client.gui; import com.mojang.blaze3d.systems.RenderSystem; -import com.mojang.blaze3d.vertex.*; +import com.mojang.blaze3d.vertex.BufferBuilder; +import com.mojang.blaze3d.vertex.DefaultVertexFormat; +import com.mojang.blaze3d.vertex.Tesselator; +import com.mojang.blaze3d.vertex.VertexFormat; import leaf.cosmere.api.IHasMetalType; import leaf.cosmere.api.manifestation.Manifestation; import leaf.cosmere.common.Cosmere; @@ -12,38 +15,46 @@ import net.minecraft.client.sounds.SoundManager; import net.minecraft.network.chat.CommonComponents; import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.Mth; import org.jetbrains.annotations.NotNull; +import org.joml.Matrix4f; public class OuterRadialButton extends Button { - private static final int OUTER_RADIUS = 100; + private static final int OUTER_RADIUS = 80; private static final int INNER_RADIUS = 60; private final double startAngle; private final double endAngle; - private Manifestation manifestation; + private final int segmentNr; + private final int centerX; + private final int centerY; + private final Manifestation manifestation; protected OuterRadialButton(int centerX, int centerY, int segmentNr, Manifestation manifestation) { super(centerX, centerY, 16, 16, CommonComponents.EMPTY, (button) -> {}, DEFAULT_NARRATION); this.manifestation = manifestation; double eighthCircle = Math.toRadians(45.d); // a circle is 360 degrees, / by 8 for 45 degrees, converted to radians + this.segmentNr = segmentNr; startAngle = segmentNr * eighthCircle; // todo: decided by power ID endAngle = startAngle + eighthCircle; + this.centerX = centerX; + this.centerY = centerY; } @Override protected void renderWidget(@NotNull GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) { - //renderRingSegment(pGuiGraphics, getX(), getY(), 0xFFFFFFFF); - //renderSegment(pGuiGraphics, isMouseOver(pMouseX, pMouseY)); + //CosmereAPI.logger.info("Rendering at " + centerX + " | " + centerY); + renderSegment(pGuiGraphics, isMouseOver(pMouseX, pMouseY)); //renderIcon(pGuiGraphics); } @Override public boolean isMouseOver(double mouseX, double mouseY) { - double distanceX = mouseX - this.getX(); - double distanceY = mouseY - this.getY(); + double distanceX = mouseX - centerX; + double distanceY = mouseY - centerY; double dSqr = distanceX * distanceX + distanceY * distanceY; if (dSqr < INNER_RADIUS * INNER_RADIUS || @@ -98,79 +109,49 @@ private double normalizeAngle(double angle) return angle; } + // inspired by SteelCodeTeam's Metallic Arts https://github.com/SteelCodeTeam/Metallics-Arts private void renderSegment(@NotNull GuiGraphics pGuiGraphics, boolean isHovered) { - final int color = isHovered ? 0xFFFFFFFF : 0xAAAAAAFF; - int segments = 32; - double angleRange = endAngle - startAngle; - - for (int i = 0; i < segments; i++) { - double angle1 = startAngle + angleRange * i / segments; - double angle2 = startAngle + angleRange * (i + 1) / segments; - - int x1Outer = getX() + (int)(Math.cos(angle1) * OUTER_RADIUS); - int y1Outer = getY() + (int)(Math.sin(angle1) * OUTER_RADIUS); - int x2Outer = getX() + (int)(Math.cos(angle2) * OUTER_RADIUS); - int y2Outer = getY() + (int)(Math.sin(angle2) * OUTER_RADIUS); - - int x1Inner = getX() + (int)(Math.cos(angle1) * INNER_RADIUS); - int y1Inner = getY() + (int)(Math.sin(angle1) * INNER_RADIUS); - int x2Inner = getX() + (int)(Math.cos(angle2) * INNER_RADIUS); - int y2Inner = getY() + (int)(Math.sin(angle2) * INNER_RADIUS); - - // Draw a quad (two triangles) to form the ring segment piece - // Triangle 1: outer1 -> outer2 -> inner1 - drawTriangle(pGuiGraphics, x1Outer, y1Outer, x2Outer, y2Outer, x1Inner, y1Inner, color); - // Triangle 2: outer2 -> inner2 -> inner1 - drawTriangle(pGuiGraphics, x2Outer, y2Outer, x2Inner, y2Inner, x1Inner, y1Inner, color); - -// pGuiGraphics.fill(x1Inner, y1Inner, x1Outer, y1Outer, color); -// pGuiGraphics.fill(x1Outer, y1Outer, x2Outer, y2Outer, color); - } - } + float r, g, b, a; - private void renderRingSegment(GuiGraphics guiGraphics, int centerX, int centerY, int color) { - int segments = 32; - double angleRange = endAngle - startAngle; + if (isHovered) { + r = g = b = a = 1.0f; + } else { + r = g = b = 0.67f; + a = 1.0f; + } - PoseStack poseStack = guiGraphics.pose(); - poseStack.pushPose(); + float radsPerSegment = (float) Math.PI * 2 / 8; + float step = (float) Math.PI / 180; + float radius = OUTER_RADIUS; + RenderSystem.disableCull(); RenderSystem.enableBlend(); RenderSystem.defaultBlendFunc(); RenderSystem.setShader(GameRenderer::getPositionColorShader); - BufferBuilder bufferBuilder = Tesselator.getInstance().getBuilder(); - bufferBuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR); - - float r = ((color >> 16) & 0xFF) / 255f; - float g = ((color >> 8) & 0xFF) / 255f; - float b = (color & 0xFF) / 255f; - float a = ((color >> 24) & 0xFF) / 255f; + Matrix4f pose = pGuiGraphics.pose().last().pose(); + Tesselator tess = Tesselator.getInstance(); + BufferBuilder buf = tess.getBuilder(); - for (int i = 0; i < segments; i++) { - double angle1 = startAngle + angleRange * i / segments; - double angle2 = startAngle + angleRange * (i + 1) / segments; + buf.begin(VertexFormat.Mode.TRIANGLE_FAN, DefaultVertexFormat.POSITION_COLOR); + buf.vertex(pose, centerX, centerY, 0).color(r, g, b, a).endVertex(); - float x1Outer = centerX + (float)(Math.cos(angle1) * OUTER_RADIUS); - float y1Outer = centerY + (float)(Math.sin(angle1) * OUTER_RADIUS); - float x2Outer = centerX + (float)(Math.cos(angle2) * OUTER_RADIUS); - float y2Outer = centerY + (float)(Math.sin(angle2) * OUTER_RADIUS); - - float x1Inner = centerX + (float)(Math.cos(angle1) * INNER_RADIUS); - float y1Inner = centerY + (float)(Math.sin(angle1) * INNER_RADIUS); - float x2Inner = centerX + (float)(Math.cos(angle2) * INNER_RADIUS); - float y2Inner = centerY + (float)(Math.sin(angle2) * INNER_RADIUS); + for (float f = 0f; f < radsPerSegment + step/2; f += step) + { + float rad = f + segmentNr * radsPerSegment; + float x = centerX + Mth.cos(rad) * radius; + float y = centerY + Mth.sin(rad) * radius; - bufferBuilder.vertex(poseStack.last().pose(), x1Inner, y1Inner, 0).color(r, g, b, a).endVertex(); - bufferBuilder.vertex(poseStack.last().pose(), x1Outer, y1Outer, 0).color(r, g, b, a).endVertex(); - bufferBuilder.vertex(poseStack.last().pose(), x2Outer, y2Outer, 0).color(r, g, b, a).endVertex(); - bufferBuilder.vertex(poseStack.last().pose(), x2Inner, y2Inner, 0).color(r, g, b, a).endVertex(); + if (f == 0) + { + buf.vertex(pose, x, y, 0).color(r,g,b,a).endVertex(); + } + buf.vertex(pose, x, y, 0).color(r,g,b,a).endVertex(); } - BufferUploader.drawWithShader(bufferBuilder.end()); + tess.end(); - poseStack.popPose(); RenderSystem.disableBlend(); } diff --git a/src/main/java/leaf/cosmere/client/gui/TabButton.java b/src/main/java/leaf/cosmere/client/gui/TabButton.java index 27da08607..54a3a4bd6 100644 --- a/src/main/java/leaf/cosmere/client/gui/TabButton.java +++ b/src/main/java/leaf/cosmere/client/gui/TabButton.java @@ -25,12 +25,12 @@ public TabButton(int x, Button.OnPress onPress, Manifestations.ManifestationType protected void renderWidget(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) { renderBackground(pGuiGraphics, pMouseX, pMouseY); - renderIcon(pGuiGraphics); + renderIcon(pGuiGraphics, pMouseX, pMouseY); } private void renderBackground(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY) { - float alpha = isMouseOver(pMouseX, pMouseY) ? 1.0f : 0.5f; + float alpha = isMouseOver(pMouseX, pMouseY) ? 1.0f : 0.3f; alpha = (SpiritwebMenu.selectedManifestationType == this.manifestation) ? 1.0f : alpha; final ResourceLocation resourceLocation = new ResourceLocation(manifestation.getName(), "textures/gui/hud_background.png"); RenderSystem.setShaderTexture(0, resourceLocation); @@ -54,10 +54,13 @@ private void renderBackground(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f); } - private void renderIcon(GuiGraphics pGuiGraphics) + private void renderIcon(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY) { + float alpha = isMouseOver(pMouseX, pMouseY) ? 1.0f : 0.3f; + alpha = (SpiritwebMenu.selectedManifestationType == this.manifestation) ? 1.0f : alpha; final ResourceLocation resourceLocation = new ResourceLocation(manifestation.getName(), "textures/icon/" + manifestation.getName() + ".png"); RenderSystem.setShaderTexture(0, resourceLocation); + RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, alpha); RenderSystem.enableBlend(); RenderSystem.blendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, 1, 0); @@ -72,5 +75,7 @@ private void renderIcon(GuiGraphics pGuiGraphics) width-2, height-2 ); + + RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f); } } From efaf5a36d4b45bdf378688794c6bee37745b1f02 Mon Sep 17 00:00:00 2001 From: Gerbagel Date: Tue, 27 Jan 2026 14:45:51 +0100 Subject: [PATCH 05/55] [Cosmere] Pass through mouseClicked to subscreens --- .../client/gui/AllomancySpiritwebMenu.java | 6 ++++++ .../client/gui/InnerRadialButton.java | 19 +++++++++++++++++++ .../client/gui/OuterRadialButton.java | 15 ++++++++++----- .../cosmere/client/gui/SpiritwebMenu.java | 10 ++++++++++ 4 files changed, 45 insertions(+), 5 deletions(-) diff --git a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/AllomancySpiritwebMenu.java b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/AllomancySpiritwebMenu.java index dc2e76c1e..d7bfca74b 100644 --- a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/AllomancySpiritwebMenu.java +++ b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/AllomancySpiritwebMenu.java @@ -45,6 +45,12 @@ protected void init() })); } + @Override + public boolean mouseClicked(double pMouseX, double pMouseY, int pButton) + { + return super.mouseClicked(pMouseX, pMouseY, pButton); + } + @Override public void render(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) { diff --git a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java index 2e2235a44..3e6cc536b 100644 --- a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java +++ b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java @@ -6,6 +6,9 @@ import com.mojang.blaze3d.vertex.Tesselator; import com.mojang.blaze3d.vertex.VertexFormat; import leaf.cosmere.api.manifestation.Manifestation; +import leaf.cosmere.common.Cosmere; +import leaf.cosmere.common.network.packets.ChangeManifestationModeMessage; +import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.Button; import net.minecraft.client.renderer.GameRenderer; @@ -73,6 +76,21 @@ public boolean isMouseOver(double mouseX, double mouseY) } } + @Override + public boolean mouseClicked(double pMouseX, double pMouseY, int pButton) + { + if (isMouseOver(pMouseX, pMouseY)) + { + if (pButton == 0) + Cosmere.packetHandler().sendToServer(new ChangeManifestationModeMessage(manifestation, 1)); + else + Cosmere.packetHandler().sendToServer(new ChangeManifestationModeMessage(manifestation, -1)); + + playDownSound(Minecraft.getInstance().getSoundManager()); + } + return super.mouseClicked(pMouseX, pMouseY, pButton); + } + private double normalizeAngle(double angle) { if (angle != 0) @@ -86,6 +104,7 @@ private double normalizeAngle(double angle) return angle; } + // inspired by SteelCodeTeam's Metallic Arts https://github.com/SteelCodeTeam/Metallics-Arts private void renderSegment(GuiGraphics pGuiGraphics, boolean isHovered) { float r, g, b, a; diff --git a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java index d40ca3a8b..0583eba0d 100644 --- a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java +++ b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java @@ -9,6 +9,7 @@ import leaf.cosmere.api.manifestation.Manifestation; import leaf.cosmere.common.Cosmere; import leaf.cosmere.common.network.packets.ChangeManifestationModeMessage; +import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.Button; import net.minecraft.client.renderer.GameRenderer; @@ -45,7 +46,6 @@ protected OuterRadialButton(int centerX, int centerY, int segmentNr, Manifestati @Override protected void renderWidget(@NotNull GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) { - //CosmereAPI.logger.info("Rendering at " + centerX + " | " + centerY); renderSegment(pGuiGraphics, isMouseOver(pMouseX, pMouseY)); //renderIcon(pGuiGraphics); } @@ -83,10 +83,15 @@ public boolean isMouseOver(double mouseX, double mouseY) @Override public boolean mouseClicked(double pMouseX, double pMouseY, int pButton) { - if (pButton == 0) - Cosmere.packetHandler().sendToServer(new ChangeManifestationModeMessage(manifestation, 1)); - else - Cosmere.packetHandler().sendToServer(new ChangeManifestationModeMessage(manifestation, -1)); + if (isMouseOver(pMouseX, pMouseY)) + { + if (pButton == 0) + Cosmere.packetHandler().sendToServer(new ChangeManifestationModeMessage(manifestation, 1)); + else + Cosmere.packetHandler().sendToServer(new ChangeManifestationModeMessage(manifestation, -1)); + + playDownSound(Minecraft.getInstance().getSoundManager()); + } return super.mouseClicked(pMouseX, pMouseY, pButton); } diff --git a/src/main/java/leaf/cosmere/client/gui/SpiritwebMenu.java b/src/main/java/leaf/cosmere/client/gui/SpiritwebMenu.java index 6576b29ca..79d093f74 100644 --- a/src/main/java/leaf/cosmere/client/gui/SpiritwebMenu.java +++ b/src/main/java/leaf/cosmere/client/gui/SpiritwebMenu.java @@ -98,6 +98,16 @@ public void render(@NotNull GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, } } + @Override + public boolean mouseClicked(double pMouseX, double pMouseY, int pButton) + { + if (selectedManifestationScreen != null) + { + selectedManifestationScreen.mouseClicked(pMouseX, pMouseY, pButton); + } + return super.mouseClicked(pMouseX, pMouseY, pButton); + } + @Override public boolean keyReleased(int pKeyCode, int pScanCode, int pModifiers) { From f55c1e1cc5e73149ee0a0e9dcc455ef2b24346b1 Mon Sep 17 00:00:00 2001 From: Gerbagel Date: Tue, 27 Jan 2026 18:51:24 +0100 Subject: [PATCH 06/55] [Cosmere] Colors for mode, hover, and unavailable --- .../client/gui/AllomancySpiritwebMenu.java | 49 ++++++---- .../client/gui/InnerRadialButton.java | 94 ++++++++++++++++--- .../client/gui/OuterRadialButton.java | 88 ++++++++++------- 3 files changed, 169 insertions(+), 62 deletions(-) diff --git a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/AllomancySpiritwebMenu.java b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/AllomancySpiritwebMenu.java index d7bfca74b..6d0190333 100644 --- a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/AllomancySpiritwebMenu.java +++ b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/AllomancySpiritwebMenu.java @@ -1,5 +1,6 @@ package leaf.cosmere.allomancy.client.gui; +import leaf.cosmere.api.Metals; import leaf.cosmere.common.cap.entity.SpiritwebCapability; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; @@ -25,23 +26,39 @@ protected void init() this.height = Minecraft.getInstance().getWindow().getGuiScaledHeight(); SpiritwebCapability.get(player).ifPresent( (iSpiritweb -> { - addRenderableWidget(new OuterRadialButton(width/2, height/2, 0, iSpiritweb.getAvailableManifestations().get(0))); - addRenderableWidget(new OuterRadialButton(width/2, height/2, 1, iSpiritweb.getAvailableManifestations().get(1))); - addRenderableWidget(new OuterRadialButton(width/2, height/2, 2, iSpiritweb.getAvailableManifestations().get(2))); - addRenderableWidget(new OuterRadialButton(width/2, height/2, 3, iSpiritweb.getAvailableManifestations().get(3))); - addRenderableWidget(new OuterRadialButton(width/2, height/2, 4, iSpiritweb.getAvailableManifestations().get(4))); - addRenderableWidget(new OuterRadialButton(width/2, height/2, 5, iSpiritweb.getAvailableManifestations().get(5))); - addRenderableWidget(new OuterRadialButton(width/2, height/2, 6, iSpiritweb.getAvailableManifestations().get(6))); - addRenderableWidget(new OuterRadialButton(width/2, height/2, 7, iSpiritweb.getAvailableManifestations().get(7))); + // Steel + addRenderableWidget(new OuterRadialButton(width/2, height/2, 7, Metals.MetalType.STEEL, iSpiritweb)); + // Iron + addRenderableWidget(new OuterRadialButton(width/2, height/2, 6, Metals.MetalType.IRON, iSpiritweb)); + // Zinc + addRenderableWidget(new OuterRadialButton(width/2, height/2, 0, Metals.MetalType.ZINC, iSpiritweb)); + // Brass + addRenderableWidget(new OuterRadialButton(width/2, height/2, 1, Metals.MetalType.BRASS, iSpiritweb)); + // Bendalloy + addRenderableWidget(new OuterRadialButton(width/2, height/2, 2, Metals.MetalType.BENDALLOY, iSpiritweb)); + // Cadmium + addRenderableWidget(new OuterRadialButton(width/2, height/2, 3, Metals.MetalType.CADMIUM, iSpiritweb)); + // Chromium + addRenderableWidget(new OuterRadialButton(width/2, height/2, 4, Metals.MetalType.CHROMIUM, iSpiritweb)); + // Nicrosil + addRenderableWidget(new OuterRadialButton(width/2, height/2, 5, Metals.MetalType.NICROSIL, iSpiritweb)); - addRenderableWidget(new InnerRadialButton(width/2, height/2, 0, iSpiritweb.getAvailableManifestations().get(0))); - addRenderableWidget(new InnerRadialButton(width/2, height/2, 1, iSpiritweb.getAvailableManifestations().get(1))); - addRenderableWidget(new InnerRadialButton(width/2, height/2, 2, iSpiritweb.getAvailableManifestations().get(2))); - addRenderableWidget(new InnerRadialButton(width/2, height/2, 3, iSpiritweb.getAvailableManifestations().get(3))); - addRenderableWidget(new InnerRadialButton(width/2, height/2, 4, iSpiritweb.getAvailableManifestations().get(4))); - addRenderableWidget(new InnerRadialButton(width/2, height/2, 5, iSpiritweb.getAvailableManifestations().get(5))); - addRenderableWidget(new InnerRadialButton(width/2, height/2, 6, iSpiritweb.getAvailableManifestations().get(6))); - addRenderableWidget(new InnerRadialButton(width/2, height/2, 7, iSpiritweb.getAvailableManifestations().get(7))); + // Pewter + addRenderableWidget(new InnerRadialButton(width/2, height/2, 7, Metals.MetalType.PEWTER, iSpiritweb)); + // Tin + addRenderableWidget(new InnerRadialButton(width/2, height/2, 6, Metals.MetalType.TIN, iSpiritweb)); + // Copper + addRenderableWidget(new InnerRadialButton(width/2, height/2, 0, Metals.MetalType.COPPER, iSpiritweb)); + // Bronze + addRenderableWidget(new InnerRadialButton(width/2, height/2, 1, Metals.MetalType.BRONZE, iSpiritweb)); + // Electrum + addRenderableWidget(new InnerRadialButton(width/2, height/2, 2, Metals.MetalType.ELECTRUM, iSpiritweb)); + // Gold + addRenderableWidget(new InnerRadialButton(width/2, height/2, 3, Metals.MetalType.GOLD, iSpiritweb)); + // Aluminum + addRenderableWidget(new InnerRadialButton(width/2, height/2, 4, Metals.MetalType.ALUMINUM, iSpiritweb)); + // Duralumin + addRenderableWidget(new InnerRadialButton(width/2, height/2, 5, Metals.MetalType.DURALUMIN, iSpiritweb)); })); } diff --git a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java index 3e6cc536b..31e4f627e 100644 --- a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java +++ b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java @@ -5,7 +5,12 @@ import com.mojang.blaze3d.vertex.DefaultVertexFormat; import com.mojang.blaze3d.vertex.Tesselator; import com.mojang.blaze3d.vertex.VertexFormat; +import leaf.cosmere.allomancy.common.manifestation.AllomancyManifestation; +import leaf.cosmere.api.IHasMetalType; +import leaf.cosmere.api.Manifestations; +import leaf.cosmere.api.Metals; import leaf.cosmere.api.manifestation.Manifestation; +import leaf.cosmere.api.spiritweb.ISpiritweb; import leaf.cosmere.common.Cosmere; import leaf.cosmere.common.network.packets.ChangeManifestationModeMessage; import net.minecraft.client.Minecraft; @@ -13,9 +18,11 @@ import net.minecraft.client.gui.components.Button; import net.minecraft.client.renderer.GameRenderer; import net.minecraft.network.chat.CommonComponents; +import net.minecraft.resources.ResourceLocation; import net.minecraft.util.Mth; import org.jetbrains.annotations.NotNull; import org.joml.Matrix4f; +import org.lwjgl.opengl.GL11; public class InnerRadialButton extends Button { @@ -26,12 +33,16 @@ public class InnerRadialButton extends Button private final int segmentNr; private final int centerX; private final int centerY; + private final boolean hasManifestation; private final Manifestation manifestation; + private final ISpiritweb spiritweb; - protected InnerRadialButton(int centerX, int centerY, int segmentNr, Manifestation manifestation) + protected InnerRadialButton(int centerX, int centerY, int segmentNr, Metals.MetalType metal, ISpiritweb spiritweb) { super(centerX, centerY, 16, 16, CommonComponents.EMPTY, (button) -> {}, DEFAULT_NARRATION); - this.manifestation = manifestation; + this.spiritweb = spiritweb; + manifestation = Manifestations.ManifestationTypes.ALLOMANCY.getManifestation(metal.getID()); + hasManifestation = spiritweb.hasManifestation(manifestation); double eighthCircle = Math.toRadians(45.d); // a circle is 360 degrees, / by 8 for 45 degrees, converted to radians this.segmentNr = segmentNr; startAngle = segmentNr * eighthCircle; // todo: decided by power ID @@ -44,6 +55,7 @@ protected InnerRadialButton(int centerX, int centerY, int segmentNr, Manifestati protected void renderWidget(@NotNull GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) { renderSegment(pGuiGraphics, isMouseOver(pMouseX, pMouseY)); + renderIcon(pGuiGraphics); } @Override @@ -79,7 +91,7 @@ public boolean isMouseOver(double mouseX, double mouseY) @Override public boolean mouseClicked(double pMouseX, double pMouseY, int pButton) { - if (isMouseOver(pMouseX, pMouseY)) + if (isMouseOver(pMouseX, pMouseY) && hasManifestation) { if (pButton == 0) Cosmere.packetHandler().sendToServer(new ChangeManifestationModeMessage(manifestation, 1)); @@ -104,17 +116,34 @@ private double normalizeAngle(double angle) return angle; } - // inspired by SteelCodeTeam's Metallic Arts https://github.com/SteelCodeTeam/Metallics-Arts + // inspired by SteelCodeTeam's Metallic Arts https://github.com/SteelCodeTeam/Metallics-Arts/blob/main/src/main/java/net/rudahee/metallics_arts/modules/logic/client/custom_guis/selectors/AllomanticSelector.java private void renderSegment(GuiGraphics pGuiGraphics, boolean isHovered) { - float r, g, b, a; + float r, g, b; + float a = 1f; - if (isHovered) { - r = g = b = a = 1.0f; - } else { - r = g = 0.f; - b = 0.67f; - a = 1.0f; + if (!hasManifestation) + { + r = g = b = 0.1f; + } + else + { + r = g = b = 0.5f; + } + + if (isHovered && hasManifestation) + { + r = g = b = 0.6f; + } + + if (manifestation instanceof AllomancyManifestation allomancyManifestation) + { + int mode = allomancyManifestation.getMode(spiritweb); + + if (mode > 0) + r = r + 0.2f * mode; + else if (mode < 0) + b = b + 0.2f * mode; } float radsPerSegment = (float) Math.PI * 2 / 8; @@ -150,4 +179,47 @@ private void renderSegment(GuiGraphics pGuiGraphics, boolean isHovered) RenderSystem.disableBlend(); } + + private void renderIcon(@NotNull GuiGraphics pGuiGraphics) + { + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.setLength(0); + stringBuilder.append("textures/icon/") + .append(manifestation.getManifestationType().getName()) + .append("/"); + + // no need for a switch case, always allomancy + if (manifestation instanceof IHasMetalType metalType) + { + stringBuilder.append(metalType.getMetalType().getName()); + } + + stringBuilder.append(".png"); + final ResourceLocation location = new ResourceLocation(manifestation.getRegistryName().getNamespace(), stringBuilder.toString()); + float alpha = hasManifestation ? 1.0f : 0.25f; + RenderSystem.setShaderTexture(0, location); + RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, alpha); + RenderSystem.enableBlend(); + RenderSystem.blendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, 1, 0); + + double midAngle = (startAngle + endAngle) / 2; + double midRadius = (INNER_RADIUS + OUTER_RADIUS) / 1.5; + int iconSize = width-2; + int posX = centerX + (int)(Math.cos(midAngle) * midRadius) - iconSize/2; + int posY = centerY + (int)(Math.sin(midAngle) * midRadius) - iconSize/2; + + pGuiGraphics.blit(location, + posX, + posY, + iconSize, + iconSize, + 0, + 0, + width, + height, + width, + height); + + RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f); + } } diff --git a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java index 0583eba0d..f6dc08fbd 100644 --- a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java +++ b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java @@ -5,8 +5,12 @@ import com.mojang.blaze3d.vertex.DefaultVertexFormat; import com.mojang.blaze3d.vertex.Tesselator; import com.mojang.blaze3d.vertex.VertexFormat; +import leaf.cosmere.allomancy.common.manifestation.AllomancyManifestation; import leaf.cosmere.api.IHasMetalType; +import leaf.cosmere.api.Manifestations; +import leaf.cosmere.api.Metals; import leaf.cosmere.api.manifestation.Manifestation; +import leaf.cosmere.api.spiritweb.ISpiritweb; import leaf.cosmere.common.Cosmere; import leaf.cosmere.common.network.packets.ChangeManifestationModeMessage; import net.minecraft.client.Minecraft; @@ -19,6 +23,7 @@ import net.minecraft.util.Mth; import org.jetbrains.annotations.NotNull; import org.joml.Matrix4f; +import org.lwjgl.opengl.GL11; public class OuterRadialButton extends Button { @@ -29,15 +34,19 @@ public class OuterRadialButton extends Button private final int segmentNr; private final int centerX; private final int centerY; + private final boolean hasManifestation; private final Manifestation manifestation; + private final ISpiritweb spiritweb; - protected OuterRadialButton(int centerX, int centerY, int segmentNr, Manifestation manifestation) + protected OuterRadialButton(int centerX, int centerY, int segmentNr, Metals.MetalType metal, ISpiritweb spiritweb) { super(centerX, centerY, 16, 16, CommonComponents.EMPTY, (button) -> {}, DEFAULT_NARRATION); - this.manifestation = manifestation; + this.spiritweb = spiritweb; + manifestation = Manifestations.ManifestationTypes.ALLOMANCY.getManifestation(metal.getID()); + hasManifestation = this.spiritweb.hasManifestation(manifestation); double eighthCircle = Math.toRadians(45.d); // a circle is 360 degrees, / by 8 for 45 degrees, converted to radians - this.segmentNr = segmentNr; - startAngle = segmentNr * eighthCircle; // todo: decided by power ID + this.segmentNr = segmentNr; // MetalType doesn't align with the chart in a pattern that can be programmatically written out; we do this manually + startAngle = segmentNr * eighthCircle; endAngle = startAngle + eighthCircle; this.centerX = centerX; this.centerY = centerY; @@ -47,7 +56,7 @@ protected OuterRadialButton(int centerX, int centerY, int segmentNr, Manifestati protected void renderWidget(@NotNull GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) { renderSegment(pGuiGraphics, isMouseOver(pMouseX, pMouseY)); - //renderIcon(pGuiGraphics); + renderIcon(pGuiGraphics); } @Override @@ -83,7 +92,7 @@ public boolean isMouseOver(double mouseX, double mouseY) @Override public boolean mouseClicked(double pMouseX, double pMouseY, int pButton) { - if (isMouseOver(pMouseX, pMouseY)) + if (isMouseOver(pMouseX, pMouseY) && hasManifestation) { if (pButton == 0) Cosmere.packetHandler().sendToServer(new ChangeManifestationModeMessage(manifestation, 1)); @@ -114,16 +123,34 @@ private double normalizeAngle(double angle) return angle; } - // inspired by SteelCodeTeam's Metallic Arts https://github.com/SteelCodeTeam/Metallics-Arts + // inspired by SteelCodeTeam's Metallic Arts https://github.com/SteelCodeTeam/Metallics-Arts/blob/main/src/main/java/net/rudahee/metallics_arts/modules/logic/client/custom_guis/selectors/AllomanticSelector.java private void renderSegment(@NotNull GuiGraphics pGuiGraphics, boolean isHovered) { - float r, g, b, a; + float r, g, b; + float a = 1f; - if (isHovered) { - r = g = b = a = 1.0f; - } else { - r = g = b = 0.67f; - a = 1.0f; + if (!hasManifestation) + { + r = g = b = 0.1f; + } + else + { + r = g = b = 0.5f; + } + + if (isHovered && hasManifestation) + { + r = g = b = 0.6f; + } + + if (manifestation instanceof AllomancyManifestation allomancyManifestation) + { + int mode = allomancyManifestation.getMode(spiritweb); + + if (mode > 0) + r = r + 0.2f * mode; + else if (mode < 0) + b = b + 0.2f * mode; } float radsPerSegment = (float) Math.PI * 2 / 8; @@ -168,47 +195,38 @@ private void renderIcon(@NotNull GuiGraphics pGuiGraphics) .append(manifestation.getManifestationType().getName()) .append("/"); - switch (manifestation.getManifestationType()) + // no need for a switch case, always allomancy + if (manifestation instanceof IHasMetalType metalType) { - case ALLOMANCY: - case FERUCHEMY: - if (manifestation instanceof IHasMetalType metalType) - { - stringBuilder.append(metalType.getMetalType().getName()); - } - break; - case SURGEBINDING: - stringBuilder.append(manifestation.getName()); - case AON_DOR: - case AWAKENING: - break; + stringBuilder.append(metalType.getMetalType().getName()); } stringBuilder.append(".png"); final ResourceLocation location = new ResourceLocation(manifestation.getRegistryName().getNamespace(), stringBuilder.toString()); + float alpha = hasManifestation ? 1.0f : 0.25f; RenderSystem.setShaderTexture(0, location); + RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, alpha); + RenderSystem.enableBlend(); + RenderSystem.blendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, 1, 0); double midAngle = (startAngle + endAngle) / 2; double midRadius = (INNER_RADIUS + OUTER_RADIUS) / 2.0; - int posX = getX() + (int)(Math.cos(midAngle) * midRadius); - int posY = getY() + (int)(Math.sin(midAngle) * midRadius); + int iconSize = width - 2; + int posX = centerX + (int)(Math.cos(midAngle) * midRadius) - iconSize/2; + int posY = centerY + (int)(Math.sin(midAngle) * midRadius) - iconSize/2; pGuiGraphics.blit(location, posX, posY, - width-2, - height-2, + iconSize, + iconSize, 0, 0, width, height, width, height); - } - private void drawTriangle(GuiGraphics guiGraphics, int x1, int y1, int x2, int y2, int x3, int y3, int color) { - // This is a simple approach - for proper rendering you'd want to use the actual vertex buffer - guiGraphics.fill(Math.min(x1, Math.min(x2, x3)), Math.min(y1, Math.min(y2, y3)), - Math.max(x1, Math.max(x2, x3)), Math.max(y1, Math.max(y2, y3)), color); + RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f); } } From fe8f3e1cc54efb35fe9289d156bfddecb1083152 Mon Sep 17 00:00:00 2001 From: Gerbagel Date: Tue, 27 Jan 2026 18:56:57 +0100 Subject: [PATCH 07/55] [Allomancy] Proper metal ordering in menu --- .../client/gui/AllomancySpiritwebMenu.java | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/AllomancySpiritwebMenu.java b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/AllomancySpiritwebMenu.java index 6d0190333..42b3eda58 100644 --- a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/AllomancySpiritwebMenu.java +++ b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/AllomancySpiritwebMenu.java @@ -27,38 +27,38 @@ protected void init() SpiritwebCapability.get(player).ifPresent( (iSpiritweb -> { // Steel - addRenderableWidget(new OuterRadialButton(width/2, height/2, 7, Metals.MetalType.STEEL, iSpiritweb)); + addRenderableWidget(new OuterRadialButton(width/2, height/2, 4, Metals.MetalType.STEEL, iSpiritweb)); // Iron - addRenderableWidget(new OuterRadialButton(width/2, height/2, 6, Metals.MetalType.IRON, iSpiritweb)); + addRenderableWidget(new OuterRadialButton(width/2, height/2, 5, Metals.MetalType.IRON, iSpiritweb)); // Zinc - addRenderableWidget(new OuterRadialButton(width/2, height/2, 0, Metals.MetalType.ZINC, iSpiritweb)); + addRenderableWidget(new OuterRadialButton(width/2, height/2, 6, Metals.MetalType.ZINC, iSpiritweb)); // Brass - addRenderableWidget(new OuterRadialButton(width/2, height/2, 1, Metals.MetalType.BRASS, iSpiritweb)); + addRenderableWidget(new OuterRadialButton(width/2, height/2, 7, Metals.MetalType.BRASS, iSpiritweb)); // Bendalloy - addRenderableWidget(new OuterRadialButton(width/2, height/2, 2, Metals.MetalType.BENDALLOY, iSpiritweb)); + addRenderableWidget(new OuterRadialButton(width/2, height/2, 0, Metals.MetalType.BENDALLOY, iSpiritweb)); // Cadmium - addRenderableWidget(new OuterRadialButton(width/2, height/2, 3, Metals.MetalType.CADMIUM, iSpiritweb)); + addRenderableWidget(new OuterRadialButton(width/2, height/2, 1, Metals.MetalType.CADMIUM, iSpiritweb)); // Chromium - addRenderableWidget(new OuterRadialButton(width/2, height/2, 4, Metals.MetalType.CHROMIUM, iSpiritweb)); + addRenderableWidget(new OuterRadialButton(width/2, height/2, 2, Metals.MetalType.CHROMIUM, iSpiritweb)); // Nicrosil - addRenderableWidget(new OuterRadialButton(width/2, height/2, 5, Metals.MetalType.NICROSIL, iSpiritweb)); + addRenderableWidget(new OuterRadialButton(width/2, height/2, 3, Metals.MetalType.NICROSIL, iSpiritweb)); // Pewter - addRenderableWidget(new InnerRadialButton(width/2, height/2, 7, Metals.MetalType.PEWTER, iSpiritweb)); + addRenderableWidget(new InnerRadialButton(width/2, height/2, 4, Metals.MetalType.PEWTER, iSpiritweb)); // Tin - addRenderableWidget(new InnerRadialButton(width/2, height/2, 6, Metals.MetalType.TIN, iSpiritweb)); + addRenderableWidget(new InnerRadialButton(width/2, height/2, 5, Metals.MetalType.TIN, iSpiritweb)); // Copper - addRenderableWidget(new InnerRadialButton(width/2, height/2, 0, Metals.MetalType.COPPER, iSpiritweb)); + addRenderableWidget(new InnerRadialButton(width/2, height/2, 6, Metals.MetalType.COPPER, iSpiritweb)); // Bronze - addRenderableWidget(new InnerRadialButton(width/2, height/2, 1, Metals.MetalType.BRONZE, iSpiritweb)); + addRenderableWidget(new InnerRadialButton(width/2, height/2, 7, Metals.MetalType.BRONZE, iSpiritweb)); // Electrum - addRenderableWidget(new InnerRadialButton(width/2, height/2, 2, Metals.MetalType.ELECTRUM, iSpiritweb)); + addRenderableWidget(new InnerRadialButton(width/2, height/2, 0, Metals.MetalType.ELECTRUM, iSpiritweb)); // Gold - addRenderableWidget(new InnerRadialButton(width/2, height/2, 3, Metals.MetalType.GOLD, iSpiritweb)); + addRenderableWidget(new InnerRadialButton(width/2, height/2, 1, Metals.MetalType.GOLD, iSpiritweb)); // Aluminum - addRenderableWidget(new InnerRadialButton(width/2, height/2, 4, Metals.MetalType.ALUMINUM, iSpiritweb)); + addRenderableWidget(new InnerRadialButton(width/2, height/2, 2, Metals.MetalType.ALUMINUM, iSpiritweb)); // Duralumin - addRenderableWidget(new InnerRadialButton(width/2, height/2, 5, Metals.MetalType.DURALUMIN, iSpiritweb)); + addRenderableWidget(new InnerRadialButton(width/2, height/2, 3, Metals.MetalType.DURALUMIN, iSpiritweb)); })); } From 12d0b9cc0705b7f5fa84f561e5cb7d28d12bcb5e Mon Sep 17 00:00:00 2001 From: Gerbagel Date: Tue, 27 Jan 2026 19:08:14 +0100 Subject: [PATCH 08/55] [Allomancy] Finetuning menu dimensions --- .../client/gui/AllomancySpiritwebMenu.java | 35 ++++++++++--------- .../client/gui/InnerRadialButton.java | 15 ++++---- .../client/gui/OuterRadialButton.java | 15 ++++---- 3 files changed, 37 insertions(+), 28 deletions(-) diff --git a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/AllomancySpiritwebMenu.java b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/AllomancySpiritwebMenu.java index 42b3eda58..4fb0fbdad 100644 --- a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/AllomancySpiritwebMenu.java +++ b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/AllomancySpiritwebMenu.java @@ -26,39 +26,42 @@ protected void init() this.height = Minecraft.getInstance().getWindow().getGuiScaledHeight(); SpiritwebCapability.get(player).ifPresent( (iSpiritweb -> { + int circleCenterX = width/2; + int circleCenterY = height/2 + height/16; // heh, 16, nice + // Steel - addRenderableWidget(new OuterRadialButton(width/2, height/2, 4, Metals.MetalType.STEEL, iSpiritweb)); + addRenderableWidget(new OuterRadialButton(circleCenterX, circleCenterY, 4, Metals.MetalType.STEEL, iSpiritweb)); // Iron - addRenderableWidget(new OuterRadialButton(width/2, height/2, 5, Metals.MetalType.IRON, iSpiritweb)); + addRenderableWidget(new OuterRadialButton(circleCenterX, circleCenterY, 5, Metals.MetalType.IRON, iSpiritweb)); // Zinc - addRenderableWidget(new OuterRadialButton(width/2, height/2, 6, Metals.MetalType.ZINC, iSpiritweb)); + addRenderableWidget(new OuterRadialButton(circleCenterX, circleCenterY, 6, Metals.MetalType.ZINC, iSpiritweb)); // Brass - addRenderableWidget(new OuterRadialButton(width/2, height/2, 7, Metals.MetalType.BRASS, iSpiritweb)); + addRenderableWidget(new OuterRadialButton(circleCenterX, circleCenterY, 7, Metals.MetalType.BRASS, iSpiritweb)); // Bendalloy - addRenderableWidget(new OuterRadialButton(width/2, height/2, 0, Metals.MetalType.BENDALLOY, iSpiritweb)); + addRenderableWidget(new OuterRadialButton(circleCenterX, circleCenterY, 0, Metals.MetalType.BENDALLOY, iSpiritweb)); // Cadmium - addRenderableWidget(new OuterRadialButton(width/2, height/2, 1, Metals.MetalType.CADMIUM, iSpiritweb)); + addRenderableWidget(new OuterRadialButton(circleCenterX, circleCenterY, 1, Metals.MetalType.CADMIUM, iSpiritweb)); // Chromium - addRenderableWidget(new OuterRadialButton(width/2, height/2, 2, Metals.MetalType.CHROMIUM, iSpiritweb)); + addRenderableWidget(new OuterRadialButton(circleCenterX, circleCenterY, 2, Metals.MetalType.CHROMIUM, iSpiritweb)); // Nicrosil - addRenderableWidget(new OuterRadialButton(width/2, height/2, 3, Metals.MetalType.NICROSIL, iSpiritweb)); + addRenderableWidget(new OuterRadialButton(circleCenterX, circleCenterY, 3, Metals.MetalType.NICROSIL, iSpiritweb)); // Pewter - addRenderableWidget(new InnerRadialButton(width/2, height/2, 4, Metals.MetalType.PEWTER, iSpiritweb)); + addRenderableWidget(new InnerRadialButton(circleCenterX, circleCenterY, 4, Metals.MetalType.PEWTER, iSpiritweb)); // Tin - addRenderableWidget(new InnerRadialButton(width/2, height/2, 5, Metals.MetalType.TIN, iSpiritweb)); + addRenderableWidget(new InnerRadialButton(circleCenterX, circleCenterY, 5, Metals.MetalType.TIN, iSpiritweb)); // Copper - addRenderableWidget(new InnerRadialButton(width/2, height/2, 6, Metals.MetalType.COPPER, iSpiritweb)); + addRenderableWidget(new InnerRadialButton(circleCenterX, circleCenterY, 6, Metals.MetalType.COPPER, iSpiritweb)); // Bronze - addRenderableWidget(new InnerRadialButton(width/2, height/2, 7, Metals.MetalType.BRONZE, iSpiritweb)); + addRenderableWidget(new InnerRadialButton(circleCenterX, circleCenterY, 7, Metals.MetalType.BRONZE, iSpiritweb)); // Electrum - addRenderableWidget(new InnerRadialButton(width/2, height/2, 0, Metals.MetalType.ELECTRUM, iSpiritweb)); + addRenderableWidget(new InnerRadialButton(circleCenterX, circleCenterY, 0, Metals.MetalType.ELECTRUM, iSpiritweb)); // Gold - addRenderableWidget(new InnerRadialButton(width/2, height/2, 1, Metals.MetalType.GOLD, iSpiritweb)); + addRenderableWidget(new InnerRadialButton(circleCenterX, circleCenterY, 1, Metals.MetalType.GOLD, iSpiritweb)); // Aluminum - addRenderableWidget(new InnerRadialButton(width/2, height/2, 2, Metals.MetalType.ALUMINUM, iSpiritweb)); + addRenderableWidget(new InnerRadialButton(circleCenterX, circleCenterY, 2, Metals.MetalType.ALUMINUM, iSpiritweb)); // Duralumin - addRenderableWidget(new InnerRadialButton(width/2, height/2, 3, Metals.MetalType.DURALUMIN, iSpiritweb)); + addRenderableWidget(new InnerRadialButton(circleCenterX, circleCenterY, 3, Metals.MetalType.DURALUMIN, iSpiritweb)); })); } diff --git a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java index 31e4f627e..f4ba8b580 100644 --- a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java +++ b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java @@ -26,8 +26,8 @@ public class InnerRadialButton extends Button { - private static final int OUTER_RADIUS = 60; - private static final int INNER_RADIUS = 0; + private final float outerRadius; + private final float innerRadius; private final double startAngle; private final double endAngle; private final int segmentNr; @@ -49,6 +49,9 @@ protected InnerRadialButton(int centerX, int centerY, int segmentNr, Metals.Meta endAngle = startAngle + eighthCircle; this.centerX = centerX; this.centerY = centerY; + + outerRadius = (float) Minecraft.getInstance().getWindow().getGuiScaledHeight() / 3f * 0.7f; + innerRadius = 0; } @Override @@ -65,8 +68,8 @@ public boolean isMouseOver(double mouseX, double mouseY) double distanceY = mouseY - centerY; double dSqr = distanceX * distanceX + distanceY * distanceY; - if (dSqr < INNER_RADIUS * INNER_RADIUS || - dSqr > OUTER_RADIUS * OUTER_RADIUS) + if (dSqr < innerRadius * innerRadius || + dSqr > outerRadius * outerRadius) { return false; } @@ -148,7 +151,7 @@ else if (mode < 0) float radsPerSegment = (float) Math.PI * 2 / 8; float step = (float) Math.PI / 180; - float radius = OUTER_RADIUS; + float radius = outerRadius; RenderSystem.disableCull(); RenderSystem.enableBlend(); @@ -203,7 +206,7 @@ private void renderIcon(@NotNull GuiGraphics pGuiGraphics) RenderSystem.blendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, 1, 0); double midAngle = (startAngle + endAngle) / 2; - double midRadius = (INNER_RADIUS + OUTER_RADIUS) / 1.5; + double midRadius = (innerRadius + outerRadius) / 1.5; int iconSize = width-2; int posX = centerX + (int)(Math.cos(midAngle) * midRadius) - iconSize/2; int posY = centerY + (int)(Math.sin(midAngle) * midRadius) - iconSize/2; diff --git a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java index f6dc08fbd..c5c45990c 100644 --- a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java +++ b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java @@ -27,8 +27,8 @@ public class OuterRadialButton extends Button { - private static final int OUTER_RADIUS = 80; - private static final int INNER_RADIUS = 60; + private final float outerRadius; + private final float innerRadius; private final double startAngle; private final double endAngle; private final int segmentNr; @@ -50,6 +50,9 @@ protected OuterRadialButton(int centerX, int centerY, int segmentNr, Metals.Meta endAngle = startAngle + eighthCircle; this.centerX = centerX; this.centerY = centerY; + + outerRadius = (float) Minecraft.getInstance().getWindow().getGuiScaledHeight() / 3; + innerRadius = outerRadius * 0.7f; } @Override @@ -66,8 +69,8 @@ public boolean isMouseOver(double mouseX, double mouseY) double distanceY = mouseY - centerY; double dSqr = distanceX * distanceX + distanceY * distanceY; - if (dSqr < INNER_RADIUS * INNER_RADIUS || - dSqr > OUTER_RADIUS * OUTER_RADIUS) + if (dSqr < innerRadius * innerRadius || + dSqr > outerRadius * outerRadius) { return false; } @@ -155,7 +158,7 @@ else if (mode < 0) float radsPerSegment = (float) Math.PI * 2 / 8; float step = (float) Math.PI / 180; - float radius = OUTER_RADIUS; + float radius = outerRadius; RenderSystem.disableCull(); RenderSystem.enableBlend(); @@ -210,7 +213,7 @@ private void renderIcon(@NotNull GuiGraphics pGuiGraphics) RenderSystem.blendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, 1, 0); double midAngle = (startAngle + endAngle) / 2; - double midRadius = (INNER_RADIUS + OUTER_RADIUS) / 2.0; + double midRadius = (innerRadius + outerRadius) / 2.0; int iconSize = width - 2; int posX = centerX + (int)(Math.cos(midAngle) * midRadius) - iconSize/2; int posY = centerY + (int)(Math.sin(midAngle) * midRadius) - iconSize/2; From af6520a1788277c81d9882a345e85a5b976d1e40 Mon Sep 17 00:00:00 2001 From: Gerbagel Date: Tue, 27 Jan 2026 22:53:21 +0100 Subject: [PATCH 09/55] [Allomancy] Add hover text to buttons --- .../client/gui/InnerRadialButton.java | 32 ++++++++++++++++++- .../client/gui/OuterRadialButton.java | 30 ++++++++++++++++- 2 files changed, 60 insertions(+), 2 deletions(-) diff --git a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java index f4ba8b580..c475e1c79 100644 --- a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java +++ b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java @@ -14,9 +14,11 @@ import leaf.cosmere.common.Cosmere; import leaf.cosmere.common.network.packets.ChangeManifestationModeMessage; import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Font; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.Button; import net.minecraft.client.renderer.GameRenderer; +import net.minecraft.client.resources.language.I18n; import net.minecraft.network.chat.CommonComponents; import net.minecraft.resources.ResourceLocation; import net.minecraft.util.Mth; @@ -26,6 +28,7 @@ public class InnerRadialButton extends Button { + private static final int TEXT_DISTANCE = 30; private final float outerRadius; private final float innerRadius; private final double startAngle; @@ -57,8 +60,13 @@ protected InnerRadialButton(int centerX, int centerY, int segmentNr, Metals.Meta @Override protected void renderWidget(@NotNull GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) { - renderSegment(pGuiGraphics, isMouseOver(pMouseX, pMouseY)); + boolean isHover = isMouseOver(pMouseX, pMouseY); + renderSegment(pGuiGraphics, isHover); renderIcon(pGuiGraphics); + if (isHover && hasManifestation) + { + renderText(pGuiGraphics); + } } @Override @@ -225,4 +233,26 @@ private void renderIcon(@NotNull GuiGraphics pGuiGraphics) RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f); } + + private void renderText(GuiGraphics pGuiGraphics) + { + Font font = Minecraft.getInstance().font; + int color = 0xffffffff; + + float radsPerSegment = (float) Math.PI * 2 / 8; + float f = (float) ((radsPerSegment + (Math.PI / 180f / 2f)) / 2f); + float rad = f + segmentNr * radsPerSegment; + float radius = (float) Minecraft.getInstance().getWindow().getGuiScaledHeight() / 3; + float x = centerX + Mth.cos(rad) * radius; + float y = centerY + Mth.sin(rad) * radius; + + final String text = I18n.get(manifestation.getTranslationKey()); + + if (x < centerX) + { + x = x - (font.width(text)); + } + + pGuiGraphics.drawString(Minecraft.getInstance().font, text, (int)x, (int)y, color); + } } diff --git a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java index c5c45990c..bd2c34d61 100644 --- a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java +++ b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java @@ -14,9 +14,11 @@ import leaf.cosmere.common.Cosmere; import leaf.cosmere.common.network.packets.ChangeManifestationModeMessage; import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Font; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.Button; import net.minecraft.client.renderer.GameRenderer; +import net.minecraft.client.resources.language.I18n; import net.minecraft.client.sounds.SoundManager; import net.minecraft.network.chat.CommonComponents; import net.minecraft.resources.ResourceLocation; @@ -58,8 +60,13 @@ protected OuterRadialButton(int centerX, int centerY, int segmentNr, Metals.Meta @Override protected void renderWidget(@NotNull GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) { - renderSegment(pGuiGraphics, isMouseOver(pMouseX, pMouseY)); + boolean isHover =isMouseOver(pMouseX, pMouseY); + renderSegment(pGuiGraphics, isHover); renderIcon(pGuiGraphics); + if (isHover && hasManifestation) + { + renderText(pGuiGraphics); + } } @Override @@ -232,4 +239,25 @@ private void renderIcon(@NotNull GuiGraphics pGuiGraphics) RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f); } + + private void renderText(GuiGraphics pGuiGraphics) + { + Font font = Minecraft.getInstance().font; + int color = 0xffffffff; + + float radsPerSegment = (float) Math.PI * 2 / 8; + float f = (float) ((radsPerSegment + (Math.PI / 180f / 2f)) / 2f); + float rad = f + segmentNr * radsPerSegment; + float x = centerX + Mth.cos(rad) * outerRadius; + float y = centerY + Mth.sin(rad) * outerRadius; + + final String text = I18n.get(manifestation.getTranslationKey()); + + if (x < centerX) + { + x = x - (font.width(text)); + } + + pGuiGraphics.drawString(Minecraft.getInstance().font, text, (int)x, (int)y, color); + } } From a49b28b377f256ad6882f24940a0a8e7282d8bca Mon Sep 17 00:00:00 2001 From: Gerbagel Date: Wed, 28 Jan 2026 09:11:06 +0100 Subject: [PATCH 10/55] [Allomancy] Added metal stores hover text --- .../client/gui/InnerRadialButton.java | 43 +++++++++++++++-- .../client/gui/OuterRadialButton.java | 47 +++++++++++++++++-- .../cosmere/client/gui/SpiritwebMenu.java | 17 +++++++ 3 files changed, 98 insertions(+), 9 deletions(-) diff --git a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java index c475e1c79..ac334aba4 100644 --- a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java +++ b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java @@ -11,6 +11,7 @@ import leaf.cosmere.api.Metals; import leaf.cosmere.api.manifestation.Manifestation; import leaf.cosmere.api.spiritweb.ISpiritweb; +import leaf.cosmere.client.gui.SpiritwebMenu; import leaf.cosmere.common.Cosmere; import leaf.cosmere.common.network.packets.ChangeManifestationModeMessage; import net.minecraft.client.Minecraft; @@ -39,12 +40,14 @@ public class InnerRadialButton extends Button private final boolean hasManifestation; private final Manifestation manifestation; private final ISpiritweb spiritweb; + private final Metals.MetalType metalType; protected InnerRadialButton(int centerX, int centerY, int segmentNr, Metals.MetalType metal, ISpiritweb spiritweb) { super(centerX, centerY, 16, 16, CommonComponents.EMPTY, (button) -> {}, DEFAULT_NARRATION); this.spiritweb = spiritweb; - manifestation = Manifestations.ManifestationTypes.ALLOMANCY.getManifestation(metal.getID()); + metalType = metal; + manifestation = Manifestations.ManifestationTypes.ALLOMANCY.getManifestation(metalType.getID()); hasManifestation = spiritweb.hasManifestation(manifestation); double eighthCircle = Math.toRadians(45.d); // a circle is 360 degrees, / by 8 for 45 degrees, converted to radians this.segmentNr = segmentNr; @@ -65,7 +68,8 @@ protected void renderWidget(@NotNull GuiGraphics pGuiGraphics, int pMouseX, int renderIcon(pGuiGraphics); if (isHover && hasManifestation) { - renderText(pGuiGraphics); + renderNameText(pGuiGraphics); + renderStoresText(pGuiGraphics); } } @@ -234,7 +238,7 @@ private void renderIcon(@NotNull GuiGraphics pGuiGraphics) RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f); } - private void renderText(GuiGraphics pGuiGraphics) + private void renderNameText(GuiGraphics pGuiGraphics) { Font font = Minecraft.getInstance().font; int color = 0xffffffff; @@ -242,7 +246,7 @@ private void renderText(GuiGraphics pGuiGraphics) float radsPerSegment = (float) Math.PI * 2 / 8; float f = (float) ((radsPerSegment + (Math.PI / 180f / 2f)) / 2f); float rad = f + segmentNr * radsPerSegment; - float radius = (float) Minecraft.getInstance().getWindow().getGuiScaledHeight() / 3; + float radius = (float) Minecraft.getInstance().getWindow().getGuiScaledHeight() / 3 + 10; float x = centerX + Mth.cos(rad) * radius; float y = centerY + Mth.sin(rad) * radius; @@ -255,4 +259,35 @@ private void renderText(GuiGraphics pGuiGraphics) pGuiGraphics.drawString(Minecraft.getInstance().font, text, (int)x, (int)y, color); } + + private void renderStoresText(GuiGraphics pGuiGraphics) + { + Font font = Minecraft.getInstance().font; + int color = 0xffffffff; + + float radsPerSegment = (float) Math.PI * 2 / 8; + float f = (float) ((radsPerSegment + (Math.PI / 180f / 2f)) / 2f); + float rad = f + segmentNr * radsPerSegment; + float radius = (float) Minecraft.getInstance().getWindow().getGuiScaledHeight() / 3 + 10; + float x = centerX + Mth.cos(rad) * radius; + float y = centerY + Mth.sin(rad) * radius; + + String text = ""; + for (String s : SpiritwebMenu.infoText) + { + if (s.toLowerCase().contains("a. " + metalType.getName())) + { + text = s.split(":")[1].stripLeading(); + break; + } + } + + if (x < centerX) + { + x = x - (font.width(text)); + } + y += font.lineHeight*1.5f; + + pGuiGraphics.drawString(Minecraft.getInstance().font, text, (int)x, (int)y, color); + } } diff --git a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java index bd2c34d61..179d42f9a 100644 --- a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java +++ b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java @@ -11,6 +11,7 @@ import leaf.cosmere.api.Metals; import leaf.cosmere.api.manifestation.Manifestation; import leaf.cosmere.api.spiritweb.ISpiritweb; +import leaf.cosmere.client.gui.SpiritwebMenu; import leaf.cosmere.common.Cosmere; import leaf.cosmere.common.network.packets.ChangeManifestationModeMessage; import net.minecraft.client.Minecraft; @@ -39,12 +40,14 @@ public class OuterRadialButton extends Button private final boolean hasManifestation; private final Manifestation manifestation; private final ISpiritweb spiritweb; + private final Metals.MetalType metalType; protected OuterRadialButton(int centerX, int centerY, int segmentNr, Metals.MetalType metal, ISpiritweb spiritweb) { super(centerX, centerY, 16, 16, CommonComponents.EMPTY, (button) -> {}, DEFAULT_NARRATION); this.spiritweb = spiritweb; - manifestation = Manifestations.ManifestationTypes.ALLOMANCY.getManifestation(metal.getID()); + metalType = metal; + manifestation = Manifestations.ManifestationTypes.ALLOMANCY.getManifestation(metalType.getID()); hasManifestation = this.spiritweb.hasManifestation(manifestation); double eighthCircle = Math.toRadians(45.d); // a circle is 360 degrees, / by 8 for 45 degrees, converted to radians this.segmentNr = segmentNr; // MetalType doesn't align with the chart in a pattern that can be programmatically written out; we do this manually @@ -65,7 +68,8 @@ protected void renderWidget(@NotNull GuiGraphics pGuiGraphics, int pMouseX, int renderIcon(pGuiGraphics); if (isHover && hasManifestation) { - renderText(pGuiGraphics); + renderNameText(pGuiGraphics); + renderStoresText(pGuiGraphics); } } @@ -240,7 +244,7 @@ private void renderIcon(@NotNull GuiGraphics pGuiGraphics) RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f); } - private void renderText(GuiGraphics pGuiGraphics) + private void renderNameText(GuiGraphics pGuiGraphics) { Font font = Minecraft.getInstance().font; int color = 0xffffffff; @@ -248,8 +252,9 @@ private void renderText(GuiGraphics pGuiGraphics) float radsPerSegment = (float) Math.PI * 2 / 8; float f = (float) ((radsPerSegment + (Math.PI / 180f / 2f)) / 2f); float rad = f + segmentNr * radsPerSegment; - float x = centerX + Mth.cos(rad) * outerRadius; - float y = centerY + Mth.sin(rad) * outerRadius; + float textRadius = outerRadius + 10; + float x = centerX + Mth.cos(rad) * textRadius; + float y = centerY + Mth.sin(rad) * textRadius; final String text = I18n.get(manifestation.getTranslationKey()); @@ -260,4 +265,36 @@ private void renderText(GuiGraphics pGuiGraphics) pGuiGraphics.drawString(Minecraft.getInstance().font, text, (int)x, (int)y, color); } + + private void renderStoresText(GuiGraphics pGuiGraphics) + { + Font font = Minecraft.getInstance().font; + int color = 0xffffffff; + + float radsPerSegment = (float) Math.PI * 2 / 8; + float f = (float) ((radsPerSegment + (Math.PI / 180f / 2f)) / 2f); + float rad = f + segmentNr * radsPerSegment; + float textRadius = outerRadius + 10; + float x = centerX + Mth.cos(rad) * textRadius; + float y = centerY + Mth.sin(rad) * textRadius; + + String text = ""; + for (String s : SpiritwebMenu.infoText) + { + if (s.toLowerCase().contains("a. " + metalType.getName())) + { + text = s.split(":")[1].stripLeading(); + + break; + } + } + + if (x < centerX) + { + x = x - (font.width(text)); + } + y += font.lineHeight*1.5f; + + pGuiGraphics.drawString(Minecraft.getInstance().font, text, (int)x, (int)y, color); + } } diff --git a/src/main/java/leaf/cosmere/client/gui/SpiritwebMenu.java b/src/main/java/leaf/cosmere/client/gui/SpiritwebMenu.java index 79d093f74..296c263a9 100644 --- a/src/main/java/leaf/cosmere/client/gui/SpiritwebMenu.java +++ b/src/main/java/leaf/cosmere/client/gui/SpiritwebMenu.java @@ -5,15 +5,18 @@ package leaf.cosmere.client.gui; import com.google.common.base.Stopwatch; +import leaf.cosmere.api.ISpiritwebSubmodule; import leaf.cosmere.api.Manifestations; import leaf.cosmere.api.math.MathHelper; import leaf.cosmere.api.spiritweb.ISpiritweb; import leaf.cosmere.client.Keybindings; +import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.screens.Screen; import net.minecraft.network.chat.Component; import org.jetbrains.annotations.NotNull; +import java.util.ArrayList; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; @@ -25,6 +28,7 @@ public class SpiritwebMenu extends Screen private final SpiritwebRegistry registry; private Screen selectedManifestationScreen = null; public static Manifestations.ManifestationTypes selectedManifestationType = Manifestations.ManifestationTypes.NONE; + public static ArrayList infoText = new ArrayList<>(); public SpiritwebMenu(Component pTitle, ISpiritweb spiritweb) { @@ -82,6 +86,19 @@ protected void init() } } + @Override + public void tick() + { + if (((int)Minecraft.getInstance().getPartialTick()) % 10 == 0) + { + for (ISpiritwebSubmodule spiritwebSubmodule : spiritweb.getSubmodules().values()) + { + spiritwebSubmodule.collectMenuInfo(infoText); + } + } + super.tick(); + } + @Override public void render(@NotNull GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) { From e7bd6fb6b8640047dfb337b55098223e70c7867c Mon Sep 17 00:00:00 2001 From: Gerbagel Date: Wed, 28 Jan 2026 09:59:18 +0100 Subject: [PATCH 11/55] [Allomancy] Render to info to block instead of hover text --- .../client/gui/InnerRadialButton.java | 79 ++++++++++--------- .../client/gui/OuterRadialButton.java | 62 ++++++++++++++- 2 files changed, 102 insertions(+), 39 deletions(-) diff --git a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java index ac334aba4..458b3737c 100644 --- a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java +++ b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java @@ -68,8 +68,7 @@ protected void renderWidget(@NotNull GuiGraphics pGuiGraphics, int pMouseX, int renderIcon(pGuiGraphics); if (isHover && hasManifestation) { - renderNameText(pGuiGraphics); - renderStoresText(pGuiGraphics); + renderInfoBlock(pGuiGraphics); } } @@ -158,7 +157,7 @@ private void renderSegment(GuiGraphics pGuiGraphics, boolean isHovered) if (mode > 0) r = r + 0.2f * mode; else if (mode < 0) - b = b + 0.2f * mode; + b = b + 0.2f * -mode; } float radsPerSegment = (float) Math.PI * 2 / 8; @@ -238,41 +237,53 @@ private void renderIcon(@NotNull GuiGraphics pGuiGraphics) RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f); } - private void renderNameText(GuiGraphics pGuiGraphics) + private void renderInfoBlock(GuiGraphics pGuiGraphics) { Font font = Minecraft.getInstance().font; - int color = 0xffffffff; - - float radsPerSegment = (float) Math.PI * 2 / 8; - float f = (float) ((radsPerSegment + (Math.PI / 180f / 2f)) / 2f); - float rad = f + segmentNr * radsPerSegment; - float radius = (float) Minecraft.getInstance().getWindow().getGuiScaledHeight() / 3 + 10; - float x = centerX + Mth.cos(rad) * radius; - float y = centerY + Mth.sin(rad) * radius; - - final String text = I18n.get(manifestation.getTranslationKey()); - - if (x < centerX) + int screenWidth = Minecraft.getInstance().getWindow().getGuiScaledWidth(); + int screenHeight = Minecraft.getInstance().getWindow().getGuiScaledHeight(); + int x = 0; + int y = 0; + int width = screenWidth / 4; + int height = screenHeight / 5; + int color = 0x99333333; + + if (segmentNr <= 1) + { + // bottom right display + x = screenWidth - width - 10; + y = screenHeight - height - 10; + } + else if (segmentNr <= 3) { - x = x - (font.width(text)); + // bottom left display + x = 10; + y = screenHeight - height - 10; + } + else if (segmentNr <= 5) + { + // top left display + x = 10; + y = 10; + } + else if (segmentNr <= 7) + { + // top right display + x = screenWidth - width - 10; + y = 10; } - pGuiGraphics.drawString(Minecraft.getInstance().font, text, (int)x, (int)y, color); - } + RenderSystem.disableCull(); + RenderSystem.enableBlend(); + RenderSystem.defaultBlendFunc(); - private void renderStoresText(GuiGraphics pGuiGraphics) - { - Font font = Minecraft.getInstance().font; - int color = 0xffffffff; + pGuiGraphics.fill(x, y, x + width, y + height, color); - float radsPerSegment = (float) Math.PI * 2 / 8; - float f = (float) ((radsPerSegment + (Math.PI / 180f / 2f)) / 2f); - float rad = f + segmentNr * radsPerSegment; - float radius = (float) Minecraft.getInstance().getWindow().getGuiScaledHeight() / 3 + 10; - float x = centerX + Mth.cos(rad) * radius; - float y = centerY + Mth.sin(rad) * radius; + String text = I18n.get(manifestation.getTranslationKey()); + pGuiGraphics.drawString(font, text, x+5, y+10, 0xFFFFFFFF); + + text = ""; - String text = ""; for (String s : SpiritwebMenu.infoText) { if (s.toLowerCase().contains("a. " + metalType.getName())) @@ -282,12 +293,6 @@ private void renderStoresText(GuiGraphics pGuiGraphics) } } - if (x < centerX) - { - x = x - (font.width(text)); - } - y += font.lineHeight*1.5f; - - pGuiGraphics.drawString(Minecraft.getInstance().font, text, (int)x, (int)y, color); + pGuiGraphics.drawString(font, text, x+5, y+10+font.lineHeight+5, 0xFFFFFFFF); } } diff --git a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java index 179d42f9a..75259aebd 100644 --- a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java +++ b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java @@ -68,8 +68,7 @@ protected void renderWidget(@NotNull GuiGraphics pGuiGraphics, int pMouseX, int renderIcon(pGuiGraphics); if (isHover && hasManifestation) { - renderNameText(pGuiGraphics); - renderStoresText(pGuiGraphics); + renderInfoBlock(pGuiGraphics); } } @@ -297,4 +296,63 @@ private void renderStoresText(GuiGraphics pGuiGraphics) pGuiGraphics.drawString(Minecraft.getInstance().font, text, (int)x, (int)y, color); } + + private void renderInfoBlock(GuiGraphics pGuiGraphics) + { + Font font = Minecraft.getInstance().font; + int screenWidth = Minecraft.getInstance().getWindow().getGuiScaledWidth(); + int screenHeight = Minecraft.getInstance().getWindow().getGuiScaledHeight(); + int x = 0; + int y = 0; + int width = screenWidth / 4; + int height = screenHeight / 5; + int color = 0x99333333; + + if (segmentNr <= 1) + { + // bottom right display + x = screenWidth - width - 10; + y = screenHeight - height - 10; + } + else if (segmentNr <= 3) + { + // bottom left display + x = 10; + y = screenHeight - height - 10; + } + else if (segmentNr <= 5) + { + // top left display + x = 10; + y = 10; + } + else if (segmentNr <= 7) + { + // top right display + x = screenWidth - width - 10; + y = 10; + } + + RenderSystem.disableCull(); + RenderSystem.enableBlend(); + RenderSystem.defaultBlendFunc(); + + pGuiGraphics.fill(x, y, x + width, y + height, color); + + String text = I18n.get(manifestation.getTranslationKey()); + pGuiGraphics.drawString(font, text, x+5, y+10, 0xFFFFFFFF); + + text = ""; + + for (String s : SpiritwebMenu.infoText) + { + if (s.toLowerCase().contains("a. " + metalType.getName())) + { + text = s.split(":")[1].stripLeading(); + break; + } + } + + pGuiGraphics.drawString(font, text, x+5, y+10+font.lineHeight+5, 0xFFFFFFFF); + } } From 69bc6dedcddc8f7ccb1a8d46e6bc651b1ac8cc4a Mon Sep 17 00:00:00 2001 From: Gerbagel Date: Wed, 28 Jan 2026 10:27:12 +0100 Subject: [PATCH 12/55] [Allomancy] Display metal stores as hours, minutes, and seconds --- .../allomancy/client/gui/InnerRadialButton.java | 13 +++++++++++++ .../allomancy/client/gui/OuterRadialButton.java | 13 +++++++++++++ 2 files changed, 26 insertions(+) diff --git a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java index 458b3737c..f3ad60cc6 100644 --- a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java +++ b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java @@ -289,6 +289,19 @@ else if (segmentNr <= 7) if (s.toLowerCase().contains("a. " + metalType.getName())) { text = s.split(":")[1].stripLeading(); + + int seconds = Integer.parseInt(text); + int hours = seconds / 3600; + int minutes = (seconds % 3600) / 60; + seconds = seconds % 60; + + if (hours > 0) + text = String.format("%d:%02d:%02d", hours, minutes, seconds); + else if (minutes > 0) + text = String.format("%d:%02d", minutes, seconds); + else + text = String.format("%d", seconds); + break; } } diff --git a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java index 75259aebd..a36cae5ee 100644 --- a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java +++ b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java @@ -349,6 +349,19 @@ else if (segmentNr <= 7) if (s.toLowerCase().contains("a. " + metalType.getName())) { text = s.split(":")[1].stripLeading(); + + int seconds = Integer.parseInt(text); + int hours = seconds / 3600; + int minutes = (seconds % 3600) / 60; + seconds = seconds % 60; + + if (hours > 0) + text = String.format("%d:%02d:%02d", hours, minutes, seconds); + else if (minutes > 0) + text = String.format("%d:%02d", minutes, seconds); + else + text = String.format("%d", seconds); + break; } } From b2438d37b4e505e86b430e65d6e8b956d46b712c Mon Sep 17 00:00:00 2001 From: Gerbagel Date: Wed, 28 Jan 2026 10:33:30 +0100 Subject: [PATCH 13/55] [Cosmere] Clear the infoText array (oops) --- src/main/java/leaf/cosmere/client/gui/SpiritwebMenu.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/leaf/cosmere/client/gui/SpiritwebMenu.java b/src/main/java/leaf/cosmere/client/gui/SpiritwebMenu.java index 296c263a9..5baebf7ee 100644 --- a/src/main/java/leaf/cosmere/client/gui/SpiritwebMenu.java +++ b/src/main/java/leaf/cosmere/client/gui/SpiritwebMenu.java @@ -89,8 +89,10 @@ protected void init() @Override public void tick() { - if (((int)Minecraft.getInstance().getPartialTick()) % 10 == 0) + assert Minecraft.getInstance().player != null; + if (Minecraft.getInstance().player.tickCount % 20 == 0) { + infoText.clear(); for (ISpiritwebSubmodule spiritwebSubmodule : spiritweb.getSubmodules().values()) { spiritwebSubmodule.collectMenuInfo(infoText); From f317eaa29185b176a8948fb8f0305e90c079127f Mon Sep 17 00:00:00 2001 From: Gerbagel Date: Wed, 28 Jan 2026 12:08:08 +0100 Subject: [PATCH 14/55] [Cosmere] Add backup if no tab background found --- .../leaf/cosmere/client/gui/TabButton.java | 41 +++++++++++-------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/src/main/java/leaf/cosmere/client/gui/TabButton.java b/src/main/java/leaf/cosmere/client/gui/TabButton.java index 54a3a4bd6..8410eda2d 100644 --- a/src/main/java/leaf/cosmere/client/gui/TabButton.java +++ b/src/main/java/leaf/cosmere/client/gui/TabButton.java @@ -2,6 +2,7 @@ import com.mojang.blaze3d.systems.RenderSystem; import leaf.cosmere.api.Manifestations; +import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.Button; import net.minecraft.network.chat.CommonComponents; @@ -33,23 +34,31 @@ private void renderBackground(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY float alpha = isMouseOver(pMouseX, pMouseY) ? 1.0f : 0.3f; alpha = (SpiritwebMenu.selectedManifestationType == this.manifestation) ? 1.0f : alpha; final ResourceLocation resourceLocation = new ResourceLocation(manifestation.getName(), "textures/gui/hud_background.png"); - RenderSystem.setShaderTexture(0, resourceLocation); - float[] shaderColor = RenderSystem.getShaderColor(); - RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, alpha); - RenderSystem.enableBlend(); - RenderSystem.blendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, 1, 0); - pGuiGraphics.blit( - resourceLocation, - getX(), - getY(), - 0, - 0, - width, - height, - width, - height - ); + if (Minecraft.getInstance().getResourceManager().getResource(resourceLocation).isPresent()) + { + RenderSystem.setShaderTexture(0, resourceLocation); + float[] shaderColor = RenderSystem.getShaderColor(); + RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, alpha); + + RenderSystem.enableBlend(); + RenderSystem.blendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, 1, 0); + pGuiGraphics.blit( + resourceLocation, + getX(), + getY(), + 0, + 0, + width, + height, + width, + height + ); + } + else + { + pGuiGraphics.fill(getX(), getY(), getX()+width, getY()+height, 0x99333333); + } RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f); } From 3d0beb615727ee77d6a6b4d0d3fdc5b435f229ac Mon Sep 17 00:00:00 2001 From: Gerbagel Date: Wed, 28 Jan 2026 12:08:34 +0100 Subject: [PATCH 15/55] [Sandmastery] Added sandmastery spiritweb menu (empty) --- .../allomancy/client/gui/InnerRadialButton.java | 2 +- .../allomancy/client/gui/OuterRadialButton.java | 2 +- .../client/gui/SandmasterySpiritwebMenu.java | 12 ++++++++++++ .../capabilities/SandmasterySpiritwebSubmodule.java | 8 ++++++++ 4 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 src/sandmastery/java/leaf/cosmere/sandmastery/client/gui/SandmasterySpiritwebMenu.java diff --git a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java index f3ad60cc6..3c2b9234c 100644 --- a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java +++ b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java @@ -300,7 +300,7 @@ else if (segmentNr <= 7) else if (minutes > 0) text = String.format("%d:%02d", minutes, seconds); else - text = String.format("%d", seconds); + text = String.format("%02ds", seconds); break; } diff --git a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java index a36cae5ee..64fe90774 100644 --- a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java +++ b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java @@ -360,7 +360,7 @@ else if (segmentNr <= 7) else if (minutes > 0) text = String.format("%d:%02d", minutes, seconds); else - text = String.format("%d", seconds); + text = String.format("%02d", seconds); break; } diff --git a/src/sandmastery/java/leaf/cosmere/sandmastery/client/gui/SandmasterySpiritwebMenu.java b/src/sandmastery/java/leaf/cosmere/sandmastery/client/gui/SandmasterySpiritwebMenu.java new file mode 100644 index 000000000..885658c0b --- /dev/null +++ b/src/sandmastery/java/leaf/cosmere/sandmastery/client/gui/SandmasterySpiritwebMenu.java @@ -0,0 +1,12 @@ +package leaf.cosmere.sandmastery.client.gui; + +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.network.chat.Component; + +public class SandmasterySpiritwebMenu extends Screen +{ + public SandmasterySpiritwebMenu() + { + super(Component.literal("Sandmastery")); + } +} diff --git a/src/sandmastery/java/leaf/cosmere/sandmastery/common/capabilities/SandmasterySpiritwebSubmodule.java b/src/sandmastery/java/leaf/cosmere/sandmastery/common/capabilities/SandmasterySpiritwebSubmodule.java index f3c95a5d7..03dcec335 100644 --- a/src/sandmastery/java/leaf/cosmere/sandmastery/common/capabilities/SandmasterySpiritwebSubmodule.java +++ b/src/sandmastery/java/leaf/cosmere/sandmastery/common/capabilities/SandmasterySpiritwebSubmodule.java @@ -13,7 +13,9 @@ import leaf.cosmere.api.manifestation.Manifestation; import leaf.cosmere.api.spiritweb.ISpiritweb; import leaf.cosmere.client.Keybindings; +import leaf.cosmere.client.gui.SpiritwebRegistry; import leaf.cosmere.sandmastery.client.SandmasteryKeybindings; +import leaf.cosmere.sandmastery.client.gui.SandmasterySpiritwebMenu; import leaf.cosmere.sandmastery.common.Sandmastery; import leaf.cosmere.sandmastery.common.config.SandmasteryConfigs; import leaf.cosmere.sandmastery.common.manifestation.SandmasteryManifestation; @@ -206,6 +208,12 @@ public void GiveStartingItem(Player player, Manifestation manifestation) { } + @Override + public void registerMenu() + { + SpiritwebRegistry.getInstance().register(Manifestations.ManifestationTypes.SANDMASTERY, SandmasterySpiritwebMenu::new); + } + @Override public List getPowers() { From 2c369d06bca1b601853f6aeed8fe07235a1b2041 Mon Sep 17 00:00:00 2001 From: Gerbagel Date: Sat, 4 Apr 2026 16:15:20 +0200 Subject: [PATCH 16/55] [Allomancy] Added metal ingestion limit Default is 7200 seconds work, or 2 hours --- .../common/capabilities/AllomancySpiritwebSubmodule.java | 2 +- .../common/commands/subcommands/FillMetalReservesCommand.java | 3 ++- .../cosmere/allomancy/common/config/AllomancyServerConfig.java | 3 +++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/allomancy/java/leaf/cosmere/allomancy/common/capabilities/AllomancySpiritwebSubmodule.java b/src/allomancy/java/leaf/cosmere/allomancy/common/capabilities/AllomancySpiritwebSubmodule.java index 6aba0cbd2..4b33f61bf 100644 --- a/src/allomancy/java/leaf/cosmere/allomancy/common/capabilities/AllomancySpiritwebSubmodule.java +++ b/src/allomancy/java/leaf/cosmere/allomancy/common/capabilities/AllomancySpiritwebSubmodule.java @@ -370,7 +370,7 @@ public boolean adjustIngestedMetal(Metals.MetalType metalType, int amountToAdjus { int ingestedMetal = getIngestedMetal(metalType); - final int newValue = ingestedMetal + amountToAdjust; + final int newValue = Math.min(ingestedMetal + amountToAdjust, AllomancyConfigs.SERVER.MAX_INGESTIBLE_METAL.get()); if (newValue >= 0) { if (doAdjust) diff --git a/src/allomancy/java/leaf/cosmere/allomancy/common/commands/subcommands/FillMetalReservesCommand.java b/src/allomancy/java/leaf/cosmere/allomancy/common/commands/subcommands/FillMetalReservesCommand.java index 65dac247c..26b4a54dc 100644 --- a/src/allomancy/java/leaf/cosmere/allomancy/common/commands/subcommands/FillMetalReservesCommand.java +++ b/src/allomancy/java/leaf/cosmere/allomancy/common/commands/subcommands/FillMetalReservesCommand.java @@ -9,6 +9,7 @@ import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.exceptions.CommandSyntaxException; import leaf.cosmere.allomancy.common.capabilities.AllomancySpiritwebSubmodule; +import leaf.cosmere.allomancy.common.config.AllomancyConfigs; import leaf.cosmere.api.EnumUtils; import leaf.cosmere.api.Manifestations; import leaf.cosmere.api.Metals; @@ -53,7 +54,7 @@ private static int fillReserves(CommandContext context) thro final Manifestation manifestation = Manifestations.ManifestationTypes.ALLOMANCY.getManifestation(metalTypeID); if (spiritweb.hasManifestation(manifestation)) { - asm.adjustIngestedMetal(metalType, 999999, true); + asm.adjustIngestedMetal(metalType, AllomancyConfigs.SERVER.MAX_INGESTIBLE_METAL.get(), true); } } } diff --git a/src/allomancy/java/leaf/cosmere/allomancy/common/config/AllomancyServerConfig.java b/src/allomancy/java/leaf/cosmere/allomancy/common/config/AllomancyServerConfig.java index 01d4dff52..a928bf03b 100644 --- a/src/allomancy/java/leaf/cosmere/allomancy/common/config/AllomancyServerConfig.java +++ b/src/allomancy/java/leaf/cosmere/allomancy/common/config/AllomancyServerConfig.java @@ -16,6 +16,7 @@ public class AllomancyServerConfig implements ICosmereConfig public final ForgeConfigSpec.DoubleValue IRON_STEEL_RANGE; public final ForgeConfigSpec.DoubleValue PUSH_PULL_WEIGHT; public final ForgeConfigSpec.DoubleValue MAX_PUSH_PULL_WEIGHT; + public final ForgeConfigSpec.IntValue MAX_INGESTIBLE_METAL; // Boost amount for Duralumin and Nicrosil //public final ForgeConfigSpec.DoubleValue boostAmount; @@ -35,6 +36,8 @@ public class AllomancyServerConfig implements ICosmereConfig PUSH_PULL_WEIGHT = builder.comment("Push/pull weight adjustment per block.").defineInRange("pushPullWeight", 0.05D, 0.01D, 100.0D); MAX_PUSH_PULL_WEIGHT = builder.comment("Maximum pull/push weight adjustment. At 1.0 (default), push/pull power maxes out at 2 times (20 blocks)").defineInRange("maxPushPullWeight", 1.0D, 0D, 999999.0D); + MAX_INGESTIBLE_METAL = builder.comment("Maximum amount of metal possible to ingest in seconds").defineInRange("maxIngestibleMetal", 7200, 1, 999999); + builder.pop(); configSpec = builder.build(); } From 1620eba3f6a60ff2844ff18cf73d67746f564df0 Mon Sep 17 00:00:00 2001 From: Gerbagel Date: Sat, 4 Apr 2026 20:17:10 +0200 Subject: [PATCH 17/55] [Cosmere] Redesigned active power HUD and how it's populated --- .../client/gui/AllomancySpiritwebMenu.java | 4 +- .../client/gui/InnerRadialButton.java | 22 +- .../client/gui/OuterRadialButton.java | 15 +- .../manifestation/AllomancyManifestation.java | 9 + .../leaf/cosmere/api/ISpiritwebSubmodule.java | 2 +- .../api/manifestation/Manifestation.java | 5 + .../client/gui/FeruchemySpiritwebMenu.java | 4 +- .../cosmere/client/ClientForgeEvents.java | 25 +++ .../cosmere/client/gui/CosmereScreen.java | 14 ++ .../leaf/cosmere/client/gui/SpiritwebHud.java | 143 +++++++++++++ .../cosmere/client/gui/SpiritwebMenu.java | 15 +- .../cosmere/client/gui/SpiritwebRegistry.java | 6 +- .../cap/entity/SpiritwebCapability.java | 193 ------------------ .../common/config/CosmereClientConfig.java | 8 +- .../client/gui/SandmasterySpiritwebMenu.java | 4 +- 15 files changed, 254 insertions(+), 215 deletions(-) create mode 100644 src/main/java/leaf/cosmere/client/gui/CosmereScreen.java create mode 100644 src/main/java/leaf/cosmere/client/gui/SpiritwebHud.java diff --git a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/AllomancySpiritwebMenu.java b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/AllomancySpiritwebMenu.java index 4fb0fbdad..ef7b324d0 100644 --- a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/AllomancySpiritwebMenu.java +++ b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/AllomancySpiritwebMenu.java @@ -1,14 +1,14 @@ package leaf.cosmere.allomancy.client.gui; import leaf.cosmere.api.Metals; +import leaf.cosmere.client.gui.CosmereScreen; import leaf.cosmere.common.cap.entity.SpiritwebCapability; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; -import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.player.LocalPlayer; import net.minecraft.network.chat.Component; -public class AllomancySpiritwebMenu extends Screen +public class AllomancySpiritwebMenu extends CosmereScreen { LocalPlayer player; public AllomancySpiritwebMenu() diff --git a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java index 3c2b9234c..d33be42b8 100644 --- a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java +++ b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java @@ -75,6 +75,7 @@ protected void renderWidget(@NotNull GuiGraphics pGuiGraphics, int pMouseX, int @Override public boolean isMouseOver(double mouseX, double mouseY) { + boolean retVal; double distanceX = mouseX - centerX; double distanceY = mouseY - centerY; double dSqr = distanceX * distanceX + distanceY * distanceY; @@ -95,11 +96,24 @@ public boolean isMouseOver(double mouseX, double mouseY) double end = normalizeAngle(endAngle); angle = normalizeAngle(angle); - if (start <= end) { - return angle >= start && angle <= end; - } else { - return angle >= start || angle <= end; + if (start <= end) + { + retVal = angle >= start && angle <= end; + } + else + { + retVal = angle >= start || angle <= end; + } + + if (hasManifestation) + { + if (retVal) + { + SpiritwebMenu.selectedManifestation = manifestation; + } } + + return retVal; } @Override diff --git a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java index 64fe90774..cef422f2f 100644 --- a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java +++ b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java @@ -75,6 +75,7 @@ protected void renderWidget(@NotNull GuiGraphics pGuiGraphics, int pMouseX, int @Override public boolean isMouseOver(double mouseX, double mouseY) { + boolean retVal; double distanceX = mouseX - centerX; double distanceY = mouseY - centerY; double dSqr = distanceX * distanceX + distanceY * distanceY; @@ -96,10 +97,20 @@ public boolean isMouseOver(double mouseX, double mouseY) angle = normalizeAngle(angle); if (start <= end) { - return angle >= start && angle <= end; + retVal = angle >= start && angle <= end; } else { - return angle >= start || angle <= end; + retVal = angle >= start || angle <= end; } + + if (hasManifestation) + { + if (retVal) + { + SpiritwebMenu.selectedManifestation = manifestation; + } + } + + return retVal; } @Override diff --git a/src/allomancy/java/leaf/cosmere/allomancy/common/manifestation/AllomancyManifestation.java b/src/allomancy/java/leaf/cosmere/allomancy/common/manifestation/AllomancyManifestation.java index 118f3fc0a..1874086ab 100644 --- a/src/allomancy/java/leaf/cosmere/allomancy/common/manifestation/AllomancyManifestation.java +++ b/src/allomancy/java/leaf/cosmere/allomancy/common/manifestation/AllomancyManifestation.java @@ -6,6 +6,7 @@ import leaf.cosmere.allomancy.client.AllomancyKeybindings; import leaf.cosmere.allomancy.common.capabilities.AllomancySpiritwebSubmodule; +import leaf.cosmere.allomancy.common.config.AllomancyConfigs; import leaf.cosmere.allomancy.common.registries.AllomancyStats; import leaf.cosmere.api.CosmereAPI; import leaf.cosmere.api.IHasMetalType; @@ -260,4 +261,12 @@ public int getRange(ISpiritweb data) final int mode = Math.max(getMode(data), 0); return Mth.floor(allomanticStrength * mode); } + + @Override + public float getInvestitureHud(ISpiritweb spiritweb) + { + AllomancySpiritwebSubmodule allo = (AllomancySpiritwebSubmodule) spiritweb.getSubmodule(Manifestations.ManifestationTypes.ALLOMANCY); + final float retVal = (float)allo.getIngestedMetal(this.metalType)/AllomancyConfigs.SERVER.MAX_INGESTIBLE_METAL.get(); + return retVal; + } } diff --git a/src/api/java/leaf/cosmere/api/ISpiritwebSubmodule.java b/src/api/java/leaf/cosmere/api/ISpiritwebSubmodule.java index 2d7b972a5..a0289c874 100644 --- a/src/api/java/leaf/cosmere/api/ISpiritwebSubmodule.java +++ b/src/api/java/leaf/cosmere/api/ISpiritwebSubmodule.java @@ -82,4 +82,4 @@ default List getEntityPowers(LivingEntity entity) } return powers; } -} +} \ No newline at end of file diff --git a/src/api/java/leaf/cosmere/api/manifestation/Manifestation.java b/src/api/java/leaf/cosmere/api/manifestation/Manifestation.java index 754c66afa..bbcd2c75a 100644 --- a/src/api/java/leaf/cosmere/api/manifestation/Manifestation.java +++ b/src/api/java/leaf/cosmere/api/manifestation/Manifestation.java @@ -145,4 +145,9 @@ public Attribute getAttribute() return ForgeRegistries.ATTRIBUTES.getValue(getRegistryName()); } + public float getInvestitureHud(ISpiritweb spiritweb) + { + return 0.f; + } + } \ No newline at end of file diff --git a/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/FeruchemySpiritwebMenu.java b/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/FeruchemySpiritwebMenu.java index 4f9001138..de726728c 100644 --- a/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/FeruchemySpiritwebMenu.java +++ b/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/FeruchemySpiritwebMenu.java @@ -1,11 +1,11 @@ package leaf.cosmere.feruchemy.client.gui; +import leaf.cosmere.client.gui.CosmereScreen; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; -import net.minecraft.client.gui.screens.Screen; import net.minecraft.network.chat.Component; -public class FeruchemySpiritwebMenu extends Screen +public class FeruchemySpiritwebMenu extends CosmereScreen { public FeruchemySpiritwebMenu() { diff --git a/src/main/java/leaf/cosmere/client/ClientForgeEvents.java b/src/main/java/leaf/cosmere/client/ClientForgeEvents.java index 97aa471d9..d4debdbab 100644 --- a/src/main/java/leaf/cosmere/client/ClientForgeEvents.java +++ b/src/main/java/leaf/cosmere/client/ClientForgeEvents.java @@ -8,6 +8,7 @@ import com.mojang.blaze3d.platform.InputConstants; import leaf.cosmere.api.Activator; import leaf.cosmere.api.manifestation.Manifestation; +import leaf.cosmere.client.gui.SpiritwebHud; import leaf.cosmere.client.gui.SpiritwebMenu; import leaf.cosmere.common.Cosmere; import leaf.cosmere.common.cap.entity.SpiritwebCapability; @@ -26,7 +27,9 @@ import net.minecraftforge.client.event.ClientPlayerNetworkEvent; import net.minecraftforge.client.event.InputEvent; import net.minecraftforge.client.event.InputEvent.MouseScrollingEvent; +import net.minecraftforge.client.event.RenderGuiOverlayEvent; import net.minecraftforge.client.event.RenderLevelStageEvent; +import net.minecraftforge.client.gui.overlay.VanillaGuiOverlay; import net.minecraftforge.eventbus.api.EventPriority; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod; @@ -215,6 +218,28 @@ public static void onRenderLevelLastEvent(final RenderLevelStageEvent event) } + @SubscribeEvent + public static void onRenderGuiOverlayPost(RenderGuiOverlayEvent.Post event) + { + // make sure it only renders once per frame + if (event.getOverlay().id().equals(VanillaGuiOverlay.HOTBAR.id())) + { + Minecraft mc = Minecraft.getInstance(); + ProfilerFiller profiler = mc.getProfiler(); + LocalPlayer playerEntity = mc.player; + profiler.push("cosmere-spiritweb-hud"); + { + SpiritwebCapability.get(playerEntity).ifPresent(spiritweb -> + { + // Shouldn't need mouse location, will only render as a HUD element + SpiritwebHud.Instance(playerEntity).render(event.getGuiGraphics(), 0, 0, event.getPartialTick()); + }); + } + profiler.pop(); + } + } + + @SubscribeEvent public static void onClientPlayerClone(ClientPlayerNetworkEvent.Clone event) { diff --git a/src/main/java/leaf/cosmere/client/gui/CosmereScreen.java b/src/main/java/leaf/cosmere/client/gui/CosmereScreen.java new file mode 100644 index 000000000..3098715db --- /dev/null +++ b/src/main/java/leaf/cosmere/client/gui/CosmereScreen.java @@ -0,0 +1,14 @@ +package leaf.cosmere.client.gui; + +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.network.chat.Component; + +// would be an interface if Screen wasn't a class +// might be unnecessary, but could be nice to have in future, I guess +public class CosmereScreen extends Screen +{ + protected CosmereScreen(Component pTitle) + { + super(pTitle); + } +} diff --git a/src/main/java/leaf/cosmere/client/gui/SpiritwebHud.java b/src/main/java/leaf/cosmere/client/gui/SpiritwebHud.java new file mode 100644 index 000000000..a1f42d8d5 --- /dev/null +++ b/src/main/java/leaf/cosmere/client/gui/SpiritwebHud.java @@ -0,0 +1,143 @@ +package leaf.cosmere.client.gui; + +import com.mojang.blaze3d.systems.RenderSystem; +import leaf.cosmere.api.IHasMetalType; +import leaf.cosmere.api.manifestation.Manifestation; +import leaf.cosmere.common.cap.entity.SpiritwebCapability; +import leaf.cosmere.common.config.CosmereConfigs; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Font; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.components.AbstractWidget; +import net.minecraft.client.gui.narration.NarrationElementOutput; +import net.minecraft.client.renderer.GameRenderer; +import net.minecraft.client.resources.language.I18n; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.player.Player; + +public class SpiritwebHud extends AbstractWidget +{ + private static SpiritwebHud INSTANCE; + private Player player; + + private SpiritwebHud(int pX, int pY, int pWidth, int pHeight, Component pMessage, Player player) + { + super(pX, pY, pWidth, pHeight, pMessage); + this.player = player; + } + + public static SpiritwebHud Instance(Player player) + { + if (INSTANCE == null) + { + INSTANCE = new SpiritwebHud(CosmereConfigs.CLIENT_CONFIG.hudXCoordinate.get(), + CosmereConfigs.CLIENT_CONFIG.hudYCoordinate.get(), + CosmereConfigs.CLIENT_CONFIG.hudSizeX.get(), + CosmereConfigs.CLIENT_CONFIG.hudSizeY.get(), + Component.literal("Spiritweb HUD"), + player); // should never be null + } + + return INSTANCE; + } + + public void setSelectedManifestation() + { + + } + + @Override + protected void renderWidget(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) + { + renderBackground(pGuiGraphics); + renderUsage(pGuiGraphics); + renderIcon(pGuiGraphics); + renderText(pGuiGraphics); + } + + @Override + protected void updateWidgetNarration(NarrationElementOutput pNarrationElementOutput) + { + // no + } + + protected void renderBackground(GuiGraphics pGuiGraphics) + { + pGuiGraphics.fill(getX(), getY(), getX() + getWidth(), getY() + getHeight(), 0xCC333333); + } + + protected void renderUsage(GuiGraphics pGuiGraphics) + { + SpiritwebCapability.get(player).ifPresent(spiritweb -> + { + float width = getWidth(); + float usagePercentage = spiritweb.getSelectedManifestation().getInvestitureHud(spiritweb); + + width = width * usagePercentage; + pGuiGraphics.fill(getX(), getY(), (int) (getX() + width), getY() + getHeight(), 0x33FFFFFF); + }); + } + + protected void renderIcon(GuiGraphics pGuiGraphics) + { + SpiritwebCapability.get(player).ifPresent(spiritweb -> + { + Manifestation selectedManifestation = spiritweb.getSelectedManifestation(); + if (selectedManifestation != null) + { + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.setLength(0); + stringBuilder.append("textures/icon/") + .append(selectedManifestation.getManifestationType().getName()) + .append("/"); + + switch (selectedManifestation.getManifestationType()) + { + case ALLOMANCY: + case FERUCHEMY: + if (selectedManifestation instanceof IHasMetalType metalType) + { + stringBuilder.append(metalType.getMetalType().getName()); + } + break; + case SURGEBINDING: + stringBuilder.append(selectedManifestation.getName()); + break; + case AON_DOR: + break; + case AWAKENING: + break; + } + + stringBuilder.append(".png"); + final ResourceLocation resourceLocation = new ResourceLocation(selectedManifestation.getRegistryName().getNamespace(), stringBuilder.toString()); + RenderSystem.setShader(GameRenderer::getPositionTexShader); + RenderSystem.enableBlend(); + RenderSystem.defaultBlendFunc(); + + pGuiGraphics.blit(resourceLocation, + getX(), + getY() + 2, + getHeight()-4, + getHeight()-4, + 0, + 0, + 18, + 18, + 18, + 18); + } + }); + } + + protected void renderText(GuiGraphics pGuiGraphics) + { + SpiritwebCapability.get(player).ifPresent(spiritweb -> + { + Font font = Minecraft.getInstance().font; + String text = I18n.get(spiritweb.getSelectedManifestation().getTranslationKey()); + pGuiGraphics.drawString(font, text, getX() + getHeight() + 2, getY() + getHeight() / 2 - font.lineHeight/2, 0xFFDDDDDD); + }); + } +} diff --git a/src/main/java/leaf/cosmere/client/gui/SpiritwebMenu.java b/src/main/java/leaf/cosmere/client/gui/SpiritwebMenu.java index 5baebf7ee..55645129d 100644 --- a/src/main/java/leaf/cosmere/client/gui/SpiritwebMenu.java +++ b/src/main/java/leaf/cosmere/client/gui/SpiritwebMenu.java @@ -7,9 +7,12 @@ import com.google.common.base.Stopwatch; import leaf.cosmere.api.ISpiritwebSubmodule; import leaf.cosmere.api.Manifestations; +import leaf.cosmere.api.manifestation.Manifestation; import leaf.cosmere.api.math.MathHelper; import leaf.cosmere.api.spiritweb.ISpiritweb; import leaf.cosmere.client.Keybindings; +import leaf.cosmere.common.Cosmere; +import leaf.cosmere.common.network.packets.SetSelectedManifestationMessage; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.screens.Screen; @@ -26,8 +29,9 @@ public class SpiritwebMenu extends Screen private Stopwatch lastChange = Stopwatch.createStarted(); private final ISpiritweb spiritweb; private final SpiritwebRegistry registry; - private Screen selectedManifestationScreen = null; + private CosmereScreen selectedManifestationScreen = null; public static Manifestations.ManifestationTypes selectedManifestationType = Manifestations.ManifestationTypes.NONE; + public static Manifestation selectedManifestation = null; public static ArrayList infoText = new ArrayList<>(); public SpiritwebMenu(Component pTitle, ISpiritweb spiritweb) @@ -46,13 +50,17 @@ public void raiseVisibility() private void CloseScreen() { + prepareClose(); this.minecraft.setScreen(null); } public void prepareClose() { - // todo - // will need later + if (selectedManifestationScreen != null && selectedManifestation != null) + { + Cosmere.packetHandler().sendToServer(new SetSelectedManifestationMessage(selectedManifestation)); + selectedManifestation = null; + } } @Override @@ -105,6 +113,7 @@ public void tick() public void render(@NotNull GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) { super.render(pGuiGraphics, pMouseX, pMouseY, pPartialTick); + selectedManifestation = null; raiseVisibility(); final int start = (int) (visibility * 98) << 24; final int end = (int) (visibility * 128) << 24; diff --git a/src/main/java/leaf/cosmere/client/gui/SpiritwebRegistry.java b/src/main/java/leaf/cosmere/client/gui/SpiritwebRegistry.java index 0334de17c..864e52bfb 100644 --- a/src/main/java/leaf/cosmere/client/gui/SpiritwebRegistry.java +++ b/src/main/java/leaf/cosmere/client/gui/SpiritwebRegistry.java @@ -9,7 +9,7 @@ public class SpiritwebRegistry { private static SpiritwebRegistry INSTANCE; - private final HashMap> manifestationScreenMap = new HashMap<>(); + private final HashMap> manifestationScreenMap = new HashMap<>(); public static SpiritwebRegistry getInstance() { @@ -20,12 +20,12 @@ public static SpiritwebRegistry getInstance() return INSTANCE; } - public void register(Manifestations.ManifestationTypes maniType, Supplier subScreen) + public void register(Manifestations.ManifestationTypes maniType, Supplier subScreen) { manifestationScreenMap.put(maniType, subScreen); } - public HashMap> getManifestationScreenMap() + public HashMap> getManifestationScreenMap() { return manifestationScreenMap; } diff --git a/src/main/java/leaf/cosmere/common/cap/entity/SpiritwebCapability.java b/src/main/java/leaf/cosmere/common/cap/entity/SpiritwebCapability.java index 92867dcc2..c37c3400a 100644 --- a/src/main/java/leaf/cosmere/common/cap/entity/SpiritwebCapability.java +++ b/src/main/java/leaf/cosmere/common/cap/entity/SpiritwebCapability.java @@ -6,13 +6,7 @@ package leaf.cosmere.common.cap.entity; import com.google.common.collect.Maps; -import com.mojang.blaze3d.systems.RenderSystem; -import com.mojang.blaze3d.vertex.BufferBuilder; -import com.mojang.blaze3d.vertex.DefaultVertexFormat; -import com.mojang.blaze3d.vertex.Tesselator; -import com.mojang.blaze3d.vertex.VertexFormat; import leaf.cosmere.api.CosmereAPI; -import leaf.cosmere.api.IHasMetalType; import leaf.cosmere.api.ISpiritwebSubmodule; import leaf.cosmere.api.Manifestations; import leaf.cosmere.api.cosmereEffect.CosmereEffect; @@ -27,14 +21,10 @@ import leaf.cosmere.common.registry.GameEventRegistry; import leaf.cosmere.common.registry.ManifestationRegistry; import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.GuiGraphics; -import net.minecraft.client.renderer.GameRenderer; -import net.minecraft.client.resources.language.I18n; import net.minecraft.core.BlockPos; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.ListTag; import net.minecraft.network.chat.Component; -import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.util.Mth; @@ -55,7 +45,6 @@ import javax.annotation.Nonnull; import javax.annotation.Nullable; -import java.io.FileNotFoundException; import java.util.*; /* @@ -547,188 +536,6 @@ public void renderWorldEffects(RenderLevelStageEvent event) } } - public void renderSelectedHUD(GuiGraphics gg) - { - if (CosmereConfigs.CLIENT_CONFIG.disableSelectedManifestationHud.get() || selectedManifestation.getManifestationType() == Manifestations.ManifestationTypes.NONE) - { - return; - } - - Minecraft mc = Minecraft.getInstance(); - int startX = CosmereConfigs.CLIENT_CONFIG.hudXCoordinate.get(); - int startY = CosmereConfigs.CLIENT_CONFIG.hudYCoordinate.get(); - int size = CosmereConfigs.CLIENT_CONFIG.hudSize.get(); - - String stringToDraw = I18n.get(selectedManifestation.getTextComponent().getString()); - int xOffset = -5; - float textScale = size / (float) (mc.font.width(stringToDraw) - 20); - gg.pose().pushPose(); - gg.pose().scale(textScale, textScale, 1f); - gg.drawString(mc.font, stringToDraw, (int) ((startX + xOffset) / textScale), (int) ((startY + size + 5) / textScale), 0xFFFFFF); - gg.pose().popPose(); - - int mode = getMode(selectedManifestation); - - String stringToDraw2 = ""; - - gg.pose().pushPose(); - RenderSystem.setShader(GameRenderer::getPositionTexShader); - RenderSystem.enableBlend(); - RenderSystem.defaultBlendFunc(); - Tesselator tesselator = Tesselator.getInstance(); - BufferBuilder buffer = tesselator.getBuilder(); - - // draw square - try { - final ResourceLocation textureLocation = new ResourceLocation(selectedManifestation.getRegistryName().getNamespace(), "textures/gui/hud_background.png"); - mc.getResourceManager().getResourceOrThrow(textureLocation); - - RenderSystem.setShaderTexture(0, textureLocation); - gg.blit(textureLocation, - startX, - startY, - size, - size, - 0, - 0, - 18, - 18, - 18, - 18); - } - catch (FileNotFoundException ex) // backup in case no texture - { - RenderSystem.setShader(GameRenderer::getPositionColorShader); - buffer.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR); - int color = 0xCC000000; - //set first triangle - buffer.vertex(startX, startY, 0).color(color).endVertex(); - buffer.vertex(startX, startY + size, 0).color(color).endVertex(); - //set second triangle - buffer.vertex(startX + size, startY + size, 0).color(color).endVertex(); - buffer.vertex(startX + size, startY, 0).color(color).endVertex(); - tesselator.end(); - } - - // draw manifestation icon - { - final StringBuilder stringBuilder = new StringBuilder(); - stringBuilder.setLength(0); - String manifestationTypeName = selectedManifestation.getManifestationType().getName(); - stringBuilder - .append("textures/icon/") - .append(manifestationTypeName) - .append("/"); - switch (selectedManifestation.getManifestationType()) - { - case ALLOMANCY: - case FERUCHEMY: - if (selectedManifestation instanceof IHasMetalType metalType) - { - stringBuilder.append(metalType.getMetalType().getName()); - } - break; - case SURGEBINDING: - stringBuilder.append(selectedManifestation.getName()); - break; - case AON_DOR: - break; - case AWAKENING: - break; - } - stringBuilder.append(".png"); - - final ResourceLocation textureLocation = new ResourceLocation(selectedManifestation.getRegistryName().getNamespace(), stringBuilder.toString()); - RenderSystem.setShaderTexture(0, textureLocation); - int posX = startX + 4; - int posY = startY + 2; - if (selectedManifestation.getManifestationType() != Manifestations.ManifestationTypes.ALLOMANCY && selectedManifestation.getManifestationType() != Manifestations.ManifestationTypes.FERUCHEMY) - { - posX = startX + 2; - } - gg.blit(textureLocation, - posX, - posY, - size - 4, - size - 4, - 0, - 0, - 18, - 18, - 18, - 18); - } - - // todo draw pentagon -// { -// int color = 0xCC000000; -// float centerX = (float) mc.getWindow().getGuiScaledWidth() /2;//startX + (float) size / 2; -// float centerY = (float) mc.getWindow().getGuiScaledHeight() /2;//startY + size + 10; -// float[][] pentagonVertices = calculatePentagonVertices(centerX, centerY, 40, 0.5f); -// -// RenderSystem.setShader(GameRenderer::getPositionColorShader); -// buffer.begin(VertexFormat.Mode.TRIANGLE_FAN, DefaultVertexFormat.POSITION_COLOR); -// -// buffer.vertex(centerX, centerY, 0).color(color).endVertex(); // Center point for triangle fan -// for (float[] vertex : pentagonVertices) -// { -// buffer.vertex(vertex[0], vertex[1], 0).color(color).endVertex(); -// } -// buffer.vertex(pentagonVertices[0][0], pentagonVertices[0][1], 0).color(color).endVertex(); -// tesselator.end(); -// } - - gg.pose().popPose(); - RenderSystem.disableBlend(); - - //todo migrate drawing text to manifestation, this shouldn't be in main module. - if (selectedManifestation.getManifestationType() == Manifestations.ManifestationTypes.FERUCHEMY) - { - //todo translations - if (mode < 0) - { - stringToDraw2 = "T" + mode; - } - else if (mode > 0) - { - stringToDraw2 = "S" + mode; - } - else - { - //don't draw - //stringToDraw2 = ""; - } - } - else if (selectedManifestation.getManifestationType() == Manifestations.ManifestationTypes.ALLOMANCY) - { - String rate; - - switch (mode) - { - case -2 -> rate = "CF"; - case -1 -> rate = "C"; - default -> rate = ""; - case 1 -> rate = "B"; - case 2, 3 -> rate = "F";//copper has a 3rd mode for only smoking self - } - stringToDraw2 = rate; - } - - //todo translations - if (!stringToDraw2.isEmpty()) - { - int yOffset = (size / 2) - (stringToDraw2.length() * mc.font.lineHeight) / 2; // center the text vertically - for (char c : stringToDraw2.toCharArray()) - { - if (c == '-') - c = '|'; - xOffset = mc.font.width(String.valueOf(c)) / 2 - 4; - gg.drawString(mc.font, String.valueOf(c), startX - xOffset, startY + yOffset, 0xFFFFFF); - yOffset += mc.font.lineHeight; - } - } - } - static float[][] calculatePentagonVertices(float centerX, float centerY, float radius, float scaleY) { // for i in range(5): diff --git a/src/main/java/leaf/cosmere/common/config/CosmereClientConfig.java b/src/main/java/leaf/cosmere/common/config/CosmereClientConfig.java index b0a267352..1d27094ae 100644 --- a/src/main/java/leaf/cosmere/common/config/CosmereClientConfig.java +++ b/src/main/java/leaf/cosmere/common/config/CosmereClientConfig.java @@ -14,7 +14,8 @@ public class CosmereClientConfig implements ICosmereConfig public final ForgeConfigSpec.BooleanValue disableSelectedManifestationHud; public final ForgeConfigSpec.IntValue hudXCoordinate; public final ForgeConfigSpec.IntValue hudYCoordinate; - public final ForgeConfigSpec.IntValue hudSize; + public final ForgeConfigSpec.IntValue hudSizeX; + public final ForgeConfigSpec.IntValue hudSizeY; public final ForgeConfigSpec.BooleanValue disableActivatorChatMessage; @@ -28,8 +29,9 @@ public class CosmereClientConfig implements ICosmereConfig disableSelectedManifestationHud = builder.comment("Disables the HUD for selected power").define("disableSelectedManifestationHud", false); hudXCoordinate = builder.comment("X coordinate for the HUD").defineInRange("hudXCoordinate", 10, 0, Integer.MAX_VALUE); - hudYCoordinate = builder.comment("Y coordinate for the HUD").defineInRange("hudYCoordinate", 20, 0, Integer.MAX_VALUE); - hudSize = builder.comment("Size of the icon in the HUD; both width and height").defineInRange("hudSize", 40, 0, Integer.MAX_VALUE); + hudYCoordinate = builder.comment("Y coordinate for the HUD").defineInRange("hudYCoordinate", 40, 0, Integer.MAX_VALUE); + hudSizeX = builder.comment("Width of the HUD").defineInRange("hudSizeX", 140, 0, Integer.MAX_VALUE); + hudSizeY = builder.comment("Height of the HUD").defineInRange("hudSizeY", 30, 0, Integer.MAX_VALUE); disableActivatorChatMessage = builder.comment("Disables the chat message alerting you when you active or save a power state").define("disableActivatorChatMessage", false); builder.pop(); diff --git a/src/sandmastery/java/leaf/cosmere/sandmastery/client/gui/SandmasterySpiritwebMenu.java b/src/sandmastery/java/leaf/cosmere/sandmastery/client/gui/SandmasterySpiritwebMenu.java index 885658c0b..04d4cfb5d 100644 --- a/src/sandmastery/java/leaf/cosmere/sandmastery/client/gui/SandmasterySpiritwebMenu.java +++ b/src/sandmastery/java/leaf/cosmere/sandmastery/client/gui/SandmasterySpiritwebMenu.java @@ -1,9 +1,9 @@ package leaf.cosmere.sandmastery.client.gui; -import net.minecraft.client.gui.screens.Screen; +import leaf.cosmere.client.gui.CosmereScreen; import net.minecraft.network.chat.Component; -public class SandmasterySpiritwebMenu extends Screen +public class SandmasterySpiritwebMenu extends CosmereScreen { public SandmasterySpiritwebMenu() { From 5e383e81406426d0a9037e5049df7d670bb216c5 Mon Sep 17 00:00:00 2001 From: Gerbagel Date: Sat, 4 Apr 2026 20:30:36 +0200 Subject: [PATCH 18/55] [Cosmere] Added color tint to hud for burning/flaring --- .../leaf/cosmere/client/gui/SpiritwebHud.java | 32 ++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/src/main/java/leaf/cosmere/client/gui/SpiritwebHud.java b/src/main/java/leaf/cosmere/client/gui/SpiritwebHud.java index a1f42d8d5..24f0bafe6 100644 --- a/src/main/java/leaf/cosmere/client/gui/SpiritwebHud.java +++ b/src/main/java/leaf/cosmere/client/gui/SpiritwebHud.java @@ -16,6 +16,8 @@ import net.minecraft.resources.ResourceLocation; import net.minecraft.world.entity.player.Player; +import java.awt.*; + public class SpiritwebHud extends AbstractWidget { private static SpiritwebHud INSTANCE; @@ -71,11 +73,31 @@ protected void renderUsage(GuiGraphics pGuiGraphics) { SpiritwebCapability.get(player).ifPresent(spiritweb -> { + float r, g, b; + float a = 0.2f; + r = g = b = 1.0f; + + int mode = spiritweb.getSelectedManifestation().getMode(spiritweb); + + // todo this won't work for feruchemy... + if (mode > 0) + { + g = g - 0.4f * mode; + b = b - 0.4f * mode; + } + else if (mode < 0) + { + r = r - 0.4f * -mode; + g = g - 0.4f * -mode; + } + + int color = toHex(new Color(r, g, b, a)); + float width = getWidth(); float usagePercentage = spiritweb.getSelectedManifestation().getInvestitureHud(spiritweb); width = width * usagePercentage; - pGuiGraphics.fill(getX(), getY(), (int) (getX() + width), getY() + getHeight(), 0x33FFFFFF); + pGuiGraphics.fill(getX(), getY(), (int) (getX() + width), getY() + getHeight(), color); }); } @@ -140,4 +162,12 @@ protected void renderText(GuiGraphics pGuiGraphics) pGuiGraphics.drawString(font, text, getX() + getHeight() + 2, getY() + getHeight() / 2 - font.lineHeight/2, 0xFFDDDDDD); }); } + + protected int toHex(Color color) + { + return (color.getAlpha() << 24) | + (color.getRed() << 16) | + (color.getGreen() << 8) | + color.getBlue(); + } } From bb29e3f30a2ca27c2d956f138b63b48b0af253c4 Mon Sep 17 00:00:00 2001 From: Gerbagel Date: Sat, 4 Apr 2026 21:03:32 +0200 Subject: [PATCH 19/55] [Cosmere] Refactored how info texts are retrieved --- .../client/gui/InnerRadialButton.java | 34 ++++++------------- .../client/gui/OuterRadialButton.java | 34 ++++++------------- .../manifestation/AllomancyManifestation.java | 9 ++++- .../api/manifestation/Manifestation.java | 5 +++ 4 files changed, 35 insertions(+), 47 deletions(-) diff --git a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java index d33be42b8..fb79ee5a6 100644 --- a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java +++ b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java @@ -296,29 +296,17 @@ else if (segmentNr <= 7) String text = I18n.get(manifestation.getTranslationKey()); pGuiGraphics.drawString(font, text, x+5, y+10, 0xFFFFFFFF); - text = ""; - - for (String s : SpiritwebMenu.infoText) - { - if (s.toLowerCase().contains("a. " + metalType.getName())) - { - text = s.split(":")[1].stripLeading(); - - int seconds = Integer.parseInt(text); - int hours = seconds / 3600; - int minutes = (seconds % 3600) / 60; - seconds = seconds % 60; - - if (hours > 0) - text = String.format("%d:%02d:%02d", hours, minutes, seconds); - else if (minutes > 0) - text = String.format("%d:%02d", minutes, seconds); - else - text = String.format("%02ds", seconds); - - break; - } - } + int seconds = manifestation.getInvestitureRemaining(spiritweb); + int hours = seconds / 3600; + int minutes = (seconds % 3600) / 60; + seconds = seconds % 60; + + if (hours > 0) + text = String.format("%d:%02d:%02d", hours, minutes, seconds); + else if (minutes > 0) + text = String.format("%d:%02d", minutes, seconds); + else + text = String.format("%02d", seconds); pGuiGraphics.drawString(font, text, x+5, y+10+font.lineHeight+5, 0xFFFFFFFF); } diff --git a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java index cef422f2f..b07be76a1 100644 --- a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java +++ b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java @@ -353,29 +353,17 @@ else if (segmentNr <= 7) String text = I18n.get(manifestation.getTranslationKey()); pGuiGraphics.drawString(font, text, x+5, y+10, 0xFFFFFFFF); - text = ""; - - for (String s : SpiritwebMenu.infoText) - { - if (s.toLowerCase().contains("a. " + metalType.getName())) - { - text = s.split(":")[1].stripLeading(); - - int seconds = Integer.parseInt(text); - int hours = seconds / 3600; - int minutes = (seconds % 3600) / 60; - seconds = seconds % 60; - - if (hours > 0) - text = String.format("%d:%02d:%02d", hours, minutes, seconds); - else if (minutes > 0) - text = String.format("%d:%02d", minutes, seconds); - else - text = String.format("%02d", seconds); - - break; - } - } + int seconds = manifestation.getInvestitureRemaining(spiritweb); + int hours = seconds / 3600; + int minutes = (seconds % 3600) / 60; + seconds = seconds % 60; + + if (hours > 0) + text = String.format("%d:%02d:%02d", hours, minutes, seconds); + else if (minutes > 0) + text = String.format("%d:%02d", minutes, seconds); + else + text = String.format("%02d", seconds); pGuiGraphics.drawString(font, text, x+5, y+10+font.lineHeight+5, 0xFFFFFFFF); } diff --git a/src/allomancy/java/leaf/cosmere/allomancy/common/manifestation/AllomancyManifestation.java b/src/allomancy/java/leaf/cosmere/allomancy/common/manifestation/AllomancyManifestation.java index 1874086ab..87f77d0c4 100644 --- a/src/allomancy/java/leaf/cosmere/allomancy/common/manifestation/AllomancyManifestation.java +++ b/src/allomancy/java/leaf/cosmere/allomancy/common/manifestation/AllomancyManifestation.java @@ -266,7 +266,14 @@ public int getRange(ISpiritweb data) public float getInvestitureHud(ISpiritweb spiritweb) { AllomancySpiritwebSubmodule allo = (AllomancySpiritwebSubmodule) spiritweb.getSubmodule(Manifestations.ManifestationTypes.ALLOMANCY); - final float retVal = (float)allo.getIngestedMetal(this.metalType)/AllomancyConfigs.SERVER.MAX_INGESTIBLE_METAL.get(); + final float retVal = (float)allo.getIngestedMetal(metalType)/AllomancyConfigs.SERVER.MAX_INGESTIBLE_METAL.get(); return retVal; } + + @Override + public int getInvestitureRemaining(ISpiritweb spiritweb) + { + AllomancySpiritwebSubmodule allo = (AllomancySpiritwebSubmodule) spiritweb.getSubmodule(Manifestations.ManifestationTypes.ALLOMANCY); + return allo.getIngestedMetal(metalType); + } } diff --git a/src/api/java/leaf/cosmere/api/manifestation/Manifestation.java b/src/api/java/leaf/cosmere/api/manifestation/Manifestation.java index bbcd2c75a..53d19e330 100644 --- a/src/api/java/leaf/cosmere/api/manifestation/Manifestation.java +++ b/src/api/java/leaf/cosmere/api/manifestation/Manifestation.java @@ -145,6 +145,11 @@ public Attribute getAttribute() return ForgeRegistries.ATTRIBUTES.getValue(getRegistryName()); } + public int getInvestitureRemaining(ISpiritweb spiritweb) + { + return 0; + } + public float getInvestitureHud(ISpiritweb spiritweb) { return 0.f; From fc9d4e29ff5d8b032164acfb42a0ab9b615dc0ea Mon Sep 17 00:00:00 2001 From: Gerbagel Date: Wed, 29 Apr 2026 23:09:21 +0200 Subject: [PATCH 20/55] [Allomancy] Pixelated power circle and coloured icons --- .../client/gui/InnerRadialButton.java | 119 +++++++++--- .../client/gui/OuterRadialButton.java | 176 +++++++++--------- .../common/config/AllomancyClientConfig.java | 2 + 3 files changed, 182 insertions(+), 115 deletions(-) diff --git a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java index fb79ee5a6..1182556c7 100644 --- a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java +++ b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java @@ -5,6 +5,7 @@ import com.mojang.blaze3d.vertex.DefaultVertexFormat; import com.mojang.blaze3d.vertex.Tesselator; import com.mojang.blaze3d.vertex.VertexFormat; +import leaf.cosmere.allomancy.common.config.AllomancyConfigs; import leaf.cosmere.allomancy.common.manifestation.AllomancyManifestation; import leaf.cosmere.api.IHasMetalType; import leaf.cosmere.api.Manifestations; @@ -22,11 +23,12 @@ import net.minecraft.client.resources.language.I18n; import net.minecraft.network.chat.CommonComponents; import net.minecraft.resources.ResourceLocation; -import net.minecraft.util.Mth; import org.jetbrains.annotations.NotNull; import org.joml.Matrix4f; import org.lwjgl.opengl.GL11; +import java.awt.*; + public class InnerRadialButton extends Button { private static final int TEXT_DISTANCE = 30; @@ -147,69 +149,109 @@ private double normalizeAngle(double angle) // inspired by SteelCodeTeam's Metallic Arts https://github.com/SteelCodeTeam/Metallics-Arts/blob/main/src/main/java/net/rudahee/metallics_arts/modules/logic/client/custom_guis/selectors/AllomanticSelector.java private void renderSegment(GuiGraphics pGuiGraphics, boolean isHovered) { - float r, g, b; + float r = 61/255.f, g = 70/255.f, b = 76/255.f; float a = 1f; if (!hasManifestation) { - r = g = b = 0.1f; - } - else - { - r = g = b = 0.5f; + r *= 0.1f; + g *= 0.1f; + b *= 0.1f; } if (isHovered && hasManifestation) { - r = g = b = 0.6f; + r *= 1.1f; + g *= 1.1f; + b *= 1.1f; } - if (manifestation instanceof AllomancyManifestation allomancyManifestation) - { + if (manifestation instanceof AllomancyManifestation allomancyManifestation) { int mode = allomancyManifestation.getMode(spiritweb); - - if (mode > 0) - r = r + 0.2f * mode; - else if (mode < 0) - b = b + 0.2f * -mode; + float intensity = Math.min(Math.abs(mode) * 0.2f, 1.0f); // Cap intensity + + if (mode > 0) { + // Blend toward pure red + r = lerp(r, 1.0f, intensity); + g = lerp(g, 0.0f, intensity); + b = lerp(b, 0.0f, intensity); + } else if (mode < 0) { + // Blend toward pure blue + r = lerp(r, 0.0f, intensity); + g = lerp(g, 0.0f, intensity); + b = lerp(b, 1.0f, intensity); + } } float radsPerSegment = (float) Math.PI * 2 / 8; - float step = (float) Math.PI / 180; - float radius = outerRadius; + float startAngle = segmentNr * radsPerSegment; + float radiusSq = outerRadius * outerRadius; + + // Defines the "chunkiness" of the pixelation + // 1 GUI pixel = 1 screen pixel at 1x scale, or scaled automatically by the game's GUI scale + int pixelSize = AllomancyConfigs.CLIENT.pixelationAmount.get(); RenderSystem.disableCull(); RenderSystem.enableBlend(); RenderSystem.defaultBlendFunc(); RenderSystem.setShader(GameRenderer::getPositionColorShader); - Matrix4f pose = pGuiGraphics.pose().last().pose(); + Tesselator tess = Tesselator.getInstance(); BufferBuilder buf = tess.getBuilder(); - buf.begin(VertexFormat.Mode.TRIANGLE_FAN, DefaultVertexFormat.POSITION_COLOR); - buf.vertex(pose, centerX, centerY, 0).color(r, g, b, a).endVertex(); + buf.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR); - for (float f = 0f; f < radsPerSegment + step/2; f += step) - { - float rad = f + segmentNr * radsPerSegment; - float x = centerX + Mth.cos(rad) * radius; - float y = centerY + Mth.sin(rad) * radius; + // Use ceil to ensure the bounding box completely covers the outermost pixels + int rInt = (int) Math.ceil(outerRadius); - if (f == 0) + for (int x = -rInt; x <= rInt; x += pixelSize) + { + for (int y = -rInt; y <= rInt; y += pixelSize) { - buf.vertex(pose, x, y, 0).color(r,g,b,a).endVertex(); + float pixelCenterX = x + (pixelSize / 2f); + float pixelCenterY = y + (pixelSize / 2f); + + float distSq = pixelCenterX * pixelCenterX + pixelCenterY * pixelCenterY; + + if (distSq <= radiusSq) + { + float angle = (float) Math.atan2(pixelCenterY, pixelCenterX); + if (angle < 0) angle += (float) (Math.PI * 2); + + float diff = angle - startAngle; + if (diff < 0) diff += (float) (Math.PI * 2); + + if (diff < radsPerSegment) + { + float px = centerX + x; + float py = centerY + y; + + buf.vertex(pose, px, py, 0).color(r, g, b, a).endVertex(); + buf.vertex(pose, px, py + pixelSize, 0).color(r, g, b, a).endVertex(); + buf.vertex(pose, px + pixelSize, py + pixelSize, 0).color(r, g, b, a).endVertex(); + buf.vertex(pose, px + pixelSize, py, 0).color(r, g, b, a).endVertex(); + } + } } - buf.vertex(pose, x, y, 0).color(r,g,b,a).endVertex(); } tess.end(); - RenderSystem.disableBlend(); } private void renderIcon(@NotNull GuiGraphics pGuiGraphics) { + Color metalColor = metalType.getColor(); + float r = metalColor.getRed()/255.f, g = metalColor.getGreen()/255.f, b = metalColor.getBlue()/255.f; + + if (!hasManifestation) + { + r *= 0.1f; + g *= 0.1f; + b *= 0.1f; + } + StringBuilder stringBuilder = new StringBuilder(); stringBuilder.setLength(0); stringBuilder.append("textures/icon/") @@ -226,7 +268,6 @@ private void renderIcon(@NotNull GuiGraphics pGuiGraphics) final ResourceLocation location = new ResourceLocation(manifestation.getRegistryName().getNamespace(), stringBuilder.toString()); float alpha = hasManifestation ? 1.0f : 0.25f; RenderSystem.setShaderTexture(0, location); - RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, alpha); RenderSystem.enableBlend(); RenderSystem.blendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, 1, 0); @@ -236,6 +277,20 @@ private void renderIcon(@NotNull GuiGraphics pGuiGraphics) int posX = centerX + (int)(Math.cos(midAngle) * midRadius) - iconSize/2; int posY = centerY + (int)(Math.sin(midAngle) * midRadius) - iconSize/2; + RenderSystem.setShaderColor(0f, 0f, 0f, alpha); + pGuiGraphics.blit(location, + posX+1, + posY+1, + iconSize, + iconSize, + 0, + 0, + width, + height, + width, + height); + + RenderSystem.setShaderColor(r, g, b, alpha); pGuiGraphics.blit(location, posX, posY, @@ -310,4 +365,8 @@ else if (minutes > 0) pGuiGraphics.drawString(font, text, x+5, y+10+font.lineHeight+5, 0xFFFFFFFF); } + + public float lerp(float start, float end, float pct) { + return start + pct * (end - start); + } } diff --git a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java index b07be76a1..42135348b 100644 --- a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java +++ b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java @@ -5,6 +5,7 @@ import com.mojang.blaze3d.vertex.DefaultVertexFormat; import com.mojang.blaze3d.vertex.Tesselator; import com.mojang.blaze3d.vertex.VertexFormat; +import leaf.cosmere.allomancy.common.config.AllomancyConfigs; import leaf.cosmere.allomancy.common.manifestation.AllomancyManifestation; import leaf.cosmere.api.IHasMetalType; import leaf.cosmere.api.Manifestations; @@ -23,11 +24,12 @@ import net.minecraft.client.sounds.SoundManager; import net.minecraft.network.chat.CommonComponents; import net.minecraft.resources.ResourceLocation; -import net.minecraft.util.Mth; import org.jetbrains.annotations.NotNull; import org.joml.Matrix4f; import org.lwjgl.opengl.GL11; +import java.awt.*; + public class OuterRadialButton extends Button { private final float outerRadius; @@ -147,72 +149,111 @@ private double normalizeAngle(double angle) return angle; } - // inspired by SteelCodeTeam's Metallic Arts https://github.com/SteelCodeTeam/Metallics-Arts/blob/main/src/main/java/net/rudahee/metallics_arts/modules/logic/client/custom_guis/selectors/AllomanticSelector.java private void renderSegment(@NotNull GuiGraphics pGuiGraphics, boolean isHovered) { - float r, g, b; + float r = 61/255.f, g = 70/255.f, b = 76/255.f; float a = 1f; if (!hasManifestation) { - r = g = b = 0.1f; - } - else - { - r = g = b = 0.5f; + r *= 0.1f; + g *= 0.1f; + b *= 0.1f; } if (isHovered && hasManifestation) { - r = g = b = 0.6f; + r *= 1.1f; + g *= 1.1f; + b *= 1.1f; } - if (manifestation instanceof AllomancyManifestation allomancyManifestation) - { + if (manifestation instanceof AllomancyManifestation allomancyManifestation) { int mode = allomancyManifestation.getMode(spiritweb); - - if (mode > 0) - r = r + 0.2f * mode; - else if (mode < 0) - b = b + 0.2f * mode; + float intensity = Math.min(Math.abs(mode) * 0.2f, 1.0f); // Cap intensity + + if (mode > 0) { + // Blend toward pure red + r = lerp(r, 1.0f, intensity); + g = lerp(g, 0.0f, intensity); + b = lerp(b, 0.0f, intensity); + } else if (mode < 0) { + // Blend toward pure blue + r = lerp(r, 0.0f, intensity); + g = lerp(g, 0.0f, intensity); + b = lerp(b, 1.0f, intensity); + } } float radsPerSegment = (float) Math.PI * 2 / 8; - float step = (float) Math.PI / 180; - float radius = outerRadius; + float startAngle = segmentNr * radsPerSegment; + float radiusSq = outerRadius * outerRadius; + + // Defines the "chunkiness" of the pixelation + // 1 GUI pixel = 1 screen pixel at 1x scale, or scaled automatically by the game's GUI scale + int pixelSize = AllomancyConfigs.CLIENT.pixelationAmount.get(); RenderSystem.disableCull(); RenderSystem.enableBlend(); RenderSystem.defaultBlendFunc(); RenderSystem.setShader(GameRenderer::getPositionColorShader); - Matrix4f pose = pGuiGraphics.pose().last().pose(); + Tesselator tess = Tesselator.getInstance(); BufferBuilder buf = tess.getBuilder(); - buf.begin(VertexFormat.Mode.TRIANGLE_FAN, DefaultVertexFormat.POSITION_COLOR); - buf.vertex(pose, centerX, centerY, 0).color(r, g, b, a).endVertex(); + buf.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR); - for (float f = 0f; f < radsPerSegment + step/2; f += step) - { - float rad = f + segmentNr * radsPerSegment; - float x = centerX + Mth.cos(rad) * radius; - float y = centerY + Mth.sin(rad) * radius; + // Use ceil to ensure the bounding box completely covers the outermost pixels + int rInt = (int) Math.ceil(outerRadius); - if (f == 0) + for (int x = -rInt; x <= rInt; x += pixelSize) + { + for (int y = -rInt; y <= rInt; y += pixelSize) { - buf.vertex(pose, x, y, 0).color(r,g,b,a).endVertex(); + float pixelCenterX = x + (pixelSize / 2f); + float pixelCenterY = y + (pixelSize / 2f); + + float distSq = pixelCenterX * pixelCenterX + pixelCenterY * pixelCenterY; + + if (distSq <= radiusSq) + { + float angle = (float) Math.atan2(pixelCenterY, pixelCenterX); + if (angle < 0) angle += (float) (Math.PI * 2); + + float diff = angle - startAngle; + if (diff < 0) diff += (float) (Math.PI * 2); + + if (diff < radsPerSegment) + { + float px = centerX + x; + float py = centerY + y; + + buf.vertex(pose, px, py, 0).color(r, g, b, a).endVertex(); + buf.vertex(pose, px, py + pixelSize, 0).color(r, g, b, a).endVertex(); + buf.vertex(pose, px + pixelSize, py + pixelSize, 0).color(r, g, b, a).endVertex(); + buf.vertex(pose, px + pixelSize, py, 0).color(r, g, b, a).endVertex(); + } + } } - buf.vertex(pose, x, y, 0).color(r,g,b,a).endVertex(); } tess.end(); - RenderSystem.disableBlend(); } private void renderIcon(@NotNull GuiGraphics pGuiGraphics) { + Color metalColor = metalType.getColor(); + float r = metalColor.getRed()/255.f, g = metalColor.getGreen()/255.f, b = metalColor.getBlue()/255.f; + + if (!hasManifestation) + { + r *= 0.1f; + g *= 0.1f; + b *= 0.1f; + } + StringBuilder stringBuilder = new StringBuilder(); stringBuilder.setLength(0); stringBuilder.append("textures/icon/") @@ -229,7 +270,7 @@ private void renderIcon(@NotNull GuiGraphics pGuiGraphics) final ResourceLocation location = new ResourceLocation(manifestation.getRegistryName().getNamespace(), stringBuilder.toString()); float alpha = hasManifestation ? 1.0f : 0.25f; RenderSystem.setShaderTexture(0, location); - RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, alpha); + RenderSystem.enableBlend(); RenderSystem.blendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, 1, 0); @@ -239,6 +280,20 @@ private void renderIcon(@NotNull GuiGraphics pGuiGraphics) int posX = centerX + (int)(Math.cos(midAngle) * midRadius) - iconSize/2; int posY = centerY + (int)(Math.sin(midAngle) * midRadius) - iconSize/2; + RenderSystem.setShaderColor(0f, 0f, 0f, alpha); + pGuiGraphics.blit(location, + posX+1, + posY+1, + iconSize, + iconSize, + 0, + 0, + width, + height, + width, + height); + + RenderSystem.setShaderColor(r, g, b, alpha); pGuiGraphics.blit(location, posX, posY, @@ -254,60 +309,6 @@ private void renderIcon(@NotNull GuiGraphics pGuiGraphics) RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f); } - private void renderNameText(GuiGraphics pGuiGraphics) - { - Font font = Minecraft.getInstance().font; - int color = 0xffffffff; - - float radsPerSegment = (float) Math.PI * 2 / 8; - float f = (float) ((radsPerSegment + (Math.PI / 180f / 2f)) / 2f); - float rad = f + segmentNr * radsPerSegment; - float textRadius = outerRadius + 10; - float x = centerX + Mth.cos(rad) * textRadius; - float y = centerY + Mth.sin(rad) * textRadius; - - final String text = I18n.get(manifestation.getTranslationKey()); - - if (x < centerX) - { - x = x - (font.width(text)); - } - - pGuiGraphics.drawString(Minecraft.getInstance().font, text, (int)x, (int)y, color); - } - - private void renderStoresText(GuiGraphics pGuiGraphics) - { - Font font = Minecraft.getInstance().font; - int color = 0xffffffff; - - float radsPerSegment = (float) Math.PI * 2 / 8; - float f = (float) ((radsPerSegment + (Math.PI / 180f / 2f)) / 2f); - float rad = f + segmentNr * radsPerSegment; - float textRadius = outerRadius + 10; - float x = centerX + Mth.cos(rad) * textRadius; - float y = centerY + Mth.sin(rad) * textRadius; - - String text = ""; - for (String s : SpiritwebMenu.infoText) - { - if (s.toLowerCase().contains("a. " + metalType.getName())) - { - text = s.split(":")[1].stripLeading(); - - break; - } - } - - if (x < centerX) - { - x = x - (font.width(text)); - } - y += font.lineHeight*1.5f; - - pGuiGraphics.drawString(Minecraft.getInstance().font, text, (int)x, (int)y, color); - } - private void renderInfoBlock(GuiGraphics pGuiGraphics) { Font font = Minecraft.getInstance().font; @@ -367,4 +368,9 @@ else if (minutes > 0) pGuiGraphics.drawString(font, text, x+5, y+10+font.lineHeight+5, 0xFFFFFFFF); } + + public float lerp(float start, float end, float pct) + { + return start + pct * (end - start); + } } diff --git a/src/allomancy/java/leaf/cosmere/allomancy/common/config/AllomancyClientConfig.java b/src/allomancy/java/leaf/cosmere/allomancy/common/config/AllomancyClientConfig.java index cffb21306..969764109 100644 --- a/src/allomancy/java/leaf/cosmere/allomancy/common/config/AllomancyClientConfig.java +++ b/src/allomancy/java/leaf/cosmere/allomancy/common/config/AllomancyClientConfig.java @@ -14,6 +14,7 @@ public class AllomancyClientConfig implements ICosmereConfig public final ForgeConfigSpec.BooleanValue drawMetalLines; public final ForgeConfigSpec.BooleanValue drawMetalBoxes; public final ForgeConfigSpec.BooleanValue canHearRain; + public final ForgeConfigSpec.IntValue pixelationAmount; AllomancyClientConfig() { @@ -23,6 +24,7 @@ public class AllomancyClientConfig implements ICosmereConfig drawMetalLines = builder.comment("Iron/Steel vision draws metal lines between the user and the source of metal").define("drawMetalLines", true); drawMetalBoxes = builder.comment("Iron/Steel vision draws a blue box overlay over blocks that contain metal").define("drawMetalBoxes", true); canHearRain = builder.comment("Allomantic Tin picks up rain sounds, generating a sculk particle to player and showing an image at position of sound").define("canHearRain", true); + pixelationAmount = builder.comment("Amount of pixelation on the Allomancy power wheel").defineInRange("pixelationAmount", 1, 1, 10); builder.pop(); configSpec = builder.build(); From b266b995dce836af4b7a0e56ad73034dc0c8b0ce Mon Sep 17 00:00:00 2001 From: Gerbagel Date: Wed, 29 Apr 2026 23:12:37 +0200 Subject: [PATCH 21/55] [Allomancy] Render ring segments instead of slices --- .../cosmere/allomancy/client/gui/OuterRadialButton.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java index 42135348b..c95c77ae3 100644 --- a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java +++ b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java @@ -187,7 +187,9 @@ private void renderSegment(@NotNull GuiGraphics pGuiGraphics, boolean isHovered) float radsPerSegment = (float) Math.PI * 2 / 8; float startAngle = segmentNr * radsPerSegment; - float radiusSq = outerRadius * outerRadius; + + float outerRadiusSq = outerRadius * outerRadius; + float innerRadiusSq = innerRadius * innerRadius; // Defines the "chunkiness" of the pixelation // 1 GUI pixel = 1 screen pixel at 1x scale, or scaled automatically by the game's GUI scale @@ -204,7 +206,6 @@ private void renderSegment(@NotNull GuiGraphics pGuiGraphics, boolean isHovered) buf.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR); - // Use ceil to ensure the bounding box completely covers the outermost pixels int rInt = (int) Math.ceil(outerRadius); for (int x = -rInt; x <= rInt; x += pixelSize) @@ -216,7 +217,7 @@ private void renderSegment(@NotNull GuiGraphics pGuiGraphics, boolean isHovered) float distSq = pixelCenterX * pixelCenterX + pixelCenterY * pixelCenterY; - if (distSq <= radiusSq) + if (distSq <= outerRadiusSq && distSq >= innerRadiusSq) { float angle = (float) Math.atan2(pixelCenterY, pixelCenterX); if (angle < 0) angle += (float) (Math.PI * 2); From 29decbae2e099b4a37abec0f2fa69fed9b4358f0 Mon Sep 17 00:00:00 2001 From: Gerbagel Date: Fri, 1 May 2026 22:33:58 +0200 Subject: [PATCH 22/55] [Feruchemy] Make the entire menu lol --- .../client/gui/AllomancySpiritwebMenu.java | 6 - .../client/gui/InnerRadialButton.java | 2 - .../feruchemy/client/gui/DiamondButton.java | 265 ++++++++++++++++++ .../client/gui/FeruchemySpiritwebMenu.java | 99 ++++++- .../feruchemy/textures/gui/feru_border.png | Bin 0 -> 3029 bytes 5 files changed, 363 insertions(+), 9 deletions(-) create mode 100644 src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/DiamondButton.java create mode 100644 src/feruchemy/resources/assets/feruchemy/textures/gui/feru_border.png diff --git a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/AllomancySpiritwebMenu.java b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/AllomancySpiritwebMenu.java index ef7b324d0..95118d2d0 100644 --- a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/AllomancySpiritwebMenu.java +++ b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/AllomancySpiritwebMenu.java @@ -65,12 +65,6 @@ protected void init() })); } - @Override - public boolean mouseClicked(double pMouseX, double pMouseY, int pButton) - { - return super.mouseClicked(pMouseX, pMouseY, pButton); - } - @Override public void render(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) { diff --git a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java index 1182556c7..7f1c0c439 100644 --- a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java +++ b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java @@ -31,7 +31,6 @@ public class InnerRadialButton extends Button { - private static final int TEXT_DISTANCE = 30; private final float outerRadius; private final float innerRadius; private final double startAngle; @@ -146,7 +145,6 @@ private double normalizeAngle(double angle) return angle; } - // inspired by SteelCodeTeam's Metallic Arts https://github.com/SteelCodeTeam/Metallics-Arts/blob/main/src/main/java/net/rudahee/metallics_arts/modules/logic/client/custom_guis/selectors/AllomanticSelector.java private void renderSegment(GuiGraphics pGuiGraphics, boolean isHovered) { float r = 61/255.f, g = 70/255.f, b = 76/255.f; diff --git a/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/DiamondButton.java b/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/DiamondButton.java new file mode 100644 index 000000000..2a9278614 --- /dev/null +++ b/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/DiamondButton.java @@ -0,0 +1,265 @@ +package leaf.cosmere.feruchemy.client.gui; + +import com.mojang.blaze3d.systems.RenderSystem; +import com.mojang.blaze3d.vertex.BufferBuilder; +import com.mojang.blaze3d.vertex.DefaultVertexFormat; +import com.mojang.blaze3d.vertex.Tesselator; +import com.mojang.blaze3d.vertex.VertexFormat; +import leaf.cosmere.api.IHasMetalType; +import leaf.cosmere.api.Manifestations; +import leaf.cosmere.api.Metals; +import leaf.cosmere.api.manifestation.Manifestation; +import leaf.cosmere.api.spiritweb.ISpiritweb; +import leaf.cosmere.client.gui.SpiritwebMenu; +import leaf.cosmere.common.Cosmere; +import leaf.cosmere.common.network.packets.ChangeManifestationModeMessage; +import leaf.cosmere.feruchemy.common.manifestation.FeruchemyManifestation; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.components.Button; +import net.minecraft.client.renderer.GameRenderer; +import net.minecraft.network.chat.CommonComponents; +import net.minecraft.resources.ResourceLocation; +import org.joml.Matrix4f; +import org.lwjgl.opengl.GL11; + +import java.awt.*; + +public class DiamondButton extends Button +{ + private final ISpiritweb spiritweb; + private final Manifestation manifestation; + private final Metals.MetalType metal; + private final boolean hasManifestation; + private final float rotation; + + public DiamondButton(int pX, int pY, int distance, float rotation, Metals.MetalType metal, ISpiritweb spiritweb) + { + super(pX, pY, distance, distance, CommonComponents.EMPTY, (button) -> { }, DEFAULT_NARRATION); + this.rotation = rotation; + this.spiritweb = spiritweb; + this.metal = metal; + manifestation = Manifestations.ManifestationTypes.FERUCHEMY.getManifestation(metal.getID()); + hasManifestation = spiritweb.hasManifestation(manifestation); + } + + @Override + protected void renderWidget(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) + { + boolean isHover = isMouseOver(pMouseX, pMouseY); + renderDiamond(pGuiGraphics, isHover); + renderIcon(pGuiGraphics); + } + + @Override + public boolean isMouseOver(double mouseX, double mouseY) + { + boolean retVal; + + float radius = getWidth() / 2.0f; + float centerX = getX() + radius; + float centerY = getY() + radius; + + float dx = (float) mouseX - centerX; + float dy = (float) mouseY - centerY; + + float cos = (float) Math.cos(-rotation); + float sin = (float) Math.sin(-rotation); + + float px = dx * cos - dy * sin; + float py = dx * sin + dy * cos; + + retVal = (px <= radius && py <= radius && (px + py) >= 0); + + if (hasManifestation) + { + if (retVal) + { + SpiritwebMenu.selectedManifestation = manifestation; + } + } + + return retVal; + } + + @Override + public boolean mouseClicked(double pMouseX, double pMouseY, int pButton) + { + if (isMouseOver(pMouseX, pMouseY) && hasManifestation) + { + if (pButton == 0) + Cosmere.packetHandler().sendToServer(new ChangeManifestationModeMessage(manifestation, 1)); + else + Cosmere.packetHandler().sendToServer(new ChangeManifestationModeMessage(manifestation, -1)); + + playDownSound(Minecraft.getInstance().getSoundManager()); + } + return super.mouseClicked(pMouseX, pMouseY, pButton); + } + + private void renderDiamond(GuiGraphics pGuiGraphics, boolean isHovered) + { + float r = 61/255.f, g = 70/255.f, b = 76/255.f; + float a = 1f; + + if (!hasManifestation) + { + r *= 0.1f; + g *= 0.1f; + b *= 0.1f; + } + + if (isHovered && hasManifestation) + { + r *= 1.1f; + g *= 1.1f; + b *= 1.1f; + } + + if (manifestation instanceof FeruchemyManifestation feruchemyManifestation) { + int mode = feruchemyManifestation.getMode(spiritweb); + float intensity = Math.min(Math.abs(mode) * 0.2f, 1.0f); // Cap intensity + + if (mode > 0) { + // Blend toward pure red + r = lerp(r, 1.0f, intensity); + g = lerp(g, 0.0f, intensity); + b = lerp(b, 0.0f, intensity); + } else if (mode < 0) { + // Blend toward pure blue + r = lerp(r, 0.0f, intensity); + g = lerp(g, 0.0f, intensity); + b = lerp(b, 1.0f, intensity); + } + } + + RenderSystem.disableCull(); + RenderSystem.enableBlend(); + RenderSystem.defaultBlendFunc(); + RenderSystem.setShader(GameRenderer::getPositionColorShader); + + Matrix4f pose = pGuiGraphics.pose().last().pose(); + + Tesselator tess = Tesselator.getInstance(); + BufferBuilder buf = tess.getBuilder(); + + buf.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR); + + float size = getWidth(); + float radius = size / 2.0f; + float centerX = getX() + radius; + float centerY = getY() + radius; + + int pixelSize = 1; + + int maxR = (int) Math.ceil(Math.sqrt(radius * radius + radius * radius)); + + float cos = (float) Math.cos(-rotation); + float sin = (float) Math.sin(-rotation); + + for (int x = -maxR; x <= maxR; x += pixelSize) + { + for (int y = -maxR; y <= maxR; y += pixelSize) + { + float pixelCenterX = x + (pixelSize / 2f); + float pixelCenterY = y + (pixelSize / 2f); + + float px = pixelCenterX * cos - pixelCenterY * sin; + float py = pixelCenterX * sin + pixelCenterY * cos; + + if (px <= radius && py <= radius && px + py >= 0) + { + float screenX = centerX + x; + float screenY = centerY + y; + + buf.vertex(pose, screenX, screenY, 0).color(r,g,b,a).endVertex(); + buf.vertex(pose, screenX, screenY + pixelSize, 0).color(r,g,b,a).endVertex(); + buf.vertex(pose, screenX + pixelSize, screenY + pixelSize, 0).color(r,g,b,a).endVertex(); + buf.vertex(pose, screenX + pixelSize, screenY, 0).color(r,g,b,a).endVertex(); + } + } + } + + tess.end(); + RenderSystem.disableBlend(); + } + + private void renderIcon(GuiGraphics pGuiGraphics) + { + Color metalColor = metal.getColor(); + float r = metalColor.getRed()/255.f, g = metalColor.getGreen()/255.f, b = metalColor.getBlue()/255.f; + + if (!hasManifestation) + { + r *= 0.1f; + g *= 0.1f; + b *= 0.1f; + } + + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.setLength(0); + stringBuilder.append("textures/icon/") + .append(manifestation.getManifestationType().getName()) + .append("/"); + + // no need for a switch case, always allomancy + if (manifestation instanceof IHasMetalType metalType) + { + stringBuilder.append(metalType.getMetalType().getName()); + } + + stringBuilder.append(".png"); + final ResourceLocation location = new ResourceLocation(manifestation.getRegistryName().getNamespace(), stringBuilder.toString()); + float alpha = hasManifestation ? 1.0f : 0.25f; + RenderSystem.setShaderTexture(0, location); + RenderSystem.enableBlend(); + RenderSystem.blendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, 1, 0); + + int iconSize = width / 4; + + float radius = width / 2.0f; + float centerX = getX() + radius; + float centerY = getY() + radius; + + float localCx = radius / 3.0f; + float localCy = radius / 3.0f; + + float cos = (float) Math.cos(rotation); + float sin = (float) Math.sin(rotation); + + int posX = (int) (centerX + localCx * cos - localCy * sin) - iconSize / 2; + int posY = (int) (centerY + localCx * sin + localCy * cos) - iconSize / 2; + + RenderSystem.setShaderColor(0f, 0f, 0f, alpha); + pGuiGraphics.blit(location, + posX + 1, + posY + 1, + iconSize, + iconSize, + 0, + 0, + width, + height, + width, + height); + + RenderSystem.setShaderColor(r, g, b, alpha); + pGuiGraphics.blit(location, + posX, + posY, + iconSize, + iconSize, + 0, + 0, + width, + height, + width, + height); + + RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f); + } + + public float lerp(float start, float end, float pct) { + return start + pct * (end - start); + } +} diff --git a/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/FeruchemySpiritwebMenu.java b/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/FeruchemySpiritwebMenu.java index de726728c..64a961c11 100644 --- a/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/FeruchemySpiritwebMenu.java +++ b/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/FeruchemySpiritwebMenu.java @@ -1,26 +1,123 @@ package leaf.cosmere.feruchemy.client.gui; +import com.mojang.blaze3d.systems.RenderSystem; +import leaf.cosmere.api.Metals; import leaf.cosmere.client.gui.CosmereScreen; +import leaf.cosmere.common.cap.entity.SpiritwebCapability; +import leaf.cosmere.feruchemy.common.Feruchemy; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.player.LocalPlayer; import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import org.lwjgl.opengl.GL11; public class FeruchemySpiritwebMenu extends CosmereScreen { + private static final float QUARTER_PI_F = (float) (Math.PI/2.f); + private int distance; + final LocalPlayer player; public FeruchemySpiritwebMenu() { super(Component.literal("Feruchemy")); + player = Minecraft.getInstance().player; + init(); } @Override protected void init() { + this.width = Minecraft.getInstance().getWindow().getGuiScaledWidth(); + this.height = Minecraft.getInstance().getWindow().getGuiScaledHeight(); + distance = this.height / 6; + final float topLeftRot = 0.f; + final float topRightRot = QUARTER_PI_F; + final float bottomRightRot = topRightRot + QUARTER_PI_F; + final float bottomLeftRot = bottomRightRot + QUARTER_PI_F; + SpiritwebCapability.get(player).ifPresent( (spiritweb -> { + int x = this.width/2 - distance; + int y = this.height/2 - distance*2; + + addRenderableWidget(new DiamondButton(x, y, + distance, topLeftRot, Metals.MetalType.IRON, spiritweb)); + addRenderableWidget(new DiamondButton(x + distance, y, + distance, topRightRot, Metals.MetalType.STEEL, spiritweb)); + addRenderableWidget(new DiamondButton(x + distance, y + distance, + distance, bottomRightRot, Metals.MetalType.TIN, spiritweb)); + addRenderableWidget(new DiamondButton(x, y + distance, + distance, bottomLeftRot, Metals.MetalType.PEWTER, spiritweb)); + + x = this.width / 2; + y = this.height / 2 - distance; + + addRenderableWidget(new DiamondButton(x, y, + distance, topLeftRot, Metals.MetalType.ZINC, spiritweb)); + addRenderableWidget(new DiamondButton(x + distance, y, + distance, topRightRot, Metals.MetalType.COPPER, spiritweb)); + addRenderableWidget(new DiamondButton(x + distance, y + distance, + distance, bottomRightRot, Metals.MetalType.BRASS, spiritweb)); + addRenderableWidget(new DiamondButton(x, y + distance, + distance, bottomLeftRot, Metals.MetalType.BRONZE, spiritweb)); + + x = this.width / 2 - distance; + y = this.height / 2; + + addRenderableWidget(new DiamondButton(x, y, + distance, topLeftRot, Metals.MetalType.GOLD, spiritweb)); + addRenderableWidget(new DiamondButton(x + distance, y, + distance, topRightRot, Metals.MetalType.ELECTRUM, spiritweb)); + addRenderableWidget(new DiamondButton(x + distance, y + distance, + distance, bottomRightRot, Metals.MetalType.CADMIUM, spiritweb)); + addRenderableWidget(new DiamondButton(x, y + distance, + distance, bottomLeftRot, Metals.MetalType.BENDALLOY, spiritweb)); + + x = this.width / 2 - distance*2; + y = this.height / 2 - distance; + + addRenderableWidget(new DiamondButton(x, y, + distance, topLeftRot, Metals.MetalType.CHROMIUM, spiritweb)); + addRenderableWidget(new DiamondButton(x + distance, y, + distance, topRightRot, Metals.MetalType.DURALUMIN, spiritweb)); + addRenderableWidget(new DiamondButton(x + distance, y + distance, + distance, bottomRightRot, Metals.MetalType.NICROSIL, spiritweb)); + addRenderableWidget(new DiamondButton(x, y + distance, + distance, bottomLeftRot, Metals.MetalType.ALUMINUM, spiritweb)); + })); } @Override public void render(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) { - pGuiGraphics.drawCenteredString(Minecraft.getInstance().font, "feruchemy", pMouseX, pMouseY, 0xFFFFFFFF); + super.render(pGuiGraphics, pMouseX, pMouseY, pPartialTick); + renderBorder(pGuiGraphics); + } + + private void renderBorder(GuiGraphics pGuiGraphics) + { + final ResourceLocation location = new ResourceLocation(Feruchemy.MODID, "textures/gui/feru_border.png"); + + RenderSystem.setShaderTexture(0, location); + RenderSystem.enableBlend(); + RenderSystem.blendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, 1, 0); + RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f); + + final int x = width/2 - distance*2, y = height/2 - distance*2; + final int screenSize = distance*4; + final int iconSize = 256; + + pGuiGraphics.blit(location, + x, + y, + screenSize, + screenSize, + 0, + 0, + iconSize, + iconSize, + iconSize, + iconSize); + + RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f); } } diff --git a/src/feruchemy/resources/assets/feruchemy/textures/gui/feru_border.png b/src/feruchemy/resources/assets/feruchemy/textures/gui/feru_border.png new file mode 100644 index 0000000000000000000000000000000000000000..4d41d7a75214c60c2928cc2045b3c8bdbcc31a42 GIT binary patch literal 3029 zcmW+&X;>3y7ky_Kbp(ZsBE}FPOf2o^8WtB&%cx;#wTQJ+q$073wt@l*f`DXF^&vnY zv~_DsC9QR1ccCI$Gk!?oR>1|a0tSsOARbol>4xG(CR^T zcS+yQWNWi|lkvIop_9W?8WkoMnkdyFk{MrZ=vOnrgia+jr^|H{@yPZcEc58*QP>C1 zuGz6FFWVd^_k3#qM^szj6y9nREn7iYH>>@)Rg}B1hjvdfH0_Ea7M8T}`re zOMy<}f=i~Ep_wZxq`o#EdU#2pg%f~!rQ!LWhoG5h&a$CpiDb-v;;cd`s$;%Q{ARB(I<}wKd zW>AW$=mNCVU~Q7(y#h8*XiJkT#^SQkW+=T8hI|yfS)e*cate)dJ}q;>glbFEV&WeO z+9ex)qvkRQ1v2QJDPaL>zie%l;${KsE>wzX*+{HTZ81vm*A(j{)H~D3F4){WORqQH zO0naG`WbZcSZuD^(ksQgDAqx!^ptms@qv-%rd(1ShSn(f9h7Pv$vGQJy{HT=N>uP^ z0#z%?jW@)(Q1`>o#kG7IrP@q%&NRe%QPx5v8;(+Q%laHR>pO2eE=J$8!-4zJsPA*y z$Xlxth?tArm6r5uht%Pr+}E5}UlEr0M~|1*xN8})Gdm|I=R+G`*>mi_QCP;%Oi!x& z(GDI!4~Why##lPC?V&Z+NS-0NA53X^%qRVZ{`wGIHmVYL(|E1eL*MJFx{cLs+xruF zH+ef>wS>4fQgQk7)pE(%a&x)|9qEUpdXowZ{HU?sepD z__wJU=flSSvQXVp6jgHXW8%!8B7M0~H4cm35iyTy4#?uGVu;(LB#*ywqjm8u*4QKD zZ_dnIJKYN^y6dltQ~}ukb-C?Ckttro}XGe$-ArVmkf^>kfd%a-RC-9CKAQqg1=*m8tIf6?sfF z3euX=v`njI-X3x{!CI6(BGq$q`YkHj6B%q@oF!$$rL?pr0BMwQ2O!zJoQigXlQlz- zw9<6VWbi{>8KvNj6-C@jkjr3M2x}=l?T4=b%~Y3<12_CxMlN+iX8p`8LTFnsm6p8+ zbR`u4T6d#}8vu~y6o9m|{PD#A>beS`U}FV220*3D7T_9X)g($d4lGf$2^d6&rOESv zVL>hQP#YTB8HKrjrAaCU{LMAyigSRGlj_R7F&o5PL;clOhqHK8q^ z%k>?OdIir}8AaSEbAMMLuF)Upr;6*2iWyC@ahF5$K&kB)a~OA1KRjRgqL;Vn1`}-R z?Ad`|&bQt4+PTrYVrW6O*Y+2Wu_wQ$b6WD{0Dq#(DrSwxvvyuoOx{fyn(ReKHk?li+TP?K!QXT&XwZ^R zwm(U@dEkAVQe6oB`QZ{`YfxrULz_RA$9#CWsqcOKTuI=ip5_yrT%uhy@s&U&zImu4 z!y1EVUDB(SJLOE6yevuy9ISNzMxdH|%RbKy$FnB2Uz7@{=wa%#u=uqO`a(B>kg63kut(q)+oa)VI@LAzj`)^r0`{hxcT;Vwc#*i5+-c5AYPnA)^ znb*M@!i0bRTym`4t%THkzZvK>zVB`}-Z|vN5YMj%fmxofN@;s>!eu1P)p#$UZ>`AO zaOvgy4wP!J%e=xG@tE8(RV=JrS&09JbzSx65KF@zH$k%*N`*?tMLJGRj<^t53Ha32Sv@t zHMWCgRHRscVg#2T3SL|>9WOJ_X++T{fg_^9f`%SX{wgir$?p$DZeq+(?L7sbU`YDQ zL9q~yVxq!y*Q}L`P+|%p)E`|*9S_JUABVnhg~H9-iLye|lo6Z{ysS$$6`x>CYQYuX zgLAe`@=%qT&*oz_mw+U&FdwGi7cJ<%4jO5H9;$n5t=x*9Z2%{Z{agy4_NWDDyDzwG z|7oh*FQ-?4=1l_2-nm7liu7rtSq}{uw=b5cFEj;>;2z3Z%j=qnsv`3o|Ae70JMOvb z+FTxr^gV^Ix!}GvH7n}&i-UrSOhKbKH5z^zl*1P?t%89ESr=dR$9NF!zb1o0Ti)C^ zo_+;a+w5qzfv$7C91N-?7za}{+xn!n6 zIR?wvMLub;YNcqDKs8@z3nV%vv`%X&4MPzUyk2OVMRZQ4b-9+fFf>Dg2f=_PI%!&< zwV1-t773mrvR_&=X(1X3ONQ_84w56} z3b7%0B6e^$*>1FUNzr&p)eA$HQ25cwp60k*G>svO*6|4x8=~g2U<~6m0_wiex=z40 zs<|Xhuro$7#6{U~G$A43S{zA6cN3zBWNL~a29Ycq0Wk*FE@z0DBwKt9BCKHt^C8xg ztnOoo4@ma7BgD5PTXO?qpa7*z0+|j<(CGE~Fn9N$$=`b8nqV)ySiKeQI0DwgM!5M4 zB(um)aE@Ysa|M+QN>N@27@-vw$^tc9@h;?A;|DTu!y_-}10a)Ry#0YWfkurt>;(nL zHNajl8;`uJhJv>wvo_s6sU@f}HV>KmccFk}A1IiJH(&l13UWwBT5T_QoZHd-@E9_f iT!IIV9s Date: Fri, 1 May 2026 22:57:03 +0200 Subject: [PATCH 23/55] [Feruchemy] Better border --- .../feruchemy/textures/gui/feru_border.png | Bin 3029 -> 3012 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/src/feruchemy/resources/assets/feruchemy/textures/gui/feru_border.png b/src/feruchemy/resources/assets/feruchemy/textures/gui/feru_border.png index 4d41d7a75214c60c2928cc2045b3c8bdbcc31a42..a3ff498f1f30a7b296ffdc446d842135d8d9ab44 100644 GIT binary patch literal 3012 zcmXArdt4LO631tE!xHQA@&O6YlvJg@NP@K#W3r%vRIh-KqM{NcB3FDwt(sOO8?}Oh z5EK->Dyh^e3X(!qRFqW|Bcj2!sI9Gp3VMaM#GpttkbC0&D|62Io|#ELncw;Cj-M0b z_JQvQ0N@robNXBW422kQN%XN~!>KgqYUA9PC^&o1{{_I%tk~(1^VLWG{v&R){|wI? z?bU$?Q}6P_i%sm|r`N8J*q8P;Zqt?pY076kk5lY{2f~7Rv0-IFZk={}caP?L)__T# zxJVcU+c?bcBW0;xsqc|g?)zxY*U0f zKSF0b9r{F!eG3JW;l_qY-b>KXEy)z(M;6VyPdRBIe z@y|qneRWXNU4NH*;|6fb<_=cM38AM4;hD1-wJMlM3b?J-EqU~8iiWPv9-dasgY^kb zZDRZf5nMlBT%XGMQvuUwOwioo-e7^dXW3xBSIaHPxjokzGy?bb7tY`&A>^7jl2;isI8TY zL+ZVw&3w{~H&yNSsx82H({1O(_!|)rAsQ-=-9)iNnu3N3Rc?fevEI7D%}a&N@q>?e zS~10vO{IiTm5-?-Z5vZK`C>?pA3Va-ZlhRDh-PgbJDFsx2d{DK#>t_`S?2Oj1Z~S$ z&XEsYDdwY$7`bxjV z!Nc?+EPSk{6Xr*ePl|a=VO3wE8$D8~NP3IaS}U*a!A>#MU$dsdmaC@Z3Gi#7Huc}G z=G*%-$GQl@B&vy>(5&8-Tnx$?WaD>!%%QlRN>3)w$kxs$41Zo6_?6JP@oPulg^J9S zxM!e@BG1kegLhTe9baa=k)7J^%34QV;S)NHUmN-g)OE+?NpM_9n05w$>C;~02*zk+ zH-6|!w;#={<_N}0L@~8ke7OCAM!pJygNfdqzHp*p%YDMrjbAdZ8A1ZD=K3=;jcn$J zByF=S{RO5+k`Hu23^%(cm=xd=L;fq69+BxY0lJLr;%dV4rDf@N5F#YHW8LYFhAj!W zeh>9X=f_a!0*ChE8-$<0A@{a&SK5tl7!?M5kG79p=^=c>7%?33Xe%da7rv!k1|!|u zJ|=05Z+RL4#fW!d{rHx<%ww1@%{(~*;*@3|6IDymoef*YVwNa!l0+c`|H1uHAk}H( zp72Eh;O@9L1s)jLDJH7K4YJ!3S8$B1tcoh3AX|QL8(Mr;K#dOqclpF_u1>rD0e@ix zN^xnmkS5R8G_%#1+45!uACss`7mx?gCC$XQhBH9Mwc4aZy_VU~0VubX<#OF;Cc zrJ4IcrIwFHb?wbfY$d8YScj7L|EExUhhW<`srLfE<>e&eAWGN$Lm(#6KaVAMp|ai8 zzG%_CmfYn$Nt%i)>9(WP5qHQgNNq*EhM!F{s~|j6T7%Nv*f@%~jM6x*Wr4=rCmF4YVSm~P!)N6TV9eKu&j@}%F@!=b&@tdWL8K>fCX z>{TAvyRy>LL2u5S)_5$C|Fij(6gnooT|;-g>XR~+Rn%cexngZvC;czfdc^ zCo$O2sb|~IC*SOIenG>#=>pvIVa4;l{o2~-FjfC-8uv8)<OxF|hWedbB$o;5v924qaGR-I#8=e|-@1#YeCzJ8>GBIg_Gi1;WjSalu5NlGKlKW4hWG6ktzsW&OvT^;bF8Ou@ibB*lR)kMp7Qqa_1CLl6mJ?Np{%*^b9 zom7QT4ijd=@c@~x#1Nf>rT>ZLsQYu!l%|mS-K3zay)2m6_>C_!+M6+E7vxdR!`H%L zbRkFJX(#o&PZk_bfa(C5pF|b6 z2TRW-bT2LZLT&d?6rD7JsmM0%p_c4l1;2HGQkI#fR4loKrSHde0~RFw;*VYRQz`nJ zhD4gYcOrn<90m*AlU?}X2fl{iZo>SC%uz~3@>?u@2X<<6|0*MUei+d*2akVg8Cj^^ zvO?DK&woEuoM^ZZs_{XSG@*5H;^*58N8e-^zb#*EOKQc^^I+Nh@tQMIsI)xawzM@4 z^S$6mJ`{?tO;9KDAC=ilKlh+hIZfZ%+lqsjMs880txXJ$6wZb+`(qvx%F`YRamYxs zi%>VTQ{D)x6`T!vJ9>-*^61sb0ic)GD`&U0AQk3_@E_s_Gk6S^M^i2RVo) zc@QBQA~bk+ChtJr!E50TYZdYijojuL$UcC#g7Zvo?-oO@2sg!N`B7|C9y_(D&7Cmt zkO}C#a1(e6PGfx5R*Lb8HuE~)Tm#;6&iRBaImL*h%~P6saxoRlwMW?o#4zV{0dzh@ z*5`BtUX<)gm@9tc#%E2S7zRnQ?X?JktDOMyPq&?b4Zd?w-7CARUNx`9Cog1kz3<-LXTuutg zPoj+s1q{191`KU)$fycyFj<#=(85Dc>AIwj5$-%$a^RO0oTaS$rE4 literal 3029 zcmW+&X;>3y7ky_Kbp(ZsBE}FPOf2o^8WtB&%cx;#wTQJ+q$073wt@l*f`DXF^&vnY zv~_DsC9QR1ccCI$Gk!?oR>1|a0tSsOARbol>4xG(CR^T zcS+yQWNWi|lkvIop_9W?8WkoMnkdyFk{MrZ=vOnrgia+jr^|H{@yPZcEc58*QP>C1 zuGz6FFWVd^_k3#qM^szj6y9nREn7iYH>>@)Rg}B1hjvdfH0_Ea7M8T}`re zOMy<}f=i~Ep_wZxq`o#EdU#2pg%f~!rQ!LWhoG5h&a$CpiDb-v;;cd`s$;%Q{ARB(I<}wKd zW>AW$=mNCVU~Q7(y#h8*XiJkT#^SQkW+=T8hI|yfS)e*cate)dJ}q;>glbFEV&WeO z+9ex)qvkRQ1v2QJDPaL>zie%l;${KsE>wzX*+{HTZ81vm*A(j{)H~D3F4){WORqQH zO0naG`WbZcSZuD^(ksQgDAqx!^ptms@qv-%rd(1ShSn(f9h7Pv$vGQJy{HT=N>uP^ z0#z%?jW@)(Q1`>o#kG7IrP@q%&NRe%QPx5v8;(+Q%laHR>pO2eE=J$8!-4zJsPA*y z$Xlxth?tArm6r5uht%Pr+}E5}UlEr0M~|1*xN8})Gdm|I=R+G`*>mi_QCP;%Oi!x& z(GDI!4~Why##lPC?V&Z+NS-0NA53X^%qRVZ{`wGIHmVYL(|E1eL*MJFx{cLs+xruF zH+ef>wS>4fQgQk7)pE(%a&x)|9qEUpdXowZ{HU?sepD z__wJU=flSSvQXVp6jgHXW8%!8B7M0~H4cm35iyTy4#?uGVu;(LB#*ywqjm8u*4QKD zZ_dnIJKYN^y6dltQ~}ukb-C?Ckttro}XGe$-ArVmkf^>kfd%a-RC-9CKAQqg1=*m8tIf6?sfF z3euX=v`njI-X3x{!CI6(BGq$q`YkHj6B%q@oF!$$rL?pr0BMwQ2O!zJoQigXlQlz- zw9<6VWbi{>8KvNj6-C@jkjr3M2x}=l?T4=b%~Y3<12_CxMlN+iX8p`8LTFnsm6p8+ zbR`u4T6d#}8vu~y6o9m|{PD#A>beS`U}FV220*3D7T_9X)g($d4lGf$2^d6&rOESv zVL>hQP#YTB8HKrjrAaCU{LMAyigSRGlj_R7F&o5PL;clOhqHK8q^ z%k>?OdIir}8AaSEbAMMLuF)Upr;6*2iWyC@ahF5$K&kB)a~OA1KRjRgqL;Vn1`}-R z?Ad`|&bQt4+PTrYVrW6O*Y+2Wu_wQ$b6WD{0Dq#(DrSwxvvyuoOx{fyn(ReKHk?li+TP?K!QXT&XwZ^R zwm(U@dEkAVQe6oB`QZ{`YfxrULz_RA$9#CWsqcOKTuI=ip5_yrT%uhy@s&U&zImu4 z!y1EVUDB(SJLOE6yevuy9ISNzMxdH|%RbKy$FnB2Uz7@{=wa%#u=uqO`a(B>kg63kut(q)+oa)VI@LAzj`)^r0`{hxcT;Vwc#*i5+-c5AYPnA)^ znb*M@!i0bRTym`4t%THkzZvK>zVB`}-Z|vN5YMj%fmxofN@;s>!eu1P)p#$UZ>`AO zaOvgy4wP!J%e=xG@tE8(RV=JrS&09JbzSx65KF@zH$k%*N`*?tMLJGRj<^t53Ha32Sv@t zHMWCgRHRscVg#2T3SL|>9WOJ_X++T{fg_^9f`%SX{wgir$?p$DZeq+(?L7sbU`YDQ zL9q~yVxq!y*Q}L`P+|%p)E`|*9S_JUABVnhg~H9-iLye|lo6Z{ysS$$6`x>CYQYuX zgLAe`@=%qT&*oz_mw+U&FdwGi7cJ<%4jO5H9;$n5t=x*9Z2%{Z{agy4_NWDDyDzwG z|7oh*FQ-?4=1l_2-nm7liu7rtSq}{uw=b5cFEj;>;2z3Z%j=qnsv`3o|Ae70JMOvb z+FTxr^gV^Ix!}GvH7n}&i-UrSOhKbKH5z^zl*1P?t%89ESr=dR$9NF!zb1o0Ti)C^ zo_+;a+w5qzfv$7C91N-?7za}{+xn!n6 zIR?wvMLub;YNcqDKs8@z3nV%vv`%X&4MPzUyk2OVMRZQ4b-9+fFf>Dg2f=_PI%!&< zwV1-t773mrvR_&=X(1X3ONQ_84w56} z3b7%0B6e^$*>1FUNzr&p)eA$HQ25cwp60k*G>svO*6|4x8=~g2U<~6m0_wiex=z40 zs<|Xhuro$7#6{U~G$A43S{zA6cN3zBWNL~a29Ycq0Wk*FE@z0DBwKt9BCKHt^C8xg ztnOoo4@ma7BgD5PTXO?qpa7*z0+|j<(CGE~Fn9N$$=`b8nqV)ySiKeQI0DwgM!5M4 zB(um)aE@Ysa|M+QN>N@27@-vw$^tc9@h;?A;|DTu!y_-}10a)Ry#0YWfkurt>;(nL zHNajl8;`uJhJv>wvo_s6sU@f}HV>KmccFk}A1IiJH(&l13UWwBT5T_QoZHd-@E9_f iT!IIV9s Date: Fri, 1 May 2026 23:02:00 +0200 Subject: [PATCH 24/55] [Cosmere] Changed font size so it doesn't extend out of the box --- .../java/leaf/cosmere/client/gui/SpiritwebHud.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/main/java/leaf/cosmere/client/gui/SpiritwebHud.java b/src/main/java/leaf/cosmere/client/gui/SpiritwebHud.java index 24f0bafe6..f5a2e7557 100644 --- a/src/main/java/leaf/cosmere/client/gui/SpiritwebHud.java +++ b/src/main/java/leaf/cosmere/client/gui/SpiritwebHud.java @@ -159,7 +159,18 @@ protected void renderText(GuiGraphics pGuiGraphics) { Font font = Minecraft.getInstance().font; String text = I18n.get(spiritweb.getSelectedManifestation().getTranslationKey()); - pGuiGraphics.drawString(font, text, getX() + getHeight() + 2, getY() + getHeight() / 2 - font.lineHeight/2, 0xFFDDDDDD); + float scale = 0.8f; + + pGuiGraphics.pose().pushPose(); + + float targetX = getX() + getHeight() + 2; + float targetY = getY() + (getHeight() / 2f) - ((font.lineHeight * scale) / 2f); + + pGuiGraphics.pose().translate(targetX, targetY, 0); + pGuiGraphics.pose().scale(scale, scale, 1.0f); + pGuiGraphics.drawString(font, text, 0, 0, 0xFFDDDDDD, false); + + pGuiGraphics.pose().popPose(); }); } From 068e715a4f52912cd81529e6bf44cca554cc7077 Mon Sep 17 00:00:00 2001 From: Gerbagel Date: Fri, 1 May 2026 23:10:06 +0200 Subject: [PATCH 25/55] [Cosmere] Open currently selected manifestation's page instead of always the 1st added --- .../java/leaf/cosmere/client/gui/SpiritwebMenu.java | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/main/java/leaf/cosmere/client/gui/SpiritwebMenu.java b/src/main/java/leaf/cosmere/client/gui/SpiritwebMenu.java index 55645129d..f8652d4d5 100644 --- a/src/main/java/leaf/cosmere/client/gui/SpiritwebMenu.java +++ b/src/main/java/leaf/cosmere/client/gui/SpiritwebMenu.java @@ -66,6 +66,10 @@ public void prepareClose() @Override protected void init() { + if (spiritweb.getSelectedManifestation() != null) + { + selectedManifestationType = spiritweb.getSelectedManifestation().getManifestationType(); + } AtomicInteger added = new AtomicInteger(0); int count = registry.getManifestationScreenMap().size(); for (int i = 0; i < Manifestations.ManifestationTypes.AVIAR.getID(); i++) @@ -83,8 +87,14 @@ protected void init() selectedManifestationScreen = registry.getManifestationScreenMap().get(maniType).get(); } }), maniType)); + added.set(added.get()+1); - if (added.get() == 1) + + if (selectedManifestationType == maniType) + { + selectedManifestationScreen = registry.getManifestationScreenMap().get(maniType).get(); + } + else if (added.get() == 1 && selectedManifestationScreen != null) { selectedManifestationType = maniType; selectedManifestationScreen = registry.getManifestationScreenMap().get(maniType).get(); From bfd514041f88b64da2ab819410979cfe58c5476a Mon Sep 17 00:00:00 2001 From: Gerbagel Date: Sat, 2 May 2026 00:07:33 +0200 Subject: [PATCH 26/55] [Feruchemy] Added info texts for submenu and charge to HUD Also RIP collectMenuInfo(), you were a real one --- .../client/gui/InnerRadialButton.java | 4 +- .../client/gui/OuterRadialButton.java | 4 +- .../AllomancySpiritwebSubmodule.java | 20 ----- .../AonDorSpiritwebSubmodule.java | 8 -- .../leaf/cosmere/api/ISpiritwebSubmodule.java | 4 - .../AwakeningSpiritwebSubmodule.java | 8 -- .../capabilities/ToolsSpiritwebSubmodule.java | 8 -- .../ExampleSpiritwebSubmodule.java | 8 -- .../feruchemy/client/gui/DiamondButton.java | 77 ++++++++++++++++++- .../client/utils/FeruchemyChargeThread.java | 47 +++++++++++ .../FeruchemySpiritwebSubmodule.java | 32 -------- .../manifestation/FeruchemyManifestation.java | 34 ++++++++ .../cosmere/client/gui/SpiritwebMenu.java | 4 +- .../SandmasterySpiritwebSubmodule.java | 19 ++--- .../SoulforgerySpiritwebSubmodule.java | 8 -- 15 files changed, 173 insertions(+), 112 deletions(-) diff --git a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java index 7f1c0c439..db82acec7 100644 --- a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java +++ b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java @@ -358,8 +358,10 @@ else if (segmentNr <= 7) text = String.format("%d:%02d:%02d", hours, minutes, seconds); else if (minutes > 0) text = String.format("%d:%02d", minutes, seconds); - else + else if (seconds > 0) text = String.format("%02d", seconds); + else + text = "Empty"; pGuiGraphics.drawString(font, text, x+5, y+10+font.lineHeight+5, 0xFFFFFFFF); } diff --git a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java index c95c77ae3..1c93721d3 100644 --- a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java +++ b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java @@ -364,8 +364,10 @@ else if (segmentNr <= 7) text = String.format("%d:%02d:%02d", hours, minutes, seconds); else if (minutes > 0) text = String.format("%d:%02d", minutes, seconds); - else + else if (seconds > 0) text = String.format("%02d", seconds); + else + text = "Empty"; pGuiGraphics.drawString(font, text, x+5, y+10+font.lineHeight+5, 0xFFFFFFFF); } diff --git a/src/allomancy/java/leaf/cosmere/allomancy/common/capabilities/AllomancySpiritwebSubmodule.java b/src/allomancy/java/leaf/cosmere/allomancy/common/capabilities/AllomancySpiritwebSubmodule.java index 4b33f61bf..265462a67 100644 --- a/src/allomancy/java/leaf/cosmere/allomancy/common/capabilities/AllomancySpiritwebSubmodule.java +++ b/src/allomancy/java/leaf/cosmere/allomancy/common/capabilities/AllomancySpiritwebSubmodule.java @@ -32,14 +32,11 @@ import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; import net.minecraft.world.phys.Vec3; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.client.event.RenderLevelStageEvent; import java.awt.*; import java.util.ArrayList; import java.util.Arrays; -import java.util.List; import java.util.Map; import java.util.function.Function; import java.util.stream.Collectors; @@ -310,23 +307,6 @@ public void renderWorldEffects(ISpiritweb spiritweb, RenderLevelStageEvent event } } - @Override - @OnlyIn(Dist.CLIENT) - public void collectMenuInfo(List m_infoText) - { - for (Metals.MetalType metalType : EnumUtils.METAL_TYPES) - { - int value = METALS_INGESTED.get(metalType); - - if (value > 0) - { - //todo localisation check - final String text = "A. " + metalType.getName() + ": " + value; - m_infoText.add(text); - } - } - } - @Override public void GiveStartingItem(Player player) { diff --git a/src/aondor/java/leaf/cosmere/aondor/common/capabilities/AonDorSpiritwebSubmodule.java b/src/aondor/java/leaf/cosmere/aondor/common/capabilities/AonDorSpiritwebSubmodule.java index a0fa4caf0..d655bee35 100644 --- a/src/aondor/java/leaf/cosmere/aondor/common/capabilities/AonDorSpiritwebSubmodule.java +++ b/src/aondor/java/leaf/cosmere/aondor/common/capabilities/AonDorSpiritwebSubmodule.java @@ -10,8 +10,6 @@ import net.minecraft.world.entity.player.Player; import net.minecraftforge.client.event.RenderLevelStageEvent; -import java.util.List; - public class AonDorSpiritwebSubmodule implements ISpiritwebSubmodule { @Override @@ -38,12 +36,6 @@ public void tickServer(ISpiritweb spiritweb) } - @Override - public void collectMenuInfo(List m_infoText) - { - - } - @Override public void renderWorldEffects(ISpiritweb spiritweb, RenderLevelStageEvent event) { diff --git a/src/api/java/leaf/cosmere/api/ISpiritwebSubmodule.java b/src/api/java/leaf/cosmere/api/ISpiritwebSubmodule.java index a0289c874..3b613b117 100644 --- a/src/api/java/leaf/cosmere/api/ISpiritwebSubmodule.java +++ b/src/api/java/leaf/cosmere/api/ISpiritwebSubmodule.java @@ -40,10 +40,6 @@ default void renderWorldEffects(ISpiritweb spiritweb, RenderLevelStageEvent even { } - default void collectMenuInfo(List m_infoText) - { - } - //give a random starting item from this power set default void GiveStartingItem(Player player) { diff --git a/src/awakening/java/leaf/cosmere/awakening/common/capabilities/AwakeningSpiritwebSubmodule.java b/src/awakening/java/leaf/cosmere/awakening/common/capabilities/AwakeningSpiritwebSubmodule.java index 999c6efd5..2203a4f83 100644 --- a/src/awakening/java/leaf/cosmere/awakening/common/capabilities/AwakeningSpiritwebSubmodule.java +++ b/src/awakening/java/leaf/cosmere/awakening/common/capabilities/AwakeningSpiritwebSubmodule.java @@ -10,8 +10,6 @@ import net.minecraft.world.entity.player.Player; import net.minecraftforge.client.event.RenderLevelStageEvent; -import java.util.List; - public class AwakeningSpiritwebSubmodule implements ISpiritwebSubmodule { @Override @@ -38,12 +36,6 @@ public void tickServer(ISpiritweb spiritweb) } - @Override - public void collectMenuInfo(List m_infoText) - { - - } - @Override public void renderWorldEffects(ISpiritweb spiritweb, RenderLevelStageEvent event) { diff --git a/src/cosmeretools/java/leaf/cosmere/tools/common/capabilities/ToolsSpiritwebSubmodule.java b/src/cosmeretools/java/leaf/cosmere/tools/common/capabilities/ToolsSpiritwebSubmodule.java index 3c026acb2..0bb2c5bb7 100644 --- a/src/cosmeretools/java/leaf/cosmere/tools/common/capabilities/ToolsSpiritwebSubmodule.java +++ b/src/cosmeretools/java/leaf/cosmere/tools/common/capabilities/ToolsSpiritwebSubmodule.java @@ -10,8 +10,6 @@ import net.minecraft.world.entity.player.Player; import net.minecraftforge.client.event.RenderLevelStageEvent; -import java.util.List; - public class ToolsSpiritwebSubmodule implements ISpiritwebSubmodule { @Override @@ -38,12 +36,6 @@ public void tickServer(ISpiritweb spiritweb) } - @Override - public void collectMenuInfo(List m_infoText) - { - - } - @Override public void renderWorldEffects(ISpiritweb spiritweb, RenderLevelStageEvent event) { diff --git a/src/example/java/leaf/cosmere/example/common/capabilities/ExampleSpiritwebSubmodule.java b/src/example/java/leaf/cosmere/example/common/capabilities/ExampleSpiritwebSubmodule.java index 8652f1cc1..219e75fd9 100644 --- a/src/example/java/leaf/cosmere/example/common/capabilities/ExampleSpiritwebSubmodule.java +++ b/src/example/java/leaf/cosmere/example/common/capabilities/ExampleSpiritwebSubmodule.java @@ -10,8 +10,6 @@ import net.minecraft.world.entity.player.Player; import net.minecraftforge.client.event.RenderLevelStageEvent; -import java.util.List; - public class ExampleSpiritwebSubmodule implements ISpiritwebSubmodule { @Override @@ -38,12 +36,6 @@ public void tickServer(ISpiritweb spiritweb) } - @Override - public void collectMenuInfo(List m_infoText) - { - - } - @Override public void renderWorldEffects(ISpiritweb spiritweb, RenderLevelStageEvent event) { diff --git a/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/DiamondButton.java b/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/DiamondButton.java index 2a9278614..c2aa1928c 100644 --- a/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/DiamondButton.java +++ b/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/DiamondButton.java @@ -15,9 +15,11 @@ import leaf.cosmere.common.network.packets.ChangeManifestationModeMessage; import leaf.cosmere.feruchemy.common.manifestation.FeruchemyManifestation; import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Font; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.Button; import net.minecraft.client.renderer.GameRenderer; +import net.minecraft.client.resources.language.I18n; import net.minecraft.network.chat.CommonComponents; import net.minecraft.resources.ResourceLocation; import org.joml.Matrix4f; @@ -49,6 +51,10 @@ protected void renderWidget(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, boolean isHover = isMouseOver(pMouseX, pMouseY); renderDiamond(pGuiGraphics, isHover); renderIcon(pGuiGraphics); + if (isHover && hasManifestation) + { + renderInfoBlock(pGuiGraphics); + } } @Override @@ -118,7 +124,11 @@ private void renderDiamond(GuiGraphics pGuiGraphics, boolean isHovered) if (manifestation instanceof FeruchemyManifestation feruchemyManifestation) { int mode = feruchemyManifestation.getMode(spiritweb); - float intensity = Math.min(Math.abs(mode) * 0.2f, 1.0f); // Cap intensity + float intensity = 0; + if (mode < 0) + intensity = Math.min(Math.abs(mode) * (1f/16f), 1.0f); + if (mode > 0) + intensity = Math.min(Math.abs(mode) * (1f/5f), 1.0f); if (mode > 0) { // Blend toward pure red @@ -259,6 +269,71 @@ private void renderIcon(GuiGraphics pGuiGraphics) RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f); } + private void renderInfoBlock(GuiGraphics pGuiGraphics) + { + Font font = Minecraft.getInstance().font; + int screenWidth = Minecraft.getInstance().getWindow().getGuiScaledWidth(); + int screenHeight = Minecraft.getInstance().getWindow().getGuiScaledHeight(); + int x = 0; + int y = 0; + int width = screenWidth / 4; + int height = screenHeight / 5; + int color = 0x99333333; + + boolean isLeft = getX() < screenWidth/2; + boolean isTop = getY() < screenHeight/2; + + if (!isLeft && !isTop) + { + // bottom right display + x = screenWidth - width - 10; + y = screenHeight - height - 10; + } + if (isLeft && !isTop) + { + // bottom left display + x = 10; + y = screenHeight - height - 10; + } + if (isLeft && isTop) + { + // top left display + x = 10; + y = 10; + } + if (!isLeft && isTop) + { + // top right display + x = screenWidth - width - 10; + y = 10; + } + + RenderSystem.disableCull(); + RenderSystem.enableBlend(); + RenderSystem.defaultBlendFunc(); + + pGuiGraphics.fill(x, y, x + width, y + height, color); + + String text = I18n.get(manifestation.getTranslationKey()); + pGuiGraphics.drawString(font, text, x+5, y+10, 0xFFFFFFFF); + + int seconds = manifestation.getInvestitureRemaining(spiritweb); + int hours = seconds / 3600; + int minutes = (seconds % 3600) / 60; + seconds = seconds % 60; + + if (hours > 0) + text = String.format("%d:%02d:%02d", hours, minutes, seconds); + else if (minutes > 0) + text = String.format("%d:%02d", minutes, seconds); + else if (seconds > 0) + text = String.format("%02d", seconds); + else + text = "Empty"; + + pGuiGraphics.drawString(font, text, x+5, y+10+font.lineHeight+5, 0xFFFFFFFF); + } + public float lerp(float start, float end, float pct) { return start + pct * (end - start); } diff --git a/src/feruchemy/java/leaf/cosmere/feruchemy/client/utils/FeruchemyChargeThread.java b/src/feruchemy/java/leaf/cosmere/feruchemy/client/utils/FeruchemyChargeThread.java index 47df8f6b3..347ff6cb8 100644 --- a/src/feruchemy/java/leaf/cosmere/feruchemy/client/utils/FeruchemyChargeThread.java +++ b/src/feruchemy/java/leaf/cosmere/feruchemy/client/utils/FeruchemyChargeThread.java @@ -24,6 +24,7 @@ public class FeruchemyChargeThread implements Runnable private static final Lock lock = new ReentrantLock(); private static FeruchemyChargeThread INSTANCE; private static final HashMap feruchemyChargeMap = new HashMap<>(); + private static final HashMap feruchemyMaxChargeMap = new HashMap<>(); static Thread t; static boolean isStopping = false; @@ -57,6 +58,27 @@ public HashMap getCharges() return new HashMap<>(); } + public HashMap getMaximumCharges() + { + HashMap retVal = new HashMap<>(); + try + { + if (lock.tryLock()) + { + retVal.putAll(feruchemyMaxChargeMap); + lock.unlock(); + } + } + catch (Exception e) + { + e.printStackTrace(); + retVal = new HashMap<>(); + lock.unlock(); + } + + return retVal; + } + public void start() { if (t == null || isStopping) @@ -83,6 +105,7 @@ public void run() // hashmap to keep track of each metal's f-charge in the inventory final HashMap metalmindCharges = new HashMap<>(); + final HashMap metalmindMaxCharges = new HashMap<>(); while (!isStopping) { @@ -108,6 +131,7 @@ public void run() } metalmindCharges.clear(); + metalmindMaxCharges.clear(); // all inventory metalminds are counted for (ItemStack stack : mc.player.getInventory().items) @@ -126,6 +150,16 @@ public void run() { metalmindCharges.put(item.getMetalType(), chargeToAdd); } + + Double maxToAdd = (double) item.getMaxCharge(stack); + if (metalmindMaxCharges.containsKey(item.getMetalType())) + { + metalmindMaxCharges.put(item.getMetalType(), metalmindMaxCharges.get(item.getMetalType()) + maxToAdd); + } + else + { + metalmindMaxCharges.put(item.getMetalType(), maxToAdd); + } } } } @@ -152,6 +186,16 @@ public void run() { metalmindCharges.put(item.getMetalType(), chargeToAdd); } + + Double maxToAdd = (double) item.getMaxCharge(stackInSlot); + if (metalmindMaxCharges.containsKey(item.getMetalType())) + { + metalmindMaxCharges.put(item.getMetalType(), metalmindMaxCharges.get(item.getMetalType()) + maxToAdd); + } + else + { + metalmindMaxCharges.put(item.getMetalType(), maxToAdd); + } } } } @@ -170,6 +214,9 @@ public void run() { feruchemyChargeMap.clear(); feruchemyChargeMap.putAll(metalmindCharges); + + feruchemyMaxChargeMap.clear(); + feruchemyMaxChargeMap.putAll(metalmindMaxCharges); lock.unlock(); } } diff --git a/src/feruchemy/java/leaf/cosmere/feruchemy/common/capabilities/FeruchemySpiritwebSubmodule.java b/src/feruchemy/java/leaf/cosmere/feruchemy/common/capabilities/FeruchemySpiritwebSubmodule.java index 24f9bbf53..b451f1038 100644 --- a/src/feruchemy/java/leaf/cosmere/feruchemy/common/capabilities/FeruchemySpiritwebSubmodule.java +++ b/src/feruchemy/java/leaf/cosmere/feruchemy/common/capabilities/FeruchemySpiritwebSubmodule.java @@ -14,29 +14,20 @@ import leaf.cosmere.client.gui.SpiritwebRegistry; import leaf.cosmere.feruchemy.client.gui.FeruchemySpiritwebMenu; import leaf.cosmere.common.registration.impl.AttributeRegistryObject; -import leaf.cosmere.feruchemy.client.utils.FeruchemyChargeThread; import leaf.cosmere.feruchemy.common.config.FeruchemyConfigs; import leaf.cosmere.feruchemy.common.items.NicrosilRingMetalmindItem; import leaf.cosmere.feruchemy.common.items.RingMetalmindItem; import leaf.cosmere.feruchemy.common.manifestation.FeruchemyManifestation; import leaf.cosmere.feruchemy.common.registries.FeruchemyAttributes; import leaf.cosmere.feruchemy.common.registries.FeruchemyItems; -import net.minecraft.client.Minecraft; import net.minecraft.world.entity.ai.attributes.Attribute; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.api.distmarker.OnlyIn; - -import java.util.HashMap; -import java.util.List; import java.util.stream.Collectors; public class FeruchemySpiritwebSubmodule implements ISpiritwebSubmodule { - private static final HashMap metalmindChargesMap = new HashMap<>(); - @Override public void GiveStartingItem(Player player) { @@ -77,29 +68,6 @@ public void drainInvestiture(ISpiritweb data, double strength) // remove the effects only? can we even detect that properly? } - @Override - @OnlyIn(Dist.CLIENT) - public void collectMenuInfo(List m_infoText) - { - if (Minecraft.getInstance().player != null && Minecraft.getInstance().player.tickCount % 2 == 1) // only do on odd tick - { - metalmindChargesMap.clear(); - metalmindChargesMap.putAll(FeruchemyChargeThread.getInstance().getCharges()); - } - - if (!metalmindChargesMap.isEmpty()) - { - for (Metals.MetalType metalType : metalmindChargesMap.keySet()) - { - // todo localisation check - final String text = "F. " + metalType.getName() + ": " + metalmindChargesMap.getOrDefault(metalType, 0D).intValue(); - m_infoText.add(text); - } - } - - ISpiritwebSubmodule.super.collectMenuInfo(m_infoText); - } - @Override public void registerMenu() { diff --git a/src/feruchemy/java/leaf/cosmere/feruchemy/common/manifestation/FeruchemyManifestation.java b/src/feruchemy/java/leaf/cosmere/feruchemy/common/manifestation/FeruchemyManifestation.java index b2f6a1f31..16193249a 100644 --- a/src/feruchemy/java/leaf/cosmere/feruchemy/common/manifestation/FeruchemyManifestation.java +++ b/src/feruchemy/java/leaf/cosmere/feruchemy/common/manifestation/FeruchemyManifestation.java @@ -13,13 +13,19 @@ import leaf.cosmere.api.manifestation.Manifestation; import leaf.cosmere.api.spiritweb.ISpiritweb; import leaf.cosmere.common.charge.MetalmindChargeHelper; +import leaf.cosmere.feruchemy.client.utils.FeruchemyChargeThread; import leaf.cosmere.feruchemy.common.registries.FeruchemyEffects; +import net.minecraft.client.Minecraft; import net.minecraft.util.Mth; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.item.ItemStack; +import java.util.HashMap; + public class FeruchemyManifestation extends Manifestation implements IHasMetalType { + private static final HashMap metalmindChargesMap = new HashMap<>(); + private static final HashMap metalmindMaxChargesMap = new HashMap<>(); protected final Metals.MetalType metalType; public FeruchemyManifestation(Metals.MetalType metalType) @@ -76,6 +82,34 @@ public void onModeChange(ISpiritweb data, int lastMode) } } + private void collectMenuInfo() + { + if (Minecraft.getInstance().player != null && Minecraft.getInstance().player.tickCount % 2 == 1) // only do on odd tick + { + metalmindChargesMap.clear(); + metalmindChargesMap.putAll(FeruchemyChargeThread.getInstance().getCharges()); + + metalmindMaxChargesMap.clear(); + metalmindMaxChargesMap.putAll(FeruchemyChargeThread.getInstance().getMaximumCharges()); + } + } + + @Override + public int getInvestitureRemaining(ISpiritweb spiritweb) + { + collectMenuInfo(); + return (int) Math.floor(metalmindChargesMap.getOrDefault(metalType, 0d)); + } + + @Override + public float getInvestitureHud(ISpiritweb spiritweb) + { + collectMenuInfo(); + double maximum = metalmindMaxChargesMap.getOrDefault(metalType, 0d); + double charge = metalmindChargesMap.getOrDefault(metalType, 0d); + return (float) (maximum/charge); + } + protected CosmereEffect getTappingEffect() { return FeruchemyEffects.TAPPING_EFFECTS.get(this.metalType).get(); diff --git a/src/main/java/leaf/cosmere/client/gui/SpiritwebMenu.java b/src/main/java/leaf/cosmere/client/gui/SpiritwebMenu.java index f8652d4d5..1ee066778 100644 --- a/src/main/java/leaf/cosmere/client/gui/SpiritwebMenu.java +++ b/src/main/java/leaf/cosmere/client/gui/SpiritwebMenu.java @@ -87,7 +87,7 @@ protected void init() selectedManifestationScreen = registry.getManifestationScreenMap().get(maniType).get(); } }), maniType)); - + added.set(added.get()+1); if (selectedManifestationType == maniType) @@ -113,7 +113,7 @@ public void tick() infoText.clear(); for (ISpiritwebSubmodule spiritwebSubmodule : spiritweb.getSubmodules().values()) { - spiritwebSubmodule.collectMenuInfo(infoText); + //spiritwebSubmodule.collectMenuInfo(infoText); } } super.tick(); diff --git a/src/sandmastery/java/leaf/cosmere/sandmastery/common/capabilities/SandmasterySpiritwebSubmodule.java b/src/sandmastery/java/leaf/cosmere/sandmastery/common/capabilities/SandmasterySpiritwebSubmodule.java index 03dcec335..c3ab8a946 100644 --- a/src/sandmastery/java/leaf/cosmere/sandmastery/common/capabilities/SandmasterySpiritwebSubmodule.java +++ b/src/sandmastery/java/leaf/cosmere/sandmastery/common/capabilities/SandmasterySpiritwebSubmodule.java @@ -32,11 +32,8 @@ import net.minecraft.world.entity.ai.attributes.AttributeModifier; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.api.distmarker.OnlyIn; import org.jetbrains.annotations.NotNull; -import java.util.List; import java.util.Random; import java.util.UUID; @@ -183,14 +180,14 @@ public void drainInvestiture(ISpiritweb data, double strength) // we could force it to turn off ribbons? } - @Override - @OnlyIn(Dist.CLIENT) - public void collectMenuInfo(List m_infoText) - { - //todo Localization - final String text = "Hydration: " + getHydrationLevel(); - m_infoText.add(text); - } +// @Override +// @OnlyIn(Dist.CLIENT) +// public void collectMenuInfo(List m_infoText) +// { +// //todo Localization +// final String text = "Hydration: " + getHydrationLevel(); +// m_infoText.add(text); +// } @Override public void GiveStartingItem(Player player) diff --git a/src/soulforgery/java/leaf/cosmere/soulforgery/common/capabilities/SoulforgerySpiritwebSubmodule.java b/src/soulforgery/java/leaf/cosmere/soulforgery/common/capabilities/SoulforgerySpiritwebSubmodule.java index e0ac9895f..9065988c1 100644 --- a/src/soulforgery/java/leaf/cosmere/soulforgery/common/capabilities/SoulforgerySpiritwebSubmodule.java +++ b/src/soulforgery/java/leaf/cosmere/soulforgery/common/capabilities/SoulforgerySpiritwebSubmodule.java @@ -10,8 +10,6 @@ import net.minecraft.world.entity.player.Player; import net.minecraftforge.client.event.RenderLevelStageEvent; -import java.util.List; - public class SoulforgerySpiritwebSubmodule implements ISpiritwebSubmodule { @Override @@ -38,12 +36,6 @@ public void tickServer(ISpiritweb spiritweb) } - @Override - public void collectMenuInfo(List m_infoText) - { - - } - @Override public void renderWorldEffects(ISpiritweb spiritweb, RenderLevelStageEvent event) { From b52951e39ca76b8c2678da8929cf8a281c2baae9 Mon Sep 17 00:00:00 2001 From: Gerbagel Date: Sat, 2 May 2026 00:17:27 +0200 Subject: [PATCH 27/55] [Feruchemy] Add rendering of usage to HUD --- .../leaf/cosmere/client/gui/SpiritwebHud.java | 60 ++++++++++++++++--- 1 file changed, 52 insertions(+), 8 deletions(-) diff --git a/src/main/java/leaf/cosmere/client/gui/SpiritwebHud.java b/src/main/java/leaf/cosmere/client/gui/SpiritwebHud.java index f5a2e7557..b688c2a2b 100644 --- a/src/main/java/leaf/cosmere/client/gui/SpiritwebHud.java +++ b/src/main/java/leaf/cosmere/client/gui/SpiritwebHud.java @@ -2,6 +2,7 @@ import com.mojang.blaze3d.systems.RenderSystem; import leaf.cosmere.api.IHasMetalType; +import leaf.cosmere.api.Manifestations; import leaf.cosmere.api.manifestation.Manifestation; import leaf.cosmere.common.cap.entity.SpiritwebCapability; import leaf.cosmere.common.config.CosmereConfigs; @@ -73,24 +74,63 @@ protected void renderUsage(GuiGraphics pGuiGraphics) { SpiritwebCapability.get(player).ifPresent(spiritweb -> { + Manifestation manifestation = spiritweb.getSelectedManifestation(); float r, g, b; float a = 0.2f; r = g = b = 1.0f; - int mode = spiritweb.getSelectedManifestation().getMode(spiritweb); + int mode = manifestation.getMode(spiritweb); - // todo this won't work for feruchemy... - if (mode > 0) + if (manifestation.getManifestationType() == Manifestations.ManifestationTypes.FERUCHEMY) { - g = g - 0.4f * mode; - b = b - 0.4f * mode; + float intensity = 0; + if (mode < 0) + intensity = Math.min(Math.abs(mode) * (1f/16f), 1.0f); + if (mode > 0) + intensity = Math.min(Math.abs(mode) * (1f/5f), 1.0f); + + if (mode > 0) + { + r = lerp(r, 1.0f, intensity); + g = lerp(g, 0.0f, intensity); + b = lerp(b, 0.0f, intensity); + } + else if (mode < 0) { + r = lerp(r, 0.0f, intensity); + g = lerp(g, 0.0f, intensity); + b = lerp(b, 1.0f, intensity); + } } - else if (mode < 0) + else if (manifestation.getManifestationType() == Manifestations.ManifestationTypes.ALLOMANCY) { - r = r - 0.4f * -mode; - g = g - 0.4f * -mode; + float intensity = Math.min(Math.abs(mode) * 0.2f, 1.0f); + + if (mode > 0) + { + r = lerp(r, 1.0f, intensity); + g = lerp(g, 0.0f, intensity); + b = lerp(b, 0.0f, intensity); + } + else if (mode < 0) + { + r = lerp(r, 0.0f, intensity); + g = lerp(g, 0.0f, intensity); + b = lerp(b, 1.0f, intensity); + } } + // todo this won't work for feruchemy... +// if (mode > 0) +// { +// g = g - 0.4f * mode; +// b = b - 0.4f * mode; +// } +// else if (mode < 0) +// { +// r = r - 0.4f * -mode; +// g = g - 0.4f * -mode; +// } + int color = toHex(new Color(r, g, b, a)); float width = getWidth(); @@ -181,4 +221,8 @@ protected int toHex(Color color) (color.getGreen() << 8) | color.getBlue(); } + + public float lerp(float start, float end, float pct) { + return start + pct * (end - start); + } } From 3f2dcd0bfaf41dc1d233cdd0e457b256b5febebf Mon Sep 17 00:00:00 2001 From: Gerbagel Date: Sat, 2 May 2026 00:50:51 +0200 Subject: [PATCH 28/55] [Allomancy] Added border to allomancy wheel --- .../client/gui/AllomancySpiritwebMenu.java | 33 ++++++++++++++++++ .../allomancy/textures/gui/allo_border.png | Bin 0 -> 3783 bytes 2 files changed, 33 insertions(+) create mode 100644 src/allomancy/resources/assets/allomancy/textures/gui/allo_border.png diff --git a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/AllomancySpiritwebMenu.java b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/AllomancySpiritwebMenu.java index 95118d2d0..6306afd91 100644 --- a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/AllomancySpiritwebMenu.java +++ b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/AllomancySpiritwebMenu.java @@ -1,5 +1,7 @@ package leaf.cosmere.allomancy.client.gui; +import com.mojang.blaze3d.systems.RenderSystem; +import leaf.cosmere.allomancy.common.Allomancy; import leaf.cosmere.api.Metals; import leaf.cosmere.client.gui.CosmereScreen; import leaf.cosmere.common.cap.entity.SpiritwebCapability; @@ -7,6 +9,8 @@ import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.player.LocalPlayer; import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import org.lwjgl.opengl.GL11; public class AllomancySpiritwebMenu extends CosmereScreen { @@ -69,5 +73,34 @@ protected void init() public void render(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) { super.render(pGuiGraphics, pMouseX, pMouseY, pPartialTick); + renderBorder(pGuiGraphics); + } + + private void renderBorder(GuiGraphics pGuiGraphics) + { + final ResourceLocation location = new ResourceLocation(Allomancy.MODID, "textures/gui/allo_border.png"); + + RenderSystem.setShaderTexture(0, location); + RenderSystem.enableBlend(); + RenderSystem.blendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, 1, 0); + RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f); + + final int diameter = Minecraft.getInstance().getWindow().getGuiScaledHeight() / 3 * 2 + 2; + final int x = width/2 - diameter/2, y = height/2 - diameter/2 + height/16; + final int iconSize = 256; + + pGuiGraphics.blit(location, + x, + y, + diameter, + diameter, + 0, + 0, + iconSize, + iconSize, + iconSize, + iconSize); + + RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f); } } diff --git a/src/allomancy/resources/assets/allomancy/textures/gui/allo_border.png b/src/allomancy/resources/assets/allomancy/textures/gui/allo_border.png new file mode 100644 index 0000000000000000000000000000000000000000..90c5d454451787745208dfaa01899481ab8beee7 GIT binary patch literal 3783 zcmW+(c|6nqAAf&#FvE-?H=`t_<{CNLm?N=5L?WA9QI3*hg%7d_sc-$tOj%Khg}#&y zU#+BzIckotQbNnsIU_ulTVh}FUZ02Dp8y7&SBNg)I< zGSVgZP*vm#b=cS48Ps;_OaOq(@^EqTOD+3+(c@0vbCnzdj=QfzD^M+#(eWb{x%W^} zJN@Unbu&dV-m=$e*v+qmnUpoOXT{|YGrsO^ReS$1{ZHdj#cMcu8HJdN{toOhBpXI{>;TB8cet5hHgEW(-BwL1AR*_^VPvjC0t&+ zbKg?$(@-^#^33cJleB783gW8F`-5LXpoFGVHpz86l~*Mh#Jjm!lD2^|W{r{M#_+Wr zk*OuZvG>bYE zjD=47^v9@g>_DeP`da?w3v}|YyvGEeM)nj|XaP<%>&~$AV)^=pDs5LsV4-~5Y|Sxc zL$1*_5N;To?mlp~Npl2EeL9%=Eo}~w%s@U7Z;Sn(e&~%g=O%{cmsO4+Y*mH`#O+r1 zpQqS@EqRm5zs#t9OuDX56Z%zAf_it+@}^6mHh)a}1)*RyLkR~*8P0EwlgB$*HLx2} zRGUz~(6HF1!bb_pmq{FL`d~)YJ-MZ#9H_dQmzZovidMKaKJw5Yd$anxqWA13kZzKC zIvbYuMR(ha+;|`c^BeUw`<)RS+VZ1jJ2c0zb9f&24m{Fl{Po$ zbbpHvtfP?TH6w`u6)Fq!joFvjnKiqG`vjaR@8fM<_<~eZg|ME;ov#l#T5Hbg394uR z7L0xREN`+76VwywJ?LW8mDyK7weLiu$&`45nHjIB?282M47cbz*=2 zjXLfY7ttPeRQ{=7!q_$U81k5%<&Fq40U z4GQv=kp?+?X=~FojD{f!G@ymZe zd3%o*Un$>-Ilm=t8=>Hir-t}x6bGD|<~Lm_zOK*sDEHZ}uX^7pwmGn5)@M-ktUNu#2=$SLG;nEXdHS_=`_kmqTEHtzjT!?|Jl_zr?1pBRI8UtRK;)7+Cq+5;Qyu*vJDGZq-lKe{UI zL101Z?OoSqxyhY&mJ?f8Sj=XqWS~qtsy}KBlY|CSy_A0z4X*ZF9dk3VGwL7G0j9#t z*;mi+Zhps!~6&3z+nCyvTPix^6n@PjdI zqfx~8!u%)j<`p{-C?C`icLJ8Vy*EPiPl}Le44>}~v !n{`&B&s76P^THf|bE&4^ z`0P6F7sn|@b7)2o$sQ-|txWdS0fo7`w(R&?D2@=#`-CB=BsPt) z5u;UJe3K_R2zaVxa@L1=j7@zzCtVlhfKUgQb&EH_ePVSD2V4%XHqV(x`M+OX`8@&{ zth$6&%b9+xH+}s{j)(y4a9QNHi&H#BpnldCHOc6)&X4|G4j3vh8ePE`ywmRD&Y7$Q zZWXquOH7fK-1s(4z^~^)C=TIG zWMS_9GUs7|^=lVJ$Xb_h>%1St!_*`O`5efIT#|uv|8+lyuYdM4@soL}9CgTHlE|wK zHS9fY3=9R)JQYJL%6c3iiJS$(V&Nwj1C@mZw+a+w-=BFd-I8)L%*B;QT%DFA$JtAMokm-I`w{_s4_uP z`|f4o0C!4DYR8s2Ui6Gi5-2&Etlc53%R<5>A;e*E|09UnIf+k@#C`yHhQD;nYy!w5 z*-Q16E-He8mtFi7W}*n6jHsU&)X+urUA{Q9BW9a4CBE)78NK&wHWB2#(niEBY1o3} z`xPOZOdTCCB4Wc_iaHJk=T?9o4mN1cl>%cNOntioHsWB0gY{i0tK2)(oAk8f838uW z`t{c`^5CMRB}p%3XZe(ao}d2jO-S_B8FOBK7SaHp5@5tG-qj&J-zinwRTp8N2vEEv z{YiY@2_&^_kn4@h3S2SbALM6zUJjCa?%lH;xGW8U46HcNSrygQ$5RrefKyU>|Gvfv z9mL?u4coi;>rc_B1r_W|z@@}7&JJaj2r%_AbrbmR)|JQ6rsE(p9q?rOe)}}O8?plj z8jmJZ!u}?AP4`__9S5X-UP(JqP>h5X&WRre<A7tsdg$)B6i>hfx2 z!Voi*nfP)2NjU=*Q(<``hCw3$<-*FoMGj_gjqjgm1Xb5fBEqjh4a{o;^=SP`Vfn59 zyslb~+C%jzrBqZg4g1cR0ujTSzNwlh$U`y+K3vKuUN9^T27E5FDBdN0sWAI|KDF!m zY#Jg^;r{MjQdi`A%Yd5wZx{RPCpjpqs|vtvpvXd7jAw``kiZbtZg-aZP{Wu`$gho$ zok5W_WzHHrQb$bN0^<>Jd@Hg3R6AfOgS3lrOIuFgrmtQ&&p(rapju&bHfvBt!L&7)4?fWOip{;S0 zzsG|cw(kHJ>r0$-hlo73AK;Tua5I(covHp){ea>5)_=<18YRCz{YB-G&p}s>VSkdQ zv*w)wf}txU*fq|XIwIL;{)X$tYU2ARBTASG#+EK&yD%=@d&uAwW1kBNX<0!tIQgy( z65LVL@KCj^-&eeJ`Dw)~0#%EFmBycuv%z0te@IYTe{lMPb5)E7Gbonf5>~uXFrh%5%Bl>O35j-g$qIq>~G~2gYGq zZb}ZI#tu)cc}W-8(EXd=Jg%36iF8lwd^oPv-Gf(?+LS9TW~B&eBvf(48qN%v)@Qm; z604)=FZUpN&8WqZF-z&R48*wErR&f}7SeujHOT>-#@d>0)*($7A7x>eSiz*)%OdSfoJ>Yd-I-BdnJD01L@J3aX9SB5fHy3ly#u zTd#jsrE8=uS(RJ32M(FtHT(UCG3SW0{ah@+yu<ihqgj+@O69DX0Ln2Vf&XXqmAF|g6P@ktf6+iO~(MGuj=FHv>%i1B@ez- zhCZrV*KpxR9Kulb04l&nzPPF^>e?7uODqX*F~{7JrK4rMV^3OMjpqpGYnkFv{#sE| z_>3eO+J?>Y<@<}857~`~cgE8LZeD=M6k6VQKYV4_XWpkjl2rQC^z6~( zj(ItQ(ehDpRXsT~3=5CpNifMKGi(r1#(cBV9aHtOdX>RRY{&GJQ4mdgk>a-pwtS~j z(raR!8K$%%FYgn(^rQuCTVc}e)r>Zw{Tnbt5Ge0JMq0fTmWvPun^7H95tnk~Ak^uC zua}L7R{H#Z3GD`dm>yO-U|FSS{UPa@0SML}MyJbxB~_+$TJRsUcYp>6%L1d`X91Vj z4d_)P*(OhY6k(HvA^|#Wc;YE9n{y694XN3EmxQh=^&|qn+q-k+{T{uka3;6jl7UNc z_KBCZeD40JN5js-o`fDdW{Z|N3LH+?O!zMIIC7T=FjfYwG1Ruu_3sXbp972=7YsL! zhsU&-2Oj(uBK4`W(Rc64-}o~eedkvI8Vsg!m4e5M8Z)wNtDW3r1z#lQvv Date: Sat, 2 May 2026 01:49:39 +0200 Subject: [PATCH 29/55] [Sandmastery] Sandmastery menu --- .../client/gui/AllomancySpiritwebMenu.java | 3 - .../client/gui/FeruchemySpiritwebMenu.java | 4 +- .../cosmere/client/gui/SpiritwebMenu.java | 21 +- .../sandmastery/client/gui/RadialButton.java | 227 ++++++++++++++++++ .../client/gui/SandmasterySpiritwebMenu.java | 32 +++ .../SandmasterySpiritwebSubmodule.java | 1 + .../client/gui/SurgebindingSpiritwebMenu.java | 28 +++ .../SurgebindingSpiritwebSubmodule.java | 7 + 8 files changed, 299 insertions(+), 24 deletions(-) create mode 100644 src/sandmastery/java/leaf/cosmere/sandmastery/client/gui/RadialButton.java create mode 100644 src/surgebinding/java/leaf/cosmere/surgebinding/client/gui/SurgebindingSpiritwebMenu.java diff --git a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/AllomancySpiritwebMenu.java b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/AllomancySpiritwebMenu.java index 6306afd91..048d575d9 100644 --- a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/AllomancySpiritwebMenu.java +++ b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/AllomancySpiritwebMenu.java @@ -19,15 +19,12 @@ public AllomancySpiritwebMenu() { super(Component.literal("Allomancy")); player = Minecraft.getInstance().player; - init(); } @Override protected void init() { super.init(); - this.width = Minecraft.getInstance().getWindow().getGuiScaledWidth(); - this.height = Minecraft.getInstance().getWindow().getGuiScaledHeight(); SpiritwebCapability.get(player).ifPresent( (iSpiritweb -> { int circleCenterX = width/2; diff --git a/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/FeruchemySpiritwebMenu.java b/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/FeruchemySpiritwebMenu.java index 64a961c11..9c66741f0 100644 --- a/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/FeruchemySpiritwebMenu.java +++ b/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/FeruchemySpiritwebMenu.java @@ -21,14 +21,12 @@ public FeruchemySpiritwebMenu() { super(Component.literal("Feruchemy")); player = Minecraft.getInstance().player; - init(); + //init(); } @Override protected void init() { - this.width = Minecraft.getInstance().getWindow().getGuiScaledWidth(); - this.height = Minecraft.getInstance().getWindow().getGuiScaledHeight(); distance = this.height / 6; final float topLeftRot = 0.f; final float topRightRot = QUARTER_PI_F; diff --git a/src/main/java/leaf/cosmere/client/gui/SpiritwebMenu.java b/src/main/java/leaf/cosmere/client/gui/SpiritwebMenu.java index 1ee066778..30e2fa273 100644 --- a/src/main/java/leaf/cosmere/client/gui/SpiritwebMenu.java +++ b/src/main/java/leaf/cosmere/client/gui/SpiritwebMenu.java @@ -5,7 +5,6 @@ package leaf.cosmere.client.gui; import com.google.common.base.Stopwatch; -import leaf.cosmere.api.ISpiritwebSubmodule; import leaf.cosmere.api.Manifestations; import leaf.cosmere.api.manifestation.Manifestation; import leaf.cosmere.api.math.MathHelper; @@ -19,7 +18,6 @@ import net.minecraft.network.chat.Component; import org.jetbrains.annotations.NotNull; -import java.util.ArrayList; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; @@ -32,7 +30,6 @@ public class SpiritwebMenu extends Screen private CosmereScreen selectedManifestationScreen = null; public static Manifestations.ManifestationTypes selectedManifestationType = Manifestations.ManifestationTypes.NONE; public static Manifestation selectedManifestation = null; - public static ArrayList infoText = new ArrayList<>(); public SpiritwebMenu(Component pTitle, ISpiritweb spiritweb) { @@ -85,6 +82,7 @@ protected void init() { selectedManifestationType = maniType; selectedManifestationScreen = registry.getManifestationScreenMap().get(maniType).get(); + selectedManifestationScreen.init(Minecraft.getInstance(), this.width, this.height); } }), maniType)); @@ -102,21 +100,8 @@ else if (added.get() == 1 && selectedManifestationScreen != null) } }); } - } - - @Override - public void tick() - { - assert Minecraft.getInstance().player != null; - if (Minecraft.getInstance().player.tickCount % 20 == 0) - { - infoText.clear(); - for (ISpiritwebSubmodule spiritwebSubmodule : spiritweb.getSubmodules().values()) - { - //spiritwebSubmodule.collectMenuInfo(infoText); - } - } - super.tick(); + if (selectedManifestationScreen != null) + selectedManifestationScreen.init(Minecraft.getInstance(), this.width, this.height); } @Override diff --git a/src/sandmastery/java/leaf/cosmere/sandmastery/client/gui/RadialButton.java b/src/sandmastery/java/leaf/cosmere/sandmastery/client/gui/RadialButton.java new file mode 100644 index 000000000..ad9493c90 --- /dev/null +++ b/src/sandmastery/java/leaf/cosmere/sandmastery/client/gui/RadialButton.java @@ -0,0 +1,227 @@ +package leaf.cosmere.sandmastery.client.gui; + +import com.mojang.blaze3d.systems.RenderSystem; +import com.mojang.blaze3d.vertex.BufferBuilder; +import com.mojang.blaze3d.vertex.DefaultVertexFormat; +import com.mojang.blaze3d.vertex.Tesselator; +import com.mojang.blaze3d.vertex.VertexFormat; +import leaf.cosmere.api.manifestation.Manifestation; +import leaf.cosmere.client.gui.SpiritwebMenu; +import leaf.cosmere.common.Cosmere; +import leaf.cosmere.common.network.packets.ChangeManifestationModeMessage; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.components.Button; +import net.minecraft.client.renderer.GameRenderer; +import net.minecraft.network.chat.CommonComponents; +import net.minecraft.resources.ResourceLocation; +import org.joml.Matrix4f; +import org.lwjgl.opengl.GL11; + +public class RadialButton extends Button +{ + private final int radius, centerX, centerY, segmentNr; + private final float startAngle; + private final float endAngle; + private final Manifestation manifestation; + protected RadialButton(int pX, int pY, int radius, int segmentNr, Manifestation manifestation) + { + super(pX, pY, 16, 16, CommonComponents.EMPTY, (button) -> { }, DEFAULT_NARRATION); + this.manifestation = manifestation; + this.radius = radius; + this.segmentNr = segmentNr; + centerX = pX; + centerY = pY; + + float fifthCircle = (float) Math.toRadians(360d/5d); + startAngle = (float) (fifthCircle*segmentNr); + endAngle = startAngle + fifthCircle; + } + + @Override + public boolean isMouseOver(double mouseX, double mouseY) + { + boolean retVal; + double distanceX = mouseX - centerX; + double distanceY = mouseY - centerY; + double dSqr = distanceX * distanceX + distanceY * distanceY; + + if (dSqr > radius * radius) + { + return false; + } + + double angle = Math.atan2(distanceY, distanceX); + + if (angle < 0) { + angle += 2 * Math.PI; + } + + double start = normalizeAngle(startAngle); + double end = normalizeAngle(endAngle); + angle = normalizeAngle(angle); + + if (start <= end) + { + retVal = angle >= start && angle <= end; + } + else + { + retVal = angle >= start || angle <= end; + } + + if (retVal) + { + SpiritwebMenu.selectedManifestation = manifestation; + } + + + return retVal; + } + + @Override + public boolean mouseClicked(double pMouseX, double pMouseY, int pButton) + { + if (isMouseOver(pMouseX, pMouseY)) + { + if (pButton == 0) + Cosmere.packetHandler().sendToServer(new ChangeManifestationModeMessage(manifestation, 1)); + else + Cosmere.packetHandler().sendToServer(new ChangeManifestationModeMessage(manifestation, -1)); + } + return super.mouseClicked(pMouseX, pMouseY, pButton); + } + + @Override + public void render(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) + { + boolean isHovered = isMouseOver(pMouseX, pMouseY); + renderRadial(pGuiGraphics, isHovered); + renderIcon(pGuiGraphics); + } + + private void renderRadial(GuiGraphics pGuiGraphics, boolean isHovered) + { + float r = 61/255.f, g = 70/255.f, b = 76/255.f; + float a = 1f; + + if (isHovered) + { + r *= 1.1f; + g *= 1.1f; + b *= 1.1f; + } + + float radsPerSegment = (float) Math.PI * 2 / 5; + float startAngle = segmentNr * radsPerSegment; + float radiusSq = radius * radius; + + int pixelSize = 1; + + RenderSystem.disableCull(); + RenderSystem.enableBlend(); + RenderSystem.defaultBlendFunc(); + RenderSystem.setShader(GameRenderer::getPositionColorShader); + Matrix4f pose = pGuiGraphics.pose().last().pose(); + + Tesselator tess = Tesselator.getInstance(); + BufferBuilder buf = tess.getBuilder(); + + buf.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR); + + for (int x = -radius; x <= radius; x += pixelSize) + { + for (int y = -radius; y <= radius; y += pixelSize) + { + float pixelCenterX = x + (pixelSize / 2f); + float pixelCenterY = y + (pixelSize / 2f); + + float distSq = pixelCenterX * pixelCenterX + pixelCenterY * pixelCenterY; + + if (distSq <= radiusSq) + { + float angle = (float) Math.atan2(pixelCenterY, pixelCenterX); + if (angle < 0) angle += (float) (Math.PI * 2); + + float diff = angle - startAngle; + if (diff < 0) diff += (float) (Math.PI * 2); + + if (diff < radsPerSegment) + { + float px = centerX + x; + float py = centerY + y; + + buf.vertex(pose, px, py, 0).color(r, g, b, a).endVertex(); + buf.vertex(pose, px, py + pixelSize, 0).color(r, g, b, a).endVertex(); + buf.vertex(pose, px + pixelSize, py + pixelSize, 0).color(r, g, b, a).endVertex(); + buf.vertex(pose, px + pixelSize, py, 0).color(r, g, b, a).endVertex(); + } + } + } + } + + tess.end(); + RenderSystem.disableBlend(); + } + + private void renderIcon(GuiGraphics pGuiGraphics) + { + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.setLength(0); + stringBuilder.append("textures/icon/") + .append(manifestation.getManifestationType().getName()) + .append("/.png"); + + final ResourceLocation location = new ResourceLocation(manifestation.getRegistryName().getNamespace(), stringBuilder.toString()); + float alpha = 1.0f; + RenderSystem.setShaderTexture(0, location); + RenderSystem.enableBlend(); + RenderSystem.blendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, 1, 0); + + double midAngle = (startAngle + endAngle) / 2; + double midRadius = (radius) / 1.5; + int iconSize = width-2; + int posX = centerX + (int)(Math.cos(midAngle) * midRadius) - iconSize/2; + int posY = centerY + (int)(Math.sin(midAngle) * midRadius) - iconSize/2; + + RenderSystem.setShaderColor(0f, 0f, 0f, alpha); + pGuiGraphics.blit(location, + posX+1, + posY+1, + iconSize, + iconSize, + 0, + 0, + width, + height, + width, + height); + + RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, alpha); + pGuiGraphics.blit(location, + posX, + posY, + iconSize, + iconSize, + 0, + 0, + width, + height, + width, + height); + + RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f); + } + + private double normalizeAngle(double angle) + { + if (angle != 0) + { + angle = angle % (2 * Math.PI); + if (angle < 0) + { + angle += 2 * Math.PI; + } + } + return angle; + } +} diff --git a/src/sandmastery/java/leaf/cosmere/sandmastery/client/gui/SandmasterySpiritwebMenu.java b/src/sandmastery/java/leaf/cosmere/sandmastery/client/gui/SandmasterySpiritwebMenu.java index 04d4cfb5d..baa0cb226 100644 --- a/src/sandmastery/java/leaf/cosmere/sandmastery/client/gui/SandmasterySpiritwebMenu.java +++ b/src/sandmastery/java/leaf/cosmere/sandmastery/client/gui/SandmasterySpiritwebMenu.java @@ -1,12 +1,44 @@ package leaf.cosmere.sandmastery.client.gui; +import leaf.cosmere.api.Manifestations; +import leaf.cosmere.api.manifestation.Manifestation; import leaf.cosmere.client.gui.CosmereScreen; +import leaf.cosmere.common.cap.entity.SpiritwebCapability; +import net.minecraft.client.Minecraft; +import net.minecraft.client.player.LocalPlayer; import net.minecraft.network.chat.Component; +import java.util.List; + public class SandmasterySpiritwebMenu extends CosmereScreen { + final LocalPlayer player; public SandmasterySpiritwebMenu() { super(Component.literal("Sandmastery")); + player = Minecraft.getInstance().player; + } + + @Override + protected void init() + { + super.init(); + + int centerX = width/2; + int centerY = height/2 + height/16; + + SpiritwebCapability.get(player).ifPresent( (spiritweb -> { + final List availableManifestations = spiritweb.getAvailableManifestations(); + + int i = 0; + for (Manifestation mani : availableManifestations) + { + if (mani.getManifestationType() == Manifestations.ManifestationTypes.SANDMASTERY) + { + addRenderableWidget(new RadialButton(centerX, centerY, height/3, i, mani)); + i++; + } + } + })); } } diff --git a/src/sandmastery/java/leaf/cosmere/sandmastery/common/capabilities/SandmasterySpiritwebSubmodule.java b/src/sandmastery/java/leaf/cosmere/sandmastery/common/capabilities/SandmasterySpiritwebSubmodule.java index c3ab8a946..cb60beee7 100644 --- a/src/sandmastery/java/leaf/cosmere/sandmastery/common/capabilities/SandmasterySpiritwebSubmodule.java +++ b/src/sandmastery/java/leaf/cosmere/sandmastery/common/capabilities/SandmasterySpiritwebSubmodule.java @@ -208,6 +208,7 @@ public void GiveStartingItem(Player player, Manifestation manifestation) @Override public void registerMenu() { + // todo: add check for if actually has Sandmastery SpiritwebRegistry.getInstance().register(Manifestations.ManifestationTypes.SANDMASTERY, SandmasterySpiritwebMenu::new); } diff --git a/src/surgebinding/java/leaf/cosmere/surgebinding/client/gui/SurgebindingSpiritwebMenu.java b/src/surgebinding/java/leaf/cosmere/surgebinding/client/gui/SurgebindingSpiritwebMenu.java new file mode 100644 index 000000000..a9d024f2e --- /dev/null +++ b/src/surgebinding/java/leaf/cosmere/surgebinding/client/gui/SurgebindingSpiritwebMenu.java @@ -0,0 +1,28 @@ +package leaf.cosmere.surgebinding.client.gui; + +import leaf.cosmere.client.gui.CosmereScreen; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Font; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.network.chat.Component; + +public class SurgebindingSpiritwebMenu extends CosmereScreen +{ + public SurgebindingSpiritwebMenu() + { + super(Component.literal("Surgebinding")); + } + + @Override + protected void init() + { + super.init(); + } + + @Override + public void render(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) + { + Font font = Minecraft.getInstance().font; + pGuiGraphics.drawString(font, "Surgebinding", width/2, height/2, 0xFFFFFFFF); + } +} diff --git a/src/surgebinding/java/leaf/cosmere/surgebinding/common/capabilities/SurgebindingSpiritwebSubmodule.java b/src/surgebinding/java/leaf/cosmere/surgebinding/common/capabilities/SurgebindingSpiritwebSubmodule.java index 7fc1b363b..dfc1601c7 100644 --- a/src/surgebinding/java/leaf/cosmere/surgebinding/common/capabilities/SurgebindingSpiritwebSubmodule.java +++ b/src/surgebinding/java/leaf/cosmere/surgebinding/common/capabilities/SurgebindingSpiritwebSubmodule.java @@ -8,7 +8,9 @@ import leaf.cosmere.api.Manifestations; import leaf.cosmere.api.helpers.EffectsHelper; import leaf.cosmere.api.spiritweb.ISpiritweb; +import leaf.cosmere.client.gui.SpiritwebRegistry; import leaf.cosmere.common.items.CapWrapper; +import leaf.cosmere.surgebinding.client.gui.SurgebindingSpiritwebMenu; import leaf.cosmere.surgebinding.common.capabilities.ideals.RadiantStateManager; import leaf.cosmere.surgebinding.common.config.SurgebindingConfigs; import leaf.cosmere.surgebinding.common.items.GemstoneItem; @@ -207,6 +209,11 @@ public void drainInvestiture(ISpiritweb data, double strength) stormlightStored = (int) (stormlightStored * 0.1f); } + @Override + public void registerMenu() + { + SpiritwebRegistry.getInstance().register(Manifestations.ManifestationTypes.SURGEBINDING, SurgebindingSpiritwebMenu::new); + } private void requestGemStormlight(ItemStack item, int amountDrawn) { From c31f06ca646303335069800653ac5360f57aa4b4 Mon Sep 17 00:00:00 2001 From: Gerbagel Date: Sat, 2 May 2026 02:26:40 +0200 Subject: [PATCH 30/55] [Surgebinding] Added entire menu --- .../sandmastery/client/gui/RadialButton.java | 11 +- .../surgebinding/client/gui/CircleButton.java | 184 ++++++++++++++++++ .../client/gui/SurgebindingSpiritwebMenu.java | 28 ++- 3 files changed, 210 insertions(+), 13 deletions(-) create mode 100644 src/surgebinding/java/leaf/cosmere/surgebinding/client/gui/CircleButton.java diff --git a/src/sandmastery/java/leaf/cosmere/sandmastery/client/gui/RadialButton.java b/src/sandmastery/java/leaf/cosmere/sandmastery/client/gui/RadialButton.java index ad9493c90..db6344183 100644 --- a/src/sandmastery/java/leaf/cosmere/sandmastery/client/gui/RadialButton.java +++ b/src/sandmastery/java/leaf/cosmere/sandmastery/client/gui/RadialButton.java @@ -7,8 +7,6 @@ import com.mojang.blaze3d.vertex.VertexFormat; import leaf.cosmere.api.manifestation.Manifestation; import leaf.cosmere.client.gui.SpiritwebMenu; -import leaf.cosmere.common.Cosmere; -import leaf.cosmere.common.network.packets.ChangeManifestationModeMessage; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.Button; import net.minecraft.client.renderer.GameRenderer; @@ -81,14 +79,7 @@ public boolean isMouseOver(double mouseX, double mouseY) @Override public boolean mouseClicked(double pMouseX, double pMouseY, int pButton) { - if (isMouseOver(pMouseX, pMouseY)) - { - if (pButton == 0) - Cosmere.packetHandler().sendToServer(new ChangeManifestationModeMessage(manifestation, 1)); - else - Cosmere.packetHandler().sendToServer(new ChangeManifestationModeMessage(manifestation, -1)); - } - return super.mouseClicked(pMouseX, pMouseY, pButton); + return false; } @Override diff --git a/src/surgebinding/java/leaf/cosmere/surgebinding/client/gui/CircleButton.java b/src/surgebinding/java/leaf/cosmere/surgebinding/client/gui/CircleButton.java new file mode 100644 index 000000000..d2a9965b5 --- /dev/null +++ b/src/surgebinding/java/leaf/cosmere/surgebinding/client/gui/CircleButton.java @@ -0,0 +1,184 @@ +package leaf.cosmere.surgebinding.client.gui; + +import com.mojang.blaze3d.systems.RenderSystem; +import com.mojang.blaze3d.vertex.BufferBuilder; +import com.mojang.blaze3d.vertex.DefaultVertexFormat; +import com.mojang.blaze3d.vertex.Tesselator; +import com.mojang.blaze3d.vertex.VertexFormat; +import leaf.cosmere.api.manifestation.Manifestation; +import leaf.cosmere.api.spiritweb.ISpiritweb; +import leaf.cosmere.client.gui.SpiritwebMenu; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Font; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.components.Button; +import net.minecraft.client.renderer.GameRenderer; +import net.minecraft.client.resources.language.I18n; +import net.minecraft.network.chat.CommonComponents; +import net.minecraft.resources.ResourceLocation; +import org.joml.Matrix4f; +import org.lwjgl.opengl.GL11; + +public class CircleButton extends Button +{ + final ISpiritweb spiritweb; + final Manifestation manifestation; + final int centerX, centerY; + final int radius; + + protected CircleButton(int pX, int pY, int radius, ISpiritweb spiritweb, Manifestation manifestation) + { + super(pX, pY, radius, radius, CommonComponents.EMPTY, (button) -> { }, DEFAULT_NARRATION); + + this.spiritweb = spiritweb; + this.centerX = pX; + this.centerY = pY; + this.radius = radius; + this.manifestation = manifestation; + } + + @Override + public boolean isMouseOver(double mouseX, double mouseY) { + double distanceX = mouseX - centerX; + double distanceY = mouseY - centerY; + + if ((distanceX * distanceX + distanceY * distanceY) <= (radius * radius)) { + SpiritwebMenu.selectedManifestation = manifestation; + return true; + } + + return false; + } + + @Override + public boolean mouseClicked(double pMouseX, double pMouseY, int pButton) + { + return false; + } + + @Override + public void render(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) + { + boolean isHovered = isMouseOver(pMouseX, pMouseY); + renderCircle(pGuiGraphics, isHovered); + renderIcon(pGuiGraphics); + if (isHovered) + renderText(pGuiGraphics); + } + + private void renderCircle(GuiGraphics pGuiGraphics, boolean isHovered) + { + float r = 61/255.f, g = 70/255.f, b = 76/255.f; + float a = 1f; + + if (isHovered) { + r *= 1.1f; + g *= 1.1f; + b *= 1.1f; + } + + float radiusSq = radius * radius; + int pixelSize = 1; + + RenderSystem.disableCull(); + RenderSystem.enableBlend(); + RenderSystem.defaultBlendFunc(); + RenderSystem.setShader(GameRenderer::getPositionColorShader); + Matrix4f pose = pGuiGraphics.pose().last().pose(); + + Tesselator tess = Tesselator.getInstance(); + BufferBuilder buf = tess.getBuilder(); + + buf.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR); + + for (int x = -radius; x <= radius; x += pixelSize) { + for (int y = -radius; y <= radius; y += pixelSize) { + float pixelCenterX = x + (pixelSize / 2f); + float pixelCenterY = y + (pixelSize / 2f); + + if ((pixelCenterX * pixelCenterX + pixelCenterY * pixelCenterY) <= radiusSq) { + float px = centerX + x; + float py = centerY + y; + + buf.vertex(pose, px, py, 0).color(r, g, b, a).endVertex(); + buf.vertex(pose, px, py + pixelSize, 0).color(r, g, b, a).endVertex(); + buf.vertex(pose, px + pixelSize, py + pixelSize, 0).color(r, g, b, a).endVertex(); + buf.vertex(pose, px + pixelSize, py, 0).color(r, g, b, a).endVertex(); + } + } + } + + tess.end(); + RenderSystem.disableBlend(); + } + + public void renderIcon(GuiGraphics pGuiGraphics) + { + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.setLength(0); + stringBuilder.append("textures/icon/") + .append(manifestation.getManifestationType().getName()) + .append("/"); + + stringBuilder.append(manifestation.getName()); + stringBuilder.append(".png"); + + final ResourceLocation location = new ResourceLocation(manifestation.getRegistryName().getNamespace(), stringBuilder.toString()); + float alpha = 1.0f; + RenderSystem.setShaderTexture(0, location); + RenderSystem.enableBlend(); + RenderSystem.blendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, 1, 0); + + int iconSize = width-2; + int posX = centerX - iconSize/2; + int posY = centerY - iconSize/2; + + RenderSystem.setShaderColor(0f, 0f, 0f, alpha); + pGuiGraphics.blit(location, + posX+1, + posY+1, + iconSize, + iconSize, + 0, + 0, + width, + height, + width, + height); + + RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, alpha); + pGuiGraphics.blit(location, + posX, + posY, + iconSize, + iconSize, + 0, + 0, + width, + height, + width, + height); + + RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f); + } + + private void renderText(GuiGraphics pGuiGraphics) + { + Font font = Minecraft.getInstance().font; + String text = I18n.get(manifestation.getTranslationKey()); + int x; + int y = getY(); + int windowWidth = Minecraft.getInstance().getWindow().getGuiScaledWidth(); + + if (getX() < windowWidth/2) + { + x = getX() - radius - 5 - font.width(text); + } + else + { + x = getX() + radius + 5; + } + + pGuiGraphics.drawString(font, text, x, y-font.lineHeight/2, 0xFFFFFFFF); + } +} diff --git a/src/surgebinding/java/leaf/cosmere/surgebinding/client/gui/SurgebindingSpiritwebMenu.java b/src/surgebinding/java/leaf/cosmere/surgebinding/client/gui/SurgebindingSpiritwebMenu.java index a9d024f2e..1f2435bcb 100644 --- a/src/surgebinding/java/leaf/cosmere/surgebinding/client/gui/SurgebindingSpiritwebMenu.java +++ b/src/surgebinding/java/leaf/cosmere/surgebinding/client/gui/SurgebindingSpiritwebMenu.java @@ -1,28 +1,50 @@ package leaf.cosmere.surgebinding.client.gui; +import leaf.cosmere.api.Manifestations; +import leaf.cosmere.api.manifestation.Manifestation; import leaf.cosmere.client.gui.CosmereScreen; +import leaf.cosmere.common.cap.entity.SpiritwebCapability; import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.Font; import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.player.LocalPlayer; import net.minecraft.network.chat.Component; +import java.util.List; + public class SurgebindingSpiritwebMenu extends CosmereScreen { + final LocalPlayer player; public SurgebindingSpiritwebMenu() { super(Component.literal("Surgebinding")); + player = Minecraft.getInstance().player; } @Override protected void init() { super.init(); + + int radius = height/16; + + SpiritwebCapability.get(player).ifPresent( (spiritweb -> { + final List availableManifestations = spiritweb.getAvailableManifestations(); + + int i = 0; + for (Manifestation mani : availableManifestations) + { + if (mani.getManifestationType() == Manifestations.ManifestationTypes.SURGEBINDING) + { + addRenderableWidget(new CircleButton((int) (width/2f - radius*1.5 + (radius*3) * i), height/2, radius, spiritweb, mani)); + i++; + } + } + })); } @Override public void render(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) { - Font font = Minecraft.getInstance().font; - pGuiGraphics.drawString(font, "Surgebinding", width/2, height/2, 0xFFFFFFFF); + super.render(pGuiGraphics, pMouseX, pMouseY, pPartialTick); } } From ecb9199f136e2f14ed9bae5991265d41be916690 Mon Sep 17 00:00:00 2001 From: Gerbagel Date: Sat, 2 May 2026 02:37:15 +0200 Subject: [PATCH 31/55] [Sandmastery] Added hover text --- .../sandmastery/client/gui/RadialButton.java | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/sandmastery/java/leaf/cosmere/sandmastery/client/gui/RadialButton.java b/src/sandmastery/java/leaf/cosmere/sandmastery/client/gui/RadialButton.java index db6344183..3a2f6c920 100644 --- a/src/sandmastery/java/leaf/cosmere/sandmastery/client/gui/RadialButton.java +++ b/src/sandmastery/java/leaf/cosmere/sandmastery/client/gui/RadialButton.java @@ -7,9 +7,12 @@ import com.mojang.blaze3d.vertex.VertexFormat; import leaf.cosmere.api.manifestation.Manifestation; import leaf.cosmere.client.gui.SpiritwebMenu; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Font; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.Button; import net.minecraft.client.renderer.GameRenderer; +import net.minecraft.client.resources.language.I18n; import net.minecraft.network.chat.CommonComponents; import net.minecraft.resources.ResourceLocation; import org.joml.Matrix4f; @@ -88,6 +91,8 @@ public void render(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPa boolean isHovered = isMouseOver(pMouseX, pMouseY); renderRadial(pGuiGraphics, isHovered); renderIcon(pGuiGraphics); + if (isHovered) + renderInfoBlock(pGuiGraphics); } private void renderRadial(GuiGraphics pGuiGraphics, boolean isHovered) @@ -203,6 +208,25 @@ private void renderIcon(GuiGraphics pGuiGraphics) RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f); } + private void renderInfoBlock(GuiGraphics pGuiGraphics) + { + Font font = Minecraft.getInstance().font; + float radsPerSegment = (float) (Math.PI * 2 / 5); + float midAngle = (segmentNr * radsPerSegment) + (radsPerSegment / 2f); + + int padding = 15; + float textOffsetDist = radius + padding; + + int textCenterX = (int) (centerX + Math.cos(midAngle) * textOffsetDist); + int textCenterY = (int) (centerY + Math.sin(midAngle) * textOffsetDist); + + int drawY = textCenterY - (font.lineHeight / 2); + + String text = I18n.get(manifestation.getTranslationKey()).replace("Sand Mastery ", ""); + + pGuiGraphics.drawCenteredString(font, text, textCenterX, drawY, 0xFFFFFF); + } + private double normalizeAngle(double angle) { if (angle != 0) From 3122c07a2aa513c61706ca2c49cf1cb4737830e3 Mon Sep 17 00:00:00 2001 From: Gerbagel Date: Sat, 2 May 2026 03:40:21 +0200 Subject: [PATCH 32/55] =?UTF-8?q?[Cosmere]=C2=A0Missing=20imports=20after?= =?UTF-8?q?=20cherrypick?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/capabilities/AllomancySpiritwebSubmodule.java | 1 + .../common/capabilities/FeruchemySpiritwebSubmodule.java | 2 ++ .../common/capabilities/SandmasterySpiritwebSubmodule.java | 1 + 3 files changed, 4 insertions(+) diff --git a/src/allomancy/java/leaf/cosmere/allomancy/common/capabilities/AllomancySpiritwebSubmodule.java b/src/allomancy/java/leaf/cosmere/allomancy/common/capabilities/AllomancySpiritwebSubmodule.java index 265462a67..c97e678ab 100644 --- a/src/allomancy/java/leaf/cosmere/allomancy/common/capabilities/AllomancySpiritwebSubmodule.java +++ b/src/allomancy/java/leaf/cosmere/allomancy/common/capabilities/AllomancySpiritwebSubmodule.java @@ -37,6 +37,7 @@ import java.awt.*; import java.util.ArrayList; import java.util.Arrays; +import java.util.List; import java.util.Map; import java.util.function.Function; import java.util.stream.Collectors; diff --git a/src/feruchemy/java/leaf/cosmere/feruchemy/common/capabilities/FeruchemySpiritwebSubmodule.java b/src/feruchemy/java/leaf/cosmere/feruchemy/common/capabilities/FeruchemySpiritwebSubmodule.java index b451f1038..73a07d39b 100644 --- a/src/feruchemy/java/leaf/cosmere/feruchemy/common/capabilities/FeruchemySpiritwebSubmodule.java +++ b/src/feruchemy/java/leaf/cosmere/feruchemy/common/capabilities/FeruchemySpiritwebSubmodule.java @@ -24,6 +24,8 @@ import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; + +import java.util.List; import java.util.stream.Collectors; public class FeruchemySpiritwebSubmodule implements ISpiritwebSubmodule diff --git a/src/sandmastery/java/leaf/cosmere/sandmastery/common/capabilities/SandmasterySpiritwebSubmodule.java b/src/sandmastery/java/leaf/cosmere/sandmastery/common/capabilities/SandmasterySpiritwebSubmodule.java index cb60beee7..c1dd21bf1 100644 --- a/src/sandmastery/java/leaf/cosmere/sandmastery/common/capabilities/SandmasterySpiritwebSubmodule.java +++ b/src/sandmastery/java/leaf/cosmere/sandmastery/common/capabilities/SandmasterySpiritwebSubmodule.java @@ -34,6 +34,7 @@ import net.minecraft.world.item.ItemStack; import org.jetbrains.annotations.NotNull; +import java.util.List; import java.util.Random; import java.util.UUID; From 0c73c07d110ac796d2265f4b7b4c7aad9a49fe03 Mon Sep 17 00:00:00 2001 From: Gerbagel Date: Sat, 2 May 2026 03:47:18 +0200 Subject: [PATCH 33/55] [Cosmere] Finishing touches before PR --- .../allomancy/client/gui/InnerRadialButton.java | 6 +++--- .../allomancy/client/gui/OuterRadialButton.java | 6 +++--- .../cosmere/feruchemy/client/gui/DiamondButton.java | 6 +++--- .../common/manifestation/FeruchemyManifestation.java | 2 +- .../java/leaf/cosmere/client/gui/SpiritwebHud.java | 12 ------------ 5 files changed, 10 insertions(+), 22 deletions(-) diff --git a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java index db82acec7..1536fc05f 100644 --- a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java +++ b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java @@ -152,9 +152,9 @@ private void renderSegment(GuiGraphics pGuiGraphics, boolean isHovered) if (!hasManifestation) { - r *= 0.1f; - g *= 0.1f; - b *= 0.1f; + r *= 0.6f; + g *= 0.6f; + b *= 0.6f; } if (isHovered && hasManifestation) diff --git a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java index 1c93721d3..4aa7f26f7 100644 --- a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java +++ b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java @@ -156,9 +156,9 @@ private void renderSegment(@NotNull GuiGraphics pGuiGraphics, boolean isHovered) if (!hasManifestation) { - r *= 0.1f; - g *= 0.1f; - b *= 0.1f; + r *= 0.6f; + g *= 0.6f; + b *= 0.6f; } if (isHovered && hasManifestation) diff --git a/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/DiamondButton.java b/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/DiamondButton.java index c2aa1928c..65ef90442 100644 --- a/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/DiamondButton.java +++ b/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/DiamondButton.java @@ -110,9 +110,9 @@ private void renderDiamond(GuiGraphics pGuiGraphics, boolean isHovered) if (!hasManifestation) { - r *= 0.1f; - g *= 0.1f; - b *= 0.1f; + r *= 0.6f; + g *= 0.6f; + b *= 0.6f; } if (isHovered && hasManifestation) diff --git a/src/feruchemy/java/leaf/cosmere/feruchemy/common/manifestation/FeruchemyManifestation.java b/src/feruchemy/java/leaf/cosmere/feruchemy/common/manifestation/FeruchemyManifestation.java index 16193249a..de5c7f072 100644 --- a/src/feruchemy/java/leaf/cosmere/feruchemy/common/manifestation/FeruchemyManifestation.java +++ b/src/feruchemy/java/leaf/cosmere/feruchemy/common/manifestation/FeruchemyManifestation.java @@ -107,7 +107,7 @@ public float getInvestitureHud(ISpiritweb spiritweb) collectMenuInfo(); double maximum = metalmindMaxChargesMap.getOrDefault(metalType, 0d); double charge = metalmindChargesMap.getOrDefault(metalType, 0d); - return (float) (maximum/charge); + return (float) (charge/maximum); } protected CosmereEffect getTappingEffect() diff --git a/src/main/java/leaf/cosmere/client/gui/SpiritwebHud.java b/src/main/java/leaf/cosmere/client/gui/SpiritwebHud.java index b688c2a2b..fbc319f60 100644 --- a/src/main/java/leaf/cosmere/client/gui/SpiritwebHud.java +++ b/src/main/java/leaf/cosmere/client/gui/SpiritwebHud.java @@ -119,18 +119,6 @@ else if (mode < 0) } } - // todo this won't work for feruchemy... -// if (mode > 0) -// { -// g = g - 0.4f * mode; -// b = b - 0.4f * mode; -// } -// else if (mode < 0) -// { -// r = r - 0.4f * -mode; -// g = g - 0.4f * -mode; -// } - int color = toHex(new Color(r, g, b, a)); float width = getWidth(); From 0d41d5769eb08218df7d9a32d50532e65155ba17 Mon Sep 17 00:00:00 2001 From: Gerbagel Date: Sat, 2 May 2026 14:13:56 +0200 Subject: [PATCH 34/55] [Feruchemy] Handle nicrosil menu --- .../client/gui/InnerRadialButton.java | 2 +- .../client/gui/OuterRadialButton.java | 2 +- .../feruchemy/client/gui/DiamondButton.java | 58 +++++++++++++------ .../client/gui/FeruchemySpiritwebMenu.java | 1 - .../manifestation/FeruchemyNicrosil.java | 1 + 5 files changed, 42 insertions(+), 22 deletions(-) diff --git a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java index 1536fc05f..b90d522a3 100644 --- a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java +++ b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java @@ -311,7 +311,7 @@ private void renderInfoBlock(GuiGraphics pGuiGraphics) int screenHeight = Minecraft.getInstance().getWindow().getGuiScaledHeight(); int x = 0; int y = 0; - int width = screenWidth / 4; + int width = (int) (screenWidth * 0.3); int height = screenHeight / 5; int color = 0x99333333; diff --git a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java index 4aa7f26f7..6c7f40ef1 100644 --- a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java +++ b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java @@ -317,7 +317,7 @@ private void renderInfoBlock(GuiGraphics pGuiGraphics) int screenHeight = Minecraft.getInstance().getWindow().getGuiScaledHeight(); int x = 0; int y = 0; - int width = screenWidth / 4; + int width = (int) (screenWidth * 0.3); int height = screenHeight / 5; int color = 0x99333333; diff --git a/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/DiamondButton.java b/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/DiamondButton.java index 65ef90442..7906f3cea 100644 --- a/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/DiamondButton.java +++ b/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/DiamondButton.java @@ -5,6 +5,7 @@ import com.mojang.blaze3d.vertex.DefaultVertexFormat; import com.mojang.blaze3d.vertex.Tesselator; import com.mojang.blaze3d.vertex.VertexFormat; +import leaf.cosmere.api.CosmereAPI; import leaf.cosmere.api.IHasMetalType; import leaf.cosmere.api.Manifestations; import leaf.cosmere.api.Metals; @@ -91,12 +92,20 @@ public boolean isMouseOver(double mouseX, double mouseY) @Override public boolean mouseClicked(double pMouseX, double pMouseY, int pButton) { + CosmereAPI.logger.info("Metal clicked: " + metal.getName() + " | Mouse over: " + isMouseOver(pMouseX, pMouseY)); if (isMouseOver(pMouseX, pMouseY) && hasManifestation) { - if (pButton == 0) - Cosmere.packetHandler().sendToServer(new ChangeManifestationModeMessage(manifestation, 1)); + if (manifestation.hasMenu()) + { + manifestation.openMenu(); + } else - Cosmere.packetHandler().sendToServer(new ChangeManifestationModeMessage(manifestation, -1)); + { + if (pButton == 0) + Cosmere.packetHandler().sendToServer(new ChangeManifestationModeMessage(manifestation, 1)); + else + Cosmere.packetHandler().sendToServer(new ChangeManifestationModeMessage(manifestation, -1)); + } playDownSound(Minecraft.getInstance().getSoundManager()); } @@ -276,7 +285,7 @@ private void renderInfoBlock(GuiGraphics pGuiGraphics) int screenHeight = Minecraft.getInstance().getWindow().getGuiScaledHeight(); int x = 0; int y = 0; - int width = screenWidth / 4; + int width = (int) (screenWidth * 0.3); int height = screenHeight / 5; int color = 0x99333333; @@ -317,21 +326,32 @@ private void renderInfoBlock(GuiGraphics pGuiGraphics) String text = I18n.get(manifestation.getTranslationKey()); pGuiGraphics.drawString(font, text, x+5, y+10, 0xFFFFFFFF); - int seconds = manifestation.getInvestitureRemaining(spiritweb); - int hours = seconds / 3600; - int minutes = (seconds % 3600) / 60; - seconds = seconds % 60; - - if (hours > 0) - text = String.format("%d:%02d:%02d", hours, minutes, seconds); - else if (minutes > 0) - text = String.format("%d:%02d", minutes, seconds); - else if (seconds > 0) - text = String.format("%02d", seconds); - else - text = "Empty"; - - pGuiGraphics.drawString(font, text, x+5, y+10+font.lineHeight+5, 0xFFFFFFFF); + if (metal != Metals.MetalType.NICROSIL) + { + int seconds = manifestation.getInvestitureRemaining(spiritweb); + int hours = seconds / 3600; + int minutes = (seconds % 3600) / 60; + seconds = seconds % 60; + + if (hours > 0) + { + text = String.format("%d:%02d:%02d", hours, minutes, seconds); + } + else if (minutes > 0) + { + text = String.format("%d:%02d", minutes, seconds); + } + else if (seconds > 0) + { + text = String.format("%02d", seconds); + } + else + { + text = "Empty"; + } + + pGuiGraphics.drawString(font, text, x + 5, y + 10 + font.lineHeight + 5, 0xFFFFFFFF); + } } public float lerp(float start, float end, float pct) { diff --git a/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/FeruchemySpiritwebMenu.java b/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/FeruchemySpiritwebMenu.java index 9c66741f0..42c2bf761 100644 --- a/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/FeruchemySpiritwebMenu.java +++ b/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/FeruchemySpiritwebMenu.java @@ -21,7 +21,6 @@ public FeruchemySpiritwebMenu() { super(Component.literal("Feruchemy")); player = Minecraft.getInstance().player; - //init(); } @Override diff --git a/src/feruchemy/java/leaf/cosmere/feruchemy/common/manifestation/FeruchemyNicrosil.java b/src/feruchemy/java/leaf/cosmere/feruchemy/common/manifestation/FeruchemyNicrosil.java index c36d32d5c..ed6689ad6 100644 --- a/src/feruchemy/java/leaf/cosmere/feruchemy/common/manifestation/FeruchemyNicrosil.java +++ b/src/feruchemy/java/leaf/cosmere/feruchemy/common/manifestation/FeruchemyNicrosil.java @@ -30,6 +30,7 @@ public void openMenu() { Minecraft minecraft = Minecraft.getInstance(); NicrosilMenu.instance.closeScreen(); + // todo: replace with SpiritwebMenu call. might also be good to send a supplier instead of a singleton minecraft.setScreen(NicrosilMenu.instance); } From a31cc718111e3bcb70ee10eacaf98c148e59e5f0 Mon Sep 17 00:00:00 2001 From: Gerbagel Date: Sat, 2 May 2026 14:26:49 +0200 Subject: [PATCH 35/55] [Cosmere] Fixed click detection bug --- .../cosmere/allomancy/client/gui/InnerRadialButton.java | 5 +++-- .../cosmere/allomancy/client/gui/OuterRadialButton.java | 5 +++-- .../leaf/cosmere/feruchemy/client/gui/DiamondButton.java | 6 +++--- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java index b90d522a3..a001b46ca 100644 --- a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java +++ b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java @@ -120,7 +120,8 @@ public boolean isMouseOver(double mouseX, double mouseY) @Override public boolean mouseClicked(double pMouseX, double pMouseY, int pButton) { - if (isMouseOver(pMouseX, pMouseY) && hasManifestation) + boolean isMouseOver = isMouseOver(pMouseX, pMouseY); + if (isMouseOver && hasManifestation) { if (pButton == 0) Cosmere.packetHandler().sendToServer(new ChangeManifestationModeMessage(manifestation, 1)); @@ -129,7 +130,7 @@ public boolean mouseClicked(double pMouseX, double pMouseY, int pButton) playDownSound(Minecraft.getInstance().getSoundManager()); } - return super.mouseClicked(pMouseX, pMouseY, pButton); + return isMouseOver; } private double normalizeAngle(double angle) diff --git a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java index 6c7f40ef1..7c1fc0aca 100644 --- a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java +++ b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java @@ -118,7 +118,8 @@ public boolean isMouseOver(double mouseX, double mouseY) @Override public boolean mouseClicked(double pMouseX, double pMouseY, int pButton) { - if (isMouseOver(pMouseX, pMouseY) && hasManifestation) + boolean isMouseOver = isMouseOver(pMouseX, pMouseY); + if (isMouseOver && hasManifestation) { if (pButton == 0) Cosmere.packetHandler().sendToServer(new ChangeManifestationModeMessage(manifestation, 1)); @@ -127,7 +128,7 @@ public boolean mouseClicked(double pMouseX, double pMouseY, int pButton) playDownSound(Minecraft.getInstance().getSoundManager()); } - return super.mouseClicked(pMouseX, pMouseY, pButton); + return isMouseOver; } @Override diff --git a/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/DiamondButton.java b/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/DiamondButton.java index 7906f3cea..64d097f70 100644 --- a/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/DiamondButton.java +++ b/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/DiamondButton.java @@ -92,8 +92,8 @@ public boolean isMouseOver(double mouseX, double mouseY) @Override public boolean mouseClicked(double pMouseX, double pMouseY, int pButton) { - CosmereAPI.logger.info("Metal clicked: " + metal.getName() + " | Mouse over: " + isMouseOver(pMouseX, pMouseY)); - if (isMouseOver(pMouseX, pMouseY) && hasManifestation) + boolean isMouseOver = isMouseOver(pMouseX, pMouseY); + if (isMouseOver && hasManifestation) { if (manifestation.hasMenu()) { @@ -109,7 +109,7 @@ public boolean mouseClicked(double pMouseX, double pMouseY, int pButton) playDownSound(Minecraft.getInstance().getSoundManager()); } - return super.mouseClicked(pMouseX, pMouseY, pButton); + return isMouseOver; } private void renderDiamond(GuiGraphics pGuiGraphics, boolean isHovered) From d9ef84d89523f617570547ee8cb4b0ea001fbfda Mon Sep 17 00:00:00 2001 From: Gerbagel Date: Sat, 2 May 2026 14:35:32 +0200 Subject: [PATCH 36/55] [Cosmere] Add client-only guard for menu registration --- .../common/capabilities/AllomancySpiritwebSubmodule.java | 6 +++++- src/api/java/leaf/cosmere/api/ISpiritwebSubmodule.java | 3 ++- .../common/capabilities/FeruchemySpiritwebSubmodule.java | 3 +++ .../common/capabilities/SandmasterySpiritwebSubmodule.java | 3 +++ .../common/capabilities/SurgebindingSpiritwebSubmodule.java | 3 +++ 5 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/allomancy/java/leaf/cosmere/allomancy/common/capabilities/AllomancySpiritwebSubmodule.java b/src/allomancy/java/leaf/cosmere/allomancy/common/capabilities/AllomancySpiritwebSubmodule.java index c97e678ab..2af02305e 100644 --- a/src/allomancy/java/leaf/cosmere/allomancy/common/capabilities/AllomancySpiritwebSubmodule.java +++ b/src/allomancy/java/leaf/cosmere/allomancy/common/capabilities/AllomancySpiritwebSubmodule.java @@ -32,6 +32,8 @@ import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; import net.minecraft.world.phys.Vec3; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.client.event.RenderLevelStageEvent; import java.awt.*; @@ -336,7 +338,9 @@ public List getPowers() return AllomancyAttributes.ALLOMANCY_ATTRIBUTES.values().stream() .map((AttributeRegistryObject::getAttribute)).collect(Collectors.toList()); } - + + @Override + @OnlyIn(Dist.CLIENT) public void registerMenu() { SpiritwebRegistry.getInstance().register(Manifestations.ManifestationTypes.ALLOMANCY, AllomancySpiritwebMenu::new); diff --git a/src/api/java/leaf/cosmere/api/ISpiritwebSubmodule.java b/src/api/java/leaf/cosmere/api/ISpiritwebSubmodule.java index 3b613b117..6baf79060 100644 --- a/src/api/java/leaf/cosmere/api/ISpiritwebSubmodule.java +++ b/src/api/java/leaf/cosmere/api/ISpiritwebSubmodule.java @@ -54,6 +54,7 @@ default void resetOnDeath(ISpiritweb spiritweb) { } + @OnlyIn(Dist.CLIENT) default void registerMenu() { } @@ -78,4 +79,4 @@ default List getEntityPowers(LivingEntity entity) } return powers; } -} \ No newline at end of file +} diff --git a/src/feruchemy/java/leaf/cosmere/feruchemy/common/capabilities/FeruchemySpiritwebSubmodule.java b/src/feruchemy/java/leaf/cosmere/feruchemy/common/capabilities/FeruchemySpiritwebSubmodule.java index 73a07d39b..5b1a0bd99 100644 --- a/src/feruchemy/java/leaf/cosmere/feruchemy/common/capabilities/FeruchemySpiritwebSubmodule.java +++ b/src/feruchemy/java/leaf/cosmere/feruchemy/common/capabilities/FeruchemySpiritwebSubmodule.java @@ -24,6 +24,8 @@ import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; import java.util.List; import java.util.stream.Collectors; @@ -71,6 +73,7 @@ public void drainInvestiture(ISpiritweb data, double strength) } @Override + @OnlyIn(Dist.CLIENT) public void registerMenu() { SpiritwebRegistry.getInstance().register(Manifestations.ManifestationTypes.FERUCHEMY, FeruchemySpiritwebMenu::new); diff --git a/src/sandmastery/java/leaf/cosmere/sandmastery/common/capabilities/SandmasterySpiritwebSubmodule.java b/src/sandmastery/java/leaf/cosmere/sandmastery/common/capabilities/SandmasterySpiritwebSubmodule.java index c1dd21bf1..092839503 100644 --- a/src/sandmastery/java/leaf/cosmere/sandmastery/common/capabilities/SandmasterySpiritwebSubmodule.java +++ b/src/sandmastery/java/leaf/cosmere/sandmastery/common/capabilities/SandmasterySpiritwebSubmodule.java @@ -32,6 +32,8 @@ import net.minecraft.world.entity.ai.attributes.AttributeModifier; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; import org.jetbrains.annotations.NotNull; import java.util.List; @@ -207,6 +209,7 @@ public void GiveStartingItem(Player player, Manifestation manifestation) } @Override + @OnlyIn(Dist.CLIENT) public void registerMenu() { // todo: add check for if actually has Sandmastery diff --git a/src/surgebinding/java/leaf/cosmere/surgebinding/common/capabilities/SurgebindingSpiritwebSubmodule.java b/src/surgebinding/java/leaf/cosmere/surgebinding/common/capabilities/SurgebindingSpiritwebSubmodule.java index dfc1601c7..28b8476ed 100644 --- a/src/surgebinding/java/leaf/cosmere/surgebinding/common/capabilities/SurgebindingSpiritwebSubmodule.java +++ b/src/surgebinding/java/leaf/cosmere/surgebinding/common/capabilities/SurgebindingSpiritwebSubmodule.java @@ -27,6 +27,8 @@ import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ArmorItem; import net.minecraft.world.item.ItemStack; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.event.ServerChatEvent; import net.minecraftforge.items.wrapper.PlayerInvWrapper; @@ -210,6 +212,7 @@ public void drainInvestiture(ISpiritweb data, double strength) } @Override + @OnlyIn(Dist.CLIENT) public void registerMenu() { SpiritwebRegistry.getInstance().register(Manifestations.ManifestationTypes.SURGEBINDING, SurgebindingSpiritwebMenu::new); From 7bab14ad2d2c5694ca324f03a027a09f287eb272 Mon Sep 17 00:00:00 2001 From: Gerbagel Date: Sat, 2 May 2026 15:11:39 +0200 Subject: [PATCH 37/55] [Cosmere] Fixed a bug where creating a new SpiritwebCap (changing worlds) would break the spiritweb HUD Also SpiritwebCap owns SpiritwebHud now --- .../cosmere/api/spiritweb/ISpiritweb.java | 3 ++ .../cosmere/client/ClientForgeEvents.java | 3 +- .../leaf/cosmere/client/gui/SpiritwebHud.java | 46 ++++++++++--------- .../cap/entity/SpiritwebCapability.java | 30 ++++++------ 4 files changed, 43 insertions(+), 39 deletions(-) diff --git a/src/api/java/leaf/cosmere/api/spiritweb/ISpiritweb.java b/src/api/java/leaf/cosmere/api/spiritweb/ISpiritweb.java index 2b14bf557..84a244c84 100644 --- a/src/api/java/leaf/cosmere/api/spiritweb/ISpiritweb.java +++ b/src/api/java/leaf/cosmere/api/spiritweb/ISpiritweb.java @@ -10,6 +10,7 @@ import leaf.cosmere.api.cosmereEffect.CosmereEffect; import leaf.cosmere.api.cosmereEffect.CosmereEffectInstance; import leaf.cosmere.api.manifestation.Manifestation; +import net.minecraft.client.gui.components.AbstractWidget; import net.minecraft.nbt.CompoundTag; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.Entity; @@ -104,4 +105,6 @@ public interface ISpiritweb extends INBTSerializable void activatePowerState(int num); + AbstractWidget getSpiritwebHud(); + } diff --git a/src/main/java/leaf/cosmere/client/ClientForgeEvents.java b/src/main/java/leaf/cosmere/client/ClientForgeEvents.java index d4debdbab..2f7a3626b 100644 --- a/src/main/java/leaf/cosmere/client/ClientForgeEvents.java +++ b/src/main/java/leaf/cosmere/client/ClientForgeEvents.java @@ -7,6 +7,7 @@ import com.mojang.blaze3d.platform.InputConstants; import leaf.cosmere.api.Activator; +import leaf.cosmere.api.CosmereAPI; import leaf.cosmere.api.manifestation.Manifestation; import leaf.cosmere.client.gui.SpiritwebHud; import leaf.cosmere.client.gui.SpiritwebMenu; @@ -232,7 +233,7 @@ public static void onRenderGuiOverlayPost(RenderGuiOverlayEvent.Post event) SpiritwebCapability.get(playerEntity).ifPresent(spiritweb -> { // Shouldn't need mouse location, will only render as a HUD element - SpiritwebHud.Instance(playerEntity).render(event.getGuiGraphics(), 0, 0, event.getPartialTick()); + spiritweb.getSpiritwebHud().render(event.getGuiGraphics(), 0, 0, event.getPartialTick()); }); } profiler.pop(); diff --git a/src/main/java/leaf/cosmere/client/gui/SpiritwebHud.java b/src/main/java/leaf/cosmere/client/gui/SpiritwebHud.java index fbc319f60..a21a2cfdd 100644 --- a/src/main/java/leaf/cosmere/client/gui/SpiritwebHud.java +++ b/src/main/java/leaf/cosmere/client/gui/SpiritwebHud.java @@ -24,31 +24,35 @@ public class SpiritwebHud extends AbstractWidget private static SpiritwebHud INSTANCE; private Player player; - private SpiritwebHud(int pX, int pY, int pWidth, int pHeight, Component pMessage, Player player) + public SpiritwebHud(Player player) { - super(pX, pY, pWidth, pHeight, pMessage); + super(CosmereConfigs.CLIENT_CONFIG.hudXCoordinate.get(), + CosmereConfigs.CLIENT_CONFIG.hudYCoordinate.get(), + CosmereConfigs.CLIENT_CONFIG.hudSizeX.get(), + CosmereConfigs.CLIENT_CONFIG.hudSizeY.get(), + Component.literal("Spiritweb HUD")); this.player = player; } - public static SpiritwebHud Instance(Player player) - { - if (INSTANCE == null) - { - INSTANCE = new SpiritwebHud(CosmereConfigs.CLIENT_CONFIG.hudXCoordinate.get(), - CosmereConfigs.CLIENT_CONFIG.hudYCoordinate.get(), - CosmereConfigs.CLIENT_CONFIG.hudSizeX.get(), - CosmereConfigs.CLIENT_CONFIG.hudSizeY.get(), - Component.literal("Spiritweb HUD"), - player); // should never be null - } - - return INSTANCE; - } - - public void setSelectedManifestation() - { - - } +// public static SpiritwebHud Instance(Player player) +// { +// if (INSTANCE == null) +// { +// INSTANCE = new SpiritwebHud(CosmereConfigs.CLIENT_CONFIG.hudXCoordinate.get(), +// CosmereConfigs.CLIENT_CONFIG.hudYCoordinate.get(), +// CosmereConfigs.CLIENT_CONFIG.hudSizeX.get(), +// CosmereConfigs.CLIENT_CONFIG.hudSizeY.get(), +// Component.literal("Spiritweb HUD"), +// player); // should never be null +// } +// +// return INSTANCE; +// } +// +// public static void killInstance() +// { +// INSTANCE = null; +// } @Override protected void renderWidget(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) diff --git a/src/main/java/leaf/cosmere/common/cap/entity/SpiritwebCapability.java b/src/main/java/leaf/cosmere/common/cap/entity/SpiritwebCapability.java index c37c3400a..edd78d499 100644 --- a/src/main/java/leaf/cosmere/common/cap/entity/SpiritwebCapability.java +++ b/src/main/java/leaf/cosmere/common/cap/entity/SpiritwebCapability.java @@ -13,6 +13,7 @@ import leaf.cosmere.api.cosmereEffect.CosmereEffectInstance; import leaf.cosmere.api.manifestation.Manifestation; import leaf.cosmere.api.spiritweb.ISpiritweb; +import leaf.cosmere.client.gui.SpiritwebHud; import leaf.cosmere.common.Cosmere; import leaf.cosmere.common.config.CosmereConfigs; import leaf.cosmere.common.network.packets.ChangeManifestationModeMessage; @@ -21,6 +22,7 @@ import leaf.cosmere.common.registry.GameEventRegistry; import leaf.cosmere.common.registry.ManifestationRegistry; import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.components.AbstractWidget; import net.minecraft.core.BlockPos; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.ListTag; @@ -34,6 +36,7 @@ import net.minecraft.world.entity.ai.attributes.Attribute; import net.minecraft.world.entity.ai.attributes.AttributeInstance; import net.minecraft.world.entity.ai.attributes.AttributeMap; +import net.minecraft.world.entity.player.Player; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.client.event.RenderLevelStageEvent; @@ -66,6 +69,7 @@ public class SpiritwebCapability implements ISpiritweb public final Map MANIFESTATIONS_MODE = new HashMap<>(); private Manifestation selectedManifestation = ManifestationRegistry.NONE.get(); + private SpiritwebHud spiritwebHud; public List pushBlocks = new ArrayList<>(4); public List pushEntities = new ArrayList<>(4); @@ -536,23 +540,6 @@ public void renderWorldEffects(RenderLevelStageEvent event) } } - static float[][] calculatePentagonVertices(float centerX, float centerY, float radius, float scaleY) - { -// for i in range(5): -// angle = 2 * math.pi * i / 5 # Divide 360° into 5 angles (in radians) -// x = cx + radius * math.cos(angle) -// y = cy + radius * math.sin(angle) -// vertices.append((x, y)) -// return vertices - float[][] vertices = new float[5][2]; - for (int i = 0; i < 5; i++) { - double angle = 2 * Math.PI * ((double) i / 5); - vertices[i][0] = centerX + (float) (radius * Math.cos(angle)); - vertices[i][1] = centerY + (float) (radius * Math.sin(angle)); // Scale Y - } - return vertices; - } - @Override public void setSelectedManifestation(Manifestation manifestation) { @@ -880,6 +867,15 @@ public void syncToClients(@Nullable ServerPlayer serverPlayerEntity) } } + @Override + @OnlyIn(Dist.CLIENT) + public AbstractWidget getSpiritwebHud() + { + if (spiritwebHud == null && livingEntity instanceof Player player) + spiritwebHud = new SpiritwebHud(player); + return spiritwebHud; + } + public void saveNewState(int num) { if(num < 0 || num > 8) From 4909cf1658b7d56600d3ead44bf022a03ec979f2 Mon Sep 17 00:00:00 2001 From: Gerbagel Date: Sat, 2 May 2026 15:15:15 +0200 Subject: [PATCH 38/55] [Feruchemy] Renamed DiamondButton to TriangleButton --- .../client/gui/FeruchemySpiritwebMenu.java | 32 +++++++++---------- ...DiamondButton.java => TriangleButton.java} | 5 ++- 2 files changed, 18 insertions(+), 19 deletions(-) rename src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/{DiamondButton.java => TriangleButton.java} (94%) diff --git a/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/FeruchemySpiritwebMenu.java b/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/FeruchemySpiritwebMenu.java index 42c2bf761..09ad9500a 100644 --- a/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/FeruchemySpiritwebMenu.java +++ b/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/FeruchemySpiritwebMenu.java @@ -36,49 +36,49 @@ protected void init() int x = this.width/2 - distance; int y = this.height/2 - distance*2; - addRenderableWidget(new DiamondButton(x, y, + addRenderableWidget(new TriangleButton(x, y, distance, topLeftRot, Metals.MetalType.IRON, spiritweb)); - addRenderableWidget(new DiamondButton(x + distance, y, + addRenderableWidget(new TriangleButton(x + distance, y, distance, topRightRot, Metals.MetalType.STEEL, spiritweb)); - addRenderableWidget(new DiamondButton(x + distance, y + distance, + addRenderableWidget(new TriangleButton(x + distance, y + distance, distance, bottomRightRot, Metals.MetalType.TIN, spiritweb)); - addRenderableWidget(new DiamondButton(x, y + distance, + addRenderableWidget(new TriangleButton(x, y + distance, distance, bottomLeftRot, Metals.MetalType.PEWTER, spiritweb)); x = this.width / 2; y = this.height / 2 - distance; - addRenderableWidget(new DiamondButton(x, y, + addRenderableWidget(new TriangleButton(x, y, distance, topLeftRot, Metals.MetalType.ZINC, spiritweb)); - addRenderableWidget(new DiamondButton(x + distance, y, + addRenderableWidget(new TriangleButton(x + distance, y, distance, topRightRot, Metals.MetalType.COPPER, spiritweb)); - addRenderableWidget(new DiamondButton(x + distance, y + distance, + addRenderableWidget(new TriangleButton(x + distance, y + distance, distance, bottomRightRot, Metals.MetalType.BRASS, spiritweb)); - addRenderableWidget(new DiamondButton(x, y + distance, + addRenderableWidget(new TriangleButton(x, y + distance, distance, bottomLeftRot, Metals.MetalType.BRONZE, spiritweb)); x = this.width / 2 - distance; y = this.height / 2; - addRenderableWidget(new DiamondButton(x, y, + addRenderableWidget(new TriangleButton(x, y, distance, topLeftRot, Metals.MetalType.GOLD, spiritweb)); - addRenderableWidget(new DiamondButton(x + distance, y, + addRenderableWidget(new TriangleButton(x + distance, y, distance, topRightRot, Metals.MetalType.ELECTRUM, spiritweb)); - addRenderableWidget(new DiamondButton(x + distance, y + distance, + addRenderableWidget(new TriangleButton(x + distance, y + distance, distance, bottomRightRot, Metals.MetalType.CADMIUM, spiritweb)); - addRenderableWidget(new DiamondButton(x, y + distance, + addRenderableWidget(new TriangleButton(x, y + distance, distance, bottomLeftRot, Metals.MetalType.BENDALLOY, spiritweb)); x = this.width / 2 - distance*2; y = this.height / 2 - distance; - addRenderableWidget(new DiamondButton(x, y, + addRenderableWidget(new TriangleButton(x, y, distance, topLeftRot, Metals.MetalType.CHROMIUM, spiritweb)); - addRenderableWidget(new DiamondButton(x + distance, y, + addRenderableWidget(new TriangleButton(x + distance, y, distance, topRightRot, Metals.MetalType.DURALUMIN, spiritweb)); - addRenderableWidget(new DiamondButton(x + distance, y + distance, + addRenderableWidget(new TriangleButton(x + distance, y + distance, distance, bottomRightRot, Metals.MetalType.NICROSIL, spiritweb)); - addRenderableWidget(new DiamondButton(x, y + distance, + addRenderableWidget(new TriangleButton(x, y + distance, distance, bottomLeftRot, Metals.MetalType.ALUMINUM, spiritweb)); })); } diff --git a/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/DiamondButton.java b/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/TriangleButton.java similarity index 94% rename from src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/DiamondButton.java rename to src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/TriangleButton.java index 64d097f70..3f60ce6eb 100644 --- a/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/DiamondButton.java +++ b/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/TriangleButton.java @@ -5,7 +5,6 @@ import com.mojang.blaze3d.vertex.DefaultVertexFormat; import com.mojang.blaze3d.vertex.Tesselator; import com.mojang.blaze3d.vertex.VertexFormat; -import leaf.cosmere.api.CosmereAPI; import leaf.cosmere.api.IHasMetalType; import leaf.cosmere.api.Manifestations; import leaf.cosmere.api.Metals; @@ -28,7 +27,7 @@ import java.awt.*; -public class DiamondButton extends Button +public class TriangleButton extends Button { private final ISpiritweb spiritweb; private final Manifestation manifestation; @@ -36,7 +35,7 @@ public class DiamondButton extends Button private final boolean hasManifestation; private final float rotation; - public DiamondButton(int pX, int pY, int distance, float rotation, Metals.MetalType metal, ISpiritweb spiritweb) + public TriangleButton(int pX, int pY, int distance, float rotation, Metals.MetalType metal, ISpiritweb spiritweb) { super(pX, pY, distance, distance, CommonComponents.EMPTY, (button) -> { }, DEFAULT_NARRATION); this.rotation = rotation; From 77e9bf80768babd3eb3f806709361174b6433c28 Mon Sep 17 00:00:00 2001 From: Gerbagel Date: Sat, 2 May 2026 15:18:35 +0200 Subject: [PATCH 39/55] [Feruchemy] Refactored mutex lock code --- .../client/utils/FeruchemyChargeThread.java | 30 ++++++++----------- 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/src/feruchemy/java/leaf/cosmere/feruchemy/client/utils/FeruchemyChargeThread.java b/src/feruchemy/java/leaf/cosmere/feruchemy/client/utils/FeruchemyChargeThread.java index 347ff6cb8..3d7a45f0d 100644 --- a/src/feruchemy/java/leaf/cosmere/feruchemy/client/utils/FeruchemyChargeThread.java +++ b/src/feruchemy/java/leaf/cosmere/feruchemy/client/utils/FeruchemyChargeThread.java @@ -40,41 +40,35 @@ public static FeruchemyChargeThread getInstance() public HashMap getCharges() { - try + HashMap retVal = new HashMap<>(); + if (lock.tryLock()) { - HashMap retVal = new HashMap<>(); - if (lock.tryLock()) + try { retVal.putAll(feruchemyChargeMap); + } + finally + { lock.unlock(); } - return retVal; - } - catch (Exception e) - { - e.printStackTrace(); - lock.unlock(); } - return new HashMap<>(); + return retVal; } public HashMap getMaximumCharges() { HashMap retVal = new HashMap<>(); - try + if (lock.tryLock()) { - if (lock.tryLock()) + try { retVal.putAll(feruchemyMaxChargeMap); + } + finally + { lock.unlock(); } } - catch (Exception e) - { - e.printStackTrace(); - retVal = new HashMap<>(); - lock.unlock(); - } return retVal; } From 66c7dcba04d9c05924a20ba4c3df9f16ab79972e Mon Sep 17 00:00:00 2001 From: Gerbagel Date: Sat, 2 May 2026 15:58:30 +0200 Subject: [PATCH 40/55] [Cosmere] Cached vertexes instead of calculating every frame --- .../client/gui/InnerRadialButton.java | 93 +++++++++------- .../client/gui/OuterRadialButton.java | 103 +++++++++++------- .../feruchemy/client/gui/TriangleButton.java | 94 +++++++++------- .../leaf/cosmere/client/gui/GuiUtils.java | 12 ++ .../sandmastery/client/gui/RadialButton.java | 89 +++++++++------ .../surgebinding/client/gui/CircleButton.java | 64 +++++++---- 6 files changed, 279 insertions(+), 176 deletions(-) create mode 100644 src/main/java/leaf/cosmere/client/gui/GuiUtils.java diff --git a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java index a001b46ca..2c45a8923 100644 --- a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java +++ b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java @@ -12,6 +12,7 @@ import leaf.cosmere.api.Metals; import leaf.cosmere.api.manifestation.Manifestation; import leaf.cosmere.api.spiritweb.ISpiritweb; +import leaf.cosmere.client.gui.GuiUtils; import leaf.cosmere.client.gui.SpiritwebMenu; import leaf.cosmere.common.Cosmere; import leaf.cosmere.common.network.packets.ChangeManifestationModeMessage; @@ -28,9 +29,12 @@ import org.lwjgl.opengl.GL11; import java.awt.*; +import java.util.ArrayList; +import java.util.List; public class InnerRadialButton extends Button { + private final List cachedQuads = new ArrayList<>(); private final float outerRadius; private final float innerRadius; private final double startAngle; @@ -59,6 +63,8 @@ protected InnerRadialButton(int centerX, int centerY, int segmentNr, Metals.Meta outerRadius = (float) Minecraft.getInstance().getWindow().getGuiScaledHeight() / 3f * 0.7f; innerRadius = 0; + + calculateVertexes(this.centerX, this.centerY, outerRadius, segmentNr); } @Override @@ -148,7 +154,7 @@ private double normalizeAngle(double angle) private void renderSegment(GuiGraphics pGuiGraphics, boolean isHovered) { - float r = 61/255.f, g = 70/255.f, b = 76/255.f; + float r = GuiUtils.BACKGROUND_COLOR.getRed()/255.f, g = GuiUtils.BACKGROUND_COLOR.getGreen()/255.f, b = GuiUtils.BACKGROUND_COLOR.getBlue()/255.f; float a = 1f; if (!hasManifestation) @@ -182,14 +188,6 @@ private void renderSegment(GuiGraphics pGuiGraphics, boolean isHovered) } } - float radsPerSegment = (float) Math.PI * 2 / 8; - float startAngle = segmentNr * radsPerSegment; - float radiusSq = outerRadius * outerRadius; - - // Defines the "chunkiness" of the pixelation - // 1 GUI pixel = 1 screen pixel at 1x scale, or scaled automatically by the game's GUI scale - int pixelSize = AllomancyConfigs.CLIENT.pixelationAmount.get(); - RenderSystem.disableCull(); RenderSystem.enableBlend(); RenderSystem.defaultBlendFunc(); @@ -201,38 +199,16 @@ private void renderSegment(GuiGraphics pGuiGraphics, boolean isHovered) buf.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR); - // Use ceil to ensure the bounding box completely covers the outermost pixels - int rInt = (int) Math.ceil(outerRadius); - - for (int x = -rInt; x <= rInt; x += pixelSize) + for (GuiUtils.CachedQuad quad : cachedQuads) { - for (int y = -rInt; y <= rInt; y += pixelSize) - { - float pixelCenterX = x + (pixelSize / 2f); - float pixelCenterY = y + (pixelSize / 2f); - - float distSq = pixelCenterX * pixelCenterX + pixelCenterY * pixelCenterY; - - if (distSq <= radiusSq) - { - float angle = (float) Math.atan2(pixelCenterY, pixelCenterX); - if (angle < 0) angle += (float) (Math.PI * 2); - - float diff = angle - startAngle; - if (diff < 0) diff += (float) (Math.PI * 2); - - if (diff < radsPerSegment) - { - float px = centerX + x; - float py = centerY + y; - - buf.vertex(pose, px, py, 0).color(r, g, b, a).endVertex(); - buf.vertex(pose, px, py + pixelSize, 0).color(r, g, b, a).endVertex(); - buf.vertex(pose, px + pixelSize, py + pixelSize, 0).color(r, g, b, a).endVertex(); - buf.vertex(pose, px + pixelSize, py, 0).color(r, g, b, a).endVertex(); - } - } - } + float px = quad.px(); + float py = quad.py(); + float size = quad.size(); + + buf.vertex(pose, px, py, 0).color(r, g, b, a).endVertex(); + buf.vertex(pose, px, py + size, 0).color(r, g, b, a).endVertex(); + buf.vertex(pose, px + size, py + size, 0).color(r, g, b, a).endVertex(); + buf.vertex(pose, px + size, py, 0).color(r, g, b, a).endVertex(); } tess.end(); @@ -367,6 +343,43 @@ else if (seconds > 0) pGuiGraphics.drawString(font, text, x+5, y+10+font.lineHeight+5, 0xFFFFFFFF); } + private void calculateVertexes(float centerX, float centerY, float outerRadius, int segmentNr) + { + cachedQuads.clear(); + + float radsPerSegment = (float) Math.PI * 2 / 8; + float startAngle = segmentNr * radsPerSegment; + float radiusSq = outerRadius * outerRadius; + + int pixelSize = AllomancyConfigs.CLIENT.pixelationAmount.get(); + int rInt = (int) Math.ceil(outerRadius); + + for (int x = -rInt; x <= rInt; x += pixelSize) + { + for (int y = -rInt; y <= rInt; y += pixelSize) + { + float pixelCenterX = x + (pixelSize / 2f); + float pixelCenterY = y + (pixelSize / 2f); + + float distSq = pixelCenterX * pixelCenterX + pixelCenterY * pixelCenterY; + + if (distSq <= radiusSq) + { + float angle = (float) Math.atan2(pixelCenterY, pixelCenterX); + if (angle < 0) angle += (float) (Math.PI * 2); + + float diff = angle - startAngle; + if (diff < 0) diff += (float) (Math.PI * 2); + + if (diff < radsPerSegment) + { + cachedQuads.add(new GuiUtils.CachedQuad(centerX + x, centerY + y, pixelSize)); + } + } + } + } + } + public float lerp(float start, float end, float pct) { return start + pct * (end - start); } diff --git a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java index 7c1fc0aca..a268ca431 100644 --- a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java +++ b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java @@ -12,6 +12,7 @@ import leaf.cosmere.api.Metals; import leaf.cosmere.api.manifestation.Manifestation; import leaf.cosmere.api.spiritweb.ISpiritweb; +import leaf.cosmere.client.gui.GuiUtils; import leaf.cosmere.client.gui.SpiritwebMenu; import leaf.cosmere.common.Cosmere; import leaf.cosmere.common.network.packets.ChangeManifestationModeMessage; @@ -28,10 +29,13 @@ import org.joml.Matrix4f; import org.lwjgl.opengl.GL11; -import java.awt.*; +import java.awt.Color; +import java.util.ArrayList; +import java.util.List; public class OuterRadialButton extends Button { + private final List cachedQuads = new ArrayList<>(); private final float outerRadius; private final float innerRadius; private final double startAngle; @@ -60,6 +64,8 @@ protected OuterRadialButton(int centerX, int centerY, int segmentNr, Metals.Meta outerRadius = (float) Minecraft.getInstance().getWindow().getGuiScaledHeight() / 3; innerRadius = outerRadius * 0.7f; + + calculateVertexes(this.centerX, this.centerY, innerRadius, outerRadius, segmentNr); } @Override @@ -152,7 +158,7 @@ private double normalizeAngle(double angle) private void renderSegment(@NotNull GuiGraphics pGuiGraphics, boolean isHovered) { - float r = 61/255.f, g = 70/255.f, b = 76/255.f; + float r = GuiUtils.BACKGROUND_COLOR.getRed()/255.f, g = GuiUtils.BACKGROUND_COLOR.getGreen()/255.f, b = GuiUtils.BACKGROUND_COLOR.getBlue()/255.f; float a = 1f; if (!hasManifestation) @@ -186,16 +192,6 @@ private void renderSegment(@NotNull GuiGraphics pGuiGraphics, boolean isHovered) } } - float radsPerSegment = (float) Math.PI * 2 / 8; - float startAngle = segmentNr * radsPerSegment; - - float outerRadiusSq = outerRadius * outerRadius; - float innerRadiusSq = innerRadius * innerRadius; - - // Defines the "chunkiness" of the pixelation - // 1 GUI pixel = 1 screen pixel at 1x scale, or scaled automatically by the game's GUI scale - int pixelSize = AllomancyConfigs.CLIENT.pixelationAmount.get(); - RenderSystem.disableCull(); RenderSystem.enableBlend(); RenderSystem.defaultBlendFunc(); @@ -207,37 +203,16 @@ private void renderSegment(@NotNull GuiGraphics pGuiGraphics, boolean isHovered) buf.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR); - int rInt = (int) Math.ceil(outerRadius); - - for (int x = -rInt; x <= rInt; x += pixelSize) + for (GuiUtils.CachedQuad quad : cachedQuads) { - for (int y = -rInt; y <= rInt; y += pixelSize) - { - float pixelCenterX = x + (pixelSize / 2f); - float pixelCenterY = y + (pixelSize / 2f); - - float distSq = pixelCenterX * pixelCenterX + pixelCenterY * pixelCenterY; - - if (distSq <= outerRadiusSq && distSq >= innerRadiusSq) - { - float angle = (float) Math.atan2(pixelCenterY, pixelCenterX); - if (angle < 0) angle += (float) (Math.PI * 2); - - float diff = angle - startAngle; - if (diff < 0) diff += (float) (Math.PI * 2); - - if (diff < radsPerSegment) - { - float px = centerX + x; - float py = centerY + y; - - buf.vertex(pose, px, py, 0).color(r, g, b, a).endVertex(); - buf.vertex(pose, px, py + pixelSize, 0).color(r, g, b, a).endVertex(); - buf.vertex(pose, px + pixelSize, py + pixelSize, 0).color(r, g, b, a).endVertex(); - buf.vertex(pose, px + pixelSize, py, 0).color(r, g, b, a).endVertex(); - } - } - } + float px = quad.px(); + float py = quad.py(); + float size = quad.size(); + + buf.vertex(pose, px, py, 0).color(r, g, b, a).endVertex(); + buf.vertex(pose, px, py + size, 0).color(r, g, b, a).endVertex(); + buf.vertex(pose, px + size, py + size, 0).color(r, g, b, a).endVertex(); + buf.vertex(pose, px + size, py, 0).color(r, g, b, a).endVertex(); } tess.end(); @@ -373,6 +348,50 @@ else if (seconds > 0) pGuiGraphics.drawString(font, text, x+5, y+10+font.lineHeight+5, 0xFFFFFFFF); } + private void calculateVertexes(float centerX, float centerY, float innerRadius, float outerRadius, int segmentNr) + { + cachedQuads.clear(); + + float radsPerSegment = (float) Math.PI * 2 / 8; + float startAngle = segmentNr * radsPerSegment; + + float outerRadiusSq = outerRadius * outerRadius; + float innerRadiusSq = innerRadius * innerRadius; + + // Fetched once during construction + int pixelSize = AllomancyConfigs.CLIENT.pixelationAmount.get(); + int rInt = (int) Math.ceil(outerRadius); + + for (int x = -rInt; x <= rInt; x += pixelSize) + { + for (int y = -rInt; y <= rInt; y += pixelSize) + { + float pixelCenterX = x + (pixelSize / 2f); + float pixelCenterY = y + (pixelSize / 2f); + + float distSq = pixelCenterX * pixelCenterX + pixelCenterY * pixelCenterY; + + if (distSq <= outerRadiusSq && distSq >= innerRadiusSq) + { + float angle = (float) Math.atan2(pixelCenterY, pixelCenterX); + if (angle < 0) angle += (float) (Math.PI * 2); + + float diff = angle - startAngle; + if (diff < 0) diff += (float) (Math.PI * 2); + + if (diff < radsPerSegment) + { + float px = centerX + x; + float py = centerY + y; + + // Cache only what the render loop strictly needs + cachedQuads.add(new GuiUtils.CachedQuad(px, py, pixelSize)); + } + } + } + } + } + public float lerp(float start, float end, float pct) { return start + pct * (end - start); diff --git a/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/TriangleButton.java b/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/TriangleButton.java index 3f60ce6eb..31d978186 100644 --- a/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/TriangleButton.java +++ b/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/TriangleButton.java @@ -10,6 +10,7 @@ import leaf.cosmere.api.Metals; import leaf.cosmere.api.manifestation.Manifestation; import leaf.cosmere.api.spiritweb.ISpiritweb; +import leaf.cosmere.client.gui.GuiUtils; import leaf.cosmere.client.gui.SpiritwebMenu; import leaf.cosmere.common.Cosmere; import leaf.cosmere.common.network.packets.ChangeManifestationModeMessage; @@ -26,9 +27,12 @@ import org.lwjgl.opengl.GL11; import java.awt.*; +import java.util.ArrayList; +import java.util.List; public class TriangleButton extends Button { + private final List cachedQuads = new ArrayList<>(); private final ISpiritweb spiritweb; private final Manifestation manifestation; private final Metals.MetalType metal; @@ -43,13 +47,15 @@ public TriangleButton(int pX, int pY, int distance, float rotation, Metals.Metal this.metal = metal; manifestation = Manifestations.ManifestationTypes.FERUCHEMY.getManifestation(metal.getID()); hasManifestation = spiritweb.hasManifestation(manifestation); + + calculateVertexes(pX, pY, getWidth(), rotation); } @Override protected void renderWidget(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) { boolean isHover = isMouseOver(pMouseX, pMouseY); - renderDiamond(pGuiGraphics, isHover); + renderTriangle(pGuiGraphics, isHover); renderIcon(pGuiGraphics); if (isHover && hasManifestation) { @@ -111,9 +117,9 @@ public boolean mouseClicked(double pMouseX, double pMouseY, int pButton) return isMouseOver; } - private void renderDiamond(GuiGraphics pGuiGraphics, boolean isHovered) + private void renderTriangle(GuiGraphics pGuiGraphics, boolean isHovered) { - float r = 61/255.f, g = 70/255.f, b = 76/255.f; + float r = GuiUtils.BACKGROUND_COLOR.getRed()/255.f, g = GuiUtils.BACKGROUND_COLOR.getGreen()/255.f, b = GuiUtils.BACKGROUND_COLOR.getBlue()/255.f; float a = 1f; if (!hasManifestation) @@ -130,7 +136,8 @@ private void renderDiamond(GuiGraphics pGuiGraphics, boolean isHovered) b *= 1.1f; } - if (manifestation instanceof FeruchemyManifestation feruchemyManifestation) { + if (manifestation instanceof FeruchemyManifestation feruchemyManifestation) + { int mode = feruchemyManifestation.getMode(spiritweb); float intensity = 0; if (mode < 0) @@ -138,12 +145,15 @@ private void renderDiamond(GuiGraphics pGuiGraphics, boolean isHovered) if (mode > 0) intensity = Math.min(Math.abs(mode) * (1f/5f), 1.0f); - if (mode > 0) { + if (mode > 0) + { // Blend toward pure red r = lerp(r, 1.0f, intensity); g = lerp(g, 0.0f, intensity); b = lerp(b, 0.0f, intensity); - } else if (mode < 0) { + } + else if (mode < 0) + { // Blend toward pure blue r = lerp(r, 0.0f, intensity); g = lerp(g, 0.0f, intensity); @@ -163,39 +173,16 @@ private void renderDiamond(GuiGraphics pGuiGraphics, boolean isHovered) buf.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR); - float size = getWidth(); - float radius = size / 2.0f; - float centerX = getX() + radius; - float centerY = getY() + radius; - - int pixelSize = 1; - - int maxR = (int) Math.ceil(Math.sqrt(radius * radius + radius * radius)); - - float cos = (float) Math.cos(-rotation); - float sin = (float) Math.sin(-rotation); - - for (int x = -maxR; x <= maxR; x += pixelSize) + for (GuiUtils.CachedQuad quad : cachedQuads) { - for (int y = -maxR; y <= maxR; y += pixelSize) - { - float pixelCenterX = x + (pixelSize / 2f); - float pixelCenterY = y + (pixelSize / 2f); - - float px = pixelCenterX * cos - pixelCenterY * sin; - float py = pixelCenterX * sin + pixelCenterY * cos; - - if (px <= radius && py <= radius && px + py >= 0) - { - float screenX = centerX + x; - float screenY = centerY + y; - - buf.vertex(pose, screenX, screenY, 0).color(r,g,b,a).endVertex(); - buf.vertex(pose, screenX, screenY + pixelSize, 0).color(r,g,b,a).endVertex(); - buf.vertex(pose, screenX + pixelSize, screenY + pixelSize, 0).color(r,g,b,a).endVertex(); - buf.vertex(pose, screenX + pixelSize, screenY, 0).color(r,g,b,a).endVertex(); - } - } + float px = quad.px(); + float py = quad.py(); + float size = quad.size(); + + buf.vertex(pose, px, py, 0).color(r,g,b,a).endVertex(); + buf.vertex(pose, px, py + size, 0).color(r,g,b,a).endVertex(); + buf.vertex(pose, px + size, py + size, 0).color(r,g,b,a).endVertex(); + buf.vertex(pose, px + size, py, 0).color(r,g,b,a).endVertex(); } tess.end(); @@ -353,6 +340,37 @@ else if (seconds > 0) } } + private void calculateVertexes(float posX, float posY, float size, float rotation) + { + cachedQuads.clear(); + + float radius = size / 2.0f; + int pixelSize = 1; + float centerX = posX + radius; + float centerY = posY + radius; + int maxR = (int) Math.ceil(Math.sqrt(radius * radius + radius * radius)); + + float cos = (float) Math.cos(-rotation); + float sin = (float) Math.sin(-rotation); + + for (int x = -maxR; x <= maxR; x += pixelSize) + { + for (int y = -maxR; y <= maxR; y += pixelSize) + { + float pixelCenterX = x + (pixelSize / 2f); + float pixelCenterY = y + (pixelSize / 2f); + + float px = pixelCenterX * cos - pixelCenterY * sin; + float py = pixelCenterX * sin + pixelCenterY * cos; + + if (px <= radius && py <= radius && px + py >= 0) + { + cachedQuads.add(new GuiUtils.CachedQuad(centerX + x, centerY + y, pixelSize)); + } + } + } + } + public float lerp(float start, float end, float pct) { return start + pct * (end - start); } diff --git a/src/main/java/leaf/cosmere/client/gui/GuiUtils.java b/src/main/java/leaf/cosmere/client/gui/GuiUtils.java new file mode 100644 index 000000000..138437e1c --- /dev/null +++ b/src/main/java/leaf/cosmere/client/gui/GuiUtils.java @@ -0,0 +1,12 @@ +package leaf.cosmere.client.gui; + +import org.checkerframework.checker.units.qual.C; + +import java.awt.*; + +public class GuiUtils +{ + public static final Color BACKGROUND_COLOR = new Color(61, 70, 76); + + public record CachedQuad(float px, float py, float size) {} +} diff --git a/src/sandmastery/java/leaf/cosmere/sandmastery/client/gui/RadialButton.java b/src/sandmastery/java/leaf/cosmere/sandmastery/client/gui/RadialButton.java index 3a2f6c920..88b81aa44 100644 --- a/src/sandmastery/java/leaf/cosmere/sandmastery/client/gui/RadialButton.java +++ b/src/sandmastery/java/leaf/cosmere/sandmastery/client/gui/RadialButton.java @@ -6,6 +6,7 @@ import com.mojang.blaze3d.vertex.Tesselator; import com.mojang.blaze3d.vertex.VertexFormat; import leaf.cosmere.api.manifestation.Manifestation; +import leaf.cosmere.client.gui.GuiUtils; import leaf.cosmere.client.gui.SpiritwebMenu; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Font; @@ -18,8 +19,12 @@ import org.joml.Matrix4f; import org.lwjgl.opengl.GL11; +import java.util.ArrayList; +import java.util.List; + public class RadialButton extends Button { + private final List cachedQuads = new ArrayList<>(); private final int radius, centerX, centerY, segmentNr; private final float startAngle; private final float endAngle; @@ -36,6 +41,8 @@ protected RadialButton(int pX, int pY, int radius, int segmentNr, Manifestation float fifthCircle = (float) Math.toRadians(360d/5d); startAngle = (float) (fifthCircle*segmentNr); endAngle = startAngle + fifthCircle; + + calculateVertexes(centerX, centerY, radius, segmentNr); } @Override @@ -97,7 +104,7 @@ public void render(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPa private void renderRadial(GuiGraphics pGuiGraphics, boolean isHovered) { - float r = 61/255.f, g = 70/255.f, b = 76/255.f; + float r = GuiUtils.BACKGROUND_COLOR.getRed()/255.f, g = GuiUtils.BACKGROUND_COLOR.getGreen()/255.f, b = GuiUtils.BACKGROUND_COLOR.getBlue()/255.f; float a = 1f; if (isHovered) @@ -107,12 +114,6 @@ private void renderRadial(GuiGraphics pGuiGraphics, boolean isHovered) b *= 1.1f; } - float radsPerSegment = (float) Math.PI * 2 / 5; - float startAngle = segmentNr * radsPerSegment; - float radiusSq = radius * radius; - - int pixelSize = 1; - RenderSystem.disableCull(); RenderSystem.enableBlend(); RenderSystem.defaultBlendFunc(); @@ -124,35 +125,16 @@ private void renderRadial(GuiGraphics pGuiGraphics, boolean isHovered) buf.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR); - for (int x = -radius; x <= radius; x += pixelSize) + for (GuiUtils.CachedQuad quad : cachedQuads) { - for (int y = -radius; y <= radius; y += pixelSize) - { - float pixelCenterX = x + (pixelSize / 2f); - float pixelCenterY = y + (pixelSize / 2f); - - float distSq = pixelCenterX * pixelCenterX + pixelCenterY * pixelCenterY; - - if (distSq <= radiusSq) - { - float angle = (float) Math.atan2(pixelCenterY, pixelCenterX); - if (angle < 0) angle += (float) (Math.PI * 2); - - float diff = angle - startAngle; - if (diff < 0) diff += (float) (Math.PI * 2); - - if (diff < radsPerSegment) - { - float px = centerX + x; - float py = centerY + y; - - buf.vertex(pose, px, py, 0).color(r, g, b, a).endVertex(); - buf.vertex(pose, px, py + pixelSize, 0).color(r, g, b, a).endVertex(); - buf.vertex(pose, px + pixelSize, py + pixelSize, 0).color(r, g, b, a).endVertex(); - buf.vertex(pose, px + pixelSize, py, 0).color(r, g, b, a).endVertex(); - } - } - } + float px = quad.px(); + float py = quad.py(); + float size = quad.size(); + + buf.vertex(pose, px, py, 0).color(r, g, b, a).endVertex(); + buf.vertex(pose, px, py + size, 0).color(r, g, b, a).endVertex(); + buf.vertex(pose, px + size, py + size, 0).color(r, g, b, a).endVertex(); + buf.vertex(pose, px + size, py, 0).color(r, g, b, a).endVertex(); } tess.end(); @@ -227,6 +209,43 @@ private void renderInfoBlock(GuiGraphics pGuiGraphics) pGuiGraphics.drawCenteredString(font, text, textCenterX, drawY, 0xFFFFFF); } + private void calculateVertexes(float centerX, float centerY, float radius, int segmentNr) + { + cachedQuads.clear(); + + float radsPerSegment = (float) Math.PI * 2 / 5; + float startAngle = segmentNr * radsPerSegment; + float radiusSq = radius * radius; + + int pixelSize = 1; + int rInt = (int) Math.ceil(radius); + + for (int x = -rInt; x <= rInt; x += pixelSize) + { + for (int y = -rInt; y <= rInt; y += pixelSize) + { + float pixelCenterX = x + (pixelSize / 2f); + float pixelCenterY = y + (pixelSize / 2f); + + float distSq = pixelCenterX * pixelCenterX + pixelCenterY * pixelCenterY; + + if (distSq <= radiusSq) + { + float angle = (float) Math.atan2(pixelCenterY, pixelCenterX); + if (angle < 0) angle += (float) (Math.PI * 2); + + float diff = angle - startAngle; + if (diff < 0) diff += (float) (Math.PI * 2); + + if (diff < radsPerSegment) + { + cachedQuads.add(new GuiUtils.CachedQuad(centerX + x, centerY + y, pixelSize)); + } + } + } + } + } + private double normalizeAngle(double angle) { if (angle != 0) diff --git a/src/surgebinding/java/leaf/cosmere/surgebinding/client/gui/CircleButton.java b/src/surgebinding/java/leaf/cosmere/surgebinding/client/gui/CircleButton.java index d2a9965b5..08910534f 100644 --- a/src/surgebinding/java/leaf/cosmere/surgebinding/client/gui/CircleButton.java +++ b/src/surgebinding/java/leaf/cosmere/surgebinding/client/gui/CircleButton.java @@ -7,6 +7,7 @@ import com.mojang.blaze3d.vertex.VertexFormat; import leaf.cosmere.api.manifestation.Manifestation; import leaf.cosmere.api.spiritweb.ISpiritweb; +import leaf.cosmere.client.gui.GuiUtils; import leaf.cosmere.client.gui.SpiritwebMenu; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Font; @@ -19,14 +20,18 @@ import org.joml.Matrix4f; import org.lwjgl.opengl.GL11; +import java.util.ArrayList; +import java.util.List; + public class CircleButton extends Button { + private final List cachedQuads = new ArrayList<>(); final ISpiritweb spiritweb; final Manifestation manifestation; final int centerX, centerY; final int radius; - protected CircleButton(int pX, int pY, int radius, ISpiritweb spiritweb, Manifestation manifestation) + public CircleButton(int pX, int pY, int radius, ISpiritweb spiritweb, Manifestation manifestation) { super(pX, pY, radius, radius, CommonComponents.EMPTY, (button) -> { }, DEFAULT_NARRATION); @@ -35,6 +40,8 @@ protected CircleButton(int pX, int pY, int radius, ISpiritweb spiritweb, Manifes this.centerY = pY; this.radius = radius; this.manifestation = manifestation; + + calculateVertexes(centerX, centerY, radius); } @Override @@ -68,18 +75,16 @@ public void render(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPa private void renderCircle(GuiGraphics pGuiGraphics, boolean isHovered) { - float r = 61/255.f, g = 70/255.f, b = 76/255.f; + float r = GuiUtils.BACKGROUND_COLOR.getRed()/255.f, g = GuiUtils.BACKGROUND_COLOR.getGreen()/255.f, b = GuiUtils.BACKGROUND_COLOR.getBlue()/255.f; float a = 1f; - if (isHovered) { + if (isHovered) + { r *= 1.1f; g *= 1.1f; b *= 1.1f; } - float radiusSq = radius * radius; - int pixelSize = 1; - RenderSystem.disableCull(); RenderSystem.enableBlend(); RenderSystem.defaultBlendFunc(); @@ -91,21 +96,16 @@ private void renderCircle(GuiGraphics pGuiGraphics, boolean isHovered) buf.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR); - for (int x = -radius; x <= radius; x += pixelSize) { - for (int y = -radius; y <= radius; y += pixelSize) { - float pixelCenterX = x + (pixelSize / 2f); - float pixelCenterY = y + (pixelSize / 2f); - - if ((pixelCenterX * pixelCenterX + pixelCenterY * pixelCenterY) <= radiusSq) { - float px = centerX + x; - float py = centerY + y; - - buf.vertex(pose, px, py, 0).color(r, g, b, a).endVertex(); - buf.vertex(pose, px, py + pixelSize, 0).color(r, g, b, a).endVertex(); - buf.vertex(pose, px + pixelSize, py + pixelSize, 0).color(r, g, b, a).endVertex(); - buf.vertex(pose, px + pixelSize, py, 0).color(r, g, b, a).endVertex(); - } - } + for (GuiUtils.CachedQuad quad : cachedQuads) + { + float px = quad.px(); + float py = quad.py(); + float size = quad.size(); + + buf.vertex(pose, px, py, 0).color(r, g, b, a).endVertex(); + buf.vertex(pose, px, py + size, 0).color(r, g, b, a).endVertex(); + buf.vertex(pose, px + size, py + size, 0).color(r, g, b, a).endVertex(); + buf.vertex(pose, px + size, py, 0).color(r, g, b, a).endVertex(); } tess.end(); @@ -181,4 +181,26 @@ private void renderText(GuiGraphics pGuiGraphics) pGuiGraphics.drawString(font, text, x, y-font.lineHeight/2, 0xFFFFFFFF); } + + private void calculateVertexes(float centerX, float centerY, int radius) + { + cachedQuads.clear(); + + float radiusSq = radius * radius; + int pixelSize = 1; + + for (int x = -radius; x <= radius; x += pixelSize) + { + for (int y = -radius; y <= radius; y += pixelSize) + { + float pixelCenterX = x + (pixelSize / 2f); + float pixelCenterY = y + (pixelSize / 2f); + + if ((pixelCenterX * pixelCenterX + pixelCenterY * pixelCenterY) <= radiusSq) + { + cachedQuads.add(new GuiUtils.CachedQuad(centerX + x, centerY + y, pixelSize)); + } + } + } + } } From 758c70d4ce10f208993960809304c0507c0707cf Mon Sep 17 00:00:00 2001 From: Gerbagel Date: Sat, 2 May 2026 16:08:23 +0200 Subject: [PATCH 41/55] [Cosmere] Don't get static resources every frame --- .../client/gui/AllomancySpiritwebMenu.java | 7 ++-- .../client/gui/InnerRadialButton.java | 36 ++++++++++--------- .../client/gui/OuterRadialButton.java | 36 ++++++++++--------- .../client/gui/FeruchemySpiritwebMenu.java | 7 ++-- .../feruchemy/client/gui/TriangleButton.java | 36 ++++++++++--------- .../cosmere/client/gui/SpiritwebRegistry.java | 2 +- .../sandmastery/client/gui/RadialButton.java | 22 ++++++------ .../surgebinding/client/gui/CircleButton.java | 28 ++++++++------- 8 files changed, 91 insertions(+), 83 deletions(-) diff --git a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/AllomancySpiritwebMenu.java b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/AllomancySpiritwebMenu.java index 048d575d9..5f2beee0a 100644 --- a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/AllomancySpiritwebMenu.java +++ b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/AllomancySpiritwebMenu.java @@ -14,6 +14,7 @@ public class AllomancySpiritwebMenu extends CosmereScreen { + private static final ResourceLocation BORDER_LOCATION = new ResourceLocation(Allomancy.MODID, "textures/gui/allo_border.png"); LocalPlayer player; public AllomancySpiritwebMenu() { @@ -75,9 +76,7 @@ public void render(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPa private void renderBorder(GuiGraphics pGuiGraphics) { - final ResourceLocation location = new ResourceLocation(Allomancy.MODID, "textures/gui/allo_border.png"); - - RenderSystem.setShaderTexture(0, location); + RenderSystem.setShaderTexture(0, BORDER_LOCATION); RenderSystem.enableBlend(); RenderSystem.blendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, 1, 0); RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f); @@ -86,7 +85,7 @@ private void renderBorder(GuiGraphics pGuiGraphics) final int x = width/2 - diameter/2, y = height/2 - diameter/2 + height/16; final int iconSize = 256; - pGuiGraphics.blit(location, + pGuiGraphics.blit(BORDER_LOCATION, x, y, diameter, diff --git a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java index 2c45a8923..b393807bc 100644 --- a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java +++ b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java @@ -34,6 +34,7 @@ public class InnerRadialButton extends Button { + private final ResourceLocation iconLocation; private final List cachedQuads = new ArrayList<>(); private final float outerRadius; private final float innerRadius; @@ -64,6 +65,21 @@ protected InnerRadialButton(int centerX, int centerY, int segmentNr, Metals.Meta outerRadius = (float) Minecraft.getInstance().getWindow().getGuiScaledHeight() / 3f * 0.7f; innerRadius = 0; + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.setLength(0); + stringBuilder.append("textures/icon/") + .append(manifestation.getManifestationType().getName()) + .append("/"); + + // no need for a switch case, always allomancy + if (manifestation instanceof IHasMetalType metalType) + { + stringBuilder.append(metalType.getMetalType().getName()); + } + + stringBuilder.append(".png"); + iconLocation = new ResourceLocation(manifestation.getRegistryName().getNamespace(), stringBuilder.toString()); + calculateVertexes(this.centerX, this.centerY, outerRadius, segmentNr); } @@ -227,22 +243,8 @@ private void renderIcon(@NotNull GuiGraphics pGuiGraphics) b *= 0.1f; } - StringBuilder stringBuilder = new StringBuilder(); - stringBuilder.setLength(0); - stringBuilder.append("textures/icon/") - .append(manifestation.getManifestationType().getName()) - .append("/"); - - // no need for a switch case, always allomancy - if (manifestation instanceof IHasMetalType metalType) - { - stringBuilder.append(metalType.getMetalType().getName()); - } - - stringBuilder.append(".png"); - final ResourceLocation location = new ResourceLocation(manifestation.getRegistryName().getNamespace(), stringBuilder.toString()); float alpha = hasManifestation ? 1.0f : 0.25f; - RenderSystem.setShaderTexture(0, location); + RenderSystem.setShaderTexture(0, iconLocation); RenderSystem.enableBlend(); RenderSystem.blendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, 1, 0); @@ -253,7 +255,7 @@ private void renderIcon(@NotNull GuiGraphics pGuiGraphics) int posY = centerY + (int)(Math.sin(midAngle) * midRadius) - iconSize/2; RenderSystem.setShaderColor(0f, 0f, 0f, alpha); - pGuiGraphics.blit(location, + pGuiGraphics.blit(iconLocation, posX+1, posY+1, iconSize, @@ -266,7 +268,7 @@ private void renderIcon(@NotNull GuiGraphics pGuiGraphics) height); RenderSystem.setShaderColor(r, g, b, alpha); - pGuiGraphics.blit(location, + pGuiGraphics.blit(iconLocation, posX, posY, iconSize, diff --git a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java index a268ca431..0005f2491 100644 --- a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java +++ b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java @@ -35,6 +35,7 @@ public class OuterRadialButton extends Button { + private final ResourceLocation iconLocation; private final List cachedQuads = new ArrayList<>(); private final float outerRadius; private final float innerRadius; @@ -65,6 +66,21 @@ protected OuterRadialButton(int centerX, int centerY, int segmentNr, Metals.Meta outerRadius = (float) Minecraft.getInstance().getWindow().getGuiScaledHeight() / 3; innerRadius = outerRadius * 0.7f; + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.setLength(0); + stringBuilder.append("textures/icon/") + .append(manifestation.getManifestationType().getName()) + .append("/"); + + // no need for a switch case, always allomancy + if (manifestation instanceof IHasMetalType metalType) + { + stringBuilder.append(metalType.getMetalType().getName()); + } + + stringBuilder.append(".png"); + iconLocation = new ResourceLocation(manifestation.getRegistryName().getNamespace(), stringBuilder.toString()); + calculateVertexes(this.centerX, this.centerY, innerRadius, outerRadius, segmentNr); } @@ -231,22 +247,8 @@ private void renderIcon(@NotNull GuiGraphics pGuiGraphics) b *= 0.1f; } - StringBuilder stringBuilder = new StringBuilder(); - stringBuilder.setLength(0); - stringBuilder.append("textures/icon/") - .append(manifestation.getManifestationType().getName()) - .append("/"); - - // no need for a switch case, always allomancy - if (manifestation instanceof IHasMetalType metalType) - { - stringBuilder.append(metalType.getMetalType().getName()); - } - - stringBuilder.append(".png"); - final ResourceLocation location = new ResourceLocation(manifestation.getRegistryName().getNamespace(), stringBuilder.toString()); float alpha = hasManifestation ? 1.0f : 0.25f; - RenderSystem.setShaderTexture(0, location); + RenderSystem.setShaderTexture(0, iconLocation); RenderSystem.enableBlend(); RenderSystem.blendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, 1, 0); @@ -258,7 +260,7 @@ private void renderIcon(@NotNull GuiGraphics pGuiGraphics) int posY = centerY + (int)(Math.sin(midAngle) * midRadius) - iconSize/2; RenderSystem.setShaderColor(0f, 0f, 0f, alpha); - pGuiGraphics.blit(location, + pGuiGraphics.blit(iconLocation, posX+1, posY+1, iconSize, @@ -271,7 +273,7 @@ private void renderIcon(@NotNull GuiGraphics pGuiGraphics) height); RenderSystem.setShaderColor(r, g, b, alpha); - pGuiGraphics.blit(location, + pGuiGraphics.blit(iconLocation, posX, posY, iconSize, diff --git a/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/FeruchemySpiritwebMenu.java b/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/FeruchemySpiritwebMenu.java index 09ad9500a..dd6e4dd20 100644 --- a/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/FeruchemySpiritwebMenu.java +++ b/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/FeruchemySpiritwebMenu.java @@ -14,6 +14,7 @@ public class FeruchemySpiritwebMenu extends CosmereScreen { + private static final ResourceLocation BORDER_LOCATION = new ResourceLocation(Feruchemy.MODID, "textures/gui/feru_border.png"); private static final float QUARTER_PI_F = (float) (Math.PI/2.f); private int distance; final LocalPlayer player; @@ -92,9 +93,7 @@ public void render(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPa private void renderBorder(GuiGraphics pGuiGraphics) { - final ResourceLocation location = new ResourceLocation(Feruchemy.MODID, "textures/gui/feru_border.png"); - - RenderSystem.setShaderTexture(0, location); + RenderSystem.setShaderTexture(0, BORDER_LOCATION); RenderSystem.enableBlend(); RenderSystem.blendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, 1, 0); RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f); @@ -103,7 +102,7 @@ private void renderBorder(GuiGraphics pGuiGraphics) final int screenSize = distance*4; final int iconSize = 256; - pGuiGraphics.blit(location, + pGuiGraphics.blit(BORDER_LOCATION, x, y, screenSize, diff --git a/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/TriangleButton.java b/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/TriangleButton.java index 31d978186..a1cc53cfe 100644 --- a/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/TriangleButton.java +++ b/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/TriangleButton.java @@ -32,6 +32,7 @@ public class TriangleButton extends Button { + private final ResourceLocation iconLocation; private final List cachedQuads = new ArrayList<>(); private final ISpiritweb spiritweb; private final Manifestation manifestation; @@ -48,6 +49,21 @@ public TriangleButton(int pX, int pY, int distance, float rotation, Metals.Metal manifestation = Manifestations.ManifestationTypes.FERUCHEMY.getManifestation(metal.getID()); hasManifestation = spiritweb.hasManifestation(manifestation); + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.setLength(0); + stringBuilder.append("textures/icon/") + .append(manifestation.getManifestationType().getName()) + .append("/"); + + // no need for a switch case, always allomancy + if (manifestation instanceof IHasMetalType metalType) + { + stringBuilder.append(metalType.getMetalType().getName()); + } + + stringBuilder.append(".png"); + iconLocation = new ResourceLocation(manifestation.getRegistryName().getNamespace(), stringBuilder.toString()); + calculateVertexes(pX, pY, getWidth(), rotation); } @@ -201,22 +217,8 @@ private void renderIcon(GuiGraphics pGuiGraphics) b *= 0.1f; } - StringBuilder stringBuilder = new StringBuilder(); - stringBuilder.setLength(0); - stringBuilder.append("textures/icon/") - .append(manifestation.getManifestationType().getName()) - .append("/"); - - // no need for a switch case, always allomancy - if (manifestation instanceof IHasMetalType metalType) - { - stringBuilder.append(metalType.getMetalType().getName()); - } - - stringBuilder.append(".png"); - final ResourceLocation location = new ResourceLocation(manifestation.getRegistryName().getNamespace(), stringBuilder.toString()); float alpha = hasManifestation ? 1.0f : 0.25f; - RenderSystem.setShaderTexture(0, location); + RenderSystem.setShaderTexture(0, iconLocation); RenderSystem.enableBlend(); RenderSystem.blendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, 1, 0); @@ -236,7 +238,7 @@ private void renderIcon(GuiGraphics pGuiGraphics) int posY = (int) (centerY + localCx * sin + localCy * cos) - iconSize / 2; RenderSystem.setShaderColor(0f, 0f, 0f, alpha); - pGuiGraphics.blit(location, + pGuiGraphics.blit(iconLocation, posX + 1, posY + 1, iconSize, @@ -249,7 +251,7 @@ private void renderIcon(GuiGraphics pGuiGraphics) height); RenderSystem.setShaderColor(r, g, b, alpha); - pGuiGraphics.blit(location, + pGuiGraphics.blit(iconLocation, posX, posY, iconSize, diff --git a/src/main/java/leaf/cosmere/client/gui/SpiritwebRegistry.java b/src/main/java/leaf/cosmere/client/gui/SpiritwebRegistry.java index 864e52bfb..692482149 100644 --- a/src/main/java/leaf/cosmere/client/gui/SpiritwebRegistry.java +++ b/src/main/java/leaf/cosmere/client/gui/SpiritwebRegistry.java @@ -8,7 +8,7 @@ public class SpiritwebRegistry { - private static SpiritwebRegistry INSTANCE; + private static volatile SpiritwebRegistry INSTANCE; private final HashMap> manifestationScreenMap = new HashMap<>(); public static SpiritwebRegistry getInstance() diff --git a/src/sandmastery/java/leaf/cosmere/sandmastery/client/gui/RadialButton.java b/src/sandmastery/java/leaf/cosmere/sandmastery/client/gui/RadialButton.java index 88b81aa44..9fe577233 100644 --- a/src/sandmastery/java/leaf/cosmere/sandmastery/client/gui/RadialButton.java +++ b/src/sandmastery/java/leaf/cosmere/sandmastery/client/gui/RadialButton.java @@ -24,6 +24,7 @@ public class RadialButton extends Button { + private final ResourceLocation iconLocation; private final List cachedQuads = new ArrayList<>(); private final int radius, centerX, centerY, segmentNr; private final float startAngle; @@ -42,6 +43,14 @@ protected RadialButton(int pX, int pY, int radius, int segmentNr, Manifestation startAngle = (float) (fifthCircle*segmentNr); endAngle = startAngle + fifthCircle; + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.setLength(0); + stringBuilder.append("textures/icon/") + .append(manifestation.getManifestationType().getName()) + .append("/.png"); + + iconLocation = new ResourceLocation(manifestation.getRegistryName().getNamespace(), stringBuilder.toString()); + calculateVertexes(centerX, centerY, radius, segmentNr); } @@ -143,15 +152,8 @@ private void renderRadial(GuiGraphics pGuiGraphics, boolean isHovered) private void renderIcon(GuiGraphics pGuiGraphics) { - StringBuilder stringBuilder = new StringBuilder(); - stringBuilder.setLength(0); - stringBuilder.append("textures/icon/") - .append(manifestation.getManifestationType().getName()) - .append("/.png"); - - final ResourceLocation location = new ResourceLocation(manifestation.getRegistryName().getNamespace(), stringBuilder.toString()); float alpha = 1.0f; - RenderSystem.setShaderTexture(0, location); + RenderSystem.setShaderTexture(0, iconLocation); RenderSystem.enableBlend(); RenderSystem.blendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, 1, 0); @@ -162,7 +164,7 @@ private void renderIcon(GuiGraphics pGuiGraphics) int posY = centerY + (int)(Math.sin(midAngle) * midRadius) - iconSize/2; RenderSystem.setShaderColor(0f, 0f, 0f, alpha); - pGuiGraphics.blit(location, + pGuiGraphics.blit(iconLocation, posX+1, posY+1, iconSize, @@ -175,7 +177,7 @@ private void renderIcon(GuiGraphics pGuiGraphics) height); RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, alpha); - pGuiGraphics.blit(location, + pGuiGraphics.blit(iconLocation, posX, posY, iconSize, diff --git a/src/surgebinding/java/leaf/cosmere/surgebinding/client/gui/CircleButton.java b/src/surgebinding/java/leaf/cosmere/surgebinding/client/gui/CircleButton.java index 08910534f..15f5f0848 100644 --- a/src/surgebinding/java/leaf/cosmere/surgebinding/client/gui/CircleButton.java +++ b/src/surgebinding/java/leaf/cosmere/surgebinding/client/gui/CircleButton.java @@ -25,6 +25,7 @@ public class CircleButton extends Button { + private final ResourceLocation iconLocation; private final List cachedQuads = new ArrayList<>(); final ISpiritweb spiritweb; final Manifestation manifestation; @@ -41,6 +42,17 @@ public CircleButton(int pX, int pY, int radius, ISpiritweb spiritweb, Manifestat this.radius = radius; this.manifestation = manifestation; + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.setLength(0); + stringBuilder.append("textures/icon/") + .append(manifestation.getManifestationType().getName()) + .append("/"); + + stringBuilder.append(manifestation.getName()); + stringBuilder.append(".png"); + + iconLocation = new ResourceLocation(manifestation.getRegistryName().getNamespace(), stringBuilder.toString()); + calculateVertexes(centerX, centerY, radius); } @@ -114,18 +126,8 @@ private void renderCircle(GuiGraphics pGuiGraphics, boolean isHovered) public void renderIcon(GuiGraphics pGuiGraphics) { - StringBuilder stringBuilder = new StringBuilder(); - stringBuilder.setLength(0); - stringBuilder.append("textures/icon/") - .append(manifestation.getManifestationType().getName()) - .append("/"); - - stringBuilder.append(manifestation.getName()); - stringBuilder.append(".png"); - - final ResourceLocation location = new ResourceLocation(manifestation.getRegistryName().getNamespace(), stringBuilder.toString()); float alpha = 1.0f; - RenderSystem.setShaderTexture(0, location); + RenderSystem.setShaderTexture(0, iconLocation); RenderSystem.enableBlend(); RenderSystem.blendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, 1, 0); @@ -134,7 +136,7 @@ public void renderIcon(GuiGraphics pGuiGraphics) int posY = centerY - iconSize/2; RenderSystem.setShaderColor(0f, 0f, 0f, alpha); - pGuiGraphics.blit(location, + pGuiGraphics.blit(iconLocation, posX+1, posY+1, iconSize, @@ -147,7 +149,7 @@ public void renderIcon(GuiGraphics pGuiGraphics) height); RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, alpha); - pGuiGraphics.blit(location, + pGuiGraphics.blit(iconLocation, posX, posY, iconSize, From 72b28a6d724efa37afbab110dc298d107f284d70 Mon Sep 17 00:00:00 2001 From: Gerbagel Date: Sat, 2 May 2026 16:27:59 +0200 Subject: [PATCH 42/55] [Cosmere] Added callback for selected manifestation --- .../client/gui/AllomancySpiritwebMenu.java | 35 ++++++++++--------- .../client/gui/InnerRadialButton.java | 8 +++-- .../client/gui/OuterRadialButton.java | 8 +++-- .../client/gui/FeruchemySpiritwebMenu.java | 35 ++++++++++--------- .../feruchemy/client/gui/TriangleButton.java | 8 +++-- .../cosmere/client/gui/CosmereScreen.java | 7 +++- .../cosmere/client/gui/SpiritwebMenu.java | 11 ++++-- .../sandmastery/client/gui/RadialButton.java | 9 +++-- .../client/gui/SandmasterySpiritwebMenu.java | 5 +-- .../surgebinding/client/gui/CircleButton.java | 8 +++-- .../client/gui/SurgebindingSpiritwebMenu.java | 5 +-- 11 files changed, 88 insertions(+), 51 deletions(-) diff --git a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/AllomancySpiritwebMenu.java b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/AllomancySpiritwebMenu.java index 5f2beee0a..fe48dd82d 100644 --- a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/AllomancySpiritwebMenu.java +++ b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/AllomancySpiritwebMenu.java @@ -4,6 +4,7 @@ import leaf.cosmere.allomancy.common.Allomancy; import leaf.cosmere.api.Metals; import leaf.cosmere.client.gui.CosmereScreen; +import leaf.cosmere.client.gui.SpiritwebMenu; import leaf.cosmere.common.cap.entity.SpiritwebCapability; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; @@ -18,7 +19,7 @@ public class AllomancySpiritwebMenu extends CosmereScreen LocalPlayer player; public AllomancySpiritwebMenu() { - super(Component.literal("Allomancy")); + super(Component.literal("Allomancy"), SpiritwebMenu::selectManiCallback); player = Minecraft.getInstance().player; } @@ -32,38 +33,38 @@ protected void init() int circleCenterY = height/2 + height/16; // heh, 16, nice // Steel - addRenderableWidget(new OuterRadialButton(circleCenterX, circleCenterY, 4, Metals.MetalType.STEEL, iSpiritweb)); + addRenderableWidget(new OuterRadialButton(circleCenterX, circleCenterY, 4, Metals.MetalType.STEEL, iSpiritweb, manifestationConsumer)); // Iron - addRenderableWidget(new OuterRadialButton(circleCenterX, circleCenterY, 5, Metals.MetalType.IRON, iSpiritweb)); + addRenderableWidget(new OuterRadialButton(circleCenterX, circleCenterY, 5, Metals.MetalType.IRON, iSpiritweb, manifestationConsumer)); // Zinc - addRenderableWidget(new OuterRadialButton(circleCenterX, circleCenterY, 6, Metals.MetalType.ZINC, iSpiritweb)); + addRenderableWidget(new OuterRadialButton(circleCenterX, circleCenterY, 6, Metals.MetalType.ZINC, iSpiritweb, manifestationConsumer)); // Brass - addRenderableWidget(new OuterRadialButton(circleCenterX, circleCenterY, 7, Metals.MetalType.BRASS, iSpiritweb)); + addRenderableWidget(new OuterRadialButton(circleCenterX, circleCenterY, 7, Metals.MetalType.BRASS, iSpiritweb, manifestationConsumer)); // Bendalloy - addRenderableWidget(new OuterRadialButton(circleCenterX, circleCenterY, 0, Metals.MetalType.BENDALLOY, iSpiritweb)); + addRenderableWidget(new OuterRadialButton(circleCenterX, circleCenterY, 0, Metals.MetalType.BENDALLOY, iSpiritweb, manifestationConsumer)); // Cadmium - addRenderableWidget(new OuterRadialButton(circleCenterX, circleCenterY, 1, Metals.MetalType.CADMIUM, iSpiritweb)); + addRenderableWidget(new OuterRadialButton(circleCenterX, circleCenterY, 1, Metals.MetalType.CADMIUM, iSpiritweb, manifestationConsumer)); // Chromium - addRenderableWidget(new OuterRadialButton(circleCenterX, circleCenterY, 2, Metals.MetalType.CHROMIUM, iSpiritweb)); + addRenderableWidget(new OuterRadialButton(circleCenterX, circleCenterY, 2, Metals.MetalType.CHROMIUM, iSpiritweb, manifestationConsumer)); // Nicrosil - addRenderableWidget(new OuterRadialButton(circleCenterX, circleCenterY, 3, Metals.MetalType.NICROSIL, iSpiritweb)); + addRenderableWidget(new OuterRadialButton(circleCenterX, circleCenterY, 3, Metals.MetalType.NICROSIL, iSpiritweb, manifestationConsumer)); // Pewter - addRenderableWidget(new InnerRadialButton(circleCenterX, circleCenterY, 4, Metals.MetalType.PEWTER, iSpiritweb)); + addRenderableWidget(new InnerRadialButton(circleCenterX, circleCenterY, 4, Metals.MetalType.PEWTER, iSpiritweb, manifestationConsumer)); // Tin - addRenderableWidget(new InnerRadialButton(circleCenterX, circleCenterY, 5, Metals.MetalType.TIN, iSpiritweb)); + addRenderableWidget(new InnerRadialButton(circleCenterX, circleCenterY, 5, Metals.MetalType.TIN, iSpiritweb, manifestationConsumer)); // Copper - addRenderableWidget(new InnerRadialButton(circleCenterX, circleCenterY, 6, Metals.MetalType.COPPER, iSpiritweb)); + addRenderableWidget(new InnerRadialButton(circleCenterX, circleCenterY, 6, Metals.MetalType.COPPER, iSpiritweb, manifestationConsumer)); // Bronze - addRenderableWidget(new InnerRadialButton(circleCenterX, circleCenterY, 7, Metals.MetalType.BRONZE, iSpiritweb)); + addRenderableWidget(new InnerRadialButton(circleCenterX, circleCenterY, 7, Metals.MetalType.BRONZE, iSpiritweb, manifestationConsumer)); // Electrum - addRenderableWidget(new InnerRadialButton(circleCenterX, circleCenterY, 0, Metals.MetalType.ELECTRUM, iSpiritweb)); + addRenderableWidget(new InnerRadialButton(circleCenterX, circleCenterY, 0, Metals.MetalType.ELECTRUM, iSpiritweb, manifestationConsumer)); // Gold - addRenderableWidget(new InnerRadialButton(circleCenterX, circleCenterY, 1, Metals.MetalType.GOLD, iSpiritweb)); + addRenderableWidget(new InnerRadialButton(circleCenterX, circleCenterY, 1, Metals.MetalType.GOLD, iSpiritweb, manifestationConsumer)); // Aluminum - addRenderableWidget(new InnerRadialButton(circleCenterX, circleCenterY, 2, Metals.MetalType.ALUMINUM, iSpiritweb)); + addRenderableWidget(new InnerRadialButton(circleCenterX, circleCenterY, 2, Metals.MetalType.ALUMINUM, iSpiritweb, manifestationConsumer)); // Duralumin - addRenderableWidget(new InnerRadialButton(circleCenterX, circleCenterY, 3, Metals.MetalType.DURALUMIN, iSpiritweb)); + addRenderableWidget(new InnerRadialButton(circleCenterX, circleCenterY, 3, Metals.MetalType.DURALUMIN, iSpiritweb, manifestationConsumer)); })); } diff --git a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java index b393807bc..b5b71b9d4 100644 --- a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java +++ b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java @@ -31,11 +31,13 @@ import java.awt.*; import java.util.ArrayList; import java.util.List; +import java.util.function.Consumer; public class InnerRadialButton extends Button { private final ResourceLocation iconLocation; private final List cachedQuads = new ArrayList<>(); + private final Consumer manifestationConsumer; private final float outerRadius; private final float innerRadius; private final double startAngle; @@ -48,7 +50,7 @@ public class InnerRadialButton extends Button private final ISpiritweb spiritweb; private final Metals.MetalType metalType; - protected InnerRadialButton(int centerX, int centerY, int segmentNr, Metals.MetalType metal, ISpiritweb spiritweb) + protected InnerRadialButton(int centerX, int centerY, int segmentNr, Metals.MetalType metal, ISpiritweb spiritweb, Consumer maniConsumer) { super(centerX, centerY, 16, 16, CommonComponents.EMPTY, (button) -> {}, DEFAULT_NARRATION); this.spiritweb = spiritweb; @@ -80,6 +82,8 @@ protected InnerRadialButton(int centerX, int centerY, int segmentNr, Metals.Meta stringBuilder.append(".png"); iconLocation = new ResourceLocation(manifestation.getRegistryName().getNamespace(), stringBuilder.toString()); + manifestationConsumer = maniConsumer; + calculateVertexes(this.centerX, this.centerY, outerRadius, segmentNr); } @@ -132,7 +136,7 @@ public boolean isMouseOver(double mouseX, double mouseY) { if (retVal) { - SpiritwebMenu.selectedManifestation = manifestation; + manifestationConsumer.accept(manifestation); } } diff --git a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java index 0005f2491..93193e891 100644 --- a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java +++ b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java @@ -32,11 +32,13 @@ import java.awt.Color; import java.util.ArrayList; import java.util.List; +import java.util.function.Consumer; public class OuterRadialButton extends Button { private final ResourceLocation iconLocation; private final List cachedQuads = new ArrayList<>(); + private final Consumer manifestationConsumer; private final float outerRadius; private final float innerRadius; private final double startAngle; @@ -49,7 +51,7 @@ public class OuterRadialButton extends Button private final ISpiritweb spiritweb; private final Metals.MetalType metalType; - protected OuterRadialButton(int centerX, int centerY, int segmentNr, Metals.MetalType metal, ISpiritweb spiritweb) + protected OuterRadialButton(int centerX, int centerY, int segmentNr, Metals.MetalType metal, ISpiritweb spiritweb, Consumer maniConsumer) { super(centerX, centerY, 16, 16, CommonComponents.EMPTY, (button) -> {}, DEFAULT_NARRATION); this.spiritweb = spiritweb; @@ -81,6 +83,8 @@ protected OuterRadialButton(int centerX, int centerY, int segmentNr, Metals.Meta stringBuilder.append(".png"); iconLocation = new ResourceLocation(manifestation.getRegistryName().getNamespace(), stringBuilder.toString()); + manifestationConsumer = maniConsumer; + calculateVertexes(this.centerX, this.centerY, innerRadius, outerRadius, segmentNr); } @@ -130,7 +134,7 @@ public boolean isMouseOver(double mouseX, double mouseY) { if (retVal) { - SpiritwebMenu.selectedManifestation = manifestation; + manifestationConsumer.accept(manifestation); } } diff --git a/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/FeruchemySpiritwebMenu.java b/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/FeruchemySpiritwebMenu.java index dd6e4dd20..3b5f21ba6 100644 --- a/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/FeruchemySpiritwebMenu.java +++ b/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/FeruchemySpiritwebMenu.java @@ -3,6 +3,7 @@ import com.mojang.blaze3d.systems.RenderSystem; import leaf.cosmere.api.Metals; import leaf.cosmere.client.gui.CosmereScreen; +import leaf.cosmere.client.gui.SpiritwebMenu; import leaf.cosmere.common.cap.entity.SpiritwebCapability; import leaf.cosmere.feruchemy.common.Feruchemy; import net.minecraft.client.Minecraft; @@ -20,7 +21,7 @@ public class FeruchemySpiritwebMenu extends CosmereScreen final LocalPlayer player; public FeruchemySpiritwebMenu() { - super(Component.literal("Feruchemy")); + super(Component.literal("Feruchemy"), SpiritwebMenu::selectManiCallback); player = Minecraft.getInstance().player; } @@ -38,49 +39,49 @@ protected void init() int y = this.height/2 - distance*2; addRenderableWidget(new TriangleButton(x, y, - distance, topLeftRot, Metals.MetalType.IRON, spiritweb)); + distance, topLeftRot, Metals.MetalType.IRON, spiritweb, manifestationConsumer)); addRenderableWidget(new TriangleButton(x + distance, y, - distance, topRightRot, Metals.MetalType.STEEL, spiritweb)); + distance, topRightRot, Metals.MetalType.STEEL, spiritweb, manifestationConsumer)); addRenderableWidget(new TriangleButton(x + distance, y + distance, - distance, bottomRightRot, Metals.MetalType.TIN, spiritweb)); + distance, bottomRightRot, Metals.MetalType.TIN, spiritweb, manifestationConsumer)); addRenderableWidget(new TriangleButton(x, y + distance, - distance, bottomLeftRot, Metals.MetalType.PEWTER, spiritweb)); + distance, bottomLeftRot, Metals.MetalType.PEWTER, spiritweb, manifestationConsumer)); x = this.width / 2; y = this.height / 2 - distance; addRenderableWidget(new TriangleButton(x, y, - distance, topLeftRot, Metals.MetalType.ZINC, spiritweb)); + distance, topLeftRot, Metals.MetalType.ZINC, spiritweb, manifestationConsumer)); addRenderableWidget(new TriangleButton(x + distance, y, - distance, topRightRot, Metals.MetalType.COPPER, spiritweb)); + distance, topRightRot, Metals.MetalType.COPPER, spiritweb, manifestationConsumer)); addRenderableWidget(new TriangleButton(x + distance, y + distance, - distance, bottomRightRot, Metals.MetalType.BRASS, spiritweb)); + distance, bottomRightRot, Metals.MetalType.BRASS, spiritweb, manifestationConsumer)); addRenderableWidget(new TriangleButton(x, y + distance, - distance, bottomLeftRot, Metals.MetalType.BRONZE, spiritweb)); + distance, bottomLeftRot, Metals.MetalType.BRONZE, spiritweb, manifestationConsumer)); x = this.width / 2 - distance; y = this.height / 2; addRenderableWidget(new TriangleButton(x, y, - distance, topLeftRot, Metals.MetalType.GOLD, spiritweb)); + distance, topLeftRot, Metals.MetalType.GOLD, spiritweb, manifestationConsumer)); addRenderableWidget(new TriangleButton(x + distance, y, - distance, topRightRot, Metals.MetalType.ELECTRUM, spiritweb)); + distance, topRightRot, Metals.MetalType.ELECTRUM, spiritweb, manifestationConsumer)); addRenderableWidget(new TriangleButton(x + distance, y + distance, - distance, bottomRightRot, Metals.MetalType.CADMIUM, spiritweb)); + distance, bottomRightRot, Metals.MetalType.CADMIUM, spiritweb, manifestationConsumer)); addRenderableWidget(new TriangleButton(x, y + distance, - distance, bottomLeftRot, Metals.MetalType.BENDALLOY, spiritweb)); + distance, bottomLeftRot, Metals.MetalType.BENDALLOY, spiritweb, manifestationConsumer)); x = this.width / 2 - distance*2; y = this.height / 2 - distance; addRenderableWidget(new TriangleButton(x, y, - distance, topLeftRot, Metals.MetalType.CHROMIUM, spiritweb)); + distance, topLeftRot, Metals.MetalType.CHROMIUM, spiritweb, manifestationConsumer)); addRenderableWidget(new TriangleButton(x + distance, y, - distance, topRightRot, Metals.MetalType.DURALUMIN, spiritweb)); + distance, topRightRot, Metals.MetalType.DURALUMIN, spiritweb, manifestationConsumer)); addRenderableWidget(new TriangleButton(x + distance, y + distance, - distance, bottomRightRot, Metals.MetalType.NICROSIL, spiritweb)); + distance, bottomRightRot, Metals.MetalType.NICROSIL, spiritweb, manifestationConsumer)); addRenderableWidget(new TriangleButton(x, y + distance, - distance, bottomLeftRot, Metals.MetalType.ALUMINUM, spiritweb)); + distance, bottomLeftRot, Metals.MetalType.ALUMINUM, spiritweb, manifestationConsumer)); })); } diff --git a/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/TriangleButton.java b/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/TriangleButton.java index a1cc53cfe..402c34895 100644 --- a/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/TriangleButton.java +++ b/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/TriangleButton.java @@ -29,18 +29,20 @@ import java.awt.*; import java.util.ArrayList; import java.util.List; +import java.util.function.Consumer; public class TriangleButton extends Button { private final ResourceLocation iconLocation; private final List cachedQuads = new ArrayList<>(); + private final Consumer manifestationConsumer; private final ISpiritweb spiritweb; private final Manifestation manifestation; private final Metals.MetalType metal; private final boolean hasManifestation; private final float rotation; - public TriangleButton(int pX, int pY, int distance, float rotation, Metals.MetalType metal, ISpiritweb spiritweb) + public TriangleButton(int pX, int pY, int distance, float rotation, Metals.MetalType metal, ISpiritweb spiritweb, Consumer maniConsumer) { super(pX, pY, distance, distance, CommonComponents.EMPTY, (button) -> { }, DEFAULT_NARRATION); this.rotation = rotation; @@ -64,6 +66,8 @@ public TriangleButton(int pX, int pY, int distance, float rotation, Metals.Metal stringBuilder.append(".png"); iconLocation = new ResourceLocation(manifestation.getRegistryName().getNamespace(), stringBuilder.toString()); + manifestationConsumer = maniConsumer; + calculateVertexes(pX, pY, getWidth(), rotation); } @@ -103,7 +107,7 @@ public boolean isMouseOver(double mouseX, double mouseY) { if (retVal) { - SpiritwebMenu.selectedManifestation = manifestation; + manifestationConsumer.accept(manifestation); } } diff --git a/src/main/java/leaf/cosmere/client/gui/CosmereScreen.java b/src/main/java/leaf/cosmere/client/gui/CosmereScreen.java index 3098715db..c364b8d82 100644 --- a/src/main/java/leaf/cosmere/client/gui/CosmereScreen.java +++ b/src/main/java/leaf/cosmere/client/gui/CosmereScreen.java @@ -1,14 +1,19 @@ package leaf.cosmere.client.gui; +import leaf.cosmere.api.manifestation.Manifestation; import net.minecraft.client.gui.screens.Screen; import net.minecraft.network.chat.Component; +import java.util.function.Consumer; + // would be an interface if Screen wasn't a class // might be unnecessary, but could be nice to have in future, I guess public class CosmereScreen extends Screen { - protected CosmereScreen(Component pTitle) + protected final Consumer manifestationConsumer; + protected CosmereScreen(Component pTitle, Consumer manifestationConsumer) { super(pTitle); + this.manifestationConsumer = manifestationConsumer; } } diff --git a/src/main/java/leaf/cosmere/client/gui/SpiritwebMenu.java b/src/main/java/leaf/cosmere/client/gui/SpiritwebMenu.java index 30e2fa273..75fb95511 100644 --- a/src/main/java/leaf/cosmere/client/gui/SpiritwebMenu.java +++ b/src/main/java/leaf/cosmere/client/gui/SpiritwebMenu.java @@ -5,6 +5,7 @@ package leaf.cosmere.client.gui; import com.google.common.base.Stopwatch; +import leaf.cosmere.api.CosmereAPI; import leaf.cosmere.api.Manifestations; import leaf.cosmere.api.manifestation.Manifestation; import leaf.cosmere.api.math.MathHelper; @@ -29,7 +30,7 @@ public class SpiritwebMenu extends Screen private final SpiritwebRegistry registry; private CosmereScreen selectedManifestationScreen = null; public static Manifestations.ManifestationTypes selectedManifestationType = Manifestations.ManifestationTypes.NONE; - public static Manifestation selectedManifestation = null; + private static Manifestation selectedManifestation = null; public SpiritwebMenu(Component pTitle, ISpiritweb spiritweb) { @@ -148,4 +149,10 @@ public boolean isPauseScreen() // no pause >:( return false; } -} \ No newline at end of file + + public static void selectManiCallback(Manifestation manifestation) + { + selectedManifestation = manifestation; + selectedManifestationType = manifestation.getManifestationType(); + } +} diff --git a/src/sandmastery/java/leaf/cosmere/sandmastery/client/gui/RadialButton.java b/src/sandmastery/java/leaf/cosmere/sandmastery/client/gui/RadialButton.java index 9fe577233..d653cda2e 100644 --- a/src/sandmastery/java/leaf/cosmere/sandmastery/client/gui/RadialButton.java +++ b/src/sandmastery/java/leaf/cosmere/sandmastery/client/gui/RadialButton.java @@ -5,6 +5,7 @@ import com.mojang.blaze3d.vertex.DefaultVertexFormat; import com.mojang.blaze3d.vertex.Tesselator; import com.mojang.blaze3d.vertex.VertexFormat; +import leaf.cosmere.api.Manifestations; import leaf.cosmere.api.manifestation.Manifestation; import leaf.cosmere.client.gui.GuiUtils; import leaf.cosmere.client.gui.SpiritwebMenu; @@ -21,16 +22,18 @@ import java.util.ArrayList; import java.util.List; +import java.util.function.Consumer; public class RadialButton extends Button { private final ResourceLocation iconLocation; private final List cachedQuads = new ArrayList<>(); + private final Consumer manifestationConsumer; private final int radius, centerX, centerY, segmentNr; private final float startAngle; private final float endAngle; private final Manifestation manifestation; - protected RadialButton(int pX, int pY, int radius, int segmentNr, Manifestation manifestation) + protected RadialButton(int pX, int pY, int radius, int segmentNr, Manifestation manifestation, Consumer maniConsumer) { super(pX, pY, 16, 16, CommonComponents.EMPTY, (button) -> { }, DEFAULT_NARRATION); this.manifestation = manifestation; @@ -51,6 +54,8 @@ protected RadialButton(int pX, int pY, int radius, int segmentNr, Manifestation iconLocation = new ResourceLocation(manifestation.getRegistryName().getNamespace(), stringBuilder.toString()); + manifestationConsumer = maniConsumer; + calculateVertexes(centerX, centerY, radius, segmentNr); } @@ -88,7 +93,7 @@ public boolean isMouseOver(double mouseX, double mouseY) if (retVal) { - SpiritwebMenu.selectedManifestation = manifestation; + manifestationConsumer.accept(manifestation); } diff --git a/src/sandmastery/java/leaf/cosmere/sandmastery/client/gui/SandmasterySpiritwebMenu.java b/src/sandmastery/java/leaf/cosmere/sandmastery/client/gui/SandmasterySpiritwebMenu.java index baa0cb226..df03d20c7 100644 --- a/src/sandmastery/java/leaf/cosmere/sandmastery/client/gui/SandmasterySpiritwebMenu.java +++ b/src/sandmastery/java/leaf/cosmere/sandmastery/client/gui/SandmasterySpiritwebMenu.java @@ -3,6 +3,7 @@ import leaf.cosmere.api.Manifestations; import leaf.cosmere.api.manifestation.Manifestation; import leaf.cosmere.client.gui.CosmereScreen; +import leaf.cosmere.client.gui.SpiritwebMenu; import leaf.cosmere.common.cap.entity.SpiritwebCapability; import net.minecraft.client.Minecraft; import net.minecraft.client.player.LocalPlayer; @@ -15,7 +16,7 @@ public class SandmasterySpiritwebMenu extends CosmereScreen final LocalPlayer player; public SandmasterySpiritwebMenu() { - super(Component.literal("Sandmastery")); + super(Component.literal("Sandmastery"), SpiritwebMenu::selectManiCallback); player = Minecraft.getInstance().player; } @@ -35,7 +36,7 @@ protected void init() { if (mani.getManifestationType() == Manifestations.ManifestationTypes.SANDMASTERY) { - addRenderableWidget(new RadialButton(centerX, centerY, height/3, i, mani)); + addRenderableWidget(new RadialButton(centerX, centerY, height/3, i, mani, manifestationConsumer)); i++; } } diff --git a/src/surgebinding/java/leaf/cosmere/surgebinding/client/gui/CircleButton.java b/src/surgebinding/java/leaf/cosmere/surgebinding/client/gui/CircleButton.java index 15f5f0848..c947a5b2e 100644 --- a/src/surgebinding/java/leaf/cosmere/surgebinding/client/gui/CircleButton.java +++ b/src/surgebinding/java/leaf/cosmere/surgebinding/client/gui/CircleButton.java @@ -22,17 +22,19 @@ import java.util.ArrayList; import java.util.List; +import java.util.function.Consumer; public class CircleButton extends Button { private final ResourceLocation iconLocation; private final List cachedQuads = new ArrayList<>(); + private final Consumer manifestationConsumer; final ISpiritweb spiritweb; final Manifestation manifestation; final int centerX, centerY; final int radius; - public CircleButton(int pX, int pY, int radius, ISpiritweb spiritweb, Manifestation manifestation) + public CircleButton(int pX, int pY, int radius, ISpiritweb spiritweb, Manifestation manifestation, Consumer maniConsumer) { super(pX, pY, radius, radius, CommonComponents.EMPTY, (button) -> { }, DEFAULT_NARRATION); @@ -53,6 +55,8 @@ public CircleButton(int pX, int pY, int radius, ISpiritweb spiritweb, Manifestat iconLocation = new ResourceLocation(manifestation.getRegistryName().getNamespace(), stringBuilder.toString()); + manifestationConsumer = maniConsumer; + calculateVertexes(centerX, centerY, radius); } @@ -62,7 +66,7 @@ public boolean isMouseOver(double mouseX, double mouseY) { double distanceY = mouseY - centerY; if ((distanceX * distanceX + distanceY * distanceY) <= (radius * radius)) { - SpiritwebMenu.selectedManifestation = manifestation; + manifestationConsumer.accept(manifestation); return true; } diff --git a/src/surgebinding/java/leaf/cosmere/surgebinding/client/gui/SurgebindingSpiritwebMenu.java b/src/surgebinding/java/leaf/cosmere/surgebinding/client/gui/SurgebindingSpiritwebMenu.java index 1f2435bcb..296792f7c 100644 --- a/src/surgebinding/java/leaf/cosmere/surgebinding/client/gui/SurgebindingSpiritwebMenu.java +++ b/src/surgebinding/java/leaf/cosmere/surgebinding/client/gui/SurgebindingSpiritwebMenu.java @@ -3,6 +3,7 @@ import leaf.cosmere.api.Manifestations; import leaf.cosmere.api.manifestation.Manifestation; import leaf.cosmere.client.gui.CosmereScreen; +import leaf.cosmere.client.gui.SpiritwebMenu; import leaf.cosmere.common.cap.entity.SpiritwebCapability; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; @@ -16,7 +17,7 @@ public class SurgebindingSpiritwebMenu extends CosmereScreen final LocalPlayer player; public SurgebindingSpiritwebMenu() { - super(Component.literal("Surgebinding")); + super(Component.literal("Surgebinding"), SpiritwebMenu::selectManiCallback); player = Minecraft.getInstance().player; } @@ -35,7 +36,7 @@ protected void init() { if (mani.getManifestationType() == Manifestations.ManifestationTypes.SURGEBINDING) { - addRenderableWidget(new CircleButton((int) (width/2f - radius*1.5 + (radius*3) * i), height/2, radius, spiritweb, mani)); + addRenderableWidget(new CircleButton((int) (width/2f - radius*1.5 + (radius*3) * i), height/2, radius, spiritweb, mani, manifestationConsumer)); i++; } } From 6b061c3185d142d249e2408e54866f97aeb9ab27 Mon Sep 17 00:00:00 2001 From: Gerbagel Date: Sat, 2 May 2026 17:02:27 +0200 Subject: [PATCH 43/55] [Cosmere] Added some missing translation strings --- .../430a276c0dd49f98e5202a1b15a1e8bf39ea6301 | 4 +-- .../allomancy/curios/entities/mistborn.json | 4 +-- .../dd0552f4815307fa79918bc7fddf7e3ebb5df25c | 12 ++++---- .../data/minecraft/tags/items/axes.json | 30 +++++++++---------- .../data/minecraft/tags/items/hoes.json | 30 +++++++++---------- .../data/minecraft/tags/items/pickaxes.json | 30 +++++++++---------- .../data/minecraft/tags/items/shovels.json | 30 +++++++++---------- .../data/minecraft/tags/items/swords.json | 30 +++++++++---------- .../60c035799f578be828205f75035ce4e4976d0466 | 4 +-- .../curios/entities/feruchemists.json | 4 +-- .../5040fc90492c7cdcc7a00ae9539bd053297496a9 | 4 +-- .../curios/entities/hemalurgists.json | 4 +-- .../c622617f6fabf890a00b9275cd5f643584a8a2c8 | 4 +-- .../assets/surgebinding/lang/en_us.json | 3 ++ .../surgebinding/SurgebindingEngLangGen.java | 7 +++-- .../client/SurgebindingKeybindings.java | 5 +--- 16 files changed, 104 insertions(+), 101 deletions(-) diff --git a/src/datagen/generated/allomancy/.cache/430a276c0dd49f98e5202a1b15a1e8bf39ea6301 b/src/datagen/generated/allomancy/.cache/430a276c0dd49f98e5202a1b15a1e8bf39ea6301 index 172ac10fa..1242b8a33 100644 --- a/src/datagen/generated/allomancy/.cache/430a276c0dd49f98e5202a1b15a1e8bf39ea6301 +++ b/src/datagen/generated/allomancy/.cache/430a276c0dd49f98e5202a1b15a1e8bf39ea6301 @@ -1,3 +1,3 @@ -// 1.20.1 2025-11-13T18:09:20.66803 Curios for allomancy -c0ef1b619d27f65ec86ee5bc46971b41748a156a data/allomancy/curios/entities/mistborn.json +// 1.20.1 2026-05-02T16:53:45.089036032 Curios for allomancy +1220185785fce5b2d78679e009b71dd157a8e419 data/allomancy/curios/entities/mistborn.json 1b40b27e696da61cb9fc699a027918ced88c562e data/allomancy/curios/slots/head.json diff --git a/src/datagen/generated/allomancy/data/allomancy/curios/entities/mistborn.json b/src/datagen/generated/allomancy/data/allomancy/curios/entities/mistborn.json index 81e90256e..fe00c9f0c 100644 --- a/src/datagen/generated/allomancy/data/allomancy/curios/entities/mistborn.json +++ b/src/datagen/generated/allomancy/data/allomancy/curios/entities/mistborn.json @@ -1,7 +1,7 @@ { "entities": [ - "minecraft:player", - "minecraft:armor_stand" + "minecraft:armor_stand", + "minecraft:player" ], "slots": [ "head" diff --git a/src/datagen/generated/cosmeretools/.cache/dd0552f4815307fa79918bc7fddf7e3ebb5df25c b/src/datagen/generated/cosmeretools/.cache/dd0552f4815307fa79918bc7fddf7e3ebb5df25c index cfddd2bf5..64a0dc533 100644 --- a/src/datagen/generated/cosmeretools/.cache/dd0552f4815307fa79918bc7fddf7e3ebb5df25c +++ b/src/datagen/generated/cosmeretools/.cache/dd0552f4815307fa79918bc7fddf7e3ebb5df25c @@ -1,6 +1,6 @@ -// 1.20.1 2026-04-27T10:20:37.528514 Tags: cosmeretools -ea66c36d742d7273f998be596425ce9b7509329e data/minecraft/tags/items/axes.json -d1a8d52c7e8ce77dab7b1ff233349270720c383a data/minecraft/tags/items/hoes.json -97965722f69c61a77ba9ff364164b23ba6cb3219 data/minecraft/tags/items/pickaxes.json -730c6af6ee4b094a3d3d9c0178ac5affaba44785 data/minecraft/tags/items/shovels.json -1cdfe1b204448c10e3d7680a1240401fe4f7c1d7 data/minecraft/tags/items/swords.json +// 1.20.1 2026-05-02T16:53:45.055293082 Tags: cosmeretools +3694ca36839984fbd1c576bac7fe663250fcac60 data/minecraft/tags/items/axes.json +42a39e4c6b8a38d120a32a452fcec2538afdf632 data/minecraft/tags/items/hoes.json +cb5b2ceaf28163930f615b55ba36985d3e6e4edf data/minecraft/tags/items/pickaxes.json +3ade9eb60271d5e216124acb8dfe4e8297c01be0 data/minecraft/tags/items/shovels.json +5763236182c5a768e612a8f1dd2cb5142be5d982 data/minecraft/tags/items/swords.json diff --git a/src/datagen/generated/cosmeretools/data/minecraft/tags/items/axes.json b/src/datagen/generated/cosmeretools/data/minecraft/tags/items/axes.json index 260fced28..1476c1ea1 100644 --- a/src/datagen/generated/cosmeretools/data/minecraft/tags/items/axes.json +++ b/src/datagen/generated/cosmeretools/data/minecraft/tags/items/axes.json @@ -1,26 +1,26 @@ { "values": [ - "cosmeretools:aluminum_axe", - "cosmeretools:electrum_axe", - "cosmeretools:lerasatium_axe", - "cosmeretools:nickel_axe", - "cosmeretools:nicrosil_axe", - "cosmeretools:tin_axe", - "cosmeretools:silver_axe", - "cosmeretools:atium_axe", + "cosmeretools:steel_axe", "cosmeretools:malatium_axe", + "cosmeretools:lead_axe", + "cosmeretools:aluminum_axe", "cosmeretools:copper_axe", - "cosmeretools:cadmium_axe", - "cosmeretools:pewter_axe", + "cosmeretools:lerasatium_axe", "cosmeretools:brass_axe", - "cosmeretools:harmonium_axe", - "cosmeretools:lead_axe", "cosmeretools:bronze_axe", + "cosmeretools:pewter_axe", "cosmeretools:chromium_axe", - "cosmeretools:bendalloy_axe", + "cosmeretools:atium_axe", + "cosmeretools:harmonium_axe", + "cosmeretools:electrum_axe", + "cosmeretools:nickel_axe", "cosmeretools:duralumin_axe", - "cosmeretools:lerasium_axe", "cosmeretools:zinc_axe", - "cosmeretools:steel_axe" + "cosmeretools:nicrosil_axe", + "cosmeretools:bendalloy_axe", + "cosmeretools:tin_axe", + "cosmeretools:lerasium_axe", + "cosmeretools:cadmium_axe", + "cosmeretools:silver_axe" ] } \ No newline at end of file diff --git a/src/datagen/generated/cosmeretools/data/minecraft/tags/items/hoes.json b/src/datagen/generated/cosmeretools/data/minecraft/tags/items/hoes.json index 40869b552..40c81a2a3 100644 --- a/src/datagen/generated/cosmeretools/data/minecraft/tags/items/hoes.json +++ b/src/datagen/generated/cosmeretools/data/minecraft/tags/items/hoes.json @@ -1,26 +1,26 @@ { "values": [ - "cosmeretools:aluminum_hoe", - "cosmeretools:electrum_hoe", - "cosmeretools:lerasatium_hoe", - "cosmeretools:nickel_hoe", - "cosmeretools:nicrosil_hoe", - "cosmeretools:tin_hoe", - "cosmeretools:silver_hoe", - "cosmeretools:atium_hoe", + "cosmeretools:steel_hoe", "cosmeretools:malatium_hoe", + "cosmeretools:lead_hoe", + "cosmeretools:aluminum_hoe", "cosmeretools:copper_hoe", - "cosmeretools:cadmium_hoe", - "cosmeretools:pewter_hoe", + "cosmeretools:lerasatium_hoe", "cosmeretools:brass_hoe", - "cosmeretools:harmonium_hoe", - "cosmeretools:lead_hoe", "cosmeretools:bronze_hoe", + "cosmeretools:pewter_hoe", "cosmeretools:chromium_hoe", - "cosmeretools:bendalloy_hoe", + "cosmeretools:atium_hoe", + "cosmeretools:harmonium_hoe", + "cosmeretools:electrum_hoe", + "cosmeretools:nickel_hoe", "cosmeretools:duralumin_hoe", - "cosmeretools:lerasium_hoe", "cosmeretools:zinc_hoe", - "cosmeretools:steel_hoe" + "cosmeretools:nicrosil_hoe", + "cosmeretools:bendalloy_hoe", + "cosmeretools:tin_hoe", + "cosmeretools:lerasium_hoe", + "cosmeretools:cadmium_hoe", + "cosmeretools:silver_hoe" ] } \ No newline at end of file diff --git a/src/datagen/generated/cosmeretools/data/minecraft/tags/items/pickaxes.json b/src/datagen/generated/cosmeretools/data/minecraft/tags/items/pickaxes.json index 9c8ecac38..d33d1f1e4 100644 --- a/src/datagen/generated/cosmeretools/data/minecraft/tags/items/pickaxes.json +++ b/src/datagen/generated/cosmeretools/data/minecraft/tags/items/pickaxes.json @@ -1,26 +1,26 @@ { "values": [ - "cosmeretools:aluminum_pickaxe", - "cosmeretools:electrum_pickaxe", - "cosmeretools:lerasatium_pickaxe", - "cosmeretools:nickel_pickaxe", - "cosmeretools:nicrosil_pickaxe", - "cosmeretools:tin_pickaxe", - "cosmeretools:silver_pickaxe", - "cosmeretools:atium_pickaxe", + "cosmeretools:steel_pickaxe", "cosmeretools:malatium_pickaxe", + "cosmeretools:lead_pickaxe", + "cosmeretools:aluminum_pickaxe", "cosmeretools:copper_pickaxe", - "cosmeretools:cadmium_pickaxe", - "cosmeretools:pewter_pickaxe", + "cosmeretools:lerasatium_pickaxe", "cosmeretools:brass_pickaxe", - "cosmeretools:harmonium_pickaxe", - "cosmeretools:lead_pickaxe", "cosmeretools:bronze_pickaxe", + "cosmeretools:pewter_pickaxe", "cosmeretools:chromium_pickaxe", - "cosmeretools:bendalloy_pickaxe", + "cosmeretools:atium_pickaxe", + "cosmeretools:harmonium_pickaxe", + "cosmeretools:electrum_pickaxe", + "cosmeretools:nickel_pickaxe", "cosmeretools:duralumin_pickaxe", - "cosmeretools:lerasium_pickaxe", "cosmeretools:zinc_pickaxe", - "cosmeretools:steel_pickaxe" + "cosmeretools:nicrosil_pickaxe", + "cosmeretools:bendalloy_pickaxe", + "cosmeretools:tin_pickaxe", + "cosmeretools:lerasium_pickaxe", + "cosmeretools:cadmium_pickaxe", + "cosmeretools:silver_pickaxe" ] } \ No newline at end of file diff --git a/src/datagen/generated/cosmeretools/data/minecraft/tags/items/shovels.json b/src/datagen/generated/cosmeretools/data/minecraft/tags/items/shovels.json index eab4849e6..929cb7cfd 100644 --- a/src/datagen/generated/cosmeretools/data/minecraft/tags/items/shovels.json +++ b/src/datagen/generated/cosmeretools/data/minecraft/tags/items/shovels.json @@ -1,26 +1,26 @@ { "values": [ - "cosmeretools:aluminum_shovel", - "cosmeretools:electrum_shovel", - "cosmeretools:lerasatium_shovel", - "cosmeretools:nickel_shovel", - "cosmeretools:nicrosil_shovel", - "cosmeretools:tin_shovel", - "cosmeretools:silver_shovel", - "cosmeretools:atium_shovel", + "cosmeretools:steel_shovel", "cosmeretools:malatium_shovel", + "cosmeretools:lead_shovel", + "cosmeretools:aluminum_shovel", "cosmeretools:copper_shovel", - "cosmeretools:cadmium_shovel", - "cosmeretools:pewter_shovel", + "cosmeretools:lerasatium_shovel", "cosmeretools:brass_shovel", - "cosmeretools:harmonium_shovel", - "cosmeretools:lead_shovel", "cosmeretools:bronze_shovel", + "cosmeretools:pewter_shovel", "cosmeretools:chromium_shovel", - "cosmeretools:bendalloy_shovel", + "cosmeretools:atium_shovel", + "cosmeretools:harmonium_shovel", + "cosmeretools:electrum_shovel", + "cosmeretools:nickel_shovel", "cosmeretools:duralumin_shovel", - "cosmeretools:lerasium_shovel", "cosmeretools:zinc_shovel", - "cosmeretools:steel_shovel" + "cosmeretools:nicrosil_shovel", + "cosmeretools:bendalloy_shovel", + "cosmeretools:tin_shovel", + "cosmeretools:lerasium_shovel", + "cosmeretools:cadmium_shovel", + "cosmeretools:silver_shovel" ] } \ No newline at end of file diff --git a/src/datagen/generated/cosmeretools/data/minecraft/tags/items/swords.json b/src/datagen/generated/cosmeretools/data/minecraft/tags/items/swords.json index 698a1fdb6..83e640fd9 100644 --- a/src/datagen/generated/cosmeretools/data/minecraft/tags/items/swords.json +++ b/src/datagen/generated/cosmeretools/data/minecraft/tags/items/swords.json @@ -1,26 +1,26 @@ { "values": [ - "cosmeretools:aluminum_sword", - "cosmeretools:electrum_sword", - "cosmeretools:lerasatium_sword", - "cosmeretools:nickel_sword", - "cosmeretools:nicrosil_sword", - "cosmeretools:tin_sword", - "cosmeretools:silver_sword", - "cosmeretools:atium_sword", + "cosmeretools:steel_sword", "cosmeretools:malatium_sword", + "cosmeretools:lead_sword", + "cosmeretools:aluminum_sword", "cosmeretools:copper_sword", - "cosmeretools:cadmium_sword", - "cosmeretools:pewter_sword", + "cosmeretools:lerasatium_sword", "cosmeretools:brass_sword", - "cosmeretools:harmonium_sword", - "cosmeretools:lead_sword", "cosmeretools:bronze_sword", + "cosmeretools:pewter_sword", "cosmeretools:chromium_sword", - "cosmeretools:bendalloy_sword", + "cosmeretools:atium_sword", + "cosmeretools:harmonium_sword", + "cosmeretools:electrum_sword", + "cosmeretools:nickel_sword", "cosmeretools:duralumin_sword", - "cosmeretools:lerasium_sword", "cosmeretools:zinc_sword", - "cosmeretools:steel_sword" + "cosmeretools:nicrosil_sword", + "cosmeretools:bendalloy_sword", + "cosmeretools:tin_sword", + "cosmeretools:lerasium_sword", + "cosmeretools:cadmium_sword", + "cosmeretools:silver_sword" ] } \ No newline at end of file diff --git a/src/datagen/generated/feruchemy/.cache/60c035799f578be828205f75035ce4e4976d0466 b/src/datagen/generated/feruchemy/.cache/60c035799f578be828205f75035ce4e4976d0466 index 2c0c87863..fcf5d02d5 100644 --- a/src/datagen/generated/feruchemy/.cache/60c035799f578be828205f75035ce4e4976d0466 +++ b/src/datagen/generated/feruchemy/.cache/60c035799f578be828205f75035ce4e4976d0466 @@ -1,5 +1,5 @@ -// 1.20.1 2026-04-27T10:20:37.638454 Curios for feruchemy -6d8604575982ef60b9658bf84e9f93720d8c1978 data/feruchemy/curios/entities/feruchemists.json +// 1.20.1 2026-05-02T16:53:45.09697956 Curios for feruchemy +73df16b7f3493192632a8179ec9b2557e25d965f data/feruchemy/curios/entities/feruchemists.json bbe073ce668da1ecdaf43df2f875912048670cff data/feruchemy/curios/slots/bracelet.json 50651f4d8ef6e4eaf677f5f40e0013e4b16d7e47 data/feruchemy/curios/slots/necklace.json 15229e2ac0d30b7253b5d5b6f82d0433d5cb414c data/feruchemy/curios/slots/ring.json diff --git a/src/datagen/generated/feruchemy/data/feruchemy/curios/entities/feruchemists.json b/src/datagen/generated/feruchemy/data/feruchemy/curios/entities/feruchemists.json index da81b44bb..61b319ff8 100644 --- a/src/datagen/generated/feruchemy/data/feruchemy/curios/entities/feruchemists.json +++ b/src/datagen/generated/feruchemy/data/feruchemy/curios/entities/feruchemists.json @@ -1,7 +1,7 @@ { "entities": [ - "minecraft:player", - "minecraft:armor_stand" + "minecraft:armor_stand", + "minecraft:player" ], "slots": [ "ring", diff --git a/src/datagen/generated/hemalurgy/.cache/5040fc90492c7cdcc7a00ae9539bd053297496a9 b/src/datagen/generated/hemalurgy/.cache/5040fc90492c7cdcc7a00ae9539bd053297496a9 index 248dc6e16..a61b31be5 100644 --- a/src/datagen/generated/hemalurgy/.cache/5040fc90492c7cdcc7a00ae9539bd053297496a9 +++ b/src/datagen/generated/hemalurgy/.cache/5040fc90492c7cdcc7a00ae9539bd053297496a9 @@ -1,5 +1,5 @@ -// 1.20.1 2026-04-27T10:20:37.696925 Curios for hemalurgy -2c626dfa8d54881552e9e9c55aa2784089584b1f data/hemalurgy/curios/entities/hemalurgists.json +// 1.20.1 2026-05-02T16:53:45.109780127 Curios for hemalurgy +626814372fa7619e348a3a7768b51867ea23cf4b data/hemalurgy/curios/entities/hemalurgists.json 3fb00e951b4f3f7f01981550080dacbe27e14423 data/hemalurgy/curios/slots/eyes.json 169721ff151c350c1c8e90f73d41f17f3737007a data/hemalurgy/curios/slots/linchpin.json becad4c0600bfd0706dc0ceb17eaf853bd029cd9 data/hemalurgy/curios/slots/mental.json diff --git a/src/datagen/generated/hemalurgy/data/hemalurgy/curios/entities/hemalurgists.json b/src/datagen/generated/hemalurgy/data/hemalurgy/curios/entities/hemalurgists.json index 61647c56e..a8f082ae1 100644 --- a/src/datagen/generated/hemalurgy/data/hemalurgy/curios/entities/hemalurgists.json +++ b/src/datagen/generated/hemalurgy/data/hemalurgy/curios/entities/hemalurgists.json @@ -1,7 +1,7 @@ { "entities": [ - "minecraft:player", - "minecraft:armor_stand" + "minecraft:armor_stand", + "minecraft:player" ], "slots": [ "linchpin", diff --git a/src/datagen/generated/surgebinding/.cache/c622617f6fabf890a00b9275cd5f643584a8a2c8 b/src/datagen/generated/surgebinding/.cache/c622617f6fabf890a00b9275cd5f643584a8a2c8 index 81f49902b..327f75351 100644 --- a/src/datagen/generated/surgebinding/.cache/c622617f6fabf890a00b9275cd5f643584a8a2c8 +++ b/src/datagen/generated/surgebinding/.cache/c622617f6fabf890a00b9275cd5f643584a8a2c8 @@ -1,2 +1,2 @@ -// 1.20.1 2026-03-04T19:26:42.166289 Languages: en_us -02db61e73dc098aa4c1d5fdf74888060397f5370 assets/surgebinding/lang/en_us.json +// 1.20.1 2026-05-02T16:53:45.078830964 Languages: en_us +84ff212b5f7fc417111fb6c551d7cfbd4c27ad1d assets/surgebinding/lang/en_us.json diff --git a/src/datagen/generated/surgebinding/assets/surgebinding/lang/en_us.json b/src/datagen/generated/surgebinding/assets/surgebinding/lang/en_us.json index 28bce1ff6..cf7b1a4ce 100644 --- a/src/datagen/generated/surgebinding/assets/surgebinding/lang/en_us.json +++ b/src/datagen/generated/surgebinding/assets/surgebinding/lang/en_us.json @@ -143,7 +143,10 @@ "item.surgebinding.windrunner_honorblade": "Windrunner Honorblade", "item.surgebinding.zircon": "Zircon", "item.surgebinding.zircon_mark": "Zircon Mark", + "key.cosmere.stormlight.dispatch_stormlight": "Dispatch Stormlight", + "key.cosmere.stormlight.request_stormlight": "Request Stormlight", "key.cosmere.stormlight.shardblade": "Summon/Dismiss Shardblade", + "keys.surgebinding.main": "Surgebinding", "manifestation.surgebinding.abrasion": "Abrasion", "manifestation.surgebinding.abrasion.description": "Needs description", "manifestation.surgebinding.adhesion": "Adhesion", diff --git a/src/datagen/surgebinding/java/leaf/cosmere/surgebinding/SurgebindingEngLangGen.java b/src/datagen/surgebinding/java/leaf/cosmere/surgebinding/SurgebindingEngLangGen.java index 3141b6905..eb785eb89 100644 --- a/src/datagen/surgebinding/java/leaf/cosmere/surgebinding/SurgebindingEngLangGen.java +++ b/src/datagen/surgebinding/java/leaf/cosmere/surgebinding/SurgebindingEngLangGen.java @@ -22,7 +22,7 @@ import java.util.List; -import static leaf.cosmere.api.Constants.Strings.KEY_SHARDBLADE; +import static leaf.cosmere.api.Constants.Strings.*; import static leaf.cosmere.surgebinding.common.registries.SurgebindingAttributes.SURGEBINDING_ATTRIBUTES; public class SurgebindingEngLangGen extends LanguageProvider @@ -181,10 +181,13 @@ private void addCommands() private void addKeybindings() { add(KEY_SHARDBLADE, "Summon/Dismiss Shardblade"); + add(KEY_REQUEST_STORMLIGHT, "Request Stormlight"); + add(KEY_DISPATCH_STORMLIGHT, "Dispatch Stormlight"); + add("keys.surgebinding.main", "Surgebinding"); } private void addStats() { } -} \ No newline at end of file +} diff --git a/src/surgebinding/java/leaf/cosmere/surgebinding/client/SurgebindingKeybindings.java b/src/surgebinding/java/leaf/cosmere/surgebinding/client/SurgebindingKeybindings.java index 2f547b13b..4af3a3592 100644 --- a/src/surgebinding/java/leaf/cosmere/surgebinding/client/SurgebindingKeybindings.java +++ b/src/surgebinding/java/leaf/cosmere/surgebinding/client/SurgebindingKeybindings.java @@ -46,16 +46,13 @@ public class SurgebindingKeybindings @SubscribeEvent public static void register(RegisterKeyMappingsEvent event) { - - event.register(SHARDBLADE = new KeyMapping(KEY_SHARDBLADE, GLFW.GLFW_KEY_X, KEYS_CATEGORY)); - for (Roshar.Surges surge : SURGEBINDING_POWER.keySet()) { KeyMapping key = SURGEBINDING_POWER.get(surge); SurgebindingManifestation manifest = (SurgebindingManifestation) SURGEBINDING_POWERS.get(surge).getManifestation(); event.register(key); Activator entry = new Activator(key, manifest); - entry.setCategory("stormlight"); + entry.setCategory("keys.surgebinding.main"); Keybindings.activators.add(entry); } From a828f3e794c4a4a6a32d40af25da8e21b6692b04 Mon Sep 17 00:00:00 2001 From: Gerbagel Date: Sat, 2 May 2026 18:06:58 +0200 Subject: [PATCH 44/55] [Cosmere] Custom mixin json management --- build.gradle | 53 +++++++++++++------ .../client/SurgebindingKeybindings.java | 10 ++-- 2 files changed, 41 insertions(+), 22 deletions(-) diff --git a/build.gradle b/build.gradle index ab8375cde..5cbfde3d6 100644 --- a/build.gradle +++ b/build.gradle @@ -478,18 +478,18 @@ dependencies { mixin { // MixinGradle Settings - add sourceSets.main, 'mixins.cosmere.refmap.json' - add sourceSets.api, 'mixins.cosmere.api.refmap.json' - add sourceSets.allomancy, 'mixins.cosmere.allomancy.refmap.json' - add sourceSets.feruchemy, 'mixins.cosmere.feruchemy.refmap.json' - add sourceSets.hemalurgy, 'mixins.cosmere.hemalurgy.refmap.json' - add sourceSets.surgebinding, 'mixins.cosmere.surgebinding.refmap.json' - add sourceSets.sandmastery, 'mixins.cosmere.sandmastery.refmap.json' - add sourceSets.aviar, 'mixins.cosmere.aviar.refmap.json' - add sourceSets.awakening, 'mixins.cosmere.awakening.refmap.json' - add sourceSets.aondor, 'mixins.cosmere.aondor.refmap.json' - add sourceSets.soulforgery, 'mixins.cosmere.soulforgery.refmap.json' - add sourceSets.cosmeretools, 'mixins.cosmere.cosmeretools.refmap.json' + //add sourceSets.main, 'mixins.cosmere.refmap.json' + //add sourceSets.api, 'mixins.cosmere.api.refmap.json' + //add sourceSets.allomancy, 'mixins.cosmere.allomancy.refmap.json' + //add sourceSets.feruchemy, 'mixins.cosmere.feruchemy.refmap.json' + //add sourceSets.hemalurgy, 'mixins.cosmere.hemalurgy.refmap.json' + //add sourceSets.surgebinding, 'mixins.cosmere.surgebinding.refmap.json' + //add sourceSets.sandmastery, 'mixins.cosmere.sandmastery.refmap.json' + //add sourceSets.aviar, 'mixins.cosmere.aviar.refmap.json' + //add sourceSets.awakening, 'mixins.cosmere.awakening.refmap.json' + //add sourceSets.aondor, 'mixins.cosmere.aondor.refmap.json' + //add sourceSets.soulforgery, 'mixins.cosmere.soulforgery.refmap.json' + //add sourceSets.cosmeretools, 'mixins.cosmere.cosmeretools.refmap.json' config 'cosmere.mixins.json' //config 'cosmere.mixins.api.json' @@ -523,6 +523,7 @@ def getManifestAttributes(String title) tasks.named('jar', Jar).configure { duplicatesStrategy(DuplicatesStrategy.FAIL) from([sourceSets.api.output, sourceSets.main.output]) + exclude 'mixin.refmap.json' manifest.attributes(getManifestAttributes("Cosmere")) } @@ -565,6 +566,7 @@ def secondaryJar(SourceSet sourceSet, String title) duplicatesStrategy(DuplicatesStrategy.FAIL) archiveClassifier.set(sourceSet.name) from sourceSet.output + exclude 'mixin.refmap.json' if (!title.isEmpty()) { def filename = "${title}-${project.version}.jar" //basically don't add cosmere if it already has cosmere in it @@ -588,9 +590,28 @@ def soulforgeryJar = secondaryJar(sourceSets.soulforgery, 'SoulForgery') def exampleJar = secondaryJar(sourceSets.example, 'Example') def cosmeretoolsJar = secondaryJar(sourceSets.cosmeretools, 'CosmereTools') -tasks.withType(JavaCompile).configureEach({ - options.encoding = 'UTF-8' - options.compilerArgs.addAll(["-Xmaxerrs", "100000"]) +tasks.withType(JavaCompile).configureEach({task -> + options.encoding = 'UTF-8' + options.compilerArgs.addAll(["-Xmaxerrs", "100000"]) + + def matcher = task.name =~ /compile(.*)Java/ + if (matcher.matches() && matcher.group(1) != 'Test') { + def sourceSetName = matcher.group(1).toLowerCase() + + // Use 'main' for the standard compileJava task + if (task.name == 'compileJava') sourceSetName = 'main' + + task.doFirst { + // Strip out any outRefMapFile arguments appended by ForgeGradle/MixinGradle + options.compilerArgs.removeIf { it.startsWith('-AoutRefMapFile=') } + + // Format the refmap name correctly: omit '.main' if it's the main source set + def refmapName = sourceSetName == 'main' ? 'mixins.cosmere.refmap.json' : "mixins.cosmere.${sourceSetName}.refmap.json" + + // Force the AP to output directly to the classes directory + options.compilerArgs << "-AoutRefMapFile=${layout.buildDirectory.dir("classes/java/${sourceSetName}").get().asFile}/${refmapName}" + } + } }) artifacts { @@ -885,4 +906,4 @@ tasks.register('publishToModSites') { if (System.getenv("CURSEFORGE_API_TOKEN") != null || project.hasProperty('curseforge_api_token')) { publishToModSites.dependsOn tasks.named("curseforge") } -} \ No newline at end of file +} diff --git a/src/surgebinding/java/leaf/cosmere/surgebinding/client/SurgebindingKeybindings.java b/src/surgebinding/java/leaf/cosmere/surgebinding/client/SurgebindingKeybindings.java index 4af3a3592..682edcafc 100644 --- a/src/surgebinding/java/leaf/cosmere/surgebinding/client/SurgebindingKeybindings.java +++ b/src/surgebinding/java/leaf/cosmere/surgebinding/client/SurgebindingKeybindings.java @@ -46,12 +46,11 @@ public class SurgebindingKeybindings @SubscribeEvent public static void register(RegisterKeyMappingsEvent event) { - for (Roshar.Surges surge : SURGEBINDING_POWER.keySet()) + for (Map.Entry kvPair : SURGEBINDING_POWER.entrySet()) { - KeyMapping key = SURGEBINDING_POWER.get(surge); - SurgebindingManifestation manifest = (SurgebindingManifestation) SURGEBINDING_POWERS.get(surge).getManifestation(); - event.register(key); - Activator entry = new Activator(key, manifest); + SurgebindingManifestation manifest = (SurgebindingManifestation) SURGEBINDING_POWERS.get(kvPair.getKey()).getManifestation(); + event.register(kvPair.getValue()); + Activator entry = new Activator(kvPair.getValue(), manifest); entry.setCategory("keys.surgebinding.main"); Keybindings.activators.add(entry); } @@ -59,7 +58,6 @@ public static void register(RegisterKeyMappingsEvent event) event.register(SHARDBLADE = new KeyMapping(KEY_SHARDBLADE, GLFW.GLFW_KEY_X, "keys.surgebinding.main")); event.register(REQUEST_STORMLIGHT = new KeyMapping(KEY_REQUEST_STORMLIGHT, GLFW.GLFW_KEY_Z, "keys.surgebinding.main")); event.register(DISPATCH_STORMLIGHT = new KeyMapping(KEY_DISPATCH_STORMLIGHT, GLFW.GLFW_KEY_Y, "keys.surgebinding.main")); - } } From 670e6d5cb8c3f9b069b96c6649c9f583c29fdb38 Mon Sep 17 00:00:00 2001 From: Gerbagel Date: Sat, 2 May 2026 18:32:01 +0200 Subject: [PATCH 45/55] [Cosmere] Claude's nit-pick commit --- .../cosmere/api/spiritweb/ISpiritweb.java | 3 +++ .../client/utils/FeruchemyChargeThread.java | 16 ++++++--------- .../manifestation/FeruchemyManifestation.java | 4 ++++ .../leaf/cosmere/client/gui/GuiUtils.java | 2 -- .../leaf/cosmere/client/gui/SpiritwebHud.java | 20 ------------------- .../cosmere/client/gui/SpiritwebRegistry.java | 6 +----- .../cap/entity/SpiritwebCapability.java | 1 + 7 files changed, 15 insertions(+), 37 deletions(-) diff --git a/src/api/java/leaf/cosmere/api/spiritweb/ISpiritweb.java b/src/api/java/leaf/cosmere/api/spiritweb/ISpiritweb.java index 84a244c84..57e4c5775 100644 --- a/src/api/java/leaf/cosmere/api/spiritweb/ISpiritweb.java +++ b/src/api/java/leaf/cosmere/api/spiritweb/ISpiritweb.java @@ -15,6 +15,8 @@ import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.LivingEntity; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.client.event.RenderLevelStageEvent; import net.minecraftforge.common.util.INBTSerializable; import net.minecraftforge.event.entity.player.PlayerEvent; @@ -105,6 +107,7 @@ public interface ISpiritweb extends INBTSerializable void activatePowerState(int num); + @OnlyIn(Dist.CLIENT) AbstractWidget getSpiritwebHud(); } diff --git a/src/feruchemy/java/leaf/cosmere/feruchemy/client/utils/FeruchemyChargeThread.java b/src/feruchemy/java/leaf/cosmere/feruchemy/client/utils/FeruchemyChargeThread.java index 3d7a45f0d..58e9e6a13 100644 --- a/src/feruchemy/java/leaf/cosmere/feruchemy/client/utils/FeruchemyChargeThread.java +++ b/src/feruchemy/java/leaf/cosmere/feruchemy/client/utils/FeruchemyChargeThread.java @@ -202,21 +202,17 @@ public void run() return true; }); + if (lock.tryLock()) try { - if (lock.tryLock()) - { - feruchemyChargeMap.clear(); - feruchemyChargeMap.putAll(metalmindCharges); + feruchemyChargeMap.clear(); + feruchemyChargeMap.putAll(metalmindCharges); - feruchemyMaxChargeMap.clear(); - feruchemyMaxChargeMap.putAll(metalmindMaxCharges); - lock.unlock(); - } + feruchemyMaxChargeMap.clear(); + feruchemyMaxChargeMap.putAll(metalmindMaxCharges); } - catch (Exception e) + finally { - e.printStackTrace(); lock.unlock(); } } diff --git a/src/feruchemy/java/leaf/cosmere/feruchemy/common/manifestation/FeruchemyManifestation.java b/src/feruchemy/java/leaf/cosmere/feruchemy/common/manifestation/FeruchemyManifestation.java index de5c7f072..68c32ffb3 100644 --- a/src/feruchemy/java/leaf/cosmere/feruchemy/common/manifestation/FeruchemyManifestation.java +++ b/src/feruchemy/java/leaf/cosmere/feruchemy/common/manifestation/FeruchemyManifestation.java @@ -19,6 +19,8 @@ import net.minecraft.util.Mth; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.item.ItemStack; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; import java.util.HashMap; @@ -82,6 +84,7 @@ public void onModeChange(ISpiritweb data, int lastMode) } } + @OnlyIn(Dist.CLIENT) private void collectMenuInfo() { if (Minecraft.getInstance().player != null && Minecraft.getInstance().player.tickCount % 2 == 1) // only do on odd tick @@ -107,6 +110,7 @@ public float getInvestitureHud(ISpiritweb spiritweb) collectMenuInfo(); double maximum = metalmindMaxChargesMap.getOrDefault(metalType, 0d); double charge = metalmindChargesMap.getOrDefault(metalType, 0d); + if (maximum <= 0) return 0.f; return (float) (charge/maximum); } diff --git a/src/main/java/leaf/cosmere/client/gui/GuiUtils.java b/src/main/java/leaf/cosmere/client/gui/GuiUtils.java index 138437e1c..c5f619995 100644 --- a/src/main/java/leaf/cosmere/client/gui/GuiUtils.java +++ b/src/main/java/leaf/cosmere/client/gui/GuiUtils.java @@ -1,7 +1,5 @@ package leaf.cosmere.client.gui; -import org.checkerframework.checker.units.qual.C; - import java.awt.*; public class GuiUtils diff --git a/src/main/java/leaf/cosmere/client/gui/SpiritwebHud.java b/src/main/java/leaf/cosmere/client/gui/SpiritwebHud.java index a21a2cfdd..35d062b62 100644 --- a/src/main/java/leaf/cosmere/client/gui/SpiritwebHud.java +++ b/src/main/java/leaf/cosmere/client/gui/SpiritwebHud.java @@ -34,26 +34,6 @@ public SpiritwebHud(Player player) this.player = player; } -// public static SpiritwebHud Instance(Player player) -// { -// if (INSTANCE == null) -// { -// INSTANCE = new SpiritwebHud(CosmereConfigs.CLIENT_CONFIG.hudXCoordinate.get(), -// CosmereConfigs.CLIENT_CONFIG.hudYCoordinate.get(), -// CosmereConfigs.CLIENT_CONFIG.hudSizeX.get(), -// CosmereConfigs.CLIENT_CONFIG.hudSizeY.get(), -// Component.literal("Spiritweb HUD"), -// player); // should never be null -// } -// -// return INSTANCE; -// } -// -// public static void killInstance() -// { -// INSTANCE = null; -// } - @Override protected void renderWidget(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) { diff --git a/src/main/java/leaf/cosmere/client/gui/SpiritwebRegistry.java b/src/main/java/leaf/cosmere/client/gui/SpiritwebRegistry.java index 692482149..ccfdabac8 100644 --- a/src/main/java/leaf/cosmere/client/gui/SpiritwebRegistry.java +++ b/src/main/java/leaf/cosmere/client/gui/SpiritwebRegistry.java @@ -8,15 +8,11 @@ public class SpiritwebRegistry { - private static volatile SpiritwebRegistry INSTANCE; + private static volatile SpiritwebRegistry INSTANCE = new SpiritwebRegistry(); private final HashMap> manifestationScreenMap = new HashMap<>(); public static SpiritwebRegistry getInstance() { - if (INSTANCE == null) - { - INSTANCE = new SpiritwebRegistry(); - } return INSTANCE; } diff --git a/src/main/java/leaf/cosmere/common/cap/entity/SpiritwebCapability.java b/src/main/java/leaf/cosmere/common/cap/entity/SpiritwebCapability.java index edd78d499..0aefc64ef 100644 --- a/src/main/java/leaf/cosmere/common/cap/entity/SpiritwebCapability.java +++ b/src/main/java/leaf/cosmere/common/cap/entity/SpiritwebCapability.java @@ -69,6 +69,7 @@ public class SpiritwebCapability implements ISpiritweb public final Map MANIFESTATIONS_MODE = new HashMap<>(); private Manifestation selectedManifestation = ManifestationRegistry.NONE.get(); + @OnlyIn(Dist.CLIENT) private SpiritwebHud spiritwebHud; public List pushBlocks = new ArrayList<>(4); From c8fecccd773ae2b670900ff39560c9866b04cc27 Mon Sep 17 00:00:00 2001 From: Gerbagel Date: Sat, 2 May 2026 18:46:55 +0200 Subject: [PATCH 46/55] [Cosmere] Reimplement optional HUD config --- .../java/leaf/cosmere/client/gui/SpiritwebHud.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/main/java/leaf/cosmere/client/gui/SpiritwebHud.java b/src/main/java/leaf/cosmere/client/gui/SpiritwebHud.java index 35d062b62..e779cb6c9 100644 --- a/src/main/java/leaf/cosmere/client/gui/SpiritwebHud.java +++ b/src/main/java/leaf/cosmere/client/gui/SpiritwebHud.java @@ -37,10 +37,13 @@ public SpiritwebHud(Player player) @Override protected void renderWidget(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) { - renderBackground(pGuiGraphics); - renderUsage(pGuiGraphics); - renderIcon(pGuiGraphics); - renderText(pGuiGraphics); + if (!CosmereConfigs.CLIENT_CONFIG.disableSelectedManifestationHud.get()) + { + renderBackground(pGuiGraphics); + renderUsage(pGuiGraphics); + renderIcon(pGuiGraphics); + renderText(pGuiGraphics); + } } @Override From 125cfaab5287e0cd4c4c1fea61b4a4ce3b962bc8 Mon Sep 17 00:00:00 2001 From: Gerbagel Date: Sat, 2 May 2026 18:56:19 +0200 Subject: [PATCH 47/55] [Cosmere] Remove leftovers --- src/main/java/leaf/cosmere/client/gui/SpiritwebHud.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/leaf/cosmere/client/gui/SpiritwebHud.java b/src/main/java/leaf/cosmere/client/gui/SpiritwebHud.java index e779cb6c9..59bd4f18d 100644 --- a/src/main/java/leaf/cosmere/client/gui/SpiritwebHud.java +++ b/src/main/java/leaf/cosmere/client/gui/SpiritwebHud.java @@ -21,7 +21,6 @@ public class SpiritwebHud extends AbstractWidget { - private static SpiritwebHud INSTANCE; private Player player; public SpiritwebHud(Player player) From 6e071d3f548f37f3257968d3a0d14cad622d571e Mon Sep 17 00:00:00 2001 From: Gerbagel Date: Sat, 2 May 2026 19:29:43 +0200 Subject: [PATCH 48/55] [Cosmere] De-green the background color --- src/main/java/leaf/cosmere/client/gui/GuiUtils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/leaf/cosmere/client/gui/GuiUtils.java b/src/main/java/leaf/cosmere/client/gui/GuiUtils.java index c5f619995..b579c9170 100644 --- a/src/main/java/leaf/cosmere/client/gui/GuiUtils.java +++ b/src/main/java/leaf/cosmere/client/gui/GuiUtils.java @@ -4,7 +4,7 @@ public class GuiUtils { - public static final Color BACKGROUND_COLOR = new Color(61, 70, 76); + public static final Color BACKGROUND_COLOR = new Color(61, 61, 71); public record CachedQuad(float px, float py, float size) {} } From 2bb8b0d87425ee22361f565ab68610ad52a1ac55 Mon Sep 17 00:00:00 2001 From: Gerbagel Date: Sat, 2 May 2026 19:59:52 +0200 Subject: [PATCH 49/55] [Allomancy] Added Atium button --- .../client/gui/AllomancySpiritwebMenu.java | 3 + .../allomancy/client/gui/SquareButton.java | 232 ++++++++++++++++++ 2 files changed, 235 insertions(+) create mode 100644 src/allomancy/java/leaf/cosmere/allomancy/client/gui/SquareButton.java diff --git a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/AllomancySpiritwebMenu.java b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/AllomancySpiritwebMenu.java index fe48dd82d..2d2a00d18 100644 --- a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/AllomancySpiritwebMenu.java +++ b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/AllomancySpiritwebMenu.java @@ -65,6 +65,9 @@ protected void init() addRenderableWidget(new InnerRadialButton(circleCenterX, circleCenterY, 2, Metals.MetalType.ALUMINUM, iSpiritweb, manifestationConsumer)); // Duralumin addRenderableWidget(new InnerRadialButton(circleCenterX, circleCenterY, 3, Metals.MetalType.DURALUMIN, iSpiritweb, manifestationConsumer)); + + // Atium + addRenderableWidget(new SquareButton(circleCenterX + height/3, circleCenterY + height/3 - height/16, height/8, Metals.MetalType.ATIUM, iSpiritweb, manifestationConsumer)); })); } diff --git a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/SquareButton.java b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/SquareButton.java new file mode 100644 index 000000000..84097b3c0 --- /dev/null +++ b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/SquareButton.java @@ -0,0 +1,232 @@ +package leaf.cosmere.allomancy.client.gui; + +import com.mojang.blaze3d.systems.RenderSystem; +import com.mojang.blaze3d.vertex.BufferBuilder; +import com.mojang.blaze3d.vertex.DefaultVertexFormat; +import com.mojang.blaze3d.vertex.Tesselator; +import com.mojang.blaze3d.vertex.VertexFormat; +import leaf.cosmere.allomancy.common.manifestation.AllomancyManifestation; +import leaf.cosmere.api.IHasMetalType; +import leaf.cosmere.api.ISpiritwebSubmodule; +import leaf.cosmere.api.Manifestations; +import leaf.cosmere.api.Metals; +import leaf.cosmere.api.manifestation.Manifestation; +import leaf.cosmere.api.spiritweb.ISpiritweb; +import leaf.cosmere.client.gui.GuiUtils; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.components.Button; +import net.minecraft.client.renderer.GameRenderer; +import net.minecraft.network.chat.CommonComponents; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import org.joml.Matrix4f; +import org.lwjgl.opengl.GL11; + +import java.awt.*; +import java.util.function.Consumer; + +public class SquareButton extends Button +{ + private final ResourceLocation iconLocation; + private final Consumer manifestationConsumer; + private final ISpiritweb spiritweb; + private final Metals.MetalType metalType; + private final Manifestation manifestation; + private final boolean hasManifestation; + + protected SquareButton(int pX, int pY, int pSize, Metals.MetalType metal, ISpiritweb spiritweb, Consumer maniConsumer) + { + super(pX, pY, pSize, pSize, CommonComponents.EMPTY, (button -> { }), DEFAULT_NARRATION); + + metalType = metal; + manifestation = Manifestations.ManifestationTypes.ALLOMANCY.getManifestation(metalType.getID()); + hasManifestation = spiritweb.hasManifestation(manifestation); + this.spiritweb = spiritweb; + manifestationConsumer = maniConsumer; + + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.setLength(0); + stringBuilder.append("textures/icon/") + .append(manifestation.getManifestationType().getName()) + .append("/"); + + // no need for a switch case, always allomancy + if (manifestation instanceof IHasMetalType metalType) + { + stringBuilder.append(metalType.getMetalType().getName()); + } + + stringBuilder.append(".png"); + iconLocation = new ResourceLocation(manifestation.getRegistryName().getNamespace(), stringBuilder.toString()); + } + + @Override + public void render(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) + { + boolean isHovered = isMouseOver(pMouseX, pMouseY); + if (isHovered) + manifestationConsumer.accept(manifestation); + + renderBackground(pGuiGraphics, isHovered); + renderIcon(pGuiGraphics); + renderBorder(pGuiGraphics); + } + + private void renderBackground(GuiGraphics pGuiGraphics, boolean isHovered) + { + float r = GuiUtils.BACKGROUND_COLOR.getRed()/255.f, g = GuiUtils.BACKGROUND_COLOR.getGreen()/255.f, b = GuiUtils.BACKGROUND_COLOR.getBlue()/255.f; + float a = 1f; + + if (!hasManifestation) + { + r *= 0.6f; + g *= 0.6f; + b *= 0.6f; + } + + if (isHovered && hasManifestation) + { + r *= 1.1f; + g *= 1.1f; + b *= 1.1f; + } + + if (manifestation instanceof AllomancyManifestation allomancyManifestation) { + int mode = allomancyManifestation.getMode(spiritweb); + float intensity = Math.min(Math.abs(mode) * 0.2f, 1.0f); // Cap intensity + + if (mode > 0) { + // Blend toward pure red + r = lerp(r, 1.0f, intensity); + g = lerp(g, 0.0f, intensity); + b = lerp(b, 0.0f, intensity); + } else if (mode < 0) { + // Blend toward pure blue + r = lerp(r, 0.0f, intensity); + g = lerp(g, 0.0f, intensity); + b = lerp(b, 1.0f, intensity); + } + } + + RenderSystem.disableCull(); + RenderSystem.enableBlend(); + RenderSystem.defaultBlendFunc(); + RenderSystem.setShader(GameRenderer::getPositionColorShader); + Matrix4f pose = pGuiGraphics.pose().last().pose(); + + Tesselator tess = Tesselator.getInstance(); + BufferBuilder buf = tess.getBuilder(); + + buf.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR); + + buf.vertex(pose, getX(), getY(), 0).color(r, g, b, a).endVertex(); + buf.vertex(pose, getX()+getWidth(), getY(), 0).color(r, g, b, a).endVertex(); + buf.vertex(pose, getX()+getWidth(), getY()+getHeight(), 0).color(r, g, b, a).endVertex(); + buf.vertex(pose, getX(), getY()+getHeight(), 0).color(r, g, b, a).endVertex(); + + tess.end(); + RenderSystem.disableBlend(); + } + + private void renderBorder(GuiGraphics pGuiGraphics) + { + int color = 0xff9badb7; + int thickness = 1; + RenderSystem.disableCull(); + RenderSystem.enableBlend(); + RenderSystem.defaultBlendFunc(); + RenderSystem.setShader(GameRenderer::getPositionColorShader); + Matrix4f pose = pGuiGraphics.pose().last().pose(); + + Tesselator tess = Tesselator.getInstance(); + BufferBuilder buf = tess.getBuilder(); + + buf.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR); + + int x = getX(); + int y = getY(); + int w = getWidth(); + int h = getHeight(); + + // Top edge + buf.vertex(pose, x, y, 0).color(color).endVertex(); + buf.vertex(pose, x + w, y, 0).color(color).endVertex(); + buf.vertex(pose, x + w, y + thickness, 0).color(color).endVertex(); + buf.vertex(pose, x, y + thickness, 0).color(color).endVertex(); + + // Bottom edge + buf.vertex(pose, x, y + h - thickness, 0).color(color).endVertex(); + buf.vertex(pose, x + w, y + h - thickness, 0).color(color).endVertex(); + buf.vertex(pose, x + w, y + h, 0).color(color).endVertex(); + buf.vertex(pose, x, y + h, 0).color(color).endVertex(); + + // Left edge + buf.vertex(pose, x, y + thickness, 0).color(color).endVertex(); + buf.vertex(pose, x + thickness, y + thickness, 0).color(color).endVertex(); + buf.vertex(pose, x + thickness, y + h - thickness, 0).color(color).endVertex(); + buf.vertex(pose, x, y + h - thickness, 0).color(color).endVertex(); + + // Right edge + buf.vertex(pose, x + w - thickness, y + thickness, 0).color(color).endVertex(); + buf.vertex(pose, x + w, y + thickness, 0).color(color).endVertex(); + buf.vertex(pose, x + w, y + h - thickness, 0).color(color).endVertex(); + buf.vertex(pose, x + w - thickness, y + h - thickness, 0).color(color).endVertex(); + + tess.end(); + RenderSystem.disableBlend(); + } + + private void renderIcon(GuiGraphics pGuiGraphics) + { + Color metalColor = metalType.getColor(); + float r = metalColor.getRed()/255.f, g = metalColor.getGreen()/255.f, b = metalColor.getBlue()/255.f; + + if (!hasManifestation) + { + r *= 0.1f; + g *= 0.1f; + b *= 0.1f; + } + + float alpha = hasManifestation ? 1.0f : 0.25f; + RenderSystem.setShaderTexture(0, iconLocation); + RenderSystem.enableBlend(); + RenderSystem.blendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, 1, 0); + + int iconSize = width-10; + int posX = getX() + 5; + int posY = getY() + 5; + + RenderSystem.setShaderColor(0f, 0f, 0f, alpha); + pGuiGraphics.blit(iconLocation, + posX+1, + posY+1, + iconSize, + iconSize, + 0, + 0, + width, + height, + width, + height); + + RenderSystem.setShaderColor(r, g, b, alpha); + pGuiGraphics.blit(iconLocation, + posX, + posY, + iconSize, + iconSize, + 0, + 0, + width, + height, + width, + height); + + RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f); + } + + public float lerp(float start, float end, float pct) { + return start + pct * (end - start); + } +} From 4bf112a2082131733fd8ba987c0fef1309c1d087 Mon Sep 17 00:00:00 2001 From: Gerbagel Date: Sat, 2 May 2026 20:20:00 +0200 Subject: [PATCH 50/55] [Feruchemy] Added atium button --- .../client/gui/FeruchemySpiritwebMenu.java | 34 ++++++++++++++++++ .../textures/gui/feru_single_border.png | Bin 0 -> 404 bytes 2 files changed, 34 insertions(+) create mode 100644 src/feruchemy/resources/assets/feruchemy/textures/gui/feru_single_border.png diff --git a/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/FeruchemySpiritwebMenu.java b/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/FeruchemySpiritwebMenu.java index 3b5f21ba6..4ee62a279 100644 --- a/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/FeruchemySpiritwebMenu.java +++ b/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/FeruchemySpiritwebMenu.java @@ -16,6 +16,7 @@ public class FeruchemySpiritwebMenu extends CosmereScreen { private static final ResourceLocation BORDER_LOCATION = new ResourceLocation(Feruchemy.MODID, "textures/gui/feru_border.png"); + private static final ResourceLocation SINGLE_BORDER_LOCATION = new ResourceLocation(Feruchemy.MODID, "textures/gui/feru_single_border.png"); private static final float QUARTER_PI_F = (float) (Math.PI/2.f); private int distance; final LocalPlayer player; @@ -82,6 +83,12 @@ protected void init() distance, bottomRightRot, Metals.MetalType.NICROSIL, spiritweb, manifestationConsumer)); addRenderableWidget(new TriangleButton(x, y + distance, distance, bottomLeftRot, Metals.MetalType.ALUMINUM, spiritweb, manifestationConsumer)); + + x = this.width / 2 - (int) (distance*1.75); + y = this.height/2 + (int) (distance*0.75); + + addRenderableWidget(new TriangleButton(x, y, + distance, topRightRot, Metals.MetalType.ATIUM, spiritweb, manifestationConsumer)); })); } @@ -90,6 +97,7 @@ public void render(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPa { super.render(pGuiGraphics, pMouseX, pMouseY, pPartialTick); renderBorder(pGuiGraphics); + renderAtiumBorder(pGuiGraphics); } private void renderBorder(GuiGraphics pGuiGraphics) @@ -117,4 +125,30 @@ private void renderBorder(GuiGraphics pGuiGraphics) RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f); } + + private void renderAtiumBorder(GuiGraphics pGuiGraphics) + { + RenderSystem.setShaderTexture(0, SINGLE_BORDER_LOCATION); + RenderSystem.enableBlend(); + RenderSystem.blendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, 1, 0); + RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f); + + final int x = this.width / 2 - (int) (distance*1.75), y = this.height/2 + (int) (distance*0.75); + final int screenSize = distance; + final int iconSize = 64; + + pGuiGraphics.blit(SINGLE_BORDER_LOCATION, + x, + y, + screenSize, + screenSize, + 0, + 0, + iconSize, + iconSize, + iconSize, + iconSize); + + RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f); + } } diff --git a/src/feruchemy/resources/assets/feruchemy/textures/gui/feru_single_border.png b/src/feruchemy/resources/assets/feruchemy/textures/gui/feru_single_border.png new file mode 100644 index 0000000000000000000000000000000000000000..5822c24f92d2fa7034973a363cf749410d163b8c GIT binary patch literal 404 zcmV;F0c-w=P)Px$PDw;TRCt`_+PxLRFbqb~7q+8j2Bu;LYQ}?(6Y__X*p~F^l`gNPPQ&B*dNb;N zyACAkGJTkWsP_dJ|9mEdp9#o_Fk69a2r~eZAuIxr2w@d~BnX=TBtZBJfH*=C0Ky2x z0Ei;&0zeR9HvnP?hX4>lI1GRY!YKd*5KaRS9H9yTff1?!5EP**009xI0}u?M2>^i* zngI|5p(y|X5Sjzv9H9#UjuE;6;1r=N01gql1K6uc038wB0?-M;H2@tD+yl@UAp`&o5yAk_2q6>z4G_WsP#Ga4 z02L9!0#FGdGyoM4!UJ#;K>~mi2r>X1M34gD0D>F Date: Sat, 2 May 2026 23:36:25 +0200 Subject: [PATCH 51/55] Revert "[Cosmere] Custom mixin json management" This reverts commit a828f3e794c4a4a6a32d40af25da8e21b6692b04. --- build.gradle | 53 ++++++------------- .../client/SurgebindingKeybindings.java | 10 ++-- 2 files changed, 22 insertions(+), 41 deletions(-) diff --git a/build.gradle b/build.gradle index 5cbfde3d6..ab8375cde 100644 --- a/build.gradle +++ b/build.gradle @@ -478,18 +478,18 @@ dependencies { mixin { // MixinGradle Settings - //add sourceSets.main, 'mixins.cosmere.refmap.json' - //add sourceSets.api, 'mixins.cosmere.api.refmap.json' - //add sourceSets.allomancy, 'mixins.cosmere.allomancy.refmap.json' - //add sourceSets.feruchemy, 'mixins.cosmere.feruchemy.refmap.json' - //add sourceSets.hemalurgy, 'mixins.cosmere.hemalurgy.refmap.json' - //add sourceSets.surgebinding, 'mixins.cosmere.surgebinding.refmap.json' - //add sourceSets.sandmastery, 'mixins.cosmere.sandmastery.refmap.json' - //add sourceSets.aviar, 'mixins.cosmere.aviar.refmap.json' - //add sourceSets.awakening, 'mixins.cosmere.awakening.refmap.json' - //add sourceSets.aondor, 'mixins.cosmere.aondor.refmap.json' - //add sourceSets.soulforgery, 'mixins.cosmere.soulforgery.refmap.json' - //add sourceSets.cosmeretools, 'mixins.cosmere.cosmeretools.refmap.json' + add sourceSets.main, 'mixins.cosmere.refmap.json' + add sourceSets.api, 'mixins.cosmere.api.refmap.json' + add sourceSets.allomancy, 'mixins.cosmere.allomancy.refmap.json' + add sourceSets.feruchemy, 'mixins.cosmere.feruchemy.refmap.json' + add sourceSets.hemalurgy, 'mixins.cosmere.hemalurgy.refmap.json' + add sourceSets.surgebinding, 'mixins.cosmere.surgebinding.refmap.json' + add sourceSets.sandmastery, 'mixins.cosmere.sandmastery.refmap.json' + add sourceSets.aviar, 'mixins.cosmere.aviar.refmap.json' + add sourceSets.awakening, 'mixins.cosmere.awakening.refmap.json' + add sourceSets.aondor, 'mixins.cosmere.aondor.refmap.json' + add sourceSets.soulforgery, 'mixins.cosmere.soulforgery.refmap.json' + add sourceSets.cosmeretools, 'mixins.cosmere.cosmeretools.refmap.json' config 'cosmere.mixins.json' //config 'cosmere.mixins.api.json' @@ -523,7 +523,6 @@ def getManifestAttributes(String title) tasks.named('jar', Jar).configure { duplicatesStrategy(DuplicatesStrategy.FAIL) from([sourceSets.api.output, sourceSets.main.output]) - exclude 'mixin.refmap.json' manifest.attributes(getManifestAttributes("Cosmere")) } @@ -566,7 +565,6 @@ def secondaryJar(SourceSet sourceSet, String title) duplicatesStrategy(DuplicatesStrategy.FAIL) archiveClassifier.set(sourceSet.name) from sourceSet.output - exclude 'mixin.refmap.json' if (!title.isEmpty()) { def filename = "${title}-${project.version}.jar" //basically don't add cosmere if it already has cosmere in it @@ -590,28 +588,9 @@ def soulforgeryJar = secondaryJar(sourceSets.soulforgery, 'SoulForgery') def exampleJar = secondaryJar(sourceSets.example, 'Example') def cosmeretoolsJar = secondaryJar(sourceSets.cosmeretools, 'CosmereTools') -tasks.withType(JavaCompile).configureEach({task -> - options.encoding = 'UTF-8' - options.compilerArgs.addAll(["-Xmaxerrs", "100000"]) - - def matcher = task.name =~ /compile(.*)Java/ - if (matcher.matches() && matcher.group(1) != 'Test') { - def sourceSetName = matcher.group(1).toLowerCase() - - // Use 'main' for the standard compileJava task - if (task.name == 'compileJava') sourceSetName = 'main' - - task.doFirst { - // Strip out any outRefMapFile arguments appended by ForgeGradle/MixinGradle - options.compilerArgs.removeIf { it.startsWith('-AoutRefMapFile=') } - - // Format the refmap name correctly: omit '.main' if it's the main source set - def refmapName = sourceSetName == 'main' ? 'mixins.cosmere.refmap.json' : "mixins.cosmere.${sourceSetName}.refmap.json" - - // Force the AP to output directly to the classes directory - options.compilerArgs << "-AoutRefMapFile=${layout.buildDirectory.dir("classes/java/${sourceSetName}").get().asFile}/${refmapName}" - } - } +tasks.withType(JavaCompile).configureEach({ + options.encoding = 'UTF-8' + options.compilerArgs.addAll(["-Xmaxerrs", "100000"]) }) artifacts { @@ -906,4 +885,4 @@ tasks.register('publishToModSites') { if (System.getenv("CURSEFORGE_API_TOKEN") != null || project.hasProperty('curseforge_api_token')) { publishToModSites.dependsOn tasks.named("curseforge") } -} +} \ No newline at end of file diff --git a/src/surgebinding/java/leaf/cosmere/surgebinding/client/SurgebindingKeybindings.java b/src/surgebinding/java/leaf/cosmere/surgebinding/client/SurgebindingKeybindings.java index 682edcafc..4af3a3592 100644 --- a/src/surgebinding/java/leaf/cosmere/surgebinding/client/SurgebindingKeybindings.java +++ b/src/surgebinding/java/leaf/cosmere/surgebinding/client/SurgebindingKeybindings.java @@ -46,11 +46,12 @@ public class SurgebindingKeybindings @SubscribeEvent public static void register(RegisterKeyMappingsEvent event) { - for (Map.Entry kvPair : SURGEBINDING_POWER.entrySet()) + for (Roshar.Surges surge : SURGEBINDING_POWER.keySet()) { - SurgebindingManifestation manifest = (SurgebindingManifestation) SURGEBINDING_POWERS.get(kvPair.getKey()).getManifestation(); - event.register(kvPair.getValue()); - Activator entry = new Activator(kvPair.getValue(), manifest); + KeyMapping key = SURGEBINDING_POWER.get(surge); + SurgebindingManifestation manifest = (SurgebindingManifestation) SURGEBINDING_POWERS.get(surge).getManifestation(); + event.register(key); + Activator entry = new Activator(key, manifest); entry.setCategory("keys.surgebinding.main"); Keybindings.activators.add(entry); } @@ -58,6 +59,7 @@ public static void register(RegisterKeyMappingsEvent event) event.register(SHARDBLADE = new KeyMapping(KEY_SHARDBLADE, GLFW.GLFW_KEY_X, "keys.surgebinding.main")); event.register(REQUEST_STORMLIGHT = new KeyMapping(KEY_REQUEST_STORMLIGHT, GLFW.GLFW_KEY_Z, "keys.surgebinding.main")); event.register(DISPATCH_STORMLIGHT = new KeyMapping(KEY_DISPATCH_STORMLIGHT, GLFW.GLFW_KEY_Y, "keys.surgebinding.main")); + } } From 9b2a0bb0e1d66836f9aa3e41b005be778b4d32bb Mon Sep 17 00:00:00 2001 From: Gerbagel Date: Sun, 3 May 2026 00:11:30 +0200 Subject: [PATCH 52/55] [Cosmere] Adjust size of info blocks and add more to GuiUtils --- .../client/gui/AllomancySpiritwebMenu.java | 2 +- .../client/gui/InnerRadialButton.java | 9 ++-- .../client/gui/OuterRadialButton.java | 9 ++-- .../allomancy/client/gui/SquareButton.java | 52 ++++++++++++++++++- .../9fb1092f32d4fcbf9e061ffd718d4ec689c6c95e | 4 +- .../dd0552f4815307fa79918bc7fddf7e3ebb5df25c | 12 ++--- .../data/minecraft/tags/items/axes.json | 32 ++++++------ .../data/minecraft/tags/items/hoes.json | 32 ++++++------ .../data/minecraft/tags/items/pickaxes.json | 32 ++++++------ .../data/minecraft/tags/items/shovels.json | 32 ++++++------ .../data/minecraft/tags/items/swords.json | 32 ++++++------ .../109f316ce3b77a5a02bbf6e9c200027075e14620 | 4 +- .../892be08db83774b45ce3700a46f41c5cc1a66597 | 4 +- .../9fb1092f32d4fcbf9e061ffd718d4ec689c6c95e | 3 +- .../a42c2d14910c607d1cdeea761ec88e5ad05f96c6 | 7 +-- .../c622617f6fabf890a00b9275cd5f643584a8a2c8 | 4 +- .../curios/entities/shardbearers.json | 8 +-- .../feruchemy/client/gui/TriangleButton.java | 9 ++-- .../leaf/cosmere/client/gui/GuiUtils.java | 23 ++++++++ .../leaf/cosmere/client/gui/SpiritwebHud.java | 8 +-- 20 files changed, 194 insertions(+), 124 deletions(-) diff --git a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/AllomancySpiritwebMenu.java b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/AllomancySpiritwebMenu.java index 2d2a00d18..075633f39 100644 --- a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/AllomancySpiritwebMenu.java +++ b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/AllomancySpiritwebMenu.java @@ -67,7 +67,7 @@ protected void init() addRenderableWidget(new InnerRadialButton(circleCenterX, circleCenterY, 3, Metals.MetalType.DURALUMIN, iSpiritweb, manifestationConsumer)); // Atium - addRenderableWidget(new SquareButton(circleCenterX + height/3, circleCenterY + height/3 - height/16, height/8, Metals.MetalType.ATIUM, iSpiritweb, manifestationConsumer)); + addRenderableWidget(new SquareButton(circleCenterX + height/4, circleCenterY + height/3 - height/16, height/8, Metals.MetalType.ATIUM, iSpiritweb, manifestationConsumer)); })); } diff --git a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java index b5b71b9d4..70f8a28a9 100644 --- a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java +++ b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/InnerRadialButton.java @@ -294,8 +294,8 @@ private void renderInfoBlock(GuiGraphics pGuiGraphics) int screenHeight = Minecraft.getInstance().getWindow().getGuiScaledHeight(); int x = 0; int y = 0; - int width = (int) (screenWidth * 0.3); - int height = screenHeight / 5; + int width = GuiUtils.getInfoBoxWidth(Minecraft.getInstance()); + int height = GuiUtils.getInfoBoxHeight(Minecraft.getInstance()); int color = 0x99333333; if (segmentNr <= 1) @@ -330,7 +330,8 @@ else if (segmentNr <= 7) pGuiGraphics.fill(x, y, x + width, y + height, color); String text = I18n.get(manifestation.getTranslationKey()); - pGuiGraphics.drawString(font, text, x+5, y+10, 0xFFFFFFFF); + float scale = 0.8f; + GuiUtils.drawScaledString(font, pGuiGraphics, text, x+5, y+10, scale, 0xFFFFFFFF); int seconds = manifestation.getInvestitureRemaining(spiritweb); int hours = seconds / 3600; @@ -346,7 +347,7 @@ else if (seconds > 0) else text = "Empty"; - pGuiGraphics.drawString(font, text, x+5, y+10+font.lineHeight+5, 0xFFFFFFFF); + GuiUtils.drawScaledString(font, pGuiGraphics, text, x+5, y+12+font.lineHeight*scale, scale, 0xFFFFFFFF); } private void calculateVertexes(float centerX, float centerY, float outerRadius, int segmentNr) diff --git a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java index 93193e891..4cc6531f4 100644 --- a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java +++ b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/OuterRadialButton.java @@ -299,8 +299,8 @@ private void renderInfoBlock(GuiGraphics pGuiGraphics) int screenHeight = Minecraft.getInstance().getWindow().getGuiScaledHeight(); int x = 0; int y = 0; - int width = (int) (screenWidth * 0.3); - int height = screenHeight / 5; + int width = GuiUtils.getInfoBoxWidth(Minecraft.getInstance()); + int height = GuiUtils.getInfoBoxHeight(Minecraft.getInstance()); int color = 0x99333333; if (segmentNr <= 1) @@ -335,7 +335,8 @@ else if (segmentNr <= 7) pGuiGraphics.fill(x, y, x + width, y + height, color); String text = I18n.get(manifestation.getTranslationKey()); - pGuiGraphics.drawString(font, text, x+5, y+10, 0xFFFFFFFF); + float scale = 0.8f; + GuiUtils.drawScaledString(font, pGuiGraphics, text, x+5, y+10, scale, 0xFFFFFFFF); int seconds = manifestation.getInvestitureRemaining(spiritweb); int hours = seconds / 3600; @@ -351,7 +352,7 @@ else if (seconds > 0) else text = "Empty"; - pGuiGraphics.drawString(font, text, x+5, y+10+font.lineHeight+5, 0xFFFFFFFF); + GuiUtils.drawScaledString(font, pGuiGraphics, text, x+5, y+12+font.lineHeight*scale, scale, 0xFFFFFFFF); } private void calculateVertexes(float centerX, float centerY, float innerRadius, float outerRadius, int segmentNr) diff --git a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/SquareButton.java b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/SquareButton.java index 84097b3c0..9afd0c3d0 100644 --- a/src/allomancy/java/leaf/cosmere/allomancy/client/gui/SquareButton.java +++ b/src/allomancy/java/leaf/cosmere/allomancy/client/gui/SquareButton.java @@ -13,9 +13,12 @@ import leaf.cosmere.api.manifestation.Manifestation; import leaf.cosmere.api.spiritweb.ISpiritweb; import leaf.cosmere.client.gui.GuiUtils; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Font; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.Button; import net.minecraft.client.renderer.GameRenderer; +import net.minecraft.client.resources.language.I18n; import net.minecraft.network.chat.CommonComponents; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; @@ -64,12 +67,16 @@ protected SquareButton(int pX, int pY, int pSize, Metals.MetalType metal, ISpiri public void render(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) { boolean isHovered = isMouseOver(pMouseX, pMouseY); - if (isHovered) - manifestationConsumer.accept(manifestation); renderBackground(pGuiGraphics, isHovered); renderIcon(pGuiGraphics); renderBorder(pGuiGraphics); + if (isHovered) + { + if (hasManifestation) + renderInfoBlock(pGuiGraphics); + manifestationConsumer.accept(manifestation); + } } private void renderBackground(GuiGraphics pGuiGraphics, boolean isHovered) @@ -226,6 +233,47 @@ private void renderIcon(GuiGraphics pGuiGraphics) RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f); } + private void renderInfoBlock(GuiGraphics pGuiGraphics) + { + Font font = Minecraft.getInstance().font; + int screenWidth = Minecraft.getInstance().getWindow().getGuiScaledWidth(); + int screenHeight = Minecraft.getInstance().getWindow().getGuiScaledHeight(); + int x = 0; + int y = 0; + int width = GuiUtils.getInfoBoxWidth(Minecraft.getInstance()); + int height = GuiUtils.getInfoBoxHeight(Minecraft.getInstance()); + int color = 0x99333333; + + x = screenWidth - width - 10; + y = screenHeight - height - 10; + + RenderSystem.disableCull(); + RenderSystem.enableBlend(); + RenderSystem.defaultBlendFunc(); + + pGuiGraphics.fill(x, y, x + width, y + height, color); + + String text = I18n.get(manifestation.getTranslationKey()); + float scale = 0.8f; + GuiUtils.drawScaledString(font, pGuiGraphics, text, x+5, y+10, scale, 0xFFFFFFFF); + + int seconds = manifestation.getInvestitureRemaining(spiritweb); + int hours = seconds / 3600; + int minutes = (seconds % 3600) / 60; + seconds = seconds % 60; + + if (hours > 0) + text = String.format("%d:%02d:%02d", hours, minutes, seconds); + else if (minutes > 0) + text = String.format("%d:%02d", minutes, seconds); + else if (seconds > 0) + text = String.format("%02d", seconds); + else + text = "Empty"; + + GuiUtils.drawScaledString(font, pGuiGraphics, text, x+5, y+12+font.lineHeight*scale, scale, 0xFFFFFFFF); + } + public float lerp(float start, float end, float pct) { return start + pct * (end - start); } diff --git a/src/datagen/generated/allomancy/.cache/9fb1092f32d4fcbf9e061ffd718d4ec689c6c95e b/src/datagen/generated/allomancy/.cache/9fb1092f32d4fcbf9e061ffd718d4ec689c6c95e index d624b1f54..76af48f07 100644 --- a/src/datagen/generated/allomancy/.cache/9fb1092f32d4fcbf9e061ffd718d4ec689c6c95e +++ b/src/datagen/generated/allomancy/.cache/9fb1092f32d4fcbf9e061ffd718d4ec689c6c95e @@ -1,6 +1,8 @@ -// 1.20.1 2024-10-09T13:22:13.338555 Recipes +// 1.20.1 2026-05-02T23:37:02.49612847 Recipes +445aa9f7a583225384441480a5bbeb7fe0b2e4da data/allomancy/advancements/recipes/combat/mistcloak.json 2ab76b8b72d83f1207051efc1cb9174ae9ae4a61 data/allomancy/advancements/recipes/tools/coin_pouch.json ff01905c7528be493d7b447b09e20762cd818089 data/allomancy/advancements/recipes/tools/metal_vial.json 97699dc7b7a7cd857564421ad0cafff04b654089 data/allomancy/recipes/coin_pouch.json 8ad78df11acb7d92cf1169192b00ab592dc78b93 data/allomancy/recipes/metal_vial.json +08f1f6f97e7fca3553d79b739ffb4ec0038a3230 data/allomancy/recipes/mistcloak.json 08792c13f9fd6638a1e2f0b0a267e81ca8c42849 data/allomancy/recipes/vial_mixing.json diff --git a/src/datagen/generated/cosmeretools/.cache/dd0552f4815307fa79918bc7fddf7e3ebb5df25c b/src/datagen/generated/cosmeretools/.cache/dd0552f4815307fa79918bc7fddf7e3ebb5df25c index 64a0dc533..d99e6d6f2 100644 --- a/src/datagen/generated/cosmeretools/.cache/dd0552f4815307fa79918bc7fddf7e3ebb5df25c +++ b/src/datagen/generated/cosmeretools/.cache/dd0552f4815307fa79918bc7fddf7e3ebb5df25c @@ -1,6 +1,6 @@ -// 1.20.1 2026-05-02T16:53:45.055293082 Tags: cosmeretools -3694ca36839984fbd1c576bac7fe663250fcac60 data/minecraft/tags/items/axes.json -42a39e4c6b8a38d120a32a452fcec2538afdf632 data/minecraft/tags/items/hoes.json -cb5b2ceaf28163930f615b55ba36985d3e6e4edf data/minecraft/tags/items/pickaxes.json -3ade9eb60271d5e216124acb8dfe4e8297c01be0 data/minecraft/tags/items/shovels.json -5763236182c5a768e612a8f1dd2cb5142be5d982 data/minecraft/tags/items/swords.json +// 1.20.1 2026-05-02T23:37:02.462411953 Tags: cosmeretools +62b7cbba3bce74a1a13f88031f5d78481ed0ec6e data/minecraft/tags/items/axes.json +0f014713bf475e02c04a42a0b3ee79ffc3b6dbd7 data/minecraft/tags/items/hoes.json +d5422673aa1da7a7c75522b526e60a1793e5a602 data/minecraft/tags/items/pickaxes.json +d41f83a87ddcca32f29085a2cbb4ebf9686036eb data/minecraft/tags/items/shovels.json +a5f97d20b5dac76def51bd5e99510da2af42bd52 data/minecraft/tags/items/swords.json diff --git a/src/datagen/generated/cosmeretools/data/minecraft/tags/items/axes.json b/src/datagen/generated/cosmeretools/data/minecraft/tags/items/axes.json index 1476c1ea1..440142691 100644 --- a/src/datagen/generated/cosmeretools/data/minecraft/tags/items/axes.json +++ b/src/datagen/generated/cosmeretools/data/minecraft/tags/items/axes.json @@ -1,26 +1,26 @@ { "values": [ + "cosmeretools:chromium_axe", + "cosmeretools:electrum_axe", "cosmeretools:steel_axe", - "cosmeretools:malatium_axe", - "cosmeretools:lead_axe", + "cosmeretools:lerasatium_axe", "cosmeretools:aluminum_axe", "cosmeretools:copper_axe", - "cosmeretools:lerasatium_axe", - "cosmeretools:brass_axe", - "cosmeretools:bronze_axe", - "cosmeretools:pewter_axe", - "cosmeretools:chromium_axe", - "cosmeretools:atium_axe", - "cosmeretools:harmonium_axe", - "cosmeretools:electrum_axe", - "cosmeretools:nickel_axe", - "cosmeretools:duralumin_axe", + "cosmeretools:tin_axe", "cosmeretools:zinc_axe", - "cosmeretools:nicrosil_axe", "cosmeretools:bendalloy_axe", - "cosmeretools:tin_axe", - "cosmeretools:lerasium_axe", + "cosmeretools:atium_axe", + "cosmeretools:brass_axe", "cosmeretools:cadmium_axe", - "cosmeretools:silver_axe" + "cosmeretools:duralumin_axe", + "cosmeretools:nicrosil_axe", + "cosmeretools:lead_axe", + "cosmeretools:malatium_axe", + "cosmeretools:nickel_axe", + "cosmeretools:bronze_axe", + "cosmeretools:harmonium_axe", + "cosmeretools:silver_axe", + "cosmeretools:pewter_axe", + "cosmeretools:lerasium_axe" ] } \ No newline at end of file diff --git a/src/datagen/generated/cosmeretools/data/minecraft/tags/items/hoes.json b/src/datagen/generated/cosmeretools/data/minecraft/tags/items/hoes.json index 40c81a2a3..7fdced381 100644 --- a/src/datagen/generated/cosmeretools/data/minecraft/tags/items/hoes.json +++ b/src/datagen/generated/cosmeretools/data/minecraft/tags/items/hoes.json @@ -1,26 +1,26 @@ { "values": [ + "cosmeretools:chromium_hoe", + "cosmeretools:electrum_hoe", "cosmeretools:steel_hoe", - "cosmeretools:malatium_hoe", - "cosmeretools:lead_hoe", + "cosmeretools:lerasatium_hoe", "cosmeretools:aluminum_hoe", "cosmeretools:copper_hoe", - "cosmeretools:lerasatium_hoe", - "cosmeretools:brass_hoe", - "cosmeretools:bronze_hoe", - "cosmeretools:pewter_hoe", - "cosmeretools:chromium_hoe", - "cosmeretools:atium_hoe", - "cosmeretools:harmonium_hoe", - "cosmeretools:electrum_hoe", - "cosmeretools:nickel_hoe", - "cosmeretools:duralumin_hoe", + "cosmeretools:tin_hoe", "cosmeretools:zinc_hoe", - "cosmeretools:nicrosil_hoe", "cosmeretools:bendalloy_hoe", - "cosmeretools:tin_hoe", - "cosmeretools:lerasium_hoe", + "cosmeretools:atium_hoe", + "cosmeretools:brass_hoe", "cosmeretools:cadmium_hoe", - "cosmeretools:silver_hoe" + "cosmeretools:duralumin_hoe", + "cosmeretools:nicrosil_hoe", + "cosmeretools:lead_hoe", + "cosmeretools:malatium_hoe", + "cosmeretools:nickel_hoe", + "cosmeretools:bronze_hoe", + "cosmeretools:harmonium_hoe", + "cosmeretools:silver_hoe", + "cosmeretools:pewter_hoe", + "cosmeretools:lerasium_hoe" ] } \ No newline at end of file diff --git a/src/datagen/generated/cosmeretools/data/minecraft/tags/items/pickaxes.json b/src/datagen/generated/cosmeretools/data/minecraft/tags/items/pickaxes.json index d33d1f1e4..b82398041 100644 --- a/src/datagen/generated/cosmeretools/data/minecraft/tags/items/pickaxes.json +++ b/src/datagen/generated/cosmeretools/data/minecraft/tags/items/pickaxes.json @@ -1,26 +1,26 @@ { "values": [ + "cosmeretools:chromium_pickaxe", + "cosmeretools:electrum_pickaxe", "cosmeretools:steel_pickaxe", - "cosmeretools:malatium_pickaxe", - "cosmeretools:lead_pickaxe", + "cosmeretools:lerasatium_pickaxe", "cosmeretools:aluminum_pickaxe", "cosmeretools:copper_pickaxe", - "cosmeretools:lerasatium_pickaxe", - "cosmeretools:brass_pickaxe", - "cosmeretools:bronze_pickaxe", - "cosmeretools:pewter_pickaxe", - "cosmeretools:chromium_pickaxe", - "cosmeretools:atium_pickaxe", - "cosmeretools:harmonium_pickaxe", - "cosmeretools:electrum_pickaxe", - "cosmeretools:nickel_pickaxe", - "cosmeretools:duralumin_pickaxe", + "cosmeretools:tin_pickaxe", "cosmeretools:zinc_pickaxe", - "cosmeretools:nicrosil_pickaxe", "cosmeretools:bendalloy_pickaxe", - "cosmeretools:tin_pickaxe", - "cosmeretools:lerasium_pickaxe", + "cosmeretools:atium_pickaxe", + "cosmeretools:brass_pickaxe", "cosmeretools:cadmium_pickaxe", - "cosmeretools:silver_pickaxe" + "cosmeretools:duralumin_pickaxe", + "cosmeretools:nicrosil_pickaxe", + "cosmeretools:lead_pickaxe", + "cosmeretools:malatium_pickaxe", + "cosmeretools:nickel_pickaxe", + "cosmeretools:bronze_pickaxe", + "cosmeretools:harmonium_pickaxe", + "cosmeretools:silver_pickaxe", + "cosmeretools:pewter_pickaxe", + "cosmeretools:lerasium_pickaxe" ] } \ No newline at end of file diff --git a/src/datagen/generated/cosmeretools/data/minecraft/tags/items/shovels.json b/src/datagen/generated/cosmeretools/data/minecraft/tags/items/shovels.json index 929cb7cfd..22dfc5827 100644 --- a/src/datagen/generated/cosmeretools/data/minecraft/tags/items/shovels.json +++ b/src/datagen/generated/cosmeretools/data/minecraft/tags/items/shovels.json @@ -1,26 +1,26 @@ { "values": [ + "cosmeretools:chromium_shovel", + "cosmeretools:electrum_shovel", "cosmeretools:steel_shovel", - "cosmeretools:malatium_shovel", - "cosmeretools:lead_shovel", + "cosmeretools:lerasatium_shovel", "cosmeretools:aluminum_shovel", "cosmeretools:copper_shovel", - "cosmeretools:lerasatium_shovel", - "cosmeretools:brass_shovel", - "cosmeretools:bronze_shovel", - "cosmeretools:pewter_shovel", - "cosmeretools:chromium_shovel", - "cosmeretools:atium_shovel", - "cosmeretools:harmonium_shovel", - "cosmeretools:electrum_shovel", - "cosmeretools:nickel_shovel", - "cosmeretools:duralumin_shovel", + "cosmeretools:tin_shovel", "cosmeretools:zinc_shovel", - "cosmeretools:nicrosil_shovel", "cosmeretools:bendalloy_shovel", - "cosmeretools:tin_shovel", - "cosmeretools:lerasium_shovel", + "cosmeretools:atium_shovel", + "cosmeretools:brass_shovel", "cosmeretools:cadmium_shovel", - "cosmeretools:silver_shovel" + "cosmeretools:duralumin_shovel", + "cosmeretools:nicrosil_shovel", + "cosmeretools:lead_shovel", + "cosmeretools:malatium_shovel", + "cosmeretools:nickel_shovel", + "cosmeretools:bronze_shovel", + "cosmeretools:harmonium_shovel", + "cosmeretools:silver_shovel", + "cosmeretools:pewter_shovel", + "cosmeretools:lerasium_shovel" ] } \ No newline at end of file diff --git a/src/datagen/generated/cosmeretools/data/minecraft/tags/items/swords.json b/src/datagen/generated/cosmeretools/data/minecraft/tags/items/swords.json index 83e640fd9..035174ba6 100644 --- a/src/datagen/generated/cosmeretools/data/minecraft/tags/items/swords.json +++ b/src/datagen/generated/cosmeretools/data/minecraft/tags/items/swords.json @@ -1,26 +1,26 @@ { "values": [ + "cosmeretools:chromium_sword", + "cosmeretools:electrum_sword", "cosmeretools:steel_sword", - "cosmeretools:malatium_sword", - "cosmeretools:lead_sword", + "cosmeretools:lerasatium_sword", "cosmeretools:aluminum_sword", "cosmeretools:copper_sword", - "cosmeretools:lerasatium_sword", - "cosmeretools:brass_sword", - "cosmeretools:bronze_sword", - "cosmeretools:pewter_sword", - "cosmeretools:chromium_sword", - "cosmeretools:atium_sword", - "cosmeretools:harmonium_sword", - "cosmeretools:electrum_sword", - "cosmeretools:nickel_sword", - "cosmeretools:duralumin_sword", + "cosmeretools:tin_sword", "cosmeretools:zinc_sword", - "cosmeretools:nicrosil_sword", "cosmeretools:bendalloy_sword", - "cosmeretools:tin_sword", - "cosmeretools:lerasium_sword", + "cosmeretools:atium_sword", + "cosmeretools:brass_sword", "cosmeretools:cadmium_sword", - "cosmeretools:silver_sword" + "cosmeretools:duralumin_sword", + "cosmeretools:nicrosil_sword", + "cosmeretools:lead_sword", + "cosmeretools:malatium_sword", + "cosmeretools:nickel_sword", + "cosmeretools:bronze_sword", + "cosmeretools:harmonium_sword", + "cosmeretools:silver_sword", + "cosmeretools:pewter_sword", + "cosmeretools:lerasium_sword" ] } \ No newline at end of file diff --git a/src/datagen/generated/surgebinding/.cache/109f316ce3b77a5a02bbf6e9c200027075e14620 b/src/datagen/generated/surgebinding/.cache/109f316ce3b77a5a02bbf6e9c200027075e14620 index 30632cb91..02ba11f4f 100644 --- a/src/datagen/generated/surgebinding/.cache/109f316ce3b77a5a02bbf6e9c200027075e14620 +++ b/src/datagen/generated/surgebinding/.cache/109f316ce3b77a5a02bbf6e9c200027075e14620 @@ -1,5 +1,6 @@ -// 1.20.1 2025-11-16T15:05:53.857381 Tags: surgebinding +// 1.20.1 2026-05-02T23:37:02.487174879 Tags: surgebinding 1f4a893d33327a86f361b3e38f9dcf2af46287fc data/cosmere/tags/worldgen/biome/spawn_ores.json +bb5e183a805f753908b6c65efaff0f102df47d81 data/curios/tags/items/shardplate.json b4bf1a40695628bad3692a7d5d6044ffdbf07e9b data/forge/tags/blocks/ores/diamond.json 535ffd326e438b4244fa9119ac3fc325a55e6769 data/forge/tags/blocks/ores/garnet.json 1f7903a2e11f5238538de7da1ab2946070c410a9 data/forge/tags/blocks/ores/heliodor.json @@ -17,6 +18,7 @@ aeaede227bae14370d9c20b5fa1fde9a29521ebb data/forge/tags/blocks/storage_blocks/h 5cd7c38bcb41dd20d7f68f84f3a282e6f3fcbf38 data/forge/tags/blocks/storage_blocks/smokestone.json 538b3e977ed89fbf5346bda5d9c2a31519709789 data/forge/tags/blocks/storage_blocks/topaz.json 5ce6a2023aa95ada658bb30be3a2bf1a1ab729a3 data/forge/tags/blocks/storage_blocks/zircon.json +bb5e183a805f753908b6c65efaff0f102df47d81 data/forge/tags/items/armors.json 9535dc5cb151b00d02ad4970b0b9b6ad387de67e data/forge/tags/items/gems.json 1740e87a5918faaa0662e6a6f82cdaceccc0f7ab data/forge/tags/items/gems/diamond.json 13fe09136216305b7e8326229706b6a29aeea74f data/forge/tags/items/gems/garnet.json diff --git a/src/datagen/generated/surgebinding/.cache/892be08db83774b45ce3700a46f41c5cc1a66597 b/src/datagen/generated/surgebinding/.cache/892be08db83774b45ce3700a46f41c5cc1a66597 index 2f5c543b2..c74644454 100644 --- a/src/datagen/generated/surgebinding/.cache/892be08db83774b45ce3700a46f41c5cc1a66597 +++ b/src/datagen/generated/surgebinding/.cache/892be08db83774b45ce3700a46f41c5cc1a66597 @@ -1,3 +1,3 @@ -// 1.20.1 2025-11-16T14:11:17.138575 Curios for surgebinding -ea0facc7e6a7280ae63171bec810b2d2fbeb682c data/surgebinding/curios/entities/shardbearers.json +// 1.20.1 2026-05-02T23:37:02.487017933 Curios for surgebinding +16d26545def8944005bbc9401156e83d07ab4e28 data/surgebinding/curios/entities/shardbearers.json aa7a9b208fbf01ed1b10da26876fa24c8af277a4 data/surgebinding/curios/slots/shardplate.json diff --git a/src/datagen/generated/surgebinding/.cache/9fb1092f32d4fcbf9e061ffd718d4ec689c6c95e b/src/datagen/generated/surgebinding/.cache/9fb1092f32d4fcbf9e061ffd718d4ec689c6c95e index 7acbc212f..349dc59eb 100644 --- a/src/datagen/generated/surgebinding/.cache/9fb1092f32d4fcbf9e061ffd718d4ec689c6c95e +++ b/src/datagen/generated/surgebinding/.cache/9fb1092f32d4fcbf9e061ffd718d4ec689c6c95e @@ -1,4 +1,4 @@ -// 1.20.1 2026-03-02T03:22:01.8457524 Recipes +// 1.20.1 2026-05-02T23:37:02.487450468 Recipes 4a484301203532f8e76dbd4dc854a2869ce2cbdc data/minecraft/advancements/recipes/misc/cut_amethyst_large_from_amethyst_shard_stonecutting.json b6af109fe2db6d0b5b0fc46dfc3e1fcb1bd36f82 data/minecraft/advancements/recipes/misc/cut_amethyst_medium_from_amethyst_shard_stonecutting.json 9cc4ea7f31a0e883bdd6185a51ea8eff5d2adbb0 data/minecraft/advancements/recipes/misc/cut_amethyst_small_from_amethyst_shard_stonecutting.json @@ -93,6 +93,7 @@ b8166393ff084e93d43d2867715f5cd4113521b0 data/surgebinding/recipes/conversions/z d0b8c41bf8cbc79ecb34acbaab234e7562602964 data/surgebinding/recipes/cooked_chull_meat.json 22c5810cae232dd766e9cf13db3134fc02c81ccb data/surgebinding/recipes/garnet_block.json f576d70fd168df476d29b0341b67edd6f6952d53 data/surgebinding/recipes/heliodor_block.json +191264d7369d8dd7d03596b160b0a28b37a58544 data/surgebinding/recipes/plate_charging.json e2c4e98de7566305d536524fb4334b61dbe18f0f data/surgebinding/recipes/rosharan_diamond_block.json 850b0804e90c35bd588551599916c9b01d5a8792 data/surgebinding/recipes/ruby_block.json 70b3a858f88b4b31446282f8c8f96e0d376473fd data/surgebinding/recipes/sapphire_block.json diff --git a/src/datagen/generated/surgebinding/.cache/a42c2d14910c607d1cdeea761ec88e5ad05f96c6 b/src/datagen/generated/surgebinding/.cache/a42c2d14910c607d1cdeea761ec88e5ad05f96c6 index 62d967290..5f770034a 100644 --- a/src/datagen/generated/surgebinding/.cache/a42c2d14910c607d1cdeea761ec88e5ad05f96c6 +++ b/src/datagen/generated/surgebinding/.cache/a42c2d14910c607d1cdeea761ec88e5ad05f96c6 @@ -1,4 +1,4 @@ -// 1.20.1 2026-04-27T10:20:37.587036 Item Models: surgebinding +// 1.20.1 2026-05-02T23:37:02.487998506 Item Models: surgebinding f11fb5b2de87bddd0918dffcc40c267bcc6b4da7 assets/surgebinding/models/item/amethyst_mark.json 63ec6c618a3a23eab4cab9c52d7d3250de9b516e assets/surgebinding/models/item/chull_spawn_egg.json e48028cab31d580fbb89862d7fd4717bd06fd66a assets/surgebinding/models/item/cooked_chull_leg.json @@ -48,10 +48,7 @@ a2fab60aae34e89444507b186249f22ba45612a0 assets/surgebinding/models/item/heliodo a91ca4972b8d3422763281c9cb8be570a54a5339 assets/surgebinding/models/item/ruby_mark.json 258e0d8e4ad57decd1a39dae134b836ce98f7f14 assets/surgebinding/models/item/sapphire.json e1a1241601f1e134a276a6beac7c6491344a004d assets/surgebinding/models/item/sapphire_mark.json -7817652b27f6e14fee558b9f7ed79a803bcc9651 assets/surgebinding/models/item/shardplate_boots.json -fbee7654e8cdfae717bccf39f76848666cc51bb5 assets/surgebinding/models/item/shardplate_chest.json -095355a2bd3bcf962839dd947514af66d6dd9639 assets/surgebinding/models/item/shardplate_helmet.json -0fc29fc960fce820dfb1b37d580efb2bdbd7d052 assets/surgebinding/models/item/shardplate_leggings.json +8b5900e5e58805cdeb319817cdd965b796e36c2d assets/surgebinding/models/item/shardplate.json f92f7e1e4564703f4c2e0007c9f8c521b080c721 assets/surgebinding/models/item/smokestone.json 273b3611916007e08e308048afb1d444167a0acd assets/surgebinding/models/item/smokestone_mark.json b50c314162637445327770e943368dd644413878 assets/surgebinding/models/item/surge_banner_pattern.json diff --git a/src/datagen/generated/surgebinding/.cache/c622617f6fabf890a00b9275cd5f643584a8a2c8 b/src/datagen/generated/surgebinding/.cache/c622617f6fabf890a00b9275cd5f643584a8a2c8 index 327f75351..e196c4f82 100644 --- a/src/datagen/generated/surgebinding/.cache/c622617f6fabf890a00b9275cd5f643584a8a2c8 +++ b/src/datagen/generated/surgebinding/.cache/c622617f6fabf890a00b9275cd5f643584a8a2c8 @@ -1,2 +1,2 @@ -// 1.20.1 2026-05-02T16:53:45.078830964 Languages: en_us -84ff212b5f7fc417111fb6c551d7cfbd4c27ad1d assets/surgebinding/lang/en_us.json +// 1.20.1 2026-05-02T23:37:02.487918438 Languages: en_us +1cc07e7eab32ed0e54a3d2e8d0a0598fdc3d126f assets/surgebinding/lang/en_us.json diff --git a/src/datagen/generated/surgebinding/data/surgebinding/curios/entities/shardbearers.json b/src/datagen/generated/surgebinding/data/surgebinding/curios/entities/shardbearers.json index 40a4037c3..324c045eb 100644 --- a/src/datagen/generated/surgebinding/data/surgebinding/curios/entities/shardbearers.json +++ b/src/datagen/generated/surgebinding/data/surgebinding/curios/entities/shardbearers.json @@ -1,10 +1,10 @@ { "entities": [ - "minecraft:vindicator", - "minecraft:pillager", "minecraft:armor_stand", - "minecraft:villager", - "minecraft:player" + "minecraft:pillager", + "minecraft:player", + "minecraft:vindicator", + "minecraft:villager" ], "slots": [ "shardplate" diff --git a/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/TriangleButton.java b/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/TriangleButton.java index 402c34895..16ff8b3f2 100644 --- a/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/TriangleButton.java +++ b/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/TriangleButton.java @@ -277,8 +277,8 @@ private void renderInfoBlock(GuiGraphics pGuiGraphics) int screenHeight = Minecraft.getInstance().getWindow().getGuiScaledHeight(); int x = 0; int y = 0; - int width = (int) (screenWidth * 0.3); - int height = screenHeight / 5; + int width = GuiUtils.getInfoBoxWidth(Minecraft.getInstance()); + int height = GuiUtils.getInfoBoxHeight(Minecraft.getInstance()); int color = 0x99333333; boolean isLeft = getX() < screenWidth/2; @@ -316,7 +316,8 @@ private void renderInfoBlock(GuiGraphics pGuiGraphics) pGuiGraphics.fill(x, y, x + width, y + height, color); String text = I18n.get(manifestation.getTranslationKey()); - pGuiGraphics.drawString(font, text, x+5, y+10, 0xFFFFFFFF); + float scale = 0.8f; + GuiUtils.drawScaledString(font, pGuiGraphics, text, x+5, y+10, scale, 0xFFFFFFFF); if (metal != Metals.MetalType.NICROSIL) { @@ -342,7 +343,7 @@ else if (seconds > 0) text = "Empty"; } - pGuiGraphics.drawString(font, text, x + 5, y + 10 + font.lineHeight + 5, 0xFFFFFFFF); + GuiUtils.drawScaledString(font, pGuiGraphics, text, x+5, y+12+font.lineHeight*scale, scale, 0xFFFFFFFF); } } diff --git a/src/main/java/leaf/cosmere/client/gui/GuiUtils.java b/src/main/java/leaf/cosmere/client/gui/GuiUtils.java index b579c9170..f7a794d38 100644 --- a/src/main/java/leaf/cosmere/client/gui/GuiUtils.java +++ b/src/main/java/leaf/cosmere/client/gui/GuiUtils.java @@ -1,10 +1,33 @@ package leaf.cosmere.client.gui; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Font; +import net.minecraft.client.gui.GuiGraphics; + import java.awt.*; public class GuiUtils { public static final Color BACKGROUND_COLOR = new Color(61, 61, 71); + public static final int getInfoBoxWidth(Minecraft minecraft) + { + return (int) (minecraft.getWindow().getGuiScaledWidth() * 0.2); + } + + public static final int getInfoBoxHeight(Minecraft minecraft) + { + return minecraft.getWindow().getGuiScaledHeight() / 8; + } + + public static void drawScaledString(Font font, GuiGraphics pGuiGraphics, String text, float x, float y, float scale, int color) + { + pGuiGraphics.pose().pushPose(); + pGuiGraphics.pose().translate(x, y, 0); + pGuiGraphics.pose().scale(scale, scale, 1.0f); + pGuiGraphics.drawString(font, text, 0, 0, color, false); + pGuiGraphics.pose().popPose(); + } + public record CachedQuad(float px, float py, float size) {} } diff --git a/src/main/java/leaf/cosmere/client/gui/SpiritwebHud.java b/src/main/java/leaf/cosmere/client/gui/SpiritwebHud.java index 59bd4f18d..bed11c64f 100644 --- a/src/main/java/leaf/cosmere/client/gui/SpiritwebHud.java +++ b/src/main/java/leaf/cosmere/client/gui/SpiritwebHud.java @@ -175,16 +175,10 @@ protected void renderText(GuiGraphics pGuiGraphics) String text = I18n.get(spiritweb.getSelectedManifestation().getTranslationKey()); float scale = 0.8f; - pGuiGraphics.pose().pushPose(); - float targetX = getX() + getHeight() + 2; float targetY = getY() + (getHeight() / 2f) - ((font.lineHeight * scale) / 2f); - pGuiGraphics.pose().translate(targetX, targetY, 0); - pGuiGraphics.pose().scale(scale, scale, 1.0f); - pGuiGraphics.drawString(font, text, 0, 0, 0xFFDDDDDD, false); - - pGuiGraphics.pose().popPose(); + GuiUtils.drawScaledString(font, pGuiGraphics, text, targetX, targetY, scale, 0xFFDDDDDD); }); } From 0c31fef6f978e705730295fbc08815dd3a40308e Mon Sep 17 00:00:00 2001 From: Gerbagel Date: Sun, 3 May 2026 00:53:07 +0200 Subject: [PATCH 53/55] [Cosmere] Final UI touches Moved atium triangle, centered tab buttons, and only show Surgebinding tab if player has Surgebinding --- .../java/leaf/cosmere/api/Manifestations.java | 18 ++++++++++++++++++ .../leaf/cosmere/api/spiritweb/ISpiritweb.java | 2 ++ .../client/gui/FeruchemySpiritwebMenu.java | 5 ++--- .../leaf/cosmere/client/ClientForgeEvents.java | 2 ++ .../leaf/cosmere/client/gui/SpiritwebMenu.java | 6 +++++- .../cosmere/client/gui/SpiritwebRegistry.java | 5 +++++ .../common/cap/entity/SpiritwebCapability.java | 11 +++++++++++ .../SurgebindingSpiritwebSubmodule.java | 7 ++++++- 8 files changed, 51 insertions(+), 5 deletions(-) diff --git a/src/api/java/leaf/cosmere/api/Manifestations.java b/src/api/java/leaf/cosmere/api/Manifestations.java index 4a22d931f..bd3db163d 100644 --- a/src/api/java/leaf/cosmere/api/Manifestations.java +++ b/src/api/java/leaf/cosmere/api/Manifestations.java @@ -109,6 +109,24 @@ public Manifestation getManifestation(int powerID) } return CosmereAPI.manifestationRegistry().getValue(new ResourceLocation("cosmere", "none")); } + + public int getNumberOfManifestations() + { + switch (this) + { + case ALLOMANCY: + case FERUCHEMY: + return 17; + case SURGEBINDING: + return 10; + case AON_DOR: + case AWAKENING: + break; + case SANDMASTERY: + return 5; + } + return 0; + } } } diff --git a/src/api/java/leaf/cosmere/api/spiritweb/ISpiritweb.java b/src/api/java/leaf/cosmere/api/spiritweb/ISpiritweb.java index 57e4c5775..16037231c 100644 --- a/src/api/java/leaf/cosmere/api/spiritweb/ISpiritweb.java +++ b/src/api/java/leaf/cosmere/api/spiritweb/ISpiritweb.java @@ -34,6 +34,8 @@ public interface ISpiritweb extends INBTSerializable boolean hasManifestation(Manifestation manifestation, boolean ignoreTemporaryPower); + boolean hasManifestationOfType(Manifestations.ManifestationTypes type); + void giveManifestation(Manifestation manifestation, int i); void removeManifestation(Manifestation manifestation); diff --git a/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/FeruchemySpiritwebMenu.java b/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/FeruchemySpiritwebMenu.java index 4ee62a279..746e8c288 100644 --- a/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/FeruchemySpiritwebMenu.java +++ b/src/feruchemy/java/leaf/cosmere/feruchemy/client/gui/FeruchemySpiritwebMenu.java @@ -84,8 +84,7 @@ protected void init() addRenderableWidget(new TriangleButton(x, y + distance, distance, bottomLeftRot, Metals.MetalType.ALUMINUM, spiritweb, manifestationConsumer)); - x = this.width / 2 - (int) (distance*1.75); - y = this.height/2 + (int) (distance*0.75); + y = this.height/2 + distance; addRenderableWidget(new TriangleButton(x, y, distance, topRightRot, Metals.MetalType.ATIUM, spiritweb, manifestationConsumer)); @@ -133,7 +132,7 @@ private void renderAtiumBorder(GuiGraphics pGuiGraphics) RenderSystem.blendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, 1, 0); RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f); - final int x = this.width / 2 - (int) (distance*1.75), y = this.height/2 + (int) (distance*0.75); + final int x = this.width / 2 - distance*2-1, y = this.height/2 + distance+1; final int screenSize = distance; final int iconSize = 64; diff --git a/src/main/java/leaf/cosmere/client/ClientForgeEvents.java b/src/main/java/leaf/cosmere/client/ClientForgeEvents.java index 2f7a3626b..d5a183a00 100644 --- a/src/main/java/leaf/cosmere/client/ClientForgeEvents.java +++ b/src/main/java/leaf/cosmere/client/ClientForgeEvents.java @@ -11,6 +11,7 @@ import leaf.cosmere.api.manifestation.Manifestation; import leaf.cosmere.client.gui.SpiritwebHud; import leaf.cosmere.client.gui.SpiritwebMenu; +import leaf.cosmere.client.gui.SpiritwebRegistry; import leaf.cosmere.common.Cosmere; import leaf.cosmere.common.cap.entity.SpiritwebCapability; import leaf.cosmere.common.fog.FogManager; @@ -74,6 +75,7 @@ public static void onKey(InputEvent.Key event) { if (Keybindings.MANIFESTATION_MENU.consumeClick()) { + SpiritwebRegistry.getInstance().clear(); SpiritwebCapability.get(player).ifPresent( (iSpiritweb -> { iSpiritweb.getSubmodules().forEach( ((manifestationTypes, iSpiritwebSubmodule) -> { diff --git a/src/main/java/leaf/cosmere/client/gui/SpiritwebMenu.java b/src/main/java/leaf/cosmere/client/gui/SpiritwebMenu.java index 75fb95511..29c4cecb9 100644 --- a/src/main/java/leaf/cosmere/client/gui/SpiritwebMenu.java +++ b/src/main/java/leaf/cosmere/client/gui/SpiritwebMenu.java @@ -70,13 +70,17 @@ protected void init() } AtomicInteger added = new AtomicInteger(0); int count = registry.getManifestationScreenMap().size(); + int buttonWidth = 32; + int offset = 5; + int totalBlockWidth = (count-1) * (buttonWidth+offset) + buttonWidth; + int startX = (this.width/2) - (totalBlockWidth/2); for (int i = 0; i < Manifestations.ManifestationTypes.AVIAR.getID(); i++) { Manifestations.ManifestationTypes.valueOf(i).ifPresent( (maniType) -> { if (registry.getManifestationScreenMap().get(maniType) != null) { - int x = (width / 2) - ((count * 32) / 2) + (added.get() * 37); + int x = startX + (added.get() * (buttonWidth+offset)); addRenderableWidget(new TabButton(x, (pButton -> { if (maniType != selectedManifestationType) diff --git a/src/main/java/leaf/cosmere/client/gui/SpiritwebRegistry.java b/src/main/java/leaf/cosmere/client/gui/SpiritwebRegistry.java index ccfdabac8..56baff54d 100644 --- a/src/main/java/leaf/cosmere/client/gui/SpiritwebRegistry.java +++ b/src/main/java/leaf/cosmere/client/gui/SpiritwebRegistry.java @@ -25,4 +25,9 @@ public HashMap> getMa { return manifestationScreenMap; } + + public void clear() + { + manifestationScreenMap.clear(); + } } diff --git a/src/main/java/leaf/cosmere/common/cap/entity/SpiritwebCapability.java b/src/main/java/leaf/cosmere/common/cap/entity/SpiritwebCapability.java index 0aefc64ef..e8c5494c9 100644 --- a/src/main/java/leaf/cosmere/common/cap/entity/SpiritwebCapability.java +++ b/src/main/java/leaf/cosmere/common/cap/entity/SpiritwebCapability.java @@ -622,6 +622,17 @@ public boolean hasManifestation(Manifestation manifestation, boolean ignoreTempo return false; } + @Override + public boolean hasManifestationOfType(Manifestations.ManifestationTypes type) + { + for (int i = 0; i < type.getNumberOfManifestations(); i++) + { + if (hasManifestation(type.getManifestation(i))) + return true; + } + return false; + } + @Override public void giveManifestation(Manifestation manifestation, int baseValue) { diff --git a/src/surgebinding/java/leaf/cosmere/surgebinding/common/capabilities/SurgebindingSpiritwebSubmodule.java b/src/surgebinding/java/leaf/cosmere/surgebinding/common/capabilities/SurgebindingSpiritwebSubmodule.java index 2b90757a4..e9d59f1c5 100644 --- a/src/surgebinding/java/leaf/cosmere/surgebinding/common/capabilities/SurgebindingSpiritwebSubmodule.java +++ b/src/surgebinding/java/leaf/cosmere/surgebinding/common/capabilities/SurgebindingSpiritwebSubmodule.java @@ -10,6 +10,7 @@ import leaf.cosmere.api.helpers.EffectsHelper; import leaf.cosmere.api.spiritweb.ISpiritweb; import leaf.cosmere.client.gui.SpiritwebRegistry; +import leaf.cosmere.common.cap.entity.SpiritwebCapability; import leaf.cosmere.common.items.CapWrapper; import leaf.cosmere.surgebinding.client.gui.SurgebindingSpiritwebMenu; import leaf.cosmere.api.helpers.CuriosHelper; @@ -22,6 +23,7 @@ import leaf.cosmere.surgebinding.common.manifestation.SurgeProgression; import leaf.cosmere.surgebinding.common.registries.SurgebindingDimensions; import leaf.cosmere.surgebinding.common.registries.SurgebindingItems; +import net.minecraft.client.Minecraft; import net.minecraft.nbt.CompoundTag; import net.minecraft.util.Mth; import net.minecraft.world.Container; @@ -188,7 +190,10 @@ public void drainInvestiture(ISpiritweb data, double strength) @OnlyIn(Dist.CLIENT) public void registerMenu() { - SpiritwebRegistry.getInstance().register(Manifestations.ManifestationTypes.SURGEBINDING, SurgebindingSpiritwebMenu::new); + SpiritwebCapability.get(Minecraft.getInstance().player).ifPresent((spiritweb -> { + if (spiritweb.hasManifestationOfType(Manifestations.ManifestationTypes.SURGEBINDING)) + SpiritwebRegistry.getInstance().register(Manifestations.ManifestationTypes.SURGEBINDING, SurgebindingSpiritwebMenu::new); + })); } private void requestGemStormlight(ItemStack item, int amountDrawn) From ffba77a626a1537c16005cfccea6e8489a449c3f Mon Sep 17 00:00:00 2001 From: Gerbagel Date: Sun, 3 May 2026 01:20:53 +0200 Subject: [PATCH 54/55] =?UTF-8?q?[Cosmere]=C2=A0Do=20not=20render=20HUD=20?= =?UTF-8?q?if=20no=20power=20selected?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../leaf/cosmere/client/gui/SpiritwebHud.java | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/main/java/leaf/cosmere/client/gui/SpiritwebHud.java b/src/main/java/leaf/cosmere/client/gui/SpiritwebHud.java index bed11c64f..9f4caeae0 100644 --- a/src/main/java/leaf/cosmere/client/gui/SpiritwebHud.java +++ b/src/main/java/leaf/cosmere/client/gui/SpiritwebHud.java @@ -36,13 +36,16 @@ public SpiritwebHud(Player player) @Override protected void renderWidget(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) { - if (!CosmereConfigs.CLIENT_CONFIG.disableSelectedManifestationHud.get()) - { - renderBackground(pGuiGraphics); - renderUsage(pGuiGraphics); - renderIcon(pGuiGraphics); - renderText(pGuiGraphics); - } + SpiritwebCapability.get(player).ifPresent( (spiritweb -> { + if (!CosmereConfigs.CLIENT_CONFIG.disableSelectedManifestationHud.get() + && spiritweb.getSelectedManifestation().getManifestationType() != Manifestations.ManifestationTypes.NONE) + { + renderBackground(pGuiGraphics); + renderUsage(pGuiGraphics); + renderIcon(pGuiGraphics); + renderText(pGuiGraphics); + } + })); } @Override From 370e4ab67a889167bec79ab0d03cf59b6a55b849 Mon Sep 17 00:00:00 2001 From: Gerbagel Date: Sun, 3 May 2026 01:25:17 +0200 Subject: [PATCH 55/55] [Cosmere] Only add spiritweb submenus if powers are present --- .../common/capabilities/AllomancySpiritwebSubmodule.java | 6 +++++- .../common/capabilities/FeruchemySpiritwebSubmodule.java | 7 ++++++- .../capabilities/SandmasterySpiritwebSubmodule.java | 8 ++++++-- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/allomancy/java/leaf/cosmere/allomancy/common/capabilities/AllomancySpiritwebSubmodule.java b/src/allomancy/java/leaf/cosmere/allomancy/common/capabilities/AllomancySpiritwebSubmodule.java index 2af02305e..ecba0aad6 100644 --- a/src/allomancy/java/leaf/cosmere/allomancy/common/capabilities/AllomancySpiritwebSubmodule.java +++ b/src/allomancy/java/leaf/cosmere/allomancy/common/capabilities/AllomancySpiritwebSubmodule.java @@ -24,6 +24,7 @@ import leaf.cosmere.api.helpers.PlayerHelper; import leaf.cosmere.api.manifestation.Manifestation; import leaf.cosmere.api.spiritweb.ISpiritweb; +import leaf.cosmere.common.cap.entity.SpiritwebCapability; import leaf.cosmere.common.registration.impl.AttributeRegistryObject; import leaf.cosmere.client.gui.SpiritwebRegistry; import net.minecraft.client.Minecraft; @@ -343,7 +344,10 @@ public List getPowers() @OnlyIn(Dist.CLIENT) public void registerMenu() { - SpiritwebRegistry.getInstance().register(Manifestations.ManifestationTypes.ALLOMANCY, AllomancySpiritwebMenu::new); + SpiritwebCapability.get(Minecraft.getInstance().player).ifPresent( (spiritweb) -> { + if (spiritweb.hasManifestationOfType(Manifestations.ManifestationTypes.ALLOMANCY)) + SpiritwebRegistry.getInstance().register(Manifestations.ManifestationTypes.ALLOMANCY, AllomancySpiritwebMenu::new); + }); } public int getIngestedMetal(Metals.MetalType metalType) diff --git a/src/feruchemy/java/leaf/cosmere/feruchemy/common/capabilities/FeruchemySpiritwebSubmodule.java b/src/feruchemy/java/leaf/cosmere/feruchemy/common/capabilities/FeruchemySpiritwebSubmodule.java index 5b1a0bd99..225593b72 100644 --- a/src/feruchemy/java/leaf/cosmere/feruchemy/common/capabilities/FeruchemySpiritwebSubmodule.java +++ b/src/feruchemy/java/leaf/cosmere/feruchemy/common/capabilities/FeruchemySpiritwebSubmodule.java @@ -12,6 +12,7 @@ import leaf.cosmere.api.math.MathHelper; import leaf.cosmere.api.spiritweb.ISpiritweb; import leaf.cosmere.client.gui.SpiritwebRegistry; +import leaf.cosmere.common.cap.entity.SpiritwebCapability; import leaf.cosmere.feruchemy.client.gui.FeruchemySpiritwebMenu; import leaf.cosmere.common.registration.impl.AttributeRegistryObject; import leaf.cosmere.feruchemy.common.config.FeruchemyConfigs; @@ -20,6 +21,7 @@ import leaf.cosmere.feruchemy.common.manifestation.FeruchemyManifestation; import leaf.cosmere.feruchemy.common.registries.FeruchemyAttributes; import leaf.cosmere.feruchemy.common.registries.FeruchemyItems; +import net.minecraft.client.Minecraft; import net.minecraft.world.entity.ai.attributes.Attribute; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.Item; @@ -76,7 +78,10 @@ public void drainInvestiture(ISpiritweb data, double strength) @OnlyIn(Dist.CLIENT) public void registerMenu() { - SpiritwebRegistry.getInstance().register(Manifestations.ManifestationTypes.FERUCHEMY, FeruchemySpiritwebMenu::new); + SpiritwebCapability.get(Minecraft.getInstance().player).ifPresent( (spiritweb) -> { + if (spiritweb.hasManifestationOfType(Manifestations.ManifestationTypes.FERUCHEMY)) + SpiritwebRegistry.getInstance().register(Manifestations.ManifestationTypes.FERUCHEMY, FeruchemySpiritwebMenu::new); + }); } private static void GiveStartingItem(Player player, Metals.MetalType metalType, float fillAmount) diff --git a/src/sandmastery/java/leaf/cosmere/sandmastery/common/capabilities/SandmasterySpiritwebSubmodule.java b/src/sandmastery/java/leaf/cosmere/sandmastery/common/capabilities/SandmasterySpiritwebSubmodule.java index 092839503..610f28dd5 100644 --- a/src/sandmastery/java/leaf/cosmere/sandmastery/common/capabilities/SandmasterySpiritwebSubmodule.java +++ b/src/sandmastery/java/leaf/cosmere/sandmastery/common/capabilities/SandmasterySpiritwebSubmodule.java @@ -14,6 +14,7 @@ import leaf.cosmere.api.spiritweb.ISpiritweb; import leaf.cosmere.client.Keybindings; import leaf.cosmere.client.gui.SpiritwebRegistry; +import leaf.cosmere.common.cap.entity.SpiritwebCapability; import leaf.cosmere.sandmastery.client.SandmasteryKeybindings; import leaf.cosmere.sandmastery.client.gui.SandmasterySpiritwebMenu; import leaf.cosmere.sandmastery.common.Sandmastery; @@ -24,6 +25,7 @@ import leaf.cosmere.sandmastery.common.registries.SandmasteryEffects; import leaf.cosmere.sandmastery.common.registries.SandmasteryItems; import leaf.cosmere.sandmastery.common.utils.SandmasteryConstants; +import net.minecraft.client.Minecraft; import net.minecraft.nbt.CompoundTag; import net.minecraft.util.Mth; import net.minecraft.world.entity.LivingEntity; @@ -212,8 +214,10 @@ public void GiveStartingItem(Player player, Manifestation manifestation) @OnlyIn(Dist.CLIENT) public void registerMenu() { - // todo: add check for if actually has Sandmastery - SpiritwebRegistry.getInstance().register(Manifestations.ManifestationTypes.SANDMASTERY, SandmasterySpiritwebMenu::new); + SpiritwebCapability.get(Minecraft.getInstance().player).ifPresent(spiritweb -> { + if (spiritweb.hasManifestationOfType(Manifestations.ManifestationTypes.SANDMASTERY)) + SpiritwebRegistry.getInstance().register(Manifestations.ManifestationTypes.SANDMASTERY, SandmasterySpiritwebMenu::new); + }); } @Override