From a671e45cd55adc4ae477225e59afb2969454b1d4 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Fri, 23 Aug 2013 19:38:39 +0100 Subject: Double slabs work *choke choke* --- source/ClientHandle.cpp | 69 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 49 insertions(+), 20 deletions(-) (limited to 'source/ClientHandle.cpp') diff --git a/source/ClientHandle.cpp b/source/ClientHandle.cpp index 57830f63c..937aebd1a 100644 --- a/source/ClientHandle.cpp +++ b/source/ClientHandle.cpp @@ -846,33 +846,62 @@ void cClientHandle::HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, c } cWorld * World = m_Player->GetWorld(); - - // Check if the block ignores build collision (water, grass etc.): - BLOCKTYPE ClickedBlock = World->GetBlock(a_BlockX, a_BlockY, a_BlockZ); - cBlockHandler * Handler = cBlockHandler::GetBlockHandler(ClickedBlock); - if (Handler->DoesIgnoreBuildCollision()) + + BLOCKTYPE ClickedBlock; + NIBBLETYPE ClickedBlockMeta; + BLOCKTYPE EquippedBlock = (BLOCKTYPE)(m_Player->GetEquippedItem().m_ItemType); + NIBBLETYPE EquippedBlockDamage = (NIBBLETYPE)(m_Player->GetEquippedItem().m_ItemDamage); + + World->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, ClickedBlock, ClickedBlockMeta); + + //Special slab handler coding + if ( + ((a_BlockFace == BLOCK_FACE_TOP) || (a_BlockFace == BLOCK_FACE_BOTTOM)) && + ((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? + ) { - Handler->OnDestroyedByPlayer(World, m_Player, a_BlockX, a_BlockY, a_BlockZ); - // World->FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0); + //Don't move the coordinates } else { - AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace); - // Check for Blocks not allowing placement on top - if ((a_BlockFace == BLOCK_FACE_TOP) && !Handler->DoesAllowBlockOnTop()) + //Check if the block ignores build collision (water, grass etc.): + cBlockHandler * Handler = cBlockHandler::GetBlockHandler(ClickedBlock); + if (Handler->DoesIgnoreBuildCollision()) { - // Resend the old block - // Some times the client still places the block O.o - World->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player); - return; + Handler->OnDestroyedByPlayer(World, m_Player, a_BlockX, a_BlockY, a_BlockZ); + //World->FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0); } - - - BLOCKTYPE PlaceBlock = World->GetBlock(a_BlockX, a_BlockY, a_BlockZ); - if (!BlockHandler(PlaceBlock)->DoesIgnoreBuildCollision()) + else { - // Tried to place a block *into* another? - return; // Happens when you place a block aiming at side of block like torch or stem + 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 + 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 + } + else + { + // Check for Blocks not allowing placement on top + if ((a_BlockFace == BLOCK_FACE_TOP) && !Handler->DoesAllowBlockOnTop()) + { + // Resend the old block + // Some times the client still places the block O.o + World->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player); + return; + } + + + BLOCKTYPE PlaceBlock = World->GetBlock(a_BlockX, a_BlockY, a_BlockZ); + if (!BlockHandler(PlaceBlock)->DoesIgnoreBuildCollision()) + { + // Tried to place a block *into* another? + // Happens when you place a block aiming at side of block like torch or stem + return; + } + } } } -- cgit v1.2.3 From 8bb2cab9930f807b8434ca6d75da0377605c84da Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sat, 24 Aug 2013 11:10:30 +0100 Subject: Fixed final slab bug This bug allowed a double slab to be made below by placing a compatible slab on a "top" slab. The coordinates are always one lower, so now it checks to see if the slab orientation can be made into a double. --- source/ClientHandle.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source/ClientHandle.cpp') diff --git a/source/ClientHandle.cpp b/source/ClientHandle.cpp index 937aebd1a..8ff93ec1b 100644 --- a/source/ClientHandle.cpp +++ b/source/ClientHandle.cpp @@ -856,7 +856,7 @@ void cClientHandle::HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, c //Special slab handler coding if ( - ((a_BlockFace == BLOCK_FACE_TOP) || (a_BlockFace == BLOCK_FACE_BOTTOM)) && + (((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? -- cgit v1.2.3 From d1cc6d9a9cd76eca7ab98ef5253b29573f8d6959 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sat, 24 Aug 2013 18:46:19 +0100 Subject: Added comments and fixed a bug Bug was placing slabs between slabs not making a double slab. --- source/ClientHandle.cpp | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) (limited to 'source/ClientHandle.cpp') 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)) -- cgit v1.2.3 From 259f08aac88c5e5ac49e5ec06f13c8b4759766c3 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 24 Aug 2013 21:25:36 +0200 Subject: Client can no longer place blocks outside the Y range of the world. Fixes #128. --- source/ClientHandle.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'source/ClientHandle.cpp') diff --git a/source/ClientHandle.cpp b/source/ClientHandle.cpp index ed76ee086..8125fc127 100644 --- a/source/ClientHandle.cpp +++ b/source/ClientHandle.cpp @@ -871,7 +871,12 @@ void cClientHandle::HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, c return; } - + if ((a_BlockY < 0) || (a_BlockY >= cChunkDef::Height)) + { + // The block is being placed outside the world, ignore this packet altogether (#128) + return; + } + BLOCKTYPE PlaceBlock = World->GetBlock(a_BlockX, a_BlockY, a_BlockZ); if (!BlockHandler(PlaceBlock)->DoesIgnoreBuildCollision()) { -- cgit v1.2.3