From 2b0c0f25b9e9ca690bb334479f798794fec6dd38 Mon Sep 17 00:00:00 2001 From: Chris Xiong Date: Tue, 14 May 2024 21:36:14 -0400 Subject: Combinable Slots: New module. --- src/main/java/org/chrisoft/trashyaddon/Addon.java | 1 + .../trashyaddon/mixin/HandledScreenMixin.java | 28 +++++++ .../chrisoft/trashyaddon/modules/AutoTrade.java | 1 - .../trashyaddon/modules/MatchedItemHighlight.java | 97 ++++++++++++++++++++++ src/main/resources/addon.mixins.json | 3 +- 5 files changed, 128 insertions(+), 2 deletions(-) create mode 100644 src/main/java/org/chrisoft/trashyaddon/mixin/HandledScreenMixin.java create mode 100644 src/main/java/org/chrisoft/trashyaddon/modules/MatchedItemHighlight.java diff --git a/src/main/java/org/chrisoft/trashyaddon/Addon.java b/src/main/java/org/chrisoft/trashyaddon/Addon.java index eb197ff..00f0869 100644 --- a/src/main/java/org/chrisoft/trashyaddon/Addon.java +++ b/src/main/java/org/chrisoft/trashyaddon/Addon.java @@ -19,6 +19,7 @@ public class Addon extends MeteorAddon { // Modules Modules.get().add(new AutoTrade()); + Modules.get().add(new MatchedItemHighlight()); // Commands Commands.add(new EntityDataCommand()); diff --git a/src/main/java/org/chrisoft/trashyaddon/mixin/HandledScreenMixin.java b/src/main/java/org/chrisoft/trashyaddon/mixin/HandledScreenMixin.java new file mode 100644 index 0000000..9a351da --- /dev/null +++ b/src/main/java/org/chrisoft/trashyaddon/mixin/HandledScreenMixin.java @@ -0,0 +1,28 @@ +package org.chrisoft.trashyaddon.mixin; + +import meteordevelopment.meteorclient.systems.modules.Modules; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.screen.ingame.HandledScreen; +import net.minecraft.client.gui.screen.ingame.ScreenHandlerProvider; +import net.minecraft.screen.ScreenHandler; +import net.minecraft.screen.slot.Slot; +import net.minecraft.text.Text; +import org.chrisoft.trashyaddon.modules.MatchedItemHighlight; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(HandledScreen.class) +public abstract class HandledScreenMixin extends Screen implements ScreenHandlerProvider { + public HandledScreenMixin(Text title) { + super(title); + } + + @Inject(method = "drawSlot", at = @At("HEAD")) + private void onDrawSlot(DrawContext context, Slot slot, CallbackInfo ci) { + int color = Modules.get().get(MatchedItemHighlight.class).getSlotColor(slot.id).getPacked(); + if (color != 0) context.fill(slot.x, slot.y, slot.x + 16, slot.y + 16, color); + } +} diff --git a/src/main/java/org/chrisoft/trashyaddon/modules/AutoTrade.java b/src/main/java/org/chrisoft/trashyaddon/modules/AutoTrade.java index 0b71598..dfb343d 100644 --- a/src/main/java/org/chrisoft/trashyaddon/modules/AutoTrade.java +++ b/src/main/java/org/chrisoft/trashyaddon/modules/AutoTrade.java @@ -15,7 +15,6 @@ import net.minecraft.item.ItemStack; import net.minecraft.item.Items; import net.minecraft.network.packet.s2c.play.ScreenHandlerSlotUpdateS2CPacket; import net.minecraft.network.packet.s2c.play.SetTradeOffersS2CPacket; -import net.minecraft.screen.MerchantScreenHandler; import net.minecraft.village.TradeOffer; import net.minecraft.village.TradeOfferList; import org.chrisoft.trashyaddon.mixin.MerchantScreenAccessor; diff --git a/src/main/java/org/chrisoft/trashyaddon/modules/MatchedItemHighlight.java b/src/main/java/org/chrisoft/trashyaddon/modules/MatchedItemHighlight.java new file mode 100644 index 0000000..41910c7 --- /dev/null +++ b/src/main/java/org/chrisoft/trashyaddon/modules/MatchedItemHighlight.java @@ -0,0 +1,97 @@ +package org.chrisoft.trashyaddon.modules; + +import meteordevelopment.meteorclient.events.packets.InventoryEvent; +import meteordevelopment.meteorclient.events.packets.PacketEvent; +import meteordevelopment.meteorclient.systems.modules.Module; +import meteordevelopment.meteorclient.systems.modules.Categories; +import meteordevelopment.meteorclient.utils.render.color.Color; +import meteordevelopment.orbit.EventHandler; +import net.minecraft.item.ItemStack; +import net.minecraft.network.packet.c2s.play.CloseHandledScreenC2SPacket; +import net.minecraft.network.packet.s2c.play.CloseScreenS2CPacket; +import net.minecraft.network.packet.s2c.play.ScreenHandlerSlotUpdateS2CPacket; +import net.minecraft.screen.PlayerScreenHandler; +import net.minecraft.screen.ScreenHandler; + +import java.util.ArrayList; + +public class MatchedItemHighlight extends Module { + private ScreenHandler screenHandler; + private final ArrayList slotColors; + private static final Color transparent = new Color(0, 0, 0, 0); + public MatchedItemHighlight() { + super(Categories.Render, "Combinable Slots", "Highlight items that can be combined in your inventory and a container."); + slotColors = new ArrayList<>(); + } + + public void onActivate() { screenHandler = null; } + + public Color getSlotColor(int index) { + if (!this.isActive() || index >= slotColors.size()) + return transparent; + return slotColors.get(index); + } + + private void updateColors() { + if (screenHandler == null) + return; + slotColors.clear(); + for (int i = 0 ; i < screenHandler.slots.size(); ++i) + slotColors.add(new Color(transparent)); + int firstInventorySlot = screenHandler.slots.size() - 36; + if (firstInventorySlot <= 0) + return; + int colorIndex = 0; + for (int i = 0; i < firstInventorySlot; ++ i) { + if (screenHandler.getSlot(i).getStack().isEmpty()) + continue; + for (int j = firstInventorySlot; j < screenHandler.slots.size(); ++ j) { + if (screenHandler.getSlot(j).getStack().isEmpty()) + continue; + if (ItemStack.canCombine(screenHandler.getSlot(i).getStack(), screenHandler.getSlot(j).getStack()) || + ItemStack.canCombine(screenHandler.getSlot(j).getStack(), screenHandler.getSlot(i).getStack())) { + Color c; + if (!slotColors.get(i).equals(transparent)) + c = new Color(slotColors.get(i)); + else if (!slotColors.get(j).equals(transparent)) + c = new Color(slotColors.get(j)); + else { + c = Color.fromHsv(colorIndex * 45, 0.6, 1.).a(160); + ++ colorIndex; + if (colorIndex > 7) colorIndex = 0; + } + slotColors.set(i, new Color(c)); + slotColors.set(j, new Color(c)); + } + } + } + } + + @EventHandler + private void onInventory(InventoryEvent event) { + if (mc.player.currentScreenHandler instanceof PlayerScreenHandler) + return; + screenHandler = mc.player.currentScreenHandler; + if (screenHandler != null && event.packet.getSyncId() == screenHandler.syncId) + updateColors(); + } + + @EventHandler + private void onReceivePacket(PacketEvent.Receive e) { + if (e.packet instanceof ScreenHandlerSlotUpdateS2CPacket p) { + if (screenHandler != null && p.getSyncId() == screenHandler.syncId) + updateColors(); + } else if (e.packet instanceof CloseScreenS2CPacket) { + screenHandler = null; + slotColors.clear(); + } + } + + @EventHandler + private void onSendPacket(PacketEvent.Send e) { + if (e.packet instanceof CloseHandledScreenC2SPacket p) { + screenHandler = null; + slotColors.clear(); + } + } +} diff --git a/src/main/resources/addon.mixins.json b/src/main/resources/addon.mixins.json index 9ddc8ba..fa5b1a5 100644 --- a/src/main/resources/addon.mixins.json +++ b/src/main/resources/addon.mixins.json @@ -3,7 +3,8 @@ "package": "org.chrisoft.trashyaddon.mixin", "compatibilityLevel": "JAVA_17", "client": [ - "MerchantScreenAccessor" + "MerchantScreenAccessor", + "HandledScreenMixin" ], "injectors": { "defaultRequire": 1 -- cgit v1.2.3