extrablocks/n/laser_mk2_alternative.lua

181 lines
4.0 KiB
Lua

--license LGPLv2+, for the changes: WTFPL
local range = 10
local dirs = 10
local side_ran = 3
local say_laser_info = false
local function info(info)
if say_laser_info then
print("[extrablocks] <laser_mk2> "..info)
end
end
local function chps(ran, m, n)
if math.floor(ran*m+0.5) == math.floor(ran*n+0.5) then
return true
end
return false
end
local function round_pos(pos, a)
local output = {x=math.floor(pos.x*a+0.5)/a, y=math.floor(pos.y*a+0.5)/a, z=math.floor(pos.z*a+0.5)/a}
info(dump(output).." round "..dump(a))
return output
end
local function get_straight(dir, range)
if dir.x == 0
and dir.z == 0 then
if dir.y >= 0 then
return {0,0, 0,range, 0,0}
end
return {0,0, range,0, 0,0}
end
if dir.x == 0
and dir.y == 0 then
if dir.z >= 0 then
return {0,0, 0,0, 0,range}
end
return {0,0, 0,0, range,0}
end
if dir.y == 0
and dir.z == 0 then
if dir.x >= 0 then
return {0,range, 0,0, 0,0}
end
return {range,0, 0,0, 0,0}
end
return false
end
local function get_qdrt(dir)
if dir.x >= 0 then
x1,x2 = 0,range
else
x1,x2 = range,0
end
if dir.y >= 0 then
y1,y2 = 0,range
else
y1,y2 = range,0
end
if dir.z >= 0 then
z1,z2 = 0,range
else
z1,z2 = range,0
end
local output = {x1,x2, y1,y2, z1,z2}
info(dump(output).." got_qdrt")
return output
end
local function make_d_table(dir)
return {
xdz = dir.x/dir.z,
zdx = dir.z/dir.x,
xdy = dir.x/dir.y,
ydx = dir.y/dir.x,
zdy = dir.z/dir.y,
ydz = dir.y/dir.z,
}
end
local function allowed_pos(i, j, k, d)
local ran = math.hypot(math.hypot(i,j),k)/side_ran
if (chps(ran, i/k, d.xdz) or chps(ran, k/i, d.zdx))
and (chps(ran, i/j, d.xdy) or chps(ran, j/i, d.ydx))
and (chps(ran, k/j, d.zdy) or chps(ran, j/k, d.ydz)) then
return true
end
return false
end
local function def_pos(startpos, i, j, k)
return {x=startpos.x+i, y=startpos.y+j, z=startpos.z+k}
end
local laser_shoot = function(itemstack, player, pointed_thing)
local playerpos=player:getpos()
local dir=player:get_look_dir()
if pointed_thing.type=="node" then
pos=minetest.get_pointed_thing_position(pointed_thing, above)
local node = minetest.get_node(pos)
if node.name~="ignore" then
minetest.node_dig(pos,node,player)
info(dump(pos).." dug (pointed)")
end
end
local startpos = {x=playerpos.x, y=playerpos.y+1.6, z=playerpos.z}
local velocity = {x=dir.x*50, y=dir.y*50, z=dir.z*50}
minetest.add_particle(startpos, dir, velocity, 1, 1, false, "extrablocks_laser_beam_mk2.png")
minetest.sound_play("extrablocks_laser_mk2", {pos = playerpos, gain = 1.0, max_hear_distance = range})
dir = round_pos(dir, dirs)
playerpos = vector.round(playerpos)
local straight = get_straight(dir, range)
if straight then
info("straight")
for i = -straight[1],straight[2],1 do
for j = -straight[3],straight[4],1 do
for k = -straight[5],straight[6],1 do
lazer_it(def_pos(startpos, i, j, k), player)
end
end
end
return true
end
info("not straight")
local sizes = get_qdrt(dir, range)
local d = make_d_table(dir)
for i = -sizes[1],sizes[2],1 do
for j = -sizes[3],sizes[4],1 do
for k = -sizes[5],sizes[6],1 do
if allowed_pos(i, j, k, d) then
lazer_it(def_pos(startpos, i, j, k), player)
end
end
end
end
return true
end
minetest.register_tool("extrablocks:laser_mk2", {
description = "Mining Laser MK2",
inventory_image = "extrablocks_mining_laser_mk2.png",
stack_max = 1,
on_use = function(itemstack, user, pointed_thing)
item=itemstack:to_table()
laser_shoot(item, user, pointed_thing)
end,
})
function lazer_it (pos, player)
local pos1={}
-- pos1.x=math.floor(pos.x)
-- pos1.y=math.floor(pos.y)
-- pos1.z=math.floor(pos.z)
local node = minetest.get_node(pos)
if node.name == "air"
or node.name == "ignore"
or node.name == "default:lava_source"
or node.name == "default:lava_flowing" then
return
end
if node.name == "default:water_source"
or node.name == "default:water_flowing" then
minetest.remove_node(pos)
info(dump(pos).." removed")
return
end
if player then
minetest.node_dig(pos,node,player)
end
end