bool cPiston::CanPull(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) { switch (a_BlockType) { case E_BLOCK_LAVA: case E_BLOCK_STATIONARY_LAVA: case E_BLOCK_STATIONARY_WATER: case E_BLOCK_WATER: { return false; } } if (CanBreakPush(a_BlockType, a_BlockMeta)) { return false; // CanBreakPush returns true, but we need false to prevent pulling } return CanPush(a_BlockType, a_BlockMeta); }
int cBlockPistonHandler::FirstPassthroughBlock(int a_PistonX, int a_PistonY, int a_PistonZ, NIBBLETYPE pistonmeta, cWorld * a_World) { // Examine each of the 12 blocks ahead of the piston: for (int ret = 0; ret < PISTON_MAX_PUSH_DISTANCE; ret++) { 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; } } // There is no space for the blocks to move, piston can't extend return -1; }
int cPiston::FirstPassthroughBlock(int pistonX, int pistonY, int pistonZ, NIBBLETYPE pistonmeta) { // Examine each of the 12 blocks ahead of the piston: for (int ret = 0; ret < 12; ret++) { BLOCKTYPE currBlock; NIBBLETYPE currMeta; AddDir(pistonX, pistonY, pistonZ, pistonmeta, 1); m_World->GetBlockTypeMeta(pistonX, pistonY, pistonZ, currBlock, currMeta); if (CanBreakPush(currBlock, currMeta)) { // 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; } } // There is no space for the blocks to move, piston can't extend return -1; }
bool cBlockPistonHandler::CanPushBlock( const Vector3i & a_BlockPos, cWorld * a_World, bool a_RequirePushable, Vector3iSet & 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), Vector3i( 0, 0, -1), Vector3i(0, 0, 1) } }; BLOCKTYPE currBlock; NIBBLETYPE currMeta; a_World->GetBlockTypeMeta(a_BlockPos.x, a_BlockPos.y, a_BlockPos.z, currBlock, currMeta); if (currBlock == E_BLOCK_AIR) { // Air can be pushed 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)) { // 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; } if (!a_BlocksPushed.insert(a_BlockPos).second || cBlockInfo::IsPistonBreakable(currBlock)) { return true; // Element exist already } if (currBlock == E_BLOCK_SLIME_BLOCK) { // Try to push the other directions for (const auto & testDir : pushingDirs) { if (!CanPushBlock(a_BlockPos + testDir, 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_BlockPos + a_PushDir, a_World, true, a_BlocksPushed, a_PushDir); }