|
|
|
|
@@ -2,13 +2,27 @@ 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.core.component.DataComponents;
|
|
|
|
|
import net.minecraft.network.RegistryFriendlyByteBuf;
|
|
|
|
|
import net.minecraft.network.codec.ByteBufCodecs;
|
|
|
|
|
import net.minecraft.network.codec.StreamCodec;
|
|
|
|
|
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
|
|
|
|
|
import net.minecraft.network.protocol.game.ClientboundSetCarriedItemPacket;
|
|
|
|
|
import net.minecraft.server.level.ServerPlayer;
|
|
|
|
|
import net.minecraft.world.InteractionHand;
|
|
|
|
|
import net.minecraft.world.InteractionResult;
|
|
|
|
|
import net.minecraft.world.entity.player.Inventory;
|
|
|
|
|
import net.minecraft.world.item.ItemStack;
|
|
|
|
|
import net.minecraft.world.item.BlockItem;
|
|
|
|
|
import net.minecraft.world.item.BowItem;
|
|
|
|
|
import net.minecraft.world.item.CrossbowItem;
|
|
|
|
|
import net.minecraft.world.item.DiggerItem;
|
|
|
|
|
import net.minecraft.world.item.Item;
|
|
|
|
|
import net.minecraft.world.item.ProjectileWeaponItem;
|
|
|
|
|
import net.minecraft.world.item.ShearsItem;
|
|
|
|
|
import net.minecraft.world.item.ShieldItem;
|
|
|
|
|
import net.minecraft.world.item.SwordItem;
|
|
|
|
|
import net.minecraft.world.item.TridentItem;
|
|
|
|
|
import net.neoforged.neoforge.network.handling.IPayloadContext;
|
|
|
|
|
|
|
|
|
|
public record OpenBagPayload(int slot) implements CustomPacketPayload {
|
|
|
|
|
@@ -37,6 +51,99 @@ public record OpenBagPayload(int slot) implements CustomPacketPayload {
|
|
|
|
|
BagCompat.BagHandler handler = BagCompat.findHandler(stack);
|
|
|
|
|
if (handler != null) {
|
|
|
|
|
handler.open(serverPlayer, payload.slot(), stack);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (BagCompat.canShowInTabs(stack)) {
|
|
|
|
|
if (!openViaHotbarFallback(serverPlayer, payload.slot())) {
|
|
|
|
|
serverPlayer.sendSystemMessage(BagTabs.translation("generic_open_failed"));
|
|
|
|
|
BagTabs.LOGGER.debug("Failed to open bag fallback for item {} in slot {}", stack, payload.slot());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static boolean openViaHotbarFallback(ServerPlayer player, int sourceSlot) {
|
|
|
|
|
Inventory inventory = player.getInventory();
|
|
|
|
|
ItemStack sourceStack = inventory.getItem(sourceSlot);
|
|
|
|
|
if (sourceStack.isEmpty()) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int targetHotbarSlot = chooseHotbarSlot(inventory, sourceSlot);
|
|
|
|
|
if (targetHotbarSlot < 0) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (sourceSlot != targetHotbarSlot) {
|
|
|
|
|
ItemStack hotbarStack = inventory.getItem(targetHotbarSlot).copy();
|
|
|
|
|
inventory.setItem(targetHotbarSlot, sourceStack.copy());
|
|
|
|
|
inventory.setItem(sourceSlot, hotbarStack);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inventory.selected = targetHotbarSlot;
|
|
|
|
|
player.connection.send(new ClientboundSetCarriedItemPacket(targetHotbarSlot));
|
|
|
|
|
player.inventoryMenu.broadcastChanges();
|
|
|
|
|
|
|
|
|
|
ItemStack mainHandStack = player.getItemInHand(InteractionHand.MAIN_HAND);
|
|
|
|
|
if (mainHandStack.isEmpty()) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int previousContainerId = player.containerMenu.containerId;
|
|
|
|
|
InteractionResult result = player.gameMode.useItem(player, player.level(), mainHandStack, InteractionHand.MAIN_HAND);
|
|
|
|
|
player.inventoryMenu.broadcastChanges();
|
|
|
|
|
return result.consumesAction() || player.containerMenu.containerId != previousContainerId;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static int chooseHotbarSlot(Inventory inventory, int sourceSlot) {
|
|
|
|
|
if (sourceSlot >= 0 && sourceSlot < Inventory.getSelectionSize()) {
|
|
|
|
|
return sourceSlot;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (int hotbarSlot = 0; hotbarSlot < Inventory.getSelectionSize(); hotbarSlot++) {
|
|
|
|
|
if (inventory.getItem(hotbarSlot).isEmpty()) {
|
|
|
|
|
return hotbarSlot;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (int hotbarSlot = 0; hotbarSlot < Inventory.getSelectionSize(); hotbarSlot++) {
|
|
|
|
|
if (isBuildingBlock(inventory.getItem(hotbarSlot))) {
|
|
|
|
|
return hotbarSlot;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (int hotbarSlot = 0; hotbarSlot < Inventory.getSelectionSize(); hotbarSlot++) {
|
|
|
|
|
if (isPreferredMiscItem(inventory.getItem(hotbarSlot))) {
|
|
|
|
|
return hotbarSlot;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static boolean isBuildingBlock(ItemStack stack) {
|
|
|
|
|
return !stack.isEmpty() && stack.getItem() instanceof BlockItem && !isTorch(stack.getItem());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static boolean isPreferredMiscItem(ItemStack stack) {
|
|
|
|
|
if (stack.isEmpty()) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
Item item = stack.getItem();
|
|
|
|
|
return !stack.has(DataComponents.FOOD)
|
|
|
|
|
&& !isTorch(item)
|
|
|
|
|
&& !(item instanceof DiggerItem)
|
|
|
|
|
&& !(item instanceof SwordItem)
|
|
|
|
|
&& !(item instanceof BowItem)
|
|
|
|
|
&& !(item instanceof CrossbowItem)
|
|
|
|
|
&& !(item instanceof TridentItem)
|
|
|
|
|
&& !(item instanceof ShieldItem)
|
|
|
|
|
&& !(item instanceof ShearsItem)
|
|
|
|
|
&& !(item instanceof ProjectileWeaponItem);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static boolean isTorch(Item item) {
|
|
|
|
|
return item instanceof BlockItem blockItem
|
|
|
|
|
&& blockItem.getBlock().getDescriptionId().toLowerCase(java.util.Locale.ROOT).contains("torch");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|