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