aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
authorAaron <51387595+AzureAaron@users.noreply.github.com>2024-08-02 21:11:34 -0400
committerGitHub <noreply@github.com>2024-08-02 21:11:34 -0400
commitaa72b770a8443c96fe5a87fa027fc9577c758563 (patch)
tree2579d06337a93edf444d0111249515089996c932 /src/main/java
parent023bf7882b4be983e42c23da286f7d59f0532533 (diff)
parent9696338aa62f5eb4a1cecdcb99dd720c0839c417 (diff)
downloadSkyblocker-aa72b770a8443c96fe5a87fa027fc9577c758563.tar.gz
Skyblocker-aa72b770a8443c96fe5a87fa027fc9577c758563.tar.bz2
Skyblocker-aa72b770a8443c96fe5a87fa027fc9577c758563.zip
Merge pull request #861 from viciscat/minion-monnies
Chest Value: Only show minion's generated stuff and visual upgrade
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/ChestValue.java121
1 files changed, 106 insertions, 15 deletions
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/ChestValue.java b/src/main/java/de/hysky/skyblocker/skyblock/ChestValue.java
index c997cda0..67928b07 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/ChestValue.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/ChestValue.java
@@ -10,18 +10,29 @@ import de.hysky.skyblocker.utils.Utils;
import it.unimi.dsi.fastutil.doubles.DoubleBooleanPair;
import net.fabricmc.fabric.api.client.screen.v1.ScreenEvents;
import net.fabricmc.fabric.api.client.screen.v1.Screens;
+import net.minecraft.client.MinecraftClient;
+import net.minecraft.client.font.TextRenderer;
+import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.ingame.GenericContainerScreen;
import net.minecraft.client.gui.tooltip.Tooltip;
import net.minecraft.client.gui.widget.ButtonWidget;
+import net.minecraft.client.gui.widget.TextWidget;
import net.minecraft.item.ItemStack;
+import net.minecraft.item.Items;
import net.minecraft.screen.GenericContainerScreenHandler;
import net.minecraft.screen.slot.Slot;
+import net.minecraft.text.Style;
import net.minecraft.text.Text;
+import net.minecraft.util.Util;
+import net.minecraft.util.math.MathHelper;
import org.apache.commons.lang3.StringUtils;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.text.DecimalFormat;
+import java.text.ParseException;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
@@ -31,6 +42,7 @@ public class ChestValue {
private static final Logger LOGGER = LoggerFactory.getLogger(ChestValue.class);
private static final Set<String> DUNGEON_CHESTS = Set.of("Wood Chest", "Gold Chest", "Diamond Chest", "Emerald Chest", "Obsidian Chest", "Bedrock Chest");
private static final Pattern ESSENCE_PATTERN = Pattern.compile("(?<type>[A-Za-z]+) Essence x(?<amount>[0-9]+)");
+ private static final Pattern MINION_PATTERN = Pattern.compile("Minion (I|II|III|IV|V|VI|VII|VIII|IX|X|XI|XII)$");
private static final DecimalFormat FORMATTER = new DecimalFormat("#,###");
public static void init() {
@@ -40,20 +52,27 @@ public class ChestValue {
String titleString = title.getString();
if (DUNGEON_CHESTS.contains(titleString)) {
if (SkyblockerConfigManager.get().dungeons.dungeonChestProfit.enableProfitCalculator) {
- ScreenEvents.afterTick(screen).register(screen_ ->
- ((ScreenAccessor) screen).setTitle(getDungeonChestProfit(genericContainerScreen.getScreenHandler(), title, titleString))
- );
+ ScreenEvents.afterTick(screen).register(ignored -> {
+ Text dungeonChestProfit = getDungeonChestProfit(genericContainerScreen.getScreenHandler());
+ if (dungeonChestProfit != null)
+ addValueToContainer(genericContainerScreen, dungeonChestProfit, title);
+ });
}
} else if (SkyblockerConfigManager.get().uiAndVisuals.chestValue.enableChestValue && !titleString.equals("SkyBlock Menu")) {
+ boolean minion = MINION_PATTERN.matcher(title.getString().trim()).find();
Screens.getButtons(screen).add(ButtonWidget
.builder(Text.literal("$"), buttonWidget -> {
Screens.getButtons(screen).remove(buttonWidget);
- ScreenEvents.afterTick(screen).register(screen_ ->
- ((ScreenAccessor) screen).setTitle(getChestValue(genericContainerScreen.getScreenHandler(), title, titleString))
- );
+ ScreenEvents.afterTick(screen).register(ignored -> {
+ Text chestValue = getChestValue(genericContainerScreen.getScreenHandler(), minion);
+ if (chestValue != null) {
+ addValueToContainer(genericContainerScreen, chestValue, title);
+ }
+ });
+
})
.dimensions(((HandledScreenAccessor) genericContainerScreen).getX() + ((HandledScreenAccessor) genericContainerScreen).getBackgroundWidth() - 16, ((HandledScreenAccessor) genericContainerScreen).getY() + 4, 12, 12)
- .tooltip(Tooltip.of(Text.translatable("skyblocker.config.general.chestValue.@Tooltip")))
+ .tooltip(minion ? Tooltip.of(Text.translatable("skyblocker.config.general.minionValue.@Tooltip")) : Tooltip.of(Text.translatable("skyblocker.config.general.chestValue.@Tooltip")))
.build()
);
}
@@ -61,14 +80,14 @@ public class ChestValue {
});
}
- private static Text getDungeonChestProfit(GenericContainerScreenHandler handler, Text title, String titleString) {
+ private static @Nullable Text getDungeonChestProfit(GenericContainerScreenHandler handler) {
try {
double profit = 0;
boolean hasIncompleteData = false, usedKismet = false;
List<Slot> slots = handler.slots.subList(0, handler.getRows() * 9);
//If the item stack for the "Open Reward Chest" button or the kismet button hasn't been sent to the client yet
- if (slots.get(31).getStack().isEmpty() || slots.get(50).getStack().isEmpty()) return title;
+ if (slots.get(31).getStack().isEmpty() || slots.get(50).getStack().isEmpty()) return null;
for (Slot slot : slots) {
ItemStack stack = slot.getStack();
@@ -136,25 +155,35 @@ public class ChestValue {
profit -= kismetPriceData.leftDouble();
}
- return Text.literal(titleString).append(getProfitText((long) profit, hasIncompleteData));
+ return getProfitText((long) profit, hasIncompleteData);
} catch (Exception e) {
LOGGER.error("[Skyblocker Profit Calculator] Failed to calculate dungeon chest profit! ", e);
}
- return title;
+ return null;
}
- private static Text getChestValue(GenericContainerScreenHandler handler, Text title, String titleString) {
+ private static @Nullable Text getChestValue(GenericContainerScreenHandler handler, boolean minion) {
try {
double value = 0;
boolean hasIncompleteData = false;
- List<Slot> slots = handler.slots.subList(0, handler.getRows() * 9);
+ List<Slot> slots = minion ? getMinionSlots(handler) : handler.slots.subList(0, handler.getRows() * 9);
for (Slot slot : slots) {
ItemStack stack = slot.getStack();
if (stack.isEmpty()) {
continue;
}
+ String coinsLine;
+ if (minion && slot.id == 28 && stack.isOf(Items.HOPPER) && (coinsLine = ItemUtils.getLoreLineIf(stack, s -> s.contains("Held Coins:"))) != null) {
+ String source = coinsLine.split(":")[1];
+ try {
+ value += DecimalFormat.getNumberInstance(java.util.Locale.US).parse(source.trim()).doubleValue();
+ } catch (ParseException e) {
+ LOGGER.warn("[Skyblocker] Failed to parse {}", source);
+ }
+ continue;
+ }
String id = stack.getSkyblockApiId();
@@ -167,12 +196,20 @@ public class ChestValue {
}
}
- return Text.literal(titleString).append(getValueText((long) value, hasIncompleteData));
+ return getValueText((long) value, hasIncompleteData);
} catch (Exception e) {
LOGGER.error("[Skyblocker Value Calculator] Failed to calculate dungeon chest value! ", e);
}
- return title;
+ return null;
+ }
+
+ private static @NotNull List<Slot> getMinionSlots(GenericContainerScreenHandler handler) {
+ return handler.slots.subList(0, handler.getRows() * 9).stream().filter(slot -> {
+ int x = slot.id % 9;
+ int y = slot.id / 9;
+ return x > 2 && x < 8 && y > 1 && y < 5 || slot.id == 28;
+ }).toList();
}
/**
@@ -191,4 +228,58 @@ public class ChestValue {
UIAndVisualsConfig.ChestValue config = SkyblockerConfigManager.get().uiAndVisuals.chestValue;
return Text.literal(' ' + FORMATTER.format(value) + " Coins").formatted(hasIncompleteData ? config.incompleteColor : config.color);
}
+
+ private static void addValueToContainer(GenericContainerScreen genericContainerScreen, Text chestValue, Text title) {
+ Screens.getButtons(genericContainerScreen).removeIf(clickableWidget -> clickableWidget instanceof ChestValueTextWidget);
+ int backgroundWidth = ((HandledScreenAccessor) genericContainerScreen).getBackgroundWidth();
+ int y = ((HandledScreenAccessor) genericContainerScreen).getY();
+ int x = ((HandledScreenAccessor) genericContainerScreen).getX();
+ ((ScreenAccessor) genericContainerScreen).setTitle(Text.empty());
+ TextRenderer textRenderer = MinecraftClient.getInstance().textRenderer;
+ int chestValueWidth = Math.min(textRenderer.getWidth(chestValue), Math.max((backgroundWidth - 8) / 2 - 2, backgroundWidth - 8 - textRenderer.getWidth(title)));
+
+ TextWidget chestValueWidget = new ChestValueTextWidget(chestValueWidth, textRenderer.fontHeight, chestValue, textRenderer);
+ chestValueWidget.setPosition(x + backgroundWidth - chestValueWidget.getWidth() - 4, y + 6);
+ Screens.getButtons(genericContainerScreen).add(chestValueWidget);
+
+ ChestValueTextWidget chestTitleWidget = new ChestValueTextWidget(backgroundWidth - 8 - chestValueWidth - 2, textRenderer.fontHeight, title.copy().fillStyle(Style.EMPTY.withColor(4210752)), textRenderer);
+ chestTitleWidget.shadow = false;
+ chestTitleWidget.setPosition(x + 8, y + 6);
+ Screens.getButtons(genericContainerScreen).add(chestTitleWidget);
+ }
+
+ private static class ChestValueTextWidget extends TextWidget {
+
+ public boolean shadow = true;
+
+ public ChestValueTextWidget(int width, int height, Text message, TextRenderer textRenderer) {
+ super(width, height, message, textRenderer);
+ alignLeft();
+ }
+
+ @Override
+ public void renderWidget(DrawContext context, int mouseX, int mouseY, float delta) {
+ draw(context, getTextRenderer(), getMessage(), getX(), getRight());
+ }
+
+ // Yoinked from ClickableWidget
+ protected void draw(
+ DrawContext context, TextRenderer textRenderer, Text text, int startX, int endX
+ ) {
+ int i = textRenderer.getWidth(text);
+ int k = endX - startX;
+ if (i > k) {
+ int l = i - k;
+ double d = (double) Util.getMeasuringTimeMs() / 600.0;
+ double e = Math.max((double) l * 0.5, 3.0);
+ double f = Math.sin((Math.PI / 2) * Math.cos((Math.PI * 2) * d / e)) / 2.0 + 0.5;
+ double g = MathHelper.lerp(f, 0.0, l);
+ context.enableScissor(startX, getY(), endX, getY() + textRenderer.fontHeight);
+ context.drawText(textRenderer, text, startX - (int) g, getY(), -1, shadow);
+ context.disableScissor();
+ } else {
+ context.drawText(textRenderer, text, startX, getY(), -1, shadow);
+ }
+ }
+ }
}