Start on recipe serde rewrite

This commit is contained in:
modmuss50 2021-12-19 13:44:46 +00:00
parent 5eab27bead
commit 47eea962a0
17 changed files with 411 additions and 229 deletions

View file

@ -9,3 +9,6 @@ indent_style = tab
[*.json] [*.json]
indent_style = tab indent_style = tab
[*.groovy]
indent_style = tab

View file

@ -24,17 +24,12 @@
package reborncore.common.crafting; package reborncore.common.crafting;
import com.google.gson.JsonObject;
import net.minecraft.block.entity.BlockEntity; import net.minecraft.block.entity.BlockEntity;
import net.minecraft.fluid.Fluid;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.util.JsonHelper;
import net.minecraft.util.collection.DefaultedList; import net.minecraft.util.collection.DefaultedList;
import net.minecraft.util.registry.Registry;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import reborncore.common.crafting.ingredient.RebornIngredient; import reborncore.common.crafting.ingredient.RebornIngredient;
import reborncore.common.fluid.FluidValue;
import reborncore.common.fluid.container.FluidInstance; import reborncore.common.fluid.container.FluidInstance;
import reborncore.common.util.Tank; import reborncore.common.util.Tank;
@ -56,35 +51,6 @@ public abstract class RebornFluidRecipe extends RebornRecipe {
this.fluidInstance = fluidInstance; this.fluidInstance = fluidInstance;
} }
@Override
public void deserialize(JsonObject jsonObject) {
super.deserialize(jsonObject);
if(jsonObject.has("tank")){
JsonObject tank = jsonObject.get("tank").getAsJsonObject();
Identifier identifier = new Identifier(JsonHelper.getString(tank, "fluid"));
Fluid fluid = Registry.FLUID.get(identifier);
FluidValue value = FluidValue.BUCKET;
if(tank.has("amount")){
value = FluidValue.parseFluidValue(tank.get("amount"));
}
fluidInstance = new FluidInstance(fluid, value);
}
}
@Override
public void serialize(JsonObject jsonObject) {
super.serialize(jsonObject);
JsonObject tankObject = new JsonObject();
tankObject.addProperty("fluid", Registry.FLUID.getId(fluidInstance.getFluid()).toString());
tankObject.addProperty("value", fluidInstance.getAmount().getRawValue());
jsonObject.add("tank", tankObject);
}
public abstract Tank getTank(BlockEntity be); public abstract Tank getTank(BlockEntity be);
@Override @Override

View file

@ -30,6 +30,7 @@ import com.mojang.serialization.Dynamic;
import com.mojang.serialization.JsonOps; import com.mojang.serialization.JsonOps;
import io.github.cottonmc.libcd.api.CustomOutputRecipe; import io.github.cottonmc.libcd.api.CustomOutputRecipe;
import net.minecraft.block.entity.BlockEntity; import net.minecraft.block.entity.BlockEntity;
import net.minecraft.data.server.recipe.RecipeJsonProvider;
import net.minecraft.inventory.Inventory; import net.minecraft.inventory.Inventory;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
@ -61,79 +62,33 @@ public class RebornRecipe implements Recipe<Inventory>, CustomOutputRecipe {
private final RebornRecipeType<?> type; private final RebornRecipeType<?> type;
private final Identifier name; private final Identifier name;
private DefaultedList<RebornIngredient> ingredients = DefaultedList.of(); private final List<RebornIngredient> ingredients;
private DefaultedList<ItemStack> outputs = DefaultedList.of(); private final List<ItemStack> outputs;
protected int power; protected final int power;
protected int time; protected final int time;
protected boolean dummy = false; protected boolean dummy = false;
public RebornRecipe(RebornRecipeType<?> type, Identifier name) { public RebornRecipe(RebornRecipeType<?> type, Identifier name, List<RebornIngredient> ingredients, List<ItemStack> outputs, int power, int time) {
this.type = type; this.type = type;
this.name = name; this.name = name;
}
public RebornRecipe(RebornRecipeType<?> type, Identifier name, DefaultedList<RebornIngredient> ingredients, DefaultedList<ItemStack> outputs, int power, int time) {
this(type, name);
this.ingredients = ingredients; this.ingredients = ingredients;
this.outputs = outputs; this.outputs = outputs;
this.power = power; this.power = power;
this.time = time; this.time = time;
} }
public void deserialize(JsonObject jsonObject) { public RebornRecipe(RebornRecipeType<?> type, Identifier name) {
if (jsonObject.has("dummy")) { this(type, name, List.of(new DummyIngredient()), Collections.emptyList(), Integer.MAX_VALUE, Integer.MAX_VALUE);
makeDummy(); this.dummy = true;
return;
}
//Crash if the recipe has all ready been deserialized
Validate.isTrue(ingredients.isEmpty());
power = JsonHelper.getInt(jsonObject, "power");
time = JsonHelper.getInt(jsonObject, "time");
ingredients = SerializationUtil.stream(JsonHelper.getArray(jsonObject, "ingredients"))
.map(IngredientManager::deserialize)
.collect(DefaultedListCollector.toList());
JsonArray resultsJson = JsonHelper.getArray(jsonObject, "results");
outputs = RecipeUtils.deserializeItems(resultsJson);
}
public void serialize(JsonObject jsonObject) {
if (isDummy()) {
jsonObject.addProperty("dummy", true);
return;
}
jsonObject.addProperty("power", power);
jsonObject.addProperty("time", time);
JsonArray ingredientsArray = new JsonArray();
getRebornIngredients().stream().map(RebornIngredient::witeToJson).forEach(ingredientsArray::add);
jsonObject.add("ingredients", ingredientsArray);
JsonArray resultsArray = new JsonArray();
for (ItemStack stack : outputs) {
JsonObject stackObject = new JsonObject();
stackObject.addProperty("item", Registry.ITEM.getId(stack.getItem()).toString());
if (stack.getCount() > 1) {
stackObject.addProperty("count", stack.getCount());
}
if (stack.hasNbt()) {
stackObject.add("nbt", Dynamic.convert(NbtOps.INSTANCE, JsonOps.INSTANCE, stack.getNbt()));
}
resultsArray.add(stackObject);
}
jsonObject.add("results", resultsArray);
} }
public void serialize(PacketByteBuf byteBuf) { public void serialize(PacketByteBuf byteBuf) {
throw new UnsupportedOperationException();
} }
public void deserialize(PacketByteBuf byteBuf) { public void deserialize(PacketByteBuf byteBuf) {
throw new UnsupportedOperationException();
} }
@Override @Override
@ -162,7 +117,7 @@ public class RebornRecipe implements Recipe<Inventory>, CustomOutputRecipe {
return ingredients.stream().map(RebornIngredient::getPreview).collect(DefaultedListCollector.toList()); return ingredients.stream().map(RebornIngredient::getPreview).collect(DefaultedListCollector.toList());
} }
public DefaultedList<RebornIngredient> getRebornIngredients() { public List<RebornIngredient> getRebornIngredients() {
return ingredients; return ingredients;
} }
@ -241,15 +196,10 @@ public class RebornRecipe implements Recipe<Inventory>, CustomOutputRecipe {
return true; return true;
} }
private boolean isDummy() { public boolean isDummy() {
return dummy; return dummy;
} }
void makeDummy() {
this.ingredients.add(new DummyIngredient());
this.dummy = true;
}
@Override @Override
public Collection<Item> getOutputItems() { public Collection<Item> getOutputItems() {
List<Item> items = new ArrayList<>(); List<Item> items = new ArrayList<>();

View file

@ -33,13 +33,13 @@ import net.minecraft.util.Identifier;
import net.minecraft.util.JsonHelper; import net.minecraft.util.JsonHelper;
import net.minecraft.world.World; import net.minecraft.world.World;
import reborncore.RebornCore; import reborncore.RebornCore;
import reborncore.common.crafting.serde.RecipeSerde;
import reborncore.common.util.serialization.SerializationUtil; import reborncore.common.util.serialization.SerializationUtil;
import java.util.List; import java.util.List;
import java.util.function.BiFunction;
public record RebornRecipeType<R extends RebornRecipe>( public record RebornRecipeType<R extends RebornRecipe>(
BiFunction<RebornRecipeType<R>, Identifier, R> recipeFunction, RecipeSerde<R> recipeSerde,
Identifier name) implements RecipeType, RecipeSerializer { Identifier name) implements RecipeType, RecipeSerializer {
@Override @Override
@ -50,22 +50,18 @@ public record RebornRecipeType<R extends RebornRecipe>(
} }
try { try {
R recipe = newRecipe(recipeId); R recipe = newRecipe(json, recipeId);
if (!ConditionManager.shouldLoadRecipe(json)) { if (!ConditionManager.shouldLoadRecipe(json)) {
recipe.makeDummy(); return recipeSerde.createDummy(this, recipeId);
return recipe;
} }
recipe.deserialize(json);
return recipe; return recipe;
} catch (Throwable t) { } catch (Throwable t) {
RebornCore.LOGGER.error("Failed to read recipe: " + recipeId, t); RebornCore.LOGGER.error("Failed to read recipe: " + recipeId, t);
// Make a new recipe - don't reuse the existing recipe object because it might be in an invalid state if an // Make a new recipe - don't reuse the existing recipe object because it might be in an invalid state if an
// exception was thrown in the middle of its deserialization. // exception was thrown in the middle of its deserialization.
R recipe = newRecipe(recipeId); return recipeSerde.createDummy(this, recipeId);
recipe.makeDummy();
return recipe;
} }
} }
@ -73,7 +69,7 @@ public record RebornRecipeType<R extends RebornRecipe>(
JsonObject jsonObject = new JsonObject(); JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("type", name.toString()); jsonObject.addProperty("type", name.toString());
recipe.serialize(jsonObject); recipeSerde.toJson(recipe, jsonObject);
return jsonObject; return jsonObject;
} }
@ -82,8 +78,8 @@ public record RebornRecipeType<R extends RebornRecipe>(
return read(recipeType, json); return read(recipeType, json);
} }
R newRecipe(Identifier recipeId) { private R newRecipe(JsonObject jsonObject, Identifier recipeId) {
return recipeFunction.apply(this, recipeId); return recipeSerde.fromJson(jsonObject, this, recipeId);
} }
@Override @Override

View file

@ -34,6 +34,7 @@ import net.minecraft.util.registry.Registry;
import net.minecraft.world.World; import net.minecraft.world.World;
import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.Validate;
import reborncore.common.crafting.ingredient.RebornIngredient; import reborncore.common.crafting.ingredient.RebornIngredient;
import reborncore.common.crafting.serde.RecipeSerde;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@ -45,11 +46,11 @@ public class RecipeManager {
private static final Map<Identifier, RebornRecipeType<?>> recipeTypes = new HashMap<>(); private static final Map<Identifier, RebornRecipeType<?>> recipeTypes = new HashMap<>();
public static <R extends RebornRecipe> RebornRecipeType<R> newRecipeType(BiFunction<RebornRecipeType<R>, Identifier, R> recipeFunction, Identifier name) { public static <R extends RebornRecipe> RebornRecipeType<R> newRecipeType(RecipeSerde<R> recipeSerde, Identifier name) {
if (recipeTypes.containsKey(name)) { if (recipeTypes.containsKey(name)) {
throw new RuntimeException("RebornRecipe type with this name already registered"); throw new RuntimeException("RebornRecipe type with this name already registered");
} }
RebornRecipeType<R> type = new RebornRecipeType<>(recipeFunction, name); RebornRecipeType<R> type = new RebornRecipeType<>(recipeSerde, name);
recipeTypes.put(name, type); recipeTypes.put(name, type);
Registry.register(Registry.RECIPE_SERIALIZER, name, (RecipeSerializer<?>) type); Registry.register(Registry.RECIPE_SERIALIZER, name, (RecipeSerializer<?>) type);

View file

@ -25,16 +25,18 @@
package reborncore.common.crafting.ingredient; package reborncore.common.crafting.ingredient;
import net.minecraft.tag.Tag; import net.minecraft.tag.Tag;
import net.minecraft.util.Identifier;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
public class SimpleTag<T> implements Tag<T> { public class SimpleTag<T> implements Tag.Identified<T> {
private final List<T> entries; private final List<T> entries;
private final Identifier identifier;
public SimpleTag(List<T> entries) { public SimpleTag(List<T> entries, Identifier identifier) {
this.entries = entries; this.entries = entries;
this.identifier = identifier;
} }
@Override @Override
@ -46,4 +48,9 @@ public class SimpleTag<T> implements Tag<T> {
public List<T> values() { public List<T> values() {
return Collections.unmodifiableList(entries); return Collections.unmodifiableList(entries);
} }
@Override
public Identifier getId() {
return identifier;
}
} }

View file

@ -38,6 +38,7 @@ import net.minecraft.util.Identifier;
import net.minecraft.util.JsonHelper; import net.minecraft.util.JsonHelper;
import net.minecraft.util.registry.Registry; import net.minecraft.util.registry.Registry;
import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.Validate;
import org.jetbrains.annotations.Nullable;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
@ -49,22 +50,23 @@ public class StackIngredient extends RebornIngredient {
private final List<ItemStack> stacks; private final List<ItemStack> stacks;
private final Optional<Integer> count; private final Optional<Integer> count;
private final Optional<NbtCompound> tag; private final Optional<NbtCompound> nbt;
private final boolean requireEmptyTag; private final boolean requireEmptyNbt;
public StackIngredient(List<ItemStack> stacks, Optional<Integer> count, Optional<NbtCompound> tag, boolean requireEmptyTag) { public StackIngredient(List<ItemStack> stacks, Optional<Integer> count, Optional<NbtCompound> nbt, boolean requireEmptyNbt) {
super(IngredientManager.STACK_RECIPE_TYPE); super(IngredientManager.STACK_RECIPE_TYPE);
this.stacks = stacks; this.stacks = stacks;
this.count = count; this.count = count;
this.tag = tag; this.nbt = nbt;
this.requireEmptyTag = requireEmptyTag; this.requireEmptyNbt = requireEmptyNbt;
Validate.isTrue(stacks.size() == 1, "stack size must 1"); Validate.isTrue(stacks.size() == 1, "stack size must 1");
} }
public static RebornIngredient deserialize(JsonObject json) { public StackIngredient(List<ItemStack> stacks, int count, @Nullable NbtCompound nbt, boolean requireEmptyNbt) {
if (!json.has("item")) { this(stacks, count > 1 ? Optional.of(count) : Optional.empty(), Optional.ofNullable(nbt), requireEmptyNbt);
System.out.println("nope");
} }
public static RebornIngredient deserialize(JsonObject json) {
Identifier identifier = new Identifier(JsonHelper.getString(json, "item")); Identifier identifier = new Identifier(JsonHelper.getString(json, "item"));
Item item = Registry.ITEM.getOrEmpty(identifier).orElseThrow(() -> new JsonSyntaxException("Unknown item '" + identifier + "'")); Item item = Registry.ITEM.getOrEmpty(identifier).orElseThrow(() -> new JsonSyntaxException("Unknown item '" + identifier + "'"));
@ -101,7 +103,7 @@ public class StackIngredient extends RebornIngredient {
if (count.isPresent() && count.get() > itemStack.getCount()) { if (count.isPresent() && count.get() > itemStack.getCount()) {
return false; return false;
} }
if (tag.isPresent()) { if (nbt.isPresent()) {
if (!itemStack.hasNbt()) { if (!itemStack.hasNbt()) {
return false; return false;
} }
@ -113,11 +115,11 @@ public class StackIngredient extends RebornIngredient {
JsonElement jsonElement = Dynamic.convert(NbtOps.INSTANCE, JsonOps.INSTANCE, compoundTag); JsonElement jsonElement = Dynamic.convert(NbtOps.INSTANCE, JsonOps.INSTANCE, compoundTag);
compoundTag = (NbtCompound) Dynamic.convert(JsonOps.INSTANCE, NbtOps.INSTANCE, jsonElement); compoundTag = (NbtCompound) Dynamic.convert(JsonOps.INSTANCE, NbtOps.INSTANCE, jsonElement);
if (!tag.get().equals(compoundTag)) { if (!nbt.get().equals(compoundTag)) {
return false; return false;
} }
} }
return !requireEmptyTag || !itemStack.hasNbt(); return !requireEmptyNbt || !itemStack.hasNbt();
} }
@Override @Override
@ -131,7 +133,7 @@ public class StackIngredient extends RebornIngredient {
stacks.stream() stacks.stream()
.map(ItemStack::copy) .map(ItemStack::copy)
.peek(itemStack -> itemStack.setCount(count.orElse(1))) .peek(itemStack -> itemStack.setCount(count.orElse(1)))
.peek(itemStack -> itemStack.setNbt(tag.orElse(null))) .peek(itemStack -> itemStack.setNbt(nbt.orElse(null)))
.collect(Collectors.toList())); .collect(Collectors.toList()));
} }
@ -142,10 +144,10 @@ public class StackIngredient extends RebornIngredient {
jsonObject.addProperty("item", Registry.ITEM.getId(stacks.get(0).getItem()).toString()); jsonObject.addProperty("item", Registry.ITEM.getId(stacks.get(0).getItem()).toString());
count.ifPresent(integer -> jsonObject.addProperty("count", integer)); count.ifPresent(integer -> jsonObject.addProperty("count", integer));
if (requireEmptyTag) { if (requireEmptyNbt) {
jsonObject.addProperty("nbt", "empty"); jsonObject.addProperty("nbt", "empty");
} else { } else {
tag.ifPresent(compoundTag -> jsonObject.add("nbt", Dynamic.convert(NbtOps.INSTANCE, JsonOps.INSTANCE, compoundTag))); nbt.ifPresent(compoundTag -> jsonObject.add("nbt", Dynamic.convert(NbtOps.INSTANCE, JsonOps.INSTANCE, compoundTag)));
} }
return jsonObject; return jsonObject;

View file

@ -26,6 +26,7 @@ package reborncore.common.crafting.ingredient;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import com.google.gson.JsonSyntaxException; import com.google.gson.JsonSyntaxException;
import net.fabricmc.fabric.api.tag.TagFactory;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.item.Items; import net.minecraft.item.Items;
@ -43,18 +44,19 @@ import java.util.Optional;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public class TagIngredient extends RebornIngredient { public class TagIngredient extends RebornIngredient {
private final Tag.Identified<Item> tag;
private final Identifier tagIdentifier;
private final Tag<Item> tag;
private final Optional<Integer> count; private final Optional<Integer> count;
public TagIngredient(Identifier tagIdentifier, Tag<Item> tag, Optional<Integer> count) { public TagIngredient(Tag.Identified<Item> tag, Optional<Integer> count) {
super(IngredientManager.TAG_RECIPE_TYPE); super(IngredientManager.TAG_RECIPE_TYPE);
this.tagIdentifier = tagIdentifier;
this.tag = tag; this.tag = tag;
this.count = count; this.count = count;
} }
public TagIngredient(Tag.Identified<Item> tag, int count) {
this(tag, count > 1 ? Optional.of(count) : Optional.empty());
}
@Override @Override
public boolean test(ItemStack itemStack) { public boolean test(ItemStack itemStack) {
if (count.isPresent() && count.get() > itemStack.getCount()) { if (count.isPresent() && count.get() > itemStack.getCount()) {
@ -88,16 +90,17 @@ public class TagIngredient extends RebornIngredient {
Validate.isTrue(item != Items.AIR, "item cannot be air"); Validate.isTrue(item != Items.AIR, "item cannot be air");
items.add(item); items.add(item);
} }
return new TagIngredient(tagIdent, new SimpleTag<>(items), count); return new TagIngredient(new SimpleTag<>(items, tagIdent), count);
} }
Identifier identifier = new Identifier(JsonHelper.getString(json, "tag")); Identifier identifier = new Identifier(JsonHelper.getString(json, "tag"));
Tag<Item> tag = ServerTagManagerHolder.getTagManager().getOrCreateTagGroup(Registry.ITEM_KEY).getTag(identifier); Tag.Identified<Item> tag = TagFactory.of(() -> ServerTagManagerHolder.getTagManager().getOrCreateTagGroup(Registry.ITEM_KEY)).create(identifier);
if (tag == null) { if (tag == null) {
throw new JsonSyntaxException("Unknown item tag '" + identifier + "'"); throw new JsonSyntaxException("Unknown item tag '" + identifier + "'");
} }
return new TagIngredient(identifier, tag, count);
return new TagIngredient(tag, count);
} }
@Override @Override
@ -113,7 +116,7 @@ public class TagIngredient extends RebornIngredient {
} }
count.ifPresent(integer -> jsonObject.addProperty("count", integer)); count.ifPresent(integer -> jsonObject.addProperty("count", integer));
jsonObject.addProperty("tag_identifier", tagIdentifier.toString()); jsonObject.addProperty("tag_identifier", tag.getId().toString());
return jsonObject; return jsonObject;
} }

View file

@ -0,0 +1,101 @@
package reborncore.common.crafting.serde;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.mojang.serialization.Dynamic;
import com.mojang.serialization.JsonOps;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NbtOps;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.util.Identifier;
import net.minecraft.util.JsonHelper;
import net.minecraft.util.registry.Registry;
import reborncore.common.crafting.RebornRecipe;
import reborncore.common.crafting.RebornRecipeType;
import reborncore.common.crafting.RecipeUtils;
import reborncore.common.crafting.ingredient.IngredientManager;
import reborncore.common.crafting.ingredient.RebornIngredient;
import reborncore.common.util.DefaultedListCollector;
import reborncore.common.util.serialization.SerializationUtil;
import java.util.List;
public abstract class AbstractRecipeSerde<R extends RebornRecipe> implements RecipeSerde<R> {
@Override
public void writeToPacket(PacketByteBuf buffer, R recipe) {
final JsonObject jsonObject = new JsonObject();
toJson(recipe, jsonObject);
final String jsonStr = SerializationUtil.GSON_FLAT.toJson(jsonObject);
buffer.writeInt(jsonStr.length());
buffer.writeString(jsonStr);
recipe.serialize(buffer);
}
@Override
public R fromPacket(PacketByteBuf buffer, RebornRecipeType<R> type) {
final Identifier identifier = new Identifier(buffer.readString(buffer.readInt()));
final String input = buffer.readString(buffer.readInt());
final JsonObject jsonObject = SerializationUtil.GSON_FLAT.fromJson(input, JsonObject.class);
final R r = fromJson(jsonObject, type, identifier);
r.deserialize(buffer);
return r;
}
protected int getPower(JsonObject jsonObject) {
return JsonHelper.getInt(jsonObject, "power");
}
protected int getTime(JsonObject jsonObject) {
return JsonHelper.getInt(jsonObject, "time");
}
protected List<RebornIngredient> getIngredients(JsonObject jsonObject) {
return SerializationUtil.stream(JsonHelper.getArray(jsonObject, "ingredients"))
.map(IngredientManager::deserialize)
.collect(DefaultedListCollector.toList());
}
protected List<ItemStack> getOutputs(JsonObject jsonObject) {
final JsonArray resultsJson = JsonHelper.getArray(jsonObject, "results");
return RecipeUtils.deserializeItems(resultsJson);
}
protected void writeIngredients(R recipe, JsonObject jsonObject) {
final JsonArray ingredientsArray = new JsonArray();
recipe.getRebornIngredients().stream().map(RebornIngredient::witeToJson).forEach(ingredientsArray::add);
jsonObject.add("ingredients", ingredientsArray);
}
protected void writeOutputs(R recipe, JsonObject jsonObject) {
final JsonArray resultsArray = new JsonArray();
for (ItemStack stack : recipe.getOutputs()) {
final JsonObject stackObject = new JsonObject();
stackObject.addProperty("item", Registry.ITEM.getId(stack.getItem()).toString());
if (stack.getCount() > 1) {
stackObject.addProperty("count", stack.getCount());
}
if (stack.hasNbt()) {
stackObject.add("nbt", Dynamic.convert(NbtOps.INSTANCE, JsonOps.INSTANCE, stack.getNbt()));
}
resultsArray.add(stackObject);
}
jsonObject.add("results", resultsArray);
}
protected void writePower(R recipe, JsonObject jsonObject) {
jsonObject.addProperty("power", recipe.getPower());
}
protected void writeTime(R recipe, JsonObject jsonObject) {
jsonObject.addProperty("time", recipe.getTime());
}
}

View file

@ -0,0 +1,47 @@
package reborncore.common.crafting.serde;
import com.google.gson.JsonObject;
import net.minecraft.fluid.Fluid;
import net.minecraft.item.ItemStack;
import net.minecraft.util.Identifier;
import net.minecraft.util.JsonHelper;
import net.minecraft.util.registry.Registry;
import org.jetbrains.annotations.Nullable;
import reborncore.common.crafting.RebornFluidRecipe;
import reborncore.common.crafting.RebornRecipeType;
import reborncore.common.crafting.ingredient.RebornIngredient;
import reborncore.common.fluid.FluidValue;
import reborncore.common.fluid.container.FluidInstance;
import java.util.List;
public abstract class RebornFluidRecipeSerde<R extends RebornFluidRecipe> extends RebornRecipeSerde<R> {
protected abstract R fromJson(JsonObject jsonObject, RebornRecipeType<R> type, Identifier name, List<RebornIngredient> ingredients, List<ItemStack> outputs, int power, int time, @Nullable FluidInstance fluidInstance);
@Override
protected final R fromJson(JsonObject jsonObject, RebornRecipeType<R> type, Identifier name, List<RebornIngredient> ingredients, List<ItemStack> outputs, int power, int time) {
final JsonObject tank = JsonHelper.getObject(jsonObject, "tank");
final Identifier identifier = new Identifier(JsonHelper.getString(tank, "fluid"));
final Fluid fluid = Registry.FLUID.get(identifier);
FluidValue value = FluidValue.BUCKET;
if(tank.has("amount")){
value = FluidValue.parseFluidValue(tank.get("amount"));
}
FluidInstance fluidInstance = new FluidInstance(fluid, value);
return fromJson(jsonObject, type, name, ingredients, outputs, power, time, fluidInstance);
}
@Override
public void toJson(R recipe, JsonObject jsonObject) {
super.toJson(recipe, jsonObject);
final JsonObject tankObject = new JsonObject();
tankObject.addProperty("fluid", Registry.FLUID.getId(recipe.getFluidInstance().getFluid()).toString());
tankObject.addProperty("value", recipe.getFluidInstance().getAmount().getRawValue());
jsonObject.add("tank", tankObject);
}
}

View file

@ -0,0 +1,53 @@
package reborncore.common.crafting.serde;
import com.google.gson.JsonObject;
import net.minecraft.item.ItemStack;
import net.minecraft.util.Identifier;
import reborncore.common.crafting.RebornRecipe;
import reborncore.common.crafting.RebornRecipeType;
import reborncore.common.crafting.ingredient.RebornIngredient;
import java.util.List;
public abstract class RebornRecipeSerde<R extends RebornRecipe> extends AbstractRecipeSerde<R> {
public static final RebornRecipeSerde<RebornRecipe> BASIC = new RebornRecipeSerde<>() {
@Override
protected RebornRecipe fromJson(JsonObject jsonObject, RebornRecipeType<RebornRecipe> type, Identifier name, List<RebornIngredient> ingredients, List<ItemStack> outputs, int power, int time) {
return new RebornRecipe(type, name, ingredients, outputs, power, time);
}
@Override
public RebornRecipe createDummy(RebornRecipeType<RebornRecipe> type, Identifier name) {
return new RebornRecipe(type, name);
}
};
protected abstract R fromJson(JsonObject jsonObject, RebornRecipeType<R> type, Identifier name, List<RebornIngredient> ingredients, List<ItemStack> outputs, int power, int time);
@Override
public final R fromJson(JsonObject jsonObject, RebornRecipeType<R> type, Identifier name) {
if (jsonObject.has("dummy")) {
return createDummy(type, name);
}
final int power = getPower(jsonObject);
final int time = getTime(jsonObject);
final List<RebornIngredient> ingredients = getIngredients(jsonObject);
final List<ItemStack> outputs = getOutputs(jsonObject);
return fromJson(jsonObject, type, name, ingredients, outputs, power, time);
}
@Override
public void toJson(R recipe, JsonObject jsonObject) {
if (recipe.isDummy()) {
jsonObject.addProperty("dummy", true);
return;
}
writePower(recipe, jsonObject);
writeTime(recipe, jsonObject);
writeIngredients(recipe, jsonObject);
writeOutputs(recipe, jsonObject);
}
}

View file

@ -0,0 +1,19 @@
package reborncore.common.crafting.serde;
import com.google.gson.JsonObject;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.util.Identifier;
import reborncore.common.crafting.RebornRecipe;
import reborncore.common.crafting.RebornRecipeType;
public interface RecipeSerde<R extends RebornRecipe> {
R fromJson(JsonObject jsonObject, RebornRecipeType<R> type, Identifier name);
void toJson(R recipe, JsonObject jsonObject);
void writeToPacket(PacketByteBuf buffer, R recipe);
R fromPacket(PacketByteBuf buffer, RebornRecipeType<R> type);
R createDummy(RebornRecipeType<R> type, Identifier name);
}

View file

@ -30,10 +30,10 @@ import net.minecraft.item.ItemConvertible
import net.minecraft.item.Items import net.minecraft.item.Items
import net.minecraft.recipe.CookingRecipeSerializer import net.minecraft.recipe.CookingRecipeSerializer
import net.minecraft.recipe.RecipeSerializer import net.minecraft.recipe.RecipeSerializer
import techreborn.datagen.tags.CommonTagsTrait import techreborn.datagen.tags.CommonTags
import techreborn.init.TRContent import techreborn.init.TRContent
class SmeltingRecipesProvider extends TechRebornRecipesProvider implements CommonTagsTrait { class SmeltingRecipesProvider extends TechRebornRecipesProvider {
SmeltingRecipesProvider(FabricDataGenerator dataGenerator) { SmeltingRecipesProvider(FabricDataGenerator dataGenerator) {
super(dataGenerator) super(dataGenerator)
} }
@ -42,23 +42,23 @@ class SmeltingRecipesProvider extends TechRebornRecipesProvider implements Commo
void generateRecipes() { void generateRecipes() {
// Add smelting and blasting recipes. // Add smelting and blasting recipes.
[ [
(TRContent.Ingots.MIXED_METAL): TRContent.Ingots.ADVANCED_ALLOY, (TRContent.Ingots.MIXED_METAL) : TRContent.Ingots.ADVANCED_ALLOY,
(cItem("brass_dusts")): TRContent.Ingots.BRASS, (CommonTags.Items.brassDusts) : TRContent.Ingots.BRASS,
(TRContent.Dusts.BRONZE): TRContent.Ingots.BRONZE, (TRContent.Dusts.BRONZE) : TRContent.Ingots.BRONZE,
(cItem("electrum_dusts")): TRContent.Ingots.ELECTRUM, (CommonTags.Items.electrumDusts): TRContent.Ingots.ELECTRUM,
(TRContent.Dusts.INVAR): TRContent.Ingots.INVAR, (TRContent.Dusts.INVAR) : TRContent.Ingots.INVAR,
(cItem("lead_ores")): TRContent.Ingots.LEAD, (CommonTags.Items.leadOres) : TRContent.Ingots.LEAD,
(cItem("raw_lead_ores")): TRContent.Ingots.LEAD, (CommonTags.Items.rawLeadOres) : TRContent.Ingots.LEAD,
(TRContent.Dusts.NICKEL): TRContent.Ingots.NICKEL, (TRContent.Dusts.NICKEL) : TRContent.Ingots.NICKEL,
(cItem("sheldonite_ores")): TRContent.Ingots.PLATINUM, (CommonTags.Items.sheldoniteOres) : TRContent.Ingots.PLATINUM,
(cItem("platinum_dusts")): TRContent.Ingots.PLATINUM, (CommonTags.Items.platinumDusts) : TRContent.Ingots.PLATINUM,
(Items.IRON_INGOT): TRContent.Ingots.REFINED_IRON, (Items.IRON_INGOT) : TRContent.Ingots.REFINED_IRON,
(cItem("silver_ores")): TRContent.Ingots.SILVER, (CommonTags.Items.silverOres) : TRContent.Ingots.SILVER,
(cItem("raw_silver_ores")): TRContent.Ingots.SILVER, (CommonTags.Items.rawSilverOres) : TRContent.Ingots.SILVER,
(cItem("tin_ores")): TRContent.Ingots.TIN, (CommonTags.Items.tinOres) : TRContent.Ingots.TIN,
(cItem("raw_tin_ores")): TRContent.Ingots.TIN, (CommonTags.Items.rawTinOres) : TRContent.Ingots.TIN,
(cItem("zinc_dusts")): TRContent.Ingots.ZINC (CommonTags.Items.zincDusts) : TRContent.Ingots.ZINC
].each {input, output -> ].each { input, output ->
offerSmelting(input, output) offerSmelting(input, output)
offerBlasting(input, output) offerBlasting(input, output)
} }

View file

@ -25,12 +25,28 @@
package techreborn.datagen.tags package techreborn.datagen.tags
import net.fabricmc.fabric.api.tag.TagFactory import net.fabricmc.fabric.api.tag.TagFactory
import net.minecraft.item.Item
import net.minecraft.tag.Tag
import net.minecraft.util.Identifier import net.minecraft.util.Identifier
trait CommonTagsTrait { class CommonTags {
static Tag.Identified<Item> cItem(String path) { static class Items {
public static zincIngots = create("zinc_ingots")
public static brassDusts = create("brass_dusts")
public static electrumDusts = create("electrum_dusts")
public static platinumDusts = create("platinum_dusts")
public static zincDusts = create("zinc_dusts")
public static leadOres = create("lead_ores")
public static sheldoniteOres = create("sheldonite_ores")
public static silverOres = create("silver_ores")
public static tinOres = create("tin_ores")
public static rawLeadOres = create("raw_lead_ores")
public static rawSilverOres = create("raw_silver_ores")
public static rawTinOres = create("raw_tin_ores")
private static def create(String path) {
return TagFactory.ITEM.create(new Identifier("c", path)) return TagFactory.ITEM.create(new Identifier("c", path))
} }
}
} }

View file

@ -38,47 +38,25 @@ import net.minecraft.util.collection.DefaultedList;
import net.minecraft.world.World; import net.minecraft.world.World;
import reborncore.common.crafting.RebornRecipe; import reborncore.common.crafting.RebornRecipe;
import reborncore.common.crafting.RebornRecipeType; import reborncore.common.crafting.RebornRecipeType;
import reborncore.common.crafting.ingredient.DummyIngredient;
import reborncore.common.crafting.ingredient.RebornIngredient; import reborncore.common.crafting.ingredient.RebornIngredient;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
public class RollingMachineRecipe extends RebornRecipe { public class RollingMachineRecipe extends RebornRecipe {
private final ShapedRecipe shapedRecipe;
private ShapedRecipe shapedRecipe; private final JsonObject shapedRecipeJson;
public RollingMachineRecipe(RebornRecipeType<?> type, Identifier name) { public RollingMachineRecipe(RebornRecipeType<?> type, Identifier name) {
super(type, name); this(type, name, List.of(new DummyIngredient()), Collections.emptyList(), Integer.MAX_VALUE, Integer.MAX_VALUE, null, null);
this.dummy = true;
} }
public RollingMachineRecipe(RebornRecipeType<?> type, Identifier name, ShapedRecipe recipe) { public RollingMachineRecipe(RebornRecipeType<?> type, Identifier name, List<RebornIngredient> ingredients, List<ItemStack> outputs, int power, int time, ShapedRecipe shapedRecipe, JsonObject shapedRecipeJson) {
super(type, name); super(type, name, ingredients, outputs, power, time);
this.shapedRecipe = recipe; this.shapedRecipe = shapedRecipe;
} this.shapedRecipeJson = shapedRecipeJson;
@Override
public void deserialize(JsonObject jsonObject) {
if (jsonObject.has("shaped")) {
JsonObject json = JsonHelper.getObject(jsonObject, "shaped");
shapedRecipe = RecipeSerializer.SHAPED.read(getId(), json);
} else {
//This will be handled by the PacketByteBuf deserialize
}
}
@Override
public void serialize(PacketByteBuf byteBuf) {
String s = shapedRecipe.getId().toString();
byteBuf.writeInt(s.length());
byteBuf.writeString(s);
RecipeSerializer.SHAPED.write(byteBuf, shapedRecipe);
}
@Override
public void deserialize(PacketByteBuf byteBuf) {
Identifier identifier = new Identifier(byteBuf.readString(byteBuf.readInt()));
shapedRecipe = RecipeSerializer.SHAPED.read(identifier, byteBuf);
} }
@Override @Override
@ -119,4 +97,8 @@ public class RollingMachineRecipe extends RebornRecipe {
public ShapedRecipe getShapedRecipe() { public ShapedRecipe getShapedRecipe() {
return shapedRecipe; return shapedRecipe;
} }
public JsonObject getShapedRecipeJson() {
return shapedRecipeJson;
}
} }

View file

@ -0,0 +1,36 @@
package techreborn.api.recipe.recipes;
import com.google.gson.JsonObject;
import net.minecraft.item.ItemStack;
import net.minecraft.recipe.RecipeSerializer;
import net.minecraft.recipe.ShapedRecipe;
import net.minecraft.util.Identifier;
import net.minecraft.util.JsonHelper;
import reborncore.common.crafting.RebornRecipeType;
import reborncore.common.crafting.ingredient.RebornIngredient;
import reborncore.common.crafting.serde.RebornRecipeSerde;
import java.util.List;
public class RollingMachineRecipeSerde extends RebornRecipeSerde<RollingMachineRecipe> {
@Override
protected RollingMachineRecipe fromJson(JsonObject jsonObject, RebornRecipeType<RollingMachineRecipe> type, Identifier name, List<RebornIngredient> ingredients, List<ItemStack> outputs, int power, int time) {
final JsonObject json = JsonHelper.getObject(jsonObject, "shaped");
final ShapedRecipe shapedRecipe = RecipeSerializer.SHAPED.read(name, json);
return new RollingMachineRecipe(type, name, ingredients, outputs, power, time, shapedRecipe, json);
}
@Override
public void toJson(RollingMachineRecipe recipe, JsonObject jsonObject) {
super.toJson(recipe, jsonObject);
if (recipe.getShapedRecipeJson() != null) {
jsonObject.add("shaped", recipe.getShapedRecipeJson());
}
}
@Override
public RollingMachineRecipe createDummy(RebornRecipeType<RollingMachineRecipe> type, Identifier name) {
return new RollingMachineRecipe(type, name);
}
}

View file

@ -33,27 +33,27 @@ import techreborn.api.recipe.recipes.*;
public class ModRecipes { public class ModRecipes {
public static final RebornRecipeType<RebornRecipe> ALLOY_SMELTER = RecipeManager.newRecipeType(RebornRecipe::new, new Identifier("techreborn:alloy_smelter")); public static final RebornRecipeType<RebornRecipe> ALLOY_SMELTER = RecipeManager.newRecipeType(RebornRecipe::deserialize, new Identifier("techreborn:alloy_smelter"));
public static final RebornRecipeType<RebornRecipe> ASSEMBLING_MACHINE = RecipeManager.newRecipeType(RebornRecipe::new, new Identifier("techreborn:assembling_machine")); public static final RebornRecipeType<RebornRecipe> ASSEMBLING_MACHINE = RecipeManager.newRecipeType(RebornRecipe::deserialize, new Identifier("techreborn:assembling_machine"));
public static final RebornRecipeType<BlastFurnaceRecipe> BLAST_FURNACE = RecipeManager.newRecipeType(BlastFurnaceRecipe::new, new Identifier("techreborn:blast_furnace")); public static final RebornRecipeType<BlastFurnaceRecipe> BLAST_FURNACE = RecipeManager.newRecipeType(BlastFurnaceRecipe::deserialize, new Identifier("techreborn:blast_furnace"));
public static final RebornRecipeType<RebornRecipe> CENTRIFUGE = RecipeManager.newRecipeType(RebornRecipe::new, new Identifier("techreborn:centrifuge")); public static final RebornRecipeType<RebornRecipe> CENTRIFUGE = RecipeManager.newRecipeType(RebornRecipe::deserialize, new Identifier("techreborn:centrifuge"));
public static final RebornRecipeType<RebornRecipe> CHEMICAL_REACTOR = RecipeManager.newRecipeType(RebornRecipe::new, new Identifier("techreborn:chemical_reactor")); public static final RebornRecipeType<RebornRecipe> CHEMICAL_REACTOR = RecipeManager.newRecipeType(RebornRecipe::deserialize, new Identifier("techreborn:chemical_reactor"));
public static final RebornRecipeType<RebornRecipe> COMPRESSOR = RecipeManager.newRecipeType(RebornRecipe::new, new Identifier("techreborn:compressor")); public static final RebornRecipeType<RebornRecipe> COMPRESSOR = RecipeManager.newRecipeType(RebornRecipe::deserialize, new Identifier("techreborn:compressor"));
public static final RebornRecipeType<RebornRecipe> DISTILLATION_TOWER = RecipeManager.newRecipeType(RebornRecipe::new, new Identifier("techreborn:distillation_tower")); public static final RebornRecipeType<RebornRecipe> DISTILLATION_TOWER = RecipeManager.newRecipeType(RebornRecipe::deserialize, new Identifier("techreborn:distillation_tower"));
public static final RebornRecipeType<RebornRecipe> EXTRACTOR = RecipeManager.newRecipeType(RebornRecipe::new, new Identifier("techreborn:extractor")); public static final RebornRecipeType<RebornRecipe> EXTRACTOR = RecipeManager.newRecipeType(RebornRecipe::deserialize, new Identifier("techreborn:extractor"));
public static final RebornRecipeType<RebornRecipe> GRINDER = RecipeManager.newRecipeType(RebornRecipe::new, new Identifier("techreborn:grinder")); public static final RebornRecipeType<RebornRecipe> GRINDER = RecipeManager.newRecipeType(RebornRecipe::deserialize, new Identifier("techreborn:grinder"));
public static final RebornRecipeType<RebornRecipe> IMPLOSION_COMPRESSOR = RecipeManager.newRecipeType(RebornRecipe::new, new Identifier("techreborn:implosion_compressor")); public static final RebornRecipeType<RebornRecipe> IMPLOSION_COMPRESSOR = RecipeManager.newRecipeType(RebornRecipe::deserialize, new Identifier("techreborn:implosion_compressor"));
public static final RebornRecipeType<RebornRecipe> INDUSTRIAL_ELECTROLYZER = RecipeManager.newRecipeType(RebornRecipe::new, new Identifier("techreborn:industrial_electrolyzer")); public static final RebornRecipeType<RebornRecipe> INDUSTRIAL_ELECTROLYZER = RecipeManager.newRecipeType(RebornRecipe::deserialize, new Identifier("techreborn:industrial_electrolyzer"));
public static final RebornRecipeType<IndustrialGrinderRecipe> INDUSTRIAL_GRINDER = RecipeManager.newRecipeType(IndustrialGrinderRecipe::new, new Identifier("techreborn:industrial_grinder")); public static final RebornRecipeType<IndustrialGrinderRecipe> INDUSTRIAL_GRINDER = RecipeManager.newRecipeType(IndustrialGrinderRecipe::deserialize, new Identifier("techreborn:industrial_grinder"));
public static final RebornRecipeType<IndustrialSawmillRecipe> INDUSTRIAL_SAWMILL = RecipeManager.newRecipeType(IndustrialSawmillRecipe::new, new Identifier("techreborn:industrial_sawmill")); public static final RebornRecipeType<IndustrialSawmillRecipe> INDUSTRIAL_SAWMILL = RecipeManager.newRecipeType(IndustrialSawmillRecipe::deserialize, new Identifier("techreborn:industrial_sawmill"));
public static final RebornRecipeType<RebornRecipe> RECYCLER = RecipeManager.newRecipeType(RebornRecipe::new, new Identifier("techreborn:recycler")); public static final RebornRecipeType<RebornRecipe> RECYCLER = RecipeManager.newRecipeType(RebornRecipe::deserialize, new Identifier("techreborn:recycler"));
public static final RebornRecipeType<RebornRecipe> SCRAPBOX = RecipeManager.newRecipeType(RebornRecipe::new, new Identifier("techreborn:scrapbox")); public static final RebornRecipeType<RebornRecipe> SCRAPBOX = RecipeManager.newRecipeType(RebornRecipe::deserialize, new Identifier("techreborn:scrapbox"));
public static final RebornRecipeType<RebornRecipe> VACUUM_FREEZER = RecipeManager.newRecipeType(RebornRecipe::new, new Identifier("techreborn:vacuum_freezer")); public static final RebornRecipeType<RebornRecipe> VACUUM_FREEZER = RecipeManager.newRecipeType(RebornRecipe::deserialize, new Identifier("techreborn:vacuum_freezer"));
public static final RebornRecipeType<FluidReplicatorRecipe> FLUID_REPLICATOR = RecipeManager.newRecipeType(FluidReplicatorRecipe::new, new Identifier("techreborn:fluid_replicator")); public static final RebornRecipeType<FluidReplicatorRecipe> FLUID_REPLICATOR = RecipeManager.newRecipeType(FluidReplicatorRecipe::deserialize, new Identifier("techreborn:fluid_replicator"));
public static final RebornRecipeType<FusionReactorRecipe> FUSION_REACTOR = RecipeManager.newRecipeType(FusionReactorRecipe::new, new Identifier("techreborn:fusion_reactor")); public static final RebornRecipeType<FusionReactorRecipe> FUSION_REACTOR = RecipeManager.newRecipeType(FusionReactorRecipe::deserialize, new Identifier("techreborn:fusion_reactor"));
public static final RebornRecipeType<RollingMachineRecipe> ROLLING_MACHINE = RecipeManager.newRecipeType(RollingMachineRecipe::new, new Identifier("techreborn:rolling_machine")); public static final RebornRecipeType<RollingMachineRecipe> ROLLING_MACHINE = RecipeManager.newRecipeType(RollingMachineRecipe::deserialize, new Identifier("techreborn:rolling_machine"));
public static final RebornRecipeType<RebornRecipe> SOLID_CANNING_MACHINE = RecipeManager.newRecipeType(RebornRecipe::new, new Identifier("techreborn:solid_canning_machine")); public static final RebornRecipeType<RebornRecipe> SOLID_CANNING_MACHINE = RecipeManager.newRecipeType(RebornRecipe::deserialize, new Identifier("techreborn:solid_canning_machine"));
public static final RebornRecipeType<RebornRecipe> WIRE_MILL = RecipeManager.newRecipeType(RebornRecipe::new, new Identifier("techreborn:wire_mill")); public static final RebornRecipeType<RebornRecipe> WIRE_MILL = RecipeManager.newRecipeType(RebornRecipe::deserialize, new Identifier("techreborn:wire_mill"));
public static RebornRecipeType<?> byName(Identifier identifier) { public static RebornRecipeType<?> byName(Identifier identifier) {
return (RebornRecipeType<?>) Registry.RECIPE_SERIALIZER.get(identifier); return (RebornRecipeType<?>) Registry.RECIPE_SERIALIZER.get(identifier);