Convert most calls to blocking GetHeight/GetBiomeAt to direct chunk accesses
* Hopefully fixes #5094
This commit is contained in:
parent
eeb63b8901
commit
9328afe65c
@ -115,13 +115,14 @@ private:
|
||||
/** Returns true if there's either a water source block close enough to hydrate the specified position, or it's raining there. */
|
||||
static bool IsWaterInNear(const cChunk & a_Chunk, const Vector3i a_RelPos)
|
||||
{
|
||||
const auto WorldPos = a_Chunk.RelativeToAbsolute(a_RelPos);
|
||||
if (a_Chunk.GetWorld()->IsWeatherWetAtXYZ(WorldPos))
|
||||
if (a_Chunk.IsWeatherWetAt(a_RelPos.addedY(1)))
|
||||
{
|
||||
// Rain hydrates farmland, too
|
||||
return true;
|
||||
}
|
||||
|
||||
const auto WorldPos = a_Chunk.RelativeToAbsolute(a_RelPos);
|
||||
|
||||
// Search for water in a close proximity:
|
||||
// Ref.: https://minecraft.gamepedia.com/Farmland#Hydration
|
||||
// TODO: Rewrite this to use the chunk and its neighbors directly
|
||||
|
@ -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];
|
||||
}
|
||||
|
||||
if ((a_X >= 0) && (a_X < Width) && (a_Z >= 0) && (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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cChunk::IsWeatherWetAt(const Vector3i a_Position) const
|
||||
{
|
||||
if ((a_Position.y < 0) || !IsWeatherWetAt(a_Position.x, a_Position.z))
|
||||
{
|
||||
return m_HeightMap[a_X + a_Z * Width];
|
||||
return false;
|
||||
}
|
||||
return 0;
|
||||
|
||||
if (a_Position.y >= cChunkDef::Height)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
12
src/Chunk.h
12
src/Chunk.h
@ -221,7 +221,17 @@ public:
|
||||
/** Sets the sign text. Returns true if successful. Also sends update packets to all clients in the chunk */
|
||||
bool SetSignLines(int a_RelX, int a_RelY, int a_RelZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4);
|
||||
|
||||
int GetHeight( int a_X, int a_Z);
|
||||
int GetHeight( int a_X, int a_Z) const;
|
||||
|
||||
/** Returns true if it is sunny at the specified location. This takes into account biomes. */
|
||||
bool IsWeatherSunnyAt(int a_RelX, int a_RelZ) const;
|
||||
|
||||
/** Returns true if it is raining or storming at the specified location, taking into account biomes. */
|
||||
bool IsWeatherWetAt(int a_RelX, int a_RelZ) const;
|
||||
|
||||
/** Returns true if it is raining or storming at the specified location,
|
||||
and the rain reaches (the bottom of) the specified block position. */
|
||||
bool IsWeatherWetAt(Vector3i a_Position) const;
|
||||
|
||||
void SendBlockTo(int a_RelX, int a_RelY, int a_RelZ, cClientHandle * a_Client);
|
||||
|
||||
|
@ -337,6 +337,63 @@ bool cChunkMap::IsChunkQueued(int a_ChunkX, int a_ChunkZ) const
|
||||
|
||||
|
||||
|
||||
bool cChunkMap::IsWeatherSunnyAt(int a_BlockX, int a_BlockZ) const
|
||||
{
|
||||
int ChunkX, ChunkZ, BlockY = 0;
|
||||
cChunkDef::AbsoluteToRelative(a_BlockX, BlockY, a_BlockZ, ChunkX, ChunkZ);
|
||||
|
||||
cCSLock Lock(m_CSChunks);
|
||||
const auto Chunk = FindChunk(ChunkX, ChunkZ);
|
||||
if ((Chunk == nullptr) || !Chunk->IsValid())
|
||||
{
|
||||
return m_World->IsWeatherSunny();
|
||||
}
|
||||
|
||||
return Chunk->IsWeatherSunnyAt(a_BlockX, a_BlockZ);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cChunkMap::IsWeatherWetAt(int a_BlockX, int a_BlockZ) const
|
||||
{
|
||||
int ChunkX, ChunkZ, BlockY = 0;
|
||||
cChunkDef::AbsoluteToRelative(a_BlockX, BlockY, a_BlockZ, ChunkX, ChunkZ);
|
||||
|
||||
cCSLock Lock(m_CSChunks);
|
||||
const auto Chunk = FindChunk(ChunkX, ChunkZ);
|
||||
if ((Chunk == nullptr) || !Chunk->IsValid())
|
||||
{
|
||||
return m_World->IsWeatherWet();
|
||||
}
|
||||
|
||||
return Chunk->IsWeatherWetAt(a_BlockX, a_BlockZ);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cChunkMap::IsWeatherWetAt(const Vector3i a_Position) const
|
||||
{
|
||||
const auto ChunkPosition = cChunkDef::BlockToChunk(a_Position);
|
||||
const auto Position = cChunkDef::AbsoluteToRelative(a_Position, ChunkPosition);
|
||||
|
||||
cCSLock Lock(m_CSChunks);
|
||||
const auto Chunk = FindChunk(ChunkPosition.m_ChunkX, ChunkPosition.m_ChunkZ);
|
||||
if ((Chunk == nullptr) || !Chunk->IsValid())
|
||||
{
|
||||
return m_World->IsWeatherWet();
|
||||
}
|
||||
|
||||
return Chunk->IsWeatherWetAt(Position);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cChunkMap::IsChunkValid(int a_ChunkX, int a_ChunkZ) const
|
||||
{
|
||||
cCSLock Lock(m_CSChunks);
|
||||
@ -647,10 +704,7 @@ EMCSBiome cChunkMap::GetBiomeAt(int a_BlockX, int a_BlockZ) const
|
||||
{
|
||||
return Chunk->GetBiomeAt(X, Z);
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_World->GetGenerator().GetBiomeAt(a_BlockX, a_BlockZ);
|
||||
}
|
||||
return EMCSBiome::biInvalidBiome;
|
||||
}
|
||||
|
||||
|
||||
|
@ -5,9 +5,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include "ChunkDataCallback.h"
|
||||
#include "EffectID.h"
|
||||
#include "FunctionRef.h"
|
||||
@ -120,6 +117,10 @@ public:
|
||||
/** Returns true iff the chunk is in the loader / generator queue. */
|
||||
bool IsChunkQueued(int a_ChunkX, int a_ChunkZ) const;
|
||||
|
||||
bool IsWeatherSunnyAt(int a_BlockX, int a_BlockZ) const;
|
||||
bool IsWeatherWetAt(int a_BlockX, int a_BlockZ) const;
|
||||
bool IsWeatherWetAt(Vector3i a_Position) const;
|
||||
|
||||
bool IsChunkValid (int a_ChunkX, int a_ChunkZ) const;
|
||||
bool HasChunkAnyClients (int a_ChunkX, int a_ChunkZ) const;
|
||||
int GetHeight (int a_BlockX, int a_BlockZ); // Waits for the chunk to get loaded / generated
|
||||
@ -143,15 +144,15 @@ public:
|
||||
Ignored if the chunk is invalid. */
|
||||
void SetBlockMeta(Vector3i a_BlockPos, NIBBLETYPE a_BlockMeta);
|
||||
|
||||
void SetBlock (Vector3i a_BlockPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
|
||||
bool GetBlockTypeMeta (Vector3i a_BlockPos, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) const;
|
||||
bool GetBlockInfo (Vector3i, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_Meta, NIBBLETYPE & a_SkyLight, NIBBLETYPE & a_BlockLight) const;
|
||||
void SetBlock (Vector3i a_BlockPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
|
||||
bool GetBlockTypeMeta (Vector3i a_BlockPos, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) const;
|
||||
bool GetBlockInfo (Vector3i, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_Meta, NIBBLETYPE & a_SkyLight, NIBBLETYPE & a_BlockLight) const;
|
||||
|
||||
/** Special function used for growing trees, replaces only blocks that tree may overwrite */
|
||||
void ReplaceTreeBlocks(const sSetBlockVector & a_Blocks);
|
||||
void ReplaceTreeBlocks(const sSetBlockVector & a_Blocks);
|
||||
|
||||
/** Returns the biome at the specified coords. Reads the biome from the chunk, if loaded, otherwise uses the world generator to provide the biome value */
|
||||
EMCSBiome GetBiomeAt (int a_BlockX, int a_BlockZ) const;
|
||||
/** Returns the biome at the specified coords. Reads the biome from the chunk, if loaded, invalid otherwise. */
|
||||
EMCSBiome GetBiomeAt(int a_BlockX, int a_BlockZ) const;
|
||||
|
||||
/** Sets the biome at the specified coords. Returns true if successful, false if not (chunk not loaded).
|
||||
Doesn't resend the chunk to clients. */
|
||||
|
@ -1198,8 +1198,8 @@ void cEntity::TickBurning(cChunk & a_Chunk)
|
||||
m_TicksLeftBurning = 0;
|
||||
}
|
||||
|
||||
// Fire is extinguished by rain
|
||||
if (GetWorld()->IsWeatherWetAtXYZ(GetPosition().Floor()))
|
||||
// Fire is extinguished by rain:
|
||||
if (a_Chunk.IsWeatherWetAt(cChunkDef::AbsoluteToRelative(GetPosition().Floor(), a_Chunk.GetPos())))
|
||||
{
|
||||
m_TicksLeftBurning = 0;
|
||||
}
|
||||
|
@ -101,11 +101,16 @@ void cFloater::SpawnOn(cClientHandle & a_Client)
|
||||
|
||||
void cFloater::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
|
||||
{
|
||||
auto & Random = GetRandomProvider();
|
||||
|
||||
HandlePhysics(a_Dt, a_Chunk);
|
||||
if (IsBlockWater(m_World->GetBlock(POSX_TOINT, POSY_TOINT, POSZ_TOINT))
|
||||
&& (m_World->GetBlockMeta(POSX_TOINT, POSY_TOINT, POSZ_TOINT) == 0))
|
||||
|
||||
PREPARE_REL_AND_CHUNK(GetPosition().Floor(), a_Chunk);
|
||||
if (!RelSuccess)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto & Random = GetRandomProvider();
|
||||
if (IsBlockWater(Chunk->GetBlock(Rel)) && (Chunk->GetMeta(Rel) == 0))
|
||||
{
|
||||
if (!m_CanPickupItem && (m_AttachedMobID == cEntity::INVALID_ID)) // Check if you can't already pickup a fish and if the floater isn't attached to a mob.
|
||||
{
|
||||
@ -113,7 +118,7 @@ void cFloater::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
|
||||
{
|
||||
m_BitePos = GetPosition();
|
||||
m_World->BroadcastSoundEffect("entity.bobber.splash", GetPosition(), 1, 1);
|
||||
SetPosY(GetPosY() - 1);
|
||||
AddSpeedY(-10);
|
||||
m_CanPickupItem = true;
|
||||
m_PickupCountDown = 20;
|
||||
m_CountDownTime = Random.RandInt(100, 900);
|
||||
@ -132,9 +137,9 @@ void cFloater::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
|
||||
}
|
||||
|
||||
m_CountDownTime--;
|
||||
if (m_World->GetHeight(POSX_TOINT, POSZ_TOINT) == POSY_TOINT)
|
||||
if (Chunk->IsWeatherWetAt(Rel))
|
||||
{
|
||||
if (m_World->IsWeatherWet() && Random.RandBool(0.25)) // 25% chance of an extra countdown when being rained on.
|
||||
if (Random.RandBool(0.25)) // 25% chance of an extra countdown when being rained on.
|
||||
{
|
||||
m_CountDownTime--;
|
||||
}
|
||||
@ -150,7 +155,10 @@ void cFloater::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
|
||||
}
|
||||
|
||||
// Check water at the top of floater otherwise it floats into the air above the water
|
||||
if (IsBlockWater(m_World->GetBlock(POSX_TOINT, FloorC(GetPosY() + GetHeight()), POSZ_TOINT)))
|
||||
if (
|
||||
const auto Above = Rel.addedY(FloorC(GetPosY() + GetHeight()));
|
||||
(Above.y < cChunkDef::Height) && IsBlockWater(m_World->GetBlock(Above))
|
||||
)
|
||||
{
|
||||
SetSpeedY(0.7);
|
||||
}
|
||||
|
@ -74,10 +74,6 @@ eMonsterType cMobSpawner::ChooseMobType(EMCSBiome a_Biome)
|
||||
|
||||
bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, Vector3i a_RelPos, eMonsterType a_MobType, EMCSBiome a_Biome, bool a_DisableSolidBelowCheck)
|
||||
{
|
||||
if (a_Chunk == nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if ((a_RelPos.y >= cChunkDef::Height - 1) || (a_RelPos.y <= 0))
|
||||
{
|
||||
return false;
|
||||
@ -502,9 +498,6 @@ cMonster * cMobSpawner::TryToSpawnHere(cChunk * a_Chunk, Vector3i a_RelPos, EMCS
|
||||
m_NewPack = false;
|
||||
}
|
||||
|
||||
// Make sure we are looking at the right chunk to spawn in
|
||||
a_Chunk = a_Chunk->GetRelNeighborChunkAdjustCoords(a_RelPos);
|
||||
|
||||
if ((m_AllowedTypes.find(m_MobType) != m_AllowedTypes.end()) && CanSpawnHere(a_Chunk, a_RelPos, m_MobType, a_Biome))
|
||||
{
|
||||
auto NewMob = cMonster::NewMonsterFromType(m_MobType);
|
||||
|
@ -1,6 +1,7 @@
|
||||
|
||||
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
|
||||
|
||||
#include "Chunk.h"
|
||||
#include "Enderman.h"
|
||||
#include "../Entities/Player.h"
|
||||
#include "../LineBlockTracer.h"
|
||||
@ -148,11 +149,14 @@ void cEnderman::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
|
||||
return;
|
||||
}
|
||||
|
||||
// Take damage when wet
|
||||
if (
|
||||
cChunkDef::IsValidHeight(POSY_TOINT) &&
|
||||
(GetWorld()->IsWeatherWetAtXYZ(GetPosition().Floor()) || IsInWater())
|
||||
)
|
||||
PREPARE_REL_AND_CHUNK(GetPosition().Floor(), a_Chunk);
|
||||
if (!RelSuccess)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Take damage when wet:
|
||||
if (IsInWater() || Chunk->IsWeatherWetAt(Rel))
|
||||
{
|
||||
EventLosePlayer();
|
||||
TakeDamage(dtEnvironment, nullptr, 1, 0);
|
||||
|
@ -1667,10 +1667,10 @@ bool cMonster::WouldBurnAt(Vector3d a_Location, cChunk & a_Chunk)
|
||||
}
|
||||
|
||||
if (
|
||||
(Chunk->GetBlock(Rel.x, Rel.y, Rel.z) != E_BLOCK_SOULSAND) && // Not on soulsand
|
||||
(GetWorld()->GetTimeOfDay() < 12000 + 1000) && // Daytime
|
||||
GetWorld()->IsWeatherSunnyAt(POSX_TOINT, POSZ_TOINT) && // Not raining
|
||||
!IsInWater() // Isn't swimming
|
||||
(Chunk->GetBlock(Rel) != E_BLOCK_SOULSAND) && // Not on soulsand
|
||||
(GetWorld()->GetTimeOfDay() < 12000 + 1000) && // Daytime
|
||||
Chunk->IsWeatherSunnyAt(Rel.x, Rel.z) && // Not raining
|
||||
!IsInWater() // Isn't swimming
|
||||
)
|
||||
{
|
||||
int MobHeight = CeilC(a_Location.y + GetHeight()) - 1; // The block Y coord of the mob's head
|
||||
|
@ -1,6 +1,7 @@
|
||||
|
||||
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
|
||||
|
||||
#include "Chunk.h"
|
||||
#include "SnowGolem.h"
|
||||
#include "../BlockInfo.h"
|
||||
#include "../World.h"
|
||||
@ -36,17 +37,22 @@ void cSnowGolem::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
|
||||
// The base class tick destroyed us
|
||||
return;
|
||||
}
|
||||
if (IsBiomeNoDownfall(m_World->GetBiomeAt(POSX_TOINT, POSZ_TOINT)))
|
||||
|
||||
PREPARE_REL_AND_CHUNK(GetPosition().Floor(), a_Chunk);
|
||||
if (!RelSuccess)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsBiomeNoDownfall(Chunk->GetBiomeAt(Rel.x, Rel.z)))
|
||||
{
|
||||
TakeDamage(dtEnvironment, nullptr, GetRawDamageAgainst(*this), GetKnockbackAmountAgainst(*this));
|
||||
}
|
||||
else
|
||||
else if (const auto Below = Rel.addedY(-1); Below.y >= 0)
|
||||
{
|
||||
BLOCKTYPE BlockBelow = m_World->GetBlock(POSX_TOINT, POSY_TOINT - 1, POSZ_TOINT);
|
||||
BLOCKTYPE Block = m_World->GetBlock(POSX_TOINT, POSY_TOINT, POSZ_TOINT);
|
||||
if ((Block == E_BLOCK_AIR) && cBlockInfo::IsSolid(BlockBelow))
|
||||
if ((Chunk->GetBlock(Rel) == E_BLOCK_AIR) && cBlockInfo::IsSolid(Chunk->GetBlock(Below)))
|
||||
{
|
||||
m_World->SetBlock(POSX_TOINT, POSY_TOINT, POSZ_TOINT, E_BLOCK_SNOW, 0);
|
||||
Chunk->SetBlock(Rel, E_BLOCK_SNOW, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -87,7 +87,6 @@ void cFireSimulator::SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX,
|
||||
for (cCoordWithIntList::iterator itr = Data.begin(); itr != Data.end();)
|
||||
{
|
||||
Vector3i relPos(itr->x, itr->y, itr->z);
|
||||
auto absPos = a_Chunk->RelativeToAbsolute(relPos);
|
||||
auto blockType = a_Chunk->GetBlock(relPos);
|
||||
|
||||
if (!IsAllowedBlock(blockType))
|
||||
@ -101,12 +100,16 @@ void cFireSimulator::SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX,
|
||||
auto BurnsForever = ((relPos.y > 0) && DoesBurnForever(a_Chunk->GetBlock(relPos.addedY(-1))));
|
||||
auto BlockMeta = a_Chunk->GetMeta(relPos);
|
||||
|
||||
auto Raining = std::any_of(std::begin(gCrossCoords), std::end(gCrossCoords),
|
||||
[this, absPos](Vector3i cc)
|
||||
auto Raining = std::any_of(std::begin(gCrossCoords), std::end(gCrossCoords), [a_Chunk, relPos](Vector3i cc)
|
||||
{
|
||||
auto Adjusted = relPos + cc;
|
||||
const auto Chunk = a_Chunk->GetRelNeighborChunkAdjustCoords(Adjusted);
|
||||
if ((Chunk != nullptr) && Chunk->IsValid())
|
||||
{
|
||||
return (m_World.IsWeatherWetAtXYZ(absPos + cc));
|
||||
return Chunk->IsWeatherWetAt(Adjusted);
|
||||
}
|
||||
);
|
||||
return false;
|
||||
});
|
||||
|
||||
// Randomly burn out the fire if it is raining:
|
||||
if (!BurnsForever && Raining && GetRandomProvider().RandBool(CHANCE_BASE_RAIN_EXTINGUISH + (BlockMeta * CHANCE_AGE_M_RAIN_EXTINGUISH)))
|
||||
|
@ -548,28 +548,27 @@ void cWorld::ChangeWeather(void)
|
||||
|
||||
|
||||
|
||||
bool cWorld::IsWeatherWetAtXYZ(Vector3i a_Pos)
|
||||
bool cWorld::IsWeatherSunnyAt(int a_BlockX, int a_BlockZ) const
|
||||
{
|
||||
if ((a_Pos.y < 0) || !IsWeatherWetAt(a_Pos.x, a_Pos.z))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return m_ChunkMap.IsWeatherSunnyAt(a_BlockX, a_BlockZ);
|
||||
}
|
||||
|
||||
if (a_Pos.y >= cChunkDef::Height)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
for (int y = GetHeight(a_Pos.x, a_Pos.z); y >= a_Pos.y; y--)
|
||||
{
|
||||
auto BlockType = GetBlock({a_Pos.x, y, a_Pos.z});
|
||||
if (cBlockInfo::IsRainBlocker(BlockType))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
|
||||
bool cWorld::IsWeatherWetAt(int a_BlockX, int a_BlockZ)
|
||||
{
|
||||
return m_ChunkMap.IsWeatherWetAt(a_BlockX, a_BlockZ);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cWorld::IsWeatherWetAtXYZ(const Vector3i a_Position)
|
||||
{
|
||||
return m_ChunkMap.IsWeatherWetAt(a_Position);
|
||||
}
|
||||
|
||||
|
||||
|
13
src/World.h
13
src/World.h
@ -999,10 +999,7 @@ public:
|
||||
bool IsWeatherSunny(void) const { return (m_Weather == wSunny); }
|
||||
|
||||
/** Returns true if it is sunny at the specified location. This takes into account biomes. */
|
||||
bool IsWeatherSunnyAt(int a_BlockX, int a_BlockZ)
|
||||
{
|
||||
return (IsWeatherSunny() || IsBiomeNoDownfall(GetBiomeAt(a_BlockX, a_BlockZ)));
|
||||
}
|
||||
bool IsWeatherSunnyAt(int a_BlockX, int a_BlockZ) const;
|
||||
|
||||
/** Returns true if the current weather is rainy. */
|
||||
bool IsWeatherRain(void) const { return (m_Weather == wRain); }
|
||||
@ -1027,15 +1024,11 @@ public:
|
||||
|
||||
/** Returns true if it is raining or storming at the specified location.
|
||||
This takes into account biomes. */
|
||||
virtual bool IsWeatherWetAt(int a_BlockX, int a_BlockZ) override
|
||||
{
|
||||
auto Biome = GetBiomeAt(a_BlockX, a_BlockZ);
|
||||
return (IsWeatherWet() && !IsBiomeNoDownfall(Biome) && !IsBiomeCold(Biome));
|
||||
}
|
||||
virtual bool IsWeatherWetAt(int a_BlockX, int a_BlockZ) override;
|
||||
|
||||
/** Returns true if it is raining or storming at the specified location,
|
||||
and the rain reaches (the bottom of) the specified block position. */
|
||||
virtual bool IsWeatherWetAtXYZ(Vector3i a_Pos) override;
|
||||
virtual bool IsWeatherWetAtXYZ(Vector3i a_Position) override;
|
||||
|
||||
/** Returns the seed of the world. */
|
||||
int GetSeed(void) { return m_Generator.GetSeed(); }
|
||||
|
Loading…
Reference in New Issue
Block a user