diff --git a/common/src/main/java/dev/dubhe/anvilcraft/block/entity/AutoCrafterBlockEntity.java b/common/src/main/java/dev/dubhe/anvilcraft/block/entity/AutoCrafterBlockEntity.java index 676068827..3cf9077b6 100644 --- a/common/src/main/java/dev/dubhe/anvilcraft/block/entity/AutoCrafterBlockEntity.java +++ b/common/src/main/java/dev/dubhe/anvilcraft/block/entity/AutoCrafterBlockEntity.java @@ -1,5 +1,6 @@ package dev.dubhe.anvilcraft.block.entity; +import dev.dubhe.anvilcraft.api.depository.ItemDepository; import dev.dubhe.anvilcraft.block.AutoCrafterBlock; import dev.dubhe.anvilcraft.init.ModBlockEntities; import dev.dubhe.anvilcraft.init.ModBlocks; @@ -43,8 +44,6 @@ private boolean record = false; private final NonNullList disabled = this.getNewDisabled(); @Getter private final NonNullList<@Unmodifiable ItemStack> filter = this.getNewFilter(); - private static int levelHash = 1; - private static NonNullList remainingItemsCache; private final Deque cache = new ArrayDeque<>(); public AutoCrafterBlockEntity(BlockPos pos, BlockState blockState) { @@ -81,26 +80,27 @@ private static void craft(@NotNull Level level, @NotNull AutoCrafterBlockEntity if (!entity.canCraft()) return; Optional cacheOptional = entity.cache.stream().filter(recipe -> recipe.test(entity)).findFirst(); Optional optional; + NonNullList remaining; if (cacheOptional.isPresent()) { - optional = cacheOptional.get().getRecipe(); + AutoCrafterCache crafterCache = cacheOptional.get(); + optional = crafterCache.getRecipe(); + remaining = crafterCache.getRemaining(); } else { optional = level.getRecipeManager().getRecipeFor(RecipeType.CRAFTING, entity, level); - AutoCrafterCache cache = new AutoCrafterCache(entity, optional); + remaining = level.getRecipeManager().getRemainingItemsFor(RecipeType.CRAFTING, entity, level); + AutoCrafterCache cache = new AutoCrafterCache(entity, optional, remaining); entity.cache.push(cache); - while (entity.cache.size() >= 10) { - entity.cache.pop(); - } + while (entity.cache.size() >= 10) entity.cache.pop(); } if (optional.isEmpty()) return; - if (level.hashCode() != levelHash) { - levelHash = level.hashCode(); - remainingItemsCache = level.getRecipeManager().getRemainingItemsFor(RecipeType.CRAFTING, entity, level); - } itemStack = optional.get().assemble(entity, level.registryAccess()); if (!itemStack.isItemEnabled(level.enabledFeatures())) return; Container result = new SimpleContainer(1); result.setItem(0, itemStack); - if (!entity.insertOrDropItem(entity.getDirection(), level, entity.getBlockPos(), result, 0, false, false, true, false)) { + Direction direction = entity.getDirection(); + BlockPos pos = entity.getBlockPos(); + ItemDepository itemDepository = ItemDepository.getItemDepository(level, pos.relative(direction), direction.getOpposite()); + if (!entity.outputItem(itemDepository, direction, level, pos, result, 0, false, false, true, false)) { return; } for (int i = 0; i < 9; i++) { @@ -108,14 +108,13 @@ private static void craft(@NotNull Level level, @NotNull AutoCrafterBlockEntity stack.shrink(1); entity.setItem(i, stack); } - Container container1 = new SimpleContainer(remainingItemsCache.size()); - for (int i = 0; i < remainingItemsCache.size(); i++) { - container1.setItem(i, remainingItemsCache.get(i)); + Container container1 = new SimpleContainer(remaining.size()); + for (int i = 0; i < remaining.size(); i++) container1.setItem(i, remaining.get(i)); + for (int i = 0; i < remaining.size(); i++) { + if (container1.getItem(i).isEmpty()) continue; + entity.outputItem(itemDepository, entity.getDirection(), level, entity.getBlockPos(), container1, i, true, true, true, false); } - for (int i = 0; i < remainingItemsCache.size(); i++) { - entity.insertOrDropItem(entity.getDirection(), level, entity.getBlockPos(), container1, i, true, true, true, false); - } - level.updateNeighborsAt(entity.getBlockPos(), ModBlocks.AUTO_CRAFTER.get()); + level.updateNeighborsAt(pos, ModBlocks.AUTO_CRAFTER.get()); } @Override @@ -218,8 +217,10 @@ public static class AutoCrafterCache implements Predicate { private final Container container; @Getter private final Optional recipe; + @Getter + private final NonNullList remaining; - public AutoCrafterCache(@NotNull Container container, Optional recipe) { + public AutoCrafterCache(@NotNull Container container, Optional recipe, NonNullList remaining) { this.container = new SimpleContainer(container.getContainerSize()); for (int i = 0; i < container.getContainerSize(); i++) { ItemStack item = container.getItem(i).copy(); @@ -227,6 +228,7 @@ public AutoCrafterCache(@NotNull Container container, Optional r this.container.setItem(i, item); } this.recipe = recipe; + this.remaining = remaining; } @Override diff --git a/common/src/main/java/dev/dubhe/anvilcraft/block/entity/BaseMachineBlockEntity.java b/common/src/main/java/dev/dubhe/anvilcraft/block/entity/BaseMachineBlockEntity.java index d332530a2..16ea631bd 100644 --- a/common/src/main/java/dev/dubhe/anvilcraft/block/entity/BaseMachineBlockEntity.java +++ b/common/src/main/java/dev/dubhe/anvilcraft/block/entity/BaseMachineBlockEntity.java @@ -15,8 +15,10 @@ import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.entity.RandomizableContainerBlockEntity; import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.Vec3; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; @Getter public abstract class BaseMachineBlockEntity extends RandomizableContainerBlockEntity { @@ -91,46 +93,39 @@ protected void setItems(@NotNull NonNullList itemStacks) { this.items = itemStacks; } + /** - * 输出或丢出物品 + * 向容器输出或丢出物品 * - * @param direction 输出目标方向 - * @param level 维度 - * @param pos 坐标 - * @param container 输出物品的容器 - * @param slot 从哪个槽位输出 - * @param part 是否允许只插入一部分物品 - * @param drop 是否强制丢出物品 - * @param momentum 是否有动量 - * @param needEmpty 丢出物品的位置是否需要为空 + * @param itemDepository 输出目标 + * @param direction 输出目标方向 + * @param level 维度 + * @param pos 坐标 + * @param container 输出物品的容器 + * @param slot 从哪个槽位输出 + * @param part 是否允许只插入一部分物品 + * @param drop 是否强制丢出物品 + * @param momentum 是否有动量 + * @param needEmpty 丢出物品的位置是否需要为空 * @return 操作是否成功 */ - protected final boolean insertOrDropItem(Direction direction, Level level, @NotNull BlockPos pos, @NotNull Container container, int slot, boolean part, boolean drop, boolean momentum, boolean needEmpty) { + protected final boolean outputItem(@Nullable ItemDepository itemDepository, Direction direction, Level level, @NotNull BlockPos pos, @NotNull Container container, int slot, boolean part, boolean drop, boolean momentum, boolean needEmpty) { ItemStack item = container.getItem(slot); BlockPos curPos = pos.relative(direction); boolean flag = false; - if ((part && getCountCanPlace(level, curPos, item, direction) > 0) || canPlaceAllItem(level, curPos, item, direction)) { - flag = this.insertItem(direction, level, curPos, container, slot); + if ((part && getCountCanPlace(itemDepository, item) > 0) || canPlaceAllItem(itemDepository, item)) { + flag = this.insertItem(itemDepository, container, slot); if (flag) return true; } - if (!drop) { - if (ItemDepository.getItemDepository(level, curPos, direction.getOpposite()) != null) return false; - } + if (!drop && itemDepository != null) return false; if (!needEmpty || this.canDropItem(level, curPos)) { flag = this.dropItem(direction, level, pos, container, slot, momentum); } return flag; } - private boolean canDropItem(@NotNull Level level, @NotNull BlockPos pos) { - Vec3 vec3 = pos.getCenter(); - ItemEntity entity = new ItemEntity(level, vec3.x, vec3.y, vec3.z, ItemStack.EMPTY); - return level.noCollision(entity); - } - - private boolean insertItem(@NotNull Direction direction, @NotNull Level level, @NotNull BlockPos pos, @NotNull Container container, int slot) { + private boolean insertItem(ItemDepository itemDepository, @NotNull Container container, int slot) { ItemStack item = container.getItem(slot); - ItemDepository itemDepository = ItemDepository.getItemDepository(level, pos, direction.getOpposite()); if (itemDepository == null) return false; long count = itemDepository.inject(item.copy(), item.getCount(), false); item.setCount((int) count); @@ -138,19 +133,22 @@ private boolean insertItem(@NotNull Direction direction, @NotNull Level level, @ return true; } - public final long getCountCanPlace(Level level, BlockPos pos, @NotNull ItemStack stack, @NotNull Direction direction) { - ItemDepository itemDepository = ItemDepository.getItemDepository(level, pos, direction.getOpposite()); + public final long getCountCanPlace(ItemDepository itemDepository, @NotNull ItemStack stack) { if (itemDepository == null) return 0; int count = stack.getCount(); return count - itemDepository.inject(stack.copy(), count, true); } - private boolean canPlaceAllItem(Level level, BlockPos pos, @NotNull ItemStack stack, @NotNull Direction direction) { - ItemDepository itemDepository = ItemDepository.getItemDepository(level, pos, direction.getOpposite()); + private boolean canPlaceAllItem(ItemDepository itemDepository, @NotNull ItemStack stack) { if (itemDepository == null) return false; return itemDepository.canInject(stack.copy(), stack.getCount()); } + private boolean canDropItem(@NotNull Level level, @NotNull BlockPos pos) { + Vec3 vec3 = pos.getCenter(); + return level.noCollision(new AABB(vec3.subtract(0.125, 0.0, 0.125), vec3.add(0.125, 0.25, 0.125))); + } + private boolean dropItem(Direction direction, Level level, @NotNull BlockPos pos, @NotNull Container container, int slot, boolean momentum) { ItemStack item = container.getItem(slot); BlockPos out = pos.relative(direction); diff --git a/common/src/main/java/dev/dubhe/anvilcraft/block/entity/ChuteBlockEntity.java b/common/src/main/java/dev/dubhe/anvilcraft/block/entity/ChuteBlockEntity.java index 3bbf11a58..c5fb8f817 100644 --- a/common/src/main/java/dev/dubhe/anvilcraft/block/entity/ChuteBlockEntity.java +++ b/common/src/main/java/dev/dubhe/anvilcraft/block/entity/ChuteBlockEntity.java @@ -1,6 +1,7 @@ package dev.dubhe.anvilcraft.block.entity; import dev.dubhe.anvilcraft.AnvilCraft; +import dev.dubhe.anvilcraft.api.depository.ItemDepository; import dev.dubhe.anvilcraft.block.ChuteBlock; import dev.dubhe.anvilcraft.init.ModBlockEntities; import dev.dubhe.anvilcraft.init.ModBlocks; @@ -97,13 +98,16 @@ public static void tick(Level level, BlockPos pos, BlockEntity e) { ChuteBlockEntity.tryMoveItems(level, pos, state, entity, () -> ChuteBlockEntity.suckInItems(level, entity)); entity.dropOrInsert(level, pos); } + level.updateNeighborsAt(pos, ModBlocks.AUTO_CRAFTER.get()); } - public void dropOrInsert(Level level, BlockPos pos) { + public void dropOrInsert(Level level, @NotNull BlockPos pos) { + Direction direction = this.getDirection(); + ItemDepository itemDepository = ItemDepository.getItemDepository(level, pos.relative(direction), direction.getOpposite()); for (int i = this.items.size() - 1; i >= 0; i--) { ItemStack stack = this.items.get(i); if (stack.isEmpty()) continue; - if (this.insertOrDropItem(this.getDirection(), level, pos, this, i, true, false, false, true)) return; + if (this.outputItem(itemDepository, direction, level, pos, this, i, true, false, false, true)) return; } } @@ -130,7 +134,7 @@ private static boolean tryMoveItems(@Nonnull Level level, BlockPos pos, BlockSta boolean bl = false; if (!blockEntity.isEmpty()) { // TODO - // bl = HopperBlockEntity.ejectItems(level, pos, state, blockEntity); +// bl = HopperBlockEntity.ejectItems(level, pos, state, blockEntity); } if (!blockEntity.inventoryFull()) { bl |= validator.getAsBoolean();