Refactor lzr_laser mod
This commit is contained in:
parent
202131968a
commit
25cba4a685
@ -1,138 +1,4 @@
|
||||
local S = minetest.get_translator("lzr_laser")
|
||||
lzr_laser = {}
|
||||
|
||||
-- Distance from center to side of the laser beam square. Not really the radius, but it sounds cooler. :P
|
||||
local LASER_RADIUS = -1/16
|
||||
|
||||
-- DATA FORMATS:
|
||||
--[[ dirstring: A representation of 6 cardinal directions which are either
|
||||
'active' (1) or 'inactive' (0)
|
||||
Each direction has the character "1" or "0".
|
||||
The characters stand for these directions, in order: -X, +X, -Y, +Y, -Z, +Z
|
||||
Example: "101010"
|
||||
]]
|
||||
--[[ dirs table: Like dirstring, but in table format. It's a table
|
||||
with 6 numbers, each of them being either 1 or 0. The same order of
|
||||
directions is used like for dirstring.
|
||||
Example: { 1, 0, 1, 0, 1, 0 }
|
||||
]]
|
||||
|
||||
-- Converts a dirstring to a dirs table
|
||||
function dirstring_to_dirs(dirstring)
|
||||
local dirs = {}
|
||||
for d=1, 6 do
|
||||
if string.sub(dirstring, d, d) == "1" then
|
||||
dirs[d] = 1
|
||||
elseif string.sub(dirstring, d, d) == "0" then
|
||||
dirs[d] = 0
|
||||
else
|
||||
error("[lzr_laser] dirstring_to_dirs: Invalid dirstring!")
|
||||
end
|
||||
end
|
||||
return dirs
|
||||
end
|
||||
|
||||
-- Converts a dirs table to a dirstring
|
||||
function dirs_to_dirstring(dirs)
|
||||
local dirstring = ""
|
||||
for d=1, 6 do
|
||||
if dirs[d] == 0 then
|
||||
dirstring = dirstring .. "0"
|
||||
elseif dirs[d] == 1 then
|
||||
dirstring = dirstring .. "1"
|
||||
else
|
||||
error("[lzr_laser] dirs_to_dirstring: Invalid dirs!")
|
||||
end
|
||||
end
|
||||
return dirstring
|
||||
end
|
||||
|
||||
-- Returns a nodebox for the given dirs table
|
||||
function dirs_to_nodebox(dirs)
|
||||
local boxes = {}
|
||||
local x = dirs[1] == 1 or dirs[4] == 1
|
||||
local y = dirs[2] == 1 or dirs[5] == 1
|
||||
local z = dirs[3] == 1 or dirs[6] == 1
|
||||
|
||||
-- True if 2 or more axes are used
|
||||
local multidir = (x and y) or (x and z) or (y and z)
|
||||
|
||||
-- Center block
|
||||
if multidir and (x or y or z) then
|
||||
table.insert(boxes, { -LASER_RADIUS, -LASER_RADIUS, -LASER_RADIUS, LASER_RADIUS, LASER_RADIUS, LASER_RADIUS })
|
||||
end
|
||||
|
||||
-- Axes (X, Y, Z)
|
||||
if x then
|
||||
if not multidir then
|
||||
table.insert(boxes, { -0.5, -LASER_RADIUS, -LASER_RADIUS, 0.5, LASER_RADIUS, LASER_RADIUS })
|
||||
else
|
||||
table.insert(boxes, { -0.5, -LASER_RADIUS, -LASER_RADIUS, LASER_RADIUS, LASER_RADIUS, LASER_RADIUS })
|
||||
table.insert(boxes, { -LASER_RADIUS, -LASER_RADIUS, -LASER_RADIUS, 0.5, LASER_RADIUS, LASER_RADIUS })
|
||||
end
|
||||
end
|
||||
if y then
|
||||
if not multidir then
|
||||
table.insert(boxes, { -LASER_RADIUS, -0.5, -LASER_RADIUS, LASER_RADIUS, 0.5, LASER_RADIUS })
|
||||
else
|
||||
table.insert(boxes, { -LASER_RADIUS, -0.5, -LASER_RADIUS, LASER_RADIUS, LASER_RADIUS, LASER_RADIUS })
|
||||
table.insert(boxes, { -LASER_RADIUS, -LASER_RADIUS, -LASER_RADIUS, LASER_RADIUS, 0.5, LASER_RADIUS })
|
||||
end
|
||||
end
|
||||
if z then
|
||||
if not multidir then
|
||||
table.insert(boxes, { -LASER_RADIUS, -LASER_RADIUS, -0.5, LASER_RADIUS, LASER_RADIUS, 0.5 })
|
||||
else
|
||||
table.insert(boxes, { -LASER_RADIUS, -LASER_RADIUS, -0.5, LASER_RADIUS, LASER_RADIUS, LASER_RADIUS })
|
||||
table.insert(boxes, { -LASER_RADIUS, -LASER_RADIUS, -LASER_RADIUS, LASER_RADIUS, LASER_RADIUS, 0.5 })
|
||||
end
|
||||
end
|
||||
return boxes
|
||||
end
|
||||
|
||||
-- Convert number to string in binary form
|
||||
-- * num: Number
|
||||
-- * minLength: Minimum number of characters the string must have, will
|
||||
-- fill string with leading zeroes if needed (default: 1)
|
||||
-- Returns: string
|
||||
function dec2bin(num, minLength)
|
||||
if not minLength then
|
||||
minLength = 1
|
||||
end
|
||||
local t = {}
|
||||
local rem
|
||||
while num > 0 do
|
||||
rem = math.fmod(num,2)
|
||||
t[#t+1] = rem
|
||||
num = (num-rem)/2
|
||||
end
|
||||
local bin = table.concat(t)
|
||||
bin = string.reverse(bin)
|
||||
local length = string.len(bin)
|
||||
if length < minLength then
|
||||
bin = string.rep("0", minLength - length) .. bin
|
||||
end
|
||||
return bin
|
||||
end
|
||||
|
||||
-- Register laser nodes
|
||||
-- 64 nodes because 2^6 (6 directions with on/off state)
|
||||
for i=1, 64 do
|
||||
local dirstring = dec2bin(i, 6)
|
||||
local dirs = dirstring_to_dirs(dirstring)
|
||||
minetest.register_node("lzr_laser:laser_"..dirstring, {
|
||||
description = S("Laser (@1)", dirstring),
|
||||
paramtype = "light",
|
||||
drawtype = "nodebox",
|
||||
sunlight_propagates = true,
|
||||
walkable = false,
|
||||
use_texture_alpha = "blend",
|
||||
tiles = { "lzr_laser_laser.png", },
|
||||
--TODO: Remove pointability
|
||||
-- pointable = false,
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = dirs_to_nodebox(dirs),
|
||||
},
|
||||
groups = { laser = 1, not_in_creative_inventory = 1 },
|
||||
})
|
||||
end
|
||||
dofile(minetest.get_modpath("lzr_laser").."/util.lua")
|
||||
dofile(minetest.get_modpath("lzr_laser").."/laser.lua")
|
||||
|
70
mods/lzr_laser/laser.lua
Normal file
70
mods/lzr_laser/laser.lua
Normal file
@ -0,0 +1,70 @@
|
||||
local S = minetest.get_translator("lzr_laser")
|
||||
|
||||
-- Distance from center to side of the laser beam square. Not really the radius, but it sounds cooler. :P
|
||||
local LASER_RADIUS = -1/16
|
||||
|
||||
-- Returns a nodebox for the given dirs table
|
||||
local function dirs_to_nodebox(dirs)
|
||||
local boxes = {}
|
||||
local x = dirs[1] == 1 or dirs[4] == 1
|
||||
local y = dirs[2] == 1 or dirs[5] == 1
|
||||
local z = dirs[3] == 1 or dirs[6] == 1
|
||||
|
||||
-- True if 2 or more axes are used
|
||||
local multidir = (x and y) or (x and z) or (y and z)
|
||||
|
||||
-- Center block
|
||||
if multidir and (x or y or z) then
|
||||
table.insert(boxes, { -LASER_RADIUS, -LASER_RADIUS, -LASER_RADIUS, LASER_RADIUS, LASER_RADIUS, LASER_RADIUS })
|
||||
end
|
||||
|
||||
-- Axes (X, Y, Z)
|
||||
if x then
|
||||
if not multidir then
|
||||
table.insert(boxes, { -0.5, -LASER_RADIUS, -LASER_RADIUS, 0.5, LASER_RADIUS, LASER_RADIUS })
|
||||
else
|
||||
table.insert(boxes, { -0.5, -LASER_RADIUS, -LASER_RADIUS, LASER_RADIUS, LASER_RADIUS, LASER_RADIUS })
|
||||
table.insert(boxes, { -LASER_RADIUS, -LASER_RADIUS, -LASER_RADIUS, 0.5, LASER_RADIUS, LASER_RADIUS })
|
||||
end
|
||||
end
|
||||
if y then
|
||||
if not multidir then
|
||||
table.insert(boxes, { -LASER_RADIUS, -0.5, -LASER_RADIUS, LASER_RADIUS, 0.5, LASER_RADIUS })
|
||||
else
|
||||
table.insert(boxes, { -LASER_RADIUS, -0.5, -LASER_RADIUS, LASER_RADIUS, LASER_RADIUS, LASER_RADIUS })
|
||||
table.insert(boxes, { -LASER_RADIUS, -LASER_RADIUS, -LASER_RADIUS, LASER_RADIUS, 0.5, LASER_RADIUS })
|
||||
end
|
||||
end
|
||||
if z then
|
||||
if not multidir then
|
||||
table.insert(boxes, { -LASER_RADIUS, -LASER_RADIUS, -0.5, LASER_RADIUS, LASER_RADIUS, 0.5 })
|
||||
else
|
||||
table.insert(boxes, { -LASER_RADIUS, -LASER_RADIUS, -0.5, LASER_RADIUS, LASER_RADIUS, LASER_RADIUS })
|
||||
table.insert(boxes, { -LASER_RADIUS, -LASER_RADIUS, -LASER_RADIUS, LASER_RADIUS, LASER_RADIUS, 0.5 })
|
||||
end
|
||||
end
|
||||
return boxes
|
||||
end
|
||||
|
||||
-- Register laser nodes
|
||||
-- 64 nodes because 2^6 (6 directions with on/off state)
|
||||
for i=1, 64 do
|
||||
local dirstring = lzr_laser.dec2bin(i, 6)
|
||||
local dirs = lzr_laser.dirstring_to_dirs(dirstring)
|
||||
minetest.register_node("lzr_laser:laser_"..dirstring, {
|
||||
description = S("Laser (@1)", dirstring),
|
||||
paramtype = "light",
|
||||
drawtype = "nodebox",
|
||||
sunlight_propagates = true,
|
||||
walkable = false,
|
||||
use_texture_alpha = "blend",
|
||||
tiles = { "lzr_laser_laser.png", },
|
||||
--TODO: Remove pointability
|
||||
-- pointable = false,
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = dirs_to_nodebox(dirs),
|
||||
},
|
||||
groups = { laser = 1, not_in_creative_inventory = 1 },
|
||||
})
|
||||
end
|
1
mods/lzr_laser/mod.conf
Normal file
1
mods/lzr_laser/mod.conf
Normal file
@ -0,0 +1 @@
|
||||
name = lzr_laser
|
BIN
mods/lzr_laser/textures/lzr_laser_laser.png
Normal file
BIN
mods/lzr_laser/textures/lzr_laser_laser.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 144 B |
71
mods/lzr_laser/util.lua
Normal file
71
mods/lzr_laser/util.lua
Normal file
@ -0,0 +1,71 @@
|
||||
-- Distance from center to side of the laser beam square. Not really the radius, but it sounds cooler. :P
|
||||
local LASER_RADIUS = -1/16
|
||||
|
||||
-- DATA FORMATS:
|
||||
--[[ dirstring: A representation of 6 cardinal directions which are either
|
||||
'active' (1) or 'inactive' (0)
|
||||
Each direction has the character "1" or "0".
|
||||
The characters stand for these directions, in order: -X, +X, -Y, +Y, -Z, +Z
|
||||
Example: "101010"
|
||||
]]
|
||||
--[[ dirs table: Like dirstring, but in table format. It's a table
|
||||
with 6 numbers, each of them being either 1 or 0. The same order of
|
||||
directions is used like for dirstring.
|
||||
Example: { 1, 0, 1, 0, 1, 0 }
|
||||
]]
|
||||
|
||||
-- Converts a dirstring to a dirs table
|
||||
function lzr_laser.dirstring_to_dirs(dirstring)
|
||||
local dirs = {}
|
||||
for d=1, 6 do
|
||||
if string.sub(dirstring, d, d) == "1" then
|
||||
dirs[d] = 1
|
||||
elseif string.sub(dirstring, d, d) == "0" then
|
||||
dirs[d] = 0
|
||||
else
|
||||
error("[lzr_laser] dirstring_to_dirs: Invalid dirstring!")
|
||||
end
|
||||
end
|
||||
return dirs
|
||||
end
|
||||
|
||||
-- Converts a dirs table to a dirstring
|
||||
function lzr_laser.dirs_to_dirstring(dirs)
|
||||
local dirstring = ""
|
||||
for d=1, 6 do
|
||||
if dirs[d] == 0 then
|
||||
dirstring = dirstring .. "0"
|
||||
elseif dirs[d] == 1 then
|
||||
dirstring = dirstring .. "1"
|
||||
else
|
||||
error("[lzr_laser] dirs_to_dirstring: Invalid dirs!")
|
||||
end
|
||||
end
|
||||
return dirstring
|
||||
end
|
||||
|
||||
-- Convert number to string in binary form
|
||||
-- * num: Number
|
||||
-- * minLength: Minimum number of characters the string must have, will
|
||||
-- fill string with leading zeroes if needed (default: 1)
|
||||
-- Returns: string
|
||||
function lzr_laser.dec2bin(num, minLength)
|
||||
if not minLength then
|
||||
minLength = 1
|
||||
end
|
||||
local t = {}
|
||||
local rem
|
||||
while num > 0 do
|
||||
rem = math.fmod(num,2)
|
||||
t[#t+1] = rem
|
||||
num = (num-rem)/2
|
||||
end
|
||||
local bin = table.concat(t)
|
||||
bin = string.reverse(bin)
|
||||
local length = string.len(bin)
|
||||
if length < minLength then
|
||||
bin = string.rep("0", minLength - length) .. bin
|
||||
end
|
||||
return bin
|
||||
end
|
||||
|
Loading…
x
Reference in New Issue
Block a user