diff options
Diffstat (limited to 'src')
5 files changed, 192 insertions, 8 deletions
diff --git a/src/main/java/me/xmrvizzy/skyblocker/mixin/HandledScreenMixin.java b/src/main/java/me/xmrvizzy/skyblocker/mixin/HandledScreenMixin.java index eccd63e6..4959f856 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/mixin/HandledScreenMixin.java +++ b/src/main/java/me/xmrvizzy/skyblocker/mixin/HandledScreenMixin.java @@ -2,28 +2,33 @@ package me.xmrvizzy.skyblocker.mixin; import me.xmrvizzy.skyblocker.SkyblockerMod; import me.xmrvizzy.skyblocker.config.SkyblockerConfig; +import me.xmrvizzy.skyblocker.mixin.accessor.DrawContextInvoker; import me.xmrvizzy.skyblocker.skyblock.BackpackPreview; -import me.xmrvizzy.skyblocker.skyblock.dungeon.DungeonChestProfit; import me.xmrvizzy.skyblocker.skyblock.experiment.ChronomatronSolver; import me.xmrvizzy.skyblocker.skyblock.experiment.ExperimentSolver; import me.xmrvizzy.skyblocker.skyblock.experiment.SuperpairsSolver; import me.xmrvizzy.skyblocker.skyblock.experiment.UltrasequencerSolver; +import me.xmrvizzy.skyblocker.skyblock.item.CompactorPreviewTooltipComponent; import me.xmrvizzy.skyblocker.skyblock.item.WikiLookup; +import me.xmrvizzy.skyblocker.skyblock.itemlist.ItemRegistry; import me.xmrvizzy.skyblocker.utils.Utils; import me.xmrvizzy.skyblocker.utils.render.gui.ContainerSolver; 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.tooltip.HoveredTooltipPositioner; +import net.minecraft.client.gui.tooltip.TooltipComponent; import net.minecraft.inventory.SimpleInventory; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.screen.GenericContainerScreenHandler; -import net.minecraft.screen.ScreenHandlerType; +import net.minecraft.nbt.NbtCompound; import net.minecraft.screen.slot.Slot; import net.minecraft.screen.slot.SlotActionType; +import net.minecraft.text.MutableText; +import net.minecraft.text.Style; import net.minecraft.text.Text; +import net.minecraft.util.Formatting; import org.jetbrains.annotations.Nullable; -import org.objectweb.asm.Opcodes; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Unique; @@ -34,10 +39,10 @@ import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import com.llamalad7.mixinextras.injector.wrapoperation.Operation; -import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; - +import java.util.HashMap; +import java.util.List; import java.util.Map; +import java.util.Set; @Mixin(HandledScreen.class) public abstract class HandledScreenMixin extends Screen { @@ -45,6 +50,17 @@ public abstract class HandledScreenMixin extends Screen { @Nullable protected Slot focusedSlot; + @Unique + private static final Map<String, int[]> personalCompactorTypeToSlot = new HashMap<>(); + // Lines, and slots per lines + static { + personalCompactorTypeToSlot.put("4000", new int[]{1,1}); + personalCompactorTypeToSlot.put("5000", new int[]{1,3}); + personalCompactorTypeToSlot.put("6000", new int[]{1,7}); + personalCompactorTypeToSlot.put("7000", new int[]{2,6}); + personalCompactorTypeToSlot.put("default", new int[]{1,6}); + } + protected HandledScreenMixin(Text title) { super(title); } @@ -80,6 +96,81 @@ public abstract class HandledScreenMixin extends Screen { return skyblocker$experimentSolvers$getStack(slot, stack); } + @Inject(method = "drawMouseoverTooltip", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;drawTooltip(Lnet/minecraft/client/font/TextRenderer;Ljava/util/List;Ljava/util/Optional;II)V"), cancellable = true) + private void skyblocker$addTooltipComponent(DrawContext context, int x, int y, CallbackInfo ci) { + if (this.focusedSlot == null || this.client == null) return; + ItemStack stack = this.focusedSlot.getStack(); + String internalName = ItemRegistry.getInternalName(stack); + // PERSONAL COMPACTOR + if (internalName.contains("PERSONAL_COMPACTOR_") || internalName.contains("PERSONAL_DELETOR_")) { + String prefix; + String itemSlotPrefix; + if (internalName.contains("PERSONAL_COMPACTOR_")) { + prefix = "PERSONAL_COMPACTOR_"; + itemSlotPrefix = "personal_compact_"; + } else { + prefix = "PERSONAL_DELETOR_"; + itemSlotPrefix = "personal_deletor_"; + } + + // Find the line to insert component + int targetIndex = -1; + int lineCount = 0; + List<Text> tooltips = Screen.getTooltipFromItem(this.client, stack); + for (int i = 0; i < tooltips.size(); i++) { + if (tooltips.get(i).getString().isEmpty()) { + lineCount += 1; + } + if (lineCount == 2) { + targetIndex = i; + break; + } + } + if (targetIndex == -1) return; + List<TooltipComponent> components = new java.util.ArrayList<>(tooltips.stream().map(Text::asOrderedText).map(TooltipComponent::of).toList()); + + // STUFF + String internalID = ItemRegistry.getInternalName(stack); + String compactorType = internalID.replaceFirst(prefix, ""); + int[] dimensions = personalCompactorTypeToSlot.containsKey(compactorType) ? personalCompactorTypeToSlot.get(compactorType) : personalCompactorTypeToSlot.get("default"); + + NbtCompound nbt = stack.getNbt(); + if (nbt == null || !nbt.contains("ExtraAttributes", 10)) { + return; + } + NbtCompound extraAttributes = nbt.getCompound("ExtraAttributes"); + Set<String> attributesKeys = extraAttributes.getKeys(); + List<String> compactorItems = attributesKeys.stream().filter(s -> s.contains(itemSlotPrefix)).toList(); + Map<Integer, ItemStack> slotAndItem = new HashMap<>(); + + compactorItems.forEach(s -> slotAndItem.put(getNumberAtEnd(s, itemSlotPrefix), ItemRegistry.getItemStack(extraAttributes.getString(s)))); + + + components.add(targetIndex, new CompactorPreviewTooltipComponent(slotAndItem, dimensions)); + components.add(targetIndex, TooltipComponent.of(Text.literal(" ").append( + Text.literal("Contents:").fillStyle(Style.EMPTY + .withItalic(true))) + .asOrderedText())); + if (attributesKeys.stream().anyMatch(s -> s.contains("PERSONAL_DELETOR_ACTIVE"))) { + MutableText isActiveText = Text.literal("Active: "); + if (extraAttributes.getBoolean("PERSONAL_DELETOR_ACTIVE")) { + components.add(targetIndex, TooltipComponent.of(isActiveText.append( + Text.literal("YES").fillStyle(Style.EMPTY.withBold(true).withColor(Formatting.GREEN)) + ).asOrderedText() + )); + } else { + components.add(targetIndex, TooltipComponent.of(isActiveText.append( + Text.literal("NO").fillStyle(Style.EMPTY.withBold(true).withColor(Formatting.RED)) + ).asOrderedText() + )); + } + } + ((DrawContextInvoker) context).invokeDrawTooltip(textRenderer, components, x, y, HoveredTooltipPositioner.INSTANCE); + ci.cancel(); + + } + } + @Unique private ItemStack skyblocker$experimentSolvers$getStack(Slot slot, ItemStack stack) { ContainerSolver currentSolver = SkyblockerMod.getInstance().containerSolverManager.getCurrentSolver(); @@ -110,4 +201,14 @@ public abstract class HandledScreenMixin extends Screen { } } } + + @Unique + private static Integer getNumberAtEnd(String str, String attributesKey) { + try { + String numberPartOfTheString = str.replace(attributesKey, ""); + return Integer.parseInt(numberPartOfTheString); + } catch (NumberFormatException e) { + return 0; + } + } } diff --git a/src/main/java/me/xmrvizzy/skyblocker/mixin/accessor/DrawContextInvoker.java b/src/main/java/me/xmrvizzy/skyblocker/mixin/accessor/DrawContextInvoker.java new file mode 100644 index 00000000..55ef0774 --- /dev/null +++ b/src/main/java/me/xmrvizzy/skyblocker/mixin/accessor/DrawContextInvoker.java @@ -0,0 +1,18 @@ +package me.xmrvizzy.skyblocker.mixin.accessor; + +import net.minecraft.client.font.TextRenderer; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.tooltip.TooltipComponent; +import net.minecraft.client.gui.tooltip.TooltipPositioner; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; + +import java.util.List; + +@Mixin(DrawContext.class) +public interface DrawContextInvoker { + + @SuppressWarnings("unused") + @Invoker("drawTooltip") + void invokeDrawTooltip(TextRenderer textRenderer, List<TooltipComponent> components, int x, int y, TooltipPositioner positioner); +} diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/item/CompactorPreviewTooltipComponent.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/item/CompactorPreviewTooltipComponent.java new file mode 100644 index 00000000..e916a94b --- /dev/null +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/item/CompactorPreviewTooltipComponent.java @@ -0,0 +1,60 @@ +package me.xmrvizzy.skyblocker.skyblock.item; + +import me.xmrvizzy.skyblocker.SkyblockerMod; +import net.minecraft.client.font.TextRenderer; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.tooltip.TooltipComponent; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.item.ItemStack; +import net.minecraft.util.Identifier; + +import java.util.Map; + +public class CompactorPreviewTooltipComponent implements TooltipComponent { + + private static final Identifier INVENTORY_TEXTURE = new Identifier(SkyblockerMod.NAMESPACE, "textures/gui/inventory_background.png"); + + Map<Integer, ItemStack> items; + int[] dimensions; + + public CompactorPreviewTooltipComponent(Map<Integer, ItemStack> items, int[] dimensions) { + this.items = items; + this.dimensions = dimensions; + } + @Override + public int getHeight() { + return dimensions[0] * 18 + 14; + } + + @Override + public int getWidth(TextRenderer textRenderer) { + return dimensions[1] * 18 + 14; + } + + @Override + public void drawItems(TextRenderer textRenderer, int x, int y, DrawContext context) { + context.drawTexture(INVENTORY_TEXTURE, x, y, 0, 0, 7 + dimensions[1] * 18, 7); + context.drawTexture(INVENTORY_TEXTURE, x + 7 + dimensions[1] * 18, y, 169, 0, 7, 7); + + for (int i = 0; i < dimensions[0]; i++) { + context.drawTexture(INVENTORY_TEXTURE, x, y + 7 + i * 18, 0, 7, 7, 18); + for (int j = 0; j < dimensions[1]; j++) { + context.drawTexture(INVENTORY_TEXTURE, x + 7 + j * 18, y + 7 + i * 18, 7, 7, 18, 18); + } + context.drawTexture(INVENTORY_TEXTURE, x + 7 + dimensions[1] * 18, y + 7 + i * 18, 169, 7, 7, 18); + } + context.drawTexture(INVENTORY_TEXTURE, x, y + 7 + dimensions[0] * 18, 0, 25, 7 + dimensions[1] * 18, 7); + context.drawTexture(INVENTORY_TEXTURE, x + 7 + dimensions[1] * 18, y + 7 + dimensions[0] * 18, 169, 25, 7, 7); + + MatrixStack matrices = context.getMatrices(); + for (Integer i : items.keySet()) { + int itemX = x + i % dimensions[1] * 18 + 8; + int itemY = y + i / dimensions[1] * 18 + 8; + matrices.push(); + matrices.translate(0, 0, 200); + context.drawItem(items.get(i), itemX, itemY); + context.drawItemInSlot(textRenderer, items.get(i), itemX, itemY); + matrices.pop(); + } + } +} diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/itemlist/ItemRegistry.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/itemlist/ItemRegistry.java index a4b566e8..426e807b 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/itemlist/ItemRegistry.java +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/itemlist/ItemRegistry.java @@ -124,5 +124,9 @@ public class ItemRegistry { if (itemStack.getNbt() == null) return ""; return itemStack.getNbt().getCompound("ExtraAttributes").getString("id"); } + + public static ItemStack getItemStack(String internalName) { + return itemsMap.get(internalName); + } } diff --git a/src/main/resources/skyblocker.mixins.json b/src/main/resources/skyblocker.mixins.json index 9d2ce7c2..d257d989 100644 --- a/src/main/resources/skyblocker.mixins.json +++ b/src/main/resources/skyblocker.mixins.json @@ -29,7 +29,8 @@ "accessor.PlayerListHudAccessor", "accessor.RecipeBookWidgetAccessor", "accessor.ScreenAccessor", - "accessor.WorldRendererAccessor" + "accessor.WorldRendererAccessor", + "accessor.DrawContextInvoker" ], "injectors": { "defaultRequire": 1 |