diff options
Diffstat (limited to 'source/Chunk.cpp')
-rw-r--r-- | source/Chunk.cpp | 519 |
1 files changed, 271 insertions, 248 deletions
diff --git a/source/Chunk.cpp b/source/Chunk.cpp index db533f642..be75eae41 100644 --- a/source/Chunk.cpp +++ b/source/Chunk.cpp @@ -30,6 +30,9 @@ #include "PluginManager.h" #include "Blocks/BlockHandler.h" #include "Simulator/FluidSimulator.h" +#include "MobCensus.h" +#include "MobSpawner.h" + #include <json/json.h> @@ -429,6 +432,129 @@ void cChunk::Stay(bool a_Stay) +void cChunk::CollectMobCensus(cMobCensus& toFill) +{ + toFill.CollectSpawnableChunk(*this); + std::list<const Vector3d*> playerPositions; + cPlayer* currentPlayer; + for (cClientHandleList::iterator itr = m_LoadedByClient.begin(), end = m_LoadedByClient.end(); itr != end; ++itr) + { + currentPlayer = (*itr)->GetPlayer(); + playerPositions.push_back(&(currentPlayer->GetPosition())); + } + + Vector3d currentPosition; + for (cEntityList::iterator itr = m_Entities.begin(); itr != m_Entities.end(); ++itr) + { + //LOGD("Counting entity #%i (%s)", (*itr)->GetUniqueID(), (*itr)->GetClass()); + if ((*itr)->IsMob()) + { + cMonster& Monster = (cMonster&)(**itr); + currentPosition = Monster.GetPosition(); + for (std::list<const Vector3d*>::const_iterator itr2 = playerPositions.begin(); itr2 != playerPositions.end(); itr2 ++) + { + toFill.CollectMob(Monster,*this,(currentPosition-**itr2).SqrLength()); + } + } + } // for itr - m_Entitites[] +} + + + + +void cChunk::getThreeRandomNumber(int& a_X, int& a_Y, int& a_Z,int a_MaxX, int a_MaxY, int a_MaxZ) +{ + ASSERT(a_MaxX * a_MaxY * a_MaxZ * 8 < 0x00ffffff); + int Random = m_World->GetTickRandomNumber(0x00ffffff); + a_X = Random % (a_MaxX * 2); + a_Y = (Random / (a_MaxX * 2)) % (a_MaxY * 2); + a_Z = ((Random / (a_MaxX * 2)) / (a_MaxY * 2)) % (a_MaxZ * 2); + a_X /= 2; + a_Y /= 2; + a_Z /= 2; +} + + + + + +void cChunk::getRandomBlockCoords(int& a_X, int& a_Y, int& a_Z) +{ + // MG TODO : check if this kind of optimization (only one random call) is still needed + // MG TODO : if so propagate it + + getThreeRandomNumber(a_X, a_Y, a_Z, Width, Height-2, Width); + a_Y++; +} + + + + + +void cChunk::SpawnMobs(cMobSpawner& a_MobSpawner) +{ + int Center_X,Center_Y,Center_Z; + getRandomBlockCoords(Center_X,Center_Y,Center_Z); + + BLOCKTYPE PackCenterBlock = GetBlock(Center_X, Center_Y, Center_Z); + if (a_MobSpawner.CheckPackCenter(PackCenterBlock)) + { + a_MobSpawner.NewPack(); + int NumberOfTries = 0; + int NumberOfSuccess = 0; + int MaxNbOfSuccess = 4; // this can be changed during the process for Wolves and Ghass + while (NumberOfTries < 12 && NumberOfSuccess < MaxNbOfSuccess) + { + const int HorizontalRange = 20; // MG TODO : relocate + const int VerticalRange = 0; // MG TODO : relocate + int Try_X, Try_Y, Try_Z; + getThreeRandomNumber(Try_X, Try_Y, Try_Z, 2*HorizontalRange+1 , 2*VerticalRange+1 , 2*HorizontalRange+1); + Try_X -= HorizontalRange; + Try_Y -= VerticalRange; + Try_Z -= HorizontalRange; + Try_X += Center_X; + Try_Y += Center_Y; + Try_Z += Center_Z; + + ASSERT(Try_Y > 0); + ASSERT(Try_Y < cChunkDef::Height-1); + + EMCSBiome Biome = m_ChunkMap->GetBiomeAt (Try_X, Try_Z); + // MG TODO : + // Moon cycle (for slime) + // check player and playerspawn presence < 24 blocks + // check mobs presence on the block + + // MG TODO : check that "Level" really means Y + + NIBBLETYPE SkyLight = 0; + + NIBBLETYPE BlockLight = 0; + + if (IsLightValid()) + { + cEntity* newMob = a_MobSpawner.TryToSpawnHere(this, Try_X, Try_Y, Try_Z, Biome, MaxNbOfSuccess); + if (newMob) + { + int WorldX, WorldY, WorldZ; + PositionToWorldPosition(Try_X, Try_Y, Try_Z, WorldX, WorldY, WorldZ); + double ActualX = WorldX + 0.5; + double ActualZ = WorldZ + 0.5; + newMob->SetPosition(ActualX, WorldY, ActualZ); + LOGD("Spawning %s #%i at %d,%d,%d",newMob->GetClass(),newMob->GetUniqueID(),WorldX, WorldY, WorldZ); + NumberOfSuccess++; + } + } + + NumberOfTries++; + } + } + +} + + + + void cChunk::Tick(float a_Dt) { @@ -457,10 +583,14 @@ void cChunk::Tick(float a_Dt) m_IsDirty = (*itr)->Tick(a_Dt, *this) | m_IsDirty; } - // Tick all entities in this chunk: + // Tick all entities in this chunk (except mobs): for (cEntityList::iterator itr = m_Entities.begin(); itr != m_Entities.end(); ++itr) { - (*itr)->Tick(a_Dt, *this); + // Mobs are tickes inside MobTick (as we don't have to tick them if they are far away from players) + if (!((*itr)->IsMob())) + { + (*itr)->Tick(a_Dt, *this); + } } // for itr - m_Entitites[] // Remove all entities that were scheduled for removal: @@ -923,45 +1053,14 @@ bool cChunk::UnboundedRelGetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE LOGWARNING("%s: requesting a block with a_RelY out of range: %d", __FUNCTION__, a_RelY); return false; } - - // Is it in this chunk? - if ((a_RelX >= 0) && (a_RelX < cChunkDef::Width) && (a_RelZ >= 0) && (a_RelZ < cChunkDef::Width)) - { - if (!IsValid()) - { - return false; - } - int BlockIdx = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY, a_RelZ); - a_BlockType = GetBlock(BlockIdx); - a_BlockMeta = GetMeta(BlockIdx); - return true; - } - - // Not in this chunk, try walking the neighbors first: - if ((a_RelX < 0) && (m_NeighborXM != NULL)) - { - return m_NeighborXM->UnboundedRelGetBlock(a_RelX + cChunkDef::Width, a_RelY, a_RelZ, a_BlockType, a_BlockMeta); - } - if ((a_RelX >= cChunkDef::Width) && (m_NeighborXP != NULL)) + cChunk * Chunk = GetRelNeighborChunkAdjustCoords(a_RelX, a_RelZ); + if ((Chunk == NULL) || !Chunk->IsValid()) { - return m_NeighborXP->UnboundedRelGetBlock(a_RelX - cChunkDef::Width, a_RelY, a_RelZ, a_BlockType, a_BlockMeta); - } - if ((a_RelZ < 0) && (m_NeighborZM != NULL)) - { - return m_NeighborZM->UnboundedRelGetBlock(a_RelX, a_RelY, a_RelZ + cChunkDef::Width, a_BlockType, a_BlockMeta); - } - if ((a_RelZ >= cChunkDef::Width) && (m_NeighborZP != NULL)) - { - return m_NeighborZP->UnboundedRelGetBlock(a_RelX, a_RelY, a_RelZ - cChunkDef::Width, a_BlockType, a_BlockMeta); + // The chunk is not available, bail out + return false; } - - // Neighbors not available, use the chunkmap to locate the chunk: - return m_ChunkMap->LockedGetBlock( - m_PosX * cChunkDef::Width + a_RelX, - ZERO_CHUNK_Y * cChunkDef::Height + a_RelY, - m_PosZ * cChunkDef::Width + a_RelZ, - a_BlockType, a_BlockMeta - ); + Chunk->GetBlockTypeMeta(a_RelX, a_RelY, a_RelZ, a_BlockType, a_BlockMeta); + return true; } @@ -975,95 +1074,100 @@ bool cChunk::UnboundedRelGetBlockType(int a_RelX, int a_RelY, int a_RelZ, BLOCKT LOGWARNING("%s: requesting a block with a_RelY out of range: %d", __FUNCTION__, a_RelY); return false; } - - // Is it in this chunk? - if ((a_RelX >= 0) && (a_RelX < cChunkDef::Width) && (a_RelZ >= 0) && (a_RelZ < cChunkDef::Width)) + cChunk * Chunk = GetRelNeighborChunkAdjustCoords(a_RelX, a_RelZ); + if ((Chunk == NULL) || !Chunk->IsValid()) { - if (!IsValid()) - { - return false; - } - int BlockIdx = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY, a_RelZ); - a_BlockType = GetBlock(BlockIdx); - return true; + // The chunk is not available, bail out + return false; } + a_BlockType = Chunk->GetBlock(a_RelX, a_RelY, a_RelZ); + return true; +} - // Not in this chunk, try walking the neighbors first: - if ((a_RelX < 0) && (m_NeighborXM != NULL)) - { - return m_NeighborXM->UnboundedRelGetBlockType(a_RelX + cChunkDef::Width, a_RelY, a_RelZ, a_BlockType); - } - if ((a_RelX >= cChunkDef::Width) && (m_NeighborXP != NULL)) - { - return m_NeighborXP->UnboundedRelGetBlockType(a_RelX - cChunkDef::Width, a_RelY, a_RelZ, a_BlockType); - } - if ((a_RelZ < 0) && (m_NeighborZM != NULL)) + + + + +bool cChunk::UnboundedRelGetBlockMeta(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE & a_BlockMeta) const +{ + if ((a_RelY < 0) || (a_RelY >= cChunkDef::Height)) { - return m_NeighborZM->UnboundedRelGetBlockType(a_RelX, a_RelY, a_RelZ + cChunkDef::Width, a_BlockType); + LOGWARNING("%s: requesting a block with a_RelY out of range: %d", __FUNCTION__, a_RelY); + return false; } - if ((a_RelZ >= cChunkDef::Width) && (m_NeighborZP != NULL)) + cChunk * Chunk = GetRelNeighborChunkAdjustCoords(a_RelX, a_RelZ); + if ((Chunk == NULL) || !Chunk->IsValid()) { - return m_NeighborZP->UnboundedRelGetBlockType(a_RelX, a_RelY, a_RelZ - cChunkDef::Width, a_BlockType); + // The chunk is not available, bail out + return false; } - - // Neighbors not available, use the chunkmap to locate the chunk: - return m_ChunkMap->LockedGetBlockType( - m_PosX * cChunkDef::Width + a_RelX, - ZERO_CHUNK_Y * cChunkDef::Height + a_RelY, - m_PosZ * cChunkDef::Width + a_RelZ, - a_BlockType - ); + a_BlockMeta = Chunk->GetMeta(a_RelX, a_RelY, a_RelZ); + return true; } -bool cChunk::UnboundedRelGetBlockMeta(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE & a_BlockMeta) const +bool cChunk::UnboundedRelGetBlockBlockLight(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE & a_BlockBlockLight) const { if ((a_RelY < 0) || (a_RelY >= cChunkDef::Height)) { LOGWARNING("%s: requesting a block with a_RelY out of range: %d", __FUNCTION__, a_RelY); return false; } - - // Is it in this chunk? - if ((a_RelX >= 0) && (a_RelX < cChunkDef::Width) && (a_RelZ >= 0) && (a_RelZ < cChunkDef::Width)) + cChunk * Chunk = GetRelNeighborChunkAdjustCoords(a_RelX, a_RelZ); + if ((Chunk == NULL) || !Chunk->IsValid()) { - if (!IsValid()) - { - return false; - } - int BlockIdx = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY, a_RelZ); - a_BlockMeta = GetMeta(BlockIdx); - return true; + // The chunk is not available, bail out + return false; } + a_BlockBlockLight = Chunk->GetBlockLight(a_RelX, a_RelY, a_RelZ); + return true; +} + + + - // Not in this chunk, try walking the neighbors first: - if ((a_RelX < 0) && (m_NeighborXM != NULL)) + +bool cChunk::UnboundedRelGetBlockSkyLight(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE & a_BlockSkyLight) const +{ + if ((a_RelY < 0) || (a_RelY >= cChunkDef::Height)) { - return m_NeighborXM->UnboundedRelGetBlockMeta(a_RelX + cChunkDef::Width, a_RelY, a_RelZ, a_BlockMeta); + LOGWARNING("%s: requesting a block with a_RelY out of range: %d", __FUNCTION__, a_RelY); + return false; } - if ((a_RelX >= cChunkDef::Width) && (m_NeighborXP != NULL)) + cChunk * Chunk = GetRelNeighborChunkAdjustCoords(a_RelX, a_RelZ); + if ((Chunk == NULL) || !Chunk->IsValid()) { - return m_NeighborXP->UnboundedRelGetBlockMeta(a_RelX - cChunkDef::Width, a_RelY, a_RelZ, a_BlockMeta); + // The chunk is not available, bail out + return false; } - if ((a_RelZ < 0) && (m_NeighborZM != NULL)) + a_BlockSkyLight = Chunk->GetSkyLight(a_RelX, a_RelY, a_RelZ); + return true; +} + + + + + +bool cChunk::UnboundedRelGetBlockLights(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE & a_BlockLight, NIBBLETYPE & a_SkyLight) const +{ + if ((a_RelY < 0) || (a_RelY >= cChunkDef::Height)) { - return m_NeighborZM->UnboundedRelGetBlockMeta(a_RelX, a_RelY, a_RelZ + cChunkDef::Width, a_BlockMeta); + LOGWARNING("%s: requesting a block with a_RelY out of range: %d", __FUNCTION__, a_RelY); + return false; } - if ((a_RelZ >= cChunkDef::Width) && (m_NeighborZP != NULL)) + cChunk * Chunk = GetRelNeighborChunkAdjustCoords(a_RelX, a_RelZ); + if ((Chunk == NULL) || !Chunk->IsValid()) { - return m_NeighborZP->UnboundedRelGetBlockMeta(a_RelX, a_RelY, a_RelZ - cChunkDef::Width, a_BlockMeta); + // The chunk is not available, bail out + return false; } - - // Neighbors not available, use the chunkmap to locate the chunk: - return m_ChunkMap->LockedGetBlockMeta( - m_PosX * cChunkDef::Width + a_RelX, - ZERO_CHUNK_Y * cChunkDef::Height + a_RelY, - m_PosZ * cChunkDef::Width + a_RelZ, - a_BlockMeta - ); + int idx = Chunk->MakeIndex(a_RelX, a_RelY, a_RelZ); + a_BlockLight = Chunk->GetBlockLight(idx); + a_SkyLight = Chunk->GetSkyLight(idx); + return true; } @@ -1077,44 +1181,15 @@ bool cChunk::UnboundedRelSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE LOGWARNING("UnboundedRelSetBlock(): requesting a block with a_RelY out of range: %d", a_RelY); return false; } - - // Is it in this chunk? - if ((a_RelX >= 0) && (a_RelX < cChunkDef::Width) && (a_RelZ >= 0) && (a_RelZ < cChunkDef::Width)) + cChunk * Chunk = GetRelNeighborChunkAdjustCoords(a_RelX, a_RelZ); + if ((Chunk == NULL) || !Chunk->IsValid()) { - if (!IsValid()) - { - return false; - } - SetBlock(a_RelX, a_RelY, a_RelZ, a_BlockType, a_BlockMeta); - return true; - } - - // Not in this chunk, try walking the neighbors first: - if ((a_RelX < 0) && (m_NeighborXM != NULL)) - { - return m_NeighborXM->UnboundedRelSetBlock(a_RelX + cChunkDef::Width, a_RelY, a_RelZ, a_BlockType, a_BlockMeta); - } - if ((a_RelX >= cChunkDef::Width) && (m_NeighborXP != NULL)) - { - return m_NeighborXP->UnboundedRelSetBlock(a_RelX - cChunkDef::Width, a_RelY, a_RelZ, a_BlockType, a_BlockMeta); - } - if ((a_RelZ < 0) && (m_NeighborZM != NULL)) - { - return m_NeighborZM->UnboundedRelSetBlock(a_RelX, a_RelY, a_RelZ + cChunkDef::Width, a_BlockType, a_BlockMeta); - } - if ((a_RelZ >= cChunkDef::Width) && (m_NeighborZP != NULL)) - { - return m_NeighborZP->UnboundedRelSetBlock(a_RelX, a_RelY, a_RelZ - cChunkDef::Width, a_BlockType, a_BlockMeta); + // The chunk is not available, bail out + return false; } - - // Neighbors not available, use the chunkmap to locate the chunk: - return m_ChunkMap->LockedSetBlock( - m_PosX * cChunkDef::Width + a_RelX, - ZERO_CHUNK_Y * cChunkDef::Height + a_RelY, - m_PosZ * cChunkDef::Width + a_RelZ, - a_BlockType, a_BlockMeta - ); -} + Chunk->SetBlock(a_RelX, a_RelY, a_RelZ, a_BlockType, a_BlockMeta); + return true; +} @@ -1127,43 +1202,14 @@ bool cChunk::UnboundedRelFastSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKT LOGWARNING("UnboundedRelFastSetBlock(): requesting a block with a_RelY out of range: %d", a_RelY); return false; } - - // Is it in this chunk? - if ((a_RelX >= 0) && (a_RelX < cChunkDef::Width) && (a_RelZ >= 0) && (a_RelZ < cChunkDef::Width)) - { - if (!IsValid()) - { - return false; - } - FastSetBlock(a_RelX, a_RelY, a_RelZ, a_BlockType, a_BlockMeta); - return true; - } - - // Not in this chunk, try walking the neighbors first: - if ((a_RelX < 0) && (m_NeighborXM != NULL)) - { - return m_NeighborXM->UnboundedRelFastSetBlock(a_RelX + cChunkDef::Width, a_RelY, a_RelZ, a_BlockType, a_BlockMeta); - } - if ((a_RelX >= cChunkDef::Width) && (m_NeighborXP != NULL)) - { - return m_NeighborXP->UnboundedRelFastSetBlock(a_RelX - cChunkDef::Width, a_RelY, a_RelZ, a_BlockType, a_BlockMeta); - } - if ((a_RelZ < 0) && (m_NeighborZM != NULL)) + cChunk * Chunk = GetRelNeighborChunkAdjustCoords(a_RelX, a_RelZ); + if ((Chunk == NULL) || !Chunk->IsValid()) { - return m_NeighborZM->UnboundedRelFastSetBlock(a_RelX, a_RelY, a_RelZ + cChunkDef::Width, a_BlockType, a_BlockMeta); - } - if ((a_RelZ >= cChunkDef::Width) && (m_NeighborZP != NULL)) - { - return m_NeighborZP->UnboundedRelFastSetBlock(a_RelX, a_RelY, a_RelZ - cChunkDef::Width, a_BlockType, a_BlockMeta); + // The chunk is not available, bail out + return false; } - - // Neighbors not available, use the chunkmap to locate the chunk: - return m_ChunkMap->LockedFastSetBlock( - m_PosX * cChunkDef::Width + a_RelX, - ZERO_CHUNK_Y * cChunkDef::Height + a_RelY, - m_PosZ * cChunkDef::Width + a_RelZ, - a_BlockType, a_BlockMeta - ); + Chunk->FastSetBlock(a_RelX, a_RelY, a_RelZ, a_BlockType, a_BlockMeta); + return true; } @@ -1177,44 +1223,18 @@ void cChunk::UnboundedQueueTickBlock(int a_RelX, int a_RelY, int a_RelZ) // Outside of chunkmap return; } - - // Is it in this chunk? - if ((a_RelX >= 0) && (a_RelX < cChunkDef::Width) && (a_RelZ >= 0) && (a_RelZ < cChunkDef::Width)) - { - QueueTickBlock(a_RelX, a_RelY, a_RelZ); - return; - } - - // Not in this chunk, try walking the neighbors first: - if ((a_RelX < 0) && (m_NeighborXM != NULL)) - { - m_NeighborXM->UnboundedQueueTickBlock(a_RelX + cChunkDef::Width, a_RelY, a_RelZ); - return; - } - if ((a_RelX >= cChunkDef::Width) && (m_NeighborXP != NULL)) - { - m_NeighborXP->UnboundedQueueTickBlock(a_RelX - cChunkDef::Width, a_RelY, a_RelZ); - return; - } - if ((a_RelZ < 0) && (m_NeighborZM != NULL)) - { - m_NeighborZM->UnboundedQueueTickBlock(a_RelX, a_RelY, a_RelZ + cChunkDef::Width); - return; - } - if ((a_RelZ >= cChunkDef::Width) && (m_NeighborZP != NULL)) + cChunk * Chunk = GetRelNeighborChunkAdjustCoords(a_RelX, a_RelZ); + if ((Chunk != NULL) && Chunk->IsValid()) { - m_NeighborZP->UnboundedQueueTickBlock(a_RelX, a_RelY, a_RelZ - cChunkDef::Width); - return; + Chunk->QueueTickBlock(a_RelX, a_RelY, a_RelZ); } - - // Neighbors not available, ignore altogether } -int cChunk::GetHeight( int a_X, int a_Z ) +int cChunk::GetHeight(int a_X, int a_Z) { ASSERT((a_X >= 0) && (a_X < Width) && (a_Z >= 0) && (a_Z < Width)); @@ -2340,66 +2360,58 @@ cChunk * cChunk::GetRelNeighborChunk(int a_RelX, int a_RelZ) -cChunk * cChunk::GetRelNeighborChunkAdjustCoords(int & a_RelX, int & a_RelZ) +cChunk * cChunk::GetRelNeighborChunkAdjustCoords(int & a_RelX, int & a_RelZ) const { - bool ReturnThis = true; - int RelX = a_RelX; + cChunk * ToReturn = const_cast<cChunk *>(this); + + // The most common case: inside this chunk: + if ( + (a_RelX >= 0) && (a_RelX < Width) && + (a_RelZ >= 0) && (a_RelZ < Width) + ) + { + return ToReturn; + } + + // Request for a different chunk, calculate chunk offset: + int RelX = a_RelX; // Make a local copy of the coords (faster access) int RelZ = a_RelZ; - if (a_RelX < 0) + while ((RelX >= Width) && (ToReturn != NULL)) { - if (m_NeighborXM != NULL) - { - RelX = a_RelX + cChunkDef::Width; - cChunk * Candidate = m_NeighborXM->GetRelNeighborChunkAdjustCoords(RelX, RelZ); - if (Candidate != NULL) - { - a_RelX = RelX; - a_RelZ = RelZ; - return Candidate; - } - } - // Going X-first failed, but if the request is crossing Z as well, let's try the Z-first later on. - ReturnThis = false; + RelX -= Width; + ToReturn = ToReturn->m_NeighborXP; } - else if (a_RelX >= cChunkDef::Width) + while ((RelX < 0) && (ToReturn != NULL)) { - if (m_NeighborXP != NULL) - { - RelX = a_RelX - cChunkDef::Width; - cChunk * Candidate = m_NeighborXP->GetRelNeighborChunkAdjustCoords(RelX, RelZ); - if (Candidate != NULL) - { - a_RelX = RelX; - a_RelZ = RelZ; - return Candidate; - } - } - // Going X-first failed, but if the request is crossing Z as well, let's try the Z-first later on. - ReturnThis = false; + RelX += Width; + ToReturn = ToReturn->m_NeighborXM; } - - if (a_RelZ < 0) + while ((RelZ >= Width) && (ToReturn != NULL)) { - if (m_NeighborZM != NULL) - { - a_RelZ += cChunkDef::Width; - return m_NeighborZM->GetRelNeighborChunkAdjustCoords(a_RelX, a_RelZ); - // For requests crossing both X and Z, the X-first way has been already tried - } - return NULL; + RelZ -= Width; + ToReturn = ToReturn->m_NeighborZP; } - else if (a_RelZ >= cChunkDef::Width) + while ((RelZ < 0) && (ToReturn != NULL)) { - if (m_NeighborZP != NULL) - { - a_RelZ -= cChunkDef::Width; - return m_NeighborZP->GetRelNeighborChunkAdjustCoords(a_RelX, a_RelZ); - // For requests crossing both X and Z, the X-first way has been already tried - } - return NULL; + RelZ += Width; + ToReturn = ToReturn->m_NeighborZM; + } + if (ToReturn != NULL) + { + a_RelX = RelX; + a_RelZ = RelZ; + return ToReturn; } - return (ReturnThis ? this : NULL); + // The chunk cannot be walked through neighbors, find it through the chunkmap: + int AbsX = a_RelX + m_PosX * Width; + int AbsZ = a_RelZ + m_PosZ * Width; + int DstChunkX, DstChunkZ; + BlockToChunk(AbsX, AbsZ, DstChunkX, DstChunkZ); + ToReturn = m_ChunkMap->FindChunk(DstChunkX, DstChunkZ); + a_RelX = AbsX - DstChunkX * Width; + a_RelZ = AbsZ - DstChunkZ * Width; + return ToReturn; } @@ -2774,6 +2786,17 @@ Vector3i cChunk::PositionToWorldPosition(int a_RelX, int a_RelY, int a_RelZ) +NIBBLETYPE cChunk::GetTimeAlteredLight(NIBBLETYPE a_Skylight) const +{ + a_Skylight -= m_World->GetSkyDarkness(); + // Because NIBBLETYPE is unsigned, we clamp it to 0 .. 15 by checking for values above 15 + return (a_Skylight < 16)? a_Skylight : 0; +} + + + + + #if !C_CHUNK_USE_INLINE # include "cChunk.inl.h" #endif |