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 |
|