Rewrite call button communication

This is a breaking change, all existing call buttons will have to be removed and re-placed
This commit is contained in:
cheapie 2024-04-04 17:38:57 -05:00
parent 6856fc3979
commit 15fd61d88a
3 changed files with 68 additions and 27 deletions

View File

@ -135,20 +135,56 @@ for _,state in ipairs(validstates) do
{-0.16,-0.37,0.475,0.17,0.13,0.5}, {-0.16,-0.37,0.475,0.17,0.13,0.5},
}, },
}, },
after_place_node = function(pos)
local meta = minetest.get_meta(pos)
meta:set_string("formspec","formspec_version[7]size[8,5]field[0.5,0.5;7,1;carid;Car ID;]field[0.5,2;7,1;landing;Landing Number;]button[3,3.5;2,1;save;Save]")
end,
on_receive_fields = function(pos,_,fields)
if tonumber(fields.carid) and tonumber(fields.landing) then
local carid = tonumber(fields.carid)
local carinfo = minetest.deserialize(celevator.storage:get_string(string.format("car%d",carid)))
if not carinfo then return end
table.insert(carinfo.callbuttons,{pos=pos,landing=tonumber(fields.landing)})
celevator.storage:set_string(string.format("car%d",carid),minetest.serialize(carinfo))
local meta = minetest.get_meta(pos)
meta:set_int("carid",carid)
meta:set_int("landing",tonumber(fields.landing))
meta:set_string("formspec","")
end
end,
on_destruct = function(pos)
local meta = minetest.get_meta(pos)
local carid = meta:get_int("carid")
if carid == 0 then return end
local carinfo = minetest.deserialize(celevator.storage:get_string(string.format("car%d",carid)))
if not carinfo then return end
for i,button in pairs(carinfo.callbuttons) do
if vector.equals(pos,button.pos) then
table.remove(carinfo.callbuttons,i)
celevator.storage:set_string(string.format("car%d",carid),minetest.serialize(carinfo))
end
end
end,
on_rightclick = function(pos,_,clicker) on_rightclick = function(pos,_,clicker)
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
local controllerpos = minetest.string_to_pos(meta:get_string("controllerpos")) local carid = meta:get_int("carid")
if not controllerpos then return end if carid == 0 then return end
local carinfo = minetest.deserialize(celevator.storage:get_string(string.format("car%d",carid)))
if not carinfo then return end
local controllerpos = carinfo.controllerpos
local controllermeta = minetest.get_meta(controllerpos)
if controllermeta:get_int("carid") ~= carid then return end
local landing = meta:get_int("landing")
if state[1] == "up" then if state[1] == "up" then
celevator.controller.handlecallbutton(controllerpos,pos,"up") celevator.controller.handlecallbutton(controllerpos,landing,"up")
elseif state[1] == "down" then elseif state[1] == "down" then
celevator.controller.handlecallbutton(controllerpos,pos,"down") celevator.controller.handlecallbutton(controllerpos,landing,"down")
elseif state[1] == "both" then elseif state[1] == "both" then
local dir = disambiguatedir(pos,clicker) local dir = disambiguatedir(pos,clicker)
if dir == "up" then if dir == "up" then
celevator.controller.handlecallbutton(controllerpos,pos,"up") celevator.controller.handlecallbutton(controllerpos,landing,"up")
elseif dir == "down" then elseif dir == "down" then
celevator.controller.handlecallbutton(controllerpos,pos,"down") celevator.controller.handlecallbutton(controllerpos,landing,"down")
end end
end end
end, end,

View File

@ -152,6 +152,10 @@ minetest.register_node("celevator:controller",{
meta:mark_as_private("mem") meta:mark_as_private("mem")
local event = {} local event = {}
event.type = "program" event.type = "program"
local carid = celevator.storage:get_int("maxcarid")+1
meta:set_int("carid",carid)
celevator.storage:set_int("maxcarid",carid)
celevator.storage:set_string(string.format("car%d",carid),minetest.serialize({controllerpos=pos,pis={},lanterns={},callbuttons={}}))
celevator.controller.run(pos,event) celevator.controller.run(pos,event)
end, end,
on_punch = function(pos,node,puncher) on_punch = function(pos,node,puncher)
@ -404,6 +408,13 @@ function celevator.controller.finish(pos,mem,changedinterrupts)
if not celevator.controller.iscontroller(pos) then if not celevator.controller.iscontroller(pos) then
return return
else else
local meta = minetest.get_meta(pos)
local carid = meta:get_int("carid")
local carinfo = minetest.deserialize(celevator.storage:get_string(string.format("car%d",carid)))
if not carinfo then
minetest.log("error","[celevator] [controller] Bad car info for controller at "..minetest.pos_to_string(pos))
return
end
local drivepos,drivetype = celevator.controller.finddrive(pos) local drivepos,drivetype = celevator.controller.finddrive(pos)
if drivetype then if drivetype then
for _,command in ipairs(mem.drive.commands) do for _,command in ipairs(mem.drive.commands) do
@ -424,20 +435,19 @@ function celevator.controller.finish(pos,mem,changedinterrupts)
end end
end end
end end
local meta = minetest.get_meta(pos)
local node = minetest.get_node(pos) local node = minetest.get_node(pos)
local oldmem = minetest.deserialize(meta:get_string("mem")) or {} local oldmem = minetest.deserialize(meta:get_string("mem")) or {}
local oldupbuttonlights = oldmem.upcalls or {} local oldupbuttonlights = oldmem.upcalls or {}
local olddownbuttonlights = oldmem.dncalls or {} local olddownbuttonlights = oldmem.dncalls or {}
local newupbuttonlights = mem.upcalls or {} local newupbuttonlights = mem.upcalls or {}
local newdownbuttonlights = mem.dncalls or {} local newdownbuttonlights = mem.dncalls or {}
local callbuttons = minetest.deserialize(meta:get_string("callbuttons")) or {} local callbuttons = carinfo.callbuttons
for hash,landing in pairs(callbuttons) do for _,button in pairs(callbuttons) do
if oldupbuttonlights[landing] ~= newupbuttonlights[landing] then if oldupbuttonlights[button.landing] ~= newupbuttonlights[button.landing] then
celevator.callbutton.setlight(minetest.get_position_from_hash(hash),"up",newupbuttonlights[landing]) celevator.callbutton.setlight(button.pos,"up",newupbuttonlights[button.landing])
end end
if olddownbuttonlights[landing] ~= newdownbuttonlights[landing] then if olddownbuttonlights[button.landing] ~= newdownbuttonlights[button.landing] then
celevator.callbutton.setlight(minetest.get_position_from_hash(hash),"down",newdownbuttonlights[landing]) celevator.callbutton.setlight(button.pos,"down",newdownbuttonlights[button.landing])
end end
end end
local oldpitext = oldmem.pifloor or "--" local oldpitext = oldmem.pifloor or "--"
@ -530,23 +540,18 @@ function celevator.controller.run(pos,event)
mem.drive.status = celevator.drives[drivetype].getstatus(drivepos) mem.drive.status = celevator.drives[drivetype].getstatus(drivepos)
end end
mem.interrupts = celevator.controller.iqueue[minetest.hash_node_position(pos)] or {} mem.interrupts = celevator.controller.iqueue[minetest.hash_node_position(pos)] or {}
mem.carid = meta:get_int("carid")
minetest.handle_async(fw,celevator.controller.finish,pos,event,mem) minetest.handle_async(fw,celevator.controller.finish,pos,event,mem)
end end
end end
function celevator.controller.handlecallbutton(controllerpos,buttonpos,dir) function celevator.controller.handlecallbutton(controllerpos,landing,dir)
local buttonhash = minetest.hash_node_position(buttonpos) local event = {
local controllermeta = minetest.get_meta(controllerpos) type = "callbutton",
local pairings = minetest.deserialize(controllermeta:get_string("callbuttons")) or {} landing = landing,
if pairings[buttonhash] then dir = dir,
local landing = pairings[buttonhash] }
local event = { celevator.controller.run(controllerpos,event)
type = "callbutton",
landing = landing,
dir = dir,
}
celevator.controller.run(controllerpos,event)
end
end end
function celevator.controller.checkiqueue(dtime) function celevator.controller.checkiqueue(dtime)

View File

@ -740,7 +740,7 @@ if mem.drive.status.dpos > mem.drive.status.apos then
elseif mem.drive.status.dpos < mem.drive.status.apos then elseif mem.drive.status.dpos < mem.drive.status.apos then
arrow = "v" arrow = "v"
end end
mem.infotext = string.format("Floor %s %s - %s - Doors %s",mem.params.floornames[getpos()],arrow,modenames[mem.carstate],doorstates[mem.doorstate]) mem.infotext = string.format("ID %d: Floor %s %s - %s - Doors %s",mem.carid,mem.params.floornames[getpos()],arrow,modenames[mem.carstate],doorstates[mem.doorstate])
if mem.drive.type then if mem.drive.type then
mem.showrunning = mem.drive.status.vel ~= 0 mem.showrunning = mem.drive.status.vel ~= 0