aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/chocolatefactory/ChocolateFactorySolver.java79
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/chocolatefactory/EggFinder.java35
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/chocolatefactory/TimeTowerReminder.java8
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/garden/VisitorHelper.java52
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/ItemTooltip.java25
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
+}