summaryrefslogtreecommitdiffstats
path: root/src/Blocks/BlockDoor.h
diff options
context:
space:
mode:
authorTiger Wang <ziwei.tiger@outlook.com>2020-09-20 15:50:52 +0200
committerGitHub <noreply@github.com>2020-09-20 15:50:52 +0200
commit68cced73afe546328cf94ed07c57deee47bfadec (patch)
tree88be88e3fd4a208b9849e526f1877caa44058ab5 /src/Blocks/BlockDoor.h
parentAdded armor and shulker box cleaning (#4875) (diff)
downloadcuberite-68cced73afe546328cf94ed07c57deee47bfadec.tar
cuberite-68cced73afe546328cf94ed07c57deee47bfadec.tar.gz
cuberite-68cced73afe546328cf94ed07c57deee47bfadec.tar.bz2
cuberite-68cced73afe546328cf94ed07c57deee47bfadec.tar.lz
cuberite-68cced73afe546328cf94ed07c57deee47bfadec.tar.xz
cuberite-68cced73afe546328cf94ed07c57deee47bfadec.tar.zst
cuberite-68cced73afe546328cf94ed07c57deee47bfadec.zip
Diffstat (limited to 'src/Blocks/BlockDoor.h')
-rw-r--r--src/Blocks/BlockDoor.h264
1 files changed, 125 insertions, 139 deletions
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)