summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTiger Wang <ziwei.tiger@hotmail.co.uk>2013-08-24 19:46:19 +0200
committerTiger Wang <ziwei.tiger@hotmail.co.uk>2013-08-24 19:46:19 +0200
commitd1cc6d9a9cd76eca7ab98ef5253b29573f8d6959 (patch)
tree1d3e3df79a989bd97760425ba9304109ab3c732d
parentFixed final slab bug (diff)
downloadcuberite-d1cc6d9a9cd76eca7ab98ef5253b29573f8d6959.tar
cuberite-d1cc6d9a9cd76eca7ab98ef5253b29573f8d6959.tar.gz
cuberite-d1cc6d9a9cd76eca7ab98ef5253b29573f8d6959.tar.bz2
cuberite-d1cc6d9a9cd76eca7ab98ef5253b29573f8d6959.tar.lz
cuberite-d1cc6d9a9cd76eca7ab98ef5253b29573f8d6959.tar.xz
cuberite-d1cc6d9a9cd76eca7ab98ef5253b29573f8d6959.tar.zst
cuberite-d1cc6d9a9cd76eca7ab98ef5253b29573f8d6959.zip
-rw-r--r--source/Blocks/BlockSlab.h76
-rw-r--r--source/ClientHandle.cpp30
2 files changed, 58 insertions, 48 deletions
diff --git a/source/Blocks/BlockSlab.h b/source/Blocks/BlockSlab.h
index 881a85615..6caa3a27a 100644
--- a/source/Blocks/BlockSlab.h
+++ b/source/Blocks/BlockSlab.h
@@ -18,8 +18,7 @@ public:
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
{
- char Count = ((m_BlockType == E_BLOCK_STONE_SLAB) || (m_BlockType == E_BLOCK_WOODEN_SLAB)) ? 1 : 1;
- a_Pickups.push_back(cItem(m_BlockType, Count, a_BlockMeta));
+ a_Pickups.push_back(cItem(m_BlockType, 1, a_BlockMeta));
}
@@ -37,39 +36,54 @@ public:
int DoubleType;
if (Type == E_BLOCK_STONE_SLAB)
{
- DoubleType = 43; //Make it a double slab (with old type wood)
+ DoubleType = 43; // Make it a double slab (with old type wood)
}
else
{
- DoubleType = 125; //Make it a wooden double slab (new type)
+ 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);
- switch (a_BlockFace)
+ // 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))
{
- case BLOCK_FACE_TOP:
+ // Special handling for non top/bottom clicks
+ if ((a_BlockFace == BLOCK_FACE_TOP) || (a_BlockFace == BLOCK_FACE_BOTTOM))
{
- if ((a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ) == E_BLOCK_STONE_SLAB) || (a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ) == E_BLOCK_WOODEN_SLAB))
+ // 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
+ 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
+ if (a_CursorY > 7)
{
- a_Player->GetClientHandle()->HandlePlaceBlock(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, *ItemHandler);
- return false;
+ // Edit the call to use BLOCK_FACE_BOTTOM, otherwise it places incorrectly
+ a_Player->GetClientHandle()->HandlePlaceBlock(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_TOP, a_CursorX, a_CursorY, a_CursorZ, *ItemHandler);
}
else
{
- a_BlockMeta = Meta & 0x7; break; //Bottom half if on top of non slab block
+ // Edit the call to use BLOCK_FACE_TOP, otherwise it places incorrectly
+ 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
+ }
+
+ 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
+ }
case BLOCK_FACE_BOTTOM:
{
- if ((a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ) == E_BLOCK_STONE_SLAB) || (a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ) == E_BLOCK_WOODEN_SLAB))
- {
- a_Player->GetClientHandle()->HandlePlaceBlock(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, *ItemHandler);
- return false;
- }
- else
- {
- a_BlockMeta = Meta | 0x8; break; //Bottom half if on top of non slab block
- }
+ a_BlockMeta = Meta | 0x8; break; // Top half slab block
}
case BLOCK_FACE_EAST:
case BLOCK_FACE_NORTH:
@@ -78,29 +92,13 @@ public:
{
if (a_CursorY > 7)
{
- // Cursor at the top half of the face, place a top half of slab
- if ((a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ) == E_BLOCK_STONE_SLAB) || (a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ) == E_BLOCK_WOODEN_SLAB))
- {
- a_Player->GetClientHandle()->HandlePlaceBlock(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, *ItemHandler);
- return false;
- }
- else
- {
- a_BlockMeta = Meta | 0x8; break;
- }
+ // Cursor at top half of block, place top slab
+ a_BlockMeta = Meta | 0x8; break;
}
else
{
- // Cursor at the bottom half of the face, place a bottom half of slab:
- if ((a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ) == E_BLOCK_STONE_SLAB) || (a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ) == E_BLOCK_WOODEN_SLAB))
- {
- a_Player->GetClientHandle()->HandlePlaceBlock(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, *ItemHandler);
- return false;
- }
- else
- {
- a_BlockMeta = Meta & 0x7; break;
- }
+ // Cursor at bottom half of block, place bottom slab
+ a_BlockMeta = Meta & 0x7; break;
}
}
} // switch (a_BlockFace)
diff --git a/source/ClientHandle.cpp b/source/ClientHandle.cpp
index 8ff93ec1b..199f43014 100644
--- a/source/ClientHandle.cpp
+++ b/source/ClientHandle.cpp
@@ -854,19 +854,29 @@ void cClientHandle::HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, c
World->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, ClickedBlock, ClickedBlockMeta);
- //Special slab handler coding
+ // Special slab handler coding
if (
+ // If clicked face top: is slab there in the "bottom" position?
+ // If clicked face bottom: is the slab there in the "top" position?
+ // This prevents a dblslab forming below if you click the top face of a "top" slab.
(((a_BlockFace == BLOCK_FACE_TOP) && (ClickedBlockMeta == (EquippedBlockDamage & 0x07))) || ((a_BlockFace == BLOCK_FACE_BOTTOM) && (ClickedBlockMeta == (EquippedBlockDamage | 0x08)))) &&
- ((ClickedBlock == E_BLOCK_STONE_SLAB) || (ClickedBlock == E_BLOCK_WOODEN_SLAB)) && //Is clicked a slab?
- ((EquippedBlock == E_BLOCK_STONE_SLAB) || (EquippedBlock == E_BLOCK_WOODEN_SLAB)) && //Is equipped a slab?
- ((ClickedBlockMeta & 0x07) == (EquippedBlockDamage & 0x07)) //Is clicked same type of slab as item in hand?
+
+ // Is clicked a slab? This is a SLAB handler, not stone or something!
+ ((ClickedBlock == E_BLOCK_STONE_SLAB) || (ClickedBlock == E_BLOCK_WOODEN_SLAB)) &&
+
+ // Is equipped a some type of slab?
+ // This prevents a bug where, well, you get a dblslab by placing TNT or something not a slab.
+ ((EquippedBlock == E_BLOCK_STONE_SLAB) || (EquippedBlock == E_BLOCK_WOODEN_SLAB)) &&
+
+ // Is equipped slab type same as the slab in the world? After all, we can't combine different slabs!
+ ((ClickedBlockMeta & 0x07) == (EquippedBlockDamage & 0x07))
)
{
- //Don't move the coordinates
+ // Coordinates at CLICKED block, don't move them anywhere
}
else
{
- //Check if the block ignores build collision (water, grass etc.):
+ // Check if the block ignores build collision (water, grass etc.):
cBlockHandler * Handler = cBlockHandler::GetBlockHandler(ClickedBlock);
if (Handler->DoesIgnoreBuildCollision())
{
@@ -876,8 +886,9 @@ void cClientHandle::HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, c
else
{
AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace);
- //On side of block, make sure that placement won't be cancelled if there is a slab there
- //No need to combinability checks, client will do that
+
+ // Clicked on side of block, make sure that placement won't be cancelled if there is a slab able to be double slabbed.
+ // No need to do combinability (dblslab) checks, client will do that here.
if ((World->GetBlock(a_BlockX, a_BlockY, a_BlockZ) == E_BLOCK_STONE_SLAB) || (World->GetBlock(a_BlockX, a_BlockY, a_BlockZ) == E_BLOCK_WOODEN_SLAB))
{
//Is a slab, don't do checks and proceed to double-slabbing
@@ -904,7 +915,8 @@ void cClientHandle::HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, c
}
}
}
-
+ // Special slab handler coding end
+
BLOCKTYPE BlockType;
NIBBLETYPE BlockMeta;
if (!a_ItemHandler.GetPlacementBlockTypeMeta(World, m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, BlockType, BlockMeta))