Skip to content

Commit

Permalink
Merge pull request #418 from Team-EnderIO/fix/crafter_lag
Browse files Browse the repository at this point in the history
  • Loading branch information
Rover656 committed Aug 4, 2023
2 parents fb3a74e + 0563ace commit f5ca4b2
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import com.enderio.machines.common.io.item.SingleSlotAccess;
import com.enderio.machines.common.menu.CrafterMenu;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.AbstractContainerMenu;
Expand All @@ -20,6 +21,7 @@
import net.minecraft.world.item.crafting.RecipeType;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import org.jetbrains.annotations.Nullable;

import java.util.ArrayDeque;
import java.util.Optional;
Expand All @@ -37,6 +39,7 @@ public class CrafterBlockEntity extends PoweredMachineBlockEntity {
public static final MultiSlotAccess GHOST = new MultiSlotAccess();
public static final SingleSlotAccess PREVIEW = new SingleSlotAccess();

@Nullable
private CraftingRecipe recipe;
private final Queue<ItemStack> outputBuffer = new ArrayDeque<>();

Expand All @@ -55,6 +58,25 @@ public boolean stillValid(Player pPlayer) {

public CrafterBlockEntity(BlockEntityType<?> type, BlockPos worldPosition, BlockState blockState) {
super(EnergyIOMode.Input, ENERGY_CAPACITY, ENERGY_USAGE, type, worldPosition, blockState);
getInventoryNN().addSlotChangedCallback(this::onSlotChanged);
}

private void onSlotChanged(int slot) {
if (GHOST.contains(slot)) {
updateRecipe();
}
}

private void updateRecipe() {
for (int i = 0; i < 9; i++) {
dummyCContainer.setItem(i, GHOST.get(i).getItemStack(this).copy());
}
recipe = getLevel()
.getRecipeManager()
.getRecipeFor(RecipeType.CRAFTING, dummyCContainer, getLevel()).orElse(null);
PREVIEW.setStackInSlot(this, ItemStack.EMPTY);
if (recipe != null)
PREVIEW.setStackInSlot(this, recipe.getResultItem(getLevel().registryAccess()));
}

@Override
Expand Down Expand Up @@ -85,6 +107,19 @@ private boolean acceptSlotInput(int slot, ItemStack stack) {
return ItemStack.isSameItem(this.getInventoryNN().getStackInSlot(slot + 10), stack);
}

@Override
public void onLoad() {
super.onLoad();
updateRecipe();
}

@Override
public void load(CompoundTag pTag) {
super.load(pTag);
if (level != null && !level.isClientSide())
updateRecipe();
}

@Override
public void serverTick() {
tryCraft();
Expand All @@ -94,21 +129,15 @@ public void serverTick() {

@Override
protected boolean isActive() {
// TODO: How to determine active state beyond power.
return canAct() && hasEnergy();
}

private void tryCraft() {
Optional<ItemStack> opt = getRecipeResult();
if (opt.isPresent()) {
ItemStack result = opt.get();
PREVIEW.setStackInSlot(this, result);
getRecipeResult().ifPresent(result -> {
if (shouldActTick() && hasPowerToCraft() && canMergeOutput(result) && outputBuffer.isEmpty()) {
craftItem();
}
} else {
PREVIEW.setStackInSlot(this, ItemStack.EMPTY);
}
});
}

private boolean shouldActTick() {
Expand Down Expand Up @@ -141,12 +170,7 @@ private void processOutputBuffer() {
}

private Optional<ItemStack> getRecipeResult() {
for (int i = 0; i < 9; i++) {
dummyCContainer.setItem(i, GHOST.get(i).getItemStack(this).copy());
}
Optional<CraftingRecipe> opt = getLevel().getRecipeManager().getRecipeFor(RecipeType.CRAFTING, dummyCContainer, getLevel());
if (opt.isPresent()) {
recipe = opt.get();
if (recipe != null) {
return Optional.of(recipe.assemble(dummyCContainer, getLevel().registryAccess()));
}
return Optional.empty();
Expand Down Expand Up @@ -175,7 +199,10 @@ private void craftItem() {
outputBuffer.removeIf(ItemStack::isEmpty);
// consume power
this.energyStorage.consumeEnergy(ENERGY_USAGE_PER_ITEM, false);

//ceck resource reload
if (level.getRecipeManager().byKey(recipe.getId()).orElse(null) != recipe) {
recipe = null;
}
}

private void clearInput() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import org.jetbrains.annotations.Nullable;

import java.util.EnumMap;
import java.util.function.IntConsumer;

/**
* A machine inventory.
Expand All @@ -24,6 +25,8 @@ public class MachineInventory extends ItemStackHandler implements IEnderCapabili
private final EnumMap<Direction, LazyOptional<Wrapped>> sideCache = new EnumMap<>(Direction.class);
private LazyOptional<Wrapped> selfCache = LazyOptional.empty();

private IntConsumer changeListener = i -> {};

/**
* Create a new machine inventory.
*/
Expand All @@ -32,6 +35,9 @@ public MachineInventory(IIOConfig config, MachineInventoryLayout layout) {
this.config = config;
this.layout = layout;
}
public void addSlotChangedCallback(IntConsumer callback) {
changeListener = changeListener.andThen(callback);
}

/**
* Get the IO config for the machine.
Expand Down Expand Up @@ -63,7 +69,7 @@ public Capability<IItemHandler> getCapabilityType() {
}

@Override
public LazyOptional<IItemHandler> getCapability(Direction side) {
public LazyOptional<IItemHandler> getCapability(@Nullable Direction side) {
if (side == null) {
// Create own cache if its been invalidated or not created yet.
if (!selfCache.isPresent())
Expand All @@ -77,7 +83,7 @@ public LazyOptional<IItemHandler> getCapability(Direction side) {
}

@Override
public void invalidateSide(Direction side) {
public void invalidateSide(@Nullable Direction side) {
if (side != null) {
if (sideCache.containsKey(side)) {
sideCache.get(side).invalidate();
Expand All @@ -95,6 +101,31 @@ public void invalidateCaps() {
}
}

@Override
public ItemStack insertItem(int slot, ItemStack stack, boolean simulate) {
boolean wasEmpty = !simulate && getStackInSlot(slot).isEmpty();
ItemStack itemStack = super.insertItem(slot, stack, simulate);
if (wasEmpty && itemStack.getCount() != stack.getCount())
changeListener.accept(slot);
return itemStack;
}

@Override
public ItemStack extractItem(int slot, int amount, boolean simulate) {
ItemStack itemStack = super.extractItem(slot, amount, simulate);
if (!itemStack.isEmpty() && !simulate && getStackInSlot(slot).isEmpty())
changeListener.accept(slot);
return itemStack;
}

@Override
public void setStackInSlot(int slot, ItemStack stack) {
boolean changed = stack.getItem() != getStackInSlot(slot).getItem();
super.setStackInSlot(slot, stack);
if (changed)
this.changeListener.accept(slot);
}

private record Wrapped(MachineInventory master, @Nullable Direction side) implements IItemHandler {

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ public List<SingleSlotAccess> getAccesses() {
return accesses;
}

public boolean contains(int slotIndex) {
return slotIndex >= accesses.get(0).getIndex() && slotIndex <= accesses.get(accesses.size() - 1).getIndex();
}

public static MultiSlotAccess wrap(SingleSlotAccess access) {
MultiSlotAccess multi = new MultiSlotAccess();
multi.accesses = List.of(access);
Expand Down

0 comments on commit f5ca4b2

Please sign in to comment.