From d48ce1d10fac9b38f17737ac81bfb686e410e081 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Wed, 20 Nov 2013 22:54:28 +0000 Subject: Multiple bugfixes [SEE DESC] * Fixed compilation on VC2013 * Fixed redstone self powering - still one more scenario to go + Redstone now powers block beneath * Improved code: functionized stuff, and reduced unneeded GetBlockMetas; also utilised direct chunk access, as recommended by xoft + Added torches powering blocks above it * Fixed repeaters getting power when they shouldn't - Stopped wires getting power from another wire through a block, which could lead to wire-powering loops (vanilla behaviour) --- source/Simulator/RedstoneSimulator.cpp | 388 ++++++++++++++++++++++----------- 1 file changed, 263 insertions(+), 125 deletions(-) (limited to 'source/Simulator/RedstoneSimulator.cpp') diff --git a/source/Simulator/RedstoneSimulator.cpp b/source/Simulator/RedstoneSimulator.cpp index 906961490..e9f9eea0c 100644 --- a/source/Simulator/RedstoneSimulator.cpp +++ b/source/Simulator/RedstoneSimulator.cpp @@ -89,7 +89,13 @@ void cRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, c for (PoweredBlocksList::iterator itr = m_PoweredBlocks.begin(); itr != m_PoweredBlocks.end();) { sPoweredBlocks & Change = *itr; - BLOCKTYPE SourceBlockType = m_World.GetBlock(Change.a_SourcePos); + + int RelX = Change.a_SourcePos.x - a_ChunkX * cChunkDef::Width; + int RelZ = Change.a_SourcePos.z - a_ChunkZ * cChunkDef::Width; + + BLOCKTYPE SourceBlockType; + NIBBLETYPE SourceBlockMeta; + a_Chunk->UnboundedRelGetBlock(RelX, Change.a_SourcePos.y, RelZ, SourceBlockType, SourceBlockMeta); if (SourceBlockType != Change.a_SourceBlock) { @@ -97,10 +103,10 @@ void cRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, c } else if ( // Changeable sources - ((SourceBlockType == E_BLOCK_REDSTONE_WIRE) && (m_World.GetBlockMeta(Change.a_SourcePos) == 0)) || - ((SourceBlockType == E_BLOCK_LEVER) && !IsLeverOn(m_World.GetBlockMeta(Change.a_SourcePos))) || - ((SourceBlockType == E_BLOCK_DETECTOR_RAIL) && (m_World.GetBlockMeta(Change.a_SourcePos) & 0x08) == 0x08) || - (((SourceBlockType == E_BLOCK_STONE_BUTTON) || (SourceBlockType == E_BLOCK_WOODEN_BUTTON)) && (!IsButtonOn(m_World.GetBlockMeta(Change.a_SourcePos)))) + ((SourceBlockType == E_BLOCK_REDSTONE_WIRE) && (SourceBlockMeta == 0)) || + ((SourceBlockType == E_BLOCK_LEVER) && !IsLeverOn(SourceBlockMeta)) || + ((SourceBlockType == E_BLOCK_DETECTOR_RAIL) && (SourceBlockMeta & 0x08) == 0x08) || + (((SourceBlockType == E_BLOCK_STONE_BUTTON) || (SourceBlockType == E_BLOCK_WOODEN_BUTTON)) && (!IsButtonOn(SourceBlockMeta))) ) { itr = m_PoweredBlocks.erase(itr); @@ -115,8 +121,17 @@ void cRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, c for (LinkedBlocksList::iterator itr = m_LinkedPoweredBlocks.begin(); itr != m_LinkedPoweredBlocks.end();) { sLinkedPoweredBlocks & Change = *itr; - BLOCKTYPE SourceBlockType = m_World.GetBlock(Change.a_SourcePos); - BLOCKTYPE MiddleBlockType = m_World.GetBlock(Change.a_MiddlePos); + + int RelX = Change.a_SourcePos.x - a_ChunkX * cChunkDef::Width; + int RelZ = Change.a_SourcePos.z - a_ChunkZ * cChunkDef::Width; + int MidRelX = Change.a_MiddlePos.x - a_ChunkX * cChunkDef::Width; + int MidRelZ = Change.a_MiddlePos.z - a_ChunkZ * cChunkDef::Width; + + BLOCKTYPE SourceBlockType; + NIBBLETYPE SourceBlockMeta; + BLOCKTYPE MiddleBlockType; + a_Chunk->UnboundedRelGetBlock(RelX, Change.a_SourcePos.y, RelZ, SourceBlockType, SourceBlockMeta); + a_Chunk->UnboundedRelGetBlockType(MidRelX, Change.a_MiddlePos.y, MidRelZ, MiddleBlockType); if (SourceBlockType != Change.a_SourceBlock) { @@ -128,9 +143,9 @@ void cRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, c } else if ( // Things that can send power through a block but which depends on meta - ((SourceBlockType == E_BLOCK_REDSTONE_WIRE) && (m_World.GetBlockMeta(Change.a_SourcePos) == 0)) || - ((SourceBlockType == E_BLOCK_LEVER) && !IsLeverOn(m_World.GetBlockMeta(Change.a_SourcePos))) || - (((SourceBlockType == E_BLOCK_STONE_BUTTON) || (SourceBlockType == E_BLOCK_WOODEN_BUTTON)) && (!IsButtonOn(m_World.GetBlockMeta(Change.a_SourcePos)))) + ((SourceBlockType == E_BLOCK_REDSTONE_WIRE) && (SourceBlockMeta == 0)) || + ((SourceBlockType == E_BLOCK_LEVER) && !IsLeverOn(SourceBlockMeta)) || + (((SourceBlockType == E_BLOCK_STONE_BUTTON) || (SourceBlockType == E_BLOCK_WOODEN_BUTTON)) && (!IsButtonOn(SourceBlockMeta))) ) { itr = m_LinkedPoweredBlocks.erase(itr); @@ -256,10 +271,12 @@ void cRedstoneSimulator::HandleRedstoneTorch(int a_BlockX, int a_BlockY, int a_B { // Top side, power whatever is there, including blocks SetBlockPowered(a_BlockX + gCrossCoords[i].x, a_BlockY + gCrossCoords[i].y, a_BlockZ + gCrossCoords[i].z, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_TORCH_ON); + // Power all blocks surrounding block above torch + SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_YP, E_BLOCK_REDSTONE_TORCH_ON); } } - if (m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) != 0x5) // Is torch standing on ground? If not (i.e. on wall), power block beneath + if (m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) != 0x5) // Is torch standing on ground? If NOT (i.e. on wall), power block beneath { BLOCKTYPE Type = m_World.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ); @@ -294,25 +311,8 @@ void cRedstoneSimulator::HandleRedstoneTorch(int a_BlockX, int a_BlockY, int a_B void cRedstoneSimulator::HandleRedstoneBlock(int a_BlockX, int a_BlockY, int a_BlockZ) { - static const struct // Define which directions the redstone block can power - { - int x, y, z; - } gCrossCoords[] = - { - { 0, 0, 0}, // Oh, anomalous redstone. Only block that powers itself - { 1, 0, 0}, - {-1, 0, 0}, - { 0, 0, 1}, - { 0, 0, -1}, - { 0, 1, 0}, - { 0,-1, 0}, - } ; - - for (int i = 0; i < ARRAYCOUNT(gCrossCoords); i++) - { - // Power everything - SetBlockPowered(a_BlockX + gCrossCoords[i].x, a_BlockY + gCrossCoords[i].y, a_BlockZ + gCrossCoords[i].z, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_BLOCK_OF_REDSTONE); - } + SetAllDirsAsPowered(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_BLOCK_OF_REDSTONE); + SetBlockPowered(a_BlockX, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_BLOCK_OF_REDSTONE); // Set self as powered return; } @@ -324,24 +324,7 @@ void cRedstoneSimulator::HandleRedstoneLever(int a_BlockX, int a_BlockY, int a_B { if (IsLeverOn(m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ))) { - static const struct // Define which directions the redstone lever can power (all sides) - { - int x, y, z; - } gCrossCoords[] = - { - { 1, 0, 0}, - {-1, 0, 0}, - { 0, 0, 1}, - { 0, 0, -1}, - { 0, 1, 0}, - { 0,-1, 0}, - } ; - - for (int i = 0; i < ARRAYCOUNT(gCrossCoords); i++) - { - // Power everything - SetBlockPowered(a_BlockX + gCrossCoords[i].x, a_BlockY + gCrossCoords[i].y, a_BlockZ + gCrossCoords[i].z, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_LEVER); - } + SetAllDirsAsPowered(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_LEVER); SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_XM, E_BLOCK_LEVER); SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_XP, E_BLOCK_LEVER); @@ -361,24 +344,7 @@ void cRedstoneSimulator::HandleRedstoneButton(int a_BlockX, int a_BlockY, int a_ { if (IsButtonOn(m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ))) { - static const struct // Define which directions the redstone button can power (all sides) - { - int x, y, z; - } gCrossCoords[] = - { - { 1, 0, 0}, - {-1, 0, 0}, - { 0, 0, 1}, - { 0, 0, -1}, - { 0, 1, 0}, - { 0,-1, 0}, - } ; - - for (int i = 0; i < ARRAYCOUNT(gCrossCoords); i++) - { - // Power everything - SetBlockPowered(a_BlockX + gCrossCoords[i].x, a_BlockY + gCrossCoords[i].y, a_BlockZ + gCrossCoords[i].z, a_BlockX, a_BlockY, a_BlockZ, a_BlockType); - } + SetAllDirsAsPowered(a_BlockX, a_BlockY, a_BlockZ, a_BlockType); SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_XM, a_BlockType); SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_XP, a_BlockType); @@ -418,6 +384,7 @@ void cRedstoneSimulator::HandleRedstoneWire(int a_BlockX, int a_BlockY, int a_Bl if (AreCoordsPowered(a_BlockX, a_BlockY, a_BlockZ)) { m_World.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, 15); // Maximum power + SetBlockPowered(a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE); // Power block beneath } else { @@ -456,7 +423,10 @@ void cRedstoneSimulator::HandleRedstoneWire(int a_BlockX, int a_BlockY, int a_Bl // However, self not directly powered anymore, so source must have been removed, // therefore, self must be set to meta zero m_World.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, 0); - } + return; // No need to process block power sets because self not powered + } + + SetBlockPowered(a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE); // Power block beneath } if (m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) != 0) // A powered wire @@ -467,33 +437,14 @@ void cRedstoneSimulator::HandleRedstoneWire(int a_BlockX, int a_BlockY, int a_Bl { case REDSTONE_NONE: { - static const struct // Define which directions the redstone wire can power - { - int x, y, z; - } gCrossCoords[] = - { - { 1, 0, 0}, // Power block in front - { 2, 0, 0}, // Power block in front of that (strongly power) - {-1, 0, 0}, - {-2, 0, 0}, - { 0, 0, 1}, - { 0, 0, 2}, - { 0, 0, -1}, - { 0, 0, -2}, - { 0, 1, 0}, - { 0, 2, 0}, - { 0,-1, 0}, - { 0,-2, 0}, - } ; + SetAllDirsAsPowered(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE); - for (int i = 0; i < ARRAYCOUNT(gCrossCoords); i++) - { - // Power if block is solid, CURRENTLY all mechanisms are solid - if (g_BlockIsSolid[m_World.GetBlock(a_BlockX + gCrossCoords[i].x, a_BlockY + gCrossCoords[i].y, a_BlockZ + gCrossCoords[i].z)]) - { - SetBlockPowered(a_BlockX + gCrossCoords[i].x, a_BlockY + gCrossCoords[i].y, a_BlockZ + gCrossCoords[i].z, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE); - } - } + SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_XM, E_BLOCK_REDSTONE_WIRE); + SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_XP, E_BLOCK_REDSTONE_WIRE); + SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_YM, E_BLOCK_REDSTONE_WIRE); + SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_YP, E_BLOCK_REDSTONE_WIRE); + SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_ZM, E_BLOCK_REDSTONE_WIRE); + SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_ZP, E_BLOCK_REDSTONE_WIRE); break; } case REDSTONE_X_POS: @@ -810,6 +761,8 @@ bool cRedstoneSimulator::IsRepeaterPowered(int a_BlockX, int a_BlockY, int a_Blo { sPoweredBlocks & Change = *itr; + if (!Change.a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) { continue; } + switch (a_Meta) { case 0x0: @@ -841,6 +794,8 @@ bool cRedstoneSimulator::IsRepeaterPowered(int a_BlockX, int a_BlockY, int a_Blo { sLinkedPoweredBlocks & Change = *itr; + if (!Change.a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) { continue; } + switch (a_Meta) { case 0x0: @@ -879,13 +834,39 @@ void cRedstoneSimulator::SetDirectionLinkedPowered(int a_BlockX, int a_BlockY, i case BLOCK_FACE_XM: { BLOCKTYPE MiddleBlock = m_World.GetBlock(a_BlockX - 1, a_BlockY, a_BlockZ); - if (!g_BlockIsSolid[MiddleBlock]) { return; } + if (!g_BlockIsSolid[MiddleBlock]) { return; } // Nothing can link power something through a non-solid block - SetBlockLinkedPowered(a_BlockX - 2, a_BlockY, a_BlockZ, a_BlockX - 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); - SetBlockLinkedPowered(a_BlockX - 1, a_BlockY + 1, a_BlockZ, a_BlockX - 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); - SetBlockLinkedPowered(a_BlockX - 1, a_BlockY - 1, a_BlockZ, a_BlockX - 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); - SetBlockLinkedPowered(a_BlockX - 1, a_BlockY, a_BlockZ + 1, a_BlockX - 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); - SetBlockLinkedPowered(a_BlockX - 1, a_BlockY, a_BlockZ - 1, a_BlockX - 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); + if (a_SourceType == E_BLOCK_REDSTONE_WIRE) // Wires can't power another wire through a block + { + if (m_World.GetBlock(a_BlockX - 2, a_BlockY, a_BlockZ) != E_BLOCK_REDSTONE_WIRE) + { + SetBlockLinkedPowered(a_BlockX - 2, a_BlockY, a_BlockZ, a_BlockX - 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); + } + if (m_World.GetBlock(a_BlockX - 1, a_BlockY + 1, a_BlockZ) != E_BLOCK_REDSTONE_WIRE) + { + SetBlockLinkedPowered(a_BlockX - 1, a_BlockY + 1, a_BlockZ, a_BlockX - 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); + } + if (m_World.GetBlock(a_BlockX - 1, a_BlockY - 1, a_BlockZ) != E_BLOCK_REDSTONE_WIRE) + { + SetBlockLinkedPowered(a_BlockX - 1, a_BlockY - 1, a_BlockZ, a_BlockX - 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); + } + if (m_World.GetBlock(a_BlockX - 1, a_BlockY, a_BlockZ + 1) != E_BLOCK_REDSTONE_WIRE) + { + SetBlockLinkedPowered(a_BlockX - 1, a_BlockY, a_BlockZ + 1, a_BlockX - 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); + } + if (m_World.GetBlock(a_BlockX - 1, a_BlockY, a_BlockZ - 1) != E_BLOCK_REDSTONE_WIRE) + { + SetBlockLinkedPowered(a_BlockX - 1, a_BlockY, a_BlockZ - 1, a_BlockX - 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); + } + } + else + { + SetBlockLinkedPowered(a_BlockX - 2, a_BlockY, a_BlockZ, a_BlockX - 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); + SetBlockLinkedPowered(a_BlockX - 1, a_BlockY + 1, a_BlockZ, a_BlockX - 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); + SetBlockLinkedPowered(a_BlockX - 1, a_BlockY - 1, a_BlockZ, a_BlockX - 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); + SetBlockLinkedPowered(a_BlockX - 1, a_BlockY, a_BlockZ + 1, a_BlockX - 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); + SetBlockLinkedPowered(a_BlockX - 1, a_BlockY, a_BlockZ - 1, a_BlockX - 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); + } break; } case BLOCK_FACE_XP: @@ -893,11 +874,37 @@ void cRedstoneSimulator::SetDirectionLinkedPowered(int a_BlockX, int a_BlockY, i BLOCKTYPE MiddleBlock = m_World.GetBlock(a_BlockX + 1, a_BlockY, a_BlockZ); if (!g_BlockIsSolid[MiddleBlock]) { return; } - SetBlockLinkedPowered(a_BlockX + 2, a_BlockY, a_BlockZ, a_BlockX + 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); - SetBlockLinkedPowered(a_BlockX + 1, a_BlockY + 1, a_BlockZ, a_BlockX + 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); - SetBlockLinkedPowered(a_BlockX + 1, a_BlockY - 1, a_BlockZ, a_BlockX + 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); - SetBlockLinkedPowered(a_BlockX + 1, a_BlockY, a_BlockZ + 1, a_BlockX + 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); - SetBlockLinkedPowered(a_BlockX + 1, a_BlockY, a_BlockZ - 1, a_BlockX + 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); + if (a_SourceType == E_BLOCK_REDSTONE_WIRE) + { + if (m_World.GetBlock(a_BlockX + 2, a_BlockY, a_BlockZ) != E_BLOCK_REDSTONE_WIRE) + { + SetBlockLinkedPowered(a_BlockX + 2, a_BlockY, a_BlockZ, a_BlockX + 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); + } + if (m_World.GetBlock(a_BlockX + 1, a_BlockY + 1, a_BlockZ) != E_BLOCK_REDSTONE_WIRE) + { + SetBlockLinkedPowered(a_BlockX + 1, a_BlockY + 1, a_BlockZ, a_BlockX + 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); + } + if (m_World.GetBlock(a_BlockX + 1, a_BlockY - 1, a_BlockZ) != E_BLOCK_REDSTONE_WIRE) + { + SetBlockLinkedPowered(a_BlockX + 1, a_BlockY - 1, a_BlockZ, a_BlockX + 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); + } + if (m_World.GetBlock(a_BlockX + 1, a_BlockY, a_BlockZ + 1) != E_BLOCK_REDSTONE_WIRE) + { + SetBlockLinkedPowered(a_BlockX + 1, a_BlockY, a_BlockZ + 1, a_BlockX + 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); + } + if (m_World.GetBlock(a_BlockX + 1, a_BlockY, a_BlockZ - 1) != E_BLOCK_REDSTONE_WIRE) + { + SetBlockLinkedPowered(a_BlockX + 1, a_BlockY, a_BlockZ - 1, a_BlockX + 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); + } + } + else + { + SetBlockLinkedPowered(a_BlockX + 2, a_BlockY, a_BlockZ, a_BlockX + 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); + SetBlockLinkedPowered(a_BlockX + 1, a_BlockY + 1, a_BlockZ, a_BlockX + 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); + SetBlockLinkedPowered(a_BlockX + 1, a_BlockY - 1, a_BlockZ, a_BlockX + 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); + SetBlockLinkedPowered(a_BlockX + 1, a_BlockY, a_BlockZ + 1, a_BlockX + 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); + SetBlockLinkedPowered(a_BlockX + 1, a_BlockY, a_BlockZ - 1, a_BlockX + 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); + } break; } case BLOCK_FACE_YM: @@ -905,11 +912,37 @@ void cRedstoneSimulator::SetDirectionLinkedPowered(int a_BlockX, int a_BlockY, i BLOCKTYPE MiddleBlock = m_World.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ); if (!g_BlockIsSolid[MiddleBlock]) { return; } - SetBlockLinkedPowered(a_BlockX, a_BlockY - 2, a_BlockZ, a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); - SetBlockLinkedPowered(a_BlockX + 1, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); - SetBlockLinkedPowered(a_BlockX - 1, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); - SetBlockLinkedPowered(a_BlockX, a_BlockY - 1, a_BlockZ + 1, a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); - SetBlockLinkedPowered(a_BlockX, a_BlockY - 1, a_BlockZ - 1, a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); + if (a_SourceType == E_BLOCK_REDSTONE_WIRE) + { + if (m_World.GetBlock(a_BlockX, a_BlockY - 2, a_BlockZ) != E_BLOCK_REDSTONE_WIRE) + { + SetBlockLinkedPowered(a_BlockX, a_BlockY - 2, a_BlockZ, a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); + } + if (m_World.GetBlock(a_BlockX + 1, a_BlockY - 1, a_BlockZ) != E_BLOCK_REDSTONE_WIRE) + { + SetBlockLinkedPowered(a_BlockX + 1, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); + } + if (m_World.GetBlock(a_BlockX - 1, a_BlockY - 1, a_BlockZ) != E_BLOCK_REDSTONE_WIRE) + { + SetBlockLinkedPowered(a_BlockX - 1, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); + } + if (m_World.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ + 1) != E_BLOCK_REDSTONE_WIRE) + { + SetBlockLinkedPowered(a_BlockX, a_BlockY - 1, a_BlockZ + 1, a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); + } + if (m_World.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ - 1) != E_BLOCK_REDSTONE_WIRE) + { + SetBlockLinkedPowered(a_BlockX, a_BlockY - 1, a_BlockZ - 1, a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); + } + } + else + { + SetBlockLinkedPowered(a_BlockX, a_BlockY - 2, a_BlockZ, a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); + SetBlockLinkedPowered(a_BlockX + 1, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); + SetBlockLinkedPowered(a_BlockX - 1, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); + SetBlockLinkedPowered(a_BlockX, a_BlockY - 1, a_BlockZ + 1, a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); + SetBlockLinkedPowered(a_BlockX, a_BlockY - 1, a_BlockZ - 1, a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); + } break; } case BLOCK_FACE_YP: @@ -917,11 +950,37 @@ void cRedstoneSimulator::SetDirectionLinkedPowered(int a_BlockX, int a_BlockY, i BLOCKTYPE MiddleBlock = m_World.GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ); if (!g_BlockIsSolid[MiddleBlock]) { return; } - SetBlockLinkedPowered(a_BlockX, a_BlockY + 2, a_BlockZ, a_BlockX, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); - SetBlockLinkedPowered(a_BlockX + 1, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); - SetBlockLinkedPowered(a_BlockX - 1, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); - SetBlockLinkedPowered(a_BlockX, a_BlockY + 1, a_BlockZ + 1, a_BlockX, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); - SetBlockLinkedPowered(a_BlockX, a_BlockY + 1, a_BlockZ - 1, a_BlockX, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); + if (a_SourceType == E_BLOCK_REDSTONE_WIRE) + { + if (m_World.GetBlock(a_BlockX, a_BlockY + 2, a_BlockZ) != E_BLOCK_REDSTONE_WIRE) + { + SetBlockLinkedPowered(a_BlockX, a_BlockY + 2, a_BlockZ, a_BlockX, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); + } + if (m_World.GetBlock(a_BlockX + 1, a_BlockY + 1, a_BlockZ) != E_BLOCK_REDSTONE_WIRE) + { + SetBlockLinkedPowered(a_BlockX + 1, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); + } + if (m_World.GetBlock(a_BlockX - 1, a_BlockY + 1, a_BlockZ) != E_BLOCK_REDSTONE_WIRE) + { + SetBlockLinkedPowered(a_BlockX - 1, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); + } + if (m_World.GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ + 1) != E_BLOCK_REDSTONE_WIRE) + { + SetBlockLinkedPowered(a_BlockX, a_BlockY + 1, a_BlockZ + 1, a_BlockX, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); + } + if (m_World.GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ - 1) != E_BLOCK_REDSTONE_WIRE) + { + SetBlockLinkedPowered(a_BlockX, a_BlockY + 1, a_BlockZ - 1, a_BlockX, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); + } + } + else + { + SetBlockLinkedPowered(a_BlockX, a_BlockY + 2, a_BlockZ, a_BlockX, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); + SetBlockLinkedPowered(a_BlockX + 1, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); + SetBlockLinkedPowered(a_BlockX - 1, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); + SetBlockLinkedPowered(a_BlockX, a_BlockY + 1, a_BlockZ + 1, a_BlockX, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); + SetBlockLinkedPowered(a_BlockX, a_BlockY + 1, a_BlockZ - 1, a_BlockX, a_BlockY + 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); + } break; } case BLOCK_FACE_ZM: @@ -929,11 +988,37 @@ void cRedstoneSimulator::SetDirectionLinkedPowered(int a_BlockX, int a_BlockY, i BLOCKTYPE MiddleBlock = m_World.GetBlock(a_BlockX, a_BlockY, a_BlockZ - 1); if (!g_BlockIsSolid[MiddleBlock]) { return; } - SetBlockLinkedPowered(a_BlockX, a_BlockY, a_BlockZ - 2, a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); - SetBlockLinkedPowered(a_BlockX + 1, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); - SetBlockLinkedPowered(a_BlockX - 1, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); - SetBlockLinkedPowered(a_BlockX, a_BlockY + 1, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); - SetBlockLinkedPowered(a_BlockX, a_BlockY - 1, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); + if (a_SourceType == E_BLOCK_REDSTONE_WIRE) + { + if (m_World.GetBlock(a_BlockX, a_BlockY, a_BlockZ - 2) != E_BLOCK_REDSTONE_WIRE) + { + SetBlockLinkedPowered(a_BlockX, a_BlockY, a_BlockZ - 2, a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); + } + if (m_World.GetBlock(a_BlockX + 1, a_BlockY, a_BlockZ - 1) != E_BLOCK_REDSTONE_WIRE) + { + SetBlockLinkedPowered(a_BlockX + 1, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); + } + if (m_World.GetBlock(a_BlockX - 1, a_BlockY, a_BlockZ - 1) != E_BLOCK_REDSTONE_WIRE) + { + SetBlockLinkedPowered(a_BlockX - 1, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); + } + if (m_World.GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ - 1) != E_BLOCK_REDSTONE_WIRE) + { + SetBlockLinkedPowered(a_BlockX, a_BlockY + 1, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); + } + if (m_World.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ - 1) != E_BLOCK_REDSTONE_WIRE) + { + SetBlockLinkedPowered(a_BlockX, a_BlockY - 1, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); + } + } + else + { + SetBlockLinkedPowered(a_BlockX, a_BlockY, a_BlockZ - 2, a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); + SetBlockLinkedPowered(a_BlockX + 1, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); + SetBlockLinkedPowered(a_BlockX - 1, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); + SetBlockLinkedPowered(a_BlockX, a_BlockY + 1, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); + SetBlockLinkedPowered(a_BlockX, a_BlockY - 1, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); + } break; } case BLOCK_FACE_ZP: @@ -941,16 +1026,42 @@ void cRedstoneSimulator::SetDirectionLinkedPowered(int a_BlockX, int a_BlockY, i BLOCKTYPE MiddleBlock = m_World.GetBlock(a_BlockX, a_BlockY, a_BlockZ + 1); if (!g_BlockIsSolid[MiddleBlock]) { return; } - SetBlockLinkedPowered(a_BlockX, a_BlockY, a_BlockZ + 2, a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); - SetBlockLinkedPowered(a_BlockX + 1, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); - SetBlockLinkedPowered(a_BlockX - 1, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); - SetBlockLinkedPowered(a_BlockX, a_BlockY + 1, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); - SetBlockLinkedPowered(a_BlockX, a_BlockY - 1, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); + if (a_SourceType == E_BLOCK_REDSTONE_WIRE) + { + if (m_World.GetBlock(a_BlockX, a_BlockY, a_BlockZ + 2) != E_BLOCK_REDSTONE_WIRE) + { + SetBlockLinkedPowered(a_BlockX, a_BlockY, a_BlockZ + 2, a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); + } + if (m_World.GetBlock(a_BlockX + 1, a_BlockY, a_BlockZ + 1) != E_BLOCK_REDSTONE_WIRE) + { + SetBlockLinkedPowered(a_BlockX + 1, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); + } + if (m_World.GetBlock(a_BlockX - 1, a_BlockY, a_BlockZ + 1) != E_BLOCK_REDSTONE_WIRE) + { + SetBlockLinkedPowered(a_BlockX - 1, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); + } + if (m_World.GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ + 1) != E_BLOCK_REDSTONE_WIRE) + { + SetBlockLinkedPowered(a_BlockX, a_BlockY + 1, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); + } + if (m_World.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ + 1) != E_BLOCK_REDSTONE_WIRE) + { + SetBlockLinkedPowered(a_BlockX, a_BlockY - 1, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); + } + } + else + { + SetBlockLinkedPowered(a_BlockX, a_BlockY, a_BlockZ + 2, a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); + SetBlockLinkedPowered(a_BlockX + 1, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); + SetBlockLinkedPowered(a_BlockX - 1, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); + SetBlockLinkedPowered(a_BlockX, a_BlockY + 1, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); + SetBlockLinkedPowered(a_BlockX, a_BlockY - 1, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, a_SourceType, MiddleBlock); + } break; } default: { - ASSERT(!"Unhandled face direction when attempting to set blocks as linked powered!"); + ASSERT(!"Unhandled face direction when attempting to set blocks as linked powered!"); // Zombies, that wasn't supposed to happen... break; } } @@ -961,8 +1072,34 @@ void cRedstoneSimulator::SetDirectionLinkedPowered(int a_BlockX, int a_BlockY, i +void cRedstoneSimulator::SetAllDirsAsPowered(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_SourceBlock) +{ + static const struct // Define which directions the torch can power + { + int x, y, z; + } gCrossCoords[] = + { + { 1, 0, 0 }, + {-1, 0, 0 }, + { 0, 0, 1 }, + { 0, 0,-1 }, + { 0, 1, 0 }, + }; + + for (int i = 0; i < ARRAYCOUNT(gCrossCoords); i++) + { + SetBlockPowered(a_BlockX + gCrossCoords[i].x, a_BlockY + gCrossCoords[i].y, a_BlockZ + gCrossCoords[i].z, a_BlockX, a_BlockY, a_BlockZ, a_SourceBlock); + } + return; +} + + + + + void cRedstoneSimulator::SetBlockPowered(int a_BlockX, int a_BlockY, int a_BlockZ, int a_SourceX, int a_SourceY, int a_SourceZ, BLOCKTYPE a_SourceBlock) { + if (m_World.GetBlock(a_BlockX, a_BlockY, a_BlockZ) == E_BLOCK_AIR) { return; } // Don't set air, fixes some bugs (wires powering themselves) if (AreCoordsPowered(a_BlockX, a_BlockY, a_BlockZ)) { return; } // Check for duplicates sPoweredBlocks RC; @@ -983,6 +1120,7 @@ void cRedstoneSimulator::SetBlockLinkedPowered(int a_BlockX, int a_BlockY, int a BLOCKTYPE a_SourceBlock, BLOCKTYPE a_MiddleBlock ) { + if (m_World.GetBlock(a_BlockX, a_BlockY, a_BlockZ) == E_BLOCK_AIR) { return; } // Don't set air, fixes some bugs (wires powering themselves) if (AreCoordsPowered(a_BlockX, a_BlockY, a_BlockZ)) { return; } // Check for duplicates sLinkedPoweredBlocks RC; -- cgit v1.2.3