mirror of
https://github.com/minetest-mods/technic.git
synced 2025-07-05 09:40:35 +02:00
This commit is contained in:
@ -32,64 +32,54 @@ minetest.register_craft({
|
||||
}
|
||||
})
|
||||
|
||||
-- Based on code by Uberi: https://gist.github.com/Uberi/3125280
|
||||
local scalar = vector.scalar or vector.dot or function vector.scalar(v1, v2)
|
||||
return v1.x*v2.x + v1.y*v2.y + v1.z*v2.z
|
||||
end
|
||||
|
||||
local function biggest_of_vec(vec)
|
||||
if vec.x < vec.y then
|
||||
if vec.y < vec.z then
|
||||
return "z"
|
||||
end
|
||||
return "y"
|
||||
end
|
||||
if vec.x < vec.z then
|
||||
return "z"
|
||||
end
|
||||
return "x"
|
||||
end
|
||||
|
||||
local function rayIter(pos, dir, range)
|
||||
local p = vector.round(pos)
|
||||
local x_step, y_step, z_step = 0, 0, 0
|
||||
local x_component, y_component, z_component = 0, 0, 0
|
||||
local x_intersect, y_intersect, z_intersect = 0, 0, 0
|
||||
|
||||
if dir.x == 0 then
|
||||
x_intersect = math.huge
|
||||
elseif dir.x > 0 then
|
||||
x_step = 1
|
||||
x_component = 1 / dir.x
|
||||
x_intersect = x_component
|
||||
else
|
||||
x_step = -1
|
||||
x_component = 1 / -dir.x
|
||||
end
|
||||
if dir.y == 0 then
|
||||
y_intersect = math.huge
|
||||
elseif dir.y > 0 then
|
||||
y_step = 1
|
||||
y_component = 1 / dir.y
|
||||
y_intersect = y_component
|
||||
else
|
||||
y_step = -1
|
||||
y_component = 1 / -dir.y
|
||||
end
|
||||
if dir.z == 0 then
|
||||
z_intersect = math.huge
|
||||
elseif dir.z > 0 then
|
||||
z_step = 1
|
||||
z_component = 1 / dir.z
|
||||
z_intersect = z_component
|
||||
else
|
||||
z_step = -1
|
||||
z_component = 1 / -dir.z
|
||||
-- make a table of possible movements
|
||||
local step = {}
|
||||
for i in pairs(pos) do
|
||||
local v = math.sign(dir[i])
|
||||
if v ~= 0 then
|
||||
step[i] = v
|
||||
end
|
||||
end
|
||||
|
||||
local p
|
||||
return function()
|
||||
if x_intersect < y_intersect then
|
||||
if x_intersect < z_intersect then
|
||||
p.x = p.x + x_step
|
||||
x_intersect = x_intersect + x_component
|
||||
else
|
||||
p.z = p.z + z_step
|
||||
z_intersect = z_intersect + z_component
|
||||
end
|
||||
elseif y_intersect < z_intersect then
|
||||
p.y = p.y + y_step
|
||||
y_intersect = y_intersect + y_component
|
||||
else
|
||||
p.z = p.z + z_step
|
||||
z_intersect = z_intersect + z_component
|
||||
if not p then
|
||||
-- avoid skipping the first position
|
||||
p = vector.round(pos)
|
||||
return vector.new(p)
|
||||
end
|
||||
if vector.distance(pos, p) > range then
|
||||
return nil
|
||||
|
||||
-- find the position which has the smallest distance to the line
|
||||
local choose = {}
|
||||
local choosefit = vector.new()
|
||||
for i in pairs(step) do
|
||||
choose[i] = vector.new(p)
|
||||
choose[i][i] = choose[i][i] + step[i]
|
||||
choosefit[i] = scalar(vector.normalize(vector.subtract(choose[i], pos)), dir)
|
||||
end
|
||||
p = choose[biggest_of_vec(choosefit)]
|
||||
|
||||
if vector.distance(pos, p) <= range then
|
||||
return vector.new(p)
|
||||
end
|
||||
return p
|
||||
end
|
||||
end
|
||||
|
||||
@ -122,11 +112,11 @@ local function laser_shoot(player, range, particle_texture, sound)
|
||||
|
||||
local start_pos = vector.new(player_pos)
|
||||
-- Adjust to head height
|
||||
start_pos.y = start_pos.y + 1.9
|
||||
start_pos.y = start_pos.y + 1.625
|
||||
minetest.add_particle({
|
||||
pos = startpos,
|
||||
vel = dir,
|
||||
acc = vector.multiply(dir, 50),
|
||||
pos = start_pos,
|
||||
velocity = dir,
|
||||
acceleration = vector.multiply(dir, 50),
|
||||
expirationtime = range / 11,
|
||||
size = 1,
|
||||
texture = particle_texture .. "^[transform" .. math.random(0, 7),
|
||||
|
Reference in New Issue
Block a user