mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-17 19:35:00 -04:00
apply correct client velocity for other entities (like falling block, item)
This commit is contained in:
parent
26b21d3404
commit
b6e46a3913
@ -20,6 +20,7 @@ import de.bixilon.minosoft.data.entities.meta.EntityMetaData
|
||||
import de.bixilon.minosoft.data.inventory.InventorySlots.EquipmentSlots
|
||||
import de.bixilon.minosoft.data.inventory.ItemStack
|
||||
import de.bixilon.minosoft.data.physics.PhysicsEntity
|
||||
import de.bixilon.minosoft.data.player.LocalPlayerEntity
|
||||
import de.bixilon.minosoft.data.registries.ResourceLocation
|
||||
import de.bixilon.minosoft.data.registries.effects.StatusEffect
|
||||
import de.bixilon.minosoft.data.registries.effects.attributes.StatusEffectAttribute
|
||||
@ -34,8 +35,11 @@ import de.bixilon.minosoft.gui.rendering.input.camera.EntityPositionInfo
|
||||
import de.bixilon.minosoft.gui.rendering.particle.types.render.texture.advanced.block.BlockDustParticle
|
||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil
|
||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.EMPTY
|
||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.chunkPosition
|
||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.empty
|
||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.floor
|
||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.horizontal
|
||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.inChunkPosition
|
||||
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
|
||||
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
|
||||
import de.bixilon.minosoft.util.KUtil.synchronizedMapOf
|
||||
@ -77,6 +81,11 @@ abstract class Entity(
|
||||
|
||||
override var velocity: Vec3d = Vec3d.EMPTY
|
||||
var movementMultiplier = Vec3d.EMPTY // ToDo: Used in cobwebs, etc
|
||||
protected open var velocityMultiplier: Double = 1.0
|
||||
|
||||
protected var horizontalCollision = false
|
||||
protected var verticalCollision = false
|
||||
protected var fallDistance = 0.0
|
||||
|
||||
protected open val hasCollisions = true
|
||||
|
||||
@ -358,6 +367,102 @@ abstract class Entity(
|
||||
return entityType.toString()
|
||||
}
|
||||
|
||||
fun fall(deltaY: Double) {
|
||||
if (onGround) {
|
||||
// ToDo: On block landing (particles, sounds, etc)
|
||||
this.fallDistance = 0.0
|
||||
return
|
||||
}
|
||||
this.fallDistance = this.fallDistance - deltaY
|
||||
}
|
||||
|
||||
fun move(delta: Vec3d) {
|
||||
if (!hasCollisions) {
|
||||
forceMove(delta)
|
||||
return
|
||||
}
|
||||
|
||||
var movement = Vec3d(delta)
|
||||
|
||||
// ToDo: Check for piston movement
|
||||
|
||||
if (!movementMultiplier.empty) {
|
||||
movement = movement * movementMultiplier
|
||||
movementMultiplier = Vec3d.EMPTY
|
||||
velocity = Vec3d.EMPTY
|
||||
}
|
||||
|
||||
if (this is LocalPlayerEntity) {
|
||||
movement = connection.collisionDetector.sneak(this, movement)
|
||||
}
|
||||
|
||||
val collisionMovement = connection.collisionDetector.collide(null, movement, aabb, true)
|
||||
|
||||
|
||||
forceMove(collisionMovement)
|
||||
|
||||
|
||||
horizontalCollision = collisionMovement.x != movement.x || collisionMovement.z != movement.z
|
||||
verticalCollision = collisionMovement.y != movement.y
|
||||
this.onGround = verticalCollision && movement.y < 0.0f
|
||||
|
||||
|
||||
fall(collisionMovement.y)
|
||||
|
||||
var velocityChanged = false
|
||||
if (movement.y != collisionMovement.y) {
|
||||
if (movement.y < 0.0 && collisionMovement.y != 0.0) {
|
||||
val landingPosition = belowBlockPosition
|
||||
val landingBlockState = connection.world[belowBlockPosition]
|
||||
|
||||
val previousVelocity = Vec3d(velocity)
|
||||
landingBlockState?.block?.onEntityLand(connection, this, landingPosition, landingBlockState)
|
||||
|
||||
velocityChanged = velocity != previousVelocity
|
||||
}
|
||||
|
||||
if (!velocityChanged) {
|
||||
velocity.y = 0.0
|
||||
}
|
||||
}
|
||||
|
||||
if (!velocityChanged) {
|
||||
if (movement.x != collisionMovement.x) {
|
||||
velocity.x = 0.0
|
||||
}
|
||||
|
||||
if (movement.z != collisionMovement.z) {
|
||||
velocity.z = 0.0
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (onGround && canStep) {
|
||||
// ToDo: Play step sound
|
||||
}
|
||||
|
||||
// ToDo: Check for move effect
|
||||
|
||||
// block collision handling
|
||||
val aabb = aabb.shrink(0.001)
|
||||
for (blockPosition in aabb.blockPositions) {
|
||||
val chunk = connection.world[blockPosition.chunkPosition] ?: continue
|
||||
val blockState = chunk[blockPosition.inChunkPosition] ?: continue
|
||||
blockState.block.onEntityCollision(connection, this, blockState, blockPosition)
|
||||
}
|
||||
|
||||
val velocityMultiplier = velocityMultiplier
|
||||
velocity.x *= velocityMultiplier
|
||||
velocity.z *= velocityMultiplier
|
||||
}
|
||||
|
||||
protected fun applyGravity(force: Boolean = false) {
|
||||
if (hasGravity) {
|
||||
velocity.y += -0.04
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val BELOW_POSITION_MINUS = Vec3(0, 0.20000000298023224f, 0)
|
||||
}
|
||||
|
@ -38,6 +38,16 @@ class FallingBlock(connection: PlayConnection, entityType: EntityType, position:
|
||||
blockState = connection.registries.blockStateRegistry[data]
|
||||
}
|
||||
|
||||
override fun realTick() {
|
||||
super.realTick()
|
||||
|
||||
applyGravity()
|
||||
move(velocity)
|
||||
|
||||
|
||||
velocity = velocity * 0.98
|
||||
}
|
||||
|
||||
companion object : EntityFactory<FallingBlock> {
|
||||
override val RESOURCE_LOCATION: ResourceLocation = ResourceLocation("falling_block")
|
||||
|
||||
|
@ -20,8 +20,10 @@ import de.bixilon.minosoft.data.inventory.ItemStack
|
||||
import de.bixilon.minosoft.data.registries.ResourceLocation
|
||||
import de.bixilon.minosoft.data.registries.entities.EntityFactory
|
||||
import de.bixilon.minosoft.data.registries.entities.EntityType
|
||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.empty
|
||||
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
|
||||
import glm_.vec3.Vec3d
|
||||
import glm_.vec3.Vec3i
|
||||
|
||||
class ItemEntity(connection: PlayConnection, entityType: EntityType, position: Vec3d, rotation: EntityRotation) : Entity(connection, entityType, position, rotation) {
|
||||
|
||||
@ -30,6 +32,30 @@ class ItemEntity(connection: PlayConnection, entityType: EntityType, position: V
|
||||
get() = entityMetaData.sets.getItemStack(EntityMetaDataFields.ITEM_ITEM)
|
||||
|
||||
|
||||
override fun realTick() {
|
||||
super.realTick()
|
||||
|
||||
when {
|
||||
// ToDo: Apply water and lava "bouncing"
|
||||
hasGravity -> applyGravity()
|
||||
}
|
||||
|
||||
if (!onGround || !velocity.empty) {
|
||||
move(velocity)
|
||||
|
||||
var movement = 0.98
|
||||
if (onGround) {
|
||||
movement = (connection.world[Vec3i(positionInfo.blockPosition.x, position.y - 1.0, position.z)]?.block?.friction ?: 1.0) * 0.98
|
||||
}
|
||||
velocity = velocity * Vec3d(movement, 0.98, movement)
|
||||
|
||||
if (onGround && velocity.y < 0.0) {
|
||||
velocity.y *= -0.5
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
companion object : EntityFactory<ItemEntity> {
|
||||
override val RESOURCE_LOCATION: ResourceLocation = ResourceLocation("item")
|
||||
|
||||
|
@ -49,9 +49,7 @@ import de.bixilon.minosoft.gui.rendering.util.VecUtil.assign
|
||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.blockPosition
|
||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.chunkPosition
|
||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.clearZero
|
||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.empty
|
||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.get
|
||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.inChunkPosition
|
||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.plus
|
||||
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
|
||||
import de.bixilon.minosoft.protocol.packets.c2s.play.*
|
||||
@ -114,13 +112,8 @@ class LocalPlayerEntity(
|
||||
private val walkingSpeed: Double
|
||||
get() = getAttributeValue(DefaultStatusEffectAttributeNames.GENERIC_MOVEMENT_SPEED, baseAbilities.walkingSpeed)
|
||||
|
||||
private var horizontalCollision = false
|
||||
private var verticalCollision = false
|
||||
|
||||
var dirtyVelocity = false
|
||||
var jumpingCoolDown = 0
|
||||
var isJumping = false
|
||||
var fallDistance = 0.0
|
||||
|
||||
private var lastFovMultiplier = 1.0
|
||||
private var currentFovMultiplier = 1.0
|
||||
@ -174,7 +167,8 @@ class LocalPlayerEntity(
|
||||
return DefaultBlockTags.CLIMBABLE.contains(blockState.block.resourceLocation)
|
||||
}
|
||||
|
||||
private val velocityMultiplier: Double
|
||||
override var velocityMultiplier: Double
|
||||
set(value) {}
|
||||
get() {
|
||||
if (isFlyingWithElytra || baseAbilities.isFlying) {
|
||||
return 1.0
|
||||
@ -194,7 +188,6 @@ class LocalPlayerEntity(
|
||||
}
|
||||
}
|
||||
return blockStateBelow.block.velocityMultiplier
|
||||
|
||||
}
|
||||
|
||||
private val jumpVelocityMultiplier: Double
|
||||
@ -292,94 +285,6 @@ class LocalPlayerEntity(
|
||||
return Vec3d(velocity.x * cos - velocity.z * sin, velocity.y, velocity.z * cos + velocity.x * sin)
|
||||
}
|
||||
|
||||
fun fall(deltaY: Double) {
|
||||
if (onGround) {
|
||||
// ToDo: On block landing (particles, sounds, etc)
|
||||
this.fallDistance = 0.0
|
||||
return
|
||||
}
|
||||
this.fallDistance = this.fallDistance - deltaY
|
||||
}
|
||||
|
||||
|
||||
fun move(delta: Vec3d) {
|
||||
if (!hasCollisions) {
|
||||
forceMove(delta)
|
||||
return
|
||||
}
|
||||
|
||||
var movement = Vec3d(delta)
|
||||
|
||||
// ToDo: Check for piston movement
|
||||
|
||||
if (!movementMultiplier.empty) {
|
||||
movement = movement * movementMultiplier
|
||||
movementMultiplier = Vec3d.EMPTY
|
||||
velocity = Vec3d.EMPTY
|
||||
}
|
||||
|
||||
movement = connection.collisionDetector.sneak(this, movement)
|
||||
|
||||
val collisionMovement = connection.collisionDetector.collide(null, movement, aabb, true)
|
||||
|
||||
|
||||
forceMove(collisionMovement)
|
||||
|
||||
|
||||
horizontalCollision = collisionMovement.x != movement.x || collisionMovement.z != movement.z
|
||||
verticalCollision = collisionMovement.y != movement.y
|
||||
this.onGround = verticalCollision && movement.y < 0.0f
|
||||
|
||||
|
||||
fall(collisionMovement.y)
|
||||
|
||||
var velocityChanged = false
|
||||
if (movement.y != collisionMovement.y) {
|
||||
if (movement.y < 0.0 && collisionMovement.y != 0.0) {
|
||||
val landingPosition = belowBlockPosition
|
||||
val landingBlockState = connection.world[belowBlockPosition]
|
||||
|
||||
val previousVelocity = Vec3d(velocity)
|
||||
landingBlockState?.block?.onEntityLand(connection, this, landingPosition, landingBlockState)
|
||||
|
||||
velocityChanged = velocity != previousVelocity
|
||||
}
|
||||
|
||||
if (!velocityChanged) {
|
||||
velocity.y = 0.0
|
||||
}
|
||||
}
|
||||
|
||||
if (!velocityChanged) {
|
||||
if (movement.x != collisionMovement.x) {
|
||||
velocity.x = 0.0
|
||||
}
|
||||
|
||||
if (movement.z != collisionMovement.z) {
|
||||
velocity.z = 0.0
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (onGround && canStep) {
|
||||
// ToDo: Play step sound
|
||||
}
|
||||
|
||||
// ToDo: Check for move effect
|
||||
|
||||
// block collision handling
|
||||
val aabb = aabb.shrink(0.001)
|
||||
for (blockPosition in aabb.blockPositions) {
|
||||
val chunk = connection.world[blockPosition.chunkPosition] ?: continue
|
||||
val blockState = chunk[blockPosition.inChunkPosition] ?: continue
|
||||
blockState.block.onEntityCollision(connection, this, blockState, blockPosition)
|
||||
}
|
||||
|
||||
val velocityMultiplier = velocityMultiplier
|
||||
velocity.x *= velocityMultiplier
|
||||
velocity.z *= velocityMultiplier
|
||||
}
|
||||
|
||||
private fun applyClimbingSpeed(velocity: Vec3d): Vec3d {
|
||||
if (!isClimbing) {
|
||||
@ -574,7 +479,6 @@ class LocalPlayerEntity(
|
||||
val yawRad = rotation.headYaw.rad
|
||||
this.velocity = this.velocity + Vec3(-(yawRad.sin * 0.2f), 0.0f, yawRad.cos * 0.2f)
|
||||
}
|
||||
dirtyVelocity = true
|
||||
}
|
||||
|
||||
private fun pushOutOfBlocks(x: Double, z: Double) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user