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", Name = "BlockPos",
Type = "number", Type = "Vector3i",
}, },
}, },
Returns = Returns =
@ -2224,16 +2224,8 @@ function OnAllChunksAvailable()</pre> All return values from the callbacks are i
Params = Params =
{ {
{ {
Name = "BlockX", Name = "BlockPos",
Type = "number", Type = "Vector3i",
},
{
Name = "BlockY",
Type = "number",
},
{
Name = "BlockZ",
Type = "number",
}, },
}, },
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.", 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 = Params =
{ {
{ {
Name = "BlockX", Name = "BlockPos",
Type = "number", Type = "Vector3i",
},
{
Name = "BlockY",
Type = "number",
},
{
Name = "BlockZ",
Type = "number",
}, },
}, },
Notes = "Grows a tree based at the specified coords. The tree type is picked from types available for the biome at those coords.", 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 = Params =
{ {
{ {
Name = "BlockX", Name = "BlockPos",
Type = "number", Type = "Vector3i",
},
{
Name = "BlockY",
Type = "number",
},
{
Name = "BlockZ",
Type = "number",
},
{
Name = "SaplingMeta",
Type = "number",
}, },
}, },
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 = 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 */ /** function: cWorld:SetNextBlockTick */
static int tolua_cWorld_SetNextBlockTick(lua_State * tolua_S) static int tolua_cWorld_SetNextBlockTick(lua_State * tolua_S)
{ {
@ -595,8 +709,11 @@ void DeprecatedBindings::Bind(lua_State * tolua_S)
tolua_endmodule(tolua_S); tolua_endmodule(tolua_S);
tolua_beginmodule(tolua_S, "cWorld"); tolua_beginmodule(tolua_S, "cWorld");
tolua_function(tolua_S, "SetNextBlockTick", tolua_cWorld_SetNextBlockTick); tolua_function(tolua_S, "GrowTree", tolua_cWorld_GrowTree);
tolua_function(tolua_S, "UpdateSign", tolua_cWorld_SetSignLines); 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); tolua_endmodule(tolua_S);
tolua_endmodule(tolua_S); 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)) 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); 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 // Only move to the next growth stage if we haven't gone there yet
else if (((Meta & 0x08) == 0) && random.RandBool(0.45)) else if (((Meta & 0x08) == 0) && random.RandBool(0.45))
@ -211,7 +211,7 @@ public:
} }
// The sapling is grown, now it becomes a tree: // 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; 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: // 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 else
{ {
// There is nothing here, grow a tree based on the current biome here: // 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()); cNoise Noise(m_Generator.GetSeed());
sSetBlockVector Logs, Other; sSetBlockVector Logs, Other;
auto WorldAge = static_cast<int>(std::chrono::duration_cast<cTickTimeLong>(m_WorldAge).count() & 0xffffffff); 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_APPLE: GetAppleTreeImage (a_BlockPos, 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_BIRCH: GetBirchTreeImage (a_BlockPos, Noise, WorldAge, Logs, Other); break;
case E_META_SAPLING_CONIFER: case E_META_SAPLING_CONIFER:
{ {
bool IsLarge = GetLargeTreeAdjustment(a_X, a_Y, a_Z, a_SaplingMeta); bool IsLarge = GetLargeTreeAdjustment(a_BlockPos, SaplingMeta);
GetConiferTreeImage({ a_X, a_Y, a_Z }, Noise, WorldAge, Logs, Other, IsLarge); GetConiferTreeImage(a_BlockPos, Noise, WorldAge, Logs, Other, IsLarge);
break; 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: case E_META_SAPLING_JUNGLE:
{ {
bool IsLarge = GetLargeTreeAdjustment(a_X, a_Y, a_Z, a_SaplingMeta); bool IsLarge = GetLargeTreeAdjustment(a_BlockPos, SaplingMeta);
GetJungleTreeImage({ a_X, a_Y, a_Z }, Noise, WorldAge, Logs, Other, IsLarge); GetJungleTreeImage(a_BlockPos, Noise, WorldAge, Logs, Other, IsLarge);
break; break;
} }
case E_META_SAPLING_DARK_OAK: case E_META_SAPLING_DARK_OAK:
{ {
if (!GetLargeTreeAdjustment(a_X, a_Y, a_Z, a_SaplingMeta)) if (!GetLargeTreeAdjustment(a_BlockPos, SaplingMeta))
{ {
return false; return false;
} }
GetDarkoakTreeImage({ a_X, a_Y, a_Z }, Noise, WorldAge, Logs, Other); GetDarkoakTreeImage(a_BlockPos, Noise, WorldAge, Logs, Other);
break; 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; bool IsLarge = true;
a_Meta = a_Meta & 0x07; a_Meta = a_Meta & 0x07;
@ -1671,8 +1672,8 @@ bool cWorld::GetLargeTreeAdjustment(int & a_X, int & a_Y, int & a_Z, NIBBLETYPE
{ {
NIBBLETYPE meta; NIBBLETYPE meta;
BLOCKTYPE type; BLOCKTYPE type;
GetBlockTypeMeta(a_X + x, a_Y, a_Z + z, type, meta); GetBlockTypeMeta(a_BlockPos.addedXZ(x, z), type, meta);
IsLarge = IsLarge && (type == E_BLOCK_SAPLING) && ((a_Meta & meta) == a_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; NIBBLETYPE meta;
BLOCKTYPE type; BLOCKTYPE type;
GetBlockTypeMeta(a_X + x, a_Y, a_Z + z, type, meta); GetBlockTypeMeta(a_BlockPos.addedXZ(x, z), type, meta);
IsLarge = IsLarge && (type == E_BLOCK_SAPLING) && ((a_Meta & meta) == a_Meta); IsLarge = IsLarge && (type == E_BLOCK_SAPLING) && ((meta & 0x07) == a_Meta);
} }
} }
if (IsLarge) if (IsLarge)
{ {
--a_Z; --a_BlockPos.z;
return true; return true;
} }
@ -1708,15 +1709,15 @@ bool cWorld::GetLargeTreeAdjustment(int & a_X, int & a_Y, int & a_Z, NIBBLETYPE
{ {
NIBBLETYPE meta; NIBBLETYPE meta;
BLOCKTYPE type; BLOCKTYPE type;
GetBlockTypeMeta(a_X + x, a_Y, a_Z + z, type, meta); GetBlockTypeMeta(a_BlockPos.addedXZ(x, z), type, meta);
IsLarge = IsLarge && (type == E_BLOCK_SAPLING) && ((a_Meta & meta) == a_Meta); IsLarge = IsLarge && (type == E_BLOCK_SAPLING) && ((meta & 0x07) == a_Meta);
} }
} }
if (IsLarge) if (IsLarge)
{ {
--a_Z; --a_BlockPos.x;
--a_X; --a_BlockPos.z;
return true; return true;
} }
@ -1728,14 +1729,14 @@ bool cWorld::GetLargeTreeAdjustment(int & a_X, int & a_Y, int & a_Z, NIBBLETYPE
{ {
NIBBLETYPE meta; NIBBLETYPE meta;
BLOCKTYPE type; BLOCKTYPE type;
GetBlockTypeMeta(a_X + x, a_Y, a_Z + z, type, meta); GetBlockTypeMeta(a_BlockPos.addedXZ(x, z), type, meta);
IsLarge = IsLarge && (type == E_BLOCK_SAPLING) && ((a_Meta & meta) == a_Meta); IsLarge = IsLarge && (type == E_BLOCK_SAPLING) && ((meta & 0x07) == a_Meta);
} }
} }
if (IsLarge) if (IsLarge)
{ {
--a_X; --a_BlockPos.x;
} }
return IsLarge; 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()); cNoise Noise(m_Generator.GetSeed());
sSetBlockVector Logs, Other; 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()); Other.insert(Other.begin(), Logs.begin(), Logs.end());
Logs.clear(); Logs.clear();
return GrowTreeImage(Other); return GrowTreeImage(Other);

View File

@ -829,30 +829,25 @@ public:
Returns true if the tree is imprinted successfully, false otherwise. */ Returns true if the tree is imprinted successfully, false otherwise. */
bool GrowTreeImage(const sSetBlockVector & a_Blocks); bool GrowTreeImage(const sSetBlockVector & a_Blocks);
// tolua_begin
/** Grows a tree at the specified coords. /** Grows a tree at the specified coords.
If the specified block is a sapling, the tree is grown from that sapling. If the specified block is a sapling, the tree is grown from that sapling.
Otherwise a tree is grown based on the biome. Otherwise a tree is grown based on the biome.
Returns true if the tree was grown, false if not (invalid chunk, insufficient space). */ 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); 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. /** Grows a tree from the sapling at the specified coords.
Returns true if the tree was grown, false if not (invalid chunk, insufficient space). */ If the sapling is a part of a large-tree sapling (2x2), a large tree growth is attempted.
bool GrowTreeFromSapling(Vector3i a_BlockPos, NIBBLETYPE a_SaplingMeta) 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. */
// TODO: Change the implementation to use Vector3i, once cTree uses Vector3i-based functions bool GrowTreeFromSapling(Vector3i a_BlockPos);
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 at the specified coords, based on the biome in the place. /** 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). */ 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); 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. /** Grows the plant at the specified position by at most a_NumStages.
The block's Grow handler is invoked. The block's Grow handler is invoked.
@ -1381,7 +1376,7 @@ private:
void SetChunkData(cSetChunkData & a_SetChunkData); void SetChunkData(cSetChunkData & a_SetChunkData);
/** Checks if the sapling at the specified block coord is a part of a large-tree sapling (2x2). /** 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. */ 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 }; // tolua_export