From 6697062b3d7374a2ad0f0cb21339f0a1362a8805 Mon Sep 17 00:00:00 2001 From: Beha Date: Thu, 5 Jan 2017 20:24:41 -0500 Subject: [PATCH] Bones: drop items when blown up. --- bones/init.lua | 19 +++++++++++++++++++ magic/spells.lua | 26 +++++++++++++++----------- magic/throwing.lua | 2 +- tnt/init.lua | 21 ++++++++++++++++++--- 4 files changed, 53 insertions(+), 15 deletions(-) diff --git a/bones/init.lua b/bones/init.lua index 2b475db..3505247 100644 --- a/bones/init.lua +++ b/bones/init.lua @@ -27,6 +27,8 @@ bones.bones_formspec = local share_bones_time = tonumber(minetest.setting_get("share_bones_time")) or 1200 local share_bones_time_early = tonumber(minetest.setting_get("share_bones_time_early")) or share_bones_time / 4 +local blast_items = {} + minetest.register_node("bones:bones", { description = "Bones", tiles = { @@ -44,6 +46,23 @@ minetest.register_node("bones:bones", { dug = {name="default_gravel_footstep", gain=1.0}, }), + on_pre_blast = function(pos) + blast_items[minetest.pos_to_string(pos)] = {} + local inv = minetest.get_meta(pos):get_inventory() + for i=1,inv:get_size("main") do + local stk = inv:get_stack("main", i) + table.insert(blast_items[minetest.pos_to_string(pos)], stk) + end + end, + + on_blast = function(pos) + if blast_items[minetest.pos_to_string(pos)] then + local c = blast_items[minetest.pos_to_string(pos)] + blast_items[minetest.pos_to_string(pos)] = nil + return c + end + end, + can_dig = function(pos, player) local inv = minetest.get_meta(pos):get_inventory() local name = "" diff --git a/magic/spells.lua b/magic/spells.lua index 2977fc0..338b266 100644 --- a/magic/spells.lua +++ b/magic/spells.lua @@ -56,6 +56,18 @@ minetest.register_craft({ }) if rawget(_G, 'tnt') and tnt.boom then + local hit_node = function(self, pos, last_empty_pos) + local puts_out = minetest.get_item_group(minetest.get_node(pos).name, "puts_out_fire") + if puts_out > 0 then + -- This spell can travel through water. + return false + end + tnt.boom(pos, { + radius = 3, + damage_radius = 5, + }) + return true + end magic.register_spell("magic:spell_bomb", { description = "Bomb Spell", type = "missile", @@ -63,17 +75,9 @@ if rawget(_G, 'tnt') and tnt.boom then emblem = "attack", speed = 15, cost = 6, - hit_node = function(self, pos, last_empty_pos) - local puts_out = minetest.get_item_group(minetest.get_node(pos).name, "puts_out_fire") - if puts_out > 0 then - -- This spell can travel through water. - return false - end - tnt.boom(pos, { - radius = 3, - damage_radius = 5, - }) - return true + hit_node = hit_node, + hit_object = function(self, pos) + return hit_node(self, pos) end, }) minetest.register_craft({ diff --git a/magic/throwing.lua b/magic/throwing.lua index 63f8fe7..3a2b9a4 100644 --- a/magic/throwing.lua +++ b/magic/throwing.lua @@ -69,7 +69,7 @@ function magic.register_missile(name, texture, def, item_def) end def.hit_player = def.hit_player or function(self, pos, obj) - return true + return def.hit_object(self, pos, obj) end def.hit_node = def.hit_node or function(self, pos, last_empty_pos) diff --git a/tnt/init.lua b/tnt/init.lua index 1dd7d52..405a45a 100644 --- a/tnt/init.lua +++ b/tnt/init.lua @@ -218,7 +218,7 @@ local function registered_nodes_by_group(group) return result end -local function tnt_explode(pos, radius, ignore_protection, ignore_on_blast) +local function tnt_explode(pos, radius, ignore_protection, ignore_on_blast, on_blast_queue) local pos = vector.round(pos) local vm = VoxelManip() local pr = PseudoRandom(os.time()) @@ -229,7 +229,6 @@ local function tnt_explode(pos, radius, ignore_protection, ignore_on_blast) local data = vm:get_data() local drops = {} - local on_blast_queue = {} local c_air = minetest.get_content_id("air") local c_fire = minetest.get_content_id("fire:basic_flame") @@ -250,6 +249,10 @@ local function tnt_explode(pos, radius, ignore_protection, ignore_on_blast) local p = {x = pos.x + x, y = pos.y + y, z = pos.z + z} if c_blocks[cid] then blocks = blocks + minetest.get_item_group(c_blocks[cid], "block_explosion") - 1 + local ndef = cid_data[cid] + if ndef and ndef.on_pre_blast and not def.ignore_on_blast then + ndef.on_pre_blast(p) + end data[vi] = destroy(drops, p, cid, c_air, c_fire, on_blast_queue, ignore_protection, ignore_on_blast) @@ -273,6 +276,10 @@ local function tnt_explode(pos, radius, ignore_protection, ignore_on_blast) local cid = data[vi] local p = {x = pos.x + x, y = pos.y + y, z = pos.z + z} if cid ~= c_air then + local ndef = cid_data[cid] + if ndef and ndef.on_pre_blast and not def.ignore_on_blast then + ndef.on_pre_blast(p) + end data[vi] = destroy(drops, p, cid, c_air, c_fire, on_blast_queue, ignore_protection, ignore_on_blast) @@ -317,11 +324,19 @@ local function tnt_explode(pos, radius, ignore_protection, ignore_on_blast) end function tnt.boom(pos, def) + local on_blast_queue = {} + local ndef = minetest.registered_nodes[minetest.get_node(pos).name] + if ndef.on_blast and not def.ignore_on_blast then + on_blast_queue[#on_blast_queue + 1] = {pos = vector.new(pos), on_blast = ndef.on_blast} + end + if ndef.on_pre_blast and not def.ignore_on_blast then + ndef.on_pre_blast(pos) + end minetest.sound_play("tnt_explode", {pos = pos, gain = 1.5, max_hear_distance = 2*64}) minetest.set_node(pos, {name = "tnt:boom"}) minetest.get_node_timer(pos):start(0.5) local drops = tnt_explode(pos, def.radius, def.ignore_protection, - def.ignore_on_blast) + def.ignore_on_blast, on_blast_queue) entity_physics(pos, def.damage_radius) if not def.disable_drops then eject_drops(drops, pos, def.radius)