mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-11 16:36:58 -04:00
block pushing
This commit is contained in:
parent
f7e4212878
commit
1ca20c243b
@ -25,6 +25,34 @@ enum class Axes {
|
|||||||
Z,
|
Z,
|
||||||
;
|
;
|
||||||
|
|
||||||
|
fun choose(vec3: Vec3): Float {
|
||||||
|
return choose(vec3.x, vec3.y, vec3.z)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun choose(vec3: Vec3d): Double {
|
||||||
|
return choose(vec3.x, vec3.y, vec3.z)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun choose(vec3i: Vec3i): Int {
|
||||||
|
return choose(Vec3(vec3i)).toInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun choose(x: Float, y: Float, z: Float): Float {
|
||||||
|
return when (this) {
|
||||||
|
X -> x
|
||||||
|
Y -> y
|
||||||
|
Z -> z
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun choose(x: Double, y: Double, z: Double): Double {
|
||||||
|
return when (this) {
|
||||||
|
X -> x
|
||||||
|
Y -> y
|
||||||
|
Z -> z
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
companion object : ValuesEnum<Axes>, BlockPropertiesSerializer {
|
companion object : ValuesEnum<Axes>, BlockPropertiesSerializer {
|
||||||
override val VALUES: Array<Axes> = values()
|
override val VALUES: Array<Axes> = values()
|
||||||
override val NAME_MAP: Map<String, Axes> = KUtil.getEnumValues(VALUES)
|
override val NAME_MAP: Map<String, Axes> = KUtil.getEnumValues(VALUES)
|
||||||
@ -37,34 +65,6 @@ enum class Axes {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun choose(axis: Axes, vec3: Vec3): Float {
|
|
||||||
return choose(axis, vec3.x, vec3.y, vec3.z)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun choose(axis: Axes, vec3: Vec3d): Double {
|
|
||||||
return choose(axis, vec3.x, vec3.y, vec3.z)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun choose(axis: Axes, vec3i: Vec3i): Int {
|
|
||||||
return choose(axis, Vec3(vec3i)).toInt()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun choose(axis: Axes, x: Float, y: Float, z: Float): Float {
|
|
||||||
return when (axis) {
|
|
||||||
X -> x
|
|
||||||
Y -> y
|
|
||||||
Z -> z
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun choose(axis: Axes, x: Double, y: Double, z: Double): Double {
|
|
||||||
return when (axis) {
|
|
||||||
X -> x
|
|
||||||
Y -> y
|
|
||||||
Z -> z
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun deserialize(value: Any): Axes {
|
override fun deserialize(value: Any): Axes {
|
||||||
return NAME_MAP[value] ?: throw IllegalArgumentException("No such property: $value")
|
return NAME_MAP[value] ?: throw IllegalArgumentException("No such property: $value")
|
||||||
}
|
}
|
||||||
|
@ -110,6 +110,7 @@ enum class Directions(val horizontalId: Int, val vector: Vec3i) {
|
|||||||
override val VALUES = values()
|
override val VALUES = values()
|
||||||
override val NAME_MAP: Map<String, Directions> = KUtil.getEnumValues(VALUES)
|
override val NAME_MAP: Map<String, Directions> = KUtil.getEnumValues(VALUES)
|
||||||
val SIDES = arrayOf(NORTH, SOUTH, WEST, EAST)
|
val SIDES = arrayOf(NORTH, SOUTH, WEST, EAST)
|
||||||
|
val PRIORITY_SIDES = arrayOf(WEST, EAST, NORTH, SOUTH)
|
||||||
private val HORIZONTAL = arrayOf(SOUTH, WEST, NORTH, EAST)
|
private val HORIZONTAL = arrayOf(SOUTH, WEST, NORTH, EAST)
|
||||||
|
|
||||||
override fun deserialize(value: Any): Directions {
|
override fun deserialize(value: Any): Directions {
|
||||||
|
@ -26,6 +26,7 @@ import de.bixilon.minosoft.protocol.network.connection.PlayConnection
|
|||||||
import glm_.vec3.Vec3
|
import glm_.vec3.Vec3
|
||||||
import glm_.vec3.Vec3bool
|
import glm_.vec3.Vec3bool
|
||||||
import glm_.vec3.Vec3d
|
import glm_.vec3.Vec3d
|
||||||
|
import glm_.vec3.Vec3i
|
||||||
import kotlin.math.abs
|
import kotlin.math.abs
|
||||||
|
|
||||||
class CollisionDetector(val connection: PlayConnection) {
|
class CollisionDetector(val connection: PlayConnection) {
|
||||||
@ -36,7 +37,8 @@ class CollisionDetector(val connection: PlayConnection) {
|
|||||||
|
|
||||||
// check if already in block
|
// check if already in block
|
||||||
if (!connection.world.isSpaceEmpty(aabb)) {
|
if (!connection.world.isSpaceEmpty(aabb)) {
|
||||||
blockPositions.remove(aabb.min.floor)
|
val center = aabb.center.floor
|
||||||
|
blockPositions.remove(Vec3i(center.x, aabb.min.y, center.z))
|
||||||
}
|
}
|
||||||
|
|
||||||
val result = VoxelShape()
|
val result = VoxelShape()
|
||||||
@ -54,7 +56,7 @@ class CollisionDetector(val connection: PlayConnection) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun sneak(entity: LocalPlayerEntity, deltaPosition: Vec3d): Vec3d {
|
fun sneak(entity: LocalPlayerEntity, deltaPosition: Vec3d): Vec3d {
|
||||||
if (entity.baseAbilities.isFlying || !entity.isSneaking || !entity.canSneak()) {
|
if (entity.baseAbilities.isFlying || !entity.isSneaking || !entity.canSneak) {
|
||||||
return deltaPosition
|
return deltaPosition
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,6 +13,8 @@
|
|||||||
package de.bixilon.minosoft.data.player
|
package de.bixilon.minosoft.data.player
|
||||||
|
|
||||||
import de.bixilon.minosoft.Minosoft
|
import de.bixilon.minosoft.Minosoft
|
||||||
|
import de.bixilon.minosoft.data.Axes
|
||||||
|
import de.bixilon.minosoft.data.Directions
|
||||||
import de.bixilon.minosoft.data.abilities.Gamemodes
|
import de.bixilon.minosoft.data.abilities.Gamemodes
|
||||||
import de.bixilon.minosoft.data.abilities.ItemCooldown
|
import de.bixilon.minosoft.data.abilities.ItemCooldown
|
||||||
import de.bixilon.minosoft.data.accounts.Account
|
import de.bixilon.minosoft.data.accounts.Account
|
||||||
@ -34,12 +36,15 @@ import de.bixilon.minosoft.data.registries.other.containers.Container
|
|||||||
import de.bixilon.minosoft.data.registries.other.containers.PlayerInventory
|
import de.bixilon.minosoft.data.registries.other.containers.PlayerInventory
|
||||||
import de.bixilon.minosoft.data.tags.DefaultBlockTags
|
import de.bixilon.minosoft.data.tags.DefaultBlockTags
|
||||||
import de.bixilon.minosoft.data.tags.Tag
|
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
|
import de.bixilon.minosoft.gui.rendering.input.camera.MovementInput
|
||||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil
|
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.EMPTY
|
||||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.chunkPosition
|
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.clearZero
|
||||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.empty
|
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.plus
|
||||||
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
|
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
|
||||||
import de.bixilon.minosoft.protocol.packets.c2s.play.*
|
import de.bixilon.minosoft.protocol.packets.c2s.play.*
|
||||||
import de.bixilon.minosoft.protocol.packets.s2c.play.TagsS2CP
|
import de.bixilon.minosoft.protocol.packets.s2c.play.TagsS2CP
|
||||||
@ -52,6 +57,7 @@ import de.bixilon.minosoft.util.MMath
|
|||||||
import glm_.func.cos
|
import glm_.func.cos
|
||||||
import glm_.func.rad
|
import glm_.func.rad
|
||||||
import glm_.func.sin
|
import glm_.func.sin
|
||||||
|
import glm_.vec2.Vec2
|
||||||
import glm_.vec3.Vec3
|
import glm_.vec3.Vec3
|
||||||
import glm_.vec3.Vec3d
|
import glm_.vec3.Vec3d
|
||||||
import glm_.vec3.Vec3i
|
import glm_.vec3.Vec3i
|
||||||
@ -460,7 +466,13 @@ class LocalPlayerEntity(
|
|||||||
movementSideways *= 0.2f
|
movementSideways *= 0.2f
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToDo: Push out of blocks
|
if (gamemode != Gamemodes.SPECTATOR) {
|
||||||
|
// ToDo: Push out of blocks
|
||||||
|
// pushOutOfBlocks(position.x - dimensions.x * 0.35, position.z + dimensions.x * 0.35)
|
||||||
|
// pushOutOfBlocks(position.x - dimensions.x * 0.35, position.z - dimensions.x * 0.35)
|
||||||
|
// pushOutOfBlocks(position.x + dimensions.x * 0.35, position.z - dimensions.x * 0.35)
|
||||||
|
// pushOutOfBlocks(position.x + dimensions.x * 0.35, position.z + dimensions.x * 0.35)
|
||||||
|
}
|
||||||
|
|
||||||
// ToDo
|
// ToDo
|
||||||
|
|
||||||
@ -544,10 +556,45 @@ class LocalPlayerEntity(
|
|||||||
dirtyVelocity = true
|
dirtyVelocity = true
|
||||||
}
|
}
|
||||||
|
|
||||||
fun canSneak(): Boolean {
|
private fun pushOutOfBlocks(x: Double, z: Double) {
|
||||||
return (onGround && fallDistance < PhysicsConstants.STEP_HEIGHT) && !connection.world.isSpaceEmpty(aabb + Vec3(0.0f, fallDistance - PhysicsConstants.STEP_HEIGHT, 0.0f))
|
val blockPosition = Vec3i(x, position.y, z)
|
||||||
|
if (!collidesAt(blockPosition)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val decimal = Vec2(x - blockPosition.x, z - blockPosition.z)
|
||||||
|
|
||||||
|
var pushDirection: Directions? = null
|
||||||
|
var minimumDistance = Float.MAX_VALUE
|
||||||
|
|
||||||
|
for (direction in Directions.PRIORITY_SIDES) {
|
||||||
|
val nearestAxisValue = direction.axis.choose(Vec3(decimal.x, 0.0, decimal.y))
|
||||||
|
val movement = (direction.vector[direction.axis] > 0.0).decide(1.0f - nearestAxisValue, nearestAxisValue)
|
||||||
|
if (movement < minimumDistance && !collidesAt(blockPosition + direction)) {
|
||||||
|
minimumDistance = movement
|
||||||
|
pushDirection = direction
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pushDirection ?: return
|
||||||
|
|
||||||
|
if (pushDirection.axis == Axes.X) {
|
||||||
|
velocity.x = 0.1 * pushDirection.vectord.x
|
||||||
|
} else {
|
||||||
|
velocity.z = 0.1 * pushDirection.vectord.z
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun collidesAt(position: Vec3i): Boolean {
|
||||||
|
val aabb = aabb
|
||||||
|
val nextAABB = AABB(Vec3(position.x, aabb.min.y, position.z), Vec3(position.x + 1.0, aabb.max.y, position.z + 1.0)).shrink(1.0E-7)
|
||||||
|
|
||||||
|
return !connection.world.isSpaceEmpty(nextAABB)
|
||||||
|
}
|
||||||
|
|
||||||
|
val canSneak: Boolean
|
||||||
|
get() = (onGround && fallDistance < PhysicsConstants.STEP_HEIGHT) && !connection.world.isSpaceEmpty(aabb + Vec3(0.0f, fallDistance - PhysicsConstants.STEP_HEIGHT, 0.0f))
|
||||||
|
|
||||||
override fun realTick() {
|
override fun realTick() {
|
||||||
if (connection.world[positionInfo.blockPosition.chunkPosition] == null) {
|
if (connection.world[positionInfo.blockPosition.chunkPosition] == null) {
|
||||||
// chunk not loaded, so we don't tick?
|
// chunk not loaded, so we don't tick?
|
||||||
|
@ -69,11 +69,11 @@ class AABB(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun min(axis: Axes): Double {
|
private fun min(axis: Axes): Double {
|
||||||
return Axes.choose(axis, min)
|
return axis.choose(min)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun max(axis: Axes): Double {
|
private fun max(axis: Axes): Double {
|
||||||
return Axes.choose(axis, max)
|
return axis.choose(max)
|
||||||
}
|
}
|
||||||
|
|
||||||
infix fun extend(vec3: Vec3d): AABB {
|
infix fun extend(vec3: Vec3d): AABB {
|
||||||
|
@ -58,7 +58,7 @@ class ElementRenderer(
|
|||||||
if (uvLock) {
|
if (uvLock) {
|
||||||
for (direction in Directions.VALUES) {
|
for (direction in Directions.VALUES) {
|
||||||
val axis = Axes.byDirection(direction)
|
val axis = Axes.byDirection(direction)
|
||||||
val angle = Axes.choose(axis, rotation) * Axes.choose(axis, direction.vector)
|
val angle = axis.choose(rotation) * axis.choose(direction.vector)
|
||||||
faces[direction]?.rotate(-angle)
|
faces[direction]?.rotate(-angle)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user