示例#1
0
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);
}
示例#2
0
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;
}
示例#3
0
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;
}
示例#4
0
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);
}