Created
July 27, 2023 03:13
-
-
Save cheapie/60945927d38c78cb7a81b1554f167381 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local techage = require("techage") | |
local is_button = {} | |
if mem.params then for k,v in ipairs(mem.params.button_ids) do is_button[v] = k end end | |
local function getnextcallabove() | |
if mem.actpos == mem.params.num_floors then return end | |
for i=mem.actpos,mem.params.num_floors,1 do | |
if mem.queue[i] then return i end | |
end | |
end | |
local function getnextcallbelow() | |
if mem.actpos == 1 then return end | |
for i=mem.actpos,1,-1 do | |
if mem.queue[i] then return i end | |
end | |
end | |
local function calc_move(act,des) | |
local movelen = 0 | |
if act<des then | |
for i=act,des-1,1 do | |
movelen = movelen+mem.params.distance_above[i] | |
end | |
elseif act>des then | |
for i=des,act-1,1 do | |
movelen = movelen-mem.params.distance_above[i] | |
end | |
end | |
return movelen | |
end | |
local function open() | |
if mem.state ~= "idle" then return end --Yes, that's the door lock. I'm sure it meets safety standards. | |
mem.state = "opening" | |
interrupt(3,"opened") | |
local doors = mem.params.door_ids[mem.actpos] | |
for _,v in ipairs(doors) do | |
techage.send(v,"a2b") | |
end | |
end | |
local function close() | |
if mem.state ~= "open" then return end | |
mem.state = "closing" | |
interrupt(3,"closed") | |
local doors = mem.params.door_ids[mem.actpos] | |
for _,v in ipairs(doors) do | |
techage.send(v,"b2a") | |
end | |
end | |
local function go() | |
if mem.despos == mem.actpos then return end | |
if mem.state ~= "idle" then return end | |
mem.state = "moving" | |
local distance = calc_move(mem.actpos,mem.despos) | |
techage.send(mem.params.hoist_id,"move2",string.format("0,%d,0",distance)) | |
interrupt(0.5,"checkhoist") | |
end | |
local function handle_call() | |
local nextup = getnextcallabove() | |
local nextdn = getnextcallbelow() | |
if mem.dir == "up" then | |
if nextup then | |
mem.despos = nextup | |
elseif nextdn then | |
mem.dir = "down" | |
mem.despos = nextdn | |
end | |
elseif mem.dir == "down" then | |
if nextdn then | |
mem.despos = nextdn | |
elseif nextup then | |
mem.dir = "up" | |
mem.despos = nextup | |
end | |
end | |
if mem.despos ~= mem.actpos then | |
go() | |
elseif mem.queue[mem.actpos] and mem.state == "idle" then | |
open() | |
mem.queue[mem.actpos] = nil | |
end | |
end | |
local function termparse(text) | |
if text == "" and mem.termstate ~= "status" then return end | |
local comma = string.find(text,",",nil,true) | |
local cmd = comma and string.upper(string.sub(text,1,comma-1)) or string.upper(text) | |
local remain = "" | |
if comma then | |
remain = string.sub(text,comma+1,-1) | |
end | |
if cmd == "CC" then | |
mem.termstate = "carcall" | |
elseif mem.termstate == "status" then | |
mem.termstate = "mainmenu" | |
if text ~= "" then termparse(text) end | |
elseif mem.termstate == "mainmenu" then | |
if cmd == ".." or cmd == "ST" then | |
mem.termstate = "status" | |
elseif cmd == "SY" then | |
mem.termstate = "system_commands" | |
elseif cmd == "AD" then | |
mem.termstate = "adjustments" | |
end | |
elseif mem.termstate == "system_commands" then | |
mem.extraspace = not mem.extraspace | |
if cmd == ".." then | |
mem.termstate = "mainmenu" | |
elseif cmd == "OP" then | |
if mem.state == "idle" then open() end | |
elseif cmd == "CL" then | |
if mem.state == "open" then interrupt(0,"close") end | |
elseif cmd == "CA" then | |
mem.termstate = "carcall" | |
end | |
elseif mem.termstate == "adjustments" then | |
if cmd == ".." then | |
mem.termstate = "mainmenu" | |
elseif cmd == "FL" then | |
mem.termstate = "floortable" | |
elseif cmd == "BU" then | |
mem.termstate = "buttonids" | |
elseif cmd == "DO" then | |
mem.termstate = "doorids" | |
elseif cmd == "MO" then | |
mem.termstate = "hoistid" | |
elseif cmd == "RE" then | |
mem.termstate = "relearn" | |
end | |
elseif mem.termstate == "floortable" then | |
if cmd == ".." then | |
mem.termstate = "adjustments" | |
elseif cmd == "AD" then | |
mem.termstate = "addfloor" | |
elseif cmd == "ED" then | |
mem.termstate = "editheight" | |
elseif cmd == "RE" then | |
mem.termstate = "removefloor" | |
end | |
elseif mem.termstate == "addfloor" then | |
local height = tonumber(cmd) | |
if height then | |
if height == math.floor(height) and height > 0 and height < 200 then | |
mem.params.num_floors = mem.params.num_floors+1 | |
mem.params.distance_above[mem.params.num_floors-1] = height | |
mem.params.door_ids[mem.params.num_floors] = {} | |
mem.termstate = "floortable" | |
end | |
else | |
mem.termstate = "floortable" | |
end | |
elseif mem.termstate == "editheight" then | |
local floor = tonumber(cmd) | |
if floor then | |
if floor == math.floor(floor) and floor > 0 and floor < mem.params.num_floors then | |
mem.editingfloor = floor | |
mem.termstate = "editheight2" | |
end | |
else | |
mem.termstate = "floortable" | |
end | |
elseif mem.termstate == "editheight2" then | |
local height = tonumber(cmd) | |
if height then | |
if height == math.floor(height) and height > 0 and height < 200 then | |
mem.params.distance_above[mem.editingfloor] = height | |
mem.termstate = "floortable" | |
end | |
else | |
mem.termstate = "floortable" | |
end | |
elseif mem.termstate == "removefloor" then | |
local floor = tonumber(cmd) | |
if floor then | |
if floor == math.floor(floor) and floor > 0 and floor <= mem.params.num_floors then | |
if floor < mem.params.num_floors then table.remove(mem.params.distance_above,floor) end | |
table.remove(mem.params.door_ids,floor) | |
mem.params.num_floors = mem.params.num_floors-1 | |
mem.termstate = "floortable" | |
end | |
else | |
mem.termstate = "floortable" | |
end | |
elseif mem.termstate == "hoistid" then | |
local id = tonumber(cmd) | |
if id then | |
if id == math.floor(id) and id >= 0 then | |
mem.params.hoist_id = id | |
mem.termstate = "adjustments" | |
end | |
else | |
mem.termstate = "adjustments" | |
end | |
elseif mem.termstate == "buttonids" then | |
if cmd == ".." then | |
mem.termstate = "adjustments" | |
elseif cmd == "AD" then | |
mem.termstate = "addbutton" | |
elseif cmd == "RE" then | |
mem.termstate = "removebutton" | |
end | |
elseif mem.termstate == "addbutton" then | |
local id = tonumber(cmd) | |
if id then | |
if id == math.floor(id) and id >= 0 then | |
if not is_button[id] then | |
table.insert(mem.params.button_ids,id) | |
end | |
mem.termstate = "buttonids" | |
end | |
else | |
mem.termstate = "buttonids" | |
end | |
elseif mem.termstate == "removebutton" then | |
local id = tonumber(cmd) | |
if id then | |
if id == math.floor(id) and id >= 0 then | |
if is_button[id] then | |
table.remove(mem.params.button_ids,is_button[id]) | |
end | |
mem.termstate = "buttonids" | |
end | |
else | |
mem.termstate = "buttonids" | |
end | |
elseif mem.termstate == "doorids" then | |
local floor = tonumber(cmd) | |
if floor then | |
if floor == math.floor(floor) and floor > 0 and floor <= mem.params.num_floors then | |
mem.editingfloor = floor | |
mem.termstate = "doorids2" | |
end | |
else | |
mem.termstate = "adjustments" | |
end | |
elseif mem.termstate == "doorids2" then | |
if cmd == ".." then | |
mem.termstate = "adjustments" | |
elseif cmd == "AD" then | |
mem.termstate = "adddoor" | |
elseif cmd == "RE" then | |
mem.termstate = "removedoor" | |
end | |
elseif mem.termstate == "adddoor" then | |
local is_door = {} | |
for k,v in ipairs(mem.params.door_ids[mem.editingfloor]) do | |
is_door[v] = k | |
end | |
local id = tonumber(cmd) | |
if id then | |
if id == math.floor(id) and id >= 0 then | |
if not is_door[id] then | |
table.insert(mem.params.door_ids[mem.editingfloor],id) | |
end | |
mem.termstate = "doorids2" | |
end | |
else | |
mem.termstate = "doorids2" | |
end | |
elseif mem.termstate == "removedoor" then | |
local is_door = {} | |
for k,v in ipairs(mem.params.door_ids[mem.editingfloor]) do | |
is_door[v] = k | |
end | |
local id = tonumber(cmd) | |
if id then | |
if id == math.floor(id) and id >= 0 then | |
if is_door[id] then | |
table.remove(mem.params.door_ids[mem.editingfloor],is_door[id]) | |
end | |
mem.termstate = "doorids2" | |
end | |
else | |
mem.termstate = "doorids2" | |
end | |
elseif mem.termstate == "carcall" then | |
mem.extraspace = not mem.extraspace | |
local floor = tonumber(cmd) | |
if floor then | |
if floor == math.floor(floor) and floor > 0 and floor <= mem.params.num_floors then | |
if mem.actpos == floor and mem.state == "idle" then | |
open() | |
else | |
mem.queue[floor] = true | |
if mem.state == "idle" then | |
handle_call() | |
elseif mem.state == "open" then | |
interrupt(0,"close") | |
end | |
end | |
mem.termstate = "system_commands" | |
end | |
else | |
mem.termstate = "system_commands" | |
end | |
end | |
if comma then termparse(remain) end | |
end | |
if event.type == "program" then | |
mem.actpos = 1 | |
mem.despos = 1 | |
mem.state = "idle" | |
mem.queue = {} | |
mem.dir = "up" | |
mem.termstate = "status" | |
if not mem.params then | |
mem.params = { | |
num_floors = 1, | |
distance_above = {}, | |
button_ids = {}, | |
door_ids = {{}}, | |
hoist_id = -1, | |
} | |
end | |
techage.init() | |
elseif event.channel and string.sub(event.channel,1,8) == "techage_" and is_button[tonumber(string.sub(event.channel,9,-1))] then | |
local callpos = tonumber(event.msg.message) | |
if event.msg.message == "open" and mem.state == "idle" then | |
open() | |
elseif callpos then | |
mem.queue[callpos] = (mem.actpos ~= callpos) or (mem.state ~= "open") | |
if mem.state == "idle" then | |
handle_call() | |
elseif mem.state == "open" then | |
interrupt(callpos == mem.actpos and 8 or 0,"close") | |
end | |
end | |
elseif event.iid == "checkdoors" then | |
techage.send(mem.params.door_ids[mem.actpos][1],"state") | |
elseif event.channel and event.channel==string.format("techagereply_%d",mem.params.door_ids[mem.actpos][1]) and mem.state == "opening" then | |
if event.msg == "stopped" then | |
interrupt(0.25,"opened") | |
else | |
interrupt(0.25,"checkdoors") | |
end | |
elseif event.channel and event.channel==string.format("techagereply_%d",mem.params.door_ids[mem.actpos][1]) and mem.state == "closing" then | |
if event.msg == "stopped" then | |
interrupt(0.25,"closed") | |
else | |
interrupt(0.25,"checkdoors") | |
end | |
elseif event.iid == "opened" and mem.state == "opening" then | |
mem.state = "open" | |
interrupt(8,"close") | |
elseif event.iid == "closed" and mem.state == "closing" then | |
mem.state = "idle" | |
handle_call() | |
elseif event.iid == "close" and mem.state == "open" then | |
close() | |
elseif event.iid == "checkhoist" and mem.state == "moving" then | |
techage.send(mem.params.hoist_id,"state") | |
elseif event.channel and event.channel==string.format("techagereply_%d",mem.params.hoist_id) then | |
if event.msg == "stopped" then | |
mem.actpos = mem.despos | |
mem.state = "idle" | |
mem.queue[mem.actpos] = nil | |
open() | |
else | |
interrupt(0.5,"checkhoist") | |
end | |
elseif event.type == "terminal" then | |
termparse(event.text) | |
end | |
clearterm() | |
if mem.termstate == "status" then | |
local date = os.datetable() | |
print("GREAPIE MINECONIC VM "..string.format("%04d-%02d-%02d %02d:%02d:%02d",date.year,date.month,date.day,date.hour,date.min,date.sec)) | |
print() | |
print() | |
print() | |
for i=mem.params.num_floors,1,-1 do | |
local car = (mem.queue[i] and " * " or " ") | |
if mem.actpos == i then | |
if mem.state == "opening" then | |
car = "[< >]" | |
elseif mem.state == "closing" then | |
car = "[> <]" | |
elseif mem.state == "open" then | |
car = "[ ]" | |
else | |
car = "[ | ]" | |
end | |
end | |
print(string.format(" %02d |%s| %02d",i,car,i)) | |
end | |
print() | |
print(string.format(" POS %02d POS",mem.actpos)) | |
print(string.format(" DRV %02d DRV",mem.despos)) | |
elseif mem.termstate == "mainmenu" then | |
print("MAIN MENU") | |
print() | |
print("* SYSTEM COMMANDS") | |
print() | |
print("* ADJUSTMENTS") | |
print() | |
print("* STATUS") | |
print() | |
print("]") | |
elseif mem.termstate == "system_commands" then | |
print("SYSTEM COMMANDS") | |
print((mem.extraspace and " " or "")) | |
print("* CAR CALL") | |
print() | |
print("* OPEN DOORS") | |
print() | |
print("* CLOSE DOORS") | |
print() | |
print("]") | |
elseif mem.termstate == "adjustments" then | |
print("ADJUSTMENTS") | |
print() | |
print("* FLOOR TABLE") | |
print() | |
print("* BUTTON IDS") | |
print() | |
print("* DOOR IDS") | |
print() | |
if mem.params.hoist_id >= 0 then | |
print("* MOTOR ID: "..tostring(mem.params.hoist_id)) | |
else | |
print("* MOTOR ID: --") | |
end | |
print() | |
print("]") | |
elseif mem.termstate == "floortable" then | |
print("FLOOR TABLE") | |
print() | |
for i=mem.params.num_floors,1,-1 do | |
if i == mem.params.num_floors then | |
print(string.format("%d: HEIGHT -",i)) | |
else | |
print(string.format("%d: HEIGHT %d",i,mem.params.distance_above[i])) | |
end | |
end | |
print() | |
print("* ADD FLOOR") | |
print() | |
print("* EDIT HEIGHT") | |
print() | |
print("* REMOVE FLOOR") | |
print() | |
print("]") | |
elseif mem.termstate == "editheight" or mem.termstate == "removefloor" then | |
print() | |
print("FLOOR NUMBER?") | |
print("]") | |
elseif mem.termstate == "addfloor" then | |
print() | |
print("HEIGHT OF PREVIOUS FLOOR?") | |
print("]") | |
elseif mem.termstate == "editheight2" then | |
print() | |
print("FLOOR HEIGHT?") | |
print("]") | |
elseif mem.termstate == "hoistid" then | |
print() | |
print("MOTOR ID?") | |
print("]") | |
elseif mem.termstate == "buttonids" then | |
print("BUTTON IDS") | |
print() | |
if #mem.params.button_ids > 0 then | |
local linecount = #mem.params.button_ids%10+1 | |
for i=1,linecount,1 do | |
local line = "" | |
local start = (i-1)*10+1 | |
for j=start,start+9,1 do | |
if j <= #mem.params.button_ids then | |
line = line..tostring(mem.params.button_ids[j])..", " | |
end | |
end | |
if string.len(line) > 2 then | |
print(string.sub(line,1,-3)) | |
end | |
end | |
else | |
print("NONE") | |
end | |
print() | |
print("* ADD BUTTON") | |
print() | |
print("* REMOVE BUTTON") | |
print() | |
print("]") | |
elseif mem.termstate == "addbutton" or mem.termstate == "removebutton" then | |
print() | |
print("BUTTON ID?") | |
print("]") | |
elseif mem.termstate == "doorids" then | |
print() | |
print("FLOOR NUMBER?") | |
print("]") | |
elseif mem.termstate == "doorids2" then | |
print("DOOR IDS - FLOOR "..tostring(mem.editingfloor)) | |
print() | |
if #mem.params.door_ids[mem.editingfloor] > 0 then | |
local linecount = #mem.params.door_ids[mem.editingfloor]%10+1 | |
for i=1,linecount,1 do | |
local line = "" | |
local start = (i-1)*10+1 | |
for j=start,start+9,1 do | |
if j <= #mem.params.door_ids[mem.editingfloor] then | |
line = line..tostring(mem.params.door_ids[mem.editingfloor][j])..", " | |
end | |
end | |
if string.len(line) > 2 then | |
print(string.sub(line,1,-3)) | |
end | |
end | |
else | |
print("NONE") | |
end | |
print() | |
print("* ADD DOOR") | |
print() | |
print("* REMOVE DOOR") | |
print() | |
print("]") | |
elseif mem.termstate == "adddoor" or mem.termstate == "removedoor" then | |
print() | |
print("DOOR ID?") | |
print("]") | |
elseif mem.termstate == "carcall" then | |
print() | |
print("FLOOR NUMBER?") | |
print("]") | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment