Skip to content

Commit

Permalink
fix: don't cache recipe inputs
Browse files Browse the repository at this point in the history
* remember to initialize data types on the client
* query output slots when checking for space
  • Loading branch information
marcus8448 committed Aug 16, 2024
1 parent b562093 commit 0d49c5c
Show file tree
Hide file tree
Showing 5 changed files with 19 additions and 69 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
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.Contract;
import org.jetbrains.annotations.NotNull;

/**
Expand All @@ -44,11 +43,6 @@
* @param <R> The type of recipe the machine uses.
*/
public abstract class BasicRecipeMachineBlockEntity<I extends RecipeInput, R extends Recipe<I>> extends RecipeMachineBlockEntity<I, R> {
/**
* An inventory for use in finding vanilla recipes for this machine.
*/
protected final @NotNull I craftingInv;

protected final SlottedStorageAccess<Item, ItemResourceSlot> inputSlots;
protected final SlottedStorageAccess<Item, ItemResourceSlot> outputSlots;

Expand Down Expand Up @@ -101,52 +95,20 @@ protected BasicRecipeMachineBlockEntity(BlockEntityType<? extends BasicRecipeMac

this.inputSlots = this.itemStorage().subStorage(inputSlots, inputSlotsLen);
this.outputSlots = this.itemStorage().subStorage(outputSlots, outputSlotsLen);

this.craftingInv = this.createCraftingInv();
}

protected abstract I createCraftingInv();

/**
* Creates an inventory for use in finding vanilla recipes for this machine.
* NOTE: This inventory can assume that it is never modified - do not modify it!
*
* @return The crafting inventory of the machine.
*/
@Override
@Contract(pure = true)
protected @NotNull I craftingInv() {
return this.craftingInv;
}

/**
* Inserts the active recipe's output into the machine's inventory.
*
* @param recipe The recipe to output.
*/
@Override
protected void outputStacks(@NotNull RecipeHolder<R> recipe) {
ItemStack assembled = recipe.value().assemble(this.craftingInv(), this.level.registryAccess());
this.outputSlots.insertMatching(assembled.getItem(), assembled.getComponentsPatch(), assembled.getCount());
}

/**
* Checks if the machine can output stacks for the given recipe.
*
* @param recipe The recipe to check.
* @return {@code true} if the machine can output stacks for the recipe, {@code false} otherwise.
*/
@Override
protected boolean canOutputStacks(@NotNull RecipeHolder<R> recipe) {
ItemStack assembled = recipe.value().assemble(this.craftingInv(), this.level.registryAccess());
return this.inputSlots.canInsert(assembled.getItem(), assembled.getComponentsPatch(), assembled.getCount());
return this.outputSlots.canInsert(assembled.getItem(), assembled.getComponentsPatch(), assembled.getCount());
}

/**
* Extracts the recipe's input from the machine's inventory.
*
* @param recipe The recipe to extract.
*/
@Override
protected void extractCraftingMaterials(@NotNull RecipeHolder<R> recipe) {
for (ItemResourceSlot slot : this.inputSlots) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,6 @@ protected RecipeMachineBlockEntity(@NotNull BlockEntityType<? extends RecipeMach

/**
* An inventory for use in finding vanilla recipes for this machine.
* NOTE: This inventory can assume that it is never modified - do not modify it!
*
* @return The crafting inventory of the machine.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,25 +37,23 @@

public class RecipeHelper {
public static @NotNull CraftingInput craftingInput(int width, int height, SlottedStorageAccess<Item, ItemResourceSlot> storage) {
ItemResourceSlot[] slots = new ItemResourceSlot[width * height];
ItemResourceSlot[] storageSlots = storage.getSlots();
int j = 0;
List<ItemStack> items = new ArrayList<>(width * height);
for (int i = 0; i < storage.size(); i++) {
if (storageSlots[i].transferMode().isInput()) {
slots[j++] = storageSlots[i];
ItemResourceSlot slot = storage.slot(i);
if (slot.transferMode().isInput()) {
items.add(ItemStackUtil.create(slot));
}
}
assert j == width * height;

return craftingInput(width, height, slots);
return CraftingInput.of(width, height, items);
}

public static @NotNull CraftingInput craftingInput(int offset, int width, int height, SlottedStorageAccess<Item, ItemResourceSlot> storage) {
ItemResourceSlot[] slots = new ItemResourceSlot[width * height];
List<ItemStack> items = new ArrayList<>(width * height);
for (int i = 0; i < width * height; i++) {
slots[i] = storage.getSlots()[offset + i];
items.add(ItemStackUtil.create(storage.slot(offset + i)));
}
return craftingInput(width, height, slots);
return CraftingInput.of(width, height, items);
}

public static @NotNull CraftingInput craftingInput(int width, int height, ItemResourceSlot... slots) {
Expand Down Expand Up @@ -87,24 +85,7 @@ public class RecipeHelper {
return new MachineRecipeInput(slots);
}

public static @NotNull RecipeInput input(ItemResourceSlot slot) {
return new SingleSlotInput(slot);
}

public static @NotNull SingleRecipeInput single(ItemResourceSlot slot) {
return new SingleRecipeInput(ItemStackUtil.create(slot));
}

private record SingleSlotInput(ItemResourceSlot slot) implements RecipeInput {
@Override
public @NotNull ItemStack getItem(int i) {
if (i == 0) return ItemStackUtil.create(slot);
throw new IndexOutOfBoundsException("Index: " + i);
}

@Override
public int size() {
return 1;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,11 @@ protected SynchronizedMenuType(Factory<BE, Menu> factory) {

@Contract(value = "_ -> new", pure = true)
public static <BE extends BaseBlockEntity, Menu extends SynchronizedMenu<BE>> @NotNull MenuType<Menu> create(ExtendedScreenHandlerType.ExtendedFactory<Menu, BlockPos> factory) {
return new ExtendedScreenHandlerType<>(factory, BlockPos.STREAM_CODEC);
return new ExtendedScreenHandlerType<>((syncId, inventory, data) -> {
Menu menu = factory.create(syncId, inventory, data);
menu.registerData(menu.getData());
return menu;
}, BlockPos.STREAM_CODEC);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,11 @@ public void apply(ClientPlayNetworking.Context context) {
if (player.containerMenu instanceof MachineMenu<?> menu && syncId == menu.containerId) {
menu.getData().handle(this.buf);
} else {
MachineLib.LOGGER.warn("Received menu sync packet for invalid menu ID: {} (active: {})", syncId, player.containerMenu.containerId);
if (player.containerMenu.containerId != 0) {
MachineLib.LOGGER.warn("Received menu sync packet for invalid menu ID: {} (active: {})", syncId, player.containerMenu.containerId);
} else {
MachineLib.LOGGER.debug("Received menu sync packet for '{}' with no menu open", syncId);
}
}
}
}
Expand Down

0 comments on commit 0d49c5c

Please sign in to comment.