MT-Modder
2015-03-01 b8c902868115a0a607da35e208a422e430d46317
commit | author | age
f90915 1 local mining_lasers_list = {
a6dae8 2 --    {<num>, <range of the laser shots>, <max_charge>, <charge_per_shot>},
BM 3     {"1", 7, 50000, 1000},
4     {"2", 14, 200000, 2000},
5     {"3", 21, 650000, 3000},
f90915 6 }
H 7
8 local S = technic.getter
9
2d7c1d 10 minetest.register_craft({
S 11     output = 'technic:laser_mk1',
12     recipe = {
5e4a87 13         {'default:diamond', 'technic:brass_ingot',        'default:obsidian_glass'},
Z 14         {'',                'technic:brass_ingot',        'technic:red_energy_crystal'},
68b7bc 15         {'',                '',                           'default:copper_ingot'},
49052d 16     }
BM 17 })
18 minetest.register_craft({
19     output = 'technic:laser_mk2',
20     recipe = {
68b7bc 21         {'default:diamond', 'technic:carbon_steel_ingot', 'technic:laser_mk1'},
Z 22         {'',                'technic:carbon_steel_ingot', 'technic:green_energy_crystal'},
23         {'',                '',                           'default:copper_ingot'},
49052d 24     }
BM 25 })
26 minetest.register_craft({
27     output = 'technic:laser_mk3',
28     recipe = {
68b7bc 29         {'default:diamond', 'technic:carbon_steel_ingot', 'technic:laser_mk2'},
Z 30         {'',                'technic:carbon_steel_ingot', 'technic:blue_energy_crystal'},
31         {'',                '',                           'default:copper_ingot'},
2d7c1d 32     }
S 33 })
34
42d008 35 -- Based on code by Uberi: https://gist.github.com/Uberi/3125280
S 36 local function rayIter(pos, dir, range)
37     local p = vector.round(pos)
38     local x_step,      y_step,      z_step      = 0, 0, 0
39     local x_component, y_component, z_component = 0, 0, 0
40     local x_intersect, y_intersect, z_intersect = 0, 0, 0
41
42     if dir.x == 0 then
43         x_intersect = math.huge
44     elseif dir.x > 0 then
45         x_step = 1
46         x_component = 1 / dir.x
47         x_intersect = x_component
48     else
49         x_step = -1
50         x_component = 1 / -dir.x
f90915 51     end
42d008 52     if dir.y == 0 then
S 53         y_intersect = math.huge
54     elseif dir.y > 0 then
55         y_step = 1
56         y_component = 1 / dir.y
57         y_intersect = y_component
58     else
59         y_step = -1
60         y_component = 1 / -dir.y
61     end
62     if dir.z == 0 then
63         z_intersect = math.huge
64     elseif dir.z > 0 then
65         z_step = 1
66         z_component = 1 / dir.z
67         z_intersect = z_component
68     else
69         z_step = -1
70         z_component = 1 / -dir.z
71     end
72
73     return function()
74         if x_intersect < y_intersect then
75             if x_intersect < z_intersect then
76                 p.x = p.x + x_step
77                 x_intersect = x_intersect + x_component
78             else
79                 p.z = p.z + z_step
80                 z_intersect = z_intersect + z_component
81             end
82         elseif y_intersect < z_intersect then
83             p.y = p.y + y_step
84             y_intersect = y_intersect + y_component
85         else
86             p.z = p.z + z_step
87             z_intersect = z_intersect + z_component
88         end
89         if vector.distance(pos, p) > range then
90             return nil
91         end
92         return p
93     end
f90915 94 end
H 95
42d008 96 local function laser_node(pos, node, player)
S 97     local def = minetest.registered_nodes[node.name]
98     if def and def.liquidtype ~= "none" then
f90915 99         minetest.remove_node(pos)
4d1f97 100         minetest.add_particle({
H 101             pos = pos,
102             vel = {x=0, y=2, z=0},
103             acc = {x=0, y=-1, z=0},
104             expirationtime = 1.5,
42d008 105             size = 6 + math.random() * 2,
S 106             texture = "smoke_puff.png^[transform" .. math.random(0, 7),
4d1f97 107         })
f90915 108         return
H 109     end
42d008 110     minetest.node_dig(pos, node, player)
f90915 111 end
H 112
42d008 113 local no_destroy = {
S 114     ["air"] = true,
115     ["default:lava_source"] = true,
116     ["default:lava_flowing"] = true,
117 }
f90915 118 local function laser_shoot(player, range, particle_texture, sound)
42d008 119     local player_pos = player:getpos()
S 120     local player_name = player:get_player_name()
f90915 121     local dir = player:get_look_dir()
H 122
42d008 123     local start_pos = vector.new(player_pos)
S 124     -- Adjust to head height
125     start_pos.y = start_pos.y + 1.9
4d1f97 126     minetest.add_particle({
H 127         pos = startpos,
128         vel = dir,
42d008 129         acc = vector.multiply(dir, 50),
4d1f97 130         expirationtime = range / 11,
H 131         size = 1,
42d008 132         texture = particle_texture .. "^[transform" .. math.random(0, 7),
4d1f97 133     })
42d008 134     minetest.sound_play(sound, {pos = player_pos, max_hear_distance = range})
S 135     for pos in rayIter(start_pos, dir, range) do
136         if minetest.is_protected(pos, player_name) then
137             minetest.record_protection_violation(pos, player_name)
138             break
139         end
140         local node = minetest.get_node_or_nil(pos)
141         if not node then
142             break
143         end
144         if not no_destroy[node.name] then
145             laser_node(pos, node, player)
146         end
4d1f97 147     end
f90915 148 end
H 149
150
151 for _, m in pairs(mining_lasers_list) do
152     technic.register_power_tool("technic:laser_mk"..m[1], m[3])
153     minetest.register_tool("technic:laser_mk"..m[1], {
154         description = S("Mining Laser Mk%d"):format(m[1]),
155         inventory_image = "technic_mining_laser_mk"..m[1]..".png",
156         stack_max = 1,
99fd5d 157         wear_represents = "technic_RE_charge",
00d7c9 158         on_refill = technic.refill_RE_charge,
f90915 159         on_use = function(itemstack, user)
5cf765 160             local meta = minetest.deserialize(itemstack:get_metadata())
f90915 161             if not meta or not meta.charge then
H 162                 return
163             end
a6dae8 164
BM 165             -- If there's enough charge left, fire the laser
166             if meta.charge >= m[4] then
f90915 167                 laser_shoot(user, m[2], "technic_laser_beam_mk"..m[1]..".png", "technic_laser_mk"..m[1])
b8c902 168                 if not technic.creative_mode then
M 169                     meta.charge = meta.charge - m[4]
170                     technic.set_RE_wear(itemstack, meta.charge, m[3])
171                     itemstack:set_metadata(minetest.serialize(meta))
172                 end
f90915 173             end
H 174             return itemstack
175         end,
176     })
177 end
178