From 984b21632d6c1e36fba3f702a5c2a55eb4046026 Mon Sep 17 00:00:00 2001 From: Flanks255 <32142731+Flanks255@users.noreply.github.com> Date: Tue, 12 Oct 2021 16:19:47 -0500 Subject: [PATCH] Added NBT Copying recipe type. --- .../data/BlockRecipeGenerator.java | 1 - .../mod/ActuallyAdditions.java | 5 + .../mod/crafting/ActuallyRecipes.java | 18 ++++ .../mod/crafting/CopyNBTRecipeShaped.java | 92 +++++++++++++++++++ .../mod/crafting/TargetNBTIngredient.java | 69 ++++++++++++++ .../mod/crafting/WrappedRecipe.java | 66 +++++++++++++ 6 files changed, 250 insertions(+), 1 deletion(-) create mode 100644 src/main/java/de/ellpeck/actuallyadditions/mod/crafting/ActuallyRecipes.java create mode 100644 src/main/java/de/ellpeck/actuallyadditions/mod/crafting/CopyNBTRecipeShaped.java create mode 100644 src/main/java/de/ellpeck/actuallyadditions/mod/crafting/TargetNBTIngredient.java create mode 100644 src/main/java/de/ellpeck/actuallyadditions/mod/crafting/WrappedRecipe.java diff --git a/src/main/java/de/ellpeck/actuallyadditions/data/BlockRecipeGenerator.java b/src/main/java/de/ellpeck/actuallyadditions/data/BlockRecipeGenerator.java index 478bb971e..10b34520e 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/data/BlockRecipeGenerator.java +++ b/src/main/java/de/ellpeck/actuallyadditions/data/BlockRecipeGenerator.java @@ -185,7 +185,6 @@ public class BlockRecipeGenerator extends RecipeProvider { @Override protected void saveAdvancement(DirectoryCache p_208310_1_, JsonObject p_208310_2_, Path p_208310_3_) { //Nope... maybe later... - } public static class Recipe { diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/ActuallyAdditions.java b/src/main/java/de/ellpeck/actuallyadditions/mod/ActuallyAdditions.java index 37ac2025a..30c414994 100644 --- a/src/main/java/de/ellpeck/actuallyadditions/mod/ActuallyAdditions.java +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/ActuallyAdditions.java @@ -13,7 +13,9 @@ package de.ellpeck.actuallyadditions.mod; import de.ellpeck.actuallyadditions.api.ActuallyAdditionsAPI; import de.ellpeck.actuallyadditions.mod.blocks.ActuallyBlocks; import de.ellpeck.actuallyadditions.mod.booklet.InitBooklet; +import de.ellpeck.actuallyadditions.mod.crafting.ActuallyRecipes; import de.ellpeck.actuallyadditions.mod.crafting.CrusherCrafting; +import de.ellpeck.actuallyadditions.mod.crafting.TargetNBTIngredient; import de.ellpeck.actuallyadditions.mod.data.WorldData; import de.ellpeck.actuallyadditions.mod.entity.InitEntities; import de.ellpeck.actuallyadditions.mod.event.CommonEvents; @@ -35,6 +37,7 @@ import de.ellpeck.actuallyadditions.mod.update.UpdateChecker; import net.minecraft.item.ItemGroup; import net.minecraft.item.ItemStack; import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.common.crafting.CraftingHelper; import net.minecraftforge.eventbus.api.IEventBus; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; @@ -81,6 +84,7 @@ public class ActuallyAdditions { ActuallyBlocks.BLOCKS.register(eventBus); ActuallyBlocks.TILES.register(eventBus); + ActuallyRecipes.init(eventBus); ActuallyContainers.CONTAINERS.register(eventBus); MinecraftForge.EVENT_BUS.addListener(this::serverStarted); @@ -99,6 +103,7 @@ public class ActuallyAdditions { ActuallyAdditionsAPI.connectionHandler = new LaserRelayConnectionHandler(); Lenses.init(); // CompatUtil.registerCraftingTweaks(); + event.enqueueWork(() -> CraftingHelper.register(TargetNBTIngredient.Serializer.NAME, TargetNBTIngredient.SERIALIZER)); commonCapsLoaded = false; // Loader.isModLoaded("commoncapabilities"); diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/crafting/ActuallyRecipes.java b/src/main/java/de/ellpeck/actuallyadditions/mod/crafting/ActuallyRecipes.java new file mode 100644 index 000000000..1651b9289 --- /dev/null +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/crafting/ActuallyRecipes.java @@ -0,0 +1,18 @@ +package de.ellpeck.actuallyadditions.mod.crafting; + +import de.ellpeck.actuallyadditions.mod.ActuallyAdditions; +import net.minecraft.item.crafting.IRecipeSerializer; +import net.minecraftforge.eventbus.api.IEventBus; +import net.minecraftforge.fml.RegistryObject; +import net.minecraftforge.registries.DeferredRegister; +import net.minecraftforge.registries.ForgeRegistries; + +public class ActuallyRecipes { + public static final DeferredRegister> RECIPE_TYPES = DeferredRegister.create(ForgeRegistries.RECIPE_SERIALIZERS, ActuallyAdditions.MODID); + + public static void init(IEventBus bus) { + RECIPE_TYPES.register(bus); + } + + public static final RegistryObject> NBT_COPY_RECIPE = RECIPE_TYPES.register(CopyNBTRecipeShaped.NAME, CopyNBTRecipeShaped.Serializer::new); +} diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/crafting/CopyNBTRecipeShaped.java b/src/main/java/de/ellpeck/actuallyadditions/mod/crafting/CopyNBTRecipeShaped.java new file mode 100644 index 000000000..8938a85bd --- /dev/null +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/crafting/CopyNBTRecipeShaped.java @@ -0,0 +1,92 @@ +package de.ellpeck.actuallyadditions.mod.crafting; + +import com.google.gson.JsonObject; +import net.minecraft.inventory.CraftingInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.IRecipeSerializer; +import net.minecraft.item.crafting.Ingredient; +import net.minecraft.item.crafting.ShapedRecipe; +import net.minecraft.network.PacketBuffer; +import net.minecraft.util.NonNullList; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.registries.ForgeRegistryEntry; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import javax.annotation.Nullable; + +public class CopyNBTRecipeShaped extends ShapedRecipe { + public static String NAME = "copy_nbt"; + public static final Logger LOGGER = LogManager.getLogger(); + public CopyNBTRecipeShaped(ResourceLocation idIn, String groupIn, int recipeWidthIn, int recipeHeightIn, NonNullList recipeItemsIn, ItemStack recipeOutputIn) { + super(idIn, groupIn, recipeWidthIn, recipeHeightIn, recipeItemsIn, recipeOutputIn); + } + + public CopyNBTRecipeShaped(ShapedRecipe shapedRecipe) { + super(shapedRecipe.getId(), shapedRecipe.getGroup(), shapedRecipe.getRecipeWidth(), shapedRecipe.getRecipeHeight(), shapedRecipe.getIngredients(), shapedRecipe.getResultItem()); + } + + @Override + public ItemStack assemble(CraftingInventory inv) { + final ItemStack craftingResult = super.assemble(inv); + TargetNBTIngredient donorIngredient = null; + ItemStack datasource = ItemStack.EMPTY; + NonNullList ingredients = getIngredients(); + for (Ingredient ingredient : ingredients) { + if (ingredient instanceof TargetNBTIngredient) { + donorIngredient = (TargetNBTIngredient) ingredient; + break; + } + } + if (donorIngredient != null && !inv.isEmpty()) { + for (int i = 0; i < inv.getContainerSize(); i++) { + final ItemStack item = inv.getItem(i); + if (!item.isEmpty() && donorIngredient.test(item)) { + datasource = item; + break; + } + } + } + + if (!datasource.isEmpty() && datasource.hasTag()) + craftingResult.setTag(datasource.getTag().copy()); + + return craftingResult; + } + + + @Override + public IRecipeSerializer getSerializer() { + return ActuallyRecipes.NBT_COPY_RECIPE.get(); + } + + public static class Serializer extends ForgeRegistryEntry> implements IRecipeSerializer { + @Nullable + @Override + public CopyNBTRecipeShaped fromNetwork(ResourceLocation recipeId, PacketBuffer buffer) { + return new CopyNBTRecipeShaped(IRecipeSerializer.SHAPED_RECIPE.fromNetwork(recipeId, buffer)); + } + + @Override + public CopyNBTRecipeShaped fromJson(ResourceLocation recipeId, JsonObject json) { + try { + return new CopyNBTRecipeShaped(IRecipeSerializer.SHAPED_RECIPE.fromJson(recipeId, json)); + } + catch (Exception exception) { + LOGGER.info("Error reading "+ NAME +" Recipe from packet: ", exception); + throw exception; + } + } + + @Override + public void toNetwork(PacketBuffer buffer, CopyNBTRecipeShaped recipe) { + try { + IRecipeSerializer.SHAPED_RECIPE.toNetwork(buffer, recipe); + } + catch (Exception exception) { + LOGGER.info("Error writing "+ NAME +" Recipe to packet: ", exception); + throw exception; + } + } + } +} diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/crafting/TargetNBTIngredient.java b/src/main/java/de/ellpeck/actuallyadditions/mod/crafting/TargetNBTIngredient.java new file mode 100644 index 000000000..4d6164818 --- /dev/null +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/crafting/TargetNBTIngredient.java @@ -0,0 +1,69 @@ +package de.ellpeck.actuallyadditions.mod.crafting; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import de.ellpeck.actuallyadditions.mod.ActuallyAdditions; +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.Ingredient; +import net.minecraft.network.PacketBuffer; +import net.minecraft.tags.ITag; +import net.minecraft.util.IItemProvider; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.common.crafting.IIngredientSerializer; + +import java.util.stream.Stream; + +public class TargetNBTIngredient extends Ingredient { + public TargetNBTIngredient(Stream itemLists) { + super(itemLists); + } + + @Override + public IIngredientSerializer getSerializer() { + return SERIALIZER; + } + + public static TargetNBTIngredient of(IItemProvider itemProvider) { + return new TargetNBTIngredient(Stream.of(new SingleItemList(new ItemStack(itemProvider)))); + } + public static TargetNBTIngredient of(ItemStack itemStack) { + return new TargetNBTIngredient(Stream.of(new SingleItemList(itemStack))); + } + public static TargetNBTIngredient of(ITag tag) { + return new TargetNBTIngredient(Stream.of(new TagList(tag))); + } + + + + @Override + public JsonElement toJson() { + JsonObject tmp = super.toJson().getAsJsonObject(); + tmp.addProperty("type", Serializer.NAME.toString()); + return tmp; + } + + + public static Serializer SERIALIZER = new Serializer(); + public static class Serializer implements IIngredientSerializer { + public static ResourceLocation NAME = new ResourceLocation(ActuallyAdditions.MODID, "nbt_target"); + + @Override + public TargetNBTIngredient parse(PacketBuffer buffer) { + return new TargetNBTIngredient(Stream.generate(() -> new SingleItemList(buffer.readItem())).limit(buffer.readVarInt())); + } + + @Override + public TargetNBTIngredient parse(JsonObject json) { + return new TargetNBTIngredient(Stream.of(Ingredient.valueFromJson(json))); + } + + @Override + public void write(PacketBuffer buffer, TargetNBTIngredient ingredient) { + ItemStack[] items = ingredient.getItems(); + buffer.writeVarInt(items.length); + + for (ItemStack stack : items) + buffer.writeItem(stack); + } + } +} diff --git a/src/main/java/de/ellpeck/actuallyadditions/mod/crafting/WrappedRecipe.java b/src/main/java/de/ellpeck/actuallyadditions/mod/crafting/WrappedRecipe.java new file mode 100644 index 000000000..e9b01f66b --- /dev/null +++ b/src/main/java/de/ellpeck/actuallyadditions/mod/crafting/WrappedRecipe.java @@ -0,0 +1,66 @@ +package de.ellpeck.actuallyadditions.mod.crafting; + +import com.google.gson.JsonObject; +import net.minecraft.data.IFinishedRecipe; +import net.minecraft.item.crafting.IRecipeSerializer; +import net.minecraft.util.ResourceLocation; + +import javax.annotation.Nullable; +import java.util.function.Consumer; + +public class WrappedRecipe implements IFinishedRecipe { + IFinishedRecipe inner; + IRecipeSerializer serializerOverride; + + public WrappedRecipe(IFinishedRecipe innerIn) { + inner = innerIn; + } + + public WrappedRecipe(IFinishedRecipe innerIn, IRecipeSerializer serializerOverrideIn) { + inner = innerIn; + serializerOverride = serializerOverrideIn; + } + + public static Consumer Inject(Consumer consumer, IRecipeSerializer serializer) { + return iFinishedRecipe -> consumer.accept(new WrappedRecipe(iFinishedRecipe, serializer)); + } + + @Override + public void serializeRecipeData(JsonObject json) { + inner.serializeRecipeData(json); + } + + @Override + public JsonObject serializeRecipe() { + JsonObject jsonObject = new JsonObject(); + + if (serializerOverride != null) + jsonObject.addProperty("type", serializerOverride.getRegistryName().toString()); + else + jsonObject.addProperty("type", inner.getType().getRegistryName().toString()); + serializeRecipeData(jsonObject); + return jsonObject; + } + + @Override + public ResourceLocation getId() { + return inner.getId(); + } + + @Override + public IRecipeSerializer getType () { + return serializerOverride != null? serializerOverride:inner.getType(); + } + + @Nullable + @Override + public JsonObject serializeAdvancement() { + return inner.serializeAdvancement(); + } + + @Nullable + @Override + public ResourceLocation getAdvancementId() { + return inner.getAdvancementId(); + } +}