diff --git a/common/src/main/kotlin/juuxel/adorn/block/ChairBlock.kt b/common/src/main/kotlin/juuxel/adorn/block/ChairBlock.kt index 61c0e9f80..9844f66c4 100644 --- a/common/src/main/kotlin/juuxel/adorn/block/ChairBlock.kt +++ b/common/src/main/kotlin/juuxel/adorn/block/ChairBlock.kt @@ -150,6 +150,9 @@ class ChairBlock(variant: BlockVariant) : CarpetedBlock(variant.createSettings() override fun canPathfindThrough(state: BlockState, world: BlockView, pos: BlockPos, type: NavigationType) = false + override fun getSittingOffset(world: World, state: BlockState, pos: BlockPos): Double = + 0.625 // 10/16 + companion object { val FACING = Properties.HORIZONTAL_FACING val HALF = Properties.DOUBLE_BLOCK_HALF diff --git a/common/src/main/kotlin/juuxel/adorn/block/SeatBlock.kt b/common/src/main/kotlin/juuxel/adorn/block/SeatBlock.kt index 30d5b460c..f2e341df0 100644 --- a/common/src/main/kotlin/juuxel/adorn/block/SeatBlock.kt +++ b/common/src/main/kotlin/juuxel/adorn/block/SeatBlock.kt @@ -19,6 +19,7 @@ import net.minecraft.util.Identifier import net.minecraft.util.hit.BlockHitResult import net.minecraft.util.math.BlockPos import net.minecraft.util.math.Box +import net.minecraft.util.math.Direction import net.minecraft.world.World abstract class SeatBlock(settings: Settings) : Block(settings) { @@ -30,7 +31,6 @@ abstract class SeatBlock(settings: Settings) : Block(settings) { } } - open val sittingYOffset: Double = 0.0 abstract val sittingStat: Identifier? override fun onUse( @@ -51,7 +51,7 @@ abstract class SeatBlock(settings: Settings) : Block(settings) { return if (!occupied) { if (world is ServerWorld) { val entity = AdornEntities.SEAT.create(world) - entity?.setPos(actualPos, sittingYOffset) + entity?.setPos(actualPos) world.spawnEntity(entity) world.setBlockState(actualPos, actualState.with(OCCUPIED, true)) player.startRiding(entity, true) @@ -94,6 +94,10 @@ abstract class SeatBlock(settings: Settings) : Block(settings) { protected open fun isSittingEnabled() = true + open fun getSittingOffset(world: World, state: BlockState, pos: BlockPos): Double { + return state.getCollisionShape(world, pos).getMax(Direction.Axis.Y) + } + companion object { @JvmField val OCCUPIED: BooleanProperty = Properties.OCCUPIED } diff --git a/common/src/main/kotlin/juuxel/adorn/block/SofaBlock.kt b/common/src/main/kotlin/juuxel/adorn/block/SofaBlock.kt index f82594366..05b235a32 100644 --- a/common/src/main/kotlin/juuxel/adorn/block/SofaBlock.kt +++ b/common/src/main/kotlin/juuxel/adorn/block/SofaBlock.kt @@ -173,6 +173,9 @@ open class SofaBlock(variant: BlockVariant) : SeatBlock(variant.createSettings() override fun canPathfindThrough(state: BlockState, world: BlockView, pos: BlockPos, type: NavigationType) = false + override fun getSittingOffset(world: World, state: BlockState, pos: BlockPos): Double + = 0.4375 // 7/16 + companion object { val FACING = Properties.HORIZONTAL_FACING val CONNECTED_LEFT = BooleanProperty.of("connected_left") diff --git a/common/src/main/kotlin/juuxel/adorn/entity/SeatEntity.kt b/common/src/main/kotlin/juuxel/adorn/entity/SeatEntity.kt index a82449f45..9368597c4 100644 --- a/common/src/main/kotlin/juuxel/adorn/entity/SeatEntity.kt +++ b/common/src/main/kotlin/juuxel/adorn/entity/SeatEntity.kt @@ -5,7 +5,11 @@ import juuxel.adorn.platform.PlatformBridges import juuxel.adorn.util.getBlockPos import juuxel.adorn.util.putBlockPos import net.minecraft.entity.Entity +import net.minecraft.entity.EntityDimensions import net.minecraft.entity.EntityType +import net.minecraft.entity.data.DataTracker +import net.minecraft.entity.data.TrackedData +import net.minecraft.entity.data.TrackedDataHandlerRegistry import net.minecraft.entity.player.PlayerEntity import net.minecraft.nbt.NbtCompound import net.minecraft.network.packet.s2c.play.EntityPassengersSetS2CPacket @@ -13,6 +17,7 @@ import net.minecraft.util.ActionResult import net.minecraft.util.Hand import net.minecraft.util.math.BlockPos import net.minecraft.world.World +import org.joml.Vector3f class SeatEntity(type: EntityType<*>, world: World) : Entity(type, world) { init { @@ -21,12 +26,16 @@ class SeatEntity(type: EntityType<*>, world: World) : Entity(type, world) { } private var seatPos = BlockPos.ofFloored(this.pos) + set(value) { + field = value + dataTracker.set(SEAT_POS, value) + } - fun setPos(pos: BlockPos, blockOffset: Double) { + fun setPos(pos: BlockPos) { check(!world.isClient) { "setPos must be called on the logical server" } - updatePosition(pos.x + 0.5, pos.y + 0.25 + blockOffset, pos.z + 0.5) + updatePosition(pos.x + 0.5, pos.y + 0.5, pos.z + 0.5) seatPos = pos } @@ -55,7 +64,9 @@ class SeatEntity(type: EntityType<*>, world: World) : Entity(type, world) { override fun hasNoGravity() = true override fun isInvisible() = true - override fun initDataTracker() {} + override fun initDataTracker() { + dataTracker.startTracking(SEAT_POS, BlockPos.ORIGIN) + } override fun readCustomDataFromNbt(tag: NbtCompound) { seatPos = tag.getBlockPos("SeatPos") @@ -64,4 +75,25 @@ class SeatEntity(type: EntityType<*>, world: World) : Entity(type, world) { override fun writeCustomDataToNbt(tag: NbtCompound) { tag.putBlockPos("SeatPos", seatPos) } + + override fun getPassengerAttachmentPos(passenger: Entity, dimensions: EntityDimensions, scaleFactor: Float): Vector3f { + val seatPos = dataTracker.get(SEAT_POS) + val state = world.getBlockState(seatPos) + val block = state.block + + // Add the offset that comes from the block's shape + val blockOffset = if (block is SeatBlock) { + block.getSittingOffset(world, state, seatPos) + } else { + 0.0 + } + // Remove the inherent offset that comes from this entity not being directly where the block is + val posOffset = y - seatPos.y + + return Vector3f(0f, (blockOffset - posOffset).toFloat(), 0f) + } + + companion object { + private val SEAT_POS: TrackedData = DataTracker.registerData(SeatEntity::class.java, TrackedDataHandlerRegistry.BLOCK_POS) + } }