ShadowNinja
2013-12-17 bab8517b2a07e41ea3b9122cb9d93d10bba3e430
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)
bab851 63     if minetest.is_protected(pos, player:get_player_name()) then
S 64         minetest.record_protection_violation(pos, player:get_player_name())
65         return
66     end
f90915 67     local node = minetest.get_node(pos)
H 68     if node.name == "air"
69     or node.name == "ignore"
70     or node.name == "default:lava_source"
71     or node.name == "default:lava_flowing" then
72         return
73     end
74     if node.name == "default:water_source"
75     or node.name == "default:water_flowing" then
76         minetest.remove_node(pos)
77         minetest.add_particle(pos,
78                 {x=0, y=2, z=0},
79                 {x=0, y=-1, z=0},
80                 1.5,
81                 8,
82                 false,
83                 "smoke_puff.png")
84         return
85     end
86     if player then
87         minetest.node_dig(pos, node, player)
88     end
89 end
90
91 local function laser_nodes(pos, dir, player, range)
92     local t_dir = get_used_dir(dir)
93     local dir_typ = t_dir[1]
94     if t_dir[3] == "+" then
95         f_tab = {0, range}
96     else
97         f_tab = {-range,0}
98     end
99     local d_ch = t_dir[2]
100     if dir_typ == "x" then
101         for d = f_tab[1],f_tab[2],1 do
102             local x = d
103             local ytab = node_tab(d_ch.y, d)
104             local ztab = node_tab(d_ch.z, d)
105             for _, y in pairs(ytab) do
106                 for _, z in pairs(ztab) do
107                     laser_node({x = pos.x + x, y = pos.y + y, z = pos.z + z}, player)
108                 end
109             end
110         end
111         return
112     end
113     if dir_typ == "y" then
114         for d = f_tab[1], f_tab[2] do
115             local xtab = node_tab(d_ch.x, d)
116             local y = d
117             local ztab = node_tab(d_ch.z, d)
118             for _, x in pairs(xtab) do
119                 for _, z in pairs(ztab) do
120                     laser_node({x = pos.x + x, y = pos.y + y, z = pos.z + z}, player)
121                 end
122             end
123         end
124         return
125     end
126     for d = f_tab[1], f_tab[2] do
127         local xtab = node_tab(d_ch.x, d)
128         local ytab = node_tab(d_ch.y, d)
129         local z = d
130         for _, x in pairs(xtab) do
131             for _, y in pairs(ytab) do
132                 laser_node({x = pos.x + x, y = pos.y + y, z = pos.z + z}, player)
133             end
134         end
135     end
136 end
137
138 local function laser_shoot(player, range, particle_texture, sound)
139     local playerpos = player:getpos()
140     local dir = player:get_look_dir()
141
142     local startpos = {x = playerpos.x, y = playerpos.y + 1.6, z = playerpos.z}
143     local mult_dir = vector.multiply(dir, 50)
144     minetest.add_particle(startpos, dir, mult_dir, range / 11, 1, false, particle_texture)
145     laser_nodes(vector.round(startpos), dir, player, range)
146     minetest.sound_play(sound, {pos = playerpos, gain = 1.0, max_hear_distance = range})
147 end
148
149
150 for _, m in pairs(mining_lasers_list) do
151     technic.register_power_tool("technic:laser_mk"..m[1], m[3])
152     minetest.register_tool("technic:laser_mk"..m[1], {
153         description = S("Mining Laser Mk%d"):format(m[1]),
154         inventory_image = "technic_mining_laser_mk"..m[1]..".png",
155         stack_max = 1,
156         on_use = function(itemstack, user)
5cf765 157             local meta = minetest.deserialize(itemstack:get_metadata())
f90915 158             if not meta or not meta.charge then
H 159                 return
160             end
161             if meta.charge - 400 > 0 then
162                 laser_shoot(user, m[2], "technic_laser_beam_mk"..m[1]..".png", "technic_laser_mk"..m[1])
163                 meta.charge = meta.charge - 400
164                 technic.set_RE_wear(itemstack, meta.charge, m[3])
5cf765 165                 itemstack:set_metadata(minetest.serialize(meta))
f90915 166             end
H 167             return itemstack
168         end,
169     })
170 end
171