diff options
author | Kevin <92656833+kevinthegreat1@users.noreply.github.com> | 2024-07-14 21:35:52 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-07-14 21:35:52 +0800 |
commit | f34b2aae6245325f293a56f190cda82895aa85f2 (patch) | |
tree | 7dffa560205d6d526c38d67aee75fec60f4dad77 /src/main/java/de/hysky | |
parent | 1c25c8dcabc2684ebc829a7cfaa50fd7f9e4c184 (diff) | |
parent | bc46261cf69d7db0e8eae50485c6c9fed2c64045 (diff) | |
download | Skyblocker-f34b2aae6245325f293a56f190cda82895aa85f2.tar.gz Skyblocker-f34b2aae6245325f293a56f190cda82895aa85f2.tar.bz2 Skyblocker-f34b2aae6245325f293a56f190cda82895aa85f2.zip |
Merge pull request #728 from Emirlol/bazaar-highlight
Bazaar Helper
Diffstat (limited to 'src/main/java/de/hysky')
13 files changed, 239 insertions, 17 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 56dbca94..ec2c561c 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 @@ package de.hysky.skyblocker.config.categories; 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; @@ -206,6 +207,20 @@ public class HelperCategory { .build()) .build()) + //Bazaar + .group(OptionGroup.createBuilder() + .name(Text.translatable("skyblocker.config.helpers.bazaar")) + .collapsed(true) + .option(Option.<Boolean>createBuilder() + .name(Text.translatable("skyblocker.config.helpers.bazaar.enableBazaarHelper")) + .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) + .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 636d76da..e009f680 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; @@ -94,4 +97,9 @@ public class HelperConfig { @SerialEntry public boolean straySound = 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 00000000..8b83b06b --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/bazaar/BazaarHelper.java @@ -0,0 +1,73 @@ +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 net.minecraft.item.ItemStack; +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.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +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"); + } + + @Override + public @NotNull List<SlotText> 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) + + 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. + + Matcher matcher = ItemUtils.getLoreLineIfMatch(item, FILLED_PATTERN); + if (matcher != null) { + List<Text> lore = ItemUtils.getLore(item); + 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)); + return SlotText.topLeftList(getFilledIcon(filled)); + } + } + + if (ItemUtils.getLoreLineIf(item, str -> str.equals("Expired!")) != null) { + 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() { + 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(YELLOW).formatted(Formatting.BOLD); + return Text.literal("✅").withColor(GREEN).formatted(Formatting.BOLD); + } +} 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 00000000..c2b11926 --- /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<ColorHighlight> getColors(String[] groups, Int2ObjectMap<ItemStack> 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<Text> 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.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/java/de/hysky/skyblocker/skyblock/filters/SimpleChatFilter.java b/src/main/java/de/hysky/skyblocker/skyblock/filters/SimpleChatFilter.java index 025b3dce..2521b3a9 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 @@ package de.hysky.skyblocker.skyblock.filters; 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/skyblock/item/slottext/SlotText.java b/src/main/java/de/hysky/skyblocker/skyblock/item/slottext/SlotText.java index 66c02ca1..73224509 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 record SlotText(Text text, TextPosition position) { public static SlotText topRight(Text text) { return new SlotText(text, TextPosition.TOP_RIGHT); } + + public static List<SlotText> topLeftList(Text text) { + return ObjectLists.singleton(topLeft(text)); + } + + public static List<SlotText> topRightList(Text text) { + return ObjectLists.singleton(topRight(text)); + } + + public static List<SlotText> bottomLeftList(Text text) { + return ObjectLists.singleton(bottomLeft(text)); + } + + public static List<SlotText> bottomRightList(Text text) { + return ObjectLists.singleton(bottomRight(text)); + } } 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 d3941d77..aa9bf939 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<SlotTextAdder> currentScreenAdders = new ArrayList<>(); 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 9bd63adc..f3395def 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 de.hysky.skyblocker.utils.render.gui.AbstractContainerMatcher; 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; } 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 cb8efb0c..bd06acba 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 e43ce783..65807886 100644 --- a/src/main/java/de/hysky/skyblocker/utils/ItemUtils.java +++ b/src/main/java/de/hysky/skyblocker/utils/ItemUtils.java @@ -43,7 +43,7 @@ import java.util.regex.Pattern; import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.literal; -public class ItemUtils { +public final class ItemUtils { public static final String ID = "id"; public static final String UUID = "uuid"; public static final Pattern NOT_DURABILITY = Pattern.compile("[^0-9 /]"); @@ -55,6 +55,8 @@ public class ItemUtils { ComponentChanges.CODEC.optionalFieldOf("components", ComponentChanges.EMPTY).forGetter(ItemStack::getComponentChanges) ).apply(instance, ItemStack::new))); + private ItemUtils() {} + public static LiteralArgumentBuilder<FabricClientCommandSource> 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()))); @@ -198,9 +200,13 @@ public class ItemUtils { 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<String> predicate) { - for (Text line : getLore(item)) { + public static String getLoreLineIf(ItemStack stack, Predicate<String> predicate) { + for (Text line : getLore(stack)) { String string = line.getString(); if (predicate.test(string)) { return string; @@ -210,21 +216,40 @@ public class ItemUtils { 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) { - for (Text line : getLore(item)) { - String string = line.getString(); - Matcher matcher = pattern.matcher(string); - if (matcher.matches()) { + public static Matcher getLoreLineIfMatch(ItemStack stack, Pattern pattern) { + Matcher matcher = pattern.matcher(""); + for (Text line : getLore(stack)) { + if (matcher.reset(line.getString()).matches()) { return matcher; } } - return null; } - public static @NotNull List<Text> getLore(ItemStack item) { - return item.getOrDefault(DataComponentTypes.LORE, LoreComponent.DEFAULT).styledLines(); + /** + * Gets the first line of the lore that matches the specified pattern, using {@link Matcher#find()}. + * @param pattern the pattern to search for + * @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 stack, Pattern pattern) { + Matcher matcher = pattern.matcher(""); + for (Text line : getLore(stack)) { + if (matcher.reset(line.getString()).find()) { + return matcher; + } + } + return null; + } + + public static @NotNull List<Text> getLore(ItemStack stack) { + return stack.getOrDefault(DataComponentTypes.LORE, LoreComponent.DEFAULT).styledLines(); } public static @NotNull PropertyMap propertyMapWithTexture(String textureValue) { 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 708af280..e701e24c 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 81c9ebec..9a9d0907 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 de.hysky.skyblocker.SkyblockerMod; 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 @@ import java.util.regex.Pattern; * 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); } 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 9a1e3072..79cc78f5 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.ReorderHelper; 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 class ContainerSolverManager { UltrasequencerSolver.INSTANCE, new NewYearCakeBagHelper(), NewYearCakesHelper.INSTANCE, - new ChocolateFactorySolver() + new ChocolateFactorySolver(), + new ReorderHelper() }; } |