diff --git a/src/main/java/org/betterx/bclib/recipes/AbstractSimpleRecipeBuilder.java b/src/main/java/org/betterx/bclib/recipes/AbstractSimpleRecipeBuilder.java index fa83ac49..546f311f 100644 --- a/src/main/java/org/betterx/bclib/recipes/AbstractSimpleRecipeBuilder.java +++ b/src/main/java/org/betterx/bclib/recipes/AbstractSimpleRecipeBuilder.java @@ -49,7 +49,7 @@ public abstract class AbstractSimpleRecipeBuilder, UnknownReceipBookCategory { public final static String GROUP = "alloying"; @@ -62,6 +64,16 @@ public class AlloyingRecipe implements Recipe, UnknownReceipBookCateg ); } + public AlloyingRecipe( + List inputs, + Optional group, + ItemStack output, + float experience, + int smeltTime + ) { + this(inputs, group.orElse(null), output, experience, smeltTime); + } + public AlloyingRecipe( String group, Ingredient primaryInput, @@ -216,8 +228,8 @@ public class AlloyingRecipe implements Recipe, UnknownReceipBookCateg Codec.list(Ingredient.CODEC_NONEMPTY) .fieldOf("ingredients") .forGetter(recipe -> List.of(recipe.primaryInput, recipe.secondaryInput)), - Codec.STRING.optionalFieldOf("group", "") - .forGetter(recipe -> recipe.group), + ExtraCodecs.strictOptionalField(Codec.STRING, "group") + .forGetter(recipe -> Optional.ofNullable(recipe.group)), ItemUtil.CODEC_ITEM_STACK_WITH_NBT.fieldOf("result").forGetter(recipe -> recipe.output), Codec.FLOAT.optionalFieldOf("experience", 0f).forGetter(recipe -> recipe.experience), Codec.INT.optionalFieldOf("smelttime", 350).forGetter(recipe -> recipe.smeltTime) diff --git a/src/main/java/org/betterx/bclib/util/ItemUtil.java b/src/main/java/org/betterx/bclib/util/ItemUtil.java index 763f6f65..a45cda05 100644 --- a/src/main/java/org/betterx/bclib/util/ItemUtil.java +++ b/src/main/java/org/betterx/bclib/util/ItemUtil.java @@ -14,8 +14,6 @@ import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.crafting.Ingredient; -import java.util.Collection; -import java.util.Collections; import java.util.List; import java.util.Optional; import org.jetbrains.annotations.Nullable; @@ -59,61 +57,34 @@ public class ItemUtil { .forGetter((itemStack) -> Optional.ofNullable(itemStack.getTag())) ).apply(instance, ItemStack::new)); - public static Codec CODEC_INGREDIENT_WITH_NBT = ingredientCodec(true); - public static Codec CODEC_INGREDIENT_WITH_NBT_NOT_EMPTY = ingredientCodec(false); + private static final Codec CODEC_NBT_ITEM_VALUE = RecordCodecBuilder.create((instance) -> instance + .group(CODEC_ITEM_STACK_WITH_NBT.fieldOf("item").forGetter((itemValue) -> itemValue.item())) + .apply(instance, Ingredient.ItemValue::new)); + private static final Codec VALUE_CODEC = ExtraCodecs + .xor(CODEC_NBT_ITEM_VALUE, Ingredient.TagValue.CODEC) + .xmap( + (either) -> either.map((itemValue) -> itemValue, (tagValue) -> tagValue), + (value) -> { + if (value instanceof Ingredient.TagValue tagValue) { + return Either.right(tagValue); + } else if (value instanceof Ingredient.ItemValue itemValue) { + return Either.left(itemValue); + } else { + throw new UnsupportedOperationException( + "This is neither an nbt-item value nor a tag value."); + } + } + ); private static Codec ingredientCodec(boolean allowEmpty) { - record NbtItemValue(ItemStack item) implements Ingredient.Value { - static final Codec CODEC = RecordCodecBuilder.create((instance) -> instance - .group(CODEC_ITEM_STACK_WITH_NBT.fieldOf("item").forGetter((itemValue) -> itemValue.item)) - .apply(instance, NbtItemValue::new)); - - public boolean equals(Object object) { - if (object instanceof NbtItemValue itemValue) { - return ItemStack.isSameItemSameTags(itemValue.item, this.item) - && itemValue.item.getCount() == this.item.getCount(); - } else if (object instanceof Ingredient.ItemValue itemValue) { - return ItemStack.isSameItemSameTags(itemValue.item(), this.item) - && itemValue.item().getCount() == this.item.getCount(); - } else { - return false; - } - } - - public Collection getItems() { - return Collections.singleton(this.item); - } - - public ItemStack item() { - return this.item; - } - } - - Codec VALUE_CODEC = ExtraCodecs - .xor(NbtItemValue.CODEC, Ingredient.TagValue.CODEC) - .xmap( - (either) -> either.map((itemValue) -> itemValue, (tagValue) -> tagValue), - (value) -> { - if (value instanceof Ingredient.TagValue tagValue) { - return Either.right(tagValue); - } else if (value instanceof NbtItemValue itemValue) { - return Either.left(itemValue); - } else { - throw new UnsupportedOperationException( - "This is neither an nbt-item value nor a tag value."); - } - } - ); - - - Codec codec = Codec.list(VALUE_CODEC).comapFlatMap((list) -> - !allowEmpty && list.size() < 1 + Codec LIST_CODEC = Codec.list(VALUE_CODEC).comapFlatMap((list) -> + !allowEmpty && list.isEmpty() ? DataResult.error(() -> "Item array cannot be empty, at least one item must be defined") : DataResult.success(list.toArray(new Ingredient.Value[0])) , List::of); - return ExtraCodecs.either(codec, VALUE_CODEC).flatComapMap( + return ExtraCodecs.either(LIST_CODEC, VALUE_CODEC).flatComapMap( (either) -> either.map(Ingredient::new, (value) -> new Ingredient(new Ingredient.Value[]{value})), (ingredient) -> { if (ingredient.values.length == 1) { @@ -126,4 +97,7 @@ public class ItemUtil { } ); } + + public static Codec CODEC_INGREDIENT_WITH_NBT = ingredientCodec(true); + public static Codec CODEC_INGREDIENT_WITH_NBT_NOT_EMPTY = ingredientCodec(false); } diff --git a/src/main/resources/bclib.accesswidener b/src/main/resources/bclib.accesswidener index e9fa1658..f7da6a43 100644 --- a/src/main/resources/bclib.accesswidener +++ b/src/main/resources/bclib.accesswidener @@ -1,7 +1,7 @@ accessWidener v1 named # Classes -accessible class net/minecraft/server/MinecraftServer$ReloadableResources +accessible class net/minecraft/server/MinecraftServer$ReloadableResources accessible class net/minecraft/world/level/levelgen/SurfaceRules$Context accessible class net/minecraft/world/level/levelgen/SurfaceRules$Condition accessible class net/minecraft/world/level/levelgen/SurfaceRules$SurfaceRule @@ -41,6 +41,7 @@ accessible method net/minecraft/world/level/levelgen/structure/pools/SinglePoolE accessible method net/minecraft/world/level/levelgen/structure/pools/LegacySinglePoolElement (Lcom/mojang/datafixers/util/Either;Lnet/minecraft/core/Holder;Lnet/minecraft/world/level/levelgen/structure/pools/StructureTemplatePool$Projection;)V accessible method net/minecraft/world/item/crafting/Ingredient ([Lnet/minecraft/world/item/crafting/Ingredient$Value;)V accessible method net/minecraft/world/item/crafting/Ingredient$TagValue (Lnet/minecraft/tags/TagKey;)V +accessible method net/minecraft/world/item/crafting/Ingredient$ItemValue (Lnet/minecraft/world/item/ItemStack;)V #Fields accessible field net/minecraft/world/entity/ai/village/poi/PoiTypes TYPE_BY_STATE Ljava/util/Map;