diff --git a/builtin/common/misc_helpers.lua b/builtin/common/misc_helpers.lua index 88bae2b0b..aa118b443 100644 --- a/builtin/common/misc_helpers.lua +++ b/builtin/common/misc_helpers.lua @@ -341,7 +341,7 @@ if INIT == "game" then local dirs2 = {20, 23, 22, 21} function core.rotate_and_place(itemstack, placer, pointed_thing, - infinitestacks, orient_flags) + infinitestacks, orient_flags, prevent_after_place) orient_flags = orient_flags or {} local unode = core.get_node_or_nil(pointed_thing.under) @@ -394,7 +394,7 @@ if INIT == "game" then local old_itemstack = ItemStack(itemstack) local new_itemstack, removed = core.item_place_node( - itemstack, placer, pointed_thing, param2 + itemstack, placer, pointed_thing, param2, prevent_after_place ) return infinitestacks and old_itemstack or new_itemstack end @@ -415,7 +415,7 @@ if INIT == "game" then local invert_wall = placer and placer:get_player_control().sneak or false core.rotate_and_place(itemstack, placer, pointed_thing, is_creative(name), - {invert_wall = invert_wall}) + {invert_wall = invert_wall}, true) return itemstack end end diff --git a/builtin/game/item.lua b/builtin/game/item.lua index a7176711f..8fbe5b672 100644 --- a/builtin/game/item.lua +++ b/builtin/game/item.lua @@ -261,7 +261,8 @@ local function make_log(name) return name ~= "" and core.log or function() end end -function core.item_place_node(itemstack, placer, pointed_thing, param2) +function core.item_place_node(itemstack, placer, pointed_thing, param2, + prevent_after_place) local def = itemstack:get_definition() if def.type ~= "node" or pointed_thing.type ~= "node" then return itemstack, false @@ -375,7 +376,7 @@ function core.item_place_node(itemstack, placer, pointed_thing, param2) local take_item = true -- Run callback - if def.after_place_node then + if def.after_place_node and not prevent_after_place then -- Deepcopy place_to and pointed_thing because callback can modify it local place_to_copy = {x=place_to.x, y=place_to.y, z=place_to.z} local pointed_thing_copy = copy_pointed_thing(pointed_thing) diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 946340cb3..69c4b3262 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -3461,9 +3461,11 @@ You can find mod channels communication scheme in `docs/mod_channels.png`. ### Defaults for the `on_*` item definition functions These functions return the leftover itemstack. -* `minetest.item_place_node(itemstack, placer, pointed_thing, param2)` +* `minetest.item_place_node(itemstack, placer, pointed_thing[, param2, prevent_after_place])` * Place item as a node * `param2` overrides `facedir` and wallmounted `param2` + * `prevent_after_place`: if set to `true`, `after_place_node` is not called + for the newly placed node to prevent a callback and placement loop * returns `itemstack, success` * `minetest.item_place_object(itemstack, placer, pointed_thing)` * Place item as-is @@ -3784,13 +3786,14 @@ These functions return the leftover itemstack. * Like `minetest.is_protected`, this function may be extended or overwritten by mods to provide a faster implementation to check the cuboid for intersections. -* `minetest.rotate_and_place(itemstack, placer, pointed_thing, infinitestacks, orient_flags)` +* `minetest.rotate_and_place(itemstack, placer, pointed_thing[, infinitestacks, + orient_flags, prevent_after_place])` * Attempt to predict the desired orientation of the facedir-capable node defined by `itemstack`, and place it accordingly (on-wall, on the floor, - or hanging from the ceiling). Stacks are handled normally if the - `infinitestacks` field is false or omitted (else, the itemstack is not - changed). `orient_flags` is an optional table containing extra tweaks to - the placement code: + or hanging from the ceiling). + * `infinitestacks`: if `true`, the itemstack is not changed. Otherwise the + stacks are handled normally. + * `orient_flags`: Optional table containing extra tweaks to the placement code: * `invert_wall`: if `true`, place wall-orientation on the ground and ground-orientation on the wall. * `force_wall` : if `true`, always place the node in wall orientation. @@ -3800,10 +3803,12 @@ These functions return the leftover itemstack. when placing on the floor or ceiling. * The first four options are mutually-exclusive; the last in the list takes precedence over the first. + * `prevent_after_place` is directly passed to `minetest.item_place_node` + * Returns the new itemstack after placement * `minetest.rotate_node(itemstack, placer, pointed_thing)` - * calls `rotate_and_place()` with infinitestacks set according to the state - of the creative mode setting, and checks for "sneak" to set the - `invert_wall` parameter. + * calls `rotate_and_place()` with `infinitestacks` set according to the state + of the creative mode setting, checks for "sneak" to set the `invert_wall` + parameter and `prevent_after_place` set to `true`. * `minetest.forceload_block(pos[, transient])` * forceloads the position `pos`.