Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public NonNullList<ItemStack> getItems() {
private final InventorySource inputSource;

private @Nullable RecipeHolder<CraftingRecipe> recipe = null;
private CraftingInput craftingInput = CraftingInput.EMPTY;
private CraftingInput.Positioned posCraftingInput = CraftingInput.Positioned.EMPTY;
private CraftingResult result = CraftingResult.EMPTY;

public CraftingHelper(InventorySource inputSource) {
Expand All @@ -61,7 +61,7 @@ public CraftingHelper(InventorySource inputSource) {
public void clear() {
recipe = null;
craftingInventory.clearContent();
craftingInput = CraftingInput.EMPTY;
posCraftingInput = CraftingInput.Positioned.EMPTY;
}

public void onInventoryChanged() {
Expand All @@ -87,14 +87,14 @@ public void loadInputs() {
for (int i = 0; i < 9; i++) {
craftingInventory.setItem(i, craftingMatrix.getItem(i).copy());
}
craftingInput = craftingInventory.asCraftInput();
posCraftingInput = craftingInventory.asPositionedCraftInput();
}

public void loadRecipe() {
recipe = inputSource.getWorld().getRecipeManager()
.getRecipeFor(RecipeType.CRAFTING, craftingInput, inputSource.getWorld()).orElse(null);
.getRecipeFor(RecipeType.CRAFTING, posCraftingInput.input(), inputSource.getWorld()).orElse(null);

craftResultInventory.setItem(0, recipe == null ? ItemStack.EMPTY : recipe.value().assemble(craftingInput, inputSource.getWorld().registryAccess()));
craftResultInventory.setItem(0, recipe == null ? ItemStack.EMPTY : recipe.value().assemble(posCraftingInput.input(), inputSource.getWorld().registryAccess()));
}

public void loadOutput() {
Expand Down Expand Up @@ -133,19 +133,20 @@ public boolean onCraftedByPlayer(Player player, boolean leaveRemainingInGrid) {

// Re-obtain remaining items in case "setCraftingPlayer" changes remaining items
CommonHooks.setCraftingPlayer(player);
NonNullList<ItemStack> remainingStacks = recipe.value().getRemainingItems(craftingInput); // Skip re-searching for recipe, should be ok
NonNullList<ItemStack> remainingStacks = recipe.value().getRemainingItems(posCraftingInput.input()); // Skip re-searching for recipe, should be ok
CommonHooks.setCraftingPlayer(null);

Container craftingGird = inputSource.getCraftingMatrix();
Container storage = inputSource.getStorage();

for (int i = 0; i < 9; i++) {
for (int i = 0; i < remainingStacks.size(); i++) {
ItemStack remaining = remainingStacks.get(i);
if (remaining.isEmpty()) continue;

// If allowed, leave remaining in crafting grid just like Vanilla crafting bench
if (leaveRemainingInGrid && craftingGird.getItem(i).isEmpty()) {
craftingGird.setItem(i, remaining.split(remaining.getCount()));
int ccSlot = craftingInputSlotToContainer(craftingInventory, posCraftingInput, i);
craftingGird.setItem(ccSlot, remaining.split(remaining.getCount()));
continue;
}

Expand Down Expand Up @@ -187,9 +188,9 @@ private CraftingResult craftFromStorage(boolean simulate) {
private CraftingResult craftFromSource(Container source, boolean simulate) {
if (recipe == null) return CraftingResult.EMPTY;

if (!recipe.value().matches(craftingInput, inputSource.getWorld())) return CraftingResult.EMPTY;
if (!recipe.value().matches(posCraftingInput.input(), inputSource.getWorld())) return CraftingResult.EMPTY;

ItemStack result = recipe.value().assemble(craftingInput, inputSource.getWorld().registryAccess());
ItemStack result = recipe.value().assemble(posCraftingInput.input(), inputSource.getWorld().registryAccess());
if (result.isEmpty()) return CraftingResult.EMPTY;

if (simulate) {
Expand Down Expand Up @@ -227,7 +228,7 @@ private CraftingResult craftFromSource(Container source, boolean simulate) {
return CraftingResult.missingIngredients(missingIngredientMask);
}

return new CraftingResult(result, recipe.value().getRemainingItems(craftingInput), 0, simulate ? source : copyInventory(source));
return new CraftingResult(result, recipe.value().getRemainingItems(posCraftingInput.input()), 0, simulate ? source : copyInventory(source));
}

private boolean consumeIngredient(Container storage, int startIndex, Predicate<ItemStack> matchFunc) {
Expand Down Expand Up @@ -317,4 +318,27 @@ default boolean canConsumeFromCraftingMatrix() {

Level getWorld(); // Required for recipe lookup
}

/**
* Maps the slot index from within a CraftingInput (which is a sub-square within a crafting container)
* into a slot index of this outer crafting container.
* <p>
* For example, if the matrix is 3x3, and the crafting input is 2x2 in bottom left, then
* slot 0 in the 2x2 input corresponds with slot 4 in the 3x3 matrix.
*
* @param matrix The CraftingContainer that the CraftingInput is in
* @param pCraftInput A CraftingInput positioned somewhere inside matrix
* @param pSlot A slot index inside pCraftInput
* @return The corresponding slot index in matrix
*/
private static int craftingInputSlotToContainer(CraftingContainer matrix, CraftingInput.Positioned pCraftInput, int pSlot) {
// xy within the crafting input
int ix = pSlot % pCraftInput.input().width();
int iy = pSlot / pCraftInput.input().width();
// xy within outer grid
int x = pCraftInput.left() + ix;
int y = pCraftInput.top() + iy;
// Outer index
return y * matrix.getWidth() + x;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,10 @@
import net.minecraft.ChatFormatting;
import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.network.chat.Component;
import net.minecraft.network.codec.ByteBufCodecs;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.world.Container;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.TooltipFlag;
import net.minecraft.world.item.component.TooltipProvider;

Expand Down Expand Up @@ -121,13 +119,13 @@ public void addToTooltip(Item.TooltipContext context, Consumer<Component> toolti
//region Codecs
// Codecs
public static final Codec<RecipePlanComponent> CODEC = RecordCodecBuilder.create(instance -> instance.group(
Codec.list(ItemStack.CODEC).fieldOf("inputs").forGetter(c -> c.inputs),
ItemStack.CODEC.fieldOf("output").forGetter(c -> c.output)
Codec.list(ItemStack.OPTIONAL_CODEC).fieldOf("inputs").forGetter(c -> c.inputs),
ItemStack.OPTIONAL_CODEC.fieldOf("output").forGetter(c -> c.output)
).apply(instance, RecipePlanComponent::new));

public static final StreamCodec<RegistryFriendlyByteBuf, RecipePlanComponent> STREAM_CODEC = StreamCodec.composite(
ItemStack.STREAM_CODEC.apply(ByteBufCodecs.list()), c -> c.inputs,
ItemStack.STREAM_CODEC, c -> c.output,
ItemStack.OPTIONAL_LIST_STREAM_CODEC, c -> c.inputs,
ItemStack.OPTIONAL_STREAM_CODEC, c -> c.output,
RecipePlanComponent::new
);
//endregion
Expand Down
Loading