From 15fd61d88ab31d9199604c37614d4459792c1016 Mon Sep 17 00:00:00 2001 From: cheapie Date: Thu, 4 Apr 2024 17:38:57 -0500 Subject: Rewrite call button communication This is a breaking change, all existing call buttons will have to be removed and re-placed --- callbuttons.lua | 48 ++++++++++++++++++++++++++++++++++++++++++------ controller.lua | 45 +++++++++++++++++++++++++-------------------- controllerfw.lua | 2 +- 3 files changed, 68 insertions(+), 27 deletions(-) diff --git a/callbuttons.lua b/callbuttons.lua index fb2fd6e..080ca54 100644 --- a/callbuttons.lua +++ b/callbuttons.lua @@ -135,20 +135,56 @@ for _,state in ipairs(validstates) do {-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) local meta = minetest.get_meta(pos) - local controllerpos = minetest.string_to_pos(meta:get_string("controllerpos")) - if not controllerpos then return end + 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 + 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 - celevator.controller.handlecallbutton(controllerpos,pos,"up") + celevator.controller.handlecallbutton(controllerpos,landing,"up") elseif state[1] == "down" then - celevator.controller.handlecallbutton(controllerpos,pos,"down") + celevator.controller.handlecallbutton(controllerpos,landing,"down") elseif state[1] == "both" then local dir = disambiguatedir(pos,clicker) if dir == "up" then - celevator.controller.handlecallbutton(controllerpos,pos,"up") + celevator.controller.handlecallbutton(controllerpos,landing,"up") elseif dir == "down" then - celevator.controller.handlecallbutton(controllerpos,pos,"down") + celevator.controller.handlecallbutton(controllerpos,landing,"down") end end end, diff --git a/controller.lua b/controller.lua index 8d6b210..3fde24f 100644 --- a/controller.lua +++ b/controller.lua @@ -152,6 +152,10 @@ minetest.register_node("celevator:controller",{ meta:mark_as_private("mem") local event = {} 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) end, on_punch = function(pos,node,puncher) @@ -404,6 +408,13 @@ function celevator.controller.finish(pos,mem,changedinterrupts) if not celevator.controller.iscontroller(pos) then return 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) if drivetype then for _,command in ipairs(mem.drive.commands) do @@ -424,20 +435,19 @@ function celevator.controller.finish(pos,mem,changedinterrupts) end end end - local meta = minetest.get_meta(pos) local node = minetest.get_node(pos) local oldmem = minetest.deserialize(meta:get_string("mem")) or {} local oldupbuttonlights = oldmem.upcalls or {} local olddownbuttonlights = oldmem.dncalls or {} local newupbuttonlights = mem.upcalls or {} local newdownbuttonlights = mem.dncalls or {} - local callbuttons = minetest.deserialize(meta:get_string("callbuttons")) or {} - for hash,landing in pairs(callbuttons) do - if oldupbuttonlights[landing] ~= newupbuttonlights[landing] then - celevator.callbutton.setlight(minetest.get_position_from_hash(hash),"up",newupbuttonlights[landing]) + local callbuttons = carinfo.callbuttons + for _,button in pairs(callbuttons) do + if oldupbuttonlights[button.landing] ~= newupbuttonlights[button.landing] then + celevator.callbutton.setlight(button.pos,"up",newupbuttonlights[button.landing]) end - if olddownbuttonlights[landing] ~= newdownbuttonlights[landing] then - celevator.callbutton.setlight(minetest.get_position_from_hash(hash),"down",newdownbuttonlights[landing]) + if olddownbuttonlights[button.landing] ~= newdownbuttonlights[button.landing] then + celevator.callbutton.setlight(button.pos,"down",newdownbuttonlights[button.landing]) end end local oldpitext = oldmem.pifloor or "--" @@ -530,23 +540,18 @@ function celevator.controller.run(pos,event) mem.drive.status = celevator.drives[drivetype].getstatus(drivepos) end 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) end end -function celevator.controller.handlecallbutton(controllerpos,buttonpos,dir) - local buttonhash = minetest.hash_node_position(buttonpos) - local controllermeta = minetest.get_meta(controllerpos) - local pairings = minetest.deserialize(controllermeta:get_string("callbuttons")) or {} - if pairings[buttonhash] then - local landing = pairings[buttonhash] - local event = { - type = "callbutton", - landing = landing, - dir = dir, - } - celevator.controller.run(controllerpos,event) - end +function celevator.controller.handlecallbutton(controllerpos,landing,dir) + local event = { + type = "callbutton", + landing = landing, + dir = dir, + } + celevator.controller.run(controllerpos,event) end function celevator.controller.checkiqueue(dtime) diff --git a/controllerfw.lua b/controllerfw.lua index abfc358..a4efbec 100644 --- a/controllerfw.lua +++ b/controllerfw.lua @@ -740,7 +740,7 @@ if mem.drive.status.dpos > mem.drive.status.apos then elseif mem.drive.status.dpos < mem.drive.status.apos then arrow = "v" 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 mem.showrunning = mem.drive.status.vel ~= 0 -- cgit v1.2.3