digiscreen/init.lua

158 lines
5.0 KiB
Lua
Raw Normal View History

2020-04-28 06:31:01 +02:00
local function removeEntity(pos)
local entitiesNearby = minetest.get_objects_inside_radius(pos,0.5)
for _,i in pairs(entitiesNearby) do
if i:get_luaentity() and i:get_luaentity().name == "digiscreen:image" then
i:remove()
end
end
end
local function generateTexture(pos,serdata)
--The data *should* always be valid, but it pays to double-check anyway due to how easily this could crash if something did go wrong
if type(serdata) ~= "string" then
minetest.log("error","[digiscreen] Serialized display data appears to be missing at "..minetest.pos_to_string(pos,0))
return
end
local data = minetest.deserialize(serdata)
if type(data) ~= "table" then
minetest.log("error","[digiscreen] Failed to deserialize display data at "..minetest.pos_to_string(pos,0))
return
end
for y=1,16,1 do
if type(data[y]) ~= "table" then
minetest.log("error","[digiscreen] Invalid row "..y.." at "..minetest.pos_to_string(pos,0))
return
end
for x=1,16,1 do
if type(data[y][x]) ~= "string" or string.len(data[y][x]) ~= 6 then
minetest.log("error","[digiscreen] Missing/wrong length display data for X="..x.." Y="..y.." at "..minetest.pos_to_string(pos,0))
return
end
for i=1,6,1 do
if not tonumber(string.sub(data[y][x],i,i),16) then
minetest.log("error","[digiscreen] Invalid digit in display data for X="..x.." Y="..y.." at "..minetest.pos_to_string(pos,0))
return
end
end
end
end
local ret = "[combine:16x16"
for y=1,16,1 do
for x=1,16,1 do
ret = ret..string.format(":%d,%d=(digiscreen_pixel.png\\^[colorize\\:#%s\\:255)",x-1,y-1,data[y][x])
end
end
return ret
end
local function updateDisplay(pos)
removeEntity(pos)
local meta = minetest.get_meta(pos)
local data = meta:get_string("data")
local entity = minetest.add_entity(pos,"digiscreen:image")
local fdir = minetest.facedir_to_dir(minetest.get_node(pos).param2)
local etex = "digiscreen_pixel.png"
etex = generateTexture(pos,data) or etex
entity:set_properties({textures={etex}})
entity:set_yaw((fdir.x ~= 0) and math.pi/2 or 0)
entity:set_pos(vector.add(pos,vector.multiply(fdir,0.39)))
end
minetest.register_entity("digiscreen:image",{
initial_properties = {
visual = "upright_sprite",
physical = false,
collisionbox = {0,0,0,0,0,0,},
textures = {"digiscreen_pixel.png",},
},
})
minetest.register_node("digiscreen:digiscreen",{
description = "Digilines Graphical Display",
tiles = {"digiscreen_pixel.png",},
groups = {cracky = 3,},
paramtype = "light",
paramtype2 = "facedir",
on_rotate = minetest.global_exists("screwdriver") and screwdriver.rotate_simple,
drawtype = "nodebox",
node_box = {
type = "fixed",
fixed = {-0.5,-0.5,0.4,0.5,0.5,0.5},
},
light_source = 10,
on_construct = function(pos)
local meta = minetest.get_meta(pos)
meta:set_string("formspec","field[channel;Channel;${channel}]")
local disp = {}
for y=1,16,1 do
disp[y] = {}
for x=1,16,1 do
disp[y][x] = "000000"
end
end
meta:set_string("data",minetest.serialize(disp))
updateDisplay(pos)
end,
on_destruct = removeEntity,
on_receive_fields = function(pos,_,fields,sender)
local name = sender:get_player_name()
if not fields.channel then return end
if minetest.is_protected(pos,name) and not minetest.check_player_privs(name,"protection_bypass") then
minetest.record_protection_violation(pos,name)
return
end
local meta = minetest.get_meta(pos)
meta:set_string("channel",fields.channel)
end,
digiline = {
wire = {
rules = digiline.rules.default,
},
effector = {
action = function(pos,_,channel,msg)
local meta = minetest.get_meta(pos)
local setchan = meta:get_string("channel")
if type(msg) ~= "table" or setchan ~= channel then return end
local data = {}
for y=1,16,1 do
data[y] = {}
if type(msg[y]) ~= "table" then msg[y] = {} end
for x=1,16,1 do
if type(msg[y][x]) == "string" and string.len(msg[y][x]) == 7 and string.sub(msg[y][x],1,1) == "#" then
msg[y][x] = string.sub(msg[y][x],2,-1)
end
if type(msg[y][x]) ~= "string" or string.len(msg[y][x]) ~= 6 then msg[y][x] = "000000" end
msg[y][x] = string.upper(msg[y][x])
for i=1,6,1 do
if not tonumber(string.sub(msg[y][x],i,i),16) then
msg[y][x] = "000000"
end
end
data[y][x] = msg[y][x]
end
end
meta:set_string("data",minetest.serialize(data))
updateDisplay(pos)
end,
},
},
})
minetest.register_lbm({
name = "digiscreen:respawn",
label = "Respawn digiscreen entities",
nodenames = {"digiscreen:digiscreen"},
run_at_every_load = true,
action = updateDisplay,
})
minetest.register_craft({
output = "digiscreen:digiscreen",
recipe = {
{"mesecons_luacontroller:luacontroller0000","rgblightstone:rgblightstone_truecolor_0","rgblightstone:rgblightstone_truecolor_0",},
{"rgblightstone:rgblightstone_truecolor_0","rgblightstone:rgblightstone_truecolor_0","rgblightstone:rgblightstone_truecolor_0",},
{"rgblightstone:rgblightstone_truecolor_0","rgblightstone:rgblightstone_truecolor_0","rgblightstone:rgblightstone_truecolor_0",},
},
})