From 9125d3f06d6e5549971964db0b4ff81e724ae7b8 Mon Sep 17 00:00:00 2001 From: disintegrate Date: Wed, 18 Mar 2026 10:45:02 +0800 Subject: [PATCH 1/3] Climbable trapdoors if connected to a ladder. ### Previous Behavior Trapdoors still has collision even if opened, making it difficult to climb with. ### New Behavior - Added a new condition in `LivingEntity::onLadder()` in case it's a trapdoor, then return as true (as if its a ladder). - If there's a ladder under the (opened) trapdoor, then its collision box returns as a nullptr. **Files:** - `LivingEntity.cpp` - `TrapDoorTile.cpp` **Methods:** - `LivingEntity::onLadder()` - `TrapDoorTile::getAABB(Level *level, int x, int y, int z)` --- Minecraft.World/LivingEntity.cpp | 25 +++++++++++++++++++++++-- Minecraft.World/TrapDoorTile.cpp | 12 ++++++++++++ 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/Minecraft.World/LivingEntity.cpp b/Minecraft.World/LivingEntity.cpp index 3af9efe962..192823f1f6 100644 --- a/Minecraft.World/LivingEntity.cpp +++ b/Minecraft.World/LivingEntity.cpp @@ -986,9 +986,30 @@ bool LivingEntity::onLadder() int yt = Mth::floor(bb->y0); int zt = Mth::floor(z); - // 4J-PB - TU9 - add climbable vines int iTile = level->getTile(xt, yt, zt); - return (iTile== Tile::ladder_Id) || (iTile== Tile::vine_Id); + switch (iTile) + { + case Tile::ladder_Id: + case Tile::vine_Id: // 4J-PB - TU9 - add climbable vines + return true; + case Tile::trapdoor_Id: // hexagonny - add climbable (opened) trapdoors + { + int data = level->getData(xt, yt, zt); + bool isOpen = (data & 0x4) != 0; + if (isOpen) + { + int belowTile = level->getTile(xt, yt - 1, zt); + if (belowTile == Tile::ladder_Id) + { + return true; + } + } + break; + } + default: + break; + } + return false; } bool LivingEntity::isShootable() diff --git a/Minecraft.World/TrapDoorTile.cpp b/Minecraft.World/TrapDoorTile.cpp index 6ea64172ee..af00275fe6 100644 --- a/Minecraft.World/TrapDoorTile.cpp +++ b/Minecraft.World/TrapDoorTile.cpp @@ -50,6 +50,18 @@ AABB *TrapDoorTile::getTileAABB(Level *level, int x, int y, int z) AABB *TrapDoorTile::getAABB(Level *level, int x, int y, int z) { + int data = level->getData(x, y, z); + bool isOpen = (data & 0x4) != 0; + + if (isOpen) + { + int belowTile = level->getTile(x, y - 1, z); + if (belowTile == Tile::ladder_Id) + { + return nullptr; // No collision when open above ladder + } + } + // Default behaviour updateShape(level, x, y, z); return Tile::getAABB(level, x, y, z); } From 9983a74198725ab4d6b4c4f4863958ddf3927286 Mon Sep 17 00:00:00 2001 From: disintegrate Date: Wed, 18 Mar 2026 11:45:44 +0800 Subject: [PATCH 2/3] Added a check above the trapdoor. Made so that it avoids alternating use of ladders (or vines) and trapdoors. --- Minecraft.World/LivingEntity.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Minecraft.World/LivingEntity.cpp b/Minecraft.World/LivingEntity.cpp index 192823f1f6..2a5982b8a4 100644 --- a/Minecraft.World/LivingEntity.cpp +++ b/Minecraft.World/LivingEntity.cpp @@ -998,10 +998,15 @@ bool LivingEntity::onLadder() bool isOpen = (data & 0x4) != 0; if (isOpen) { + int aboveTile = level->getTile(xt, yt + 1, zt); int belowTile = level->getTile(xt, yt - 1, zt); - if (belowTile == Tile::ladder_Id) + switch (aboveTile) { - return true; + case Tile::ladder_Id: + case Tile::vine_Id: + return false; // Opened trapdoor should only be climbable when it's only at the top. + default: + return belowTile == Tile::ladder_Id; } } break; From ab9a7ae8319e8d6133a555b5c6010e10919b36cb Mon Sep 17 00:00:00 2001 From: disintegrate Date: Wed, 18 Mar 2026 17:00:50 +0800 Subject: [PATCH 3/3] Added a check if trapdoor is attached. Just incase if neighborChanged is modified. --- Minecraft.World/LivingEntity.cpp | 10 +++------- Minecraft.World/TrapDoorTile.cpp | 15 +++++++++------ 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/Minecraft.World/LivingEntity.cpp b/Minecraft.World/LivingEntity.cpp index 2a5982b8a4..7876e88c40 100644 --- a/Minecraft.World/LivingEntity.cpp +++ b/Minecraft.World/LivingEntity.cpp @@ -994,19 +994,15 @@ bool LivingEntity::onLadder() return true; case Tile::trapdoor_Id: // hexagonny - add climbable (opened) trapdoors { - int data = level->getData(xt, yt, zt); - bool isOpen = (data & 0x4) != 0; - if (isOpen) + if ((level->getData(xt, yt, zt) & 0x4) != 0) { - int aboveTile = level->getTile(xt, yt + 1, zt); - int belowTile = level->getTile(xt, yt - 1, zt); - switch (aboveTile) + switch (level->getTile(xt, yt + 1, zt)) { case Tile::ladder_Id: case Tile::vine_Id: return false; // Opened trapdoor should only be climbable when it's only at the top. default: - return belowTile == Tile::ladder_Id; + return level->getTile(xt, yt - 1, zt) == Tile::ladder_Id; } } break; diff --git a/Minecraft.World/TrapDoorTile.cpp b/Minecraft.World/TrapDoorTile.cpp index af00275fe6..173435b84c 100644 --- a/Minecraft.World/TrapDoorTile.cpp +++ b/Minecraft.World/TrapDoorTile.cpp @@ -51,14 +51,17 @@ AABB *TrapDoorTile::getTileAABB(Level *level, int x, int y, int z) AABB *TrapDoorTile::getAABB(Level *level, int x, int y, int z) { int data = level->getData(x, y, z); - bool isOpen = (data & 0x4) != 0; - - if (isOpen) + if (isOpen(data)) { - int belowTile = level->getTile(x, y - 1, z); - if (belowTile == Tile::ladder_Id) + int xt = x, zt = z; + if ((data & 3) == 0) zt++; + if ((data & 3) == 1) zt--; + if ((data & 3) == 2) xt++; + if ((data & 3) == 3) xt--; + + if (level->getTile(x, y - 1, z) == Tile::ladder_Id && attachesTo(level->getTile(xt, y, zt))) { - return nullptr; // No collision when open above ladder + return nullptr; // No collision when open above ladder (add is attached to a block) } } // Default behaviour