From af1ce9bfdd1b578655f146080ada0dd582a370b4 Mon Sep 17 00:00:00 2001 From: semleks Date: Wed, 8 Jul 2026 14:33:59 +0300 Subject: [PATCH] fix(physics): allow climbing through open trapdoors above ladders The bot can now climb up through a trapdoor/hatch if it is open and aligned with the ladder underneath (same facing property). --- botcraft/src/Game/Physics/PhysicsManager.cpp | 31 ++++++++++++++++---- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/botcraft/src/Game/Physics/PhysicsManager.cpp b/botcraft/src/Game/Physics/PhysicsManager.cpp index fe88fab4c..8057809b7 100644 --- a/botcraft/src/Game/Physics/PhysicsManager.cpp +++ b/botcraft/src/Game/Physics/PhysicsManager.cpp @@ -1171,9 +1171,30 @@ namespace Botcraft static_cast(std::floor(player->position.z)) )); - // TODO: if trapdoor AND below block is a ladder with the same facing property - // as the trapdoor then the trapdoor is a climbable block too - return feet_block != nullptr && feet_block->IsClimbable(); + if (feet_block != nullptr && feet_block->IsClimbable()) + return true; + + if (feet_block != nullptr && feet_block->GetName().find("trapdoor") != std::string::npos) + { + if (feet_block->GetVariableValue("open") == "true") + { + const Blockstate* below_block = world->GetBlock(Position( + static_cast(std::floor(player->position.x)), + static_cast(std::floor(player->position.y)) - 1, + static_cast(std::floor(player->position.z)) + )); + + if (below_block != nullptr && below_block != nullptr && below_block->GetName().find("ladder") != std::string::npos) + { + if (feet_block->GetVariableValue("facing") == below_block->GetVariableValue("facing")) + { + return true; + } + } + } + } + + return false; } void PhysicsManager::MovePlayer() const @@ -1280,8 +1301,8 @@ namespace Botcraft // Move with elytra else if (player->GetDataSharedFlagsIdImpl(EntitySharedFlagsId::FallFlying)) { - // sqrt(front_vector.x² + front_vector.z²) to follow vanilla code - // it's equal to cos(pitch) (as -90°<=pitch<=90°, cos(pitch) >= 0.0) + // sqrt(front_vector.x� + front_vector.z�) to follow vanilla code + // it's equal to cos(pitch) (as -90�<=pitch<=90�, cos(pitch) >= 0.0) const double cos_pitch_from_length = std::sqrt(player->front_vector.x * player->front_vector.x + player->front_vector.z * player->front_vector.z); const double cos_pitch = std::cos(static_cast(player->pitch * 0.017453292f /* PI/180 */)); const double cos_pitch_sqr = cos_pitch * cos_pitch;