1
0

Fixed block-getting so that simulators work again

git-svn-id: http://mc-server.googlecode.com/svn/trunk@301 0a769ca7-a7f5-676a-18bf-c427514a06d6
This commit is contained in:
madmaxoft@gmail.com 2012-02-21 12:29:05 +00:00
parent f07251625d
commit b4a68e58a9
6 changed files with 129 additions and 25 deletions

View File

@ -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) 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); cCSLock Lock(m_CSLayers);

View File

@ -54,6 +54,8 @@ public:
int GetHeight (int a_BlockX, int a_BlockZ); int GetHeight (int a_BlockX, int a_BlockZ);
void FastSetBlocks (sSetBlockList & a_BlockList); void FastSetBlocks (sSetBlockList & a_BlockList);
void CollectPickupsByPlayer(cPlayer * a_Player); 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 /// 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); void CompareChunkClients(int a_ChunkX1, int a_ChunkY1, int a_ChunkZ1, int a_ChunkX2, int a_ChunkY2, int a_ChunkZ2, cClientDiffCallback & a_Callback);

View File

@ -199,8 +199,6 @@ public:
} }
return Points; return Points;
} }
std::set< Vector3i >* m_ActiveFluid; std::set< Vector3i >* m_ActiveFluid;
@ -228,6 +226,10 @@ public:
unsigned char m_CurResult; unsigned char m_CurResult;
}; };
cFluidSimulator::cFluidSimulator( cWorld* a_World ) cFluidSimulator::cFluidSimulator( cWorld* a_World )
: cSimulator(a_World) : cSimulator(a_World)
, m_Data(0) , m_Data(0)
@ -235,20 +237,35 @@ cFluidSimulator::cFluidSimulator( cWorld* a_World )
m_Data = new FluidData(a_World, this); m_Data = new FluidData(a_World, this);
} }
cFluidSimulator::~cFluidSimulator() cFluidSimulator::~cFluidSimulator()
{ {
delete m_Data; delete m_Data;
} }
void cFluidSimulator::AddBlock( int a_X, int a_Y, int a_Z ) 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; return;
}
std::set< Vector3i > & ActiveFluid = *m_Data->m_ActiveFluid; std::set< Vector3i > & ActiveFluid = *m_Data->m_ActiveFluid;
ActiveFluid.insert( Vector3i( a_X, a_Y, a_Z ) ); ActiveFluid.insert( Vector3i( a_X, a_Y, a_Z ) );
} }
char cFluidSimulator::GetHighestLevelAround( int a_X, int a_Y, int a_Z ) char cFluidSimulator::GetHighestLevelAround( int a_X, int a_Y, int a_Z )
{ {
char Max = m_MaxHeight + m_FlowReduction; char Max = m_MaxHeight + m_FlowReduction;
@ -270,12 +287,18 @@ char cFluidSimulator::GetHighestLevelAround( int a_X, int a_Y, int a_Z )
return Max; return Max;
} }
void cFluidSimulator::Simulate( float a_Dt ) void cFluidSimulator::Simulate( float a_Dt )
{ {
m_Timer += 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; return;
}
std::swap( m_Data->m_ActiveFluid, m_Data->m_Buffer ); // Swap so blocks can be added to empty ActiveFluid array 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(); m_Data->m_ActiveFluid->clear();
@ -393,6 +416,9 @@ void cFluidSimulator::Simulate( float a_Dt )
} }
bool cFluidSimulator::IsPassableForFluid(char a_BlockID) bool cFluidSimulator::IsPassableForFluid(char a_BlockID)
{ {
return a_BlockID == E_BLOCK_AIR return a_BlockID == E_BLOCK_AIR
@ -401,11 +427,19 @@ bool cFluidSimulator::IsPassableForFluid(char a_BlockID)
|| CanWashAway(a_BlockID); || CanWashAway(a_BlockID);
} }
bool cFluidSimulator::IsStationaryBlock (char a_BlockID) bool cFluidSimulator::IsStationaryBlock (char a_BlockID)
{ {
return a_BlockID == m_StationaryFluidBlock; return a_BlockID == m_StationaryFluidBlock;
} }
bool cFluidSimulator::CanWashAway( char a_BlockID ) bool cFluidSimulator::CanWashAway( char a_BlockID )
{ {
switch( a_BlockID ) switch( a_BlockID )
@ -421,6 +455,10 @@ bool cFluidSimulator::CanWashAway( char a_BlockID )
}; };
} }
bool cFluidSimulator::IsSolidBlock( char a_BlockID ) bool cFluidSimulator::IsSolidBlock( char a_BlockID )
{ {
return !(a_BlockID == E_BLOCK_AIR return !(a_BlockID == E_BLOCK_AIR
@ -430,6 +468,10 @@ bool cFluidSimulator::IsSolidBlock( char a_BlockID )
|| CanWashAway(a_BlockID)); || CanWashAway(a_BlockID));
} }
//TODO Not working very well yet :s //TODO Not working very well yet :s
Direction cFluidSimulator::GetFlowingDirection(int a_X, int a_Y, int a_Z, bool a_Over) 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; delete Pos;
} }
if(LowestPoint == m_World->GetBlockMeta(a_X, a_Y, a_Z)) if(LowestPoint == m_World->GetBlockMeta(a_X, a_Y, a_Z))
return NONE; return NONE;
@ -514,10 +555,12 @@ Direction cFluidSimulator::GetFlowingDirection(int a_X, int a_Y, int a_Z, bool a
} }
return NONE; return NONE;
} }
bool cFluidSimulator::UniqueSituation(Vector3i a_Pos) bool cFluidSimulator::UniqueSituation(Vector3i a_Pos)
{ {
bool result = false; bool result = false;
@ -607,6 +650,10 @@ bool cFluidSimulator::UniqueSituation(Vector3i a_Pos)
return result; return result;
} }
void cFluidSimulator::ApplyUniqueToNearest(Vector3i a_Pos) void cFluidSimulator::ApplyUniqueToNearest(Vector3i a_Pos)
{ {
Vector3i NearPoints [] = { Vector3i NearPoints [] = {
@ -621,4 +668,8 @@ void cFluidSimulator::ApplyUniqueToNearest(Vector3i a_Pos)
{ {
UniqueSituation(NearPoints[i]); UniqueSituation(NearPoints[i]);
} }
} }

View File

@ -16,5 +16,5 @@ public:
protected: protected:
virtual void AddBlock(int a_X, int a_Y, int a_Z) = 0; virtual void AddBlock(int a_X, int a_Y, int a_Z) = 0;
cWorld *m_World; cWorld * m_World;
}; };

View File

@ -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) char cWorld::GetBlock(int a_X, int a_Y, int a_Z)
{ {
int ChunkX, ChunkY, ChunkZ; // First check if it isn't queued in the m_FastSetBlockQueue:
AbsoluteToRelative( a_X, a_Y, a_Z, ChunkX, ChunkY, ChunkZ );
cChunkPtr Chunk = GetChunk( ChunkX, ChunkY, ChunkZ );
if ( Chunk->IsValid() )
{ {
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 ) char cWorld::GetBlockMeta( int a_X, int a_Y, int a_Z )
{ {
int ChunkX, ChunkY, ChunkZ; // First check if it isn't queued in the m_FastSetBlockQueue:
AbsoluteToRelative( a_X, a_Y, a_Z, ChunkX, ChunkY, ChunkZ );
cChunkPtr Chunk = GetChunk( ChunkX, ChunkY, ChunkZ );
if ( Chunk->IsValid() )
{ {
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);
} }

View File

@ -188,6 +188,10 @@ void cWorldGenerator::GenerateTerrain(int a_ChunkX, int a_ChunkY, int a_ChunkZ,
{ {
Height = 127 - Lower; Height = 127 - Lower;
} }
if (Height < -63)
{
Height = -63;
}
const int Top = Lower + Height; const int Top = Lower + Height;
const float WaveNoise = 1; // m_Noise.CubicNoise2D( xx*0.01f, zz*0.01f ) + 0.5f; const float WaveNoise = 1; // m_Noise.CubicNoise2D( xx*0.01f, zz*0.01f ) + 0.5f;
for( int y = 1; y < Top; ++y ) for( int y = 1; y < Top; ++y )