Skip to content

Commit

Permalink
Let vanilla try to handle Container interactions before checking for …
Browse files Browse the repository at this point in the history
…item handlers (#1787)
  • Loading branch information
Technici4n authored Jan 4, 2025
1 parent 05084dc commit 3de035b
Show file tree
Hide file tree
Showing 6 changed files with 207 additions and 216 deletions.
32 changes: 25 additions & 7 deletions patches/net/minecraft/world/level/block/CrafterBlock.java.patch
Original file line number Diff line number Diff line change
@@ -1,11 +1,29 @@
--- a/net/minecraft/world/level/block/CrafterBlock.java
+++ b/net/minecraft/world/level/block/CrafterBlock.java
@@ -214,6 +_,8 @@
@@ -194,7 +_,8 @@
ServerLevel p_335887_, BlockPos p_307620_, CrafterBlockEntity p_307387_, ItemStack p_307296_, BlockState p_307501_, RecipeHolder<?> p_335494_
) {
Direction direction = p_307501_.getValue(ORIENTATION).front();
- Container container = HopperBlockEntity.getContainerAt(p_335887_, p_307620_.relative(direction));
+ var containerOrHandler = HopperBlockEntity.getContainerOrHandlerAt(p_335887_, p_307620_.relative(direction), direction.getOpposite());
+ Container container = containerOrHandler.container();
ItemStack itemstack = p_307296_.copy();
if (container != null && (container instanceof CrafterBlockEntity || p_307296_.getCount() > container.getMaxStackSize(p_307296_))) {
while (!itemstack.isEmpty()) {
@@ -206,10 +_,14 @@

itemstack.shrink(1);
}
- } else if (container != null) {
+ } else if (!containerOrHandler.isEmpty()) {
while (!itemstack.isEmpty()) {
int i = itemstack.getCount();
- itemstack = HopperBlockEntity.addItem(p_307387_, container, itemstack, direction.getOpposite());
+ if (container != null) {
+ itemstack = HopperBlockEntity.addItem(p_307387_, container, itemstack, direction.getOpposite());
+ } else {
+ itemstack = net.neoforged.neoforge.items.ItemHandlerHelper.insertItem(containerOrHandler.itemHandler(), itemstack, false);
+ }
if (i == itemstack.getCount()) {
break;
}
}
+ } else {
+ itemstack = net.neoforged.neoforge.items.VanillaInventoryCodeHooks.insertCrafterOutput(p_335887_, p_307620_, p_307387_, itemstack);
}

if (!itemstack.isEmpty()) {
23 changes: 17 additions & 6 deletions patches/net/minecraft/world/level/block/DropperBlock.java.patch
Original file line number Diff line number Diff line change
@@ -1,11 +1,22 @@
--- a/net/minecraft/world/level/block/DropperBlock.java
+++ b/net/minecraft/world/level/block/DropperBlock.java
@@ -56,7 +_,7 @@
p_52944_.levelEvent(1001, p_52945_, 0);
} else {
@@ -58,12 +_,16 @@
ItemStack itemstack = dispenserblockentity.getItem(i);
- if (!itemstack.isEmpty()) {
+ if (!itemstack.isEmpty() && net.neoforged.neoforge.items.VanillaInventoryCodeHooks.dropperInsertHook(p_52944_, p_52945_, dispenserblockentity, i, itemstack)) {
if (!itemstack.isEmpty()) {
Direction direction = p_52944_.getBlockState(p_52945_).getValue(FACING);
Container container = HopperBlockEntity.getContainerAt(p_52944_, p_52945_.relative(direction));
- Container container = HopperBlockEntity.getContainerAt(p_52944_, p_52945_.relative(direction));
+ var containerOrHandler = HopperBlockEntity.getContainerOrHandlerAt(p_52944_, p_52945_.relative(direction), direction.getOpposite());
ItemStack itemstack1;
- if (container == null) {
+ if (containerOrHandler.isEmpty()) {
itemstack1 = DISPENSE_BEHAVIOUR.dispense(blocksource, itemstack);
} else {
- itemstack1 = HopperBlockEntity.addItem(dispenserblockentity, container, itemstack.copyWithCount(1), direction.getOpposite());
+ if (containerOrHandler.container() != null) {
+ itemstack1 = HopperBlockEntity.addItem(dispenserblockentity, containerOrHandler.container(), itemstack.copyWithCount(1), direction.getOpposite());
+ } else {
+ itemstack1 = net.neoforged.neoforge.items.ItemHandlerHelper.insertItem(containerOrHandler.itemHandler(), itemstack.copyWithCount(1), false);
+ }
if (itemstack1.isEmpty()) {
itemstack1 = itemstack.copy();
itemstack1.shrink(1);
Original file line number Diff line number Diff line change
@@ -1,22 +1,88 @@
--- a/net/minecraft/world/level/block/entity/HopperBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/HopperBlockEntity.java
@@ -137,6 +_,7 @@
@@ -137,10 +_,11 @@
}

private static boolean ejectItems(Level p_155563_, BlockPos p_155564_, HopperBlockEntity p_326256_) {
+ if (net.neoforged.neoforge.items.VanillaInventoryCodeHooks.insertHook(p_326256_)) return true;
Container container = getAttachedContainer(p_155563_, p_155564_, p_326256_);
if (container == null) {
- Container container = getAttachedContainer(p_155563_, p_155564_, p_326256_);
- if (container == null) {
+ var containerOrHandler = getContainerOrHandlerAt(p_155563_, p_155564_.relative(p_326256_.facing), p_326256_.facing.getOpposite());
+ if (containerOrHandler.isEmpty()) {
return false;
@@ -214,6 +_,8 @@
- } else {
+ } else if (containerOrHandler.container() != null) {
+ Container container = containerOrHandler.container();
Direction direction = p_326256_.facing.getOpposite();
if (isFullContainer(container, direction)) {
return false;
@@ -164,6 +_,8 @@

return false;
}
+ } else {
+ return net.neoforged.neoforge.items.VanillaInventoryCodeHooks.insertHook(p_326256_, containerOrHandler.itemHandler());
}
}

@@ -214,8 +_,9 @@
public static boolean suckInItems(Level p_155553_, Hopper p_155554_) {
BlockPos blockpos = BlockPos.containing(p_155554_.getLevelX(), p_155554_.getLevelY() + 1.0, p_155554_.getLevelZ());
BlockState blockstate = p_155553_.getBlockState(blockpos);
+ Boolean ret = net.neoforged.neoforge.items.VanillaInventoryCodeHooks.extractHook(p_155553_, p_155554_);
+ if (ret != null) return ret;
Container container = getSourceContainer(p_155553_, p_155554_, blockpos, blockstate);
if (container != null) {
- Container container = getSourceContainer(p_155553_, p_155554_, blockpos, blockstate);
- if (container != null) {
+ var containerOrHandler = getSourceContainerOrHandler(p_155553_, p_155554_, blockpos, blockstate);
+ if (containerOrHandler.container() != null) {
+ Container container = containerOrHandler.container();
Direction direction = Direction.DOWN;

for (int i : getSlots(container, direction)) {
@@ -225,6 +_,8 @@
}

return false;
+ } else if (containerOrHandler.itemHandler() != null) {
+ return net.neoforged.neoforge.items.VanillaInventoryCodeHooks.extractHook(p_155554_, containerOrHandler.itemHandler());
} else {
boolean flag = p_155554_.isGridAligned()
&& blockstate.isCollisionShapeFullBlock(p_155553_, blockpos)
@@ -368,6 +_,8 @@
return p_155590_.getEntitiesOfClass(ItemEntity.class, aabb, EntitySelector.ENTITY_STILL_ALIVE);
}

+ /** @deprecated Use IItemHandler capability instead. To preserve Container-specific interactions, use {@link #getContainerOrHandlerAt} and handle both cases. */
+ @Deprecated
@Nullable
public static Container getContainerAt(Level p_59391_, BlockPos p_59392_) {
return getContainerAt(
@@ -411,6 +_,28 @@
return !list.isEmpty() ? (Container)list.get(p_326325_.random.nextInt(list.size())) : null;
}

+ private static net.neoforged.neoforge.items.ContainerOrHandler getSourceContainerOrHandler(Level p_155597_, Hopper p_155598_, BlockPos p_326315_, BlockState p_326093_) {
+ return getContainerOrHandlerAt(p_155597_, p_326315_, p_326093_, p_155598_.getLevelX(), p_155598_.getLevelY() + 1.0, p_155598_.getLevelZ(), Direction.DOWN);
+ }
+
+ public static net.neoforged.neoforge.items.ContainerOrHandler getContainerOrHandlerAt(Level level, BlockPos pos, @Nullable Direction side) {
+ return getContainerOrHandlerAt(
+ level, pos, level.getBlockState(pos), (double)pos.getX() + 0.5, (double)pos.getY() + 0.5, (double)pos.getZ() + 0.5, side
+ );
+ }
+
+ private static net.neoforged.neoforge.items.ContainerOrHandler getContainerOrHandlerAt(Level level, BlockPos pos, BlockState state, double x, double y, double z, @Nullable Direction side) {
+ Container container = getBlockContainer(level, pos, state);
+ if (container != null) {
+ return new net.neoforged.neoforge.items.ContainerOrHandler(container, null);
+ }
+ var blockItemHandler = level.getCapability(net.neoforged.neoforge.capabilities.Capabilities.ItemHandler.BLOCK, pos, state, null, side);
+ if (blockItemHandler != null) {
+ return new net.neoforged.neoforge.items.ContainerOrHandler(null, blockItemHandler);
+ }
+ return net.neoforged.neoforge.items.VanillaInventoryCodeHooks.getEntityContainerOrHandler(level, x, y, z, side);
+ }
+
private static boolean canMergeItems(ItemStack p_59345_, ItemStack p_59346_) {
return p_59345_.getCount() <= p_59345_.getMaxStackSize() && ItemStack.isSameItemSameComponents(p_59345_, p_59346_);
}
@@ -470,5 +_,9 @@
@Override
protected AbstractContainerMenu createMenu(int p_59312_, Inventory p_59313_) {
Expand Down
25 changes: 25 additions & 0 deletions src/main/java/net/neoforged/neoforge/items/ContainerOrHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Copyright (c) NeoForged and contributors
* SPDX-License-Identifier: LGPL-2.1-only
*/

package net.neoforged.neoforge.items;

import net.minecraft.world.Container;
import org.jetbrains.annotations.Nullable;

public record ContainerOrHandler(
@Nullable Container container,
@Nullable IItemHandler itemHandler) {
public ContainerOrHandler {
if (container != null && itemHandler != null) {
throw new IllegalArgumentException("Cannot have both a container and an item handler.");
}
}

public static final ContainerOrHandler EMPTY = new ContainerOrHandler(null, null);

public boolean isEmpty() {
return container == null && itemHandler == null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ public ItemStack insertItem(int slot, ItemStack stack, boolean simulate) {
// This cooldown is always set to 8 in vanilla with one exception:
// Hopper -> Hopper transfer sets this cooldown to 7 when this hopper
// has not been updated as recently as the one pushing items into it.
// This vanilla behavior is preserved by VanillaInventoryCodeHooks#insertStack,
// the cooldown is set properly by the hopper that is pushing items into this one.
// This vanilla behavior is preserved because we let vanilla handle
// hopper - hopper interactions.
hopper.setCooldown(8);
}
}
Expand Down
Loading

2 comments on commit 3de035b

@azalty
Copy link

@azalty azalty commented on 3de035b Jan 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This crashes my game when launching it

@TelepathicGrunt
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@azalty Please make a fresh new issue report with logs and reproduction steps so we can see what exactly is crashing and if this code is even the true cause

Please sign in to comment.