From 19d69394b61ed9370d79c5efbd1b23fb8c5eac6a Mon Sep 17 00:00:00 2001 From: cheapie Date: Wed, 17 Apr 2024 17:56:01 -0500 Subject: Allow changing destination in-flight This allows new calls entered while the car is moving to be serviced before the original destination, provided they are in the correct direction, will be reached before the original destination, and the car can stop soon enough. --- controllerfw.lua | 116 +++++++++++++++++++++++++++++++++---------------------- drive_entity.lua | 55 ++++++++++++++++---------- drive_null.lua | 1 + 3 files changed, 104 insertions(+), 68 deletions(-) diff --git a/controllerfw.lua b/controllerfw.lua index 3065db2..ef99714 100644 --- a/controllerfw.lua +++ b/controllerfw.lua @@ -685,58 +685,80 @@ if mem.carmotion then end end -if (mem.carstate == "normal" or mem.carstate == "capture" or mem.carstate == "test" or mem.carstate == "indep" or mem.carstate == "fs2") and mem.doorstate == "closed" and not mem.carmotion then - if mem.direction == "up" then - if getnextcallabove("up") then - mem.direction = "up" - gotofloor(getnextcallabove("up")) - elseif gethighestdowncall() then - mem.direction = "down" - gotofloor(gethighestdowncall()) - elseif getlowestupcall() then - gotofloor(getlowestupcall()) - elseif getnextcallbelow("down") then - mem.direction = "down" - gotofloor(getnextcallbelow("down")) +if (mem.carstate == "normal" or mem.carstate == "capture" or mem.carstate == "test" or mem.carstate == "indep" or mem.carstate == "fs2") and mem.doorstate == "closed" then + if not mem.carmotion then + if mem.direction == "up" then + if getnextcallabove("up") then + mem.direction = "up" + gotofloor(getnextcallabove("up")) + elseif gethighestdowncall() then + mem.direction = "down" + gotofloor(gethighestdowncall()) + elseif getlowestupcall() then + gotofloor(getlowestupcall()) + elseif getnextcallbelow("down") then + mem.direction = "down" + gotofloor(getnextcallbelow("down")) + else + mem.direction = nil + end + elseif mem.direction == "down" then + if getnextcallbelow("down") then + gotofloor(getnextcallbelow("down")) + elseif getlowestupcall() then + mem.direction = "up" + gotofloor(getlowestupcall()) + elseif gethighestdowncall() then + gotofloor(gethighestdowncall()) + elseif getnextcallabove("up") then + mem.direction = "up" + gotofloor(getnextcallabove()) + else + mem.direction = nil + end else - mem.direction = nil + if getnextcallabove("up") then + mem.direction = "up" + gotofloor(getnextcallabove()) + elseif getnextcallbelow("down") then + mem.direction = "down" + gotofloor(getnextcallbelow("down")) + elseif getlowestupcall() then + mem.direction = "up" + gotofloor(getlowestupcall()) + elseif gethighestdowncall() then + mem.direction = "down" + gotofloor(gethighestdowncall()) + end end - elseif mem.direction == "down" then - if getnextcallbelow("down") then - gotofloor(getnextcallbelow("down")) - elseif getlowestupcall() then - mem.direction = "up" - gotofloor(getlowestupcall()) - elseif gethighestdowncall() then - gotofloor(gethighestdowncall()) - elseif getnextcallabove("up") then - mem.direction = "up" - gotofloor(getnextcallabove()) - else - mem.direction = nil + if mem.carstate == "normal" and mem.capturesw and not mem.direction then + mem.upcalls = {} + mem.dncalls = {} + mem.carstate = "capture" + elseif mem.carstate == "capture" and mem.direction then + mem.carstate = "normal" end - else - if getnextcallabove("up") then - mem.direction = "up" - gotofloor(getnextcallabove()) - elseif getnextcallbelow("down") then - mem.direction = "down" - gotofloor(getnextcallbelow("down")) - elseif getlowestupcall() then - mem.direction = "up" - gotofloor(getlowestupcall()) - elseif gethighestdowncall() then - mem.direction = "down" - gotofloor(gethighestdowncall()) + elseif (mem.carstate == "normal" or mem.carstate == "capture" or mem.carstate == "test") and mem.carmotion then + if mem.drive.status.vel > 0 then + local nextup = getnextcallabove("up") + if nextup then + mem.direction = "up" + local target = gettarget(nextup) + if target < mem.drive.status.dpos and target > mem.drive.status.neareststop then + gotofloor(nextup) + end + end + elseif mem.drive.status.vel < 0 then + local nextdown = getnextcallbelow("down") + if nextdown then + mem.direction = "down" + local target = gettarget(nextdown) + if target > mem.drive.status.dpos and target < mem.drive.status.neareststop then + gotofloor(nextdown) + end + end end end - if mem.carstate == "normal" and mem.capturesw and not mem.direction then - mem.upcalls = {} - mem.dncalls = {} - mem.carstate = "capture" - elseif mem.carstate == "capture" and mem.direction then - mem.carstate = "normal" - end end if mem.scrollfollowscar and mem.screenstate == "status" then diff --git a/drive_entity.lua b/drive_entity.lua index e1e448b..6378725 100644 --- a/drive_entity.lua +++ b/drive_entity.lua @@ -463,7 +463,6 @@ minetest.register_globalstep(celevator.drives.entity.step) function celevator.drives.entity.moveto(pos,target) local meta = minetest.get_meta(pos) - if meta:get_string("state") ~= "stopped" then return end local carid = minetest.get_meta(pos):get_int("carid") local carinfo = minetest.deserialize(celevator.storage:get_string(string.format("car%d",carid))) if not (carinfo and carinfo.machinepos) then return end @@ -477,27 +476,40 @@ function celevator.drives.entity.moveto(pos,target) meta:set_string("fault","outofbounds") return end - meta:set_string("dpos",tostring(target)) - meta:set_string("state","start") - meta:set_string("startpos",meta:get_string("apos")) - local hash = minetest.hash_node_position(pos) - local entitydrives_running = minetest.deserialize(celevator.storage:get_string("entitydrives_running")) or {} - local running = false - for _,dhash in ipairs(entitydrives_running) do - if hash == dhash then - running = true - break - end - end - if not running then - table.insert(entitydrives_running,hash) - celevator.storage:set_string("entitydrives_running",minetest.serialize(entitydrives_running)) - --Controller needs to see something so it knows the drive is running + if meta:get_string("state") ~= "stopped" then local apos = tonumber(meta:get_string("apos")) - if apos and apos > target then - meta:set_string("vel","-0.0001") + local vel = tonumber(meta:get_string("vel")) + if vel > 0 then + if target < apos+(vel*2) then return end + elseif vel < 0 then + if target > apos-(vel*-2) then return end else - meta:set_string("vel","0.0001") + return + end + end + meta:set_string("dpos",tostring(target)) + if meta:get_string("state") == "stopped" then + meta:set_string("state","start") + meta:set_string("startpos",meta:get_string("apos")) + local hash = minetest.hash_node_position(pos) + local entitydrives_running = minetest.deserialize(celevator.storage:get_string("entitydrives_running")) or {} + local running = false + for _,dhash in ipairs(entitydrives_running) do + if hash == dhash then + running = true + break + end + end + if not running then + table.insert(entitydrives_running,hash) + celevator.storage:set_string("entitydrives_running",minetest.serialize(entitydrives_running)) + --Controller needs to see something so it knows the drive is running + local apos = tonumber(meta:get_string("apos")) + if apos and apos > target then + meta:set_string("vel","-0.0001") + else + meta:set_string("vel","0.0001") + end end end end @@ -540,7 +552,7 @@ function celevator.drives.entity.getstatus(pos,call2) local node = minetest.get_node(pos) if node.name == "ignore" and not call2 then minetest.forceload_block(pos,true) - return celevator.drives.null.get_status(pos,true) + return celevator.drives.entity.get_status(pos,true) elseif node.name ~= "celevator:drive" then minetest.log("error","[celevator] [entity drive] Could not load drive status at "..minetest.pos_to_string(pos)) return {fault = "metaload"} @@ -554,6 +566,7 @@ function celevator.drives.entity.getstatus(pos,call2) ret.state = meta:get_string("state") ret.doorstate = meta:get_string("doorstate") ret.fault = meta:get_string("fault") + ret.neareststop = ret.apos+(ret.vel*2) if ret.fault == "" then ret.fault = nil end return ret end diff --git a/drive_null.lua b/drive_null.lua index 1a98970..eaf1515 100644 --- a/drive_null.lua +++ b/drive_null.lua @@ -222,6 +222,7 @@ function celevator.drives.null.getstatus(pos,call2) ret.vel = tonumber(meta:get_string("vel")) or 0 ret.maxvel = tonumber(meta:get_string("maxvel")) or 0.2 ret.doorstate = meta:get_string("doorstate") + ret.neareststop = ret.apos+(ret.vel*2) return ret end end -- cgit v1.2.3