From fe7684c847950afd10c24f8b1d25ab53e6354b72 Mon Sep 17 00:00:00 2001 From: cheapie Date: Fri, 4 Aug 2023 13:02:38 -0500 Subject: Add pairing tool and make call buttons functional --- callbuttons.lua | 15 +++++--- controller.lua | 31 ++++++++++++++- controllerfw.lua | 6 +++ init.lua | 1 + pairingtool.lua | 76 +++++++++++++++++++++++++++++++++++++ textures/celevator_pairingtool.png | Bin 0 -> 620 bytes 6 files changed, 123 insertions(+), 6 deletions(-) create mode 100644 pairingtool.lua create mode 100644 textures/celevator_pairingtool.png diff --git a/callbuttons.lua b/callbuttons.lua index 97d839f..e41f863 100644 --- a/callbuttons.lua +++ b/callbuttons.lua @@ -1,3 +1,5 @@ +celevator.callbutton = {} + local function makebuttontex(dir,upon,downon) local tex = "[combine:64x64:0,0=celevator_cabinet_sides.png:32,0=celevator_cabinet_sides.png:0,32=celevator_cabinet_sides.png:32,32=celevator_cabinet_sides.png:22,24=celevator_callbutton_panel.png" if dir == "up" then @@ -33,7 +35,7 @@ local validstates = { {"both",true,true,"Up and Down"}, } -local function setlight(pos,dir,newstate) +function celevator.callbutton.setlight(pos,dir,newstate) local node = minetest.get_node(pos) if minetest.get_item_group(node.name,"_celevator_callbutton") ~= 1 then return end if dir == "up" then @@ -135,16 +137,19 @@ for _,state in ipairs(validstates) do }, }, 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 if state[1] == "up" then - setlight(pos,"up",not state[2]) + celevator.controller.handlecallbutton(controllerpos,pos,"up") elseif state[1] == "down" then - setlight(pos,"down",not state[3]) + celevator.controller.handlecallbutton(controllerpos,pos,"down") elseif state[1] == "both" then local dir = disambiguatedir(pos,clicker) if dir == "up" then - setlight(pos,"up",not state[2]) + celevator.controller.handlecallbutton(controllerpos,pos,"up") elseif dir == "down" then - setlight(pos,"down",not state[3]) + celevator.controller.handlecallbutton(controllerpos,pos,"down") end end end, diff --git a/controller.lua b/controller.lua index a2071ec..a607666 100644 --- a/controller.lua +++ b/controller.lua @@ -419,6 +419,20 @@ function celevator.controller.finish(pos,mem) 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]) + end + if olddownbuttonlights[landing] ~= newdownbuttonlights[landing] then + celevator.callbutton.setlight(minetest.get_position_from_hash(hash),"down",newdownbuttonlights[landing]) + end + end meta:set_string("mem",minetest.serialize(mem)) if node.name == "celevator:controller_open" then meta:set_string("formspec",mem.formspec or "") end meta:set_string("formspec_hidden",mem.formspec or "") @@ -459,7 +473,7 @@ function celevator.controller.run(pos,event) local mem = minetest.deserialize(meta:get_string("mem")) if not mem then minetest.log("error","[celevator] [controller] Failed to load controller memory at "..minetest.pos_to_string(pos)) - mem = {} + return end mem.drive = {} mem.drive.commands = {} @@ -473,6 +487,21 @@ function celevator.controller.run(pos,event) 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 +end + function celevator.controller.checkiqueue(dtime) for hash,iqueue in pairs(celevator.controller.iqueue) do local pos = minetest.get_position_from_hash(hash) diff --git a/controllerfw.lua b/controllerfw.lua index e21a9e7..f9dfacc 100644 --- a/controllerfw.lua +++ b/controllerfw.lua @@ -395,6 +395,12 @@ elseif event.iid == "closed" and (mem.doorstate == "closing" or mem.doorstate == mem.carmotion = true juststarted = true end +elseif event.type == "callbutton" and mem.carstate == "normal" then + if event.dir == "up" and event.landing >= 1 and event.landing < #mem.params.floornames then + mem.upcalls[event.landing] = true + elseif event.dir == "down" and event.landing > 1 and event.landing <= #mem.params.floornames then + mem.dncalls[event.landing] = true + end end local oldstate = mem.carstate diff --git a/init.lua b/init.lua index 0c44a32..6de4cb6 100644 --- a/init.lua +++ b/init.lua @@ -3,6 +3,7 @@ local components = { "drive_null", "controller", "callbuttons", + "pairingtool", } for _,v in ipairs(components) do diff --git a/pairingtool.lua b/pairingtool.lua new file mode 100644 index 0000000..770c7d7 --- /dev/null +++ b/pairingtool.lua @@ -0,0 +1,76 @@ +celevator.pairing = { + playerstate = {} +} + +minetest.register_on_player_receive_fields(function (player,formname,fields) + if formname ~= "celevator:pairing_floornum" then return end + if not celevator.pairing.playerstate[player:get_player_name()] then return end + if not tonumber(fields.floornum) then return end + local targetpos = celevator.pairing.playerstate[player:get_player_name()].pos + local controllerpos = celevator.pairing.playerstate[player:get_player_name()].controllerpos + if minetest.get_item_group(minetest.get_node(targetpos).name,"_celevator_callbutton") == 1 then + local nodemeta = minetest.get_meta(targetpos) + nodemeta:set_string("controllerpos",minetest.pos_to_string(controllerpos)) + local controllermeta = minetest.get_meta(controllerpos) + local pairings = minetest.deserialize(controllermeta:get_string("callbuttons")) or {} + local hash = minetest.hash_node_position(targetpos) + pairings[hash] = math.floor(tonumber(fields.floornum)) + controllermeta:set_string("callbuttons",minetest.serialize(pairings)) + minetest.chat_send_player(player:get_player_name(),"Paired to "..minetest.pos_to_string(controllerpos).." as landing "..pairings[hash]) + celevator.pairing.playerstate[player:get_player_name()] = nil + end +end) + +minetest.register_tool("celevator:pairingtool",{ + description = "Pairing Tool", + inventory_image = "celevator_pairingtool.png", + on_use = function(itemstack,player,pointed) + if not (pointed and pointed.under) then return itemstack end + if not (player and player:get_player_name()) then return end + local pos = pointed.under + local name = player:get_player_name() + local node = minetest.get_node(pos) + if not node then return itemstack end + if celevator.controller.iscontroller(pos) then + local stackmeta = itemstack:get_meta() + stackmeta:set_string("controllerpos",minetest.pos_to_string(pos)) + minetest.chat_send_player(name,"Now pairing with controller at "..minetest.pos_to_string(pos)) + elseif minetest.get_item_group(node.name,"_celevator_callbutton") == 1 then + local stackmeta = itemstack:get_meta() + local nodemeta = minetest.get_meta(pos) + local oldpairing = minetest.string_to_pos(nodemeta:get_string("controllerpos")) + local controllerpos = minetest.string_to_pos(stackmeta:get_string("controllerpos")) + if not controllerpos then + minetest.chat_send_player(name,"Nothing has been selected to pair with! Punch a controller or dispatcher first.") + elseif oldpairing then + local controllermeta = minetest.get_meta(oldpairing) + local pairings = minetest.deserialize(controllermeta:get_string("callbuttons")) + if pairings then + local hash = minetest.hash_node_position(pos) + pairings[hash] = nil + controllermeta:set_string("callbuttons",minetest.serialize(pairings)) + end + nodemeta:set_string("controllerpos","") + minetest.chat_send_player(player:get_player_name(),"Unpaired from "..minetest.pos_to_string(oldpairing)) + elseif celevator.controller.iscontroller(controllerpos) then + if minetest.is_protected(controllerpos,name) and not minetest.check_player_privs(name,{protection_bypass=true}) then + minetest.chat_send_player(name,"Unable to pair - controller at "..minetest.pos_to_string(controllerpos).." is protected!") + minetest.record_protection_violation(controllerpos,name) + elseif minetest.is_protected(pos,name) and not minetest.check_player_privs(name,{protection_bypass=true}) then + minetest.chat_send_player(name,"Unable to pair - item to be paired is protected!") + minetest.record_protection_violation(pos,name) + else + celevator.pairing.playerstate[name] = { + pos = pos, + controllerpos = controllerpos, + } + minetest.show_formspec(name,"celevator:pairing_floornum","field[floornum;Landing Number;1]") + end + else + minetest.chat_send_player(name,"Controller or dispatcher has been removed. Punch a new controller or dispatcher to pair to that one.") + end + end + return itemstack + end, +}) + diff --git a/textures/celevator_pairingtool.png b/textures/celevator_pairingtool.png new file mode 100644 index 0000000..6e570cc Binary files /dev/null and b/textures/celevator_pairingtool.png differ -- cgit v1.2.3