mirror of
https://github.com/minetest-mods/technic.git
synced 2024-12-25 10:20:37 +01:00
update mining lasers
This commit is contained in:
parent
6d90ebb94e
commit
4d1f9753e3
@ -5,3 +5,4 @@ bucket?
|
|||||||
mesecons_mvps?
|
mesecons_mvps?
|
||||||
intllib?
|
intllib?
|
||||||
unified_inventory?
|
unified_inventory?
|
||||||
|
vector_extras?
|
||||||
|
@ -1,6 +1,3 @@
|
|||||||
|
|
||||||
local r_corr = 0.25 -- Remove a bit more nodes (if shooting diagonal) to let it look like a hole (sth like antialiasing)
|
|
||||||
|
|
||||||
local mining_lasers_list = {
|
local mining_lasers_list = {
|
||||||
-- {<num>, <range of the laser shots>, <max_charge>, <charge_per_shot>},
|
-- {<num>, <range of the laser shots>, <max_charge>, <charge_per_shot>},
|
||||||
{"1", 7, 50000, 1000},
|
{"1", 7, 50000, 1000},
|
||||||
@ -8,9 +5,6 @@ local mining_lasers_list = {
|
|||||||
{"3", 21, 650000, 3000},
|
{"3", 21, 650000, 3000},
|
||||||
}
|
}
|
||||||
|
|
||||||
local f_1 = 0.5 - r_corr
|
|
||||||
local f_2 = 0.5 + r_corr
|
|
||||||
|
|
||||||
local S = technic.getter
|
local S = technic.getter
|
||||||
|
|
||||||
minetest.register_craft({
|
minetest.register_craft({
|
||||||
@ -38,64 +32,35 @@ minetest.register_craft({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
local function table_icontains(t, v)
|
||||||
local function get_used_dir(dir)
|
for i = 1,#t do
|
||||||
local abs_dir = {x = math.abs(dir.x),
|
if v == t[i] then
|
||||||
y = math.abs(dir.y),
|
return true
|
||||||
z = math.abs(dir.z)}
|
|
||||||
local dir_max = math.max(abs_dir.x, abs_dir.y, abs_dir.z)
|
|
||||||
if dir_max == abs_dir.x then
|
|
||||||
local tab = {"x", {x = 1, y = dir.y / dir.x, z = dir.z / dir.x}}
|
|
||||||
if dir.x >= 0 then
|
|
||||||
tab[3] = "+"
|
|
||||||
end
|
end
|
||||||
return tab
|
|
||||||
end
|
end
|
||||||
if dir_max == abs_dir.y then
|
return false
|
||||||
local tab = {"y", {x = dir.x / dir.y, y = 1, z = dir.z / dir.y}}
|
|
||||||
if dir.y >= 0 then
|
|
||||||
tab[3] = "+"
|
|
||||||
end
|
|
||||||
return tab
|
|
||||||
end
|
|
||||||
local tab = {"z", {x = dir.x / dir.z, y = dir.y / dir.z, z = 1}}
|
|
||||||
if dir.z >= 0 then
|
|
||||||
tab[3] = "+"
|
|
||||||
end
|
|
||||||
return tab
|
|
||||||
end
|
|
||||||
|
|
||||||
local function node_tab(z, d)
|
|
||||||
local n1 = math.floor(z * d + f_1)
|
|
||||||
local n2 = math.floor(z * d + f_2)
|
|
||||||
if n1 == n2 then
|
|
||||||
return {n1}
|
|
||||||
end
|
|
||||||
return {n1, n2}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local function laser_node(pos, player)
|
local function laser_node(pos, player)
|
||||||
local node = minetest.get_node(pos)
|
local node = minetest.get_node(pos)
|
||||||
if node.name == "air"
|
if table_icontains({"air", "ignore", "default:lava_source", "default:lava_flowing"}, node.name) then
|
||||||
or node.name == "ignore"
|
|
||||||
or node.name == "default:lava_source"
|
|
||||||
or node.name == "default:lava_flowing" then
|
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
if minetest.is_protected(pos, player:get_player_name()) then
|
local pname = player:get_player_name()
|
||||||
minetest.record_protection_violation(pos, player:get_player_name())
|
if minetest.is_protected(pos, pname) then
|
||||||
|
minetest.record_protection_violation(pos, pname)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
if node.name == "default:water_source"
|
if table_icontains({"default:water_flowing", "default:water_source"}, node.name) then
|
||||||
or node.name == "default:water_flowing" then
|
|
||||||
minetest.remove_node(pos)
|
minetest.remove_node(pos)
|
||||||
minetest.add_particle(pos,
|
minetest.add_particle({
|
||||||
{x=0, y=2, z=0},
|
pos = pos,
|
||||||
{x=0, y=-1, z=0},
|
vel = {x=0, y=2, z=0},
|
||||||
1.5,
|
acc = {x=0, y=-1, z=0},
|
||||||
8,
|
expirationtime = 1.5,
|
||||||
false,
|
size = 6+math.random()*2,
|
||||||
"smoke_puff.png")
|
texture = "smoke_puff.png^[transform"..math.random(0,7),
|
||||||
|
})
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
if player then
|
if player then
|
||||||
@ -103,62 +68,28 @@ local function laser_node(pos, player)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function laser_nodes(pos, dir, player, range)
|
if not vector.line then
|
||||||
local t_dir = get_used_dir(dir)
|
dofile(technic.modpath.."/tools/vector_line.lua")
|
||||||
local dir_typ = t_dir[1]
|
|
||||||
if t_dir[3] == "+" then
|
|
||||||
f_tab = {1, range}
|
|
||||||
else
|
|
||||||
f_tab = {-range, -1}
|
|
||||||
end
|
|
||||||
local d_ch = t_dir[2]
|
|
||||||
if dir_typ == "x" then
|
|
||||||
for d = f_tab[1],f_tab[2],1 do
|
|
||||||
local x = d
|
|
||||||
local ytab = node_tab(d_ch.y, d)
|
|
||||||
local ztab = node_tab(d_ch.z, d)
|
|
||||||
for _, y in pairs(ytab) do
|
|
||||||
for _, z in pairs(ztab) do
|
|
||||||
laser_node({x = pos.x + x, y = pos.y + y, z = pos.z + z}, player)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return
|
|
||||||
end
|
|
||||||
if dir_typ == "y" then
|
|
||||||
for d = f_tab[1], f_tab[2] do
|
|
||||||
local xtab = node_tab(d_ch.x, d)
|
|
||||||
local y = d
|
|
||||||
local ztab = node_tab(d_ch.z, d)
|
|
||||||
for _, x in pairs(xtab) do
|
|
||||||
for _, z in pairs(ztab) do
|
|
||||||
laser_node({x = pos.x + x, y = pos.y + y, z = pos.z + z}, player)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return
|
|
||||||
end
|
|
||||||
for d = f_tab[1], f_tab[2] do
|
|
||||||
local xtab = node_tab(d_ch.x, d)
|
|
||||||
local ytab = node_tab(d_ch.y, d)
|
|
||||||
local z = d
|
|
||||||
for _, x in pairs(xtab) do
|
|
||||||
for _, y in pairs(ytab) do
|
|
||||||
laser_node({x = pos.x + x, y = pos.y + y, z = pos.z + z}, player)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local function laser_shoot(player, range, particle_texture, sound)
|
local function laser_shoot(player, range, particle_texture, sound)
|
||||||
local playerpos = player:getpos()
|
local playerpos = player:getpos()
|
||||||
local dir = player:get_look_dir()
|
local dir = player:get_look_dir()
|
||||||
|
|
||||||
local startpos = {x = playerpos.x, y = playerpos.y + 1.6, z = playerpos.z}
|
local startpos = {x = playerpos.x, y = playerpos.y + 1.625, z = playerpos.z}
|
||||||
local mult_dir = vector.multiply(dir, 50)
|
local mult_dir = vector.multiply(dir, 50)
|
||||||
minetest.add_particle(startpos, dir, mult_dir, range / 11, 1, false, particle_texture)
|
minetest.add_particle({
|
||||||
laser_nodes(vector.round(startpos), dir, player, range)
|
pos = startpos,
|
||||||
minetest.sound_play(sound, {pos = playerpos, gain = 1.0, max_hear_distance = range})
|
vel = dir,
|
||||||
|
acc = mult_dir,
|
||||||
|
expirationtime = range / 11,
|
||||||
|
size = 1,
|
||||||
|
texture = particle_texture.."^[transform"..math.random(0,7),
|
||||||
|
})
|
||||||
|
for _,pos in ipairs(vector.line(vector.round(startpos), dir, range)) do
|
||||||
|
laser_node(pos, player)
|
||||||
|
end
|
||||||
|
minetest.sound_play(sound, {pos = playerpos, max_hear_distance = range})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
83
technic/tools/vector_line.lua
Normal file
83
technic/tools/vector_line.lua
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
local twolines = {}
|
||||||
|
function vector.twoline(x, y)
|
||||||
|
local pstr = x.." "..y
|
||||||
|
local line = twolines[pstr]
|
||||||
|
if line then
|
||||||
|
return line
|
||||||
|
end
|
||||||
|
line = {}
|
||||||
|
local n = 1
|
||||||
|
local dirx = 1
|
||||||
|
if x < 0 then
|
||||||
|
dirx = -dirx
|
||||||
|
end
|
||||||
|
local ymin, ymax = 0, y
|
||||||
|
if y < 0 then
|
||||||
|
ymin, ymax = ymax, ymin
|
||||||
|
end
|
||||||
|
local m = y/x --y/0 works too
|
||||||
|
local dir = 1
|
||||||
|
if m < 0 then
|
||||||
|
dir = -dir
|
||||||
|
end
|
||||||
|
for i = 0,x,dirx do
|
||||||
|
local p1 = math.max(math.min(math.floor((i-0.5)*m+0.5), ymax), ymin)
|
||||||
|
local p2 = math.max(math.min(math.floor((i+0.5)*m+0.5), ymax), ymin)
|
||||||
|
for j = p1,p2,dir do
|
||||||
|
line[n] = {i, j}
|
||||||
|
n = n+1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
twolines[pstr] = line
|
||||||
|
return line
|
||||||
|
end
|
||||||
|
|
||||||
|
local threelines = {}
|
||||||
|
function vector.threeline(x, y, z)
|
||||||
|
local pstr = x.." "..y.." "..z
|
||||||
|
local line = threelines[pstr]
|
||||||
|
if line then
|
||||||
|
return line
|
||||||
|
end
|
||||||
|
if x ~= math.floor(x) then
|
||||||
|
print("[technic] INFO: The position used for vector.threeline isn't round.")
|
||||||
|
end
|
||||||
|
local two_line = vector.twoline(x, y)
|
||||||
|
line = {}
|
||||||
|
local n = 1
|
||||||
|
local zmin, zmax = 0, z
|
||||||
|
if z < 0 then
|
||||||
|
zmin, zmax = zmax, zmin
|
||||||
|
end
|
||||||
|
local m = z/math.hypot(x, y)
|
||||||
|
local dir = 1
|
||||||
|
if m < 0 then
|
||||||
|
dir = -dir
|
||||||
|
end
|
||||||
|
for _,i in ipairs(two_line) do
|
||||||
|
local px, py = unpack(i)
|
||||||
|
local ph = math.hypot(px, py)
|
||||||
|
local z1 = math.max(math.min(math.floor((ph-0.5)*m+0.5), zmax), zmin)
|
||||||
|
local z2 = math.max(math.min(math.floor((ph+0.5)*m+0.5), zmax), zmin)
|
||||||
|
for pz = z1,z2,dir do
|
||||||
|
line[n] = {px, py, pz}
|
||||||
|
n = n+1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
threelines[pstr] = line
|
||||||
|
return line
|
||||||
|
end
|
||||||
|
|
||||||
|
function vector.line(pos, dir, range)
|
||||||
|
if range then --dir = pos2
|
||||||
|
dir = vector.round(vector.multiply(dir, range))
|
||||||
|
else
|
||||||
|
dir = vector.subtract(dir, pos)
|
||||||
|
end
|
||||||
|
local line,n = {},1
|
||||||
|
for _,i in ipairs(vector.threeline(dir.x, dir.y, dir.z)) do
|
||||||
|
line[n] = {x=pos.x+i[1], y=pos.y+i[2], z=pos.z+i[3]}
|
||||||
|
n = n+1
|
||||||
|
end
|
||||||
|
return line
|
||||||
|
end
|
Loading…
Reference in New Issue
Block a user