improve rain simulation (#4017)
* Uses vanilla logic to decide which blocks rain falls through. * Rain falls infinitely above the world, and stops at y=0. * Entities will now be extinguished if they are under rain-blocking blocks, and fire will now be extinguished by rain similarly. * Create IsWeatherWetAtXYZ to identify wetness at a particular location. * Use new code for enderman rain detection. * Fixes issue #916 * Disable warnings for global constructors in the fire simulator.
This commit is contained in:
parent
ab5ff6a6f8
commit
6309c6a97f
@ -238,7 +238,7 @@ return
|
||||
Type = "boolean",
|
||||
},
|
||||
},
|
||||
Notes = "Returns whether the specified block type will be destroyed after a single hit.",
|
||||
Notes = "Returns true if the specified block type will be destroyed after a single hit.",
|
||||
},
|
||||
IsPistonBreakable =
|
||||
{
|
||||
@ -256,7 +256,43 @@ return
|
||||
Type = "boolean",
|
||||
},
|
||||
},
|
||||
Notes = "Returns whether a piston can break the specified block type.",
|
||||
Notes = "Returns true if a piston can break the specified block type.",
|
||||
},
|
||||
IsRainBlocker =
|
||||
{
|
||||
IsStatic = true,
|
||||
Params =
|
||||
{
|
||||
{
|
||||
Name = "BlockType",
|
||||
Type = "number",
|
||||
},
|
||||
},
|
||||
Returns =
|
||||
{
|
||||
{
|
||||
Type = "boolean",
|
||||
},
|
||||
},
|
||||
Notes = "Returns true if the specified block type blocks rain from passing through.",
|
||||
},
|
||||
IsSkylightDispersant =
|
||||
{
|
||||
IsStatic = true,
|
||||
Params =
|
||||
{
|
||||
{
|
||||
Name = "BlockType",
|
||||
Type = "number",
|
||||
},
|
||||
},
|
||||
Returns =
|
||||
{
|
||||
{
|
||||
Type = "boolean",
|
||||
},
|
||||
},
|
||||
Notes = "Returns true if skylight is impeded by passage through a block of the specified type.",
|
||||
},
|
||||
IsSnowable =
|
||||
{
|
||||
@ -294,24 +330,6 @@ return
|
||||
},
|
||||
Notes = "Returns whether the specified block type is solid.",
|
||||
},
|
||||
IsSkylightDispersant =
|
||||
{
|
||||
IsStatic = true,
|
||||
Params =
|
||||
{
|
||||
{
|
||||
Name = "BlockType",
|
||||
Type = "number",
|
||||
},
|
||||
},
|
||||
Returns =
|
||||
{
|
||||
{
|
||||
Type = "boolean",
|
||||
},
|
||||
},
|
||||
Notes = "Returns true if skylight is impeded by passage through a block of the specified type.",
|
||||
},
|
||||
IsTransparent =
|
||||
{
|
||||
IsStatic = true,
|
||||
|
@ -2237,7 +2237,7 @@ function OnAllChunksAvailable()</pre> All return values from the callbacks are i
|
||||
Type = "boolean",
|
||||
},
|
||||
},
|
||||
Notes = "Returns true if the current world is raining (no thunderstorm).",
|
||||
Notes = "Returns true if the current weather is rainy.",
|
||||
},
|
||||
IsWeatherRainAt =
|
||||
{
|
||||
@ -2258,7 +2258,7 @@ function OnAllChunksAvailable()</pre> All return values from the callbacks are i
|
||||
Type = "boolean",
|
||||
},
|
||||
},
|
||||
Notes = "Returns true if the specified location is raining (takes biomes into account - it never rains in a desert).",
|
||||
Notes = "Returns true if it is rainy at the specified location. This takes into account biomes.",
|
||||
},
|
||||
IsWeatherStorm =
|
||||
{
|
||||
@ -2268,7 +2268,7 @@ function OnAllChunksAvailable()</pre> All return values from the callbacks are i
|
||||
Type = "boolean",
|
||||
},
|
||||
},
|
||||
Notes = "Returns true if the current world is stormy.",
|
||||
Notes = "Returns true if the current weather is stormy.",
|
||||
},
|
||||
IsWeatherStormAt =
|
||||
{
|
||||
@ -2289,7 +2289,7 @@ function OnAllChunksAvailable()</pre> All return values from the callbacks are i
|
||||
Type = "boolean",
|
||||
},
|
||||
},
|
||||
Notes = "Returns true if the specified location is stormy (takes biomes into account - no storm in a desert).",
|
||||
Notes = "Returns true if it is stormy at the specified location. This takes into account biomes.",
|
||||
},
|
||||
IsWeatherSunny =
|
||||
{
|
||||
@ -2320,7 +2320,7 @@ function OnAllChunksAvailable()</pre> All return values from the callbacks are i
|
||||
Type = "boolean",
|
||||
},
|
||||
},
|
||||
Notes = "Returns true if the current weather is sunny at the specified location (takes into account biomes).",
|
||||
Notes = "Returns true if it is sunny at the specified location. This takes into account biomes.",
|
||||
},
|
||||
IsWeatherWet =
|
||||
{
|
||||
@ -2330,7 +2330,7 @@ function OnAllChunksAvailable()</pre> All return values from the callbacks are i
|
||||
Type = "boolean",
|
||||
},
|
||||
},
|
||||
Notes = "Returns true if the current world has any precipitation (rain or storm).",
|
||||
Notes = "Returns true if the world currently has any precipitation - rain, storm or snow.",
|
||||
},
|
||||
IsWeatherWetAt =
|
||||
{
|
||||
@ -2351,7 +2351,24 @@ function OnAllChunksAvailable()</pre> All return values from the callbacks are i
|
||||
Type = "boolean",
|
||||
},
|
||||
},
|
||||
Notes = "Returns true if the specified location has any precipitation (rain or storm) (takes biomes into account, deserts are never wet).",
|
||||
Notes = "Returns true if it is raining or storming at the specified location. This takes into account biomes.",
|
||||
},
|
||||
IsWeatherWetAtXYZ =
|
||||
{
|
||||
Params =
|
||||
{
|
||||
{
|
||||
Name = "Pos",
|
||||
Type = "Vector3i",
|
||||
},
|
||||
},
|
||||
Returns =
|
||||
{
|
||||
{
|
||||
Type = "boolean",
|
||||
},
|
||||
},
|
||||
Notes = "Returns true if the specified location has wet weather (rain or storm), using the same logic as IsWeatherWetAt, except that any rain-blocking blocks above the specified position will block the precipitation and this function will return false.",
|
||||
},
|
||||
PrepareChunk =
|
||||
{
|
||||
@ -3637,4 +3654,3 @@ World:ForEachEntity(
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -464,6 +464,16 @@ cBlockInfo::cBlockInfoArray::cBlockInfoArray()
|
||||
Info[E_BLOCK_YELLOW_SHULKER_BOX ].m_PistonBreakable = true;
|
||||
|
||||
|
||||
/* Blocks that block rain or snow's passage:
|
||||
* All solid blocks are also rain blockers, and they are set automatically
|
||||
* at the end of this function.
|
||||
*/
|
||||
Info[E_BLOCK_SIGN_POST ].m_IsRainBlocker = true;
|
||||
Info[E_BLOCK_WALLSIGN ].m_IsRainBlocker = true;
|
||||
Info[E_BLOCK_WALL_BANNER ].m_IsRainBlocker = true;
|
||||
Info[E_BLOCK_STANDING_BANNER ].m_IsRainBlocker = true;
|
||||
|
||||
|
||||
// Blocks that can be snowed over:
|
||||
Info[E_BLOCK_BEDROCK ].m_IsSnowable = true;
|
||||
Info[E_BLOCK_BLOCK_OF_COAL ].m_IsSnowable = true;
|
||||
@ -554,8 +564,8 @@ cBlockInfo::cBlockInfoArray::cBlockInfoArray()
|
||||
Info[E_BLOCK_BIG_FLOWER ].m_IsSolid = false;
|
||||
Info[E_BLOCK_BROWN_MUSHROOM ].m_IsSolid = false;
|
||||
Info[E_BLOCK_CARROTS ].m_IsSolid = false;
|
||||
Info[E_BLOCK_CHORUS_PLANT ].m_IsSolid = false;
|
||||
Info[E_BLOCK_CHORUS_FLOWER ].m_IsSolid = false;
|
||||
Info[E_BLOCK_CHORUS_PLANT ].m_IsSolid = false;
|
||||
Info[E_BLOCK_COBWEB ].m_IsSolid = false;
|
||||
Info[E_BLOCK_CROPS ].m_IsSolid = false;
|
||||
Info[E_BLOCK_DANDELION ].m_IsSolid = false;
|
||||
@ -575,17 +585,17 @@ cBlockInfo::cBlockInfoArray::cBlockInfoArray()
|
||||
Info[E_BLOCK_POTATOES ].m_IsSolid = false;
|
||||
Info[E_BLOCK_POWERED_RAIL ].m_IsSolid = false;
|
||||
Info[E_BLOCK_RAIL ].m_IsSolid = false;
|
||||
Info[E_BLOCK_RED_MUSHROOM ].m_IsSolid = false;
|
||||
Info[E_BLOCK_REDSTONE_TORCH_OFF ].m_IsSolid = false;
|
||||
Info[E_BLOCK_REDSTONE_TORCH_ON ].m_IsSolid = false;
|
||||
Info[E_BLOCK_REDSTONE_WIRE ].m_IsSolid = false;
|
||||
Info[E_BLOCK_RED_MUSHROOM ].m_IsSolid = false;
|
||||
Info[E_BLOCK_REEDS ].m_IsSolid = false;
|
||||
Info[E_BLOCK_SAPLING ].m_IsSolid = false;
|
||||
Info[E_BLOCK_SIGN_POST ].m_IsSolid = false;
|
||||
Info[E_BLOCK_SNOW ].m_IsSolid = false;
|
||||
Info[E_BLOCK_STANDING_BANNER ].m_IsSolid = false;
|
||||
Info[E_BLOCK_STATIONARY_LAVA ].m_IsSolid = false;
|
||||
Info[E_BLOCK_STATIONARY_WATER ].m_IsSolid = false;
|
||||
Info[E_BLOCK_STANDING_BANNER ].m_IsSolid = false;
|
||||
Info[E_BLOCK_STONE_BUTTON ].m_IsSolid = false;
|
||||
Info[E_BLOCK_STONE_PRESSURE_PLATE ].m_IsSolid = false;
|
||||
Info[E_BLOCK_TALL_GRASS ].m_IsSolid = false;
|
||||
@ -974,8 +984,9 @@ cBlockInfo::cBlockInfoArray::cBlockInfoArray()
|
||||
Info[E_BLOCK_RED_SHULKER_BOX ].m_Hardness = 0.2f;
|
||||
Info[E_BLOCK_BLACK_SHULKER_BOX ].m_Hardness = 0.2f;
|
||||
Info[E_BLOCK_STRUCTURE_BLOCK ].m_Hardness = -1.0f;
|
||||
|
||||
for (size_t i = 0; i < Info.size(); ++i)
|
||||
{
|
||||
Info[i].m_IsRainBlocker |= Info[i].m_IsSolid;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -37,7 +37,10 @@ public:
|
||||
/** Can a piston break this block? */
|
||||
bool m_PistonBreakable;
|
||||
|
||||
/** Does a block disperse sky light? (only relevant for transparent blocks) */
|
||||
/** Does this block block the passage of rain? */
|
||||
bool m_IsRainBlocker;
|
||||
|
||||
/** Does this block disperse sky light? (only relevant for transparent blocks) */
|
||||
bool m_IsSkylightDispersant;
|
||||
|
||||
/** Can this block hold snow atop? */
|
||||
@ -79,6 +82,7 @@ public:
|
||||
inline static bool IsTransparent (BLOCKTYPE a_Type) { return Get(a_Type).m_Transparent; }
|
||||
inline static bool IsOneHitDig (BLOCKTYPE a_Type) { return Get(a_Type).m_OneHitDig; }
|
||||
inline static bool IsPistonBreakable (BLOCKTYPE a_Type) { return Get(a_Type).m_PistonBreakable; }
|
||||
inline static bool IsRainBlocker (BLOCKTYPE a_Type) { return Get(a_Type).m_IsRainBlocker; }
|
||||
inline static bool IsSkylightDispersant (BLOCKTYPE a_Type)
|
||||
{
|
||||
return ((Get(a_Type).m_IsSkylightDispersant) || (Get(a_Type).m_SpreadLightFalloff > 1));
|
||||
@ -102,6 +106,7 @@ public:
|
||||
, m_Transparent(false)
|
||||
, m_OneHitDig(false)
|
||||
, m_PistonBreakable(false)
|
||||
, m_IsRainBlocker(false)
|
||||
, m_IsSkylightDispersant(false)
|
||||
, m_IsSnowable(false)
|
||||
, m_IsSolid(true)
|
||||
@ -149,7 +154,3 @@ inline cBlockHandler * BlockHandler(BLOCKTYPE a_BlockType)
|
||||
{
|
||||
return cBlockInfo::Get(a_BlockType).m_Handler.get();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -65,7 +65,7 @@ public:
|
||||
|
||||
virtual void SetTimeOfDay(int a_TimeOfDay) = 0;
|
||||
|
||||
/** Returns true if it is raining, stormy or snowing at the specified location. This takes into account biomes. */
|
||||
/** 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) = 0;
|
||||
|
||||
/** Returns or sets the minumim or maximum netherportal width */
|
||||
|
@ -1172,12 +1172,9 @@ void cEntity::TickBurning(cChunk & a_Chunk)
|
||||
}
|
||||
|
||||
// Fire is extinguished by rain
|
||||
if (GetWorld()->IsWeatherWetAt(POSX_TOINT, POSZ_TOINT))
|
||||
if (GetWorld()->IsWeatherWetAtXYZ(GetPosition().Floor()))
|
||||
{
|
||||
if (POSY_TOINT > m_World->GetHeight(POSX_TOINT, POSZ_TOINT))
|
||||
{
|
||||
m_TicksLeftBurning = 0;
|
||||
}
|
||||
m_TicksLeftBurning = 0;
|
||||
}
|
||||
|
||||
// Do the burning damage:
|
||||
|
@ -194,37 +194,13 @@ void cEnderman::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
|
||||
}
|
||||
|
||||
// Take damage when touching water, drowning damage seems to be most appropriate
|
||||
if (CheckRain() || IsSwimming())
|
||||
if (
|
||||
cChunkDef::IsValidHeight(POSY_TOINT) &&
|
||||
(GetWorld()->IsWeatherWetAtXYZ(GetPosition().Floor()) || IsSwimming())
|
||||
)
|
||||
{
|
||||
EventLosePlayer();
|
||||
TakeDamage(dtDrowning, nullptr, 1, 0);
|
||||
// TODO teleport to a safe location
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cEnderman::CheckRain(void)
|
||||
{
|
||||
if (!GetWorld()->IsWeatherRain())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Vector3d coords = GetPosition();
|
||||
for (int Y = static_cast<int>(coords.y); Y < cChunkDef::Height; ++Y)
|
||||
{
|
||||
BLOCKTYPE Block = m_World->GetBlock(static_cast<int>(coords.x), Y, static_cast<int>(coords.z));
|
||||
if (Block != E_BLOCK_AIR)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -29,8 +29,6 @@ public:
|
||||
|
||||
/** Returns if the current sky light level is sufficient for the enderman to become aggravated */
|
||||
bool CheckLight(void);
|
||||
/** Returns if the enderman gets hit by the rain */
|
||||
bool CheckRain(void);
|
||||
|
||||
private:
|
||||
|
||||
@ -39,7 +37,3 @@ private:
|
||||
NIBBLETYPE CarriedMeta;
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -29,7 +29,6 @@ SET (HDRS
|
||||
VaporizeFluidSimulator.h
|
||||
)
|
||||
|
||||
|
||||
if(NOT MSVC)
|
||||
add_library(Simulator ${SRCS} ${HDRS})
|
||||
endif()
|
||||
|
@ -25,15 +25,22 @@
|
||||
|
||||
#define MAX_CHANCE_REPLACE_FUEL 100000
|
||||
#define MAX_CHANCE_FLAMMABILITY 100000
|
||||
// The base chance that in a tick, rain will extinguish a fire block.
|
||||
#define CHANCE_BASE_RAIN_EXTINGUISH 0.2
|
||||
// The additional chance, multiplied by the meta of the fire block, that rain
|
||||
// will extinguish a fire block in a tick.
|
||||
#define CHANCE_AGE_M_RAIN_EXTINGUISH 0.03
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static const struct
|
||||
{
|
||||
int x, y, z;
|
||||
} gCrossCoords[] =
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wglobal-constructors"
|
||||
#endif
|
||||
|
||||
static const Vector3i gCrossCoords[] =
|
||||
{
|
||||
{ 1, 0, 0},
|
||||
{-1, 0, 0},
|
||||
@ -45,10 +52,7 @@ static const struct
|
||||
|
||||
|
||||
|
||||
static const struct
|
||||
{
|
||||
int x, y, z;
|
||||
} gNeighborCoords[] =
|
||||
static const Vector3i gNeighborCoords[] =
|
||||
{
|
||||
{ 1, 0, 0},
|
||||
{-1, 0, 0},
|
||||
@ -58,6 +62,10 @@ static const struct
|
||||
{ 0, 0, -1},
|
||||
} ;
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
@ -97,20 +105,39 @@ void cFireSimulator::SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX,
|
||||
int x = itr->x;
|
||||
int y = itr->y;
|
||||
int z = itr->z;
|
||||
auto AbsPos = cChunkDef::RelativeToAbsolute({x, y, z}, a_Chunk->GetPosX(), a_Chunk->GetPosZ());
|
||||
BLOCKTYPE BlockType = a_Chunk->GetBlock(x, y, z);
|
||||
|
||||
if (!IsAllowedBlock(BlockType))
|
||||
{
|
||||
// The block is no longer eligible (not a fire block anymore; a player probably placed a block over the fire)
|
||||
FLOG("FS: Removing block {%d, %d, %d}",
|
||||
itr->x + a_ChunkX * cChunkDef::Width, itr->y, itr->z + a_ChunkZ * cChunkDef::Width
|
||||
AbsPos.x, AbsPos.y, AbsPos.z
|
||||
);
|
||||
itr = Data.erase(itr);
|
||||
continue;
|
||||
}
|
||||
|
||||
auto BurnsForever = ((y > 0) && DoesBurnForever(a_Chunk->GetBlock(x, (y - 1), z)));
|
||||
auto BlockMeta = a_Chunk->GetMeta(x, y, z);
|
||||
|
||||
auto Raining = std::any_of(std::begin(gCrossCoords), std::end(gCrossCoords),
|
||||
[this, AbsPos](Vector3i cc)
|
||||
{
|
||||
return (m_World.IsWeatherWetAtXYZ(AbsPos + cc));
|
||||
}
|
||||
);
|
||||
|
||||
// Randomly burn out the fire if it is raining:
|
||||
if (!BurnsForever && Raining && GetRandomProvider().RandBool(CHANCE_BASE_RAIN_EXTINGUISH + (BlockMeta * CHANCE_AGE_M_RAIN_EXTINGUISH)))
|
||||
{
|
||||
a_Chunk->SetBlock(x, y, z, E_BLOCK_AIR, 0);
|
||||
itr = Data.erase(itr);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Try to spread the fire:
|
||||
TrySpreadFire(a_Chunk, itr->x, itr->y, itr->z);
|
||||
TrySpreadFire(a_Chunk, x, y, z);
|
||||
|
||||
itr->Data -= NumMSecs;
|
||||
if (itr->Data >= 0)
|
||||
@ -120,30 +147,30 @@ void cFireSimulator::SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX,
|
||||
continue;
|
||||
}
|
||||
|
||||
// Burn out the fire one step by increasing the meta:
|
||||
/*
|
||||
FLOG("FS: Fire at {%d, %d, %d} is stepping",
|
||||
itr->x + a_ChunkX * cChunkDef::Width, itr->y, itr->z + a_ChunkZ * cChunkDef::Width
|
||||
);
|
||||
*/
|
||||
NIBBLETYPE BlockMeta = a_Chunk->GetMeta(x, y, z);
|
||||
// Has the fire burnt out?
|
||||
if (BlockMeta == 0x0f)
|
||||
{
|
||||
// The fire burnt out completely
|
||||
FLOG("FS: Fire at {%d, %d, %d} burnt out, removing the fire block",
|
||||
itr->x + a_ChunkX * cChunkDef::Width, itr->y, itr->z + a_ChunkZ * cChunkDef::Width
|
||||
);
|
||||
a_Chunk->SetBlock(itr->x, itr->y, itr->z, E_BLOCK_AIR, 0);
|
||||
RemoveFuelNeighbors(a_Chunk, itr->x, itr->y, itr->z);
|
||||
a_Chunk->SetBlock(x, y, z, E_BLOCK_AIR, 0);
|
||||
RemoveFuelNeighbors(a_Chunk, x, y, z);
|
||||
itr = Data.erase(itr);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((itr->y > 0) && (!DoesBurnForever(a_Chunk->GetBlock(itr->x, itr->y - 1, itr->z))))
|
||||
// Burn out the fire one step by increasing the meta:
|
||||
if (!BurnsForever)
|
||||
{
|
||||
a_Chunk->SetMeta(x, y, z, BlockMeta + 1);
|
||||
}
|
||||
itr->Data = GetBurnStepTime(a_Chunk, itr->x, itr->y, itr->z); // TODO: Add some randomness into this
|
||||
|
||||
itr->Data = GetBurnStepTime(a_Chunk, x, y, z); // TODO: Add some randomness into this
|
||||
++itr;
|
||||
} // for itr - Data[]
|
||||
}
|
||||
@ -283,7 +310,7 @@ int cFireSimulator::GetBurnStepTime(cChunk * a_Chunk, int a_RelX, int a_RelY, in
|
||||
}
|
||||
} // for i - gCrossCoords[]
|
||||
|
||||
if (!IsBlockBelowSolid && (a_RelY >= 0))
|
||||
if (!IsBlockBelowSolid)
|
||||
{
|
||||
// Checked through everything, nothing was flammable
|
||||
// If block below isn't solid, we can't have fire, it would be a non-fueled fire
|
||||
@ -427,7 +454,3 @@ bool cFireSimulator::CanStartFireInBlock(cChunk * a_NearChunk, int a_RelX, int a
|
||||
} // for i - Coords[]
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -542,6 +542,34 @@ void cWorld::ChangeWeather(void)
|
||||
|
||||
|
||||
|
||||
bool cWorld::IsWeatherWetAtXYZ(Vector3i a_Pos)
|
||||
{
|
||||
if ((a_Pos.y < 0) || !IsWeatherWetAt(a_Pos.x, a_Pos.z))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cWorld::SetNextBlockTick(int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||
{
|
||||
return m_ChunkMap->SetNextBlockTick(a_BlockX, a_BlockY, a_BlockZ);
|
||||
|
24
src/World.h
24
src/World.h
@ -766,7 +766,7 @@ public:
|
||||
/** Returns the current weather. Instead of comparing values directly to the weather constants, use IsWeatherXXX() functions, if possible */
|
||||
eWeather GetWeather(void) const { return m_Weather; }
|
||||
|
||||
/** Returns true if the current weather is sun */
|
||||
/** Returns true if the current weather is sunny. */
|
||||
bool IsWeatherSunny(void) const { return (m_Weather == wSunny); }
|
||||
|
||||
/** Returns true if it is sunny at the specified location. This takes into account biomes. */
|
||||
@ -775,7 +775,7 @@ public:
|
||||
return (IsWeatherSunny() || IsBiomeNoDownfall(GetBiomeAt(a_BlockX, a_BlockZ)));
|
||||
}
|
||||
|
||||
/** Returns true if the current weather is rain */
|
||||
/** Returns true if the current weather is rainy. */
|
||||
bool IsWeatherRain(void) const { return (m_Weather == wRain); }
|
||||
|
||||
/** Returns true if it is raining at the specified location. This takes into account biomes. */
|
||||
@ -784,7 +784,7 @@ public:
|
||||
return (IsWeatherRain() && !IsBiomeNoDownfall(GetBiomeAt(a_BlockX, a_BlockZ)));
|
||||
}
|
||||
|
||||
/** Returns true if the current weather is stormy */
|
||||
/** Returns true if the current weather is stormy. */
|
||||
bool IsWeatherStorm(void) const { return (m_Weather == wStorm); }
|
||||
|
||||
/** Returns true if the weather is stormy at the specified location. This takes into account biomes. */
|
||||
@ -793,15 +793,23 @@ public:
|
||||
return (IsWeatherStorm() && !IsBiomeNoDownfall(GetBiomeAt(a_BlockX, a_BlockZ)));
|
||||
}
|
||||
|
||||
/** Returns true if the current weather has any precipitation - rain, storm or snow */
|
||||
/** Returns true if the world currently has any precipitation - rain, storm or snow. */
|
||||
bool IsWeatherWet(void) const { return !IsWeatherSunny(); }
|
||||
|
||||
/** Returns true if it is raining, stormy or snowing at the specified location. This takes into account biomes. */
|
||||
/** 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
|
||||
{
|
||||
return (IsWeatherWet() && !IsBiomeNoDownfall(GetBiomeAt(a_BlockX, a_BlockZ)));
|
||||
auto Biome = GetBiomeAt(a_BlockX, a_BlockZ);
|
||||
return (IsWeatherWet() && !IsBiomeNoDownfall(Biome) && !IsBiomeCold(Biome));
|
||||
}
|
||||
|
||||
/** Returns true if the specified location has wet weather (rain or storm),
|
||||
using the same logic as IsWeatherWetAt, except that any rain-blocking blocks
|
||||
above the specified position will block the precipitation and this function
|
||||
will return false. */
|
||||
virtual bool IsWeatherWetAtXYZ(Vector3i a_Pos);
|
||||
|
||||
/** Returns the seed of the world. */
|
||||
int GetSeed(void) { return m_Generator.GetSeed(); }
|
||||
|
||||
@ -1129,7 +1137,3 @@ private:
|
||||
void SetChunkData(cSetChunkData & a_SetChunkData);
|
||||
|
||||
}; // tolua_export
|
||||
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user