core.rotate_node: Do not trigger after_place_node (#6900)
authorSmallJoker <SmallJoker@users.noreply.github.com>
Thu, 29 Mar 2018 19:44:13 +0000 (21:44 +0200)
committerSmallJoker <mk939@ymail.com>
Sun, 3 Jun 2018 15:32:00 +0000 (17:32 +0200)
builtin/common/misc_helpers.lua
builtin/game/item.lua
doc/lua_api.txt

index ab2da14ea64716d60b9b815a964872a8fd07cdfc..aad5f2d218391f71105676bc0930b452021ee860 100644 (file)
@@ -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
index d4ce6002fe0900d91488a641bceb6f216090eb02..ea9681ae23bf2b71682c6f461684e231eeb4c3a0 100644 (file)
@@ -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)
index 04ae336545c674f1ea01622bc6b02e256aee7cb8..bb64916277dd88e9afcdf5dd07782b01f6780d81 100644 (file)
@@ -2857,9 +2857,11 @@ and `minetest.auth_reload` call the authetification handler.
 ### 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
@@ -3100,25 +3102,29 @@ These functions return the leftover itemstack.
 * `minetest.record_protection_violation(pos, name)`
      * This function calls functions registered with
        `minetest.register_on_protection_violation`.
-* `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:
-        * `invert_wall`:   if `true`, place wall-orientation on the ground and ground-
-    orientation on the wall.
+      defined by `itemstack`, and place it accordingly (on-wall, on the floor,
+      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.
         * `force_ceiling`: if `true`, always place on the ceiling.
         * `force_floor`:   if `true`, always place the node on the floor.
-        * `force_facedir`: if `true`, forcefully reset the facedir to north when placing on
-          the floor or ceiling
-        * The first four options are mutually-exclusive; the last in the list takes
-          precedence over the first.
+        * `force_facedir`: if `true`, forcefully reset the facedir to north
+          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`.