diff --git a/src/main/java/ca/spottedleaf/moonrise/mixin/explosions/ExplosionMixin.java b/src/main/java/ca/spottedleaf/moonrise/mixin/explosions/ExplosionMixin.java index a9326cb..cc6288c 100644 --- a/src/main/java/ca/spottedleaf/moonrise/mixin/explosions/ExplosionMixin.java +++ b/src/main/java/ca/spottedleaf/moonrise/mixin/explosions/ExplosionMixin.java @@ -350,7 +350,7 @@ public abstract class ExplosionMixin { public void explode() { this.level.gameEvent(this.source, GameEvent.EXPLODE, new Vec3(this.x, this.y, this.z)); - this.blockCache = new it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap<>(); + this.blockCache = new Long2ObjectOpenHashMap<>(); this.chunkPosCache = new long[CHUNK_CACHE_WIDTH * CHUNK_CACHE_WIDTH]; Arrays.fill(this.chunkPosCache, ChunkPos.INVALID_CHUNK_POS); diff --git a/src/main/java/ca/spottedleaf/moonrise/mixin/hopper/HopperBlockEntityMixin.java b/src/main/java/ca/spottedleaf/moonrise/mixin/hopper/HopperBlockEntityMixin.java index 6d7e9ea..2a4aed1 100644 --- a/src/main/java/ca/spottedleaf/moonrise/mixin/hopper/HopperBlockEntityMixin.java +++ b/src/main/java/ca/spottedleaf/moonrise/mixin/hopper/HopperBlockEntityMixin.java @@ -30,6 +30,11 @@ import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Overwrite; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.Redirect; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import org.spongepowered.asm.mixin.injection.callback.LocalCapture; import java.util.List; import java.util.function.BooleanSupplier; @@ -130,46 +135,57 @@ public abstract class HopperBlockEntityMixin extends RandomizableContainerBlockE }); } + /** + * @reason Forces a return false when container is not null so that the below mixin can inject its own return logic. + * @author Spottedleaf + */ + @Redirect( + method = "suckInItems", + at = @At( + target = "Lnet/minecraft/world/level/block/entity/HopperBlockEntity;isEmptyContainer(Lnet/minecraft/world/Container;Lnet/minecraft/core/Direction;)Z", + value = "INVOKE" + ) + ) + private static boolean forceReturnFalseForContainer(final Container container, final Direction direction) { + return true; + } + /** * @reason Avoid checking for empty container and remove streams / indirection * @author Spottedleaf */ - @Overwrite - public static boolean suckInItems(final Level level, final Hopper hopper) { - final Container aboveContainer = getSourceContainer(level, hopper); - if (aboveContainer != null) { - final Direction down = Direction.DOWN; + @Inject( + method = "suckInItems", + cancellable = true, + locals = LocalCapture.CAPTURE_FAILHARD, + at = @At( + value = "RETURN", + ordinal = 0 + ) + ) + private static void handleContainerSuck(final Level level, final Hopper hopper, final CallbackInfoReturnable cir, + final Container aboveContainer) { + final Direction down = Direction.DOWN; + // don't bother checking for empty, because the same logic can be done by trying to move items - as + // that checks for an empty item. - // don't bother checking for empty, because the same logic can be done by trying to move items - as - // that checks for an empty item. - - if (aboveContainer instanceof WorldlyContainer worldlyContainer) { - for (final int slot : worldlyContainer.getSlotsForFace(down)) { - if (tryTakeInItemFromSlot(hopper, aboveContainer, slot, down)) { - return true; - } + if (aboveContainer instanceof WorldlyContainer worldlyContainer) { + for (final int slot : worldlyContainer.getSlotsForFace(down)) { + if (tryTakeInItemFromSlot(hopper, aboveContainer, slot, down)) { + cir.setReturnValue(Boolean.TRUE); + return; } - return false; - } else { - for (int slot = 0, max = aboveContainer.getContainerSize(); slot < max; ++slot) { - if (tryTakeInItemFromSlot(hopper, aboveContainer, slot, down)) { - return true; - } - } - return false; } - } else { - final List items = getItemsAtAndAbove(level, hopper); - - for (int i = 0, len = items.size(); i < len; ++i) { - if (addItem(hopper, items.get(i))) { - return true; + for (int slot = 0, max = aboveContainer.getContainerSize(); slot < max; ++slot) { + if (tryTakeInItemFromSlot(hopper, aboveContainer, slot, down)) { + cir.setReturnValue(Boolean.TRUE); + return; } } - - return false; } + cir.setReturnValue(Boolean.FALSE); + return; } /** @@ -315,4 +331,29 @@ public abstract class HopperBlockEntityMixin extends RandomizableContainerBlockE return true; } } + + /** + * @reason Remove streams + * @author Spottedleaf + */ + @Overwrite + private static boolean isEmptyContainer(final Container container, final Direction direction) { + if (container instanceof WorldlyContainer worldlyContainer) { + for (final int slot : worldlyContainer.getSlotsForFace(direction)) { + final ItemStack stack = container.getItem(slot); + if (!stack.isEmpty()) { + return false; + } + } + return true; + } else { + for (int slot = 0, max = container.getContainerSize(); slot < max; ++slot) { + final ItemStack stack = container.getItem(slot); + if (!stack.isEmpty()) { + return false; + } + } + return true; + } + } }