diff --git a/src/content/loading/BlockLoader.cpp b/src/content/loading/BlockLoader.cpp index 56903db79..d6bcad92b 100644 --- a/src/content/loading/BlockLoader.cpp +++ b/src/content/loading/BlockLoader.cpp @@ -151,6 +151,8 @@ template<> void ContentUnitLoader::loadUnit( def.rotations = BlockRotProfile::PANE; } else if (profile == BlockRotProfile::STAIRS_NAME) { def.rotations = BlockRotProfile::STAIRS; + } else if (profile == BlockRotProfile::LADDER_NAME) { + def.rotations = BlockRotProfile::LADDER; } else if (profile != "none") { logger.error() << "unknown rotation profile " << profile; def.rotatable = false; diff --git a/src/logic/PlayerController.cpp b/src/logic/PlayerController.cpp index 03abc07b2..2a63f131b 100644 --- a/src/logic/PlayerController.cpp +++ b/src/logic/PlayerController.cpp @@ -340,6 +340,19 @@ static int determine_rotation( if (camDir.z > 0.0f) return BLOCK_DIR_SOUTH | verticalBit; if (camDir.z < 0.0f) return BLOCK_DIR_NORTH | verticalBit; } + } else if (name == "ladder") { + if (norm.x < 0.0f) return BLOCK_DIR_EAST; + if (norm.x > 0.0f) return BLOCK_DIR_WEST; + if (norm.z > 0.0f) return BLOCK_DIR_NORTH; + if (norm.z < 0.0f) return BLOCK_DIR_SOUTH; + if (abs(camDir.x) > abs(camDir.z)) { + if (camDir.x > 0.0f) return BLOCK_DIR_EAST; + if (camDir.x < 0.0f) return BLOCK_DIR_WEST; + } + if (abs(camDir.x) < abs(camDir.z)) { + if (camDir.z > 0.0f) return BLOCK_DIR_SOUTH; + if (camDir.z < 0.0f) return BLOCK_DIR_NORTH; + } } } return 0; diff --git a/src/voxels/Block.cpp b/src/voxels/Block.cpp index 11933a697..ad02e5d8e 100644 --- a/src/voxels/Block.cpp +++ b/src/voxels/Block.cpp @@ -109,6 +109,17 @@ const BlockRotProfile BlockRotProfile::STAIRS { 8 }; +const BlockRotProfile BlockRotProfile::LADDER { + "ladder", + { + {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}, // North + {{0, 0, -1}, {0, 1, 0}, {1, 0, 0}}, // East + {{-1, 0, 0}, {0, 1, 0}, {0, 0, -1}}, // South + {{0, 0, 1}, {0, 1, 0}, {-1, 0, 0}}, // West + }, + 4 +}; + Block::Block(const std::string& name) : name(name), caption(util::id_to_caption(name)) { for (int i = 0; i < defaults.textureFaces.size(); i++) { diff --git a/src/voxels/Block.hpp b/src/voxels/Block.hpp index ded51244e..a5185106b 100644 --- a/src/voxels/Block.hpp +++ b/src/voxels/Block.hpp @@ -90,9 +90,13 @@ struct BlockRotProfile { /// @brief Stairs, stairs and stairs static const BlockRotProfile STAIRS; + /// @brief Ladders, wall signs, paintings + static const BlockRotProfile LADDER; + static inline std::string PIPE_NAME = "pipe"; static inline std::string PANE_NAME = "pane"; static inline std::string STAIRS_NAME = "stairs"; + static inline std::string LADDER_NAME = "ladder"; }; enum class BlockModelType { diff --git a/src/world/generator/VoxelFragment.cpp b/src/world/generator/VoxelFragment.cpp index 68257f32e..659a67ad3 100644 --- a/src/world/generator/VoxelFragment.cpp +++ b/src/world/generator/VoxelFragment.cpp @@ -219,7 +219,8 @@ std::unique_ptr VoxelFragment::rotated(const Content& content) co | ((voxel.state.segment & 0b100) >> 2); auto& def = content.blocks.require(blockNames[voxel.id]); if (def.rotations.name == BlockRotProfile::PANE_NAME || - def.rotations.name == BlockRotProfile::PIPE_NAME) { + def.rotations.name == BlockRotProfile::PIPE_NAME || + def.rotations.name == BlockRotProfile::LADDER_NAME) { if (voxel.state.rotation < 4) { voxel.state.rotation = (voxel.state.rotation + 3) & 0b11; }