ShadowNinja
2013-12-17 5cf765b2f19ef9bf443178e26787fe16233b3f4c
commit | author | age
f90915 1
H 2 local r_corr = 0.25 -- Remove a bit more nodes (if shooting diagonal) to let it look like a hole (sth like antialiasing)
3 local mk1_charge = 40000
4
5 local mining_lasers_list = {
6 --    {<num>, <range of the laser shots>, <max_charge>},
7     {"1",  7, mk1_charge},
8     {"2", 11, mk1_charge * 4},
9     {"3", 30, mk1_charge * 16},
10 }
11
12 local f_1 = 0.5 - r_corr
13 local f_2 = 0.5 + r_corr
14
15 local S = technic.getter
16
2d7c1d 17 minetest.register_craft({
S 18     output = 'technic:laser_mk1',
19     recipe = {
20         {'default:diamond', 'default:steel_ingot', 'technic:battery'},
21         {'',                'default:steel_ingot', 'technic:battery'},
22         {'',                '',                    'default:copper_ingot'},
23     }
24 })
25
26
f90915 27 local function get_used_dir(dir)
H 28     local abs_dir = {x = math.abs(dir.x),
29             y = math.abs(dir.y),
30             z = math.abs(dir.z)}
31     local dir_max = math.max(abs_dir.x, abs_dir.y, abs_dir.z)
32     if dir_max == abs_dir.x then
33         local tab = {"x", {x = 1, y = dir.y / dir.x, z = dir.z / dir.x}}
34         if dir.x >= 0 then
35             tab[3] = "+"
36         end
37         return tab
38     end
39     if dir_max == abs_dir.y then
40         local tab = {"y", {x = dir.x / dir.y, y = 1, z = dir.z / dir.y}}
41         if dir.y >= 0 then
42             tab[3] = "+"
43         end
44         return tab
45     end
46     local tab = {"z", {x = dir.x / dir.z, y = dir.y / dir.z, z = 1}}
47     if dir.z >= 0 then
48         tab[3] = "+"
49     end
50     return tab
51 end
52
53 local function node_tab(z, d)
54     local n1 = math.floor(z * d + f_1)
55     local n2 = math.floor(z * d + f_2)
56     if n1 == n2 then
57         return {n1}
58     end
59     return {n1, n2}
60 end
61
62 local function laser_node(pos, player)
63     local node = minetest.get_node(pos)
64     if node.name == "air"
65     or node.name == "ignore"
66     or node.name == "default:lava_source"
67     or node.name == "default:lava_flowing" then
68         return
69     end
70     if node.name == "default:water_source"
71     or node.name == "default:water_flowing" then
72         minetest.remove_node(pos)
73         minetest.add_particle(pos,
74                 {x=0, y=2, z=0},
75                 {x=0, y=-1, z=0},
76                 1.5,
77                 8,
78                 false,
79                 "smoke_puff.png")
80         return
81     end
82     if player then
83         minetest.node_dig(pos, node, player)
84     end
85 end
86
87 local function laser_nodes(pos, dir, player, range)
88     local t_dir = get_used_dir(dir)
89     local dir_typ = t_dir[1]
90     if t_dir[3] == "+" then
91         f_tab = {0, range}
92     else
93         f_tab = {-range,0}
94     end
95     local d_ch = t_dir[2]
96     if dir_typ == "x" then
97         for d = f_tab[1],f_tab[2],1 do
98             local x = d
99             local ytab = node_tab(d_ch.y, d)
100             local ztab = node_tab(d_ch.z, d)
101             for _, y in pairs(ytab) do
102                 for _, z in pairs(ztab) do
103                     laser_node({x = pos.x + x, y = pos.y + y, z = pos.z + z}, player)
104                 end
105             end
106         end
107         return
108     end
109     if dir_typ == "y" then
110         for d = f_tab[1], f_tab[2] do
111             local xtab = node_tab(d_ch.x, d)
112             local y = d
113             local ztab = node_tab(d_ch.z, d)
114             for _, x in pairs(xtab) do
115                 for _, z in pairs(ztab) do
116                     laser_node({x = pos.x + x, y = pos.y + y, z = pos.z + z}, player)
117                 end
118             end
119         end
120         return
121     end
122     for d = f_tab[1], f_tab[2] do
123         local xtab = node_tab(d_ch.x, d)
124         local ytab = node_tab(d_ch.y, d)
125         local z = d
126         for _, x in pairs(xtab) do
127             for _, y in pairs(ytab) do
128                 laser_node({x = pos.x + x, y = pos.y + y, z = pos.z + z}, player)
129             end
130         end
131     end
132 end
133
134 local function laser_shoot(player, range, particle_texture, sound)
135     local playerpos = player:getpos()
136     local dir = player:get_look_dir()
137
138     local startpos = {x = playerpos.x, y = playerpos.y + 1.6, z = playerpos.z}
139     local mult_dir = vector.multiply(dir, 50)
140     minetest.add_particle(startpos, dir, mult_dir, range / 11, 1, false, particle_texture)
141     laser_nodes(vector.round(startpos), dir, player, range)
142     minetest.sound_play(sound, {pos = playerpos, gain = 1.0, max_hear_distance = range})
143 end
144
145
146 for _, m in pairs(mining_lasers_list) do
147     technic.register_power_tool("technic:laser_mk"..m[1], m[3])
148     minetest.register_tool("technic:laser_mk"..m[1], {
149         description = S("Mining Laser Mk%d"):format(m[1]),
150         inventory_image = "technic_mining_laser_mk"..m[1]..".png",
151         stack_max = 1,
152         on_use = function(itemstack, user)
5cf765 153             local meta = minetest.deserialize(itemstack:get_metadata())
f90915 154             if not meta or not meta.charge then
H 155                 return
156             end
157             if meta.charge - 400 > 0 then
158                 laser_shoot(user, m[2], "technic_laser_beam_mk"..m[1]..".png", "technic_laser_mk"..m[1])
159                 meta.charge = meta.charge - 400
160                 technic.set_RE_wear(itemstack, meta.charge, m[3])
5cf765 161                 itemstack:set_metadata(minetest.serialize(meta))
f90915 162             end
H 163             return itemstack
164         end,
165     })
166 end
167