1
0

Changed tree-growing functions in cWorld to use Vector3i coords.

This commit is contained in:
Mattes D 2020-08-26 14:08:37 +02:00 committed by Tiger Wang
parent 0e3039d44c
commit c98a2d9acf
5 changed files with 176 additions and 90 deletions

View File

@ -2178,7 +2178,7 @@ function OnAllChunksAvailable()</pre> All return values from the callbacks are i
{
{
Name = "BlockPos",
Type = "number",
Type = "Vector3i",
},
},
Returns =
@ -2224,16 +2224,8 @@ function OnAllChunksAvailable()</pre> All return values from the callbacks are i
Params =
{
{
Name = "BlockX",
Type = "number",
},
{
Name = "BlockY",
Type = "number",
},
{
Name = "BlockZ",
Type = "number",
Name = "BlockPos",
Type = "Vector3i",
},
},
Notes = "Grows a tree based at the specified coords. If there is a sapling there, grows the tree based on that sapling, otherwise chooses a tree image based on the biome.",
@ -2243,16 +2235,8 @@ function OnAllChunksAvailable()</pre> All return values from the callbacks are i
Params =
{
{
Name = "BlockX",
Type = "number",
},
{
Name = "BlockY",
Type = "number",
},
{
Name = "BlockZ",
Type = "number",
Name = "BlockPos",
Type = "Vector3i",
},
},
Notes = "Grows a tree based at the specified coords. The tree type is picked from types available for the biome at those coords.",
@ -2262,23 +2246,11 @@ function OnAllChunksAvailable()</pre> All return values from the callbacks are i
Params =
{
{
Name = "BlockX",
Type = "number",
},
{
Name = "BlockY",
Type = "number",
},
{
Name = "BlockZ",
Type = "number",
},
{
Name = "SaplingMeta",
Type = "number",
Name = "BlockPos",
Type = "Vector3i",
},
},
Notes = "Grows a tree based at the specified coords. The tree type is determined from the sapling meta (the sapling itself needn't be present).",
Notes = "Grows a tree based at the specified coords. The tree type is determined from the sapling meta. If the sapling is part of a 2x2 sapling area, grows a large tree.",
},
IsBlockDirectlyWatered =
{

View File

@ -518,6 +518,120 @@ static int tolua_cWorld_SetSignLines(lua_State * tolua_S)
/** Function: cWorld:GrowTree.
Exported manually because of the obsolete int-based overload.
When removing from DeprecatedBindings, make sure the function is exported automatically. */
static int tolua_cWorld_GrowTree(lua_State * a_LuaState)
{
cLuaState LuaState(a_LuaState);
if (lua_isnumber(LuaState, 2))
{
// This is the obsolete signature, warn and translate:
LOGWARNING("Warning: cWorld:GrowTree function expects Vector3i-based coords rather than int-based coords. Emulating old-style call.");
LuaState.LogStackTrace(0);
cWorld * Self = nullptr;
int BlockX, BlockY, BlockZ;
if (!LuaState.GetStackValues(1, Self, BlockX, BlockY, BlockZ))
{
return LuaState.ApiParamError("Failed to read int-based coord parameters");
}
LuaState.Push(Self->GrowTree({BlockX, BlockY, BlockZ}));
return 1;
}
// This is the correct signature, execute:
cWorld * Self = nullptr;
Vector3i BlockPos;
if (!LuaState.GetStackValues(1, Self, BlockPos))
{
return LuaState.ApiParamError("Failed to read Vector3i-based coord parameters");
}
LuaState.Push(Self->GrowTree(BlockPos));
return 1;
}
/** Function: cWorld:GrowTreeByBiome.
Exported manually because of the obsolete int-based overload.
When removing from DeprecatedBindings, make sure the function is exported automatically. */
static int tolua_cWorld_GrowTreeByBiome(lua_State * a_LuaState)
{
cLuaState LuaState(a_LuaState);
if (lua_isnumber(LuaState, 2))
{
// This is the obsolete signature, warn and translate:
LOGWARNING("Warning: cWorld:GrowTreeByBiome function expects Vector3i-based coords rather than int-based coords. Emulating old-style call.");
LuaState.LogStackTrace(0);
cWorld * Self = nullptr;
int BlockX, BlockY, BlockZ;
if (!LuaState.GetStackValues(1, Self, BlockX, BlockY, BlockZ))
{
return LuaState.ApiParamError("Failed to read int-based coord parameters");
}
LuaState.Push(Self->GrowTreeByBiome({BlockX, BlockY, BlockZ}));
return 1;
}
// This is the correct signature, execute:
cWorld * Self = nullptr;
Vector3i BlockPos;
if (!LuaState.GetStackValues(1, Self, BlockPos))
{
return LuaState.ApiParamError("Failed to read Vector3i-based coord parameters");
}
LuaState.Push(Self->GrowTreeByBiome(BlockPos));
return 1;
}
/** Function: cWorld:GrowTreeFromSapling.
Exported manually because of the obsolete int-based overload and obsolete SaplingMeta parameter.
When removing from DeprecatedBindings, make sure the function is exported automatically. */
static int tolua_cWorld_GrowTreeFromSapling(lua_State * a_LuaState)
{
cLuaState LuaState(a_LuaState);
if (lua_isnumber(LuaState, 2))
{
// This is the obsolete signature, warn and translate:
LOGWARNING("Warning: cWorld:GrowTreeFromSapling function expects Vector3i-based coords rather than int-based coords. Emulating old-style call.");
LuaState.LogStackTrace(0);
cWorld * Self = nullptr;
int BlockX, BlockY, BlockZ;
if (!LuaState.GetStackValues(1, Self, BlockX, BlockY, BlockZ))
{
return LuaState.ApiParamError("Failed to read int-based coord parameters");
}
LuaState.Push(Self->GrowTreeFromSapling({BlockX, BlockY, BlockZ}));
return 1;
}
// This is the correct signature, execute:
cWorld * Self = nullptr;
Vector3i BlockPos;
if (!LuaState.GetStackValues(1, Self, BlockPos))
{
return LuaState.ApiParamError("Failed to read Vector3i-based coord parameters");
}
if (lua_isnumber(LuaState, 3))
{
// There's an extra parameter, the obsolete SaplingMeta
LOGWARNING("Warning: cWorld:GrowTreeFromSapling function no longer has the SaplingMeta parameter. Ignoring it now.");
LuaState.LogStackTrace(0);
}
LuaState.Push(Self->GrowTreeFromSapling(BlockPos));
return 1;
}
/** function: cWorld:SetNextBlockTick */
static int tolua_cWorld_SetNextBlockTick(lua_State * tolua_S)
{
@ -595,6 +709,9 @@ void DeprecatedBindings::Bind(lua_State * tolua_S)
tolua_endmodule(tolua_S);
tolua_beginmodule(tolua_S, "cWorld");
tolua_function(tolua_S, "GrowTree", tolua_cWorld_GrowTree);
tolua_function(tolua_S, "GrowTreeByBiome", tolua_cWorld_GrowTreeByBiome);
tolua_function(tolua_S, "GrowTreeFromSapling", tolua_cWorld_GrowTreeFromSapling);
tolua_function(tolua_S, "SetNextBlockTick", tolua_cWorld_SetNextBlockTick);
tolua_function(tolua_S, "UpdateSign", tolua_cWorld_SetSignLines);
tolua_endmodule(tolua_S);

View File

@ -62,7 +62,7 @@ public:
if (((Meta & 0x08) != 0) && random.RandBool(0.45) && CanGrowAt(a_Chunk, a_RelPos.x, a_RelPos.y, a_RelPos.z, Meta))
{
auto WorldPos = a_Chunk.RelativeToAbsolute(a_RelPos);
a_Chunk.GetWorld()->GrowTree(WorldPos.x, WorldPos.y, WorldPos.z);
a_Chunk.GetWorld()->GrowTree(WorldPos);
}
// Only move to the next growth stage if we haven't gone there yet
else if (((Meta & 0x08) == 0) && random.RandBool(0.45))
@ -211,7 +211,7 @@ public:
}
// The sapling is grown, now it becomes a tree:
a_Chunk.GetWorld()->GrowTreeFromSapling(a_Chunk.RelativeToAbsolute(a_RelPos), blockMeta);
a_Chunk.GetWorld()->GrowTreeFromSapling(a_Chunk.RelativeToAbsolute(a_RelPos));
return res + 1;
}

View File

@ -1599,17 +1599,17 @@ bool cWorld::DoWithChunkAt(Vector3i a_BlockPos, cChunkCallback a_Callback)
bool cWorld::GrowTree(int a_X, int a_Y, int a_Z)
bool cWorld::GrowTree(const Vector3i a_BlockPos)
{
if (GetBlock(a_X, a_Y, a_Z) == E_BLOCK_SAPLING)
if (GetBlock(a_BlockPos) == E_BLOCK_SAPLING)
{
// There is a sapling here, grow a tree according to its type:
return GrowTreeFromSapling(a_X, a_Y, a_Z, GetBlockMeta(a_X, a_Y, a_Z));
return GrowTreeFromSapling(a_BlockPos);
}
else
{
// There is nothing here, grow a tree based on the current biome here:
return GrowTreeByBiome(a_X, a_Y, a_Z);
return GrowTreeByBiome(a_BlockPos);
}
}
@ -1617,36 +1617,37 @@ bool cWorld::GrowTree(int a_X, int a_Y, int a_Z)
bool cWorld::GrowTreeFromSapling(int a_X, int a_Y, int a_Z, NIBBLETYPE a_SaplingMeta)
bool cWorld::GrowTreeFromSapling(Vector3i a_BlockPos)
{
cNoise Noise(m_Generator.GetSeed());
sSetBlockVector Logs, Other;
auto WorldAge = static_cast<int>(std::chrono::duration_cast<cTickTimeLong>(m_WorldAge).count() & 0xffffffff);
switch (a_SaplingMeta & 0x07)
auto SaplingMeta = GetBlockMeta(a_BlockPos);
switch (SaplingMeta & 0x07)
{
case E_META_SAPLING_APPLE: GetAppleTreeImage ({ a_X, a_Y, a_Z }, Noise, WorldAge, Logs, Other); break;
case E_META_SAPLING_BIRCH: GetBirchTreeImage ({ a_X, a_Y, a_Z }, Noise, WorldAge, Logs, Other); break;
case E_META_SAPLING_APPLE: GetAppleTreeImage (a_BlockPos, Noise, WorldAge, Logs, Other); break;
case E_META_SAPLING_BIRCH: GetBirchTreeImage (a_BlockPos, Noise, WorldAge, Logs, Other); break;
case E_META_SAPLING_CONIFER:
{
bool IsLarge = GetLargeTreeAdjustment(a_X, a_Y, a_Z, a_SaplingMeta);
GetConiferTreeImage({ a_X, a_Y, a_Z }, Noise, WorldAge, Logs, Other, IsLarge);
bool IsLarge = GetLargeTreeAdjustment(a_BlockPos, SaplingMeta);
GetConiferTreeImage(a_BlockPos, Noise, WorldAge, Logs, Other, IsLarge);
break;
}
case E_META_SAPLING_ACACIA: GetAcaciaTreeImage ({ a_X, a_Y, a_Z }, Noise, WorldAge, Logs, Other); break;
case E_META_SAPLING_ACACIA: GetAcaciaTreeImage (a_BlockPos, Noise, WorldAge, Logs, Other); break;
case E_META_SAPLING_JUNGLE:
{
bool IsLarge = GetLargeTreeAdjustment(a_X, a_Y, a_Z, a_SaplingMeta);
GetJungleTreeImage({ a_X, a_Y, a_Z }, Noise, WorldAge, Logs, Other, IsLarge);
bool IsLarge = GetLargeTreeAdjustment(a_BlockPos, SaplingMeta);
GetJungleTreeImage(a_BlockPos, Noise, WorldAge, Logs, Other, IsLarge);
break;
}
case E_META_SAPLING_DARK_OAK:
{
if (!GetLargeTreeAdjustment(a_X, a_Y, a_Z, a_SaplingMeta))
if (!GetLargeTreeAdjustment(a_BlockPos, SaplingMeta))
{
return false;
}
GetDarkoakTreeImage({ a_X, a_Y, a_Z }, Noise, WorldAge, Logs, Other);
GetDarkoakTreeImage(a_BlockPos, Noise, WorldAge, Logs, Other);
break;
}
}
@ -1659,7 +1660,7 @@ bool cWorld::GrowTreeFromSapling(int a_X, int a_Y, int a_Z, NIBBLETYPE a_Sapling
bool cWorld::GetLargeTreeAdjustment(int & a_X, int & a_Y, int & a_Z, NIBBLETYPE a_Meta)
bool cWorld::GetLargeTreeAdjustment(Vector3i & a_BlockPos, NIBBLETYPE a_Meta)
{
bool IsLarge = true;
a_Meta = a_Meta & 0x07;
@ -1671,8 +1672,8 @@ bool cWorld::GetLargeTreeAdjustment(int & a_X, int & a_Y, int & a_Z, NIBBLETYPE
{
NIBBLETYPE meta;
BLOCKTYPE type;
GetBlockTypeMeta(a_X + x, a_Y, a_Z + z, type, meta);
IsLarge = IsLarge && (type == E_BLOCK_SAPLING) && ((a_Meta & meta) == a_Meta);
GetBlockTypeMeta(a_BlockPos.addedXZ(x, z), type, meta);
IsLarge = IsLarge && (type == E_BLOCK_SAPLING) && ((meta & 0x07) == a_Meta);
}
}
@ -1689,14 +1690,14 @@ bool cWorld::GetLargeTreeAdjustment(int & a_X, int & a_Y, int & a_Z, NIBBLETYPE
{
NIBBLETYPE meta;
BLOCKTYPE type;
GetBlockTypeMeta(a_X + x, a_Y, a_Z + z, type, meta);
IsLarge = IsLarge && (type == E_BLOCK_SAPLING) && ((a_Meta & meta) == a_Meta);
GetBlockTypeMeta(a_BlockPos.addedXZ(x, z), type, meta);
IsLarge = IsLarge && (type == E_BLOCK_SAPLING) && ((meta & 0x07) == a_Meta);
}
}
if (IsLarge)
{
--a_Z;
--a_BlockPos.z;
return true;
}
@ -1708,15 +1709,15 @@ bool cWorld::GetLargeTreeAdjustment(int & a_X, int & a_Y, int & a_Z, NIBBLETYPE
{
NIBBLETYPE meta;
BLOCKTYPE type;
GetBlockTypeMeta(a_X + x, a_Y, a_Z + z, type, meta);
IsLarge = IsLarge && (type == E_BLOCK_SAPLING) && ((a_Meta & meta) == a_Meta);
GetBlockTypeMeta(a_BlockPos.addedXZ(x, z), type, meta);
IsLarge = IsLarge && (type == E_BLOCK_SAPLING) && ((meta & 0x07) == a_Meta);
}
}
if (IsLarge)
{
--a_Z;
--a_X;
--a_BlockPos.x;
--a_BlockPos.z;
return true;
}
@ -1728,14 +1729,14 @@ bool cWorld::GetLargeTreeAdjustment(int & a_X, int & a_Y, int & a_Z, NIBBLETYPE
{
NIBBLETYPE meta;
BLOCKTYPE type;
GetBlockTypeMeta(a_X + x, a_Y, a_Z + z, type, meta);
IsLarge = IsLarge && (type == E_BLOCK_SAPLING) && ((a_Meta & meta) == a_Meta);
GetBlockTypeMeta(a_BlockPos.addedXZ(x, z), type, meta);
IsLarge = IsLarge && (type == E_BLOCK_SAPLING) && ((meta & 0x07) == a_Meta);
}
}
if (IsLarge)
{
--a_X;
--a_BlockPos.x;
}
return IsLarge;
@ -1745,11 +1746,12 @@ bool cWorld::GetLargeTreeAdjustment(int & a_X, int & a_Y, int & a_Z, NIBBLETYPE
bool cWorld::GrowTreeByBiome(int a_X, int a_Y, int a_Z)
bool cWorld::GrowTreeByBiome(const Vector3i a_BlockPos)
{
cNoise Noise(m_Generator.GetSeed());
sSetBlockVector Logs, Other;
GetTreeImageByBiome({ a_X, a_Y, a_Z }, Noise, static_cast<int>(std::chrono::duration_cast<cTickTimeLong>(m_WorldAge).count() & 0xffffffff), GetBiomeAt(a_X, a_Z), Logs, Other);
auto seq = static_cast<int>(std::chrono::duration_cast<cTickTimeLong>(m_WorldAge).count() & 0xffffffff);
GetTreeImageByBiome(a_BlockPos, Noise, seq, GetBiomeAt(a_BlockPos.x, a_BlockPos.z), Logs, Other);
Other.insert(Other.begin(), Logs.begin(), Logs.end());
Logs.clear();
return GrowTreeImage(Other);

View File

@ -829,30 +829,25 @@ public:
Returns true if the tree is imprinted successfully, false otherwise. */
bool GrowTreeImage(const sSetBlockVector & a_Blocks);
// tolua_begin
/** Grows a tree at the specified coords.
If the specified block is a sapling, the tree is grown from that sapling.
Otherwise a tree is grown based on the biome.
Returns true if the tree was grown, false if not (invalid chunk, insufficient space). */
bool GrowTree(int a_BlockX, int a_BlockY, int a_BlockZ);
Returns true if the tree was grown, false if not (invalid chunk, insufficient space).
Exported in DeprecatedBindings due to the obsolete int-based overload. */
bool GrowTree(const Vector3i a_BlockPos);
/** Grows a tree at the specified coords, based on the sapling meta provided.
Returns true if the tree was grown, false if not (invalid chunk, insufficient space). */
bool GrowTreeFromSapling(Vector3i a_BlockPos, NIBBLETYPE a_SaplingMeta)
{
// TODO: Change the implementation to use Vector3i, once cTree uses Vector3i-based functions
return GrowTreeFromSapling(a_BlockPos.x, a_BlockPos.y, a_BlockPos.z, a_SaplingMeta);
}
/** OBSOLETE, use the Vector3-based overload instead.
Grows a tree at the specified coords, based on the sapling meta provided.
Returns true if the tree was grown, false if not (invalid chunk, insufficient space). */
bool GrowTreeFromSapling(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_SaplingMeta);
/** Grows a tree from the sapling at the specified coords.
If the sapling is a part of a large-tree sapling (2x2), a large tree growth is attempted.
Returns true if the tree was grown, false if not (invalid chunk, insufficient space).
Exported in DeprecatedBindings due to the obsolete int-based overload and obsolete additional SaplingMeta param. */
bool GrowTreeFromSapling(Vector3i a_BlockPos);
/** Grows a tree at the specified coords, based on the biome in the place.
Returns true if the tree was grown, false if not (invalid chunk, insufficient space). */
bool GrowTreeByBiome(int a_BlockX, int a_BlockY, int a_BlockZ);
Returns true if the tree was grown, false if not (invalid chunk, insufficient space).
Exported in DeprecatedBindings due to the obsolete int-based overload. */
bool GrowTreeByBiome(const Vector3i a_BlockPos);
// tolua_begin
/** Grows the plant at the specified position by at most a_NumStages.
The block's Grow handler is invoked.
@ -1381,7 +1376,7 @@ private:
void SetChunkData(cSetChunkData & a_SetChunkData);
/** Checks if the sapling at the specified block coord is a part of a large-tree sapling (2x2).
If so, adjusts the X and Z coords so that they point to the northwest (XM ZM) corner of the sapling area and returns true.
If so, adjusts the coords so that they point to the northwest (XM ZM) corner of the sapling area and returns true.
Returns false if not a part of large-tree sapling. */
bool GetLargeTreeAdjustment(int & a_BlockX, int & a_BlockY, int & a_BlockZ, NIBBLETYPE a_SaplingMeta);
bool GetLargeTreeAdjustment(Vector3i & a_BlockPos, NIBBLETYPE a_SaplingMeta);
}; // tolua_export