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
|
dofile(minetest.get_modpath("lzr_laser").."/util.lua")
|
||||||
local LASER_RADIUS = -1/16
|
dofile(minetest.get_modpath("lzr_laser").."/laser.lua")
|
||||||
|
|
||||||
-- 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
|
|
||||||
|
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