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 ++++++++++++++++++++++++++++------------------ 1 file changed, 34 insertions(+), 22 deletions(-) (limited to 'src/Blocks/BlockPiston.cpp') 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; } -- 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(-) (limited to 'src/Blocks/BlockPiston.cpp') 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(-) (limited to 'src/Blocks/BlockPiston.cpp') 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(-) (limited to 'src/Blocks/BlockPiston.cpp') 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(-) (limited to 'src/Blocks/BlockPiston.cpp') 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 +++++++++++++++++++++------------------------ 1 file changed, 60 insertions(+), 72 deletions(-) (limited to 'src/Blocks/BlockPiston.cpp') 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)) -- 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 +++++++++++++++++---------------------------- 1 file changed, 48 insertions(+), 77 deletions(-) (limited to 'src/Blocks/BlockPiston.cpp') 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); } -- 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 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) (limited to 'src/Blocks/BlockPiston.cpp') 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; -- 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 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/Blocks/BlockPiston.cpp') 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; -- 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 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 36 insertions(+), 16 deletions(-) (limited to 'src/Blocks/BlockPiston.cpp') 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); } } + + + + + -- 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 ++++++++++++++++++++-------------------------- 1 file changed, 37 insertions(+), 47 deletions(-) (limited to 'src/Blocks/BlockPiston.cpp') 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); } } -- cgit v1.2.3