Skip to content

Commit

Permalink
Add attachment support to ItemStack, recipe output codecs, and recipe…
Browse files Browse the repository at this point in the history
… builders (#475)
  • Loading branch information
Technici4n authored Jan 21, 2024
1 parent 5150301 commit 684d4ca
Show file tree
Hide file tree
Showing 12 changed files with 487 additions and 18 deletions.
47 changes: 47 additions & 0 deletions patches/net/minecraft/data/recipes/ShapedRecipeBuilder.java.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
--- a/net/minecraft/data/recipes/ShapedRecipeBuilder.java
+++ b/net/minecraft/data/recipes/ShapedRecipeBuilder.java
@@ -25,6 +_,7 @@
private final RecipeCategory category;
private final Item result;
private final int count;
+ private final ItemStack resultStack; // Neo: add stack result support
private final List<String> rows = Lists.newArrayList();
private final Map<Character, Ingredient> key = Maps.newLinkedHashMap();
private final Map<String, Criterion<?>> criteria = new LinkedHashMap<>();
@@ -33,9 +_,14 @@
private boolean showNotification = true;

public ShapedRecipeBuilder(RecipeCategory p_249996_, ItemLike p_251475_, int p_248948_) {
+ this(p_249996_, new ItemStack(p_251475_, p_248948_));
+ }
+
+ public ShapedRecipeBuilder(RecipeCategory p_249996_, ItemStack result) {
this.category = p_249996_;
- this.result = p_251475_.asItem();
- this.count = p_248948_;
+ this.result = result.getItem();
+ this.count = result.getCount();
+ this.resultStack = result;
}

public static ShapedRecipeBuilder shaped(RecipeCategory p_250853_, ItemLike p_249747_) {
@@ -46,6 +_,10 @@
return new ShapedRecipeBuilder(p_251325_, p_250636_, p_249081_);
}

+ public static ShapedRecipeBuilder shaped(RecipeCategory p_251325_, ItemStack result) {
+ return new ShapedRecipeBuilder(p_251325_, result);
+ }
+
public ShapedRecipeBuilder define(Character p_206417_, TagKey<Item> p_206418_) {
return this.define(p_206417_, Ingredient.of(p_206418_));
}
@@ -106,7 +_,7 @@
Objects.requireNonNullElse(this.group, ""),
RecipeBuilder.determineBookCategory(this.category),
shapedrecipepattern,
- new ItemStack(this.result, this.count),
+ this.resultStack,
this.showNotification
);
p_301098_.accept(p_126142_, shapedrecipe, advancement$builder.build(p_126142_.withPrefix("recipes/" + this.category.getFolderName() + "/")));
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
--- a/net/minecraft/data/recipes/ShapelessRecipeBuilder.java
+++ b/net/minecraft/data/recipes/ShapelessRecipeBuilder.java
@@ -22,15 +_,21 @@
private final RecipeCategory category;
private final Item result;
private final int count;
+ private final ItemStack resultStack; // Neo: add stack result support
private final NonNullList<Ingredient> ingredients = NonNullList.create();
private final Map<String, Criterion<?>> criteria = new LinkedHashMap<>();
@Nullable
private String group;

public ShapelessRecipeBuilder(RecipeCategory p_250837_, ItemLike p_251897_, int p_252227_) {
+ this(p_250837_, new ItemStack(p_251897_, p_252227_));
+ }
+
+ public ShapelessRecipeBuilder(RecipeCategory p_250837_, ItemStack result) {
this.category = p_250837_;
- this.result = p_251897_.asItem();
- this.count = p_252227_;
+ this.result = result.getItem();
+ this.count = result.getCount();
+ this.resultStack = result;
}

public static ShapelessRecipeBuilder shapeless(RecipeCategory p_250714_, ItemLike p_249659_) {
@@ -41,6 +_,10 @@
return new ShapelessRecipeBuilder(p_252339_, p_250836_, p_249928_);
}

+ public static ShapelessRecipeBuilder shapeless(RecipeCategory p_252339_, ItemStack result) {
+ return new ShapelessRecipeBuilder(p_252339_, result);
+ }
+
public ShapelessRecipeBuilder requires(TagKey<Item> p_206420_) {
return this.requires(Ingredient.of(p_206420_));
}
@@ -95,7 +_,7 @@
ShapelessRecipe shapelessrecipe = new ShapelessRecipe(
Objects.requireNonNullElse(this.group, ""),
RecipeBuilder.determineBookCategory(this.category),
- new ItemStack(this.result, this.count),
+ this.resultStack,
this.ingredients
);
p_301215_.accept(p_126206_, shapelessrecipe, advancement$builder.build(p_126206_.withPrefix("recipes/" + this.category.getFolderName() + "/")));
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
--- a/net/minecraft/data/recipes/SimpleCookingRecipeBuilder.java
+++ b/net/minecraft/data/recipes/SimpleCookingRecipeBuilder.java
@@ -27,6 +_,7 @@
private final RecipeCategory category;
private final CookingBookCategory bookCategory;
private final Item result;
+ private final ItemStack stackResult; // Neo: add stack result support
private final Ingredient ingredient;
private final float experience;
private final int cookingTime;
@@ -44,9 +_,22 @@
int p_250189_,
AbstractCookingRecipe.Factory<?> p_311960_
) {
+ this(p_251345_, p_251607_, new ItemStack(p_252112_), p_250362_, p_251204_, p_250189_, p_311960_);
+ }
+
+ private SimpleCookingRecipeBuilder(
+ RecipeCategory p_251345_,
+ CookingBookCategory p_251607_,
+ ItemStack result,
+ Ingredient p_250362_,
+ float p_251204_,
+ int p_250189_,
+ AbstractCookingRecipe.Factory<?> p_311960_
+ ) {
this.category = p_251345_;
this.bookCategory = p_251607_;
- this.result = p_252112_.asItem();
+ this.result = result.getItem();
+ this.stackResult = result;
this.ingredient = p_250362_;
this.experience = p_251204_;
this.cookingTime = p_250189_;
@@ -85,6 +_,38 @@
return new SimpleCookingRecipeBuilder(p_250319_, CookingBookCategory.FOOD, p_250377_, p_248930_, p_252329_, p_250482_, SmokingRecipe::new);
}

+ public static <T extends AbstractCookingRecipe> SimpleCookingRecipeBuilder generic(
+ Ingredient p_250999_,
+ RecipeCategory p_248815_,
+ ItemStack result,
+ float p_251320_,
+ int p_248693_,
+ RecipeSerializer<T> p_250921_,
+ AbstractCookingRecipe.Factory<T> p_312657_
+ ) {
+ return new SimpleCookingRecipeBuilder(p_248815_, determineSmeltingRecipeCategory(result.getItem()), result, p_250999_, p_251320_, p_248693_, p_312657_);
+ }
+
+ public static SimpleCookingRecipeBuilder campfireCooking(Ingredient p_249393_, RecipeCategory p_249372_, ItemStack result, float p_252321_, int p_251916_) {
+ return new SimpleCookingRecipeBuilder(p_249372_, CookingBookCategory.FOOD, result, p_249393_, p_252321_, p_251916_, CampfireCookingRecipe::new);
+ }
+
+ public static SimpleCookingRecipeBuilder blasting(Ingredient p_252115_, RecipeCategory p_249421_, ItemStack result, float p_250383_, int p_250476_) {
+ return new SimpleCookingRecipeBuilder(
+ p_249421_, determineBlastingRecipeCategory(result.getItem()), result, p_252115_, p_250383_, p_250476_, BlastingRecipe::new
+ );
+ }
+
+ public static SimpleCookingRecipeBuilder smelting(Ingredient p_249223_, RecipeCategory p_251240_, ItemStack result, float p_249452_, int p_250496_) {
+ return new SimpleCookingRecipeBuilder(
+ p_251240_, determineSmeltingRecipeCategory(result.getItem()), result, p_249223_, p_249452_, p_250496_, SmeltingRecipe::new
+ );
+ }
+
+ public static SimpleCookingRecipeBuilder smoking(Ingredient p_248930_, RecipeCategory p_250319_, ItemStack result, float p_252329_, int p_250482_) {
+ return new SimpleCookingRecipeBuilder(p_250319_, CookingBookCategory.FOOD, result, p_248930_, p_252329_, p_250482_, SmokingRecipe::new);
+ }
+
public SimpleCookingRecipeBuilder unlockedBy(String p_176792_, Criterion<?> p_300970_) {
this.criteria.put(p_176792_, p_300970_);
return this;
@@ -110,7 +_,7 @@
this.criteria.forEach(advancement$builder::addCriterion);
AbstractCookingRecipe abstractcookingrecipe = this.factory
.create(
- Objects.requireNonNullElse(this.group, ""), this.bookCategory, this.ingredient, new ItemStack(this.result), this.experience, this.cookingTime
+ Objects.requireNonNullElse(this.group, ""), this.bookCategory, this.ingredient, this.stackResult, this.experience, this.cookingTime
);
p_301266_.accept(p_126264_, abstractcookingrecipe, advancement$builder.build(p_126264_.withPrefix("recipes/" + this.category.getFolderName() + "/")));
}
37 changes: 29 additions & 8 deletions patches/net/minecraft/world/item/ItemStack.java.patch
Original file line number Diff line number Diff line change
@@ -1,30 +1,43 @@
--- a/net/minecraft/world/item/ItemStack.java
+++ b/net/minecraft/world/item/ItemStack.java
@@ -81,7 +_,8 @@
@@ -81,12 +_,13 @@
import net.minecraft.world.level.block.state.pattern.BlockInWorld;
import org.slf4j.Logger;

-public final class ItemStack {
+public final class ItemStack extends net.neoforged.neoforge.attachment.AttachmentHolder implements net.neoforged.neoforge.common.extensions.IItemStackExtension {
+ // TODO: add attachment support here
public static final Codec<ItemStack> CODEC = RecordCodecBuilder.create(
p_311716_ -> p_311716_.group(
BuiltInRegistries.ITEM.holderByNameCodec().fieldOf("id").forGetter(ItemStack::getItemHolder),
@@ -101,10 +_,12 @@
Codec.INT.fieldOf("Count").forGetter(ItemStack::getCount),
- CompoundTag.CODEC.optionalFieldOf("tag").forGetter(p_281115_ -> Optional.ofNullable(p_281115_.getTag()))
+ CompoundTag.CODEC.optionalFieldOf("tag").forGetter(p_281115_ -> Optional.ofNullable(p_281115_.getTag())),
+ ExtraCodecs.strictOptionalField(CompoundTag.CODEC, ATTACHMENTS_NBT_KEY).forGetter(s -> Optional.ofNullable(s.serializeAttachments()))
)
.apply(p_311717_, (p_311722_, p_311723_) -> new ItemStack(p_311722_, 1, p_311723_))
.apply(p_311716_, ItemStack::new)
);
@@ -97,14 +_,17 @@
public static final Codec<ItemStack> ADVANCEMENT_ICON_CODEC = RecordCodecBuilder.create(
p_311717_ -> p_311717_.group(
BuiltInRegistries.ITEM.holderByNameCodec().fieldOf("item").forGetter(ItemStack::getItemHolder),
- ExtraCodecs.strictOptionalField(TagParser.AS_CODEC, "nbt").forGetter(p_311718_ -> Optional.ofNullable(p_311718_.getTag()))
+ ExtraCodecs.strictOptionalField(TagParser.AS_CODEC, "nbt").forGetter(p_311718_ -> Optional.ofNullable(p_311718_.getTag())),
+ ExtraCodecs.strictOptionalField(TagParser.AS_CODEC, ATTACHMENTS_NBT_KEY).forGetter(s -> Optional.ofNullable(s.serializeAttachments()))
)
- .apply(p_311717_, (p_311722_, p_311723_) -> new ItemStack(p_311722_, 1, p_311723_))
+ .apply(p_311717_, (p_311722_, p_311723_, attachments) -> new ItemStack(p_311722_, 1, p_311723_, attachments))
);
+ // TODO: add attachment support here
public static final Codec<ItemStack> ITEM_WITH_COUNT_CODEC = RecordCodecBuilder.create(
p_311720_ -> p_311720_.group(
ITEM_NON_AIR_CODEC.fieldOf("item").forGetter(ItemStack::getItem),
- ExtraCodecs.strictOptionalField(ExtraCodecs.POSITIVE_INT, "count", 1).forGetter(ItemStack::getCount)
+ ExtraCodecs.strictOptionalField(ExtraCodecs.POSITIVE_INT, "count", 1).forGetter(ItemStack::getCount),
+ ExtraCodecs.strictOptionalField(net.neoforged.neoforge.common.crafting.CraftingHelper.TAG_CODEC, "nbt").forGetter(stack -> java.util.Optional.ofNullable(net.neoforged.neoforge.common.crafting.CraftingHelper.getTagForWriting(stack)))
+ ExtraCodecs.strictOptionalField(net.neoforged.neoforge.common.crafting.CraftingHelper.TAG_CODEC, "nbt").forGetter(stack -> java.util.Optional.ofNullable(net.neoforged.neoforge.common.crafting.CraftingHelper.getTagForWriting(stack))),
+ ExtraCodecs.strictOptionalField(net.neoforged.neoforge.common.crafting.CraftingHelper.TAG_CODEC, ATTACHMENTS_NBT_KEY).forGetter(s -> Optional.ofNullable(s.serializeAttachments()))
)
.apply(p_311720_, ItemStack::new)
);
@@ -162,6 +_,9 @@
@@ -162,18 +_,30 @@
}

public ItemStack(Holder<Item> p_312081_, int p_41605_, Optional<CompoundTag> p_41606_) {
Expand All @@ -34,7 +47,15 @@
this(p_312081_, p_41605_);
p_41606_.ifPresent(this::setTag);
}
@@ -170,10 +_,12 @@
+ private ItemStack(Holder<Item> p_312081_, int p_41605_, Optional<CompoundTag> p_41606_, Optional<CompoundTag> attachmentsNbt) {
+ this(p_312081_.value(), p_41605_, p_41606_, attachmentsNbt);
+ }
+ private ItemStack(ItemLike p_312081_, int p_41605_, Optional<CompoundTag> p_41606_, Optional<CompoundTag> attachmentsNbt) {
+ this(p_312081_, p_41605_, attachmentsNbt.orElse(null));
+ p_41606_.ifPresent(this::setTag);
+ }

public ItemStack(Holder<Item> p_220155_, int p_220156_) {
this(p_220155_.value(), p_220156_);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,10 @@
import net.neoforged.neoforge.common.NeoForgeMod;
import net.neoforged.neoforge.common.util.NeoForgeExtraCodecs;
import net.neoforged.neoforge.registries.NeoForgeRegistries;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.Marker;
import org.apache.logging.log4j.MarkerManager;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;

public class CraftingHelper {
@SuppressWarnings("unused")
private static final Logger LOGGER = LogManager.getLogger();
@SuppressWarnings("unused")
private static final Marker CRAFTHELPER = MarkerManager.getMarker("CRAFTHELPER");
public static final Codec<CompoundTag> TAG_CODEC = ExtraCodecs.withAlternative(TagParser.AS_CODEC, net.minecraft.nbt.CompoundTag.CODEC);

@ApiStatus.Internal
Expand All @@ -46,7 +38,8 @@ public static Codec<ItemStack> smeltingResultCodec() {
}

var tagForWriting = getTagForWriting(stack);
return tagForWriting == null ? Either.left(stack.getItem()) : Either.right(stack);
var attachments = stack.serializeAttachments();
return tagForWriting == null && attachments == null ? Either.left(stack.getItem()) : Either.right(stack);
});
}

Expand All @@ -55,7 +48,7 @@ public static CompoundTag getTagForWriting(ItemStack stack) {
// Check if not writing the NBT would still give the correct item.
// Just checking for tag != null is not enough: damageable items get a tag set in the stack constructor,
// but we don't want to write it to the recipe file.
if (ItemStack.matches(stack, new ItemStack(stack.getItem(), stack.getCount()))) {
if (stack.getTag() == null || stack.getTag().equals(new ItemStack(stack.getItem(), stack.getCount()).getTag())) {
return null;
} else {
return stack.getTag();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"parent": "minecraft:recipes/root",
"criteria": {
"has_shovel": {
"conditions": {
"items": [
{
"items": [
"minecraft:golden_shovel"
]
}
]
},
"trigger": "minecraft:inventory_changed"
},
"has_the_recipe": {
"conditions": {
"recipe": "neotests_item_attachment_recipe_output:test_blasting"
},
"trigger": "minecraft:recipe_unlocked"
}
},
"requirements": [
[
"has_the_recipe",
"has_shovel"
]
],
"rewards": {
"recipes": [
"neotests_item_attachment_recipe_output:test_blasting"
]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"parent": "minecraft:recipes/root",
"criteria": {
"has_shovel": {
"conditions": {
"items": [
{
"items": [
"minecraft:golden_shovel"
]
}
]
},
"trigger": "minecraft:inventory_changed"
},
"has_the_recipe": {
"conditions": {
"recipe": "neotests_item_attachment_recipe_output:test_shaped"
},
"trigger": "minecraft:recipe_unlocked"
}
},
"requirements": [
[
"has_the_recipe",
"has_shovel"
]
],
"rewards": {
"recipes": [
"neotests_item_attachment_recipe_output:test_shaped"
]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"parent": "minecraft:recipes/root",
"criteria": {
"has_shovel": {
"conditions": {
"items": [
{
"items": [
"minecraft:golden_shovel"
]
}
]
},
"trigger": "minecraft:inventory_changed"
},
"has_the_recipe": {
"conditions": {
"recipe": "neotests_item_attachment_recipe_output:test_shapeless"
},
"trigger": "minecraft:recipe_unlocked"
}
},
"requirements": [
[
"has_the_recipe",
"has_shovel"
]
],
"rewards": {
"recipes": [
"neotests_item_attachment_recipe_output:test_shapeless"
]
}
}
Loading

0 comments on commit 684d4ca

Please sign in to comment.