Skip to content

Commit 7a77673

Browse files
committed
fix: Fix crash when result ItemStackTemplate of a recipe is null #810
1 parent d6bb241 commit 7a77673

9 files changed

Lines changed: 34 additions & 16 deletions

‎common/src/main/java/net/blay09/mods/cookingforblockheads/api/KitchenRecipeHandler.java‎

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,29 +8,34 @@
88
import net.minecraft.world.item.crafting.Recipe;
99
import net.minecraft.world.item.crafting.RecipeHolder;
1010
import net.minecraft.world.item.crafting.RecipeInput;
11+
import org.jspecify.annotations.Nullable;
1112

1213
import java.util.List;
1314
import java.util.Optional;
1415

1516
public interface KitchenRecipeHandler<C extends RecipeInput, T extends Recipe<C>> {
17+
@SuppressWarnings("unchecked")
1618
default int mapToMatrixSlot(RecipeHolder<?> recipe, int ingredientIndex) {
1719
return mapToMatrixSlot((T) recipe.value(), ingredientIndex);
1820
}
1921

2022
int mapToMatrixSlot(T recipe, int ingredientIndex);
2123

24+
@SuppressWarnings("unchecked")
2225
default List<Optional<Ingredient>> getIngredients(RecipeHolder<?> recipe) {
2326
return getIngredients((T) recipe.value());
2427
}
2528

2629
List<Optional<Ingredient>> getIngredients(T recipe);
2730

28-
default ItemStackTemplate predictResultItem(RecipeHolder<?> recipe) {
31+
@SuppressWarnings("unchecked")
32+
default @Nullable ItemStackTemplate predictResultItem(RecipeHolder<?> recipe) {
2933
return predictResultItem((T) recipe.value());
3034
}
3135

32-
ItemStackTemplate predictResultItem(T recipe);
36+
@Nullable ItemStackTemplate predictResultItem(T recipe);
3337

38+
@SuppressWarnings("unchecked")
3439
default ItemStack assemble(CraftingContext context, RecipeHolder<?> recipe, List<IngredientToken> ingredientTokens, RegistryAccess registryAccess) {
3540
return assemble(context, (T) recipe.value(), ingredientTokens, registryAccess);
3641
}

‎common/src/main/java/net/blay09/mods/cookingforblockheads/crafting/KitchenAbstractCookingRecipeHandler.java‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import net.minecraft.world.item.crafting.AbstractCookingRecipe;
1010
import net.minecraft.world.item.crafting.Ingredient;
1111
import net.minecraft.world.item.crafting.SingleRecipeInput;
12+
import org.jspecify.annotations.Nullable;
1213

1314
import java.util.List;
1415
import java.util.Optional;
@@ -37,7 +38,7 @@ public ItemStack assemble(CraftingContext context, AbstractCookingRecipe recipe,
3738
}
3839

3940
@Override
40-
public ItemStackTemplate predictResultItem(AbstractCookingRecipe recipe) {
41+
public @Nullable ItemStackTemplate predictResultItem(AbstractCookingRecipe recipe) {
4142
return ((SingleItemRecipeAccessor) recipe).getResult();
4243
}
4344
}

‎common/src/main/java/net/blay09/mods/cookingforblockheads/crafting/KitchenShapedRecipeHandler.java‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import net.minecraft.world.item.ItemStackTemplate;
55
import net.minecraft.world.item.crafting.Ingredient;
66
import net.minecraft.world.item.crafting.ShapedRecipe;
7+
import org.jspecify.annotations.Nullable;
78

89
import java.util.List;
910
import java.util.Optional;
@@ -27,7 +28,7 @@ public List<Optional<Ingredient>> getIngredients(ShapedRecipe recipe) {
2728
}
2829

2930
@Override
30-
public ItemStackTemplate predictResultItem(ShapedRecipe recipe) {
31+
public @Nullable ItemStackTemplate predictResultItem(ShapedRecipe recipe) {
3132
return ((ShapedRecipeAccessor) recipe).getResult();
3233
}
3334
}

‎common/src/main/java/net/blay09/mods/cookingforblockheads/crafting/KitchenShapelessRecipeHandler.java‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import net.minecraft.world.item.ItemStackTemplate;
55
import net.minecraft.world.item.crafting.Ingredient;
66
import net.minecraft.world.item.crafting.ShapelessRecipe;
7+
import org.jspecify.annotations.Nullable;
78

89
import java.util.List;
910
import java.util.Optional;
@@ -20,7 +21,7 @@ public List<Optional<Ingredient>> getIngredients(ShapelessRecipe recipe) {
2021
}
2122

2223
@Override
23-
public ItemStackTemplate predictResultItem(ShapelessRecipe recipe) {
24+
public @Nullable ItemStackTemplate predictResultItem(ShapelessRecipe recipe) {
2425
return ((ShapelessRecipeAccessor) recipe).getResult();
2526
}
2627
}

‎common/src/main/java/net/blay09/mods/cookingforblockheads/menu/KitchenMenu.java‎

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,8 @@ public List<CraftableWithStatus> buildAvailableCraftables() {
259259
private <C extends RecipeInput, T extends Recipe<C>> @Nullable CraftableWithStatus craftableWithStatusFromRecipe(RecipeHolder<?> recipeHolder) {
260260
final var recipe = recipeHolder.value();
261261
final var recipeHandler = CookingForBlockheadsAPI.getKitchenRecipeHandler(recipe);
262-
final var resultItem = recipeHandler.predictResultItem(recipeHolder).create();
262+
final var resultItemTemplate = recipeHandler.predictResultItem(recipeHolder);
263+
final var resultItem = resultItemTemplate != null ? resultItemTemplate.create() : ItemStack.EMPTY;
263264
if (isGroupItem(resultItem)) {
264265
return null;
265266
}
@@ -373,7 +374,8 @@ private int getCraftableAmount(CraftingOperation operation, RecipeHolder<?> reci
373374
}
374375

375376
final var recipeHandler = CookingForBlockheadsAPI.getKitchenRecipeHandler(recipe.value());
376-
final var resultItem = recipeHandler.predictResultItem(recipe).create();
377+
final var resultItemTemplate = recipeHandler.predictResultItem(recipe);
378+
final var resultItem = resultItemTemplate != null ? resultItemTemplate.create() : ItemStack.EMPTY;
377379
final int resultCount = Math.max(1, resultItem.getCount());
378380
final int maxExecutions = Math.max(1, Mth.ceil(CraftingContext.COUNT_CUTOFF / (float) resultCount));
379381
final int craftableExecutions = operation.countCraftableRepeats(maxExecutions);
@@ -400,7 +402,8 @@ public void craft(RecipeDisplayId recipeDisplayId, NonNullList<ItemStack> locked
400402
final var recipe = serverDisplayInfo.parent();
401403
final var operation = state.craftingContext().createOperation(recipe).withLockedInputs(lockedInputs);
402404
final var recipeHandler = CookingForBlockheadsAPI.getKitchenRecipeHandler(recipe.value());
403-
final var resultItem = recipeHandler.predictResultItem(recipe).create();
405+
final var resultItemTemplate = recipeHandler.predictResultItem(recipe);
406+
final var resultItem = resultItemTemplate != null ? resultItemTemplate.create() : ItemStack.EMPTY;
404407
final var repeats = craftFullStack ? resultItem.getMaxStackSize() / resultItem.getCount() : 1;
405408
for (int i = 0; i < repeats; i++) {
406409
operation.prepare();

‎common/src/main/java/net/blay09/mods/cookingforblockheads/mixin/ShapedRecipeAccessor.java‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@
22

33
import net.minecraft.world.item.ItemStackTemplate;
44
import net.minecraft.world.item.crafting.ShapedRecipe;
5+
import org.jspecify.annotations.Nullable;
56
import org.spongepowered.asm.mixin.Mixin;
67
import org.spongepowered.asm.mixin.gen.Accessor;
78

89
@Mixin(ShapedRecipe.class)
910
public interface ShapedRecipeAccessor {
1011
@Accessor
11-
ItemStackTemplate getResult();
12+
@Nullable ItemStackTemplate getResult();
1213
}

‎common/src/main/java/net/blay09/mods/cookingforblockheads/mixin/ShapelessRecipeAccessor.java‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import net.minecraft.world.item.ItemStackTemplate;
44
import net.minecraft.world.item.crafting.Ingredient;
55
import net.minecraft.world.item.crafting.ShapelessRecipe;
6+
import org.jspecify.annotations.Nullable;
67
import org.spongepowered.asm.mixin.Mixin;
78
import org.spongepowered.asm.mixin.gen.Accessor;
89

@@ -14,5 +15,5 @@ public interface ShapelessRecipeAccessor {
1415
List<Ingredient> getIngredients();
1516

1617
@Accessor
17-
ItemStackTemplate getResult();
18+
@Nullable ItemStackTemplate getResult();
1819
}

‎common/src/main/java/net/blay09/mods/cookingforblockheads/mixin/SingleItemRecipeAccessor.java‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@
22

33
import net.minecraft.world.item.ItemStackTemplate;
44
import net.minecraft.world.item.crafting.SingleItemRecipe;
5+
import org.jspecify.annotations.Nullable;
56
import org.spongepowered.asm.mixin.Mixin;
67
import org.spongepowered.asm.mixin.gen.Accessor;
78

89
@Mixin(SingleItemRecipe.class)
910
public interface SingleItemRecipeAccessor {
1011
@Accessor
11-
ItemStackTemplate getResult();
12+
@Nullable ItemStackTemplate getResult();
1213
}

‎common/src/main/java/net/blay09/mods/cookingforblockheads/registry/CookingForBlockheadsRegistry.java‎

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,8 @@ private static <C extends RecipeInput, T extends Recipe<C>> void loadRecipesByTy
6464
continue;
6565
}
6666

67-
final var resultItem = recipeHandler.predictResultItem(recipe).create();
67+
final var resultItemTemplate = recipeHandler.predictResultItem(recipe);
68+
final var resultItem = resultItemTemplate != null ? resultItemTemplate.create() : ItemStack.EMPTY;
6869
if (isEligibleResultItem(resultItem)) {
6970
if (recipe instanceof AbstractCookingRecipe cookingRecipe && isOvenDuplicate(cookingRecipe, (KitchenRecipeHandler<?, AbstractCookingRecipe>) recipeHandler, resultItem)) {
7071
continue;
@@ -91,10 +92,13 @@ private static <T extends Recipe<?>> boolean isOvenDuplicate(T recipe, KitchenRe
9192
final var ingredients = recipeHandler.getIngredients(recipe);
9293
for (final var recipeHolder : existing) {
9394
final var otherRecipeHandler = getKitchenRecipeHandler(recipeHolder.value());
94-
final var otherIngredients = otherRecipeHandler.getIngredients(recipeHolder);
95-
final var otherResultItem = otherRecipeHandler.predictResultItem(recipeHolder).create();
96-
if (ItemStack.isSameItemSameComponents(resultItem, otherResultItem) && ingredients.equals(otherIngredients)) {
97-
return true;
95+
if (otherRecipeHandler != null) {
96+
final var otherIngredients = otherRecipeHandler.getIngredients(recipeHolder);
97+
final var otherResultItemTemplate = otherRecipeHandler.predictResultItem(recipeHolder);
98+
final var otherResultItem = otherResultItemTemplate != null ? otherResultItemTemplate.create() : ItemStack.EMPTY;
99+
if (ItemStack.isSameItemSameComponents(resultItem, otherResultItem) && ingredients.equals(otherIngredients)) {
100+
return true;
101+
}
98102
}
99103
}
100104

0 commit comments

Comments
 (0)