TNT: Add on_blast to all nodes with an inventory
authorAuke Kok <sofar@foo-projects.org>
Sat, 16 Apr 2016 02:21:45 +0000 (19:21 -0700)
committerparamat <mat.gregory@virginmedia.com>
Tue, 26 Apr 2016 21:33:59 +0000 (22:33 +0100)
Adds a minor helper function that allows efficient retrieval of
several inventories from a node inventory. We use this helper to
quickly retrieve the items in chests, vessel shelves, book shelves
and furnaces, and return these with the nodes itself to the TNT caller.

The TNT caller then performs the entity physics, and we don't need
to do anything else.

We disable TNT doing anything with bones.

We expose a bug in the code that drops the items - metadata was lost
entirely. This patch corrects that by properly copying the metadata
and creating the drops list inclusive metadata.

game_api.txt
mods/bones/init.lua
mods/default/functions.lua
mods/default/furnace.lua
mods/default/nodes.lua
mods/tnt/init.lua
mods/vessels/init.lua

index bdb2450b046d3610b4689ca671221370cc472b5f..02ee58e0876bde5029e0c58dbe89ef5fa572186e 100644 (file)
@@ -241,6 +241,23 @@ tnt.register_tnt(definition)
 
 ^ Ignite TNT at position
 
+
+To make dropping items from node inventories easier, you can use the
+following helper function from 'default':
+
+default.get_inventory_drops(pos, inventory, drops)
+
+^ Return drops from node inventory "inventory" in drops.
+
+* `pos` - the node position
+* `inventory` - the name of the inventory (string)
+* `drops` - an initialized list
+
+The function returns no values. The drops are returned in the `drops`
+parameter, and drops is not reinitialized so you can call it several
+times in a row to add more inventory items to it.
+
+
 Screwdriver API
 ---------------
 
index afa56eca5375fab7bbc99e7cd852a48da348b90f..661bbab85f718aff87cad8ce8e83a826c8476281 100644 (file)
@@ -123,6 +123,8 @@ minetest.register_node("bones:bones", {
                        return true
                end
        end,
+       on_blast = function(pos)
+       end,
 })
 
 local function may_replace(pos, player)
index c0ea1f5b53f00d0faaf1a3e93bb938ccbe0ecdc4..d0164cd6ac5c227f219877875582839595ea746d 100644 (file)
@@ -110,6 +110,21 @@ minetest.register_abm({
 })
 
 
+--
+-- optimized helper to put all items in an inventory into a drops list
+--
+function default.get_inventory_drops(pos, inventory, drops)
+       local inv = minetest.get_meta(pos):get_inventory()
+       local n = #drops
+       for i = 1, inv:get_size(inventory) do
+               local stack = inv:get_stack(inventory, i)
+               if stack:get_count() > 0 then
+                       drops[n+1] = stack:to_table()
+                       n = n + 1
+               end
+       end
+end
+
 --
 -- Papyrus and cactus growing
 --
index 4fb2071ad522076a7b4ee118a8a2a43e3727abc0..3047dc41fc4fb0ba4153badb2879947b8d53d46d 100644 (file)
@@ -260,6 +260,15 @@ minetest.register_node("default:furnace", {
                local timer = minetest.get_node_timer(pos)
                timer:start(1.0)
        end,
+       on_blast = function(pos)
+               local drops = {}
+               default.get_inventory_drops(pos, "src", drops)
+               default.get_inventory_drops(pos, "fuel", drops)
+               default.get_inventory_drops(pos, "dst", drops)
+               drops[#drops+1] = "default:furnace"
+               minetest.remove_node(pos)
+               return drops
+       end,
 
        allow_metadata_inventory_put = allow_metadata_inventory_put,
        allow_metadata_inventory_move = allow_metadata_inventory_move,
index 36ae5861c30fffee4df96c7a3910a87e25f5d9b2..506dd0add13535ac7554803c15e3c5c0acf8883d 100644 (file)
@@ -1474,6 +1474,13 @@ minetest.register_node("default:chest", {
                        " takes " .. stack:get_name() ..
                        " from chest at " .. minetest.pos_to_string(pos))
        end,
+       on_blast = function(pos)
+               local drops = {}
+               default.get_inventory_drops(pos, "main", drops)
+               drops[#drops+1] = "default:chest"
+               minetest.remove_node(pos)
+               return drops
+       end,
 })
 
 minetest.register_node("default:chest_locked", {
@@ -1597,6 +1604,13 @@ minetest.register_node("default:bookshelf", {
                minetest.log("action", player:get_player_name() ..
                        " takes stuff from bookshelf at " .. minetest.pos_to_string(pos))
        end,
+       on_blast = function(pos)
+               local drops = {}
+               default.get_inventory_drops(pos, "books", drops)
+               drops[#drops+1] = "default:bookshelf"
+               minetest.remove_node(pos)
+               return drops
+       end,
 })
 
 local function register_sign(material, desc, def)
index a8deeb0c78228ea54564a7f7e15f97dde476107b..66b01f1a1876f5398663c3f963ecc15c8c7d79f2 100644 (file)
@@ -55,7 +55,9 @@ local function eject_drops(drops, pos, radius)
                                        item:get_count(),
                                        item:get_stack_max()))
                        rand_pos(pos, drop_pos, radius)
-                       local obj = minetest.add_item(drop_pos, item:get_name() .. " " .. take)
+                       local dropitem = ItemStack(item)
+                       dropitem:set_count(take)
+                       local obj = minetest.add_item(drop_pos, dropitem)
                        if obj then
                                obj:get_luaentity().collect = true
                                obj:setacceleration({x = 0, y = -10, z = 0})
index d5378919958cd505a0bece7f8801272b670e9c21..165efbd50d938412b664c57c82dfba877699bde0 100644 (file)
@@ -48,6 +48,13 @@ minetest.register_node("vessels:shelf", {
                minetest.log("action", player:get_player_name() ..
                           " takes stuff from vessels shelf at ".. minetest.pos_to_string(pos))
        end,
+       on_blast = function(pos)
+               local drops = {}
+               default.get_inventory_drops(pos, "vessels", drops)
+               drops[#drops+1] = "vessels:shelf"
+               minetest.remove_node(pos)
+               return drops
+       end,
 })
 
 minetest.register_craft({