]> git.lizzy.rs Git - Crafter.git/blob - mods/tnt/init.lua
Make tnt throw players and items
[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         
111         get_staticdata = function(self)
112                 return minetest.serialize({
113                         range = self.range,
114                         timer = self.timer,                     
115                 })
116         end,
117         
118         on_activate = function(self, staticdata, dtime_s)
119                 self.object:set_armor_groups({immortal = 1})
120                 self.object:set_velocity({x = math.random(-5,5), y = 5, z = math.random(-5,5)})
121                 self.object:set_acceleration({x = 0, y = -9.81, z = 0})
122                 if string.sub(staticdata, 1, string.len("return")) == "return" then
123                         local data = minetest.deserialize(staticdata)
124                         if data and type(data) == "table" then
125                                 self.range = data.range
126                                 self.timer = data.timer
127                         end
128                 end
129                 
130                 minetest.add_particlespawner({
131                         amount = 50,
132                         time = 0,
133                         minpos = pos,
134                         maxpos = pos,
135                         minvel = vector.new(-0.5,1,-0.5),
136                         maxvel = vector.new(0.5,5,0.5),
137                         minacc = {x=0, y=0, z=0},
138                         maxacc = {x=0, y=0, z=0},
139                         minexptime = 1.1,
140                         maxexptime = 1.5,
141                         minsize = 1,
142                         maxsize = 2,
143                         collisiondetection = false,
144                         vertical = false,
145                         texture = "smoke.png",
146                         attached = self.object,
147                 })
148         end,
149                 
150         on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, dir)
151                 local obj = minetest.add_item(self.object:getpos(), "tnt:tnt")
152                 obj:get_luaentity().collection_timer = 2
153                 self.object:remove()
154         end,
155
156         sound_played = false,
157         on_step = function(self, dtime)
158                 self.timer = self.timer - dtime
159                 local vel = self.object:getvelocity()
160                 vel = vector.multiply(vel,-0.05)
161                 self.object:add_velocity(vector.new(vel.x,0,vel.z))
162                 
163                 if self.timer <= 0 then
164                         local pos = self.object:getpos()
165                         if not self.range then
166                                 self.range = 7
167                         end
168                         tnt(pos,self.range)
169                         self.object:remove()
170                 end
171         end,
172 })
173
174
175 minetest.register_node("tnt:tnt", {
176     description = "Cobblestone",
177     tiles = {"tnt_top.png", "tnt_bottom.png",
178                         "tnt_side.png", "tnt_side.png",
179                         "tnt_side.png", "tnt_side.png"},
180     groups = {stone = 2, hard = 1, pickaxe = 2, hand = 4},
181     sounds = main.stoneSound(),
182     on_punch = function(pos, node, puncher, pointed_thing)
183                 local obj = minetest.add_entity(pos,"tnt:tnt")
184                 local range = 7
185                 obj:get_luaentity().range = range
186                 minetest.sound_play("tnt_ignite", {object = obj, gain = 1.0, max_hear_distance = range*range*range})
187                 minetest.remove_node(pos)
188     end,
189 })
190
191 minetest.register_node("tnt:uh_oh", {
192     description = "Cobblestone",
193     tiles = {"tnt_top.png", "tnt_bottom.png",
194                         "tnt_side.png", "tnt_side.png",
195                         "tnt_side.png", "tnt_side.png"},
196     groups = {stone = 2, hard = 1, pickaxe = 2, hand = 4},
197     sounds = main.stoneSound(),
198     on_punch = function(pos, node, puncher, pointed_thing)
199                 local range = 10
200                 for x=-range, range do
201                 for y=-range, range do
202                 for z=-range, range do 
203                         minetest.add_node(vector.new(pos.x+x,pos.y+y,pos.z+z),{name="tnt:tnt"})
204                 end
205                 end
206                 end
207     end,
208 })
209
210
211
212 minetest.register_craft({
213         output = "tnt:tnt",
214         recipe = {
215                 {"main:wood", "main:wood", "main:wood"},
216                 {"main:wood", "main:coal", "main:wood"},
217                 {"main:wood", "main:wood", "main:wood"},
218         },
219 })