-
Notifications
You must be signed in to change notification settings - Fork 755
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add potion casting recipe and add recipes for filling potion bottles …
…and tipping arrows
- Loading branch information
1 parent
725e1ee
commit 77c3eea
Showing
9 changed files
with
375 additions
and
0 deletions.
There are no files selected for viewing
12 changes: 12 additions & 0 deletions
12
src/generated/resources/data/tconstruct/recipes/smeltery/casting/filling/bottle.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
{ | ||
"type": "tconstruct:casting_table_potion", | ||
"bottle": { | ||
"item": "minecraft:glass_bottle" | ||
}, | ||
"fluid": { | ||
"tag": "forge:potion", | ||
"amount": 250 | ||
}, | ||
"result": "minecraft:potion", | ||
"cooling_time": 0 | ||
} |
12 changes: 12 additions & 0 deletions
12
...generated/resources/data/tconstruct/recipes/smeltery/casting/filling/lingerng_bottle.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
{ | ||
"type": "tconstruct:casting_table_potion", | ||
"bottle": { | ||
"tag": "forge:bottles/splash" | ||
}, | ||
"fluid": { | ||
"tag": "forge:potion", | ||
"amount": 250 | ||
}, | ||
"result": "minecraft:splash_potion", | ||
"cooling_time": 0 | ||
} |
12 changes: 12 additions & 0 deletions
12
src/generated/resources/data/tconstruct/recipes/smeltery/casting/filling/splash_bottle.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
{ | ||
"type": "tconstruct:casting_table_potion", | ||
"bottle": { | ||
"tag": "forge:bottles/lingering" | ||
}, | ||
"fluid": { | ||
"tag": "forge:potion", | ||
"amount": 250 | ||
}, | ||
"result": "minecraft:lingering_potion", | ||
"cooling_time": 0 | ||
} |
12 changes: 12 additions & 0 deletions
12
src/generated/resources/data/tconstruct/recipes/smeltery/casting/filling/tipped_arrow.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
{ | ||
"type": "tconstruct:casting_table_potion", | ||
"bottle": { | ||
"item": "minecraft:arrow" | ||
}, | ||
"fluid": { | ||
"tag": "forge:potion", | ||
"amount": 25 | ||
}, | ||
"result": "minecraft:tipped_arrow", | ||
"cooling_time": 20 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
151 changes: 151 additions & 0 deletions
151
src/main/java/slimeknights/tconstruct/library/recipe/casting/PotionCastingRecipe.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
package slimeknights.tconstruct.library.recipe.casting; | ||
|
||
import com.google.gson.JsonObject; | ||
import lombok.Getter; | ||
import lombok.RequiredArgsConstructor; | ||
import net.minecraft.core.NonNullList; | ||
import net.minecraft.network.FriendlyByteBuf; | ||
import net.minecraft.resources.ResourceLocation; | ||
import net.minecraft.util.GsonHelper; | ||
import net.minecraft.world.Container; | ||
import net.minecraft.world.item.Item; | ||
import net.minecraft.world.item.ItemStack; | ||
import net.minecraft.world.item.alchemy.PotionUtils; | ||
import net.minecraft.world.item.crafting.Ingredient; | ||
import net.minecraft.world.item.crafting.RecipeSerializer; | ||
import net.minecraft.world.item.crafting.RecipeType; | ||
import net.minecraft.world.level.Level; | ||
import net.minecraftforge.fluids.FluidStack; | ||
import net.minecraftforge.registries.ForgeRegistries; | ||
import slimeknights.mantle.recipe.IMultiRecipe; | ||
import slimeknights.mantle.recipe.helper.LoggingRecipeSerializer; | ||
import slimeknights.mantle.recipe.ingredient.FluidIngredient; | ||
import slimeknights.mantle.util.JsonHelper; | ||
|
||
import javax.annotation.Nullable; | ||
import java.util.List; | ||
import java.util.function.Supplier; | ||
|
||
/** | ||
* Recipe for casting a fluid onto an item, copying the fluid NBT to the item | ||
*/ | ||
@RequiredArgsConstructor | ||
public class PotionCastingRecipe implements ICastingRecipe, IMultiRecipe<DisplayCastingRecipe> { | ||
@Getter | ||
private final RecipeType<?> type; | ||
@Getter | ||
private final RecipeSerializer<?> serializer; | ||
@Getter | ||
private final ResourceLocation id; | ||
@Getter | ||
private final String group; | ||
/** Input on the casting table, always consumed */ | ||
private final Ingredient bottle; | ||
/** Potion ingredient, typically just the potion tag */ | ||
private final FluidIngredient fluid; | ||
/** Potion item result, will be given the proper NBT */ | ||
private final Item result; | ||
/** Cooling time, used for arrows */ | ||
private final int coolingTime; | ||
|
||
private List<DisplayCastingRecipe> displayRecipes = null; | ||
|
||
@Override | ||
public boolean matches(ICastingContainer inv, Level level) { | ||
return bottle.test(inv.getStack()) && fluid.test(inv.getFluid()); | ||
} | ||
|
||
@Override | ||
public int getFluidAmount(ICastingContainer inv) { | ||
return fluid.getAmount(inv.getFluid()); | ||
} | ||
|
||
@Override | ||
public boolean isConsumed() { | ||
return true; | ||
} | ||
|
||
@Override | ||
public boolean switchSlots() { | ||
return false; | ||
} | ||
|
||
@Override | ||
public int getCoolingTime(ICastingContainer inv) { | ||
return coolingTime; | ||
} | ||
|
||
@Override | ||
public ItemStack assemble(ICastingContainer inv) { | ||
ItemStack result = new ItemStack(this.result); | ||
result.setTag(inv.getFluidTag()); | ||
return result; | ||
} | ||
|
||
@Override | ||
public List<DisplayCastingRecipe> getRecipes() { | ||
if (displayRecipes == null) { | ||
// create a subrecipe for every potion variant | ||
List<ItemStack> bottles = List.of(bottle.getItems()); | ||
displayRecipes = ForgeRegistries.POTIONS.getValues().stream() | ||
.map(potion -> { | ||
ItemStack result = PotionUtils.setPotion(new ItemStack(this.result), potion); | ||
return new DisplayCastingRecipe(type, bottles, fluid.getFluids().stream() | ||
.map(fluid -> new FluidStack(fluid.getFluid(), fluid.getAmount(), result.getTag())) | ||
.toList(), | ||
result, coolingTime, true); | ||
}).toList(); | ||
} | ||
return displayRecipes; | ||
} | ||
|
||
|
||
/* Recipe interface methods */ | ||
|
||
@Override | ||
public NonNullList<Ingredient> getIngredients() { | ||
return NonNullList.of(Ingredient.EMPTY, bottle); | ||
} | ||
|
||
/** @deprecated use {@link #assemble(Container)} */ | ||
@Deprecated | ||
@Override | ||
public ItemStack getResultItem() { | ||
return new ItemStack(this.result); | ||
} | ||
|
||
@RequiredArgsConstructor | ||
public static class Serializer extends LoggingRecipeSerializer<PotionCastingRecipe> { | ||
private final Supplier<RecipeType<ICastingRecipe>> type; | ||
|
||
@Override | ||
public PotionCastingRecipe fromJson(ResourceLocation id, JsonObject json) { | ||
String group = GsonHelper.getAsString(json, "group", ""); | ||
Ingredient bottle = Ingredient.fromJson(JsonHelper.getElement(json, "bottle")); | ||
FluidIngredient fluid = FluidIngredient.deserialize(json, "fluid"); | ||
Item result = JsonHelper.getAsEntry(ForgeRegistries.ITEMS, json, "result"); | ||
int coolingTime = GsonHelper.getAsInt(json, "cooling_time"); | ||
return new PotionCastingRecipe(type.get(), this, id, group, bottle, fluid, result, coolingTime); | ||
} | ||
|
||
@Nullable | ||
@Override | ||
protected PotionCastingRecipe fromNetworkSafe(ResourceLocation id, FriendlyByteBuf buffer) { | ||
String group = buffer.readUtf(Short.MAX_VALUE); | ||
Ingredient bottle = Ingredient.fromNetwork(buffer); | ||
FluidIngredient fluid = FluidIngredient.read(buffer); | ||
Item result = buffer.readRegistryIdUnsafe(ForgeRegistries.ITEMS); | ||
int coolingTime = buffer.readVarInt(); | ||
return new PotionCastingRecipe(type.get(), this, id, group, bottle, fluid, result, coolingTime); | ||
} | ||
|
||
@Override | ||
protected void toNetworkSafe(FriendlyByteBuf buffer, PotionCastingRecipe recipe) { | ||
buffer.writeUtf(recipe.group); | ||
recipe.bottle.toNetwork(buffer); | ||
recipe.fluid.write(buffer); | ||
buffer.writeRegistryIdUnsafe(ForgeRegistries.ITEMS, recipe.result); | ||
buffer.writeVarInt(recipe.coolingTime); | ||
} | ||
} | ||
} |
152 changes: 152 additions & 0 deletions
152
src/main/java/slimeknights/tconstruct/library/recipe/casting/PotionCastingRecipeBuilder.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
package slimeknights.tconstruct.library.recipe.casting; | ||
|
||
import com.google.gson.JsonObject; | ||
import lombok.RequiredArgsConstructor; | ||
import lombok.Setter; | ||
import lombok.experimental.Accessors; | ||
import net.minecraft.data.recipes.FinishedRecipe; | ||
import net.minecraft.resources.ResourceLocation; | ||
import net.minecraft.tags.TagKey; | ||
import net.minecraft.world.item.Item; | ||
import net.minecraft.world.item.crafting.Ingredient; | ||
import net.minecraft.world.item.crafting.RecipeSerializer; | ||
import net.minecraft.world.level.ItemLike; | ||
import net.minecraft.world.level.material.Fluid; | ||
import slimeknights.mantle.recipe.data.AbstractRecipeBuilder; | ||
import slimeknights.mantle.recipe.ingredient.FluidIngredient; | ||
import slimeknights.tconstruct.smeltery.TinkerSmeltery; | ||
|
||
import javax.annotation.Nullable; | ||
import java.util.Objects; | ||
import java.util.function.Consumer; | ||
|
||
/** | ||
* Builder for a potion bottle filling recipe. Takes a fluid and optional cast to create an item that copies the fluid NBT | ||
*/ | ||
@SuppressWarnings({"WeakerAccess", "unused", "UnusedReturnValue"}) | ||
@RequiredArgsConstructor(staticName = "castingRecipe") | ||
public class PotionCastingRecipeBuilder extends AbstractRecipeBuilder<PotionCastingRecipeBuilder> { | ||
private final Item result; | ||
private final PotionCastingRecipe.Serializer recipeSerializer; | ||
private Ingredient bottle = Ingredient.EMPTY; | ||
private FluidIngredient fluid = FluidIngredient.EMPTY; | ||
@Setter @Accessors(chain = true) | ||
private int coolingTime = 0; | ||
|
||
/** | ||
* Creates a new casting basin recipe | ||
* @param result Recipe result | ||
* @return Builder instance | ||
*/ | ||
public static PotionCastingRecipeBuilder basinRecipe(ItemLike result) { | ||
return castingRecipe(result.asItem(), TinkerSmeltery.basinPotionRecipeSerializer.get()); | ||
} | ||
|
||
/** | ||
* Creates a new casting table recipe | ||
* @param result Recipe result | ||
* @return Builder instance | ||
*/ | ||
public static PotionCastingRecipeBuilder tableRecipe(ItemLike result) { | ||
return castingRecipe(result.asItem(), TinkerSmeltery.tablePotionRecipeSerializer.get()); | ||
} | ||
|
||
|
||
/* Fluids */ | ||
|
||
/** | ||
* Sets the fluid for this recipe | ||
* @param tagIn Tag<Fluid> instance | ||
* @param amount amount of fluid | ||
* @return Builder instance | ||
*/ | ||
public PotionCastingRecipeBuilder setFluid(TagKey<Fluid> tagIn, int amount) { | ||
return this.setFluid(FluidIngredient.of(tagIn, amount)); | ||
} | ||
|
||
/** | ||
* Sets the fluid ingredient | ||
* @param fluid Fluid ingredient instance | ||
* @return Builder instance | ||
*/ | ||
public PotionCastingRecipeBuilder setFluid(FluidIngredient fluid) { | ||
this.fluid = fluid; | ||
return this; | ||
} | ||
|
||
|
||
/* Cast */ | ||
|
||
/** | ||
* Sets the cast from a tag, bottles are always consumed | ||
* @param tagIn Cast tag | ||
* @return Builder instance | ||
*/ | ||
public PotionCastingRecipeBuilder setBottle(TagKey<Item> tagIn) { | ||
return this.setBottle(Ingredient.of(tagIn)); | ||
} | ||
|
||
/** | ||
* Sets the bottle from an item, bottles are always consumed | ||
* @param itemIn Cast item | ||
* @return Builder instance | ||
*/ | ||
public PotionCastingRecipeBuilder setBottle(ItemLike itemIn) { | ||
return this.setBottle(Ingredient.of(itemIn)); | ||
} | ||
|
||
/** | ||
* Sets the bottle from an ingredient, bottles are always consumed | ||
* @param ingredient Cast ingredient | ||
* @return Builder instance | ||
*/ | ||
public PotionCastingRecipeBuilder setBottle(Ingredient ingredient) { | ||
this.bottle = ingredient; | ||
return this; | ||
} | ||
|
||
/** | ||
* Builds a recipe using the registry name as the recipe name | ||
* @param consumerIn Recipe consumer | ||
*/ | ||
@Override | ||
public void save(Consumer<FinishedRecipe> consumerIn) { | ||
this.save(consumerIn, Objects.requireNonNull(this.result.getRegistryName())); | ||
} | ||
|
||
@Override | ||
public void save(Consumer<FinishedRecipe> consumer, ResourceLocation id) { | ||
if (this.fluid == FluidIngredient.EMPTY) { | ||
throw new IllegalStateException("Casting recipes require a fluid input"); | ||
} | ||
if (this.coolingTime < 0) { | ||
throw new IllegalStateException("Cooling time is too low, must be at least 0"); | ||
} | ||
ResourceLocation advancementId = this.buildOptionalAdvancement(id, "casting"); | ||
consumer.accept(new PotionCastingRecipeBuilder.Result(id, advancementId)); | ||
} | ||
|
||
private class Result extends AbstractFinishedRecipe { | ||
public Result(ResourceLocation ID, @Nullable ResourceLocation advancementID) { | ||
super(ID, advancementID); | ||
} | ||
|
||
@Override | ||
public RecipeSerializer<?> getType() { | ||
return recipeSerializer; | ||
} | ||
|
||
@Override | ||
public void serializeRecipeData(JsonObject json) { | ||
if (!group.isEmpty()) { | ||
json.addProperty("group", group); | ||
} | ||
if (bottle != Ingredient.EMPTY) { | ||
json.add("bottle", bottle.toJson()); | ||
} | ||
json.add("fluid", fluid.serialize()); | ||
json.addProperty("result", Objects.requireNonNull(result.getRegistryName()).toString()); | ||
json.addProperty("cooling_time", coolingTime); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.