summaryrefslogtreecommitdiffstats
path: root/src/Blocks/BlockSlab.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/Blocks/BlockSlab.h')
-rw-r--r--src/Blocks/BlockSlab.h87
1 files changed, 15 insertions, 72 deletions
diff --git a/src/Blocks/BlockSlab.h b/src/Blocks/BlockSlab.h
index 98f327b5b..566c88c71 100644
--- a/src/Blocks/BlockSlab.h
+++ b/src/Blocks/BlockSlab.h
@@ -46,64 +46,25 @@ private:
}
-
-
-
- virtual bool GetPlacementBlockTypeMeta(
- cChunkInterface & a_ChunkInterface,
- cPlayer & a_Player,
- const Vector3i a_PlacedBlockPos,
- eBlockFace a_ClickedBlockFace,
- const Vector3i a_CursorPos,
- BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
- ) const override
+ virtual bool DoesIgnoreBuildCollision(const cWorld & a_World, const cItem & a_HeldItem, const Vector3i a_Position, const NIBBLETYPE a_Meta, const eBlockFace a_ClickedBlockFace, const bool a_ClickedDirectly) const override
{
- a_BlockType = m_BlockType;
- NIBBLETYPE Meta = static_cast<NIBBLETYPE>(a_Player.GetEquippedItem().m_ItemDamage);
-
- // Set the correct metadata based on player equipped item (i.e. a_BlockMeta not initialised yet)
- switch (a_ClickedBlockFace)
+ /* Double slab combining uses build collision checks to replace single slabs with double slabs in the right conditions.
+ For us to be replaced, the player must be:
+ 1. Placing the same slab material.
+ 2. Placing the same slab sub-kind (and existing slab is single). */
+ if ((m_BlockType != a_HeldItem.m_ItemType) || ((a_Meta & 0x07) != a_HeldItem.m_ItemDamage))
{
- case BLOCK_FACE_TOP:
- {
- // Bottom half slab block
- a_BlockMeta = Meta & 0x07;
- break;
- }
- case BLOCK_FACE_BOTTOM:
- {
- // Top half slab block
- a_BlockMeta = Meta | 0x08;
- break;
- }
- case BLOCK_FACE_EAST:
- case BLOCK_FACE_NORTH:
- case BLOCK_FACE_SOUTH:
- case BLOCK_FACE_WEST:
- {
- if (a_CursorPos.y > 7)
- {
- // Cursor at top half of block, place top slab
- a_BlockMeta = Meta | 0x08; break;
- }
- else
- {
- // Cursor at bottom half of block, place bottom slab
- a_BlockMeta = Meta & 0x07; break;
- }
- }
- case BLOCK_FACE_NONE: return false;
- } // switch (a_BlockFace)
-
- // Check if the block at the coordinates is a single slab. Eligibility for combining has already been processed in ClientHandle
- // Changed to-be-placed to a double slab if we are clicking on a single slab, as opposed to placing one for the first time
- if (IsAnySlabType(a_ChunkInterface.GetBlock(a_PlacedBlockPos)))
- {
- a_BlockType = GetDoubleSlabType(m_BlockType);
- a_BlockMeta = a_BlockMeta & 0x07;
+ return false;
}
- return true;
+ const bool IsTopSlab = (a_Meta & 0x08) == 0x08;
+ const auto CanClickCombine = ((a_ClickedBlockFace == BLOCK_FACE_TOP) && !IsTopSlab) || ((a_ClickedBlockFace == BLOCK_FACE_BOTTOM) && IsTopSlab);
+
+ /* When the player clicks on us directly, we'll combine if we're
+ a bottom slab and he clicked the top, or vice versa. Clicking on the sides will not combine.
+ However, when indirectly clicked (on the side of another block, that caused placement to go to us)
+ the conditions are exactly the opposite. */
+ return a_ClickedDirectly ? CanClickCombine : !CanClickCombine;
}
@@ -131,24 +92,6 @@ private:
- /** Converts the single-slab blocktype to its equivalent double-slab blocktype */
- static BLOCKTYPE GetDoubleSlabType(BLOCKTYPE a_SingleSlabBlockType)
- {
- switch (a_SingleSlabBlockType)
- {
- case E_BLOCK_STONE_SLAB: return E_BLOCK_DOUBLE_STONE_SLAB;
- case E_BLOCK_WOODEN_SLAB: return E_BLOCK_DOUBLE_WOODEN_SLAB;
- case E_BLOCK_RED_SANDSTONE_SLAB: return E_BLOCK_DOUBLE_RED_SANDSTONE_SLAB;
- case E_BLOCK_PURPUR_SLAB: return E_BLOCK_PURPUR_DOUBLE_SLAB;
- }
- ASSERT(!"Unhandled slab type!");
- return E_BLOCK_AIR;
- }
-
-
-
-
-
virtual NIBBLETYPE MetaMirrorXZ(NIBBLETYPE a_Meta) const override
{
// Toggle the 4th bit - up / down: