Версия(и) Minecraft
1.14+
Хочу поделиться своим вариантом создания предмета с инвентарём.
Этот вариант создания таких предметов я не видел ещё нигде, по крайней мере, не нашёл на просторах GitHub. Этот вариант использует напрямую IItemHandler, вместо создания нового экземляра IInventory.

ВНИМАНИЕ!
Не спешить добавлять этот код в свой проект, так как в этом коде нету необходимых проверок для исправления некоторых багов и недоработок.

BackpackItem.class:
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.inventory.container.SimpleNamedContainerProvider;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.world.World;
import net.minecraftforge.common.capabilities.ICapabilityProvider;
import net.minecraftforge.items.CapabilityItemHandler;
import net.mymod.inventory.container.BackpackContainer;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

public class BackpackItem extends Item {
    public BackpackItem(Properties properties) {
        super(properties);
    }

    @Nonnull
    @Override
    public ActionResult<ItemStack> onItemRightClick(@Nonnull World world, @Nonnull PlayerEntity player, @Nonnull Hand hand) {
        ItemStack heldStack = player.getHeldItem(hand);

        if (!world.isRemote) {
            heldStack.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY)
                    .ifPresent(itemHandler -> {
                        player.openContainer(new SimpleNamedContainerProvider(
                                (id, playerInv, pl) -> new BackpackContainer(id, playerInv, itemHandler),
                                heldStack.getDisplayName()));
                    });
        }

        return ActionResult.resultSuccess(heldStack);
    }

    @Nullable
    @Override
    public ICapabilityProvider initCapabilities(ItemStack stack, @Nullable CompoundNBT nbt) {
        return new BackpackCapability(stack);
    }
}
BackpackCapability.java:
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.nbt.ListNBT;
import net.minecraft.util.Direction;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.ICapabilityProvider;
import net.minecraftforge.common.util.Constants;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.ItemStackHandler;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

public class BackpackCapability extends ItemStackHandler implements ICapabilityProvider {
    private final LazyOptional<ItemStackHandler> holder = LazyOptional.of(() -> this);
    private final ItemStack stack;

    public BackpackCapability(ItemStack stack) {
        super(27); // размер инвентаря
        this.stack = stack;

        CompoundNBT nbt = stack.getTag();
        if (nbt != null) {
            deserializeNBT(nbt);
        }
    }

    @Override
    protected void onContentsChanged(int slot) {
        CompoundNBT itemsNbt = serializeNBT();
        stack.getOrCreateTag().put("Items", itemsNbt.getList("Items", Constants.NBT.TAG_COMPOUND));
    }

    @Override
    public CompoundNBT serializeNBT() {
        CompoundNBT nbt = new CompoundNBT();
        ItemStackHelper.saveAllItems(nbt, stacks);
        return nbt;
    }

    @Override
    public void deserializeNBT(CompoundNBT nbt) {
        ItemStackHelper.loadAllItems(nbt, stacks);
        onLoad();
    }

    @Nonnull
    @Override
    public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable Direction side) {
        return CapabilityItemHandler.ITEM_HANDLER_CAPABILITY.orEmpty(cap, holder.cast());
    }
}
BackpackContainer.java:
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.Inventory;
import net.minecraft.inventory.container.Container;
import net.minecraft.inventory.container.Slot;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.SlotItemHandler;
import net.mymod.MyMod;

import javax.annotation.Nonnull;

public class BackpackContainer extends Container {

    public BackpackContainer(int id, PlayerInventory playerInv, ISlotCreate slotSupplier) {
        super(MyMod.BACKPACK_CONT.get(), id);

        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 9; j++) {
                addSlot(slotSupplier.createSlot(j + i * 9, 8 + j * 18, 18 + i * 18));
            }
        }

        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 9; j++) {
                addSlot(new Slot(playerInv, j + i * 9 + 9, 8 + j * 18, 103 + i * 18 - 18));
            }
        }

        for(int i = 0; i < 9; i++) {
            addSlot(new Slot(playerInv, i, 8 + i * 18, 161 - 18));
        }
    }

    public BackpackContainer(int id, PlayerInventory playerInv, IItemHandler itemHandler) {
        this(id, playerInv, (index, x, y) -> new SlotItemHandler(itemHandler, index, x, y));
    }

    public static BackpackContainer createClientContainer(int id, PlayerInventory playerInv) {
        Inventory inv = new Inventory(27); // размер инвентаря
        return new BackpackContainer(id, playerInv, (index, x, y) -> new Slot(inv, index, x, y));
    }

    @Override
    public boolean canInteractWith(@Nonnull PlayerEntity player) {
        return true;
    }

    public interface ISlotCreate {
        Slot createSlot(int index, int x, int y);
    }
}
BackpackScreen.java:
import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.gui.screen.inventory.ContainerScreen;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.ITextComponent;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.mymod.inventory.container.BackpackContainer;

import javax.annotation.Nonnull;

@OnlyIn(Dist.CLIENT)
public class BackpackScreen extends ContainerScreen<BackpackContainer> {
    private static final ResourceLocation CHEST_GUI_TEXTURE = new ResourceLocation("textures/gui/container/generic_54.png");

    public BackpackScreen(BackpackContainer container, PlayerInventory inv, ITextComponent title) {
        super(container, inv, title);
        ySize = 168;
        playerInventoryTitleY = this.ySize - 94;
    }

    @Override
    public void render(@Nonnull MatrixStack ms, int mouseX, int mouseY, float partialTicks) {
        renderBackground(ms);
        super.render(ms, mouseX, mouseY, partialTicks);
        renderHoveredTooltip(ms, mouseX, mouseY);
    }

    @Override
    protected void drawGuiContainerBackgroundLayer(@Nonnull MatrixStack ms, float partialTicks, int x, int y) {
        RenderSystem.color4f(1F, 1F, 1F, 1F);
        getMinecraft().getTextureManager().bindTexture(CHEST_GUI_TEXTURE);
        int i = (width - xSize) / 2;
        int j = (height - ySize) / 2;
        blit(ms, i, j, 0, 0, xSize, 3 * 18 + 17);
        blit(ms, i, j + 3 * 18 + 17, 0, 126, xSize, 96);
    }
}
Где-то в главном классе:
private static final DeferredRegister<Item> ITEMS = DeferredRegister.create(ForgeRegistries.ITEMS, MODID);
private static final DeferredRegister<ContainerType<?>> CONTAINERS = DeferredRegister.create(ForgeRegistries.CONTAINERS, MODID);

public static final RegistryObject<Item> BACKPACK = regItem("backpack", () -> new BackpackItem(new Item.Properties().maxStackSize(1)));

public static final RegistryObject<ContainerType<BackpackContainer>> BACKPACK_CONT = regCont("backpack", BackpackContainer::createClientContainer);

@OnlyIn(Dist.CLIENT)
public static void onClientSetup(FMLClientSetupEvent event) {
    ScreenManager.registerFactory(BACKPACK_CONT.get(), BackpackScreen::new);
}

private static RegistryObject<Item> regItem(String id, Supplier<Item> item) {
    return ITEMS.register(id, item);
}

private static <T extends Container> RegistryObject<ContainerType<T>> regCont(String id, ContainerType.IFactory<T> factory) {
    return CONTAINERS.register(id, () -> new ContainerType<>(factory));
}
Автор
MaximPixel
Просмотры
386
Первый выпуск
Обновление
Оценка
4.00 звёзд 1 оценок

Другие ресурсы пользователя MaximPixel

Сверху