From 2d8e4df7bc72e6f8855efbebff6da5a2d00c81c4 Mon Sep 17 00:00:00 2001 From: 1F616EMO~nya Date: Fri, 5 Apr 2024 19:00:50 +0800 Subject: [PATCH] Allow optional actor ObjectRef value in node interaction calls (#14505) --- builtin/game/features.lua | 1 + doc/lua_api.md | 12 ++++++--- src/script/lua_api/l_env.cpp | 52 ++++++++++++++++++++++++++++-------- src/script/lua_api/l_env.h | 6 ++--- 4 files changed, 54 insertions(+), 17 deletions(-) diff --git a/builtin/game/features.lua b/builtin/game/features.lua index 874d3e885..286c3f146 100644 --- a/builtin/game/features.lua +++ b/builtin/game/features.lua @@ -39,6 +39,7 @@ core.features = { dynamic_add_media_filepath = true, lsystem_decoration_type = true, item_meta_range = true, + node_interaction_actor = true, } function core.has_feature(arg) diff --git a/doc/lua_api.md b/doc/lua_api.md index cca231c73..796a0f39e 100644 --- a/doc/lua_api.md +++ b/doc/lua_api.md @@ -5432,6 +5432,9 @@ Utilities lsystem_decoration_type = true, -- Overrideable pointing range using the itemstack meta key `"range"` (5.9.0) item_meta_range = true, + -- Allow passing an optional "actor" ObjectRef to the following functions: + -- minetest.place_node, minetest.dig_node, minetest.punch_node (5.9.0) + node_interaction_actor = true, } ``` @@ -6062,13 +6065,16 @@ Environment access * Returns a number between `0` and `15` * Currently it's the same as `math.floor(param1 / 16)`, except that it ensures compatibility. -* `minetest.place_node(pos, node)` +* `minetest.place_node(pos, node[, placer])` * Place node with the same effects that a player would cause -* `minetest.dig_node(pos)` + * `placer`: The ObjectRef that places the node (optional) +* `minetest.dig_node(pos[, digger])` * Dig node with the same effects that a player would cause + * `digger`: The ObjectRef that digs the node (optional) * Returns `true` if successful, `false` on failure (e.g. protected location) -* `minetest.punch_node(pos)` +* `minetest.punch_node(pos[, puncher])` * Punch node with the same effects that a player would cause + * `puncher`: The ObjectRef that punches the node (optional) * `minetest.spawn_falling_node(pos)` * Change node into falling node * Returns `true` and the ObjectRef of the spawned entity if successful, `false` on failure diff --git a/src/script/lua_api/l_env.cpp b/src/script/lua_api/l_env.cpp index b348a0f47..06dc27b2d 100644 --- a/src/script/lua_api/l_env.cpp +++ b/src/script/lua_api/l_env.cpp @@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "lua_api/l_nodetimer.h" #include "lua_api/l_noise.h" #include "lua_api/l_vmanip.h" +#include "lua_api/l_object.h" #include "common/c_converter.h" #include "common/c_content.h" #include "scripting_server.h" @@ -416,7 +417,7 @@ int ModApiEnv::l_get_natural_light(lua_State *L) return 1; } -// place_node(pos, node) +// place_node(pos, node, [placer]) // pos = {x=num, y=num, z=num} int ModApiEnv::l_place_node(lua_State *L) { @@ -436,6 +437,7 @@ int ModApiEnv::l_place_node(lua_State *L) lua_pushboolean(L, false); return 1; } + // Create item to place std::optional item = ItemStack(ndef->get(n).name, 1, 0, idef); // Make pointed position @@ -443,13 +445,22 @@ int ModApiEnv::l_place_node(lua_State *L) pointed.type = POINTEDTHING_NODE; pointed.node_abovesurface = pos; pointed.node_undersurface = pos + v3s16(0,-1,0); - // Place it with a NULL placer (appears in Lua as nil) - bool success = scriptIfaceItem->item_OnPlace(item, nullptr, pointed); + + ServerActiveObject *placer = nullptr; + + if (!lua_isnoneornil(L, 3)) { + ObjectRef *ref = checkObject(L, 3); + placer = ObjectRef::getobject(ref); + } + + // Place it with a nullptr placer (appears in Lua as nil) + // or the given ObjectRef + bool success = scriptIfaceItem->item_OnPlace(item, placer, pointed); lua_pushboolean(L, success); return 1; } -// dig_node(pos) +// dig_node(pos, [digger]) // pos = {x=num, y=num, z=num} int ModApiEnv::l_dig_node(lua_State *L) { @@ -465,14 +476,23 @@ int ModApiEnv::l_dig_node(lua_State *L) lua_pushboolean(L, false); return 1; } - // Dig it out with a NULL digger (appears in Lua as a - // non-functional ObjectRef) - bool success = scriptIfaceNode->node_on_dig(pos, n, NULL); + + ServerActiveObject *digger = nullptr; + + if (!lua_isnoneornil(L, 2)) { + ObjectRef *ref = checkObject(L, 2); + digger = ObjectRef::getobject(ref); + } + + // Dig it out with a nullptr digger + // (appears in Lua as a non-functional ObjectRef) + // or the given ObjectRef + bool success = scriptIfaceNode->node_on_dig(pos, n, digger); lua_pushboolean(L, success); return 1; } -// punch_node(pos) +// punch_node(pos, [puncher]) // pos = {x=num, y=num, z=num} int ModApiEnv::l_punch_node(lua_State *L) { @@ -488,9 +508,19 @@ int ModApiEnv::l_punch_node(lua_State *L) lua_pushboolean(L, false); return 1; } - // Punch it with a NULL puncher (appears in Lua as a non-functional - // ObjectRef) - bool success = scriptIfaceNode->node_on_punch(pos, n, NULL, PointedThing()); + + ServerActiveObject *puncher = nullptr; + + if (!lua_isnoneornil(L, 2)) { + ObjectRef *ref = checkObject(L, 2); + puncher = ObjectRef::getobject(ref); + } + + // Punch it with a nullptr puncher + // (appears in Lua as a non-functional ObjectRef) + // or the given ObjectRef + // TODO: custom PointedThing (requires a converter function) + bool success = scriptIfaceNode->node_on_punch(pos, n, puncher, PointedThing()); lua_pushboolean(L, success); return 1; } diff --git a/src/script/lua_api/l_env.h b/src/script/lua_api/l_env.h index f657424d0..2ed0eb114 100644 --- a/src/script/lua_api/l_env.h +++ b/src/script/lua_api/l_env.h @@ -89,15 +89,15 @@ private: // timeofday: nil = current time, 0 = night, 0.5 = day static int l_get_natural_light(lua_State *L); - // place_node(pos, node) + // place_node(pos, node, [placer]) // pos = {x=num, y=num, z=num} static int l_place_node(lua_State *L); - // dig_node(pos) + // dig_node(pos, [digger]) // pos = {x=num, y=num, z=num} static int l_dig_node(lua_State *L); - // punch_node(pos) + // punch_node(pos, [puncher]) // pos = {x=num, y=num, z=num} static int l_punch_node(lua_State *L);