diff options
Diffstat (limited to '')
-rw-r--r-- | source/Blocks/BlockSlab.h | 113 |
1 files changed, 89 insertions, 24 deletions
diff --git a/source/Blocks/BlockSlab.h b/source/Blocks/BlockSlab.h index 6caa3a27a..7c1251b28 100644 --- a/source/Blocks/BlockSlab.h +++ b/source/Blocks/BlockSlab.h @@ -1,7 +1,17 @@ +// BlockSlab.h + +// Declares cBlockSlabHandler and cBlockDoubleSlabHandler classes + + + + + #pragma once #include "BlockHandler.h" +#include "../Items/ItemHandler.h" + @@ -30,36 +40,26 @@ public: ) override { a_BlockType = m_BlockType; - BLOCKTYPE Type = (BLOCKTYPE)(a_Player->GetEquippedItem().m_ItemType); + BLOCKTYPE Type = (BLOCKTYPE) (a_Player->GetEquippedItem().m_ItemType); NIBBLETYPE Meta = (NIBBLETYPE)(a_Player->GetEquippedItem().m_ItemDamage & 0x07); - int DoubleType; - if (Type == E_BLOCK_STONE_SLAB) - { - DoubleType = 43; // Make it a double slab (with old type wood) - } - else - { - DoubleType = 125; // Make it a wooden double slab (new type) - } // HandlePlaceBlock wants a cItemHandler pointer thing, so let's give it one - cItemHandler * ItemHandler = cItemHandler::GetItemHandler(DoubleType); + cItemHandler * ItemHandler = cItemHandler::GetItemHandler(GetDoubleSlabType(Type)); - // Check if the block at the coordinates is a slab. Eligibility for combining etc. were processed in ClientHandle - BLOCKTYPE IsSlab; - IsSlab = a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ); - if ((IsSlab == E_BLOCK_STONE_SLAB) || (IsSlab == E_BLOCK_WOODEN_SLAB)) + // Check if the block at the coordinates is a slab. Eligibility for combining has already been processed in ClientHandle + if (IsAnySlabType(a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ))) { - // Special handling for non top/bottom clicks + // Call the function in ClientHandle that places a block when the client sends the packet, + // so that plugins may interfere with the placement. + if ((a_BlockFace == BLOCK_FACE_TOP) || (a_BlockFace == BLOCK_FACE_BOTTOM)) { - // As with previous, call the function in ClientHandle that places a block when the client sends the packet - // This effectively simulates a client placing a double slab, so it goes through plugins etc. so the slabbing can be cancelled + // Top and bottom faces need no parameter modification a_Player->GetClientHandle()->HandlePlaceBlock(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, *ItemHandler); } else { - // If player cursor is at top half of block + // The other faces need to distinguish between top and bottom cursor positions if (a_CursorY > 7) { // Edit the call to use BLOCK_FACE_BOTTOM, otherwise it places incorrectly @@ -71,19 +71,23 @@ public: a_Player->GetClientHandle()->HandlePlaceBlock(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_BOTTOM, a_CursorX, a_CursorY, a_CursorZ, *ItemHandler); } } - return false; // Cancel the event because dblslabs were already placed, nothing else needed + return false; // Cancel the event, because dblslabs were already placed, nothing else needed } + // Place the single-slab with correct metas: switch (a_BlockFace) { - // Previous IF condition didn't cancel the event (not a slab at coords), so place slab with correct metas case BLOCK_FACE_TOP: { - a_BlockMeta = Meta & 0x7; break; // Bottom half slab block + // Bottom half slab block + a_BlockMeta = Meta & 0x7; + break; } case BLOCK_FACE_BOTTOM: { - a_BlockMeta = Meta | 0x8; break; // Top half slab block + // Top half slab block + a_BlockMeta = Meta | 0x8; + break; } case BLOCK_FACE_EAST: case BLOCK_FACE_NORTH: @@ -107,8 +111,69 @@ public: virtual const char * GetStepSound(void) override + { + switch (m_BlockType) + { + case E_BLOCK_WOODEN_SLAB: return "step.wood"; + case E_BLOCK_STONE_SLAB: return "step.stone"; + } + ASSERT(!"Unhandled slab type!"); + return ""; + } + + + /// Returns true if the specified blocktype is one of the slabs handled by this handler + static bool IsAnySlabType(BLOCKTYPE a_BlockType) + { + return ((a_BlockType == E_BLOCK_WOODEN_SLAB) || (a_BlockType == E_BLOCK_STONE_SLAB)); + } + + + /// 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; + } + ASSERT(!"Unhandled slab type!"); + return E_BLOCK_AIR; + } + +} ; + + + + + +class cBlockDoubleSlabHandler : + public cBlockHandler +{ +public: + cBlockDoubleSlabHandler(BLOCKTYPE a_BlockType) + : cBlockHandler(a_BlockType) + { + } + + + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override + { + if (m_BlockType == E_BLOCK_DOUBLE_STONE_SLAB) + { + m_BlockType = E_BLOCK_STONE_SLAB; + } + else + { + m_BlockType = E_BLOCK_WOODEN_SLAB; + } + a_Pickups.push_back(cItem(m_BlockType, 2, a_BlockMeta)); + } + + + virtual const char * GetStepSound(void) override { - return ((m_BlockType == E_BLOCK_WOODEN_SLAB) || (m_BlockType == E_BLOCK_STONE_SLAB)) ? "step.wood" : "step.stone"; + return ((m_BlockType == E_BLOCK_DOUBLE_WOODEN_SLAB) || (m_BlockType == E_BLOCK_DOUBLE_WOODEN_SLAB)) ? "step.wood" : "step.stone"; } } ; |