FoxWorn3365

acc

Nov 16th, 2025 (edited)
150
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 14.79 KB | None | 0 0
  1. -- FILLEDBOX
  2. local function drawPixelInternal(xPos, yPos)
  3.     term.setCursorPos(xPos, yPos)
  4.     term.write(" ")
  5. end
  6.  
  7. local tColourLookup = {}
  8. for n = 1, 16 do
  9.     tColourLookup[string.byte("0123456789abcdef", n, n)] = 2 ^ (n - 1)
  10. end
  11.  
  12. function drawFilledBox(startX, startY, endX, endY, nColour)
  13.     if type(startX) ~= "number" or type(startX) ~= "number" or type(endX) ~=
  14.         "number" or type(endY) ~= "number" or
  15.         (nColour ~= nil and type(nColour) ~= "number") then
  16.         error("Expected startX, startY, endX, endY, colour", 2)
  17.     end
  18.  
  19.     startX = math.floor(startX)
  20.     startY = math.floor(startY)
  21.     endX = math.floor(endX)
  22.     endY = math.floor(endY)
  23.  
  24.     if nColour then term.setBackgroundColor(nColour) end
  25.     if startX == endX and startY == endY then
  26.         drawPixelInternal(startX, startY)
  27.         return
  28.     end
  29.  
  30.     local minX = math.min(startX, endX)
  31.     if minX == startX then
  32.         minY = startY
  33.         maxX = endX
  34.         maxY = endY
  35.     else
  36.         minY = endY
  37.         maxX = startX
  38.         maxY = startY
  39.     end
  40.  
  41.     for x = minX, maxX do for y = minY, maxY do drawPixelInternal(x, y) end end
  42. end
  43.  
  44. -- Importa enti
  45. local h = fs.open("qlvdata-published", "r")
  46. enti = textutils.unserialize(h.readAll())
  47. h.close()
  48.  
  49. -- Importa itinerari
  50. local h2 = fs.open("qlvd", "r")
  51. itinerari = textutils.unserialize(h2.readAll())
  52. h2.close()
  53.  
  54. -- Importa scritte
  55. local h3 = fs.open("qlvtxt", "r")
  56. txt = textutils.unserialize(h3.readAll())
  57. h3.close()
  58.  
  59. -- Importa pedali
  60. local h4 = fs.open("qlvpedali", "r")
  61. pedali = textutils.unserialize(h4.readAll())
  62. h4.close()
  63.  
  64. -- Importa nome
  65. local h5 = fs.open("qlvname", "r")
  66. nome = h5.readAll()
  67. h5.close()
  68.  
  69. -- Variabili da popolare
  70. output = {}
  71. clicktoit = {}
  72. status = {}
  73. locked = {}
  74. active = {}
  75. _active = {}
  76. pedaletoit = {}
  77. statuspedali = {}
  78. itnametoitkey = {}
  79.  
  80. auta = false
  81. canRotate = true
  82. statusinfo = colors.gray
  83.  
  84. tm = nil
  85. scenery = 69
  86. blwait = false
  87. ccshut = false
  88.  
  89. apt = 0
  90.  
  91. -- Variabili statiche
  92. bundled = "bottom"
  93. pedaliSide = "left"
  94. seq = {"-","\\","|","/"}
  95. lasts = 0
  96. autax = 44
  97. autay = 3
  98. autatext = " AutA "
  99. allowedchanges = {}
  100.  
  101. -- Funzioni
  102. function ac()
  103.     allowedchanges[3] = {5}
  104.     allowedchanges[2] = {5}
  105.     allowedchanges[1] = {2,3,5}
  106.     allowedchanges[5] = {0,4}
  107. end
  108.  
  109. function checkAutA()
  110.     if fs.exists(".auta") == true then
  111.         auta = true
  112.         handleAutAOutput()
  113.         return
  114.     end
  115.  
  116.     auta = false
  117.  
  118.     handleAutAOutput()
  119. end
  120.  
  121. function handleAutAOutput()
  122.     if auta == true then
  123.         rs.setBundledOutput(pedaliSide, colors.blue)
  124.         return
  125.     end
  126.  
  127.     rs.setBundledOutput(pedaliSide, 0)
  128. end
  129.  
  130. function switchAutA()
  131.     if auta == true then
  132.         fs.delete(".auta")
  133.     else
  134.         local h = fs.open(".auta", "w")
  135.         h.write("on")
  136.         h.close()
  137.     end
  138.  
  139.     checkAutA()
  140. end
  141.  
  142. function bitand(a, b)
  143.     local result = 0
  144.     local bitval = 1
  145.     while a > 0 and b > 0 do
  146.       if a % 2 == 1 and b % 2 == 1 then -- test the rightmost bits
  147.           result = result + bitval      -- set the current bit
  148.       end
  149.       bitval = bitval * 2 -- shift left
  150.       a = math.floor(a/2) -- shift right
  151.       b = math.floor(b/2)
  152.     end
  153.     return result
  154. end
  155.  
  156.  
  157. function associatePedale()
  158.     for k, v in ipairs(itinerari) do
  159.         itnametoitkey[v.name] = k
  160.         local pedale = pedali[v.pedale]
  161.         if pedaletoit[pedale.color] == nil then
  162.             pedaletoit[pedale.color] = {}
  163.         end
  164.  
  165.         table.insert(pedaletoit[pedale.color], k)
  166.     end
  167. end
  168.  
  169. function getGiragira()
  170.     if canRotate == true then
  171.         lasts = lasts+1
  172.  
  173.         if lasts > 4 then
  174.             lasts = 1
  175.         end
  176.     end
  177.  
  178.     return seq[lasts]
  179. end
  180.  
  181. function contains(table, element)
  182.     for k, v in pairs(table) do
  183.         if v == element then
  184.             return true
  185.         end
  186.     end
  187.  
  188.     return false
  189. end
  190.  
  191. function containsString(table, element)
  192.     for k, v in pairs(table) do
  193.         if tostring(v) == tostring(element) then
  194.             --print("ELEMENT: "..k)
  195.             return true
  196.         end
  197.     end
  198.  
  199.     return false
  200. end
  201.  
  202. function removeSingolo(tb, element)
  203.     local newt = tb
  204.     for k, v in ipairs(tb) do
  205.         if v == element then
  206.             table.remove(newt, k)
  207.             return newt
  208.         end
  209.     end
  210.  
  211.     return newt
  212. end
  213.  
  214. function proposeTimer()
  215.     tm = os.startTimer(1)
  216. end
  217.  
  218. function titolo(testo)
  219.     local maxw = 51
  220.     drawFilledBox(1, 1, maxw, 1, colors.blue)
  221.     term.setCursorPos((maxw - #testo) / 2, 1)
  222.     term.setTextColor(colors.white)
  223.     term.write(testo)
  224.     term.setBackgroundColor(colors.white)
  225.     term.setTextColor(colors.black)
  226. end
  227.  
  228. function qlv()
  229.     term.setBackgroundColor(colors.white)
  230.     term.setTextColor(colors.black)
  231.     titolo(nome.." - ACC")
  232.  
  233.     term.setBackgroundColor(colors.white)
  234.     term.setTextColor(colors.black)
  235.     local qlv = paintutils.loadImage("qlv")
  236.     paintutils.drawImage(qlv, 2, 1)
  237.  
  238.     drawEnti()
  239.     drawItinerari()
  240.     drawTesti()
  241. end
  242.  
  243. function drawEnti()
  244.     for k, v in ipairs(enti) do
  245.         local c = colors.lightGray
  246.         if v.type == "d" then
  247.             c = colors.gray
  248.         end
  249.  
  250.         if v.type == "s" then
  251.             c = colors[loadStato(v)]
  252.             term.setBackgroundColor(c)
  253.             drawPixelInternal(v.position.x, v.position.y)
  254.         else
  255.             local visual = v.def
  256.             if status[v.color] == true then visual = v.active end
  257.             term.setBackgroundColor(c)
  258.             term.setCursorPos(v.position.x, v.position.y)
  259.             term.setTextColor(colors.white)
  260.             term.write(visual)
  261.         end
  262.     end
  263. end
  264.  
  265. function drawTesti()
  266.     for k, v in ipairs(txt) do
  267.         term.setTextColor(colors.black)
  268.         term.setBackgroundColor(colors.white)
  269.         term.setCursorPos(v.x, v.y)
  270.         term.write(v.text)
  271.     end
  272. end
  273.  
  274. function drawItinerari()
  275.     for k, v in ipairs(itinerari) do
  276.         local y = 16
  277.         local x = k-1
  278.         if k > 6 then
  279.             y = 18
  280.             x = k-8
  281.         end
  282.  
  283.         drawItinerarioBox(k, v, x, y)
  284.     end
  285. end
  286.  
  287. function drawItinerarioBox(k, v, x, y)
  288.     local length = 8
  289.     local p = x*length
  290.  
  291.     local cr = colors.blue
  292.  
  293.     if auta == true then
  294.         cr = colors.gray
  295.     end
  296.  
  297.     if active[k] ~= nil then
  298.         cr = colors.red
  299.     end
  300.  
  301.     drawFilledBox(p+2, y, p+length-1, y, cr)
  302.     term.setBackgroundColor(cr)
  303.     term.setTextColor(colors.white)
  304.     term.setCursorPos(p+2, y)
  305.     term.write(" "..v.name)
  306.  
  307.     for i=p+1,p+length,1 do
  308.         clicktoit[i.."_"..y] = k
  309.     end
  310. end
  311.  
  312. function drawAutAButton()
  313.     local color = colors.red
  314.  
  315.     if auta == true then
  316.         color = colors.green
  317.     end
  318.  
  319.     --drawFilledBox(autax, autay, autax + #autatext, autay, color)
  320.     term.setTextColor(colors.white)
  321.     term.setBackgroundColor(color)
  322.     term.setCursorPos(autax, autay)
  323.     term.write(autatext)
  324.     term.setTextColor(colors.black)
  325.     term.setBackgroundColor(colors.white)
  326. end
  327.  
  328. function loadStato(element)
  329.     if status[element.color] == true then
  330.         local c = element.active
  331.         if c == "off" then return "lightGray" end
  332.         return c
  333.     else
  334.         local c = element.def
  335.         if c == "off" then return "lightGray" end
  336.         return c
  337.     end
  338. end
  339.  
  340. function comandaItinerario(id, internal)
  341.     if internal == false then
  342.         if auta == true then return end
  343.         setStatusInfo(colors.yellow)
  344.         sleep(1)
  345.         proposeTimer()
  346.     end
  347.  
  348.     local itinerario = itinerari[id]
  349.  
  350.     if active[id] ~= nil then
  351.         if internal == false then erore() end
  352.         return
  353.     end
  354.  
  355.     if canCreateItinerario(itinerario) ~= true then
  356.         if internal == false then erore() end
  357.         return
  358.     end
  359.  
  360.     active[id] = true
  361.  
  362.     table.insert(_active, itinerario)
  363.  
  364.     -- Attiva gli enti necessari
  365.     for k, v in ipairs(itinerario.enti) do
  366.         table.insert(output, v)
  367.         status[v] = true
  368.     end
  369.  
  370.     -- Blocca gli enti non necessari
  371.     for k, v in ipairs(itinerario.lock) do
  372.         table.insert(locked, v)
  373.     end
  374.  
  375.     refreshBundledOutput()
  376.  
  377.     if internal == false then
  378.         setStatusInfo(colors.green)
  379.     end
  380. end
  381.  
  382. function erore()
  383.     setStatusInfo(colors.red)
  384.     sleep(0.5)
  385.     setStatusInfo(colors.gray)
  386. end
  387.  
  388. function distruggiItinerario(id, internal)
  389.     if internal == false then
  390.         if auta == true then return end
  391.         setStatusInfo(colors.orange)
  392.         sleep(1)
  393.         proposeTimer()
  394.     end
  395.  
  396.     local itinerario = itinerari[id]
  397.  
  398.     if active[id] == nil then
  399.         if internal == false then erore() end
  400.         return
  401.     end
  402.  
  403.     -- Disable all
  404.     for k, v in ipairs(itinerario.enti) do
  405.         output = removeSingolo(output, v)
  406.         status[v] = false
  407.     end
  408.  
  409.     -- Unlock
  410.     for k, v in ipairs(itinerario.lock) do
  411.         locked = removeSingolo(locked, v)
  412.     end
  413.  
  414.     active[id] = nil
  415.     removeSingolo(_active, itinerario)
  416.  
  417.     refreshBundledOutput()
  418.  
  419.     if internal == false then
  420.         setStatusInfo(colors.green)
  421.     end
  422. end
  423.  
  424. function refreshBundledOutput()
  425.     local used = {}
  426.     local color = 0
  427.    
  428.     for k, v in ipairs(output) do
  429.         if used[v] == nil then
  430.             used[v] = true
  431.             color = color + colors[v]
  432.         end
  433.     end
  434.  
  435.     rs.setBundledOutput(bundled, color)
  436. end
  437.  
  438. function setStatusInfo(color)
  439.     statusinfo = color
  440.     drawStatusInfo()
  441. end
  442.  
  443. function drawStatusInfo()
  444.     term.setBackgroundColor(statusinfo)
  445.     term.setTextColor(colors.white)
  446.     term.setCursorPos(51, 19)
  447.     term.write(getGiragira())
  448.     term.setTextColor(colors.black)
  449.     term.setBackgroundColor(colors.white)
  450. end
  451.  
  452. function canCreateItinerario(it)
  453.     if #_active >= 2 then
  454.         return false
  455.     end
  456.  
  457.     if #_active == 0 then
  458.         return true
  459.     end
  460.  
  461.     local act = _active[1]
  462.  
  463.     --error(textutils.serialize(_active))
  464.  
  465.     local common = 0
  466.     for k, v in ipairs(it.lock) do
  467.         if contains(locked, v) == true then
  468.             common = common + 1
  469.         end
  470.     end
  471.  
  472.     --print(act.direction.."_"..it.direction)
  473.     --error(common)
  474.     if act.direction ~= it.direction then
  475.         if common > 3 then
  476.             return false
  477.         end
  478.     else
  479.         if common > 3 then
  480.             return false
  481.         end
  482.     end
  483.  
  484.     return true
  485. end
  486.  
  487. function handleRedstoneVariation()
  488.     apt = apt + 1
  489.     local input = rs.getBundledInput(pedaliSide)
  490.     --error(textutils.serialize(ipairs(pedaletoit)))
  491.     for k, v in pairs(pedaletoit) do
  492.         local status = bitand(input, colors[k])
  493.  
  494.         if status == 0 then
  495.             statuspedali[k] = false
  496.         else
  497.             statuspedali[k] = true
  498.         end
  499.  
  500.         if status ~= 0 then
  501.             -- Is active
  502.             for ka, va in ipairs(v) do
  503.                 distruggiItinerario(va, true)
  504.             end
  505.         end
  506.     end
  507.     statuspedali["c"] = apt
  508.     --print(textutils.serialize(statuspedali))
  509.    
  510.     --exit()
  511. end
  512.  
  513. function AutALogic()
  514.     if auta == false then
  515.         return
  516.     end
  517.  
  518.     local newscenery = nil
  519.  
  520.     if containsString(statuspedali, true) == false then
  521.         if scenery == 69 then
  522.             newscenery = 0
  523.         else
  524.             newscenery = scenery
  525.         end
  526.  
  527.         --print(textutils.serialize(statuspedali))
  528.  
  529.         if blwait == true then
  530.             ccshut = true
  531.         end
  532.     end
  533.  
  534.     if statuspedali["black"] == true and statuspedali["red"] == false and statuspedali["cyan"] == false and statuspedali["green"] == false then
  535.         -- Libero transito da Grottalupara
  536.         newscenery = 0
  537.     end
  538.  
  539.     if statuspedali["cyan"] == true and statuspedali["black"] == true then
  540.         -- Treno in arrivo da entrambi i lati
  541.         newscenery = 1
  542.     end
  543.  
  544.     if statuspedali["cyan"] == true and statuspedali["red"] == true then
  545.         -- Treno in arrivo da thwolle e treno da Grottalupara fermo al bin 2
  546.         if blwait == true then
  547.             newscenery = 5
  548.             ccshut = true
  549.         else
  550.             newscenery = 2
  551.         end
  552.     end
  553.  
  554.     if statuspedali["black"] == true and statuspedali["green"] == true then
  555.         -- Treno in arrivo da Grottalupara e treno da THwolle fermo al bin 1
  556.         if blwait == true then
  557.             newscenery = 5
  558.             ccshut = true
  559.         else
  560.             newscenery = 3
  561.         end
  562.     end
  563.  
  564.     if statuspedali["black"] == false and statuspedali["red"] == false and statuspedali["cyan"] == true and statuspedali["green"] == false then
  565.         -- Libero transito da Thwolle
  566.         newscenery = 4
  567.     end
  568.  
  569.     if statuspedali["black"] == false and statuspedali["cyan"] == false and statuspedali["red"] == true and statuspedali["green"] == true then
  570.         -- DUe treni fermi ai 2 bin per incrocio i guess
  571.         newscenery = 5
  572.         blwait = true
  573.     end
  574.  
  575.     if statuspedali["red"] == true and statuspedali["black"] == false and statuspedali["cyan"] == false then
  576.         -- Treno di un libero transito entrato in stazione
  577.         if scenery == 4 or scenery == 6 then
  578.             newscenery = 6
  579.         elseif scenery == 0 or scenery == 7 then
  580.             newscenery = 7
  581.         end
  582.     end
  583.  
  584.     if allowedchanges[scenery] ~= nil and contains(allowedchanges[scenery], newscenery) == false then
  585.         newscenery = scenery
  586.     end
  587.  
  588.     if ccshut == true then
  589.         newscenery = 0
  590.         ccshut = false
  591.         blwait = false
  592.     end
  593.  
  594.     --print(textutils.serialize(statuspedali))
  595.     if newscenery ~= scenery then
  596.         --print(containsString(statuspedali, true))
  597.         --print(tostring(blwait))
  598.         --print(tostring(ccshut))
  599.         print(newscenery)
  600.         --print(textutils.serialize(statuspedali))
  601.         destroyAll()
  602.         destroyAll()
  603.  
  604.         scenery = newscenery
  605.  
  606.         if scenery == nil then
  607.             return
  608.         end
  609.  
  610.         AutAScenery()
  611.     end
  612. end
  613.  
  614. function AutAScenery()
  615.     if scenery == 0 then
  616.         comandaItinerario(itnametoitkey["1-II"], true)
  617.         comandaItinerario(itnametoitkey["II-2"], true)
  618.     elseif scenery == 1 then
  619.         comandaItinerario(itnametoitkey["1-II"], true)
  620.         comandaItinerario(itnametoitkey["2-I"], true)
  621.     elseif scenery == 2 then
  622.         comandaItinerario(itnametoitkey["2-I"], true)
  623.     elseif scenery == 3 then
  624.         comandaItinerario(itnametoitkey["1-II"], true)
  625.     elseif scenery == 4 then
  626.         comandaItinerario(itnametoitkey["2-II"], true)
  627.         comandaItinerario(itnametoitkey["II-1"], true)
  628.     elseif scenery == 5 then
  629.         comandaItinerario(itnametoitkey["I-1"], true)
  630.         comandaItinerario(itnametoitkey["II-2"], true)
  631.     elseif scenery == 6 then
  632.         comandaItinerario(itnametoitkey["II-1"], true)
  633.     elseif scenery == 7 then
  634.         comandaItinerario(itnametoitkey["II-2"], true)
  635.     else
  636.         error("CANNOT HANDLE SCENERY "..scenery)
  637.     end
  638. end
  639.  
  640. function destroyAll()
  641.     for k, v in ipairs(itinerari) do
  642.         distruggiItinerario(k, true)
  643.     end
  644.  
  645.     if #_active > 0 then
  646.         error("NON HO CANCELLATO TUTTO . "..textutils.serialize(active))
  647.     end
  648. end
  649.  
  650. function drawLogo()
  651.     term.setCursorPos(1, 2)
  652.     term.setTextColor(colors.black)
  653.     term.setBackgroundColor(colors.white)
  654.     term.write("ALST M")
  655.     term.setTextColor(colors.red)
  656.     term.setCursorPos(5, 2)
  657.     term.write("O")
  658.     term.setTextColor(colors.black)
  659.     term.setBackgroundColor(colors.white)
  660. end
  661.  
  662. -- DISPLAY
  663. ac()
  664.  
  665. associatePedale()
  666. checkAutA()
  667.  
  668. term.setBackgroundColor(colors.white)
  669. term.clear()
  670. proposeTimer()
  671.  
  672. handleRedstoneVariation()
  673. while true do
  674.     qlv()
  675.     drawStatusInfo()
  676.     drawAutAButton()
  677.     drawLogo()
  678.  
  679.     AutALogic()
  680.  
  681.     local ev, b, x, y = os.pullEvent() -- mouse_click AND redstone
  682.     handleRedstoneVariation()
  683.  
  684.     if ev == "timer" and b == tm then
  685.         proposeTimer()
  686.         --handleRedstoneVariation()
  687.         canRotate = true
  688.     else
  689.         canRotate = false
  690.     end
  691.  
  692.     if ev == "redstone" then
  693.         --handleRedstoneVariation()
  694.     elseif ev == "mouse_click" then
  695.         local qid = clicktoit[x.."_"..y]
  696.         if qid ~= nil then
  697.             -- Comanda itinerario
  698.             if active[qid] == nil then
  699.                 comandaItinerario(qid, false)
  700.             else
  701.                 distruggiItinerario(qid, false)
  702.             end
  703.         end
  704.  
  705.         if y == autay and x >= autax and x <= autax+#autatext then
  706.             -- Handle AutA ONLY IF THE CONDITIONS ARE OK
  707.             setStatusInfo(colors.yellow)
  708.             sleep(1)
  709.             --proposeTimer()
  710.  
  711.             if contains(statuspedali, true) == false then
  712.                 switchAutA()
  713.                 setStatusInfo(colors.green)
  714.             else
  715.                 setStatusInfo(colors.red)
  716.             end
  717.         end
  718.     end
  719. end
Advertisement
Add Comment
Please, Sign In to add comment