From d48ce1d10fac9b38f17737ac81bfb686e410e081 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Wed, 20 Nov 2013 22:54:28 +0000 Subject: [PATCH 01/12] 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) --- VC2013/MCServer.vcxproj | 1 + VC2013/MCServer.vcxproj.filters | 3 + source/Simulator/RedstoneSimulator.cpp | 388 +++++++++++++++++-------- source/Simulator/RedstoneSimulator.h | 16 +- 4 files changed, 282 insertions(+), 126 deletions(-) diff --git a/VC2013/MCServer.vcxproj b/VC2013/MCServer.vcxproj index cd9f6eb4f..b69867a99 100644 --- a/VC2013/MCServer.vcxproj +++ b/VC2013/MCServer.vcxproj @@ -568,6 +568,7 @@ + diff --git a/VC2013/MCServer.vcxproj.filters b/VC2013/MCServer.vcxproj.filters index c37f00958..2a752bcdc 100644 --- a/VC2013/MCServer.vcxproj.filters +++ b/VC2013/MCServer.vcxproj.filters @@ -1651,6 +1651,9 @@ Source Files\HTTPServer + + Source Files\BlockEntities + 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; diff --git a/source/Simulator/RedstoneSimulator.h b/source/Simulator/RedstoneSimulator.h index d68c6daeb..ab88f51e2 100644 --- a/source/Simulator/RedstoneSimulator.h +++ b/source/Simulator/RedstoneSimulator.h @@ -97,14 +97,23 @@ private: /* ===================== */ /* ====== Helper functions ====== */ + ///Marks a block as powered void SetBlockPowered(int a_BlockX, int a_BlockY, int a_BlockZ, int a_SourceX, int a_SourceY, int a_SourceZ, BLOCKTYPE a_SourceBlock); + ///Marks a block as being powered through another block void SetBlockLinkedPowered(int a_BlockX, int a_BlockY, int a_BlockZ, int a_MiddleX, int a_MiddleY, int a_MiddleZ, int a_SourceX, int a_SourceY, int a_SourceZ, BLOCKTYPE a_SourceBlock, BLOCKTYPE a_MiddeBlock); - void SetDirectionLinkedPowered(int a_BlockX, int a_BlockY, int a_BlockZ, char a_Direction, BLOCKTYPE a_SourceType); + ///Marks the second block in a direction as linked powered + void SetDirectionLinkedPowered(int a_BlockX, int a_BlockY, int a_BlockZ, char a_Direction, BLOCKTYPE a_SourceBlock); + ///Marks all blocks immediately surrounding a coordinate as powered + void SetAllDirsAsPowered(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_SourceBlock); + ///Returns if a coordiante is powered or linked powered bool AreCoordsPowered(int a_BlockX, int a_BlockY, int a_BlockZ); + ///Returns if a repeater is powered bool IsRepeaterPowered(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_Meta); + ///Returns if lever metadata marks it as emitting power bool IsLeverOn(NIBBLETYPE a_BlockMeta); + ///Returns if button metadata marks it as emitting power bool IsButtonOn(NIBBLETYPE a_BlockMeta); /* ============================== */ @@ -112,11 +121,16 @@ private: { switch (Block) { + case E_BLOCK_ACTIVATOR_RAIL: case E_BLOCK_PISTON: case E_BLOCK_STICKY_PISTON: case E_BLOCK_DISPENSER: case E_BLOCK_DROPPER: + case E_BLOCK_FENCE_GATE: + case E_BLOCK_HOPPER: + case E_BLOCK_NOTE_BLOCK: case E_BLOCK_TNT: + case E_BLOCK_TRAPDOOR: case E_BLOCK_REDSTONE_LAMP_OFF: case E_BLOCK_REDSTONE_LAMP_ON: case E_BLOCK_WOODEN_DOOR: From 314884d9bbd5ec1edf0ec473a1c29b493964f955 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Thu, 21 Nov 2013 22:44:18 +0000 Subject: [PATCH 02/12] Multiple enhancements [SEE DESC] + Added lever location checking * Fixed button location checking * Fixed button pressing/unpressing * Fixed repeaters updating * Minor enhancements --- source/Blocks/BlockButton.cpp | 4 +- source/Blocks/BlockButton.h | 7 +- source/Blocks/BlockLever.cpp | 2 +- source/Blocks/BlockLever.h | 47 +++++++++++-- source/Simulator/RedstoneSimulator.cpp | 91 ++++++++++---------------- source/Simulator/RedstoneSimulator.h | 27 +++++++- 6 files changed, 108 insertions(+), 70 deletions(-) diff --git a/source/Blocks/BlockButton.cpp b/source/Blocks/BlockButton.cpp index 19b055b62..a48e82f4d 100644 --- a/source/Blocks/BlockButton.cpp +++ b/source/Blocks/BlockButton.cpp @@ -18,13 +18,13 @@ cBlockButtonHandler::cBlockButtonHandler(BLOCKTYPE a_BlockType) void cBlockButtonHandler::OnUse(cWorld *a_World, cPlayer *a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) { // Flip the ON bit on/off using the XOR bitwise operation - NIBBLETYPE Meta = ((a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) ^ 0x08) & 0x0f); + NIBBLETYPE Meta = (a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) | 0x08); a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, Meta); a_World->BroadcastSoundEffect("random.click", a_BlockX * 8, a_BlockY * 8, a_BlockZ * 8, 0.5f, (Meta & 0x08) ? 0.6f : 0.5f); // Queue a button reset (unpress) - a_World->QueueSetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, ((a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) ^ 0x08) & 0x0f), m_BlockType == E_BLOCK_STONE_BUTTON ? 20 : 30); + a_World->QueueSetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, (a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) & 0x07), m_BlockType == E_BLOCK_STONE_BUTTON ? 20 : 30); } diff --git a/source/Blocks/BlockButton.h b/source/Blocks/BlockButton.h index 15649acc0..e2c60002b 100644 --- a/source/Blocks/BlockButton.h +++ b/source/Blocks/BlockButton.h @@ -81,10 +81,13 @@ public: virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override { - NIBBLETYPE Meta = a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ); + NIBBLETYPE Meta; + a_Chunk.UnboundedRelGetBlockMeta(a_RelX, a_RelY, a_RelZ, Meta); AddFaceDirection(a_RelX, a_RelY, a_RelZ, BlockMetaDataToBlockFace(Meta), true); - return (a_RelY > 0) && (g_BlockIsSolid[a_Chunk.GetBlock(a_RelX, a_RelY, a_RelZ)]); + BLOCKTYPE BlockIsOn; a_Chunk.UnboundedRelGetBlockType(a_RelX, a_RelY, a_RelZ, BlockIsOn); + + return (a_RelY > 0) && (g_BlockIsSolid[BlockIsOn]); } } ; diff --git a/source/Blocks/BlockLever.cpp b/source/Blocks/BlockLever.cpp index 2739fa3a9..c482b0246 100644 --- a/source/Blocks/BlockLever.cpp +++ b/source/Blocks/BlockLever.cpp @@ -20,7 +20,7 @@ cBlockLeverHandler::cBlockLeverHandler(BLOCKTYPE a_BlockType) void cBlockLeverHandler::OnUse(cWorld *a_World, cPlayer *a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) { // Flip the ON bit on/off using the XOR bitwise operation - NIBBLETYPE Meta = ((a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) ^ 0x08) & 0x0f); + NIBBLETYPE Meta = (a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) ^ 0x08); a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, Meta); a_World->BroadcastSoundEffect("random.click", a_BlockX * 8, a_BlockY * 8, a_BlockZ * 8, 0.5f, (Meta & 0x08) ? 0.6f : 0.5f); diff --git a/source/Blocks/BlockLever.h b/source/Blocks/BlockLever.h index fe7ecdf7e..5e6a3bd1e 100644 --- a/source/Blocks/BlockLever.h +++ b/source/Blocks/BlockLever.h @@ -46,13 +46,13 @@ public: // Determine lever direction: switch (a_Dir) { - case BLOCK_FACE_TOP: return 0x6; - case BLOCK_FACE_EAST: return 0x1; - case BLOCK_FACE_WEST: return 0x2; - case BLOCK_FACE_SOUTH: return 0x3; - case BLOCK_FACE_NORTH: return 0x4; - case BLOCK_FACE_BOTTOM: return 0x0; - default: return 0x6; + case BLOCK_FACE_YP: return 0x6; + case BLOCK_FACE_XP: return 0x1; + case BLOCK_FACE_XM: return 0x2; + case BLOCK_FACE_ZP: return 0x3; + case BLOCK_FACE_ZM: return 0x4; + case BLOCK_FACE_YM: return 0x0; + default: return 0x6; } } @@ -61,6 +61,39 @@ public: { return "step.wood"; } + + + inline static NIBBLETYPE BlockMetaDataToBlockFace(NIBBLETYPE a_Meta) + { + switch (a_Meta & 0x7) + { + case 0x1: return BLOCK_FACE_XP; + case 0x2: return BLOCK_FACE_XM; + case 0x3: return BLOCK_FACE_ZP; + case 0x4: return BLOCK_FACE_ZM; + case 0x5: + case 0x6: return BLOCK_FACE_YP; + case 0x7: + case 0x0: return BLOCK_FACE_YM; + default: + { + ASSERT(!"Unhandled block meta!"); + return BLOCK_FACE_NONE; + } + } + } + + + virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override + { + NIBBLETYPE Meta; + a_Chunk.UnboundedRelGetBlockMeta(a_RelX, a_RelY, a_RelZ, Meta); + + AddFaceDirection(a_RelX, a_RelY, a_RelZ, BlockMetaDataToBlockFace(Meta), true); + BLOCKTYPE BlockIsOn; a_Chunk.UnboundedRelGetBlockType(a_RelX, a_RelY, a_RelZ, BlockIsOn); + + return (a_RelY > 0) && (g_BlockIsSolid[BlockIsOn]); + } } ; diff --git a/source/Simulator/RedstoneSimulator.cpp b/source/Simulator/RedstoneSimulator.cpp index e9f9eea0c..15d954313 100644 --- a/source/Simulator/RedstoneSimulator.cpp +++ b/source/Simulator/RedstoneSimulator.cpp @@ -85,7 +85,7 @@ void cRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, c continue; } - // Check to see if PoweredBlocks have invalid items (source is air or an unpowered source) + // Check to see if PoweredBlocks have invalid items (source is air or unpowered) for (PoweredBlocksList::iterator itr = m_PoweredBlocks.begin(); itr != m_PoweredBlocks.end();) { sPoweredBlocks & Change = *itr; @@ -494,47 +494,46 @@ void cRedstoneSimulator::HandleRedstoneWire(int a_BlockX, int a_BlockY, int a_Bl void cRedstoneSimulator::HandleRedstoneRepeater(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyState) { + // We do this so that the repeater can continually update block power status (without being affected by it's own block type, which would happen if the block powering code was in an IF statement) + bool IsOn = false; + if (a_MyState == E_BLOCK_REDSTONE_REPEATER_ON) { IsOn = true; } + NIBBLETYPE a_Meta = m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); - if (a_MyState == E_BLOCK_REDSTONE_REPEATER_OFF) + + if (IsRepeaterPowered(a_BlockX, a_BlockY, a_BlockZ, a_Meta & 0x3)) { - if (IsRepeaterPowered(a_BlockX, a_BlockY, a_BlockZ, a_Meta & 0x3)) + if (!IsOn) { m_World.SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_REPEATER_ON, a_Meta); } // Only set if not on; SetBlock otherwise server doesn't set it in time for SimulateChunk's invalidation + switch (a_Meta & 0x3) // We only want the direction (bottom) bits { - m_World.FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_REPEATER_ON, a_Meta); - switch (a_Meta & 0x3) // We only want the direction (bottom) bits + case 0x0: { - case 0x0: - { - SetBlockPowered(a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_REPEATER_ON); - SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_ZM, E_BLOCK_REDSTONE_REPEATER_ON); - break; - } - case 0x1: - { - SetBlockPowered(a_BlockX + 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_REPEATER_ON); - SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_XP, E_BLOCK_REDSTONE_REPEATER_ON); - break; - } - case 0x2: - { - SetBlockPowered(a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_REPEATER_ON); - SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_ZP, E_BLOCK_REDSTONE_REPEATER_ON); - break; - } - case 0x3: - { - SetBlockPowered(a_BlockX - 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_REPEATER_ON); - SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_XM, E_BLOCK_REDSTONE_REPEATER_ON); - break; - } + SetBlockPowered(a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_REPEATER_ON); + SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_ZM, E_BLOCK_REDSTONE_REPEATER_ON); + break; + } + case 0x1: + { + SetBlockPowered(a_BlockX + 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_REPEATER_ON); + SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_XP, E_BLOCK_REDSTONE_REPEATER_ON); + break; + } + case 0x2: + { + SetBlockPowered(a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_REPEATER_ON); + SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_ZP, E_BLOCK_REDSTONE_REPEATER_ON); + break; + } + case 0x3: + { + SetBlockPowered(a_BlockX - 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_REPEATER_ON); + SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_XM, E_BLOCK_REDSTONE_REPEATER_ON); + break; } } } else { - if (!IsRepeaterPowered(a_BlockX, a_BlockY, a_BlockZ, a_Meta & 0x3)) - { - m_World.FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_REPEATER_OFF, a_Meta); - } + if (IsOn) { m_World.FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_REPEATER_OFF, a_Meta); } } return; } @@ -685,24 +684,7 @@ void cRedstoneSimulator::HandleRail(int a_BlockX, int a_BlockY, int a_BlockZ, BL { if ((m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) & 0x08) == 0x08) { - static const struct // Define which directions the rail 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_MyType); - } + SetAllDirsAsPowered(a_BlockX, a_BlockY, a_BlockZ, a_MyType); } break; } @@ -834,7 +816,6 @@ 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; } // Nothing can link power something through a non-solid block if (a_SourceType == E_BLOCK_REDSTONE_WIRE) // Wires can't power another wire through a block { @@ -872,7 +853,6 @@ void cRedstoneSimulator::SetDirectionLinkedPowered(int a_BlockX, int a_BlockY, i case BLOCK_FACE_XP: { BLOCKTYPE MiddleBlock = m_World.GetBlock(a_BlockX + 1, a_BlockY, a_BlockZ); - if (!g_BlockIsSolid[MiddleBlock]) { return; } if (a_SourceType == E_BLOCK_REDSTONE_WIRE) { @@ -910,7 +890,6 @@ void cRedstoneSimulator::SetDirectionLinkedPowered(int a_BlockX, int a_BlockY, i case BLOCK_FACE_YM: { BLOCKTYPE MiddleBlock = m_World.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ); - if (!g_BlockIsSolid[MiddleBlock]) { return; } if (a_SourceType == E_BLOCK_REDSTONE_WIRE) { @@ -948,7 +927,6 @@ void cRedstoneSimulator::SetDirectionLinkedPowered(int a_BlockX, int a_BlockY, i case BLOCK_FACE_YP: { BLOCKTYPE MiddleBlock = m_World.GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ); - if (!g_BlockIsSolid[MiddleBlock]) { return; } if (a_SourceType == E_BLOCK_REDSTONE_WIRE) { @@ -986,7 +964,6 @@ void cRedstoneSimulator::SetDirectionLinkedPowered(int a_BlockX, int a_BlockY, i case BLOCK_FACE_ZM: { BLOCKTYPE MiddleBlock = m_World.GetBlock(a_BlockX, a_BlockY, a_BlockZ - 1); - if (!g_BlockIsSolid[MiddleBlock]) { return; } if (a_SourceType == E_BLOCK_REDSTONE_WIRE) { @@ -1024,7 +1001,6 @@ void cRedstoneSimulator::SetDirectionLinkedPowered(int a_BlockX, int a_BlockY, i case BLOCK_FACE_ZP: { BLOCKTYPE MiddleBlock = m_World.GetBlock(a_BlockX, a_BlockY, a_BlockZ + 1); - if (!g_BlockIsSolid[MiddleBlock]) { return; } if (a_SourceType == E_BLOCK_REDSTONE_WIRE) { @@ -1122,6 +1098,7 @@ void cRedstoneSimulator::SetBlockLinkedPowered(int a_BlockX, int a_BlockY, int a { 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 + if (!IsViableMiddleBlock(m_World.GetBlock(a_MiddleX, a_MiddleY, a_MiddleZ))) { return; } // See if middle block is viable sLinkedPoweredBlocks RC; RC.a_BlockPos = Vector3i(a_BlockX, a_BlockY, a_BlockZ); diff --git a/source/Simulator/RedstoneSimulator.h b/source/Simulator/RedstoneSimulator.h index ab88f51e2..10d87505c 100644 --- a/source/Simulator/RedstoneSimulator.h +++ b/source/Simulator/RedstoneSimulator.h @@ -106,7 +106,7 @@ private: ///Marks all blocks immediately surrounding a coordinate as powered void SetAllDirsAsPowered(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_SourceBlock); - ///Returns if a coordiante is powered or linked powered + ///Returns if a coordinate is powered or linked powered bool AreCoordsPowered(int a_BlockX, int a_BlockY, int a_BlockZ); ///Returns if a repeater is powered bool IsRepeaterPowered(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_Meta); @@ -117,6 +117,29 @@ private: bool IsButtonOn(NIBBLETYPE a_BlockMeta); /* ============================== */ + /* ====== Misc Functions ====== */ + + ///Returns if a block is viable to be the MiddleBlock of a SetLinkedPowered operation + inline static bool IsViableMiddleBlock(BLOCKTYPE Block) + { + if (!g_BlockIsSolid[Block]) { return false; } + + switch (Block) + { + // Add SOLID but not viable middle blocks here + case E_BLOCK_REDSTONE_REPEATER_ON: + case E_BLOCK_REDSTONE_REPEATER_OFF: + { + return false; + } + default: + { + return true; + } + } + } + + ///Returns if a block is a mechanism (something that accepts power and does something) inline static bool IsMechanism(BLOCKTYPE Block) { switch (Block) @@ -145,6 +168,7 @@ private: } } + ///Returns if a block has the potential to output power inline static bool IsPotentialSource(BLOCKTYPE Block) { switch (Block) @@ -167,6 +191,7 @@ private: } } + ///Returns if a block is any sort of redstone device inline static bool IsRedstone(BLOCKTYPE Block) { switch (Block) From c7d55d8bbdcf08bd8f5a4b613f8931f63bc90470 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Fri, 22 Nov 2013 21:57:06 +0000 Subject: [PATCH 03/12] Fixed spawning pickups with piston arms --- source/Blocks/BlockPiston.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source/Blocks/BlockPiston.cpp b/source/Blocks/BlockPiston.cpp index d5750ebdd..42d7e8d35 100644 --- a/source/Blocks/BlockPiston.cpp +++ b/source/Blocks/BlockPiston.cpp @@ -93,6 +93,11 @@ void cBlockPistonHeadHandler::OnDestroyedByPlayer(cWorld * a_World, cPlayer * a_ if ((Block == E_BLOCK_STICKY_PISTON) || (Block == E_BLOCK_PISTON)) { a_World->DigBlock(newX, newY, newZ); + if (a_Player->IsGameModeCreative()) { return; } // No pickups if creative + + cItems Pickups; + Pickups.push_back(cItem(Block, 1)); + a_World->SpawnItemPickups(Pickups, a_BlockX + 0.5, a_BlockY + 0.5, a_BlockZ + 0.5); } } From e40b3845474aec799ad28021763f93160f9c8c0b Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Fri, 22 Nov 2013 22:00:37 +0000 Subject: [PATCH 04/12] Fixed some piston bugs Due to our QueueSetBlocks, a fast extension then retraction would lead to invalid game states. This hopefully fixes it. Also reduced delay speed. --- source/Piston.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/source/Piston.cpp b/source/Piston.cpp index 048cc355d..25702e2b6 100644 --- a/source/Piston.cpp +++ b/source/Piston.cpp @@ -15,7 +15,7 @@ /// Number of ticks that the piston extending / retracting waits before setting the block -const int PISTON_TICK_DELAY = 6; +const int PISTON_TICK_DELAY = 5; @@ -24,7 +24,6 @@ const int PISTON_TICK_DELAY = 6; cPiston::cPiston(cWorld * a_World) : m_World(a_World) { - } @@ -132,19 +131,19 @@ void cPiston::RetractPiston(int pistx, int pisty, int pistz) // Already retracted, bail out return; } - - m_World->BroadcastBlockAction(pistx, pisty, pistz, 1, pistonMeta & ~(8), pistonBlock); - m_World->BroadcastSoundEffect("tile.piston.in", pistx * 8, pisty * 8, pistz * 8, 0.5f, 0.7f); - m_World->SetBlock(pistx, pisty, pistz, pistonBlock, pistonMeta & ~(8)); // Check the extension: AddDir(pistx, pisty, pistz, pistonMeta, 1); if (m_World->GetBlock(pistx, pisty, pistz) != E_BLOCK_PISTON_EXTENSION) { - LOGD("%s: Piston without an extension?", __FUNCTION__); + LOGD("%s: Piston without an extension - still extending, or just in an invalid state?", __FUNCTION__); return; } + m_World->BroadcastBlockAction(pistx, pisty, pistz, 1, pistonMeta & ~(8), pistonBlock); + m_World->BroadcastSoundEffect("tile.piston.in", pistx * 8, pisty * 8, pistz * 8, 0.5f, 0.7f); + m_World->SetBlock(pistx, pisty, pistz, pistonBlock, pistonMeta & ~(8)); + // Retract the extension, pull block if appropriate if (IsSticky(pistonBlock)) { From 6a051b7cd88d3c547e1c257972d7299b0df9c32a Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Fri, 22 Nov 2013 23:15:59 +0000 Subject: [PATCH 05/12] Properly fixed piston bugs --- source/Piston.cpp | 4 +++- source/Simulator/RedstoneSimulator.cpp | 13 +++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/source/Piston.cpp b/source/Piston.cpp index 25702e2b6..63ffbad0b 100644 --- a/source/Piston.cpp +++ b/source/Piston.cpp @@ -15,7 +15,7 @@ /// Number of ticks that the piston extending / retracting waits before setting the block -const int PISTON_TICK_DELAY = 5; +const int PISTON_TICK_DELAY = 6; @@ -140,9 +140,11 @@ void cPiston::RetractPiston(int pistx, int pisty, int pistz) return; } + AddDir(pistx, pisty, pistz, pistonMeta, -1); m_World->BroadcastBlockAction(pistx, pisty, pistz, 1, pistonMeta & ~(8), pistonBlock); m_World->BroadcastSoundEffect("tile.piston.in", pistx * 8, pisty * 8, pistz * 8, 0.5f, 0.7f); m_World->SetBlock(pistx, pisty, pistz, pistonBlock, pistonMeta & ~(8)); + AddDir(pistx, pisty, pistz, pistonMeta, 1); // Retract the extension, pull block if appropriate if (IsSticky(pistonBlock)) diff --git a/source/Simulator/RedstoneSimulator.cpp b/source/Simulator/RedstoneSimulator.cpp index 15d954313..76a4dafb0 100644 --- a/source/Simulator/RedstoneSimulator.cpp +++ b/source/Simulator/RedstoneSimulator.cpp @@ -431,8 +431,6 @@ void cRedstoneSimulator::HandleRedstoneWire(int a_BlockX, int a_BlockY, int a_Bl if (m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) != 0) // A powered wire { - //SetBlockPowered(a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE); // No matter what, block underneath gets powered - switch (GetWireDirection(a_BlockX, a_BlockY, a_BlockZ)) { case REDSTONE_NONE: @@ -496,7 +494,10 @@ void cRedstoneSimulator::HandleRedstoneRepeater(int a_BlockX, int a_BlockY, int { // We do this so that the repeater can continually update block power status (without being affected by it's own block type, which would happen if the block powering code was in an IF statement) bool IsOn = false; - if (a_MyState == E_BLOCK_REDSTONE_REPEATER_ON) { IsOn = true; } + if (a_MyState == E_BLOCK_REDSTONE_REPEATER_ON) + { + IsOn = true; + } NIBBLETYPE a_Meta = m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); @@ -533,7 +534,10 @@ void cRedstoneSimulator::HandleRedstoneRepeater(int a_BlockX, int a_BlockY, int } else { - if (IsOn) { m_World.FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_REPEATER_OFF, a_Meta); } + if (IsOn) + { + m_World.FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_REPEATER_OFF, a_Meta); + } } return; } @@ -1060,6 +1064,7 @@ void cRedstoneSimulator::SetAllDirsAsPowered(int a_BlockX, int a_BlockY, int a_B { 0, 0, 1 }, { 0, 0,-1 }, { 0, 1, 0 }, + { 0,-1, 0 } }; for (int i = 0; i < ARRAYCOUNT(gCrossCoords); i++) From a6695564f3297e2fa6787e2c5e1e68d36c3fd9b1 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sat, 23 Nov 2013 12:10:33 +0000 Subject: [PATCH 06/12] Expanded one-line if statement --- source/Blocks/BlockPiston.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/source/Blocks/BlockPiston.cpp b/source/Blocks/BlockPiston.cpp index 42d7e8d35..3e1ca1d15 100644 --- a/source/Blocks/BlockPiston.cpp +++ b/source/Blocks/BlockPiston.cpp @@ -93,7 +93,10 @@ void cBlockPistonHeadHandler::OnDestroyedByPlayer(cWorld * a_World, cPlayer * a_ if ((Block == E_BLOCK_STICKY_PISTON) || (Block == E_BLOCK_PISTON)) { a_World->DigBlock(newX, newY, newZ); - if (a_Player->IsGameModeCreative()) { return; } // No pickups if creative + if (a_Player->IsGameModeCreative()) + { + return; // No pickups if creative + } cItems Pickups; Pickups.push_back(cItem(Block, 1)); From f570948d7987bbf41627eb2e939016f6d18031d3 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 24 Nov 2013 14:52:28 +0000 Subject: [PATCH 07/12] Fixed some comments and added debug logging --- source/Simulator/RedstoneSimulator.cpp | 19 ++++++++++++------- source/Simulator/RedstoneSimulator.h | 2 -- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/source/Simulator/RedstoneSimulator.cpp b/source/Simulator/RedstoneSimulator.cpp index 76a4dafb0..81d4e26f6 100644 --- a/source/Simulator/RedstoneSimulator.cpp +++ b/source/Simulator/RedstoneSimulator.cpp @@ -100,6 +100,7 @@ void cRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, c if (SourceBlockType != Change.a_SourceBlock) { itr = m_PoweredBlocks.erase(itr); + LOGD("cRedstoneSimulator: Erased block %s from powered blocks list due to present/past block type mismatch", ItemToFullString(Change.a_SourceBlock)); } else if ( // Changeable sources @@ -110,6 +111,7 @@ void cRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, c ) { itr = m_PoweredBlocks.erase(itr); + LOGD("cRedstoneSimulator: Erased block %s from powered blocks list due to present/past metadata mismatch", ItemToFullString(Change.a_SourceBlock)); } else { @@ -136,10 +138,12 @@ void cRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, c if (SourceBlockType != Change.a_SourceBlock) { itr = m_LinkedPoweredBlocks.erase(itr); + LOGD("cRedstoneSimulator: Erased block %s from linked powered blocks list due to present/past block type mismatch", ItemToFullString(Change.a_SourceBlock)); } else if (MiddleBlockType != Change.a_MiddleBlock) { itr = m_LinkedPoweredBlocks.erase(itr); + LOGD("cRedstoneSimulator: Erased block %s from linked powered blocks list due to present/past middle block mismatch", ItemToFullString(Change.a_SourceBlock)); } else if ( // Things that can send power through a block but which depends on meta @@ -149,6 +153,7 @@ void cRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, c ) { itr = m_LinkedPoweredBlocks.erase(itr); + LOGD("cRedstoneSimulator: Erased block %s from linked powered blocks list due to present/past metadata mismatch", ItemToFullString(Change.a_SourceBlock)); } else { @@ -248,7 +253,6 @@ void cRedstoneSimulator::HandleRedstoneTorch(int a_BlockX, int a_BlockY, int a_B if (AreCoordsPowered(X, Y, Z)) { // There was a match, torch goes off - // FastSetBlock so the server doesn't fail an assert -_- m_World.FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_TORCH_OFF, m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ)); return; } @@ -299,7 +303,6 @@ void cRedstoneSimulator::HandleRedstoneTorch(int a_BlockX, int a_BlockY, int a_B } // Block torch on not powered, can be turned on again! - // FastSetBlock so the server doesn't fail an assert -_- m_World.FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_TORCH_ON, m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ)); } return; @@ -503,7 +506,10 @@ void cRedstoneSimulator::HandleRedstoneRepeater(int a_BlockX, int a_BlockY, int if (IsRepeaterPowered(a_BlockX, a_BlockY, a_BlockZ, a_Meta & 0x3)) { - if (!IsOn) { m_World.SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_REPEATER_ON, a_Meta); } // Only set if not on; SetBlock otherwise server doesn't set it in time for SimulateChunk's invalidation + if (!IsOn) + { + m_World.SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_REPEATER_ON, a_Meta); // Only set if not on; SetBlock otherwise server doesn't set it in time for SimulateChunk's invalidation + } switch (a_Meta & 0x3) // We only want the direction (bottom) bits { case 0x0: @@ -548,14 +554,13 @@ 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)) { - cPiston Piston(&m_World); Piston.ExtendPiston(a_BlockX, a_BlockY, a_BlockZ); } else { - cPiston Piston(&m_World); Piston.RetractPiston(a_BlockX, a_BlockY, a_BlockZ); } return; @@ -1054,7 +1059,7 @@ 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 + static const struct { int x, y, z; } gCrossCoords[] = @@ -1067,7 +1072,7 @@ void cRedstoneSimulator::SetAllDirsAsPowered(int a_BlockX, int a_BlockY, int a_B { 0,-1, 0 } }; - for (int i = 0; i < ARRAYCOUNT(gCrossCoords); i++) + for (int i = 0; i < ARRAYCOUNT(gCrossCoords); i++) // Loop through struct to power all directions { SetBlockPowered(a_BlockX + gCrossCoords[i].x, a_BlockY + gCrossCoords[i].y, a_BlockZ + gCrossCoords[i].z, a_BlockX, a_BlockY, a_BlockZ, a_SourceBlock); } diff --git a/source/Simulator/RedstoneSimulator.h b/source/Simulator/RedstoneSimulator.h index 10d87505c..25959ac0b 100644 --- a/source/Simulator/RedstoneSimulator.h +++ b/source/Simulator/RedstoneSimulator.h @@ -32,7 +32,6 @@ public: REDSTONE_Z_NEG = 0x8, }; eRedstoneDirection GetWireDirection(int a_BlockX, int a_BlockY, int a_BlockZ); - eRedstoneDirection GetWireDirection(const Vector3i & a_Pos) { return GetWireDirection(a_Pos.x, a_Pos.y, a_Pos.z); } private: @@ -118,7 +117,6 @@ private: /* ============================== */ /* ====== Misc Functions ====== */ - ///Returns if a block is viable to be the MiddleBlock of a SetLinkedPowered operation inline static bool IsViableMiddleBlock(BLOCKTYPE Block) { From b628cfb7348d02737e3045944ac6e1f311797961 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Tue, 26 Nov 2013 21:54:07 +0000 Subject: [PATCH 08/12] Fixed repeaters not powering from wire This should also fix comparators (in the future). This also updates XML comments so that they are compatible with Doxygen. --- source/Simulator/RedstoneSimulator.h | 50 +++++++++++++--------------- 1 file changed, 24 insertions(+), 26 deletions(-) diff --git a/source/Simulator/RedstoneSimulator.h b/source/Simulator/RedstoneSimulator.h index 25959ac0b..d3002394a 100644 --- a/source/Simulator/RedstoneSimulator.h +++ b/source/Simulator/RedstoneSimulator.h @@ -63,61 +63,61 @@ private: // In addition to being non-performant, it would stop the player from actually breaking said device /* ====== SOURCES ====== */ - ///Handles the redstone torch + /// Handles the redstone torch void HandleRedstoneTorch(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyState); - ///Handles the redstone block + /// Handles the redstone block void HandleRedstoneBlock(int a_BlockX, int a_BlockY, int a_BlockZ); - ///Handles levers + /// Handles levers void HandleRedstoneLever(int a_BlockX, int a_BlockY, int a_BlockZ); - ///Handles buttons + /// Handles buttons void HandleRedstoneButton(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType); /* ==================== */ /* ====== CARRIERS ====== */ - ///Handles redstone wire + /// Handles redstone wire void HandleRedstoneWire(int a_BlockX, int a_BlockY, int a_BlockZ); - ///Handles repeaters + /// Handles repeaters void HandleRedstoneRepeater(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyState); /* ====================== */ /* ====== DEVICES ====== */ - ///Handles pistons + /// Handles pistons void HandlePiston(int a_BlockX, int a_BlockY, int a_BlockZ); - ///Handles dispensers and droppers + /// Handles dispensers and droppers void HandleDropSpenser(int a_BlockX, int a_BlockY, int a_BlockZ); - ///Handles TNT (exploding) + /// Handles TNT (exploding) void HandleTNT(int a_BlockX, int a_BlockY, int a_BlockZ); - ///Handles redstone lamps + /// Handles redstone lamps void HandleRedstoneLamp(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyState); - ///Handles doords + /// Handles doords void HandleDoor(int a_BlockX, int a_BlockY, int a_BlockZ); - ///Handles activator, detector, and powered rails + /// Handles activator, detector, and powered rails void HandleRail(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyType); /* ===================== */ /* ====== Helper functions ====== */ - ///Marks a block as powered + /// Marks a block as powered void SetBlockPowered(int a_BlockX, int a_BlockY, int a_BlockZ, int a_SourceX, int a_SourceY, int a_SourceZ, BLOCKTYPE a_SourceBlock); - ///Marks a block as being powered through another block + /// Marks a block as being powered through another block void SetBlockLinkedPowered(int a_BlockX, int a_BlockY, int a_BlockZ, int a_MiddleX, int a_MiddleY, int a_MiddleZ, int a_SourceX, int a_SourceY, int a_SourceZ, BLOCKTYPE a_SourceBlock, BLOCKTYPE a_MiddeBlock); - ///Marks the second block in a direction as linked powered + /// Marks the second block in a direction as linked powered void SetDirectionLinkedPowered(int a_BlockX, int a_BlockY, int a_BlockZ, char a_Direction, BLOCKTYPE a_SourceBlock); - ///Marks all blocks immediately surrounding a coordinate as powered + /// Marks all blocks immediately surrounding a coordinate as powered void SetAllDirsAsPowered(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_SourceBlock); - ///Returns if a coordinate is powered or linked powered + /// Returns if a coordinate is powered or linked powered bool AreCoordsPowered(int a_BlockX, int a_BlockY, int a_BlockZ); - ///Returns if a repeater is powered + /// Returns if a repeater is powered bool IsRepeaterPowered(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_Meta); - ///Returns if lever metadata marks it as emitting power + /// Returns if lever metadata marks it as emitting power bool IsLeverOn(NIBBLETYPE a_BlockMeta); - ///Returns if button metadata marks it as emitting power + /// Returns if button metadata marks it as emitting power bool IsButtonOn(NIBBLETYPE a_BlockMeta); /* ============================== */ /* ====== Misc Functions ====== */ - ///Returns if a block is viable to be the MiddleBlock of a SetLinkedPowered operation + /// Returns if a block is viable to be the MiddleBlock of a SetLinkedPowered operation inline static bool IsViableMiddleBlock(BLOCKTYPE Block) { if (!g_BlockIsSolid[Block]) { return false; } @@ -137,7 +137,7 @@ private: } } - ///Returns if a block is a mechanism (something that accepts power and does something) + /// Returns if a block is a mechanism (something that accepts power and does something) inline static bool IsMechanism(BLOCKTYPE Block) { switch (Block) @@ -166,7 +166,7 @@ private: } } - ///Returns if a block has the potential to output power + /// Returns if a block has the potential to output power inline static bool IsPotentialSource(BLOCKTYPE Block) { switch (Block) @@ -178,10 +178,8 @@ private: case E_BLOCK_REDSTONE_TORCH_ON: case E_BLOCK_LEVER: case E_BLOCK_REDSTONE_REPEATER_ON: - case E_BLOCK_REDSTONE_REPEATER_OFF: case E_BLOCK_BLOCK_OF_REDSTONE: case E_BLOCK_ACTIVE_COMPARATOR: - case E_BLOCK_INACTIVE_COMPARATOR: { return true; } @@ -189,7 +187,7 @@ private: } } - ///Returns if a block is any sort of redstone device + /// Returns if a block is any sort of redstone device inline static bool IsRedstone(BLOCKTYPE Block) { switch (Block) From 83ce4d4792238926d09242f330e0e821de2ba88b Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Tue, 26 Nov 2013 21:54:40 +0000 Subject: [PATCH 09/12] Fixed spawn point being generally in an ocean --- source/World.cpp | 84 +++++++++++++++++++++++++++++++++++++++++------- source/World.h | 6 +++- 2 files changed, 78 insertions(+), 12 deletions(-) diff --git a/source/World.cpp b/source/World.cpp index 531952e37..4bda6395e 100644 --- a/source/World.cpp +++ b/source/World.cpp @@ -236,7 +236,8 @@ cWorld::cWorld(const AString & a_WorldName) : m_Weather(eWeather_Sunny), m_WeatherInterval(24000), // Guaranteed 1 day of sunshine at server start :) m_TickThread(*this), - m_SkyDarkness(0) + m_SkyDarkness(0), + m_bSpawnExplicitlySet(false) { LOGD("cWorld::cWorld(\"%s\")", a_WorldName.c_str()); @@ -327,6 +328,20 @@ void cWorld::SetNextBlockTick(int a_BlockX, int a_BlockY, int a_BlockZ) void cWorld::InitializeSpawn(void) { + if (!m_bSpawnExplicitlySet) // Check if spawn position was already explicitly set or not + { + GenerateRandomSpawn(); // Generate random solid-land coordinate and then write it to the world configuration + + cIniFile IniFile; + IniFile.ReadFile(m_IniFileName); + + IniFile.SetValueF("SpawnPosition", "X", m_SpawnX); + IniFile.SetValueF("SpawnPosition", "Y", m_SpawnY); + IniFile.SetValueF("SpawnPosition", "Z", m_SpawnZ); + + IniFile.WriteFile(m_IniFileName); + } + int ChunkX = 0, ChunkY = 0, ChunkZ = 0; BlockToChunk((int)m_SpawnX, (int)m_SpawnY, (int)m_SpawnZ, ChunkX, ChunkY, ChunkZ); @@ -381,10 +396,6 @@ void cWorld::InitializeSpawn(void) Progress.Stop(); } - // TODO: Better spawn detection - move spawn out of the water if it isn't set in the INI already - m_SpawnY = (double)GetHeight((int)m_SpawnX, (int)m_SpawnZ) + 1.6f; // +1.6f eye height - - #ifdef TEST_LINEBLOCKTRACER // DEBUG: Test out the cLineBlockTracer class by tracing a few lines: class cTracerCallbacks : @@ -445,10 +456,9 @@ void cWorld::InitializeSpawn(void) void cWorld::Start(void) { - // TODO: Find a proper spawn location, based on the biomes (not in ocean) - m_SpawnX = (double)((m_TickRand.randInt() % 1000) - 500); + m_SpawnX = 0; m_SpawnY = cChunkDef::Height; - m_SpawnZ = (double)((m_TickRand.randInt() % 1000) - 500); + m_SpawnZ = 0; m_GameMode = eGameMode_Creative; cIniFile IniFile; @@ -473,9 +483,36 @@ void cWorld::Start(void) break; } } // switch (m_Dimension) - m_SpawnX = IniFile.GetValueSetF("SpawnPosition", "X", m_SpawnX); - m_SpawnY = IniFile.GetValueSetF("SpawnPosition", "Y", m_SpawnY); - m_SpawnZ = IniFile.GetValueSetF("SpawnPosition", "Z", m_SpawnZ); + + // Try to find the "SpawnPosition" key in the world configuration + // Set a boolean value if so + int KeyNum = IniFile.FindKey("SpawnPosition"); + unsigned int NumSpawnPositionKeys = ((KeyNum != -1) ? (IniFile.GetNumValues(KeyNum)) : 0); + + if (NumSpawnPositionKeys > 0) + { + for (unsigned int i = 0; i < NumSpawnPositionKeys; i++) + { + AString ValueName = IniFile.GetValueName(KeyNum, i); + if ( + (ValueName.compare("X") == 0) || + (ValueName.compare("Y") == 0) || + (ValueName.compare("Z") == 0) + ) + { + m_bSpawnExplicitlySet = true; + LOGD("Spawnpoint explicitly set!"); + } + } + } + + if (m_bSpawnExplicitlySet) + { + m_SpawnX = IniFile.GetValueF("SpawnPosition", "X", m_SpawnX); + m_SpawnY = IniFile.GetValueF("SpawnPosition", "Y", m_SpawnY); + m_SpawnZ = IniFile.GetValueF("SpawnPosition", "Z", m_SpawnZ); + } + m_StorageSchema = IniFile.GetValueSet ("Storage", "Schema", m_StorageSchema); m_MaxCactusHeight = IniFile.GetValueSetI("Plants", "MaxCactusHeight", 3); m_MaxSugarcaneHeight = IniFile.GetValueSetI("Plants", "MaxSugarcaneHeight", 3); @@ -573,6 +610,31 @@ void cWorld::Start(void) +void cWorld::GenerateRandomSpawn(void) +{ + LOGD("Generating random spawnpoint..."); + + while (GetBiomeAt((int)m_SpawnX, (int)m_SpawnZ) == biOcean) // Anything but ocean is fine + { + if ((GetTickRandomNumber(4) % 2) == 0) // Randomise whether to increment X or Z coords + { + m_SpawnX += cChunkDef::Width; + } + else + { + m_SpawnZ += cChunkDef::Width; + } + } + + m_SpawnY = (double)GetHeight((int)m_SpawnX, (int)m_SpawnZ) + 1.6f; // 1.6f to accomodate player height + + LOGD("Generated random spawnpoint %i %i %i", (int)m_SpawnX, (int)m_SpawnY, (int)m_SpawnZ); +} + + + + + void cWorld::Stop(void) { // Delete the clients that have been in this world: diff --git a/source/World.h b/source/World.h index d10aa3b78..73ad46b8b 100644 --- a/source/World.h +++ b/source/World.h @@ -632,6 +632,7 @@ private: /// This random generator is to be used only in the Tick() method, and thus only in the World-Tick-thread (MTRand is not exactly thread-safe) MTRand m_TickRand; + bool m_bSpawnExplicitlySet; double m_SpawnX; double m_SpawnY; double m_SpawnZ; @@ -739,7 +740,10 @@ private: /// Ticks all clients that are in this world void TickClients(float a_Dt); - void UpdateSkyDarkness(); + void UpdateSkyDarkness(void); + + /// Generates a random spawnpoint on solid land by walking chunks and finding their biomes + void GenerateRandomSpawn(void); /// Creates a new fluid simulator, loads its settings from the inifile (a_FluidName section) cFluidSimulator * InitializeFluidSimulator(cIniFile & a_IniFile, const char * a_FluidName, BLOCKTYPE a_SimulateBlock, BLOCKTYPE a_StationaryBlock); From 994e1d73355df62fb458936433f7478c9a0ef1ba Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Wed, 27 Nov 2013 22:03:04 +0000 Subject: [PATCH 10/12] Made TNT pickups spawning chance 25% --- src/ChunkMap.cpp | 4 ++-- src/World.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index 611e9f24e..75346f9b2 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -1655,12 +1655,12 @@ void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_ default: { - if (m_World->GetTickRandomNumber(10) == 5) + if (m_World->GetTickRandomNumber(4) == 4) // Around 25% chance of pickups { cItems Drops; cBlockHandler * Handler = BlockHandler(Block); - Handler->ConvertToPickups(Drops, area.GetBlockMeta(bx + x, by + y, bz + z)); + Handler->ConvertToPickups(Drops, area.GetBlockMeta(bx + x, by + y, bz + z)); // Stone becomes cobblestone, coal ore becomes coal, etc. m_World->SpawnItemPickups(Drops, bx + x, by + y, bz + z); } area.SetBlockType(bx + x, by + y, bz + z, E_BLOCK_AIR); diff --git a/src/World.cpp b/src/World.cpp index a2ab545af..8ef4dc0f3 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -1046,7 +1046,7 @@ void cWorld::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_Blo return; } - // TODO: Add damage to entities, add support for pickups, and implement block hardiness + // TODO: Add damage to entities and implement block hardiness Vector3d explosion_pos = Vector3d(a_BlockX, a_BlockY, a_BlockZ); cVector3iArray BlocksAffected; m_ChunkMap->DoExplosionAt(a_ExplosionSize, a_BlockX, a_BlockY, a_BlockZ, BlocksAffected); From f9e1be0d57f28c72b415c1b6cd37c1c2383c0679 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Thu, 28 Nov 2013 18:22:13 +0000 Subject: [PATCH 11/12] Improved TNT pickup randomisation --- src/ChunkMap.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index 75346f9b2..7d5b61346 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -1655,7 +1655,7 @@ void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_ default: { - if (m_World->GetTickRandomNumber(4) == 4) // Around 25% chance of pickups + if (m_World->GetTickRandomNumber(100) <= 25) // 25% chance of pickups { cItems Drops; cBlockHandler * Handler = BlockHandler(Block); From 96759637e94ddbe0d6cbf11505a6c63c254786ff Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Thu, 28 Nov 2013 18:24:25 +0000 Subject: [PATCH 12/12] Fixed a bug with TNT waking simulators --- src/ChunkMap.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index 7d5b61346..692f97ddf 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -1674,9 +1674,9 @@ void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_ // Wake up all simulators for the area, so that water and lava flows and sand falls into the blasted holes (FS #391): WakeUpSimulatorsInArea( - bx - ExplosionSizeInt, bx + ExplosionSizeInt + 1, + bx - ExplosionSizeInt - 1, bx + ExplosionSizeInt + 1, MinY, MaxY, - bz - ExplosionSizeInt, bz + ExplosionSizeInt + 1 + bz - ExplosionSizeInt - 1, bz + ExplosionSizeInt + 1 ); }