Pistons no longer accept power through front face

This fixes #60.
master
Tiger Wang 2013-11-30 12:11:39 +00:00
parent ab382ef6b4
commit 455686e3ad
2 changed files with 96 additions and 3 deletions

View File

@ -566,7 +566,7 @@ void cRedstoneSimulator::HandleRedstoneRepeater(int a_BlockX, int a_BlockY, int
void cRedstoneSimulator::HandlePiston(int a_BlockX, int a_BlockY, int a_BlockZ)
{
cPiston Piston(&m_World);
if (AreCoordsPowered(a_BlockX, a_BlockY, a_BlockZ))
if (IsPistonPowered(a_BlockX, a_BlockY, a_BlockZ, m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) & 0x7)) // We only want the bottom three bits (4th controls extended-ness)
{
Piston.ExtendPiston(a_BlockX, a_BlockY, a_BlockZ);
}
@ -774,7 +774,8 @@ bool cRedstoneSimulator::AreCoordsPowered(int a_BlockX, int a_BlockY, int a_Bloc
bool cRedstoneSimulator::IsRepeaterPowered(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_Meta)
{
// Check through powered blocks list
// Repeaters cannot be powered by any face except their back; verify that this is true for a source
for (PoweredBlocksList::iterator itr = m_PoweredBlocks.begin(); itr != m_PoweredBlocks.end(); ++itr)
{
sPoweredBlocks & Change = *itr;
@ -807,7 +808,6 @@ bool cRedstoneSimulator::IsRepeaterPowered(int a_BlockX, int a_BlockY, int a_Blo
}
}
// Check linked powered list, 'middle' blocks
for (LinkedBlocksList::iterator itr = m_LinkedPoweredBlocks.begin(); itr != m_LinkedPoweredBlocks.end(); ++itr)
{
sLinkedPoweredBlocks & Change = *itr;
@ -844,6 +844,97 @@ bool cRedstoneSimulator::IsRepeaterPowered(int a_BlockX, int a_BlockY, int a_Blo
bool cRedstoneSimulator::IsPistonPowered(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_Meta)
{
// Pistons cannot be powered through their front face; this function verifies that a source meets this requirement
for (PoweredBlocksList::iterator itr = m_PoweredBlocks.begin(); itr != m_PoweredBlocks.end(); ++itr)
{
sPoweredBlocks & Change = *itr;
if (!Change.a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) { continue; }
switch (a_Meta) // Pistons' metas are the directions they face; the source cannot be there
{
case BLOCK_FACE_YM:
{
if (!Change.a_SourcePos.Equals(Vector3i(a_BlockX, a_BlockY - 1, a_BlockZ))) { return true; }
break;
}
case BLOCK_FACE_YP:
{
if (!Change.a_SourcePos.Equals(Vector3i(a_BlockX, a_BlockY + 1, a_BlockZ))) { return true; }
break;
}
case BLOCK_FACE_ZM:
{
if (!Change.a_SourcePos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ - 1))) { return true; }
break;
}
case BLOCK_FACE_ZP:
{
if (!Change.a_SourcePos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ + 1))) { return true; }
break;
}
case BLOCK_FACE_XM:
{
if (!Change.a_SourcePos.Equals(Vector3i(a_BlockX - 1, a_BlockY, a_BlockZ))) { return true; }
break;
}
case BLOCK_FACE_XP:
{
if (!Change.a_SourcePos.Equals(Vector3i(a_BlockX + 1, a_BlockY, a_BlockZ))) { return true; }
break;
}
}
}
for (LinkedBlocksList::iterator itr = m_LinkedPoweredBlocks.begin(); itr != m_LinkedPoweredBlocks.end(); ++itr)
{
sLinkedPoweredBlocks & Change = *itr;
if (!Change.a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) { continue; }
switch (a_Meta)
{
case BLOCK_FACE_YM:
{
if (!Change.a_MiddlePos.Equals(Vector3i(a_BlockX, a_BlockY - 1, a_BlockZ))) { return true; }
break;
}
case BLOCK_FACE_YP:
{
if (!Change.a_MiddlePos.Equals(Vector3i(a_BlockX, a_BlockY + 1, a_BlockZ))) { return true; }
break;
}
case BLOCK_FACE_ZM:
{
if (!Change.a_MiddlePos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ - 1))) { return true; }
break;
}
case BLOCK_FACE_ZP:
{
if (!Change.a_MiddlePos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ + 1))) { return true; }
break;
}
case BLOCK_FACE_XM:
{
if (!Change.a_MiddlePos.Equals(Vector3i(a_BlockX - 1, a_BlockY, a_BlockZ))) { return true; }
break;
}
case BLOCK_FACE_XP:
{
if (!Change.a_MiddlePos.Equals(Vector3i(a_BlockX + 1, a_BlockY, a_BlockZ))) { return true; }
break;
}
}
}
return false; // Source was in front of the piston's front face
}
void cRedstoneSimulator::SetDirectionLinkedPowered(int a_BlockX, int a_BlockY, int a_BlockZ, char a_Direction, BLOCKTYPE a_SourceType)
{

View File

@ -111,6 +111,8 @@ private:
bool AreCoordsPowered(int a_BlockX, int a_BlockY, int a_BlockZ);
/// <summary>Returns if a repeater is powered</summary>
bool IsRepeaterPowered(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_Meta);
/// <summary>Returns if a piston is powered</summary>
bool IsPistonPowered(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_Meta);
/// <summary>Returns if lever metadata marks it as emitting power</summary>
bool IsLeverOn(NIBBLETYPE a_BlockMeta);