From 2b9c8ed13a80ea5356616f1af40d3956d38aa1b3 Mon Sep 17 00:00:00 2001 From: Rime <81419447+Emirlol@users.noreply.github.com> Date: Fri, 24 May 2024 17:55:38 +0300 Subject: [PATCH 01/14] Bazaar Helper initial commit --- .../config/categories/HelperCategory.java | 14 +++++++ .../config/configs/HelperConfig.java | 8 ++++ .../skyblock/bazaar/BazaarHelper.java | 40 +++++++++++++++++++ .../render/gui/ContainerSolverManager.java | 5 ++- .../assets/skyblocker/lang/en_us.json | 4 ++ 5 files changed, 69 insertions(+), 2 deletions(-) create mode 100644 src/main/java/de/hysky/skyblocker/skyblock/bazaar/BazaarHelper.java diff --git a/src/main/java/de/hysky/skyblocker/config/categories/HelperCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/HelperCategory.java index 1518dfe7d9..12547018a7 100644 --- a/src/main/java/de/hysky/skyblocker/config/categories/HelperCategory.java +++ b/src/main/java/de/hysky/skyblocker/config/categories/HelperCategory.java @@ -198,6 +198,20 @@ public static ConfigCategory create(SkyblockerConfig defaults, SkyblockerConfig .build()) .build()) + //Bazaar + .group(OptionGroup.createBuilder() + .name(Text.translatable("skyblocker.config.helpers.bazaar")) + .collapsed(true) + .option(Option.createBuilder() + .name(Text.translatable("skyblocker.config.helpers.bazaar.enableBazaarHelper")) + .description(OptionDescription.of(Text.translatable("skyblocker.config.helpers.bazaar.enableBazaarHelper.@Tooltip"))) + .binding(defaults.helpers.bazaar.enableBazaarHelper, + () -> config.helpers.bazaar.enableBazaarHelper, + newValue -> config.helpers.bazaar.enableBazaarHelper = newValue) + .controller(ConfigUtils::createBooleanController) + .build()) + .build()) + .build(); } } diff --git a/src/main/java/de/hysky/skyblocker/config/configs/HelperConfig.java b/src/main/java/de/hysky/skyblocker/config/configs/HelperConfig.java index 33047f1c5b..6ddb1a74bc 100644 --- a/src/main/java/de/hysky/skyblocker/config/configs/HelperConfig.java +++ b/src/main/java/de/hysky/skyblocker/config/configs/HelperConfig.java @@ -26,6 +26,9 @@ public class HelperConfig { @SerialEntry public ChocolateFactory chocolateFactory = new ChocolateFactory(); + @SerialEntry + public Bazaar bazaar = new Bazaar(); + public static class MythologicalRitual { @SerialEntry public boolean enableMythologicalRitualHelper = true; @@ -91,4 +94,9 @@ public static class ChocolateFactory { @SerialEntry public boolean enableTimeTowerReminder = true; } + + public static class Bazaar { + @SerialEntry + public boolean enableBazaarHelper = true; + } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/bazaar/BazaarHelper.java b/src/main/java/de/hysky/skyblocker/skyblock/bazaar/BazaarHelper.java new file mode 100644 index 0000000000..6129d604cf --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/bazaar/BazaarHelper.java @@ -0,0 +1,40 @@ +package de.hysky.skyblocker.skyblock.bazaar; + +import de.hysky.skyblocker.config.SkyblockerConfigManager; +import de.hysky.skyblocker.utils.ItemUtils; +import de.hysky.skyblocker.utils.render.gui.ColorHighlight; +import de.hysky.skyblocker.utils.render.gui.ContainerSolver; +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import net.minecraft.item.ItemStack; + +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class BazaarHelper extends ContainerSolver { + private static final Pattern ORDER_PATTERN = Pattern.compile("You have [\\d,]+ (items|coins) to claim!"); + public BazaarHelper() { + super("Your Bazaar Orders"); + } + + @Override + protected boolean isEnabled() { + return SkyblockerConfigManager.get().helpers.bazaar.enableBazaarHelper; + } + + @Override + protected List getColors(String[] groups, Int2ObjectMap slots) { + ArrayList highlights = new ArrayList<>(); + for (int slot = 0; slot < slots.size(); slot++) { + Matcher matcher = ItemUtils.getLoreLineIfMatch(slots.get(slot), ORDER_PATTERN); + if (matcher != null) { + switch (matcher.group(1)) { + case "items" -> highlights.add(new ColorHighlight(slot, 0x7000AA00)); + case "coins" -> highlights.add(new ColorHighlight(slot, 0x70FFAA00)); + } + } + } + return highlights; + } +} diff --git a/src/main/java/de/hysky/skyblocker/utils/render/gui/ContainerSolverManager.java b/src/main/java/de/hysky/skyblocker/utils/render/gui/ContainerSolverManager.java index 9a1e307217..5ef4e07557 100644 --- a/src/main/java/de/hysky/skyblocker/utils/render/gui/ContainerSolverManager.java +++ b/src/main/java/de/hysky/skyblocker/utils/render/gui/ContainerSolverManager.java @@ -1,10 +1,10 @@ package de.hysky.skyblocker.utils.render.gui; import com.mojang.blaze3d.systems.RenderSystem; - import de.hysky.skyblocker.mixins.accessors.HandledScreenAccessor; import de.hysky.skyblocker.skyblock.accessories.newyearcakes.NewYearCakeBagHelper; import de.hysky.skyblocker.skyblock.accessories.newyearcakes.NewYearCakesHelper; +import de.hysky.skyblocker.skyblock.bazaar.BazaarHelper; import de.hysky.skyblocker.skyblock.chocolatefactory.ChocolateFactorySolver; import de.hysky.skyblocker.skyblock.dungeon.CroesusHelper; import de.hysky.skyblocker.skyblock.dungeon.CroesusProfit; @@ -59,7 +59,8 @@ public ContainerSolverManager() { UltrasequencerSolver.INSTANCE, new NewYearCakeBagHelper(), NewYearCakesHelper.INSTANCE, - new ChocolateFactorySolver() + new ChocolateFactorySolver(), + new BazaarHelper() }; } diff --git a/src/main/resources/assets/skyblocker/lang/en_us.json b/src/main/resources/assets/skyblocker/lang/en_us.json index 5ac9dbbbd7..5a138a4111 100644 --- a/src/main/resources/assets/skyblocker/lang/en_us.json +++ b/src/main/resources/assets/skyblocker/lang/en_us.json @@ -286,6 +286,10 @@ "skyblocker.config.helpers": "Helpers", + "skyblocker.config.helpers.bazaar": "Bazaar", + "skyblocker.config.helpers.bazaar.enableBazaarHelper": "Enable Bazaar Helper", + "skyblocker.config.helpers.bazaar.enableBazaarHelper.@Tooltip": "Highlights orders with items or coins to claim.", + "skyblocker.config.helpers.chocolateFactory": "Chocolate Factory", "skyblocker.config.helpers.chocolateFactory.enableChocolateFactoryHelper": "Enable Chocolate Factory Helper", "skyblocker.config.helpers.chocolateFactory.enableChocolateFactoryHelper.@Tooltip": "Highlights the best upgrade when enabled. \n\nThe best upgrade is marked as green, but if you can't afford it, it's marked as yellow while marking the next best upgrade that you can afford as green.", From 354e8d07be12acbdec4be113f39c5c3609636bd0 Mon Sep 17 00:00:00 2001 From: Rime <81419447+Emirlol@users.noreply.github.com> Date: Sun, 26 May 2024 19:17:47 +0300 Subject: [PATCH 02/14] Add red highlight for expired orders --- .../de/hysky/skyblocker/skyblock/bazaar/BazaarHelper.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/java/de/hysky/skyblocker/skyblock/bazaar/BazaarHelper.java b/src/main/java/de/hysky/skyblocker/skyblock/bazaar/BazaarHelper.java index 6129d604cf..c9a4b73212 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/bazaar/BazaarHelper.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/bazaar/BazaarHelper.java @@ -14,6 +14,7 @@ public class BazaarHelper extends ContainerSolver { private static final Pattern ORDER_PATTERN = Pattern.compile("You have [\\d,]+ (items|coins) to claim!"); + public BazaarHelper() { super("Your Bazaar Orders"); } @@ -27,6 +28,11 @@ protected boolean isEnabled() { protected List getColors(String[] groups, Int2ObjectMap slots) { ArrayList highlights = new ArrayList<>(); for (int slot = 0; slot < slots.size(); slot++) { + if (ItemUtils.getLoreLineIf(slots.get(slot), str -> str.equals("Expired!")) != null) { + highlights.add(ColorHighlight.red(slot)); + continue; + } + Matcher matcher = ItemUtils.getLoreLineIfMatch(slots.get(slot), ORDER_PATTERN); if (matcher != null) { switch (matcher.group(1)) { From 8d9a883f97c30b9958fedae7527215e005afcd2b Mon Sep 17 00:00:00 2001 From: Rime <81419447+Emirlol@users.noreply.github.com> Date: Thu, 13 Jun 2024 18:20:27 +0300 Subject: [PATCH 03/14] Add @Language annotation where necessary --- .../de/hysky/skyblocker/skyblock/filters/SimpleChatFilter.java | 3 ++- .../de/hysky/skyblocker/utils/chat/ChatPatternListener.java | 3 ++- .../de/hysky/skyblocker/utils/render/gui/ContainerSolver.java | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/main/java/de/hysky/skyblocker/skyblock/filters/SimpleChatFilter.java b/src/main/java/de/hysky/skyblocker/skyblock/filters/SimpleChatFilter.java index 025b3dcee5..2521b3a90e 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/filters/SimpleChatFilter.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/filters/SimpleChatFilter.java @@ -2,11 +2,12 @@ import de.hysky.skyblocker.utils.chat.ChatPatternListener; import net.minecraft.text.Text; +import org.intellij.lang.annotations.Language; import java.util.regex.Matcher; public abstract class SimpleChatFilter extends ChatPatternListener { - public SimpleChatFilter(String pattern) { + protected SimpleChatFilter(@Language("RegExp") String pattern) { super(pattern); } diff --git a/src/main/java/de/hysky/skyblocker/utils/chat/ChatPatternListener.java b/src/main/java/de/hysky/skyblocker/utils/chat/ChatPatternListener.java index 708af280f6..e701e24c22 100644 --- a/src/main/java/de/hysky/skyblocker/utils/chat/ChatPatternListener.java +++ b/src/main/java/de/hysky/skyblocker/utils/chat/ChatPatternListener.java @@ -1,6 +1,7 @@ package de.hysky.skyblocker.utils.chat; import net.minecraft.text.Text; +import org.intellij.lang.annotations.Language; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -9,7 +10,7 @@ public abstract class ChatPatternListener implements ChatMessageListener { protected static final String NUMBER = "-?[0-9]{1,3}(?>,[0-9]{3})*(?:\\.[1-9])?"; public final Pattern pattern; - public ChatPatternListener(String pattern) { + protected ChatPatternListener(@Language("RegExp") String pattern) { this.pattern = Pattern.compile(pattern); } diff --git a/src/main/java/de/hysky/skyblocker/utils/render/gui/ContainerSolver.java b/src/main/java/de/hysky/skyblocker/utils/render/gui/ContainerSolver.java index 81c9ebecf8..9a9d090709 100644 --- a/src/main/java/de/hysky/skyblocker/utils/render/gui/ContainerSolver.java +++ b/src/main/java/de/hysky/skyblocker/utils/render/gui/ContainerSolver.java @@ -4,6 +4,7 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import net.minecraft.client.gui.screen.ingame.GenericContainerScreen; import net.minecraft.item.ItemStack; +import org.intellij.lang.annotations.Language; import java.util.List; import java.util.regex.Pattern; @@ -12,7 +13,7 @@ * Abstract class for gui solvers. Extend this class to add a new gui solver, like terminal solvers or experiment solvers. */ public abstract class ContainerSolver extends AbstractContainerMatcher { - protected ContainerSolver(String titlePattern) { + protected ContainerSolver(@Language("RegExp") String titlePattern) { super(titlePattern); } From efbe9568050b7efce6871e0623eae35b205d2b83 Mon Sep 17 00:00:00 2001 From: Rime <81419447+Emirlol@users.noreply.github.com> Date: Thu, 13 Jun 2024 19:52:18 +0300 Subject: [PATCH 04/14] Add secondary highlighting color scheme to BazaarHelper --- .../config/categories/HelperCategory.java | 10 ++++ .../config/configs/HelperConfig.java | 3 ++ .../skyblock/bazaar/BazaarHelper.java | 49 ++++++++++++++++--- .../assets/skyblocker/lang/en_us.json | 2 + 4 files changed, 57 insertions(+), 7 deletions(-) diff --git a/src/main/java/de/hysky/skyblocker/config/categories/HelperCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/HelperCategory.java index 12547018a7..fd373f7368 100644 --- a/src/main/java/de/hysky/skyblocker/config/categories/HelperCategory.java +++ b/src/main/java/de/hysky/skyblocker/config/categories/HelperCategory.java @@ -2,6 +2,7 @@ import de.hysky.skyblocker.config.ConfigUtils; import de.hysky.skyblocker.config.SkyblockerConfig; +import de.hysky.skyblocker.skyblock.bazaar.BazaarHelper; import de.hysky.skyblocker.utils.waypoint.Waypoint; import dev.isxander.yacl3.api.ConfigCategory; import dev.isxander.yacl3.api.Option; @@ -210,6 +211,15 @@ public static ConfigCategory create(SkyblockerConfig defaults, SkyblockerConfig newValue -> config.helpers.bazaar.enableBazaarHelper = newValue) .controller(ConfigUtils::createBooleanController) .build()) + .option(Option.createBuilder() + .name(Text.translatable("skyblocker.config.helpers.bazaar.highlightingScheme")) + .description(OptionDescription.of(Text.translatable("skyblocker.config.helpers.bazaar.highlightingScheme.@Tooltip"))) + .binding(defaults.helpers.bazaar.highlightingScheme, + () -> config.helpers.bazaar.highlightingScheme, + newValue -> config.helpers.bazaar.highlightingScheme = newValue) + .controller(ConfigUtils::createEnumCyclingListController) + .build() + ) .build()) .build(); diff --git a/src/main/java/de/hysky/skyblocker/config/configs/HelperConfig.java b/src/main/java/de/hysky/skyblocker/config/configs/HelperConfig.java index 6ddb1a74bc..f805d69fce 100644 --- a/src/main/java/de/hysky/skyblocker/config/configs/HelperConfig.java +++ b/src/main/java/de/hysky/skyblocker/config/configs/HelperConfig.java @@ -1,5 +1,6 @@ package de.hysky.skyblocker.config.configs; +import de.hysky.skyblocker.skyblock.bazaar.BazaarHelper; import de.hysky.skyblocker.utils.waypoint.Waypoint; import dev.isxander.yacl3.config.v2.api.SerialEntry; @@ -98,5 +99,7 @@ public static class ChocolateFactory { public static class Bazaar { @SerialEntry public boolean enableBazaarHelper = true; + @SerialEntry + public BazaarHelper.HighlightingScheme highlightingScheme = BazaarHelper.HighlightingScheme.ORDER_TYPE; } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/bazaar/BazaarHelper.java b/src/main/java/de/hysky/skyblocker/skyblock/bazaar/BazaarHelper.java index c9a4b73212..8a9a7aa39f 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/bazaar/BazaarHelper.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/bazaar/BazaarHelper.java @@ -6,6 +6,9 @@ import de.hysky.skyblocker.utils.render.gui.ContainerSolver; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.util.Formatting; +import org.apache.commons.lang3.math.NumberUtils; import java.util.ArrayList; import java.util.List; @@ -14,6 +17,7 @@ public class BazaarHelper extends ContainerSolver { private static final Pattern ORDER_PATTERN = Pattern.compile("You have [\\d,]+ (items|coins) to claim!"); + private static final Pattern FILLED_PATTERN = Pattern.compile("Filled: \\S+ \\(?([\\d.]+)%\\)?!?"); public BazaarHelper() { super("Your Bazaar Orders"); @@ -27,20 +31,51 @@ protected boolean isEnabled() { @Override protected List getColors(String[] groups, Int2ObjectMap slots) { ArrayList highlights = new ArrayList<>(); - for (int slot = 0; slot < slots.size(); slot++) { + // Skip the first and last 10 slots as those are always glass panes. + for (int slot = 10; slot < slots.size() - 10; slot++) { + ItemStack item = slots.get(slot); + if (item.isEmpty() || item.isOf(Items.BLACK_STAINED_GLASS_PANE)) continue; if (ItemUtils.getLoreLineIf(slots.get(slot), str -> str.equals("Expired!")) != null) { highlights.add(ColorHighlight.red(slot)); continue; } - - Matcher matcher = ItemUtils.getLoreLineIfMatch(slots.get(slot), ORDER_PATTERN); - if (matcher != null) { - switch (matcher.group(1)) { - case "items" -> highlights.add(new ColorHighlight(slot, 0x7000AA00)); - case "coins" -> highlights.add(new ColorHighlight(slot, 0x70FFAA00)); + switch (SkyblockerConfigManager.get().helpers.bazaar.highlightingScheme) { + case ORDER_TYPE -> { + Matcher matcher = ItemUtils.getLoreLineIfMatch(slots.get(slot), ORDER_PATTERN); + if (matcher != null) { + switch (matcher.group(1)) { + case "items" -> highlights.add(new ColorHighlight(slot, Formatting.DARK_GREEN.getColorValue() & 0x70000000)); + case "coins" -> highlights.add(new ColorHighlight(slot, Formatting.GOLD.getColorValue() & 0x70000000)); + } + } + } + case FULFILLMENT -> { + Matcher matcher = ItemUtils.getLoreLineIfMatch(slots.get(slot), FILLED_PATTERN); + if (matcher != null) { + int filled = NumberUtils.toInt(matcher.group(1)); + if (filled < 100) { + highlights.add(ColorHighlight.yellow(slot)); + } else if (filled == 100) { + highlights.add(ColorHighlight.green(slot)); + } + } } } } + return highlights; } + + public enum HighlightingScheme { + ORDER_TYPE, + FULFILLMENT; + + @Override + public String toString() { + return switch (this) { + case ORDER_TYPE -> "Order Type"; + case FULFILLMENT -> "Fulfillment"; + }; + } + } } diff --git a/src/main/resources/assets/skyblocker/lang/en_us.json b/src/main/resources/assets/skyblocker/lang/en_us.json index 5a138a4111..e992c7af29 100644 --- a/src/main/resources/assets/skyblocker/lang/en_us.json +++ b/src/main/resources/assets/skyblocker/lang/en_us.json @@ -289,6 +289,8 @@ "skyblocker.config.helpers.bazaar": "Bazaar", "skyblocker.config.helpers.bazaar.enableBazaarHelper": "Enable Bazaar Helper", "skyblocker.config.helpers.bazaar.enableBazaarHelper.@Tooltip": "Highlights orders with items or coins to claim.", + "skyblocker.config.helpers.bazaar.highlightingScheme": "Highlighting Scheme", + "skyblocker.config.helpers.bazaar.highlightingScheme.@Tooltip": "Order Type: Highlight items based on whether you have coins or items to claim. Dark green when items, gold when coins.\n\nFulfillment: Highlight items based on the % of the order that is filled. Yellow for 0-99%, green at 100%.\n\n\nExpired orders are highlighted with red regardless of this setting.", "skyblocker.config.helpers.chocolateFactory": "Chocolate Factory", "skyblocker.config.helpers.chocolateFactory.enableChocolateFactoryHelper": "Enable Chocolate Factory Helper", From b99fb26b5a049e7bd5a7a485e5f43938ae6d33ea Mon Sep 17 00:00:00 2001 From: Rime <81419447+Emirlol@users.noreply.github.com> Date: Thu, 13 Jun 2024 20:29:31 +0300 Subject: [PATCH 05/14] Whoops, missed one --- .../hysky/skyblocker/skyblock/item/tooltip/TooltipAdder.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/TooltipAdder.java b/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/TooltipAdder.java index 9bd63adc64..f3395def4f 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/TooltipAdder.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/TooltipAdder.java @@ -4,6 +4,7 @@ import net.minecraft.item.ItemStack; import net.minecraft.screen.slot.Slot; import net.minecraft.text.Text; +import org.intellij.lang.annotations.Language; import org.jetbrains.annotations.Nullable; import java.util.List; @@ -19,7 +20,7 @@ public abstract class TooltipAdder extends AbstractContainerMatcher { */ public final int priority; - protected TooltipAdder(String titlePattern, int priority) { + protected TooltipAdder(@Language("RegExp") String titlePattern, int priority) { super(titlePattern); this.priority = priority; } From 26af94886e964b5f83a26bf4a6866fd1553d0d79 Mon Sep 17 00:00:00 2001 From: Rime <81419447+Emirlol@users.noreply.github.com> Date: Thu, 13 Jun 2024 20:58:28 +0300 Subject: [PATCH 06/14] Add reorder helper that copies the number of items to clipboard --- .../skyblock/bazaar/ReorderHelper.java | 73 +++++++++++++++++++ .../skyblock/item/tooltip/TooltipManager.java | 2 + .../de/hysky/skyblocker/utils/ItemUtils.java | 13 ++++ .../render/gui/ContainerSolverManager.java | 4 +- 4 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 src/main/java/de/hysky/skyblocker/skyblock/bazaar/ReorderHelper.java diff --git a/src/main/java/de/hysky/skyblocker/skyblock/bazaar/ReorderHelper.java b/src/main/java/de/hysky/skyblocker/skyblock/bazaar/ReorderHelper.java new file mode 100644 index 0000000000..f779be9882 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/bazaar/ReorderHelper.java @@ -0,0 +1,73 @@ +package de.hysky.skyblocker.skyblock.bazaar; + +import de.hysky.skyblocker.skyblock.item.tooltip.TooltipAdder; +import de.hysky.skyblocker.utils.ItemUtils; +import de.hysky.skyblocker.utils.render.gui.ColorHighlight; +import de.hysky.skyblocker.utils.render.gui.ContainerSolver; +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.util.InputUtil; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.screen.slot.Slot; +import net.minecraft.text.Text; +import net.minecraft.util.Formatting; +import org.jetbrains.annotations.Nullable; +import org.lwjgl.glfw.GLFW; + +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class ReorderHelper extends ContainerSolver { + private static final Pattern BUY_PATTERN = Pattern.compile("([\\d,]+)x missing items\\."); + private static final Pattern SELL_PATTERN = Pattern.compile("([\\d,]+)x items\\."); + + public ReorderHelper() { + super("^Order options"); + } + + @Override + protected boolean isEnabled() { + return true; + } + + @Override + protected boolean onClickSlot(int slot, ItemStack stack, int screenId, String[] groups) { + // V This part is so that it short-circuits if not necessary + if ((slot == 11 || slot == 13) && stack.isOf(Items.GREEN_TERRACOTTA) && InputUtil.isKeyPressed(MinecraftClient.getInstance().getWindow().getHandle(), GLFW.GLFW_KEY_LEFT_CONTROL)) { + Matcher matcher; + // The terracotta is at slot 13 on sell orders and at slot 11 on buy orders + if (slot == 13) matcher = ItemUtils.getLoreLineIfContainsMatch(stack, SELL_PATTERN); + else matcher = ItemUtils.getLoreLineIfContainsMatch(stack, BUY_PATTERN); + if (matcher != null) { + MinecraftClient.getInstance().keyboard.setClipboard(matcher.group(1).replace(",", "")); + return false; + } + } + return false; + } + + @Override + protected List getColors(String[] groups, Int2ObjectMap slots) { + return List.of(); + } + + public static class Tooltip extends TooltipAdder { + public Tooltip() { + super("^Order options", Integer.MIN_VALUE); + } + + @Override + public void addToTooltip(@Nullable Slot focusedSlot, ItemStack stack, List lines) { + if (focusedSlot == null || !stack.isOf(Items.GREEN_TERRACOTTA)) return; + switch (focusedSlot.id) { + case 11, 13 -> { + lines.add(Text.empty()); + lines.add(Text.empty().append(Text.literal("[Skyblocker] You can copy the amount of items").formatted(Formatting.DARK_GRAY, Formatting.ITALIC))); + lines.add(Text.empty().append(Text.literal("by holding CTRL while clicking on the item!").formatted(Formatting.DARK_GRAY, Formatting.ITALIC))); + } + } + } + } +} diff --git a/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/TooltipManager.java b/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/TooltipManager.java index cb8efb0caf..bd06acba51 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/TooltipManager.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/TooltipManager.java @@ -1,6 +1,7 @@ package de.hysky.skyblocker.skyblock.item.tooltip; import de.hysky.skyblocker.mixins.accessors.HandledScreenAccessor; +import de.hysky.skyblocker.skyblock.bazaar.ReorderHelper; import de.hysky.skyblocker.skyblock.chocolatefactory.ChocolateFactorySolver; import de.hysky.skyblocker.skyblock.item.tooltip.adders.*; import de.hysky.skyblocker.skyblock.item.tooltip.adders.CraftPriceTooltip; @@ -24,6 +25,7 @@ public class TooltipManager { new LineSmoothener(), // Applies before anything else new SupercraftReminder(), new ChocolateFactorySolver.Tooltip(), + new ReorderHelper.Tooltip(), new NpcPriceTooltip(1), new BazaarPriceTooltip(2), new LBinTooltip(3), diff --git a/src/main/java/de/hysky/skyblocker/utils/ItemUtils.java b/src/main/java/de/hysky/skyblocker/utils/ItemUtils.java index e43ce783c5..ff6daad228 100644 --- a/src/main/java/de/hysky/skyblocker/utils/ItemUtils.java +++ b/src/main/java/de/hysky/skyblocker/utils/ItemUtils.java @@ -223,6 +223,19 @@ public static Matcher getLoreLineIfMatch(ItemStack item, Pattern pattern) { return null; } + @Nullable + public static Matcher getLoreLineIfContainsMatch(ItemStack item, Pattern pattern) { + for (Text line : getLore(item)) { + String string = line.getString(); + Matcher matcher = pattern.matcher(string); + if (matcher.find()) { + return matcher; + } + } + + return null; + } + public static @NotNull List getLore(ItemStack item) { return item.getOrDefault(DataComponentTypes.LORE, LoreComponent.DEFAULT).styledLines(); } diff --git a/src/main/java/de/hysky/skyblocker/utils/render/gui/ContainerSolverManager.java b/src/main/java/de/hysky/skyblocker/utils/render/gui/ContainerSolverManager.java index 5ef4e07557..c5ed0494b7 100644 --- a/src/main/java/de/hysky/skyblocker/utils/render/gui/ContainerSolverManager.java +++ b/src/main/java/de/hysky/skyblocker/utils/render/gui/ContainerSolverManager.java @@ -5,6 +5,7 @@ import de.hysky.skyblocker.skyblock.accessories.newyearcakes.NewYearCakeBagHelper; import de.hysky.skyblocker.skyblock.accessories.newyearcakes.NewYearCakesHelper; import de.hysky.skyblocker.skyblock.bazaar.BazaarHelper; +import de.hysky.skyblocker.skyblock.bazaar.ReorderHelper; import de.hysky.skyblocker.skyblock.chocolatefactory.ChocolateFactorySolver; import de.hysky.skyblocker.skyblock.dungeon.CroesusHelper; import de.hysky.skyblocker.skyblock.dungeon.CroesusProfit; @@ -60,7 +61,8 @@ public ContainerSolverManager() { new NewYearCakeBagHelper(), NewYearCakesHelper.INSTANCE, new ChocolateFactorySolver(), - new BazaarHelper() + new BazaarHelper(), + new ReorderHelper() }; } From 478451fdc0a24b1b3616ca1d43c19fc5b90cfe70 Mon Sep 17 00:00:00 2001 From: Rime <81419447+Emirlol@users.noreply.github.com> Date: Thu, 27 Jun 2024 16:14:40 +0300 Subject: [PATCH 07/14] Add some javadocs for ItemUtils and simplify getLoreLine methods --- .../de/hysky/skyblocker/utils/ItemUtils.java | 29 +++++++++++++------ 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/src/main/java/de/hysky/skyblocker/utils/ItemUtils.java b/src/main/java/de/hysky/skyblocker/utils/ItemUtils.java index ff6daad228..b8e9963389 100644 --- a/src/main/java/de/hysky/skyblocker/utils/ItemUtils.java +++ b/src/main/java/de/hysky/skyblocker/utils/ItemUtils.java @@ -43,7 +43,8 @@ import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.literal; -public class ItemUtils { +public final class ItemUtils { + private ItemUtils() {} public static final String ID = "id"; public static final String UUID = "uuid"; public static final Pattern NOT_DURABILITY = Pattern.compile("[^0-9 /]"); @@ -198,6 +199,10 @@ public static IntIntPair getDurability(@NotNull ItemStack stack) { return null; } + /** + * Gets the first line of the lore that matches the specified predicate. + * @return The first line of the lore that matches the predicate, or {@code null} if no line matches. + */ @Nullable public static String getLoreLineIf(ItemStack item, Predicate predicate) { for (Text line : getLore(item)) { @@ -210,29 +215,35 @@ public static String getLoreLineIf(ItemStack item, Predicate predicate) return null; } + /** + * Gets the first line of the lore that matches the specified pattern, using {@link Matcher#matches()}. + * @return A matcher that contains match results if the pattern was found in the lore, otherwise {@code null}. + */ @Nullable public static Matcher getLoreLineIfMatch(ItemStack item, Pattern pattern) { + Matcher matcher = pattern.matcher(""); for (Text line : getLore(item)) { - String string = line.getString(); - Matcher matcher = pattern.matcher(string); - if (matcher.matches()) { + if (matcher.reset(line.getString()).matches()) { return matcher; } } - return null; } + /** + * Gets the first line of the lore that matches the specified pattern, using {@link Matcher#find()}. + * @param pattern the pattern to search for + * @param item the item to search the lore of + * @return A {@link Matcher matcher} that contains match results if the pattern was found in the lore, otherwise {@code null}. + */ @Nullable public static Matcher getLoreLineIfContainsMatch(ItemStack item, Pattern pattern) { + Matcher matcher = pattern.matcher(""); for (Text line : getLore(item)) { - String string = line.getString(); - Matcher matcher = pattern.matcher(string); - if (matcher.find()) { + if (matcher.reset(line.getString()).find()) { return matcher; } } - return null; } From a5d43a82d09e20a0ec37756496b9a7c65b7569c4 Mon Sep 17 00:00:00 2001 From: Rime <81419447+Emirlol@users.noreply.github.com> Date: Thu, 27 Jun 2024 16:26:29 +0300 Subject: [PATCH 08/14] Fix highlighting not working on co-op profiles --- .../java/de/hysky/skyblocker/skyblock/bazaar/BazaarHelper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/de/hysky/skyblocker/skyblock/bazaar/BazaarHelper.java b/src/main/java/de/hysky/skyblocker/skyblock/bazaar/BazaarHelper.java index 8a9a7aa39f..546bc9bca3 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/bazaar/BazaarHelper.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/bazaar/BazaarHelper.java @@ -20,7 +20,7 @@ public class BazaarHelper extends ContainerSolver { private static final Pattern FILLED_PATTERN = Pattern.compile("Filled: \\S+ \\(?([\\d.]+)%\\)?!?"); public BazaarHelper() { - super("Your Bazaar Orders"); + super("(?:Co-op|Your) Bazaar Orders"); } @Override From 1dbb973e791456c418acfa45be824640db2b111f Mon Sep 17 00:00:00 2001 From: Rime <81419447+Emirlol@users.noreply.github.com> Date: Wed, 10 Jul 2024 02:07:08 +0300 Subject: [PATCH 09/14] Refactor the bz order helper to display slot text instead of highlights Also removes the coloring schema option as that's not relevant anymore. Or rather, there's no reasonable way to display the order type anymore without making the item impossible to see. --- .../config/categories/HelperCategory.java | 11 +-- .../config/configs/HelperConfig.java | 3 - .../skyblock/bazaar/BazaarHelper.java | 93 ++++++++----------- .../item/slottext/SlotTextManager.java | 2 + .../render/gui/ContainerSolverManager.java | 2 - .../assets/skyblocker/lang/en_us.json | 4 +- 6 files changed, 44 insertions(+), 71 deletions(-) diff --git a/src/main/java/de/hysky/skyblocker/config/categories/HelperCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/HelperCategory.java index fd373f7368..d5c6b09747 100644 --- a/src/main/java/de/hysky/skyblocker/config/categories/HelperCategory.java +++ b/src/main/java/de/hysky/skyblocker/config/categories/HelperCategory.java @@ -205,21 +205,12 @@ public static ConfigCategory create(SkyblockerConfig defaults, SkyblockerConfig .collapsed(true) .option(Option.createBuilder() .name(Text.translatable("skyblocker.config.helpers.bazaar.enableBazaarHelper")) - .description(OptionDescription.of(Text.translatable("skyblocker.config.helpers.bazaar.enableBazaarHelper.@Tooltip"))) + .description(OptionDescription.of(Text.translatable("skyblocker.config.helpers.bazaar.enableBazaarHelper.@Tooltip", BazaarHelper.getExpiredIcon(false), BazaarHelper.getExpiredIcon(true), BazaarHelper.getFilledIcon(69), BazaarHelper.getFilledIcon(100)))) .binding(defaults.helpers.bazaar.enableBazaarHelper, () -> config.helpers.bazaar.enableBazaarHelper, newValue -> config.helpers.bazaar.enableBazaarHelper = newValue) .controller(ConfigUtils::createBooleanController) .build()) - .option(Option.createBuilder() - .name(Text.translatable("skyblocker.config.helpers.bazaar.highlightingScheme")) - .description(OptionDescription.of(Text.translatable("skyblocker.config.helpers.bazaar.highlightingScheme.@Tooltip"))) - .binding(defaults.helpers.bazaar.highlightingScheme, - () -> config.helpers.bazaar.highlightingScheme, - newValue -> config.helpers.bazaar.highlightingScheme = newValue) - .controller(ConfigUtils::createEnumCyclingListController) - .build() - ) .build()) .build(); diff --git a/src/main/java/de/hysky/skyblocker/config/configs/HelperConfig.java b/src/main/java/de/hysky/skyblocker/config/configs/HelperConfig.java index f805d69fce..6ddb1a74bc 100644 --- a/src/main/java/de/hysky/skyblocker/config/configs/HelperConfig.java +++ b/src/main/java/de/hysky/skyblocker/config/configs/HelperConfig.java @@ -1,6 +1,5 @@ package de.hysky.skyblocker.config.configs; -import de.hysky.skyblocker.skyblock.bazaar.BazaarHelper; import de.hysky.skyblocker.utils.waypoint.Waypoint; import dev.isxander.yacl3.config.v2.api.SerialEntry; @@ -99,7 +98,5 @@ public static class ChocolateFactory { public static class Bazaar { @SerialEntry public boolean enableBazaarHelper = true; - @SerialEntry - public BazaarHelper.HighlightingScheme highlightingScheme = BazaarHelper.HighlightingScheme.ORDER_TYPE; } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/bazaar/BazaarHelper.java b/src/main/java/de/hysky/skyblocker/skyblock/bazaar/BazaarHelper.java index 546bc9bca3..032d2295d8 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/bazaar/BazaarHelper.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/bazaar/BazaarHelper.java @@ -1,22 +1,23 @@ package de.hysky.skyblocker.skyblock.bazaar; import de.hysky.skyblocker.config.SkyblockerConfigManager; +import de.hysky.skyblocker.skyblock.item.slottext.SlotText; +import de.hysky.skyblocker.skyblock.item.slottext.SlotTextAdder; import de.hysky.skyblocker.utils.ItemUtils; -import de.hysky.skyblocker.utils.render.gui.ColorHighlight; -import de.hysky.skyblocker.utils.render.gui.ContainerSolver; -import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import it.unimi.dsi.fastutil.objects.ObjectArrayList; import net.minecraft.item.ItemStack; -import net.minecraft.item.Items; +import net.minecraft.screen.slot.Slot; +import net.minecraft.text.MutableText; +import net.minecraft.text.Text; import net.minecraft.util.Formatting; import org.apache.commons.lang3.math.NumberUtils; +import org.jetbrains.annotations.NotNull; -import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; -public class BazaarHelper extends ContainerSolver { - private static final Pattern ORDER_PATTERN = Pattern.compile("You have [\\d,]+ (items|coins) to claim!"); +public class BazaarHelper extends SlotTextAdder { private static final Pattern FILLED_PATTERN = Pattern.compile("Filled: \\S+ \\(?([\\d.]+)%\\)?!?"); public BazaarHelper() { @@ -24,58 +25,44 @@ public BazaarHelper() { } @Override - protected boolean isEnabled() { - return SkyblockerConfigManager.get().helpers.bazaar.enableBazaarHelper; - } + public @NotNull List getText(Slot slot) { + if (!SkyblockerConfigManager.get().helpers.bazaar.enableBazaarHelper) return List.of(); + // Skip the first row as it's always glass panes. + if (slot.id < 10) return List.of(); + // Skip the last 10 items. 11 is subtracted because size is 1-based so the last slot is size - 1. + if (slot.id > slot.inventory.size() - 11) return List.of(); //Note that this also skips the slots in player's inventory (anything above 36/45/54 depending on the order count) - @Override - protected List getColors(String[] groups, Int2ObjectMap slots) { - ArrayList highlights = new ArrayList<>(); - // Skip the first and last 10 slots as those are always glass panes. - for (int slot = 10; slot < slots.size() - 10; slot++) { - ItemStack item = slots.get(slot); - if (item.isEmpty() || item.isOf(Items.BLACK_STAINED_GLASS_PANE)) continue; - if (ItemUtils.getLoreLineIf(slots.get(slot), str -> str.equals("Expired!")) != null) { - highlights.add(ColorHighlight.red(slot)); - continue; - } - switch (SkyblockerConfigManager.get().helpers.bazaar.highlightingScheme) { - case ORDER_TYPE -> { - Matcher matcher = ItemUtils.getLoreLineIfMatch(slots.get(slot), ORDER_PATTERN); - if (matcher != null) { - switch (matcher.group(1)) { - case "items" -> highlights.add(new ColorHighlight(slot, Formatting.DARK_GREEN.getColorValue() & 0x70000000)); - case "coins" -> highlights.add(new ColorHighlight(slot, Formatting.GOLD.getColorValue() & 0x70000000)); - } - } - } - case FULFILLMENT -> { - Matcher matcher = ItemUtils.getLoreLineIfMatch(slots.get(slot), FILLED_PATTERN); - if (matcher != null) { - int filled = NumberUtils.toInt(matcher.group(1)); - if (filled < 100) { - highlights.add(ColorHighlight.yellow(slot)); - } else if (filled == 100) { - highlights.add(ColorHighlight.green(slot)); - } - } - } + int column = slot.id % 9; + if (column == 0 || column == 8) return List.of(); // Skip the first and last column as those are always glass panes as well. + + ItemStack item = slot.getStack(); + if (item.isEmpty()) return List.of(); //We've skipped all invalid slots, so we can just check if it's not air here. + + ObjectArrayList icons = new ObjectArrayList<>(); + if (ItemUtils.getLoreLineIf(item, str -> str.equals("Expired!")) != null) { + //Todo: Handle the case where the order is close to expiring but hasn't expired yet. + icons.add(SlotText.topRight(getExpiredIcon(true))); + } + + Matcher matcher = ItemUtils.getLoreLineIfMatch(item, FILLED_PATTERN); + if (matcher != null) { + List lore = ItemUtils.getLore(item); + if (!lore.isEmpty() && lore.getLast().getString().equals("Click to claim!")) { + int filled = NumberUtils.toInt(matcher.group(1)); + icons.add(SlotText.topLeft(getFilledIcon(filled))); } } - return highlights; + return icons; } - public enum HighlightingScheme { - ORDER_TYPE, - FULFILLMENT; + public static @NotNull MutableText getExpiredIcon(boolean expired) { + if (expired) return Text.literal("⏰").withColor(0xe60b1e).formatted(Formatting.BOLD); + return Text.literal("⏰").withColor(0xe6ba0b).formatted(Formatting.BOLD); + } - @Override - public String toString() { - return switch (this) { - case ORDER_TYPE -> "Order Type"; - case FULFILLMENT -> "Fulfillment"; - }; - } + public static @NotNull MutableText getFilledIcon(int filled) { + if (filled < 100) return Text.literal("%").withColor(0xe6ba0b).formatted(Formatting.BOLD); + return Text.literal("✅").withColor(0x1ee60b).formatted(Formatting.BOLD); } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/item/slottext/SlotTextManager.java b/src/main/java/de/hysky/skyblocker/skyblock/item/slottext/SlotTextManager.java index d3941d7757..aa9bf93952 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/item/slottext/SlotTextManager.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/item/slottext/SlotTextManager.java @@ -1,5 +1,6 @@ package de.hysky.skyblocker.skyblock.item.slottext; +import de.hysky.skyblocker.skyblock.bazaar.BazaarHelper; import de.hysky.skyblocker.skyblock.item.slottext.adders.*; import de.hysky.skyblocker.utils.Utils; import net.fabricmc.fabric.api.client.screen.v1.ScreenEvents; @@ -30,6 +31,7 @@ public class SlotTextManager { new CommunityShopAdder(), new YourEssenceAdder(), new PowerStonesGuideAdder(), + new BazaarHelper(), new StatsTuningAdder() }; private static final ArrayList currentScreenAdders = new ArrayList<>(); diff --git a/src/main/java/de/hysky/skyblocker/utils/render/gui/ContainerSolverManager.java b/src/main/java/de/hysky/skyblocker/utils/render/gui/ContainerSolverManager.java index c5ed0494b7..79cc78f577 100644 --- a/src/main/java/de/hysky/skyblocker/utils/render/gui/ContainerSolverManager.java +++ b/src/main/java/de/hysky/skyblocker/utils/render/gui/ContainerSolverManager.java @@ -4,7 +4,6 @@ import de.hysky.skyblocker.mixins.accessors.HandledScreenAccessor; import de.hysky.skyblocker.skyblock.accessories.newyearcakes.NewYearCakeBagHelper; import de.hysky.skyblocker.skyblock.accessories.newyearcakes.NewYearCakesHelper; -import de.hysky.skyblocker.skyblock.bazaar.BazaarHelper; import de.hysky.skyblocker.skyblock.bazaar.ReorderHelper; import de.hysky.skyblocker.skyblock.chocolatefactory.ChocolateFactorySolver; import de.hysky.skyblocker.skyblock.dungeon.CroesusHelper; @@ -61,7 +60,6 @@ public ContainerSolverManager() { new NewYearCakeBagHelper(), NewYearCakesHelper.INSTANCE, new ChocolateFactorySolver(), - new BazaarHelper(), new ReorderHelper() }; } diff --git a/src/main/resources/assets/skyblocker/lang/en_us.json b/src/main/resources/assets/skyblocker/lang/en_us.json index e992c7af29..5012b91865 100644 --- a/src/main/resources/assets/skyblocker/lang/en_us.json +++ b/src/main/resources/assets/skyblocker/lang/en_us.json @@ -288,9 +288,7 @@ "skyblocker.config.helpers.bazaar": "Bazaar", "skyblocker.config.helpers.bazaar.enableBazaarHelper": "Enable Bazaar Helper", - "skyblocker.config.helpers.bazaar.enableBazaarHelper.@Tooltip": "Highlights orders with items or coins to claim.", - "skyblocker.config.helpers.bazaar.highlightingScheme": "Highlighting Scheme", - "skyblocker.config.helpers.bazaar.highlightingScheme.@Tooltip": "Order Type: Highlight items based on whether you have coins or items to claim. Dark green when items, gold when coins.\n\nFulfillment: Highlight items based on the % of the order that is filled. Yellow for 0-99%, green at 100%.\n\n\nExpired orders are highlighted with red regardless of this setting.", + "skyblocker.config.helpers.bazaar.enableBazaarHelper.@Tooltip": "Draws icons on top of orders to explain the current state of the order.\n\n%s: Order is going to expire soon\n%s: Order has expired\n%s: Order is filled to some degree and there are items/coins to claim\n%s: Order is filled", "skyblocker.config.helpers.chocolateFactory": "Chocolate Factory", "skyblocker.config.helpers.chocolateFactory.enableChocolateFactoryHelper": "Enable Chocolate Factory Helper", From 1f94e68c0f319941395ac0940472cf1686e1d8d2 Mon Sep 17 00:00:00 2001 From: Rime <81419447+Emirlol@users.noreply.github.com> Date: Thu, 11 Jul 2024 18:34:12 +0300 Subject: [PATCH 10/14] Change the bz order helper to only show one icon at a time Also adds some convenience methods to SlotText to make the `SlotTextAdder` logic more readable --- .../skyblock/bazaar/BazaarHelper.java | 18 ++++++++---------- .../skyblock/item/slottext/SlotText.java | 19 +++++++++++++++++++ 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/src/main/java/de/hysky/skyblocker/skyblock/bazaar/BazaarHelper.java b/src/main/java/de/hysky/skyblocker/skyblock/bazaar/BazaarHelper.java index 032d2295d8..aeef9d2172 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/bazaar/BazaarHelper.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/bazaar/BazaarHelper.java @@ -4,7 +4,6 @@ import de.hysky.skyblocker.skyblock.item.slottext.SlotText; import de.hysky.skyblocker.skyblock.item.slottext.SlotTextAdder; import de.hysky.skyblocker.utils.ItemUtils; -import it.unimi.dsi.fastutil.objects.ObjectArrayList; import net.minecraft.item.ItemStack; import net.minecraft.screen.slot.Slot; import net.minecraft.text.MutableText; @@ -38,22 +37,21 @@ public BazaarHelper() { ItemStack item = slot.getStack(); if (item.isEmpty()) return List.of(); //We've skipped all invalid slots, so we can just check if it's not air here. - ObjectArrayList icons = new ObjectArrayList<>(); - if (ItemUtils.getLoreLineIf(item, str -> str.equals("Expired!")) != null) { - //Todo: Handle the case where the order is close to expiring but hasn't expired yet. - icons.add(SlotText.topRight(getExpiredIcon(true))); - } - Matcher matcher = ItemUtils.getLoreLineIfMatch(item, FILLED_PATTERN); if (matcher != null) { List lore = ItemUtils.getLore(item); - if (!lore.isEmpty() && lore.getLast().getString().equals("Click to claim!")) { + if (!lore.isEmpty() && lore.getLast().getString().equals("Click to claim!")) { //Only show the filled icon when there are items to claim int filled = NumberUtils.toInt(matcher.group(1)); - icons.add(SlotText.topLeft(getFilledIcon(filled))); + return SlotText.topLeftList(getFilledIcon(filled)); } } - return icons; + if (ItemUtils.getLoreLineIf(item, str -> str.equals("Expired!")) != null) { + //Todo: Handle the case where the order is close to expiring but hasn't expired yet. + return SlotText.topLeftList(getExpiredIcon(true)); + } + + return List.of(); } public static @NotNull MutableText getExpiredIcon(boolean expired) { diff --git a/src/main/java/de/hysky/skyblocker/skyblock/item/slottext/SlotText.java b/src/main/java/de/hysky/skyblocker/skyblock/item/slottext/SlotText.java index 66c02ca143..73224509f2 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/item/slottext/SlotText.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/item/slottext/SlotText.java @@ -1,7 +1,10 @@ package de.hysky.skyblocker.skyblock.item.slottext; +import it.unimi.dsi.fastutil.objects.ObjectLists; import net.minecraft.text.Text; +import java.util.List; + public record SlotText(Text text, TextPosition position) { public static SlotText bottomLeft(Text text) { return new SlotText(text, TextPosition.BOTTOM_LEFT); @@ -18,4 +21,20 @@ public static SlotText topLeft(Text text) { public static SlotText topRight(Text text) { return new SlotText(text, TextPosition.TOP_RIGHT); } + + public static List topLeftList(Text text) { + return ObjectLists.singleton(topLeft(text)); + } + + public static List topRightList(Text text) { + return ObjectLists.singleton(topRight(text)); + } + + public static List bottomLeftList(Text text) { + return ObjectLists.singleton(bottomLeft(text)); + } + + public static List bottomRightList(Text text) { + return ObjectLists.singleton(bottomRight(text)); + } } From 2f1995590660d850ac0658419efba75af9e92857 Mon Sep 17 00:00:00 2001 From: Rime <81419447+Emirlol@users.noreply.github.com> Date: Thu, 11 Jul 2024 18:51:56 +0300 Subject: [PATCH 11/14] Handle the case where an order is close to expiry but hasn't expired yet --- .../config/categories/HelperCategory.java | 2 +- .../skyblock/bazaar/BazaarHelper.java | 21 ++++++++++++------- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/main/java/de/hysky/skyblocker/config/categories/HelperCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/HelperCategory.java index d5c6b09747..56e2ed4d02 100644 --- a/src/main/java/de/hysky/skyblocker/config/categories/HelperCategory.java +++ b/src/main/java/de/hysky/skyblocker/config/categories/HelperCategory.java @@ -205,7 +205,7 @@ public static ConfigCategory create(SkyblockerConfig defaults, SkyblockerConfig .collapsed(true) .option(Option.createBuilder() .name(Text.translatable("skyblocker.config.helpers.bazaar.enableBazaarHelper")) - .description(OptionDescription.of(Text.translatable("skyblocker.config.helpers.bazaar.enableBazaarHelper.@Tooltip", BazaarHelper.getExpiredIcon(false), BazaarHelper.getExpiredIcon(true), BazaarHelper.getFilledIcon(69), BazaarHelper.getFilledIcon(100)))) + .description(OptionDescription.of(Text.translatable("skyblocker.config.helpers.bazaar.enableBazaarHelper.@Tooltip", BazaarHelper.getExpiringIcon(), BazaarHelper.getExpiredIcon(), BazaarHelper.getFilledIcon(69), BazaarHelper.getFilledIcon(100)))) .binding(defaults.helpers.bazaar.enableBazaarHelper, () -> config.helpers.bazaar.enableBazaarHelper, newValue -> config.helpers.bazaar.enableBazaarHelper = newValue) diff --git a/src/main/java/de/hysky/skyblocker/skyblock/bazaar/BazaarHelper.java b/src/main/java/de/hysky/skyblocker/skyblock/bazaar/BazaarHelper.java index aeef9d2172..8b83b06bdf 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/bazaar/BazaarHelper.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/bazaar/BazaarHelper.java @@ -18,6 +18,9 @@ public class BazaarHelper extends SlotTextAdder { private static final Pattern FILLED_PATTERN = Pattern.compile("Filled: \\S+ \\(?([\\d.]+)%\\)?!?"); + private static final int RED = 0xe60b1e; + private static final int YELLOW = 0xe6ba0b; + private static final int GREEN = 0x1ee60b; public BazaarHelper() { super("(?:Co-op|Your) Bazaar Orders"); @@ -47,20 +50,24 @@ public BazaarHelper() { } if (ItemUtils.getLoreLineIf(item, str -> str.equals("Expired!")) != null) { - //Todo: Handle the case where the order is close to expiring but hasn't expired yet. - return SlotText.topLeftList(getExpiredIcon(true)); + return SlotText.topLeftList(getExpiredIcon()); + } else if (ItemUtils.getLoreLineIf(item, str -> str.startsWith("Expires in")) != null) { + return SlotText.topLeftList(getExpiringIcon()); } return List.of(); } - public static @NotNull MutableText getExpiredIcon(boolean expired) { - if (expired) return Text.literal("⏰").withColor(0xe60b1e).formatted(Formatting.BOLD); - return Text.literal("⏰").withColor(0xe6ba0b).formatted(Formatting.BOLD); + public static @NotNull MutableText getExpiredIcon() { + return Text.literal("⏰").withColor(RED).formatted(Formatting.BOLD); + } + + public static @NotNull MutableText getExpiringIcon() { + return Text.literal("⏰").withColor(YELLOW).formatted(Formatting.BOLD); } public static @NotNull MutableText getFilledIcon(int filled) { - if (filled < 100) return Text.literal("%").withColor(0xe6ba0b).formatted(Formatting.BOLD); - return Text.literal("✅").withColor(0x1ee60b).formatted(Formatting.BOLD); + if (filled < 100) return Text.literal("%").withColor(YELLOW).formatted(Formatting.BOLD); + return Text.literal("✅").withColor(GREEN).formatted(Formatting.BOLD); } } From 30b73a0557437c86a20f89b65eb878b850e207f7 Mon Sep 17 00:00:00 2001 From: Rime <81419447+Emirlol@users.noreply.github.com> Date: Sun, 14 Jul 2024 05:56:33 +0300 Subject: [PATCH 12/14] Refactor ItemUtils constructor to be sandwiched between fields and methods --- src/main/java/de/hysky/skyblocker/utils/ItemUtils.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/de/hysky/skyblocker/utils/ItemUtils.java b/src/main/java/de/hysky/skyblocker/utils/ItemUtils.java index b8e9963389..5dc51089bc 100644 --- a/src/main/java/de/hysky/skyblocker/utils/ItemUtils.java +++ b/src/main/java/de/hysky/skyblocker/utils/ItemUtils.java @@ -44,7 +44,6 @@ import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.literal; public final class ItemUtils { - private ItemUtils() {} public static final String ID = "id"; public static final String UUID = "uuid"; public static final Pattern NOT_DURABILITY = Pattern.compile("[^0-9 /]"); @@ -56,6 +55,8 @@ private ItemUtils() {} ComponentChanges.CODEC.optionalFieldOf("components", ComponentChanges.EMPTY).forGetter(ItemStack::getComponentChanges) ).apply(instance, ItemStack::new))); + private ItemUtils() {} + public static LiteralArgumentBuilder dumpHeldItemCommand() { return literal("dumpHeldItem").executes(context -> { context.getSource().sendFeedback(Text.literal("[Skyblocker Debug] Held Item: " + SkyblockerMod.GSON_COMPACT.toJson(ItemStack.CODEC.encodeStart(JsonOps.INSTANCE, context.getSource().getPlayer().getMainHandStack()).getOrThrow()))); From 3f1b9d9842018c905b29a763e018916ee3dcabe3 Mon Sep 17 00:00:00 2001 From: Rime <81419447+Emirlol@users.noreply.github.com> Date: Sun, 14 Jul 2024 05:57:48 +0300 Subject: [PATCH 13/14] Rename all `ItemStack` parameters in `ItemUtils` from `item` into `stack` --- .../de/hysky/skyblocker/utils/ItemUtils.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/main/java/de/hysky/skyblocker/utils/ItemUtils.java b/src/main/java/de/hysky/skyblocker/utils/ItemUtils.java index 5dc51089bc..658078868e 100644 --- a/src/main/java/de/hysky/skyblocker/utils/ItemUtils.java +++ b/src/main/java/de/hysky/skyblocker/utils/ItemUtils.java @@ -205,8 +205,8 @@ public static IntIntPair getDurability(@NotNull ItemStack stack) { * @return The first line of the lore that matches the predicate, or {@code null} if no line matches. */ @Nullable - public static String getLoreLineIf(ItemStack item, Predicate predicate) { - for (Text line : getLore(item)) { + public static String getLoreLineIf(ItemStack stack, Predicate predicate) { + for (Text line : getLore(stack)) { String string = line.getString(); if (predicate.test(string)) { return string; @@ -221,9 +221,9 @@ public static String getLoreLineIf(ItemStack item, Predicate predicate) * @return A matcher that contains match results if the pattern was found in the lore, otherwise {@code null}. */ @Nullable - public static Matcher getLoreLineIfMatch(ItemStack item, Pattern pattern) { + public static Matcher getLoreLineIfMatch(ItemStack stack, Pattern pattern) { Matcher matcher = pattern.matcher(""); - for (Text line : getLore(item)) { + for (Text line : getLore(stack)) { if (matcher.reset(line.getString()).matches()) { return matcher; } @@ -234,13 +234,13 @@ public static Matcher getLoreLineIfMatch(ItemStack item, Pattern pattern) { /** * Gets the first line of the lore that matches the specified pattern, using {@link Matcher#find()}. * @param pattern the pattern to search for - * @param item the item to search the lore of + * @param stack the stack to search the lore of * @return A {@link Matcher matcher} that contains match results if the pattern was found in the lore, otherwise {@code null}. */ @Nullable - public static Matcher getLoreLineIfContainsMatch(ItemStack item, Pattern pattern) { + public static Matcher getLoreLineIfContainsMatch(ItemStack stack, Pattern pattern) { Matcher matcher = pattern.matcher(""); - for (Text line : getLore(item)) { + for (Text line : getLore(stack)) { if (matcher.reset(line.getString()).find()) { return matcher; } @@ -248,8 +248,8 @@ public static Matcher getLoreLineIfContainsMatch(ItemStack item, Pattern pattern return null; } - public static @NotNull List getLore(ItemStack item) { - return item.getOrDefault(DataComponentTypes.LORE, LoreComponent.DEFAULT).styledLines(); + public static @NotNull List getLore(ItemStack stack) { + return stack.getOrDefault(DataComponentTypes.LORE, LoreComponent.DEFAULT).styledLines(); } public static @NotNull PropertyMap propertyMapWithTexture(String textureValue) { From bc46261cf69d7db0e8eae50485c6c9fed2c64045 Mon Sep 17 00:00:00 2001 From: Rime <81419447+Emirlol@users.noreply.github.com> Date: Sun, 14 Jul 2024 06:04:26 +0300 Subject: [PATCH 14/14] Refactor the reorder helper tooltip messages into translatables --- .../de/hysky/skyblocker/skyblock/bazaar/ReorderHelper.java | 4 ++-- src/main/resources/assets/skyblocker/lang/en_us.json | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/java/de/hysky/skyblocker/skyblock/bazaar/ReorderHelper.java b/src/main/java/de/hysky/skyblocker/skyblock/bazaar/ReorderHelper.java index f779be9882..c2b11926b1 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/bazaar/ReorderHelper.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/bazaar/ReorderHelper.java @@ -64,8 +64,8 @@ public void addToTooltip(@Nullable Slot focusedSlot, ItemStack stack, List switch (focusedSlot.id) { case 11, 13 -> { lines.add(Text.empty()); - lines.add(Text.empty().append(Text.literal("[Skyblocker] You can copy the amount of items").formatted(Formatting.DARK_GRAY, Formatting.ITALIC))); - lines.add(Text.empty().append(Text.literal("by holding CTRL while clicking on the item!").formatted(Formatting.DARK_GRAY, Formatting.ITALIC))); + lines.add(Text.empty().append(Text.translatable("skyblocker.reorderHelper.tooltip.line1")).formatted(Formatting.DARK_GRAY, Formatting.ITALIC)); + lines.add(Text.empty().append(Text.translatable("skyblocker.reorderHelper.tooltip.line2")).formatted(Formatting.DARK_GRAY, Formatting.ITALIC)); } } } diff --git a/src/main/resources/assets/skyblocker/lang/en_us.json b/src/main/resources/assets/skyblocker/lang/en_us.json index 5012b91865..d380807cbc 100644 --- a/src/main/resources/assets/skyblocker/lang/en_us.json +++ b/src/main/resources/assets/skyblocker/lang/en_us.json @@ -745,7 +745,6 @@ "skyblocker.events.tab.noMore": "No more this year!", "skyblocker.events.tab.startsIn": "Starts in %s", - "skyblocker.garden.hud.mouseLocked": "Mouse locked.", "skyblocker.fishing.reelNow": "Reel in now!", @@ -894,6 +893,9 @@ "skyblocker.partyFinder.deList": "Click to de-list", "skyblocker.partyFinder.join": "Click to join", + "skyblocker.reorderHelper.tooltip.line1": "[Skyblocker] You can copy the amount of items", + "skyblocker.reorderHelper.tooltip.line2": "by holding CTRL while clicking on the item!", + "skyblocker.fancyAuctionHouse.editBid": "Click to edit bid!", "skyblocker.fancyAuctionHouse.price": "Price:", "skyblocker.fancyAuctionHouse.newBid": "New Bid:",