diff options
author | Kevin <92656833+kevinthegreat1@users.noreply.github.com> | 2023-09-16 12:32:52 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-09-16 12:32:52 -0400 |
commit | 045e5c5c8693b9c71b32672df404c129995ed867 (patch) | |
tree | 4aa5474638053bfce4a0d368bde8f3567a2547ea /src/main/java | |
parent | 113027308dc87ab63e7180182c0dd6be35aac599 (diff) | |
parent | 3881303e47384cc0b619c9172fcef685f29a56ce (diff) | |
download | Skyblocker-045e5c5c8693b9c71b32672df404c129995ed867.tar.gz Skyblocker-045e5c5c8693b9c71b32672df404c129995ed867.tar.bz2 Skyblocker-045e5c5c8693b9c71b32672df404c129995ed867.zip |
Merge pull request #302 from viciscat/compactor_preview
Personal Compactor/Deletor preview
Diffstat (limited to 'src/main/java')
-rw-r--r-- | src/main/java/me/xmrvizzy/skyblocker/config/SkyblockerConfig.java | 1 | ||||
-rw-r--r-- | src/main/java/me/xmrvizzy/skyblocker/mixin/HandledScreenMixin.java | 32 | ||||
-rw-r--r-- | src/main/java/me/xmrvizzy/skyblocker/mixin/accessor/DrawContextInvoker.java | 17 | ||||
-rw-r--r-- | src/main/java/me/xmrvizzy/skyblocker/skyblock/item/BackpackPreview.java (renamed from src/main/java/me/xmrvizzy/skyblocker/skyblock/BackpackPreview.java) | 2 | ||||
-rw-r--r-- | src/main/java/me/xmrvizzy/skyblocker/skyblock/item/CompactorDeletorPreview.java | 92 | ||||
-rw-r--r-- | src/main/java/me/xmrvizzy/skyblocker/skyblock/item/CompactorPreviewTooltipComponent.java | 54 | ||||
-rw-r--r-- | src/main/java/me/xmrvizzy/skyblocker/skyblock/itemlist/ItemRegistry.java | 4 |
7 files changed, 190 insertions, 12 deletions
diff --git a/src/main/java/me/xmrvizzy/skyblocker/config/SkyblockerConfig.java b/src/main/java/me/xmrvizzy/skyblocker/config/SkyblockerConfig.java index d20dd29b..4225c698 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/config/SkyblockerConfig.java +++ b/src/main/java/me/xmrvizzy/skyblocker/config/SkyblockerConfig.java @@ -158,6 +158,7 @@ public class SkyblockerConfig implements ConfigData { public static class General { public boolean acceptReparty = true; public boolean backpackPreviewWithoutShift = false; + public boolean compactorDeletorPreview = true; public boolean hideEmptyTooltips = true; public boolean hideStatusEffectOverlay = false; diff --git a/src/main/java/me/xmrvizzy/skyblocker/mixin/HandledScreenMixin.java b/src/main/java/me/xmrvizzy/skyblocker/mixin/HandledScreenMixin.java index eccd63e6..33532788 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/mixin/HandledScreenMixin.java +++ b/src/main/java/me/xmrvizzy/skyblocker/mixin/HandledScreenMixin.java @@ -2,13 +2,14 @@ package me.xmrvizzy.skyblocker.mixin; import me.xmrvizzy.skyblocker.SkyblockerMod; import me.xmrvizzy.skyblocker.config.SkyblockerConfig; -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.BackpackPreview; +import me.xmrvizzy.skyblocker.skyblock.item.CompactorDeletorPreview; 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; @@ -17,13 +18,10 @@ import net.minecraft.client.gui.screen.ingame.HandledScreen; 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.screen.slot.Slot; import net.minecraft.screen.slot.SlotActionType; import net.minecraft.text.Text; 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 +32,8 @@ 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.Map; +import java.util.regex.Matcher; @Mixin(HandledScreen.class) public abstract class HandledScreenMixin extends Screen { @@ -56,18 +52,31 @@ public abstract class HandledScreenMixin extends Screen { } } - @Inject(at = @At("HEAD"), method = "drawMouseoverTooltip", cancellable = true) + @SuppressWarnings("DataFlowIssue") + // makes intellij be quiet about this.focusedSlot maybe being null. It's already null checked in mixined method. + @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) public void skyblocker$drawMouseOverTooltip(DrawContext context, int x, int y, CallbackInfo ci) { + if (!Utils.isOnSkyblock()) return; + // Hide Empty Tooltips - if (Utils.isOnSkyblock() && SkyblockerConfig.get().general.hideEmptyTooltips && this.focusedSlot != null && focusedSlot.getStack().getName().getString().equals(" ")) { + if (SkyblockerConfig.get().general.hideEmptyTooltips && focusedSlot.getStack().getName().getString().equals(" ")) { ci.cancel(); } // Backpack Preview boolean shiftDown = SkyblockerConfig.get().general.backpackPreviewWithoutShift ^ Screen.hasShiftDown(); - if (this.client != null && this.client.player != null && this.focusedSlot != null && shiftDown && this.getTitle().getString().equals("Storage") && this.focusedSlot.inventory != this.client.player.getInventory() && BackpackPreview.renderPreview(context, this.focusedSlot.getIndex(), x, y)) { + if (shiftDown && getTitle().getString().equals("Storage") && focusedSlot.inventory != client.player.getInventory() && BackpackPreview.renderPreview(context, focusedSlot.getIndex(), x, y)) { ci.cancel(); } + + // Compactor Preview + if (SkyblockerConfig.get().general.compactorDeletorPreview) { + ItemStack stack = focusedSlot.getStack(); + Matcher matcher = CompactorDeletorPreview.NAME.matcher(ItemRegistry.getInternalName(stack)); + if (matcher.matches() && CompactorDeletorPreview.drawPreview(context, stack, matcher.group("type"), matcher.group("size"), x, y)) { + ci.cancel(); + } + } } @Redirect(method = "drawMouseoverTooltip", at = @At(value = "INVOKE", target = "Lnet/minecraft/screen/slot/Slot;getStack()Lnet/minecraft/item/ItemStack;", ordinal = 0)) @@ -80,6 +89,7 @@ public abstract class HandledScreenMixin extends Screen { return skyblocker$experimentSolvers$getStack(slot, stack); } + @Unique private ItemStack skyblocker$experimentSolvers$getStack(Slot slot, ItemStack stack) { ContainerSolver currentSolver = SkyblockerMod.getInstance().containerSolverManager.getCurrentSolver(); 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..f1e5b684 --- /dev/null +++ b/src/main/java/me/xmrvizzy/skyblocker/mixin/accessor/DrawContextInvoker.java @@ -0,0 +1,17 @@ +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 { + + @Invoker + void invokeDrawTooltip(TextRenderer textRenderer, List<TooltipComponent> components, int x, int y, TooltipPositioner positioner); +} diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/BackpackPreview.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/item/BackpackPreview.java index f4615b52..dc8f77cd 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/BackpackPreview.java +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/item/BackpackPreview.java @@ -1,4 +1,4 @@ -package me.xmrvizzy.skyblocker.skyblock; +package me.xmrvizzy.skyblocker.skyblock.item; import com.mojang.blaze3d.systems.RenderSystem; import me.xmrvizzy.skyblocker.SkyblockerMod; diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/item/CompactorDeletorPreview.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/item/CompactorDeletorPreview.java new file mode 100644 index 00000000..7b93fe1e --- /dev/null +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/item/CompactorDeletorPreview.java @@ -0,0 +1,92 @@ +package me.xmrvizzy.skyblocker.skyblock.item; + +import it.unimi.dsi.fastutil.ints.IntIntPair; +import it.unimi.dsi.fastutil.ints.IntObjectPair; +import me.xmrvizzy.skyblocker.mixin.accessor.DrawContextInvoker; +import me.xmrvizzy.skyblocker.skyblock.itemlist.ItemRegistry; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.tooltip.HoveredTooltipPositioner; +import net.minecraft.client.gui.tooltip.TooltipComponent; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NbtCompound; +import net.minecraft.text.Text; +import net.minecraft.util.Formatting; + +import java.util.List; +import java.util.Map; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +public class CompactorDeletorPreview { + /** + * The width and height in slots of the compactor/deletor + */ + private static final Map<String, IntIntPair> DIMENSIONS = Map.of( + "4000", IntIntPair.of(1, 1), + "5000", IntIntPair.of(1, 3), + "6000", IntIntPair.of(1, 7), + "7000", IntIntPair.of(2, 6) + ); + private static final IntIntPair DEFAULT_DIMENSION = IntIntPair.of(1, 6); + public static final Pattern NAME = Pattern.compile("PERSONAL_(?<type>COMPACTOR|DELETOR)_(?<size>\\d+)"); + private static final MinecraftClient client = MinecraftClient.getInstance(); + + public static boolean drawPreview(DrawContext context, ItemStack stack, String type, String size, int x, int y) { + List<Text> tooltips = Screen.getTooltipFromItem(client, stack); + int targetIndex = getTargetIndex(tooltips); + if (targetIndex == -1) return false; + + // Get items in compactor or deletor + NbtCompound nbt = stack.getNbt(); + if (nbt == null || !nbt.contains("ExtraAttributes", 10)) { + return false; + } + NbtCompound extraAttributes = nbt.getCompound("ExtraAttributes"); + // Get the slots and their items from the nbt, which is in the format personal_compact_<slot_number> or personal_deletor_<slot_number> + List<IntObjectPair<ItemStack>> slots = extraAttributes.getKeys().stream().filter(slot -> slot.contains(type.toLowerCase().substring(0, 7))).map(slot -> IntObjectPair.of(Integer.parseInt(slot.substring(17)), ItemRegistry.getItemStack(extraAttributes.getString(slot)))).toList(); + + List<TooltipComponent> components = tooltips.stream().map(Text::asOrderedText).map(TooltipComponent::of).collect(Collectors.toList()); + IntIntPair dimensions = DIMENSIONS.getOrDefault(size, DEFAULT_DIMENSION); + + // If there are no items in compactor or deletor + if (slots.isEmpty()) { + int slotsCount = dimensions.leftInt() * dimensions.rightInt(); + components.add(targetIndex, TooltipComponent.of(Text.literal(slotsCount + (slotsCount == 1 ? " slot" : " slots")).formatted(Formatting.GRAY).asOrderedText())); + + ((DrawContextInvoker) context).invokeDrawTooltip(client.textRenderer, components, x, y, HoveredTooltipPositioner.INSTANCE); + return true; + } + + // Add the preview tooltip component + components.add(targetIndex, new CompactorPreviewTooltipComponent(slots, dimensions)); + + // Render accompanying text + components.add(targetIndex, TooltipComponent.of(Text.literal("Contents:").asOrderedText())); + if (extraAttributes.contains("PERSONAL_DELETOR_ACTIVE")) { + components.add(targetIndex, TooltipComponent.of(Text.literal("Active: ") + .append(extraAttributes.getBoolean("PERSONAL_DELETOR_ACTIVE") ? Text.literal("YES").formatted(Formatting.BOLD).formatted(Formatting.GREEN) : Text.literal("NO").formatted(Formatting.BOLD).formatted(Formatting.RED)).asOrderedText())); + } + ((DrawContextInvoker) context).invokeDrawTooltip(client.textRenderer, components, x, y, HoveredTooltipPositioner.INSTANCE); + return true; + } + + /** + * Finds the target index to insert the preview component, which is the second empty line + */ + private static int getTargetIndex(List<Text> tooltips) { + int targetIndex = -1; + int lineCount = 0; + for (int i = 0; i < tooltips.size(); i++) { + if (tooltips.get(i).getString().isEmpty()) { + lineCount += 1; + } + if (lineCount == 2) { + targetIndex = i; + break; + } + } + return targetIndex; + } +} 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..45e3c635 --- /dev/null +++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/item/CompactorPreviewTooltipComponent.java @@ -0,0 +1,54 @@ +package me.xmrvizzy.skyblocker.skyblock.item; + +import it.unimi.dsi.fastutil.ints.IntIntPair; +import it.unimi.dsi.fastutil.ints.IntObjectPair; +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.item.ItemStack; +import net.minecraft.util.Identifier; + +public class CompactorPreviewTooltipComponent implements TooltipComponent { + private static final Identifier INVENTORY_TEXTURE = new Identifier(SkyblockerMod.NAMESPACE, "textures/gui/inventory_background.png"); + private final Iterable<IntObjectPair<ItemStack>> items; + private final IntIntPair dimensions; + + public CompactorPreviewTooltipComponent(Iterable<IntObjectPair<ItemStack>> items, IntIntPair dimensions) { + this.items = items; + this.dimensions = dimensions; + } + + @Override + public int getHeight() { + return dimensions.leftInt() * 18 + 14; + } + + @Override + public int getWidth(TextRenderer textRenderer) { + return dimensions.rightInt() * 18 + 14; + } + + @Override + public void drawItems(TextRenderer textRenderer, int x, int y, DrawContext context) { + context.drawTexture(INVENTORY_TEXTURE, x, y, 0, 0, 7 + dimensions.rightInt() * 18, 7); + context.drawTexture(INVENTORY_TEXTURE, x + 7 + dimensions.rightInt() * 18, y, 169, 0, 7, 7); + + for (int i = 0; i < dimensions.leftInt(); i++) { + context.drawTexture(INVENTORY_TEXTURE, x, y + 7 + i * 18, 0, 7, 7, 18); + for (int j = 0; j < dimensions.rightInt(); j++) { + context.drawTexture(INVENTORY_TEXTURE, x + 7 + j * 18, y + 7 + i * 18, 7, 7, 18, 18); + } + context.drawTexture(INVENTORY_TEXTURE, x + 7 + dimensions.rightInt() * 18, y + 7 + i * 18, 169, 7, 7, 18); + } + context.drawTexture(INVENTORY_TEXTURE, x, y + 7 + dimensions.leftInt() * 18, 0, 25, 7 + dimensions.rightInt() * 18, 7); + context.drawTexture(INVENTORY_TEXTURE, x + 7 + dimensions.rightInt() * 18, y + 7 + dimensions.leftInt() * 18, 169, 25, 7, 7); + + for (IntObjectPair<ItemStack> entry : items) { + int itemX = x + entry.leftInt() % dimensions.rightInt() * 18 + 8; + int itemY = y + entry.leftInt() / dimensions.rightInt() * 18 + 8; + context.drawItem(entry.right(), itemX, itemY); + context.drawItemInSlot(textRenderer, entry.right(), itemX, itemY); + } + } +} 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); + } } |