mirror of
https://github.com/minetest-mods/technic.git
synced 2024-12-22 13:52:31 +01:00
Add trace_node_ray_fat and use it for mining lasers
This function includes more nodes, so laser tunnels aren't always only one node wide.
This commit is contained in:
parent
e501c4622b
commit
1475ee6e40
@ -110,3 +110,82 @@ function technic.trace_node_ray(pos, dir, range)
|
|||||||
end, vector.round(pos)
|
end, vector.round(pos)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Like trace_node_ray, but includes extra positions close to the ray.
|
||||||
|
function technic.trace_node_ray_fat(pos, dir, range)
|
||||||
|
local x_step = dir.x > 0 and 1 or -1
|
||||||
|
local y_step = dir.y > 0 and 1 or -1
|
||||||
|
local z_step = dir.z > 0 and 1 or -1
|
||||||
|
|
||||||
|
local next_poses = {}
|
||||||
|
|
||||||
|
local i = 1
|
||||||
|
return function(p)
|
||||||
|
local ni, np = next(next_poses)
|
||||||
|
if np then
|
||||||
|
next_poses[ni] = nil
|
||||||
|
return np
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Approximation of where we should be if we weren't rounding
|
||||||
|
-- to nodes. This moves forward a bit faster then we do.
|
||||||
|
-- A correction is done below.
|
||||||
|
local real_x = pos.x + (dir.x * i)
|
||||||
|
local real_y = pos.y + (dir.y * i)
|
||||||
|
local real_z = pos.z + (dir.z * i)
|
||||||
|
|
||||||
|
-- How far off we've gotten from where we should be.
|
||||||
|
local dx = math.abs(real_x - p.x)
|
||||||
|
local dy = math.abs(real_y - p.y)
|
||||||
|
local dz = math.abs(real_z - p.z)
|
||||||
|
|
||||||
|
-- If the real position moves ahead too fast, stop it so we
|
||||||
|
-- can catch up. If it gets too far ahead it will smooth
|
||||||
|
-- out our movement too much and we won't turn fast enough.
|
||||||
|
if dx + dy + dz < 2 then
|
||||||
|
i = i + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Step in whichever direction we're most off course in.
|
||||||
|
local sx, sy, sz -- Whether we've already stepped along each axis
|
||||||
|
if dx > dy then
|
||||||
|
if dx > dz then
|
||||||
|
sx = true
|
||||||
|
p.x = p.x + x_step
|
||||||
|
else
|
||||||
|
sz = true
|
||||||
|
p.z = p.z + z_step
|
||||||
|
end
|
||||||
|
elseif dy > dz then
|
||||||
|
sy = true
|
||||||
|
p.y = p.y + y_step
|
||||||
|
else
|
||||||
|
sz = true
|
||||||
|
p.z = p.z + z_step
|
||||||
|
end
|
||||||
|
|
||||||
|
if vector.distance(pos, p) > range then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Add other positions that we're significantly off on.
|
||||||
|
-- We can just use fixed integer keys here because the
|
||||||
|
-- table will be completely cleared before we reach this
|
||||||
|
-- code block again.
|
||||||
|
local dlen = math.sqrt(dx*dx + dy*dy + dz*dz)
|
||||||
|
-- Normalized axis deltas
|
||||||
|
local dxn, dyn, dzn = dx / dlen, dy / dlen, dz / dlen
|
||||||
|
if not sx and dxn > 0.5 then
|
||||||
|
next_poses[1] = vector.new(p.x + x_step, p.y, p.z)
|
||||||
|
end
|
||||||
|
if not sy and dyn > 0.5 then
|
||||||
|
next_poses[2] = vector.new(p.x, p.y + y_step, p.z)
|
||||||
|
end
|
||||||
|
if not sz and dzn > 0.5 then
|
||||||
|
next_poses[3] = vector.new(p.x, p.y, p.z + z_step)
|
||||||
|
end
|
||||||
|
|
||||||
|
return p
|
||||||
|
end, vector.round(pos)
|
||||||
|
end
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ local function laser_shoot(player, range, particle_texture, sound)
|
|||||||
texture = particle_texture .. "^[transform" .. math.random(0, 7),
|
texture = particle_texture .. "^[transform" .. math.random(0, 7),
|
||||||
})
|
})
|
||||||
minetest.sound_play(sound, {pos = player_pos, max_hear_distance = range})
|
minetest.sound_play(sound, {pos = player_pos, max_hear_distance = range})
|
||||||
for pos in technic.trace_node_ray(start_pos, dir, range) do
|
for pos in technic.trace_node_ray_fat(start_pos, dir, range) do
|
||||||
if minetest.is_protected(pos, player_name) then
|
if minetest.is_protected(pos, player_name) then
|
||||||
minetest.record_protection_violation(pos, player_name)
|
minetest.record_protection_violation(pos, player_name)
|
||||||
break
|
break
|
||||||
|
Loading…
Reference in New Issue
Block a user