Allow optional actor ObjectRef value in node interaction calls (#14505)

This commit is contained in:
1F616EMO~nya 2024-04-05 19:00:50 +08:00 committed by GitHub
parent 4e1679d2a2
commit 2d8e4df7bc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 54 additions and 17 deletions

@ -39,6 +39,7 @@ core.features = {
dynamic_add_media_filepath = true, dynamic_add_media_filepath = true,
lsystem_decoration_type = true, lsystem_decoration_type = true,
item_meta_range = true, item_meta_range = true,
node_interaction_actor = true,
} }
function core.has_feature(arg) function core.has_feature(arg)

@ -5432,6 +5432,9 @@ Utilities
lsystem_decoration_type = true, lsystem_decoration_type = true,
-- Overrideable pointing range using the itemstack meta key `"range"` (5.9.0) -- Overrideable pointing range using the itemstack meta key `"range"` (5.9.0)
item_meta_range = true, 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` * Returns a number between `0` and `15`
* Currently it's the same as `math.floor(param1 / 16)`, except that it * Currently it's the same as `math.floor(param1 / 16)`, except that it
ensures compatibility. ensures compatibility.
* `minetest.place_node(pos, node)` * `minetest.place_node(pos, node[, placer])`
* Place node with the same effects that a player would cause * 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 * 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) * 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 * Punch node with the same effects that a player would cause
* `puncher`: The ObjectRef that punches the node (optional)
* `minetest.spawn_falling_node(pos)` * `minetest.spawn_falling_node(pos)`
* Change node into falling node * Change node into falling node
* Returns `true` and the ObjectRef of the spawned entity if successful, `false` on failure * Returns `true` and the ObjectRef of the spawned entity if successful, `false` on failure

@ -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_nodetimer.h"
#include "lua_api/l_noise.h" #include "lua_api/l_noise.h"
#include "lua_api/l_vmanip.h" #include "lua_api/l_vmanip.h"
#include "lua_api/l_object.h"
#include "common/c_converter.h" #include "common/c_converter.h"
#include "common/c_content.h" #include "common/c_content.h"
#include "scripting_server.h" #include "scripting_server.h"
@ -416,7 +417,7 @@ int ModApiEnv::l_get_natural_light(lua_State *L)
return 1; return 1;
} }
// place_node(pos, node) // place_node(pos, node, [placer])
// pos = {x=num, y=num, z=num} // pos = {x=num, y=num, z=num}
int ModApiEnv::l_place_node(lua_State *L) int ModApiEnv::l_place_node(lua_State *L)
{ {
@ -436,6 +437,7 @@ int ModApiEnv::l_place_node(lua_State *L)
lua_pushboolean(L, false); lua_pushboolean(L, false);
return 1; return 1;
} }
// Create item to place // Create item to place
std::optional<ItemStack> item = ItemStack(ndef->get(n).name, 1, 0, idef); std::optional<ItemStack> item = ItemStack(ndef->get(n).name, 1, 0, idef);
// Make pointed position // Make pointed position
@ -443,13 +445,22 @@ int ModApiEnv::l_place_node(lua_State *L)
pointed.type = POINTEDTHING_NODE; pointed.type = POINTEDTHING_NODE;
pointed.node_abovesurface = pos; pointed.node_abovesurface = pos;
pointed.node_undersurface = pos + v3s16(0,-1,0); 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<ObjectRef>(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); lua_pushboolean(L, success);
return 1; return 1;
} }
// dig_node(pos) // dig_node(pos, [digger])
// pos = {x=num, y=num, z=num} // pos = {x=num, y=num, z=num}
int ModApiEnv::l_dig_node(lua_State *L) int ModApiEnv::l_dig_node(lua_State *L)
{ {
@ -465,14 +476,23 @@ int ModApiEnv::l_dig_node(lua_State *L)
lua_pushboolean(L, false); lua_pushboolean(L, false);
return 1; return 1;
} }
// Dig it out with a NULL digger (appears in Lua as a
// non-functional ObjectRef) ServerActiveObject *digger = nullptr;
bool success = scriptIfaceNode->node_on_dig(pos, n, NULL);
if (!lua_isnoneornil(L, 2)) {
ObjectRef *ref = checkObject<ObjectRef>(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); lua_pushboolean(L, success);
return 1; return 1;
} }
// punch_node(pos) // punch_node(pos, [puncher])
// pos = {x=num, y=num, z=num} // pos = {x=num, y=num, z=num}
int ModApiEnv::l_punch_node(lua_State *L) int ModApiEnv::l_punch_node(lua_State *L)
{ {
@ -488,9 +508,19 @@ int ModApiEnv::l_punch_node(lua_State *L)
lua_pushboolean(L, false); lua_pushboolean(L, false);
return 1; return 1;
} }
// Punch it with a NULL puncher (appears in Lua as a non-functional
// ObjectRef) ServerActiveObject *puncher = nullptr;
bool success = scriptIfaceNode->node_on_punch(pos, n, NULL, PointedThing());
if (!lua_isnoneornil(L, 2)) {
ObjectRef *ref = checkObject<ObjectRef>(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); lua_pushboolean(L, success);
return 1; return 1;
} }

@ -89,15 +89,15 @@ private:
// timeofday: nil = current time, 0 = night, 0.5 = day // timeofday: nil = current time, 0 = night, 0.5 = day
static int l_get_natural_light(lua_State *L); 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} // pos = {x=num, y=num, z=num}
static int l_place_node(lua_State *L); static int l_place_node(lua_State *L);
// dig_node(pos) // dig_node(pos, [digger])
// pos = {x=num, y=num, z=num} // pos = {x=num, y=num, z=num}
static int l_dig_node(lua_State *L); static int l_dig_node(lua_State *L);
// punch_node(pos) // punch_node(pos, [puncher])
// pos = {x=num, y=num, z=num} // pos = {x=num, y=num, z=num}
static int l_punch_node(lua_State *L); static int l_punch_node(lua_State *L);