]> git.lizzy.rs Git - Crafter.git/blob - mods/tnt/init.lua
Make tnt explode with redstone
[Crafter.git] / mods / tnt / init.lua
1 --here is where tnt is defined
2
3 local function tnt(pos,range)
4         local pos = vector.floor(vector.add(pos,0.5))
5         
6         --throw players and items
7         for _,object in ipairs(minetest.get_objects_inside_radius(pos, range)) do
8                 if  object:is_player() then 
9                         local ppos = object:getpos()
10                         local power = (range - vector.distance(pos,ppos))*2
11                         local distance = vector.subtract(ppos,pos)
12                         local force = vector.multiply(distance,power)
13                         object:add_player_velocity(force)
14                 elseif object:get_luaentity() and object:get_luaentity().name == "__builtin:item" then
15                         local ppos = object:getpos()
16                         local power = (range - vector.distance(pos,ppos))*2
17                         local distance = vector.subtract(pos,ppos)
18                         local force = vector.multiply(distance,power)
19                         object:setvelocity(force)
20                 end
21         end
22                         
23         
24         
25         local min = vector.add(pos,range)
26         local max = vector.subtract(pos,range)
27         local vm = minetest.get_voxel_manip()   
28         local emin, emax = vm:read_from_map(min,max)
29         local area = VoxelArea:new{MinEdge=emin, MaxEdge=emax}
30         local data = vm:get_data()
31         
32         local air = minetest.get_content_id("air")
33         local content_id = minetest.get_name_from_content_id
34         
35         local pos2 = vector.new(0,0,0)
36         
37         for x=-range, range do
38         for y=-range, range do
39         for z=-range, range do
40                 if vector.distance(pos2, vector.new(x,y,z)) <= range then
41                         local p_pos = area:index(pos.x+x,pos.y+y,pos.z+z)                                                       
42                         local n = content_id(data[p_pos])
43                         if n == "tnt:tnt" then
44                                 --print("adding tnt")
45                                 local obj = minetest.add_entity(vector.new(pos.x+x,pos.y+y,pos.z+z),"tnt:tnt")
46                                 obj:get_luaentity().range = 5
47                                 obj:get_luaentity().timer = math.random(1,10)*math.random()
48                                 --minetest.sound_play("tnt_ignite", {object=obj, gain = 1.0, max_hear_distance = range*range*range})
49                         elseif n ~= "air" and n ~= "ignore" then
50                                 if math.random()>0.99 then
51                                         local item = minetest.get_node_drops(n, "main:diamondpick")[1]
52                                         minetest.add_item(vector.new(pos.x+x,pos.y+y,pos.z+z), item)
53                                 end
54                         end
55                         
56                         data[p_pos] = air
57                 end
58         end
59         end
60         end
61         
62         vm:set_data(data)
63         vm:write_to_map()
64         vm:update_map()
65         
66         minetest.sound_play("tnt_explode", {pos = pos, gain = 1.0, max_hear_distance = range*range*range})
67         
68         --stop client from lagging
69         local particle = range
70         if particle > 15 then
71                 particle = 15
72         end
73         
74         minetest.add_particlespawner({
75                         amount = particle*particle*particle,
76                         time = 0.001,
77                         minpos = pos,
78                         maxpos = pos,
79                         minvel = vector.new(-range,-range,-range),
80                         maxvel = vector.new(range,range,range),
81                         minacc = {x=0, y=0, z=0},
82                         maxacc = {x=0, y=0, z=0},
83                         minexptime = 1.1,
84                         maxexptime = 1.5,
85                         minsize = 1,
86                         maxsize = 2,
87                         collisiondetection = false,
88                         vertical = false,
89                         texture = "smoke.png",
90                 })
91 end
92
93
94 minetest.register_entity("tnt:tnt", {
95         initial_properties = {
96                 hp_max = 1,
97                 physical = true,
98                 collide_with_objects = false,
99                 collisionbox = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
100                 visual = "cube",
101                 visual_size = {x = 1, y = 1},
102                 textures = {"tnt_top.png", "tnt_bottom.png",
103                         "tnt_side.png", "tnt_side.png",
104                         "tnt_side.png", "tnt_side.png"},
105                 is_visible = true,
106                 pointable = true,
107         },
108
109         timer = 5,
110         range = 7,
111         
112         get_staticdata = function(self)
113                 return minetest.serialize({
114                         range = self.range,
115                         timer = self.timer,                     
116                 })
117         end,
118         
119         on_activate = function(self, staticdata, dtime_s)
120                 self.object:set_armor_groups({immortal = 1})
121                 self.object:set_velocity({x = math.random(-5,5), y = 5, z = math.random(-5,5)})
122                 self.object:set_acceleration({x = 0, y = -9.81, z = 0})
123                 if string.sub(staticdata, 1, string.len("return")) == "return" then
124                         local data = minetest.deserialize(staticdata)
125                         if data and type(data) == "table" then
126                                 self.range = data.range
127                                 self.timer = data.timer
128                         end
129                 end
130                 
131                 minetest.add_particlespawner({
132                         amount = 50,
133                         time = 0,
134                         minpos = pos,
135                         maxpos = pos,
136                         minvel = vector.new(-0.5,1,-0.5),
137                         maxvel = vector.new(0.5,5,0.5),
138                         minacc = {x=0, y=0, z=0},
139                         maxacc = {x=0, y=0, z=0},
140                         minexptime = 1.1,
141                         maxexptime = 1.5,
142                         minsize = 1,
143                         maxsize = 2,
144                         collisiondetection = false,
145                         vertical = false,
146                         texture = "smoke.png",
147                         attached = self.object,
148                 })
149                 minetest.sound_play("tnt_ignite", {object = self.object, gain = 1.0, max_hear_distance = self.range*self.range*self.range})
150         end,
151                 
152         on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, dir)
153                 local obj = minetest.add_item(self.object:getpos(), "tnt:tnt")
154                 self.object:remove()
155         end,
156
157         sound_played = false,
158         on_step = function(self, dtime)
159                 self.timer = self.timer - dtime
160                 local vel = self.object:getvelocity()
161                 vel = vector.multiply(vel,-0.05)
162                 self.object:add_velocity(vector.new(vel.x,0,vel.z))
163                 
164                 if self.timer <= 0 then
165                         local pos = self.object:getpos()
166                         if not self.range then
167                                 self.range = 7
168                         end
169                         tnt(pos,self.range)
170                         self.object:remove()
171                 end
172         end,
173 })
174
175
176 minetest.register_node("tnt:tnt", {
177     description = "Cobblestone",
178     tiles = {"tnt_top.png", "tnt_bottom.png",
179                         "tnt_side.png", "tnt_side.png",
180                         "tnt_side.png", "tnt_side.png"},
181     groups = {stone = 2, hard = 1, pickaxe = 2, hand = 4, redstone_activation = 1},
182     sounds = main.stoneSound(),
183     redstone_activation = function(pos)
184                 local obj = minetest.add_entity(pos,"tnt:tnt")
185                 local range = 7
186                 obj:get_luaentity().range = range
187                 minetest.remove_node(pos)
188     end,
189     on_punch = function(pos, node, puncher, pointed_thing)
190                 local obj = minetest.add_entity(pos,"tnt:tnt")
191                 local range = 7
192                 obj:get_luaentity().range = range
193                 minetest.remove_node(pos)
194     end,
195 })
196
197 minetest.register_node("tnt:uranium_tnt", {
198     description = "Cobblestone",
199     tiles = {"tnt_top.png^[colorize:green:100", "tnt_bottom.png^[colorize:green:100",
200                         "tnt_side.png^[colorize:green:100", "tnt_side.png^[colorize:green:100",
201                         "tnt_side.png^[colorize:green:100", "tnt_side.png^[colorize:green:100"},
202     groups = {stone = 2, hard = 1, pickaxe = 2, hand = 4},
203     sounds = main.stoneSound(),
204     on_punch = function(pos, node, puncher, pointed_thing)
205                 local obj = minetest.add_entity(pos,"tnt:tnt")
206                 local range = 145
207                 obj:get_luaentity().range = range
208                 minetest.remove_node(pos)
209     end,
210 })
211
212 minetest.register_node("tnt:uh_oh", {
213     description = "Cobblestone",
214     tiles = {"tnt_top.png", "tnt_bottom.png",
215                         "tnt_side.png", "tnt_side.png",
216                         "tnt_side.png", "tnt_side.png"},
217     groups = {stone = 2, hard = 1, pickaxe = 2, hand = 4},
218     sounds = main.stoneSound(),
219     on_punch = function(pos, node, puncher, pointed_thing)
220                 local range = 10
221                 for x=-range, range do
222                 for y=-range, range do
223                 for z=-range, range do 
224                         minetest.add_node(vector.new(pos.x+x,pos.y+y,pos.z+z),{name="tnt:tnt"})
225                 end
226                 end
227                 end
228     end,
229 })
230
231
232
233 minetest.register_craft({
234         output = "tnt:tnt",
235         recipe = {
236                 {"main:wood", "main:wood", "main:wood"},
237                 {"main:wood", "main:coal", "main:wood"},
238                 {"main:wood", "main:wood", "main:wood"},
239         },
240 })