- Версия(и) Minecraft
- 1.14+
Хочу поделиться своим вариантом создания предмета с инвентарём.
Этот вариант создания таких предметов я не видел ещё нигде, по крайней мере, не нашёл на просторах GitHub. Этот вариант использует напрямую
ВНИМАНИЕ!
Не спешить добавлять этот код в свой проект, так как в этом коде нету необходимых проверок для исправления некоторых багов и недоработок.
Этот вариант создания таких предметов я не видел ещё нигде, по крайней мере, не нашёл на просторах GitHub. Этот вариант использует напрямую
IItemHandler
, вместо создания нового экземляра IInventory
.ВНИМАНИЕ!
Не спешить добавлять этот код в свой проект, так как в этом коде нету необходимых проверок для исправления некоторых багов и недоработок.
BackpackItem.class:
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:
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:
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:
@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));
}