From f03c49fbcc587426880477914b923eac1a2718f0 Mon Sep 17 00:00:00 2001 From: Bixilon Date: Sun, 20 Jun 2021 23:14:23 +0200 Subject: [PATCH] wip: fluid pushing --- .../minosoft/data/player/LocalPlayerEntity.kt | 38 +++++++--------- .../registries/blocks/types/FluidBlock.kt | 10 ----- .../data/registries/fluid/FlowableFluid.kt | 43 +++++++++++++++++-- .../minosoft/data/registries/fluid/Fluid.kt | 5 +++ 4 files changed, 61 insertions(+), 35 deletions(-) diff --git a/src/main/java/de/bixilon/minosoft/data/player/LocalPlayerEntity.kt b/src/main/java/de/bixilon/minosoft/data/player/LocalPlayerEntity.kt index 0a9118a3a..5332e113e 100644 --- a/src/main/java/de/bixilon/minosoft/data/player/LocalPlayerEntity.kt +++ b/src/main/java/de/bixilon/minosoft/data/player/LocalPlayerEntity.kt @@ -39,7 +39,6 @@ import de.bixilon.minosoft.data.registries.items.Item import de.bixilon.minosoft.data.registries.other.containers.Container import de.bixilon.minosoft.data.registries.other.containers.PlayerInventory import de.bixilon.minosoft.data.tags.DefaultBlockTags -import de.bixilon.minosoft.data.tags.DefaultFluidTags import de.bixilon.minosoft.data.tags.Tag import de.bixilon.minosoft.gui.rendering.chunk.models.AABB import de.bixilon.minosoft.gui.rendering.input.camera.MovementInput @@ -308,7 +307,7 @@ class LocalPlayerEntity( var movement = Vec3d(delta) - // ToDo: Check for piston movement+ + // ToDo: Check for piston movement if (!movementMultiplier.empty) { movement = movement * movementMultiplier @@ -615,7 +614,7 @@ class LocalPlayerEntity( get() = (onGround && fallDistance < PhysicsConstants.STEP_HEIGHT) && !connection.world.isSpaceEmpty(aabb + Vec3(0.0f, fallDistance - PhysicsConstants.STEP_HEIGHT, 0.0f)) - private fun updateFluidState(fluidType: ResourceLocation): Boolean { + private fun updateFluidState(fluid: ResourceLocation): Boolean { val aabb = aabb.shrink() var height = 0.0f @@ -624,18 +623,15 @@ class LocalPlayerEntity( val velocity = Vec3d.EMPTY var checks = 0 - var velocityMultiplier = 1.0 - for ((blockPosition, blockState) in connection.world[aabb]) { if (blockState.block !is FluidBlock) { continue } - - if (!connection.inTag(blockState.block.fluid, TagsS2CP.FLUID_TAG_RESOURCE_LOCATION, fluidType)) { + if (blockState.block.fluid.resourceLocation != fluid) { continue } - val fluidHeight = blockPosition.y + blockState.block.getFluidHeight(blockState) + val fluidHeight = blockPosition.y + blockState.block.fluid.getHeight(blockState) if (fluidHeight < aabb.min.y) { continue @@ -654,47 +650,45 @@ class LocalPlayerEntity( if (fluid !is FlowableFluid) { continue } - velocityMultiplier = fluid.getVelocityMultiplier(connection, blockState, blockPosition) val fluidVelocity = fluid.getVelocity(connection, blockState, blockPosition) if (height < 0.4) { fluidVelocity *= height } - velocity += fluidVelocity + velocity += (fluidVelocity * fluid.getVelocityMultiplier(connection, blockState, blockPosition)) checks++ } if (velocity.length() > 0.0) { if (checks > 0) { - velocity *= 1.0 / checks + velocity /= checks } velocity *= velocityMultiplier - if (abs(velocity.x) < 0.004 && abs(velocity.z) < 0.003 && velocity.length() < 0.0045000000000000005) { - velocity assign velocity.normalize() * 0.0045000000000000005 + if (abs(this.velocity.x) < 0.003 && abs(this.velocity.z) < 0.003 && velocity.length() < 0.0045000000000000005) { + velocity assign (velocity.normalize() * 0.0045000000000000005) } - this.velocity assign (this.velocity + velocity) + val finalVelocity = this.velocity + velocity + this.velocity assign finalVelocity } - fluidHeights[fluidType] = height + fluidHeights[fluid] = height return inFluid } - private fun updateWaterState() { + private fun updateFluidStates() { fluidHeights.clear() if (vehicle is Boat) { return // ToDo } - if (updateFluidState(DefaultFluidTags.WATER_TAG)) { - // Log.log(LogMessageType.OTHER, LogLevels.VERBOSE){"In Water: Yes"} - return - // ToDo + connection.registries.fluidRegistry.forEachItem { + updateFluidState(it.resourceLocation) } - // Log.log(LogMessageType.OTHER, LogLevels.VERBOSE){"In Water: No"} + } override fun realTick() { @@ -704,7 +698,7 @@ class LocalPlayerEntity( } super.realTick() tickMovement() - updateWaterState() + updateFluidStates() sendMovementPackets() diff --git a/src/main/java/de/bixilon/minosoft/data/registries/blocks/types/FluidBlock.kt b/src/main/java/de/bixilon/minosoft/data/registries/blocks/types/FluidBlock.kt index ac79f9983..e82a05baf 100644 --- a/src/main/java/de/bixilon/minosoft/data/registries/blocks/types/FluidBlock.kt +++ b/src/main/java/de/bixilon/minosoft/data/registries/blocks/types/FluidBlock.kt @@ -16,13 +16,11 @@ package de.bixilon.minosoft.data.registries.blocks.types import com.google.gson.JsonObject import de.bixilon.minosoft.data.registries.ResourceLocation import de.bixilon.minosoft.data.registries.blocks.BlockState -import de.bixilon.minosoft.data.registries.blocks.properties.BlockProperties import de.bixilon.minosoft.data.registries.fluid.Fluid import de.bixilon.minosoft.data.registries.versions.Registries import de.bixilon.minosoft.gui.rendering.chunk.models.renderable.BlockLikeRenderer import de.bixilon.minosoft.gui.rendering.chunk.models.renderable.FluidRenderer import de.bixilon.minosoft.protocol.network.connection.PlayConnection -import de.bixilon.minosoft.util.KUtil.nullCast import glm_.vec3.Vec3i import kotlin.random.Random @@ -40,17 +38,9 @@ open class FluidBlock(resourceLocation: ResourceLocation, registries: Registries } } - fun getFluidHeight(blockState: BlockState): Float { - return (blockState.properties[BlockProperties.FLUID_LEVEL]?.nullCast() ?: 0) * FLUID_HEIGHT_CALCULATOR - } - override fun randomTick(connection: PlayConnection, blockState: BlockState, blockPosition: Vec3i, random: Random) { super.randomTick(connection, blockState, blockPosition, random) // ToDO fluid.randomTick(connection, blockState, blockPosition, random) } - - companion object { - private const val FLUID_HEIGHT_CALCULATOR = 1.0f / 16.0f - } } diff --git a/src/main/java/de/bixilon/minosoft/data/registries/fluid/FlowableFluid.kt b/src/main/java/de/bixilon/minosoft/data/registries/fluid/FlowableFluid.kt index 7fa1aaa6a..770782d7b 100644 --- a/src/main/java/de/bixilon/minosoft/data/registries/fluid/FlowableFluid.kt +++ b/src/main/java/de/bixilon/minosoft/data/registries/fluid/FlowableFluid.kt @@ -13,10 +13,13 @@ package de.bixilon.minosoft.data.registries.fluid import com.google.gson.JsonObject +import de.bixilon.minosoft.data.Directions import de.bixilon.minosoft.data.registries.ResourceLocation import de.bixilon.minosoft.data.registries.blocks.BlockState +import de.bixilon.minosoft.data.registries.blocks.types.FluidBlock import de.bixilon.minosoft.data.registries.versions.Registries import de.bixilon.minosoft.gui.rendering.util.VecUtil.EMPTY +import de.bixilon.minosoft.gui.rendering.util.VecUtil.plus import de.bixilon.minosoft.protocol.network.connection.PlayConnection import glm_.vec3.Vec3d import glm_.vec3.Vec3i @@ -31,8 +34,42 @@ abstract class FlowableFluid( abstract fun getVelocityMultiplier(connection: PlayConnection, blockState: BlockState, blockPosition: Vec3i): Double - fun getVelocity(connection: PlayConnection, blockState: BlockState, blockPosition: Vec3i): Vec3d { - // ToDo - return Vec3d.EMPTY + open fun getVelocity(connection: PlayConnection, blockState: BlockState, blockPosition: Vec3i): Vec3d { + if (blockState.block !is FluidBlock) { + return Vec3d.EMPTY + } + val thisFluidHeight = blockState.block.fluid.getHeight(blockState) + + val velocity = Vec3d.EMPTY + + + for (direction in Directions.SIDES) { + val neighbourBlockState = connection.world[blockPosition + direction] ?: continue + if (neighbourBlockState.block !is FluidBlock) { + continue + } + val fluid = neighbourBlockState.block.fluid + if (!matches(fluid)) { + continue + } + val height = neighbourBlockState.block.fluid.getHeight(neighbourBlockState) + + var magic = 0.0f + + if (height == 0.0f) { + // ToDo + } else { + magic = thisFluidHeight - height + } + + if (magic != 0.0f) { + velocity += (direction.vectord * magic) + } + + } + + // ToDo: Falling fluid + + return velocity.normalize() * -1.0 } } diff --git a/src/main/java/de/bixilon/minosoft/data/registries/fluid/Fluid.kt b/src/main/java/de/bixilon/minosoft/data/registries/fluid/Fluid.kt index a3eb3a893..654b5b28b 100644 --- a/src/main/java/de/bixilon/minosoft/data/registries/fluid/Fluid.kt +++ b/src/main/java/de/bixilon/minosoft/data/registries/fluid/Fluid.kt @@ -15,6 +15,7 @@ package de.bixilon.minosoft.data.registries.fluid import com.google.gson.JsonObject import de.bixilon.minosoft.data.registries.ResourceLocation import de.bixilon.minosoft.data.registries.blocks.BlockState +import de.bixilon.minosoft.data.registries.blocks.properties.BlockProperties import de.bixilon.minosoft.data.registries.blocks.types.FluidBlock import de.bixilon.minosoft.data.registries.fluid.lava.LavaFluid import de.bixilon.minosoft.data.registries.fluid.water.WaterFluid @@ -24,6 +25,7 @@ import de.bixilon.minosoft.data.registries.registry.RegistryItem import de.bixilon.minosoft.data.registries.registry.ResourceLocationDeserializer import de.bixilon.minosoft.data.registries.versions.Registries import de.bixilon.minosoft.protocol.network.connection.PlayConnection +import de.bixilon.minosoft.util.KUtil.unsafeCast import glm_.vec3.Vec3i import kotlin.random.Random @@ -59,6 +61,9 @@ open class Fluid( return matches(other.block.fluid) } + fun getHeight(blockState: BlockState): Float { + return (blockState.properties[BlockProperties.FLUID_LEVEL] ?: return 0.0f).unsafeCast() / 9.0f + } open fun randomTick(connection: PlayConnection, blockState: BlockState, blockPosition: Vec3i, random: Random) {}