From d92a92d78aae9617b973a142878ab7c038cf0d3d Mon Sep 17 00:00:00 2001 From: bibo38 Date: Sun, 1 Nov 2015 20:36:54 +0100 Subject: Implemented the slime block dropping behaviour. Fixes #2530 --- src/BlockInfo.cpp | 1 + src/Blocks/BlockHandler.cpp | 2 ++ src/Blocks/BlockSlime.h | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 35 insertions(+) create mode 100644 src/Blocks/BlockSlime.h diff --git a/src/BlockInfo.cpp b/src/BlockInfo.cpp index 70ca38362..54f11158e 100644 --- a/src/BlockInfo.cpp +++ b/src/BlockInfo.cpp @@ -305,6 +305,7 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info) a_Info[E_BLOCK_RED_MUSHROOM ].m_OneHitDig = true; a_Info[E_BLOCK_REEDS ].m_OneHitDig = true; a_Info[E_BLOCK_SAPLING ].m_OneHitDig = true; + a_Info[E_BLOCK_SLIME_BLOCK ].m_OneHitDig = true; a_Info[E_BLOCK_TNT ].m_OneHitDig = true; a_Info[E_BLOCK_TALL_GRASS ].m_OneHitDig = true; a_Info[E_BLOCK_TORCH ].m_OneHitDig = true; diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp index dab99e53d..bb479db53 100644 --- a/src/Blocks/BlockHandler.cpp +++ b/src/Blocks/BlockHandler.cpp @@ -72,6 +72,7 @@ #include "BlockSideways.h" #include "BlockSignPost.h" #include "BlockSlab.h" +#include "BlockSlime.h" #include "BlockSnow.h" #include "BlockStairs.h" #include "BlockStems.h" @@ -297,6 +298,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType) case E_BLOCK_SEA_LANTERN: return new cBlockSeaLanternHandler (a_BlockType); case E_BLOCK_SIGN_POST: return new cBlockSignPostHandler (a_BlockType); case E_BLOCK_SNOW: return new cBlockSnowHandler (a_BlockType); + case E_BLOCK_SLIME_BLOCK: return new cBlockSlimeHandler (a_BlockType); case E_BLOCK_SPRUCE_DOOR: return new cBlockDoorHandler (a_BlockType); case E_BLOCK_SPRUCE_FENCE_GATE: return new cBlockFenceGateHandler (a_BlockType); case E_BLOCK_SPRUCE_WOOD_STAIRS: return new cBlockStairsHandler (a_BlockType); diff --git a/src/Blocks/BlockSlime.h b/src/Blocks/BlockSlime.h new file mode 100644 index 000000000..e785a6a13 --- /dev/null +++ b/src/Blocks/BlockSlime.h @@ -0,0 +1,32 @@ +#pragma once + +#include "BlockHandler.h" + + + + + +class cBlockSlimeHandler : + public cBlockHandler +{ +public: + cBlockSlimeHandler(BLOCKTYPE a_BlockType) + : cBlockHandler(a_BlockType) + { + } + + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override + { + a_Pickups.push_back(cItem(m_BlockType, 1, 0)); + } + + virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override + { + UNUSED(a_Meta); + return 1; + } +}; + + + + -- cgit v1.2.3 From e2d88106a9558d26d3cb8b05ac6ade6aca088737 Mon Sep 17 00:00:00 2001 From: bibo38 Date: Mon, 2 Nov 2015 22:12:58 +0100 Subject: Added the CanPushBlock method for the piston push check. This allows the recursive check for blocks to push, which is needed to implement the slime blocks into the piston system. --- src/Blocks/BlockPiston.cpp | 56 ++++++++++++++++++++++++++++------------------ src/Blocks/BlockPiston.h | 9 ++++++-- 2 files changed, 41 insertions(+), 24 deletions(-) diff --git a/src/Blocks/BlockPiston.cpp b/src/Blocks/BlockPiston.cpp index 94782a7ed..83a1b83c4 100644 --- a/src/Blocks/BlockPiston.cpp +++ b/src/Blocks/BlockPiston.cpp @@ -86,28 +86,38 @@ bool cBlockPistonHandler::GetPlacementBlockTypeMeta( -int cBlockPistonHandler::FirstPassthroughBlock(int a_PistonX, int a_PistonY, int a_PistonZ, NIBBLETYPE pistonmeta, cWorld * a_World) +bool cBlockPistonHandler::CanPushBlock( + int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World, bool a_RequirePushable, + std::unordered_set> & a_BlocksPushed, NIBBLETYPE a_PistonMeta +) { - // Examine each of the 12 blocks ahead of the piston: - for (int ret = 0; ret < PISTON_MAX_PUSH_DISTANCE; ret++) + BLOCKTYPE currBlock; + NIBBLETYPE currMeta; + a_World->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, currBlock, currMeta); + + if (currBlock == E_BLOCK_AIR) { - BLOCKTYPE currBlock; - NIBBLETYPE currMeta; - AddPistonDir(a_PistonX, a_PistonY, a_PistonZ, pistonmeta, 1); - a_World->GetBlockTypeMeta(a_PistonX, a_PistonY, a_PistonZ, currBlock, currMeta); - if (cBlockInfo::IsPistonBreakable(currBlock)) - { - // This block breaks when pushed, extend up to here - return ret; - } - if (!CanPush(currBlock, currMeta)) - { - // This block cannot be pushed at all, the piston can't extend - return -1; - } + // Air can be pushed + return true; + } + + if (!CanPush(currBlock, currMeta)) + { + return !a_RequirePushable; + } + + if (a_BlocksPushed.size() >= PISTON_MAX_PUSH_DISTANCE) + { + return false; } - // There is no space for the blocks to move, piston can't extend - return -1; + + if (!a_BlocksPushed.emplace(a_BlockX, a_BlockY, a_BlockZ).second || cBlockInfo::IsPistonBreakable(currBlock)) + { + return true; // Element exist already + } + + AddPistonDir(a_BlockX, a_BlockY, a_BlockZ, a_PistonMeta, 1); + return CanPushBlock(a_BlockX, a_BlockY, a_BlockZ, a_World, true, a_BlocksPushed, a_PistonMeta); } @@ -126,10 +136,12 @@ void cBlockPistonHandler::ExtendPiston(int a_BlockX, int a_BlockY, int a_BlockZ, return; } - int dist = FirstPassthroughBlock(a_BlockX, a_BlockY, a_BlockZ, pistonMeta, a_World); - if (dist < 0) + int dist = 1; // TODO + AddPistonDir(a_BlockX, a_BlockY, a_BlockZ, pistonMeta, 1); + std::unordered_set> blocksPushed; + if (!CanPushBlock(a_BlockX, a_BlockY, a_BlockZ, a_World, true, blocksPushed, pistonMeta)) { - // FirstPassthroughBlock says piston can't push anything, bail out + // Can't push anything, bail out return; } diff --git a/src/Blocks/BlockPiston.h b/src/Blocks/BlockPiston.h index 56f7f9951..41ef79aa6 100644 --- a/src/Blocks/BlockPiston.h +++ b/src/Blocks/BlockPiston.h @@ -3,6 +3,8 @@ #include "BlockHandler.h" +#include + class cWorld; @@ -152,8 +154,11 @@ private: return CanPush(a_BlockType, a_BlockMeta); } - /** Returns how many blocks the piston has to push (where the first free space is); < 0 when unpushable */ - static int FirstPassthroughBlock(int a_PistonX, int a_PistonY, int a_PistonZ, NIBBLETYPE a_PistonMeta, cWorld * a_World); + /** Tries to push a block and increases the pushed blocks variable. Returns true if the block is pushable */ + static bool CanPushBlock( + int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World, bool a_RequirePushable, + std::unordered_set> & a_BlocksPushed, NIBBLETYPE a_PistonMeta + ); } ; -- cgit v1.2.3 From 8f066a16ec0eda3e0558cbf6decf3e0c7c82302a Mon Sep 17 00:00:00 2001 From: bibo38 Date: Wed, 4 Nov 2015 21:45:51 +0100 Subject: Piston extension now works with the new recursive CanPushBlock method. --- src/Blocks/BlockPiston.cpp | 77 ++++++++++++++++++++++++---------------------- 1 file changed, 41 insertions(+), 36 deletions(-) diff --git a/src/Blocks/BlockPiston.cpp b/src/Blocks/BlockPiston.cpp index 83a1b83c4..8e56fe06b 100644 --- a/src/Blocks/BlockPiston.cpp +++ b/src/Blocks/BlockPiston.cpp @@ -7,6 +7,8 @@ #include "BlockInServerPluginInterface.h" #include "ChunkInterface.h" +#include + @@ -136,56 +138,59 @@ void cBlockPistonHandler::ExtendPiston(int a_BlockX, int a_BlockY, int a_BlockZ, return; } - int dist = 1; // TODO - AddPistonDir(a_BlockX, a_BlockY, a_BlockZ, pistonMeta, 1); + int moveX = a_BlockX; + int moveY = a_BlockY; + int moveZ = a_BlockZ; + + AddPistonDir(moveX, moveY, moveZ, pistonMeta, 1); std::unordered_set> blocksPushed; - if (!CanPushBlock(a_BlockX, a_BlockY, a_BlockZ, a_World, true, blocksPushed, pistonMeta)) + if (!CanPushBlock(moveX, moveY, moveZ, a_World, true, blocksPushed, pistonMeta)) { // Can't push anything, bail out return; } + + Vector3i pistonMoveVec; + AddPistonDir(pistonMoveVec.x, pistonMoveVec.y, pistonMoveVec.z, pistonMeta, 1); + std::vector sortedBlocks(blocksPushed.begin(), blocksPushed.end()); + std::sort(sortedBlocks.begin(), sortedBlocks.end(), [pistonMoveVec](const Vector3i & a, const Vector3i & b) + { + return a.Dot(pistonMoveVec) > b.Dot(pistonMoveVec); + }); a_World->BroadcastBlockAction(a_BlockX, a_BlockY, a_BlockZ, 0, pistonMeta, pistonBlock); a_World->BroadcastSoundEffect("tile.piston.out", static_cast(a_BlockX), static_cast(a_BlockY), static_cast(a_BlockZ), 0.5f, 0.7f); - // Drop the breakable block in the line, if appropriate: - AddPistonDir(a_BlockX, a_BlockY, a_BlockZ, pistonMeta, dist + 1); // "a_Block" now at the breakable / empty block - BLOCKTYPE currBlock; - NIBBLETYPE currMeta; - a_World->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, currBlock, currMeta); - if (currBlock != E_BLOCK_AIR) + BLOCKTYPE moveBlock; + NIBBLETYPE moveMeta; + for (const Vector3i & moveBlockVec : sortedBlocks) { - cBlockHandler * Handler = BlockHandler(currBlock); - if (Handler->DoesDropOnUnsuitable()) + moveX = moveBlockVec.x; + moveY = moveBlockVec.y; + moveZ = moveBlockVec.z; + a_World->GetBlockTypeMeta(moveX, moveY, moveZ, moveBlock, moveMeta); + a_World->SetBlock(moveX, moveY, moveZ, E_BLOCK_AIR, 0); + + AddPistonDir(moveX, moveY, moveZ, pistonMeta, 1); + + if (cBlockInfo::IsPistonBreakable(moveBlock)) + { + cBlockHandler * Handler = BlockHandler(moveBlock); + if (Handler->DoesDropOnUnsuitable()) + { + cChunkInterface ChunkInterface(a_World->GetChunkMap()); + cBlockInServerPluginInterface PluginInterface(*a_World); + Handler->DropBlock(ChunkInterface, *a_World, PluginInterface, nullptr, moveX, moveY, moveZ); + } + } else { - cChunkInterface ChunkInterface(a_World->GetChunkMap()); - cBlockInServerPluginInterface PluginInterface(*a_World); - Handler->DropBlock(ChunkInterface, *a_World, PluginInterface, nullptr, a_BlockX, a_BlockY, a_BlockZ); + a_World->SetBlock(moveX, moveY, moveZ, moveBlock, moveMeta); } } - - // Push blocks, from the furthest to the nearest: - int oldx = a_BlockX, oldy = a_BlockY, oldz = a_BlockZ; - NIBBLETYPE currBlockMeta; - - for (int i = dist + 1; i > 1; i--) - { - AddPistonDir(a_BlockX, a_BlockY, a_BlockZ, pistonMeta, -1); - a_World->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, currBlock, currBlockMeta); - a_World->SetBlock(oldx, oldy, oldz, currBlock, currBlockMeta); - oldx = a_BlockX; - oldy = a_BlockY; - oldz = a_BlockZ; - } - - int extx = a_BlockX; - int exty = a_BlockY; - int extz = a_BlockZ; - AddPistonDir(a_BlockX, a_BlockY, a_BlockZ, pistonMeta, -1); - // "a_Block" now at piston body, "ext" at future extension - + a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, pistonBlock, pistonMeta | 0x8); - a_World->SetBlock(extx, exty, extz, E_BLOCK_PISTON_EXTENSION, pistonMeta | (IsSticky(pistonBlock) ? 8 : 0)); + AddPistonDir(a_BlockX, a_BlockY, a_BlockZ, pistonMeta, 1); + a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_PISTON_EXTENSION, pistonMeta | (IsSticky(pistonBlock) ? 8 : 0)); } -- cgit v1.2.3 From 59a9ac5e6ff26f598660cc2670dfeb68cd403bf2 Mon Sep 17 00:00:00 2001 From: bibo38 Date: Thu, 5 Nov 2015 10:25:59 +0100 Subject: Implemented the SlimeBlock into the CanPush method to allow slimeblocks to work correctly when pushed --- src/Blocks/BlockPiston.cpp | 41 ++++++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/src/Blocks/BlockPiston.cpp b/src/Blocks/BlockPiston.cpp index 8e56fe06b..a73b0d331 100644 --- a/src/Blocks/BlockPiston.cpp +++ b/src/Blocks/BlockPiston.cpp @@ -8,6 +8,7 @@ #include "ChunkInterface.h" #include +#include @@ -93,16 +94,19 @@ bool cBlockPistonHandler::CanPushBlock( std::unordered_set> & a_BlocksPushed, NIBBLETYPE a_PistonMeta ) { + const static std::array pushingDirs = {{ Vector3i(-1, 0, 0), Vector3i(1, 0, 0), Vector3i(0, -1, 0), Vector3i(0, 1, 0), + Vector3i(0, 0, -1), Vector3i(0, 0, 1) }}; + BLOCKTYPE currBlock; NIBBLETYPE currMeta; a_World->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, currBlock, currMeta); - + if (currBlock == E_BLOCK_AIR) { // Air can be pushed return true; } - + if (!CanPush(currBlock, currMeta)) { return !a_RequirePushable; @@ -112,12 +116,24 @@ bool cBlockPistonHandler::CanPushBlock( { return false; } - + if (!a_BlocksPushed.emplace(a_BlockX, a_BlockY, a_BlockZ).second || cBlockInfo::IsPistonBreakable(currBlock)) { return true; // Element exist already } - + + if(currBlock == E_BLOCK_SLIME_BLOCK) + { + // Try to push the other directions + for(const Vector3i & testDir : pushingDirs) + { + if(!CanPushBlock(a_BlockX + testDir.x, a_BlockY + testDir.y, a_BlockZ + testDir.z, a_World, false, a_BlocksPushed, a_PistonMeta)) + { + return false; + } + } + } + AddPistonDir(a_BlockX, a_BlockY, a_BlockZ, a_PistonMeta, 1); return CanPushBlock(a_BlockX, a_BlockY, a_BlockZ, a_World, true, a_BlocksPushed, a_PistonMeta); } @@ -141,7 +157,7 @@ void cBlockPistonHandler::ExtendPiston(int a_BlockX, int a_BlockY, int a_BlockZ, int moveX = a_BlockX; int moveY = a_BlockY; int moveZ = a_BlockZ; - + AddPistonDir(moveX, moveY, moveZ, pistonMeta, 1); std::unordered_set> blocksPushed; if (!CanPushBlock(moveX, moveY, moveZ, a_World, true, blocksPushed, pistonMeta)) @@ -149,7 +165,7 @@ void cBlockPistonHandler::ExtendPiston(int a_BlockX, int a_BlockY, int a_BlockZ, // Can't push anything, bail out return; } - + Vector3i pistonMoveVec; AddPistonDir(pistonMoveVec.x, pistonMoveVec.y, pistonMoveVec.z, pistonMeta, 1); std::vector sortedBlocks(blocksPushed.begin(), blocksPushed.end()); @@ -170,9 +186,9 @@ void cBlockPistonHandler::ExtendPiston(int a_BlockX, int a_BlockY, int a_BlockZ, moveZ = moveBlockVec.z; a_World->GetBlockTypeMeta(moveX, moveY, moveZ, moveBlock, moveMeta); a_World->SetBlock(moveX, moveY, moveZ, E_BLOCK_AIR, 0); - + AddPistonDir(moveX, moveY, moveZ, pistonMeta, 1); - + if (cBlockInfo::IsPistonBreakable(moveBlock)) { cBlockHandler * Handler = BlockHandler(moveBlock); @@ -187,7 +203,7 @@ void cBlockPistonHandler::ExtendPiston(int a_BlockX, int a_BlockY, int a_BlockZ, a_World->SetBlock(moveX, moveY, moveZ, moveBlock, moveMeta); } } - + a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, pistonBlock, pistonMeta | 0x8); AddPistonDir(a_BlockX, a_BlockY, a_BlockZ, pistonMeta, 1); a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_PISTON_EXTENSION, pistonMeta | (IsSticky(pistonBlock) ? 8 : 0)); @@ -239,7 +255,7 @@ void cBlockPistonHandler::RetractPiston(int a_BlockX, int a_BlockY, int a_BlockZ return; } } - + // Retract without pulling a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0); } @@ -283,8 +299,3 @@ void cBlockPistonHeadHandler::OnDestroyedByPlayer(cChunkInterface & a_ChunkInter a_WorldInterface.SpawnItemPickups(Pickups, a_BlockX + 0.5, a_BlockY + 0.5, a_BlockZ + 0.5); } } - - - - - -- cgit v1.2.3 From ede4eec4c5ce38fb862ebaba923ee017d567de12 Mon Sep 17 00:00:00 2001 From: bibo38 Date: Thu, 5 Nov 2015 11:39:07 +0100 Subject: Implemented the basic slime block pulling --- src/Blocks/BlockPiston.cpp | 79 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 62 insertions(+), 17 deletions(-) diff --git a/src/Blocks/BlockPiston.cpp b/src/Blocks/BlockPiston.cpp index a73b0d331..cb56cc0d8 100644 --- a/src/Blocks/BlockPiston.cpp +++ b/src/Blocks/BlockPiston.cpp @@ -233,31 +233,76 @@ void cBlockPistonHandler::RetractPiston(int a_BlockX, int a_BlockY, int a_BlockZ return; } + // Remove Extension + a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0); + AddPistonDir(a_BlockX, a_BlockY, a_BlockZ, pistonMeta, -1); a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, pistonBlock, pistonMeta & ~(8)); a_World->BroadcastBlockAction(a_BlockX, a_BlockY, a_BlockZ, 1, pistonMeta & ~(8), pistonBlock); a_World->BroadcastSoundEffect("tile.piston.in", static_cast(a_BlockX), static_cast(a_BlockY), static_cast(a_BlockZ), 0.5f, 0.7f); - AddPistonDir(a_BlockX, a_BlockY, a_BlockZ, pistonMeta, 1); - // Retract the extension, pull block if appropriate - if (IsSticky(pistonBlock)) + if(!IsSticky(pistonBlock)) { - int tempx = a_BlockX, tempy = a_BlockY, tempz = a_BlockZ; - AddPistonDir(tempx, tempy, tempz, pistonMeta, 1); - BLOCKTYPE tempBlock; - NIBBLETYPE tempMeta; - a_World->GetBlockTypeMeta(tempx, tempy, tempz, tempBlock, tempMeta); - if (CanPull(tempBlock, tempMeta)) - { - // Pull the block - a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, tempBlock, tempMeta); - a_World->SetBlock(tempx, tempy, tempz, E_BLOCK_AIR, 0); - return; - } + // No need for block pulling, bail out + return; } - // Retract without pulling - a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0); + AddPistonDir(a_BlockX, a_BlockY, a_BlockZ, pistonMeta, 2); + // Try to "push" the pulling block in the opposite direction + switch(pistonMeta & 0x07) + { + case 0: + case 1: + pistonMeta = 1 - pistonMeta; + break; + case 2: + case 3: + pistonMeta = 5 - pistonMeta; + break; + + case 4: + case 5: + pistonMeta = 9 - pistonMeta; + break; + + default: + { + LOGWARNING("%s: invalid direction %d, ignoring", __FUNCTION__, pistonMeta & 0x07); \ + break; + } + } + + std::unordered_set> pushedBlocks; + if (!CanPushBlock(a_BlockX, a_BlockY, a_BlockZ, a_World, true, pushedBlocks, pistonMeta)) + { + // Not pushable, bail out + return; + } + + Vector3i pistonMoveVec; + AddPistonDir(pistonMoveVec.x, pistonMoveVec.y, pistonMoveVec.z, pistonMeta, 1); + std::vector sortedBlocks(pushedBlocks.begin(), pushedBlocks.end()); + std::sort(sortedBlocks.begin(), sortedBlocks.end(), [pistonMoveVec](const Vector3i & a, const Vector3i & b) + { + return a.Dot(pistonMoveVec) > b.Dot(pistonMoveVec); + }); + + int moveX, moveY, moveZ; + BLOCKTYPE moveBlock; + NIBBLETYPE moveMeta; + for (const Vector3i & moveBlockVec : sortedBlocks) + { + moveX = moveBlockVec.x; + moveY = moveBlockVec.y; + moveZ = moveBlockVec.z; + a_World->GetBlockTypeMeta(moveX, moveY, moveZ, moveBlock, moveMeta); + a_World->SetBlock(moveX, moveY, moveZ, E_BLOCK_AIR, 0); + + AddPistonDir(moveX, moveY, moveZ, pistonMeta, 1); + + // TODO Do not allow pisons to pull breakable blocks + a_World->SetBlock(moveX, moveY, moveZ, moveBlock, moveMeta); + } } -- cgit v1.2.3 From ceec6c936d5608049da5532572cefaea242fa16e Mon Sep 17 00:00:00 2001 From: bibo38 Date: Thu, 5 Nov 2015 12:36:51 +0100 Subject: Fixed pulling/pushing of breakable blocks, which are not required to be moved --- src/Blocks/BlockPiston.cpp | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/src/Blocks/BlockPiston.cpp b/src/Blocks/BlockPiston.cpp index cb56cc0d8..601e0999d 100644 --- a/src/Blocks/BlockPiston.cpp +++ b/src/Blocks/BlockPiston.cpp @@ -107,6 +107,12 @@ bool cBlockPistonHandler::CanPushBlock( return true; } + if(!a_RequirePushable && cBlockInfo::IsPistonBreakable(currBlock)) + { + // Block should not be broken, when it's not in the pushing direction + return true; + } + if (!CanPush(currBlock, currMeta)) { return !a_RequirePushable; @@ -273,7 +279,7 @@ void cBlockPistonHandler::RetractPiston(int a_BlockX, int a_BlockY, int a_BlockZ } std::unordered_set> pushedBlocks; - if (!CanPushBlock(a_BlockX, a_BlockY, a_BlockZ, a_World, true, pushedBlocks, pistonMeta)) + if (!CanPushBlock(a_BlockX, a_BlockY, a_BlockZ, a_World, false, pushedBlocks, pistonMeta)) { // Not pushable, bail out return; @@ -300,8 +306,19 @@ void cBlockPistonHandler::RetractPiston(int a_BlockX, int a_BlockY, int a_BlockZ AddPistonDir(moveX, moveY, moveZ, pistonMeta, 1); - // TODO Do not allow pisons to pull breakable blocks - a_World->SetBlock(moveX, moveY, moveZ, moveBlock, moveMeta); + if (cBlockInfo::IsPistonBreakable(moveBlock)) + { + cBlockHandler * Handler = BlockHandler(moveBlock); + if (Handler->DoesDropOnUnsuitable()) + { + cChunkInterface ChunkInterface(a_World->GetChunkMap()); + cBlockInServerPluginInterface PluginInterface(*a_World); + Handler->DropBlock(ChunkInterface, *a_World, PluginInterface, nullptr, moveX, moveY, moveZ); + } + } else + { + a_World->SetBlock(moveX, moveY, moveZ, moveBlock, moveMeta); + } } } -- cgit v1.2.3 From f35060e8b518cac8521528a7398be7a095ccc108 Mon Sep 17 00:00:00 2001 From: bibo38 Date: Thu, 5 Nov 2015 14:50:43 +0100 Subject: Replaced the usage of pistonMeta with a direction vector to allow better meta value abstraction --- src/Blocks/BlockPiston.cpp | 132 +++++++++++++++++++++------------------------ src/Blocks/BlockPiston.h | 4 +- 2 files changed, 63 insertions(+), 73 deletions(-) diff --git a/src/Blocks/BlockPiston.cpp b/src/Blocks/BlockPiston.cpp index 601e0999d..01d97acd6 100644 --- a/src/Blocks/BlockPiston.cpp +++ b/src/Blocks/BlockPiston.cpp @@ -14,22 +14,6 @@ -#define AddPistonDir(x, y, z, dir, amount) \ - switch (dir & 0x07) \ - { \ - case 0: (y) -= (amount); break; \ - case 1: (y) += (amount); break; \ - case 2: (z) -= (amount); break; \ - case 3: (z) += (amount); break; \ - case 4: (x) -= (amount); break; \ - case 5: (x) += (amount); break; \ - default: \ - { \ - LOGWARNING("%s: invalid direction %d, ignoring", __FUNCTION__, dir & 0x07); \ - break; \ - } \ - } - #define PISTON_MAX_PUSH_DISTANCE 12 @@ -48,10 +32,10 @@ void cBlockPistonHandler::OnDestroyed(cChunkInterface & a_ChunkInterface, cWorld { NIBBLETYPE OldMeta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); - int newX = a_BlockX; - int newY = a_BlockY; - int newZ = a_BlockZ; - AddPistonDir(newX, newY, newZ, OldMeta, 1); + const Vector3i pushDir = GetDirectionVec(OldMeta); + int newX = a_BlockX + pushDir.x; + int newY = a_BlockY + pushDir.y; + int newZ = a_BlockZ + pushDir.z; if (a_ChunkInterface.GetBlock(newX, newY, newZ) == E_BLOCK_PISTON_EXTENSION) { @@ -89,9 +73,31 @@ bool cBlockPistonHandler::GetPlacementBlockTypeMeta( +Vector3i cBlockPistonHandler::GetDirectionVec(int a_PistonMeta) +{ + switch (a_PistonMeta & 0x07) + { + case 0: return Vector3i( 0, -1, 0); + case 1: return Vector3i( 0, 1, 0); + case 2: return Vector3i( 0, 0, -1); + case 3: return Vector3i( 0, 0, 1); + case 4: return Vector3i(-1, 0, 0); + case 5: return Vector3i( 1, 0, 0); + default: + { + LOGWARNING("%s: invalid direction %d, ignoring", __FUNCTION__, a_PistonMeta & 0x07); + return Vector3i(); + } + } +} + + + + + bool cBlockPistonHandler::CanPushBlock( int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World, bool a_RequirePushable, - std::unordered_set> & a_BlocksPushed, NIBBLETYPE a_PistonMeta + std::unordered_set> & a_BlocksPushed, const Vector3i & a_PushDir ) { const static std::array pushingDirs = {{ Vector3i(-1, 0, 0), Vector3i(1, 0, 0), Vector3i(0, -1, 0), Vector3i(0, 1, 0), @@ -133,15 +139,14 @@ bool cBlockPistonHandler::CanPushBlock( // Try to push the other directions for(const Vector3i & testDir : pushingDirs) { - if(!CanPushBlock(a_BlockX + testDir.x, a_BlockY + testDir.y, a_BlockZ + testDir.z, a_World, false, a_BlocksPushed, a_PistonMeta)) + if(!CanPushBlock(a_BlockX + testDir.x, a_BlockY + testDir.y, a_BlockZ + testDir.z, a_World, false, a_BlocksPushed, a_PushDir)) { return false; } } } - AddPistonDir(a_BlockX, a_BlockY, a_BlockZ, a_PistonMeta, 1); - return CanPushBlock(a_BlockX, a_BlockY, a_BlockZ, a_World, true, a_BlocksPushed, a_PistonMeta); + return CanPushBlock(a_BlockX + a_PushDir.x, a_BlockY + a_PushDir.y, a_BlockZ + a_PushDir.z, a_World, true, a_BlocksPushed, a_PushDir); } @@ -160,24 +165,22 @@ void cBlockPistonHandler::ExtendPiston(int a_BlockX, int a_BlockY, int a_BlockZ, return; } - int moveX = a_BlockX; - int moveY = a_BlockY; - int moveZ = a_BlockZ; + Vector3i pushDir = GetDirectionVec(pistonMeta); + int moveX = a_BlockX + pushDir.x; + int moveY = a_BlockY + pushDir.y; + int moveZ = a_BlockZ + pushDir.z; - AddPistonDir(moveX, moveY, moveZ, pistonMeta, 1); std::unordered_set> blocksPushed; - if (!CanPushBlock(moveX, moveY, moveZ, a_World, true, blocksPushed, pistonMeta)) + if (!CanPushBlock(moveX, moveY, moveZ, a_World, true, blocksPushed, pushDir)) { // Can't push anything, bail out return; } - Vector3i pistonMoveVec; - AddPistonDir(pistonMoveVec.x, pistonMoveVec.y, pistonMoveVec.z, pistonMeta, 1); std::vector sortedBlocks(blocksPushed.begin(), blocksPushed.end()); - std::sort(sortedBlocks.begin(), sortedBlocks.end(), [pistonMoveVec](const Vector3i & a, const Vector3i & b) + std::sort(sortedBlocks.begin(), sortedBlocks.end(), [pushDir](const Vector3i & a, const Vector3i & b) { - return a.Dot(pistonMoveVec) > b.Dot(pistonMoveVec); + return a.Dot(pushDir) > b.Dot(pushDir); }); a_World->BroadcastBlockAction(a_BlockX, a_BlockY, a_BlockZ, 0, pistonMeta, pistonBlock); @@ -193,7 +196,9 @@ void cBlockPistonHandler::ExtendPiston(int a_BlockX, int a_BlockY, int a_BlockZ, a_World->GetBlockTypeMeta(moveX, moveY, moveZ, moveBlock, moveMeta); a_World->SetBlock(moveX, moveY, moveZ, E_BLOCK_AIR, 0); - AddPistonDir(moveX, moveY, moveZ, pistonMeta, 1); + moveX += pushDir.x; + moveY += pushDir.y; + moveZ += pushDir.z; if (cBlockInfo::IsPistonBreakable(moveBlock)) { @@ -211,7 +216,9 @@ void cBlockPistonHandler::ExtendPiston(int a_BlockX, int a_BlockY, int a_BlockZ, } a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, pistonBlock, pistonMeta | 0x8); - AddPistonDir(a_BlockX, a_BlockY, a_BlockZ, pistonMeta, 1); + a_BlockX += pushDir.x; + a_BlockY += pushDir.y; + a_BlockZ += pushDir.z; a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_PISTON_EXTENSION, pistonMeta | (IsSticky(pistonBlock) ? 8 : 0)); } @@ -231,18 +238,18 @@ void cBlockPistonHandler::RetractPiston(int a_BlockX, int a_BlockY, int a_BlockZ return; } + Vector3i pushDir = GetDirectionVec(pistonMeta); + // Check the extension: - AddPistonDir(a_BlockX, a_BlockY, a_BlockZ, pistonMeta, 1); - if (a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ) != E_BLOCK_PISTON_EXTENSION) + if (a_World->GetBlock(a_BlockX + pushDir.x, a_BlockY + pushDir.y, a_BlockZ + pushDir.z) != E_BLOCK_PISTON_EXTENSION) { LOGD("%s: Piston without an extension - still extending, or just in an invalid state?", __FUNCTION__); return; } // Remove Extension - a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0); + a_World->SetBlock(a_BlockX + pushDir.x, a_BlockY + pushDir.y, a_BlockZ + pushDir.z, E_BLOCK_AIR, 0); - AddPistonDir(a_BlockX, a_BlockY, a_BlockZ, pistonMeta, -1); a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, pistonBlock, pistonMeta & ~(8)); a_World->BroadcastBlockAction(a_BlockX, a_BlockY, a_BlockZ, 1, pistonMeta & ~(8), pistonBlock); a_World->BroadcastSoundEffect("tile.piston.in", static_cast(a_BlockX), static_cast(a_BlockY), static_cast(a_BlockZ), 0.5f, 0.7f); @@ -253,44 +260,23 @@ void cBlockPistonHandler::RetractPiston(int a_BlockX, int a_BlockY, int a_BlockZ return; } - AddPistonDir(a_BlockX, a_BlockY, a_BlockZ, pistonMeta, 2); + a_BlockX += 2 * pushDir.x; + a_BlockY += 2 * pushDir.y; + a_BlockZ += 2 * pushDir.z; // Try to "push" the pulling block in the opposite direction - switch(pistonMeta & 0x07) - { - case 0: - case 1: - pistonMeta = 1 - pistonMeta; - break; - case 2: - case 3: - pistonMeta = 5 - pistonMeta; - break; - - case 4: - case 5: - pistonMeta = 9 - pistonMeta; - break; - - default: - { - LOGWARNING("%s: invalid direction %d, ignoring", __FUNCTION__, pistonMeta & 0x07); \ - break; - } - } + pushDir *= -1; std::unordered_set> pushedBlocks; - if (!CanPushBlock(a_BlockX, a_BlockY, a_BlockZ, a_World, false, pushedBlocks, pistonMeta)) + if (!CanPushBlock(a_BlockX, a_BlockY, a_BlockZ, a_World, false, pushedBlocks, pushDir)) { // Not pushable, bail out return; } - Vector3i pistonMoveVec; - AddPistonDir(pistonMoveVec.x, pistonMoveVec.y, pistonMoveVec.z, pistonMeta, 1); std::vector sortedBlocks(pushedBlocks.begin(), pushedBlocks.end()); - std::sort(sortedBlocks.begin(), sortedBlocks.end(), [pistonMoveVec](const Vector3i & a, const Vector3i & b) + std::sort(sortedBlocks.begin(), sortedBlocks.end(), [pushDir](const Vector3i & a, const Vector3i & b) { - return a.Dot(pistonMoveVec) > b.Dot(pistonMoveVec); + return a.Dot(pushDir) > b.Dot(pushDir); }); int moveX, moveY, moveZ; @@ -304,7 +290,9 @@ void cBlockPistonHandler::RetractPiston(int a_BlockX, int a_BlockY, int a_BlockZ a_World->GetBlockTypeMeta(moveX, moveY, moveZ, moveBlock, moveMeta); a_World->SetBlock(moveX, moveY, moveZ, E_BLOCK_AIR, 0); - AddPistonDir(moveX, moveY, moveZ, pistonMeta, 1); + moveX += pushDir.x; + moveY += pushDir.y; + moveZ += pushDir.z; if (cBlockInfo::IsPistonBreakable(moveBlock)) { @@ -342,10 +330,10 @@ void cBlockPistonHeadHandler::OnDestroyedByPlayer(cChunkInterface & a_ChunkInter { NIBBLETYPE OldMeta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); - int newX = a_BlockX; - int newY = a_BlockY; - int newZ = a_BlockZ; - AddPistonDir(newX, newY, newZ, OldMeta, -1); + Vector3i pushDir = cBlockPistonHandler::GetDirectionVec(OldMeta); + int newX = a_BlockX - pushDir.x; + int newY = a_BlockY - pushDir.y; + int newZ = a_BlockZ - pushDir.z; BLOCKTYPE Block = a_ChunkInterface.GetBlock(newX, newY, newZ); if ((Block == E_BLOCK_STICKY_PISTON) || (Block == E_BLOCK_PISTON)) diff --git a/src/Blocks/BlockPiston.h b/src/Blocks/BlockPiston.h index 41ef79aa6..b08ca5fee 100644 --- a/src/Blocks/BlockPiston.h +++ b/src/Blocks/BlockPiston.h @@ -81,6 +81,8 @@ public: } } + static Vector3i GetDirectionVec(int a_PistonMeta); + static void ExtendPiston(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); static void RetractPiston(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); @@ -157,7 +159,7 @@ private: /** Tries to push a block and increases the pushed blocks variable. Returns true if the block is pushable */ static bool CanPushBlock( int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World, bool a_RequirePushable, - std::unordered_set> & a_BlocksPushed, NIBBLETYPE a_PistonMeta + std::unordered_set> & a_BlocksPushed, const Vector3i & a_PushDir ); } ; -- cgit v1.2.3 From 558991a7256afb2d110579346006cafec73bc275 Mon Sep 17 00:00:00 2001 From: bibo38 Date: Thu, 5 Nov 2015 18:49:15 +0100 Subject: Extracted block moving code into a seperate method --- src/Blocks/BlockPiston.cpp | 125 +++++++++++++++++---------------------------- src/Blocks/BlockPiston.h | 4 ++ 2 files changed, 52 insertions(+), 77 deletions(-) diff --git a/src/Blocks/BlockPiston.cpp b/src/Blocks/BlockPiston.cpp index 01d97acd6..f2c64875a 100644 --- a/src/Blocks/BlockPiston.cpp +++ b/src/Blocks/BlockPiston.cpp @@ -95,6 +95,46 @@ Vector3i cBlockPistonHandler::GetDirectionVec(int a_PistonMeta) +void cBlockPistonHandler::PushBlocks(const std::unordered_set> & a_BlocksToPush, + cWorld * a_World, const Vector3i & a_PushDir +) +{ + std::vector sortedBlocks(a_BlocksToPush.begin(), a_BlocksToPush.end()); + std::sort(sortedBlocks.begin(), sortedBlocks.end(), [a_PushDir](const Vector3i & a, const Vector3i & b) + { + return a.Dot(a_PushDir) > b.Dot(a_PushDir); + }); + + BLOCKTYPE moveBlock; + NIBBLETYPE moveMeta; + for (Vector3i & moveBlockPos : sortedBlocks) + { + a_World->GetBlockTypeMeta(moveBlockPos.x, moveBlockPos.y, moveBlockPos.z, moveBlock, moveMeta); + a_World->SetBlock(moveBlockPos.x, moveBlockPos.y, moveBlockPos.z, E_BLOCK_AIR, 0); + + moveBlockPos += a_PushDir; + if (cBlockInfo::IsPistonBreakable(moveBlock)) + { + cBlockHandler * Handler = BlockHandler(moveBlock); + if (Handler->DoesDropOnUnsuitable()) + { + cChunkInterface ChunkInterface(a_World->GetChunkMap()); + cBlockInServerPluginInterface PluginInterface(*a_World); + Handler->DropBlock(ChunkInterface, *a_World, PluginInterface, nullptr, + moveBlockPos.x, moveBlockPos.y, moveBlockPos.z + ); + } + } else + { + a_World->SetBlock(moveBlockPos.x, moveBlockPos.y, moveBlockPos.z, moveBlock, moveMeta); + } + } +} + + + + + bool cBlockPistonHandler::CanPushBlock( int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World, bool a_RequirePushable, std::unordered_set> & a_BlocksPushed, const Vector3i & a_PushDir @@ -166,60 +206,25 @@ void cBlockPistonHandler::ExtendPiston(int a_BlockX, int a_BlockY, int a_BlockZ, } Vector3i pushDir = GetDirectionVec(pistonMeta); - int moveX = a_BlockX + pushDir.x; - int moveY = a_BlockY + pushDir.y; - int moveZ = a_BlockZ + pushDir.z; std::unordered_set> blocksPushed; - if (!CanPushBlock(moveX, moveY, moveZ, a_World, true, blocksPushed, pushDir)) + if (!CanPushBlock(a_BlockX + pushDir.x, a_BlockY + pushDir.y, a_BlockZ + pushDir.z, + a_World, true, blocksPushed, pushDir) + ) { // Can't push anything, bail out return; } - std::vector sortedBlocks(blocksPushed.begin(), blocksPushed.end()); - std::sort(sortedBlocks.begin(), sortedBlocks.end(), [pushDir](const Vector3i & a, const Vector3i & b) - { - return a.Dot(pushDir) > b.Dot(pushDir); - }); - a_World->BroadcastBlockAction(a_BlockX, a_BlockY, a_BlockZ, 0, pistonMeta, pistonBlock); a_World->BroadcastSoundEffect("tile.piston.out", static_cast(a_BlockX), static_cast(a_BlockY), static_cast(a_BlockZ), 0.5f, 0.7f); - BLOCKTYPE moveBlock; - NIBBLETYPE moveMeta; - for (const Vector3i & moveBlockVec : sortedBlocks) - { - moveX = moveBlockVec.x; - moveY = moveBlockVec.y; - moveZ = moveBlockVec.z; - a_World->GetBlockTypeMeta(moveX, moveY, moveZ, moveBlock, moveMeta); - a_World->SetBlock(moveX, moveY, moveZ, E_BLOCK_AIR, 0); - - moveX += pushDir.x; - moveY += pushDir.y; - moveZ += pushDir.z; - - if (cBlockInfo::IsPistonBreakable(moveBlock)) - { - cBlockHandler * Handler = BlockHandler(moveBlock); - if (Handler->DoesDropOnUnsuitable()) - { - cChunkInterface ChunkInterface(a_World->GetChunkMap()); - cBlockInServerPluginInterface PluginInterface(*a_World); - Handler->DropBlock(ChunkInterface, *a_World, PluginInterface, nullptr, moveX, moveY, moveZ); - } - } else - { - a_World->SetBlock(moveX, moveY, moveZ, moveBlock, moveMeta); - } - } + PushBlocks(blocksPushed, a_World, pushDir); a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, pistonBlock, pistonMeta | 0x8); - a_BlockX += pushDir.x; - a_BlockY += pushDir.y; - a_BlockZ += pushDir.z; - a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_PISTON_EXTENSION, pistonMeta | (IsSticky(pistonBlock) ? 8 : 0)); + a_World->SetBlock(a_BlockX + pushDir.x, a_BlockY + pushDir.y, a_BlockZ + pushDir.z, + E_BLOCK_PISTON_EXTENSION, pistonMeta | (IsSticky(pistonBlock) ? 8 : 0) + ); } @@ -273,41 +278,7 @@ void cBlockPistonHandler::RetractPiston(int a_BlockX, int a_BlockY, int a_BlockZ return; } - std::vector sortedBlocks(pushedBlocks.begin(), pushedBlocks.end()); - std::sort(sortedBlocks.begin(), sortedBlocks.end(), [pushDir](const Vector3i & a, const Vector3i & b) - { - return a.Dot(pushDir) > b.Dot(pushDir); - }); - - int moveX, moveY, moveZ; - BLOCKTYPE moveBlock; - NIBBLETYPE moveMeta; - for (const Vector3i & moveBlockVec : sortedBlocks) - { - moveX = moveBlockVec.x; - moveY = moveBlockVec.y; - moveZ = moveBlockVec.z; - a_World->GetBlockTypeMeta(moveX, moveY, moveZ, moveBlock, moveMeta); - a_World->SetBlock(moveX, moveY, moveZ, E_BLOCK_AIR, 0); - - moveX += pushDir.x; - moveY += pushDir.y; - moveZ += pushDir.z; - - if (cBlockInfo::IsPistonBreakable(moveBlock)) - { - cBlockHandler * Handler = BlockHandler(moveBlock); - if (Handler->DoesDropOnUnsuitable()) - { - cChunkInterface ChunkInterface(a_World->GetChunkMap()); - cBlockInServerPluginInterface PluginInterface(*a_World); - Handler->DropBlock(ChunkInterface, *a_World, PluginInterface, nullptr, moveX, moveY, moveZ); - } - } else - { - a_World->SetBlock(moveX, moveY, moveZ, moveBlock, moveMeta); - } - } + PushBlocks(pushedBlocks, a_World, pushDir); } diff --git a/src/Blocks/BlockPiston.h b/src/Blocks/BlockPiston.h index b08ca5fee..f05e73f38 100644 --- a/src/Blocks/BlockPiston.h +++ b/src/Blocks/BlockPiston.h @@ -161,6 +161,10 @@ private: int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World, bool a_RequirePushable, std::unordered_set> & a_BlocksPushed, const Vector3i & a_PushDir ); + + static void PushBlocks(const std::unordered_set> & a_BlocksToPush, + cWorld * a_World, const Vector3i & a_PushDir + ); } ; -- cgit v1.2.3 From 5fa077f869919325f82395161795ece9abbda280 Mon Sep 17 00:00:00 2001 From: bibo38 Date: Thu, 5 Nov 2015 18:56:06 +0100 Subject: Removed unused CanPull method --- src/Blocks/BlockPiston.h | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/Blocks/BlockPiston.h b/src/Blocks/BlockPiston.h index f05e73f38..af9e3d3bc 100644 --- a/src/Blocks/BlockPiston.h +++ b/src/Blocks/BlockPiston.h @@ -145,17 +145,6 @@ private: return true; } - /** Returns true if the specified block can be pulled by a sticky piston */ - static inline bool CanPull(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) - { - if (cBlockInfo::IsPistonBreakable(a_BlockType)) - { - return false; // CanBreakPush returns true, but we need false to prevent pulling - } - - return CanPush(a_BlockType, a_BlockMeta); - } - /** Tries to push a block and increases the pushed blocks variable. Returns true if the block is pushable */ static bool CanPushBlock( int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World, bool a_RequirePushable, -- cgit v1.2.3 From 64012bf46fb00f792b3f48fb396f17fc9f6be677 Mon Sep 17 00:00:00 2001 From: bibo38 Date: Thu, 5 Nov 2015 20:13:58 +0100 Subject: Fixed the style problems and added some comments --- src/Blocks/BlockPiston.cpp | 23 +++++++++++++++++------ src/Blocks/BlockPiston.h | 1 + 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/Blocks/BlockPiston.cpp b/src/Blocks/BlockPiston.cpp index f2c64875a..baf3b3e9c 100644 --- a/src/Blocks/BlockPiston.cpp +++ b/src/Blocks/BlockPiston.cpp @@ -99,22 +99,26 @@ void cBlockPistonHandler::PushBlocks(const std::unordered_set sortedBlocks(a_BlocksToPush.begin(), a_BlocksToPush.end()); std::sort(sortedBlocks.begin(), sortedBlocks.end(), [a_PushDir](const Vector3i & a, const Vector3i & b) { return a.Dot(a_PushDir) > b.Dot(a_PushDir); }); + // Move every block BLOCKTYPE moveBlock; NIBBLETYPE moveMeta; for (Vector3i & moveBlockPos : sortedBlocks) - { + { a_World->GetBlockTypeMeta(moveBlockPos.x, moveBlockPos.y, moveBlockPos.z, moveBlock, moveMeta); a_World->SetBlock(moveBlockPos.x, moveBlockPos.y, moveBlockPos.z, E_BLOCK_AIR, 0); moveBlockPos += a_PushDir; if (cBlockInfo::IsPistonBreakable(moveBlock)) { + // Block is breakable, drop it cBlockHandler * Handler = BlockHandler(moveBlock); if (Handler->DoesDropOnUnsuitable()) { @@ -126,6 +130,7 @@ void cBlockPistonHandler::PushBlocks(const std::unordered_setSetBlock(moveBlockPos.x, moveBlockPos.y, moveBlockPos.z, moveBlock, moveMeta); } } @@ -153,7 +158,7 @@ bool cBlockPistonHandler::CanPushBlock( return true; } - if(!a_RequirePushable && cBlockInfo::IsPistonBreakable(currBlock)) + if (!a_RequirePushable && cBlockInfo::IsPistonBreakable(currBlock)) { // Block should not be broken, when it's not in the pushing direction return true; @@ -161,11 +166,13 @@ bool cBlockPistonHandler::CanPushBlock( if (!CanPush(currBlock, currMeta)) { + // When it's not required to push this block, don't fail return !a_RequirePushable; } if (a_BlocksPushed.size() >= PISTON_MAX_PUSH_DISTANCE) { + // Do not allow to push too much blocks return false; } @@ -174,18 +181,20 @@ bool cBlockPistonHandler::CanPushBlock( return true; // Element exist already } - if(currBlock == E_BLOCK_SLIME_BLOCK) + if (currBlock == E_BLOCK_SLIME_BLOCK) { // Try to push the other directions - for(const Vector3i & testDir : pushingDirs) + for (const Vector3i & testDir : pushingDirs) { - if(!CanPushBlock(a_BlockX + testDir.x, a_BlockY + testDir.y, a_BlockZ + testDir.z, a_World, false, a_BlocksPushed, a_PushDir)) + if (!CanPushBlock(a_BlockX + testDir.x, a_BlockY + testDir.y, a_BlockZ + testDir.z, a_World, false, a_BlocksPushed, a_PushDir)) { + // When it's not possible for a direction, then fail return false; } } } + // Try to push the block in front of this block return CanPushBlock(a_BlockX + a_PushDir.x, a_BlockY + a_PushDir.y, a_BlockZ + a_PushDir.z, a_World, true, a_BlocksPushed, a_PushDir); } @@ -221,6 +230,7 @@ void cBlockPistonHandler::ExtendPiston(int a_BlockX, int a_BlockY, int a_BlockZ, PushBlocks(blocksPushed, a_World, pushDir); + // Set the extension and the piston base correctly a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, pistonBlock, pistonMeta | 0x8); a_World->SetBlock(a_BlockX + pushDir.x, a_BlockY + pushDir.y, a_BlockZ + pushDir.z, E_BLOCK_PISTON_EXTENSION, pistonMeta | (IsSticky(pistonBlock) ? 8 : 0) @@ -259,12 +269,13 @@ void cBlockPistonHandler::RetractPiston(int a_BlockX, int a_BlockY, int a_BlockZ a_World->BroadcastBlockAction(a_BlockX, a_BlockY, a_BlockZ, 1, pistonMeta & ~(8), pistonBlock); a_World->BroadcastSoundEffect("tile.piston.in", static_cast(a_BlockX), static_cast(a_BlockY), static_cast(a_BlockZ), 0.5f, 0.7f); - if(!IsSticky(pistonBlock)) + if (!IsSticky(pistonBlock)) { // No need for block pulling, bail out return; } + // Get the block to pull a_BlockX += 2 * pushDir.x; a_BlockY += 2 * pushDir.y; a_BlockZ += 2 * pushDir.z; diff --git a/src/Blocks/BlockPiston.h b/src/Blocks/BlockPiston.h index af9e3d3bc..f8851e091 100644 --- a/src/Blocks/BlockPiston.h +++ b/src/Blocks/BlockPiston.h @@ -151,6 +151,7 @@ private: std::unordered_set> & a_BlocksPushed, const Vector3i & a_PushDir ); + /** Moves a list of blocks in a specific direction */ static void PushBlocks(const std::unordered_set> & a_BlocksToPush, cWorld * a_World, const Vector3i & a_PushDir ); -- cgit v1.2.3 From f8c28cc373b1942f19f1b343f301e16d25463ac5 Mon Sep 17 00:00:00 2001 From: bibo38 Date: Thu, 5 Nov 2015 21:39:37 +0100 Subject: Commented the GetDirectionVec method --- src/Blocks/BlockPiston.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Blocks/BlockPiston.h b/src/Blocks/BlockPiston.h index f8851e091..0001a5787 100644 --- a/src/Blocks/BlockPiston.h +++ b/src/Blocks/BlockPiston.h @@ -81,6 +81,9 @@ public: } } + /** This method converts the magic piston metadata into a direction vector. + This vector has a length of 1 and points into the direction, in which the piston will extend. + */ static Vector3i GetDirectionVec(int a_PistonMeta); static void ExtendPiston(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); -- cgit v1.2.3 From 0447af8bcba4394387c339945f020fb023b6eb5e Mon Sep 17 00:00:00 2001 From: bibo38 Date: Thu, 5 Nov 2015 21:57:30 +0100 Subject: Renamed GetDirectionVec into VectorFromMetaData to improve code readability. --- src/Blocks/BlockPiston.cpp | 10 +++++----- src/Blocks/BlockPiston.h | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Blocks/BlockPiston.cpp b/src/Blocks/BlockPiston.cpp index baf3b3e9c..25fb0edee 100644 --- a/src/Blocks/BlockPiston.cpp +++ b/src/Blocks/BlockPiston.cpp @@ -32,7 +32,7 @@ void cBlockPistonHandler::OnDestroyed(cChunkInterface & a_ChunkInterface, cWorld { NIBBLETYPE OldMeta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); - const Vector3i pushDir = GetDirectionVec(OldMeta); + const Vector3i pushDir = VectorFromMetaData(OldMeta); int newX = a_BlockX + pushDir.x; int newY = a_BlockY + pushDir.y; int newZ = a_BlockZ + pushDir.z; @@ -73,7 +73,7 @@ bool cBlockPistonHandler::GetPlacementBlockTypeMeta( -Vector3i cBlockPistonHandler::GetDirectionVec(int a_PistonMeta) +Vector3i cBlockPistonHandler::VectorFromMetaData(int a_PistonMeta) { switch (a_PistonMeta & 0x07) { @@ -214,7 +214,7 @@ void cBlockPistonHandler::ExtendPiston(int a_BlockX, int a_BlockY, int a_BlockZ, return; } - Vector3i pushDir = GetDirectionVec(pistonMeta); + Vector3i pushDir = VectorFromMetaData(pistonMeta); std::unordered_set> blocksPushed; if (!CanPushBlock(a_BlockX + pushDir.x, a_BlockY + pushDir.y, a_BlockZ + pushDir.z, @@ -253,7 +253,7 @@ void cBlockPistonHandler::RetractPiston(int a_BlockX, int a_BlockY, int a_BlockZ return; } - Vector3i pushDir = GetDirectionVec(pistonMeta); + Vector3i pushDir = VectorFromMetaData(pistonMeta); // Check the extension: if (a_World->GetBlock(a_BlockX + pushDir.x, a_BlockY + pushDir.y, a_BlockZ + pushDir.z) != E_BLOCK_PISTON_EXTENSION) @@ -312,7 +312,7 @@ void cBlockPistonHeadHandler::OnDestroyedByPlayer(cChunkInterface & a_ChunkInter { NIBBLETYPE OldMeta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); - Vector3i pushDir = cBlockPistonHandler::GetDirectionVec(OldMeta); + Vector3i pushDir = cBlockPistonHandler::VectorFromMetaData(OldMeta); int newX = a_BlockX - pushDir.x; int newY = a_BlockY - pushDir.y; int newZ = a_BlockZ - pushDir.z; diff --git a/src/Blocks/BlockPiston.h b/src/Blocks/BlockPiston.h index 0001a5787..418af6d27 100644 --- a/src/Blocks/BlockPiston.h +++ b/src/Blocks/BlockPiston.h @@ -84,7 +84,7 @@ public: /** This method converts the magic piston metadata into a direction vector. This vector has a length of 1 and points into the direction, in which the piston will extend. */ - static Vector3i GetDirectionVec(int a_PistonMeta); + static Vector3i VectorFromMetaData(int a_PistonMeta); static void ExtendPiston(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); static void RetractPiston(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); -- cgit v1.2.3 From 429f6153901c1b178eff3e3c2b642331b052475b Mon Sep 17 00:00:00 2001 From: bibo38 Date: Fri, 6 Nov 2015 17:11:54 +0100 Subject: Added some code improvements --- src/Blocks/BlockPiston.cpp | 52 ++++++++++++++++++++++++++++++++-------------- src/Blocks/BlockPiston.h | 12 +++++------ 2 files changed, 42 insertions(+), 22 deletions(-) diff --git a/src/Blocks/BlockPiston.cpp b/src/Blocks/BlockPiston.cpp index 25fb0edee..de58215f1 100644 --- a/src/Blocks/BlockPiston.cpp +++ b/src/Blocks/BlockPiston.cpp @@ -32,7 +32,7 @@ void cBlockPistonHandler::OnDestroyed(cChunkInterface & a_ChunkInterface, cWorld { NIBBLETYPE OldMeta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); - const Vector3i pushDir = VectorFromMetaData(OldMeta); + const Vector3i pushDir = MetadataToOffset(OldMeta); int newX = a_BlockX + pushDir.x; int newY = a_BlockY + pushDir.y; int newZ = a_BlockZ + pushDir.z; @@ -73,7 +73,7 @@ bool cBlockPistonHandler::GetPlacementBlockTypeMeta( -Vector3i cBlockPistonHandler::VectorFromMetaData(int a_PistonMeta) +Vector3i cBlockPistonHandler::MetadataToOffset(NIBBLETYPE a_PistonMeta) { switch (a_PistonMeta & 0x07) { @@ -86,6 +86,7 @@ Vector3i cBlockPistonHandler::VectorFromMetaData(int a_PistonMeta) default: { LOGWARNING("%s: invalid direction %d, ignoring", __FUNCTION__, a_PistonMeta & 0x07); + ASSERT(!"Invalid direction"); return Vector3i(); } } @@ -95,7 +96,8 @@ Vector3i cBlockPistonHandler::VectorFromMetaData(int a_PistonMeta) -void cBlockPistonHandler::PushBlocks(const std::unordered_set> & a_BlocksToPush, +void cBlockPistonHandler::PushBlocks( + const Vector3iSet & a_BlocksToPush, cWorld * a_World, const Vector3i & a_PushDir ) { @@ -110,7 +112,7 @@ void cBlockPistonHandler::PushBlocks(const std::unordered_setGetBlockTypeMeta(moveBlockPos.x, moveBlockPos.y, moveBlockPos.z, moveBlock, moveMeta); a_World->SetBlock(moveBlockPos.x, moveBlockPos.y, moveBlockPos.z, E_BLOCK_AIR, 0); @@ -142,11 +144,17 @@ void cBlockPistonHandler::PushBlocks(const std::unordered_set> & a_BlocksPushed, const Vector3i & a_PushDir + Vector3iSet & a_BlocksPushed, const Vector3i & a_PushDir ) { - const static std::array pushingDirs = {{ Vector3i(-1, 0, 0), Vector3i(1, 0, 0), Vector3i(0, -1, 0), Vector3i(0, 1, 0), - Vector3i(0, 0, -1), Vector3i(0, 0, 1) }}; + const static std::array pushingDirs = + { + { + Vector3i(-1, 0, 0), Vector3i(1, 0, 0), + Vector3i( 0, -1, 0), Vector3i(0, 1, 0), + Vector3i( 0, 0, -1), Vector3i(0, 0, 1) + } + }; BLOCKTYPE currBlock; NIBBLETYPE currMeta; @@ -184,9 +192,12 @@ bool cBlockPistonHandler::CanPushBlock( if (currBlock == E_BLOCK_SLIME_BLOCK) { // Try to push the other directions - for (const Vector3i & testDir : pushingDirs) + for (const auto & testDir : pushingDirs) { - if (!CanPushBlock(a_BlockX + testDir.x, a_BlockY + testDir.y, a_BlockZ + testDir.z, a_World, false, a_BlocksPushed, a_PushDir)) + if (!CanPushBlock( + a_BlockX + testDir.x, a_BlockY + testDir.y, a_BlockZ + testDir.z, + a_World, false, a_BlocksPushed, a_PushDir) + ) { // When it's not possible for a direction, then fail return false; @@ -195,7 +206,10 @@ bool cBlockPistonHandler::CanPushBlock( } // Try to push the block in front of this block - return CanPushBlock(a_BlockX + a_PushDir.x, a_BlockY + a_PushDir.y, a_BlockZ + a_PushDir.z, a_World, true, a_BlocksPushed, a_PushDir); + return CanPushBlock( + a_BlockX + a_PushDir.x, a_BlockY + a_PushDir.y, a_BlockZ + a_PushDir.z, + a_World, true, a_BlocksPushed, a_PushDir + ); } @@ -214,10 +228,11 @@ void cBlockPistonHandler::ExtendPiston(int a_BlockX, int a_BlockY, int a_BlockZ, return; } - Vector3i pushDir = VectorFromMetaData(pistonMeta); + Vector3i pushDir = MetadataToOffset(pistonMeta); - std::unordered_set> blocksPushed; - if (!CanPushBlock(a_BlockX + pushDir.x, a_BlockY + pushDir.y, a_BlockZ + pushDir.z, + Vector3iSet blocksPushed; + if (!CanPushBlock( + a_BlockX + pushDir.x, a_BlockY + pushDir.y, a_BlockZ + pushDir.z, a_World, true, blocksPushed, pushDir) ) { @@ -253,7 +268,7 @@ void cBlockPistonHandler::RetractPiston(int a_BlockX, int a_BlockY, int a_BlockZ return; } - Vector3i pushDir = VectorFromMetaData(pistonMeta); + Vector3i pushDir = MetadataToOffset(pistonMeta); // Check the extension: if (a_World->GetBlock(a_BlockX + pushDir.x, a_BlockY + pushDir.y, a_BlockZ + pushDir.z) != E_BLOCK_PISTON_EXTENSION) @@ -282,7 +297,7 @@ void cBlockPistonHandler::RetractPiston(int a_BlockX, int a_BlockY, int a_BlockZ // Try to "push" the pulling block in the opposite direction pushDir *= -1; - std::unordered_set> pushedBlocks; + Vector3iSet pushedBlocks; if (!CanPushBlock(a_BlockX, a_BlockY, a_BlockZ, a_World, false, pushedBlocks, pushDir)) { // Not pushable, bail out @@ -312,7 +327,7 @@ void cBlockPistonHeadHandler::OnDestroyedByPlayer(cChunkInterface & a_ChunkInter { NIBBLETYPE OldMeta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); - Vector3i pushDir = cBlockPistonHandler::VectorFromMetaData(OldMeta); + Vector3i pushDir = cBlockPistonHandler::MetadataToOffset(OldMeta); int newX = a_BlockX - pushDir.x; int newY = a_BlockY - pushDir.y; int newZ = a_BlockZ - pushDir.z; @@ -331,3 +346,8 @@ void cBlockPistonHeadHandler::OnDestroyedByPlayer(cChunkInterface & a_ChunkInter a_WorldInterface.SpawnItemPickups(Pickups, a_BlockX + 0.5, a_BlockY + 0.5, a_BlockZ + 0.5); } } + + + + + diff --git a/src/Blocks/BlockPiston.h b/src/Blocks/BlockPiston.h index 418af6d27..82f079954 100644 --- a/src/Blocks/BlockPiston.h +++ b/src/Blocks/BlockPiston.h @@ -81,10 +81,8 @@ public: } } - /** This method converts the magic piston metadata into a direction vector. - This vector has a length of 1 and points into the direction, in which the piston will extend. - */ - static Vector3i VectorFromMetaData(int a_PistonMeta); + /** Converts piston block's metadata into a unit vector representing the direction in which the piston will extend. */ + static Vector3i MetadataToOffset(NIBBLETYPE a_PistonMeta); static void ExtendPiston(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); static void RetractPiston(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); @@ -96,6 +94,8 @@ public: } private: + + typedef std::unordered_set> Vector3iSet; /** Returns true if the piston (specified by blocktype) is a sticky piston */ static inline bool IsSticky(BLOCKTYPE a_BlockType) { return (a_BlockType == E_BLOCK_STICKY_PISTON); } @@ -151,11 +151,11 @@ private: /** Tries to push a block and increases the pushed blocks variable. Returns true if the block is pushable */ static bool CanPushBlock( int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World, bool a_RequirePushable, - std::unordered_set> & a_BlocksPushed, const Vector3i & a_PushDir + Vector3iSet & a_BlocksPushed, const Vector3i & a_PushDir ); /** Moves a list of blocks in a specific direction */ - static void PushBlocks(const std::unordered_set> & a_BlocksToPush, + static void PushBlocks(const Vector3iSet & a_BlocksToPush, cWorld * a_World, const Vector3i & a_PushDir ); } ; -- cgit v1.2.3 From ea55e756724d5b68a2f25b073323f7289db30a98 Mon Sep 17 00:00:00 2001 From: bibo38 Date: Sat, 7 Nov 2015 17:22:53 +0100 Subject: Refactored code to use vectors in the cPistonHandler class --- src/Blocks/BlockPiston.cpp | 84 ++++++++++++-------------- src/Blocks/BlockPiston.h | 6 +- src/Simulator/IncrementalRedstoneSimulator.cpp | 4 +- 3 files changed, 42 insertions(+), 52 deletions(-) diff --git a/src/Blocks/BlockPiston.cpp b/src/Blocks/BlockPiston.cpp index de58215f1..1da2a61ec 100644 --- a/src/Blocks/BlockPiston.cpp +++ b/src/Blocks/BlockPiston.cpp @@ -30,16 +30,15 @@ cBlockPistonHandler::cBlockPistonHandler(BLOCKTYPE a_BlockType) void cBlockPistonHandler::OnDestroyed(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ) { - NIBBLETYPE OldMeta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); + Vector3i blockPos(a_BlockX, a_BlockY, a_BlockZ); - const Vector3i pushDir = MetadataToOffset(OldMeta); - int newX = a_BlockX + pushDir.x; - int newY = a_BlockY + pushDir.y; - int newZ = a_BlockZ + pushDir.z; + // Get the extension of the piston + NIBBLETYPE OldMeta = a_ChunkInterface.GetBlockMeta(blockPos.x, blockPos.y, blockPos.z); + blockPos += MetadataToOffset(OldMeta); - if (a_ChunkInterface.GetBlock(newX, newY, newZ) == E_BLOCK_PISTON_EXTENSION) + if (a_ChunkInterface.GetBlock(blockPos) == E_BLOCK_PISTON_EXTENSION) { - a_ChunkInterface.SetBlock(newX, newY, newZ, E_BLOCK_AIR, 0); + a_ChunkInterface.SetBlock(blockPos.x, blockPos.y, blockPos.z, E_BLOCK_AIR, 0); } } @@ -143,7 +142,7 @@ void cBlockPistonHandler::PushBlocks( bool cBlockPistonHandler::CanPushBlock( - int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World, bool a_RequirePushable, + const Vector3i & a_BlockPos, cWorld * a_World, bool a_RequirePushable, Vector3iSet & a_BlocksPushed, const Vector3i & a_PushDir ) { @@ -158,7 +157,7 @@ bool cBlockPistonHandler::CanPushBlock( BLOCKTYPE currBlock; NIBBLETYPE currMeta; - a_World->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, currBlock, currMeta); + a_World->GetBlockTypeMeta(a_BlockPos.x, a_BlockPos.y, a_BlockPos.z, currBlock, currMeta); if (currBlock == E_BLOCK_AIR) { @@ -184,7 +183,7 @@ bool cBlockPistonHandler::CanPushBlock( return false; } - if (!a_BlocksPushed.emplace(a_BlockX, a_BlockY, a_BlockZ).second || cBlockInfo::IsPistonBreakable(currBlock)) + if (!a_BlocksPushed.insert(a_BlockPos).second || cBlockInfo::IsPistonBreakable(currBlock)) { return true; // Element exist already } @@ -194,10 +193,7 @@ bool cBlockPistonHandler::CanPushBlock( // Try to push the other directions for (const auto & testDir : pushingDirs) { - if (!CanPushBlock( - a_BlockX + testDir.x, a_BlockY + testDir.y, a_BlockZ + testDir.z, - a_World, false, a_BlocksPushed, a_PushDir) - ) + if (!CanPushBlock(a_BlockPos + testDir, a_World, false, a_BlocksPushed, a_PushDir)) { // When it's not possible for a direction, then fail return false; @@ -206,21 +202,18 @@ bool cBlockPistonHandler::CanPushBlock( } // Try to push the block in front of this block - return CanPushBlock( - a_BlockX + a_PushDir.x, a_BlockY + a_PushDir.y, a_BlockZ + a_PushDir.z, - a_World, true, a_BlocksPushed, a_PushDir - ); + return CanPushBlock(a_BlockPos + a_PushDir, a_World, true, a_BlocksPushed, a_PushDir); } -void cBlockPistonHandler::ExtendPiston(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World) +void cBlockPistonHandler::ExtendPiston(Vector3i a_BlockPos, cWorld * a_World) { BLOCKTYPE pistonBlock; NIBBLETYPE pistonMeta; - a_World->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, pistonBlock, pistonMeta); + a_World->GetBlockTypeMeta(a_BlockPos.x, a_BlockPos.y, a_BlockPos.z, pistonBlock, pistonMeta); if (IsExtended(pistonMeta)) { @@ -231,23 +224,22 @@ void cBlockPistonHandler::ExtendPiston(int a_BlockX, int a_BlockY, int a_BlockZ, Vector3i pushDir = MetadataToOffset(pistonMeta); Vector3iSet blocksPushed; - if (!CanPushBlock( - a_BlockX + pushDir.x, a_BlockY + pushDir.y, a_BlockZ + pushDir.z, - a_World, true, blocksPushed, pushDir) - ) + if (!CanPushBlock(a_BlockPos + pushDir, a_World, true, blocksPushed, pushDir)) { // Can't push anything, bail out return; } - a_World->BroadcastBlockAction(a_BlockX, a_BlockY, a_BlockZ, 0, pistonMeta, pistonBlock); - a_World->BroadcastSoundEffect("tile.piston.out", static_cast(a_BlockX), static_cast(a_BlockY), static_cast(a_BlockZ), 0.5f, 0.7f); + a_World->BroadcastBlockAction(a_BlockPos.x, a_BlockPos.y, a_BlockPos.z, 0, pistonMeta, pistonBlock); + a_World->BroadcastSoundEffect("tile.piston.out", a_BlockPos.x, a_BlockPos.y, a_BlockPos.z, 0.5f, 0.7f); PushBlocks(blocksPushed, a_World, pushDir); // Set the extension and the piston base correctly - a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, pistonBlock, pistonMeta | 0x8); - a_World->SetBlock(a_BlockX + pushDir.x, a_BlockY + pushDir.y, a_BlockZ + pushDir.z, + Vector3i extensionPos = a_BlockPos + pushDir; + a_World->SetBlock(a_BlockPos.x, a_BlockPos.y, a_BlockPos.z, pistonBlock, pistonMeta | 0x8); + a_World->SetBlock( + extensionPos.x, extensionPos.y, extensionPos.z, E_BLOCK_PISTON_EXTENSION, pistonMeta | (IsSticky(pistonBlock) ? 8 : 0) ); } @@ -256,11 +248,11 @@ void cBlockPistonHandler::ExtendPiston(int a_BlockX, int a_BlockY, int a_BlockZ, -void cBlockPistonHandler::RetractPiston(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World) +void cBlockPistonHandler::RetractPiston(Vector3i a_BlockPos, cWorld * a_World) { BLOCKTYPE pistonBlock; NIBBLETYPE pistonMeta; - a_World->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, pistonBlock, pistonMeta); + a_World->GetBlockTypeMeta(a_BlockPos.x, a_BlockPos.y, a_BlockPos.z, pistonBlock, pistonMeta); if (!IsExtended(pistonMeta)) { @@ -271,18 +263,19 @@ void cBlockPistonHandler::RetractPiston(int a_BlockX, int a_BlockY, int a_BlockZ Vector3i pushDir = MetadataToOffset(pistonMeta); // Check the extension: - if (a_World->GetBlock(a_BlockX + pushDir.x, a_BlockY + pushDir.y, a_BlockZ + pushDir.z) != E_BLOCK_PISTON_EXTENSION) + Vector3i extensionPos = a_BlockPos + pushDir; + if (a_World->GetBlock(extensionPos) != E_BLOCK_PISTON_EXTENSION) { LOGD("%s: Piston without an extension - still extending, or just in an invalid state?", __FUNCTION__); return; } // Remove Extension - a_World->SetBlock(a_BlockX + pushDir.x, a_BlockY + pushDir.y, a_BlockZ + pushDir.z, E_BLOCK_AIR, 0); + a_World->SetBlock(extensionPos.x, extensionPos.y, extensionPos.z, E_BLOCK_AIR, 0); - a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, pistonBlock, pistonMeta & ~(8)); - a_World->BroadcastBlockAction(a_BlockX, a_BlockY, a_BlockZ, 1, pistonMeta & ~(8), pistonBlock); - a_World->BroadcastSoundEffect("tile.piston.in", static_cast(a_BlockX), static_cast(a_BlockY), static_cast(a_BlockZ), 0.5f, 0.7f); + a_World->SetBlock(a_BlockPos.x, a_BlockPos.y, a_BlockPos.z, pistonBlock, pistonMeta & ~(8)); + a_World->BroadcastBlockAction(a_BlockPos.x, a_BlockPos.y, a_BlockPos.z, 1, pistonMeta & ~(8), pistonBlock); + a_World->BroadcastSoundEffect("tile.piston.in", a_BlockPos.x, a_BlockPos.y, a_BlockPos.z, 0.5f, 0.7f); if (!IsSticky(pistonBlock)) { @@ -291,14 +284,12 @@ void cBlockPistonHandler::RetractPiston(int a_BlockX, int a_BlockY, int a_BlockZ } // Get the block to pull - a_BlockX += 2 * pushDir.x; - a_BlockY += 2 * pushDir.y; - a_BlockZ += 2 * pushDir.z; + a_BlockPos += pushDir * 2; // Try to "push" the pulling block in the opposite direction pushDir *= -1; Vector3iSet pushedBlocks; - if (!CanPushBlock(a_BlockX, a_BlockY, a_BlockZ, a_World, false, pushedBlocks, pushDir)) + if (!CanPushBlock(a_BlockPos, a_World, false, pushedBlocks, pushDir)) { // Not pushable, bail out return; @@ -325,17 +316,16 @@ cBlockPistonHeadHandler::cBlockPistonHeadHandler(void) : void cBlockPistonHeadHandler::OnDestroyedByPlayer(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) { - NIBBLETYPE OldMeta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); + Vector3i blockPos(a_BlockX, a_BlockY, a_BlockZ); - Vector3i pushDir = cBlockPistonHandler::MetadataToOffset(OldMeta); - int newX = a_BlockX - pushDir.x; - int newY = a_BlockY - pushDir.y; - int newZ = a_BlockZ - pushDir.z; + // Get the base of the piston + NIBBLETYPE OldMeta = a_ChunkInterface.GetBlockMeta(blockPos.x, blockPos.y, blockPos.z); + blockPos -= cBlockPistonHandler::MetadataToOffset(OldMeta); - BLOCKTYPE Block = a_ChunkInterface.GetBlock(newX, newY, newZ); + BLOCKTYPE Block = a_ChunkInterface.GetBlock(blockPos); if ((Block == E_BLOCK_STICKY_PISTON) || (Block == E_BLOCK_PISTON)) { - a_ChunkInterface.DigBlock(a_WorldInterface, newX, newY, newZ); + a_ChunkInterface.DigBlock(a_WorldInterface, blockPos.x, blockPos.y, blockPos.z); if (a_Player->IsGameModeCreative()) { return; // No pickups if creative @@ -343,7 +333,7 @@ void cBlockPistonHeadHandler::OnDestroyedByPlayer(cChunkInterface & a_ChunkInter cItems Pickups; Pickups.push_back(cItem(Block, 1)); - a_WorldInterface.SpawnItemPickups(Pickups, a_BlockX + 0.5, a_BlockY + 0.5, a_BlockZ + 0.5); + a_WorldInterface.SpawnItemPickups(Pickups, blockPos.x + 0.5, blockPos.y + 0.5, blockPos.z + 0.5); } } diff --git a/src/Blocks/BlockPiston.h b/src/Blocks/BlockPiston.h index 82f079954..e0066e8ab 100644 --- a/src/Blocks/BlockPiston.h +++ b/src/Blocks/BlockPiston.h @@ -84,8 +84,8 @@ public: /** Converts piston block's metadata into a unit vector representing the direction in which the piston will extend. */ static Vector3i MetadataToOffset(NIBBLETYPE a_PistonMeta); - static void ExtendPiston(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); - static void RetractPiston(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); + static void ExtendPiston(Vector3i a_BlockPos, cWorld * a_World); + static void RetractPiston(Vector3i a_BlockPos, cWorld * a_World); virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override { @@ -150,7 +150,7 @@ private: /** Tries to push a block and increases the pushed blocks variable. Returns true if the block is pushable */ static bool CanPushBlock( - int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World, bool a_RequirePushable, + const Vector3i & a_BlockPos, cWorld * a_World, bool a_RequirePushable, Vector3iSet & a_BlocksPushed, const Vector3i & a_PushDir ); diff --git a/src/Simulator/IncrementalRedstoneSimulator.cpp b/src/Simulator/IncrementalRedstoneSimulator.cpp index a23ee8ec2..15c702585 100644 --- a/src/Simulator/IncrementalRedstoneSimulator.cpp +++ b/src/Simulator/IncrementalRedstoneSimulator.cpp @@ -882,11 +882,11 @@ void cIncrementalRedstoneSimulator::HandlePiston(int a_RelBlockX, int a_RelBlock if (IsPistonPowered(a_RelBlockX, a_RelBlockY, a_RelBlockZ, m_Chunk->GetMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ) & 0x7)) // We only want the bottom three bits (4th controls extended-ness) { - GetHandlerCompileTime::type::ExtendPiston(BlockX, a_RelBlockY, BlockZ, &this->m_World); + GetHandlerCompileTime::type::ExtendPiston(Vector3i(BlockX, a_RelBlockY, BlockZ), &this->m_World); } else { - GetHandlerCompileTime::type::RetractPiston(BlockX, a_RelBlockY, BlockZ, &this->m_World); + GetHandlerCompileTime::type::RetractPiston(Vector3i(BlockX, a_RelBlockY, BlockZ), &this->m_World); } } -- cgit v1.2.3