summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcheapie <no-email-for-you@example.com>2025-07-26 19:16:05 -0500
committercheapie <no-email-for-you@example.com>2025-07-26 19:16:05 -0500
commita365f1da5c50ef4d2ee6085fbfbdd2f476f9d6ce (patch)
treef5185cd21626bd4427c7670cc7ee4a25f5b5bf58
parent2426aa5eccdf255c8865d3067d0b8d187f45f1dc (diff)
downloaddigiscreen-master.tar
digiscreen-master.tar.gz
digiscreen-master.tar.bz2
digiscreen-master.tar.xz
digiscreen-master.zip
Add high-resolution variantHEADmaster
-rw-r--r--init.lua234
1 files changed, 147 insertions, 87 deletions
diff --git a/init.lua b/init.lua
index 4291fa2..49c803e 100644
--- a/init.lua
+++ b/init.lua
@@ -9,12 +9,13 @@ function digiscreen.removeEntity(pos)
end
end
-function digiscreen.processDigilinesMessage(pos,msg)
+function digiscreen.processDigilinesMessage(pos,msg,size)
+ if (not size) or size < 1 then size = 16 end
local data = {}
- for y=1,16,1 do
+ for y=1,size,1 do
data[y] = {}
if type(msg[y]) ~= "table" then msg[y] = {} end
- for x=1,16,1 do
+ for x=1,size,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
@@ -29,9 +30,9 @@ function digiscreen.processDigilinesMessage(pos,msg)
end
end
local bincolors = ""
- for y=1,16,1 do
+ for y=1,size,1 do
if type(data[y]) ~= "table" then data[y] = {} end
- for x=1,16,1 do
+ for x=1,size,1 do
local colorspec = 0
if data[y][x] then
colorspec = tonumber(data[y][x],16) or 0
@@ -40,7 +41,7 @@ function digiscreen.processDigilinesMessage(pos,msg)
bincolors = bincolors..core.colorspec_to_bytes(colorspec)
end
end
- local img = core.encode_png(16,16,bincolors,1)
+ local img = core.encode_png(size,size,bincolors,1)
return pos,"[png:"..core.encode_base64(img),bincolors
end
@@ -66,7 +67,7 @@ end
function digiscreen.asyncDone(pos,texture,bincolors)
local node = core.get_node(pos)
- if node.name ~= "digiscreen:digiscreen" then return end
+ if core.get_item_group(node.name,"digiscreen") ~= 1 then return end
local meta = core.get_meta(pos)
meta:set_string("data","")
meta:set_string("bincolors",bincolors)
@@ -76,16 +77,17 @@ function digiscreen.asyncDone(pos,texture,bincolors)
core.get_node_timer(pos):start(5)
end
-function digiscreen.recompress(pos,bincolors)
- if string.len(bincolors) ~= 1024 then return false end
- local img = core.encode_png(16,16,bincolors,9)
+function digiscreen.recompress(pos,bincolors,size)
+ if (not size) or size < 1 then size = 16 end
+ if string.len(bincolors) ~= (size^2)*4 then return false end
+ local img = core.encode_png(size,size,bincolors,9)
return true,pos,"[png:"..core.encode_base64(img)
end
function digiscreen.recompressDone(ok,pos,texture)
if not ok then return end
local node = core.get_node(pos)
- if node.name ~= "digiscreen:digiscreen" then return end
+ if core.get_item_group(node.name,"digiscreen") ~= 1 then return end
local meta = core.get_meta(pos)
meta:set_string("bincolors","")
meta:set_string("texture",texture)
@@ -93,6 +95,96 @@ function digiscreen.recompressDone(ok,pos,texture)
digiscreen.updateDisplay(pos)
end
+function digiscreen.on_construct(pos,size)
+ if (not size) or size < 1 then size = 16 end
+ local meta = core.get_meta(pos)
+ meta:set_string("formspec","field[channel;Channel;${channel}]")
+ local disp = {}
+ for y=1,size,1 do
+ disp[y] = {}
+ for x=1,size,1 do
+ disp[y][x] = "000000"
+ end
+ end
+ meta:set_string("data",core.serialize(disp))
+ meta:mark_as_private("data")
+ meta:set_int("size",size)
+ digiscreen.updateDisplay(pos)
+end
+
+function digiscreen.on_receive_fields(pos,_,fields,sender)
+ local name = sender:get_player_name()
+ if not fields.channel then return end
+ if core.is_protected(pos,name) and not core.check_player_privs(name,"protection_bypass") then
+ core.record_protection_violation(pos,name)
+ return
+ end
+ local meta = core.get_meta(pos)
+ meta:set_string("channel",fields.channel)
+end
+
+function digiscreen.on_punch(screenpos,_,player)
+ local meta = core.get_meta(screenpos)
+ local size = meta:get_int("size")
+ if (not size) or size < 1 then size = 16 end
+ if player and not player.is_fake_player then
+ local eyepos = vector.add(player:get_pos(),vector.add(player:get_eye_offset(),vector.new(0,1.5,0)))
+ local lookdir = player:get_look_dir()
+ local distance = vector.distance(eyepos,screenpos)
+ local endpos = vector.add(eyepos,vector.multiply(lookdir,distance+1))
+ local ray = core.raycast(eyepos,endpos,true,false)
+ local pointed,screen,hitpos
+ repeat
+ pointed = ray:next()
+ if pointed and pointed.type == "node" then
+ local node = core.get_node(pointed.under)
+ if node.name == "digiscreen:digiscreen" then
+ screen = pointed.under
+ hitpos = vector.subtract(pointed.intersection_point,screen)
+ end
+ end
+ until screen or not pointed
+ if not hitpos then return end
+ local facedir = core.facedir_to_dir(core.get_node(screen).param2)
+ if facedir.x > 0 then
+ hitpos.x = -1*hitpos.z
+ elseif facedir.x < 0 then
+ hitpos.x = hitpos.z
+ elseif facedir.z < 0 then
+ hitpos.x = -1*hitpos.x
+ end
+ hitpos.y = -1*hitpos.y
+ local hitpixel = {}
+ hitpixel.x = math.floor((hitpos.x+0.5)*size+0.5)+1
+ hitpixel.y = math.floor((hitpos.y+0.5)*size+0.5)+1
+ if hitpixel.x < 1 or hitpixel.x > size or hitpixel.y < 1 or hitpixel.y > size then return end
+ local message = {
+ x = hitpixel.x,
+ y = hitpixel.y,
+ player = player:get_player_name(),
+ }
+ digilines.receptor_send(screenpos,digilines.rules.default,meta:get_string("channel"),message)
+ end
+end
+
+function digiscreen.on_timer(pos)
+ local bincolors = core.get_meta(pos):get_string("bincolors")
+ local size = core.get_meta(pos):get_int("size")
+ if (not size) or size < 1 then size = 16 end
+ if string.len(bincolors) > 0 then
+ core.handle_async(digiscreen.recompress,digiscreen.recompressDone,pos,bincolors,size)
+ end
+end
+
+function digiscreen.on_digilines(pos,_,channel,msg)
+ local meta = core.get_meta(pos)
+ local setchan = meta:get_string("channel")
+ if type(msg) ~= "table" or setchan ~= channel then return end
+ local size = meta:get_int("size")
+ if (not size) or size < 1 then size = 16 end
+ core.handle_async(digiscreen.processDigilinesMessage,digiscreen.asyncDone,pos,msg,size)
+end
+
core.register_entity("digiscreen:image",{
initial_properties = {
visual = "upright_sprite",
@@ -108,7 +200,7 @@ core.register_entity("digiscreen:image",{
core.register_node("digiscreen:digiscreen",{
description = "Digilines Graphical Display",
tiles = {"digiscreen_pixel.png",},
- groups = {cracky = 3,},
+ groups = {cracky = 3,digiscreen = 1,},
paramtype = "light",
paramtype2 = "facedir",
on_rotate = core.global_exists("screwdriver") and screwdriver.rotate_simple,
@@ -119,86 +211,46 @@ core.register_node("digiscreen:digiscreen",{
},
_digistuff_channelcopier_fieldname = "channel",
light_source = 10,
- on_construct = function(pos)
- local meta = core.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",core.serialize(disp))
- meta:mark_as_private("data")
- digiscreen.updateDisplay(pos)
- end,
+ on_construct = digiscreen.on_construct,
on_destruct = digiscreen.removeEntity,
- on_receive_fields = function(pos,_,fields,sender)
- local name = sender:get_player_name()
- if not fields.channel then return end
- if core.is_protected(pos,name) and not core.check_player_privs(name,"protection_bypass") then
- core.record_protection_violation(pos,name)
- return
- end
- local meta = core.get_meta(pos)
- meta:set_string("channel",fields.channel)
- end,
- on_punch = function(screenpos,_,player)
- if player and not player.is_fake_player then
- local eyepos = vector.add(player:get_pos(),vector.add(player:get_eye_offset(),vector.new(0,1.5,0)))
- local lookdir = player:get_look_dir()
- local distance = vector.distance(eyepos,screenpos)
- local endpos = vector.add(eyepos,vector.multiply(lookdir,distance+1))
- local ray = core.raycast(eyepos,endpos,true,false)
- local pointed,screen,hitpos
- repeat
- pointed = ray:next()
- if pointed and pointed.type == "node" then
- local node = core.get_node(pointed.under)
- if node.name == "digiscreen:digiscreen" then
- screen = pointed.under
- hitpos = vector.subtract(pointed.intersection_point,screen)
- end
- end
- until screen or not pointed
- if not hitpos then return end
- local facedir = core.facedir_to_dir(core.get_node(screen).param2)
- if facedir.x > 0 then
- hitpos.x = -1*hitpos.z
- elseif facedir.x < 0 then
- hitpos.x = hitpos.z
- elseif facedir.z < 0 then
- hitpos.x = -1*hitpos.x
- end
- hitpos.y = -1*hitpos.y
- local hitpixel = {}
- hitpixel.x = math.floor((hitpos.x+0.5)*16+0.5)+1
- hitpixel.y = math.floor((hitpos.y+0.5)*16+0.5)+1
- if hitpixel.x < 1 or hitpixel.x > 16 or hitpixel.y < 1 or hitpixel.y > 16 then return end
- local message = {
- x = hitpixel.x,
- y = hitpixel.y,
- player = player:get_player_name(),
- }
- digilines.receptor_send(screenpos,digilines.rules.default,core.get_meta(screenpos):get_string("channel"),message)
- end
- end,
- on_timer = function(pos)
- local bincolors = core.get_meta(pos):get_string("bincolors")
- if string.len(bincolors) > 0 then core.handle_async(digiscreen.recompress,digiscreen.recompressDone,pos,bincolors) end
- end,
+ on_receive_fields = digiscreen.on_receive_fields,
+ on_punch = digiscreen.on_punch,
+ on_timer = digiscreen.on_timer,
digiline = {
wire = {
rules = digilines.rules.default,
},
effector = {
- action = function(pos,_,channel,msg)
- local meta = core.get_meta(pos)
- local setchan = meta:get_string("channel")
- if type(msg) ~= "table" or setchan ~= channel then return end
- core.handle_async(digiscreen.processDigilinesMessage,digiscreen.asyncDone,pos,msg)
- end,
+ action = digiscreen.on_digilines,
+ },
+ },
+})
+
+core.register_node("digiscreen:digiscreen_big",{
+ description = "High-Resolution Digilines Graphical Display",
+ tiles = {"digiscreen_pixel.png",},
+ groups = {cracky = 3,digiscreen = 1,},
+ paramtype = "light",
+ paramtype2 = "facedir",
+ on_rotate = core.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},
+ },
+ _digistuff_channelcopier_fieldname = "channel",
+ light_source = 10,
+ on_construct = function(pos) digiscreen.on_construct(pos,64) end,
+ on_destruct = digiscreen.removeEntity,
+ on_receive_fields = digiscreen.on_receive_fields,
+ on_punch = digiscreen.on_punch,
+ on_timer = digiscreen.on_timer,
+ digiline = {
+ wire = {
+ rules = digilines.rules.default,
+ },
+ effector = {
+ action = digiscreen.on_digilines,
},
},
})
@@ -206,7 +258,7 @@ core.register_node("digiscreen:digiscreen",{
core.register_lbm({
name = "digiscreen:respawn",
label = "Respawn/upgrade digiscreen entities",
- nodenames = {"digiscreen:digiscreen"},
+ nodenames = {"group:digiscreen",},
run_at_every_load = true,
action = digiscreen.updateDisplay,
})
@@ -222,3 +274,11 @@ core.register_craft({
{rgblightstone,rgblightstone,rgblightstone,},
},
})
+
+core.register_craft({
+ output = "digiscreen:digiscreen_big",
+ recipe = {
+ {"digiscreen:digiscreen","digiscreen:digiscreen",},
+ {"digiscreen:digiscreen","digiscreen:digiscreen",},
+ },
+})