From 40cd2ced5fc719c08722cc2831288e5095ae1fcb Mon Sep 17 00:00:00 2001 From: direwolf20 <39863894+Direwolf20-MC@users.noreply.github.com> Date: Thu, 12 Sep 2024 22:38:43 -0400 Subject: [PATCH] Render Value and Bar on screen --- .../screens/ExperienceHolderScreen.java | 48 ++++++++++++++++++- .../blockentities/ExperienceHolderBE.java | 1 + .../justdirethings/util/ExperienceUtils.java | 27 +++++++++++ 3 files changed, 74 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/direwolf20/justdirethings/client/screens/ExperienceHolderScreen.java b/src/main/java/com/direwolf20/justdirethings/client/screens/ExperienceHolderScreen.java index 41fc0623..60657073 100644 --- a/src/main/java/com/direwolf20/justdirethings/client/screens/ExperienceHolderScreen.java +++ b/src/main/java/com/direwolf20/justdirethings/client/screens/ExperienceHolderScreen.java @@ -5,14 +5,22 @@ import com.direwolf20.justdirethings.common.blockentities.ExperienceHolderBE; import com.direwolf20.justdirethings.common.containers.ExperienceHolderContainer; import com.direwolf20.justdirethings.common.network.data.ExperienceHolderPayload; +import com.direwolf20.justdirethings.util.ExperienceUtils; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.components.StringWidget; import net.minecraft.client.gui.screens.Screen; import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; import net.minecraft.world.entity.player.Inventory; import net.neoforged.neoforge.network.PacketDistributor; public class ExperienceHolderScreen extends BaseMachineScreen { private ExperienceHolderBE experienceHolderBE; private int exp; + private StringWidget expValue; + private static final ResourceLocation EXPERIENCE_BAR_BACKGROUND_SPRITE = ResourceLocation.withDefaultNamespace("hud/experience_bar_background"); + private static final ResourceLocation EXPERIENCE_BAR_PROGRESS_SPRITE = ResourceLocation.withDefaultNamespace("hud/experience_bar_progress"); + public ExperienceHolderScreen(ExperienceHolderContainer container, Inventory inv, Component name) { super(container, inv, name); if (container.baseMachineBE instanceof ExperienceHolderBE experienceHolderBE) { @@ -24,7 +32,7 @@ public ExperienceHolderScreen(ExperienceHolderContainer container, Inventory inv @Override public void init() { super.init(); - addRenderableWidget(ToggleButtonFactory.STOREEXPBUTTON(getGuiLeft() + 62, topSectionTop + 62, true, b -> { + addRenderableWidget(ToggleButtonFactory.STOREEXPBUTTON(topSectionLeft + (topSectionWidth / 2) - 15 - 18, topSectionTop + 62, true, b -> { int amt = 1; if (Screen.hasControlDown()) amt = -1; @@ -32,7 +40,7 @@ else if (Screen.hasShiftDown()) amt = amt * 10; PacketDistributor.sendToServer(new ExperienceHolderPayload(true, amt)); })); - addRenderableWidget(ToggleButtonFactory.EXTRACTEXPBUTTON(getGuiLeft() + 102, topSectionTop + 62, true, b -> { + addRenderableWidget(ToggleButtonFactory.EXTRACTEXPBUTTON(topSectionLeft + (topSectionWidth / 2) + 15, topSectionTop + 62, true, b -> { int amt = 1; if (Screen.hasControlDown()) amt = -1; @@ -40,5 +48,41 @@ else if (Screen.hasShiftDown()) amt = amt * 10; PacketDistributor.sendToServer(new ExperienceHolderPayload(false, amt)); })); + expValue = new StringWidget(topSectionLeft + (topSectionWidth / 2) - 15, topSectionTop + 62 + (font.lineHeight / 2), 30, font.lineHeight, Component.literal(String.valueOf(ExperienceUtils.getLevelFromTotalExperience(experienceHolderBE.exp))), font); + + addRenderableWidget(expValue); + } + + @Override + public void render(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick) { + super.render(guiGraphics, mouseX, mouseY, partialTick); + updateDisplay(); + renderXPAmount(guiGraphics, partialTick, mouseX, mouseY); + } + + @Override + protected void renderBg(GuiGraphics guiGraphics, float partialTicks, int mouseX, int mouseY) { + super.renderBg(guiGraphics, partialTicks, mouseX, mouseY); + renderXPBar(guiGraphics, partialTicks, mouseX, mouseY); + } + + public void renderXPBar(GuiGraphics guiGraphics, float partialTicks, int mouseX, int mouseY) { + int barX = topSectionLeft + (topSectionWidth / 2) - (182 / 2); // Position for the XP bar in your GUI + int barY = topSectionTop + topSectionHeight - 15; // Y position for the XP bar + + // Bind the vanilla experience bar texture (this is the same texture used by the player XP bar) + guiGraphics.blitSprite(EXPERIENCE_BAR_BACKGROUND_SPRITE, barX, barY, 182, 5); + int partialAmount = (int) (ExperienceUtils.getProgressToNextLevel(experienceHolderBE.exp) * 183.0F); + if (partialAmount > 0) { + guiGraphics.blitSprite(EXPERIENCE_BAR_PROGRESS_SPRITE, 182, 5, 0, 0, barX, barY, partialAmount, 5); + } + } + + public void renderXPAmount(GuiGraphics guiGraphics, float partialTicks, int mouseX, int mouseY) { + + } + + private void updateDisplay() { + this.expValue.setMessage(Component.literal(String.valueOf(ExperienceUtils.getLevelFromTotalExperience(experienceHolderBE.exp)))); } } diff --git a/src/main/java/com/direwolf20/justdirethings/common/blockentities/ExperienceHolderBE.java b/src/main/java/com/direwolf20/justdirethings/common/blockentities/ExperienceHolderBE.java index 61079a36..b4f172e9 100644 --- a/src/main/java/com/direwolf20/justdirethings/common/blockentities/ExperienceHolderBE.java +++ b/src/main/java/com/direwolf20/justdirethings/common/blockentities/ExperienceHolderBE.java @@ -103,6 +103,7 @@ public void extractExp(Player player, int levelChange) { } public boolean roundUpToNextLevel(Player player) { + if (this.exp <= 0) return false; // No experience available to round up int expInCurrentLevel = (int) (player.experienceProgress * player.getXpNeededForNextLevel()); if (expInCurrentLevel > 0) { int expToGive = Math.min(exp, ExperienceUtils.getExpNeededForNextLevel(player)); diff --git a/src/main/java/com/direwolf20/justdirethings/util/ExperienceUtils.java b/src/main/java/com/direwolf20/justdirethings/util/ExperienceUtils.java index bb22bce2..a5eeeb8f 100644 --- a/src/main/java/com/direwolf20/justdirethings/util/ExperienceUtils.java +++ b/src/main/java/com/direwolf20/justdirethings/util/ExperienceUtils.java @@ -14,6 +14,20 @@ public static int getTotalExperienceForLevel(int level) { } } + public static int getLevelFromTotalExperience(int totalExp) { + // Check in the level ranges where experience requirements change + if (totalExp < getTotalExperienceForLevel(16)) { + // Level range 0-15 + return (int) Math.floor((-6 + Math.sqrt(36 + 4 * totalExp)) / 2); + } else if (totalExp < getTotalExperienceForLevel(31)) { + // Level range 16-30 + return (int) Math.floor((40.5 + Math.sqrt(-40.5 * -40.5 - 4 * 2.5 * (360 - totalExp))) / (2 * 2.5)); + } else { + // Level range 31+ + return (int) Math.floor((162.5 + Math.sqrt(-162.5 * -162.5 - 4 * 4.5 * (2220 - totalExp))) / (2 * 4.5)); + } + } + // Remove levels from a player, ensuring they don't lose more than available public static int removeLevels(Player player, int levelsToRemove) { int currentTotalExp = getPlayerTotalExperience(player); @@ -47,6 +61,19 @@ public static int getExpNeededForNextLevel(Player player) { return player.getXpNeededForNextLevel() - (int) (player.experienceProgress * player.getXpNeededForNextLevel()); } + // Get the progress to the next level as a fraction (float) from total experience points + public static float getProgressToNextLevel(int totalExp) { + int level = getLevelFromTotalExperience(totalExp); // Get the number of full levels + int expForCurrentLevel = getTotalExperienceForLevel(level); // Total exp required to reach this level + int expForNextLevel = getExperienceForNextLevel(level); // Exp needed for the next level + + // Remaining experience after subtracting full levels + int expAfterFullLevels = totalExp - expForCurrentLevel; + + // Calculate the fractional progress (as a float between 0.0 and 1.0) + return (float) expAfterFullLevels / (float) expForNextLevel; + } + // Remove points from a player, ensuring they don't lose more than available public static int removePoints(Player player, int pointsToRemove) { int currentTotalExp = getPlayerTotalExperience(player);