]> git.lizzy.rs Git - Crafter.git/blobdiff - mods/tnt/init.lua
Fix tnt running deprecated call
[Crafter.git] / mods / tnt / init.lua
index 30c4bb48628183995cef5be26851808af9536bd7..9e4800975b053015d3dd997ac2961917c5a7879f 100644 (file)
@@ -1,18 +1,9 @@
---here is where tnt is defined
-local function extreme_tnt(pos,range)
+local minetest,type,vector,math,ipairs,os = 
+minetest,type,vector,math,ipairs,os
+
+
+local function extreme_tnt(pos,range,explosion_type)
        local pos = vector.floor(vector.add(pos,0.5))
-       
-       --kill
-       --[[
-       for _,object in ipairs(minetest.get_objects_inside_radius(pos, range)) do
-               if  object:is_player() then 
-                       object:set_hp(-50)
-               elseif object:get_luaentity() and object:get_luaentity().name == "__builtin:item" then
-                       object:remove()
-               end
-       end
-       ]]--
-       
        local delay = 0
        for x=-1,0 do
        for y=-1,0 do
@@ -46,31 +37,7 @@ local function extreme_tnt(pos,range)
        
        minetest.sound_play("tnt_explode", {pos = pos, gain = 1.0, max_hear_distance = range*range*range})
 end
---[[
-minetest.register_globalstep(function(dtime)
-       --collection
-       for _,player in ipairs(minetest.get_connected_players()) do
-               local pos = player:get_pos()
-               pos.y = pos.y + player:get_properties().eye_height
-               local look_dir = player:get_look_dir()
-               look_dir = vector.multiply(look_dir,7)
-               local pos2 = vector.add(pos,look_dir)
-               
-               local ray = minetest.raycast(pos, pos2, false, false)           
-               if ray then
-                       print("------------------------------------------------------------")
-                       for pointed_thing in ray do
-                               print(minetest.get_node(pointed_thing.under).name)
-                               --if pointed_thing then
-                               --      return({under=pointed_thing.under,above=pointed_thing.above})
-                               --end
-                       end
-               end
-       end
-end)
-]]--
 --use raycasting to create actual explosion
-local old_node_table
 local n_pos
 local node2
 local ray
@@ -78,61 +45,97 @@ local stop
 local found
 local positional_data
 local pos2 = vector.new(0,0,0)
-function tnt(pos,range)
-       local in_node = minetest.get_node(pos).name
-       local in_water =  ( in_node == "main:water" or minetest.get_node(pos).name == "main:waterflow")
-       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 insert = table.insert
-       
-       vm:get_light_data()
-       
-       
-       
+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
-                       local distance = vector.distance(pos2, vector.new(x,y,z))
-                       if distance <= range and distance >= range-1 then                       
+                       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
-                                       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
-                                               break
-                                       elseif node2 == "tnt:tnt" then
-                                               data[n_pos] = air
-                                               local obj = minetest.add_entity(vector.new(pointed_thing.under.x,pointed_thing.under.y,pointed_thing.under.z), "tnt:tnt",minetest.serialize({do_ignition_particles=true,timer = math.random()}))
-                                       else
-                                               data[n_pos] = air
-                                               minetest.after(0, function(pointed_thing)
-                                                       minetest.check_for_falling(vector.new(pointed_thing.under.x,pointed_thing.under.y+1,pointed_thing.under.z))
-                                               end,pointed_thing)
-                                               if math.random()>0.999 then
-                                                       if n ~= "nether:obsidian" and n ~= "nether:bedrock" then
-                                                               local item = minetest.get_node_drops(n, "main:diamondpick")[1]
-                                                               local ppos = vector.new(pointed_thing.under.x,pointed_thing.under.y,pointed_thing.under.z)
-                                                               local obj = minetest.add_item(ppos, item)
-                                                               if obj then
-                                                                       local power = (range - vector.distance(pos,ppos))*2
-                                                                       local dir = vector.subtract(ppos,pos)
-                                                                       local force = vector.multiply(dir,power)
-                                                                       obj:set_velocity(force)
+                                       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
@@ -143,26 +146,28 @@ function tnt(pos,range)
                vm:update_liquids()
                vm:write_to_map()
        end
-       
-       minetest.sound_play("tnt_explode", {pos = pos, gain = 1.0, max_hear_distance = range*range}) --hear twice as far away
+       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
        
        --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
-                       local do_it = true
+                       do_it = true
                        if not object:is_player() and object:get_luaentity().name == "tnt:tnt" then
-                               local in_node = minetest.get_node(object:get_pos()).name
+                               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
-                               local ppos = object:get_pos()
+                               ppos = object:get_pos()
                                if object:is_player() then
                                        ppos.y = ppos.y + 1
                                end
                                ray = minetest.raycast(pos, ppos, false, false)
-                               local clear = true
+                               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])
@@ -171,15 +176,19 @@ function tnt(pos,range)
                                        end
                                end
                                if clear == true then
-                                       local power = (range - vector.distance(pos,ppos))*10
-                                       
-                                       local dir = vector.direction(pos,ppos)
-                                       local force = vector.multiply(dir,power)
+                                       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
-                                               local hp = object:get_hp()
-                                               if hp then
-                                                       object:set_hp(hp - math.floor(power*2))
+                                               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
@@ -189,10 +198,12 @@ function tnt(pos,range)
                                                        object:punch(object, 2, 
                                                                {
                                                                full_punch_interval=1.5,
-                                                               damage_groups = {damage=math.floor(power*2)},
+                                                               damage_groups = {damage=math.floor(power)},
                                                                })
-                                                       object:set_velocity(force)
+                                               elseif object:get_luaentity().name == "__builtin:item" then
+                                                       object:get_luaentity().poll_timer = 0
                                                end
+                                               object:set_velocity(force)
                                        end
                                end
                        end
@@ -200,14 +211,13 @@ function tnt(pos,range)
        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,
+               amount = range,
                time = 0.001,
                minpos = pos,
                maxpos = pos,
@@ -226,6 +236,68 @@ function tnt(pos,range)
        })
 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 = 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 = {
@@ -246,74 +318,27 @@ minetest.register_entity("tnt:tnt", {
        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,
-                       exploded = self.exploded,       
-               })
+               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(-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 = 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 = self.range*self.range*self.range})
-               end
+               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:get_pos(), "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
-               if not self.shot or not self.redstone_activated then
-                       local vel = self.object:getvelocity()
-                       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
-                       tnt(self.object:get_pos(),self.range)
-                       self.object:remove()
-               end
+               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"},
@@ -321,21 +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"},
@@ -353,7 +378,7 @@ minetest.register_node("tnt:uranium_tnt", {
 })
 
 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"},
@@ -376,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"},
        },
 })