@@ -12,7 +12,6 @@ import org.bukkit.World
1212import org.bukkit.block.Block
1313import org.bukkit.block.data.Bisected
1414import org.bukkit.block.data.BlockData
15- import org.bukkit.block.data.type.Slab
1615import org.bukkit.entity.Entity
1716import org.bukkit.entity.LivingEntity
1817import org.bukkit.entity.Mannequin
@@ -969,12 +968,9 @@ class NPCImpl(
969968 newPosition.y = currentLoc.y + 0.2
970969 } else if (groundY != null ) {
971970 // There's ground below - check if we should be on it or falling to it
971+ // groundY is already calculated from collision shapes, so it's accurate for all block types
972972 val distanceToGround = currentLoc.y - groundY
973973
974- // Check if the ground is a slab for smoother positioning
975- val groundBlock = world.getBlockAt(newPosition.blockX, (groundY - 1 ).toInt(), newPosition.blockZ)
976- val isGroundSlab = isSlab(groundBlock)
977-
978974 if (distanceToGround > 0.1 ) {
979975 // We're above ground - simulate gravity (fall down)
980976 // Gravity: 0.08 blocks per tick (1.6 blocks per second)
@@ -983,19 +979,16 @@ class NPCImpl(
983979 logDebug(" [NPC] moveTowards: Falling - distanceToGround=$distanceToGround , fallDistance=$fallDistance , newY=${newPosition.y} " )
984980 } else if (distanceToGround < - 0.1 ) {
985981 // We're below ground - place on ground
986- // For slabs, use the exact slab top Y for smoother walking
987- if (isGroundSlab) {
988- newPosition.y = groundY
989- } else {
990- newPosition.y = groundY
991- }
992- logDebug(" [NPC] moveTowards: Below ground, placed on ground at Y=$groundY (slab=$isGroundSlab )" )
982+ // groundY is already accurate from collision shapes (handles slabs, stairs, etc.)
983+ newPosition.y = groundY
984+ logDebug(" [NPC] moveTowards: Below ground, placed on ground at Y=$groundY " )
993985 } else {
994- // We're on ground - stay there or adjust to slab height if needed
995- if (isGroundSlab && Math .abs(currentLoc.y - groundY) > 0.1 ) {
996- // Adjust to slab height for smoother walking
986+ // We're on ground - stay there or adjust if needed
987+ if (Math .abs(currentLoc.y - groundY) > 0.1 ) {
988+ // Adjust to ground height for smoother walking
989+ // This works for all block types including slabs and stairs
997990 newPosition.y = groundY
998- logDebug(" [NPC] moveTowards: Adjusted to slab height Y=$groundY " )
991+ logDebug(" [NPC] moveTowards: Adjusted to ground height Y=$groundY " )
999992 } else {
1000993 // We're on ground - stay there
1001994 newPosition.y = currentLoc.y
@@ -1056,31 +1049,6 @@ class NPCImpl(
10561049 logDebug(" [NPC] moveTowards: Teleported to ${newPosition.blockX} ,${newPosition.blockY} ,${newPosition.blockZ} , yaw=$yaw , pitch=$pitch " )
10571050 }
10581051
1059- /* *
1060- * Checks if a block is a slab (half-height block).
1061- */
1062- private fun isSlab (block : Block ): Boolean {
1063- return block.blockData is Slab
1064- }
1065-
1066- /* *
1067- * Gets the top Y coordinate of a slab block.
1068- * @param block The slab block
1069- * @param blockY The Y coordinate of the block
1070- * @return The Y coordinate where the top of the slab is (0.5 for bottom, 1.0 for top, 0.5 for double)
1071- */
1072- private fun getSlabTopY (block : Block , blockY : Int ): Double {
1073- val blockData = block.blockData
1074- if (blockData is Slab ) {
1075- return when (blockData.type) {
1076- Slab .Type .BOTTOM -> blockY + 0.5
1077- Slab .Type .TOP -> blockY + 1.0
1078- Slab .Type .DOUBLE -> blockY + 1.0
1079- }
1080- }
1081- return blockY + 1.0
1082- }
1083-
10841052 /* *
10851053 * Checks if a block is passable (can be walked through) using the official Paper API.
10861054 * Uses Block.isPassable() which checks if the block has no colliding parts.
@@ -1120,24 +1088,19 @@ class NPCImpl(
11201088 return false
11211089 } catch (e: Exception ) {
11221090 // Fallback to material check if collision shape API is not available
1123- return type.isSolid || isSlab(block)
1091+ return type.isSolid
11241092 }
11251093 }
11261094
11271095 /* *
11281096 * Gets the top Y coordinate of a block based on its collision shape.
1129- * Uses the collision shape's bounding box for accurate height detection.
1130- * For slabs, this returns the actual top of the slab.
1131- * For full blocks, returns blockY + 1.0.
1097+ * Uses the collision shape's bounding boxes for accurate height detection.
1098+ * Works for all block types including slabs, stairs, and partial blocks.
11321099 * @see org.bukkit.block.Block#getCollisionShape()
1100+ * @see org.bukkit.util.VoxelShape#getBoundingBoxes()
11331101 */
11341102 private fun getBlockTopY (block : Block , blockY : Int ): Double {
1135- // Handle slabs specially for precise positioning
1136- if (isSlab(block)) {
1137- return getSlabTopY(block, blockY)
1138- }
1139-
1140- // For other blocks, use collision shape to determine top
1103+ // Use collision shape to determine top - works for all block types
11411104 try {
11421105 val collisionShape = block.collisionShape
11431106 if (collisionShape != null ) {
@@ -1146,6 +1109,7 @@ class NPCImpl(
11461109 val boundingBoxes = collisionShape.boundingBoxes
11471110 if (boundingBoxes.isNotEmpty()) {
11481111 // Find the maximum Y from all bounding boxes
1112+ // This automatically handles slabs, stairs, and other partial blocks
11491113 val maxY = boundingBoxes.maxOfOrNull { it.maxY } ? : 1.0
11501114 return blockY + maxY
11511115 }
@@ -1171,10 +1135,12 @@ class NPCImpl(
11711135 }
11721136
11731137 /* *
1174- * Finds the ground level (top solid block or slab) at the given X, Z coordinates.
1138+ * Finds the ground level at the given X, Z coordinates using collision shapes .
11751139 * Returns null if no solid ground is found within reasonable range.
11761140 * Only returns a ground level if there's sufficient air space above for the NPC to stand.
1177- * Uses collision shapes for accurate detection.
1141+ * Uses collision shapes and bounding boxes for accurate detection of all block types.
1142+ * @see org.bukkit.block.Block#getCollisionShape()
1143+ * @see org.bukkit.util.VoxelShape#getBoundingBoxes()
11781144 */
11791145 private fun findGroundLevel (world : World , x : Int , z : Int , startY : Int ): Double? {
11801146 // Search from startY + 2 down to startY - 10
0 commit comments