diff options
author | bibo38 <bibo38@github.com> | 2015-11-05 14:50:43 +0100 |
---|---|---|
committer | bibo38 <bibo38@github.com> | 2015-11-07 17:23:02 +0100 |
commit | f35060e8b518cac8521528a7398be7a095ccc108 (patch) | |
tree | 425d62fca03468e5be2b8934c251383b37bec1ed | |
parent | Fixed pulling/pushing of breakable blocks, which are not required to be moved (diff) | |
download | cuberite-f35060e8b518cac8521528a7398be7a095ccc108.tar cuberite-f35060e8b518cac8521528a7398be7a095ccc108.tar.gz cuberite-f35060e8b518cac8521528a7398be7a095ccc108.tar.bz2 cuberite-f35060e8b518cac8521528a7398be7a095ccc108.tar.lz cuberite-f35060e8b518cac8521528a7398be7a095ccc108.tar.xz cuberite-f35060e8b518cac8521528a7398be7a095ccc108.tar.zst cuberite-f35060e8b518cac8521528a7398be7a095ccc108.zip |
-rw-r--r-- | src/Blocks/BlockPiston.cpp | 132 | ||||
-rw-r--r-- | 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<Vector3i, VectorHasher<int>> & a_BlocksPushed, NIBBLETYPE a_PistonMeta + std::unordered_set<Vector3i, VectorHasher<int>> & a_BlocksPushed, const Vector3i & a_PushDir ) { const static std::array<Vector3i, 6> 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<Vector3i, VectorHasher<int>> 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<Vector3i> 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<double>(a_BlockX), static_cast<double>(a_BlockY), static_cast<double>(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<Vector3i, VectorHasher<int>> 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<Vector3i> 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<Vector3i, VectorHasher<int>> & a_BlocksPushed, NIBBLETYPE a_PistonMeta + std::unordered_set<Vector3i, VectorHasher<int>> & a_BlocksPushed, const Vector3i & a_PushDir ); } ; |