diff options
Diffstat (limited to 'src/Simulator/RedstoneSimulator.cpp')
-rw-r--r-- | src/Simulator/RedstoneSimulator.cpp | 117 |
1 files changed, 85 insertions, 32 deletions
diff --git a/src/Simulator/RedstoneSimulator.cpp b/src/Simulator/RedstoneSimulator.cpp index f61e1c63b..fc9471b91 100644 --- a/src/Simulator/RedstoneSimulator.cpp +++ b/src/Simulator/RedstoneSimulator.cpp @@ -3,6 +3,7 @@ #include "RedstoneSimulator.h" #include "../BlockEntities/DropSpenserEntity.h" +#include "../BlockEntities/NoteEntity.h" #include "../Entities/TNTEntity.h" #include "../Blocks/BlockTorch.h" #include "../Blocks/BlockDoor.h" @@ -91,8 +92,8 @@ void cRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, c if (SourceBlockType != itr->a_SourceBlock) { - itr = m_PoweredBlocks.erase(itr); LOGD("cRedstoneSimulator: Erased block %s from powered blocks list due to present/past block type mismatch", ItemToFullString(itr->a_SourceBlock).c_str()); + itr = m_PoweredBlocks.erase(itr); } else if ( // Changeable sources @@ -102,8 +103,8 @@ void cRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, c (((SourceBlockType == E_BLOCK_STONE_BUTTON) || (SourceBlockType == E_BLOCK_WOODEN_BUTTON)) && (!IsButtonOn(SourceBlockMeta))) ) { - itr = m_PoweredBlocks.erase(itr); LOGD("cRedstoneSimulator: Erased block %s from powered blocks list due to present/past metadata mismatch", ItemToFullString(itr->a_SourceBlock).c_str()); + itr = m_PoweredBlocks.erase(itr); } else { @@ -132,13 +133,13 @@ void cRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, c if (SourceBlockType != itr->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(itr->a_SourceBlock).c_str()); + itr = m_LinkedPoweredBlocks.erase(itr); } else if (MiddleBlockType != itr->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(itr->a_SourceBlock).c_str()); + itr = m_LinkedPoweredBlocks.erase(itr); } else if ( // Things that can send power through a block but which depends on meta @@ -147,8 +148,8 @@ void cRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, c (((SourceBlockType == E_BLOCK_STONE_BUTTON) || (SourceBlockType == E_BLOCK_WOODEN_BUTTON)) && (!IsButtonOn(SourceBlockMeta))) ) { - itr = m_LinkedPoweredBlocks.erase(itr); LOGD("cRedstoneSimulator: Erased block %s from linked powered blocks list due to present/past metadata mismatch", ItemToFullString(itr->a_SourceBlock).c_str()); + itr = m_LinkedPoweredBlocks.erase(itr); } else { @@ -196,6 +197,7 @@ void cRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, c case E_BLOCK_TNT: HandleTNT(a_X, dataitr->y, a_Z); break; case E_BLOCK_TRAPDOOR: HandleTrapdoor(a_X, dataitr->y, a_Z); break; case E_BLOCK_REDSTONE_WIRE: HandleRedstoneWire(a_X, dataitr->y, a_Z); break; + case E_BLOCK_NOTE_BLOCK: HandleNoteBlock(a_X, dataitr->y, a_Z); break; case E_BLOCK_REDSTONE_TORCH_OFF: case E_BLOCK_REDSTONE_TORCH_ON: @@ -392,18 +394,18 @@ void cRedstoneSimulator::HandleRedstoneWire(int a_BlockX, int a_BlockY, int a_Bl int x, y, z; } gCrossCoords[] = { - { 1, 0, 0}, + { 1, 0, 0}, /* Wires on same level start */ {-1, 0, 0}, { 0, 0, 1}, - { 0, 0, -1}, - { 1, 1, 0}, // From here to end, check for wire placed on sides of blocks + { 0, 0, -1}, /* Wires on same level stop */ + { 1, 1, 0}, /* Wires one higher, surrounding self start */ {-1, 1, 0}, { 0, 1, 1}, - { 0, 1, -1}, - { 1,-1, 0}, + { 0, 1, -1}, /* Wires one higher, surrounding self stop */ + { 1,-1, 0}, /* Wires one lower, surrounding self start */ {-1,-1, 0}, { 0,-1, 1}, - { 0,-1, -1}, + { 0,-1, -1}, /* Wires one lower, surrounding self stop */ } ; // Check to see if directly beside a power source @@ -419,6 +421,21 @@ void cRedstoneSimulator::HandleRedstoneWire(int a_BlockX, int a_BlockY, int a_Bl for (size_t i = 0; i < ARRAYCOUNT(gCrossCoords); i++) // Loop through all directions to transfer or receive power { + if ((i >= 4) && (i <= 7)) // If we are currently checking for wire surrounding ourself one block above... + { + if (g_BlockIsSolid[m_World.GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ)]) // If there is something solid above us (wire cut off)... + { + continue; // We don't receive power from that wire + } + } + else if ((i >= 8) && (i <= 11)) // See above, but this is for wire below us + { + if (g_BlockIsSolid[m_World.GetBlock(a_BlockX + gCrossCoords[i].x, a_BlockY + gCrossCoords[i].y + 1, a_BlockZ + gCrossCoords[i].z)]) + { + continue; + } + } + BLOCKTYPE SurroundType; NIBBLETYPE SurroundMeta; m_World.GetBlockTypeMeta(a_BlockX + gCrossCoords[i].x, a_BlockY + gCrossCoords[i].y, a_BlockZ + gCrossCoords[i].z, SurroundType, SurroundMeta); @@ -459,12 +476,12 @@ void cRedstoneSimulator::HandleRedstoneWire(int a_BlockX, int a_BlockY, int a_Bl } } - // Wire still powered, power blocks beneath - SetBlockPowered(a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE); - SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_YM, E_BLOCK_REDSTONE_WIRE); - if (m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) != 0) // A powered wire { + // Wire still powered, power blocks beneath + SetBlockPowered(a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE); + SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_YM, E_BLOCK_REDSTONE_WIRE); + switch (GetWireDirection(a_BlockX, a_BlockY, a_BlockZ)) { case REDSTONE_NONE: @@ -481,37 +498,25 @@ void cRedstoneSimulator::HandleRedstoneWire(int a_BlockX, int a_BlockY, int a_Bl } case REDSTONE_X_POS: { - if (m_World.GetBlock(a_BlockX + 1, a_BlockY, a_BlockZ) != E_BLOCK_REDSTONE_WIRE) - { - SetBlockPowered(a_BlockX + 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE); - } + SetBlockPowered(a_BlockX + 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE); SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_XP, E_BLOCK_REDSTONE_WIRE); break; } case REDSTONE_X_NEG: { - if (m_World.GetBlock(a_BlockX - 1, a_BlockY, a_BlockZ) != E_BLOCK_REDSTONE_WIRE) - { - SetBlockPowered(a_BlockX - 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE); - } + SetBlockPowered(a_BlockX - 1, a_BlockY, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE); SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_XM, E_BLOCK_REDSTONE_WIRE); break; } case REDSTONE_Z_POS: { - if (m_World.GetBlock(a_BlockX, a_BlockY, a_BlockZ + 1) != E_BLOCK_REDSTONE_WIRE) - { - SetBlockPowered(a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE); - } + SetBlockPowered(a_BlockX, a_BlockY, a_BlockZ + 1, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE); SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_ZP, E_BLOCK_REDSTONE_WIRE); break; } case REDSTONE_Z_NEG: { - if (m_World.GetBlock(a_BlockX, a_BlockY, a_BlockZ - 1) != E_BLOCK_REDSTONE_WIRE) - { - SetBlockPowered(a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE); - } + SetBlockPowered(a_BlockX, a_BlockY, a_BlockZ - 1, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_WIRE); SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_ZM, E_BLOCK_REDSTONE_WIRE); break; } @@ -821,6 +826,48 @@ void cRedstoneSimulator::HandleTrapdoor(int a_BlockX, int a_BlockY, int a_BlockZ +void cRedstoneSimulator::HandleNoteBlock(int a_BlockX, int a_BlockY, int a_BlockZ) +{ + bool m_bAreCoordsPowered = AreCoordsPowered(a_BlockX, a_BlockY, a_BlockZ); + + if (m_bAreCoordsPowered) + { + if (!AreCoordsSimulated(a_BlockX, a_BlockY, a_BlockZ, true)) + { + class cSetPowerToNoteBlock : + public cNoteBlockCallback + { + bool m_IsPowered; + public: + cSetPowerToNoteBlock(bool a_IsPowered) : m_IsPowered(a_IsPowered) {} + + virtual bool Item(cNoteEntity * a_NoteBlock) override + { + if (m_IsPowered) + { + a_NoteBlock->MakeSound(); + } + return false; + } + } NoteBlockSP(m_bAreCoordsPowered); + + m_World.DoWithNoteBlockAt(a_BlockX, a_BlockY, a_BlockZ, NoteBlockSP); + SetPlayerToggleableBlockAsSimulated(a_BlockX, a_BlockY, a_BlockZ, true); + } + } + else + { + if (!AreCoordsSimulated(a_BlockX, a_BlockY, a_BlockZ, false)) + { + SetPlayerToggleableBlockAsSimulated(a_BlockX, a_BlockY, a_BlockZ, false); + } + } +} + + + + + bool cRedstoneSimulator::AreCoordsDirectlyPowered(int a_BlockX, int a_BlockY, int a_BlockZ) { for (PoweredBlocksList::const_iterator itr = m_PoweredBlocks.begin(); itr != m_PoweredBlocks.end(); ++itr) // Check powered list @@ -1103,11 +1150,17 @@ void cRedstoneSimulator::SetAllDirsAsPowered(int a_BlockX, int a_BlockY, int a_B 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) + BLOCKTYPE Block = m_World.GetBlock(a_BlockX, a_BlockY, a_BlockZ); + if (Block == E_BLOCK_AIR) { // Don't set air, fixes some bugs (wires powering themselves) return; } + if ((Block == E_BLOCK_REDSTONE_WIRE) && (a_SourceBlock == E_BLOCK_REDSTONE_WIRE)) + { + // Wires cannot power themselves normally, instead, the wire handler will manually set meta + return; + } for (PoweredBlocksList::const_iterator itr = m_PoweredBlocks.begin(); itr != m_PoweredBlocks.end(); ++itr) // Check powered list { |