diff options
author | Tiger Wang <ziwei.tiger@hotmail.co.uk> | 2014-01-10 21:31:05 +0100 |
---|---|---|
committer | Tiger Wang <ziwei.tiger@hotmail.co.uk> | 2014-01-10 21:31:05 +0100 |
commit | e7fba08e6cbba1801dd45ad4c14ea743b7743e84 (patch) | |
tree | 131d299d3925a1b98b540b40b28d20eae970d4b5 /src/Simulator | |
parent | Added a known working favicon. (diff) | |
download | cuberite-e7fba08e6cbba1801dd45ad4c14ea743b7743e84.tar cuberite-e7fba08e6cbba1801dd45ad4c14ea743b7743e84.tar.gz cuberite-e7fba08e6cbba1801dd45ad4c14ea743b7743e84.tar.bz2 cuberite-e7fba08e6cbba1801dd45ad4c14ea743b7743e84.tar.lz cuberite-e7fba08e6cbba1801dd45ad4c14ea743b7743e84.tar.xz cuberite-e7fba08e6cbba1801dd45ad4c14ea743b7743e84.tar.zst cuberite-e7fba08e6cbba1801dd45ad4c14ea743b7743e84.zip |
Diffstat (limited to 'src/Simulator')
-rw-r--r-- | src/Simulator/RedstoneSimulator.cpp | 284 | ||||
-rw-r--r-- | src/Simulator/RedstoneSimulator.h | 79 |
2 files changed, 178 insertions, 185 deletions
diff --git a/src/Simulator/RedstoneSimulator.cpp b/src/Simulator/RedstoneSimulator.cpp index f65908729..a21c57f38 100644 --- a/src/Simulator/RedstoneSimulator.cpp +++ b/src/Simulator/RedstoneSimulator.cpp @@ -44,83 +44,45 @@ void cRedstoneSimulator::AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChu int RelX = a_BlockX - a_Chunk->GetPosX() * cChunkDef::Width; int RelZ = a_BlockZ - a_Chunk->GetPosZ() * cChunkDef::Width; + + BLOCKTYPE Block; + NIBBLETYPE Meta; + a_Chunk->GetBlockTypeMeta(RelX, a_BlockY, RelZ, Block, Meta); - if (!IsAllowedBlock(a_Chunk->GetBlock(RelX, a_BlockY, RelZ))) - { - return; - } - - // Check for duplicates: - cRedstoneSimulatorChunkData & ChunkData = a_Chunk->GetRedstoneSimulatorData(); - for (cRedstoneSimulatorChunkData::const_iterator itr = ChunkData.begin(); itr != ChunkData.end(); ++itr) - { - if ((itr->x == RelX) && (itr->y == a_BlockY) && (itr->z == RelZ)) - { - return; - } - } - - ChunkData.push_back(cCoordWithInt(RelX, a_BlockY, RelZ)); -} - - - - - -void cRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk) -{ - cRedstoneSimulatorChunkData & ChunkData = a_Chunk->GetRedstoneSimulatorData(); - if (ChunkData.empty()) - { - return; - } - - int BaseX = a_Chunk->GetPosX() * cChunkDef::Width; - int BaseZ = a_Chunk->GetPosZ() * cChunkDef::Width; + // Every time a block is changed (AddBlock called), we want to go through all lists and check to see if the coordiantes stored within are still valid + // Checking only when a block is changed, as opposed to every tick, also improves performance - // Check to see if PoweredBlocks have invalid items (source is air or unpowered) for (PoweredBlocksList::iterator itr = m_PoweredBlocks.begin(); itr != m_PoweredBlocks.end();) { - int RelX = itr->a_SourcePos.x - a_ChunkX * cChunkDef::Width; - int RelZ = itr->a_SourcePos.z - a_ChunkZ * cChunkDef::Width; - int DestRelX = itr->a_BlockPos.x - a_ChunkX * cChunkDef::Width; - int DestRelZ = itr->a_BlockPos.z - a_ChunkZ * cChunkDef::Width; - - BLOCKTYPE SourceBlockType; - NIBBLETYPE SourceBlockMeta; - BLOCKTYPE DestBlockType; - if ( - !a_Chunk->UnboundedRelGetBlock(RelX, itr->a_SourcePos.y, RelZ, SourceBlockType, SourceBlockMeta) || - !a_Chunk->UnboundedRelGetBlockType(DestRelX, itr->a_BlockPos.y, DestRelZ, DestBlockType) - ) + if (!itr->a_SourcePos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) { + ++itr; continue; } - if (SourceBlockType != itr->a_SourceBlock) + if (!IsPotentialSource(Block)) { - LOGD("cRedstoneSimulator: Erased block %s from powered blocks list due to present/past block type mismatch", ItemToFullString(itr->a_SourceBlock).c_str()); + LOGD("cRedstoneSimulator: Erased block @ {%i, %i, %i} from powered blocks list as it no longer connected to a source", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z); itr = m_PoweredBlocks.erase(itr); } else if ( // Changeable sources - ((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))) || - (((SourceBlockType == E_BLOCK_STONE_PRESSURE_PLATE) || (SourceBlockType == E_BLOCK_WOODEN_PRESSURE_PLATE)) && (SourceBlockMeta == 0)) + ((Block == E_BLOCK_REDSTONE_WIRE) && (Meta == 0)) || + ((Block == E_BLOCK_LEVER) && !IsLeverOn(Meta)) || + ((Block == E_BLOCK_DETECTOR_RAIL) && (Meta & 0x08) == 0x08) || + (((Block == E_BLOCK_STONE_BUTTON) || (Block == E_BLOCK_WOODEN_BUTTON)) && (!IsButtonOn(Meta))) || + (((Block == E_BLOCK_STONE_PRESSURE_PLATE) || (Block == E_BLOCK_WOODEN_PRESSURE_PLATE)) && (Meta == 0)) ) { - LOGD("cRedstoneSimulator: Erased block %s from powered blocks list due to present/past metadata mismatch", ItemToFullString(itr->a_SourceBlock).c_str()); + LOGD("cRedstoneSimulator: Erased block @ {%i, %i, %i} from powered blocks list due to present/past metadata mismatch", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z); itr = m_PoweredBlocks.erase(itr); } - else if (SourceBlockType == E_BLOCK_DAYLIGHT_SENSOR) + else if (Block == E_BLOCK_DAYLIGHT_SENSOR) { if (!a_Chunk->IsLightValid()) { - m_World.QueueLightChunk(a_ChunkX, a_ChunkZ); + m_World.QueueLightChunk(a_Chunk->GetPosX(), a_Chunk->GetPosZ()); ++itr; - continue; } else { @@ -135,60 +97,50 @@ void cRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, c else { ++itr; - continue; } } } - else if ((SourceBlockType == E_BLOCK_REDSTONE_WIRE) && (DestBlockType == E_BLOCK_REDSTONE_WIRE)) - { - // It is simply not allowed that a wire powers another wire, presuming that data here is sane and a dest and source are beside each other - LOGD("cRedstoneSimulator: Erased redstone wire from powered blocks list because its source was also wire"); - itr = m_PoweredBlocks.erase(itr); - } else { ++itr; } } - // Check to see if LinkedPoweredBlocks have invalid items: source, block powered through, or power destination block has changed for (LinkedBlocksList::iterator itr = m_LinkedPoweredBlocks.begin(); itr != m_LinkedPoweredBlocks.end();) { - int RelX = itr->a_SourcePos.x - a_ChunkX * cChunkDef::Width; - int RelZ = itr->a_SourcePos.z - a_ChunkZ * cChunkDef::Width; - int MidRelX = itr->a_MiddlePos.x - a_ChunkX * cChunkDef::Width; - int MidRelZ = itr->a_MiddlePos.z - a_ChunkZ * cChunkDef::Width; - - BLOCKTYPE SourceBlockType; - NIBBLETYPE SourceBlockMeta; - BLOCKTYPE MiddleBlockType; - if ( - !a_Chunk->UnboundedRelGetBlock(RelX, itr->a_SourcePos.y, RelZ, SourceBlockType, SourceBlockMeta) || - !a_Chunk->UnboundedRelGetBlockType(MidRelX, itr->a_MiddlePos.y, MidRelZ, MiddleBlockType) - ) + if (itr->a_SourcePos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) { - continue; - } - - if (SourceBlockType != itr->a_SourceBlock) - { - 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); + if (!IsPotentialSource(Block)) + { + LOGD("cRedstoneSimulator: Erased block @ {%i, %i, %i} from linked powered blocks list as it is no longer connected to a source", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z); + itr = m_LinkedPoweredBlocks.erase(itr); + } + else if ( + // Things that can send power through a block but which depends on meta + ((Block == E_BLOCK_REDSTONE_WIRE) && (Meta == 0)) || + ((Block == E_BLOCK_LEVER) && !IsLeverOn(Meta)) || + (((Block == E_BLOCK_STONE_BUTTON) || (Block == E_BLOCK_WOODEN_BUTTON)) && (!IsButtonOn(Meta))) + ) + { + LOGD("cRedstoneSimulator: Erased block @ {%i, %i, %i} from linked powered blocks list due to present/past metadata mismatch", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z); + itr = m_LinkedPoweredBlocks.erase(itr); + } + else + { + ++itr; + } } - else if (MiddleBlockType != itr->a_MiddleBlock) + else if (itr->a_MiddlePos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) { - 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 - ((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))) - ) - { - 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); + if (!IsViableMiddleBlock(Block)) + { + LOGD("cRedstoneSimulator: Erased block @ {%i, %i, %i} from linked powered blocks list as it is no longer powered through a valid middle block", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z); + itr = m_LinkedPoweredBlocks.erase(itr); + } + else + { + ++itr; + } } else { @@ -196,60 +148,85 @@ void cRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, c } } - for (SimulatedPlayerToggleableList::iterator itr = m_SimulatedPlayerToggleableBlocks.begin(); itr != m_SimulatedPlayerToggleableBlocks.end();) + for (SimulatedPlayerToggleableList::iterator itr = m_SimulatedPlayerToggleableBlocks.begin(); itr != m_SimulatedPlayerToggleableBlocks.end(); ++itr) { - int RelX = itr->a_BlockPos.x - a_ChunkX * cChunkDef::Width; - int RelZ = itr->a_BlockPos.z - a_ChunkZ * cChunkDef::Width; - - BLOCKTYPE SourceBlockType; - if (!a_Chunk->UnboundedRelGetBlockType(RelX, itr->a_BlockPos.y, RelZ, SourceBlockType)) + if (!itr->a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) { continue; } - else if (!IsAllowedBlock(SourceBlockType)) + + if (!IsAllowedBlock(Block)) { - LOGD("cRedstoneSimulator: Erased block %s from toggleable simulated list as block is no longer redstone", ItemToFullString(SourceBlockType).c_str()); + LOGD("cRedstoneSimulator: Erased block @ {%i, %i, %i} from toggleable simulated list as it is no longer redstone", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z); itr = m_SimulatedPlayerToggleableBlocks.erase(itr); - } - else - { - ++itr; + break; } } - for (RepeatersDelayList::iterator itr = m_RepeatersDelayList.begin(); itr != m_RepeatersDelayList.end();) + for (RepeatersDelayList::iterator itr = m_RepeatersDelayList.begin(); itr != m_RepeatersDelayList.end(); ++itr) { - int RelX = itr->a_BlockPos.x - a_ChunkX * cChunkDef::Width; - int RelZ = itr->a_BlockPos.z - a_ChunkZ * cChunkDef::Width; - - BLOCKTYPE SourceBlockType; - if (!a_Chunk->UnboundedRelGetBlockType(RelX, itr->a_BlockPos.y, RelZ, SourceBlockType)) + if (!itr->a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) { continue; } - if ((SourceBlockType != E_BLOCK_REDSTONE_REPEATER_ON) && (SourceBlockType != E_BLOCK_REDSTONE_REPEATER_OFF)) + if ((Block != E_BLOCK_REDSTONE_REPEATER_ON) && (Block != E_BLOCK_REDSTONE_REPEATER_OFF)) { itr = m_RepeatersDelayList.erase(itr); - continue; + break; } - - ++itr; } - for (cRedstoneSimulatorChunkData::iterator dataitr = ChunkData.begin(), end = ChunkData.end(); dataitr != end;) + cRedstoneSimulatorChunkData & ChunkData = a_Chunk->GetRedstoneSimulatorData(); + for (cRedstoneSimulatorChunkData::iterator itr = ChunkData.begin(); itr != ChunkData.end(); ++itr) { - BLOCKTYPE BlockType = a_Chunk->GetBlock(dataitr->x, dataitr->y, dataitr->z); - if (!IsAllowedBlock(BlockType)) + if ((itr->x == RelX) && (itr->y == a_BlockY) && (itr->z == RelZ)) // We are at an entry matching the current (changed) block { - dataitr = ChunkData.erase(dataitr); - continue; + if (!IsAllowedBlock(Block)) + { + ChunkData.erase(itr); // The new blocktype is not redstone; it must be removed from this list + } + else + { + itr->Data = Block; // Update block information + } + return; } + } + + if (!IsAllowedBlock(Block)) + { + return; + } + + ChunkData.push_back(cCoordWithBlock(RelX, a_BlockY, RelZ, Block)); +} + + + + + +void cRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk) +{ + // We still attempt to simulate all blocks in the chunk every tick, because of outside influence that needs to be taken into account + // For example, repeaters need to be ticked, pressure plates checked for entities, daylight sensor checked for light changes, etc. + // The easiest way to make this more efficient is probably just to reduce code within the handlers that put too much strain on server, like getting or setting blocks + // A marking dirty system might be a TODO for later on, perhaps - // PoweredBlock and LinkedPoweredBlock list was fine, now to the actual handling + cRedstoneSimulatorChunkData & ChunkData = a_Chunk->GetRedstoneSimulatorData(); + if (ChunkData.empty()) + { + return; + } + + int BaseX = a_Chunk->GetPosX() * cChunkDef::Width; + int BaseZ = a_Chunk->GetPosZ() * cChunkDef::Width; + + for (cRedstoneSimulatorChunkData::iterator dataitr = ChunkData.begin(), end = ChunkData.end(); dataitr != end;) + { int a_X = BaseX + dataitr->x; int a_Z = BaseZ + dataitr->z; - switch (BlockType) + switch (dataitr->Data) { case E_BLOCK_BLOCK_OF_REDSTONE: HandleRedstoneBlock(a_X, dataitr->y, a_Z); break; case E_BLOCK_LEVER: HandleRedstoneLever(a_X, dataitr->y, a_Z); break; @@ -262,19 +239,19 @@ void cRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, c case E_BLOCK_REDSTONE_TORCH_OFF: case E_BLOCK_REDSTONE_TORCH_ON: { - HandleRedstoneTorch(a_X, dataitr->y, a_Z, BlockType); + HandleRedstoneTorch(a_X, dataitr->y, a_Z, dataitr->Data); break; } case E_BLOCK_STONE_BUTTON: case E_BLOCK_WOODEN_BUTTON: { - HandleRedstoneButton(a_X, dataitr->y, a_Z, BlockType); + HandleRedstoneButton(a_X, dataitr->y, a_Z, dataitr->Data); break; } case E_BLOCK_REDSTONE_REPEATER_OFF: case E_BLOCK_REDSTONE_REPEATER_ON: { - HandleRedstoneRepeater(a_X, dataitr->y, a_Z, BlockType); + HandleRedstoneRepeater(a_X, dataitr->y, a_Z, dataitr->Data); break; } case E_BLOCK_PISTON: @@ -286,7 +263,7 @@ void cRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, c case E_BLOCK_REDSTONE_LAMP_OFF: case E_BLOCK_REDSTONE_LAMP_ON: { - HandleRedstoneLamp(a_X, dataitr->y, a_Z, BlockType); + HandleRedstoneLamp(a_X, dataitr->y, a_Z, dataitr->Data); break; } case E_BLOCK_DISPENSER: @@ -305,13 +282,13 @@ void cRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, c case E_BLOCK_DETECTOR_RAIL: case E_BLOCK_POWERED_RAIL: { - HandleRail(a_X, dataitr->y, a_Z, BlockType); + HandleRail(a_X, dataitr->y, a_Z, dataitr->Data); break; } case E_BLOCK_WOODEN_PRESSURE_PLATE: case E_BLOCK_STONE_PRESSURE_PLATE: { - HandlePressurePlate(a_X, dataitr->y, a_Z, BlockType); + HandlePressurePlate(a_X, dataitr->y, a_Z, dataitr->Data); break; } } @@ -487,7 +464,7 @@ void cRedstoneSimulator::HandleRedstoneWire(int a_BlockX, int a_BlockY, int a_Bl }; // Check to see if directly beside a power source - if (AreCoordsPowered(a_BlockX, a_BlockY, a_BlockZ)) + if (IsWirePowered(a_BlockX, a_BlockY, a_BlockZ)) { m_World.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, 15); // Maximum power } @@ -546,6 +523,7 @@ 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); + m_World.WakeUpSimulators(a_BlockX, a_BlockY, a_BlockZ); return; // No need to process block power sets because self not powered } else @@ -693,7 +671,7 @@ void cRedstoneSimulator::HandleRedstoneRepeater(int a_BlockX, int a_BlockY, int // Apparently, incrementing ticks only works reliably here, and not in SimChunk; // With a world with lots of redstone, the repeaters simply do not delay // I am confounded to say why. Perhaps optimisation failure. - LOGD("Incremented a repeater @ %i %i %i | Elapsed ticks: %i | Target delay: %i", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z, itr->a_ElapsedTicks, itr->a_DelayTicks); + LOGD("Incremented a repeater @ {%i %i %i} | Elapsed ticks: %i | Target delay: %i", itr->a_BlockPos.x, itr->a_BlockPos.y, itr->a_BlockPos.z, itr->a_ElapsedTicks, itr->a_DelayTicks); itr->a_ElapsedTicks++; } } @@ -1188,6 +1166,33 @@ bool cRedstoneSimulator::IsPistonPowered(int a_BlockX, int a_BlockY, int a_Block +bool cRedstoneSimulator::IsWirePowered(int a_BlockX, int a_BlockY, int a_BlockZ) +{ + for (PoweredBlocksList::const_iterator itr = m_PoweredBlocks.begin(); itr != m_PoweredBlocks.end(); ++itr) + { + if (!itr->a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) { continue; } + + if (m_World.GetBlock(itr->a_SourcePos) != E_BLOCK_REDSTONE_WIRE) + { + return true; + } + } + + for (LinkedBlocksList::const_iterator itr = m_LinkedPoweredBlocks.begin(); itr != m_LinkedPoweredBlocks.end(); ++itr) + { + if (!itr->a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) { continue; } + + if (m_World.GetBlock(itr->a_SourcePos) != E_BLOCK_REDSTONE_WIRE) + { + return true; + } + } + return false; // Source was in front of the piston's front face +} + + + + bool cRedstoneSimulator::AreCoordsSimulated(int a_BlockX, int a_BlockY, int a_BlockZ, bool IsCurrentStatePowered) { @@ -1333,11 +1338,6 @@ void cRedstoneSimulator::SetBlockPowered(int a_BlockX, int a_BlockY, int a_Block // 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 { @@ -1354,7 +1354,6 @@ void cRedstoneSimulator::SetBlockPowered(int a_BlockX, int a_BlockY, int a_Block sPoweredBlocks RC; RC.a_BlockPos = Vector3i(a_BlockX, a_BlockY, a_BlockZ); RC.a_SourcePos = Vector3i(a_SourceX, a_SourceY, a_SourceZ); - RC.a_SourceBlock = a_SourceBlock; m_PoweredBlocks.push_back(RC); } @@ -1379,11 +1378,6 @@ void cRedstoneSimulator::SetBlockLinkedPowered( { return; } - if ((a_SourceBlock == E_BLOCK_REDSTONE_WIRE) && (DestBlock == E_BLOCK_REDSTONE_WIRE)) - { - // Wires cannot power another wire through a block - return; - } for (LinkedBlocksList::const_iterator itr = m_LinkedPoweredBlocks.begin(); itr != m_LinkedPoweredBlocks.end(); ++itr) // Check linked powered list { @@ -1402,8 +1396,6 @@ void cRedstoneSimulator::SetBlockLinkedPowered( RC.a_BlockPos = Vector3i(a_BlockX, a_BlockY, a_BlockZ); RC.a_MiddlePos = Vector3i(a_MiddleX, a_MiddleY, a_MiddleZ); RC.a_SourcePos = Vector3i(a_SourceX, a_SourceY, a_SourceZ); - RC.a_SourceBlock = a_SourceBlock; - RC.a_MiddleBlock = a_MiddleBlock; m_LinkedPoweredBlocks.push_back(RC); } diff --git a/src/Simulator/RedstoneSimulator.h b/src/Simulator/RedstoneSimulator.h index 1080c3f81..4fe8b59b3 100644 --- a/src/Simulator/RedstoneSimulator.h +++ b/src/Simulator/RedstoneSimulator.h @@ -4,7 +4,7 @@ #include "Simulator.h" /// Per-chunk data for the simulator, specified individual chunks to simulate; 'Data' is not used -typedef cCoordWithIntList cRedstoneSimulatorChunkData; +typedef cCoordWithBlockVector cRedstoneSimulatorChunkData; @@ -39,7 +39,6 @@ private: { Vector3i a_BlockPos; // Position of powered block Vector3i a_SourcePos; // Position of source powering the block at a_BlockPos - BLOCKTYPE a_SourceBlock; // The source block type (for pistons pushing away sources and replacing with non source etc.) }; struct sLinkedPoweredBlocks // Define structure of the indirectly powered blocks list (i.e. repeaters powering through a block to the block at the other side) @@ -47,8 +46,6 @@ private: Vector3i a_BlockPos; Vector3i a_MiddlePos; Vector3i a_SourcePos; - BLOCKTYPE a_SourceBlock; - BLOCKTYPE a_MiddleBlock; }; struct sSimulatedPlayerToggleableList @@ -81,81 +78,86 @@ private: // In addition to being non-performant, it would stop the player from actually breaking said device /* ====== SOURCES ====== */ - /// <summary>Handles the redstone torch</summary> + /** Handles the redstone torch */ void HandleRedstoneTorch(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyState); - /// <summary>Handles the redstone block</summary> + /** Handles the redstone block */ void HandleRedstoneBlock(int a_BlockX, int a_BlockY, int a_BlockZ); - /// <summary>Handles levers</summary> + /** Handles levers */ void HandleRedstoneLever(int a_BlockX, int a_BlockY, int a_BlockZ); - /// <summary>Handles buttons</summary> + /** Handles buttons */ void HandleRedstoneButton(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType); - /// <summary>Handles daylight sensors</summary> + /** Handles daylight sensors */ void HandleDaylightSensor(int a_BlockX, int a_BlockY, int a_BlockZ); - /// <summary>Handles pressure plates</summary> + /** Handles pressure plates */ void HandlePressurePlate(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyType); /* ==================== */ /* ====== CARRIERS ====== */ - /// <summary>Handles redstone wire</summary> + /** Handles redstone wire */ void HandleRedstoneWire(int a_BlockX, int a_BlockY, int a_BlockZ); - /// <summary>Handles repeaters</summary> + /** Handles repeaters */ void HandleRedstoneRepeater(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyState); /* ====================== */ /* ====== DEVICES ====== */ - /// <summary>Handles pistons</summary> + /** Handles pistons */ void HandlePiston(int a_BlockX, int a_BlockY, int a_BlockZ); - /// <summary>Handles dispensers and droppers</summary> + /** Handles dispensers and droppers */ void HandleDropSpenser(int a_BlockX, int a_BlockY, int a_BlockZ); - /// <summary>Handles TNT (exploding)</summary> + /** Handles TNT (exploding) */ void HandleTNT(int a_BlockX, int a_BlockY, int a_BlockZ); - /// <summary>Handles redstone lamps</summary> + /** Handles redstone lamps */ void HandleRedstoneLamp(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyState); - /// <summary>Handles doords</summary> + /** Handles doords */ void HandleDoor(int a_BlockX, int a_BlockY, int a_BlockZ); - /// <summary>Handles activator, detector, and powered rails</summary> + /** Handles activator, detector, and powered rails */ void HandleRail(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyType); - /// <summary>Handles trapdoors</summary> + /** Handles trapdoors */ void HandleTrapdoor(int a_BlockX, int a_BlockY, int a_BlockZ); - /// <summary>Handles noteblocks</summary> + /** Handles noteblocks */ void HandleNoteBlock(int a_BlockX, int a_BlockY, int a_BlockZ); /* ===================== */ /* ====== Helper functions ====== */ - /// <summary>Marks a block as powered</summary> + /** 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); - /// <summary>Marks a block as being powered through another block</summary> + /** 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); - /// <summary>Marks a block as simulated, who should not be simulated further unless their power state changes, to accomodate a player manually toggling the block without triggering the simulator toggling it back</summary> + /** Marks a block as simulated, who should not be simulated further unless their power state changes, to accomodate a player manually toggling the block without triggering the simulator toggling it back */ void SetPlayerToggleableBlockAsSimulated(int a_BlockX, int a_BlockY, int a_BlockZ, bool WasLastStatePowered); - /// <summary>Marks the second block in a direction as linked powered</summary> + /** 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); - /// <summary>Marks all blocks immediately surrounding a coordinate as powered</summary> + /** Marks all blocks immediately surrounding a coordinate as powered */ void SetAllDirsAsPowered(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_SourceBlock); - /// <summary>Queues a repeater to be powered or unpowered</summary> + /** Queues a repeater to be powered or unpowered */ void QueueRepeaterPowerChange(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_Meta, short a_ElapsedTicks, bool ShouldPowerOn); - /// <summary>Returns if a coordinate is powered or linked powered</summary> + /** Returns if a coordinate is powered or linked powered */ bool AreCoordsPowered(int a_BlockX, int a_BlockY, int a_BlockZ) { return AreCoordsDirectlyPowered(a_BlockX, a_BlockY, a_BlockZ) || AreCoordsLinkedPowered(a_BlockX, a_BlockY, a_BlockZ); } - /// <summary>Returns if a coordinate is in the directly powered blocks list</summary> + /** Returns if a coordinate is in the directly powered blocks list */ bool AreCoordsDirectlyPowered(int a_BlockX, int a_BlockY, int a_BlockZ); - /// <summary>Returns if a coordinate is in the indirectly powered blocks list</summary> + /** Returns if a coordinate is in the indirectly powered blocks list */ bool AreCoordsLinkedPowered(int a_BlockX, int a_BlockY, int a_BlockZ); - /// <summary>Returns if a coordinate was marked as simulated (for blocks toggleable by players)</summary> + /** Returns if a coordinate was marked as simulated (for blocks toggleable by players) */ bool AreCoordsSimulated(int a_BlockX, int a_BlockY, int a_BlockZ, bool IsCurrentStatePowered); - /// <summary>Returns if a repeater is powered</summary> + /** Returns if a repeater is powered */ bool IsRepeaterPowered(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_Meta); - /// <summary>Returns if a piston is powered</summary> + /** Returns if a piston is powered */ bool IsPistonPowered(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_Meta); + /** Returns if a wire is powered + The only diffence between this and a normal AreCoordsPowered is that this function checks for a wire powering another wire + */ + bool IsWirePowered(int a_BlockX, int a_BlockY, int a_BlockZ); - /// <summary>Returns if lever metadata marks it as emitting power</summary> + + /** Returns if lever metadata marks it as emitting power */ bool IsLeverOn(NIBBLETYPE a_BlockMeta); - /// <summary>Returns if button metadata marks it as emitting power</summary> + /** Returns if button metadata marks it as emitting power */ bool IsButtonOn(NIBBLETYPE a_BlockMeta); /* ============================== */ /* ====== Misc Functions ====== */ - /// <summary>Returns if a block is viable to be the MiddleBlock of a SetLinkedPowered operation</summary> + /** 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; } @@ -176,7 +178,7 @@ private: } } - /// <summary>Returns if a block is a mechanism (something that accepts power and does something)</summary> + /** Returns if a block is a mechanism (something that accepts power and does something) */ inline static bool IsMechanism(BLOCKTYPE Block) { switch (Block) @@ -205,7 +207,7 @@ private: } } - /// <summary>Returns if a block has the potential to output power</summary> + /** Returns if a block has the potential to output power */ inline static bool IsPotentialSource(BLOCKTYPE Block) { switch (Block) @@ -214,7 +216,6 @@ private: case E_BLOCK_WOODEN_BUTTON: case E_BLOCK_STONE_BUTTON: case E_BLOCK_REDSTONE_WIRE: - case E_BLOCK_REDSTONE_TORCH_OFF: case E_BLOCK_REDSTONE_TORCH_ON: case E_BLOCK_LEVER: case E_BLOCK_REDSTONE_REPEATER_ON: @@ -227,7 +228,7 @@ private: } } - /// <summary>Returns if a block is any sort of redstone device</summary> + /** Returns if a block is any sort of redstone device */ inline static bool IsRedstone(BLOCKTYPE Block) { switch (Block) |