diff options
Diffstat (limited to 'source/Simulator')
-rw-r--r-- | source/Simulator/DelayedFluidSimulator.cpp | 158 | ||||
-rw-r--r-- | source/Simulator/DelayedFluidSimulator.h | 82 | ||||
-rw-r--r-- | source/Simulator/FireSimulator.cpp | 374 | ||||
-rw-r--r-- | source/Simulator/FireSimulator.h | 75 | ||||
-rw-r--r-- | source/Simulator/FloodyFluidSimulator.cpp | 330 | ||||
-rw-r--r-- | source/Simulator/FloodyFluidSimulator.h | 53 | ||||
-rw-r--r-- | source/Simulator/FluidSimulator.cpp | 212 | ||||
-rw-r--r-- | source/Simulator/FluidSimulator.h | 75 | ||||
-rw-r--r-- | source/Simulator/NoopFluidSimulator.h | 36 | ||||
-rw-r--r-- | source/Simulator/RedstoneSimulator.cpp | 1073 | ||||
-rw-r--r-- | source/Simulator/RedstoneSimulator.h | 199 | ||||
-rw-r--r-- | source/Simulator/SandSimulator.cpp | 309 | ||||
-rw-r--r-- | source/Simulator/SandSimulator.h | 63 | ||||
-rw-r--r-- | source/Simulator/Simulator.cpp | 51 | ||||
-rw-r--r-- | source/Simulator/Simulator.h | 46 | ||||
-rw-r--r-- | source/Simulator/SimulatorManager.cpp | 80 | ||||
-rw-r--r-- | source/Simulator/SimulatorManager.h | 52 | ||||
-rw-r--r-- | source/Simulator/VaporizeFluidSimulator.cpp | 53 | ||||
-rw-r--r-- | source/Simulator/VaporizeFluidSimulator.h | 34 |
19 files changed, 0 insertions, 3355 deletions
diff --git a/source/Simulator/DelayedFluidSimulator.cpp b/source/Simulator/DelayedFluidSimulator.cpp deleted file mode 100644 index a4645ca09..000000000 --- a/source/Simulator/DelayedFluidSimulator.cpp +++ /dev/null @@ -1,158 +0,0 @@ - -// DelayedFluidSimulator.cpp - -// Interfaces to the cDelayedFluidSimulator class representing a fluid simulator that has a configurable delay -// before simulating a block. Each tick it takes a consecutive delay "slot" and simulates only blocks in that slot. - -#include "Globals.h" - -#include "DelayedFluidSimulator.h" -#include "../World.h" -#include "../Chunk.h" - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cDelayedFluidSimulatorChunkData::cSlot - -bool cDelayedFluidSimulatorChunkData::cSlot::Add(int a_RelX, int a_RelY, int a_RelZ) -{ - ASSERT(a_RelZ >= 0); - ASSERT(a_RelZ < ARRAYCOUNT(m_Blocks)); - - cCoordWithIntVector & Blocks = m_Blocks[a_RelZ]; - int Index = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY, a_RelZ); - for (cCoordWithIntVector::const_iterator itr = Blocks.begin(), end = Blocks.end(); itr != end; ++itr) - { - if (itr->Data == Index) - { - // Already present - return false; - } - } // for itr - Blocks[] - Blocks.push_back(cCoordWithInt(a_RelX, a_RelY, a_RelZ, Index)); - return true; -} - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cDelayedFluidSimulatorChunkData: - -cDelayedFluidSimulatorChunkData::cDelayedFluidSimulatorChunkData(int a_TickDelay) : - m_Slots(new cSlot[a_TickDelay]) -{ -} - - - - - -cDelayedFluidSimulatorChunkData::~cDelayedFluidSimulatorChunkData() -{ - delete[] m_Slots; - m_Slots = NULL; -} - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cDelayedFluidSimulator: - -cDelayedFluidSimulator::cDelayedFluidSimulator(cWorld & a_World, BLOCKTYPE a_Fluid, BLOCKTYPE a_StationaryFluid, int a_TickDelay) : - super(a_World, a_Fluid, a_StationaryFluid), - m_TickDelay(a_TickDelay), - m_AddSlotNum(a_TickDelay - 1), - m_SimSlotNum(0), - m_TotalBlocks(0) -{ -} - - - - - -void cDelayedFluidSimulator::AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk) -{ - if ((a_BlockY < 0) || (a_BlockY >= cChunkDef::Height)) - { - // Not inside the world (may happen when rclk with a full bucket - the client sends Y = -1) - return; - } - - if ((a_Chunk == NULL) || !a_Chunk->IsValid()) - { - return; - } - - int RelX = a_BlockX - a_Chunk->GetPosX() * cChunkDef::Width; - int RelZ = a_BlockZ - a_Chunk->GetPosZ() * cChunkDef::Width; - BLOCKTYPE BlockType = a_Chunk->GetBlock(RelX, a_BlockY, RelZ); - if (BlockType != m_FluidBlock) - { - return; - } - - void * ChunkDataRaw = (m_FluidBlock == E_BLOCK_WATER) ? a_Chunk->GetWaterSimulatorData() : a_Chunk->GetLavaSimulatorData(); - cDelayedFluidSimulatorChunkData * ChunkData = (cDelayedFluidSimulatorChunkData *)ChunkDataRaw; - cDelayedFluidSimulatorChunkData::cSlot & Slot = ChunkData->m_Slots[m_AddSlotNum]; - - // Add, if not already present: - if (!Slot.Add(RelX, a_BlockY, RelZ)) - { - return; - } - - ++m_TotalBlocks; -} - - - - - -void cDelayedFluidSimulator::Simulate(float a_Dt) -{ - m_AddSlotNum = m_SimSlotNum; - m_SimSlotNum += 1; - if (m_SimSlotNum >= m_TickDelay) - { - m_SimSlotNum = 0; - } -} - - - - - -void cDelayedFluidSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk) -{ - void * ChunkDataRaw = (m_FluidBlock == E_BLOCK_WATER) ? a_Chunk->GetWaterSimulatorData() : a_Chunk->GetLavaSimulatorData(); - cDelayedFluidSimulatorChunkData * ChunkData = (cDelayedFluidSimulatorChunkData *)ChunkDataRaw; - cDelayedFluidSimulatorChunkData::cSlot & Slot = ChunkData->m_Slots[m_SimSlotNum]; - - // Simulate all the blocks in the scheduled slot: - for (int i = 0; i < ARRAYCOUNT(Slot.m_Blocks); i++) - { - cCoordWithIntVector & Blocks = Slot.m_Blocks[i]; - if (Blocks.empty()) - { - continue; - } - for (cCoordWithIntVector::iterator itr = Blocks.begin(), end = Blocks.end(); itr != end; ++itr) - { - SimulateBlock(a_Chunk, itr->x, itr->y, itr->z); - } - m_TotalBlocks -= Blocks.size(); - Blocks.clear(); - } -} - - - - diff --git a/source/Simulator/DelayedFluidSimulator.h b/source/Simulator/DelayedFluidSimulator.h deleted file mode 100644 index c81500741..000000000 --- a/source/Simulator/DelayedFluidSimulator.h +++ /dev/null @@ -1,82 +0,0 @@ - -// DelayedFluidSimulator.h - -// Interfaces to the cDelayedFluidSimulator class representing a fluid simulator that has a configurable delay -// before simulating a block. Each tick it takes a consecutive delay "slot" and simulates only blocks in that slot. - - - - -#pragma once - -#include "FluidSimulator.h" - - - - - -class cDelayedFluidSimulatorChunkData : - public cFluidSimulatorData -{ -public: - class cSlot - { - public: - /// Returns true if the specified block is stored - bool HasBlock(int a_RelX, int a_RelY, int a_RelZ); - - /// Adds the specified block unless already present; returns true if added, false if the block was already present - bool Add(int a_RelX, int a_RelY, int a_RelZ); - - /** Array of block containers, each item stores blocks for one Z coord - Int param is the block index (for faster duplicate comparison in Add()) - */ - cCoordWithIntVector m_Blocks[16]; - } ; - - cDelayedFluidSimulatorChunkData(int a_TickDelay); - virtual ~cDelayedFluidSimulatorChunkData(); - - /// Slots, one for each delay tick, each containing the blocks to simulate - cSlot * m_Slots; -} ; - - - - - -class cDelayedFluidSimulator : - public cFluidSimulator -{ - typedef cFluidSimulator super; - -public: - cDelayedFluidSimulator(cWorld & a_World, BLOCKTYPE a_Fluid, BLOCKTYPE a_StationaryFluid, int a_TickDelay); - - // cSimulator overrides: - virtual void AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk) override; - virtual void Simulate(float a_Dt) override; - virtual void SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk) override; - virtual cFluidSimulatorData * CreateChunkData(void) override { return new cDelayedFluidSimulatorChunkData(m_TickDelay); } - -protected: - - 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 - - int m_TotalBlocks; // Statistics only: the total number of blocks currently queued - - /* - Slots: - | 0 | 1 | ... | m_AddSlotNum | m_SimSlotNum | ... | m_TickDelay - 1 | - adding blocks here ^ | ^ simulating here - */ - - /// Called from SimulateChunk() to simulate each block in one slot of blocks. Descendants override this method to provide custom simulation. - virtual void SimulateBlock(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ) = 0; -} ; - - - - diff --git a/source/Simulator/FireSimulator.cpp b/source/Simulator/FireSimulator.cpp deleted file mode 100644 index ac3fb9695..000000000 --- a/source/Simulator/FireSimulator.cpp +++ /dev/null @@ -1,374 +0,0 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "FireSimulator.h" -#include "../World.h" -#include "../BlockID.h" -#include "../Defines.h" -#include "../Chunk.h" - - - - - -// Easy switch for turning on debugging logging: -#if 0 - #define FLOG LOGD -#else - #define FLOG(...) -#endif - - - - - -#define MAX_CHANCE_REPLACE_FUEL 100000 -#define MAX_CHANCE_FLAMMABILITY 100000 - - - - - -static const struct -{ - int x, y, z; -} gCrossCoords[] = -{ - { 1, 0, 0}, - {-1, 0, 0}, - { 0, 0, 1}, - { 0, 0, -1}, -} ; - - - - - -static const struct -{ - int x, y, z; -} gNeighborCoords[] = -{ - { 1, 0, 0}, - {-1, 0, 0}, - { 0, 1, 0}, - { 0, -1, 0}, - { 0, 0, 1}, - { 0, 0, -1}, -} ; - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cFireSimulator: - -cFireSimulator::cFireSimulator(cWorld & a_World, cIniFile & a_IniFile) : - cSimulator(a_World) -{ - // Read params from the ini file: - m_BurnStepTimeFuel = a_IniFile.GetValueSetI("FireSimulator", "BurnStepTimeFuel", 500); - m_BurnStepTimeNonfuel = a_IniFile.GetValueSetI("FireSimulator", "BurnStepTimeNonfuel", 100); - m_Flammability = a_IniFile.GetValueSetI("FireSimulator", "Flammability", 50); - m_ReplaceFuelChance = a_IniFile.GetValueSetI("FireSimulator", "ReplaceFuelChance", 50000); -} - - - - - -cFireSimulator::~cFireSimulator() -{ -} - - - - - -void cFireSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk) -{ - cCoordWithIntList & Data = a_Chunk->GetFireSimulatorData(); - - int NumMSecs = (int)a_Dt; - for (cCoordWithIntList::iterator itr = Data.begin(); itr != Data.end();) - { - int idx = cChunkDef::MakeIndexNoCheck(itr->x, itr->y, itr->z); - BLOCKTYPE BlockType = a_Chunk->GetBlock(idx); - - if (!IsAllowedBlock(BlockType)) - { - // The block is no longer eligible (not a fire block anymore; a player probably placed a block over the fire) - FLOG("FS: Removing block {%d, %d, %d}", - itr->x + a_ChunkX * cChunkDef::Width, itr->y, itr->z + a_ChunkZ * cChunkDef::Width - ); - itr = Data.erase(itr); - continue; - } - - // Try to spread the fire: - TrySpreadFire(a_Chunk, itr->x, itr->y, itr->z); - - itr->Data -= NumMSecs; - if (itr->Data >= 0) - { - // Not yet, wait for it longer - ++itr; - continue; - } - - // Burn out the fire one step by increasing the meta: - /* - FLOG("FS: Fire at {%d, %d, %d} is stepping", - itr->x + a_ChunkX * cChunkDef::Width, itr->y, itr->z + a_ChunkZ * cChunkDef::Width - ); - */ - NIBBLETYPE BlockMeta = a_Chunk->GetMeta(idx); - if (BlockMeta == 0x0f) - { - // The fire burnt out completely - FLOG("FS: Fire at {%d, %d, %d} burnt out, removing the fire block", - itr->x + a_ChunkX * cChunkDef::Width, itr->y, itr->z + a_ChunkZ * cChunkDef::Width - ); - a_Chunk->SetBlock(itr->x, itr->y, itr->z, E_BLOCK_AIR, 0); - RemoveFuelNeighbors(a_Chunk, itr->x, itr->y, itr->z); - itr = Data.erase(itr); - continue; - } - a_Chunk->SetMeta(idx, BlockMeta + 1); - itr->Data = GetBurnStepTime(a_Chunk, itr->x, itr->y, itr->z); // TODO: Add some randomness into this - } // for itr - Data[] -} - - - - - -bool cFireSimulator::IsAllowedBlock(BLOCKTYPE a_BlockType) -{ - return (a_BlockType == E_BLOCK_FIRE); -} - - - - - -bool cFireSimulator::IsFuel(BLOCKTYPE a_BlockType) -{ - switch (a_BlockType) - { - case E_BLOCK_PLANKS: - case E_BLOCK_LEAVES: - case E_BLOCK_LOG: - case E_BLOCK_WOOL: - case E_BLOCK_BOOKCASE: - case E_BLOCK_FENCE: - case E_BLOCK_TNT: - case E_BLOCK_VINES: - { - return true; - } - } - return false; -} - - - - - -bool cFireSimulator::IsForever(BLOCKTYPE a_BlockType) -{ - return (a_BlockType == E_BLOCK_NETHERRACK); -} - - - - - -void cFireSimulator::AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk) -{ - if ((a_Chunk == NULL) || !a_Chunk->IsValid()) - { - return; - } - - int RelX = a_BlockX - a_Chunk->GetPosX() * cChunkDef::Width; - int RelZ = a_BlockZ - a_Chunk->GetPosZ() * cChunkDef::Width; - BLOCKTYPE BlockType = a_Chunk->GetBlock(RelX, a_BlockY, RelZ); - if (!IsAllowedBlock(BlockType)) - { - return; - } - - // Check for duplicates: - cFireSimulatorChunkData & ChunkData = a_Chunk->GetFireSimulatorData(); - for (cCoordWithIntList::iterator itr = ChunkData.begin(), end = ChunkData.end(); itr != end; ++itr) - { - if ((itr->x == RelX) && (itr->y == a_BlockY) && (itr->z == RelZ)) - { - // Already present, skip adding - return; - } - } // for itr - ChunkData[] - - FLOG("FS: Adding block {%d, %d, %d}", a_BlockX, a_BlockY, a_BlockZ); - ChunkData.push_back(cCoordWithInt(RelX, a_BlockY, RelZ, 100)); -} - - - - - -int cFireSimulator::GetBurnStepTime(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ) -{ - bool IsBlockBelowSolid = false; - if (a_RelY > 0) - { - BLOCKTYPE BlockBelow = a_Chunk->GetBlock(a_RelX, a_RelY - 1, a_RelZ); - if (IsForever(BlockBelow)) - { - // Is burning atop of netherrack, burn forever (re-check in 10 sec) - return 10000; - } - if (IsFuel(BlockBelow)) - { - return m_BurnStepTimeFuel; - } - IsBlockBelowSolid = g_BlockIsSolid[BlockBelow]; - } - - for (int i = 0; i < ARRAYCOUNT(gCrossCoords); i++) - { - BLOCKTYPE BlockType; - NIBBLETYPE BlockMeta; - if (a_Chunk->UnboundedRelGetBlock(a_RelX + gCrossCoords[i].x, a_RelY, a_RelZ + gCrossCoords[i].z, BlockType, BlockMeta)) - { - if (IsFuel(BlockType)) - { - return m_BurnStepTimeFuel; - } - } - } // for i - gCrossCoords[] - - if (!IsBlockBelowSolid && (a_RelY >= 0)) - { - // Checked through everything, nothing was flammable - // If block below isn't solid, we can't have fire, it would be a non-fueled fire - // SetBlock just to make sure fire doesn't spawn - a_Chunk->SetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_AIR, 0); - return 0; - } - return m_BurnStepTimeNonfuel; -} - - - - - -void cFireSimulator::TrySpreadFire(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ) -{ - /* - if (m_World.GetTickRandomNumber(10000) > 100) - { - // Make the chance to spread 100x smaller - return; - } - */ - - for (int x = a_RelX - 1; x <= a_RelX + 1; x++) - { - for (int z = a_RelZ - 1; z <= a_RelZ + 1; z++) - { - for (int y = a_RelY - 1; y <= a_RelY + 2; y++) // flames spread up one more block than around - { - // No need to check the coords for equality with the parent block, - // it cannot catch fire anyway (because it's not an air block) - - if (m_World.GetTickRandomNumber(MAX_CHANCE_FLAMMABILITY) > m_Flammability) - { - continue; - } - - // Start the fire in the neighbor {x, y, z} - /* - FLOG("FS: Trying to start fire at {%d, %d, %d}.", - x + a_Chunk->GetPosX() * cChunkDef::Width, y, z + a_Chunk->GetPosZ() * cChunkDef::Width - ); - */ - if (CanStartFireInBlock(a_Chunk, x, y, z)) - { - FLOG("FS: Starting new fire at {%d, %d, %d}.", - x + a_Chunk->GetPosX() * cChunkDef::Width, y, z + a_Chunk->GetPosZ() * cChunkDef::Width - ); - a_Chunk->UnboundedRelSetBlock(x, y, z, E_BLOCK_FIRE, 0); - } - } // for y - } // for z - } // for x -} - - - - - -void cFireSimulator::RemoveFuelNeighbors(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ) -{ - for (int i = 0; i < ARRAYCOUNT(gNeighborCoords); i++) - { - BLOCKTYPE BlockType; - NIBBLETYPE BlockMeta; - if (!a_Chunk->UnboundedRelGetBlock(a_RelX + gNeighborCoords[i].x, a_RelY + gNeighborCoords[i].y, a_RelZ + gNeighborCoords[i].z, BlockType, BlockMeta)) - { - // Neighbor not accessible, ignore it - continue; - } - if (!IsFuel(BlockType)) - { - continue; - } - bool ShouldReplaceFuel = (m_World.GetTickRandomNumber(MAX_CHANCE_REPLACE_FUEL) < m_ReplaceFuelChance); - a_Chunk->UnboundedRelSetBlock( - a_RelX + gNeighborCoords[i].x, a_RelY + gNeighborCoords[i].y, a_RelZ + gNeighborCoords[i].z, - ShouldReplaceFuel ? E_BLOCK_FIRE : E_BLOCK_AIR, 0 - ); - } // for i - Coords[] -} - - - - - -bool cFireSimulator::CanStartFireInBlock(cChunk * a_NearChunk, int a_RelX, int a_RelY, int a_RelZ) -{ - BLOCKTYPE BlockType; - NIBBLETYPE BlockMeta; - if (!a_NearChunk->UnboundedRelGetBlock(a_RelX, a_RelY, a_RelZ, BlockType, BlockMeta)) - { - // The chunk is not accessible - return false; - } - - if (BlockType != E_BLOCK_AIR) - { - // Only an air block can be replaced by a fire block - return false; - } - - for (int i = 0; i < ARRAYCOUNT(gNeighborCoords); i++) - { - if (!a_NearChunk->UnboundedRelGetBlock(a_RelX + gNeighborCoords[i].x, a_RelY + gNeighborCoords[i].y, a_RelZ + gNeighborCoords[i].z, BlockType, BlockMeta)) - { - // Neighbor inaccessible, skip it while evaluating - continue; - } - if (IsFuel(BlockType)) - { - return true; - } - } // for i - Coords[] - return false; -} - - - - diff --git a/source/Simulator/FireSimulator.h b/source/Simulator/FireSimulator.h deleted file mode 100644 index 0d8a548ef..000000000 --- a/source/Simulator/FireSimulator.h +++ /dev/null @@ -1,75 +0,0 @@ - -#pragma once - -#include "Simulator.h" -#include "../BlockEntities/BlockEntity.h" - - - - - -/** The fire simulator takes care of the fire blocks. -It periodically increases their meta ("steps") until they "burn out"; it also supports the forever burning netherrack. -Each individual fire block gets stored in per-chunk data; that list is then used for fast retrieval. -The data value associated with each coord is used as the number of msec that the fire takes until -it progresses to the next step (blockmeta++). This value is updated if a neighbor is changed. -The simulator reads its parameters from the ini file given to the constructor. -*/ -class cFireSimulator : - public cSimulator -{ -public: - cFireSimulator(cWorld & a_World, cIniFile & a_IniFile); - ~cFireSimulator(); - - virtual void Simulate(float a_Dt) override {} // not used - virtual void SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk) override; - - virtual bool IsAllowedBlock(BLOCKTYPE a_BlockType) override; - - bool IsFuel (BLOCKTYPE a_BlockType); - bool IsForever(BLOCKTYPE a_BlockType); - -protected: - /// Time (in msec) that a fire block takes to burn with a fuel block into the next step - unsigned m_BurnStepTimeFuel; - - /// Time (in msec) that a fire block takes to burn without a fuel block into the next step - unsigned m_BurnStepTimeNonfuel; - - /// Chance [0..100000] of an adjacent fuel to catch fire on each tick - int m_Flammability; - - /// Chance [0..100000] of a fuel burning out being replaced by a new fire block instead of an air block - int m_ReplaceFuelChance; - - - virtual void AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk) override; - - /// Returns the time [msec] after which the specified fire block is stepped again; based on surrounding fuels - int GetBurnStepTime(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ); - - /// Tries to spread fire to a neighborhood of the specified block - void TrySpreadFire(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ); - - /// Removes all burnable blocks neighboring the specified block - void RemoveFuelNeighbors(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ); - - /** Returns true if a fire can be started in the specified block, - that is, it is an air block and has fuel next to it. - Note that a_NearChunk may be a chunk neighbor to the block specified! - The coords are relative to a_NearChunk but not necessarily in it. - */ - bool CanStartFireInBlock(cChunk * a_NearChunk, int a_RelX, int a_RelY, int a_RelZ); -} ; - - - - - -/// Stores individual fire blocks in the chunk; the int data is used as the time [msec] the fire takes to step to another stage (blockmeta++) -typedef cCoordWithIntList cFireSimulatorChunkData; - - - - diff --git a/source/Simulator/FloodyFluidSimulator.cpp b/source/Simulator/FloodyFluidSimulator.cpp deleted file mode 100644 index d204a1f8b..000000000 --- a/source/Simulator/FloodyFluidSimulator.cpp +++ /dev/null @@ -1,330 +0,0 @@ - -// FloodyFluidSimulator.cpp - -// Interfaces to the cFloodyFluidSimulator that represents a fluid simulator that tries to flood everything :) -// http://forum.mc-server.org/showthread.php?tid=565 - -#include "Globals.h" - -#include "FloodyFluidSimulator.h" -#include "../World.h" -#include "../Chunk.h" -#include "../BlockArea.h" -#include "../Blocks/BlockHandler.h" - - - - - -// Enable or disable detailed logging -#if 0 - #define FLOG LOGD -#else - #define FLOG(...) -#endif - - - - - -cFloodyFluidSimulator::cFloodyFluidSimulator( - cWorld & a_World, - BLOCKTYPE a_Fluid, - BLOCKTYPE a_StationaryFluid, - NIBBLETYPE a_Falloff, - int a_TickDelay, - int a_NumNeighborsForSource -) : - super(a_World, a_Fluid, a_StationaryFluid, a_TickDelay), - m_Falloff(a_Falloff), - m_NumNeighborsForSource(a_NumNeighborsForSource) -{ -} - - - - - -void cFloodyFluidSimulator::SimulateBlock(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ) -{ - FLOG("Simulating block {%d, %d, %d}: block %d, meta %d", - a_Chunk->GetPosX() * cChunkDef::Width + a_RelX, a_RelY, a_Chunk->GetPosZ() * cChunkDef::Width + a_RelZ, - a_Chunk->GetBlock(a_RelX, a_RelY, a_RelZ), - a_Chunk->GetMeta(a_RelX, a_RelY, a_RelZ) - ); - - NIBBLETYPE MyMeta = a_Chunk->GetMeta(a_RelX, a_RelY, a_RelZ); - if (!IsAnyFluidBlock(a_Chunk->GetBlock(a_RelX, a_RelY, a_RelZ))) - { - // Can happen - if a block is scheduled for simulating and gets replaced in the meantime. - FLOG(" BadBlockType exit"); - return; - } - - if (MyMeta != 0) - { - // Source blocks aren't checked for tributaries, others are. - if (CheckTributaries(a_Chunk, a_RelX, a_RelY, a_RelZ, MyMeta)) - { - // Has no tributary, has been decreased (in CheckTributaries()), - // no more processing needed (neighbors have been scheduled by the decrease) - FLOG(" CheckTributaries exit"); - return; - } - } - - // New meta for the spreading to neighbors: - // If this is a source block or was falling, the new meta is just the falloff - // Otherwise it is the current meta plus falloff (may be larger than max height, will be checked later) - NIBBLETYPE NewMeta = ((MyMeta == 0) || ((MyMeta & 0x08) != 0)) ? m_Falloff : (MyMeta + m_Falloff); - bool SpreadFurther = true; - if (a_RelY > 0) - { - BLOCKTYPE Below = a_Chunk->GetBlock(a_RelX, a_RelY - 1, a_RelZ); - if (IsPassableForFluid(Below) || IsBlockLava(Below) || IsBlockWater(Below)) - { - // Spread only down, possibly washing away what's there or turning lava to stone / cobble / obsidian: - SpreadToNeighbor(a_Chunk, a_RelX, a_RelY - 1, a_RelZ, 8); - SpreadFurther = false; - } - // If source creation is on, check for it here: - else if ( - (m_NumNeighborsForSource > 0) && // Source creation is on - (MyMeta == m_Falloff) && // Only exactly one block away from a source (fast bail-out) - !IsPassableForFluid(Below) && // Only exactly 1 block deep - CheckNeighborsForSource(a_Chunk, a_RelX, a_RelY, a_RelZ) // Did we create a source? - ) - { - // We created a source, no more spreading is to be done now - // Also has been re-scheduled for ticking in the next wave, so no marking is needed - return; - } - } - - if (SpreadFurther && (NewMeta < 8)) - { - // Spread to the neighbors: - SpreadToNeighbor(a_Chunk, a_RelX - 1, a_RelY, a_RelZ, NewMeta); - SpreadToNeighbor(a_Chunk, a_RelX + 1, a_RelY, a_RelZ, NewMeta); - SpreadToNeighbor(a_Chunk, a_RelX, a_RelY, a_RelZ - 1, NewMeta); - SpreadToNeighbor(a_Chunk, a_RelX, a_RelY, a_RelZ + 1, NewMeta); - } - - // Mark as processed: - a_Chunk->FastSetBlock(a_RelX, a_RelY, a_RelZ, m_StationaryFluidBlock, MyMeta); -} - - - - - -bool cFloodyFluidSimulator::CheckTributaries(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_MyMeta) -{ - // If we have a section above, check if there's fluid above this block that would feed it: - if (a_RelY < cChunkDef::Height - 1) - { - if (IsAnyFluidBlock(a_Chunk->GetBlock(a_RelX, a_RelY + 1, a_RelZ))) - { - // This block is fed from above, no more processing needed - FLOG(" Fed from above"); - return false; - } - } - - // Not fed from above, check if there's a feed from the side (but not if it's a downward-flowing block): - if (a_MyMeta != 8) - { - BLOCKTYPE BlockType; - NIBBLETYPE BlockMeta; - static const Vector3i Coords[] = - { - Vector3i( 1, 0, 0), - Vector3i(-1, 0, 0), - Vector3i( 0, 0, 1), - Vector3i( 0, 0, -1), - } ; - for (int i = 0; i < ARRAYCOUNT(Coords); i++) - { - if (!a_Chunk->UnboundedRelGetBlock(a_RelX + Coords[i].x, a_RelY, a_RelZ + Coords[i].z, BlockType, BlockMeta)) - { - continue; - } - if (IsAllowedBlock(BlockType) && IsHigherMeta(BlockMeta, a_MyMeta)) - { - // This block is fed, no more processing needed - FLOG(" Fed from {%d, %d, %d}, type %d, meta %d", - a_Chunk->GetPosX() * cChunkDef::Width + a_RelX + Coords[i].x, - a_RelY, - a_Chunk->GetPosZ() * cChunkDef::Width + a_RelZ + Coords[i].z, - BlockType, BlockMeta - ); - return false; - } - } // for i - Coords[] - } // if not fed from above - - // Block is not fed, decrease by m_Falloff levels: - if (a_MyMeta >= 8) - { - FLOG(" Not fed and downwards, turning into non-downwards meta %d", m_Falloff); - a_Chunk->SetBlock(a_RelX, a_RelY, a_RelZ, m_StationaryFluidBlock, m_Falloff); - } - else - { - a_MyMeta += m_Falloff; - if (a_MyMeta < 8) - { - FLOG(" Not fed, decreasing from %d to %d", a_MyMeta - m_Falloff, a_MyMeta); - a_Chunk->SetBlock(a_RelX, a_RelY, a_RelZ, m_StationaryFluidBlock, a_MyMeta); - } - else - { - FLOG(" Not fed, meta %d, erasing altogether", a_MyMeta); - a_Chunk->SetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_AIR, 0); - } - } - return true; -} - - - - - -void cFloodyFluidSimulator::SpreadToNeighbor(cChunk * a_NearChunk, int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_NewMeta) -{ - ASSERT(a_NewMeta <= 8); // Invalid meta values - ASSERT(a_NewMeta > 0); // Source blocks aren't spread - - BLOCKTYPE BlockType; - NIBBLETYPE BlockMeta; - if (!a_NearChunk->UnboundedRelGetBlock(a_RelX, a_RelY, a_RelZ, BlockType, BlockMeta)) - { - // Chunk not available - return; - } - - if (IsAllowedBlock(BlockType)) - { - if ((BlockMeta == a_NewMeta) || IsHigherMeta(BlockMeta, a_NewMeta)) - { - // Don't spread there, there's already a higher or same level there - return; - } - } - - // Check water - lava interaction: - if (m_FluidBlock == E_BLOCK_LAVA) - { - if (IsBlockWater(BlockType)) - { - // Lava flowing into water, change to stone / cobblestone based on direction: - BLOCKTYPE NewBlock = (a_NewMeta == 8) ? E_BLOCK_STONE : E_BLOCK_COBBLESTONE; - FLOG(" Lava flowing into water, turning water at rel {%d, %d, %d} into stone", - a_RelX, a_RelY, a_RelZ, - ItemTypeToString(NewBlock).c_str() - ); - a_NearChunk->UnboundedRelSetBlock(a_RelX, a_RelY, a_RelZ, NewBlock, 0); - m_World.BroadcastSoundEffect("random.fizz", a_RelX * 8, a_RelY * 8, a_RelZ * 8, 0.5f, 1.5f); - return; - } - } - else if (m_FluidBlock == E_BLOCK_WATER) - { - if (IsBlockLava(BlockType)) - { - // Water flowing into lava, change to cobblestone / obsidian based on dest block: - BLOCKTYPE NewBlock = (BlockMeta == 0) ? E_BLOCK_OBSIDIAN : E_BLOCK_COBBLESTONE; - FLOG(" Water flowing into lava, turning lava at rel {%d, %d, %d} into %s", - a_RelX, a_RelY, a_RelZ, ItemTypeToString(NewBlock).c_str() - ); - a_NearChunk->UnboundedRelSetBlock(a_RelX, a_RelY, a_RelZ, NewBlock, 0); - m_World.BroadcastSoundEffect("random.fizz", a_RelX * 8, a_RelY * 8, a_RelZ * 8, 0.5f, 1.5f); - return; - } - } - else - { - ASSERT(!"Unknown fluid!"); - } - - if (!IsPassableForFluid(BlockType)) - { - // Can't spread there - return; - } - - // Wash away the block there, if possible: - if (CanWashAway(BlockType)) - { - cBlockHandler * Handler = BlockHandler(BlockType); - if (Handler->DoesDropOnUnsuitable()) - { - Handler->DropBlock( - &m_World, NULL, - a_NearChunk->GetPosX() * cChunkDef::Width + a_RelX, - a_RelY, - a_NearChunk->GetPosZ() * cChunkDef::Width + a_RelZ - ); - } - } // if (CanWashAway) - - // Spread: - FLOG(" Spreading to {%d, %d, %d} with meta %d", - a_NearChunk->GetPosX() * cChunkDef::Width + a_RelX, - a_RelY, - a_NearChunk->GetPosZ() * cChunkDef::Width + a_RelZ, - a_NewMeta - ); - a_NearChunk->UnboundedRelSetBlock(a_RelX, a_RelY, a_RelZ, m_FluidBlock, a_NewMeta); -} - - - - - -bool cFloodyFluidSimulator::CheckNeighborsForSource(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ) -{ - FLOG(" Checking neighbors for source creation"); - - static const Vector3i NeighborCoords[] = - { - Vector3i(-1, 0, 0), - Vector3i( 1, 0, 0), - Vector3i( 0, 0, -1), - Vector3i( 0, 0, 1), - } ; - - int NumNeeded = m_NumNeighborsForSource; - for (int i = 0; i < ARRAYCOUNT(NeighborCoords); i++) - { - int x = a_RelX + NeighborCoords[i].x; - int y = a_RelY + NeighborCoords[i].y; - int z = a_RelZ + NeighborCoords[i].z; - BLOCKTYPE BlockType; - NIBBLETYPE BlockMeta; - if (!a_Chunk->UnboundedRelGetBlock(x, y, z, BlockType, BlockMeta)) - { - // Neighbor not available, skip it - continue; - } - // FLOG(" Neighbor at {%d, %d, %d}: %s", x, y, z, ItemToFullString(cItem(BlockType, 1, BlockMeta)).c_str()); - if ((BlockMeta == 0) && IsAnyFluidBlock(BlockType)) - { - NumNeeded--; - // FLOG(" Found a neighbor source at {%d, %d, %d}, NumNeeded := %d", x, y, z, NumNeeded); - if (NumNeeded == 0) - { - // Found enough, turn into a source and bail out - // FLOG(" Found enough neighbor sources, turning into a source"); - a_Chunk->SetBlock(a_RelX, a_RelY, a_RelZ, m_FluidBlock, 0); - return true; - } - } - } - // FLOG(" Not enough neighbors for turning into a source, NumNeeded = %d", NumNeeded); - return false; -} - - - - diff --git a/source/Simulator/FloodyFluidSimulator.h b/source/Simulator/FloodyFluidSimulator.h deleted file mode 100644 index c4af2e246..000000000 --- a/source/Simulator/FloodyFluidSimulator.h +++ /dev/null @@ -1,53 +0,0 @@ - -// FloodyFluidSimulator.h - -// Interfaces to the cFloodyFluidSimulator that represents a fluid simulator that tries to flood everything :) -// http://forum.mc-server.org/showthread.php?tid=565 - - - - - -#pragma once - -#include "DelayedFluidSimulator.h" - - - - - -// fwd: -class cBlockArea; - - - - - -class cFloodyFluidSimulator : - public cDelayedFluidSimulator -{ - typedef cDelayedFluidSimulator super; - -public: - cFloodyFluidSimulator(cWorld & a_World, BLOCKTYPE a_Fluid, BLOCKTYPE a_StationaryFluid, NIBBLETYPE a_Falloff, int a_TickDelay, int a_NumNeighborsForSource); - -protected: - NIBBLETYPE m_Falloff; - int m_NumNeighborsForSource; - - // cDelayedFluidSimulator overrides: - virtual void SimulateBlock(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ) override; - - /// Checks tributaries, if not fed, decreases the block's level and returns true - bool CheckTributaries(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_MyMeta); - - /// Spreads into the specified block, if the blocktype there allows. a_Area is for checking. - void SpreadToNeighbor(cChunk * a_NearChunk, int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_NewMeta); - - /// Checks if there are enough neighbors to create a source at the coords specified; turns into source and returns true if so - bool CheckNeighborsForSource(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ); -} ; - - - - diff --git a/source/Simulator/FluidSimulator.cpp b/source/Simulator/FluidSimulator.cpp deleted file mode 100644 index dac666484..000000000 --- a/source/Simulator/FluidSimulator.cpp +++ /dev/null @@ -1,212 +0,0 @@ - -#include "Globals.h" - -#include "FluidSimulator.h" -#include "../World.h" - - - - - -cFluidSimulator::cFluidSimulator(cWorld & a_World, BLOCKTYPE a_Fluid, BLOCKTYPE a_StationaryFluid) : - super(a_World), - m_FluidBlock(a_Fluid), - m_StationaryFluidBlock(a_StationaryFluid) -{ -} - - - - - -bool cFluidSimulator::IsAllowedBlock(BLOCKTYPE a_BlockType) -{ - return ((a_BlockType == m_FluidBlock) || (a_BlockType == m_StationaryFluidBlock)); -} - - - - - -bool cFluidSimulator::CanWashAway(BLOCKTYPE a_BlockType) -{ - switch (a_BlockType) - { - case E_BLOCK_BROWN_MUSHROOM: - case E_BLOCK_CACTUS: - case E_BLOCK_COBWEB: - case E_BLOCK_CROPS: - case E_BLOCK_DEAD_BUSH: - case E_BLOCK_RAIL: - case E_BLOCK_REDSTONE_TORCH_OFF: - case E_BLOCK_REDSTONE_TORCH_ON: - case E_BLOCK_REDSTONE_WIRE: - case E_BLOCK_RED_MUSHROOM: - case E_BLOCK_RED_ROSE: - case E_BLOCK_SNOW: - case E_BLOCK_SUGARCANE: - case E_BLOCK_TALL_GRASS: - case E_BLOCK_TORCH: - case E_BLOCK_YELLOW_FLOWER: - { - return true; - } - default: - { - return false; - } - } -} - - - - - -bool cFluidSimulator::IsSolidBlock(BLOCKTYPE a_BlockType) -{ - return !IsPassableForFluid(a_BlockType); -} - - - - - -bool cFluidSimulator::IsPassableForFluid(BLOCKTYPE a_BlockType) -{ - return ( - (a_BlockType == E_BLOCK_AIR) || - (a_BlockType == E_BLOCK_FIRE) || - IsAllowedBlock(a_BlockType) || - CanWashAway(a_BlockType) - ); -} - - - - - -bool cFluidSimulator::IsHigherMeta(NIBBLETYPE a_Meta1, NIBBLETYPE a_Meta2) -{ - if (a_Meta1 == 0) - { - // Source block is higher than anything, even itself. - return true; - } - if ((a_Meta1 & 0x08) != 0) - { - // Falling fluid is higher than anything, including self - return true; - } - - if (a_Meta2 == 0) - { - // Second block is a source and first block isn't - return false; - } - if ((a_Meta2 & 0x08) != 0) - { - // Second block is falling and the first one is neither a source nor falling - return false; - } - - // All special cases have been handled, now it's just a raw comparison: - return (a_Meta1 < a_Meta2); -} - - - - - -// TODO Not working very well yet :s -Direction cFluidSimulator::GetFlowingDirection(int a_X, int a_Y, int a_Z, bool a_Over) -{ - if ((a_Y < 0) || (a_Y >= cChunkDef::Height)) - { - return NONE; - } - BLOCKTYPE BlockID = m_World.GetBlock(a_X, a_Y, a_Z); - if (!IsAllowedBlock(BlockID)) // No Fluid -> No Flowing direction :D - { - return NONE; - } - - /* - Disabled because of causing problems and being useless atm - char BlockBelow = m_World.GetBlock(a_X, a_Y - 1, a_Z); //If there is nothing or fluid below it -> dominating flow is down :D - if (BlockBelow == E_BLOCK_AIR || IsAllowedBlock(BlockBelow)) - return Y_MINUS; - */ - - NIBBLETYPE LowestPoint = m_World.GetBlockMeta(a_X, a_Y, a_Z); //Current Block Meta so only lower points will be counted - int X = 0, Y = 0, Z = 0; //Lowest Pos will be stored here - - if (IsAllowedBlock(m_World.GetBlock(a_X, a_Y + 1, a_Z)) && a_Over) //check for upper block to flow because this also affects the flowing direction - { - return GetFlowingDirection(a_X, a_Y + 1, a_Z, false); - } - - std::vector< Vector3i * > Points; - - Points.reserve(4); //Already allocate 4 places :D - - //add blocks around the checking pos - Points.push_back(new Vector3i(a_X - 1, a_Y, a_Z)); - Points.push_back(new Vector3i(a_X + 1, a_Y, a_Z)); - Points.push_back(new Vector3i(a_X, a_Y, a_Z + 1)); - Points.push_back(new Vector3i(a_X, a_Y, a_Z - 1)); - - for (std::vector<Vector3i *>::iterator it = Points.begin(); it < Points.end(); it++) - { - Vector3i *Pos = (*it); - char BlockID = m_World.GetBlock(Pos->x, Pos->y, Pos->z); - if(IsAllowedBlock(BlockID)) - { - char Meta = m_World.GetBlockMeta(Pos->x, Pos->y, Pos->z); - - if(Meta > LowestPoint) - { - LowestPoint = Meta; - X = Pos->x; - Y = Pos->y; - Z = Pos->z; - } - }else if(BlockID == E_BLOCK_AIR) - { - LowestPoint = 9; //This always dominates - X = Pos->x; - Y = Pos->y; - Z = Pos->z; - - } - delete Pos; - } - - if (LowestPoint == m_World.GetBlockMeta(a_X, a_Y, a_Z)) - return NONE; - - if (a_X - X > 0) - { - return X_MINUS; - } - - if (a_X - X < 0) - { - return X_PLUS; - } - - if (a_Z - Z > 0) - { - return Z_MINUS; - } - - if (a_Z - Z < 0) - { - return Z_PLUS; - } - - return NONE; -} - - - - diff --git a/source/Simulator/FluidSimulator.h b/source/Simulator/FluidSimulator.h deleted file mode 100644 index 672b740a2..000000000 --- a/source/Simulator/FluidSimulator.h +++ /dev/null @@ -1,75 +0,0 @@ - -#pragma once - -#include "Simulator.h" - - - - - -enum Direction -{ - X_PLUS, - X_MINUS, - Y_PLUS, - Y_MINUS, - Z_PLUS, - Z_MINUS, - NONE -}; - - - - - -/** This is a base class for all fluid simulator data classes. -Needed so that cChunk can properly delete instances of fluid simulator data, no matter what simulator it's using -*/ -class cFluidSimulatorData -{ -public: - virtual ~cFluidSimulatorData() {} -} ; - - - - - -class cFluidSimulator : - public cSimulator -{ - typedef cSimulator super; - -public: - cFluidSimulator(cWorld & a_World, BLOCKTYPE a_Fluid, BLOCKTYPE a_StationaryFluid); - - // cSimulator overrides: - virtual bool IsAllowedBlock(BLOCKTYPE a_BlockType) override; - - /// Gets the flowing direction. If a_Over is true also the block over the current block affects the direction (standard) - virtual Direction GetFlowingDirection(int a_X, int a_Y, int a_Z, bool a_Over = true); - - /// Creates a ChunkData object for the simulator to use. The simulator returns the correct object type. - virtual cFluidSimulatorData * CreateChunkData(void) { return NULL; } - - bool IsFluidBlock (BLOCKTYPE a_BlockType) const { return (a_BlockType == m_FluidBlock); } - bool IsStationaryFluidBlock(BLOCKTYPE a_BlockType) const { return (a_BlockType == m_StationaryFluidBlock); } - bool IsAnyFluidBlock (BLOCKTYPE a_BlockType) const { return ((a_BlockType == m_FluidBlock) || (a_BlockType == m_StationaryFluidBlock)); } - - static bool CanWashAway(BLOCKTYPE a_BlockType); - - bool IsSolidBlock (BLOCKTYPE a_BlockType); - bool IsPassableForFluid(BLOCKTYPE a_BlockType); - - /// Returns true if a_Meta1 is a higher fluid than a_Meta2. Takes source blocks into account. - bool IsHigherMeta(NIBBLETYPE a_Meta1, NIBBLETYPE a_Meta2); - -protected: - 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/source/Simulator/NoopFluidSimulator.h b/source/Simulator/NoopFluidSimulator.h deleted file mode 100644 index 8f894433f..000000000 --- a/source/Simulator/NoopFluidSimulator.h +++ /dev/null @@ -1,36 +0,0 @@ - -// NoopFluidSimulator.h - -// Declares the cNoopFluidSimulator class representing a fluid simulator that performs nothing, it ignores all blocks - - - - - -#pragma once - -#include "FluidSimulator.h" - - - - - -class cNoopFluidSimulator : - public cFluidSimulator -{ - typedef cFluidSimulator super; - -public: - cNoopFluidSimulator(cWorld & a_World, BLOCKTYPE a_Fluid, BLOCKTYPE a_StationaryFluid) : - super(a_World, a_Fluid, a_StationaryFluid) - { - } - - // cSimulator overrides: - virtual void AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk) override {} - virtual void Simulate(float a_Dt) override {} -} ; - - - - diff --git a/source/Simulator/RedstoneSimulator.cpp b/source/Simulator/RedstoneSimulator.cpp deleted file mode 100644 index 906961490..000000000 --- a/source/Simulator/RedstoneSimulator.cpp +++ /dev/null @@ -1,1073 +0,0 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "RedstoneSimulator.h" -#include "../BlockEntities/DropSpenserEntity.h" -#include "../Entities/TNTEntity.h" -#include "../Blocks/BlockTorch.h" -#include "../Blocks/BlockDoor.h" -#include "../Piston.h" - - - - - -cRedstoneSimulator::cRedstoneSimulator(cWorld & a_World) - : super(a_World) -{ -} - - - - - -cRedstoneSimulator::~cRedstoneSimulator() -{ -} - - - - - -void cRedstoneSimulator::AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk) -{ - if ((a_Chunk == NULL) || !a_Chunk->IsValid()) - { - return; - } - else if ((a_BlockY < 0) || (a_BlockY > cChunkDef::Height)) - { - return; - } - - int RelX = a_BlockX - a_Chunk->GetPosX() * cChunkDef::Width; - int RelZ = a_BlockZ - a_Chunk->GetPosZ() * cChunkDef::Width; - - if (!IsAllowedBlock(a_Chunk->GetBlock(RelX, a_BlockY, RelZ))) - { - return; - } - - // Check for duplicates: - cRedstoneSimulatorChunkData & ChunkData = a_Chunk->GetRedstoneSimulatorData(); - for (cRedstoneSimulatorChunkData::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; - - for (cRedstoneSimulatorChunkData::iterator dataitr = ChunkData.begin(), end = ChunkData.end(); dataitr != end;) - { - BLOCKTYPE BlockType = a_Chunk->GetBlock(dataitr->x, dataitr->y, dataitr->z); - if (!IsAllowedBlock(BlockType)) - { - dataitr = ChunkData.erase(dataitr); - continue; - } - - // Check to see if PoweredBlocks have invalid items (source is air or an unpowered source) - for (PoweredBlocksList::iterator itr = m_PoweredBlocks.begin(); itr != m_PoweredBlocks.end();) - { - sPoweredBlocks & Change = *itr; - BLOCKTYPE SourceBlockType = m_World.GetBlock(Change.a_SourcePos); - - if (SourceBlockType != Change.a_SourceBlock) - { - itr = m_PoweredBlocks.erase(itr); - } - 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)))) - ) - { - 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();) - { - sLinkedPoweredBlocks & Change = *itr; - BLOCKTYPE SourceBlockType = m_World.GetBlock(Change.a_SourcePos); - BLOCKTYPE MiddleBlockType = m_World.GetBlock(Change.a_MiddlePos); - - if (SourceBlockType != Change.a_SourceBlock) - { - itr = m_LinkedPoweredBlocks.erase(itr); - } - else if (MiddleBlockType != Change.a_MiddleBlock) - { - 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) && (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)))) - ) - { - itr = m_LinkedPoweredBlocks.erase(itr); - } - else - { - itr++; - } - } - - // PoweredBlock list was fine, now to the actual handling - int a_X = BaseX + dataitr->x; - int a_Z = BaseZ + dataitr->z; - switch (BlockType) - { - 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; - case E_BLOCK_TNT: HandleTNT(a_X, dataitr->y, a_Z); break; - case E_BLOCK_REDSTONE_WIRE: HandleRedstoneWire(a_X, dataitr->y, a_Z); break; - - case E_BLOCK_REDSTONE_TORCH_OFF: - case E_BLOCK_REDSTONE_TORCH_ON: - { - HandleRedstoneTorch(a_X, dataitr->y, a_Z, BlockType); - break; - } - case E_BLOCK_STONE_BUTTON: - case E_BLOCK_WOODEN_BUTTON: - { - HandleRedstoneButton(a_X, dataitr->y, a_Z, BlockType); - break; - } - case E_BLOCK_REDSTONE_REPEATER_OFF: - case E_BLOCK_REDSTONE_REPEATER_ON: - { - HandleRedstoneRepeater(a_X, dataitr->y, a_Z, BlockType); - break; - } - case E_BLOCK_PISTON: - case E_BLOCK_STICKY_PISTON: - { - HandlePiston(a_X, dataitr->y, a_Z); - break; - } - case E_BLOCK_REDSTONE_LAMP_OFF: - case E_BLOCK_REDSTONE_LAMP_ON: - { - HandleRedstoneLamp(a_X, dataitr->y, a_Z, BlockType); - break; - } - case E_BLOCK_DISPENSER: - case E_BLOCK_DROPPER: - { - HandleDropSpenser(a_X, dataitr->y, a_Z); - break; - } - case E_BLOCK_WOODEN_DOOR: - case E_BLOCK_IRON_DOOR: - { - HandleDoor(a_X, dataitr->y, a_Z); - break; - } - case E_BLOCK_ACTIVATOR_RAIL: - case E_BLOCK_DETECTOR_RAIL: - case E_BLOCK_POWERED_RAIL: - { - HandleRail(a_X, dataitr->y, a_Z, BlockType); - break; - } - } - - ++dataitr; - } -} - - - - - -void cRedstoneSimulator::HandleRedstoneTorch(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyState) -{ - 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}, - } ; - - if (a_MyState == E_BLOCK_REDSTONE_TORCH_ON) - { - // Check if the block the torch is on is powered - int X = a_BlockX; int Y = a_BlockY; int Z = a_BlockZ; - AddFaceDirection(X, Y, Z, cBlockTorchHandler::MetaDataToDirection(m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ)), true); // Inverse true to get the block torch is on - - 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; - } - - // Torch still on, make all 4(X, Z) + 1(Y) sides powered - for (int i = 0; i < ARRAYCOUNT(gCrossCoords); i++) - { - BLOCKTYPE Type = m_World.GetBlock(a_BlockX + gCrossCoords[i].x, a_BlockY + gCrossCoords[i].y, a_BlockZ + gCrossCoords[i].z); - if (i < ARRAYCOUNT(gCrossCoords) - 1) // Sides of torch, not top (top is last) - { - if ( - ((IsMechanism(Type)) || (Type == E_BLOCK_REDSTONE_WIRE)) && // Is it a mechanism or wire? Not block/other torch etc. - (!Vector3i(a_BlockX + gCrossCoords[i].x, a_BlockY + gCrossCoords[i].y, a_BlockZ + gCrossCoords[i].z).Equals(Vector3i(X, Y, Z))) // CAN'T power block is that it is on - ) - { - 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); - } - } - else - { - // 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); - } - } - - 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); - - if ((IsMechanism(Type)) || (Type == E_BLOCK_REDSTONE_WIRE)) // Still can't make a normal block powered though! - { - SetBlockPowered(a_BlockX, a_BlockY - 1, a_BlockZ, a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_TORCH_ON); - } - } - } - else - { - // Check if the block the torch is on is powered - int X = a_BlockX; int Y = a_BlockY; int Z = a_BlockZ; - AddFaceDirection(X, Y, Z, cBlockTorchHandler::MetaDataToDirection(m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ)), true); // Inverse true to get the block torch is on - - // See if off state torch can be turned on again - if (AreCoordsPowered(X, Y, Z)) - { - return; // Something matches, torch still powered - } - - // 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; -} - - - - - -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); - } - return; -} - - - - - -void cRedstoneSimulator::HandleRedstoneLever(int a_BlockX, int a_BlockY, int a_BlockZ) -{ - 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); - } - - 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); - SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_YM, E_BLOCK_LEVER); - SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_YP, E_BLOCK_LEVER); - SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_ZM, E_BLOCK_LEVER); - SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_ZP, E_BLOCK_LEVER); - } - return; -} - - - - - -void cRedstoneSimulator::HandleRedstoneButton(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType) -{ - 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); - } - - SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_XM, a_BlockType); - SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_XP, a_BlockType); - SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_YM, a_BlockType); - SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_YP, a_BlockType); - SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_ZM, a_BlockType); - SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_ZP, a_BlockType); - } -} - - - - - -void cRedstoneSimulator::HandleRedstoneWire(int a_BlockX, int a_BlockY, int a_BlockZ) -{ - static const struct // Define which directions the wire can receive power from - { - int x, y, z; - } gCrossCoords[] = - { - { 1, 0, 0}, - {-1, 0, 0}, - { 0, 0, 1}, - { 0, 0, -1}, - { 1, 1, 0}, // From here to end, check for wire placed on sides of blocks - {-1, 1, 0}, - { 0, 1, 1}, - { 0, 1, -1}, - { 1,-1, 0}, - {-1,-1, 0}, - { 0,-1, 1}, - { 0,-1, -1}, - } ; - - // Check to see if directly beside a power source - if (AreCoordsPowered(a_BlockX, a_BlockY, a_BlockZ)) - { - m_World.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, 15); // Maximum power - } - else - { - NIBBLETYPE MyMeta = m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); - int TimesMetaSmaller = 0, TimesFoundAWire = 0; - - for (int i = 0; i < ARRAYCOUNT(gCrossCoords); i++) // Loop through all directions to transfer or receive power - { - BLOCKTYPE SurroundType; - NIBBLETYPE SurroundMeta; - m_World.GetBlockTypeMeta(a_BlockX + gCrossCoords[i].x, a_BlockY + gCrossCoords[i].y, a_BlockZ + gCrossCoords[i].z, SurroundType, SurroundMeta); - - if (SurroundType == E_BLOCK_REDSTONE_WIRE) - { - TimesFoundAWire++; - - if (SurroundMeta > 1) // Wires of power 1 or 0 cannot transfer power TO ME, don't bother checking - { - if (SurroundMeta > MyMeta) // Does surrounding wire have a higher power level than self? - { - m_World.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, SurroundMeta - 1); - } - } - - if (SurroundMeta < MyMeta) // Go through all surroundings to see if self power is larger than everyone else's - { - TimesMetaSmaller++; - } - } - } - - if (TimesMetaSmaller == TimesFoundAWire) - { - // All surrounding metas were smaller - self must have been a wire that was - // transferring power to other wires around. - // 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); - } - } - - 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: - { - 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}, - } ; - - 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); - } - } - break; - } - 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); - } - 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); - } - 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); - } - 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); - } - SetDirectionLinkedPowered(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_ZM, E_BLOCK_REDSTONE_WIRE); - break; - } - } - } - return; -} - - - - - -void cRedstoneSimulator::HandleRedstoneRepeater(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyState) -{ - 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)) - { - 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: - { - 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); - } - } - return; -} - - - - - -void cRedstoneSimulator::HandlePiston(int a_BlockX, int a_BlockY, int a_BlockZ) -{ - 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; -} - - - - - -void cRedstoneSimulator::HandleDropSpenser(int a_BlockX, int a_BlockY, int a_BlockZ) -{ - class cSetPowerToDropSpenser : - public cDropSpenserCallback - { - bool m_IsPowered; - public: - cSetPowerToDropSpenser(bool a_IsPowered) : m_IsPowered(a_IsPowered) {} - - virtual bool Item(cDropSpenserEntity * a_DropSpenser) override - { - a_DropSpenser->SetRedstonePower(m_IsPowered); - return false; - } - } DrSpSP (AreCoordsPowered(a_BlockX, a_BlockY, a_BlockZ)); - - m_World.DoWithDropSpenserAt(a_BlockX, a_BlockY, a_BlockZ, DrSpSP); - return; -} - - - - - -void cRedstoneSimulator::HandleRedstoneLamp(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyState) -{ - if (a_MyState == E_BLOCK_REDSTONE_LAMP_OFF) - { - if (AreCoordsPowered(a_BlockX, a_BlockY, a_BlockZ)) - { - m_World.FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_LAMP_ON, 0); - } - } - else - { - if (!AreCoordsPowered(a_BlockX, a_BlockY, a_BlockZ)) - { - m_World.FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_REDSTONE_LAMP_OFF, 0); - } - } - return; -} - - - - - -void cRedstoneSimulator::HandleTNT(int a_BlockX, int a_BlockY, int a_BlockZ) -{ - if (AreCoordsPowered(a_BlockX, a_BlockY, a_BlockZ)) - { - m_World.BroadcastSoundEffect("random.fuse", a_BlockX * 8, a_BlockY * 8, a_BlockZ * 8, 0.5f, 0.6f); - m_World.SpawnPrimedTNT(a_BlockX + 0.5, a_BlockY + 0.5, a_BlockZ + 0.5, 4); // 4 seconds to boom - m_World.FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0); - } - return; -} - - - - - -void cRedstoneSimulator::HandleDoor(int a_BlockX, int a_BlockY, int a_BlockZ) -{ - if ((m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) & 0x08) == 0x08) - { - // Block position is located at top half of door - // Is Y - 1 both within world boundaries, a door block, and the bottom half of a door? - // The bottom half stores the open/closed information - if ( - (a_BlockY - 1 >= 0) && - ((m_World.GetBlock(a_BlockX, a_BlockY, a_BlockZ) == E_BLOCK_WOODEN_DOOR) || (m_World.GetBlock(a_BlockX, a_BlockY, a_BlockZ) == E_BLOCK_IRON_DOOR)) && - (m_World.GetBlockMeta(a_BlockX, a_BlockY - 1, a_BlockZ & 0x08) == 0) - ) - { - if ((m_World.GetBlockMeta(a_BlockX, a_BlockY - 1, a_BlockZ) & 0x04) == 0) // Closed door? - { - if (AreCoordsPowered(a_BlockX, a_BlockY, a_BlockZ)) // Powered? If so, toggle open - { - cBlockDoorHandler::ChangeDoor(&m_World, a_BlockX, a_BlockY, a_BlockZ); - } - } - else // Opened door - { - if (!AreCoordsPowered(a_BlockX, a_BlockY, a_BlockZ)) // Unpowered? Close if so - { - cBlockDoorHandler::ChangeDoor(&m_World, a_BlockX, a_BlockY, a_BlockZ); - } - } - } - } - else - { - if ((m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) & 0x04) == 0) // Closed door? - { - if (AreCoordsPowered(a_BlockX, a_BlockY, a_BlockZ)) // Powered? If so, toggle open - { - cBlockDoorHandler::ChangeDoor(&m_World, a_BlockX, a_BlockY, a_BlockZ); - } - } - else // Opened door - { - if (!AreCoordsPowered(a_BlockX, a_BlockY, a_BlockZ)) // Unpowered? Close if so - { - cBlockDoorHandler::ChangeDoor(&m_World, a_BlockX, a_BlockY, a_BlockZ); - } - } - } - return; -} - - - - - -void cRedstoneSimulator::HandleRail(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyType) -{ - switch (a_MyType) - { - case E_BLOCK_DETECTOR_RAIL: - { - 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); - } - } - break; - } - case E_BLOCK_ACTIVATOR_RAIL: - case E_BLOCK_POWERED_RAIL: - { - if (AreCoordsPowered(a_BlockX, a_BlockY, a_BlockZ)) - { - m_World.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) | 0x08); - } - else - { - m_World.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, m_World.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) & 0x07); - } - break; - } - } -} - - - - - -bool cRedstoneSimulator::AreCoordsPowered(int a_BlockX, int a_BlockY, int a_BlockZ) -{ - for (PoweredBlocksList::iterator itr = m_PoweredBlocks.begin(); itr != m_PoweredBlocks.end(); ++itr) // Check powered list - { - sPoweredBlocks & Change = *itr; - - if (Change.a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) - { - return true; - } - } - - for (LinkedBlocksList::iterator itr = m_LinkedPoweredBlocks.begin(); itr != m_LinkedPoweredBlocks.end(); ++itr) // Check linked powered list - { - sLinkedPoweredBlocks & Change = *itr; - - if (Change.a_BlockPos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ))) - { - return true; - } - } - return false; -} - - - - - -bool cRedstoneSimulator::IsRepeaterPowered(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_Meta) -{ - // Check through powered blocks list - for (PoweredBlocksList::iterator itr = m_PoweredBlocks.begin(); itr != m_PoweredBlocks.end(); ++itr) - { - sPoweredBlocks & Change = *itr; - - switch (a_Meta) - { - case 0x0: - { - // Flip the coords to check the back of the repeater - if (Change.a_SourcePos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ + 1))) { return true; } - break; - } - case 0x1: - { - if (Change.a_SourcePos.Equals(Vector3i(a_BlockX - 1, a_BlockY, a_BlockZ))) { return true; } - break; - } - case 0x2: - { - if (Change.a_SourcePos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ - 1))) { return true; } - break; - } - case 0x3: - { - if (Change.a_SourcePos.Equals(Vector3i(a_BlockX + 1, a_BlockY, a_BlockZ))) { return true; } - break; - } - } - } - - // Check linked powered list, 'middle' blocks - for (LinkedBlocksList::iterator itr = m_LinkedPoweredBlocks.begin(); itr != m_LinkedPoweredBlocks.end(); ++itr) - { - sLinkedPoweredBlocks & Change = *itr; - - switch (a_Meta) - { - case 0x0: - { - if (Change.a_MiddlePos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ + 1))) { return true; } - break; - } - case 0x1: - { - if (Change.a_MiddlePos.Equals(Vector3i(a_BlockX - 1, a_BlockY, a_BlockZ))) { return true; } - break; - } - case 0x2: - { - if (Change.a_MiddlePos.Equals(Vector3i(a_BlockX, a_BlockY, a_BlockZ - 1))) { return true; } - break; - } - case 0x3: - { - if (Change.a_MiddlePos.Equals(Vector3i(a_BlockX + 1, a_BlockY, a_BlockZ))) { return true; } - break; - } - } - } - return false; // Couldn't find power source behind repeater -} - - - - - -void cRedstoneSimulator::SetDirectionLinkedPowered(int a_BlockX, int a_BlockY, int a_BlockZ, char a_Direction, BLOCKTYPE a_SourceType) -{ - switch (a_Direction) - { - case BLOCK_FACE_XM: - { - 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); - break; - } - case BLOCK_FACE_XP: - { - 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); - break; - } - case BLOCK_FACE_YM: - { - 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); - break; - } - case BLOCK_FACE_YP: - { - 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); - break; - } - case BLOCK_FACE_ZM: - { - 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); - break; - } - case BLOCK_FACE_ZP: - { - 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); - break; - } - default: - { - ASSERT(!"Unhandled face direction when attempting to set blocks as linked powered!"); - break; - } - } - 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 (AreCoordsPowered(a_BlockX, a_BlockY, a_BlockZ)) { return; } // Check for duplicates - - 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); - return; -} - - - - - -void cRedstoneSimulator::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_MiddleBlock - ) -{ - if (AreCoordsPowered(a_BlockX, a_BlockY, a_BlockZ)) { return; } // Check for duplicates - - sLinkedPoweredBlocks RC; - 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); - return; -} - - - - - -cRedstoneSimulator::eRedstoneDirection cRedstoneSimulator::GetWireDirection(int a_BlockX, int a_BlockY, int a_BlockZ) -{ - int Dir = REDSTONE_NONE; - - BLOCKTYPE NegX = m_World.GetBlock(a_BlockX - 1, a_BlockY, a_BlockZ); - if (IsPotentialSource(NegX)) - { - Dir |= (REDSTONE_X_POS); - } - - BLOCKTYPE PosX = m_World.GetBlock(a_BlockX + 1, a_BlockY, a_BlockZ); - if (IsPotentialSource(PosX)) - { - Dir |= (REDSTONE_X_NEG); - } - - BLOCKTYPE NegZ = m_World.GetBlock(a_BlockX, a_BlockY, a_BlockZ - 1); - if (IsPotentialSource(NegZ)) - { - if ((Dir & REDSTONE_X_POS) && !(Dir & REDSTONE_X_NEG)) // corner - { - Dir ^= REDSTONE_X_POS; - Dir |= REDSTONE_X_NEG; - } - if ((Dir & REDSTONE_X_NEG) && !(Dir & REDSTONE_X_POS)) // corner - { - Dir ^= REDSTONE_X_NEG; - Dir |= REDSTONE_X_POS; - } - Dir |= REDSTONE_Z_POS; - } - - BLOCKTYPE PosZ = m_World.GetBlock(a_BlockX, a_BlockY, a_BlockZ + 1); - if (IsPotentialSource(PosZ)) - { - if ((Dir & REDSTONE_X_POS) && !(Dir & REDSTONE_X_NEG)) // corner - { - Dir ^= REDSTONE_X_POS; - Dir |= REDSTONE_X_NEG; - } - if ((Dir & REDSTONE_X_NEG) && !(Dir & REDSTONE_X_POS)) // corner - { - Dir ^= REDSTONE_X_NEG; - Dir |= REDSTONE_X_POS; - } - Dir |= REDSTONE_Z_NEG; - } - return (eRedstoneDirection)Dir; -} - - - - - -bool cRedstoneSimulator::IsLeverOn(NIBBLETYPE a_BlockMeta) -{ - // Extract the ON bit from metadata and return if true if it is set: - return ((a_BlockMeta & 0x8) == 0x8); -} - - - - - -bool cRedstoneSimulator::IsButtonOn(NIBBLETYPE a_BlockMeta) -{ - return IsLeverOn(a_BlockMeta); -} - - - - diff --git a/source/Simulator/RedstoneSimulator.h b/source/Simulator/RedstoneSimulator.h deleted file mode 100644 index d68c6daeb..000000000 --- a/source/Simulator/RedstoneSimulator.h +++ /dev/null @@ -1,199 +0,0 @@ - -#pragma once - -#include "Simulator.h" - -/// Per-chunk data for the simulator, specified individual chunks to simulate; 'Data' is not used -typedef cCoordWithIntList cRedstoneSimulatorChunkData; - - - - - -class cRedstoneSimulator : - public cSimulator -{ - typedef cSimulator super; -public: - - cRedstoneSimulator(cWorld & a_World); - ~cRedstoneSimulator(); - - virtual void Simulate(float a_Dt) override {}; // Not used in this simulator - virtual void SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk) override; - virtual bool IsAllowedBlock( BLOCKTYPE a_BlockType ) override { return IsRedstone(a_BlockType); } - - enum eRedstoneDirection - { - REDSTONE_NONE = 0, - REDSTONE_X_POS = 0x1, - REDSTONE_X_NEG = 0x2, - REDSTONE_Z_POS = 0x4, - 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: - - struct sPoweredBlocks // Define structure of the directly powered blocks list - { - 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) - { - Vector3i a_BlockPos; - Vector3i a_MiddlePos; - Vector3i a_SourcePos; - BLOCKTYPE a_SourceBlock; - BLOCKTYPE a_MiddleBlock; - }; - - typedef std::vector <sPoweredBlocks> PoweredBlocksList; - typedef std::vector <sLinkedPoweredBlocks> LinkedBlocksList; - - PoweredBlocksList m_PoweredBlocks; - LinkedBlocksList m_LinkedPoweredBlocks; - - virtual void AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk) override; - - // We want a_MyState for devices needing a full FastSetBlock (as opposed to meta) because with our simulation model, we cannot keep setting the block if it is already set correctly - // In addition to being non-performant, it would stop the player from actually breaking said device - - /* ====== SOURCES ====== */ - ///<summary>Handles the redstone torch</summary> - void HandleRedstoneTorch(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyState); - ///<summary>Handles the redstone block</summary> - void HandleRedstoneBlock(int a_BlockX, int a_BlockY, int a_BlockZ); - ///<summary>Handles levers</summary> - void HandleRedstoneLever(int a_BlockX, int a_BlockY, int a_BlockZ); - ///<summary>Handles buttons</summary> - void HandleRedstoneButton(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType); - /* ==================== */ - - /* ====== CARRIERS ====== */ - ///<summary>Handles redstone wire</summary> - void HandleRedstoneWire(int a_BlockX, int a_BlockY, int a_BlockZ); - ///<summary>Handles repeaters</summary> - void HandleRedstoneRepeater(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyState); - /* ====================== */ - - /* ====== DEVICES ====== */ - ///<summary>Handles pistons</summary> - void HandlePiston(int a_BlockX, int a_BlockY, int a_BlockZ); - ///<summary>Handles dispensers and droppers</summary> - void HandleDropSpenser(int a_BlockX, int a_BlockY, int a_BlockZ); - ///<summary>Handles TNT (exploding)</summary> - void HandleTNT(int a_BlockX, int a_BlockY, int a_BlockZ); - ///<summary>Handles redstone lamps</summary> - void HandleRedstoneLamp(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyState); - ///<summary>Handles doords</summary> - void HandleDoor(int a_BlockX, int a_BlockY, int a_BlockZ); - ///<summary>Handles activator, detector, and powered rails</summary> - void HandleRail(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_MyType); - /* ===================== */ - - /* ====== Helper functions ====== */ - void SetBlockPowered(int a_BlockX, int a_BlockY, int a_BlockZ, int a_SourceX, int a_SourceY, int a_SourceZ, BLOCKTYPE a_SourceBlock); - 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); - - bool AreCoordsPowered(int a_BlockX, int a_BlockY, int a_BlockZ); - bool IsRepeaterPowered(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_Meta); - - bool IsLeverOn(NIBBLETYPE a_BlockMeta); - bool IsButtonOn(NIBBLETYPE a_BlockMeta); - /* ============================== */ - - inline static bool IsMechanism(BLOCKTYPE Block) - { - switch (Block) - { - case E_BLOCK_PISTON: - case E_BLOCK_STICKY_PISTON: - case E_BLOCK_DISPENSER: - case E_BLOCK_DROPPER: - case E_BLOCK_TNT: - case E_BLOCK_REDSTONE_LAMP_OFF: - case E_BLOCK_REDSTONE_LAMP_ON: - case E_BLOCK_WOODEN_DOOR: - case E_BLOCK_IRON_DOOR: - case E_BLOCK_REDSTONE_REPEATER_OFF: - case E_BLOCK_REDSTONE_REPEATER_ON: - case E_BLOCK_POWERED_RAIL: - { - return true; - } - default: return false; - } - } - - inline static bool IsPotentialSource(BLOCKTYPE Block) - { - switch (Block) - { - 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: - case E_BLOCK_REDSTONE_REPEATER_OFF: - case E_BLOCK_BLOCK_OF_REDSTONE: - case E_BLOCK_ACTIVE_COMPARATOR: - case E_BLOCK_INACTIVE_COMPARATOR: - { - return true; - } - default: return false; - } - } - - inline static bool IsRedstone(BLOCKTYPE Block) - { - switch (Block) - { - // All redstone devices, please alpha sort - case E_BLOCK_ACTIVATOR_RAIL: - case E_BLOCK_ACTIVE_COMPARATOR: - case E_BLOCK_BLOCK_OF_REDSTONE: - case E_BLOCK_DETECTOR_RAIL: - case E_BLOCK_DISPENSER: - case E_BLOCK_DAYLIGHT_SENSOR: - case E_BLOCK_DROPPER: - case E_BLOCK_FENCE_GATE: - case E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE: - case E_BLOCK_HOPPER: - case E_BLOCK_INACTIVE_COMPARATOR: - case E_BLOCK_IRON_DOOR: - case E_BLOCK_LEVER: - case E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE: - case E_BLOCK_NOTE_BLOCK: - case E_BLOCK_REDSTONE_LAMP_OFF: - case E_BLOCK_REDSTONE_LAMP_ON: - case E_BLOCK_REDSTONE_REPEATER_OFF: - case E_BLOCK_REDSTONE_REPEATER_ON: - case E_BLOCK_REDSTONE_TORCH_OFF: - case E_BLOCK_REDSTONE_TORCH_ON: - case E_BLOCK_REDSTONE_WIRE: - case E_BLOCK_STICKY_PISTON: - case E_BLOCK_STONE_BUTTON: - case E_BLOCK_STONE_PRESSURE_PLATE: - case E_BLOCK_TNT: - case E_BLOCK_TRAPDOOR: - case E_BLOCK_TRIPWIRE_HOOK: - case E_BLOCK_WOODEN_BUTTON: - case E_BLOCK_WOODEN_DOOR: - case E_BLOCK_WOODEN_PRESSURE_PLATE: - case E_BLOCK_PISTON: - { - return true; - } - default: return false; - } - } -};
\ No newline at end of file diff --git a/source/Simulator/SandSimulator.cpp b/source/Simulator/SandSimulator.cpp deleted file mode 100644 index 87fb83357..000000000 --- a/source/Simulator/SandSimulator.cpp +++ /dev/null @@ -1,309 +0,0 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "SandSimulator.h" -#include "../World.h" -#include "../BlockID.h" -#include "../Defines.h" -#include "../Entities/FallingBlock.h" -#include "../Chunk.h" - - - - - -cSandSimulator::cSandSimulator(cWorld & a_World, cIniFile & a_IniFile) : - cSimulator(a_World), - m_TotalBlocks(0) -{ - m_IsInstantFall = a_IniFile.GetValueSetB("Physics", "SandInstantFall", false); -} - - - - - -void cSandSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk) -{ - cSandSimulatorChunkData & ChunkData = a_Chunk->GetSandSimulatorData(); - if (ChunkData.empty()) - { - return; - } - - int BaseX = a_Chunk->GetPosX() * cChunkDef::Width; - int BaseZ = a_Chunk->GetPosZ() * cChunkDef::Width; - for (cSandSimulatorChunkData::const_iterator itr = ChunkData.begin(), end = ChunkData.end(); itr != end; ++itr) - { - BLOCKTYPE BlockType = a_Chunk->GetBlock(itr->x, itr->y, itr->z); - if (!IsAllowedBlock(BlockType) || (itr->y <= 0)) - { - continue; - } - - BLOCKTYPE BlockBelow = (itr->y > 0) ? a_Chunk->GetBlock(itr->x, itr->y - 1, itr->z) : E_BLOCK_AIR; - if (CanStartFallingThrough(BlockBelow)) - { - if (m_IsInstantFall) - { - DoInstantFall(a_Chunk, itr->x, itr->y, itr->z); - continue; - } - Vector3i Pos; - Pos.x = itr->x + BaseX; - Pos.y = itr->y; - Pos.z = itr->z + BaseZ; - /* - LOGD( - "Creating a falling block at {%d, %d, %d} of type %s, block below: %s", - Pos.x, Pos.y, Pos.z, ItemTypeToString(BlockType).c_str(), ItemTypeToString(BlockBelow).c_str() - ); - */ - cFallingBlock * FallingBlock = new cFallingBlock(Pos, BlockType, a_Chunk->GetMeta(itr->x, itr->y, itr->z)); - FallingBlock->Initialize(&m_World); - a_Chunk->SetBlock(itr->x, itr->y, itr->z, E_BLOCK_AIR, 0); - } - } - m_TotalBlocks -= ChunkData.size(); - ChunkData.clear(); -} - - - - - -bool cSandSimulator::IsAllowedBlock(BLOCKTYPE a_BlockType) -{ - switch (a_BlockType) - { - case E_BLOCK_SAND: - case E_BLOCK_GRAVEL: - case E_BLOCK_ANVIL: - case E_BLOCK_DRAGON_EGG: - { - return true; - } - } - return false; -} - - - - - -void cSandSimulator::AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk) -{ - if ((a_Chunk == NULL) || !a_Chunk->IsValid()) - { - return; - } - int RelX = a_BlockX - a_Chunk->GetPosX() * cChunkDef::Width; - int RelZ = a_BlockZ - a_Chunk->GetPosZ() * cChunkDef::Width; - if (!IsAllowedBlock(a_Chunk->GetBlock(RelX, a_BlockY, RelZ))) - { - return; - } - - // Check for duplicates: - cSandSimulatorChunkData & ChunkData = a_Chunk->GetSandSimulatorData(); - for (cSandSimulatorChunkData::iterator itr = ChunkData.begin(); itr != ChunkData.end(); ++itr) - { - if ((itr->x == RelX) && (itr->y == a_BlockY) && (itr->z == RelZ)) - { - return; - } - } - - m_TotalBlocks += 1; - ChunkData.push_back(cCoordWithInt(RelX, a_BlockY, RelZ)); -} - - - - - -bool cSandSimulator::CanStartFallingThrough(BLOCKTYPE a_BlockType) -{ - // Please keep the list alpha-sorted - switch (a_BlockType) - { - case E_BLOCK_AIR: - case E_BLOCK_FIRE: - case E_BLOCK_LAVA: - case E_BLOCK_SNOW: - case E_BLOCK_STATIONARY_LAVA: - case E_BLOCK_STATIONARY_WATER: - case E_BLOCK_WATER: - { - return true; - } - } - return false; -} - - - - - -bool cSandSimulator::CanContinueFallThrough(BLOCKTYPE a_BlockType) -{ - // Please keep the list alpha-sorted - switch (a_BlockType) - { - case E_BLOCK_AIR: - case E_BLOCK_BROWN_MUSHROOM: - case E_BLOCK_COBWEB: - case E_BLOCK_CROPS: - case E_BLOCK_DEAD_BUSH: - case E_BLOCK_DETECTOR_RAIL: - case E_BLOCK_FIRE: - case E_BLOCK_FLOWER_POT: - case E_BLOCK_LAVA: - case E_BLOCK_LEVER: - case E_BLOCK_MINECART_TRACKS: - case E_BLOCK_MELON_STEM: - case E_BLOCK_POWERED_RAIL: - case E_BLOCK_PUMPKIN_STEM: - case E_BLOCK_REDSTONE_REPEATER_OFF: - case E_BLOCK_REDSTONE_REPEATER_ON: - case E_BLOCK_REDSTONE_TORCH_OFF: - case E_BLOCK_REDSTONE_TORCH_ON: - case E_BLOCK_REDSTONE_WIRE: - case E_BLOCK_RED_MUSHROOM: - case E_BLOCK_RED_ROSE: - case E_BLOCK_SIGN_POST: - case E_BLOCK_SNOW: - case E_BLOCK_STATIONARY_LAVA: - case E_BLOCK_STATIONARY_WATER: - case E_BLOCK_STONE_BUTTON: - case E_BLOCK_STONE_PRESSURE_PLATE: - case E_BLOCK_TALL_GRASS: - case E_BLOCK_TORCH: - case E_BLOCK_TRAPDOOR: - case E_BLOCK_TRIPWIRE: - case E_BLOCK_TRIPWIRE_HOOK: - case E_BLOCK_WALLSIGN: - case E_BLOCK_WATER: - case E_BLOCK_WOODEN_BUTTON: - case E_BLOCK_WOODEN_PRESSURE_PLATE: - case E_BLOCK_YELLOW_FLOWER: - { - return true; - } - } - return false; -} - - - - - -bool cSandSimulator::IsReplacedOnRematerialization(BLOCKTYPE a_BlockType) -{ - // Please keep the list alpha-sorted - switch (a_BlockType) - { - case E_BLOCK_AIR: - case E_BLOCK_DEAD_BUSH: - case E_BLOCK_FIRE: - case E_BLOCK_LAVA: - case E_BLOCK_SNOW: - case E_BLOCK_STATIONARY_LAVA: - case E_BLOCK_STATIONARY_WATER: - case E_BLOCK_TALL_GRASS: - case E_BLOCK_WATER: - { - return true; - } - } - return false; -} - - - - - -bool cSandSimulator::DoesBreakFallingThrough(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) -{ - switch (a_BlockType) - { - case E_BLOCK_STONE_SLAB: - case E_BLOCK_WOODEN_SLAB: - { - return ((a_BlockMeta & 0x08) == 0); // Only a bottom-slab breaks the block - } - } - return false; -} - - - - - -void cSandSimulator::FinishFalling( - cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, - BLOCKTYPE a_FallingBlockType, NIBBLETYPE a_FallingBlockMeta -) -{ - ASSERT(a_BlockY < cChunkDef::Height); - - BLOCKTYPE CurrentBlockType = a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ); - if ((a_FallingBlockType == E_BLOCK_ANVIL) || IsReplacedOnRematerialization(CurrentBlockType)) - { - // Rematerialize the material here: - a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, a_FallingBlockType, a_FallingBlockMeta); - return; - } - - // Create a pickup instead: - cItems Pickups; - Pickups.Add((ENUM_ITEM_ID)a_FallingBlockType, 1, a_FallingBlockMeta); - a_World->SpawnItemPickups(Pickups, (double)a_BlockX + 0.5, (double)a_BlockY + 0.5, (double)a_BlockZ + 0.5); -} - - - - - -void cSandSimulator::DoInstantFall(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ) -{ - // Remove the original block: - BLOCKTYPE FallingBlockType; - NIBBLETYPE FallingBlockMeta; - a_Chunk->GetBlockTypeMeta(a_RelX, a_RelY, a_RelZ, FallingBlockType, FallingBlockMeta); - a_Chunk->SetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_AIR, 0); - - // Search for a place to put it: - for (int y = a_RelY - 1; y >= 0; y--) - { - BLOCKTYPE BlockType; - NIBBLETYPE BlockMeta; - a_Chunk->GetBlockTypeMeta(a_RelX, y, a_RelZ, BlockType, BlockMeta); - int BlockY; - if (DoesBreakFallingThrough(BlockType, BlockMeta)) - { - BlockY = y; - } - else if (!CanContinueFallThrough(BlockType)) - { - BlockY = y + 1; - } - else - { - // Can fall further down - continue; - } - - // Finish the fall at the found bottom: - int BlockX = a_RelX + a_Chunk->GetPosX() * cChunkDef::Width; - int BlockZ = a_RelZ + a_Chunk->GetPosZ() * cChunkDef::Width; - FinishFalling(&m_World, BlockX, BlockY, BlockZ, FallingBlockType, FallingBlockMeta); - return; - } - - // The block just "fell off the world" without leaving a trace -} - - - - diff --git a/source/Simulator/SandSimulator.h b/source/Simulator/SandSimulator.h deleted file mode 100644 index 6e9ea15ac..000000000 --- a/source/Simulator/SandSimulator.h +++ /dev/null @@ -1,63 +0,0 @@ - -#pragma once - -#include "Simulator.h" - - - - - -/// Despite the class name, this simulator takes care of all blocks that fall when suspended in the air. -class cSandSimulator : - public cSimulator -{ -public: - cSandSimulator(cWorld & a_World, cIniFile & a_IniFile); - - // cSimulator overrides: - virtual void Simulate(float a_Dt) override {} // Unused in this simulator - virtual void SimulateChunk(float 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); - - /// Returns true if an already-falling block can pass through the specified block type (e. g. torch) - static bool CanContinueFallThrough(BLOCKTYPE a_BlockType); - - /// Returns true if the falling block rematerializing will replace the specified block type (e. g. tall grass) - static bool IsReplacedOnRematerialization(BLOCKTYPE a_BlockType); - - /// Returns true if the specified block breaks falling blocks while they fall through it (e. g. halfslabs) - static bool DoesBreakFallingThrough(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); - - /** Called when a block finishes falling at the specified coords, either by insta-fall, - or through cFallingBlock entity. - It either rematerializes the block (a_FallingBlockType) at the specified coords, or creates a pickup, - based on the block currently present in the world at the dest specified coords - */ - static void FinishFalling( - cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, - BLOCKTYPE a_FallingBlockType, NIBBLETYPE a_FallingBlockMeta - ); - -protected: - bool m_IsInstantFall; // If set to true, blocks don't fall using cFallingBlock entity, but instantly instead - - int m_TotalBlocks; // Total number of blocks currently in the queue for simulating - - virtual void AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk) override; - - /// Performs the instant fall of the block - removes it from top, Finishes it at the bottom - void DoInstantFall(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ); -}; - - - - -/// Per-chunk data for the simulator, specified individual chunks to simulate; Data is not used -typedef cCoordWithIntList cSandSimulatorChunkData; - - - - diff --git a/source/Simulator/Simulator.cpp b/source/Simulator/Simulator.cpp deleted file mode 100644 index 06fd0f858..000000000 --- a/source/Simulator/Simulator.cpp +++ /dev/null @@ -1,51 +0,0 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "Simulator.h" -#include "../World.h" -#include "../Vector3i.h" -#include "../BlockID.h" -#include "../Defines.h" -#include "../Chunk.h" - - - - - -cSimulator::cSimulator(cWorld & a_World) - : m_World(a_World) -{ -} - - - - - -cSimulator::~cSimulator() -{ -} - - - - - -void cSimulator::WakeUp(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk) -{ - AddBlock(a_BlockX, a_BlockY, a_BlockZ, a_Chunk); - AddBlock(a_BlockX - 1, a_BlockY, a_BlockZ, a_Chunk->GetNeighborChunk(a_BlockX - 1, a_BlockZ)); - AddBlock(a_BlockX + 1, a_BlockY, a_BlockZ, a_Chunk->GetNeighborChunk(a_BlockX + 1, a_BlockZ)); - AddBlock(a_BlockX, a_BlockY, a_BlockZ - 1, a_Chunk->GetNeighborChunk(a_BlockX, a_BlockZ - 1)); - AddBlock(a_BlockX, a_BlockY, a_BlockZ + 1, a_Chunk->GetNeighborChunk(a_BlockX, a_BlockZ + 1)); - if (a_BlockY > 0) - { - AddBlock(a_BlockX, a_BlockY - 1, a_BlockZ, a_Chunk); - } - if (a_BlockY < cChunkDef::Height - 1) - { - AddBlock(a_BlockX, a_BlockY + 1, a_BlockZ, a_Chunk); - } -} - - - - diff --git a/source/Simulator/Simulator.h b/source/Simulator/Simulator.h deleted file mode 100644 index e1d88f1c5..000000000 --- a/source/Simulator/Simulator.h +++ /dev/null @@ -1,46 +0,0 @@ - -#pragma once - -#include "../Vector3i.h" -#include "../../iniFile/iniFile.h" - - - - - -class cWorld; -class cChunk; - - - - - -class cSimulator -{ -public: - cSimulator(cWorld & a_World); - virtual ~cSimulator(); - - /// Called in each tick, a_Dt is the time passed since the last tick, in msec - virtual void Simulate(float a_Dt) = 0; - - /// Called in each tick for each chunk, a_Dt is the time passed since the last tick, in msec; direct access to chunk data available - virtual void SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk) {}; - - /// Called when a block changes - virtual void WakeUp(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk); - - virtual bool IsAllowedBlock(BLOCKTYPE a_BlockType) = 0; - -protected: - friend class cChunk; // Calls AddBlock() in its WakeUpSimulators() function, to speed things up - - /// Called to simulate a new block - virtual void AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk) = 0; - - cWorld & m_World; -} ; - - - - diff --git a/source/Simulator/SimulatorManager.cpp b/source/Simulator/SimulatorManager.cpp deleted file mode 100644 index 2bc483cbd..000000000 --- a/source/Simulator/SimulatorManager.cpp +++ /dev/null @@ -1,80 +0,0 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "SimulatorManager.h" -#include "../World.h" - - - - - -cSimulatorManager::cSimulatorManager(cWorld & a_World) : - m_World(a_World), - m_Ticks(0) -{ -} - - - - - -cSimulatorManager::~cSimulatorManager() -{ -} - - - - - -void cSimulatorManager::Simulate(float a_Dt) -{ - m_Ticks++; - for (cSimulators::iterator itr = m_Simulators.begin(); itr != m_Simulators.end(); ++itr ) - { - if ((m_Ticks % itr->second) == 0) - { - itr->first->Simulate(a_Dt); - } - } -} - - - - - -void cSimulatorManager::SimulateChunk(float a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk) -{ - // m_Ticks has already been increased in Simulate() - for (cSimulators::iterator itr = m_Simulators.begin(); itr != m_Simulators.end(); ++itr ) - { - if ((m_Ticks % itr->second) == 0) - { - itr->first->SimulateChunk(a_Dt, a_ChunkX, a_ChunkZ, a_Chunk); - } - } -} - - - - - -void cSimulatorManager::WakeUp(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk) -{ - for (cSimulators::iterator itr = m_Simulators.begin(); itr != m_Simulators.end(); ++itr ) - { - itr->first->WakeUp(a_BlockX, a_BlockY, a_BlockZ, a_Chunk); - } -} - - - - - -void cSimulatorManager::RegisterSimulator(cSimulator * a_Simulator, int a_Rate) -{ - m_Simulators.push_back(std::make_pair(a_Simulator, a_Rate)); -} - - - - diff --git a/source/Simulator/SimulatorManager.h b/source/Simulator/SimulatorManager.h deleted file mode 100644 index 31a709316..000000000 --- a/source/Simulator/SimulatorManager.h +++ /dev/null @@ -1,52 +0,0 @@ - -// cSimulatorManager.h - - - - -#pragma once - - - - -#include "Simulator.h" - - - - - -// fwd: Chunk.h -class cChunk; - -// fwd: World.h -class cWorld; - - - - - -class cSimulatorManager -{ -public: - cSimulatorManager(cWorld & a_World); - ~cSimulatorManager(); - - void Simulate(float a_Dt); - - void SimulateChunk(float a_DT, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk); - - void WakeUp(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk); - - void RegisterSimulator(cSimulator * a_Simulator, int a_Rate); // Takes ownership of the simulator object! - -protected: - typedef std::vector <std::pair<cSimulator *, int> > cSimulators; - - cWorld & m_World; - cSimulators m_Simulators; - long long m_Ticks; -}; - - - - diff --git a/source/Simulator/VaporizeFluidSimulator.cpp b/source/Simulator/VaporizeFluidSimulator.cpp deleted file mode 100644 index 4206c64d1..000000000 --- a/source/Simulator/VaporizeFluidSimulator.cpp +++ /dev/null @@ -1,53 +0,0 @@ - -// VaporizeFluidSimulator.cpp - -// Implements the cVaporizeFluidSimulator class representing a fluid simulator that replaces all fluid blocks with air - -#include "Globals.h" -#include "VaporizeFluidSimulator.h" -#include "../Chunk.h" - - - - - -cVaporizeFluidSimulator::cVaporizeFluidSimulator(cWorld & a_World, BLOCKTYPE a_Fluid, BLOCKTYPE a_StationaryFluid) : - super(a_World, a_Fluid, a_StationaryFluid) -{ -} - - - - - -void cVaporizeFluidSimulator::AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk) -{ - if (a_Chunk == NULL) - { - return; - } - int RelX = a_BlockX - a_Chunk->GetPosX() * cChunkDef::Width; - int RelZ = a_BlockZ - a_Chunk->GetPosZ() * cChunkDef::Width; - BLOCKTYPE BlockType = a_Chunk->GetBlock(RelX, a_BlockY, RelZ); - if ( - (BlockType == m_FluidBlock) || - (BlockType == m_StationaryFluidBlock) - ) - { - a_Chunk->SetBlock(RelX, a_BlockY, RelZ, E_BLOCK_AIR, 0); - a_Chunk->BroadcastSoundEffect("random.fizz", a_BlockX * 8, a_BlockY * 8, a_BlockZ * 8, 1.0f, 0.6f); - } -} - - - - - -void cVaporizeFluidSimulator::Simulate(float a_Dt) -{ - // Nothing needed -} - - - - diff --git a/source/Simulator/VaporizeFluidSimulator.h b/source/Simulator/VaporizeFluidSimulator.h deleted file mode 100644 index c8eb7802b..000000000 --- a/source/Simulator/VaporizeFluidSimulator.h +++ /dev/null @@ -1,34 +0,0 @@ - -// VaporizeFluidSimulator.h - -// Declares the cVaporizeFluidSimulator class representing a fluid simulator that replaces all fluid blocks with air -// Useful for water simulation in the Nether - - - - - -#pragma once - -#include "FluidSimulator.h" - - - - - -class cVaporizeFluidSimulator : - public cFluidSimulator -{ - typedef cFluidSimulator super; - -public: - cVaporizeFluidSimulator(cWorld & a_World, BLOCKTYPE a_Fluid, BLOCKTYPE a_StationaryFluid); - - // cSimulator overrides: - virtual void AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk) override; - virtual void Simulate(float a_Dt) override; -} ; - - - - |