From 68cced73afe546328cf94ed07c57deee47bfadec Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 20 Sep 2020 14:50:52 +0100 Subject: BlockHandler initialisation is a constant expression (#4891) * BlockHandler initialisation is a constant expression If we can't make it all namespaces, this is the next best I guess. + Tag handlers constexpr, const as needed + Inherit constructors * Privatise handler functions * More constexpr Co-authored-by: Alexander Harkness --- src/Blocks/BlockDoor.h | 264 +++++++++++++++++++++++-------------------------- 1 file changed, 125 insertions(+), 139 deletions(-) (limited to 'src/Blocks/BlockDoor.h') diff --git a/src/Blocks/BlockDoor.h b/src/Blocks/BlockDoor.h index a953a8553..ff3757d79 100644 --- a/src/Blocks/BlockDoor.h +++ b/src/Blocks/BlockDoor.h @@ -18,13 +18,124 @@ class cBlockDoorHandler : public: - cBlockDoorHandler(BLOCKTYPE a_BlockType); + using Super::Super; + + /** Returns true if door can be placed on the specified block type. */ + static bool CanBeOn(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) + { + // Vanilla refuses to place doors on transparent blocks, except top-half slabs and other doors + // We need to keep the door compatible with itself, otherwise the top half drops while the bottom half stays + + // Doors can be placed on upside-down slabs + if (cBlockSlabHandler::IsAnySlabType(a_BlockType) && ((a_BlockMeta & 0x08) != 0)) + { + return true; + } + // Doors can also be placed on other doors + else if (IsDoorBlockType(a_BlockType)) + { + return true; + } + // Doors can not be placed on transparent blocks, but on any other block + else + { + return !cBlockInfo::IsTransparent(a_BlockType); + } + } + + static bool CanReplaceBlock(BLOCKTYPE a_BlockType) + { + switch (a_BlockType) + { + case E_BLOCK_AIR: + case E_BLOCK_TALL_GRASS: + case E_BLOCK_WATER: + case E_BLOCK_STATIONARY_WATER: + case E_BLOCK_LAVA: + case E_BLOCK_STATIONARY_LAVA: + case E_BLOCK_SNOW: + case E_BLOCK_FIRE: + { + return true; + } + } + return false; + } + + /** Returns a vector pointing one block in the direction the door is facing (where the outside is). */ + inline static Vector3i GetRelativeDirectionToOutside(NIBBLETYPE a_BlockMeta) + { + switch (a_BlockMeta & 0x03) + { + case 0: return Vector3i(-1, 0, 0); // Facing West / XM + case 1: return Vector3i(0, 0, -1); // Facing North / ZM + case 2: return Vector3i(1, 0, 0); // Facing East / XP + default: return Vector3i(0, 0, 1); // Facing South / ZP + } + } + + /** Returns true if the specified blocktype is any kind of door */ + inline static bool IsDoorBlockType(BLOCKTYPE a_Block) + { + switch (a_Block) + { + case E_BLOCK_ACACIA_DOOR: + case E_BLOCK_BIRCH_DOOR: + case E_BLOCK_DARK_OAK_DOOR: + case E_BLOCK_IRON_DOOR: + case E_BLOCK_JUNGLE_DOOR: + case E_BLOCK_SPRUCE_DOOR: + case E_BLOCK_OAK_DOOR: + { + return true; + } + default: + { + return false; + } + } + } + + /** Sets the door to the specified state. If the door is already in that state, does nothing. */ + static void SetOpen(cChunkInterface & a_ChunkInterface, const Vector3i a_BlockPos, bool a_Open) + { + BLOCKTYPE Block = a_ChunkInterface.GetBlock(a_BlockPos); + if (!IsDoorBlockType(Block)) + { + return; + } + + NIBBLETYPE Meta = GetCompleteDoorMeta(a_ChunkInterface, a_BlockPos); + bool IsOpened = ((Meta & 0x04) != 0); + if (IsOpened == a_Open) + { + return; + } + + // Change the door + NIBBLETYPE NewMeta = (Meta & 0x07) ^ 0x04; // Flip the "IsOpen" bit (0x04) + if ((Meta & 0x08) == 0) + { + // The block is the bottom part of the door + a_ChunkInterface.SetBlockMeta(a_BlockPos, NewMeta); + } + else + { + // The block is the top part of the door, set the meta to the corresponding top part + if (a_BlockPos.y > 0) + { + a_ChunkInterface.SetBlockMeta(a_BlockPos.addedY(-1), NewMeta); + } + } + } + +private: virtual void OnBroken( cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, Vector3i a_BlockPos, BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta - ) override; + ) const override; virtual bool OnUse( cChunkInterface & a_ChunkInterface, @@ -33,7 +144,7 @@ public: const Vector3i a_BlockPos, eBlockFace a_BlockFace, const Vector3i a_CursorPos - ) override; + ) const override; virtual void OnCancelRightClick( cChunkInterface & a_ChunkInterface, @@ -41,12 +152,12 @@ public: cPlayer & a_Player, const Vector3i a_BlockPos, eBlockFace a_BlockFace - ) override; + ) const override; - virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override; - virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) override; - virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) override; - virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) override; + virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) const override; + virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) const override; + virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) const override; + virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) const override; @@ -59,7 +170,7 @@ public: eBlockFace a_ClickedBlockFace, const Vector3i a_CursorPos, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta - ) override + ) const override { // If clicking a bottom face, place the door one block lower: auto PlacedPos = a_PlacedBlockPos; @@ -79,13 +190,13 @@ public: return Super::GetPlacementBlockTypeMeta(a_ChunkInterface, a_Player, PlacedPos, a_ClickedBlockFace, a_CursorPos, a_BlockType, a_BlockMeta); } - virtual cBoundingBox GetPlacementCollisionBox(BLOCKTYPE a_XM, BLOCKTYPE a_XP, BLOCKTYPE a_YM, BLOCKTYPE a_YP, BLOCKTYPE a_ZM, BLOCKTYPE a_ZP) override; + virtual cBoundingBox GetPlacementCollisionBox(BLOCKTYPE a_XM, BLOCKTYPE a_XP, BLOCKTYPE a_YM, BLOCKTYPE a_YP, BLOCKTYPE a_ZM, BLOCKTYPE a_ZP) const override; - virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) override + virtual cItems ConvertToPickups(NIBBLETYPE a_BlockMeta, cBlockEntity * a_BlockEntity, const cEntity * a_Digger, const cItem * a_Tool) const override { switch (m_BlockType) { @@ -108,7 +219,7 @@ public: - virtual bool IsUseable(void) override + virtual bool IsUseable(void) const override { return true; } @@ -117,7 +228,7 @@ public: - virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) override + virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, const Vector3i a_RelPos, const cChunk & a_Chunk) const override { return ((a_RelPos.y > 0) && CanBeOn(a_Chunk.GetBlock(a_RelPos.addedY(-1)), a_Chunk.GetMeta(a_RelPos.addedY(-1)))); } @@ -126,94 +237,6 @@ public: - /** Returns true if door can be placed on the specified block type. */ - static bool CanBeOn(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) - { - // Vanilla refuses to place doors on transparent blocks, except top-half slabs and other doors - // We need to keep the door compatible with itself, otherwise the top half drops while the bottom half stays - - // Doors can be placed on upside-down slabs - if (cBlockSlabHandler::IsAnySlabType(a_BlockType) && ((a_BlockMeta & 0x08) != 0)) - { - return true; - } - // Doors can also be placed on other doors - else if (IsDoorBlockType(a_BlockType)) - { - return true; - } - // Doors can not be placed on transparent blocks, but on any other block - else - { - return !cBlockInfo::IsTransparent(a_BlockType); - } - } - - static bool CanReplaceBlock(BLOCKTYPE a_BlockType) - { - switch (a_BlockType) - { - case E_BLOCK_AIR: - case E_BLOCK_TALL_GRASS: - case E_BLOCK_WATER: - case E_BLOCK_STATIONARY_WATER: - case E_BLOCK_LAVA: - case E_BLOCK_STATIONARY_LAVA: - case E_BLOCK_SNOW: - case E_BLOCK_FIRE: - { - return true; - } - } - return false; - } - - - - - - /** Returns a vector pointing one block in the direction the door is facing (where the outside is). */ - inline static Vector3i GetRelativeDirectionToOutside(NIBBLETYPE a_BlockMeta) - { - switch (a_BlockMeta & 0x03) - { - case 0: return Vector3i(-1, 0, 0); // Facing West / XM - case 1: return Vector3i( 0, 0, -1); // Facing North / ZM - case 2: return Vector3i( 1, 0, 0); // Facing East / XP - default: return Vector3i( 0, 0, 1); // Facing South / ZP - } - } - - - - - - /** Returns true if the specified blocktype is any kind of door */ - inline static bool IsDoorBlockType(BLOCKTYPE a_Block) - { - switch (a_Block) - { - case E_BLOCK_ACACIA_DOOR: - case E_BLOCK_BIRCH_DOOR: - case E_BLOCK_DARK_OAK_DOOR: - case E_BLOCK_IRON_DOOR: - case E_BLOCK_JUNGLE_DOOR: - case E_BLOCK_SPRUCE_DOOR: - case E_BLOCK_OAK_DOOR: - { - return true; - } - default: - { - return false; - } - } - } - - - - - /** Returns true iff the door at the specified coords is open. The coords may point to either the top part or the bottom part of the door. */ static NIBBLETYPE IsOpen(cChunkInterface & a_ChunkInterface, const Vector3i a_BlockPos) @@ -262,43 +285,6 @@ public: - /** Sets the door to the specified state. If the door is already in that state, does nothing. */ - static void SetOpen(cChunkInterface & a_ChunkInterface, const Vector3i a_BlockPos, bool a_Open) - { - BLOCKTYPE Block = a_ChunkInterface.GetBlock(a_BlockPos); - if (!IsDoorBlockType(Block)) - { - return; - } - - NIBBLETYPE Meta = GetCompleteDoorMeta(a_ChunkInterface, a_BlockPos); - bool IsOpened = ((Meta & 0x04) != 0); - if (IsOpened == a_Open) - { - return; - } - - // Change the door - NIBBLETYPE NewMeta = (Meta & 0x07) ^ 0x04; // Flip the "IsOpen" bit (0x04) - if ((Meta & 0x08) == 0) - { - // The block is the bottom part of the door - a_ChunkInterface.SetBlockMeta(a_BlockPos, NewMeta); - } - else - { - // The block is the top part of the door, set the meta to the corresponding top part - if (a_BlockPos.y > 0) - { - a_ChunkInterface.SetBlockMeta(a_BlockPos.addedY(-1), NewMeta); - } - } - } - - - - - /** Changes the door at the specified coords from open to close or vice versa */ static void ChangeDoor(cChunkInterface & a_ChunkInterface, const Vector3i a_BlockPos) { @@ -309,7 +295,7 @@ public: - virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override + virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) const override { UNUSED(a_Meta); switch (m_BlockType) -- cgit v1.2.3