Part 2 of ARC Recipe Implementation
Added the ability for FluidStacks to be used as inputs and outputs, with a bit of cribbing off of how Mekanism handled their FluidStackIngredient.
This commit is contained in:
parent
f9327d8f5a
commit
f0d62b997a
|
@ -195,7 +195,7 @@ f38355165034ce314a9f0344ebc3a6cad22c76c8 data/bloodmagic/recipes/altar/reinforce
|
|||
926d4a0e165c87a15a609744d832d2f5f04a40d0 data/bloodmagic/recipes/altar/water_tool.json
|
||||
7551501cf361667ec7454c307b9d2368536fbed6 data/bloodmagic/recipes/altar/weakbloodorb.json
|
||||
4f511cfb93faf65aa50fabd7e753e0759ed95a1c data/bloodmagic/recipes/arc/test1.json
|
||||
14e7bce6990a346e36171564c29f93a14e50df44 data/bloodmagic/recipes/arc/test2.json
|
||||
5e735ea45bb2a49b43803c53a586ecbd5f3cbfe1 data/bloodmagic/recipes/arc/test2.json
|
||||
e1285ec51100f2336c1ea1a1a3057e74a0dd84d1 data/bloodmagic/recipes/array/airsigil.json
|
||||
d1ac23080f72f21adb5908befefe965ffb4efd4f data/bloodmagic/recipes/array/bloodlightsigil.json
|
||||
1890706e5b93cd6df764b0419483c348e0d7f277 data/bloodmagic/recipes/array/divinationsigil.json
|
||||
|
|
|
@ -6,6 +6,14 @@
|
|||
"tool": {
|
||||
"item": "minecraft:acacia_boat"
|
||||
},
|
||||
"inputfluid": {
|
||||
"amount": 1000,
|
||||
"fluid": "minecraft:lava"
|
||||
},
|
||||
"outputfluid": {
|
||||
"fluid": "minecraft:water",
|
||||
"amount": 100
|
||||
},
|
||||
"output": {
|
||||
"item": "bloodmagic:altar"
|
||||
}
|
||||
|
|
|
@ -141,10 +141,15 @@ public class Constants
|
|||
public static final String ITEM = "item";
|
||||
public static final String COUNT = "count";
|
||||
public static final String NBT = "nbt";
|
||||
public static final String TAG = "tag";
|
||||
public static final String TYPE = "type";
|
||||
public static final String TEXTURE = "texture";
|
||||
public static final String CONDITIONS = "conditions";
|
||||
public static final String CHANCE = "chance";
|
||||
public static final String FLUID = "fluid";
|
||||
public static final String AMOUNT = "amount";
|
||||
public static final String INPUT_FLUID = "inputfluid";
|
||||
public static final String OUTPUT_FLUID = "outputfluid";
|
||||
|
||||
public static final String ALTAR_TIER = Constants.NBT.ALTAR_TIER;
|
||||
public static final String ALTAR_SYPHON = "altarSyphon";
|
||||
|
|
|
@ -7,10 +7,18 @@ import com.google.gson.GsonBuilder;
|
|||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
|
||||
import net.minecraft.fluid.Fluid;
|
||||
import net.minecraft.fluid.Fluids;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.crafting.ShapedRecipe;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.nbt.JsonToNBT;
|
||||
import net.minecraft.util.JSONUtils;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
import wayoftime.bloodmagic.util.Constants;
|
||||
|
||||
/**
|
||||
|
@ -57,4 +65,65 @@ public class SerializerHelper
|
|||
}
|
||||
return json;
|
||||
}
|
||||
|
||||
public static FluidStack getFluidStack(@Nonnull JsonObject json, @Nonnull String key)
|
||||
{
|
||||
validateKey(json, key);
|
||||
return deserializeFluid(JSONUtils.getJsonObject(json, key));
|
||||
}
|
||||
|
||||
public static FluidStack deserializeFluid(@Nonnull JsonObject json)
|
||||
{
|
||||
if (!json.has(Constants.JSON.AMOUNT))
|
||||
{
|
||||
throw new JsonSyntaxException("Expected to receive a amount that is greater than zero");
|
||||
}
|
||||
JsonElement count = json.get(Constants.JSON.AMOUNT);
|
||||
if (!JSONUtils.isNumber(count))
|
||||
{
|
||||
throw new JsonSyntaxException("Expected amount to be a number greater than zero.");
|
||||
}
|
||||
int amount = count.getAsJsonPrimitive().getAsInt();
|
||||
if (amount < 1)
|
||||
{
|
||||
throw new JsonSyntaxException("Expected amount to be greater than zero.");
|
||||
}
|
||||
ResourceLocation resourceLocation = new ResourceLocation(JSONUtils.getString(json, Constants.JSON.FLUID));
|
||||
Fluid fluid = ForgeRegistries.FLUIDS.getValue(resourceLocation);
|
||||
if (fluid == null || fluid == Fluids.EMPTY)
|
||||
{
|
||||
throw new JsonSyntaxException("Invalid fluid type '" + resourceLocation + "'");
|
||||
}
|
||||
CompoundNBT nbt = null;
|
||||
if (json.has(Constants.JSON.NBT))
|
||||
{
|
||||
JsonElement jsonNBT = json.get(Constants.JSON.NBT);
|
||||
try
|
||||
{
|
||||
if (jsonNBT.isJsonObject())
|
||||
{
|
||||
nbt = JsonToNBT.getTagFromJson(GSON.toJson(jsonNBT));
|
||||
} else
|
||||
{
|
||||
nbt = JsonToNBT.getTagFromJson(JSONUtils.getString(jsonNBT, Constants.JSON.NBT));
|
||||
}
|
||||
} catch (CommandSyntaxException e)
|
||||
{
|
||||
throw new JsonSyntaxException("Invalid NBT entry for fluid '" + resourceLocation + "'");
|
||||
}
|
||||
}
|
||||
return new FluidStack(fluid, amount, nbt);
|
||||
}
|
||||
|
||||
public static JsonElement serializeFluidStack(@Nonnull FluidStack stack)
|
||||
{
|
||||
JsonObject json = new JsonObject();
|
||||
json.addProperty(Constants.JSON.FLUID, stack.getFluid().getRegistryName().toString());
|
||||
json.addProperty(Constants.JSON.AMOUNT, stack.getAmount());
|
||||
if (stack.hasTag())
|
||||
{
|
||||
json.addProperty(Constants.JSON.NBT, stack.getTag().toString());
|
||||
}
|
||||
return json;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,385 @@
|
|||
package wayoftime.bloodmagic.api.event.recipes;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
|
||||
import net.minecraft.fluid.Fluid;
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
import net.minecraft.tags.FluidTags;
|
||||
import net.minecraft.tags.ITag;
|
||||
import net.minecraft.tags.TagCollectionManager;
|
||||
import net.minecraft.util.JSONUtils;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
import wayoftime.bloodmagic.api.SerializerHelper;
|
||||
import wayoftime.bloodmagic.util.Constants;
|
||||
|
||||
/**
|
||||
* Created by Thiakil on 12/07/2019.
|
||||
*/
|
||||
public abstract class FluidStackIngredient implements InputIngredient<FluidStack>
|
||||
{
|
||||
|
||||
public static FluidStackIngredient from(@Nonnull Fluid instance, int amount)
|
||||
{
|
||||
return from(new FluidStack(instance, amount));
|
||||
}
|
||||
|
||||
public static FluidStackIngredient from(@Nonnull FluidStack instance)
|
||||
{
|
||||
return new Single(instance);
|
||||
}
|
||||
|
||||
public static FluidStackIngredient from(@Nonnull ITag<Fluid> fluidTag, int minAmount)
|
||||
{
|
||||
return new Tagged(fluidTag, minAmount);
|
||||
}
|
||||
|
||||
public static FluidStackIngredient read(PacketBuffer buffer)
|
||||
{
|
||||
// TODO: Allow supporting serialization of different types than just the ones we
|
||||
// implement?
|
||||
IngredientType type = buffer.readEnumValue(IngredientType.class);
|
||||
if (type == IngredientType.SINGLE)
|
||||
{
|
||||
return Single.read(buffer);
|
||||
} else if (type == IngredientType.TAGGED)
|
||||
{
|
||||
return Tagged.read(buffer);
|
||||
}
|
||||
return Multi.read(buffer);
|
||||
}
|
||||
|
||||
public static FluidStackIngredient deserialize(@Nullable JsonElement json)
|
||||
{
|
||||
if (json == null || json.isJsonNull())
|
||||
{
|
||||
throw new JsonSyntaxException("Ingredient cannot be null");
|
||||
}
|
||||
if (json.isJsonArray())
|
||||
{
|
||||
JsonArray jsonArray = json.getAsJsonArray();
|
||||
int size = jsonArray.size();
|
||||
if (size == 0)
|
||||
{
|
||||
throw new JsonSyntaxException("Ingredient array cannot be empty, at least one ingredient must be defined");
|
||||
} else if (size > 1)
|
||||
{
|
||||
FluidStackIngredient[] ingredients = new FluidStackIngredient[size];
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
// Read all the ingredients
|
||||
ingredients[i] = deserialize(jsonArray.get(i));
|
||||
}
|
||||
return createMulti(ingredients);
|
||||
}
|
||||
// If we only have a single element, just set our json as that so that we don't
|
||||
// have to use Multi for efficiency reasons
|
||||
json = jsonArray.get(0);
|
||||
}
|
||||
if (!json.isJsonObject())
|
||||
{
|
||||
throw new JsonSyntaxException("Expected fluid to be object or array of objects");
|
||||
}
|
||||
JsonObject jsonObject = json.getAsJsonObject();
|
||||
if (jsonObject.has(Constants.JSON.FLUID) && jsonObject.has(Constants.JSON.TAG))
|
||||
{
|
||||
throw new JsonParseException("An ingredient entry is either a tag or an fluid, not both");
|
||||
} else if (jsonObject.has(Constants.JSON.FLUID))
|
||||
{
|
||||
return from(SerializerHelper.deserializeFluid(jsonObject));
|
||||
} else if (jsonObject.has(Constants.JSON.TAG))
|
||||
{
|
||||
if (!jsonObject.has(Constants.JSON.AMOUNT))
|
||||
{
|
||||
throw new JsonSyntaxException("Expected to receive a amount that is greater than zero");
|
||||
}
|
||||
JsonElement count = jsonObject.get(Constants.JSON.AMOUNT);
|
||||
if (!JSONUtils.isNumber(count))
|
||||
{
|
||||
throw new JsonSyntaxException("Expected amount to be a number greater than zero.");
|
||||
}
|
||||
int amount = count.getAsJsonPrimitive().getAsInt();
|
||||
if (amount < 1)
|
||||
{
|
||||
throw new JsonSyntaxException("Expected amount to be greater than zero.");
|
||||
}
|
||||
ResourceLocation resourceLocation = new ResourceLocation(JSONUtils.getString(jsonObject, Constants.JSON.TAG));
|
||||
ITag<Fluid> tag = TagCollectionManager.getManager().getFluidTags().get(resourceLocation);
|
||||
if (tag == null)
|
||||
{
|
||||
throw new JsonSyntaxException("Unknown fluid tag '" + resourceLocation + "'");
|
||||
}
|
||||
return from(tag, amount);
|
||||
}
|
||||
throw new JsonSyntaxException("Expected to receive a resource location representing either a tag or a fluid.");
|
||||
}
|
||||
|
||||
public static FluidStackIngredient createMulti(FluidStackIngredient... ingredients)
|
||||
{
|
||||
if (ingredients.length == 0)
|
||||
{
|
||||
// TODO: Throw error
|
||||
} else if (ingredients.length == 1)
|
||||
{
|
||||
return ingredients[0];
|
||||
}
|
||||
List<FluidStackIngredient> cleanedIngredients = new ArrayList<>();
|
||||
for (FluidStackIngredient ingredient : ingredients)
|
||||
{
|
||||
if (ingredient instanceof Multi)
|
||||
{
|
||||
// Don't worry about if our inner ingredients are multi as well, as if this is
|
||||
// the only external method for
|
||||
// creating a multi ingredient, then we are certified they won't be of a higher
|
||||
// depth
|
||||
cleanedIngredients.addAll(Arrays.asList(((Multi) ingredient).ingredients));
|
||||
} else
|
||||
{
|
||||
cleanedIngredients.add(ingredient);
|
||||
}
|
||||
}
|
||||
// There should be more than a single fluid or we would have split out earlier
|
||||
return new Multi(cleanedIngredients.toArray(new FluidStackIngredient[0]));
|
||||
}
|
||||
|
||||
public static class Single extends FluidStackIngredient
|
||||
{
|
||||
|
||||
@Nonnull
|
||||
private final FluidStack fluidInstance;
|
||||
|
||||
public Single(@Nonnull FluidStack fluidInstance)
|
||||
{
|
||||
this.fluidInstance = Objects.requireNonNull(fluidInstance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test(@Nonnull FluidStack fluidStack)
|
||||
{
|
||||
return testType(fluidStack) && fluidStack.getAmount() >= fluidInstance.getAmount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean testType(@Nonnull FluidStack fluidStack)
|
||||
{
|
||||
return Objects.requireNonNull(fluidStack).isFluidEqual(fluidInstance);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public FluidStack getMatchingInstance(@Nonnull FluidStack fluidStack)
|
||||
{
|
||||
return test(fluidStack) ? fluidInstance : FluidStack.EMPTY;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public List<FluidStack> getRepresentations()
|
||||
{
|
||||
return Collections.singletonList(fluidInstance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(PacketBuffer buffer)
|
||||
{
|
||||
buffer.writeEnumValue(IngredientType.SINGLE);
|
||||
fluidInstance.writeToPacket(buffer);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public JsonElement serialize()
|
||||
{
|
||||
JsonObject json = new JsonObject();
|
||||
json.addProperty(Constants.JSON.AMOUNT, fluidInstance.getAmount());
|
||||
json.addProperty(Constants.JSON.FLUID, fluidInstance.getFluid().getRegistryName().toString());
|
||||
if (fluidInstance.hasTag())
|
||||
{
|
||||
json.addProperty(Constants.JSON.NBT, fluidInstance.getTag().toString());
|
||||
}
|
||||
return json;
|
||||
}
|
||||
|
||||
public static Single read(PacketBuffer buffer)
|
||||
{
|
||||
return new Single(FluidStack.readFromPacket(buffer));
|
||||
}
|
||||
}
|
||||
|
||||
public static class Tagged extends FluidStackIngredient
|
||||
{
|
||||
|
||||
@Nonnull
|
||||
private final ITag<Fluid> tag;
|
||||
private final int amount;
|
||||
|
||||
public Tagged(@Nonnull ITag<Fluid> tag, int amount)
|
||||
{
|
||||
this.tag = tag;
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test(@Nonnull FluidStack fluidStack)
|
||||
{
|
||||
return testType(fluidStack) && fluidStack.getAmount() >= amount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean testType(@Nonnull FluidStack fluidStack)
|
||||
{
|
||||
return Objects.requireNonNull(fluidStack).getFluid().isIn(tag);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public FluidStack getMatchingInstance(@Nonnull FluidStack fluidStack)
|
||||
{
|
||||
if (test(fluidStack))
|
||||
{
|
||||
// Our fluid is in the tag so we make a new stack with the given amount
|
||||
return new FluidStack(fluidStack, amount);
|
||||
}
|
||||
return FluidStack.EMPTY;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public List<FluidStack> getRepresentations()
|
||||
{
|
||||
// TODO: Can this be cached some how
|
||||
List<FluidStack> representations = new ArrayList<>();
|
||||
for (Fluid fluid : TagResolverHelper.getRepresentations(tag))
|
||||
{
|
||||
representations.add(new FluidStack(fluid, amount));
|
||||
}
|
||||
return representations;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(PacketBuffer buffer)
|
||||
{
|
||||
buffer.writeEnumValue(IngredientType.TAGGED);
|
||||
buffer.writeResourceLocation(TagCollectionManager.getManager().getFluidTags().getValidatedIdFromTag(tag));
|
||||
buffer.writeVarInt(amount);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public JsonElement serialize()
|
||||
{
|
||||
JsonObject json = new JsonObject();
|
||||
json.addProperty(Constants.JSON.AMOUNT, amount);
|
||||
json.addProperty(Constants.JSON.TAG, TagCollectionManager.getManager().getFluidTags().getValidatedIdFromTag(tag).toString());
|
||||
return json;
|
||||
}
|
||||
|
||||
public static Tagged read(PacketBuffer buffer)
|
||||
{
|
||||
return new Tagged(FluidTags.makeWrapperTag(buffer.readResourceLocation().toString()), buffer.readVarInt());
|
||||
}
|
||||
}
|
||||
|
||||
public static class Multi extends FluidStackIngredient
|
||||
{
|
||||
|
||||
private final FluidStackIngredient[] ingredients;
|
||||
|
||||
protected Multi(@Nonnull FluidStackIngredient... ingredients)
|
||||
{
|
||||
this.ingredients = ingredients;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test(@Nonnull FluidStack stack)
|
||||
{
|
||||
return Arrays.stream(ingredients).anyMatch(ingredient -> ingredient.test(stack));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean testType(@Nonnull FluidStack stack)
|
||||
{
|
||||
return Arrays.stream(ingredients).anyMatch(ingredient -> ingredient.testType(stack));
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public FluidStack getMatchingInstance(@Nonnull FluidStack stack)
|
||||
{
|
||||
for (FluidStackIngredient ingredient : ingredients)
|
||||
{
|
||||
FluidStack matchingInstance = ingredient.getMatchingInstance(stack);
|
||||
if (!matchingInstance.isEmpty())
|
||||
{
|
||||
return matchingInstance;
|
||||
}
|
||||
}
|
||||
return FluidStack.EMPTY;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public List<FluidStack> getRepresentations()
|
||||
{
|
||||
List<FluidStack> representations = new ArrayList<>();
|
||||
for (FluidStackIngredient ingredient : ingredients)
|
||||
{
|
||||
representations.addAll(ingredient.getRepresentations());
|
||||
}
|
||||
return representations;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(PacketBuffer buffer)
|
||||
{
|
||||
buffer.writeEnumValue(IngredientType.MULTI);
|
||||
buffer.writeVarInt(ingredients.length);
|
||||
for (FluidStackIngredient ingredient : ingredients)
|
||||
{
|
||||
ingredient.write(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public JsonElement serialize()
|
||||
{
|
||||
JsonArray json = new JsonArray();
|
||||
for (FluidStackIngredient ingredient : ingredients)
|
||||
{
|
||||
json.add(ingredient.serialize());
|
||||
}
|
||||
return json;
|
||||
}
|
||||
|
||||
public static FluidStackIngredient read(PacketBuffer buffer)
|
||||
{
|
||||
FluidStackIngredient[] ingredients = new FluidStackIngredient[buffer.readVarInt()];
|
||||
for (int i = 0; i < ingredients.length; i++)
|
||||
{
|
||||
ingredients[i] = FluidStackIngredient.read(buffer);
|
||||
}
|
||||
return createMulti(ingredients);
|
||||
}
|
||||
}
|
||||
|
||||
private enum IngredientType
|
||||
{
|
||||
SINGLE,
|
||||
TAGGED,
|
||||
MULTI
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
package wayoftime.bloodmagic.api.event.recipes;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
|
||||
public interface InputIngredient<TYPE> extends Predicate<TYPE>
|
||||
{
|
||||
|
||||
/**
|
||||
* Evaluates this predicate on the given argument, ignoring any size data.
|
||||
*
|
||||
* @param type the input argument
|
||||
*
|
||||
* @return {@code true} if the input argument matches the predicate, otherwise
|
||||
* {@code false}
|
||||
*/
|
||||
boolean testType(@Nonnull TYPE type);
|
||||
|
||||
TYPE getMatchingInstance(TYPE type);
|
||||
|
||||
/**
|
||||
* Primarily for JEI, a list of valid instances of the type
|
||||
*
|
||||
* @return List (empty means no valid registrations found and recipe is to be
|
||||
* hidden)
|
||||
*
|
||||
* @apiNote Do not modify any of the values returned by the representations
|
||||
*/
|
||||
@Nonnull
|
||||
List<TYPE> getRepresentations();
|
||||
|
||||
/**
|
||||
* Writes this ingredient to a PacketBuffer.
|
||||
*
|
||||
* @param buffer The buffer to write to.
|
||||
*/
|
||||
void write(PacketBuffer buffer);
|
||||
|
||||
/**
|
||||
* Serializes this ingredient to a JsonElement
|
||||
*
|
||||
* @return JsonElement representation of this ingredient.
|
||||
*/
|
||||
@Nonnull
|
||||
JsonElement serialize();
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package wayoftime.bloodmagic.api.event.recipes;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.tags.ITag;
|
||||
|
||||
/**
|
||||
* Copied from Mekanism, including the author's rant about tags.
|
||||
*/
|
||||
public class TagResolverHelper
|
||||
{
|
||||
|
||||
public static <TYPE> List<TYPE> getRepresentations(ITag<TYPE> tag)
|
||||
{
|
||||
try
|
||||
{
|
||||
return tag.getAllElements();
|
||||
} catch (IllegalStateException e)
|
||||
{
|
||||
// Why do tags have to be such an annoyance in 1.16
|
||||
// This is needed so that we can ensure we give JEI an empty list of
|
||||
// representations
|
||||
// instead of crashing on the first run, as recipes get "initialized" before
|
||||
// tags are
|
||||
// done initializing, and we don't want to spam the log with errors. JEI and
|
||||
// things
|
||||
// still work fine regardless of this
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -13,6 +13,8 @@ import net.minecraft.item.crafting.Ingredient;
|
|||
import net.minecraft.network.PacketBuffer;
|
||||
import net.minecraft.util.NonNullList;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
import wayoftime.bloodmagic.api.event.recipes.FluidStackIngredient;
|
||||
|
||||
public abstract class RecipeARC extends BloodMagicRecipe
|
||||
{
|
||||
|
@ -22,23 +24,27 @@ public abstract class RecipeARC extends BloodMagicRecipe
|
|||
private final Ingredient input;
|
||||
@Nonnull
|
||||
private final Ingredient arc_tool;
|
||||
private final FluidStackIngredient inputFluid;
|
||||
@Nonnull
|
||||
private final ItemStack output;
|
||||
private final FluidStack outputFluid;
|
||||
|
||||
private final List<Pair<ItemStack, Double>> addedItems;
|
||||
|
||||
protected RecipeARC(ResourceLocation id, Ingredient input, Ingredient arc_tool, ItemStack output)
|
||||
protected RecipeARC(ResourceLocation id, Ingredient input, Ingredient arc_tool, FluidStackIngredient inputFluid, ItemStack output, FluidStack outputFluid)
|
||||
{
|
||||
this(id, input, arc_tool, output, new ArrayList<Pair<ItemStack, Double>>());
|
||||
this(id, input, arc_tool, inputFluid, output, new ArrayList<Pair<ItemStack, Double>>(), outputFluid);
|
||||
}
|
||||
|
||||
protected RecipeARC(ResourceLocation id, Ingredient input, Ingredient arc_tool, ItemStack output, List<Pair<ItemStack, Double>> addedItems)
|
||||
protected RecipeARC(ResourceLocation id, Ingredient input, Ingredient arc_tool, FluidStackIngredient inputFluid, ItemStack output, List<Pair<ItemStack, Double>> addedItems, FluidStack outputFluid)
|
||||
{
|
||||
super(id);
|
||||
this.input = input;
|
||||
this.arc_tool = arc_tool;
|
||||
this.inputFluid = inputFluid;
|
||||
this.output = output;
|
||||
this.addedItems = addedItems;
|
||||
this.outputFluid = outputFluid;
|
||||
}
|
||||
|
||||
public RecipeARC addRandomOutput(ItemStack stack, double chance)
|
||||
|
@ -106,5 +112,17 @@ public abstract class RecipeARC extends BloodMagicRecipe
|
|||
buffer.writeItemStack(pair.getLeft());
|
||||
buffer.writeDouble(pair.getValue());
|
||||
}
|
||||
|
||||
buffer.writeBoolean(inputFluid != null);
|
||||
if (inputFluid != null)
|
||||
{
|
||||
inputFluid.write(buffer);
|
||||
}
|
||||
|
||||
buffer.writeBoolean(outputFluid != null);
|
||||
if (outputFluid != null)
|
||||
{
|
||||
outputFluid.writeToPacket(buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,9 @@ import com.google.gson.JsonObject;
|
|||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.crafting.Ingredient;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
import wayoftime.bloodmagic.api.SerializerHelper;
|
||||
import wayoftime.bloodmagic.api.event.recipes.FluidStackIngredient;
|
||||
import wayoftime.bloodmagic.api.impl.recipe.RecipeARC;
|
||||
import wayoftime.bloodmagic.common.data.recipe.BloodMagicRecipeBuilder;
|
||||
import wayoftime.bloodmagic.util.Constants;
|
||||
|
@ -22,20 +24,24 @@ public class ARCRecipeBuilder extends BloodMagicRecipeBuilder<ARCRecipeBuilder>
|
|||
{
|
||||
private final Ingredient input;
|
||||
private final Ingredient arcTool;
|
||||
private final FluidStackIngredient inputFluid;
|
||||
private final ItemStack output;
|
||||
private final FluidStack outputFluid;
|
||||
private final List<Pair<ItemStack, Double>> addedItems = new ArrayList<Pair<ItemStack, Double>>();
|
||||
|
||||
protected ARCRecipeBuilder(Ingredient input, Ingredient arcTool, ItemStack output)
|
||||
protected ARCRecipeBuilder(Ingredient input, Ingredient arcTool, FluidStackIngredient inputFluid, ItemStack output, FluidStack outputFluid)
|
||||
{
|
||||
super(bmSerializer("arc"));
|
||||
this.input = input;
|
||||
this.arcTool = arcTool;
|
||||
this.inputFluid = inputFluid;
|
||||
this.output = output;
|
||||
this.outputFluid = outputFluid;
|
||||
}
|
||||
|
||||
public static ARCRecipeBuilder arc(Ingredient input, Ingredient arcTool, ItemStack output)
|
||||
public static ARCRecipeBuilder arc(Ingredient input, Ingredient arcTool, FluidStackIngredient inputFluid, ItemStack output, FluidStack outputFluid)
|
||||
{
|
||||
return new ARCRecipeBuilder(input, arcTool, output);
|
||||
return new ARCRecipeBuilder(input, arcTool, inputFluid, output, outputFluid);
|
||||
}
|
||||
|
||||
public ARCRecipeBuilder addRandomOutput(ItemStack stack, double chance)
|
||||
|
@ -69,6 +75,9 @@ public class ARCRecipeBuilder extends BloodMagicRecipeBuilder<ARCRecipeBuilder>
|
|||
json.add(Constants.JSON.INPUT, input.serialize());
|
||||
json.add(Constants.JSON.TOOL, arcTool.serialize());
|
||||
|
||||
if (inputFluid != null)
|
||||
json.add(Constants.JSON.INPUT_FLUID, inputFluid.serialize());
|
||||
|
||||
if (addedItems.size() > 0)
|
||||
{
|
||||
JsonArray mainArray = new JsonArray();
|
||||
|
@ -83,6 +92,9 @@ public class ARCRecipeBuilder extends BloodMagicRecipeBuilder<ARCRecipeBuilder>
|
|||
json.add(Constants.JSON.ADDEDOUTPUT, mainArray);
|
||||
}
|
||||
|
||||
if (outputFluid != null)
|
||||
json.add(Constants.JSON.OUTPUT_FLUID, SerializerHelper.serializeFluidStack(outputFluid));
|
||||
|
||||
json.add(Constants.JSON.OUTPUT, SerializerHelper.serializeItemStack(output));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,11 +3,14 @@ package wayoftime.bloodmagic.common.recipe;
|
|||
import java.util.function.Consumer;
|
||||
|
||||
import net.minecraft.data.IFinishedRecipe;
|
||||
import net.minecraft.fluid.Fluids;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.item.crafting.Ingredient;
|
||||
import net.minecraftforge.common.Tags;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
import wayoftime.bloodmagic.BloodMagic;
|
||||
import wayoftime.bloodmagic.api.event.recipes.FluidStackIngredient;
|
||||
import wayoftime.bloodmagic.common.block.BloodMagicBlocks;
|
||||
import wayoftime.bloodmagic.common.data.recipe.builder.ARCRecipeBuilder;
|
||||
|
||||
|
@ -17,7 +20,7 @@ public class ARCRecipeProvider implements ISubRecipeProvider
|
|||
public void addRecipes(Consumer<IFinishedRecipe> consumer)
|
||||
{
|
||||
String basePath = "arc/";
|
||||
ARCRecipeBuilder.arc(Ingredient.fromTag(Tags.Items.GEMS_DIAMOND), Ingredient.fromTag(Tags.Items.BONES), new ItemStack(BloodMagicBlocks.BLOOD_ALTAR.get())).addRandomOutput(new ItemStack(Items.DIAMOND), 0.5).build(consumer, BloodMagic.rl(basePath + "test1"));
|
||||
ARCRecipeBuilder.arc(Ingredient.fromTag(Tags.Items.GEMS_DIAMOND), Ingredient.fromItems(Items.ACACIA_BOAT), new ItemStack(BloodMagicBlocks.BLOOD_ALTAR.get())).build(consumer, BloodMagic.rl(basePath + "test2"));
|
||||
ARCRecipeBuilder.arc(Ingredient.fromTag(Tags.Items.GEMS_DIAMOND), Ingredient.fromTag(Tags.Items.BONES), null, new ItemStack(BloodMagicBlocks.BLOOD_ALTAR.get()), null).addRandomOutput(new ItemStack(Items.DIAMOND), 0.5).build(consumer, BloodMagic.rl(basePath + "test1"));
|
||||
ARCRecipeBuilder.arc(Ingredient.fromTag(Tags.Items.GEMS_DIAMOND), Ingredient.fromItems(Items.ACACIA_BOAT), FluidStackIngredient.from(Fluids.LAVA, 1000), new ItemStack(BloodMagicBlocks.BLOOD_ALTAR.get()), new FluidStack(Fluids.WATER, 100)).build(consumer, BloodMagic.rl(basePath + "test2"));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,8 +17,10 @@ import net.minecraft.item.crafting.Ingredient;
|
|||
import net.minecraft.network.PacketBuffer;
|
||||
import net.minecraft.util.JSONUtils;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
import net.minecraftforge.registries.ForgeRegistryEntry;
|
||||
import wayoftime.bloodmagic.api.SerializerHelper;
|
||||
import wayoftime.bloodmagic.api.event.recipes.FluidStackIngredient;
|
||||
import wayoftime.bloodmagic.api.impl.recipe.RecipeARC;
|
||||
import wayoftime.bloodmagic.util.Constants;
|
||||
|
||||
|
@ -70,7 +72,24 @@ public class ARCRecipeSerializer<RECIPE extends RecipeARC> extends ForgeRegistry
|
|||
}
|
||||
}
|
||||
|
||||
return this.factory.create(recipeId, inputIng, toolIng, output, addedItems);
|
||||
FluidStackIngredient inputFluidIng = null;
|
||||
|
||||
if (json.has(Constants.JSON.INPUT_FLUID))
|
||||
{
|
||||
JsonElement inputFluid = JSONUtils.isJsonArray(json, Constants.JSON.INPUT_FLUID)
|
||||
? JSONUtils.getJsonArray(json, Constants.JSON.INPUT_FLUID)
|
||||
: JSONUtils.getJsonObject(json, Constants.JSON.INPUT_FLUID);
|
||||
inputFluidIng = FluidStackIngredient.deserialize(inputFluid);
|
||||
}
|
||||
|
||||
FluidStack outputFluid = null;
|
||||
|
||||
if (json.has(Constants.JSON.OUTPUT_FLUID))
|
||||
{
|
||||
outputFluid = SerializerHelper.deserializeFluid(json);
|
||||
}
|
||||
|
||||
return this.factory.create(recipeId, inputIng, toolIng, inputFluidIng, output, addedItems, outputFluid);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -98,7 +117,20 @@ public class ARCRecipeSerializer<RECIPE extends RecipeARC> extends ForgeRegistry
|
|||
buffer.writeDouble(pair.getValue());
|
||||
}
|
||||
|
||||
return this.factory.create(recipeId, inputIng, toolIng, output, addedItems);
|
||||
FluidStackIngredient inputFluid = null;
|
||||
FluidStack outputFluid = null;
|
||||
|
||||
if (buffer.readBoolean())
|
||||
{
|
||||
inputFluid = FluidStackIngredient.read(buffer);
|
||||
}
|
||||
|
||||
if (buffer.readBoolean())
|
||||
{
|
||||
outputFluid = FluidStack.readFromPacket(buffer);
|
||||
}
|
||||
|
||||
return this.factory.create(recipeId, inputIng, toolIng, inputFluid, output, addedItems, outputFluid);
|
||||
} catch (Exception e)
|
||||
{
|
||||
// Mekanism.logger.error("Error reading electrolysis recipe from packet.", e);
|
||||
|
@ -122,6 +154,6 @@ public class ARCRecipeSerializer<RECIPE extends RecipeARC> extends ForgeRegistry
|
|||
@FunctionalInterface
|
||||
public interface IFactory<RECIPE extends RecipeARC>
|
||||
{
|
||||
RECIPE create(ResourceLocation id, Ingredient input, Ingredient arcTool, ItemStack output, List<Pair<ItemStack, Double>> addedItems);
|
||||
RECIPE create(ResourceLocation id, Ingredient input, Ingredient arcTool, FluidStackIngredient inputFluid, ItemStack output, List<Pair<ItemStack, Double>> addedItems, FluidStack outputFluid);
|
||||
}
|
||||
}
|
|
@ -10,20 +10,22 @@ import net.minecraft.item.crafting.IRecipeSerializer;
|
|||
import net.minecraft.item.crafting.IRecipeType;
|
||||
import net.minecraft.item.crafting.Ingredient;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
import wayoftime.bloodmagic.api.event.recipes.FluidStackIngredient;
|
||||
import wayoftime.bloodmagic.api.impl.recipe.RecipeARC;
|
||||
import wayoftime.bloodmagic.common.recipe.BloodMagicRecipeType;
|
||||
import wayoftime.bloodmagic.common.registries.BloodMagicRecipeSerializers;
|
||||
|
||||
public class IRecipeARC extends RecipeARC
|
||||
{
|
||||
public IRecipeARC(ResourceLocation id, Ingredient input, Ingredient arc_tool, ItemStack output)
|
||||
public IRecipeARC(ResourceLocation id, Ingredient input, Ingredient arc_tool, FluidStackIngredient inputFluid, ItemStack output, FluidStack outputFluid)
|
||||
{
|
||||
super(id, input, arc_tool, output, new ArrayList<Pair<ItemStack, Double>>());
|
||||
super(id, input, arc_tool, inputFluid, output, new ArrayList<Pair<ItemStack, Double>>(), outputFluid);
|
||||
}
|
||||
|
||||
public IRecipeARC(ResourceLocation id, Ingredient input, Ingredient arc_tool, ItemStack output, List<Pair<ItemStack, Double>> addedItems)
|
||||
public IRecipeARC(ResourceLocation id, Ingredient input, Ingredient arc_tool, FluidStackIngredient inputFluid, ItemStack output, List<Pair<ItemStack, Double>> addedItems, FluidStack outputFluid)
|
||||
{
|
||||
super(id, input, arc_tool, output, addedItems);
|
||||
super(id, input, arc_tool, inputFluid, output, addedItems, outputFluid);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
Loading…
Reference in a new issue