mirror of
https://github.com/cuberite/cuberite.git
synced 2025-01-07 03:16:55 +08:00
Refactor sapling growth handler
Remove old code and combine growth logic to single function
This commit is contained in:
parent
52d5760be1
commit
885fa6bb0f
@ -45,25 +45,10 @@ public:
|
||||
|
||||
virtual void OnUpdate(cChunkInterface & cChunkInterface, cWorldInterface & a_WorldInterface, cBlockPluginInterface & a_PluginInterface, cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ) override
|
||||
{
|
||||
NIBBLETYPE Meta = a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ);
|
||||
NIBBLETYPE Light = std::max(a_Chunk.GetBlockLight(a_RelX, a_RelY, a_RelZ), a_Chunk.GetTimeAlteredLight(a_Chunk.GetSkyLight(a_RelX, a_RelY, a_RelZ)));
|
||||
|
||||
// Only grow if we have the right amount of light
|
||||
if (Light > 8)
|
||||
if ((a_Chunk.GetLightAltered(Vector3i(a_RelX, a_RelY, a_RelZ)) > 8) && GetRandomProvider().RandBool(0.45))
|
||||
{
|
||||
auto & random = GetRandomProvider();
|
||||
// Only grow if we are in the right growth stage and have the right amount of space around them.
|
||||
if (((Meta & 0x08) != 0) && random.RandBool(0.45) && CanGrowAt(a_Chunk, a_RelX, a_RelY, a_RelZ, Meta))
|
||||
{
|
||||
int BlockX = a_RelX + a_Chunk.GetPosX() * cChunkDef::Width;
|
||||
int BlockZ = a_RelZ + a_Chunk.GetPosZ() * cChunkDef::Width;
|
||||
a_Chunk.GetWorld()->GrowTree(BlockX, a_RelY, BlockZ);
|
||||
}
|
||||
// Only move to the next growth stage if we haven't gone there yet
|
||||
else if (((Meta & 0x08) == 0) && random.RandBool(0.45))
|
||||
{
|
||||
a_Chunk.SetMeta(a_RelX, a_RelY, a_RelZ, Meta | 0x08);
|
||||
}
|
||||
Grow(a_Chunk, Vector3i(a_RelX, a_RelY, a_RelZ));
|
||||
}
|
||||
}
|
||||
|
||||
@ -71,120 +56,6 @@ public:
|
||||
|
||||
|
||||
|
||||
bool CanGrowAt(cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_Meta)
|
||||
{
|
||||
a_Meta = a_Meta & 0x07;
|
||||
int CheckHeight = 0;
|
||||
bool LargeTree = false;
|
||||
|
||||
// Get the height to check against
|
||||
switch (a_Meta)
|
||||
{
|
||||
case E_META_SAPLING_APPLE:
|
||||
{
|
||||
CheckHeight = 5;
|
||||
break;
|
||||
}
|
||||
case E_META_SAPLING_CONIFER:
|
||||
{
|
||||
CheckHeight = 7;
|
||||
if (IsLargeTree(a_Chunk, a_RelX, a_RelY, a_RelZ, a_Meta))
|
||||
{
|
||||
CheckHeight = 16;
|
||||
LargeTree = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case E_META_SAPLING_BIRCH:
|
||||
{
|
||||
CheckHeight = 6;
|
||||
break;
|
||||
}
|
||||
case E_META_SAPLING_JUNGLE:
|
||||
{
|
||||
CheckHeight = 7;
|
||||
if (IsLargeTree(a_Chunk, a_RelX, a_RelY, a_RelZ, a_Meta))
|
||||
{
|
||||
CheckHeight = 13;
|
||||
LargeTree = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
// Acacias don't need horizontal clearance
|
||||
case E_META_SAPLING_ACACIA:
|
||||
{
|
||||
if (!IsLargeTree(a_Chunk, a_RelX, a_RelY, a_RelZ, a_Meta))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
CheckHeight = 7;
|
||||
LargeTree = true;
|
||||
break;
|
||||
}
|
||||
// Dark Oaks don't need horizontal clearance
|
||||
case E_META_SAPLING_DARK_OAK:
|
||||
{
|
||||
if (!IsLargeTree(a_Chunk, a_RelX, a_RelY, a_RelZ, a_Meta))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
CheckHeight = 7;
|
||||
LargeTree = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// We should always get a valid CheckHeight
|
||||
ASSERT(CheckHeight != 0);
|
||||
|
||||
// Don't grow a tree if we don't have enough space left above it in the chunk
|
||||
if ((a_RelY + CheckHeight) > cChunkDef::Height)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
bool CanGrow = true;
|
||||
|
||||
// Validate the neighbor blocks. They cannot be solid.
|
||||
BLOCKTYPE check = E_BLOCK_AIR;
|
||||
a_Chunk.UnboundedRelGetBlockType(a_RelX - 1, a_RelY, a_RelZ, check);
|
||||
CanGrow = CanGrow && cBlockInfo::IsTransparent(check);
|
||||
|
||||
a_Chunk.UnboundedRelGetBlockType(a_RelX + 1, a_RelY, a_RelZ, check);
|
||||
CanGrow = CanGrow && cBlockInfo::IsTransparent(check);
|
||||
|
||||
a_Chunk.UnboundedRelGetBlockType(a_RelX, a_RelY, a_RelZ - 1, check);
|
||||
CanGrow = CanGrow && cBlockInfo::IsTransparent(check);
|
||||
|
||||
a_Chunk.UnboundedRelGetBlockType(a_RelX, a_RelY, a_RelZ + 1, check);
|
||||
CanGrow = CanGrow && cBlockInfo::IsTransparent(check);
|
||||
|
||||
while (CheckHeight && CanGrow)
|
||||
{
|
||||
check = a_Chunk.GetBlock(a_RelX, a_RelY + CheckHeight, a_RelZ);
|
||||
CanGrow = CanGrow && ((check == E_BLOCK_AIR) || (check == E_BLOCK_LEAVES));
|
||||
|
||||
// We have to check above the neighboring saplings as well
|
||||
if (LargeTree)
|
||||
{
|
||||
a_Chunk.UnboundedRelGetBlockType(a_RelX + 1, a_RelY + CheckHeight, a_RelZ, check);
|
||||
CanGrow = CanGrow && ((check == E_BLOCK_AIR) || (check == E_BLOCK_LEAVES));
|
||||
|
||||
a_Chunk.UnboundedRelGetBlockType(a_RelX, a_RelY + CheckHeight, a_RelZ + 1, check);
|
||||
CanGrow = CanGrow && ((check == E_BLOCK_AIR) || (check == E_BLOCK_LEAVES));
|
||||
|
||||
a_Chunk.UnboundedRelGetBlockType(a_RelX + 1, a_RelY + CheckHeight, a_RelZ + 1, check);
|
||||
CanGrow = CanGrow && ((check == E_BLOCK_AIR) || (check == E_BLOCK_LEAVES));
|
||||
}
|
||||
|
||||
--CheckHeight;
|
||||
}
|
||||
|
||||
return CanGrow;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
virtual int Grow(cChunk & a_Chunk, Vector3i a_RelPos, int a_NumStages = 1) override
|
||||
{
|
||||
auto blockMeta = a_Chunk.GetMeta(a_RelPos);
|
||||
|
Loading…
Reference in New Issue
Block a user