From b4a68e58a9badb0f33d43a4cce9877935b2cc917 Mon Sep 17 00:00:00 2001 From: "madmaxoft@gmail.com" Date: Tue, 21 Feb 2012 12:29:05 +0000 Subject: Fixed block-getting so that simulators work again git-svn-id: http://mc-server.googlecode.com/svn/trunk@301 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- source/cChunkMap.cpp | 37 ++++++++++++++++++++++++++ source/cChunkMap.h | 2 ++ source/cFluidSimulator.cpp | 65 +++++++++++++++++++++++++++++++++++++++++----- source/cSimulator.h | 2 +- source/cWorld.cpp | 42 ++++++++++++++++++------------ source/cWorldGenerator.cpp | 4 +++ 6 files changed, 128 insertions(+), 24 deletions(-) diff --git a/source/cChunkMap.cpp b/source/cChunkMap.cpp index 6ae3fd987..3e59c08ef 100644 --- a/source/cChunkMap.cpp +++ b/source/cChunkMap.cpp @@ -442,6 +442,43 @@ void cChunkMap::CollectPickupsByPlayer(cPlayer * a_Player) +char cChunkMap::GetBlock(int a_X, int a_Y, int a_Z) +{ + int ChunkX, ChunkZ; + AbsoluteToRelative( a_X, a_Y, a_Z, ChunkX, ChunkZ ); + + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunkNoGen(ChunkX, ZERO_CHUNK_Y, ChunkZ); + if ((Chunk != NULL) && Chunk->IsValid()) + { + return Chunk->GetBlock(a_X, a_Y, a_Z); + } + return 0; +} + + + + + +char cChunkMap::GetBlockMeta(int a_X, int a_Y, int a_Z) +{ + int ChunkX, ChunkZ; + AbsoluteToRelative( a_X, a_Y, a_Z, ChunkX, ChunkZ ); + + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunk( ChunkX, ZERO_CHUNK_Y, ChunkZ ); + if ((Chunk != NULL) && Chunk->IsValid() ) + { + // Although it is called GetLight(), it actually gets meta when passed the Meta field + return Chunk->GetLight( Chunk->pGetMeta(), a_X, a_Y, a_Z ); + } + return 0; +} + + + + + void cChunkMap::CompareChunkClients(int a_ChunkX1, int a_ChunkY1, int a_ChunkZ1, int a_ChunkX2, int a_ChunkY2, int a_ChunkZ2, cClientDiffCallback & a_Callback) { cCSLock Lock(m_CSLayers); diff --git a/source/cChunkMap.h b/source/cChunkMap.h index 33e468eb1..2ab8ea0d0 100644 --- a/source/cChunkMap.h +++ b/source/cChunkMap.h @@ -54,6 +54,8 @@ public: int GetHeight (int a_BlockX, int a_BlockZ); void FastSetBlocks (sSetBlockList & a_BlockList); void CollectPickupsByPlayer(cPlayer * a_Player); + char GetBlock (int a_X, int a_Y, int a_Z); + char GetBlockMeta (int a_X, int a_Y, int a_Z); /// Compares clients of two chunks, calls the callback accordingly void CompareChunkClients(int a_ChunkX1, int a_ChunkY1, int a_ChunkZ1, int a_ChunkX2, int a_ChunkY2, int a_ChunkZ2, cClientDiffCallback & a_Callback); diff --git a/source/cFluidSimulator.cpp b/source/cFluidSimulator.cpp index 2d8952a05..68a6af599 100644 --- a/source/cFluidSimulator.cpp +++ b/source/cFluidSimulator.cpp @@ -199,8 +199,6 @@ public: } return Points; - - } std::set< Vector3i >* m_ActiveFluid; @@ -228,6 +226,10 @@ public: unsigned char m_CurResult; }; + + + + cFluidSimulator::cFluidSimulator( cWorld* a_World ) : cSimulator(a_World) , m_Data(0) @@ -235,20 +237,35 @@ cFluidSimulator::cFluidSimulator( cWorld* a_World ) m_Data = new FluidData(a_World, this); } + + + + cFluidSimulator::~cFluidSimulator() { delete m_Data; } + + + + void cFluidSimulator::AddBlock( int a_X, int a_Y, int a_Z ) { - if(!IsAllowedBlock(m_World->GetBlock(a_X, a_Y, a_Z))) //This should save very much time because it doesn´t have to iterate through all blocks + char BlockType = m_World->GetBlock(a_X, a_Y, a_Z); + if (!IsAllowedBlock(BlockType)) //This should save very much time because it doesn´t have to iterate through all blocks + { return; + } std::set< Vector3i > & ActiveFluid = *m_Data->m_ActiveFluid; ActiveFluid.insert( Vector3i( a_X, a_Y, a_Z ) ); } + + + + char cFluidSimulator::GetHighestLevelAround( int a_X, int a_Y, int a_Z ) { char Max = m_MaxHeight + m_FlowReduction; @@ -270,12 +287,18 @@ char cFluidSimulator::GetHighestLevelAround( int a_X, int a_Y, int a_Z ) return Max; } + + + + void cFluidSimulator::Simulate( float a_Dt ) { m_Timer += a_Dt; - if(m_Data->m_ActiveFluid->empty()) //Nothing to do if there is no active fluid ;) saves very little time ;D + if (m_Data->m_ActiveFluid->empty()) //Nothing to do if there is no active fluid ;) saves very little time ;D + { return; + } std::swap( m_Data->m_ActiveFluid, m_Data->m_Buffer ); // Swap so blocks can be added to empty ActiveFluid array m_Data->m_ActiveFluid->clear(); @@ -393,6 +416,9 @@ void cFluidSimulator::Simulate( float a_Dt ) } + + + bool cFluidSimulator::IsPassableForFluid(char a_BlockID) { return a_BlockID == E_BLOCK_AIR @@ -401,11 +427,19 @@ bool cFluidSimulator::IsPassableForFluid(char a_BlockID) || CanWashAway(a_BlockID); } + + + + bool cFluidSimulator::IsStationaryBlock (char a_BlockID) { return a_BlockID == m_StationaryFluidBlock; } + + + + bool cFluidSimulator::CanWashAway( char a_BlockID ) { switch( a_BlockID ) @@ -421,6 +455,10 @@ bool cFluidSimulator::CanWashAway( char a_BlockID ) }; } + + + + bool cFluidSimulator::IsSolidBlock( char a_BlockID ) { return !(a_BlockID == E_BLOCK_AIR @@ -430,6 +468,10 @@ bool cFluidSimulator::IsSolidBlock( char a_BlockID ) || CanWashAway(a_BlockID)); } + + + + //TODO Not working very well yet :s Direction cFluidSimulator::GetFlowingDirection(int a_X, int a_Y, int a_Z, bool a_Over) { @@ -489,7 +531,6 @@ Direction cFluidSimulator::GetFlowingDirection(int a_X, int a_Y, int a_Z, bool a delete Pos; } - if(LowestPoint == m_World->GetBlockMeta(a_X, a_Y, a_Z)) return NONE; @@ -514,9 +555,11 @@ Direction cFluidSimulator::GetFlowingDirection(int a_X, int a_Y, int a_Z, bool a } return NONE; +} + + -} bool cFluidSimulator::UniqueSituation(Vector3i a_Pos) { @@ -607,6 +650,10 @@ bool cFluidSimulator::UniqueSituation(Vector3i a_Pos) return result; } + + + + void cFluidSimulator::ApplyUniqueToNearest(Vector3i a_Pos) { Vector3i NearPoints [] = { @@ -621,4 +668,8 @@ void cFluidSimulator::ApplyUniqueToNearest(Vector3i a_Pos) { UniqueSituation(NearPoints[i]); } -} \ No newline at end of file +} + + + + diff --git a/source/cSimulator.h b/source/cSimulator.h index e045c18a8..4e92ec152 100644 --- a/source/cSimulator.h +++ b/source/cSimulator.h @@ -16,5 +16,5 @@ public: protected: virtual void AddBlock(int a_X, int a_Y, int a_Z) = 0; - cWorld *m_World; + cWorld * m_World; }; \ No newline at end of file diff --git a/source/cWorld.cpp b/source/cWorld.cpp index 83f36f1d5..a8e02a277 100644 --- a/source/cWorld.cpp +++ b/source/cWorld.cpp @@ -853,16 +853,23 @@ void cWorld::FastSetBlock( int a_X, int a_Y, int a_Z, char a_BlockType, char a_B char cWorld::GetBlock(int a_X, int a_Y, int a_Z) { - int ChunkX, ChunkY, ChunkZ; - - AbsoluteToRelative( a_X, a_Y, a_Z, ChunkX, ChunkY, ChunkZ ); - - cChunkPtr Chunk = GetChunk( ChunkX, ChunkY, ChunkZ ); - if ( Chunk->IsValid() ) + // First check if it isn't queued in the m_FastSetBlockQueue: { - return Chunk->GetBlock(a_X, a_Y, a_Z); + int X = a_X, Y = a_Y, Z = a_Z; + int ChunkX, ChunkY, ChunkZ; + AbsoluteToRelative(X, Y, Z, ChunkX, ChunkY, ChunkZ); + + cCSLock Lock(m_CSFastSetBlock); + for (sSetBlockList::iterator itr = m_FastSetBlockQueue.begin(); itr != m_FastSetBlockQueue.end(); ++itr) + { + if ((itr->x == X) && (itr->y == Y) && (itr->z == Z) && (itr->ChunkX == ChunkX) && (itr->ChunkZ == ChunkZ)) + { + return itr->BlockType; + } + } // for itr - m_FastSetBlockQueue[] } - return 0; + + return m_ChunkMap->GetBlock(a_X, a_Y, a_Z); } @@ -871,16 +878,19 @@ char cWorld::GetBlock(int a_X, int a_Y, int a_Z) char cWorld::GetBlockMeta( int a_X, int a_Y, int a_Z ) { - int ChunkX, ChunkY, ChunkZ; - - AbsoluteToRelative( a_X, a_Y, a_Z, ChunkX, ChunkY, ChunkZ ); - - cChunkPtr Chunk = GetChunk( ChunkX, ChunkY, ChunkZ ); - if ( Chunk->IsValid() ) + // First check if it isn't queued in the m_FastSetBlockQueue: { - return Chunk->GetLight( Chunk->pGetMeta(), a_X, a_Y, a_Z ); + cCSLock Lock(m_CSFastSetBlock); + for (sSetBlockList::iterator itr = m_FastSetBlockQueue.begin(); itr != m_FastSetBlockQueue.end(); ++itr) + { + if ((itr->x == a_X) && (itr->y == a_Y) && (itr->y == a_Y)) + { + return itr->BlockMeta; + } + } // for itr - m_FastSetBlockQueue[] } - return 0; + + return m_ChunkMap->GetBlockMeta(a_X, a_Y, a_Z); } diff --git a/source/cWorldGenerator.cpp b/source/cWorldGenerator.cpp index 6fecfc2e6..c933cf804 100644 --- a/source/cWorldGenerator.cpp +++ b/source/cWorldGenerator.cpp @@ -188,6 +188,10 @@ void cWorldGenerator::GenerateTerrain(int a_ChunkX, int a_ChunkY, int a_ChunkZ, { Height = 127 - Lower; } + if (Height < -63) + { + Height = -63; + } const int Top = Lower + Height; const float WaveNoise = 1; // m_Noise.CubicNoise2D( xx*0.01f, zz*0.01f ) + 0.5f; for( int y = 1; y < Top; ++y ) -- cgit v1.2.3