From 11bd6fc165d7fa8d95f17f1d81d49fad69137e06 Mon Sep 17 00:00:00 2001 From: Koiro <1165997495@qq.com> Date: Fri, 31 May 2024 09:43:58 +0800 Subject: [PATCH] feat: fix strainer filtering recipe not work rft: IHydrationUsable --- .../watersource/WaterSourceDataGenerator.kt | 2 + .../datagen/HydrationDataGenerator.kt | 14 +++- ...TagProvider.kt => ModFluidTagGenerator.kt} | 10 ++- .../datagen/ModItemTagGenerator.kt | 5 ++ .../watersource/datagen/ModRecipeGenerator.kt | 2 +- ...StrainerFilteringFluidRecipeJsonBuilder.kt | 4 +- .../watersource/event/ModEventsRegistries.kt | 26 +++----- .../watersource/world/block/ModBlocks.kt | 2 +- .../world/item/DrinkableContainer.kt | 33 ++++++++-- .../watersource/world/item/FluidContainer.kt | 16 +++-- .../world/item/IHydrationUsable.kt | 33 ++++++++++ .../koiro/watersource/world/item/ModItems.kt | 1 + .../watersource/world/recipe/ModRecipes.kt | 3 +- .../recipe/StrainerFilteringFluidRecipe.kt | 64 ++++++++----------- 14 files changed, 140 insertions(+), 75 deletions(-) rename src/main/kotlin/xyz/koiro/watersource/datagen/{ModFluidTagProvider.kt => ModFluidTagGenerator.kt} (63%) create mode 100644 src/main/kotlin/xyz/koiro/watersource/world/item/IHydrationUsable.kt diff --git a/src/main/kotlin/xyz/koiro/watersource/WaterSourceDataGenerator.kt b/src/main/kotlin/xyz/koiro/watersource/WaterSourceDataGenerator.kt index 51147cb..373aa23 100644 --- a/src/main/kotlin/xyz/koiro/watersource/WaterSourceDataGenerator.kt +++ b/src/main/kotlin/xyz/koiro/watersource/WaterSourceDataGenerator.kt @@ -7,6 +7,7 @@ import xyz.koiro.watersource.datagen.ModChineseLangGenerator import xyz.koiro.watersource.datagen.ModEnglishLangGenerator import xyz.koiro.watersource.datagen.ModModelGenerator import xyz.koiro.watersource.datagen.ModItemTagGenerator +import xyz.koiro.watersource.datagen.ModFluidTagGenerator import xyz.koiro.watersource.datagen.ModRecipeGenerator object WaterSourceDataGenerator : DataGeneratorEntrypoint { @@ -17,6 +18,7 @@ object WaterSourceDataGenerator : DataGeneratorEntrypoint { pack.addProvider(::ModChineseLangGenerator) pack.addProvider(::ModEnglishLangGenerator) pack.addProvider(::ModItemTagGenerator) + pack.addProvider(::ModFluidTagGenerator) pack.addProvider(::ModRecipeGenerator) } } \ No newline at end of file diff --git a/src/main/kotlin/xyz/koiro/watersource/datagen/HydrationDataGenerator.kt b/src/main/kotlin/xyz/koiro/watersource/datagen/HydrationDataGenerator.kt index 57e225a..8cbc8f8 100644 --- a/src/main/kotlin/xyz/koiro/watersource/datagen/HydrationDataGenerator.kt +++ b/src/main/kotlin/xyz/koiro/watersource/datagen/HydrationDataGenerator.kt @@ -7,10 +7,18 @@ import net.minecraft.item.Items import xyz.koiro.watersource.WaterSource import xyz.koiro.watersource.datagen.provider.HydrationDataProvider import xyz.koiro.watersource.world.effect.ModStatusEffects +import xyz.koiro.watersource.world.fluid.ModFluids -class HydrationDataGenerator(output: DataOutput): HydrationDataProvider(output) { +class HydrationDataGenerator(output: DataOutput) : HydrationDataProvider(output) { override fun addData(adder: HydrationDataAdder) { - adder.add(WaterSource.identifier("item_apple"), item(Items.APPLE, 1, 1)) - adder.add(WaterSource.identifier("fluid_water"), fluid(Fluids.WATER, 2, 0, StatusEffectInstance(ModStatusEffects.THIRSTY, 1200))) + adder.add(WaterSource.identifier("item_apple"), item(Items.APPLE, 1, 2)) + adder.add( + WaterSource.identifier("fluid_water"), + fluid(Fluids.WATER, 2, 0, StatusEffectInstance(ModStatusEffects.THIRSTY, 1200)) + ) + adder.add( + WaterSource.identifier("fluid_purified_water"), + fluid(ModFluids.PURIFIED_WATER, 4, 6) + ) } } \ No newline at end of file diff --git a/src/main/kotlin/xyz/koiro/watersource/datagen/ModFluidTagProvider.kt b/src/main/kotlin/xyz/koiro/watersource/datagen/ModFluidTagGenerator.kt similarity index 63% rename from src/main/kotlin/xyz/koiro/watersource/datagen/ModFluidTagProvider.kt rename to src/main/kotlin/xyz/koiro/watersource/datagen/ModFluidTagGenerator.kt index 262d73d..4ee444e 100644 --- a/src/main/kotlin/xyz/koiro/watersource/datagen/ModFluidTagProvider.kt +++ b/src/main/kotlin/xyz/koiro/watersource/datagen/ModFluidTagGenerator.kt @@ -2,17 +2,21 @@ package xyz.koiro.watersource.datagen import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput import net.fabricmc.fabric.api.datagen.v1.provider.FabricTagProvider.FluidTagProvider +import net.fabricmc.fabric.api.datagen.v1.provider.FabricTagProvider.ItemTagProvider import net.minecraft.registry.RegistryWrapper import net.minecraft.registry.tag.FluidTags import xyz.koiro.watersource.world.fluid.ModFluids +import xyz.koiro.watersource.world.item.ModItems +import xyz.koiro.watersource.world.tag.ModTags import java.util.concurrent.CompletableFuture -class ModFluidTagProvider( +class ModFluidTagGenerator( output: FabricDataOutput?, completableFuture: CompletableFuture? ) : FluidTagProvider(output, completableFuture) { override fun configure(arg: RegistryWrapper.WrapperLookup?) { - getOrCreateTagBuilder(FluidTags.WATER).add(ModFluids.PURIFIED_WATER) - getOrCreateTagBuilder(FluidTags.WATER).add(ModFluids.FLOWING_PURIFIED_WATER) + getOrCreateTagBuilder(FluidTags.WATER) + .add(ModFluids.PURIFIED_WATER) + .add(ModFluids.FLOWING_PURIFIED_WATER) } } \ No newline at end of file diff --git a/src/main/kotlin/xyz/koiro/watersource/datagen/ModItemTagGenerator.kt b/src/main/kotlin/xyz/koiro/watersource/datagen/ModItemTagGenerator.kt index 81bb75e..45971bb 100644 --- a/src/main/kotlin/xyz/koiro/watersource/datagen/ModItemTagGenerator.kt +++ b/src/main/kotlin/xyz/koiro/watersource/datagen/ModItemTagGenerator.kt @@ -8,6 +8,7 @@ import net.minecraft.registry.RegistryWrapper import net.minecraft.registry.tag.TagKey import net.minecraft.util.Identifier import xyz.koiro.watersource.world.item.ModItems +import xyz.koiro.watersource.world.tag.ModTags import java.util.concurrent.CompletableFuture class ModItemTagGenerator( @@ -21,5 +22,9 @@ class ModItemTagGenerator( getOrCreateTagBuilder(TagKey.of(RegistryKeys.ITEM, Identifier(id))).add(it.first) } } + + getOrCreateTagBuilder(ModTags.Item.PURIFICATION_STRAINER) + .add(ModItems.PAPER_STRAINER) + .add(ModItems.NATURAL_STRAINER) } } diff --git a/src/main/kotlin/xyz/koiro/watersource/datagen/ModRecipeGenerator.kt b/src/main/kotlin/xyz/koiro/watersource/datagen/ModRecipeGenerator.kt index 6e2877c..5003b99 100644 --- a/src/main/kotlin/xyz/koiro/watersource/datagen/ModRecipeGenerator.kt +++ b/src/main/kotlin/xyz/koiro/watersource/datagen/ModRecipeGenerator.kt @@ -31,6 +31,6 @@ class ModRecipeGenerator(output: FabricDataOutput?) : FabricRecipeProvider(outpu outFluid: Fluid, strainer: Ingredient ) { - StrainerFilteringFluidRecipeJsonBuilder(id, outFluid, inFluid, strainer).offerTo(exporter, id) + StrainerFilteringFluidRecipeJsonBuilder(id, inFluid, outFluid, strainer).offerTo(exporter, id) } } \ No newline at end of file diff --git a/src/main/kotlin/xyz/koiro/watersource/datagen/recipe/StrainerFilteringFluidRecipeJsonBuilder.kt b/src/main/kotlin/xyz/koiro/watersource/datagen/recipe/StrainerFilteringFluidRecipeJsonBuilder.kt index efd24f4..07a1e6a 100644 --- a/src/main/kotlin/xyz/koiro/watersource/datagen/recipe/StrainerFilteringFluidRecipeJsonBuilder.kt +++ b/src/main/kotlin/xyz/koiro/watersource/datagen/recipe/StrainerFilteringFluidRecipeJsonBuilder.kt @@ -71,7 +71,7 @@ class StrainerFilteringFluidRecipeJsonBuilder( val outFluidId: String, val strainer: Ingredient, val advancementBuilder: Advancement.Builder?, - val advancementId: Identifier?, + val advancementIdentifier: Identifier?, val group: String?, ) : RecipeJsonProvider { override fun serialize(json: JsonObject) { @@ -87,6 +87,6 @@ class StrainerFilteringFluidRecipeJsonBuilder( override fun toAdvancementJson(): JsonObject? = this.advancementBuilder?.toJson() - override fun getAdvancementId(): Identifier? = this.advancementId + override fun getAdvancementId(): Identifier? = this.advancementIdentifier } } diff --git a/src/main/kotlin/xyz/koiro/watersource/event/ModEventsRegistries.kt b/src/main/kotlin/xyz/koiro/watersource/event/ModEventsRegistries.kt index ad5b409..a78adf8 100644 --- a/src/main/kotlin/xyz/koiro/watersource/event/ModEventsRegistries.kt +++ b/src/main/kotlin/xyz/koiro/watersource/event/ModEventsRegistries.kt @@ -21,6 +21,7 @@ import xyz.koiro.watersource.api.ifInSurvivalAndGetWaterData import xyz.koiro.watersource.data.HydrationData import xyz.koiro.watersource.world.effect.ModStatusEffects import xyz.koiro.watersource.world.item.DrinkableContainer +import xyz.koiro.watersource.world.item.IHydrationUsable import java.util.* object ModEventsRegistries { @@ -149,24 +150,17 @@ object ModEventsRegistries { player.ifInSurvivalAndGetWaterData { waterLevelData -> WaterSource.LOGGER.info("Player ${player.name} finishes using ${stack.name}") - val isItemDrinkable = stack.item is DrinkableContainer - val data: HydrationData? = if (isItemDrinkable) { - stack.getOrCreateFluidStorageData()?.let { storage -> - HydrationDataManager.SERVER.findByFluid(storage.fluid) + val item = stack.item + if (item is IHydrationUsable){ + val data = item.findHydrationData(stack, HydrationDataManager.SERVER) + data?.let { + item.hydrationUse(stack, it, waterLevelData, player) + item.onHydrationUsingFinished(stack) } } else { - HydrationDataManager.SERVER.findByItemStack(stack) - } - - data?.let { hydrationData -> - val multiplier = if (isItemDrinkable) (stack.item as DrinkableContainer).drinkVolumeMultiplier else 1 - val level = hydrationData.level - val saturation = hydrationData.saturation - waterLevelData.restoreWater(level, saturation, multiplier) - waterLevelData.updateToClient(player) - hydrationData.applyEffectsToPlayer(player, multiplier) - if (isItemDrinkable){ - stack.extractFluid(WSConfig.UNIT_DRINK_VOLUME) + val data = HydrationDataManager.SERVER.findByItemStack(stack) + data?.let { + IHydrationUsable.restoreWaterFromHydrationData(it, waterLevelData, player) } } } diff --git a/src/main/kotlin/xyz/koiro/watersource/world/block/ModBlocks.kt b/src/main/kotlin/xyz/koiro/watersource/world/block/ModBlocks.kt index 1b27d8e..941a81c 100644 --- a/src/main/kotlin/xyz/koiro/watersource/world/block/ModBlocks.kt +++ b/src/main/kotlin/xyz/koiro/watersource/world/block/ModBlocks.kt @@ -26,7 +26,7 @@ object ModBlocks { } fun reflectAutoGenDataBlocks(): Iterable> = - ModItems::class.java.getDeclaredFields().filter { + ModBlocks::class.java.getDeclaredFields().filter { val block = it.get(null) as? Block val isBlock = block != null val isAutoGenData = it.getAnnotation(AutoGenBlockData::class.java) != null diff --git a/src/main/kotlin/xyz/koiro/watersource/world/item/DrinkableContainer.kt b/src/main/kotlin/xyz/koiro/watersource/world/item/DrinkableContainer.kt index 57851f1..810c180 100644 --- a/src/main/kotlin/xyz/koiro/watersource/world/item/DrinkableContainer.kt +++ b/src/main/kotlin/xyz/koiro/watersource/world/item/DrinkableContainer.kt @@ -4,21 +4,25 @@ package xyz.koiro.watersource.world.item import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.ItemStack +import net.minecraft.item.ItemUsage +import net.minecraft.server.network.ServerPlayerEntity import net.minecraft.util.ActionResult import net.minecraft.util.Hand import net.minecraft.util.TypedActionResult import net.minecraft.util.UseAction import net.minecraft.world.World import xyz.koiro.watersource.WSConfig -import xyz.koiro.watersource.WaterSource +import xyz.koiro.watersource.api.extractFluid import xyz.koiro.watersource.api.getOrCreateFluidStorageData +import xyz.koiro.watersource.data.HydrationData import xyz.koiro.watersource.data.HydrationDataManager +import xyz.koiro.watersource.world.attachment.WaterLevelData open class DrinkableContainer( settings: Settings, capacity: Long, val useDuration: Int = 32, val drinkVolumeMultiplier: Int = 1 -) : FluidContainer(settings, capacity) { +) : FluidContainer(settings, capacity), IHydrationUsable { override fun use(world: World, user: PlayerEntity, hand: Hand): TypedActionResult { val result = super.use(world, user, hand) if (result.result != ActionResult.PASS) return result @@ -33,9 +37,7 @@ open class DrinkableContainer( val fluid = storageData.fluid HydrationDataManager.SERVER.findByFluid(fluid)?.let { hydration -> if (storageData.amount >= WSConfig.UNIT_DRINK_VOLUME) { - WaterSource.LOGGER.info("Debug use drinkable") - //restore player water level - return TypedActionResult.consume(user.getStackInHand(hand)) + return ItemUsage.consumeHeldItem(world, user, hand) } } } @@ -49,4 +51,25 @@ open class DrinkableContainer( override fun getUseAction(stack: ItemStack?): UseAction { return UseAction.DRINK } + + override fun onHydrationUsingFinished(stack: ItemStack) { + updateDamage(stack) + } + + override fun hydrationUse( + stack: ItemStack, + hydrationData: HydrationData, + waterLevelData: WaterLevelData, + player: ServerPlayerEntity + ) { + val multiplier = drinkVolumeMultiplier + IHydrationUsable.restoreWaterFromHydrationData(hydrationData, waterLevelData, player, multiplier) + stack.extractFluid(WSConfig.UNIT_DRINK_VOLUME) + } + + override fun findHydrationData(stack: ItemStack, manager: HydrationDataManager): HydrationData? { + return stack.getOrCreateFluidStorageData()?.let { + manager.findByFluid(it.fluid) + } + } } \ No newline at end of file diff --git a/src/main/kotlin/xyz/koiro/watersource/world/item/FluidContainer.kt b/src/main/kotlin/xyz/koiro/watersource/world/item/FluidContainer.kt index 65375de..58dfcb4 100644 --- a/src/main/kotlin/xyz/koiro/watersource/world/item/FluidContainer.kt +++ b/src/main/kotlin/xyz/koiro/watersource/world/item/FluidContainer.kt @@ -24,6 +24,7 @@ import xyz.koiro.watersource.* import xyz.koiro.watersource.api.FluidStorageData import xyz.koiro.watersource.api.getOrCreateFluidStorageData import xyz.koiro.watersource.api.insertFluid +import kotlin.math.round open class FluidContainer( settings: Settings, @@ -37,6 +38,14 @@ open class FluidContainer( return fluid == currentData.fluid || currentData.isBlank() } + fun updateDamage(stack: ItemStack) { + stack.getOrCreateFluidStorageData()?.let { + val amount = it.amount + val damage = round((1 - amount.toDouble() / capacity.toDouble()) * maxDamage).toInt() + stack.damage = damage + } + } + override fun use(world: World, user: PlayerEntity, hand: Hand): TypedActionResult { if (!world.isClient()) { //todo get delta @@ -46,6 +55,7 @@ open class FluidContainer( val blockState = world.getBlockState(hit.blockPos) if (blockState.fluidState.fluid == Fluids.WATER) { handItem.insertFluid(Fluids.WATER) { it.capacity } + updateDamage(handItem) return TypedActionResult.success(handItem) } } @@ -65,7 +75,7 @@ open class FluidContainer( val nbtCompound = NbtCompound() this.writeNbt(nbtCompound) stack.setSubNbt("FluidStorage", nbtCompound) - updateDamageFromAmount(stack, this.getAmount()) + updateDamage(stack) } } if (nbt != null) { @@ -74,10 +84,6 @@ open class FluidContainer( return ret } - open fun updateDamageFromAmount(stack: ItemStack, amount: Long) { - stack.damage = stack.maxDamage - (amount / WSConfig.UNIT_DRINK_VOLUME).toInt() - } - override fun appendTooltip( stack: ItemStack, world: World?, diff --git a/src/main/kotlin/xyz/koiro/watersource/world/item/IHydrationUsable.kt b/src/main/kotlin/xyz/koiro/watersource/world/item/IHydrationUsable.kt new file mode 100644 index 0000000..56c661b --- /dev/null +++ b/src/main/kotlin/xyz/koiro/watersource/world/item/IHydrationUsable.kt @@ -0,0 +1,33 @@ +package xyz.koiro.watersource.world.item + +import net.minecraft.item.ItemStack +import net.minecraft.server.network.ServerPlayerEntity +import xyz.koiro.watersource.data.HydrationData +import xyz.koiro.watersource.data.HydrationDataManager +import xyz.koiro.watersource.world.attachment.WaterLevelData + +interface IHydrationUsable { + fun onHydrationUsingFinished(stack: ItemStack) + fun hydrationUse( + stack: ItemStack, + hydrationData: HydrationData, + waterLevelData: WaterLevelData, + player: ServerPlayerEntity + ) + fun findHydrationData(stack: ItemStack, manager: HydrationDataManager): HydrationData? + + companion object{ + fun restoreWaterFromHydrationData( + hydrationData: HydrationData, + waterLevelData: WaterLevelData, + player: ServerPlayerEntity, + multiplier: Int = 1, + ){ + val level = hydrationData.level + val saturation = hydrationData.saturation + waterLevelData.restoreWater(level, saturation, multiplier) + waterLevelData.updateToClient(player) + hydrationData.applyEffectsToPlayer(player, multiplier) + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/xyz/koiro/watersource/world/item/ModItems.kt b/src/main/kotlin/xyz/koiro/watersource/world/item/ModItems.kt index f986eb1..3578629 100644 --- a/src/main/kotlin/xyz/koiro/watersource/world/item/ModItems.kt +++ b/src/main/kotlin/xyz/koiro/watersource/world/item/ModItems.kt @@ -42,6 +42,7 @@ object ModItems { @AutoGenItemData(enLang = "Purified Water Bottle", cnLang = "净水瓶") val PURIFIED_WATTER_BOTTLE = registerItem("purified_water_bottle", DrinkOnceItem(FabricItemSettings().maxCount(0), Items.GLASS_BOTTLE)) + fun active() { } diff --git a/src/main/kotlin/xyz/koiro/watersource/world/recipe/ModRecipes.kt b/src/main/kotlin/xyz/koiro/watersource/world/recipe/ModRecipes.kt index 1772bc8..448fe35 100644 --- a/src/main/kotlin/xyz/koiro/watersource/world/recipe/ModRecipes.kt +++ b/src/main/kotlin/xyz/koiro/watersource/world/recipe/ModRecipes.kt @@ -12,8 +12,7 @@ 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()) + val STRAINER_FILTERING_FLUID_SERIALIZER = registerRecipeSerializer("strainer_filtering_fluid", StrainerFilteringFluidRecipe.Serializer()) private fun registerRecipeType(registryName: String, recipeType: RecipeType<*>): RecipeType<*> { return Registry.register(Registries.RECIPE_TYPE, Identifier(WaterSource.MODID, registryName), recipeType) diff --git a/src/main/kotlin/xyz/koiro/watersource/world/recipe/StrainerFilteringFluidRecipe.kt b/src/main/kotlin/xyz/koiro/watersource/world/recipe/StrainerFilteringFluidRecipe.kt index b110ac9..70de434 100644 --- a/src/main/kotlin/xyz/koiro/watersource/world/recipe/StrainerFilteringFluidRecipe.kt +++ b/src/main/kotlin/xyz/koiro/watersource/world/recipe/StrainerFilteringFluidRecipe.kt @@ -22,29 +22,27 @@ import xyz.koiro.watersource.world.item.Strainer class StrainerFilteringFluidRecipe( val inFluid: Fluid, val outFluid: Fluid, - val id: Identifier, val strainer: Ingredient + 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.. (strainer.item as? Strainer)?.calCostDamage(strainer, fluidStorageData.amount)?.let { dmg -> - return strainer.damage + dmg < strainer.maxDamage + return strainer.damage + dmg <= strainer.maxDamage } } } @@ -78,13 +76,15 @@ class StrainerFilteringFluidRecipe( } override fun getRemainder(inventory: RecipeInputInventory): DefaultedList { - val defaultedList = super.getRemainder(inventory) + val defaultedList = DefaultedList.ofSize(inventory.size(), ItemStack.EMPTY) + for (i in defaultedList.indices) { + val item = inventory.getStack(i).item + if (!item.hasRecipeRemainder()) continue + defaultedList[i] = ItemStack(item.recipeRemainder) + } 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 + val remained = (ctx.strainer.item as? Strainer)?.useStrainer(ctx.strainer, fluidStorageData.amount) ?: ItemStack.EMPTY defaultedList[ctx.strainerIndex] = remained } } @@ -92,24 +92,14 @@ class StrainerFilteringFluidRecipe( } override fun fits(width: Int, height: Int): Boolean { - return true + return width * height >= 2 } - 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 + class Type : RecipeType class Serializer : RecipeSerializer { override fun read(id: Identifier, json: JsonObject): StrainerFilteringFluidRecipe {