Skip to content

Commit 0f7d0bf

Browse files
fozoloparamat
authored andcommittedJul 2, 2017
TNT: Track TNT owner in metadata for protection mods
It is useful for protection mods to know who owns an exploding TNT block. This allows the blocks destroyed by the TNT to be limited to the same ones the owner could destroy without using TNT. TNT placed within a protected area by the area owner, and later ignited by another player will destroy within the protected area nodes the igniter may not otherwise be able to interact with. Any player could significantly increase the size of an explosion by placing more TNT in an adjacent unprotected area if the original TNT block was placed withing 1 node of such a boundary. This feature sounds dangerous, but we are talking about TNT. Players should use it carefully.
1 parent c51ebcb commit 0f7d0bf

File tree

1 file changed

+23
-9
lines changed

1 file changed

+23
-9
lines changed
 

Diff for: ‎mods/tnt/init.lua

+23-9
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,8 @@ end
8686
local basic_flame_on_construct -- cached value
8787
local function destroy(drops, npos, cid, c_air, c_fire,
8888
on_blast_queue, on_construct_queue,
89-
ignore_protection, ignore_on_blast)
90-
if not ignore_protection and minetest.is_protected(npos, "") then
89+
ignore_protection, ignore_on_blast, owner)
90+
if not ignore_protection and minetest.is_protected(npos, owner) then
9191
return cid
9292
end
9393

@@ -266,13 +266,13 @@ function tnt.burn(pos, nodename)
266266
elseif def.on_ignite then
267267
def.on_ignite(pos)
268268
elseif minetest.get_item_group(name, "tnt") > 0 then
269+
minetest.swap_node(pos, {name = name .. "_burning"})
269270
minetest.sound_play("tnt_ignite", {pos = pos})
270-
minetest.set_node(pos, {name = name .. "_burning"})
271271
minetest.get_node_timer(pos):start(1)
272272
end
273273
end
274274

275-
local function tnt_explode(pos, radius, ignore_protection, ignore_on_blast)
275+
local function tnt_explode(pos, radius, ignore_protection, ignore_on_blast, owner)
276276
pos = vector.round(pos)
277277
-- scan for adjacent TNT nodes first, and enlarge the explosion
278278
local vm1 = VoxelManip()
@@ -333,7 +333,7 @@ local function tnt_explode(pos, radius, ignore_protection, ignore_on_blast)
333333
if cid ~= c_air then
334334
data[vi] = destroy(drops, p, cid, c_air, c_fire,
335335
on_blast_queue, on_construct_queue,
336-
ignore_protection, ignore_on_blast)
336+
ignore_protection, ignore_on_blast, owner)
337337
end
338338
end
339339
vi = vi + 1
@@ -375,14 +375,19 @@ local function tnt_explode(pos, radius, ignore_protection, ignore_on_blast)
375375
queued_data.fn(queued_data.pos)
376376
end
377377

378+
minetest.log("action", "TNT owned by " .. owner .. " detonated at " ..
379+
minetest.pos_to_string(pos) .. " with radius " .. radius)
380+
378381
return drops, radius
379382
end
380383

381384
function tnt.boom(pos, def)
385+
local meta = minetest.get_meta(pos)
386+
local owner = meta:get_string("owner")
382387
minetest.sound_play("tnt_explode", {pos = pos, gain = 1.5, max_hear_distance = 2*64})
383388
minetest.set_node(pos, {name = "tnt:boom"})
384389
local drops, radius = tnt_explode(pos, def.radius, def.ignore_protection,
385-
def.ignore_on_blast)
390+
def.ignore_on_blast, owner)
386391
-- append entity drops
387392
local damage_radius = (radius / def.radius) * def.damage_radius
388393
entity_physics(pos, damage_radius, drops)
@@ -579,9 +584,16 @@ function tnt.register_tnt(def)
579584
is_ground_content = false,
580585
groups = {dig_immediate = 2, mesecon = 2, tnt = 1, flammable = 5},
581586
sounds = default.node_sound_wood_defaults(),
587+
after_place_node = function(pos, placer)
588+
if placer:is_player() then
589+
local meta = minetest.get_meta(pos)
590+
meta:set_string("owner", placer:get_player_name())
591+
end
592+
end,
582593
on_punch = function(pos, node, puncher)
583594
if puncher:get_wielded_item():get_name() == "default:torch" then
584-
minetest.set_node(pos, {name = name .. "_burning"})
595+
minetest.swap_node(pos, {name = name .. "_burning"})
596+
minetest.registered_nodes[name .. "_burning"].on_construct(pos)
585597
minetest.log("action", puncher:get_player_name() ..
586598
" ignites " .. node.name .. " at " ..
587599
minetest.pos_to_string(pos))
@@ -600,10 +612,12 @@ function tnt.register_tnt(def)
600612
}
601613
},
602614
on_burn = function(pos)
603-
minetest.set_node(pos, {name = name .. "_burning"})
615+
minetest.swap_node(pos, {name = name .. "_burning"})
616+
minetest.registered_nodes[name .. "_burning"].on_construct(pos)
604617
end,
605618
on_ignite = function(pos, igniter)
606-
minetest.set_node(pos, {name = name .. "_burning"})
619+
minetest.swap_node(pos, {name = name .. "_burning"})
620+
minetest.registered_nodes[name .. "_burning"].on_construct(pos)
607621
end,
608622
})
609623
end

0 commit comments

Comments
 (0)
Please sign in to comment.