From 9328afe65c72b29f5cedbf1897ea8559f6b2c42f Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Tue, 5 Jan 2021 02:13:02 +0000 Subject: Convert most calls to blocking GetHeight/GetBiomeAt to direct chunk accesses * Hopefully fixes #5094 --- src/Chunk.cpp | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 51 insertions(+), 7 deletions(-) (limited to 'src/Chunk.cpp') diff --git a/src/Chunk.cpp b/src/Chunk.cpp index 5a6cca3eb..4140d4f85 100644 --- a/src/Chunk.cpp +++ b/src/Chunk.cpp @@ -626,7 +626,6 @@ void cChunk::SpawnMobs(cMobSpawner & a_MobSpawner) int WorldX, WorldY, WorldZ; PositionToWorldPosition(TryX, TryY, TryZ, WorldX, WorldY, WorldZ); - EMCSBiome Biome = m_ChunkMap->GetBiomeAt(WorldX, WorldZ); // MG TODO : // Moon cycle (for slime) // check player and playerspawn presence < 24 blocks @@ -641,12 +640,16 @@ void cChunk::SpawnMobs(cMobSpawner & a_MobSpawner) */ NumberOfTries++; - if (!IsLightValid()) + + Vector3i Try(TryX, TryY, TryZ); + const auto Chunk = GetRelNeighborChunkAdjustCoords(Try); + + if ((Chunk == nullptr) || !Chunk->IsValid() || !Chunk->IsLightValid()) { continue; } - auto newMob = a_MobSpawner.TryToSpawnHere(this, {TryX, TryY, TryZ}, Biome, MaxNbOfSuccess); + auto newMob = a_MobSpawner.TryToSpawnHere(this, Try, GetBiomeAt(Try.x, Try.z), MaxNbOfSuccess); if (newMob == nullptr) { continue; @@ -1190,15 +1193,56 @@ bool cChunk::UnboundedRelFastSetBlock(Vector3i a_RelPos, BLOCKTYPE a_BlockType, -int cChunk::GetHeight(int a_X, int a_Z) +int cChunk::GetHeight(int a_X, int a_Z) const { ASSERT((a_X >= 0) && (a_X < Width) && (a_Z >= 0) && (a_Z < Width)); + return m_HeightMap[a_X + a_Z * Width]; +} + + + + + +bool cChunk::IsWeatherSunnyAt(int a_RelX, int a_RelZ) const +{ + return m_World->IsWeatherSunny() || IsBiomeNoDownfall(GetBiomeAt(a_RelX, a_RelZ)); +} + + + + + +bool cChunk::IsWeatherWetAt(const int a_RelX, const int a_RelZ) const +{ + const auto Biome = GetBiomeAt(a_RelX, a_RelZ); + return m_World->IsWeatherWet() && !IsBiomeNoDownfall(Biome) && !IsBiomeCold(Biome); +} - if ((a_X >= 0) && (a_X < Width) && (a_Z >= 0) && (a_Z < Width)) + + + + +bool cChunk::IsWeatherWetAt(const Vector3i a_Position) const +{ + if ((a_Position.y < 0) || !IsWeatherWetAt(a_Position.x, a_Position.z)) + { + return false; + } + + if (a_Position.y >= cChunkDef::Height) { - return m_HeightMap[a_X + a_Z * Width]; + return true; } - return 0; + + for (int y = GetHeight(a_Position.x, a_Position.z); y >= a_Position.y; y--) + { + if (cBlockInfo::IsRainBlocker(GetBlock({ a_Position.x, y, a_Position.z }))) + { + return false; + } + } + + return true; } -- cgit v1.2.3