Skip to content

Commit

Permalink
Merge pull request #184 from Gu-ZT/Depository
Browse files Browse the repository at this point in the history
修改合成器与溜槽的输出方式以降低卡顿
  • Loading branch information
Gugle2308 authored Apr 5, 2024
2 parents 2f2ef61 + 0a8c06c commit 6dee4b5
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 51 deletions.
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -43,8 +44,6 @@ private boolean record = false;
private final NonNullList<Boolean> disabled = this.getNewDisabled();
@Getter
private final NonNullList<@Unmodifiable ItemStack> filter = this.getNewFilter();
private static int levelHash = 1;
private static NonNullList<ItemStack> remainingItemsCache;
private final Deque<AutoCrafterCache> cache = new ArrayDeque<>();

public AutoCrafterBlockEntity(BlockPos pos, BlockState blockState) {
Expand Down Expand Up @@ -81,41 +80,41 @@ private static void craft(@NotNull Level level, @NotNull AutoCrafterBlockEntity
if (!entity.canCraft()) return;
Optional<AutoCrafterCache> cacheOptional = entity.cache.stream().filter(recipe -> recipe.test(entity)).findFirst();
Optional<CraftingRecipe> optional;
NonNullList<ItemStack> 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++) {
ItemStack stack = entity.getItem(i);
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
Expand Down Expand Up @@ -218,15 +217,18 @@ public static class AutoCrafterCache implements Predicate<Container> {
private final Container container;
@Getter
private final Optional<CraftingRecipe> recipe;
@Getter
private final NonNullList<ItemStack> remaining;

public AutoCrafterCache(@NotNull Container container, Optional<CraftingRecipe> recipe) {
public AutoCrafterCache(@NotNull Container container, Optional<CraftingRecipe> recipe, NonNullList<ItemStack> remaining) {
this.container = new SimpleContainer(container.getContainerSize());
for (int i = 0; i < container.getContainerSize(); i++) {
ItemStack item = container.getItem(i).copy();
item.setCount(1);
this.container.setItem(i, item);
}
this.recipe = recipe;
this.remaining = remaining;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -91,66 +93,62 @@ protected void setItems(@NotNull NonNullList<ItemStack> 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);
container.setItem(slot, item);
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);
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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;
}
}

Expand All @@ -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();
Expand Down

0 comments on commit 6dee4b5

Please sign in to comment.