From c98a2d9acfdf4350479b925f216a1b1fb49688f6 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Wed, 26 Aug 2020 14:08:37 +0200 Subject: Changed tree-growing functions in cWorld to use Vector3i coords. --- Server/Plugins/APIDump/Classes/World.lua | 44 ++--------- src/Bindings/DeprecatedBindings.cpp | 121 ++++++++++++++++++++++++++++++- src/Blocks/BlockSapling.h | 4 +- src/World.cpp | 62 ++++++++-------- src/World.h | 35 ++++----- 5 files changed, 176 insertions(+), 90 deletions(-) diff --git a/Server/Plugins/APIDump/Classes/World.lua b/Server/Plugins/APIDump/Classes/World.lua index 338935a7b..4de9c68f4 100644 --- a/Server/Plugins/APIDump/Classes/World.lua +++ b/Server/Plugins/APIDump/Classes/World.lua @@ -2178,7 +2178,7 @@ function OnAllChunksAvailable() All return values from the callbacks are i { { Name = "BlockPos", - Type = "number", + Type = "Vector3i", }, }, Returns = @@ -2224,16 +2224,8 @@ function OnAllChunksAvailable() 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() 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() 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 = { diff --git a/src/Bindings/DeprecatedBindings.cpp b/src/Bindings/DeprecatedBindings.cpp index 11b15a8c8..0d216f94b 100644 --- a/src/Bindings/DeprecatedBindings.cpp +++ b/src/Bindings/DeprecatedBindings.cpp @@ -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,8 +709,11 @@ void DeprecatedBindings::Bind(lua_State * tolua_S) tolua_endmodule(tolua_S); tolua_beginmodule(tolua_S, "cWorld"); - tolua_function(tolua_S, "SetNextBlockTick", tolua_cWorld_SetNextBlockTick); - tolua_function(tolua_S, "UpdateSign", tolua_cWorld_SetSignLines); + 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); tolua_endmodule(tolua_S); diff --git a/src/Blocks/BlockSapling.h b/src/Blocks/BlockSapling.h index 86397d806..e52ae5fc7 100644 --- a/src/Blocks/BlockSapling.h +++ b/src/Blocks/BlockSapling.h @@ -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; } diff --git a/src/World.cpp b/src/World.cpp index aca640091..721624790 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -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(std::chrono::duration_cast(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(std::chrono::duration_cast(m_WorldAge).count() & 0xffffffff), GetBiomeAt(a_X, a_Z), Logs, Other); + auto seq = static_cast(std::chrono::duration_cast(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); diff --git a/src/World.h b/src/World.h index b6936a9d5..010959762 100644 --- a/src/World.h +++ b/src/World.h @@ -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); - - /** 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); - } + 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); - /** 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 -- cgit v1.2.3