diff options
Diffstat (limited to 'src')
5 files changed, 136 insertions, 63 deletions
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/chocolatefactory/ChocolateFactorySolver.java b/src/main/java/de/hysky/skyblocker/skyblock/chocolatefactory/ChocolateFactorySolver.java index 2d530b6d..e04e632a 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/chocolatefactory/ChocolateFactorySolver.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/chocolatefactory/ChocolateFactorySolver.java @@ -28,6 +28,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; public class ChocolateFactorySolver extends ContainerSolver { + //Patterns private static final Pattern CPS_PATTERN = Pattern.compile("([\\d,.]+) Chocolate per second"); private static final Pattern CPS_INCREASE_PATTERN = Pattern.compile("\\+([\\d,]+) Chocolate per second"); private static final Pattern COST_PATTERN = Pattern.compile("Cost ([\\d,]+) Chocolate"); @@ -36,17 +37,31 @@ public class ChocolateFactorySolver extends ContainerSolver { private static final Pattern CHOCOLATE_PATTERN = Pattern.compile("^([\\d,]+) Chocolate$"); private static final Pattern PRESTIGE_REQUIREMENT_PATTERN = Pattern.compile("Chocolate this Prestige: ([\\d,]+) +Requires (\\S+) Chocolate this Prestige!"); private static final Pattern TIME_TOWER_STATUS_PATTERN = Pattern.compile("Status: (ACTIVE|INACTIVE)"); - private static final ObjectArrayList<Rabbit> cpsIncreaseFactors = new ObjectArrayList<>(6); + + private static final ObjectArrayList<Rabbit> cpsIncreaseFactors = new ObjectArrayList<>(8); private static long totalChocolate = -1L; private static double totalCps = -1.0; private static double totalCpsMultiplier = -1.0; private static long requiredUntilNextPrestige = -1L; + private static boolean canPrestige = false; + private static boolean reachedMaxPrestige = false; private static double timeTowerMultiplier = -1.0; private static boolean isTimeTowerActive = false; private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("#,###.#", DecimalFormatSymbols.getInstance(Locale.ENGLISH)); private static ItemStack bestUpgrade = null; private static ItemStack bestAffordableUpgrade = null; + //Slots, for ease of maintenance rather than using magic numbers everywhere. + private static final byte RABBITS_START = 28; + private static final byte RABBITS_END = 34; + private static final byte COACH_SLOT = 42; + private static final byte CHOCOLATE_SLOT = 13; + private static final byte CPS_SLOT = 45; + private static final byte PRESTIGE_SLOT = 27; + private static final byte TIME_TOWER_SLOT = 39; + private static final byte STRAY_RABBIT_START = 0; + private static final byte STRAY_RABBIT_END = 26; + public ChocolateFactorySolver() { super("^Chocolate Factory$"); ItemTooltipCallback.EVENT.register(ChocolateFactorySolver::handleTooltip); @@ -62,7 +77,8 @@ public class ChocolateFactorySolver extends ContainerSolver { updateFactoryInfo(slots); List<ColorHighlight> highlights = new ArrayList<>(); - getPrestigeHighlight(slots.get(28)).ifPresent(highlights::add); + getPrestigeHighlight().ifPresent(highlights::add); + highlights.addAll(getStrayRabbitHighlight(slots)); if (totalChocolate <= 0 || cpsIncreaseFactors.isEmpty()) return highlights; //Something went wrong or there's nothing we can afford. Rabbit bestRabbit = cpsIncreaseFactors.getFirst(); @@ -87,7 +103,7 @@ public class ChocolateFactorySolver extends ContainerSolver { private static void updateFactoryInfo(Int2ObjectMap<ItemStack> slots) { cpsIncreaseFactors.clear(); - for (int i = 29; i <= 33; i++) { // The 5 rabbits slots are in 29, 30, 31, 32 and 33. + for (int i = RABBITS_START; i <= RABBITS_END; i++) { // The 7 rabbits slots are in 28, 29, 30, 31, 32, 33 and 34. ItemStack item = slots.get(i); if (item.isOf(Items.PLAYER_HEAD)) { getRabbit(item, i).ifPresent(cpsIncreaseFactors::add); @@ -95,20 +111,21 @@ public class ChocolateFactorySolver extends ContainerSolver { } //Coach is in slot 42 - getCoach(slots.get(42)).ifPresent(cpsIncreaseFactors::add); + getCoach(slots.get(COACH_SLOT)).ifPresent(cpsIncreaseFactors::add); //The clickable chocolate is in slot 13, holds the total chocolate - RegexUtils.getLongFromMatcher(CHOCOLATE_PATTERN.matcher(slots.get(13).getName().getString())).ifPresent(l -> totalChocolate = l); + RegexUtils.getLongFromMatcher(CHOCOLATE_PATTERN.matcher(slots.get(CHOCOLATE_SLOT).getName().getString())).ifPresent(l -> totalChocolate = l); //Cps item (cocoa bean) is in slot 45 - String cpsItemLore = getConcatenatedLore(slots.get(45)); + String cpsItemLore = getConcatenatedLore(slots.get(CPS_SLOT)); Matcher cpsMatcher = CPS_PATTERN.matcher(cpsItemLore); RegexUtils.getDoubleFromMatcher(cpsMatcher).ifPresent(d -> totalCps = d); Matcher multiplierMatcher = TOTAL_MULTIPLIER_PATTERN.matcher(cpsItemLore); RegexUtils.getDoubleFromMatcher(multiplierMatcher, cpsMatcher.hasMatch() ? cpsMatcher.end() : 0).ifPresent(d -> totalCpsMultiplier = d); //Prestige item is in slot 28 - Matcher prestigeMatcher = PRESTIGE_REQUIREMENT_PATTERN.matcher(getConcatenatedLore(slots.get(28))); + String prestigeLore = getConcatenatedLore(slots.get(PRESTIGE_SLOT)); + Matcher prestigeMatcher = PRESTIGE_REQUIREMENT_PATTERN.matcher(prestigeLore); OptionalLong currentChocolate = RegexUtils.getLongFromMatcher(prestigeMatcher); if (currentChocolate.isPresent()) { String requirement = prestigeMatcher.group(2); //If the first one matched, we can assume the 2nd one is also matched since it's one whole regex @@ -117,11 +134,17 @@ public class ChocolateFactorySolver extends ContainerSolver { if (NumberUtils.isParsable(amountString)) { requiredUntilNextPrestige = Long.parseLong(amountString) - currentChocolate.getAsLong(); } + } else if (prestigeLore.endsWith("Click to prestige!")) { + canPrestige = true; + reachedMaxPrestige = false; + } else if (prestigeLore.endsWith("You have reached max prestige!")) { + canPrestige = false; + reachedMaxPrestige = true; } //Time Tower is in slot 39 - timeTowerMultiplier = romanToDecimal(StringUtils.substringAfterLast(slots.get(39).getName().getString(), ' ')) / 10.0; //The name holds the level, which is multiplier * 10 in roman numerals - Matcher timeTowerStatusMatcher = TIME_TOWER_STATUS_PATTERN.matcher(getConcatenatedLore(slots.get(39))); + timeTowerMultiplier = romanToDecimal(StringUtils.substringAfterLast(slots.get(TIME_TOWER_SLOT).getName().getString(), ' ')) / 10.0; //The name holds the level, which is multiplier * 10 in roman numerals + Matcher timeTowerStatusMatcher = TIME_TOWER_STATUS_PATTERN.matcher(getConcatenatedLore(slots.get(TIME_TOWER_SLOT))); if (timeTowerStatusMatcher.find()) { isTimeTowerActive = timeTowerStatusMatcher.group(1).equals("ACTIVE"); } @@ -146,7 +169,7 @@ public class ChocolateFactorySolver extends ContainerSolver { if (cost.isPresent()) shouldAddLine = addUpgradeTimerToLore(lines, cost.getAsLong()); //Prestige item - if (stack.isOf(Items.DROPPER) && requiredUntilNextPrestige != -1L) { + if (stack.isOf(Items.DROPPER)) { shouldAddLine = addPrestigeTimerToLore(lines) || shouldAddLine; } //Time tower @@ -171,11 +194,13 @@ public class ChocolateFactorySolver extends ContainerSolver { } private static boolean addPrestigeTimerToLore(List<Text> lines) { - if (requiredUntilNextPrestige == -1L || totalCps == -1.0) return false; - lines.add(Text.empty() - .append(Text.literal("Chocolate until next prestige: ").formatted(Formatting.GRAY)) - .append(Text.literal(DECIMAL_FORMAT.format(requiredUntilNextPrestige)).formatted(Formatting.GOLD))); - lines.add(Text.empty() + if (totalCps < 0.0 || reachedMaxPrestige) return false; + if (requiredUntilNextPrestige > 0 && !canPrestige) { + lines.add(Text.empty() + .append(Text.literal("Chocolate until next prestige: ").formatted(Formatting.GRAY)) + .append(Text.literal(DECIMAL_FORMAT.format(requiredUntilNextPrestige)).formatted(Formatting.GOLD))); + } + lines.add(Text.empty() //Keep this outside of the `if` to match the format of the upgrade tooltips, that say "Time until upgrade: Now" when it's possible .append(Text.literal("Time until next prestige: ").formatted(Formatting.GRAY)) .append(formatTime(requiredUntilNextPrestige / totalCps))); return true; @@ -292,7 +317,7 @@ public class ChocolateFactorySolver extends ContainerSolver { OptionalInt cost = RegexUtils.getIntFromMatcher(costMatcher, multiplierIncreaseMatcher.hasMatch() ? multiplierIncreaseMatcher.end() : 0); //Cost comes after the multiplier line if (cost.isEmpty()) return Optional.empty(); - return Optional.of(new Rabbit(totalCps / totalCpsMultiplier * (nextCpsMultiplier.getAsDouble() - currentCpsMultiplier.getAsDouble()), cost.getAsInt(), 42, coachItem)); + return Optional.of(new Rabbit(totalCps / totalCpsMultiplier * (nextCpsMultiplier.getAsDouble() - currentCpsMultiplier.getAsDouble()), cost.getAsInt(), COACH_SLOT, coachItem)); } private static Optional<Rabbit> getRabbit(ItemStack item, int slot) { @@ -312,13 +337,23 @@ public class ChocolateFactorySolver extends ContainerSolver { return Optional.of(new Rabbit(nextCps.getAsInt() - currentCps.getAsInt(), cost.getAsInt(), slot, item)); } - private static Optional<ColorHighlight> getPrestigeHighlight(ItemStack item) { - List<Text> loreList = ItemUtils.getLore(item); - if (loreList.isEmpty()) return Optional.empty(); + private static Optional<ColorHighlight> getPrestigeHighlight() { + if (reachedMaxPrestige) return Optional.empty(); + if (canPrestige) return Optional.of(ColorHighlight.green(PRESTIGE_SLOT)); + return Optional.of(ColorHighlight.red(PRESTIGE_SLOT)); + } - String lore = loreList.getLast().getString(); //The last line holds the text we're looking for - if (lore.equals("Click to prestige!")) return Optional.of(ColorHighlight.green(28)); - return Optional.of(ColorHighlight.red(28)); + private static List<ColorHighlight> getStrayRabbitHighlight(Int2ObjectMap<ItemStack> slots) { + final List<ColorHighlight> highlights = new ArrayList<>(); + for (byte i = STRAY_RABBIT_START; i <= STRAY_RABBIT_END; i++) { + ItemStack item = slots.get(i); + if (!item.isOf(Items.PLAYER_HEAD)) continue; + String name = item.getName().getString(); + if (name.equals("CLICK ME!") || name.startsWith("GOLDEN RABBIT")) { + highlights.add(ColorHighlight.green(i)); + } + } + return highlights; } private record Rabbit(double cpsIncrease, int cost, int slot, ItemStack itemStack) { diff --git a/src/main/java/de/hysky/skyblocker/skyblock/chocolatefactory/EggFinder.java b/src/main/java/de/hysky/skyblocker/skyblock/chocolatefactory/EggFinder.java index c4fd7d4d..cad7ef8b 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/chocolatefactory/EggFinder.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/chocolatefactory/EggFinder.java @@ -1,10 +1,17 @@ package de.hysky.skyblocker.skyblock.chocolatefactory; +import com.mojang.brigadier.Command; +import com.mojang.brigadier.arguments.IntegerArgumentType; +import com.mojang.brigadier.arguments.StringArgumentType; +import de.hysky.skyblocker.SkyblockerMod; import de.hysky.skyblocker.config.SkyblockerConfigManager; import de.hysky.skyblocker.events.SkyblockEvents; import de.hysky.skyblocker.utils.*; +import de.hysky.skyblocker.utils.scheduler.MessageScheduler; import de.hysky.skyblocker.utils.waypoint.Waypoint; import it.unimi.dsi.fastutil.objects.ObjectImmutableList; +import net.fabricmc.fabric.api.client.command.v2.ClientCommandManager; +import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback; import net.fabricmc.fabric.api.client.message.v1.ClientReceiveMessageEvents; import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents; import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext; @@ -13,6 +20,8 @@ import net.minecraft.client.MinecraftClient; import net.minecraft.entity.Entity; import net.minecraft.entity.decoration.ArmorStandEntity; import net.minecraft.item.ItemStack; +import net.minecraft.text.ClickEvent; +import net.minecraft.text.HoverEvent; import net.minecraft.text.Text; import net.minecraft.util.Formatting; import org.apache.commons.lang3.mutable.MutableObject; @@ -25,7 +34,6 @@ import java.util.regex.Pattern; public class EggFinder { private static final Pattern eggFoundPattern = Pattern.compile("^(?:HOPPITY'S HUNT You found a Chocolate|You have already collected this Chocolate) (Breakfast|Lunch|Dinner)"); - private static final Pattern newEggPattern = Pattern.compile("^HOPPITY'S HUNT A Chocolate (Breakfast|Lunch|Dinner) Egg has appeared!$"); private static final Logger logger = LoggerFactory.getLogger("Skyblocker Egg Finder"); private static final LinkedList<ArmorStandEntity> armorStandQueue = new LinkedList<>(); private static final Location[] possibleLocations = {Location.CRIMSON_ISLE, Location.CRYSTAL_HOLLOWS, Location.DUNGEON_HUB, Location.DWARVEN_MINES, Location.HUB, Location.THE_END, Location.THE_PARK, Location.GOLD_MINE}; @@ -39,6 +47,17 @@ public class EggFinder { SkyblockEvents.LOCATION_CHANGE.register(EggFinder::handleLocationChange); ClientReceiveMessageEvents.GAME.register(EggFinder::onChatMessage); WorldRenderEvents.AFTER_TRANSLUCENT.register(EggFinder::renderWaypoints); + ClientCommandRegistrationCallback.EVENT.register((dispatcher, registryAccess) -> dispatcher.register(ClientCommandManager.literal(SkyblockerMod.NAMESPACE) + .then(ClientCommandManager.literal("eggFinder") + .then(ClientCommandManager.literal("shareLocation") + .then(ClientCommandManager.argument("x", IntegerArgumentType.integer()) + .then(ClientCommandManager.argument("y", IntegerArgumentType.integer()) + .then(ClientCommandManager.argument("z", IntegerArgumentType.integer()) + .then(ClientCommandManager.argument("eggType", StringArgumentType.word()) + .executes(context -> { + MessageScheduler.INSTANCE.sendMessageAfterCooldown("[Skyblocker] Chocolate " + context.getArgument("eggType", String.class) + " Egg found at " + context.getArgument("x", Integer.class) + " " + context.getArgument("y", Integer.class) + " " + context.getArgument("z", Integer.class) + "!"); + return Command.SINGLE_SUCCESS; + }))))))))); } private static void handleLocationChange(Location location) { @@ -102,7 +121,9 @@ public class EggFinder { .append("Found a ") .append(Text.literal("Chocolate " + eggType + " Egg") .withColor(eggType.color)) - .append(" at " + entity.getBlockPos().up(2).toShortString() + "!")); + .append(" at " + entity.getBlockPos().up(2).toShortString() + "!") + .styled(style -> style.withClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/skyblocker eggFinder shareLocation " + entity.getBlockX() + " " + entity.getBlockY() + 2 + " " + entity.getBlockZ() + " " + eggType)) + .withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Text.literal("Click to share the location in chat!").formatted(Formatting.GREEN))))); } private static void renderWaypoints(WorldRenderContext context) { @@ -124,16 +145,6 @@ public class EggFinder { logger.error("[Skyblocker Egg Finder] Failed to find egg type for egg found message. Tried to match against: " + matcher.group(0), e); } } - - //There's only one egg of the same type at any given time, so we can set the changed egg to null - matcher = newEggPattern.matcher(text.getString()); - if (matcher.find()) { - try { - EggType.valueOf(matcher.group(1).toUpperCase()).egg.setValue(null); - } catch (IllegalArgumentException e) { - logger.error("[Skyblocker Egg Finder] Failed to find egg type for egg spawn message. Tried to match against: " + matcher.group(0), e); - } - } } record Egg(ArmorStandEntity entity, Waypoint waypoint) { } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/chocolatefactory/TimeTowerReminder.java b/src/main/java/de/hysky/skyblocker/skyblock/chocolatefactory/TimeTowerReminder.java index 72cbeb2a..c679f152 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/chocolatefactory/TimeTowerReminder.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/chocolatefactory/TimeTowerReminder.java @@ -2,6 +2,7 @@ package de.hysky.skyblocker.skyblock.chocolatefactory; import com.mojang.brigadier.Message; import de.hysky.skyblocker.SkyblockerMod; +import de.hysky.skyblocker.config.SkyblockerConfigManager; import de.hysky.skyblocker.events.SkyblockEvents; import de.hysky.skyblocker.utils.Constants; import de.hysky.skyblocker.utils.Utils; @@ -49,7 +50,7 @@ public class TimeTowerReminder { } try (FileWriter writer = new FileWriter(tempFile)) { - writer.write(String.valueOf(System.currentTimeMillis())); + writer.write(String.valueOf(System.currentTimeMillis())); //Overwrites the file so no need to handle case where the file already exists and has text } catch (IOException e) { LOGGER.error("[Skyblocker Time Tower Reminder] Failed to write to temp file for Time Tower Reminder!", e); } @@ -57,8 +58,9 @@ public class TimeTowerReminder { private static void sendMessage() { if (MinecraftClient.getInstance().player == null || !Utils.isOnSkyblock()) return; - MinecraftClient.getInstance().player.sendMessage(Constants.PREFIX.get().append(Text.literal("Your Chocolate Factory's Time Tower has deactivated!").formatted(Formatting.RED))); - + if (SkyblockerConfigManager.get().helpers.chocolateFactory.enableTimeTowerReminder) { + MinecraftClient.getInstance().player.sendMessage(Constants.PREFIX.get().append(Text.literal("Your Chocolate Factory's Time Tower has deactivated!").formatted(Formatting.RED))); + } File tempFile = SkyblockerMod.CONFIG_DIR.resolve(TIME_TOWER_FILE).toFile(); try { scheduled = false; diff --git a/src/main/java/de/hysky/skyblocker/skyblock/garden/VisitorHelper.java b/src/main/java/de/hysky/skyblocker/skyblock/garden/VisitorHelper.java index 682933f4..d8f4dad7 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/garden/VisitorHelper.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/garden/VisitorHelper.java @@ -2,6 +2,7 @@ package de.hysky.skyblocker.skyblock.garden; import de.hysky.skyblocker.config.SkyblockerConfigManager; import de.hysky.skyblocker.skyblock.itemlist.ItemRepository; +import de.hysky.skyblocker.utils.Constants; import de.hysky.skyblocker.utils.ItemUtils; import de.hysky.skyblocker.utils.NEURepoManager; import de.hysky.skyblocker.utils.Utils; @@ -12,6 +13,7 @@ import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import it.unimi.dsi.fastutil.objects.ObjectObjectImmutablePair; import net.fabricmc.fabric.api.client.screen.v1.ScreenEvents; +import net.minecraft.client.MinecraftClient; import net.minecraft.client.font.TextRenderer; import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.screen.ingame.HandledScreen; @@ -40,7 +42,8 @@ public class VisitorHelper { private static final Map<String, ItemStack> itemCache = new HashMap<>(); private static final int TEXT_START_X = 4; private static final int TEXT_START_Y = 4; - private static final int TEXT_INDENT = 8; + private static final int ENTRY_INDENT = 8; + private static final int ITEM_INDENT = 20; private static final int LINE_SPACING = 3; public static void init() { @@ -59,22 +62,32 @@ public class VisitorHelper { public static void onMouseClicked(double mouseX, double mouseY, int mouseButton, TextRenderer textRenderer) { int yPosition = TEXT_START_Y; - for (Map.Entry<Pair<String, String>, Object2IntMap<String>> visitorEntry : itemMap.entrySet()) { - int textWidth; - int textHeight = textRenderer.fontHeight; - - yPosition += LINE_SPACING + textHeight; + yPosition += LINE_SPACING + textRenderer.fontHeight; for (Object2IntMap.Entry<String> itemEntry : visitorEntry.getValue().object2IntEntrySet()) { String itemText = itemEntry.getKey(); - textWidth = textRenderer.getWidth(itemText + " x" + itemEntry.getIntValue()); + int textWidth = textRenderer.getWidth(itemText + " x" + itemEntry.getIntValue()); - if (isMouseOverText(mouseX, mouseY, TEXT_START_X + TEXT_INDENT, yPosition, textWidth, textHeight)) { + // Check if the mouse is over the item text + // The text starts at `TEXT_START_X + ENTRY_INDENT + ITEM_INDENT` + if (isMouseOverText(mouseX, mouseY, TEXT_START_X + ENTRY_INDENT + ITEM_INDENT, yPosition, textWidth, textRenderer.fontHeight)) { + // Send command to buy the item from the bazaar MessageScheduler.INSTANCE.sendMessageAfterCooldown("/bz " + itemText); return; } - yPosition += LINE_SPACING + textHeight; + + // Check if the mouse is over the copy amount text + // The copy amount text starts at `TEXT_START_X + ENTRY_INDENT + ITEM_INDENT + textWidth` + MinecraftClient client = MinecraftClient.getInstance(); + if (client.player != null && isMouseOverText(mouseX, mouseY, TEXT_START_X + ENTRY_INDENT + ITEM_INDENT + textWidth, yPosition, textRenderer.getWidth(" [Copy Amount]"), textRenderer.fontHeight)) { + // Copy the amount to the clipboard + client.keyboard.setClipboard(String.valueOf(itemEntry.getIntValue())); + client.player.sendMessage(Constants.PREFIX.get().append("Copied amount successfully"), false); + return; + } + + yPosition += LINE_SPACING + textRenderer.fontHeight; } } } @@ -112,7 +125,7 @@ public class VisitorHelper { } } - private static void updateItemMap(String visitorName, @Nullable String visitorTexture, Text lore) { + private static void updateItemMap(String visitorName, @Nullable String visitorTexture, Text lore) { String[] splitItemText = lore.getString().split(" x"); String itemName = splitItemText[0].trim(); if (itemName.isEmpty()) return; @@ -168,12 +181,23 @@ public class VisitorHelper { return stack; } - private static void drawItemEntryWithHover(DrawContext context, TextRenderer textRenderer, @Nullable ItemStack stack, String itemName, int amount, int index, int mouseX, int mousseY) { - Text text = stack != null ? stack.getName().copy().append(" x" + amount) : Text.literal(itemName + " x" + amount); - drawTextWithOptionalUnderline(context, textRenderer, text, TEXT_START_X + TEXT_INDENT, TEXT_START_Y + (index * (LINE_SPACING + textRenderer.fontHeight)), mouseX, mousseY); + /** + * Draws the item entry, amount, and copy amount text with optional underline and the item icon + */ + private static void drawItemEntryWithHover(DrawContext context, TextRenderer textRenderer, @Nullable ItemStack stack, String itemName, int amount, int index, int mouseX, int mouseY) { + Text text = stack != null ? stack.getName().copy().append(" x" + amount) : Text.literal(itemName + " x" + amount); + Text copyAmount = Text.literal(" [Copy Amount]"); + + // Calculate the y position of the text with index as the line number + int y = TEXT_START_Y + index * (LINE_SPACING + textRenderer.fontHeight); + // Draw the item and amount text + drawTextWithOptionalUnderline(context, textRenderer, text, TEXT_START_X + ENTRY_INDENT + ITEM_INDENT, y, mouseX, mouseY); + // Draw the copy amount text separately after the item and amount text + drawTextWithOptionalUnderline(context, textRenderer, copyAmount, TEXT_START_X + ENTRY_INDENT + ITEM_INDENT + textRenderer.getWidth(text), y, mouseX, mouseY); + // drawItem adds 150 to the z, which puts our z at 350, above the item in the slot (250) and their text (300) and below the cursor stack (382) and their text (432) if (stack != null) { - context.drawItem(stack, TEXT_START_X + TEXT_INDENT + 2 + textRenderer.getWidth(text), TEXT_START_Y + (index * (LINE_SPACING + textRenderer.fontHeight)) - textRenderer.fontHeight + 5); + context.drawItem(stack, TEXT_START_X + ENTRY_INDENT, y - textRenderer.fontHeight + 5); } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/ItemTooltip.java b/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/ItemTooltip.java index 8c083e25..031817ac 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/ItemTooltip.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/ItemTooltip.java @@ -128,17 +128,18 @@ public class ItemTooltip { } } - final Map<Integer, String> itemTierFloors = Map.of( - 1, "F1", - 2, "F2", - 3, "F3", - 4, "F4/M1", - 5, "F5/M2", - 6, "F6/M3", - 7, "F7/M4", - 8, "M5", - 9, "M6", - 10, "M7" + final Map<Integer, String> itemTierFloors = Map.ofEntries( + Map.entry(0, "E"), + Map.entry(1, "F1"), + Map.entry(2, "F2"), + Map.entry(3, "F3"), + Map.entry(4, "F4/M1"), + Map.entry(5, "F5/M2"), + Map.entry(6, "F6/M3"), + Map.entry(7, "F7/M4"), + Map.entry(8, "M5"), + Map.entry(9, "M6"), + Map.entry(10, "M7") ); if (SkyblockerConfigManager.get().general.itemTooltip.dungeonQuality) { @@ -455,4 +456,4 @@ public class ItemTooltip { }); }, 1200, true); } -}
\ No newline at end of file +} |