diff --git a/src/generated/resources/.cache/cache b/src/generated/resources/.cache/cache index 610a9228..e9baf560 100644 --- a/src/generated/resources/.cache/cache +++ b/src/generated/resources/.cache/cache @@ -772,13 +772,14 @@ bd3b6173001ed0b2203ea2335e99483b9f76c04e data/inspirations/recipes/cauldron/pota 55b751b5237c3c8dbe171f55604e7c7a94df5923 data/inspirations/recipes/cauldron/potato_soup/item.json 2cfa24cdbb1d4bc3fd15412cdb3b30eb36e338e0 data/inspirations/recipes/cauldron/potato_soup/stew_large.json ed2a7b617ee025608ece02f1bd49c6ba3ed497ad data/inspirations/recipes/cauldron/potato_soup/stew_small.json -3ffb6885e1a9c5ccc210c5e15573b3a101e5406e data/inspirations/recipes/cauldron/potion/forge_brewing.json +4bc0c49d46ca8634ad03920ad3fc73aa655f3db1 data/inspirations/recipes/cauldron/potion/forge_brewing.json c9de2e3800af3d019d81be1eace6d08e6deb7195 data/inspirations/recipes/cauldron/potion/lingering_bottle.json 3c4d644f1f1072d8a9ada2ff147de2b0bcf15354 data/inspirations/recipes/cauldron/potion/lingering_empty.json d9c611348b17634f9ea886a154104241a274db34 data/inspirations/recipes/cauldron/potion/lingering_fill.json 47424706c9c3dd50cc12453931821682d18a9f5c data/inspirations/recipes/cauldron/potion/normal_empty.json 49b05c1a42d06cfe853c8519028b6cfe07c2b8d9 data/inspirations/recipes/cauldron/potion/normal_fill.json -81909dc96f087ca6e01e2aad944d91ad912e5d14 data/inspirations/recipes/cauldron/potion/potion_brewing.json +386ad3be1ee2b6d03ad0b8ea9024e7eab367f389 data/inspirations/recipes/cauldron/potion/potion_brewing.json +d7c18d79d56bd1d40532e86276130c76809f56af data/inspirations/recipes/cauldron/potion/potion_ferment.json f8323b474fafb97b99f72e735540059420e4daf3 data/inspirations/recipes/cauldron/potion/splash_bottle.json 19f63976122e48ba4c58d5966fc3e3f88ba2633b data/inspirations/recipes/cauldron/potion/splash_empty.json c7e3e2f5fd5b1366c14b1877727c3ba4e2e3dde6 data/inspirations/recipes/cauldron/potion/splash_fill.json diff --git a/src/generated/resources/data/inspirations/recipes/cauldron/potion/forge_brewing.json b/src/generated/resources/data/inspirations/recipes/cauldron/potion/forge_brewing.json index 6aff1a09..067bcbc5 100644 --- a/src/generated/resources/data/inspirations/recipes/cauldron/potion/forge_brewing.json +++ b/src/generated/resources/data/inspirations/recipes/cauldron/potion/forge_brewing.json @@ -9,5 +9,6 @@ "prop": "cauldron_brewing", "type": "inspirations:config" } - ] + ], + "instant": false } \ No newline at end of file diff --git a/src/generated/resources/data/inspirations/recipes/cauldron/potion/potion_brewing.json b/src/generated/resources/data/inspirations/recipes/cauldron/potion/potion_brewing.json index c0a010be..7ac56810 100644 --- a/src/generated/resources/data/inspirations/recipes/cauldron/potion/potion_brewing.json +++ b/src/generated/resources/data/inspirations/recipes/cauldron/potion/potion_brewing.json @@ -9,5 +9,6 @@ "prop": "cauldron_brewing", "type": "inspirations:config" } - ] + ], + "instant": false } \ No newline at end of file diff --git a/src/generated/resources/data/inspirations/recipes/cauldron/potion/potion_ferment.json b/src/generated/resources/data/inspirations/recipes/cauldron/potion/potion_ferment.json new file mode 100644 index 00000000..ecd7df74 --- /dev/null +++ b/src/generated/resources/data/inspirations/recipes/cauldron/potion/potion_ferment.json @@ -0,0 +1,14 @@ +{ + "type": "inspirations:cauldron_potion_ferment", + "conditions": [ + { + "prop": "recipes_module", + "type": "inspirations:config" + }, + { + "prop": "cauldron_brewing", + "type": "inspirations:config" + } + ], + "time": 600 +} \ No newline at end of file diff --git a/src/main/java/knightminer/inspirations/common/network/CauldronTransformUpatePacket.java b/src/main/java/knightminer/inspirations/common/network/CauldronTransformUpatePacket.java index 8b39df9d..4b9ec6ff 100644 --- a/src/main/java/knightminer/inspirations/common/network/CauldronTransformUpatePacket.java +++ b/src/main/java/knightminer/inspirations/common/network/CauldronTransformUpatePacket.java @@ -1,6 +1,6 @@ package knightminer.inspirations.common.network; -import knightminer.inspirations.library.recipe.cauldron.recipe.CauldronTransform; +import knightminer.inspirations.library.recipe.cauldron.recipe.ICauldronTransform; import knightminer.inspirations.recipes.tileentity.CauldronTileEntity; import net.minecraft.client.Minecraft; import net.minecraft.network.PacketBuffer; @@ -22,7 +22,7 @@ public class CauldronTransformUpatePacket implements IThreadsafePacket { @Nullable private final ResourceLocation recipe; - public CauldronTransformUpatePacket(BlockPos pos, @Nullable CauldronTransform recipe) { + public CauldronTransformUpatePacket(BlockPos pos, @Nullable ICauldronTransform recipe) { this.pos = pos; this.recipe = recipe == null ? null : recipe.getId(); } @@ -57,7 +57,7 @@ private static class HandleClient { private static void handle(CauldronTransformUpatePacket packet) { World world = Minecraft.getInstance().world; if (world != null) { - CauldronTransform recipe = packet.recipe == null ? null : RecipeHelper.getRecipe(world.getRecipeManager(), packet.recipe, CauldronTransform.class).orElse(null); + ICauldronTransform recipe = packet.recipe == null ? null : RecipeHelper.getRecipe(world.getRecipeManager(), packet.recipe, ICauldronTransform.class).orElse(null); TileEntityHelper.getTile(CauldronTileEntity.class, world, packet.pos, true).ifPresent(te -> { te.setTransformRecipe(recipe); }); diff --git a/src/main/java/knightminer/inspirations/library/recipe/RecipeSerializers.java b/src/main/java/knightminer/inspirations/library/recipe/RecipeSerializers.java index 83fed9ce..1e2b9109 100644 --- a/src/main/java/knightminer/inspirations/library/recipe/RecipeSerializers.java +++ b/src/main/java/knightminer/inspirations/library/recipe/RecipeSerializers.java @@ -13,6 +13,7 @@ import knightminer.inspirations.recipes.recipe.cauldron.FillBucketCauldronRecipe; import knightminer.inspirations.recipes.recipe.cauldron.FillDyedBottleRecipe; import knightminer.inspirations.recipes.recipe.cauldron.MixCauldronDyeRecipe; +import knightminer.inspirations.recipes.recipe.cauldron.PotionFermentCauldronTransform; import knightminer.inspirations.recipes.recipe.cauldron.RemoveBannerPatternCauldronRecipe; import knightminer.inspirations.tools.recipe.CopyWaypointCompassRecipe; import knightminer.inspirations.tools.recipe.DyeWaypointCompassRecipe; @@ -48,6 +49,7 @@ public class RecipeSerializers { public static final SpecialRecipeSerializer CAULDRON_FILL_BUCKET = injected(); public static final SpecialRecipeSerializer CAULDRON_FILL_DYED_BOTTLE = injected(); public static final SpecialRecipeSerializer CAULDRON_REMOVE_BANNER_PATTERN = injected(); - public static final SpecialRecipeSerializer CAULDRON_POTION_BREWING = injected(); - public static final SpecialRecipeSerializer CAULDRON_FORGE_BREWING = injected(); + public static final BrewingCauldronRecipe.Serializer CAULDRON_POTION_BREWING = injected(); + public static final BrewingCauldronRecipe.Serializer CAULDRON_FORGE_BREWING = injected(); + public static final PotionFermentCauldronTransform.Serializer CAULDRON_POTION_FERMENT = injected(); } diff --git a/src/main/java/knightminer/inspirations/library/recipe/RecipeTypes.java b/src/main/java/knightminer/inspirations/library/recipe/RecipeTypes.java index 43d23948..54db187d 100644 --- a/src/main/java/knightminer/inspirations/library/recipe/RecipeTypes.java +++ b/src/main/java/knightminer/inspirations/library/recipe/RecipeTypes.java @@ -1,8 +1,8 @@ package knightminer.inspirations.library.recipe; import knightminer.inspirations.Inspirations; -import knightminer.inspirations.library.recipe.cauldron.recipe.CauldronTransform; import knightminer.inspirations.library.recipe.cauldron.recipe.ICauldronRecipe; +import knightminer.inspirations.library.recipe.cauldron.recipe.ICauldronTransform; import net.minecraft.item.crafting.IRecipe; import net.minecraft.item.crafting.IRecipeType; @@ -12,7 +12,7 @@ public class RecipeTypes { /** Recipe type for cauldron recipes */ public static final IRecipeType CAULDRON = register("cauldron"); - public static final IRecipeType CAULDRON_TRANSFORM = register("cauldron_transform"); + public static final IRecipeType CAULDRON_TRANSFORM = register("cauldron_transform"); /** * Registers an Inspirations recipe type diff --git a/src/main/java/knightminer/inspirations/library/recipe/cauldron/CauldronContentTypes.java b/src/main/java/knightminer/inspirations/library/recipe/cauldron/CauldronContentTypes.java index 256cf345..f53c3dd4 100644 --- a/src/main/java/knightminer/inspirations/library/recipe/cauldron/CauldronContentTypes.java +++ b/src/main/java/knightminer/inspirations/library/recipe/cauldron/CauldronContentTypes.java @@ -46,8 +46,10 @@ public class CauldronContentTypes { /** Contains a specific color */ public static final CauldronContentType DYE = register("dye", new DyeContentType()); - /** Contains a specific color */ - public static final CauldronContentType POTION = register("potion", new PotionContentType()); + /** Contains a specific potion */ + public static final CauldronContentType POTION = register("potion", new PotionContentType(Inspirations.getResource("potion"), false)); + /** Potion that is currently in progress brewing */ + public static final CauldronContentType UNFERMENTED_POTION = register("unfermented_potion", new PotionContentType(Inspirations.getResource("unfermented_potion"), true)); /** Contains a specific fluid */ public static final CauldronContentType CUSTOM = register("custom", new CustomContentType()); diff --git a/src/main/java/knightminer/inspirations/library/recipe/cauldron/recipe/CauldronTransform.java b/src/main/java/knightminer/inspirations/library/recipe/cauldron/recipe/CauldronTransform.java index 8dc08fe7..fda7536e 100644 --- a/src/main/java/knightminer/inspirations/library/recipe/cauldron/recipe/CauldronTransform.java +++ b/src/main/java/knightminer/inspirations/library/recipe/cauldron/recipe/CauldronTransform.java @@ -3,7 +3,6 @@ import com.google.gson.JsonObject; import knightminer.inspirations.library.recipe.RecipeSerializer; import knightminer.inspirations.library.recipe.RecipeSerializers; -import knightminer.inspirations.library.recipe.RecipeTypes; import knightminer.inspirations.library.recipe.cauldron.CauldronContentTypes; import knightminer.inspirations.library.recipe.cauldron.CauldronIngredients; import knightminer.inspirations.library.recipe.cauldron.contents.ICauldronContents; @@ -13,14 +12,12 @@ import knightminer.inspirations.library.recipe.cauldron.util.TemperaturePredicate; import net.minecraft.item.ItemStack; import net.minecraft.item.crafting.IRecipeSerializer; -import net.minecraft.item.crafting.IRecipeType; import net.minecraft.network.PacketBuffer; import net.minecraft.util.JSONUtils; import net.minecraft.util.ResourceLocation; import net.minecraft.util.SoundEvent; import net.minecraft.util.SoundEvents; import net.minecraft.world.World; -import slimeknights.mantle.recipe.ICustomOutputRecipe; import javax.annotation.Nullable; import java.util.Collections; @@ -30,7 +27,7 @@ /** * Base cauldron transform implementation */ -public class CauldronTransform extends AbstractCauldronRecipe implements ICustomOutputRecipe { +public class CauldronTransform extends AbstractCauldronRecipe implements ICauldronTransform { private final ResourceLocation id; private final String group; private final int time; @@ -60,14 +57,24 @@ public boolean matches(ICauldronState inv, World worldIn) { return inv.getLevel() != 0 && matches(inv); } - /** - * Gets the sound to play for this recipe - * @return Recipe sound - */ + @Override + public ICauldronContents getContentOutput(ICauldronState inv) { + if (outputContents == null) { + return inv.getContents(); + } + return outputContents; + } + + @Override public SoundEvent getSound() { return sound; } + @Override + public int getTime() { + return time; + } + /* Display */ @@ -76,11 +83,6 @@ public List getItemInputs() { return Collections.emptyList(); } - @Override - public int getTime() { - return time; - } - @Override public int getLevelInput() { return level.getMax(); @@ -109,11 +111,6 @@ public String getGroup() { return group; } - @Override - public IRecipeType getType() { - return RecipeTypes.CAULDRON_TRANSFORM; - } - @Override public IRecipeSerializer getSerializer() { return RecipeSerializers.CAULDRON_TRANSFORM; diff --git a/src/main/java/knightminer/inspirations/library/recipe/cauldron/recipe/ICauldronTransform.java b/src/main/java/knightminer/inspirations/library/recipe/cauldron/recipe/ICauldronTransform.java new file mode 100644 index 00000000..bed07b59 --- /dev/null +++ b/src/main/java/knightminer/inspirations/library/recipe/cauldron/recipe/ICauldronTransform.java @@ -0,0 +1,37 @@ +package knightminer.inspirations.library.recipe.cauldron.recipe; + +import knightminer.inspirations.library.recipe.RecipeTypes; +import knightminer.inspirations.library.recipe.cauldron.contents.ICauldronContents; +import knightminer.inspirations.library.recipe.cauldron.inventory.ICauldronState; +import net.minecraft.item.crafting.IRecipeType; +import net.minecraft.util.SoundEvent; +import slimeknights.mantle.recipe.ICustomOutputRecipe; + +/** + * Recipe that transforms contents in a cauldron given time and temperature + */ +public interface ICauldronTransform extends ICustomOutputRecipe { + /** + * Gets the output contents for this recipe based on the input contents + * @param inv Cauldron state + * @return New contents + */ + ICauldronContents getContentOutput(ICauldronState inv); + + /** + * Gets the sound to play upon completion of the recipe + * @return Recipe sound + */ + SoundEvent getSound(); + + /** + * Gets the recipe duration in ticks (1/20 of a second) + * @return Recipe duration + */ + int getTime(); + + @Override + default IRecipeType getType() { + return RecipeTypes.CAULDRON_TRANSFORM; + } +} diff --git a/src/main/java/knightminer/inspirations/plugins/jei/cauldron/CauldronContentHelper.java b/src/main/java/knightminer/inspirations/plugins/jei/cauldron/CauldronContentHelper.java index 4c80c90d..5559a0c0 100644 --- a/src/main/java/knightminer/inspirations/plugins/jei/cauldron/CauldronContentHelper.java +++ b/src/main/java/knightminer/inspirations/plugins/jei/cauldron/CauldronContentHelper.java @@ -2,6 +2,7 @@ import knightminer.inspirations.Inspirations; import knightminer.inspirations.library.recipe.cauldron.CauldronContentTypes; +import knightminer.inspirations.library.recipe.cauldron.contents.CauldronContentType; import knightminer.inspirations.library.recipe.cauldron.contents.ICauldronContents; import mezz.jei.api.ingredients.IIngredientHelper; @@ -14,11 +15,28 @@ public class CauldronContentHelper implements IIngredientHelper getType(ICauldronContents contents) { + // TODO: consider making this more generic so addons can add more aliases + CauldronContentType type = contents.getType(); + // if unfermented, treat as potion for recipe lookups + if (type == CauldronContentTypes.UNFERMENTED_POTION) { + return CauldronContentTypes.POTION; + } + return type; + } + @Nullable @Override public ICauldronContents getMatch(Iterable options, ICauldronContents match) { + CauldronContentType type = getType(match); + String name = match.getName(); for (ICauldronContents content : options) { - if (content.equals(match)) { + if (type == getType(content) && name.equals(content.getName())) { return content; } } @@ -37,7 +55,7 @@ public String getDisplayName(ICauldronContents contents) { @Override public String getUniqueId(ICauldronContents contents) { - return CauldronContentTypes.getName(contents.getType()).toString() + ":" + contents.getName(); + return CauldronContentTypes.getName(getType(contents)).toString() + ":" + contents.getName(); } @Override diff --git a/src/main/java/knightminer/inspirations/recipes/InspirationsRecipes.java b/src/main/java/knightminer/inspirations/recipes/InspirationsRecipes.java index 43f481c1..3e90dd29 100644 --- a/src/main/java/knightminer/inspirations/recipes/InspirationsRecipes.java +++ b/src/main/java/knightminer/inspirations/recipes/InspirationsRecipes.java @@ -21,6 +21,7 @@ import knightminer.inspirations.recipes.recipe.cauldron.FillBucketCauldronRecipe; import knightminer.inspirations.recipes.recipe.cauldron.FillDyedBottleRecipe; import knightminer.inspirations.recipes.recipe.cauldron.MixCauldronDyeRecipe; +import knightminer.inspirations.recipes.recipe.cauldron.PotionFermentCauldronTransform; import knightminer.inspirations.recipes.recipe.cauldron.RemoveBannerPatternCauldronRecipe; import knightminer.inspirations.recipes.tileentity.CauldronTileEntity; import net.minecraft.block.Block; @@ -200,13 +201,14 @@ void registerSerializers(Register> event) { registry.register(new DyeableCauldronRecipe.Serializer(DyeableCauldronRecipe.Dye::new), "cauldron_dye_dyeable"); registry.register(new DyeableCauldronRecipe.Serializer(DyeableCauldronRecipe.Clear::new), "cauldron_clear_dyeable"); registry.register(new CauldronTransform.Serializer(), "cauldron_transform"); + registry.register(new PotionFermentCauldronTransform.Serializer(), "cauldron_potion_ferment"); registry.register(new SpecialRecipeSerializer<>(EmptyBucketCauldronRecipe::new), "cauldron_empty_bucket"); registry.register(new SpecialRecipeSerializer<>(FillBucketCauldronRecipe::new), "cauldron_fill_bucket"); registry.register(new SpecialRecipeSerializer<>(FillDyedBottleRecipe::new), "cauldron_fill_dyed_bottle"); registry.register(new SpecialRecipeSerializer<>(RemoveBannerPatternCauldronRecipe::new), "cauldron_remove_banner_pattern"); - registry.register(new SpecialRecipeSerializer<>(BrewingCauldronRecipe.Vanilla::new), "cauldron_potion_brewing"); - registry.register(new SpecialRecipeSerializer<>(BrewingCauldronRecipe.Forge::new), "cauldron_forge_brewing"); + registry.register(new BrewingCauldronRecipe.Serializer(BrewingCauldronRecipe.Vanilla::new), "cauldron_potion_brewing"); + registry.register(new BrewingCauldronRecipe.Serializer(BrewingCauldronRecipe.Forge::new), "cauldron_forge_brewing"); // add water as an override to potions ICauldronContents water = CauldronContentTypes.FLUID.of(Fluids.WATER); diff --git a/src/main/java/knightminer/inspirations/recipes/data/RecipesRecipeProvider.java b/src/main/java/knightminer/inspirations/recipes/data/RecipesRecipeProvider.java index c6dc3e83..7d06c554 100644 --- a/src/main/java/knightminer/inspirations/recipes/data/RecipesRecipeProvider.java +++ b/src/main/java/knightminer/inspirations/recipes/data/RecipesRecipeProvider.java @@ -17,8 +17,10 @@ import knightminer.inspirations.library.recipe.cauldron.special.FillPotionCauldronRecipe; import knightminer.inspirations.library.recipe.cauldron.util.TemperaturePredicate; import knightminer.inspirations.recipes.InspirationsRecipes; +import knightminer.inspirations.recipes.recipe.cauldron.BrewingCauldronRecipe; import knightminer.inspirations.recipes.recipe.cauldron.DyeCauldronWaterRecipe; import knightminer.inspirations.recipes.recipe.cauldron.MixCauldronDyeRecipe; +import knightminer.inspirations.recipes.recipe.cauldron.PotionFermentCauldronTransform; import knightminer.inspirations.shared.InspirationsShared; import knightminer.inspirations.utility.InspirationsUtility; import net.minecraft.advancements.ICriterionInstance; @@ -407,10 +409,9 @@ private void addCauldronRecipes() { // brew the potions Consumer brewingConsumer = withCondition(ConfigEnabledCondition.CAULDRON_BREWING); - CustomRecipeBuilder.customRecipe(RecipeSerializers.CAULDRON_POTION_BREWING) - .build(brewingConsumer, resourceName(potionFolder + "potion_brewing")); - CustomRecipeBuilder.customRecipe(RecipeSerializers.CAULDRON_FORGE_BREWING) - .build(brewingConsumer, resourceName(potionFolder + "forge_brewing")); + brewingConsumer.accept(new BrewingCauldronRecipe.FinishedRecipe(resource(potionFolder + "potion_brewing"), RecipeSerializers.CAULDRON_POTION_BREWING, false)); + brewingConsumer.accept(new BrewingCauldronRecipe.FinishedRecipe(resource(potionFolder + "forge_brewing"), RecipeSerializers.CAULDRON_FORGE_BREWING, false)); + brewingConsumer.accept(new PotionFermentCauldronTransform.FinishedRecipe(resource(potionFolder + "potion_ferment"), 600)); // fluid recipes // // beetroot is just water based diff --git a/src/main/java/knightminer/inspirations/recipes/recipe/cauldron/BrewingCauldronRecipe.java b/src/main/java/knightminer/inspirations/recipes/recipe/cauldron/BrewingCauldronRecipe.java index b26b7fcb..dd4d71a3 100644 --- a/src/main/java/knightminer/inspirations/recipes/recipe/cauldron/BrewingCauldronRecipe.java +++ b/src/main/java/knightminer/inspirations/recipes/recipe/cauldron/BrewingCauldronRecipe.java @@ -1,5 +1,8 @@ package knightminer.inspirations.recipes.recipe.cauldron; +import com.google.gson.JsonObject; +import knightminer.inspirations.library.recipe.DynamicFinishedRecipe; +import knightminer.inspirations.library.recipe.RecipeSerializer; import knightminer.inspirations.library.recipe.RecipeSerializers; import knightminer.inspirations.library.recipe.cauldron.CauldronContentTypes; import knightminer.inspirations.library.recipe.cauldron.inventory.ICauldronInventory; @@ -7,16 +10,19 @@ import knightminer.inspirations.library.recipe.cauldron.recipe.ICauldronRecipe; import knightminer.inspirations.library.recipe.cauldron.util.CauldronTemperature; import knightminer.inspirations.library.recipe.cauldron.util.DisplayCauldronRecipe; +import knightminer.inspirations.library.recipe.cauldron.util.TemperaturePredicate; import knightminer.inspirations.library.util.ReflectionUtil; import knightminer.inspirations.tweaks.recipe.NormalBrewingRecipe; import net.minecraft.item.ItemStack; import net.minecraft.item.Items; import net.minecraft.item.crafting.IRecipeSerializer; import net.minecraft.item.crafting.Ingredient; +import net.minecraft.network.PacketBuffer; import net.minecraft.potion.Potion; import net.minecraft.potion.PotionBrewing; import net.minecraft.potion.PotionUtils; import net.minecraft.potion.Potions; +import net.minecraft.util.JSONUtils; import net.minecraft.util.ResourceLocation; import net.minecraft.util.SoundEvents; import net.minecraft.world.World; @@ -26,10 +32,12 @@ import net.minecraftforge.common.brewing.VanillaBrewingRecipe; import slimeknights.mantle.recipe.IMultiRecipe; +import javax.annotation.Nullable; import java.util.Arrays; import java.util.IdentityHashMap; import java.util.List; import java.util.Map; +import java.util.function.BiFunction; import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -39,9 +47,17 @@ */ public abstract class BrewingCauldronRecipe implements ICauldronRecipe, IMultiRecipe { private final ResourceLocation id; + private final boolean instant; private List displayRecipes; - protected BrewingCauldronRecipe(ResourceLocation id) { + + /** + * Creates a new recipe instance + * @param id Recipe ID + * @param instant If true, recipe produces potion. If false, recipe produces unfermented potion + */ + protected BrewingCauldronRecipe(ResourceLocation id, boolean instant) { this.id = id; + this.instant = instant; } @Override @@ -70,7 +86,7 @@ public void handleRecipe(IModifyableCauldronInventory inventory) { Potion output = getResult(potion, stack); if (output != Potions.EMPTY) { // change the potion - inventory.setContents(CauldronContentTypes.POTION.of(output)); + inventory.setContents((instant ? CauldronContentTypes.POTION : CauldronContentTypes.UNFERMENTED_POTION).of(output)); // shrink the stack in hand and return the container ItemStack container = stack.getContainerItem().copy(); @@ -78,7 +94,7 @@ public void handleRecipe(IModifyableCauldronInventory inventory) { inventory.setOrGiveStack(container); // play sound - inventory.playSound(SoundEvents.BLOCK_BREWING_STAND_BREW); + inventory.playSound(SoundEvents.ENTITY_GENERIC_SPLASH); } }); } @@ -103,12 +119,13 @@ public ResourceLocation getId() { * @param output Potion output * @return Recipe instance */ - protected static DisplayCauldronRecipe makeRecipe(Potion input, Ingredient reagent, Potion output) { + protected DisplayCauldronRecipe makeRecipe(Potion input, Ingredient reagent, Potion output) { return DisplayCauldronRecipe.builder(3) - .setItemInputs(Arrays.asList(reagent.getMatchingStacks())) - .setContentInputs(CauldronContentTypes.POTION.of(input)) - .setContentOutput(CauldronContentTypes.POTION.of(output)) - .build(); + .setTemperature(TemperaturePredicate.BOILING) + .setItemInputs(Arrays.asList(reagent.getMatchingStacks())) + .setContentInputs(CauldronContentTypes.POTION.of(input)) + .setContentOutput((instant ? CauldronContentTypes.POTION : CauldronContentTypes.UNFERMENTED_POTION).of(output)) + .build(); } /** @@ -132,10 +149,11 @@ public static class Vanilla extends BrewingCauldronRecipe { /** * Creates a new recipe instance - * @param id Recipe ID + * @param id Recipe ID + * @param instant If true, recipe produces potion. If false, recipe produces unfermented potion */ - public Vanilla(ResourceLocation id) { - super(id); + public Vanilla(ResourceLocation id, boolean instant) { + super(id, instant); } /** @@ -212,10 +230,11 @@ public static class Forge extends BrewingCauldronRecipe { /** * Creates a new recipe instance - * @param id Recipe ID + * @param id Recipe ID + * @param instant If true, recipe produces potion. If false, recipe produces unfermented potion */ - public Forge(ResourceLocation id) { - super(id); + public Forge(ResourceLocation id, boolean instant) { + super(id, instant); } /** @@ -293,4 +312,48 @@ public IRecipeSerializer getSerializer() { return RecipeSerializers.CAULDRON_FORGE_BREWING; } } + + /** Recipe serializer */ + public static class Serializer extends RecipeSerializer { + private final BiFunction factory; + + /** + * Creates a new serializer instance + * @param factory Recipe constructor + */ + public Serializer(BiFunction factory) { + this.factory = factory; + } + + @Override + public BrewingCauldronRecipe read(ResourceLocation id, JsonObject json) { + boolean instant = JSONUtils.getBoolean(json, "instant"); + return factory.apply(id, instant); + } + + @Nullable + @Override + public BrewingCauldronRecipe read(ResourceLocation id, PacketBuffer buffer) { + return factory.apply(id, buffer.readBoolean()); + } + + @Override + public void write(PacketBuffer buffer, BrewingCauldronRecipe recipe) { + buffer.writeBoolean(recipe.instant); + } + } + + /** Finished recipe for datagen */ + public static class FinishedRecipe extends DynamicFinishedRecipe { + private final boolean instant; + public FinishedRecipe(ResourceLocation id, Serializer serializer, boolean instant) { + super(id, serializer); + this.instant = instant; + } + + @Override + public void serialize(JsonObject json) { + json.addProperty("instant", instant); + } + } } diff --git a/src/main/java/knightminer/inspirations/recipes/recipe/cauldron/PotionFermentCauldronTransform.java b/src/main/java/knightminer/inspirations/recipes/recipe/cauldron/PotionFermentCauldronTransform.java new file mode 100644 index 00000000..b9b3fc06 --- /dev/null +++ b/src/main/java/knightminer/inspirations/recipes/recipe/cauldron/PotionFermentCauldronTransform.java @@ -0,0 +1,100 @@ +package knightminer.inspirations.recipes.recipe.cauldron; + +import com.google.gson.JsonObject; +import knightminer.inspirations.library.recipe.DynamicFinishedRecipe; +import knightminer.inspirations.library.recipe.RecipeSerializer; +import knightminer.inspirations.library.recipe.RecipeSerializers; +import knightminer.inspirations.library.recipe.cauldron.CauldronContentTypes; +import knightminer.inspirations.library.recipe.cauldron.contents.ICauldronContents; +import knightminer.inspirations.library.recipe.cauldron.inventory.ICauldronState; +import knightminer.inspirations.library.recipe.cauldron.recipe.ICauldronTransform; +import knightminer.inspirations.library.recipe.cauldron.util.CauldronTemperature; +import net.minecraft.item.crafting.IRecipeSerializer; +import net.minecraft.network.PacketBuffer; +import net.minecraft.util.JSONUtils; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.SoundEvent; +import net.minecraft.util.SoundEvents; +import net.minecraft.world.World; + +import javax.annotation.Nullable; + +/** + * Recipe to transform a potion from the "brewing" form to the usable potion + */ +public class PotionFermentCauldronTransform implements ICauldronTransform { + private final ResourceLocation id; + private final int time; + + public PotionFermentCauldronTransform(ResourceLocation id, int time) { + this.id = id; + this.time = time; + } + + @Override + public boolean matches(ICauldronState inv, World worldIn) { + return inv.getLevel() > 0 && inv.getTemperature() == CauldronTemperature.BOILING && inv.getContents().contains(CauldronContentTypes.UNFERMENTED_POTION); + } + + @Override + public int getTime() { + return time; + } + + @Override + public ICauldronContents getContentOutput(ICauldronState inv) { + return inv.getContents() + .get(CauldronContentTypes.UNFERMENTED_POTION) + .map(CauldronContentTypes.POTION::of) + .orElseGet(CauldronContentTypes.DEFAULT); + } + + @Override + public ResourceLocation getId() { + return id; + } + + @Override + public IRecipeSerializer getSerializer() { + return RecipeSerializers.CAULDRON_POTION_FERMENT; + } + + @Override + public SoundEvent getSound() { + return SoundEvents.BLOCK_BREWING_STAND_BREW; + } + + /** Serializer for a potion transform */ + public static class Serializer extends RecipeSerializer { + @Override + public PotionFermentCauldronTransform read(ResourceLocation id, JsonObject json) { + int time = JSONUtils.getInt(json, "time"); + return new PotionFermentCauldronTransform(id, time); + } + + @Nullable + @Override + public PotionFermentCauldronTransform read(ResourceLocation id, PacketBuffer buffer) { + return new PotionFermentCauldronTransform(id, buffer.readVarInt()); + } + + @Override + public void write(PacketBuffer buffer, PotionFermentCauldronTransform recipe) { + buffer.writeVarInt(recipe.time); + } + } + + /** Finished recipe for datagen */ + public static class FinishedRecipe extends DynamicFinishedRecipe { + private final int time; + public FinishedRecipe(ResourceLocation id, int time) { + super(id, RecipeSerializers.CAULDRON_POTION_FERMENT); + this.time = time; + } + + @Override + public void serialize(JsonObject json) { + json.addProperty("time", time); + } + } +} diff --git a/src/main/java/knightminer/inspirations/recipes/recipe/cauldron/contents/PotionContentType.java b/src/main/java/knightminer/inspirations/recipes/recipe/cauldron/contents/PotionContentType.java index 4568e2f1..38ded863 100644 --- a/src/main/java/knightminer/inspirations/recipes/recipe/cauldron/contents/PotionContentType.java +++ b/src/main/java/knightminer/inspirations/recipes/recipe/cauldron/contents/PotionContentType.java @@ -1,6 +1,5 @@ package knightminer.inspirations.recipes.recipe.cauldron.contents; -import knightminer.inspirations.Inspirations; import knightminer.inspirations.library.recipe.cauldron.contents.RegistryContentType; import net.minecraft.client.util.ITooltipFlag; import net.minecraft.potion.Effect; @@ -9,6 +8,7 @@ import net.minecraft.potion.Potion; import net.minecraft.potion.PotionUtils; import net.minecraft.util.ResourceLocation; +import net.minecraft.util.Util; import net.minecraft.util.text.IFormattableTextComponent; import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.StringTextComponent; @@ -16,25 +16,37 @@ import net.minecraft.util.text.TranslationTextComponent; import net.minecraftforge.registries.ForgeRegistries; +import javax.annotation.Nullable; import java.util.List; /** * Potion content type */ public class PotionContentType extends RegistryContentType { - public static final ResourceLocation TEXTURE_NAME = Inspirations.getResource("potion"); private static final String PREFIX = "item.minecraft.potion.effect."; + private final ResourceLocation textureName; + @Nullable + private final String wrapName; + /** * Creates a new instance + * @param textureName Name of the texture for this type + * @param wrapName If true, name will be wrapped using a translation key from the texture name */ - public PotionContentType() { + public PotionContentType(ResourceLocation textureName, boolean wrapName) { super(ForgeRegistries.POTION_TYPES); + this.textureName = textureName; + if (wrapName) { + this.wrapName = Util.makeTranslationKey("cauldron_contents", textureName); + } else { + this.wrapName = null; + } } @Override public ResourceLocation getTexture(Potion value) { - return TEXTURE_NAME; + return textureName; } @Override @@ -44,7 +56,11 @@ public int getColor(Potion value) { @Override public ITextComponent getDisplayName(Potion value) { - return new TranslationTextComponent(value.getNamePrefixed(PREFIX)); + ITextComponent component = new TranslationTextComponent(value.getNamePrefixed(PREFIX)); + if (wrapName != null) { + return new TranslationTextComponent(wrapName, component); + } + return component; } @Override @@ -63,5 +79,9 @@ public void addInformation(Potion potion, List tooltip, ITooltip effectString.mergeStyle(effect.isBeneficial() ? TextFormatting.BLUE : TextFormatting.RED); tooltip.add(effectString); } + // add tooltip for unfermented + if (wrapName != null) { + tooltip.add(new TranslationTextComponent(wrapName + ".tooltip").mergeStyle(TextFormatting.GRAY, TextFormatting.ITALIC)); + } } } diff --git a/src/main/java/knightminer/inspirations/recipes/tileentity/CauldronTileEntity.java b/src/main/java/knightminer/inspirations/recipes/tileentity/CauldronTileEntity.java index c7713389..0ca102bf 100644 --- a/src/main/java/knightminer/inspirations/recipes/tileentity/CauldronTileEntity.java +++ b/src/main/java/knightminer/inspirations/recipes/tileentity/CauldronTileEntity.java @@ -9,8 +9,8 @@ import knightminer.inspirations.library.recipe.RecipeTypes; import knightminer.inspirations.library.recipe.cauldron.CauldronContentTypes; import knightminer.inspirations.library.recipe.cauldron.contents.ICauldronContents; -import knightminer.inspirations.library.recipe.cauldron.recipe.CauldronTransform; import knightminer.inspirations.library.recipe.cauldron.recipe.ICauldronRecipe; +import knightminer.inspirations.library.recipe.cauldron.recipe.ICauldronTransform; import knightminer.inspirations.library.recipe.cauldron.util.CauldronTemperature; import knightminer.inspirations.recipes.InspirationsRecipes; import knightminer.inspirations.recipes.block.EnhancedCauldronBlock; @@ -85,9 +85,9 @@ public class CauldronTileEntity extends TileEntity implements ITickableTileEntit /** Name of the in progress transform recipe */ private ResourceLocation currentTransformName; /** Transform recipe currently in progress */ - private CauldronTransform currentTransform; + private ICauldronTransform currentTransform; /** Last successful transform found */ - private CauldronTransform lastTransform; + private ICauldronTransform lastTransform; /** If true, updates the transform recipe during the next tick */ private boolean updateTransform; @@ -546,12 +546,12 @@ public void updateTransform() { timer = 0; // try to find a recipe - CauldronTransform transform = null; + ICauldronTransform transform = null; if (getLevel() > 0) { if (lastTransform != null && lastTransform.matches(craftingInventory, world)) { transform = lastTransform; } else { - Optional newTransform = world.getRecipeManager().getRecipe(RecipeTypes.CAULDRON_TRANSFORM, craftingInventory, world); + Optional newTransform = world.getRecipeManager().getRecipe(RecipeTypes.CAULDRON_TRANSFORM, craftingInventory, world); if (newTransform.isPresent()) { transform = lastTransform = newTransform.get(); } @@ -595,7 +595,7 @@ public void tick() { world.playSound(null, pos, sound, SoundCategory.BLOCKS, 1.0f, 1.0f); // set contents will clear the current transform if no longer current - setContents(currentTransform.getContentOutput()); + setContents(currentTransform.getContentOutput(craftingInventory)); } } @@ -603,7 +603,7 @@ public void tick() { * Called on the client to update the current transform recipe * @param recipe New recipe */ - public void setTransformRecipe(@Nullable CauldronTransform recipe) { + public void setTransformRecipe(@Nullable ICauldronTransform recipe) { this.currentTransform = recipe; timer = 0; } @@ -689,7 +689,7 @@ public void setWorldAndPos(World world, BlockPos pos) { * @param name Recipe name */ private void loadTransform(World world, ResourceLocation name) { - RecipeHelper.getRecipe(world.getRecipeManager(), name, CauldronTransform.class).ifPresent(recipe -> this.currentTransform = recipe); + RecipeHelper.getRecipe(world.getRecipeManager(), name, ICauldronTransform.class).ifPresent(recipe -> this.currentTransform = recipe); } @Override diff --git a/src/main/resources/assets/inspirations/lang/en_us.json b/src/main/resources/assets/inspirations/lang/en_us.json index 139c2b9f..57fd0690 100644 --- a/src/main/resources/assets/inspirations/lang/en_us.json +++ b/src/main/resources/assets/inspirations/lang/en_us.json @@ -160,6 +160,8 @@ "cauldron_contents.inspirations.empty": "Empty", "cauldron_contents.inspirations.color": "Dyed Water", "cauldron_contents.inspirations.dye": "%s Dyed Water", + "cauldron_contents.inspirations.unfermented_potion": "Unfermented %s", + "cauldron_contents.inspirations.unfermented_potion.tooltip": "Boil to produce usable potion", "cauldron_contents.minecraft.ice": "Ice", "cauldron_contents.minecraft.packed_ice": "Packed Ice", diff --git a/src/main/resources/assets/inspirations/models/cauldron_textures.json b/src/main/resources/assets/inspirations/models/cauldron_textures.json index 3486b68f..1574d564 100644 --- a/src/main/resources/assets/inspirations/models/cauldron_textures.json +++ b/src/main/resources/assets/inspirations/models/cauldron_textures.json @@ -6,6 +6,7 @@ "inspirations:color": "inspirations:block/fluid/colorless", "inspirations:dye": "inspirations:block/fluid/colorless", "inspirations:potion": "inspirations:block/fluid/potion", + "inspirations:unfermented_potion": "inspirations:block/fluid/potion_brewing", "rats:cheese": "rats:block/cheese" } \ No newline at end of file diff --git a/src/main/resources/assets/inspirations/textures/block/fluid/potion_brewing.png b/src/main/resources/assets/inspirations/textures/block/fluid/potion_brewing.png new file mode 100644 index 00000000..e0d4d469 Binary files /dev/null and b/src/main/resources/assets/inspirations/textures/block/fluid/potion_brewing.png differ diff --git a/src/main/resources/assets/inspirations/textures/block/fluid/potion_brewing.png.mcmeta b/src/main/resources/assets/inspirations/textures/block/fluid/potion_brewing.png.mcmeta new file mode 100644 index 00000000..4f0718ac --- /dev/null +++ b/src/main/resources/assets/inspirations/textures/block/fluid/potion_brewing.png.mcmeta @@ -0,0 +1,3 @@ +{ + "animation": {} +} \ No newline at end of file