master
HybridDog 2013-08-20 23:05:10 +02:00
parent 0eeeafdd1b
commit e410590fbc
1 changed files with 86 additions and 40 deletions

View File

@ -1,16 +1,15 @@
local destroy = function(pos) local tnt_range = 2
local nodename = minetest.env:get_node(pos).name local tnt_preserve_items = true
if nodename ~= "air" then local tnt_drop_items = true
minetest.env:remove_node(pos) local tnt_seed = 15
nodeupdate(pos)
if minetest.registered_nodes[nodename].groups.flammable ~= nil then local function get_tnt_random(pos)
minetest.env:set_node(pos, {name="fire:basic_flame"}) return PseudoRandom(math.abs(pos.x+pos.y*3+pos.z*5)+tnt_seed)
return end
end
if math.random(1,3) == 3 then local function drop_item(pos, nodename)
return local drop = minetest.get_node_drops(nodename, "")
end if tnt_drop_items then
local drop = minetest.get_node_drops(nodename, "")
for _,item in ipairs(drop) do for _,item in ipairs(drop) do
if type(item) == "string" then if type(item) == "string" then
local obj = minetest.env:add_item(pos, item) local obj = minetest.env:add_item(pos, item)
@ -19,7 +18,7 @@ local destroy = function(pos)
end end
obj:get_luaentity().collect = true obj:get_luaentity().collect = true
obj:setacceleration({x=0, y=-10, z=0}) obj:setacceleration({x=0, y=-10, z=0})
obj:setvelocity({x=math.random(0,6)-3, y=10, z=math.random(0,6)-3}) obj:setvelocity({x=pr:next(0,6)-3, y=10, z=pr:next(0,6)-3})
else else
for i=1,item:get_count() do for i=1,item:get_count() do
local obj = minetest.env:add_item(pos, item:get_name()) local obj = minetest.env:add_item(pos, item:get_name())
@ -28,23 +27,52 @@ local destroy = function(pos)
end end
obj:get_luaentity().collect = true obj:get_luaentity().collect = true
obj:setacceleration({x=0, y=-10, z=0}) obj:setacceleration({x=0, y=-10, z=0})
obj:setvelocity({x=math.random(0,6)-3, y=10, z=math.random(0,6)-3}) obj:setvelocity({x=pr:next(0,6)-3, y=10, z=pr:next(0,6)-3})
end end
end end
end end
end end
end end
local destroy = function(pos)
local nodename = minetest.env:get_node(pos).name
local p_pos = area:index(pos.x, pos.y, pos.z)
if nodes[p_pos] ~= tnt_c_air then
-- minetest.env:remove_node(pos)
-- nodeupdate(pos)
if minetest.registered_nodes[nodename].groups.flammable ~= nil then
nodes[p_pos] = tnt_c_fire
return
end
nodes[p_pos] = tnt_c_air
if pr:next(1,3) == 3
or not tnt_preserve_items then
return
end
end
drop_item(pos, nodename)
end
boom = function(pos, time) boom = function(pos, time)
minetest.after(time, function(pos) minetest.after(time, function(pos)
if minetest.env:get_node(pos).name ~= "tnt:tnt_burning" then if minetest.env:get_node(pos).name ~= "tnt:tnt_burning" then
return return
end end
minetest.sound_play("tnt_explode", {pos=pos, gain=1.5, max_hear_distance=2*64})
minetest.env:set_node(pos, {name="tnt:boom"}) local t1 = os.clock()
minetest.after(0.5, function(pos) pr = get_tnt_random(pos)
minetest.env:remove_node(pos) minetest.sound_play("tnt_explode", {pos=pos, gain=1.5, max_hear_distance=tnt_range*64})
end, {x=pos.x, y=pos.y, z=pos.z})
local manip = minetest.get_voxel_manip()
local width = tnt_range
local emerged_pos1, emerged_pos2 = manip:read_from_map({x=pos.x-width, y=pos.y-width, z=pos.z-width},
{x=pos.x+width, y=pos.y+width, z=pos.z+width})
area = VoxelArea:new{MinEdge=emerged_pos1, MaxEdge=emerged_pos2}
nodes = manip:get_data()
local p_pos = area:index(pos.x, pos.y, pos.z)
nodes[p_pos] = tnt_c_boom
--minetest.env:set_node(pos, {name="tnt:boom"})
local objects = minetest.env:get_objects_inside_radius(pos, 7) local objects = minetest.env:get_objects_inside_radius(pos, 7)
for _,obj in ipairs(objects) do for _,obj in ipairs(objects) do
@ -60,32 +88,33 @@ boom = function(pos, time)
end end
end end
for dx=-2,2 do for dx=-tnt_range,tnt_range do
for dz=-2,2 do for dz=-tnt_range,tnt_range do
for dy=2,-2,-1 do for dy=tnt_range,-tnt_range,-1 do
pos.x = pos.x+dx local p = {x=pos.x+dx, y=pos.y+dy, z=pos.z+dz}
pos.y = pos.y+dy
pos.z = pos.z+dz
local node = minetest.env:get_node(pos) local p_node = area:index(p.x, p.y, p.z)
if node.name == "tnt:tnt" or node.name == "tnt:tnt_burning" then local d_p_node = nodes[p_node]
minetest.env:set_node(pos, {name="tnt:tnt_burning"}) local node = minetest.env:get_node(p)
boom({x=pos.x, y=pos.y, z=pos.z}, 0) --if node.name == "tnt:tnt" or node.name == "tnt:tnt_burning" then
elseif node.name == "fire:basic_flame" or string.find(node.name, "default:water_") or string.find(node.name, "default:lava_") or node.name == "tnt:boom" then if d_p_node == tnt_c_tnt
or d_p_node == tnt_c_tnt_burning then
else nodes[p_node] = tnt_c_tnt_burning
if math.abs(dx)<2 and math.abs(dy)<2 and math.abs(dz)<2 then --minetest.env:set_node(pos, {name="tnt:tnt_burning"})
destroy(pos) boom({x=p.x, y=p.y, z=p.z}, 0)
elseif not ( d_p_node == tnt_c_fire
or string.find(node.name, "default:water_")
or string.find(node.name, "default:lava_")
or d_p_node == tnt_c_boom ) then
if math.abs(dx)<tnt_range and math.abs(dy)<tnt_range and math.abs(dz)<tnt_range then
destroy(p)
else else
if math.random(1,5) <= 4 then if pr:next(1,5) <= 4 then
destroy(pos) destroy(p)
end end
end end
end end
pos.x = pos.x-dx
pos.y = pos.y-dy
pos.z = pos.z-dz
end end
end end
end end
@ -106,6 +135,16 @@ boom = function(pos, time)
false, --collisiondetection false, --collisiondetection
"tnt_smoke.png" --texture "tnt_smoke.png" --texture
) )
manip:set_data(nodes)
manip:write_to_map()
print(string.format("[tnt] exploded in: %.2fs", os.clock() - t1))
local t1 = os.clock()
manip:update_map()
print(string.format("[tnt] map updated after: %.2fs", os.clock() - t1))
minetest.after(0.5, function(pos)
minetest.env:remove_node(pos)
end, {x=pos.x, y=pos.y, z=pos.z}
)
end, pos) end, pos)
end end
@ -234,6 +273,13 @@ minetest.register_node("tnt:gunpowder_burning", {
sounds = default.node_sound_leaves_defaults(), sounds = default.node_sound_leaves_defaults(),
}) })
tnt_c_boom = minetest.get_content_id("tnt:boom")
tnt_c_tnt = minetest.get_content_id("tnt:tnt")
tnt_c_tnt_burning = minetest.get_content_id("tnt:tnt_burning")
tnt_c_air = minetest.get_content_id("air")
tnt_c_fire = minetest.get_content_id("fire:basic_flame")
minetest.register_abm({ minetest.register_abm({
nodenames = {"tnt:tnt", "tnt:gunpowder"}, nodenames = {"tnt:tnt", "tnt:gunpowder"},
neighbors = {"fire:basic_flame"}, neighbors = {"fire:basic_flame"},