diff --git a/src/BlockEntities/BlockEntityWithItems.cpp b/src/BlockEntities/BlockEntityWithItems.cpp index 1a8ae4342..b2f225aa7 100644 --- a/src/BlockEntities/BlockEntityWithItems.cpp +++ b/src/BlockEntities/BlockEntityWithItems.cpp @@ -58,10 +58,10 @@ void cBlockEntityWithItems::OnSlotChanged(cItemGrid * a_Grid, int a_SlotNum) auto & Simulator = *m_World->GetRedstoneSimulator(); // Notify comparators: - Simulator.WakeUp(m_Pos + Vector3i(1, 0, 0), &a_Chunk); - Simulator.WakeUp(m_Pos + Vector3i(-1, 0, 0), &a_Chunk); - Simulator.WakeUp(m_Pos + Vector3i(0, 0, 1), &a_Chunk); - Simulator.WakeUp(m_Pos + Vector3i(0, 0, -1), &a_Chunk); + m_World->WakeUpSimulators(m_Pos + Vector3i(1, 0, 0)); + m_World->WakeUpSimulators(m_Pos + Vector3i(-1, 0, 0)); + m_World->WakeUpSimulators(m_Pos + Vector3i(0, 0, 1)); + m_World->WakeUpSimulators(m_Pos + Vector3i(0, 0, -1)); return true; }); } diff --git a/src/BlockEntities/ChestEntity.cpp b/src/BlockEntities/ChestEntity.cpp index d9648df18..cb26f4d08 100644 --- a/src/BlockEntities/ChestEntity.cpp +++ b/src/BlockEntities/ChestEntity.cpp @@ -216,3 +216,42 @@ bool cChestEntity::IsBlocked() + +void cChestEntity::OnSlotChanged(cItemGrid * a_Grid, int a_SlotNum) +{ + ASSERT(a_Grid == &m_Contents); + + if (m_World == nullptr) + { + return; + } + + // Have cBlockEntityWithItems update redstone and try to broadcast our window: + Super::OnSlotChanged(a_Grid, a_SlotNum); + + cWindow * Window = GetWindow(); + if ((Window == nullptr) && (m_Neighbour != nullptr)) + { + // Window was null, Super will have failed. + // Neighbour might own the window: + Window = m_Neighbour->GetWindow(); + } + + if (Window != nullptr) + { + Window->BroadcastWholeWindow(); + } + + m_World->MarkChunkDirty(GetChunkX(), GetChunkZ()); + m_World->DoWithChunkAt(m_Pos, [&](cChunk & a_Chunk) + { + auto & Simulator = *m_World->GetRedstoneSimulator(); + + // Notify comparators: + m_World->WakeUpSimulators(m_Pos + Vector3i(1, 0, 0)); + m_World->WakeUpSimulators(m_Pos + Vector3i(-1, 0, 0)); + m_World->WakeUpSimulators(m_Pos + Vector3i(0, 0, 1)); + m_World->WakeUpSimulators(m_Pos + Vector3i(0, 0, -1)); + return true; + }); +} diff --git a/src/BlockEntities/ChestEntity.h b/src/BlockEntities/ChestEntity.h index c6d13fa38..84b6eef0c 100644 --- a/src/BlockEntities/ChestEntity.h +++ b/src/BlockEntities/ChestEntity.h @@ -74,44 +74,7 @@ private: cChestEntity * m_Neighbour; /** cItemGrid::cListener overrides: */ - virtual void OnSlotChanged(cItemGrid * a_Grid, int a_SlotNum) override - { - ASSERT(a_Grid == &m_Contents); - - if (m_World == nullptr) - { - return; - } - - // Have cBlockEntityWithItems update redstone and try to broadcast our window: - Super::OnSlotChanged(a_Grid, a_SlotNum); - - cWindow * Window = GetWindow(); - if ((Window == nullptr) && (m_Neighbour != nullptr)) - { - // Window was null, Super will have failed. - // Neighbour might own the window: - Window = m_Neighbour->GetWindow(); - } - - if (Window != nullptr) - { - Window->BroadcastWholeWindow(); - } - - m_World->MarkChunkDirty(GetChunkX(), GetChunkZ()); - m_World->DoWithChunkAt(m_Pos, [&](cChunk & a_Chunk) - { - auto & Simulator = *m_World->GetRedstoneSimulator(); - - // Notify comparators: - Simulator.WakeUp(m_Pos + Vector3i(1, 0, 0), &a_Chunk); - Simulator.WakeUp(m_Pos + Vector3i(-1, 0, 0), &a_Chunk); - Simulator.WakeUp(m_Pos + Vector3i(0, 0, 1), &a_Chunk); - Simulator.WakeUp(m_Pos + Vector3i(0, 0, -1), &a_Chunk); - return true; - }); - } + virtual void OnSlotChanged(cItemGrid * a_Grid, int a_SlotNum) override; } ; // tolua_export diff --git a/src/Blocks/BlockVine.h b/src/Blocks/BlockVine.h index 2cf6e985c..68e6e2ddc 100644 --- a/src/Blocks/BlockVine.h +++ b/src/Blocks/BlockVine.h @@ -196,8 +196,7 @@ public: } else { - auto absPos = a_Chunk.RelativeToAbsolute(a_RelPos); - a_Chunk.GetWorld()->GetSimulatorManager()->WakeUp(absPos, &a_Chunk); + a_Chunk.GetWorld()->GetSimulatorManager()->WakeUp(a_Chunk, a_RelPos); } } diff --git a/src/Chunk.cpp b/src/Chunk.cpp index cb14b36a0..1c06ed3b3 100644 --- a/src/Chunk.cpp +++ b/src/Chunk.cpp @@ -1241,40 +1241,12 @@ void cChunk::WakeUpSimulators(void) for (size_t BlockIdx = 0; BlockIdx != cChunkData::SectionBlockCount; ++BlockIdx) { - auto BlockType = Section->m_BlockTypes[BlockIdx]; + const auto BlockType = Section->m_BlockTypes[BlockIdx]; + const auto Position = IndexToCoordinate(BlockIdx); - // Defer calculation until it's actually needed - auto WorldPos = [&] - { - auto RelPos = IndexToCoordinate(BlockIdx); - RelPos.y += static_cast(SectionIdx * cChunkData::SectionHeight); - return RelativeToAbsolute(RelPos); - }; - - // The redstone sim takes multiple blocks, use the inbuilt checker - if (RedstoneSimulator->IsAllowedBlock(BlockType)) - { - RedstoneSimulator->AddBlock(WorldPos(), this); - continue; - } - - switch (BlockType) - { - case E_BLOCK_WATER: - { - WaterSimulator->AddBlock(WorldPos(), this); - break; - } - case E_BLOCK_LAVA: - { - LavaSimulator->AddBlock(WorldPos(), this); - break; - } - default: - { - break; - } - } // switch (BlockType) + RedstoneSimulator->AddBlock(*this, Position, BlockType); + WaterSimulator->AddBlock(*this, Position, BlockType); + LavaSimulator->AddBlock(*this, Position, BlockType); } } } @@ -1316,7 +1288,7 @@ void cChunk::SetBlock(Vector3i a_RelPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_Blo // TODO: use relative coordinates, cChunk reference // Wake up the simulators for this block: - GetWorld()->GetSimulatorManager()->WakeUp(RelativeToAbsolute(a_RelPos), this); + GetWorld()->GetSimulatorManager()->WakeUp(*this, a_RelPos); // If there was a block entity, remove it: cBlockEntity * BlockEntity = GetBlockEntityRel(a_RelPos); diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index 43253a91d..6b1ece612 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -227,7 +227,8 @@ void cChunkMap::WakeUpSimulators(Vector3i a_Block) { return; } - m_World->GetSimulatorManager()->WakeUp(a_Block, Chunk); + + m_World->GetSimulatorManager()->WakeUp(*Chunk, cChunkDef::AbsoluteToRelative(a_Block, Chunk->GetPos())); } @@ -644,7 +645,6 @@ void cChunkMap::SetBlock(Vector3i a_BlockPos, BLOCKTYPE a_BlockType, NIBBLETYPE BlockHandler(blockType)->OnBroken(ChunkInterface, *m_World, a_BlockPos, blockType, blockMeta); chunk->SetBlock(relPos, a_BlockType, a_BlockMeta); - m_World->GetSimulatorManager()->WakeUp(a_BlockPos, chunk); BlockHandler(a_BlockType)->OnPlaced(ChunkInterface, *m_World, a_BlockPos, a_BlockType, a_BlockMeta); } } @@ -867,7 +867,6 @@ bool cChunkMap::DigBlock(Vector3i a_BlockPos) } destChunk->SetBlock(relPos, E_BLOCK_AIR, 0); - m_World->GetSimulatorManager()->WakeUp(a_BlockPos, destChunk); } return true; } diff --git a/src/Simulator/DelayedFluidSimulator.cpp b/src/Simulator/DelayedFluidSimulator.cpp index af9007548..b27e34e5f 100644 --- a/src/Simulator/DelayedFluidSimulator.cpp +++ b/src/Simulator/DelayedFluidSimulator.cpp @@ -78,27 +78,15 @@ cDelayedFluidSimulator::cDelayedFluidSimulator(cWorld & a_World, BLOCKTYPE a_Flu -void cDelayedFluidSimulator::AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) +void cDelayedFluidSimulator::WakeUp(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) { - int RelX = a_Block.x - a_Chunk->GetPosX() * cChunkDef::Width; - int RelZ = a_Block.z - a_Chunk->GetPosZ() * cChunkDef::Width; - BLOCKTYPE BlockType = a_Chunk->GetBlock(RelX, a_Block.y, RelZ); - if (BlockType != m_FluidBlock) + if (!cChunkDef::IsValidHeight(a_Position.y)) { + // Not inside the world (may happen when rclk with a full bucket - the client sends Y = -1) return; } - auto ChunkDataRaw = (m_FluidBlock == E_BLOCK_WATER) ? a_Chunk->GetWaterSimulatorData() : a_Chunk->GetLavaSimulatorData(); - cDelayedFluidSimulatorChunkData * ChunkData = static_cast(ChunkDataRaw); - cDelayedFluidSimulatorChunkData::cSlot & Slot = ChunkData->m_Slots[m_AddSlotNum]; - - // Add, if not already present: - if (!Slot.Add(RelX, a_Block.y, RelZ)) - { - return; - } - - ++m_TotalBlocks; + Super::WakeUp(a_Chunk, a_Position, a_Block); } @@ -146,13 +134,22 @@ void cDelayedFluidSimulator::SimulateChunk(std::chrono::milliseconds a_Dt, int a -void cDelayedFluidSimulator::WakeUp(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) +void cDelayedFluidSimulator::AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) { - if (!cChunkDef::IsValidHeight(a_Position.y)) + if (a_Block != m_FluidBlock) { - // Not inside the world (may happen when rclk with a full bucket - the client sends Y = -1) return; } - Super::WakeUp(a_Chunk, a_Position, a_Block); + auto ChunkDataRaw = (m_FluidBlock == E_BLOCK_WATER) ? a_Chunk.GetWaterSimulatorData() : a_Chunk.GetLavaSimulatorData(); + cDelayedFluidSimulatorChunkData * ChunkData = static_cast(ChunkDataRaw); + cDelayedFluidSimulatorChunkData::cSlot & Slot = ChunkData->m_Slots[m_AddSlotNum]; + + // Add, if not already present: + if (!Slot.Add(a_Position.x, a_Position.y, a_Position.z)) + { + return; + } + + ++m_TotalBlocks; } diff --git a/src/Simulator/DelayedFluidSimulator.h b/src/Simulator/DelayedFluidSimulator.h index b3158efec..e307e4ad7 100644 --- a/src/Simulator/DelayedFluidSimulator.h +++ b/src/Simulator/DelayedFluidSimulator.h @@ -54,15 +54,15 @@ public: cDelayedFluidSimulator(cWorld & a_World, BLOCKTYPE a_Fluid, BLOCKTYPE a_StationaryFluid, int a_TickDelay); - // cSimulator overrides: virtual void WakeUp(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) override; - virtual void AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) override; - virtual void Simulate(float a_Dt) override; - virtual void SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk) override; - virtual cFluidSimulatorData * CreateChunkData(void) override { return new cDelayedFluidSimulatorChunkData(m_TickDelay); } protected: + virtual void Simulate(float a_Dt) override; + virtual void SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk) override; + virtual void AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) override; + virtual cFluidSimulatorData * CreateChunkData(void) override { return new cDelayedFluidSimulatorChunkData(m_TickDelay); } + int m_TickDelay; // Count of the m_Slots array in each ChunkData int m_AddSlotNum; // Index into m_Slots[] where to add new blocks in each ChunkData int m_SimSlotNum; // Index into m_Slots[] where to simulate blocks in each ChunkData diff --git a/src/Simulator/FireSimulator.cpp b/src/Simulator/FireSimulator.cpp index 1f212e2a5..30fe88acd 100644 --- a/src/Simulator/FireSimulator.cpp +++ b/src/Simulator/FireSimulator.cpp @@ -79,14 +79,6 @@ cFireSimulator::cFireSimulator(cWorld & a_World, cIniFile & a_IniFile) : -cFireSimulator::~cFireSimulator() -{ -} - - - - - void cFireSimulator::SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk) { cCoordWithIntList & Data = a_Chunk->GetFireSimulatorData(); @@ -241,28 +233,21 @@ bool cFireSimulator::DoesBurnForever(BLOCKTYPE a_BlockType) void cFireSimulator::AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) { - if ((a_Chunk == nullptr) || !a_Chunk->IsValid()) - { - return; - } - - const auto RelPos = cChunkDef::AbsoluteToRelative(a_Block, a_Chunk->GetPos()); - BLOCKTYPE BlockType = a_Chunk->GetBlock(RelPos); - if (!IsAllowedBlock(BlockType)) + if (!IsAllowedBlock(a_Block)) { return; } // Check for duplicates: - cFireSimulatorChunkData & ChunkData = a_Chunk->GetFireSimulatorData(); + cFireSimulatorChunkData & ChunkData = a_Chunk.GetFireSimulatorData(); for (cCoordWithIntList::iterator itr = ChunkData.begin(), end = ChunkData.end(); itr != end; ++itr) { const Vector3i ItrPos{itr->x, itr->y, itr->z}; - if (ItrPos == RelPos) + if (ItrPos == a_Position) { // Block already present, check if burn step should decrease // This means if fuel is removed, then the fire burns out sooner - const auto NewBurnStep = GetBurnStepTime(a_Chunk, RelPos); + const auto NewBurnStep = GetBurnStepTime(&a_Chunk, a_Position); if (itr->Data > NewBurnStep) { FIRE_FLOG("FS: Block lost its fuel at {0}", a_Block); @@ -274,7 +259,7 @@ void cFireSimulator::AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a } // for itr - ChunkData[] FIRE_FLOG("FS: Adding block {0}", a_Block); - ChunkData.push_back(cCoordWithInt(RelPos.x, RelPos.y, RelPos.z, 100)); + ChunkData.push_back(cCoordWithInt(a_Position.x, a_Position.y, a_Position.z, 100)); } diff --git a/src/Simulator/FireSimulator.h b/src/Simulator/FireSimulator.h index 1bc6e7c0b..1e9b0b6d7 100644 --- a/src/Simulator/FireSimulator.h +++ b/src/Simulator/FireSimulator.h @@ -19,18 +19,19 @@ class cFireSimulator : public cSimulator { public: + cFireSimulator(cWorld & a_World, cIniFile & a_IniFile); - virtual ~cFireSimulator() override; - - virtual void Simulate(float a_Dt) override { UNUSED(a_Dt);} // not used - virtual void SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk) override; - - virtual bool IsAllowedBlock(BLOCKTYPE a_BlockType) override; static bool IsFuel (BLOCKTYPE a_BlockType); static bool DoesBurnForever(BLOCKTYPE a_BlockType); -protected: +private: + + virtual void Simulate(float a_Dt) override { UNUSED(a_Dt);} // not used + virtual void SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk) override; + + static bool IsAllowedBlock(BLOCKTYPE a_BlockType); + /** Time (in msec) that a fire block takes to burn with a fuel block into the next step */ unsigned m_BurnStepTimeFuel; diff --git a/src/Simulator/FloodyFluidSimulator.cpp b/src/Simulator/FloodyFluidSimulator.cpp index c63d7e965..5f4d5ba85 100644 --- a/src/Simulator/FloodyFluidSimulator.cpp +++ b/src/Simulator/FloodyFluidSimulator.cpp @@ -309,7 +309,7 @@ void cFloodyFluidSimulator::SpreadToNeighbor(cChunk * a_NearChunk, int a_RelX, i // Spread: FLUID_FLOG(" Spreading to {0} with meta {1}", absPos, a_NewMeta); a_NearChunk->SetBlock(relPos, m_FluidBlock, a_NewMeta); - m_World.GetSimulatorManager()->WakeUp(absPos, a_NearChunk); + m_World.GetSimulatorManager()->WakeUp(*a_NearChunk, relPos); HardenBlock(a_NearChunk, relPos, m_FluidBlock, a_NewMeta); } diff --git a/src/Simulator/FluidSimulator.h b/src/Simulator/FluidSimulator.h index e9157fa69..2dc499375 100644 --- a/src/Simulator/FluidSimulator.h +++ b/src/Simulator/FluidSimulator.h @@ -43,14 +43,11 @@ public: cFluidSimulator(cWorld & a_World, BLOCKTYPE a_Fluid, BLOCKTYPE a_StationaryFluid); - // cSimulator overrides: - virtual bool IsAllowedBlock(BLOCKTYPE a_BlockType) override; - /** Returns a unit vector in the direction the fluid is flowing or a zero-vector if not flowing. */ virtual Vector3f GetFlowingDirection(int a_X, int a_Y, int a_Z); /** Creates a ChunkData object for the simulator to use. The simulator returns the correct object type. */ - virtual cFluidSimulatorData * CreateChunkData(void) { return nullptr; } + virtual cFluidSimulatorData * CreateChunkData(void) = 0; bool IsFluidBlock (BLOCKTYPE a_BlockType) const { return (a_BlockType == m_FluidBlock); } bool IsStationaryFluidBlock(BLOCKTYPE a_BlockType) const { return (a_BlockType == m_StationaryFluidBlock); } @@ -65,6 +62,9 @@ public: bool IsHigherMeta(NIBBLETYPE a_Meta1, NIBBLETYPE a_Meta2); protected: + + bool IsAllowedBlock(BLOCKTYPE a_BlockType); + BLOCKTYPE m_FluidBlock; // The fluid block type that needs simulating BLOCKTYPE m_StationaryFluidBlock; // The fluid block type that indicates no simulation is needed }; diff --git a/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.cpp b/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.cpp index 33c0f9523..f2c8b7e65 100644 --- a/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.cpp +++ b/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.cpp @@ -273,26 +273,18 @@ void cIncrementalRedstoneSimulator::ProcessWorkItem(cChunk & Chunk, cChunk & Tic void cIncrementalRedstoneSimulator::AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) { - // Can't inspect block, ignore: - if ((a_Chunk == nullptr) || !a_Chunk->IsValid()) + auto & ChunkData = *static_cast(a_Chunk.GetRedstoneSimulatorData()); + + if (!IsRedstone(a_Block)) { return; } - auto & ChunkData = *static_cast(a_Chunk->GetRedstoneSimulatorData()); - const auto Relative = cChunkDef::AbsoluteToRelative(a_Block, a_Chunk->GetPos()); - const auto CurrentBlock = a_Chunk->GetBlock(Relative); - - if (!IsRedstone(CurrentBlock)) + if (IsAlwaysTicked(a_Block)) { - return; - } - - if (IsAlwaysTicked(CurrentBlock)) - { - ChunkData.AlwaysTickedPositions.emplace(Relative); + ChunkData.AlwaysTickedPositions.emplace(a_Position); } // Always update redstone devices: - ChunkData.WakeUp(Relative); + ChunkData.WakeUp(a_Position); } diff --git a/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.h b/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.h index 7f1a6a9cf..44c63a5a8 100644 --- a/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.h +++ b/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.h @@ -21,26 +21,7 @@ public: { } -private: - - virtual void WakeUp(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) override; - - virtual void Simulate(float Dt) override {}; - virtual void SimulateChunk(std::chrono::milliseconds Dt, int ChunkX, int ChunkZ, cChunk * Chunk) override; - - void ProcessWorkItem(cChunk & Chunk, cChunk & TickingSource, const Vector3i Position); - - virtual cIncrementalRedstoneSimulatorChunkData * CreateChunkData() override - { - return new cIncrementalRedstoneSimulatorChunkData; - } - - virtual bool IsAllowedBlock(BLOCKTYPE a_BlockType) override - { - return IsRedstone(a_BlockType); - } - - virtual void AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) override; + static const cRedstoneHandler * GetComponentHandler(BLOCKTYPE a_BlockType); /** Returns if a block is a mechanism (something that accepts power and does something) Used by torches to determine if they will power a block */ @@ -164,7 +145,20 @@ private: } } - static const cRedstoneHandler * GetComponentHandler(BLOCKTYPE a_BlockType); +private: + + virtual void WakeUp(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) override; + virtual void Simulate(float Dt) override {}; + virtual void SimulateChunk(std::chrono::milliseconds Dt, int ChunkX, int ChunkZ, cChunk * Chunk) override; + + void ProcessWorkItem(cChunk & Chunk, cChunk & TickingSource, const Vector3i Position); + + virtual cIncrementalRedstoneSimulatorChunkData * CreateChunkData() override + { + return new cIncrementalRedstoneSimulatorChunkData; + } + + virtual void AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) override; private: diff --git a/src/Simulator/NoopFluidSimulator.h b/src/Simulator/NoopFluidSimulator.h index 71c37d92d..2be4f86a9 100644 --- a/src/Simulator/NoopFluidSimulator.h +++ b/src/Simulator/NoopFluidSimulator.h @@ -22,18 +22,17 @@ class cNoopFluidSimulator: public: - cNoopFluidSimulator(cWorld & a_World, BLOCKTYPE a_Fluid, BLOCKTYPE a_StationaryFluid): - Super(a_World, a_Fluid, a_StationaryFluid) - { - } + using Super::cFluidSimulator; - // cSimulator overrides: +private: + + virtual void Simulate(float a_Dt) override { UNUSED(a_Dt);} virtual void AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) override { UNUSED(a_Block); UNUSED(a_Chunk); } - virtual void Simulate(float a_Dt) override { UNUSED(a_Dt);} + virtual cFluidSimulatorData * CreateChunkData(void) override { return nullptr; } } ; diff --git a/src/Simulator/NoopRedstoneSimulator.h b/src/Simulator/NoopRedstoneSimulator.h index 8d47ceccf..746ee1886 100644 --- a/src/Simulator/NoopRedstoneSimulator.h +++ b/src/Simulator/NoopRedstoneSimulator.h @@ -20,14 +20,6 @@ public: } virtual void Simulate(float a_Dt) override { UNUSED(a_Dt);} // not used - virtual void SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk) override - { - UNUSED(a_Dt); - UNUSED(a_ChunkX); - UNUSED(a_ChunkZ); - UNUSED(a_Chunk); - } - virtual bool IsAllowedBlock( BLOCKTYPE a_BlockType) override { return false; } virtual void AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) override { UNUSED(a_Block); diff --git a/src/Simulator/SandSimulator.cpp b/src/Simulator/SandSimulator.cpp index ef02339bc..95f514cc9 100644 --- a/src/Simulator/SandSimulator.cpp +++ b/src/Simulator/SandSimulator.cpp @@ -99,29 +99,23 @@ bool cSandSimulator::IsAllowedBlock(BLOCKTYPE a_BlockType) void cSandSimulator::AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) { - if ((a_Chunk == nullptr) || !a_Chunk->IsValid()) - { - return; - } - int RelX = a_Block.x - a_Chunk->GetPosX() * cChunkDef::Width; - int RelZ = a_Block.z - a_Chunk->GetPosZ() * cChunkDef::Width; - if (!IsAllowedBlock(a_Chunk->GetBlock(RelX, a_Block.y, RelZ))) + if (!IsAllowedBlock(a_Block)) { return; } // Check for duplicates: - cSandSimulatorChunkData & ChunkData = a_Chunk->GetSandSimulatorData(); + cSandSimulatorChunkData & ChunkData = a_Chunk.GetSandSimulatorData(); for (cSandSimulatorChunkData::iterator itr = ChunkData.begin(); itr != ChunkData.end(); ++itr) { - if ((itr->x == RelX) && (itr->y == a_Block.y) && (itr->z == RelZ)) + if ((itr->x == a_Position.x) && (itr->y == a_Position.y) && (itr->z == a_Position.z)) { return; } } m_TotalBlocks += 1; - ChunkData.push_back(cCoordWithInt(RelX, a_Block.y, RelZ)); + ChunkData.push_back(cCoordWithInt(a_Position.x, a_Position.y, a_Position.z)); } diff --git a/src/Simulator/SandSimulator.h b/src/Simulator/SandSimulator.h index 665208fbe..113484158 100644 --- a/src/Simulator/SandSimulator.h +++ b/src/Simulator/SandSimulator.h @@ -30,11 +30,6 @@ public: cSandSimulator(cWorld & a_World, cIniFile & a_IniFile); - // cSimulator overrides: - virtual void Simulate(float a_Dt) override { UNUSED(a_Dt);} // not used - virtual void SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk) override; - virtual bool IsAllowedBlock(BLOCKTYPE a_BlockType) override; - /** Returns true if a falling-able block can start falling through the specified block type */ static bool CanStartFallingThrough(BLOCKTYPE a_BlockType); @@ -56,7 +51,12 @@ public: BLOCKTYPE a_FallingBlockType, NIBBLETYPE a_FallingBlockMeta ); -protected: +private: + + virtual void Simulate(float a_Dt) override { UNUSED(a_Dt);} // not used + virtual void SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk) override; + + static bool IsAllowedBlock(BLOCKTYPE a_BlockType); bool m_IsInstantFall; // If set to true, blocks don't fall using cFallingBlock entity, but instantly instead diff --git a/src/Simulator/Simulator.h b/src/Simulator/Simulator.h index 5bd5d8f30..aacd5f52f 100644 --- a/src/Simulator/Simulator.h +++ b/src/Simulator/Simulator.h @@ -32,6 +32,7 @@ public: protected: friend class cChunk; // Calls AddBlock() in its WakeUpSimulators() function, to speed things up + friend class cSimulatorManager; // Class reponsible for dispatching calls to the various slave Simulators virtual void Simulate(float a_Dt) = 0; virtual void SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk) @@ -42,11 +43,8 @@ protected: UNUSED(a_Chunk); } - /** Returns true if the specified block type is "interesting" for this simulator. */ - virtual bool IsAllowedBlock(BLOCKTYPE a_BlockType) = 0; - /** Called to simulate a new block. Unlike WakeUp this function will perform minimal checking. - It queues the block to be simulated as fast as possible, only making sure that the block type IsAllowedBlock. */ + It queues the block to be simulated as fast as possible, suitable for area wakeups. */ virtual void AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) = 0; /** Called to simulate a single new block, typically as a result of a single block break or change. diff --git a/src/Simulator/VaporizeFluidSimulator.cpp b/src/Simulator/VaporizeFluidSimulator.cpp index 8063a0706..82f71c03f 100644 --- a/src/Simulator/VaporizeFluidSimulator.cpp +++ b/src/Simulator/VaporizeFluidSimulator.cpp @@ -13,32 +13,14 @@ -cVaporizeFluidSimulator::cVaporizeFluidSimulator(cWorld & a_World, BLOCKTYPE a_Fluid, BLOCKTYPE a_StationaryFluid) : - Super(a_World, a_Fluid, a_StationaryFluid) -{ -} - - - - - void cVaporizeFluidSimulator::AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) { - if (a_Chunk == nullptr) + if ((a_Block == m_FluidBlock) || (a_Block == m_StationaryFluidBlock)) { - return; - } - auto relPos = cChunkDef::AbsoluteToRelative(a_Block); - auto blockType = a_Chunk->GetBlock(relPos); - if ( - (blockType == m_FluidBlock) || - (blockType == m_StationaryFluidBlock) - ) - { - a_Chunk->SetBlock(relPos, E_BLOCK_AIR, 0); + a_Chunk.FastSetBlock(a_Position, E_BLOCK_AIR, 0); World::GetBroadcastInterface(m_World).BroadcastSoundEffect( "block.fire.extinguish", - Vector3d(a_Block), + Vector3d(a_Position), 1.0f, 0.6f ); diff --git a/src/Simulator/VaporizeFluidSimulator.h b/src/Simulator/VaporizeFluidSimulator.h index 2d259e56e..ef61c9a84 100644 --- a/src/Simulator/VaporizeFluidSimulator.h +++ b/src/Simulator/VaporizeFluidSimulator.h @@ -23,11 +23,13 @@ class cVaporizeFluidSimulator: public: - cVaporizeFluidSimulator(cWorld & a_World, BLOCKTYPE a_Fluid, BLOCKTYPE a_StationaryFluid); + using Super::cFluidSimulator; + +private: - // cSimulator overrides: - virtual void AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) override; virtual void Simulate(float a_Dt) override; + virtual void AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block) override; + virtual cFluidSimulatorData * CreateChunkData(void) override { return nullptr; } } ;