Add compat for /dank/null
This commit is contained in:
@@ -127,6 +127,10 @@ dependencies {
|
||||
compileOnly "curse.maven:jei-238222:7391682"
|
||||
localRuntime "curse.maven:jade-324717:6155158"
|
||||
localRuntime "curse.maven:jei-238222:7391682"
|
||||
localRuntime "curse.maven:travelers-backpack-321117:7485008"
|
||||
localRuntime "curse.maven:sophisticated-core-618298:7635107"
|
||||
localRuntime "curse.maven:sophisticated-backpacks-422301:7645643"
|
||||
localRuntime "curse.maven:dank-storage-335673:7539725"
|
||||
}
|
||||
|
||||
// This block of code expands all declared replace properties in the specified resource targets.
|
||||
|
||||
@@ -16,8 +16,9 @@ public final class BagAccess {
|
||||
|
||||
for (int slot = 0; slot < inventory.getContainerSize(); slot++) {
|
||||
ItemStack stack = inventory.getItem(slot);
|
||||
if (stack.getItem() instanceof InventoryBag inventoryBag) {
|
||||
bags.add(new BagEntry(slot, stack.copy(), inventoryBag));
|
||||
BagCompat.BagHandler handler = BagCompat.findHandler(stack);
|
||||
if (handler != null) {
|
||||
bags.add(new BagEntry(slot, stack.copy(), handler));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
279
src/main/java/com/trunksbomb/bagtabs/bag/BagCompat.java
Normal file
279
src/main/java/com/trunksbomb/bagtabs/bag/BagCompat.java
Normal file
@@ -0,0 +1,279 @@
|
||||
package com.trunksbomb.bagtabs.bag;
|
||||
|
||||
import com.trunksbomb.bagtabs.menu.BagMenu;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.MenuProvider;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||
import net.minecraft.world.inventory.Slot;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
|
||||
public final class BagCompat {
|
||||
private static final List<BagHandler> HANDLERS = List.of(
|
||||
new NativeBagHandler(),
|
||||
new DankStorageHandler(),
|
||||
new TravelersBackpackHandler(),
|
||||
new SophisticatedBackpacksHandler()
|
||||
);
|
||||
|
||||
private BagCompat() {
|
||||
}
|
||||
|
||||
public static BagHandler findHandler(ItemStack stack) {
|
||||
if (stack.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (BagHandler handler : HANDLERS) {
|
||||
if (handler.supports(stack)) {
|
||||
return handler;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean supportsMenu(AbstractContainerMenu menu) {
|
||||
return getActiveBagSlot(menu) >= 0;
|
||||
}
|
||||
|
||||
public static int getActiveBagSlot(AbstractContainerMenu menu) {
|
||||
if (menu instanceof BagMenu bagMenu) {
|
||||
return bagMenu.getBagSlot();
|
||||
}
|
||||
|
||||
for (BagHandler handler : HANDLERS) {
|
||||
int slot = handler.getActiveBagSlot(menu);
|
||||
if (slot >= 0) {
|
||||
return slot;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public interface BagHandler {
|
||||
boolean supports(ItemStack stack);
|
||||
|
||||
void open(ServerPlayer player, int slot, ItemStack stack);
|
||||
|
||||
default int getActiveBagSlot(AbstractContainerMenu menu) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
private static final class NativeBagHandler implements BagHandler {
|
||||
@Override
|
||||
public boolean supports(ItemStack stack) {
|
||||
return stack.getItem() instanceof InventoryBag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void open(ServerPlayer player, int slot, ItemStack stack) {
|
||||
if (stack.getItem() instanceof InventoryBag inventoryBag) {
|
||||
inventoryBag.openFromInventory(player, slot);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final class TravelersBackpackHandler implements BagHandler {
|
||||
private static final String ITEM_CLASS = "com.tiviacz.travelersbackpack.items.TravelersBackpackItem";
|
||||
private static final String MENU_CLASS = "com.tiviacz.travelersbackpack.inventory.menu.AbstractBackpackMenu";
|
||||
private static final String WRAPPER_CLASS = "com.tiviacz.travelersbackpack.inventory.BackpackWrapper";
|
||||
private static final String CONTAINER_CLASS = "com.tiviacz.travelersbackpack.inventory.BackpackContainer";
|
||||
|
||||
@Override
|
||||
public boolean supports(ItemStack stack) {
|
||||
return isInstance(ITEM_CLASS, stack.getItem());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void open(ServerPlayer player, int slot, ItemStack stack) {
|
||||
invokeStatic(
|
||||
CONTAINER_CLASS,
|
||||
"openBackpack",
|
||||
new Class<?>[] {ServerPlayer.class, ItemStack.class, int.class, int.class},
|
||||
player,
|
||||
stack,
|
||||
1,
|
||||
slot
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getActiveBagSlot(AbstractContainerMenu menu) {
|
||||
if (!isInstance(MENU_CLASS, menu)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
Object wrapper = invoke(menu, "getWrapper");
|
||||
if (wrapper == null || !isInstance(WRAPPER_CLASS, wrapper)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
Object slot = invoke(wrapper, "getBackpackSlotIndex");
|
||||
return slot instanceof Integer integer ? integer : -1;
|
||||
}
|
||||
}
|
||||
|
||||
private static final class DankStorageHandler implements BagHandler {
|
||||
private static final String ITEM_CLASS = "tfar.dankstorage.item.DankItem";
|
||||
private static final String MENU_CLASS = "tfar.dankstorage.menu.DankMenu";
|
||||
|
||||
@Override
|
||||
public boolean supports(ItemStack stack) {
|
||||
return isInstance(ITEM_CLASS, stack.getItem());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void open(ServerPlayer player, int slot, ItemStack stack) {
|
||||
try {
|
||||
Method createProvider = stack.getItem().getClass().getMethod("createProvider", ItemStack.class);
|
||||
Object provider = createProvider.invoke(stack.getItem(), stack);
|
||||
if (provider instanceof MenuProvider menuProvider) {
|
||||
player.openMenu(menuProvider);
|
||||
return;
|
||||
}
|
||||
|
||||
throw new IllegalStateException("Dank Storage did not return a MenuProvider");
|
||||
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException exception) {
|
||||
throw new RuntimeException("Failed to open Dank Storage via compatibility bridge", exception);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getActiveBagSlot(AbstractContainerMenu menu) {
|
||||
if (!isInstance(MENU_CLASS, menu)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
Object bag = invoke(menu, "getBag");
|
||||
if (!(bag instanceof ItemStack bagStack) || bagStack.isEmpty()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return findMatchingPlayerSlot(menu, bagStack);
|
||||
}
|
||||
}
|
||||
|
||||
private static final class SophisticatedBackpacksHandler implements BagHandler {
|
||||
private static final String ITEM_CLASS = "net.p3pp3rf1y.sophisticatedbackpacks.backpack.BackpackItem";
|
||||
private static final String MENU_CLASS = "net.p3pp3rf1y.sophisticatedbackpacks.common.gui.BackpackContainer";
|
||||
private static final String CONTEXT_CLASS = "net.p3pp3rf1y.sophisticatedbackpacks.common.gui.BackpackContext";
|
||||
private static final String PAYLOAD_CLASS = "net.p3pp3rf1y.sophisticatedbackpacks.network.BackpackOpenPayload";
|
||||
|
||||
@Override
|
||||
public boolean supports(ItemStack stack) {
|
||||
return isInstance(ITEM_CLASS, stack.getItem());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void open(ServerPlayer player, int slot, ItemStack stack) {
|
||||
try {
|
||||
Class<?> payloadClass = Class.forName(PAYLOAD_CLASS);
|
||||
Method handlePayload = payloadClass.getMethod(
|
||||
"handlePayload",
|
||||
payloadClass,
|
||||
Class.forName("net.neoforged.neoforge.network.handling.IPayloadContext")
|
||||
);
|
||||
Object payload = payloadClass.getConstructor(int.class).newInstance(slot);
|
||||
handlePayload.invoke(null, payload, new ServerPayloadContext(player));
|
||||
} catch (ReflectiveOperationException exception) {
|
||||
throw new RuntimeException("Failed to open Sophisticated Backpack via compatibility bridge", exception);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getActiveBagSlot(AbstractContainerMenu menu) {
|
||||
if (!isInstance(MENU_CLASS, menu)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
Object context = invoke(menu, "getBackpackContext");
|
||||
if (context == null || !isInstance(CONTEXT_CLASS, context)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
Object slot = invoke(context, "getBackpackSlotIndex");
|
||||
return slot instanceof Integer integer ? integer : -1;
|
||||
}
|
||||
}
|
||||
|
||||
private static int findMatchingPlayerSlot(AbstractContainerMenu menu, ItemStack bagStack) {
|
||||
Inventory playerInventory = findPlayerInventory(menu);
|
||||
if (playerInventory == null) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (Slot slot : menu.slots) {
|
||||
if (slot.container != playerInventory) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ItemStack slotStack = slot.getItem();
|
||||
if (slotStack == bagStack) {
|
||||
return slot.getContainerSlot();
|
||||
}
|
||||
}
|
||||
|
||||
for (Slot slot : menu.slots) {
|
||||
if (slot.container != playerInventory) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ItemStack slotStack = slot.getItem();
|
||||
if (ItemStack.isSameItemSameComponents(slotStack, bagStack)) {
|
||||
return slot.getContainerSlot();
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
private static Inventory findPlayerInventory(AbstractContainerMenu menu) {
|
||||
for (Slot slot : menu.slots) {
|
||||
if (slot.container instanceof Inventory inventory) {
|
||||
return inventory;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
Field inventoryField = menu.getClass().getField("playerInventory");
|
||||
Object inventory = inventoryField.get(menu);
|
||||
return inventory instanceof Inventory playerInventory ? playerInventory : null;
|
||||
} catch (IllegalAccessException | NoSuchFieldException exception) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isInstance(String className, Object instance) {
|
||||
try {
|
||||
return instance != null && Class.forName(className).isInstance(instance);
|
||||
} catch (ClassNotFoundException exception) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static Object invoke(Object target, String methodName) {
|
||||
try {
|
||||
Method method = target.getClass().getMethod(methodName);
|
||||
return method.invoke(target);
|
||||
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException exception) {
|
||||
throw new RuntimeException("Failed to invoke " + methodName + " on " + target.getClass().getName(), exception);
|
||||
}
|
||||
}
|
||||
|
||||
private static void invokeStatic(String className, String methodName, Class<?>[] parameterTypes, Object... args) {
|
||||
try {
|
||||
Class<?> targetClass = Class.forName(className);
|
||||
Method method = targetClass.getMethod(methodName, parameterTypes);
|
||||
method.invoke(null, args);
|
||||
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException | ClassNotFoundException exception) {
|
||||
throw new RuntimeException("Failed to invoke compatibility method " + className + "#" + methodName, exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,5 +2,5 @@ package com.trunksbomb.bagtabs.bag;
|
||||
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
|
||||
public record BagEntry(int slot, ItemStack stack, InventoryBag bag) {
|
||||
public record BagEntry(int slot, ItemStack stack, BagCompat.BagHandler handler) {
|
||||
}
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
package com.trunksbomb.bagtabs.bag;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Supplier;
|
||||
import net.minecraft.network.Connection;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.protocol.Packet;
|
||||
import net.minecraft.network.protocol.PacketFlow;
|
||||
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.server.network.ConfigurationTask;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.neoforged.neoforge.common.extensions.ICommonPacketListener;
|
||||
import net.neoforged.neoforge.network.handling.IPayloadContext;
|
||||
|
||||
public class ServerPayloadContext implements IPayloadContext {
|
||||
private final ServerPlayer player;
|
||||
|
||||
public ServerPayloadContext(ServerPlayer player) {
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICommonPacketListener listener() {
|
||||
return (ICommonPacketListener)this.player.connection;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Player player() {
|
||||
return this.player;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> enqueueWork(Runnable task) {
|
||||
task.run();
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> CompletableFuture<T> enqueueWork(Supplier<T> task) {
|
||||
return CompletableFuture.completedFuture(task.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public PacketFlow flow() {
|
||||
return PacketFlow.SERVERBOUND;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(CustomPacketPayload payload) {
|
||||
throw new UnsupportedOperationException("Nested payload handling is not supported by this compatibility context");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finishCurrentTask(ConfigurationTask.Type type) {
|
||||
throw new UnsupportedOperationException("Configuration tasks are not supported by this compatibility context");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection connection() {
|
||||
return this.player.connection.getConnection();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reply(CustomPacketPayload payload) {
|
||||
this.player.connection.send(payload);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disconnect(Component reason) {
|
||||
this.player.connection.disconnect(reason);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(Packet<?> packet) {
|
||||
throw new UnsupportedOperationException("Packet forwarding is not supported by this compatibility context");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelHandlerContext channelHandlerContext() {
|
||||
return this.player.connection.getConnection().channel().pipeline().lastContext();
|
||||
}
|
||||
}
|
||||
@@ -2,8 +2,10 @@ package com.trunksbomb.bagtabs.client;
|
||||
|
||||
import com.trunksbomb.bagtabs.BagTabs;
|
||||
import com.trunksbomb.bagtabs.bag.BagAccess;
|
||||
import com.trunksbomb.bagtabs.bag.BagCompat;
|
||||
import com.trunksbomb.bagtabs.bag.BagEntry;
|
||||
import com.trunksbomb.bagtabs.item.BagItem;
|
||||
import com.trunksbomb.bagtabs.menu.BagMenu;
|
||||
import com.trunksbomb.bagtabs.network.OpenBagPayload;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import java.util.ArrayList;
|
||||
@@ -11,12 +13,12 @@ import java.util.List;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
|
||||
import net.minecraft.client.gui.screens.inventory.InventoryScreen;
|
||||
import net.minecraft.client.resources.sounds.SimpleSoundInstance;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.sounds.SoundEvents;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.component.DyedItemColor;
|
||||
import net.minecraft.world.inventory.Slot;
|
||||
import net.neoforged.neoforge.client.event.ScreenEvent;
|
||||
import net.neoforged.neoforge.network.PacketDistributor;
|
||||
|
||||
@@ -27,13 +29,13 @@ public final class BagTabOverlay {
|
||||
private static final int TAB_HEIGHT = 22;
|
||||
private static final int TAB_GAP = 0;
|
||||
private static final int TAB_Y_OFFSET = -3;
|
||||
private static final int TAB_X_OFFSET = 7;
|
||||
private static final int TAB_X_OFFSET = -6;
|
||||
|
||||
private BagTabOverlay() {
|
||||
}
|
||||
|
||||
public static void render(ScreenEvent.Render.Post event) {
|
||||
if (!(event.getScreen() instanceof InventoryScreen inventoryScreen)) {
|
||||
if (!(event.getScreen() instanceof AbstractContainerScreen<?> screen) || !supportsTabs(screen)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -42,7 +44,7 @@ public final class BagTabOverlay {
|
||||
return;
|
||||
}
|
||||
|
||||
List<RenderedTab> tabs = getRenderedTabs(inventoryScreen, player);
|
||||
List<RenderedTab> tabs = getRenderedTabs(screen, player);
|
||||
if (tabs.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
@@ -65,7 +67,7 @@ public final class BagTabOverlay {
|
||||
}
|
||||
|
||||
public static void mouseClicked(ScreenEvent.MouseButtonPressed.Pre event) {
|
||||
if (!(event.getScreen() instanceof InventoryScreen inventoryScreen) || event.getButton() != 0) {
|
||||
if (!(event.getScreen() instanceof AbstractContainerScreen<?> screen) || !supportsTabs(screen) || event.getButton() != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -74,7 +76,7 @@ public final class BagTabOverlay {
|
||||
return;
|
||||
}
|
||||
|
||||
for (RenderedTab tab : getRenderedTabs(inventoryScreen, player)) {
|
||||
for (RenderedTab tab : getRenderedTabs(screen, player)) {
|
||||
if (tab.isHovered(event.getMouseX(), event.getMouseY())) {
|
||||
PacketDistributor.sendToServer(new OpenBagPayload(tab.entry().slot()));
|
||||
Minecraft.getInstance().getSoundManager().play(SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK, 1.0F));
|
||||
@@ -87,37 +89,74 @@ public final class BagTabOverlay {
|
||||
private static List<RenderedTab> getRenderedTabs(AbstractContainerScreen<?> screen, Player player) {
|
||||
List<BagEntry> bags = BagAccess.findBags(player);
|
||||
List<RenderedTab> renderedTabs = new ArrayList<>();
|
||||
int x = screen.getGuiLeft() + TAB_X_OFFSET;
|
||||
int activeBagSlot = getActiveBagSlot(screen);
|
||||
int leftBound = getInventoryLeftBound(screen, player);
|
||||
int rightBound = getInventoryRightBound(screen, player);
|
||||
int x = leftBound + TAB_X_OFFSET;
|
||||
int y = screen.getGuiTop() + screen.getYSize() + TAB_Y_OFFSET;
|
||||
int maxX = screen.getGuiLeft() + screen.getXSize() - TAB_WIDTH;
|
||||
int maxX = rightBound - TAB_WIDTH;
|
||||
|
||||
for (BagEntry bag : bags) {
|
||||
if (x > maxX) {
|
||||
break;
|
||||
}
|
||||
|
||||
renderedTabs.add(new RenderedTab(bag, x, y));
|
||||
renderedTabs.add(new RenderedTab(bag, x, y, bag.slot() == activeBagSlot));
|
||||
x += TAB_WIDTH + TAB_GAP;
|
||||
}
|
||||
|
||||
return renderedTabs;
|
||||
}
|
||||
|
||||
private static int getInventoryLeftBound(AbstractContainerScreen<?> screen, Player player) {
|
||||
return screen.getGuiLeft() + getPlayerInventorySlots(screen, player).stream()
|
||||
.mapToInt(slot -> slot.x)
|
||||
.min()
|
||||
.orElse(8);
|
||||
}
|
||||
|
||||
private static int getInventoryRightBound(AbstractContainerScreen<?> screen, Player player) {
|
||||
return screen.getGuiLeft() + getPlayerInventorySlots(screen, player).stream()
|
||||
.mapToInt(slot -> slot.x + 16)
|
||||
.max()
|
||||
.orElse(screen.getXSize() - 8);
|
||||
}
|
||||
|
||||
private static List<Slot> getPlayerInventorySlots(AbstractContainerScreen<?> screen, Player player) {
|
||||
List<Slot> slots = screen.getMenu().slots.stream()
|
||||
.filter(slot -> slot.container == player.getInventory())
|
||||
.toList();
|
||||
return slots.isEmpty() ? screen.getMenu().slots : slots;
|
||||
}
|
||||
|
||||
private static void renderTab(GuiGraphics guiGraphics, RenderedTab tab, int mouseX, int mouseY) {
|
||||
boolean hovered = tab.isHovered(mouseX, mouseY);
|
||||
boolean selected = tab.selected();
|
||||
int color = DyedItemColor.getOrDefault(tab.entry().stack(), BagItem.DEFAULT_COLOR);
|
||||
float red = ((color >> 16) & 0xFF) / 255.0F;
|
||||
float green = ((color >> 8) & 0xFF) / 255.0F;
|
||||
float blue = (color & 0xFF) / 255.0F;
|
||||
int uOffset = hovered ? TAB_WIDTH : 0;
|
||||
int uOffset = (hovered || selected) ? TAB_WIDTH : 0;
|
||||
|
||||
RenderSystem.setShaderColor(red, green, blue, 1.0F);
|
||||
guiGraphics.blit(TAB_BASE_TEXTURE, tab.x(), tab.y(), uOffset, 0, TAB_WIDTH, TAB_HEIGHT, TAB_WIDTH * 2, TAB_HEIGHT);
|
||||
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
guiGraphics.blit(TAB_OVERLAY_TEXTURE, tab.x(), tab.y(), uOffset, 0, TAB_WIDTH, TAB_HEIGHT, TAB_WIDTH * 2, TAB_HEIGHT);
|
||||
|
||||
if (selected) {
|
||||
guiGraphics.fill(tab.x() + 2, tab.y() + 2, tab.x() + TAB_WIDTH - 2, tab.y() + 4, 0x90FFFFFF);
|
||||
}
|
||||
}
|
||||
|
||||
private record RenderedTab(BagEntry entry, int x, int y) {
|
||||
private static boolean supportsTabs(AbstractContainerScreen<?> screen) {
|
||||
return screen instanceof net.minecraft.client.gui.screens.inventory.InventoryScreen || BagCompat.supportsMenu(screen.getMenu());
|
||||
}
|
||||
|
||||
private static int getActiveBagSlot(AbstractContainerScreen<?> screen) {
|
||||
return BagCompat.getActiveBagSlot(screen.getMenu());
|
||||
}
|
||||
|
||||
private record RenderedTab(BagEntry entry, int x, int y, boolean selected) {
|
||||
private boolean isHovered(double mouseX, double mouseY) {
|
||||
return mouseX >= this.x && mouseX < this.x + TAB_WIDTH && mouseY >= this.y && mouseY < this.y + TAB_HEIGHT;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.trunksbomb.bagtabs.network;
|
||||
|
||||
import com.trunksbomb.bagtabs.BagTabs;
|
||||
import com.trunksbomb.bagtabs.bag.BagCompat;
|
||||
import com.trunksbomb.bagtabs.bag.InventoryBag;
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
import net.minecraft.network.codec.ByteBufCodecs;
|
||||
@@ -33,8 +34,9 @@ public record OpenBagPayload(int slot) implements CustomPacketPayload {
|
||||
}
|
||||
|
||||
ItemStack stack = serverPlayer.getInventory().getItem(payload.slot());
|
||||
if (stack.getItem() instanceof InventoryBag inventoryBag) {
|
||||
inventoryBag.openFromInventory(serverPlayer, payload.slot());
|
||||
BagCompat.BagHandler handler = BagCompat.findHandler(stack);
|
||||
if (handler != null) {
|
||||
handler.open(serverPlayer, payload.slot(), stack);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user