From a62b2b1be2103d7de2fd66c7304b7473e369be3c Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Wed, 5 May 2021 14:25:10 +0100 Subject: Move item placement into item handlers (#5184) * Move item placement into item handlers + Add appropriate CanBeAt checks in cPlayer::PlaceBlocks, into which all placement handlers call. * Partly addresses #5157 * Fixes #4878 * Fixes #2919 * Fixes #4629 * Fixes #4239 * Fixes #4849 Co-authored-by: changyong guo Co-authored-by: Xotheus Co-authored-by: Krist Pregracke * Review fixes * Update APIDesc.lua * Rename Co-authored-by: changyong guo Co-authored-by: Xotheus Co-authored-by: Krist Pregracke --- src/Blocks/BlockSlab.h | 87 +++++++++----------------------------------------- 1 file changed, 15 insertions(+), 72 deletions(-) (limited to 'src/Blocks/BlockSlab.h') 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(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: -- cgit v1.2.3