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