]> git.lizzy.rs Git - Crafter.git/blobdiff - mods/tnt/init.lua
Fix tnt running deprecated call
[Crafter.git] / mods / tnt / init.lua
index 7557f56212e4384f879b53b8f0f7c7640fe186ff..9e4800975b053015d3dd997ac2961917c5a7879f 100644 (file)
---here is where tnt is defined
+local minetest,type,vector,math,ipairs,os = 
+minetest,type,vector,math,ipairs,os
 
-local function tnt(pos,range)
+
+local function extreme_tnt(pos,range,explosion_type)
        local pos = vector.floor(vector.add(pos,0.5))
-       
-       --throw players and items
-       for _,object in ipairs(minetest.get_objects_inside_radius(pos, range)) do
-               if  object:is_player() then 
-                       local ppos = object:getpos()
-                       local power = (range - vector.distance(pos,ppos))*2
-                       local distance = vector.subtract(ppos,pos)
-                       local force = vector.multiply(distance,power)
-                       object:add_player_velocity(force)
-               elseif object:get_luaentity() and object:get_luaentity().name == "__builtin:item" then
-                       local ppos = object:getpos()
-                       local power = (range - vector.distance(pos,ppos))*2
-                       local distance = vector.subtract(pos,ppos)
-                       local force = vector.multiply(distance,power)
-                       object:setvelocity(force)
-               end
-       end
+       local delay = 0
+       for x=-1,0 do
+       for y=-1,0 do
+       for z=-1,0 do
+               minetest.after(delay, function(pos,range,x,y,z)
+                       local min = vector.add(pos,vector.multiply(vector.new(x,y,z),range))
+                       local max = vector.add(pos,vector.multiply(vector.new(x+1,y+1,z+1),range))
+                       local vm = minetest.get_voxel_manip()   
+                       local emin, emax = vm:read_from_map(min,max)
+                       local area = VoxelArea:new{MinEdge=emin, MaxEdge=emax}
+                       local data = vm:get_data()
+                       local air = minetest.get_content_id("air")
                        
+                       for x=min.x, max.x do
+                       for y=min.y, max.y do
+                       for z=min.z, max.z do
+                               --if vector.distance(pos, vector.new(x,y,z)) <= range then              
+                               --minetest.remove_node(vector.new(x,y,z))
+                               data[area:index(x,y,z)] = air
+                               --end
+                       end
+                       end
+                       end
+                       vm:set_data(data)
+                       vm:write_to_map()
+               end,pos,range,x,y,z)
+               delay = delay + 1
+       end
+       end
+       end
        
-       
-       local min = vector.add(pos,range)
-       local max = vector.subtract(pos,range)
-       local vm = minetest.get_voxel_manip()   
-       local emin, emax = vm:read_from_map(min,max)
-       local area = VoxelArea:new{MinEdge=emin, MaxEdge=emax}
-       local data = vm:get_data()
-       
-       local air = minetest.get_content_id("air")
-       local content_id = minetest.get_name_from_content_id
-       
-       local pos2 = vector.new(0,0,0)
-       
-       for x=-range, range do
-       for y=-range, range do
-       for z=-range, range do
-               if vector.distance(pos2, vector.new(x,y,z)) <= range then
-                       local p_pos = area:index(pos.x+x,pos.y+y,pos.z+z)                                               
-                       local n = content_id(data[p_pos])
-                       if n == "tnt:tnt" then
-                               --print("adding tnt")
-                               local obj = minetest.add_entity(vector.new(pos.x+x,pos.y+y,pos.z+z),"tnt:tnt")
-                               obj:get_luaentity().range = 5
-                               obj:get_luaentity().timer = math.random(1,10)*math.random()
-                               --minetest.sound_play("tnt_ignite", {object=obj, gain = 1.0, max_hear_distance = range*range*range})
-                       elseif n ~= "air" and n ~= "ignore" then
-                               if math.random()>0.99 then
-                                       local item = minetest.get_node_drops(n, "main:diamondpick")[1]
-                                       minetest.add_item(vector.new(pos.x+x,pos.y+y,pos.z+z), item)
+       minetest.sound_play("tnt_explode", {pos = pos, gain = 1.0, max_hear_distance = range*range*range})
+end
+--use raycasting to create actual explosion
+local n_pos
+local node2
+local ray
+local stop
+local found
+local positional_data
+local pos2 = vector.new(0,0,0)
+local in_node
+local in_water
+local min
+local max
+local vm
+local emin
+local emax
+local area
+local data
+local air = minetest.get_content_id("air")
+local content_id = minetest.get_name_from_content_id
+local distance
+local item
+local ppos
+local obj
+local do_it
+local in_node
+local clear
+local power
+local dir
+local force
+local hp
+local explosion_force
+local explosion_depletion
+local range_calc
+local boom_time = minetest.get_us_time()/1000000
+local digging_nodes = {
+       ["utility:chest_open"] = true,
+       ["utility:chest"] = true,
+       ["utility:furnace_active"] = true,
+       ["utility:furnace"] = true,
+}
+function tnt(pos,range,explosion_type)
+       in_node = minetest.get_node(pos).name
+       in_water =  ( in_node == "main:water" or minetest.get_node(pos).name == "main:waterflow")
+       min = vector.add(pos,range)
+       max = vector.subtract(pos,range)
+       vm = minetest.get_voxel_manip(min,max)
+               emin, emax = vm:read_from_map(min,max)
+               area = VoxelArea:new{MinEdge=emin, MaxEdge=emax}
+               data = vm:get_data()
+               
+       if in_water == false then
+               vm:get_light_data()
+               range_calc = range/100
+               explosion_depletion = range/2
+               --raycast explosion
+               for x=-range, range do
+               for y=-range, range do
+               for z=-range, range do
+                       distance = vector.distance(pos2, vector.new(x,y,z))
+                       if distance <= range and distance >= range-1 then
+                               ray = minetest.raycast(pos, vector.new(pos.x+x,pos.y+y,pos.z+z), false, false)
+                               explosion_force = range
+                               for pointed_thing in ray do
+                                       explosion_force = explosion_force - math.random()
+                                       if pointed_thing and explosion_force >= explosion_depletion then
+                                               n_pos = area:index(pointed_thing.under.x,pointed_thing.under.y,pointed_thing.under.z)
+
+                                               if n_pos and data[n_pos] then
+                                                       node2 = content_id(data[n_pos])
+                                                       
+                                                       if node2 == "nether:obsidian" or node2 == "nether:bedrock" then
+                                                               break
+                                                       elseif digging_nodes[node2] then
+                                                               minetest.dig_node({x=pointed_thing.under.x,y=pointed_thing.under.y,z=pointed_thing.under.z})
+                                                               data[n_pos] = air
+                                                       elseif node2 == "tnt:tnt" then
+                                                               data[n_pos] = air
+                                                               minetest.add_entity({x=pointed_thing.under.x,y=pointed_thing.under.y,z=pointed_thing.under.z}, "tnt:tnt",minetest.serialize({do_ignition_particles=true,timer = math.random()}))
+                                                       elseif not string.match(node2, "mob_spawners:") then
+                                                               data[n_pos] = air
+
+                                                               minetest.after(0, function(pointed_thing)
+                                                                       minetest.check_for_falling({x=pointed_thing.under.x,y=pointed_thing.under.y+1,z=pointed_thing.under.z})
+                                                               end,pointed_thing)
+                                                               if range_calc < 1 and math.random() > 0.9 + range_calc then
+                                                                       item = minetest.get_node_drops(node2, "main:diamondpick")[1]
+                                                                       ppos = {x=pointed_thing.under.x,y=pointed_thing.under.y,z=pointed_thing.under.z}
+                                                                       obj = minetest.add_item(ppos, item)
+                                                                       if obj then
+                                                                               power = (range - vector.distance(pos,ppos))*2
+                                                                               dir = vector.subtract(ppos,pos)
+                                                                               force = vector.multiply(dir,power)
+                                                                               obj:set_velocity(force)
+                                                                       end
+                                                               end
+                                                       end
+                                               end
+                                       else
+                                               break
+                                       end
                                end
                        end
-                       
-                       data[p_pos] = air
                end
+               end
+               end
+               vm:set_data(data)
+               vm:update_liquids()
+               vm:write_to_map()
        end
-       end
+       if minetest.get_us_time()/1000000 - boom_time >= 0.1 then
+               boom_time = minetest.get_us_time()/1000000
+               minetest.sound_play("tnt_explode", {pos = pos, gain = 1.0, max_hear_distance = 64}) --hear twice as far away
        end
        
-       vm:set_data(data)
-       vm:write_to_map()
-       
-       minetest.sound_play("tnt_explode", {pos = pos, gain = 1.0, max_hear_distance = range*range*range})
+       --throw players and items
+       for _,object in ipairs(minetest.get_objects_inside_radius(pos, range)) do
+               if object:is_player() or (object:get_luaentity() and (object:get_luaentity().name == "__builtin:item" or object:get_luaentity().name == "tnt:tnt" or object:get_luaentity().is_mob == true)) then
+                       do_it = true
+                       if not object:is_player() and object:get_luaentity().name == "tnt:tnt" then
+                               in_node = minetest.get_node(object:get_pos()).name
+                               if ( in_node == "main:water" or in_node == "main:waterflow") then
+                                       do_it = false
+                               end
+                       end
+                       if do_it == true then
+                               ppos = object:get_pos()
+                               if object:is_player() then
+                                       ppos.y = ppos.y + 1
+                               end
+                               ray = minetest.raycast(pos, ppos, false, false)
+                               clear = true
+                               for pointed_thing in ray do
+                                       n_pos = area:index(pointed_thing.under.x,pointed_thing.under.y,pointed_thing.under.z)
+                                       node2 = content_id(data[n_pos])
+                                       if node2 == "nether:obsidian" or node2 == "nether:bedrock" then
+                                               clear = false
+                                       end
+                               end
+                               if clear == true then
+                                       power = (range - vector.distance(pos,ppos))*10
+                                       dir = vector.direction(pos,ppos)
+                                       force = vector.multiply(dir,power)
+                                       if object:is_player() then
+                                               --damage the player
+                                               hp = object:get_hp()
+                                               if hp > 0 then
+                                                       --object:set_hp(hp - math.floor(power*2))
+                                                       object:punch(object, 2, 
+                                                               {
+                                                               full_punch_interval=1.5,
+                                                               damage_groups = {damage=math.floor(power)},
+                                                               })
+                                               end
+                                               object:add_player_velocity(force)
+                                       elseif object:get_luaentity() and (object:get_luaentity().name == "__builtin:item" or object:get_luaentity().name == "tnt:tnt" or object:get_luaentity().is_mob == true)  then
+                                               if object:get_luaentity().name == "tnt:tnt" then
+                                                       object:get_luaentity().shot = true
+                                               elseif object:get_luaentity().is_mob == true then
+                                                       object:punch(object, 2, 
+                                                               {
+                                                               full_punch_interval=1.5,
+                                                               damage_groups = {damage=math.floor(power)},
+                                                               })
+                                               elseif object:get_luaentity().name == "__builtin:item" then
+                                                       object:get_luaentity().poll_timer = 0
+                                               end
+                                               object:set_velocity(force)
+                                       end
+                               end
+                       end
+               end
+       end
        
        --stop client from lagging
-       local particle = range
-       if particle > 15 then
-               particle = 15
+       if range > 15 then
+               range = 15
        end
        
+
        minetest.add_particlespawner({
-                       amount = particle*particle*particle,
-                       time = 0.001,
-                       minpos = pos,
-                       maxpos = pos,
-                       minvel = vector.new(-range,-range,-range),
-                       maxvel = vector.new(range,range,range),
+               amount = range,
+               time = 0.001,
+               minpos = pos,
+               maxpos = pos,
+               minvel = vector.new(-range,-range,-range),
+               maxvel = vector.new(range,range,range),
+               minacc = {x=0, y=0, z=0},
+               maxacc = {x=0, y=0, z=0},
+               minexptime = 1.1,
+               maxexptime = 1.5,
+               minsize = 1,
+               maxsize = 2,
+               collisiondetection = true,
+               collision_removal = true,
+               vertical = false,
+               texture = "smoke.png",
+       })
+end
+
+local pos
+local vel
+local range
+local tnt_boom = function(self,dtime)
+       self.timer = self.timer - dtime
+       if not self.shot or not self.redstone_activated then
+               vel = self.object:get_velocity()
+               vel = vector.multiply(vel,-0.05)
+               self.object:add_velocity(vector.new(vel.x,0,vel.z))
+       end
+       if self.timer <= 0 then
+               if not self.range then
+                       self.range = 7
+               end
+               pos = self.object:get_pos()
+               range = self.range
+               self.object:remove()
+               tnt(pos,range)
+       end
+end
+local activation = function(self, staticdata, dtime_s)
+       self.object:set_armor_groups({immortal = 1})
+       self.object:set_velocity({x = math.random(-3,3), y = 3, z = math.random(-3,3)})
+       self.object:set_acceleration({x = 0, y = -9.81, z = 0})
+       if string.sub(staticdata, 1, string.len("return")) == "return" then
+               local data = minetest.deserialize(staticdata)
+               if data and type(data) == "table" then
+                       self.range = data.range
+                       self.timer = data.timer
+                       self.exploded = data.exploded
+               end
+       end
+       if self.timer == self.timer_max then
+               minetest.add_particlespawner({
+                       amount = 10,
+                       time = 0,
+                       minpos = vector.new(0,0.5,0),
+                       minpos = vector.new(0,0.5,0),
+                       minvel = vector.new(-0.5,1,-0.5),
+                       maxvel = vector.new(0.5,5,0.5),
                        minacc = {x=0, y=0, z=0},
                        maxacc = {x=0, y=0, z=0},
-                       minexptime = 1.1,
-                       maxexptime = 1.5,
+                       minexptime = 0.5,
+                       maxexptime = 1.0,
                        minsize = 1,
                        maxsize = 2,
                        collisiondetection = false,
                        vertical = false,
                        texture = "smoke.png",
+                       attached = self.object,
                })
+               minetest.sound_play("tnt_ignite", {object = self.object, gain = 1.0, max_hear_distance = 64})
+       end
 end
 
+local static = function(self)
+       return minetest.serialize({
+               range = self.range,
+               timer = self.timer,
+               exploded = self.exploded,       
+       })
+end
 
 minetest.register_entity("tnt:tnt", {
        initial_properties = {
@@ -106,74 +315,30 @@ minetest.register_entity("tnt:tnt", {
        },
 
        timer = 5,
+       timer_max = 5, --this has to be equal to timer
        range = 7,
-       
        get_staticdata = function(self)
-               return minetest.serialize({
-                       range = self.range,
-                       timer = self.timer,                     
-               })
+               return(static(self))
        end,
        
        on_activate = function(self, staticdata, dtime_s)
-               self.object:set_armor_groups({immortal = 1})
-               self.object:set_velocity({x = math.random(-5,5), y = 5, z = math.random(-5,5)})
-               self.object:set_acceleration({x = 0, y = -9.81, z = 0})
-               if string.sub(staticdata, 1, string.len("return")) == "return" then
-                       local data = minetest.deserialize(staticdata)
-                       if data and type(data) == "table" then
-                               self.range = data.range
-                               self.timer = data.timer
-                       end
-               end
-               
-               minetest.add_particlespawner({
-                       amount = 50,
-                       time = 0,
-                       minpos = pos,
-                       maxpos = pos,
-                       minvel = vector.new(-0.5,1,-0.5),
-                       maxvel = vector.new(0.5,5,0.5),
-                       minacc = {x=0, y=0, z=0},
-                       maxacc = {x=0, y=0, z=0},
-                       minexptime = 1.1,
-                       maxexptime = 1.5,
-                       minsize = 1,
-                       maxsize = 2,
-                       collisiondetection = false,
-                       vertical = false,
-                       texture = "smoke.png",
-                       attached = self.object,
-               })
-               minetest.sound_play("tnt_ignite", {object = self.object, gain = 1.0, max_hear_distance = self.range*self.range*self.range})
+               activation(self, staticdata, dtime_s)
        end,
                
        on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, dir)
-               local obj = minetest.add_item(self.object:getpos(), "tnt:tnt")
+               minetest.throw_item(self.object:get_pos(), "tnt:tnt")
                self.object:remove()
        end,
 
        sound_played = false,
-       on_step = function(self, dtime)
-               self.timer = self.timer - dtime
-               local vel = self.object:getvelocity()
-               vel = vector.multiply(vel,-0.05)
-               self.object:add_velocity(vector.new(vel.x,0,vel.z))
-               
-               if self.timer <= 0 then
-                       local pos = self.object:getpos()
-                       if not self.range then
-                               self.range = 7
-                       end
-                       tnt(pos,self.range)
-                       self.object:remove()
-               end
+       on_step = function(self, dtime) 
+               tnt_boom(self,dtime)
        end,
 })
 
 
 minetest.register_node("tnt:tnt", {
-    description = "Cobblestone",
+    description = "TNT",
     tiles = {"tnt_top.png", "tnt_bottom.png",
                        "tnt_side.png", "tnt_side.png",
                        "tnt_side.png", "tnt_side.png"},
@@ -181,20 +346,21 @@ minetest.register_node("tnt:tnt", {
     sounds = main.stoneSound(),
     redstone_activation = function(pos)
                local obj = minetest.add_entity(pos,"tnt:tnt")
-               local range = 7
+               local range = 4
                obj:get_luaentity().range = range
+               obj:get_luaentity().redstone_activated = true
                minetest.remove_node(pos)
     end,
     on_punch = function(pos, node, puncher, pointed_thing)
                local obj = minetest.add_entity(pos,"tnt:tnt")
-               local range = 7
+               local range = 4
                obj:get_luaentity().range = range
                minetest.remove_node(pos)
     end,
 })
 
 minetest.register_node("tnt:uranium_tnt", {
-    description = "Cobblestone",
+    description = "Uranium TNT",
     tiles = {"tnt_top.png^[colorize:green:100", "tnt_bottom.png^[colorize:green:100",
                        "tnt_side.png^[colorize:green:100", "tnt_side.png^[colorize:green:100",
                        "tnt_side.png^[colorize:green:100", "tnt_side.png^[colorize:green:100"},
@@ -202,21 +368,24 @@ minetest.register_node("tnt:uranium_tnt", {
     sounds = main.stoneSound(),
     on_punch = function(pos, node, puncher, pointed_thing)
                local obj = minetest.add_entity(pos,"tnt:tnt")
-               local range = 145
+               local range = 50
                obj:get_luaentity().range = range
+               obj:get_luaentity().timer = 7
+               obj:get_luaentity().extreme = true
+               
                minetest.remove_node(pos)
     end,
 })
 
 minetest.register_node("tnt:uh_oh", {
-    description = "Cobblestone",
+    description = "Uh Oh",
     tiles = {"tnt_top.png", "tnt_bottom.png",
                        "tnt_side.png", "tnt_side.png",
                        "tnt_side.png", "tnt_side.png"},
     groups = {stone = 2, hard = 1, pickaxe = 2, hand = 4},
     sounds = main.stoneSound(),
-    on_punch = function(pos, node, puncher, pointed_thing)
-               local range = 10
+    on_construct = function(pos)
+               local range = 5
                for x=-range, range do
                for y=-range, range do
                for z=-range, range do 
@@ -232,8 +401,8 @@ minetest.register_node("tnt:uh_oh", {
 minetest.register_craft({
        output = "tnt:tnt",
        recipe = {
-               {"main:wood", "main:wood", "main:wood"},
-               {"main:wood", "main:coal", "main:wood"},
-               {"main:wood", "main:wood", "main:wood"},
+               {"mob:gunpowder", "main:sand",     "mob:gunpowder"},
+               {"main:sand",     "mob:gunpowder", "main:sand"},
+               {"mob:gunpowder", "main:sand",     "mob:gunpowder"},
        },
 })