From 7d8d64c6d6bf699617909d11099303048904cbfc Mon Sep 17 00:00:00 2001 From: Koiro <1165997495@qq.com> Date: Mon, 17 Jun 2024 10:40:47 +0800 Subject: [PATCH] migration: solve 1.20.6 compiling error --- build.gradle | 18 +- gradle.properties | 13 +- .../watersource/api/VertexConsumersExt.kt | 2 +- .../event/ItemTooltipEventHandlers.kt | 6 +- .../network/ModClientNetworking.kt | 14 +- .../render/blockentity/FilterBERenderer.kt | 3 +- .../render/color/ModItemColorProviders.kt | 12 +- .../watersource/render/hud/ModClientHUD.kt | 3 +- .../resources/watersource.client.mixins.json | 2 +- .../xyz/koiro/watersource/ModItemGroups.kt | 4 +- .../kotlin/xyz/koiro/watersource/WSConfig.kt | 19 +- .../xyz/koiro/watersource/WaterSource.kt | 4 + .../watersource/WaterSourceDataGenerator.kt | 34 ++- .../xyz/koiro/watersource/{ => api}/Tools.kt | 16 +- .../api/serialize/IngredientFormat.kt | 53 ----- .../api/serialize/SerializeUtils.kt | 39 ---- .../api/storage/FluidStorageData.kt | 38 +++- .../api/storage/ItemFluidDataExt.kt | 11 +- .../api/storage/ItemStorageData.kt | 29 ++- .../xyz/koiro/watersource/data/DataManager.kt | 5 +- .../watersource/data/FilterRecipeData.kt | 41 ++-- .../data/FilterRecipeDataManager.kt | 20 +- .../koiro/watersource/data/HydrationData.kt | 203 ++++++++---------- .../watersource/data/HydrationDataManager.kt | 16 +- .../watersource/data/ModResourceRegistries.kt | 7 +- .../datagen/FilterRecipeDataGenerator.kt | 6 +- .../datagen/HydrationDataGenerator.kt | 22 +- .../datagen/ModBlockLootTableGenerator.kt | 6 +- .../datagen/ModChineseLangGenerator.kt | 10 +- .../datagen/ModEnglishLangGenerator.kt | 6 +- .../watersource/datagen/ModRecipeGenerator.kt | 16 +- .../provider/FilterRecipeDataProvider.kt | 21 +- .../datagen/provider/HydrationDataProvider.kt | 39 ++-- .../datagen/provider/ModDataProvider.kt | 29 ++- .../watersource/datagen/provider/Utils.kt | 2 +- ...StrainerFilteringFluidRecipeJsonBuilder.kt | 58 +---- .../StrainerFilteringItemRecipeJsonBuilder.kt | 63 +----- .../watersource/event/ModEventsHandlers.kt | 5 +- .../watersource/network/ModNetworking.kt | 11 +- .../network/UpdateWaterLevelPayload.kt | 28 +++ .../world/attachment/WaterLevelData.kt | 6 +- .../watersource/world/block/FilterBlock.kt | 27 ++- .../block/entity/ContainerBlockEntity.kt | 9 +- .../world/block/entity/FilterBlockEntity.kt | 46 ++-- .../datacomponent/ModDataComponentTypes.kt | 26 +++ .../world/effect/ModStatusEffects.kt | 3 +- .../enchantment/MoisturizingEnchantment.kt | 31 +-- .../world/item/EmptyFluidContainerItem.kt | 8 +- .../world/item/FluidContainerItem.kt | 46 +--- .../world/item/IHydrationUsable.kt | 2 +- .../koiro/watersource/world/item/ModItems.kt | 34 +-- .../koiro/watersource/world/item/Strainer.kt | 13 +- .../recipe/StrainerFilteringFluidRecipe.kt | 61 ++++-- .../recipe/StrainerFilteringItemRecipe.kt | 65 +++--- .../world/recipe/StrainerFilteringRecipe.kt | 20 +- src/main/resources/fabric.mod.json | 4 +- src/main/resources/watersource.mixins.json | 2 +- 57 files changed, 647 insertions(+), 690 deletions(-) rename src/main/kotlin/xyz/koiro/watersource/{ => api}/Tools.kt (56%) delete mode 100644 src/main/kotlin/xyz/koiro/watersource/api/serialize/IngredientFormat.kt delete mode 100644 src/main/kotlin/xyz/koiro/watersource/api/serialize/SerializeUtils.kt create mode 100644 src/main/kotlin/xyz/koiro/watersource/network/UpdateWaterLevelPayload.kt create mode 100644 src/main/kotlin/xyz/koiro/watersource/world/datacomponent/ModDataComponentTypes.kt diff --git a/build.gradle b/build.gradle index 15db58e..8540d96 100644 --- a/build.gradle +++ b/build.gradle @@ -64,11 +64,11 @@ dependencies { implementation 'com.akuleshov7:ktoml-core:0.5.1' implementation 'com.akuleshov7:ktoml-file:0.5.1' - // compile against the JEI API but do not include it at runtime - modCompileOnlyApi("mezz.jei:jei-${mc_version}-common-api:${jei_version}") - modCompileOnlyApi("mezz.jei:jei-${mc_version}-fabric-api:${jei_version}") - // at runtime, use the full JEI jar for Fabric - modRuntimeOnly("mezz.jei:jei-${mc_version}-fabric:${jei_version}") +// // compile against the JEI API but do not include it at runtime +// modCompileOnlyApi("mezz.jei:jei-${mc_version}-common-api:${jei_version}") +// modCompileOnlyApi("mezz.jei:jei-${mc_version}-fabric-api:${jei_version}") +// // at runtime, use the full JEI jar for Fabric +// modRuntimeOnly("mezz.jei:jei-${mc_version}-fabric:${jei_version}") } processResources { @@ -80,12 +80,12 @@ processResources { } tasks.withType(JavaCompile).configureEach { - it.options.release = 17 + it.options.release = 21 } tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all { kotlinOptions { - jvmTarget = 17 + jvmTarget = 21 } } @@ -95,8 +95,8 @@ java { // If you remove this line, sources will not be generated. withSourcesJar() - sourceCompatibility = JavaVersion.VERSION_17 - targetCompatibility = JavaVersion.VERSION_17 + sourceCompatibility = JavaVersion.VERSION_21 + targetCompatibility = JavaVersion.VERSION_21 } jar { diff --git a/gradle.properties b/gradle.properties index 94e408b..3a49cce 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,13 +1,13 @@ # Done to increase the memory available to gradle. -org.gradle.jvmargs=-Xmx1G +org.gradle.jvmargs=-Xmx3G org.gradle.parallel=true # Fabric Properties # check these on https://fabricmc.net/develop -mc_version=1.20.1 -yarn_mappings=1.20.1+build.10 -loader_version=0.15.7 -fabric_kotlin_version=1.10.18+kotlin.1.9.22 +mc_version=1.20.6 +yarn_mappings=1.20.6+build.1 +loader_version=0.15.10 +fabric_kotlin_version=1.11.0+kotlin.2.0.0 # Mod Properties mod_version=2.0.0 @@ -16,5 +16,4 @@ maven_group=xyz.koiro.watersource archives_base_name=watersource # Dependencies -fabric_version=0.92.0+1.20.1 -jei_version=15.3.0.4 \ No newline at end of file +fabric_version=0.97.8+1.20.6 \ No newline at end of file diff --git a/src/client/kotlin/xyz/koiro/watersource/api/VertexConsumersExt.kt b/src/client/kotlin/xyz/koiro/watersource/api/VertexConsumersExt.kt index 35df974..b509c1c 100644 --- a/src/client/kotlin/xyz/koiro/watersource/api/VertexConsumersExt.kt +++ b/src/client/kotlin/xyz/koiro/watersource/api/VertexConsumersExt.kt @@ -51,6 +51,6 @@ fun VertexConsumer.quadFace( .overlay(OverlayTexture.DEFAULT_UV) .texture(u, v) .light(240) - .normal(matrixStack.peek().normalMatrix, normalN.x, normalN.y, normalN.z).next() + .normal(matrixStack.peek(), normalN.x, normalN.y, normalN.z).next() } } \ No newline at end of file diff --git a/src/client/kotlin/xyz/koiro/watersource/event/ItemTooltipEventHandlers.kt b/src/client/kotlin/xyz/koiro/watersource/event/ItemTooltipEventHandlers.kt index f7e4acc..1a65457 100644 --- a/src/client/kotlin/xyz/koiro/watersource/event/ItemTooltipEventHandlers.kt +++ b/src/client/kotlin/xyz/koiro/watersource/event/ItemTooltipEventHandlers.kt @@ -20,7 +20,7 @@ object ItemTooltipEventHandlers { val renderItemTooltipHydrationData = ModClientEvents.DrawMouseoverTooltip { context, x, y, stack -> HydrationDataManager.findByItemStack(stack)?.let { hydrationData -> - val isThirty = hydrationData.effects.any { it.effect.effectType == ModStatusEffects.THIRSTY } + val isThirty = hydrationData.effects?.any { it.effect == ModStatusEffects.THIRSTY } ?: false if (hydrationData.isDry()) { if (WSClientConfig.format.showHydrationDryItemTooltip) drawDry(context, hydrationData, isThirty, x, y) @@ -62,8 +62,8 @@ object ItemTooltipEventHandlers { } fun drawRestoration(context: DrawContext, hydrationData: HydrationData, isThirty: Boolean, x: Int, y: Int) { - val level = hydrationData.level - val saturation = hydrationData.saturation + val level = hydrationData.level ?: 0 + val saturation = hydrationData.saturation ?: 0 val levelCount = ceil(level.toFloat() / 2f).toInt() val isLevelEndHalf = level % 2 != 0 diff --git a/src/client/kotlin/xyz/koiro/watersource/network/ModClientNetworking.kt b/src/client/kotlin/xyz/koiro/watersource/network/ModClientNetworking.kt index a3c7667..03a5952 100644 --- a/src/client/kotlin/xyz/koiro/watersource/network/ModClientNetworking.kt +++ b/src/client/kotlin/xyz/koiro/watersource/network/ModClientNetworking.kt @@ -7,19 +7,11 @@ import xyz.koiro.watersource.world.block.entity.FilterBlockEntity object ModClientNetworking { fun initialize() { - ClientPlayNetworking.registerGlobalReceiver(ModNetworking.UPDATE_WATER_DATA_ID){ client, _, buf, sent -> - val data = WaterLevelData.readBuf(buf) - + ClientPlayNetworking.registerGlobalReceiver(ModNetworking.UPDATE_WATER_LEVEL){ payload, handler -> + val client = handler.client() client.execute { val player = client.player!! - player.setAttached(ModAttachmentTypes.WATER_LEVEL, data) - } - } - ClientPlayNetworking.registerGlobalReceiver(ModNetworking.UPDATE_FILTER_ENTITY_ID) { mc, _, buf, sent -> - val pos = buf.readBlockPos() - val entity = mc.world?.getBlockEntity(pos) - if (entity is FilterBlockEntity) { - entity.readPacket(buf) + player.getAttachedOrCreate(ModAttachmentTypes.WATER_LEVEL).setData(payload.level, payload.saturation, payload.exhaustion) } } } diff --git a/src/client/kotlin/xyz/koiro/watersource/render/blockentity/FilterBERenderer.kt b/src/client/kotlin/xyz/koiro/watersource/render/blockentity/FilterBERenderer.kt index a3a82b4..7b2c1e5 100644 --- a/src/client/kotlin/xyz/koiro/watersource/render/blockentity/FilterBERenderer.kt +++ b/src/client/kotlin/xyz/koiro/watersource/render/blockentity/FilterBERenderer.kt @@ -1,7 +1,6 @@ package xyz.koiro.watersource.render.blockentity import com.mojang.blaze3d.systems.RenderSystem -import net.fabricmc.fabric.api.renderer.v1.render.RenderContext import net.minecraft.client.MinecraftClient import net.minecraft.client.render.RenderLayer import net.minecraft.client.render.VertexConsumerProvider @@ -63,7 +62,7 @@ class FilterBERenderer : BlockEntityRenderer { matrices.push() RenderSystem.enableBlend() - val consumer = vertexConsumers.getBuffer(RenderLayer.getTranslucentNoCrumbling()) + val consumer = vertexConsumers.getBuffer(RenderLayer.getGlintTranslucent()) val u0 = fluidSprite.minU val v0 = fluidSprite.minV val u1 = fluidSprite.maxU diff --git a/src/client/kotlin/xyz/koiro/watersource/render/color/ModItemColorProviders.kt b/src/client/kotlin/xyz/koiro/watersource/render/color/ModItemColorProviders.kt index 7859463..5550e23 100644 --- a/src/client/kotlin/xyz/koiro/watersource/render/color/ModItemColorProviders.kt +++ b/src/client/kotlin/xyz/koiro/watersource/render/color/ModItemColorProviders.kt @@ -2,28 +2,30 @@ package xyz.koiro.watersource.render.color import net.fabricmc.fabric.api.client.render.fluid.v1.FluidRenderHandlerRegistry import net.fabricmc.fabric.api.client.rendering.v1.ColorProviderRegistry +import net.fabricmc.fabric.api.client.rendering.v1.ColorResolverRegistry import net.minecraft.client.MinecraftClient import net.minecraft.item.ItemStack import net.minecraft.util.math.BlockPos +import net.minecraft.util.math.ColorHelper import xyz.koiro.watersource.api.storage.getOrCreateFluidStorageData import xyz.koiro.watersource.world.fluid.ModFluids import xyz.koiro.watersource.world.item.ModItems object ModItemColorProviders { val cupColorProvider = { stack: ItemStack, layer: Int -> - if (layer == 1) { + ColorHelper.Argb.fullAlpha(if (layer == 1) { stack.getOrCreateFluidStorageData()?.let { FluidRenderHandlerRegistry.INSTANCE?.get(it.fluid)?.getFluidColor( - MinecraftClient.getInstance().world, - BlockPos.ORIGIN, - ModFluids.PURIFIED_WATER.defaultState + MinecraftClient.getInstance().world, BlockPos.ORIGIN, ModFluids.PURIFIED_WATER.defaultState ) } ?: 0xFFFFFF } else { 0xFFFFFF - } + }) } + fun initialize() { + ColorProviderRegistry.ITEM.register(cupColorProvider, ModItems.WOODEN_CUP) ColorProviderRegistry.ITEM.register(cupColorProvider, ModItems.POTTERY_CUP) } diff --git a/src/client/kotlin/xyz/koiro/watersource/render/hud/ModClientHUD.kt b/src/client/kotlin/xyz/koiro/watersource/render/hud/ModClientHUD.kt index 2ad3863..13abe5e 100644 --- a/src/client/kotlin/xyz/koiro/watersource/render/hud/ModClientHUD.kt +++ b/src/client/kotlin/xyz/koiro/watersource/render/hud/ModClientHUD.kt @@ -7,6 +7,7 @@ import net.minecraft.util.hit.BlockHitResult import xyz.koiro.watersource.WSClientConfig import xyz.koiro.watersource.api.WaterBallRenderer import xyz.koiro.watersource.api.WaterLevelUiRenderUtils +import xyz.koiro.watersource.api.entry import xyz.koiro.watersource.world.attachment.ModAttachmentTypes import xyz.koiro.watersource.world.block.entity.FilterBlockEntity import xyz.koiro.watersource.world.effect.ModStatusEffects @@ -59,7 +60,7 @@ object ModClientHUD { var y: Int = context.scaledWindowHeight - 39 - offsetBetweenFoodBar if (player.isSubmergedInWater || player.air < player.maxAir) y -= 10 val xStart: Int = context.scaledWindowWidth / 2 + 91 - val isThirty = player.hasStatusEffect(ModStatusEffects.THIRSTY) + val isThirty = player.hasStatusEffect(ModStatusEffects.THIRSTY.entry()) val yOffsetList = if (saturation <= 0.0f && elapsedTime.toInt() % (level * 3 + 1) == 0) { List(10) { diff --git a/src/client/resources/watersource.client.mixins.json b/src/client/resources/watersource.client.mixins.json index f64d6b2..4ec6133 100644 --- a/src/client/resources/watersource.client.mixins.json +++ b/src/client/resources/watersource.client.mixins.json @@ -1,7 +1,7 @@ { "required": true, "package": "xyz.koiro.watersource.mixin.client", - "compatibilityLevel": "JAVA_17", + "compatibilityLevel": "JAVA_21", "client": [ "ExampleClientMixin", "HandledScreenMixin" ], diff --git a/src/main/kotlin/xyz/koiro/watersource/ModItemGroups.kt b/src/main/kotlin/xyz/koiro/watersource/ModItemGroups.kt index f95ec13..aa767b5 100644 --- a/src/main/kotlin/xyz/koiro/watersource/ModItemGroups.kt +++ b/src/main/kotlin/xyz/koiro/watersource/ModItemGroups.kt @@ -1,7 +1,6 @@ package xyz.koiro.watersource import net.fabricmc.fabric.api.itemgroup.v1.FabricItemGroup -import net.minecraft.enchantment.EnchantmentHelper import net.minecraft.enchantment.EnchantmentLevelEntry import net.minecraft.fluid.Fluids import net.minecraft.item.EnchantedBookItem @@ -9,11 +8,10 @@ import net.minecraft.item.ItemStack import net.minecraft.registry.Registries import net.minecraft.registry.Registry import net.minecraft.text.Text -import net.minecraft.village.TradeOffers.EnchantBookFactory +import xyz.koiro.watersource.api.simpleStack import xyz.koiro.watersource.api.storage.insertFluid import xyz.koiro.watersource.world.enchantment.ModEnchantments import xyz.koiro.watersource.world.fluid.ModFluids -import xyz.koiro.watersource.world.item.FluidContainerItem import xyz.koiro.watersource.world.item.ModItems object ModItemGroups { diff --git a/src/main/kotlin/xyz/koiro/watersource/WSConfig.kt b/src/main/kotlin/xyz/koiro/watersource/WSConfig.kt index 44508ef..ec06337 100644 --- a/src/main/kotlin/xyz/koiro/watersource/WSConfig.kt +++ b/src/main/kotlin/xyz/koiro/watersource/WSConfig.kt @@ -1,12 +1,15 @@ package xyz.koiro.watersource import kotlinx.serialization.Serializable +import net.minecraft.component.DataComponentTypes import net.minecraft.entity.effect.StatusEffect import net.minecraft.entity.effect.StatusEffectInstance import net.minecraft.entity.effect.StatusEffects import net.minecraft.item.ItemStack import net.minecraft.registry.Registries +import net.minecraft.registry.entry.RegistryEntry import net.minecraft.util.Identifier +import xyz.koiro.watersource.api.identifier import xyz.koiro.watersource.data.HydrationData import xyz.koiro.watersource.datagen.provider.HydrationDataProvider import xyz.koiro.watersource.world.effect.ModStatusEffects @@ -91,7 +94,7 @@ object WSConfig { } return raw.map { StatusEffectInstance( - Registries.STATUS_EFFECT.get(Identifier.tryParse(it.id)), + RegistryEntry.of(Registries.STATUS_EFFECT.get(Identifier.tryParse(it.id))) , duration, it.amplifier ) @@ -104,7 +107,7 @@ object WSConfig { val id: String, val amplifier: Int = 0 ) { - constructor(effectType: StatusEffect, amplifier: Int = 0) : this(effectType.identifier().toString(), amplifier) + constructor(effectType: RegistryEntry, amplifier: Int = 0) : this(effectType.identifier().toString(), amplifier) companion object { fun fromInstance(instance: StatusEffectInstance): EffectObject { @@ -131,11 +134,8 @@ object WSConfig { return value * (1 + (mul - 1) / 2) } - fun getWaterThirstyProbabilityEffect(): HydrationData.ProbabilityStatusEffectInstance = - HydrationData.ProbabilityStatusEffectInstance( - 0.8f, - StatusEffectInstance(ModStatusEffects.THIRSTY, 1200) - ) + fun getWaterThirstyProbabilityEffect(): HydrationData.StatusEffectObject = + HydrationData.StatusEffectObject(ModStatusEffects.THIRSTY, 0, 10f, 0.8f) fun getMoisturizingRatio(levelSum: Int): Float { return 1f / (1f + levelSum.toFloat() * 0.15f) @@ -181,8 +181,9 @@ object WSConfig { } fun getDefaultFoodDryData(itemStack: ItemStack): HydrationData? { - if (format.enableDefaultDryData && itemStack.isFood) { - itemStack.item.foodComponent?.hunger?.let { + val foodData = itemStack.get(DataComponentTypes.FOOD) + if (format.enableDefaultDryData && foodData != null) { + foodData.nutrition.let { if (it > 1) { return HydrationDataProvider.dryItem(itemStack.item, floor(it / 2f).toInt()) } diff --git a/src/main/kotlin/xyz/koiro/watersource/WaterSource.kt b/src/main/kotlin/xyz/koiro/watersource/WaterSource.kt index 8c777e8..a0f7745 100644 --- a/src/main/kotlin/xyz/koiro/watersource/WaterSource.kt +++ b/src/main/kotlin/xyz/koiro/watersource/WaterSource.kt @@ -7,8 +7,10 @@ import org.slf4j.LoggerFactory import xyz.koiro.watersource.config.ModConfigLoader import xyz.koiro.watersource.data.ModResourceRegistries import xyz.koiro.watersource.event.ModEventsHandlers +import xyz.koiro.watersource.network.ModNetworking import xyz.koiro.watersource.world.block.ModBlocks import xyz.koiro.watersource.world.block.entity.ModBlockEntities +import xyz.koiro.watersource.world.datacomponent.ModDataComponentTypes import xyz.koiro.watersource.world.effect.ModStatusEffects import xyz.koiro.watersource.world.fluid.ModFluids import xyz.koiro.watersource.world.item.ModFuelRegister @@ -27,10 +29,12 @@ object WaterSource : ModInitializer { ModBlockEntities.active() ModStatusEffects.active() ModItemGroups.active() + ModDataComponentTypes.active() ModRecipes.initialize() ModResourceRegistries.initialize() ModEventsHandlers.initialize() ModCommands.initialize() + ModNetworking.initialize() WSConfig.format = ModConfigLoader.loadOrCreateConfig("common", WSConfig.Format()) } diff --git a/src/main/kotlin/xyz/koiro/watersource/WaterSourceDataGenerator.kt b/src/main/kotlin/xyz/koiro/watersource/WaterSourceDataGenerator.kt index 1ca74bb..c089de6 100644 --- a/src/main/kotlin/xyz/koiro/watersource/WaterSourceDataGenerator.kt +++ b/src/main/kotlin/xyz/koiro/watersource/WaterSourceDataGenerator.kt @@ -2,27 +2,19 @@ package xyz.koiro.watersource import net.fabricmc.fabric.api.datagen.v1.DataGeneratorEntrypoint import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator -import xyz.koiro.watersource.datagen.HydrationDataGenerator -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 -import xyz.koiro.watersource.datagen.FilterRecipeDataGenerator -import xyz.koiro.watersource.datagen.ModBlockLootTableGenerator +import xyz.koiro.watersource.datagen.* object WaterSourceDataGenerator : DataGeneratorEntrypoint { - override fun onInitializeDataGenerator(fabricDataGenerator: FabricDataGenerator) { - val pack = fabricDataGenerator.createPack() - pack.addProvider(::HydrationDataGenerator) - pack.addProvider(::FilterRecipeDataGenerator) - pack.addProvider(::ModModelGenerator) - pack.addProvider(::ModChineseLangGenerator) - pack.addProvider(::ModEnglishLangGenerator) - pack.addProvider(::ModItemTagGenerator) - pack.addProvider(::ModFluidTagGenerator) - pack.addProvider(::ModRecipeGenerator) - pack.addProvider(::ModBlockLootTableGenerator) - } + override fun onInitializeDataGenerator(fabricDataGenerator: FabricDataGenerator) { + val pack = fabricDataGenerator.createPack() + pack.addProvider(::HydrationDataGenerator) + pack.addProvider(::FilterRecipeDataGenerator) + pack.addProvider(::ModModelGenerator) + pack.addProvider(::ModChineseLangGenerator) + pack.addProvider(::ModEnglishLangGenerator) + pack.addProvider(::ModItemTagGenerator) + pack.addProvider(::ModFluidTagGenerator) + pack.addProvider(::ModRecipeGenerator) + pack.addProvider(::ModBlockLootTableGenerator) + } } \ No newline at end of file diff --git a/src/main/kotlin/xyz/koiro/watersource/Tools.kt b/src/main/kotlin/xyz/koiro/watersource/api/Tools.kt similarity index 56% rename from src/main/kotlin/xyz/koiro/watersource/Tools.kt rename to src/main/kotlin/xyz/koiro/watersource/api/Tools.kt index 21b08aa..ab826a7 100644 --- a/src/main/kotlin/xyz/koiro/watersource/Tools.kt +++ b/src/main/kotlin/xyz/koiro/watersource/api/Tools.kt @@ -1,10 +1,11 @@ -package xyz.koiro.watersource +package xyz.koiro.watersource.api import net.minecraft.entity.effect.StatusEffect import net.minecraft.fluid.Fluid import net.minecraft.item.Item import net.minecraft.item.ItemStack import net.minecraft.registry.Registries +import net.minecraft.registry.entry.RegistryEntry import net.minecraft.util.Identifier fun Item.identifier(): Identifier { @@ -24,3 +25,16 @@ fun StatusEffect.identifier(): Identifier? { return Registries.STATUS_EFFECT.getId(this) } +fun RegistryEntry.identifier(): Identifier? { + return if (this.hasKeyAndValue()) + Registries.STATUS_EFFECT.getId(this.value()) + else null +} + +fun String.toIdentifier(): Identifier? { + return Identifier.tryParse(this) +} + +fun StatusEffect.entry(): RegistryEntry{ + return RegistryEntry.of(this) +} diff --git a/src/main/kotlin/xyz/koiro/watersource/api/serialize/IngredientFormat.kt b/src/main/kotlin/xyz/koiro/watersource/api/serialize/IngredientFormat.kt deleted file mode 100644 index cac4d1a..0000000 --- a/src/main/kotlin/xyz/koiro/watersource/api/serialize/IngredientFormat.kt +++ /dev/null @@ -1,53 +0,0 @@ -package xyz.koiro.watersource.api.serialize - -import kotlinx.serialization.SerialInfo -import kotlinx.serialization.SerialName -import kotlinx.serialization.Serializable -import kotlinx.serialization.Serializer -import net.minecraft.item.Item -import net.minecraft.recipe.Ingredient -import net.minecraft.registry.Registries -import net.minecraft.registry.RegistryKeys -import net.minecraft.registry.tag.TagKey -import net.minecraft.util.Identifier -import net.minecraft.util.JsonHelper -import xyz.koiro.watersource.WaterSource -import xyz.koiro.watersource.data.FilterRecipeData -import kotlin.jvm.optionals.getOrNull - -@Serializable -class IngredientFormat( - @SerialName("item") - val itemId: String? = null, - @SerialName("tag") - val tagId: String? = null -) { - fun asItem(): Item?{ - return itemId?.let { Registries.ITEM.getOrEmpty(Identifier.tryParse(it)).getOrNull() } - } - - fun asTag(): TagKey? { - return tagId?.let { TagKey.of(RegistryKeys.ITEM, Identifier.tryParse(tagId)) } - } - - fun toIngredient(): Ingredient { - val item = asItem() - val tag = asTag() - return when { - tag != null -> Ingredient.fromTag(tag) - item != null -> Ingredient.ofItems(item) - else -> { - Ingredient.EMPTY - } - } - } - - companion object { - fun fromIngredient(ingredient: Ingredient): IngredientFormat { - val json = ingredient.toJson().asJsonObject - val item = JsonHelper.getString(json, "item", null) - val tag = JsonHelper.getString(json, "tag", null) - return IngredientFormat(item, tag) - } - } -} \ No newline at end of file diff --git a/src/main/kotlin/xyz/koiro/watersource/api/serialize/SerializeUtils.kt b/src/main/kotlin/xyz/koiro/watersource/api/serialize/SerializeUtils.kt deleted file mode 100644 index 0bcd0c7..0000000 --- a/src/main/kotlin/xyz/koiro/watersource/api/serialize/SerializeUtils.kt +++ /dev/null @@ -1,39 +0,0 @@ -package xyz.koiro.watersource.api.serialize - -import com.google.gson.JsonObject -import net.minecraft.item.ItemStack -import net.minecraft.nbt.StringNbtReader -import net.minecraft.nbt.visitor.StringNbtWriter -import net.minecraft.registry.Registries -import net.minecraft.util.Identifier -import xyz.koiro.watersource.identifier - -object SerializeUtils { - fun itemStackToJsonObject(itemStack: ItemStack): JsonObject { - val ret = JsonObject() - ret.addProperty("item", itemStack.item.identifier().toString()) - if (itemStack.count != 1) - ret.addProperty("count", itemStack.count) - if (itemStack.hasNbt()) - ret.addProperty("nbt", StringNbtWriter().apply(itemStack.nbt)) - return ret - } - - fun jsonObjectToItemStack(jsonObject: JsonObject): ItemStack? { - val valid = jsonObject.has("item") - if (valid) { - val item = Identifier.tryParse(jsonObject.get("item").asString)?.let { Registries.ITEM.get(it) } - val count = if (jsonObject.has("count")) jsonObject.get("count").asInt else 1 - val nbt = if (jsonObject.has("nbt")) - StringNbtReader.parse(jsonObject.get("nbt").asString) - else null - if (item != null && count > 0) { - val stack = ItemStack(item, count).apply { - if (nbt != null) this.nbt = nbt - } - return stack - } - } - return null - } -} \ No newline at end of file diff --git a/src/main/kotlin/xyz/koiro/watersource/api/storage/FluidStorageData.kt b/src/main/kotlin/xyz/koiro/watersource/api/storage/FluidStorageData.kt index 5d9af4f..00c3ffa 100644 --- a/src/main/kotlin/xyz/koiro/watersource/api/storage/FluidStorageData.kt +++ b/src/main/kotlin/xyz/koiro/watersource/api/storage/FluidStorageData.kt @@ -1,14 +1,18 @@ package xyz.koiro.watersource.api.storage +import com.mojang.serialization.Codec +import com.mojang.serialization.codecs.RecordCodecBuilder import net.minecraft.fluid.Fluid import net.minecraft.fluid.Fluids import net.minecraft.nbt.NbtCompound +import net.minecraft.network.RegistryByteBuf +import net.minecraft.network.codec.PacketCodec import net.minecraft.registry.Registries import net.minecraft.text.MutableText import net.minecraft.text.Text import net.minecraft.util.Identifier import xyz.koiro.watersource.datagen.ModLanguages -import xyz.koiro.watersource.identifier +import xyz.koiro.watersource.api.identifier class FluidStorageData( var fluid: Fluid, @@ -95,6 +99,38 @@ class FluidStorageData( fun getEmptyText(capacity: Long): MutableText { return Text.translatable(ModLanguages.INFO_CAPACITY_KYE).append(Text.of(": $capacity mB")) } + + + val CODEC: Codec = RecordCodecBuilder.mapCodec { instance -> + val a = instance.group( + Codec.LONG.fieldOf("amount").forGetter { + it.amount + }, + Codec.LONG.fieldOf("capacity").forGetter { + it.capacity + }, + Registries.FLUID.codec.fieldOf("fluid").forGetter { + it.fluid + } + ) + return@mapCodec a.apply(instance) { amount, capacity, fluid -> + FluidStorageData(fluid, amount, capacity) + } + }.codec() + + val PACKET_CODEC = PacketCodec.ofStatic(::write, ::read) + fun write(buf: RegistryByteBuf, it: FluidStorageData) { + buf.writeLong(it.amount) + buf.writeLong(it.capacity) + buf.writeIdentifier(it.fluid.identifier()) + } + fun read(buf: RegistryByteBuf): FluidStorageData { + val amount = buf.readLong() + val capacity = buf.readLong() + val id =buf.readIdentifier() + val fluid = Registries.FLUID.get(id) + return FluidStorageData(fluid, amount, capacity) + } } fun getDisplayText(): MutableText { diff --git a/src/main/kotlin/xyz/koiro/watersource/api/storage/ItemFluidDataExt.kt b/src/main/kotlin/xyz/koiro/watersource/api/storage/ItemFluidDataExt.kt index 85fdda8..361b2ab 100644 --- a/src/main/kotlin/xyz/koiro/watersource/api/storage/ItemFluidDataExt.kt +++ b/src/main/kotlin/xyz/koiro/watersource/api/storage/ItemFluidDataExt.kt @@ -3,10 +3,9 @@ package xyz.koiro.watersource.api.storage import net.minecraft.fluid.Fluid import net.minecraft.fluid.Fluids import net.minecraft.item.ItemStack +import xyz.koiro.watersource.world.datacomponent.ModDataComponentTypes import xyz.koiro.watersource.world.item.FluidContainerItem -const val FLUID_STORAGE_KEY = "WaterSourceFluidStorage" - fun ItemStack.insertFluid(fluid: Fluid, amountGetter: (FluidStorageData) -> Long): Long? { var flag: Long? = null this.modifyFluidStorage { itemStack, data -> @@ -36,13 +35,13 @@ fun ItemStack.extractFluid(amount: Long): Long? { fun ItemStack.getOrCreateFluidStorageData(): FluidStorageData? { val item = this.item if (item is FluidContainerItem) { - val data = FluidStorageData.fromNbt(this.getSubNbt(FLUID_STORAGE_KEY)) + val data = this.get(ModDataComponentTypes.FLUID_STORAGE) return if (data != null) { data } else { // Init val ret = FluidStorageData(Fluids.EMPTY, 0, item.capacity) - this.setSubNbt(FLUID_STORAGE_KEY, ret.toNbt()) + this.set(ModDataComponentTypes.FLUID_STORAGE, ret) ret } } @@ -55,13 +54,13 @@ fun ItemStack.getOrCreateFluidStorageData(): FluidStorageData? { fun ItemStack.modifyFluidStorage(action: (ItemStack, FluidStorageData) -> Unit) { this.getOrCreateFluidStorageData()?.let { action(this, it) - this.setSubNbt(FLUID_STORAGE_KEY, it.toNbt()) + this.set(ModDataComponentTypes.FLUID_STORAGE, it) } } fun ItemStack.setFluidStorage(data: FluidStorageData): Boolean { val ret = this.getOrCreateFluidStorageData() != null if (ret) - this.setSubNbt(FLUID_STORAGE_KEY, data.toNbt()) + this.set(ModDataComponentTypes.FLUID_STORAGE, data) return ret } diff --git a/src/main/kotlin/xyz/koiro/watersource/api/storage/ItemStorageData.kt b/src/main/kotlin/xyz/koiro/watersource/api/storage/ItemStorageData.kt index 30486d3..ec58fca 100644 --- a/src/main/kotlin/xyz/koiro/watersource/api/storage/ItemStorageData.kt +++ b/src/main/kotlin/xyz/koiro/watersource/api/storage/ItemStorageData.kt @@ -1,18 +1,35 @@ package xyz.koiro.watersource.api.storage +import com.mojang.serialization.codecs.RecordCodecBuilder import net.minecraft.item.ItemStack import net.minecraft.nbt.NbtCompound +import net.minecraft.nbt.NbtOps +import net.minecraft.registry.RegistryWrapper.WrapperLookup +import java.util.Optional +import kotlin.jvm.optionals.getOrNull class ItemStorageData(var stack: ItemStack = ItemStack.EMPTY) { - fun clear(){ - stack = ItemStack.EMPTY + companion object { + val CODEC = RecordCodecBuilder.create { instance -> + instance.group( + ItemStack.CODEC.optionalFieldOf("stack") + .forGetter { Optional.ofNullable(if (it.stack.isEmpty) null else it.stack) } + ).apply(instance) { + ItemStorageData(it.orElse(ItemStack.EMPTY)) + } + } + + fun fromNbt(lookup: WrapperLookup, nbtCompound: NbtCompound): ItemStorageData? { + val result = CODEC.parse(lookup.getOps(NbtOps.INSTANCE), nbtCompound) + return result.result().getOrNull() + } } - fun writeNbt(nbtCompound: NbtCompound){ - stack.writeNbt(nbtCompound) + fun clear() { + stack = ItemStack.EMPTY } - fun readNbt(nbtCompound: NbtCompound){ - stack = ItemStack.fromNbt(nbtCompound) + fun writeNbt(lookup: WrapperLookup, nbtCompound: NbtCompound) { + CODEC.encode(this, lookup.getOps(NbtOps.INSTANCE), nbtCompound).getOrThrow() } } \ No newline at end of file diff --git a/src/main/kotlin/xyz/koiro/watersource/data/DataManager.kt b/src/main/kotlin/xyz/koiro/watersource/data/DataManager.kt index 4f18eb9..0bc0a74 100644 --- a/src/main/kotlin/xyz/koiro/watersource/data/DataManager.kt +++ b/src/main/kotlin/xyz/koiro/watersource/data/DataManager.kt @@ -1,6 +1,7 @@ package xyz.koiro.watersource.data import net.fabricmc.fabric.api.resource.SimpleSynchronousResourceReloadListener +import net.minecraft.data.DataProvider import net.minecraft.resource.Resource import net.minecraft.resource.ResourceManager import net.minecraft.util.Identifier @@ -15,10 +16,6 @@ abstract class DataManager(val startingPath: String, val id: Identifier): } abstract fun processResourceToData(resId: Identifier, res: Resource): Data -// val stream = res.inputStream -// val string = String(stream.readAllBytes()) -// val format = Json.decodeFromString(string) -// val data = HydrationData(format) override fun reload(manager: ResourceManager) { val res = findResource(manager) diff --git a/src/main/kotlin/xyz/koiro/watersource/data/FilterRecipeData.kt b/src/main/kotlin/xyz/koiro/watersource/data/FilterRecipeData.kt index 334b119..30224b5 100644 --- a/src/main/kotlin/xyz/koiro/watersource/data/FilterRecipeData.kt +++ b/src/main/kotlin/xyz/koiro/watersource/data/FilterRecipeData.kt @@ -1,14 +1,11 @@ package xyz.koiro.watersource.data -import kotlinx.serialization.SerialName -import kotlinx.serialization.Serializable +import com.mojang.serialization.Codec +import com.mojang.serialization.codecs.RecordCodecBuilder import net.minecraft.fluid.Fluid import net.minecraft.item.ItemStack import net.minecraft.recipe.Ingredient import net.minecraft.registry.Registries -import net.minecraft.util.Identifier -import xyz.koiro.watersource.api.serialize.IngredientFormat -import xyz.koiro.watersource.identifier class FilterRecipeData( val inputFluid: Fluid, @@ -20,27 +17,17 @@ class FilterRecipeData( return fluidIn == this.inputFluid && strainer.test(strainerStack) } - fun format(): Format { - return Format( - IngredientFormat.fromIngredient(strainer), - inputFluid.identifier().toString(), - outputFluid.identifier().toString() - ) + companion object { + val CODEC: Codec = + RecordCodecBuilder.mapCodec { instance -> + val group = instance.group( + Ingredient.DISALLOW_EMPTY_CODEC.fieldOf("strainer").forGetter { it.strainer }, + Registries.FLUID.codec.fieldOf("input_fluid").forGetter { it.inputFluid }, + Registries.FLUID.codec.fieldOf("output_fluid").forGetter { it.outputFluid }, + ) + group.apply(instance) { strainer, iF, oF -> + FilterRecipeData(iF, oF, strainer) + } + }.codec() } - - constructor(format: Format) : this( - Registries.FLUID.get(Identifier.tryParse(format.inputFluid)), - Registries.FLUID.get(Identifier.tryParse(format.outputFluid)), - format.strainer.toIngredient() - ) - - - @Serializable - class Format( - val strainer: IngredientFormat, - @SerialName("input_fluid") - val inputFluid: String, - @SerialName("output_fluid") - val outputFluid: String - ) } \ No newline at end of file diff --git a/src/main/kotlin/xyz/koiro/watersource/data/FilterRecipeDataManager.kt b/src/main/kotlin/xyz/koiro/watersource/data/FilterRecipeDataManager.kt index 3d5d665..e700bf5 100644 --- a/src/main/kotlin/xyz/koiro/watersource/data/FilterRecipeDataManager.kt +++ b/src/main/kotlin/xyz/koiro/watersource/data/FilterRecipeDataManager.kt @@ -1,26 +1,36 @@ package xyz.koiro.watersource.data +import com.google.gson.Gson +import com.google.gson.JsonElement +import com.mojang.brigadier.StringReader +import com.mojang.serialization.JsonOps import kotlinx.serialization.json.Json +import net.fabricmc.fabric.impl.resource.loader.ModResourcePackUtil.GSON import net.minecraft.fluid.Fluid import net.minecraft.item.ItemStack +import net.minecraft.registry.BuiltinRegistries +import net.minecraft.registry.RegistryEntryLookup.RegistryLookup +import net.minecraft.registry.RegistryOps +import net.minecraft.registry.RegistryWrapper import net.minecraft.resource.Resource import net.minecraft.util.Identifier +import net.minecraft.util.JsonReaderUtils import xyz.koiro.watersource.WaterSource object FilterRecipeDataManager : DataManager( ModResourceRegistries.FILTER_RECIPE_KEY, WaterSource.identifier(ModResourceRegistries.FILTER_RECIPE_KEY) ) { + val registryLookup: RegistryWrapper.WrapperLookup = BuiltinRegistries.createWrapperLookup() + override fun processResourceToData(resId: Identifier, res: Resource): FilterRecipeData { - val stream = res.inputStream - val string = String(stream.readAllBytes()) - val format = Json.decodeFromString(string) - val data = FilterRecipeData(format) + val reader = StringReader(String(res.inputStream.readAllBytes())) + val data = JsonReaderUtils.parse(registryLookup, reader, FilterRecipeData.CODEC) return data } fun findRecipe(fluidIn: Fluid, strainerStack: ItemStack): FilterRecipeData? { - return sequence?.find { data -> + return this.sequence?.find { data -> data.match(fluidIn, strainerStack) } } diff --git a/src/main/kotlin/xyz/koiro/watersource/data/HydrationData.kt b/src/main/kotlin/xyz/koiro/watersource/data/HydrationData.kt index 9399cdf..7e5b8e3 100644 --- a/src/main/kotlin/xyz/koiro/watersource/data/HydrationData.kt +++ b/src/main/kotlin/xyz/koiro/watersource/data/HydrationData.kt @@ -2,100 +2,93 @@ package xyz.koiro.watersource.data -import com.google.gson.annotations.SerializedName -import kotlinx.serialization.SerialName -import kotlinx.serialization.Serializable +import com.mojang.serialization.Codec +import com.mojang.serialization.codecs.ListCodec +import com.mojang.serialization.codecs.RecordCodecBuilder import net.fabricmc.fabric.api.transfer.v1.context.ContainerItemContext import net.fabricmc.fabric.api.transfer.v1.fluid.FluidStorage +import net.minecraft.component.ComponentChanges +import net.minecraft.entity.effect.StatusEffect import net.minecraft.entity.effect.StatusEffectInstance import net.minecraft.fluid.Fluid import net.minecraft.item.Item import net.minecraft.item.ItemStack -import net.minecraft.nbt.NbtCompound -import net.minecraft.nbt.NbtIo -import net.minecraft.nbt.StringNbtReader -import net.minecraft.nbt.visitor.StringNbtWriter import net.minecraft.registry.Registries import net.minecraft.registry.RegistryKeys +import net.minecraft.registry.entry.RegistryEntry +import net.minecraft.registry.tag.FluidTags import net.minecraft.registry.tag.TagKey import net.minecraft.server.network.ServerPlayerEntity -import net.minecraft.util.Identifier -import xyz.koiro.watersource.identifier +import java.util.Optional +import kotlin.jvm.optionals.getOrNull import kotlin.random.Random class HydrationData( - val level: Int, - val saturation: Int, + val level: Int?, + val saturation: Int?, val dryLevel: Int?, val matchMode: MatchMode = MatchMode.All, val matchList: ArrayList, - val effects: ArrayList, + val effects: ArrayList?, ) { - fun isDry(): Boolean{ - return dryLevel != null && dryLevel > 0 - } - - fun format(): Format{ - val item = (matchList.find { it is ItemMatch } as? ItemMatch)?.item?.identifier()?.toString() - val fluid = (matchList.find { it is FluidMatch } as? FluidMatch)?.fluid?.identifier()?.toString() - val itemTag = (matchList.find { it is ItemTagMatch } as? ItemTagMatch)?.key?.id?.toString() - val fluidTag = (matchList.find { it is FluidTagMatch } as? FluidTagMatch)?.key?.id?.toString() - val nbtTag = (matchList.find { it is NBTMatch } as? NBTMatch)?.nbt?.let { StringNbtWriter().apply(it) } - val effectsObjs = effects.mapNotNull { pEffect -> - val effectInstance = pEffect.effect - val id = effectInstance.effectType.identifier() - id?.let { - StatusEffectObject( - it.toString(), - effectInstance.amplifier, - effectInstance.duration.toFloat() * 0.05f, - pEffect.probability + companion object { + val CODEC: Codec = RecordCodecBuilder.mapCodec { instance -> + val group = instance.group( + Codec.INT.optionalFieldOf("level").forGetter { Optional.ofNullable(it.level) }, + Codec.INT.optionalFieldOf("saturation").forGetter { Optional.ofNullable(it.saturation) }, + Codec.INT.optionalFieldOf("dryLevel").forGetter { Optional.ofNullable(it.dryLevel) }, + Codec.STRING.lenientOptionalFieldOf("match_mode", MatchMode.All.name) + .forGetter { it.matchMode.name }, + Registries.ITEM.codec.optionalFieldOf("item").forGetter { + Optional.ofNullable(it.matchList.find { it is ItemMatch }?.let { (it as ItemMatch).item }) + }, + Registries.FLUID.codec.optionalFieldOf("fluid").forGetter { + Optional.ofNullable(it.matchList.find { it is FluidMatch }?.let { (it as FluidMatch).fluid }) + }, + TagKey.codec(RegistryKeys.ITEM).optionalFieldOf("item_tag").forGetter { + Optional.ofNullable(it.matchList.find { it is ItemTagMatch }?.let { (it as ItemTagMatch).key }) + }, + TagKey.codec(RegistryKeys.FLUID).optionalFieldOf("fluid_tag").forGetter { + Optional.ofNullable(it.matchList.find { it is FluidTagMatch }?.let { (it as FluidTagMatch).key }) + }, + ComponentChanges.CODEC.optionalFieldOf("components").forGetter { + Optional.ofNullable(it.matchList.find { it is ComponentMatch } + ?.let { (it as ComponentMatch).components }) + }, + ListCodec(StatusEffectObject.CODEC, 0, Int.MAX_VALUE).optionalFieldOf("effects") + .forGetter { Optional.ofNullable(it.effects) } + ) + group.apply(instance) { level, saturation, dryLevel, matchMode, item, fluid, itemTag, fluidTag, components, effects -> + val matchList = arrayListOf() + item.ifPresent { matchList.add(ItemMatch(it)) } + fluid.ifPresent { matchList.add(FluidMatch(it)) } + itemTag.ifPresent { matchList.add(ItemTagMatch(it)) } + fluidTag.ifPresent { matchList.add(FluidTagMatch(it)) } + components.ifPresent { matchList.add(ComponentMatch(it)) } + + HydrationData( + level.getOrNull(), + saturation.getOrNull(), + dryLevel.getOrNull(), + MatchMode.valueOf(matchMode), + matchList, + effects.getOrNull()?.let { ArrayList(it) } ) } - } - return Format(level, saturation, dryLevel, matchMode, item, fluid, itemTag, fluidTag, nbtTag, effectsObjs) + }.codec() } - constructor(format: Format) : this( - format.level ?: 0, - format.saturation ?: 0, - format.dryLevel, - format.matchMode ?: MatchMode.All, - arrayListOf(), - arrayListOf() - ) { - fun valid(it: String?): String? = if (!it.isNullOrBlank() && it != "null") it else null - valid(format.item)?.let { - matchList.add(ItemMatch(Registries.ITEM.get(Identifier.tryParse(it)))) - } - valid(format.fluid)?.let { - matchList.add(FluidMatch(Registries.FLUID.get(Identifier.tryParse(it)))) - } - valid(format.itemTag)?.let { - matchList.add(ItemTagMatch(TagKey.of(RegistryKeys.ITEM, Identifier.tryParse(it)))) - } - valid(format.fluidTag)?.let { - matchList.add(FluidTagMatch(TagKey.of(RegistryKeys.FLUID, Identifier.tryParse(it)))) - } - valid(format.nbtString)?.let { - matchList.add(NBTMatch(StringNbtReader.parse(it))) - } - format.effects?.forEach { obj -> - val type = Registries.STATUS_EFFECT.get(Identifier.tryParse(obj.id)) - type?.let { effectType -> - effects.add( - ProbabilityStatusEffectInstance( - obj.probability, - StatusEffectInstance(effectType, ((obj.duration ?: 0f) * 20f).toInt(), obj.amplifier ?: 0) - ) - ) - } - } + fun isDry(): Boolean { + return dryLevel != null && dryLevel > 0 } fun applyEffectsToPlayer(player: ServerPlayerEntity, multiplier: Int = 1) { - effects.forEach { pEffect -> - val effectInstance = pEffect.effect + effects?.forEach { pEffect -> + val effectInstance = StatusEffectInstance( + RegistryEntry.of(pEffect.effect), + (pEffect.durationInSec * 50).toInt(), + pEffect.amplifier + ) if (Random.Default.nextFloat() < pEffect.probability) player.addStatusEffect( StatusEffectInstance( @@ -121,9 +114,9 @@ class HydrationData( } } - class NBTMatch(val nbt: NbtCompound) : IMatch { + class ComponentMatch(val components: ComponentChanges) : IMatch { override fun match(itemStack: ItemStack?): Boolean { - return itemStack?.nbt == nbt + return itemStack?.componentChanges == components } override fun match(fluid: Fluid?): Boolean = false @@ -178,58 +171,34 @@ class HydrationData( fun match(fluid: Fluid?): Boolean } - @Serializable - data class Format( - val level: Int? = null, - val saturation: Int? = null, - - @SerializedName("dry_level") - @SerialName("dry_level") - val dryLevel: Int? = null, - - @SerializedName("match_mode") - @SerialName("match_mode") - val matchMode: MatchMode? = null, - - val item: String? = null, - val fluid: String? = null, - - @SerializedName("item_tag") - @SerialName("item_tag") - val itemTag: String? = null, - - @SerializedName("fluid_tag") - @SerialName("fluid_tag") - val fluidTag: String? = null, - - @SerializedName("nbt") - @SerialName("nbt") - val nbtString: String? = null, - - val effects: List? - ) - - class ProbabilityStatusEffectInstance(val probability: Float, val effect: StatusEffectInstance) - - @Serializable - data class StatusEffectObject( - val id: String?, + class StatusEffectObject( + val effect: StatusEffect, // 0 = I, 1 = II... - val amplifier: Int?, - val duration: Float?, + val amplifier: Int, + val durationInSec: Float, // 0.0 ~ 1.0 val probability: Float - ) + ) { + companion object { + val CODEC = RecordCodecBuilder.mapCodec { + val group = it.group( + Registries.STATUS_EFFECT.codec.fieldOf("id").forGetter { it.effect }, + Codec.INT.lenientOptionalFieldOf("amplifier", 0).forGetter { it.amplifier }, + Codec.FLOAT.lenientOptionalFieldOf("duration", 1f) + .forGetter { it.durationInSec }, + Codec.FLOAT.lenientOptionalFieldOf("probability", 1f) + .forGetter { it.probability } + ); + group.apply(it) { id, amp, dur, pro -> + StatusEffectObject(id, amp, dur, pro) + } + }.codec() + } + } - @Serializable enum class MatchMode { - @SerializedName("all") - @SerialName("all") All, - - @SerializedName("any") - @SerialName("any") Any } } \ No newline at end of file diff --git a/src/main/kotlin/xyz/koiro/watersource/data/HydrationDataManager.kt b/src/main/kotlin/xyz/koiro/watersource/data/HydrationDataManager.kt index 3e0d426..354939f 100644 --- a/src/main/kotlin/xyz/koiro/watersource/data/HydrationDataManager.kt +++ b/src/main/kotlin/xyz/koiro/watersource/data/HydrationDataManager.kt @@ -1,16 +1,24 @@ package xyz.koiro.watersource.data +import com.mojang.brigadier.StringReader import kotlinx.serialization.json.Json import net.minecraft.fluid.Fluid import net.minecraft.item.ItemStack +import net.minecraft.registry.BuiltinRegistries +import net.minecraft.registry.RegistryWrapper.WrapperLookup import net.minecraft.resource.Resource import net.minecraft.util.Identifier +import net.minecraft.util.JsonReaderUtils import xyz.koiro.watersource.WSConfig import xyz.koiro.watersource.WaterSource import xyz.koiro.watersource.api.storage.getOrCreateFluidStorageData object HydrationDataManager : - DataManager(ModResourceRegistries.HYDRATION_KEY, WaterSource.identifier(ModResourceRegistries.HYDRATION_KEY)) { + DataManager( + ModResourceRegistries.HYDRATION_KEY, + WaterSource.identifier(ModResourceRegistries.HYDRATION_KEY) + ) { + val registryLookup = BuiltinRegistries.createWrapperLookup() fun findByItemStack(itemStack: ItemStack): HydrationData? { val data = sequence?.find { @@ -27,10 +35,8 @@ object HydrationDataManager : } override fun processResourceToData(resId: Identifier, res: Resource): HydrationData { - val stream = res.inputStream - val string = String(stream.readAllBytes()) - val format = Json.decodeFromString(string) - val data = HydrationData(format) + val reader = StringReader(String(res.inputStream.readAllBytes())) + val data = JsonReaderUtils.parse(registryLookup, reader, HydrationData.CODEC) return data } diff --git a/src/main/kotlin/xyz/koiro/watersource/data/ModResourceRegistries.kt b/src/main/kotlin/xyz/koiro/watersource/data/ModResourceRegistries.kt index 34de209..50f6a4f 100644 --- a/src/main/kotlin/xyz/koiro/watersource/data/ModResourceRegistries.kt +++ b/src/main/kotlin/xyz/koiro/watersource/data/ModResourceRegistries.kt @@ -1,13 +1,16 @@ package xyz.koiro.watersource.data import net.fabricmc.fabric.api.resource.ResourceManagerHelper +import net.minecraft.registry.BuiltinRegistries +import net.minecraft.registry.Registries import net.minecraft.resource.ResourceType object ModResourceRegistries { const val HYDRATION_KEY = "hydration" const val FILTER_RECIPE_KEY = "filter_recipe" - fun initialize(){ - ResourceManagerHelper.get(ResourceType.SERVER_DATA).registerReloadListener(HydrationDataManager) + + fun initialize() { ResourceManagerHelper.get(ResourceType.SERVER_DATA).registerReloadListener(FilterRecipeDataManager) + ResourceManagerHelper.get(ResourceType.SERVER_DATA).registerReloadListener(HydrationDataManager) } } \ No newline at end of file diff --git a/src/main/kotlin/xyz/koiro/watersource/datagen/FilterRecipeDataGenerator.kt b/src/main/kotlin/xyz/koiro/watersource/datagen/FilterRecipeDataGenerator.kt index cfa358a..d400530 100644 --- a/src/main/kotlin/xyz/koiro/watersource/datagen/FilterRecipeDataGenerator.kt +++ b/src/main/kotlin/xyz/koiro/watersource/datagen/FilterRecipeDataGenerator.kt @@ -3,13 +3,17 @@ package xyz.koiro.watersource.datagen import net.minecraft.data.DataOutput import net.minecraft.fluid.Fluids import net.minecraft.recipe.Ingredient +import net.minecraft.registry.RegistryWrapper import xyz.koiro.watersource.WaterSource import xyz.koiro.watersource.data.FilterRecipeData import xyz.koiro.watersource.datagen.provider.FilterRecipeDataProvider import xyz.koiro.watersource.world.fluid.ModFluids import xyz.koiro.watersource.world.tag.ModTags +import java.util.concurrent.CompletableFuture -class FilterRecipeDataGenerator(output: DataOutput) : FilterRecipeDataProvider(output) { +class FilterRecipeDataGenerator(output: DataOutput, + lookup: CompletableFuture +) : FilterRecipeDataProvider(output, lookup) { override fun addData(adder: DataAdder) { adder.add( WaterSource.identifier("water_to_purified_water"), diff --git a/src/main/kotlin/xyz/koiro/watersource/datagen/HydrationDataGenerator.kt b/src/main/kotlin/xyz/koiro/watersource/datagen/HydrationDataGenerator.kt index 9616d8c..989e99f 100644 --- a/src/main/kotlin/xyz/koiro/watersource/datagen/HydrationDataGenerator.kt +++ b/src/main/kotlin/xyz/koiro/watersource/datagen/HydrationDataGenerator.kt @@ -1,9 +1,14 @@ package xyz.koiro.watersource.datagen +import net.minecraft.component.ComponentChanges +import net.minecraft.component.DataComponentTypes +import net.minecraft.component.type.PotionContentsComponent import net.minecraft.data.DataOutput import net.minecraft.fluid.Fluids import net.minecraft.item.Items import net.minecraft.nbt.NbtCompound +import net.minecraft.potion.Potions +import net.minecraft.registry.RegistryWrapper import net.minecraft.util.Identifier import xyz.koiro.watersource.WSConfig import xyz.koiro.watersource.WaterSource @@ -13,8 +18,12 @@ import xyz.koiro.watersource.datagen.provider.addDryItemWithAutoId import xyz.koiro.watersource.datagen.provider.addItemWithAutoId import xyz.koiro.watersource.world.fluid.ModFluids import xyz.koiro.watersource.world.item.ModItems +import java.util.concurrent.CompletableFuture -class HydrationDataGenerator(output: DataOutput) : HydrationDataProvider(output) { +class HydrationDataGenerator(output: DataOutput, lookup: CompletableFuture) : HydrationDataProvider( + output, + lookup +) { override fun addData(adder: DataAdder) { // WaterSource ----------------------- adder.add( @@ -41,9 +50,14 @@ class HydrationDataGenerator(output: DataOutput) : HydrationDataProvider(output) adder.addItemWithAutoId(Items.GLOW_BERRIES, 1, 3) adder.add( Identifier("item_potion_water"), - item(Items.POTION, 2, 0, WSConfig.getWaterThirstyProbabilityEffect()).apply { matchList.add(HydrationData.NBTMatch( - NbtCompound().apply { this.putString("Potion", "minecraft:water") } - ))} + item(Items.POTION, 2, 0, WSConfig.getWaterThirstyProbabilityEffect()).apply { + matchList.add( + HydrationData.ComponentMatch( + ComponentChanges.builder() + .add(DataComponentTypes.POTION_CONTENTS, PotionContentsComponent(Potions.WATER)).build() + ) + ) + } ) adder.addDryItemWithAutoId(Items.COOKIE, 1) diff --git a/src/main/kotlin/xyz/koiro/watersource/datagen/ModBlockLootTableGenerator.kt b/src/main/kotlin/xyz/koiro/watersource/datagen/ModBlockLootTableGenerator.kt index 4c2100f..7afdf9b 100644 --- a/src/main/kotlin/xyz/koiro/watersource/datagen/ModBlockLootTableGenerator.kt +++ b/src/main/kotlin/xyz/koiro/watersource/datagen/ModBlockLootTableGenerator.kt @@ -2,10 +2,14 @@ package xyz.koiro.watersource.datagen import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput import net.fabricmc.fabric.api.datagen.v1.provider.FabricBlockLootTableProvider +import net.minecraft.registry.RegistryWrapper import xyz.koiro.watersource.BlockLootTableType import xyz.koiro.watersource.world.block.ModBlocks +import java.util.concurrent.CompletableFuture -class ModBlockLootTableGenerator(dataOutput: FabricDataOutput?) : FabricBlockLootTableProvider(dataOutput) { +class ModBlockLootTableGenerator(dataOutput: FabricDataOutput?, + registryLookup: CompletableFuture? +) : FabricBlockLootTableProvider(dataOutput, registryLookup) { override fun generate() { ModBlocks.reflectAutoGenDataBlocks().forEach { val data = it.second diff --git a/src/main/kotlin/xyz/koiro/watersource/datagen/ModChineseLangGenerator.kt b/src/main/kotlin/xyz/koiro/watersource/datagen/ModChineseLangGenerator.kt index 2fd928f..72a754e 100644 --- a/src/main/kotlin/xyz/koiro/watersource/datagen/ModChineseLangGenerator.kt +++ b/src/main/kotlin/xyz/koiro/watersource/datagen/ModChineseLangGenerator.kt @@ -2,11 +2,17 @@ package xyz.koiro.watersource.datagen import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput import net.fabricmc.fabric.api.datagen.v1.provider.FabricLanguageProvider +import net.minecraft.registry.RegistryWrapper +import net.minecraft.registry.RegistryWrapper.WrapperLookup import xyz.koiro.watersource.world.block.ModBlocks import xyz.koiro.watersource.world.item.ModItems +import java.util.concurrent.CompletableFuture -class ModChineseLangGenerator(dataOutput: FabricDataOutput) : FabricLanguageProvider(dataOutput, "zh_cn") { - override fun generateTranslations(translationBuilder: TranslationBuilder) { +class ModChineseLangGenerator(dataOutput: FabricDataOutput, lookup: CompletableFuture) : FabricLanguageProvider(dataOutput,"zh_cn", lookup) { + override fun generateTranslations( + registryLookup: RegistryWrapper.WrapperLookup?, + translationBuilder: TranslationBuilder + ) { ModItems.reflectAutoGenDataItems().forEach { translationBuilder.add(it.first, it.second.cnLang) } diff --git a/src/main/kotlin/xyz/koiro/watersource/datagen/ModEnglishLangGenerator.kt b/src/main/kotlin/xyz/koiro/watersource/datagen/ModEnglishLangGenerator.kt index 9ef7c23..d12a883 100644 --- a/src/main/kotlin/xyz/koiro/watersource/datagen/ModEnglishLangGenerator.kt +++ b/src/main/kotlin/xyz/koiro/watersource/datagen/ModEnglishLangGenerator.kt @@ -2,11 +2,13 @@ package xyz.koiro.watersource.datagen import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput import net.fabricmc.fabric.api.datagen.v1.provider.FabricLanguageProvider +import net.minecraft.registry.RegistryWrapper.WrapperLookup import xyz.koiro.watersource.world.block.ModBlocks import xyz.koiro.watersource.world.item.ModItems +import java.util.concurrent.CompletableFuture -class ModEnglishLangGenerator(dataOutput: FabricDataOutput) : FabricLanguageProvider(dataOutput, "en_us") { - override fun generateTranslations(translationBuilder: TranslationBuilder) { +class ModEnglishLangGenerator(dataOutput: FabricDataOutput ,lookup: CompletableFuture) : FabricLanguageProvider(dataOutput,"en_us", lookup) { + override fun generateTranslations(registryLookup: WrapperLookup?, translationBuilder: TranslationBuilder) { ModItems.reflectAutoGenDataItems().forEach { translationBuilder.add(it.first, it.second.enLang) } diff --git a/src/main/kotlin/xyz/koiro/watersource/datagen/ModRecipeGenerator.kt b/src/main/kotlin/xyz/koiro/watersource/datagen/ModRecipeGenerator.kt index 465f085..9597bfe 100644 --- a/src/main/kotlin/xyz/koiro/watersource/datagen/ModRecipeGenerator.kt +++ b/src/main/kotlin/xyz/koiro/watersource/datagen/ModRecipeGenerator.kt @@ -2,27 +2,27 @@ 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.data.server.recipe.RecipeProvider -import net.minecraft.data.server.recipe.ShapedRecipeJsonBuilder -import net.minecraft.data.server.recipe.ShapelessRecipeJsonBuilder +import net.minecraft.data.server.recipe.* import net.minecraft.fluid.Fluids import net.minecraft.item.Items import net.minecraft.recipe.Ingredient import net.minecraft.recipe.book.RecipeCategory +import net.minecraft.registry.RegistryWrapper import net.minecraft.registry.tag.ItemTags import xyz.koiro.watersource.WaterSource import xyz.koiro.watersource.api.inputWithCriterion import xyz.koiro.watersource.datagen.recipe.StrainerFilteringFluidRecipeJsonBuilder import xyz.koiro.watersource.datagen.recipe.StrainerFilteringItemRecipeJsonBuilder -import xyz.koiro.watersource.simpleStack +import xyz.koiro.watersource.api.simpleStack import xyz.koiro.watersource.world.fluid.ModFluids import xyz.koiro.watersource.world.item.ModItems import xyz.koiro.watersource.world.tag.ModTags -import java.util.function.Consumer +import java.util.concurrent.CompletableFuture -class ModRecipeGenerator(output: FabricDataOutput?) : FabricRecipeProvider(output) { - override fun generate(exporter: Consumer?) { +class ModRecipeGenerator(output: FabricDataOutput?, + registriesFuture: CompletableFuture? +) : FabricRecipeProvider(output, registriesFuture) { + override fun generate(exporter: RecipeExporter?) { StrainerFilteringFluidRecipeJsonBuilder( WaterSource.identifier("water_to_purified_water"), Fluids.WATER, diff --git a/src/main/kotlin/xyz/koiro/watersource/datagen/provider/FilterRecipeDataProvider.kt b/src/main/kotlin/xyz/koiro/watersource/datagen/provider/FilterRecipeDataProvider.kt index 010b31d..6261815 100644 --- a/src/main/kotlin/xyz/koiro/watersource/datagen/provider/FilterRecipeDataProvider.kt +++ b/src/main/kotlin/xyz/koiro/watersource/datagen/provider/FilterRecipeDataProvider.kt @@ -5,21 +5,28 @@ import com.google.common.hash.HashingOutputStream import kotlinx.serialization.json.Json import kotlinx.serialization.json.encodeToStream import net.minecraft.data.DataOutput +import net.minecraft.data.DataProvider import net.minecraft.data.DataWriter +import net.minecraft.registry.RegistryEntryLookup.RegistryLookup +import net.minecraft.registry.RegistryWrapper.WrapperLookup import net.minecraft.util.Identifier import xyz.koiro.watersource.data.FilterRecipeData import xyz.koiro.watersource.data.HydrationData import xyz.koiro.watersource.data.ModResourceRegistries import java.io.ByteArrayOutputStream import java.nio.file.Path +import java.util.concurrent.CompletableFuture -abstract class FilterRecipeDataProvider(output: DataOutput) : - ModDataProvider(output, ModResourceRegistries.FILTER_RECIPE_KEY, "Filter Recipe") { +abstract class FilterRecipeDataProvider(output: DataOutput, lookup: CompletableFuture) : + ModDataProvider(output, ModResourceRegistries.FILTER_RECIPE_KEY, "Filter Recipe", lookup) { - override fun writeData(id: Identifier, data: FilterRecipeData, path: Path, writer: DataWriter) { - val byteArrayOutputStream = ByteArrayOutputStream() - val hashingOutputStream = HashingOutputStream(Hashing.sha1(), byteArrayOutputStream) - Json.encodeToStream(data.format(), hashingOutputStream) - writer.write(path, byteArrayOutputStream.toByteArray(), hashingOutputStream.hash()) + override fun writeData( + id: Identifier, + data: FilterRecipeData, + path: Path, + writer: DataWriter, + lookup: WrapperLookup + ): CompletableFuture<*> { + return DataProvider.writeCodecToPath(writer, lookup, FilterRecipeData.CODEC, data, path); } } \ No newline at end of file diff --git a/src/main/kotlin/xyz/koiro/watersource/datagen/provider/HydrationDataProvider.kt b/src/main/kotlin/xyz/koiro/watersource/datagen/provider/HydrationDataProvider.kt index 0a2396b..114bf6b 100644 --- a/src/main/kotlin/xyz/koiro/watersource/datagen/provider/HydrationDataProvider.kt +++ b/src/main/kotlin/xyz/koiro/watersource/datagen/provider/HydrationDataProvider.kt @@ -1,41 +1,38 @@ package xyz.koiro.watersource.datagen.provider -import com.google.common.hash.Hashing -import com.google.common.hash.HashingOutputStream -import kotlinx.serialization.json.Json -import kotlinx.serialization.json.encodeToStream import net.minecraft.data.DataOutput import net.minecraft.data.DataProvider import net.minecraft.data.DataWriter -import net.minecraft.entity.effect.StatusEffectInstance import net.minecraft.fluid.Fluid import net.minecraft.item.Item +import net.minecraft.registry.RegistryWrapper +import net.minecraft.registry.RegistryWrapper.WrapperLookup import net.minecraft.registry.tag.TagKey import net.minecraft.util.Identifier -import xyz.koiro.watersource.WaterSource import xyz.koiro.watersource.data.HydrationData import xyz.koiro.watersource.data.ModResourceRegistries -import xyz.koiro.watersource.identifier -import java.io.ByteArrayOutputStream -import java.io.IOException import java.nio.file.Path import java.util.concurrent.CompletableFuture -abstract class HydrationDataProvider(output: DataOutput) : - ModDataProvider(output, ModResourceRegistries.HYDRATION_KEY, "Hydration Data") { +abstract class HydrationDataProvider(output: DataOutput, lookup: CompletableFuture) : + ModDataProvider(output, ModResourceRegistries.HYDRATION_KEY, "Hydration Data", lookup) { - override fun writeData(id: Identifier, data: HydrationData, path: Path, writer: DataWriter) { - val byteArrayOutputStream = ByteArrayOutputStream() - val hashingOutputStream = HashingOutputStream(Hashing.sha1(), byteArrayOutputStream) - Json.encodeToStream(data.format(), hashingOutputStream) - writer.write(path, byteArrayOutputStream.toByteArray(), hashingOutputStream.hash()) + + override fun writeData( + id: Identifier, + data: HydrationData, + path: Path, + writer: DataWriter, + lookup: WrapperLookup + ): CompletableFuture<*> { + return DataProvider.writeCodecToPath(writer, lookup, HydrationData.CODEC, data, path); } companion object { fun dryItem( item: Item, dryLevel: Int, - vararg effectInstance: HydrationData.ProbabilityStatusEffectInstance + vararg effectInstance: HydrationData.StatusEffectObject ): HydrationData { val effects = ArrayList(effectInstance.toList()) return HydrationData( @@ -51,7 +48,7 @@ abstract class HydrationDataProvider(output: DataOutput) : item: Item, level: Int, saturation: Int, - vararg effectInstance: HydrationData.ProbabilityStatusEffectInstance + vararg effectInstance: HydrationData.StatusEffectObject ): HydrationData { val effects = ArrayList(effectInstance.toList()) return HydrationData( @@ -67,7 +64,7 @@ abstract class HydrationDataProvider(output: DataOutput) : fluid: Fluid, level: Int, saturation: Int, - vararg effectInstance: HydrationData.ProbabilityStatusEffectInstance + vararg effectInstance: HydrationData.StatusEffectObject ): HydrationData { val effects = ArrayList(effectInstance.toList()) return HydrationData( @@ -80,7 +77,7 @@ abstract class HydrationDataProvider(output: DataOutput) : tag: TagKey, level: Int, saturation: Int, - vararg effectInstance: HydrationData.ProbabilityStatusEffectInstance + vararg effectInstance: HydrationData.StatusEffectObject ): HydrationData { val effects = ArrayList(effectInstance.toList()) return HydrationData( @@ -93,7 +90,7 @@ abstract class HydrationDataProvider(output: DataOutput) : tag: TagKey, level: Int, saturation: Int, - vararg effectInstance: HydrationData.ProbabilityStatusEffectInstance + vararg effectInstance: HydrationData.StatusEffectObject ): HydrationData { val effects = ArrayList(effectInstance.toList()) return HydrationData( diff --git a/src/main/kotlin/xyz/koiro/watersource/datagen/provider/ModDataProvider.kt b/src/main/kotlin/xyz/koiro/watersource/datagen/provider/ModDataProvider.kt index a363307..8b9b988 100644 --- a/src/main/kotlin/xyz/koiro/watersource/datagen/provider/ModDataProvider.kt +++ b/src/main/kotlin/xyz/koiro/watersource/datagen/provider/ModDataProvider.kt @@ -3,13 +3,16 @@ package xyz.koiro.watersource.datagen.provider import net.minecraft.data.DataOutput import net.minecraft.data.DataProvider import net.minecraft.data.DataWriter +import net.minecraft.registry.RegistryEntryLookup.RegistryLookup +import net.minecraft.registry.RegistryWrapper +import net.minecraft.registry.RegistryWrapper.WrapperLookup import net.minecraft.util.Identifier import xyz.koiro.watersource.WaterSource import java.io.IOException import java.nio.file.Path import java.util.concurrent.CompletableFuture -abstract class ModDataProvider(val output: DataOutput, val directoryPath: String, val providerName: String) : DataProvider { +abstract class ModDataProvider(val output: DataOutput, val directoryPath: String, val providerName: String, val registryLookup: CompletableFuture) : DataProvider { class DataAdder { val dataMap = hashMapOf() @@ -18,23 +21,19 @@ abstract class ModDataProvider(val output: DataOutput, val directoryPath: Str } } - abstract fun writeData(id: Identifier, data: D, path: Path, writer: DataWriter) + abstract fun writeData(id: Identifier, data: D, path: Path, writer: DataWriter, lookup: WrapperLookup): CompletableFuture<*> abstract fun addData(adder: DataAdder) override fun run(writer: DataWriter): CompletableFuture<*> { - val dataAdder = DataAdder() - addData(dataAdder) - val array = dataAdder.dataMap.map { (ident, data) -> - val path = output.getResolver(DataOutput.OutputType.DATA_PACK, directoryPath).resolveJson(ident) - CompletableFuture.runAsync { - try { - writeData(ident, data, path, writer) - } catch (e: IOException) { - WaterSource.LOGGER.error("Failed to save file {}", path, e) - } - } - }.toTypedArray() - return (CompletableFuture.allOf(*array)) + return registryLookup.thenCompose { lookup -> + val dataAdder = DataAdder() + addData(dataAdder) + val array = dataAdder.dataMap.map { (ident, data) -> + val path = output.getResolver(DataOutput.OutputType.DATA_PACK, directoryPath).resolveJson(ident) + writeData(ident, data, path, writer, lookup) + }.toTypedArray() + CompletableFuture.allOf(*array) + } } override fun getName(): String { diff --git a/src/main/kotlin/xyz/koiro/watersource/datagen/provider/Utils.kt b/src/main/kotlin/xyz/koiro/watersource/datagen/provider/Utils.kt index f139551..64424a1 100644 --- a/src/main/kotlin/xyz/koiro/watersource/datagen/provider/Utils.kt +++ b/src/main/kotlin/xyz/koiro/watersource/datagen/provider/Utils.kt @@ -5,7 +5,7 @@ import net.minecraft.util.Identifier import xyz.koiro.watersource.data.HydrationData import xyz.koiro.watersource.datagen.provider.HydrationDataProvider.Companion.dryItem import xyz.koiro.watersource.datagen.provider.HydrationDataProvider.Companion.item -import xyz.koiro.watersource.identifier +import xyz.koiro.watersource.api.identifier fun ModDataProvider.DataAdder.addItemWithAutoId(item: Item, level: Int, saturation: Int) { 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 07a1e6a..5f848d0 100644 --- a/src/main/kotlin/xyz/koiro/watersource/datagen/recipe/StrainerFilteringFluidRecipeJsonBuilder.kt +++ b/src/main/kotlin/xyz/koiro/watersource/datagen/recipe/StrainerFilteringFluidRecipeJsonBuilder.kt @@ -1,22 +1,15 @@ 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.advancement.AdvancementCriterion import net.minecraft.data.server.recipe.CraftingRecipeJsonBuilder -import net.minecraft.data.server.recipe.RecipeJsonProvider +import net.minecraft.data.server.recipe.RecipeExporter 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 +import xyz.koiro.watersource.world.recipe.StrainerFilteringFluidRecipe class StrainerFilteringFluidRecipeJsonBuilder( val id: Identifier, @@ -34,8 +27,8 @@ class StrainerFilteringFluidRecipeJsonBuilder( return this } - override fun criterion(name: String?, conditions: CriterionConditions?): CraftingRecipeJsonBuilder { - this.advancementBuilder?.criterion(name, conditions) + override fun criterion(name: String?, criterion: AdvancementCriterion<*>?): CraftingRecipeJsonBuilder? { + this.advancementBuilder?.criterion(name, criterion) return this } @@ -48,45 +41,8 @@ class StrainerFilteringFluidRecipeJsonBuilder( return Items.APPLE } - override fun offerTo(exporter: Consumer?, 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 advancementIdentifier: 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.advancementIdentifier + override fun offerTo(exporter: RecipeExporter, recipeId: Identifier) { + exporter.accept(recipeId, StrainerFilteringFluidRecipe(inFluid, outFluid, strainer), advancementBuilder?.build(recipeId.withPrefixedPath("recipes/"))) } } diff --git a/src/main/kotlin/xyz/koiro/watersource/datagen/recipe/StrainerFilteringItemRecipeJsonBuilder.kt b/src/main/kotlin/xyz/koiro/watersource/datagen/recipe/StrainerFilteringItemRecipeJsonBuilder.kt index 38c7633..074b7c3 100644 --- a/src/main/kotlin/xyz/koiro/watersource/datagen/recipe/StrainerFilteringItemRecipeJsonBuilder.kt +++ b/src/main/kotlin/xyz/koiro/watersource/datagen/recipe/StrainerFilteringItemRecipeJsonBuilder.kt @@ -1,21 +1,14 @@ 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.advancement.AdvancementCriterion import net.minecraft.data.server.recipe.CraftingRecipeJsonBuilder -import net.minecraft.data.server.recipe.RecipeJsonProvider +import net.minecraft.data.server.recipe.RecipeExporter import net.minecraft.item.Item import net.minecraft.item.ItemStack import net.minecraft.recipe.Ingredient -import net.minecraft.recipe.RecipeSerializer import net.minecraft.util.Identifier -import xyz.koiro.watersource.api.serialize.SerializeUtils -import xyz.koiro.watersource.world.recipe.ModRecipes -import java.util.function.Consumer +import xyz.koiro.watersource.world.recipe.StrainerFilteringItemRecipe class StrainerFilteringItemRecipeJsonBuilder( val id: Identifier, @@ -34,8 +27,8 @@ class StrainerFilteringItemRecipeJsonBuilder( return this } - override fun criterion(name: String?, conditions: CriterionConditions?): CraftingRecipeJsonBuilder { - this.advancementBuilder?.criterion(name, conditions) + override fun criterion(name: String?, criterion: AdvancementCriterion<*>?): CraftingRecipeJsonBuilder? { + this.advancementBuilder?.criterion(name, criterion) return this } @@ -48,49 +41,7 @@ class StrainerFilteringItemRecipeJsonBuilder( return output.item } - override fun offerTo(exporter: Consumer?, 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, - input, - output, - cost, - strainer, - advancementBuilder, - advancementId, - group, - ) - ) - } - - class Provider( - val id: Identifier, - val input: Ingredient, - val output: ItemStack, - val cost: Int, - val strainer: Ingredient, - val advancementBuilder: Advancement.Builder?, - val advancementIdentifier: Identifier?, - val group: String?, - ) : RecipeJsonProvider { - override fun serialize(json: JsonObject) { - if (!group.isNullOrBlank()) json.addProperty("group", group) - val outputJson = SerializeUtils.itemStackToJsonObject(output) - json.add("input", input.toJson()) - json.add("output", outputJson) - json.addProperty("cost", cost) - json.add("strainer", strainer.toJson()) - } - - override fun getRecipeId(): Identifier = id - - override fun getSerializer(): RecipeSerializer<*> = ModRecipes.STRAINER_FILTERING_ITEM_SERIALIZER - - override fun toAdvancementJson(): JsonObject? = this.advancementBuilder?.toJson() - - override fun getAdvancementId(): Identifier? = this.advancementIdentifier + override fun offerTo(exporter: RecipeExporter, recipeId: Identifier) { + exporter.accept(recipeId, StrainerFilteringItemRecipe(input, output, cost, strainer), advancementBuilder?.build(recipeId.withPrefixedPath("recipes/"))) } } diff --git a/src/main/kotlin/xyz/koiro/watersource/event/ModEventsHandlers.kt b/src/main/kotlin/xyz/koiro/watersource/event/ModEventsHandlers.kt index d7e54db..d1e2ecb 100644 --- a/src/main/kotlin/xyz/koiro/watersource/event/ModEventsHandlers.kt +++ b/src/main/kotlin/xyz/koiro/watersource/event/ModEventsHandlers.kt @@ -5,6 +5,7 @@ package xyz.koiro.watersource.event import net.fabricmc.fabric.api.event.lifecycle.v1.ServerEntityEvents import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents import net.minecraft.entity.effect.StatusEffectInstance +import net.minecraft.registry.entry.RegistryEntry import net.minecraft.server.network.ServerPlayerEntity import net.minecraft.util.ActionResult import net.minecraft.world.World @@ -48,7 +49,7 @@ object ModEventsHandlers { private fun thirstyTick(player: ServerPlayerEntity) { player.ifInSurvivalAndGetWaterData { waterData -> - player.getStatusEffect(ModStatusEffects.THIRSTY)?.let { effectInstance -> + player.getStatusEffect(RegistryEntry.of(ModStatusEffects.THIRSTY))?.let { effectInstance -> waterData.addExhaustion(Exhaustion.thirstyPerSecond(effectInstance.amplifier) / 50f, player) waterData.updateToClient(player) } @@ -58,7 +59,7 @@ object ModEventsHandlers { private fun highWaterLevelReward(player: ServerPlayerEntity, world: World) { if (world.isClient()) return player.ifInSurvivalAndGetWaterData { waterLevelData -> - if (waterLevelData.level > 16 && !player.hasStatusEffect(ModStatusEffects.THIRSTY)) { + if (waterLevelData.level > 16 && !player.hasStatusEffect(RegistryEntry.of(ModStatusEffects.THIRSTY))) { val tick = player.getAttachedOrCreate(ModAttachmentTypes.WATER_REWARD_HEAL_TICKER) tick.add(1) if (tick.value > (WSConfig.format.highWaterPlayerHealingIntervalSecond * 50).toInt()) { diff --git a/src/main/kotlin/xyz/koiro/watersource/network/ModNetworking.kt b/src/main/kotlin/xyz/koiro/watersource/network/ModNetworking.kt index e4731fe..e8f00d0 100644 --- a/src/main/kotlin/xyz/koiro/watersource/network/ModNetworking.kt +++ b/src/main/kotlin/xyz/koiro/watersource/network/ModNetworking.kt @@ -1,8 +1,15 @@ package xyz.koiro.watersource.network +import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry +import net.minecraft.network.NetworkSide +import net.minecraft.network.packet.CustomPayload +import net.minecraft.network.packet.PacketType +import net.minecraft.registry.Registries import xyz.koiro.watersource.WaterSource object ModNetworking { - val UPDATE_WATER_DATA_ID = WaterSource.identifier("update_water_level_data") - val UPDATE_FILTER_ENTITY_ID = WaterSource.identifier("update_filter_entity") + val UPDATE_WATER_LEVEL = CustomPayload.Id(WaterSource.identifier("update_water_level")) + fun initialize(){ + PayloadTypeRegistry.playS2C().register(UPDATE_WATER_LEVEL, UpdateWaterLevelPayload.PACK_CODEC) + } } \ No newline at end of file diff --git a/src/main/kotlin/xyz/koiro/watersource/network/UpdateWaterLevelPayload.kt b/src/main/kotlin/xyz/koiro/watersource/network/UpdateWaterLevelPayload.kt new file mode 100644 index 0000000..eca07d0 --- /dev/null +++ b/src/main/kotlin/xyz/koiro/watersource/network/UpdateWaterLevelPayload.kt @@ -0,0 +1,28 @@ +package xyz.koiro.watersource.network + +import net.minecraft.network.PacketByteBuf +import net.minecraft.network.RegistryByteBuf +import net.minecraft.network.codec.PacketCodec +import net.minecraft.network.packet.CustomPayload + +class UpdateWaterLevelPayload(val level: Int, val saturation: Int, val exhaustion: Float): CustomPayload { + companion object{ + val PACK_CODEC = PacketCodec.ofStatic(::write, ::read) + + fun write(buf: RegistryByteBuf, payload: UpdateWaterLevelPayload){ + buf.writeInt(payload.level) + buf.writeInt(payload.saturation) + buf.writeFloat(payload.exhaustion) + } + fun read(buf: RegistryByteBuf): UpdateWaterLevelPayload{ + val level = buf.readInt() + val saturation = buf.readInt() + val exhaustion = buf.readFloat() + return UpdateWaterLevelPayload(level, saturation, exhaustion) + } + } + + override fun getId(): CustomPayload.Id { + return ModNetworking.UPDATE_WATER_LEVEL + } +} \ No newline at end of file diff --git a/src/main/kotlin/xyz/koiro/watersource/world/attachment/WaterLevelData.kt b/src/main/kotlin/xyz/koiro/watersource/world/attachment/WaterLevelData.kt index 23ee7ee..f83d36e 100644 --- a/src/main/kotlin/xyz/koiro/watersource/world/attachment/WaterLevelData.kt +++ b/src/main/kotlin/xyz/koiro/watersource/world/attachment/WaterLevelData.kt @@ -4,9 +4,11 @@ import net.fabricmc.fabric.api.networking.v1.PacketByteBufs import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking import net.minecraft.entity.player.PlayerEntity import net.minecraft.network.PacketByteBuf +import net.minecraft.registry.entry.RegistryEntry import net.minecraft.server.network.ServerPlayerEntity import xyz.koiro.watersource.WSConfig import xyz.koiro.watersource.network.ModNetworking +import xyz.koiro.watersource.network.UpdateWaterLevelPayload import xyz.koiro.watersource.world.effect.ModStatusEffects import xyz.koiro.watersource.world.enchantment.MoisturizingEnchantment @@ -38,7 +40,7 @@ class WaterLevelData( /** Consume water by adding exhaustion like hungry system in vanilla. * */ fun addExhaustion(amount: Float, player: PlayerEntity) { - val effect = player.getStatusEffect(ModStatusEffects.THIRSTY) + val effect = player.getStatusEffect(RegistryEntry.of(ModStatusEffects.THIRSTY)) var finalAmount = amount * WSConfig.Exhaustion.multiplier * MoisturizingEnchantment.getPlayerMoisturizingRatio(player) effect?.let { @@ -97,7 +99,7 @@ class WaterLevelData( } fun updateToClient(user: ServerPlayerEntity) { - ServerPlayNetworking.send(user, ModNetworking.UPDATE_WATER_DATA_ID, writeBuf(PacketByteBufs.create())) + ServerPlayNetworking.send(user, UpdateWaterLevelPayload(level, saturation, exhaustion)) } fun setData(level: Int = 20, saturation: Int = 16, exhaustion: Float = 0f) { diff --git a/src/main/kotlin/xyz/koiro/watersource/world/block/FilterBlock.kt b/src/main/kotlin/xyz/koiro/watersource/world/block/FilterBlock.kt index 44982b2..dffeaa8 100644 --- a/src/main/kotlin/xyz/koiro/watersource/world/block/FilterBlock.kt +++ b/src/main/kotlin/xyz/koiro/watersource/world/block/FilterBlock.kt @@ -1,15 +1,18 @@ package xyz.koiro.watersource.world.block +import com.mojang.serialization.MapCodec import net.minecraft.block.* import net.minecraft.block.entity.BlockEntity import net.minecraft.block.entity.BlockEntityTicker import net.minecraft.block.entity.BlockEntityType +import net.minecraft.component.DataComponentTypes +import net.minecraft.component.type.PotionContentsComponent import net.minecraft.entity.LivingEntity import net.minecraft.entity.player.PlayerEntity import net.minecraft.fluid.Fluids import net.minecraft.item.ItemStack import net.minecraft.item.Items -import net.minecraft.potion.PotionUtil +import net.minecraft.potion.Potion import net.minecraft.potion.Potions import net.minecraft.sound.SoundCategory import net.minecraft.sound.SoundEvents @@ -25,11 +28,12 @@ import net.minecraft.world.World import net.minecraft.world.WorldView import xyz.koiro.watersource.api.setStackInHandOrInsertIntoInventory import xyz.koiro.watersource.api.storage.getOrCreateFluidStorageData -import xyz.koiro.watersource.simpleStack +import xyz.koiro.watersource.api.simpleStack import xyz.koiro.watersource.world.block.entity.FilterBlockEntity import xyz.koiro.watersource.world.block.entity.ModBlockEntities import xyz.koiro.watersource.world.fluid.ModFluids import xyz.koiro.watersource.world.item.* +import kotlin.jvm.optionals.getOrNull import kotlin.math.min open class FilterBlock(val capacity: Long, val filterVolumePerSecond: Long, settings: Settings?) : @@ -47,11 +51,11 @@ open class FilterBlock(val capacity: Long, val filterVolumePerSecond: Long, sett world: World, pos: BlockPos, player: PlayerEntity?, - hand: Hand?, hit: BlockHitResult? - ): ActionResult { + ): ActionResult? { val entity = world.getBlockEntity(pos) - if (player != null && hand != null && entity is FilterBlockEntity) { + if (player != null && entity is FilterBlockEntity) { + val hand = player.activeHand val handStack = player.getStackInHand(hand) val data = entity.fluidStorageData val handItem = handStack.item @@ -190,7 +194,7 @@ open class FilterBlock(val capacity: Long, val filterVolumePerSecond: Long, sett handItem == Items.GLASS_BOTTLE && (data.fluid == Fluids.WATER || data.fluid == ModFluids.PURIFIED_WATER) && data.amount >= 250 -> { val newStack = when (data.fluid) { - Fluids.WATER -> PotionUtil.setPotion(Items.POTION.simpleStack(), Potions.WATER) + Fluids.WATER -> PotionContentsComponent.createStack(Items.POTION, Potions.WATER) ModFluids.PURIFIED_WATER -> ModItems.PURIFIED_WATER_BOTTLE.simpleStack() else -> null } @@ -202,7 +206,7 @@ open class FilterBlock(val capacity: Long, val filterVolumePerSecond: Long, sett } } - handItem == Items.POTION && PotionUtil.getPotion(handStack) == Potions.WATER && hasStrainerAndIsUp -> { + handItem == Items.POTION && handStack.get(DataComponentTypes.POTION_CONTENTS)?.potion?.getOrNull()?.value() == Potions.WATER && hasStrainerAndIsUp -> { if (data.insert(250, Fluids.WATER, true)) { handStack.decrement(1) val newStack = Items.GLASS_BOTTLE.simpleStack() @@ -255,12 +259,13 @@ open class FilterBlock(val capacity: Long, val filterVolumePerSecond: Long, sett builder?.add(IS_UP) } - override fun onBreak(world: World?, pos: BlockPos, state: BlockState, player: PlayerEntity?) { + override fun onBreak(world: World?, pos: BlockPos, state: BlockState, player: PlayerEntity?): BlockState? { super.onBreak(world, pos, state, player) val isUp = state.get(IS_UP) val otherPos = if (isUp) pos.down() else pos.up() world?.removeBlock(otherPos, false) world?.removeBlockEntity(otherPos) + return state } override fun isCullingShapeFullCube(state: BlockState?, world: BlockView?, pos: BlockPos?): Boolean { @@ -278,6 +283,10 @@ open class FilterBlock(val capacity: Long, val filterVolumePerSecond: Long, sett return FilterBlockEntity(pos, state, isUp = state.get(IS_UP), capacity = capacity) } + override fun getCodec(): MapCodec { + TODO("Not yet implemented") + } + override fun getRenderType(state: BlockState?): BlockRenderType { return BlockRenderType.MODEL } @@ -305,7 +314,7 @@ open class FilterBlock(val capacity: Long, val filterVolumePerSecond: Long, sett state: BlockState?, type: BlockEntityType? ): BlockEntityTicker? { - return checkType(type, ModBlockEntities.FILTER) { world1, pos, state1, be -> + return validateTicker(type, ModBlockEntities.FILTER) { world1, pos, state1, be -> FilterBlockEntity.tick(world1, pos, state1, be) } } diff --git a/src/main/kotlin/xyz/koiro/watersource/world/block/entity/ContainerBlockEntity.kt b/src/main/kotlin/xyz/koiro/watersource/world/block/entity/ContainerBlockEntity.kt index 6394823..dffd53f 100644 --- a/src/main/kotlin/xyz/koiro/watersource/world/block/entity/ContainerBlockEntity.kt +++ b/src/main/kotlin/xyz/koiro/watersource/world/block/entity/ContainerBlockEntity.kt @@ -5,6 +5,7 @@ import net.minecraft.block.entity.BlockEntity import net.minecraft.block.entity.BlockEntityType import net.minecraft.fluid.Fluids import net.minecraft.nbt.NbtCompound +import net.minecraft.registry.RegistryWrapper import net.minecraft.util.math.BlockPos import xyz.koiro.watersource.api.storage.FluidStorageData @@ -12,13 +13,13 @@ open class ContainerBlockEntity(type: BlockEntityType<*>?, pos: BlockPos?, state BlockEntity(type, pos, state) { var fluidStorageData: FluidStorageData = FluidStorageData(Fluids.EMPTY, 0, capacity) - override fun writeNbt(nbt: NbtCompound?) { - super.writeNbt(nbt) + override fun writeNbt(nbt: NbtCompound?, registryLookup: RegistryWrapper.WrapperLookup?) { + super.writeNbt(nbt, registryLookup) nbt?.put("FluidStorageData", fluidStorageData.toNbt()) } - override fun readNbt(nbt: NbtCompound?) { - super.readNbt(nbt) + override fun readNbt(nbt: NbtCompound?, registryLookup: RegistryWrapper.WrapperLookup?) { + super.readNbt(nbt, registryLookup) nbt?.getCompound("FluidStorageData")?.let { nbtCompound -> FluidStorageData.fromNbt(nbtCompound)?.let { fluidStorageData = it diff --git a/src/main/kotlin/xyz/koiro/watersource/world/block/entity/FilterBlockEntity.kt b/src/main/kotlin/xyz/koiro/watersource/world/block/entity/FilterBlockEntity.kt index 0e7977b..ca3acbe 100644 --- a/src/main/kotlin/xyz/koiro/watersource/world/block/entity/FilterBlockEntity.kt +++ b/src/main/kotlin/xyz/koiro/watersource/world/block/entity/FilterBlockEntity.kt @@ -2,16 +2,14 @@ package xyz.koiro.watersource.world.block.entity -import net.fabricmc.fabric.api.networking.v1.PacketByteBufs -import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking import net.minecraft.block.BlockState import net.minecraft.fluid.Fluid import net.minecraft.item.ItemStack import net.minecraft.nbt.NbtCompound -import net.minecraft.network.PacketByteBuf import net.minecraft.network.listener.ClientPlayPacketListener import net.minecraft.network.packet.Packet import net.minecraft.network.packet.s2c.play.BlockEntityUpdateS2CPacket +import net.minecraft.registry.RegistryWrapper import net.minecraft.server.network.ServerPlayerEntity import net.minecraft.util.math.BlockPos import net.minecraft.world.World @@ -19,7 +17,6 @@ import xyz.koiro.watersource.WSConfig import xyz.koiro.watersource.api.storage.FluidStorageData import xyz.koiro.watersource.api.storage.ItemStorageData import xyz.koiro.watersource.data.FilterRecipeDataManager -import xyz.koiro.watersource.network.ModNetworking import xyz.koiro.watersource.world.block.FilterBlock import xyz.koiro.watersource.world.item.Strainer import kotlin.math.min @@ -40,9 +37,10 @@ class FilterBlockEntity(pos: BlockPos, state: BlockState, var capacity: Long, va protected var strainerStorage: ItemStorageData = ItemStorageData() var filterTicks: Int = 0 - fun getFilterVolumePerSecond(): Long{ + fun getFilterVolumePerSecond(): Long { return (cachedState.block as FilterBlock).filterVolumePerSecond } + /** Return the strainer in the up filter. If inserting failed, return null. */ fun insertStrainerInUp(world: World, insert: ItemStack): ItemStack? { val storage = getStrainerStorage(world) @@ -83,23 +81,23 @@ class FilterBlockEntity(pos: BlockPos, state: BlockState, var capacity: Long, va return getUpEntity(world)?.strainerStorage } - override fun writeNbt(nbt: NbtCompound?) { - super.writeNbt(nbt) - if (nbt == null) return + override fun writeNbt(nbt: NbtCompound?, registryLookup: RegistryWrapper.WrapperLookup?) { + super.writeNbt(nbt, registryLookup) + if (nbt == null || registryLookup == null) return nbt.putBoolean("isUp", isUp) val strainerNbt = NbtCompound() - strainerStorage.writeNbt(strainerNbt) + strainerStorage.writeNbt(registryLookup, strainerNbt) nbt.put("strainer", strainerNbt) nbt.putBoolean("isWorking", isWorking) nbt.putInt("ticks", filterTicks) } - override fun readNbt(nbt: NbtCompound?) { - super.readNbt(nbt) - if (nbt == null) return + override fun readNbt(nbt: NbtCompound?, registryLookup: RegistryWrapper.WrapperLookup?) { + super.readNbt(nbt, registryLookup) + if (nbt == null || registryLookup == null) return isUp = nbt.getBoolean("isUp") ?: false val strainerNbt = nbt.getCompound("strainer") - strainerNbt?.let { strainerStorage.readNbt(it) } + strainerNbt?.let { strainerStorage = ItemStorageData.fromNbt(registryLookup, it) ?: ItemStorageData() } isWorking = nbt.getBoolean("isWorking") nbt.putInt("ticks", filterTicks) } @@ -109,10 +107,7 @@ class FilterBlockEntity(pos: BlockPos, state: BlockState, var capacity: Long, va } fun syncToClient(player: ServerPlayerEntity) { - val buf = PacketByteBufs.create() - buf.writeBlockPos(pos) - writePacket(buf) - ServerPlayNetworking.send(player, ModNetworking.UPDATE_FILTER_ENTITY_ID, buf) + player.networkHandler.sendPacket(toUpdatePacket()) } fun syncToClientOfPlayersInRadius(world: World, radius: Float) { @@ -124,21 +119,8 @@ class FilterBlockEntity(pos: BlockPos, state: BlockState, var capacity: Long, va } } - fun writePacket(buf: PacketByteBuf) { - val nbt = NbtCompound() - writeNbt(nbt) - - buf.writeNbt(nbt) - } - - fun readPacket(buf: PacketByteBuf) { - val nbt = buf.readNbt() - - this.readNbt(nbt) - } - - override fun toInitialChunkDataNbt(): NbtCompound { - return createNbt() + override fun toInitialChunkDataNbt(registryLookup: RegistryWrapper.WrapperLookup?): NbtCompound? { + return createNbt(registryLookup) } var endSynced: Boolean = false diff --git a/src/main/kotlin/xyz/koiro/watersource/world/datacomponent/ModDataComponentTypes.kt b/src/main/kotlin/xyz/koiro/watersource/world/datacomponent/ModDataComponentTypes.kt new file mode 100644 index 0000000..03c1315 --- /dev/null +++ b/src/main/kotlin/xyz/koiro/watersource/world/datacomponent/ModDataComponentTypes.kt @@ -0,0 +1,26 @@ +package xyz.koiro.watersource.world.datacomponent + +import net.minecraft.component.DataComponentType +import net.minecraft.registry.Registries +import net.minecraft.registry.Registry +import xyz.koiro.watersource.WaterSource +import xyz.koiro.watersource.api.storage.FluidStorageData +import java.util.function.UnaryOperator + +object ModDataComponentTypes { + fun active(){} + + val FLUID_STORAGE = register("fluid_storage") { + it.codec(FluidStorageData.CODEC).packetCodec(FluidStorageData.PACKET_CODEC) + } + + private fun register( + id: String, + builderOperator: UnaryOperator> + ): DataComponentType { + return Registry.register( + Registries.DATA_COMPONENT_TYPE, + WaterSource.identifier(id), (builderOperator.apply(DataComponentType.builder())).build() + ) as DataComponentType + } +} \ No newline at end of file diff --git a/src/main/kotlin/xyz/koiro/watersource/world/effect/ModStatusEffects.kt b/src/main/kotlin/xyz/koiro/watersource/world/effect/ModStatusEffects.kt index 653ef0f..74945f0 100644 --- a/src/main/kotlin/xyz/koiro/watersource/world/effect/ModStatusEffects.kt +++ b/src/main/kotlin/xyz/koiro/watersource/world/effect/ModStatusEffects.kt @@ -9,9 +9,10 @@ import xyz.koiro.watersource.WaterSource object ModStatusEffects { val THIRSTY = regStatusEffect("thirsty") { CustomEffect(StatusEffectCategory.HARMFUL, 0xE8A655) }; - fun active(){ + fun active() { } + fun regStatusEffect(id: String, effect: () -> StatusEffect): StatusEffect { return Registry.register(Registries.STATUS_EFFECT, WaterSource.identifier(id), effect()) } diff --git a/src/main/kotlin/xyz/koiro/watersource/world/enchantment/MoisturizingEnchantment.kt b/src/main/kotlin/xyz/koiro/watersource/world/enchantment/MoisturizingEnchantment.kt index 2b4736c..4f7bb8f 100644 --- a/src/main/kotlin/xyz/koiro/watersource/world/enchantment/MoisturizingEnchantment.kt +++ b/src/main/kotlin/xyz/koiro/watersource/world/enchantment/MoisturizingEnchantment.kt @@ -2,29 +2,34 @@ package xyz.koiro.watersource.world.enchantment import net.minecraft.enchantment.Enchantment import net.minecraft.enchantment.EnchantmentHelper -import net.minecraft.enchantment.EnchantmentTarget +import net.minecraft.enchantment.Enchantments import net.minecraft.entity.EquipmentSlot import net.minecraft.entity.player.PlayerEntity +import net.minecraft.registry.tag.ItemTags import xyz.koiro.watersource.WSConfig -import xyz.koiro.watersource.WaterSource class MoisturizingEnchantment() : - Enchantment(Rarity.UNCOMMON, EnchantmentTarget.ARMOR, arrayOf(EquipmentSlot.FEET, EquipmentSlot.HEAD, EquipmentSlot.LEGS, EquipmentSlot.CHEST)) { - override fun getMaxLevel(): Int { - return 3 - } - override fun getMinPower(level: Int): Int { - return 1 - } + Enchantment( + properties( + ItemTags.ARMOR_ENCHANTABLE, + ItemTags.CHEST_ARMOR_ENCHANTABLE, + 1, + 3, + leveledCost(10, 20), + leveledCost(60, 20), + 8, + EquipmentSlot.HEAD, EquipmentSlot.CHEST, EquipmentSlot.LEGS, EquipmentSlot.FEET + ) + ) { companion object { fun getPlayerMoisturizingLevelSum(player: PlayerEntity): Int{ var levelSum = 0 player.armorItems.forEach { - val enchantments = EnchantmentHelper.fromNbt(it.enchantments) - enchantments.forEach { enchantment, level -> - if (enchantment == ModEnchantments.MOISTURIZING) - levelSum += level + val enchantments = EnchantmentHelper.getEnchantments(it) + enchantments.enchantmentsMap.forEach { enchantment -> + if (enchantment.key.value() == ModEnchantments.MOISTURIZING) + levelSum += enchantment.intValue } } return levelSum diff --git a/src/main/kotlin/xyz/koiro/watersource/world/item/EmptyFluidContainerItem.kt b/src/main/kotlin/xyz/koiro/watersource/world/item/EmptyFluidContainerItem.kt index 819d5f4..f3037bf 100644 --- a/src/main/kotlin/xyz/koiro/watersource/world/item/EmptyFluidContainerItem.kt +++ b/src/main/kotlin/xyz/koiro/watersource/world/item/EmptyFluidContainerItem.kt @@ -1,6 +1,6 @@ package xyz.koiro.watersource.world.item -import net.minecraft.client.item.TooltipContext +import net.minecraft.client.item.TooltipType import net.minecraft.entity.player.PlayerEntity import net.minecraft.fluid.Fluids import net.minecraft.item.Item @@ -44,13 +44,13 @@ class EmptyFluidContainerItem(settings: Settings?, val containerStack: () -> Ite override fun appendTooltip( stack: ItemStack?, - world: World?, + context: TooltipContext?, tooltip: MutableList?, - context: TooltipContext? + type: TooltipType? ) { containerStack().getOrCreateFluidStorageData()?.let { storageData -> tooltip?.add(FluidStorageData.getEmptyText(storageData.capacity).styled { it.withColor(Formatting.GRAY) }) } - super.appendTooltip(stack, world, tooltip, context) + super.appendTooltip(stack, context, tooltip, type) } } \ No newline at end of file diff --git a/src/main/kotlin/xyz/koiro/watersource/world/item/FluidContainerItem.kt b/src/main/kotlin/xyz/koiro/watersource/world/item/FluidContainerItem.kt index 400a3f4..5221630 100644 --- a/src/main/kotlin/xyz/koiro/watersource/world/item/FluidContainerItem.kt +++ b/src/main/kotlin/xyz/koiro/watersource/world/item/FluidContainerItem.kt @@ -2,18 +2,12 @@ package xyz.koiro.watersource.world.item -import net.fabricmc.fabric.api.transfer.v1.context.ContainerItemContext -import net.fabricmc.fabric.api.transfer.v1.fluid.FluidStorage -import net.fabricmc.fabric.api.transfer.v1.fluid.FluidVariant -import net.fabricmc.fabric.api.transfer.v1.fluid.base.SingleFluidStorage -import net.fabricmc.fabric.api.transfer.v1.storage.Storage -import net.minecraft.client.item.TooltipContext +import net.minecraft.client.item.TooltipType import net.minecraft.entity.player.PlayerEntity import net.minecraft.fluid.Fluid import net.minecraft.fluid.Fluids import net.minecraft.item.Item import net.minecraft.item.ItemStack -import net.minecraft.nbt.NbtCompound import net.minecraft.text.Text import net.minecraft.util.Formatting import net.minecraft.util.Hand @@ -32,9 +26,6 @@ open class FluidContainerItem( val capacity: Long, val emptyContainer: (() -> ItemStack)? = null ) : Item(settings.maxDamage((capacity / WSConfig.UNIT_DRINK_VOLUME).toInt())) { - init { - FluidStorage.ITEM.registerForItems(::getFluidStorage, this) - } fun canInsert(itemStack: ItemStack, fluid: Fluid, amount: Long, currentData: FluidStorageData): Boolean { return fluid == currentData.fluid || currentData.isBlank() @@ -43,6 +34,7 @@ open class FluidContainerItem( fun onFluidDataChanged(stack: ItemStack, playerEntity: PlayerEntity, hand: Hand) { stack.getOrCreateFluidStorageData()?.let { val amount = it.amount + val maxDamage = stack.maxDamage val damage = round((1 - amount.toDouble() / capacity.toDouble()) * maxDamage).toInt() if (damage >= maxDamage){ if (emptyContainer != null){ @@ -75,35 +67,15 @@ open class FluidContainerItem( return super.use(world, user, hand) } - open fun getFluidStorage(stack: ItemStack, context: ContainerItemContext): Storage { - val nbt = stack.getSubNbt("FluidStorage") - val ret = object : SingleFluidStorage() { - override fun getCapacity(variant: FluidVariant?): Long { - return (stack.item as FluidContainerItem).capacity - } - - override fun onFinalCommit() { - super.onFinalCommit() - val nbtCompound = NbtCompound() - this.writeNbt(nbtCompound) - stack.setSubNbt("FluidStorage", nbtCompound) - } - } - if (nbt != null) { - ret.readNbt(nbt) - } - return ret - } - override fun appendTooltip( - stack: ItemStack, - world: World?, - tooltip: MutableList, - context: TooltipContext + stack: ItemStack?, + context: TooltipContext?, + tooltip: MutableList?, + type: TooltipType? ) { - stack.getOrCreateFluidStorageData()?.let { storageData -> - tooltip.add(storageData.getDisplayText().styled { it.withColor(Formatting.GRAY) }) + stack?.getOrCreateFluidStorageData()?.let { storageData -> + tooltip?.add(storageData.getDisplayText().styled { it.withColor(Formatting.GRAY) }) } - super.appendTooltip(stack, world, tooltip, context) + super.appendTooltip(stack, context, tooltip, type) } } \ No newline at end of file diff --git a/src/main/kotlin/xyz/koiro/watersource/world/item/IHydrationUsable.kt b/src/main/kotlin/xyz/koiro/watersource/world/item/IHydrationUsable.kt index f5b08b7..0bbd457 100644 --- a/src/main/kotlin/xyz/koiro/watersource/world/item/IHydrationUsable.kt +++ b/src/main/kotlin/xyz/koiro/watersource/world/item/IHydrationUsable.kt @@ -31,7 +31,7 @@ interface IHydrationUsable { val dryLevel = hydrationData.dryLevel!! waterLevelData.dryConsumeWater(dryLevel) } else { - waterLevelData.restoreWater(level, saturation, multiplier) + waterLevelData.restoreWater(level!!, saturation!!, multiplier) } waterLevelData.updateToClient(player) hydrationData.applyEffectsToPlayer(player, multiplier) 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 ff8b018..28cbda6 100644 --- a/src/main/kotlin/xyz/koiro/watersource/world/item/ModItems.kt +++ b/src/main/kotlin/xyz/koiro/watersource/world/item/ModItems.kt @@ -1,9 +1,9 @@ package xyz.koiro.watersource.world.item -import net.fabricmc.fabric.api.item.v1.FabricItemSettings import net.minecraft.item.BlockItem import net.minecraft.item.BucketItem import net.minecraft.item.Item +import net.minecraft.item.Item.Settings import net.minecraft.item.ItemStack import net.minecraft.item.Items import net.minecraft.registry.Registries @@ -19,50 +19,50 @@ object ModItems { @AutoGenItemData(enLang = "Natural Strainer", cnLang = "自然滤网") val NATURAL_STRAINER = registerItem( "natural_strainer", - Strainer(FabricItemSettings().maxCount(1).maxDamage(16)) + Strainer(Settings().maxCount(1).maxDamage(16)) ) @AutoGenItemData(enLang = "Compressed Strainer", cnLang = "压缩滤网") val COMPRESSED_STRAINER = registerItem( "compressed_strainer", - Strainer(FabricItemSettings().maxCount(1).maxDamage(80)) + Strainer(Settings().maxCount(1).maxDamage(80)) ) @AutoGenItemData(enLang = "Paper Strainer", cnLang = "纸滤网") val PAPER_STRAINER = registerItem( "paper_strainer", - Strainer(FabricItemSettings().maxCount(1).maxDamage(8)) + Strainer(Settings().maxCount(1).maxDamage(8)) ) @AutoGenItemData(enLang = "Waste Strainer", cnLang = "旧滤网") val WASTE_STRAINER = registerItem( "waste_strainer", - Item(FabricItemSettings()) + Item(Settings()) ) @AutoGenItemData(enLang = "Leather Water Bag (Small)", cnLang = "皮水袋(小)") val LEATHER_WATER_BAG_SMALL = registerItem( "leather_water_bag_small", - DrinkableContainer(FabricItemSettings().maxCount(1), 1000) + DrinkableContainer(Settings().maxCount(1), 1000) ) @AutoGenItemData(enLang = "Leather Water Bag (Medium)", cnLang = "皮水袋(中)") val LEATHER_WATER_BAG_MEDIUM = registerItem( "leather_water_bag_medium", - DrinkableContainer(FabricItemSettings().maxCount(1), 2000) + DrinkableContainer(Settings().maxCount(1), 2000) ) @AutoGenItemData(enLang = "Leather Water Bag (Large)", cnLang = "皮水袋(大)") val LEATHER_WATER_BAG_LARGE = registerItem( "leather_water_bag_large", - DrinkableContainer(FabricItemSettings().maxCount(1), 4000, drinkVolumeMultiplier = 2) + DrinkableContainer(Settings().maxCount(1), 4000, drinkVolumeMultiplier = 2) ) @AutoGenItemData(enLang = "Wooden Cup", cnLang = "木杯子", modelType = ModelType.DontGen) val WOODEN_CUP: Item = registerItem( "wooden_cup", DrinkableContainer( - FabricItemSettings().maxCount(1), + Settings().maxCount(1), 250, emptyContainerStack = { ItemStack(WOODEN_CUP_EMPTY) } ) @@ -71,23 +71,23 @@ object ModItems { @AutoGenItemData(enLang = "Wooden Cup", cnLang = "木杯子") val WOODEN_CUP_EMPTY: Item = registerItem( "wooden_cup_empty", - EmptyFluidContainerItem(FabricItemSettings()) { ItemStack(WOODEN_CUP) } + EmptyFluidContainerItem(Settings()) { ItemStack(WOODEN_CUP) } ) @AutoGenItemData(enLang = "Raw Pottery Cup", cnLang = "陶杯子(未烤制)") - val RAW_POTTERY_CUP = registerItem("raw_pottery_cup", Item(FabricItemSettings())) + val RAW_POTTERY_CUP = registerItem("raw_pottery_cup", Item(Settings())) @AutoGenItemData(enLang = "Pottery Cup", cnLang = "陶杯子") val POTTERY_CUP_EMPTY: Item = registerItem( "pottery_cup_empty", - EmptyFluidContainerItem(FabricItemSettings()) { ItemStack(POTTERY_CUP) } + EmptyFluidContainerItem(Settings()) { ItemStack(POTTERY_CUP) } ) @AutoGenItemData(enLang = "Pottery Cup", cnLang = "陶杯子", modelType = ModelType.DontGen) val POTTERY_CUP: Item = registerItem( "pottery_cup", DrinkableContainer( - FabricItemSettings().maxCount(1), + Settings().maxCount(1), 750, emptyContainerStack = { ItemStack(POTTERY_CUP_EMPTY) } ) @@ -95,23 +95,23 @@ object ModItems { @AutoGenItemData(enLang = "Purified Water Bucket", cnLang = "净水桶") val PURIFIED_WATER_BUCKET = - registerItem("purified_water_bucket", BucketItem(ModFluids.PURIFIED_WATER, FabricItemSettings().maxCount(1))) + registerItem("purified_water_bucket", BucketItem(ModFluids.PURIFIED_WATER, Settings().maxCount(1))) @AutoGenItemData(enLang = "Purified Water Bottle", cnLang = "净水瓶") val PURIFIED_WATER_BOTTLE = registerItem( "purified_water_bottle", - DrinkOnceItem(FabricItemSettings().maxCount(8), 32) { ItemStack(Items.GLASS_BOTTLE) } + DrinkOnceItem(Settings().maxCount(8), 32) { ItemStack(Items.GLASS_BOTTLE) } ) val WOODEN_FILTER_BLOCK = registerItem( "wooden_filter", - BlockItem(ModBlocks.WOODEN_FILTER, FabricItemSettings()) + BlockItem(ModBlocks.WOODEN_FILTER, Settings()) ) val IRON_FILTER_BLOCK = registerItem( "iron_filter", - BlockItem(ModBlocks.IRON_FILTER, FabricItemSettings()) + BlockItem(ModBlocks.IRON_FILTER, Settings()) ) fun active() { diff --git a/src/main/kotlin/xyz/koiro/watersource/world/item/Strainer.kt b/src/main/kotlin/xyz/koiro/watersource/world/item/Strainer.kt index adad88e..330d881 100644 --- a/src/main/kotlin/xyz/koiro/watersource/world/item/Strainer.kt +++ b/src/main/kotlin/xyz/koiro/watersource/world/item/Strainer.kt @@ -1,6 +1,6 @@ package xyz.koiro.watersource.world.item -import net.minecraft.client.item.TooltipContext +import net.minecraft.client.item.TooltipType import net.minecraft.item.Item import net.minecraft.item.ItemStack import net.minecraft.text.Text @@ -26,12 +26,13 @@ class Strainer(settings: Settings?) : Item(settings) { } override fun appendTooltip( - stack: ItemStack, - world: World?, - tooltip: MutableList, - context: TooltipContext + stack: ItemStack?, + context: TooltipContext?, + tooltip: MutableList?, + type: TooltipType? ) { - super.appendTooltip(stack, world, tooltip, context) + super.appendTooltip(stack, context, tooltip, type) + if (stack != null && tooltip != null) tooltip.add( Text.of("${stack.maxDamage - stack.damage}/${stack.maxDamage}").copy() .styled { it.withColor(Formatting.GRAY) }) 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 108832f..7f0f6d2 100644 --- a/src/main/kotlin/xyz/koiro/watersource/world/recipe/StrainerFilteringFluidRecipe.kt +++ b/src/main/kotlin/xyz/koiro/watersource/world/recipe/StrainerFilteringFluidRecipe.kt @@ -1,25 +1,27 @@ package xyz.koiro.watersource.world.recipe -import com.google.gson.JsonObject +import com.mojang.serialization.Codec +import com.mojang.serialization.MapCodec +import com.mojang.serialization.codecs.RecordCodecBuilder import net.minecraft.fluid.Fluid import net.minecraft.inventory.RecipeInputInventory import net.minecraft.item.ItemStack -import net.minecraft.network.PacketByteBuf +import net.minecraft.network.RegistryByteBuf import net.minecraft.recipe.Ingredient import net.minecraft.recipe.RecipeSerializer import net.minecraft.recipe.book.CraftingRecipeCategory -import net.minecraft.registry.DynamicRegistryManager import net.minecraft.registry.Registries -import net.minecraft.util.Identifier +import net.minecraft.registry.RegistryWrapper import xyz.koiro.watersource.api.storage.getOrCreateFluidStorageData import xyz.koiro.watersource.api.storage.modifyFluidStorage -import xyz.koiro.watersource.identifier +import xyz.koiro.watersource.api.identifier +import xyz.koiro.watersource.api.toIdentifier import xyz.koiro.watersource.world.item.Strainer class StrainerFilteringFluidRecipe( val inFluid: Fluid, val outFluid: Fluid, - id: Identifier, strainer: Ingredient -) : StrainerFilteringRecipe(id, CraftingRecipeCategory.MISC, strainer) { + strainer: Ingredient +) : StrainerFilteringRecipe(CraftingRecipeCategory.MISC, strainer) { override fun matchInput(stack: ItemStack): Boolean { return stack.getOrCreateFluidStorageData()?.fluid == inFluid } @@ -30,7 +32,7 @@ class StrainerFilteringFluidRecipe( } ?: 0 } - override fun craft(inventory: RecipeInputInventory, registryManager: DynamicRegistryManager): ItemStack? { + override fun craft(inventory: RecipeInputInventory, lookup: RegistryWrapper.WrapperLookup?): ItemStack { getInputAndStrainer(inventory)?.let { ctx -> val input = ctx.input @@ -43,29 +45,46 @@ class StrainerFilteringFluidRecipe( return ItemStack.EMPTY } + override fun getSerializer(): RecipeSerializer<*> { return ModRecipes.STRAINER_FILTERING_FLUID_SERIALIZER } - class Serializer : RecipeSerializer { - 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) + class Serializer : StrainerFilteringRecipe.Serializer() { + val codec = RecordCodecBuilder.mapCodec { instance -> + val grouped = + instance.group( + Codec.STRING.fieldOf("fluidIn") + .forGetter { it.inFluid.identifier().toString() }, + Codec.STRING.fieldOf("fluidOut") + .forGetter { it.outFluid.identifier().toString() }, + Ingredient.DISALLOW_EMPTY_CODEC.fieldOf("strainer") + .forGetter { it.strainer } + ) + return@mapCodec grouped.apply(instance) { fluidInId, fluidOutId, strainer -> + StrainerFilteringFluidRecipe( + Registries.FLUID.get(fluidInId.toIdentifier()), + Registries.FLUID.get(fluidOutId.toIdentifier()), + strainer + ) + } + } + + override fun codec(): MapCodec { + return codec } - 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 read(buf: RegistryByteBuf): StrainerFilteringFluidRecipe { + val inId = buf.readString() + val outId = buf.readString() + val strainer = Ingredient.PACKET_CODEC.decode(buf) + return StrainerFilteringFluidRecipe(Registries.FLUID.get(inId.toIdentifier()), Registries.FLUID.get(outId.toIdentifier()), strainer) } - override fun write(buf: PacketByteBuf, recipe: StrainerFilteringFluidRecipe) { + override fun write(buf: RegistryByteBuf, recipe: StrainerFilteringFluidRecipe) { buf.writeString(recipe.inFluid.identifier().toString()) buf.writeString(recipe.outFluid.identifier().toString()) - recipe.strainer.write(buf) + Ingredient.PACKET_CODEC.encode(buf, recipe.strainer) } } } \ No newline at end of file diff --git a/src/main/kotlin/xyz/koiro/watersource/world/recipe/StrainerFilteringItemRecipe.kt b/src/main/kotlin/xyz/koiro/watersource/world/recipe/StrainerFilteringItemRecipe.kt index d7cc780..1b71b62 100644 --- a/src/main/kotlin/xyz/koiro/watersource/world/recipe/StrainerFilteringItemRecipe.kt +++ b/src/main/kotlin/xyz/koiro/watersource/world/recipe/StrainerFilteringItemRecipe.kt @@ -1,23 +1,22 @@ package xyz.koiro.watersource.world.recipe -import com.google.gson.JsonObject +import com.mojang.serialization.Codec +import com.mojang.serialization.MapCodec +import com.mojang.serialization.codecs.RecordCodecBuilder import net.minecraft.inventory.RecipeInputInventory import net.minecraft.item.ItemStack -import net.minecraft.network.PacketByteBuf +import net.minecraft.network.RegistryByteBuf import net.minecraft.recipe.Ingredient import net.minecraft.recipe.RecipeSerializer import net.minecraft.recipe.book.CraftingRecipeCategory -import net.minecraft.registry.DynamicRegistryManager -import net.minecraft.util.Identifier -import xyz.koiro.watersource.api.serialize.SerializeUtils +import net.minecraft.registry.RegistryWrapper class StrainerFilteringItemRecipe( val input: Ingredient, val output: ItemStack, val cost: Int, - id: Identifier, strainer: Ingredient -) : StrainerFilteringRecipe(id, CraftingRecipeCategory.MISC, strainer) { +) : StrainerFilteringRecipe(CraftingRecipeCategory.MISC, strainer) { override fun matchInput(stack: ItemStack): Boolean { return input.test(stack) } @@ -26,7 +25,7 @@ class StrainerFilteringItemRecipe( return cost } - override fun craft(inventory: RecipeInputInventory, registryManager: DynamicRegistryManager): ItemStack { + override fun craft(inventory: RecipeInputInventory?, lookup: RegistryWrapper.WrapperLookup?): ItemStack { return output.copy() } @@ -34,28 +33,46 @@ class StrainerFilteringItemRecipe( return ModRecipes.STRAINER_FILTERING_ITEM_SERIALIZER } - class Serializer : RecipeSerializer { - override fun read(id: Identifier, json: JsonObject): StrainerFilteringItemRecipe { - val input = Ingredient.fromJson(json.get("input")) - val output = SerializeUtils.jsonObjectToItemStack(json.getAsJsonObject("output")) - val cost = json.get("cost").asInt - val strainer = Ingredient.fromJson(json.get("strainer")) - return StrainerFilteringItemRecipe(input, output!!, cost, id, strainer) + class Serializer : StrainerFilteringRecipe.Serializer() { + val codec = RecordCodecBuilder.mapCodec { instance -> + val grouped = + instance.group( + Ingredient.DISALLOW_EMPTY_CODEC.fieldOf("input").forGetter { + it.input + }, + ItemStack.CODEC.fieldOf("output").forGetter { + it.output + }, + Codec.INT.fieldOf("cost").forGetter { + it.cost + }, + Ingredient.DISALLOW_EMPTY_CODEC.fieldOf("strainer") + .forGetter { it.strainer } + ) + return@mapCodec grouped.apply(instance) { input, output, cost, strainer -> + StrainerFilteringItemRecipe( + input, output, cost, strainer + ) + } } - override fun read(id: Identifier, buf: PacketByteBuf): StrainerFilteringItemRecipe { - val input = Ingredient.fromPacket(buf) - val output = buf.readItemStack() + override fun codec(): MapCodec { + return codec + } + + override fun read(buf: RegistryByteBuf): StrainerFilteringItemRecipe { + val input = Ingredient.PACKET_CODEC.decode(buf) + val output = ItemStack.PACKET_CODEC.decode(buf) val cost = buf.readInt() - val strainer = Ingredient.fromPacket(buf) - return StrainerFilteringItemRecipe(input, output, cost, id, strainer) + val strainer = Ingredient.PACKET_CODEC.decode(buf) + return StrainerFilteringItemRecipe(input, output, cost, strainer) } - override fun write(buf: PacketByteBuf, recipe: StrainerFilteringItemRecipe) { - recipe.input.write(buf) - buf.writeItemStack(recipe.output) + override fun write(buf: RegistryByteBuf, recipe: StrainerFilteringItemRecipe) { + Ingredient.PACKET_CODEC.encode(buf, recipe.input) + ItemStack.PACKET_CODEC.encode(buf, recipe.output) buf.writeInt(recipe.cost) - recipe.strainer.write(buf) + Ingredient.PACKET_CODEC.encode(buf, recipe.strainer) } } } \ No newline at end of file diff --git a/src/main/kotlin/xyz/koiro/watersource/world/recipe/StrainerFilteringRecipe.kt b/src/main/kotlin/xyz/koiro/watersource/world/recipe/StrainerFilteringRecipe.kt index 4da67c3..56364c6 100644 --- a/src/main/kotlin/xyz/koiro/watersource/world/recipe/StrainerFilteringRecipe.kt +++ b/src/main/kotlin/xyz/koiro/watersource/world/recipe/StrainerFilteringRecipe.kt @@ -2,20 +2,24 @@ package xyz.koiro.watersource.world.recipe import net.minecraft.inventory.RecipeInputInventory import net.minecraft.item.ItemStack +import net.minecraft.item.Items +import net.minecraft.network.RegistryByteBuf +import net.minecraft.network.codec.PacketCodec import net.minecraft.recipe.Ingredient +import net.minecraft.recipe.RecipeSerializer import net.minecraft.recipe.SpecialCraftingRecipe import net.minecraft.recipe.book.CraftingRecipeCategory -import net.minecraft.util.Identifier import net.minecraft.util.collection.DefaultedList import net.minecraft.world.World import xyz.koiro.watersource.WSConfig +import xyz.koiro.watersource.world.item.ModItems import xyz.koiro.watersource.world.item.Strainer abstract class StrainerFilteringRecipe( - id: Identifier, category: CraftingRecipeCategory, + category: CraftingRecipeCategory, val strainer: Ingredient ) : - SpecialCraftingRecipe(id, category) { + SpecialCraftingRecipe(category) { abstract fun matchInput(stack: ItemStack): Boolean abstract fun getCost(ctx: Ctx): Int @@ -51,7 +55,7 @@ abstract class StrainerFilteringRecipe( } override fun getRemainder(inventory: RecipeInputInventory): DefaultedList { - val defaultedList = DefaultedList.ofSize(inventory.size(), ItemStack.EMPTY) + val defaultedList = DefaultedList.ofSize(inventory.size(), ItemStack(Items.APPLE)) for (i in defaultedList.indices) { val item = inventory.getStack(i).item if (!item.hasRecipeRemainder()) continue @@ -69,4 +73,12 @@ abstract class StrainerFilteringRecipe( } data class Ctx(val strainer: ItemStack, val input: ItemStack, val strainerIndex: Int, val inputIndex: Int) + + abstract class Serializer: RecipeSerializer { + override fun packetCodec(): PacketCodec { + return PacketCodec.ofStatic(::write, ::read) + } + abstract fun read(buf: RegistryByteBuf): T + abstract fun write(buf: RegistryByteBuf, recipe: T) + } } \ No newline at end of file diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 3e2bba4..3755d75 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -43,8 +43,8 @@ ], "depends": { "fabricloader": ">=0.15.7", - "minecraft": "~1.20.1", - "java": ">=17", + "minecraft": "~1.20.6", + "java": ">=21", "fabric-api": "*", "fabric-language-kotlin": ">=1.9.22" }, diff --git a/src/main/resources/watersource.mixins.json b/src/main/resources/watersource.mixins.json index 706d039..761bbf2 100644 --- a/src/main/resources/watersource.mixins.json +++ b/src/main/resources/watersource.mixins.json @@ -1,7 +1,7 @@ { "required": true, "package": "xyz.koiro.watersource.mixin", - "compatibilityLevel": "JAVA_17", + "compatibilityLevel": "JAVA_21", "mixins": [ "ExampleMixin", "PlayerEntityMixin",