Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ItemHandler for ItemEntity and ItemFrame #1607

Draft
wants to merge 1 commit into
base: 1.21.x
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
import net.neoforged.neoforge.items.wrapper.EntityHandsInvWrapper;
import net.neoforged.neoforge.items.wrapper.ForwardingItemHandler;
import net.neoforged.neoforge.items.wrapper.InvWrapper;
import net.neoforged.neoforge.items.wrapper.ItemEntityWrapper;
import net.neoforged.neoforge.items.wrapper.ItemFrameWrapper;
import net.neoforged.neoforge.items.wrapper.PlayerInvWrapper;
import net.neoforged.neoforge.items.wrapper.SidedInvWrapper;
import org.jetbrains.annotations.ApiStatus;
Expand Down Expand Up @@ -113,6 +115,14 @@ public static void registerVanillaProviders(RegisterCapabilitiesEvent event) {
}
event.registerEntity(Capabilities.ItemHandler.ENTITY, EntityType.PLAYER, (player, ctx) -> new PlayerInvWrapper(player.getInventory()));

for (var entityType : List.of(EntityType.ITEM_FRAME, EntityType.GLOW_ITEM_FRAME)) {
event.registerEntity(Capabilities.ItemHandler.ENTITY, entityType, (frame, ctx) -> new ItemFrameWrapper(frame));
event.registerEntity(Capabilities.ItemHandler.ENTITY_AUTOMATION, entityType, (frame, dir) -> dir == null || dir == frame.getDirection() ? new ItemFrameWrapper(frame) : null);
}

event.registerEntity(Capabilities.ItemHandler.ENTITY, EntityType.ITEM, (item, ctx) -> new ItemEntityWrapper(item));
event.registerEntity(Capabilities.ItemHandler.ENTITY_AUTOMATION, EntityType.ITEM, (item, ctx) -> new ItemEntityWrapper(item));

// Items
event.registerItem(Capabilities.ItemHandler.ITEM, (stack, ctx) -> new ComponentItemHandler(stack, DataComponents.CONTAINER, 27),
Items.SHULKER_BOX,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,9 +126,7 @@ public ItemStack extractItem(int slot, int amount, boolean simulate) {
if (stackInSlot.getCount() < amount) {
return stackInSlot.copy();
} else {
ItemStack copy = stackInSlot.copy();
copy.setCount(amount);
return copy;
return stackInSlot.copyWithCount(amount);
}
} else {
int m = Math.min(stackInSlot.getCount(), amount);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/*
* Copyright (c) Forge Development LLC and contributors SPDX-License-Identifier: LGPL-2.1-only
*/
package net.neoforged.neoforge.items.wrapper;

import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.item.ItemStack;
import net.neoforged.neoforge.items.IItemHandlerModifiable;

public class ItemEntityWrapper implements IItemHandlerModifiable {
protected final ItemEntity itemEntity;

public ItemEntityWrapper(ItemEntity itemEntity) {
this.itemEntity = itemEntity;
}

@Override
public int getSlots() {
return 1;
}

@Override
public ItemStack getStackInSlot(int slot) {
validateSlotIndex(slot);
return itemEntity.getItem();
}

@Override
public ItemStack insertItem(int slot, ItemStack stack, boolean simulate) {
validateSlotIndex(slot);
ItemStack stackInSlot = itemEntity.getItem();
if (!ItemEntity.areMergable(stackInSlot, stack)) {
return stack;
}

int insertableCount = Math.min(stackInSlot.getMaxStackSize() - stackInSlot.getCount(), stack.getCount());
if (!simulate) {
stackInSlot.grow(insertableCount);
itemEntity.setItem(stackInSlot);
}
return stack.getCount() == insertableCount ? ItemStack.EMPTY : stack.copyWithCount(stack.getCount() - insertableCount);
}

@Override
public ItemStack extractItem(int slot, int amount, boolean simulate) {
if (amount == 0) return ItemStack.EMPTY;

validateSlotIndex(slot);
ItemStack stackInSlot = itemEntity.getItem();

if (stackInSlot.isEmpty()) return ItemStack.EMPTY;

if (stackInSlot.getCount() < amount) {
if (!simulate) {
itemEntity.setItem(ItemStack.EMPTY);
itemEntity.discard();
}
return stackInSlot.copy();
} else {
if (simulate)

return stackInSlot.copyWithCount(amount);

ItemStack extracted = stackInSlot.split(amount);
itemEntity.setItem(stackInSlot);
return extracted;
}
}

@Override
public int getSlotLimit(int slot) {
return itemEntity.getItem().getMaxStackSize();
}

@Override
public boolean isItemValid(int slot, ItemStack stack) {
return true;
}

@Override
public void setStackInSlot(int slot, ItemStack stack) {
validateSlotIndex(slot);
itemEntity.setItem(stack);
}

private void validateSlotIndex(int slot) {
if (slot != 0) throw new IllegalArgumentException("Only slot 0 is present - requested: " + slot);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*
* Copyright (c) Forge Development LLC and contributors SPDX-License-Identifier: LGPL-2.1-only
*/
package net.neoforged.neoforge.items.wrapper;

import net.minecraft.world.entity.decoration.ItemFrame;
import net.minecraft.world.item.ItemStack;
import net.neoforged.neoforge.items.IItemHandlerModifiable;

public class ItemFrameWrapper implements IItemHandlerModifiable {
protected final ItemFrame itemFrame;

public ItemFrameWrapper(ItemFrame itemFrame) {
this.itemFrame = itemFrame;
}

@Override
public int getSlots() {
return 1;
}

@Override
public ItemStack getStackInSlot(int slot) {
validateSlotIndex(slot);
return itemFrame.getItem();
}

@Override
public ItemStack insertItem(int slot, ItemStack stack, boolean simulate) {
validateSlotIndex(slot);
if (itemFrame.getItem().isEmpty() && !simulate) {
itemFrame.setItem(stack);
return stack.getCount() == 1 ? ItemStack.EMPTY : stack.copyWithCount(stack.getCount() - 1);
}
// itemFrame has stack of size 1, so nothing to insert
return stack;
}

@Override
public ItemStack extractItem(int slot, int amount, boolean simulate) {
if (amount == 0) return ItemStack.EMPTY;

validateSlotIndex(slot);
ItemStack stackInSlot = itemFrame.getItem();

if (stackInSlot.isEmpty()) return ItemStack.EMPTY;

if (simulate) {
return stackInSlot.copy();
} else {
itemFrame.setItem(ItemStack.EMPTY);
return stackInSlot;
}
}

@Override
public int getSlotLimit(int slot) {
return 1;
}

@Override
public boolean isItemValid(int slot, ItemStack stack) {
return true;
}

@Override
public void setStackInSlot(int slot, ItemStack stack) {
validateSlotIndex(slot);
itemFrame.setItem(stack);
}

private void validateSlotIndex(int slot) {
if (slot != 0) throw new IllegalArgumentException("Only slot 0 is present - requested: " + slot);
}
}
Loading