133 lines
4.5 KiB
Java
133 lines
4.5 KiB
Java
package net.minecraft.world.item.crafting;
|
|
|
|
import com.mojang.serialization.Codec;
|
|
import com.mojang.serialization.DataResult;
|
|
import com.mojang.serialization.MapCodec;
|
|
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
|
import net.minecraft.core.HolderLookup;
|
|
import net.minecraft.core.NonNullList;
|
|
import net.minecraft.network.RegistryFriendlyByteBuf;
|
|
import net.minecraft.network.codec.StreamCodec;
|
|
import net.minecraft.world.item.ItemStack;
|
|
import net.minecraft.world.level.Level;
|
|
|
|
public class ShapelessRecipe implements CraftingRecipe {
|
|
final String group;
|
|
final CraftingBookCategory category;
|
|
final ItemStack result;
|
|
final NonNullList<Ingredient> ingredients;
|
|
|
|
public ShapelessRecipe(String group, CraftingBookCategory category, ItemStack result, NonNullList<Ingredient> ingredients) {
|
|
this.group = group;
|
|
this.category = category;
|
|
this.result = result;
|
|
this.ingredients = ingredients;
|
|
}
|
|
|
|
@Override
|
|
public RecipeSerializer<?> getSerializer() {
|
|
return RecipeSerializer.SHAPELESS_RECIPE;
|
|
}
|
|
|
|
@Override
|
|
public String getGroup() {
|
|
return this.group;
|
|
}
|
|
|
|
@Override
|
|
public CraftingBookCategory category() {
|
|
return this.category;
|
|
}
|
|
|
|
@Override
|
|
public ItemStack getResultItem(HolderLookup.Provider registries) {
|
|
return this.result;
|
|
}
|
|
|
|
@Override
|
|
public NonNullList<Ingredient> getIngredients() {
|
|
return this.ingredients;
|
|
}
|
|
|
|
public boolean matches(CraftingInput input, Level level) {
|
|
if (input.ingredientCount() != this.ingredients.size()) {
|
|
return false;
|
|
} else {
|
|
return input.size() == 1 && this.ingredients.size() == 1
|
|
? ((Ingredient)this.ingredients.getFirst()).test(input.getItem(0))
|
|
: input.stackedContents().canCraft(this, null);
|
|
}
|
|
}
|
|
|
|
public ItemStack assemble(CraftingInput input, HolderLookup.Provider registries) {
|
|
return this.result.copy();
|
|
}
|
|
|
|
@Override
|
|
public boolean canCraftInDimensions(int width, int height) {
|
|
return width * height >= this.ingredients.size();
|
|
}
|
|
|
|
public static class Serializer implements RecipeSerializer<ShapelessRecipe> {
|
|
private static final MapCodec<ShapelessRecipe> CODEC = RecordCodecBuilder.mapCodec(
|
|
instance -> instance.group(
|
|
Codec.STRING.optionalFieldOf("group", "").forGetter(shapelessRecipe -> shapelessRecipe.group),
|
|
CraftingBookCategory.CODEC.fieldOf("category").orElse(CraftingBookCategory.MISC).forGetter(shapelessRecipe -> shapelessRecipe.category),
|
|
ItemStack.STRICT_CODEC.fieldOf("result").forGetter(shapelessRecipe -> shapelessRecipe.result),
|
|
Ingredient.CODEC_NONEMPTY
|
|
.listOf()
|
|
.fieldOf("ingredients")
|
|
.flatXmap(
|
|
list -> {
|
|
Ingredient[] ingredients = (Ingredient[])list.stream().filter(ingredient -> !ingredient.isEmpty()).toArray(Ingredient[]::new);
|
|
if (ingredients.length == 0) {
|
|
return DataResult.error(() -> "No ingredients for shapeless recipe");
|
|
} else {
|
|
return ingredients.length > 9
|
|
? DataResult.error(() -> "Too many ingredients for shapeless recipe")
|
|
: DataResult.success(NonNullList.of(Ingredient.EMPTY, ingredients));
|
|
}
|
|
},
|
|
DataResult::success
|
|
)
|
|
.forGetter(shapelessRecipe -> shapelessRecipe.ingredients)
|
|
)
|
|
.apply(instance, ShapelessRecipe::new)
|
|
);
|
|
public static final StreamCodec<RegistryFriendlyByteBuf, ShapelessRecipe> STREAM_CODEC = StreamCodec.of(
|
|
ShapelessRecipe.Serializer::toNetwork, ShapelessRecipe.Serializer::fromNetwork
|
|
);
|
|
|
|
@Override
|
|
public MapCodec<ShapelessRecipe> codec() {
|
|
return CODEC;
|
|
}
|
|
|
|
@Override
|
|
public StreamCodec<RegistryFriendlyByteBuf, ShapelessRecipe> streamCodec() {
|
|
return STREAM_CODEC;
|
|
}
|
|
|
|
private static ShapelessRecipe fromNetwork(RegistryFriendlyByteBuf buffer) {
|
|
String string = buffer.readUtf();
|
|
CraftingBookCategory craftingBookCategory = buffer.readEnum(CraftingBookCategory.class);
|
|
int i = buffer.readVarInt();
|
|
NonNullList<Ingredient> nonNullList = NonNullList.withSize(i, Ingredient.EMPTY);
|
|
nonNullList.replaceAll(ingredient -> Ingredient.CONTENTS_STREAM_CODEC.decode(buffer));
|
|
ItemStack itemStack = ItemStack.STREAM_CODEC.decode(buffer);
|
|
return new ShapelessRecipe(string, craftingBookCategory, itemStack, nonNullList);
|
|
}
|
|
|
|
private static void toNetwork(RegistryFriendlyByteBuf buffer, ShapelessRecipe recipe) {
|
|
buffer.writeUtf(recipe.group);
|
|
buffer.writeEnum(recipe.category);
|
|
buffer.writeVarInt(recipe.ingredients.size());
|
|
|
|
for (Ingredient ingredient : recipe.ingredients) {
|
|
Ingredient.CONTENTS_STREAM_CODEC.encode(buffer, ingredient);
|
|
}
|
|
|
|
ItemStack.STREAM_CODEC.encode(buffer, recipe.result);
|
|
}
|
|
}
|
|
}
|