[Change] Recipes use Codecs for Serialization now
This commit is contained in:
parent
7e06e9ce3f
commit
7a972fc22f
4 changed files with 162 additions and 160 deletions
|
@ -5,13 +5,14 @@ import org.betterx.bclib.interfaces.AlloyingRecipeWorkstation;
|
|||
import org.betterx.bclib.interfaces.UnknownReceipBookCategory;
|
||||
import org.betterx.bclib.util.ItemUtil;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||
import net.minecraft.core.NonNullList;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.tags.TagKey;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
|
@ -25,9 +26,10 @@ import net.minecraft.world.level.Level;
|
|||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class AlloyingRecipe implements Recipe<Container>, UnknownReceipBookCategory {
|
||||
public final static String GROUP = "alloying";
|
||||
public final static RecipeType<AlloyingRecipe> TYPE = BCLRecipeManager.registerType(BCLib.MOD_ID, GROUP);
|
||||
|
@ -38,7 +40,6 @@ public class AlloyingRecipe implements Recipe<Container>, UnknownReceipBookCateg
|
|||
);
|
||||
|
||||
protected final RecipeType<?> type;
|
||||
protected final ResourceLocation id;
|
||||
protected final Ingredient primaryInput;
|
||||
protected final Ingredient secondaryInput;
|
||||
protected final ItemStack output;
|
||||
|
@ -47,7 +48,23 @@ public class AlloyingRecipe implements Recipe<Container>, UnknownReceipBookCateg
|
|||
protected final int smeltTime;
|
||||
|
||||
public AlloyingRecipe(
|
||||
ResourceLocation id,
|
||||
List<Ingredient> inputs,
|
||||
String group,
|
||||
ItemStack output,
|
||||
float experience,
|
||||
int smeltTime
|
||||
) {
|
||||
this(
|
||||
group,
|
||||
!inputs.isEmpty() ? inputs.get(0) : null,
|
||||
inputs.size() > 1 ? inputs.get(1) : null,
|
||||
output,
|
||||
experience,
|
||||
smeltTime
|
||||
);
|
||||
}
|
||||
|
||||
public AlloyingRecipe(
|
||||
String group,
|
||||
Ingredient primaryInput,
|
||||
Ingredient secondaryInput,
|
||||
|
@ -56,7 +73,6 @@ public class AlloyingRecipe implements Recipe<Container>, UnknownReceipBookCateg
|
|||
int smeltTime
|
||||
) {
|
||||
this.group = group;
|
||||
this.id = id;
|
||||
this.primaryInput = primaryInput;
|
||||
this.secondaryInput = secondaryInput;
|
||||
this.output = output;
|
||||
|
@ -103,11 +119,6 @@ public class AlloyingRecipe implements Recipe<Container>, UnknownReceipBookCateg
|
|||
return this.output;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RecipeSerializer<?> getSerializer() {
|
||||
return SERIALIZER;
|
||||
|
@ -209,27 +220,19 @@ public class AlloyingRecipe implements Recipe<Container>, UnknownReceipBookCateg
|
|||
}
|
||||
|
||||
public static class Serializer implements RecipeSerializer<AlloyingRecipe> {
|
||||
@Override
|
||||
public AlloyingRecipe fromJson(ResourceLocation id, JsonObject json) {
|
||||
JsonArray ingredients = GsonHelper.getAsJsonArray(json, "ingredients");
|
||||
Ingredient primaryInput = Ingredient.fromJson(ingredients.get(0));
|
||||
Ingredient secondaryInput = Ingredient.fromJson(ingredients.get(1));
|
||||
|
||||
String group = GsonHelper.getAsString(json, "group", "");
|
||||
|
||||
JsonObject result = GsonHelper.getAsJsonObject(json, "result");
|
||||
ItemStack output = ItemUtil.fromJsonRecipeWithNBT(result);
|
||||
if (output == null) {
|
||||
throw new IllegalStateException("Output item does not exists!");
|
||||
}
|
||||
float experience = GsonHelper.getAsFloat(json, "experience", 0.0F);
|
||||
int smeltTime = GsonHelper.getAsInt(json, "smelttime", 350);
|
||||
|
||||
return new AlloyingRecipe(id, group, primaryInput, secondaryInput, output, experience, smeltTime);
|
||||
}
|
||||
public static final Codec<AlloyingRecipe> CODEC = RecordCodecBuilder.create(instance -> instance.group(
|
||||
Codec.list(Ingredient.CODEC_NONEMPTY)
|
||||
.fieldOf("ingredients")
|
||||
.forGetter(recipe -> List.of(recipe.primaryInput, recipe.secondaryInput)),
|
||||
Codec.STRING.optionalFieldOf("group", "")
|
||||
.forGetter(recipe -> 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)
|
||||
).apply(instance, AlloyingRecipe::new));
|
||||
|
||||
@Override
|
||||
public AlloyingRecipe fromNetwork(ResourceLocation id, FriendlyByteBuf packetBuffer) {
|
||||
public AlloyingRecipe fromNetwork(FriendlyByteBuf packetBuffer) {
|
||||
String group = packetBuffer.readUtf(32767);
|
||||
Ingredient primary = Ingredient.fromNetwork(packetBuffer);
|
||||
Ingredient secondary = Ingredient.fromNetwork(packetBuffer);
|
||||
|
@ -237,7 +240,12 @@ public class AlloyingRecipe implements Recipe<Container>, UnknownReceipBookCateg
|
|||
float experience = packetBuffer.readFloat();
|
||||
int smeltTime = packetBuffer.readVarInt();
|
||||
|
||||
return new AlloyingRecipe(id, group, primary, secondary, output, experience, smeltTime);
|
||||
return new AlloyingRecipe(group, primary, secondary, output, experience, smeltTime);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Codec<AlloyingRecipe> codec() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -6,6 +6,8 @@ import org.betterx.bclib.util.ItemUtil;
|
|||
import org.betterx.worlds.together.tag.v3.CommonItemTags;
|
||||
import org.betterx.worlds.together.world.event.WorldBootstrap;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.NonNullList;
|
||||
|
@ -16,7 +18,6 @@ import net.minecraft.nbt.CompoundTag;
|
|||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.tags.TagKey;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
|
@ -53,7 +54,6 @@ public class AnvilRecipe implements Recipe<Container>, UnknownReceipBookCategory
|
|||
//we call this to make sure that TYPE is initialized
|
||||
}
|
||||
|
||||
private final ResourceLocation id;
|
||||
private final Ingredient input;
|
||||
private final ItemStack output;
|
||||
private final int damage;
|
||||
|
@ -62,7 +62,6 @@ public class AnvilRecipe implements Recipe<Container>, UnknownReceipBookCategory
|
|||
private final int inputCount;
|
||||
|
||||
public AnvilRecipe(
|
||||
ResourceLocation identifier,
|
||||
Ingredient input,
|
||||
ItemStack output,
|
||||
int inputCount,
|
||||
|
@ -70,7 +69,6 @@ public class AnvilRecipe implements Recipe<Container>, UnknownReceipBookCategory
|
|||
int anvilLevel,
|
||||
int damage
|
||||
) {
|
||||
this.id = identifier;
|
||||
this.input = input;
|
||||
this.output = output;
|
||||
this.toolLevel = toolLevel;
|
||||
|
@ -214,11 +212,6 @@ public class AnvilRecipe implements Recipe<Container>, UnknownReceipBookCategory
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RecipeType<?> getType() {
|
||||
return TYPE;
|
||||
|
@ -234,18 +227,25 @@ public class AnvilRecipe implements Recipe<Container>, UnknownReceipBookCategory
|
|||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
AnvilRecipe that = (AnvilRecipe) o;
|
||||
return damage == that.damage && toolLevel == that.toolLevel && id.equals(that.id) && input.equals(that.input) && output.equals(
|
||||
that.output);
|
||||
return damage == that.damage && toolLevel == that.toolLevel && input.equals(that.input) && output.equals(that.output);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id, input, output, damage, toolLevel);
|
||||
return Objects.hash(input, output, damage, toolLevel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "AnvilRecipe [" + id + "]";
|
||||
final StringBuffer sb = new StringBuffer("AnvilRecipe{");
|
||||
sb.append("input=").append(input);
|
||||
sb.append(", output=").append(output);
|
||||
sb.append(", damage=").append(damage);
|
||||
sb.append(", toolLevel=").append(toolLevel);
|
||||
sb.append(", anvilLevel=").append(anvilLevel);
|
||||
sb.append(", inputCount=").append(inputCount);
|
||||
sb.append('}');
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static class Builder extends AbstractSingleInputRecipeBuilder<Builder, AnvilRecipe> {
|
||||
|
@ -357,25 +357,23 @@ public class AnvilRecipe implements Recipe<Container>, UnknownReceipBookCategory
|
|||
}
|
||||
|
||||
public static class Serializer implements RecipeSerializer<AnvilRecipe> {
|
||||
@Override
|
||||
public AnvilRecipe fromJson(ResourceLocation id, JsonObject json) {
|
||||
Ingredient input = Ingredient.fromJson(json.get("input"));
|
||||
JsonObject result = GsonHelper.getAsJsonObject(json, "result");
|
||||
ItemStack output = ItemUtil.fromJsonRecipeWithNBT(result);
|
||||
if (output == null) {
|
||||
throw new IllegalStateException("Output item does not exists!");
|
||||
}
|
||||
|
||||
int inputCount = GsonHelper.getAsInt(json, "inputCount", 1);
|
||||
int toolLevel = GsonHelper.getAsInt(json, "toolLevel", 1);
|
||||
int anvilLevel = GsonHelper.getAsInt(json, "anvilLevel", 1);
|
||||
int damage = GsonHelper.getAsInt(json, "damage", 1);
|
||||
|
||||
return new AnvilRecipe(id, input, output, inputCount, toolLevel, anvilLevel, damage);
|
||||
}
|
||||
public static Codec<AnvilRecipe> CODEC = RecordCodecBuilder.create(instance -> instance.group(
|
||||
Ingredient.CODEC_NONEMPTY.fieldOf("input").forGetter(recipe -> recipe.input),
|
||||
ItemUtil.CODEC_ITEM_STACK_WITH_NBT.fieldOf("result").forGetter(recipe -> recipe.output),
|
||||
Codec.INT.fieldOf("inputCount").forGetter(recipe -> recipe.inputCount),
|
||||
Codec.INT.fieldOf("toolLevel").forGetter(recipe -> recipe.toolLevel),
|
||||
Codec.INT.fieldOf("anvilLevel").forGetter(recipe -> recipe.anvilLevel),
|
||||
Codec.INT.fieldOf("damage").forGetter(recipe -> recipe.damage)
|
||||
).apply(instance, AnvilRecipe::new));
|
||||
|
||||
@Override
|
||||
public AnvilRecipe fromNetwork(ResourceLocation id, FriendlyByteBuf packetBuffer) {
|
||||
public Codec<AnvilRecipe> codec() {
|
||||
return CODEC;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public AnvilRecipe fromNetwork(FriendlyByteBuf packetBuffer) {
|
||||
Ingredient input = Ingredient.fromNetwork(packetBuffer);
|
||||
ItemStack output = packetBuffer.readItem();
|
||||
int inputCount = packetBuffer.readVarInt();
|
||||
|
@ -383,7 +381,7 @@ public class AnvilRecipe implements Recipe<Container>, UnknownReceipBookCategory
|
|||
int anvilLevel = packetBuffer.readVarInt();
|
||||
int damage = packetBuffer.readVarInt();
|
||||
|
||||
return new AnvilRecipe(id, input, output, inputCount, toolLevel, anvilLevel, damage);
|
||||
return new AnvilRecipe(input, output, inputCount, toolLevel, anvilLevel, damage);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -2,26 +2,28 @@ package org.betterx.bclib.util;
|
|||
|
||||
import org.betterx.bclib.BCLib;
|
||||
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import com.mojang.datafixers.util.Either;
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.DataResult;
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.TagParser;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
import net.minecraft.util.ExtraCodecs;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.crafting.Ingredient;
|
||||
import net.minecraft.world.level.ItemLike;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class ItemUtil {
|
||||
@Nullable
|
||||
public static ItemStack fromStackString(String stackString) {
|
||||
if (stackString == null || stackString.equals("")) {
|
||||
if (stackString == null || stackString.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
|
@ -29,112 +31,99 @@ public class ItemUtil {
|
|||
if (parts.length < 2) return null;
|
||||
if (parts.length == 2) {
|
||||
ResourceLocation itemId = new ResourceLocation(stackString);
|
||||
Item item = BuiltInRegistries.ITEM.getOptional(itemId).orElseThrow(() -> {
|
||||
return new IllegalStateException("Output item " + itemId + " does not exists!");
|
||||
});
|
||||
Item item = BuiltInRegistries
|
||||
.ITEM
|
||||
.getOptional(itemId)
|
||||
.orElseThrow(() -> new IllegalStateException("Output item " + itemId + " does not exists!"));
|
||||
return new ItemStack(item);
|
||||
}
|
||||
ResourceLocation itemId = new ResourceLocation(parts[0], parts[1]);
|
||||
Item item = BuiltInRegistries.ITEM.getOptional(itemId)
|
||||
Item item = BuiltInRegistries
|
||||
.ITEM
|
||||
.getOptional(itemId)
|
||||
.orElseThrow(() -> new IllegalStateException("Output item " + itemId + " does not exists!"));
|
||||
return new ItemStack(item, Integer.valueOf(parts[2]));
|
||||
return new ItemStack(item, Integer.parseInt(parts[2]));
|
||||
} catch (Exception ex) {
|
||||
BCLib.LOGGER.error("ItemStack deserialization error!", ex);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static CompoundTag readNBT(JsonObject recipe) {
|
||||
if (recipe.has("nbt")) {
|
||||
try {
|
||||
String nbtData = GsonHelper.getAsString(recipe, "nbt");
|
||||
CompoundTag nbt = TagParser.parseTag(nbtData);
|
||||
return nbt;
|
||||
} catch (CommandSyntaxException ex) {
|
||||
BCLib.LOGGER.warning("Error parsing nbt data for output.", ex);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public static Codec<ItemStack> CODEC_ITEM_STACK_WITH_NBT = RecordCodecBuilder.create((instance) -> instance.group(
|
||||
BuiltInRegistries.ITEM.holderByNameCodec()
|
||||
.fieldOf("item")
|
||||
.forGetter(ItemStack::getItemHolder),
|
||||
Codec.INT.optionalFieldOf("count", 1)
|
||||
.forGetter(ItemStack::getCount),
|
||||
ExtraCodecs.strictOptionalField(TagParser.AS_CODEC, "nbt")
|
||||
.forGetter((itemStack) -> Optional.ofNullable(itemStack.getTag()))
|
||||
).apply(instance, ItemStack::new));
|
||||
|
||||
public static void writeNBT(JsonObject root, CompoundTag nbt) {
|
||||
if (nbt != null) {
|
||||
final String nbtData = nbt.toString();
|
||||
root.addProperty("nbt", nbtData);
|
||||
public static Codec<Ingredient> CODEC_INGREDIENT_WITH_NBT = ingredientCodec(true);
|
||||
public static Codec<Ingredient> CODEC_INGREDIENT_WITH_NBT_NOT_EMPTY = ingredientCodec(false);
|
||||
|
||||
|
||||
private static Codec<Ingredient> ingredientCodec(boolean allowEmpty) {
|
||||
record NbtItemValue(ItemStack item) implements Ingredient.Value {
|
||||
static final Codec<NbtItemValue> 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 static Ingredient fromJsonIngredientWithNBT(JsonObject ingredient) {
|
||||
Ingredient ing = Ingredient.fromJson(ingredient);
|
||||
CompoundTag nbt = readNBT(ingredient);
|
||||
if (nbt != null && !ing.isEmpty()) {
|
||||
ing.getItems()[0].setTag(nbt);
|
||||
}
|
||||
return ing;
|
||||
public Collection<ItemStack> getItems() {
|
||||
return Collections.singleton(this.item);
|
||||
}
|
||||
|
||||
public static ItemStack fromJsonRecipeWithNBT(JsonObject recipe) {
|
||||
ItemStack output = ItemUtil.fromJsonRecipe(recipe);
|
||||
CompoundTag nbt = ItemUtil.readNBT(recipe);
|
||||
if (output != null && nbt != null) {
|
||||
output.setTag(nbt);
|
||||
public ItemStack item() {
|
||||
return this.item;
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static ItemStack fromJsonRecipe(JsonObject recipe) {
|
||||
try {
|
||||
if (!recipe.has("item")) {
|
||||
throw new IllegalStateException("Invalid JsonObject. Entry 'item' does not exists!");
|
||||
Codec<Ingredient.Value> 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.");
|
||||
}
|
||||
ResourceLocation itemId = new ResourceLocation(GsonHelper.getAsString(recipe, "item"));
|
||||
Item item = BuiltInRegistries.ITEM.getOptional(itemId).orElseThrow(() -> {
|
||||
return new IllegalStateException("Output item " + itemId + " does not exists!");
|
||||
});
|
||||
int count = GsonHelper.getAsInt(recipe, "count", 1);
|
||||
return new ItemStack(item, count);
|
||||
} catch (Exception ex) {
|
||||
BCLib.LOGGER.error("ItemStack deserialization error!", ex);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static JsonElement toJsonIngredientWithNBT(Ingredient ing) {
|
||||
JsonElement el = ing.toJson();
|
||||
if (el.isJsonObject() && !ing.isEmpty() && ing.getItems()[0].hasTag()) {
|
||||
JsonObject obj = el.getAsJsonObject();
|
||||
writeNBT(obj, ing.getItems()[0].getTag());
|
||||
}
|
||||
return el;
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
public static JsonObject toJsonRecipeWithNBT(ItemStack stack) {
|
||||
return toJsonRecipeWithNBT(stack.getItem(), stack.getCount(), stack.getTag());
|
||||
}
|
||||
Codec<Ingredient.Value[]> codec = Codec.list(VALUE_CODEC).comapFlatMap((list) ->
|
||||
!allowEmpty && list.size() < 1
|
||||
? DataResult.error(() -> "Item array cannot be empty, at least one item must be defined")
|
||||
: DataResult.success(list.toArray(new Ingredient.Value[0]))
|
||||
, List::of);
|
||||
|
||||
public static JsonObject toJsonRecipeWithNBT(ItemLike item, int count, CompoundTag nbt) {
|
||||
JsonObject root = toJsonRecipe(item, count);
|
||||
writeNBT(root, nbt);
|
||||
return root;
|
||||
}
|
||||
|
||||
public static JsonObject toJsonRecipe(ItemStack stack) {
|
||||
return toJsonRecipe(stack.getItem(), stack.getCount());
|
||||
}
|
||||
|
||||
public static JsonObject toJsonRecipe(ItemLike item, int count) {
|
||||
final ResourceLocation id = BuiltInRegistries.ITEM.getKey(item.asItem());
|
||||
if (id == null) {
|
||||
throw new IllegalStateException("Unknown Item " + item);
|
||||
}
|
||||
|
||||
final JsonObject root = new JsonObject();
|
||||
root.addProperty("item", BuiltInRegistries.ITEM.getKey(item.asItem()).toString());
|
||||
if (count > 1) {
|
||||
root.addProperty("count", count);
|
||||
}
|
||||
return root;
|
||||
return ExtraCodecs.either(codec, VALUE_CODEC).flatComapMap(
|
||||
(either) -> either.map(Ingredient::new, (value) -> new Ingredient(new Ingredient.Value[]{value})),
|
||||
(ingredient) -> {
|
||||
if (ingredient.values.length == 1) {
|
||||
return DataResult.success(Either.right(ingredient.values[0]));
|
||||
} else {
|
||||
return ingredient.values.length == 0 && !allowEmpty
|
||||
? DataResult.error(() -> "Item array cannot be empty, at least one item must be defined")
|
||||
: DataResult.success(Either.left(ingredient.values));
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,9 @@ accessible class net/minecraft/client/resources/model/AtlasSet$AtlasEntry
|
|||
extendable class net/minecraft/world/level/block/state/properties/WoodType
|
||||
accessible class net/minecraft/world/level/levelgen/SurfaceRules$BiomeConditionSource
|
||||
accessible class net/minecraft/world/level/levelgen/SurfaceRules$TestRuleSource
|
||||
accessible class net/minecraft/world/item/crafting/Ingredient$Value
|
||||
accessible class net/minecraft/world/item/crafting/Ingredient$TagValue
|
||||
accessible class net/minecraft/world/item/crafting/Ingredient$ItemValue
|
||||
|
||||
#Methods
|
||||
accessible method net/minecraft/world/level/storage/loot/LootPool <init> (Ljava/util/List;Ljava/util/List;Ljava/util/List;Lnet/minecraft/world/level/storage/loot/providers/number/NumberProvider;Lnet/minecraft/world/level/storage/loot/providers/number/NumberProvider;)V
|
||||
|
@ -36,7 +39,11 @@ accessible method net/minecraft/world/level/block/Blocks never (Lnet/minecraft/w
|
|||
accessible method net/minecraft/world/level/block/Blocks never (Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/BlockGetter;Lnet/minecraft/core/BlockPos;)Z
|
||||
accessible method net/minecraft/world/level/levelgen/structure/pools/SinglePoolElement <init> (Lcom/mojang/datafixers/util/Either;Lnet/minecraft/core/Holder;Lnet/minecraft/world/level/levelgen/structure/pools/StructureTemplatePool$Projection;)V
|
||||
accessible method net/minecraft/world/level/levelgen/structure/pools/LegacySinglePoolElement <init> (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 <init> ([Lnet/minecraft/world/item/crafting/Ingredient$Value;)V
|
||||
accessible method net/minecraft/world/item/crafting/Ingredient$TagValue <init> (Lnet/minecraft/tags/TagKey;)V
|
||||
|
||||
#Fields
|
||||
accessible field net/minecraft/world/entity/ai/village/poi/PoiTypes TYPE_BY_STATE Ljava/util/Map;
|
||||
accessible field net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity lootTable Lnet/minecraft/resources/ResourceLocation;
|
||||
accessible field net/minecraft/world/item/crafting/Ingredient values [Lnet/minecraft/world/item/crafting/Ingredient$Value;
|
||||
accessible field net/minecraft/world/item/crafting/Ingredient$TagValue CODEC Lcom/mojang/serialization/Codec;
|
Loading…
Add table
Add a link
Reference in a new issue