-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: recipe generator and strainer filtering fluid recipe
- Loading branch information
1 parent
f14b101
commit a35967e
Showing
9 changed files
with
315 additions
and
3 deletions.
There are no files selected for viewing
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
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
36 changes: 36 additions & 0 deletions
36
src/main/kotlin/xyz/koiro/watersource/datagen/ModRecipeGenerator.kt
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,36 @@ | ||
package xyz.koiro.watersource.datagen | ||
|
||
import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput | ||
import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider | ||
import net.minecraft.data.server.recipe.RecipeJsonProvider | ||
import net.minecraft.fluid.Fluid | ||
import net.minecraft.fluid.Fluids | ||
import net.minecraft.recipe.Ingredient | ||
import net.minecraft.util.Identifier | ||
import xyz.koiro.watersource.WaterSource | ||
import xyz.koiro.watersource.datagen.recipe.StrainerFilteringFluidRecipeJsonBuilder | ||
import xyz.koiro.watersource.world.fluid.ModFluids | ||
import xyz.koiro.watersource.world.tag.ModTags | ||
import java.util.function.Consumer | ||
|
||
class ModRecipeGenerator(output: FabricDataOutput?) : FabricRecipeProvider(output) { | ||
override fun generate(exporter: Consumer<RecipeJsonProvider>?) { | ||
genSFFRecipe( | ||
exporter, | ||
WaterSource.identifier("water_to_purified_water"), | ||
Fluids.WATER, | ||
ModFluids.PURIFIED_WATER, | ||
Ingredient.fromTag(ModTags.Item.PURIFICATION_STRAINER) | ||
) | ||
} | ||
|
||
private fun genSFFRecipe( | ||
exporter: Consumer<RecipeJsonProvider>?, | ||
id: Identifier, | ||
inFluid: Fluid, | ||
outFluid: Fluid, | ||
strainer: Ingredient | ||
) { | ||
StrainerFilteringFluidRecipeJsonBuilder(id, outFluid, inFluid, strainer).offerTo(exporter, id) | ||
} | ||
} |
92 changes: 92 additions & 0 deletions
92
...in/kotlin/xyz/koiro/watersource/datagen/recipe/StrainerFilteringFluidRecipeJsonBuilder.kt
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,92 @@ | ||
package xyz.koiro.watersource.datagen.recipe | ||
|
||
import com.google.gson.JsonObject | ||
import net.minecraft.advancement.Advancement | ||
import net.minecraft.advancement.AdvancementRewards | ||
import net.minecraft.advancement.CriterionMerger | ||
import net.minecraft.advancement.criterion.CriterionConditions | ||
import net.minecraft.advancement.criterion.RecipeUnlockedCriterion | ||
import net.minecraft.data.server.recipe.CraftingRecipeJsonBuilder | ||
import net.minecraft.data.server.recipe.RecipeJsonProvider | ||
import net.minecraft.fluid.Fluid | ||
import net.minecraft.item.Item | ||
import net.minecraft.item.Items | ||
import net.minecraft.recipe.Ingredient | ||
import net.minecraft.recipe.RecipeSerializer | ||
import net.minecraft.util.Identifier | ||
import xyz.koiro.watersource.identifier | ||
import xyz.koiro.watersource.world.recipe.ModRecipes | ||
import java.util.function.Consumer | ||
|
||
class StrainerFilteringFluidRecipeJsonBuilder( | ||
val id: Identifier, | ||
val inFluid: Fluid, | ||
val outFluid: Fluid, | ||
val strainer: Ingredient | ||
) : CraftingRecipeJsonBuilder { | ||
var advancementBuilder: Advancement.Builder? = null | ||
var advancementId: Identifier? = null | ||
var group: String? = null | ||
|
||
fun advancement(advancementId: Identifier, advancementBuilder: Advancement.Builder): CraftingRecipeJsonBuilder { | ||
this.advancementId = advancementId | ||
this.advancementBuilder = advancementBuilder | ||
return this | ||
} | ||
|
||
override fun criterion(name: String?, conditions: CriterionConditions?): CraftingRecipeJsonBuilder { | ||
this.advancementBuilder?.criterion(name, conditions) | ||
return this | ||
} | ||
|
||
override fun group(group: String?): CraftingRecipeJsonBuilder { | ||
this.group = group | ||
return this | ||
} | ||
|
||
override fun getOutputItem(): Item { | ||
return Items.APPLE | ||
} | ||
|
||
override fun offerTo(exporter: Consumer<RecipeJsonProvider>?, recipeId: Identifier?) { | ||
advancementBuilder?.parent(CraftingRecipeJsonBuilder.ROOT) | ||
?.criterion("has_the_recipe", RecipeUnlockedCriterion.create(recipeId)) | ||
?.rewards(AdvancementRewards.Builder.recipe(recipeId))?.criteriaMerger(CriterionMerger.OR) | ||
exporter?.accept( | ||
Provider( | ||
id, | ||
inFluid.identifier().toString(), | ||
outFluid.identifier().toString(), | ||
strainer, | ||
advancementBuilder, | ||
advancementId, | ||
group, | ||
) | ||
) | ||
} | ||
|
||
class Provider( | ||
val id: Identifier, | ||
val inFluidId: String, | ||
val outFluidId: String, | ||
val strainer: Ingredient, | ||
val advancementBuilder: Advancement.Builder?, | ||
val advancementId: Identifier?, | ||
val group: String?, | ||
) : RecipeJsonProvider { | ||
override fun serialize(json: JsonObject) { | ||
if (!group.isNullOrBlank()) json.addProperty("group", group) | ||
json.addProperty("fluidIn", inFluidId) | ||
json.addProperty("fluidOut", outFluidId) | ||
json.add("strainer", strainer.toJson()) | ||
} | ||
|
||
override fun getRecipeId(): Identifier = id | ||
|
||
override fun getSerializer(): RecipeSerializer<*> = ModRecipes.STRAINER_FILTERING_FLUID_SERIALIZER | ||
|
||
override fun toAdvancementJson(): JsonObject? = this.advancementBuilder?.toJson() | ||
|
||
override fun getAdvancementId(): Identifier? = this.advancementId | ||
} | ||
} |
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
17 changes: 17 additions & 0 deletions
17
src/main/kotlin/xyz/koiro/watersource/world/item/Strainer.kt
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 |
---|---|---|
@@ -1,7 +1,24 @@ | ||
package xyz.koiro.watersource.world.item | ||
|
||
import net.minecraft.item.Item | ||
import net.minecraft.item.ItemStack | ||
import xyz.koiro.watersource.WSConfig | ||
import kotlin.math.ceil | ||
|
||
class Strainer(settings: Settings?) : Item(settings) { | ||
fun calCostDamage(strainerStack: ItemStack, volume: Long): Int { | ||
return ceil(volume.toDouble() / WSConfig.UNIT_DRINK_VOLUME.toDouble()).toInt() | ||
} | ||
|
||
fun useStrainer(strainerStack: ItemStack, volume: Long): ItemStack { | ||
val dmg = calCostDamage(strainerStack, volume) | ||
val remainedStrainer = if (strainerStack.damage + dmg >= strainerStack.maxDamage) { | ||
ItemStack(ModItems.WASTE_STRAINER) | ||
} else { | ||
val strainerCopy = strainerStack.copy() | ||
strainerCopy.damage += dmg | ||
strainerCopy | ||
} | ||
return remainedStrainer | ||
} | ||
} |
19 changes: 19 additions & 0 deletions
19
src/main/kotlin/xyz/koiro/watersource/world/recipe/ModRecipes.kt
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 |
---|---|---|
@@ -1,6 +1,25 @@ | ||
package xyz.koiro.watersource.world.recipe | ||
|
||
import net.minecraft.recipe.RecipeSerializer | ||
import net.minecraft.recipe.RecipeType | ||
import net.minecraft.registry.Registries | ||
import net.minecraft.registry.Registry | ||
import net.minecraft.util.Identifier | ||
import xyz.koiro.watersource.WaterSource | ||
|
||
object ModRecipes { | ||
|
||
fun initialize(){ | ||
} | ||
|
||
val STRAINER_FILTERING_FLUID_TYPE = registerRecipeType("strainer_filtering_fluid_type", StrainerFilteringFluidRecipe.Type()) | ||
val STRAINER_FILTERING_FLUID_SERIALIZER = registerRecipeSerializer("strainer_filtering_fluid_serializer", StrainerFilteringFluidRecipe.Serializer()) | ||
|
||
private fun registerRecipeType(registryName: String, recipeType: RecipeType<*>): RecipeType<*> { | ||
return Registry.register(Registries.RECIPE_TYPE, Identifier(WaterSource.MODID, registryName), recipeType) | ||
} | ||
|
||
private fun registerRecipeSerializer(registryName: String, recipeType: RecipeSerializer<*>): RecipeSerializer<*> { | ||
return Registry.register(Registries.RECIPE_SERIALIZER, Identifier(WaterSource.MODID, registryName), recipeType) | ||
} | ||
} |
135 changes: 135 additions & 0 deletions
135
src/main/kotlin/xyz/koiro/watersource/world/recipe/StrainerFilteringFluidRecipe.kt
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,135 @@ | ||
package xyz.koiro.watersource.world.recipe | ||
|
||
import com.google.gson.JsonObject | ||
import net.minecraft.fluid.Fluid | ||
import net.minecraft.inventory.RecipeInputInventory | ||
import net.minecraft.item.ItemStack | ||
import net.minecraft.network.PacketByteBuf | ||
import net.minecraft.recipe.Ingredient | ||
import net.minecraft.recipe.RecipeSerializer | ||
import net.minecraft.recipe.RecipeType | ||
import net.minecraft.recipe.SpecialCraftingRecipe | ||
import net.minecraft.recipe.book.CraftingRecipeCategory | ||
import net.minecraft.registry.DynamicRegistryManager | ||
import net.minecraft.registry.Registries | ||
import net.minecraft.util.Identifier | ||
import net.minecraft.util.collection.DefaultedList | ||
import net.minecraft.world.World | ||
import xyz.koiro.watersource.api.getOrCreateFluidStorageData | ||
import xyz.koiro.watersource.api.modifyFluidStorage | ||
import xyz.koiro.watersource.identifier | ||
import xyz.koiro.watersource.world.item.Strainer | ||
|
||
class StrainerFilteringFluidRecipe( | ||
val inFluid: Fluid, val outFluid: Fluid, | ||
val id: Identifier, val strainer: Ingredient | ||
) : SpecialCraftingRecipe(id, CraftingRecipeCategory.MISC) { | ||
fun getInputAndStrainer(inventory: RecipeInputInventory): Ctx? { | ||
if (inventory.size() == 2) { | ||
var strainerStack: ItemStack? = null | ||
var inputStack: ItemStack? = null | ||
var sIndex = 0 | ||
var iIndex = 0 | ||
|
||
for (i in 0..<inventory.size()) { | ||
val stack = inventory.getStack(i) | ||
if (this.strainer.test(strainerStack)) { | ||
strainerStack = stack | ||
sIndex = i | ||
} | ||
if (stack.getOrCreateFluidStorageData()?.fluid == inFluid) { | ||
inputStack = stack | ||
iIndex = i | ||
} | ||
} | ||
if (inputStack != null && strainerStack != null) | ||
return Ctx(strainerStack, inputStack, sIndex, iIndex) | ||
} | ||
return null; | ||
} | ||
|
||
override fun matches(inventory: RecipeInputInventory, world: World): Boolean { | ||
getInputAndStrainer(inventory)?.let { ctx -> | ||
val input = ctx.input | ||
val strainer = ctx.strainer | ||
|
||
input.getOrCreateFluidStorageData()?.let { fluidStorageData -> | ||
(strainer.item as? Strainer)?.calCostDamage(strainer, fluidStorageData.amount)?.let { dmg -> | ||
return strainer.damage + dmg < strainer.maxDamage | ||
} | ||
} | ||
} | ||
return false | ||
} | ||
|
||
data class Ctx(val strainer: ItemStack, val input: ItemStack, val strainerIndex: Int, val inputIndex: Int) | ||
|
||
override fun craft(inventory: RecipeInputInventory, registryManager: DynamicRegistryManager): ItemStack? { | ||
getInputAndStrainer(inventory)?.let { ctx -> | ||
val input = ctx.input | ||
|
||
val output = input.copy() | ||
output.modifyFluidStorage { _, fluidStorageData -> | ||
fluidStorageData.copy(fluid = outFluid) | ||
} | ||
return output | ||
} | ||
return ItemStack.EMPTY | ||
} | ||
|
||
override fun getRemainder(inventory: RecipeInputInventory): DefaultedList<ItemStack> { | ||
val defaultedList = super.getRemainder(inventory) | ||
getInputAndStrainer(inventory)?.let { ctx -> | ||
ctx.input.getOrCreateFluidStorageData()?.let { fluidStorageData -> | ||
val remained = (ctx.strainer.item as? Strainer)?.useStrainer( | ||
strainerStack = ctx.strainer, | ||
volume = fluidStorageData.amount | ||
) ?: ItemStack.EMPTY | ||
defaultedList[ctx.strainerIndex] = remained | ||
} | ||
} | ||
return defaultedList | ||
} | ||
|
||
override fun fits(width: Int, height: Int): Boolean { | ||
return true | ||
} | ||
|
||
override fun getOutput(registryManager: DynamicRegistryManager?): ItemStack { | ||
return ItemStack.EMPTY | ||
} | ||
|
||
override fun getId(): Identifier = id | ||
|
||
override fun getSerializer(): RecipeSerializer<*> { | ||
return ModRecipes.STRAINER_FILTERING_FLUID_SERIALIZER | ||
} | ||
|
||
override fun getType(): RecipeType<*> { | ||
return ModRecipes.STRAINER_FILTERING_FLUID_TYPE | ||
} | ||
|
||
class Type: RecipeType<StrainerFilteringFluidRecipe> | ||
|
||
class Serializer : RecipeSerializer<StrainerFilteringFluidRecipe> { | ||
override fun read(id: Identifier, json: JsonObject): StrainerFilteringFluidRecipe { | ||
val fI = Registries.FLUID.get(Identifier.tryParse(json.get("fluidIn").asString)) | ||
val fO = Registries.FLUID.get(Identifier.tryParse(json.get("fluidOut").asString)) | ||
val strainer = Ingredient.fromJson(json.get("strainer")) | ||
return StrainerFilteringFluidRecipe(fI, fO, id, strainer) | ||
} | ||
|
||
override fun read(id: Identifier, buf: PacketByteBuf): StrainerFilteringFluidRecipe { | ||
val fI = Registries.FLUID.get(Identifier.tryParse(buf.readString())) | ||
val fO = Registries.FLUID.get(Identifier.tryParse(buf.readString())) | ||
val strainer = Ingredient.fromPacket(buf) | ||
return StrainerFilteringFluidRecipe(fI, fO, id, strainer) | ||
} | ||
|
||
override fun write(buf: PacketByteBuf, recipe: StrainerFilteringFluidRecipe) { | ||
buf.writeString(recipe.inFluid.identifier().toString()) | ||
buf.writeString(recipe.outFluid.identifier().toString()) | ||
recipe.strainer.write(buf) | ||
} | ||
} | ||
} |
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