ReDestroyDeR

client.lua

Oct 11th, 2021 (edited)
393
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 6.61 KB | None | 0 0
  1. local api = require ("graph_api")
  2. local config = require ("config_api")
  3.  
  4. -- Configuration Setup
  5. CONFIG = Config:new("farm_client_config")
  6. CONFIG:fetchFromFile()
  7. if CONFIG:size() ~= 4 then
  8.     CONFIG.properties = {}
  9.     CONFIG.properties["DEFAULT_TOOLTIP_TEXT"] = "Select where your Gearshift is located to pass redstone signal to it; When you are ready, hit TOGGLE button"
  10.     CONFIG.properties["CYCLE_TIMER"] = 60
  11.     CONFIG.properties["AUTO_TOGGLE"] = false
  12.     CONFIG.properties["REDSTONE_OUTPUT"] = "NONE"
  13.     CONFIG:updateFile()
  14. end
  15.  
  16. INFO_UPDATE_SECONDS_SLEEP = 0.5
  17. local UPDATE_TIMER = nil
  18.  
  19. local root_width, root_height = term.getSize()
  20. local root_terminal = term.current()
  21. local root_window = window.create(root_terminal, 1, 1, root_width, root_height)
  22. root_window.setBackgroundColor(colors.cyan)
  23. root_window.setTextColor(colors.green)
  24. root_window.clear()
  25. term.redirect(root_window)
  26.  
  27. --------------
  28. -----CODE-----
  29. --------------
  30.  
  31. local cycle_metadata = {status="IDLE", redstone_output="NONE", alarms={}, alarm_tokens={}, timers={}, last_harvest=0}
  32.  
  33. -- Event handlers
  34.  
  35. function redstoneOutputEventHandler(raw_event)
  36.     local event, previous_tag, tag, button = raw_event[1], raw_event[2], raw_event[3], raw_event[4]
  37.     cycle_metadata["redstone_output"] = tag
  38.     CONFIG.properties["REDSTONE_OUTPUT"] = tag
  39.     CONFIG:updateFile()
  40. end
  41.  
  42. function alarmEventHandler(raw_event)
  43.     local event, id = raw_event[1], raw_event[2]
  44.     for index, alarm in ipairs(cycle_metadata["alarm_tokens"]) do
  45.         if id == alarm then
  46.             local current_time = math.floor(os.time())
  47.             table.remove(cycle_metadata["alarms"], index)
  48.             table.remove(cycle_metadata["alarm_tokens"], index)
  49.             table.insert(cycle_metadata["alarms"], current_time)
  50.             table.insert(cycle_metadata["alarm_tokens"], os.setAlarm(current_time))
  51.             table.insert(cycle_metadata["timers"], os.startTimer(CONFIG.properties["CYCLE_TIMER"]))
  52.             cycle_metadata["status"] = "RUNNING"
  53.             cycle_metadata["last_harvest"] = os.epoch("utc") / 1000.0
  54.             redstone.setOutput(cycle_metadata["redstone_output"], true)
  55.             break
  56.         end
  57.     end
  58. end
  59.  
  60. function bussinesTimerEventHandler(raw_event)
  61.     local event, id = raw_event[1], raw_event[2]
  62.     for _, timer in pairs(cycle_metadata["timers"]) do
  63.         if id == timer then
  64.             cycle_metadata["status"] = "WAITING"
  65.             redstone.setOutput(cycle_metadata["redstone_output"], false)
  66.             break
  67.         end
  68.     end
  69.  
  70.     if id == UPDATE_TIMER then
  71.         updateStatus()
  72.         return
  73.     end
  74. end
  75.  
  76. function bussinesEventHandler(event, eventData)
  77.     if event == "redstone_output" then
  78.         redstoneOutputEventHandler(eventData)
  79.         else if event == "alarm" then
  80.             alarmEventHandler(eventData)
  81.             else if event == "timer" then
  82.                 bussinesTimerEventHandler(eventData)
  83.             end
  84.         end
  85.     end
  86. end
  87.  
  88. -- Redstone Output Selection Buttons
  89.  
  90. local redstone_buttons = api.createDirectionButtons(root_width - 11, 2, 3, 2, colors.white, colors.red, "redstone_output", root_window)
  91. info_box = MutableTextArea:new(
  92.     root_window,
  93.     3,
  94.     3,
  95.     34,
  96.     5,
  97.     colors.lightGray,
  98.     colors.white,
  99.     true,
  100.     colors.gray,
  101.     CONFIG.properties["DEFAULT_TOOLTIP_TEXT"]
  102. )
  103. info_box:refresh()
  104.  
  105. -- Info Box Update callback
  106.  
  107. local alarm_cache = nil
  108.  
  109. function ternary(o, t, f)
  110.     if o then
  111.         return t
  112.     else
  113.         return f
  114.     end
  115. end
  116.  
  117. function time24Wrapper(time, add)
  118.     local t = time + add
  119.     return ternary(t >= 24, t - 24, t)
  120. end
  121.  
  122. function calculateDeltaTime(start, finish)
  123.     result = finish - start
  124.     return ternary(result < 0, result + 24, result)
  125. end
  126.  
  127. function getNextAlarm(current_time)
  128.     if (alarm_cache ~= nil) then
  129.         return alarm_cache
  130.     end
  131.  
  132.     delta, m = 0, 25
  133.     for i, v in ipairs(cycle_metadata["alarms"]) do
  134.         local d = calculateDeltaTime(current_time, v);
  135.         if d < m then
  136.             m = v
  137.             delta = d
  138.         end
  139.     end
  140.  
  141.     alarm_cache = m
  142.     return m
  143. end
  144.  
  145. function updateStatus()
  146.     current_time = os.time()
  147.  
  148.     info_box:setText("Status: " .. cycle_metadata["status"] .. "\n" .. "Current time: " .. textutils.formatTime(current_time, true) .. "\n")
  149.     if (cycle_metadata["status"] == "WAITING") then
  150.         alarm_cache = nil -- reset alarm cache
  151.         info_box:setText(
  152.             info_box.text ..
  153.             "Time to the next harvest: " ..
  154.             textutils.formatTime(
  155.                 calculateDeltaTime(current_time, getNextAlarm(current_time)),
  156.                 true
  157.             )
  158.         )
  159.         else if (cycle_metadata["status"] == "RUNNING") then
  160.             local t = math.ceil(cycle_metadata["last_harvest"] + CONFIG.properties["CYCLE_TIMER"] - (os.epoch("utc") / 1000.0))
  161.             info_box:setText(
  162.                 "Harvesting... ~" .. ternary(t > 0, t, 0) .. " seconds left"
  163.             )
  164.         end
  165.     end
  166.     info_box:refresh()
  167.    
  168.     UPDATE_TIMER = os.startTimer(INFO_UPDATE_SECONDS_SLEEP)
  169. end
  170.  
  171. -- Toggle Farm Button Action
  172.  
  173. function toggleFarm(window, data)
  174.     if data["redstone_output"] == "NONE" then
  175.         info_box:setText("You have to select redstone output!")
  176.         info_box:setTextColor(colors.red)
  177.         info_box:refresh()
  178.         window.setBackgroundColor(colors.red)
  179.         return
  180.     end
  181.  
  182.     info_box:setTextColor(colors.white)
  183.     data["status"] = data["status"] == "IDLE" and "WAITING" or "IDLE"
  184.     redstone.setOutput(data["redstone_output"], false)
  185.  
  186.     for _, button in pairs(api.buttons) do
  187.         if button["window"] ~= window then
  188.             button["available"] = not button["available"]
  189.         end
  190.     end
  191.  
  192.     CONFIG.properties["AUTO_TOGGLE"] = data["status"] ~= "IDLE"
  193.     CONFIG:updateFile()
  194.  
  195.     if data["status"] == "WAITING" then
  196.         data["alarms"] = {
  197.             21.0,
  198.             18.0,
  199.             15.0,
  200.             12.0,
  201.             9.0,
  202.             6.0,
  203.             3.0,
  204.             0.0
  205.         }
  206.  
  207.         for _, v in ipairs(data["alarms"]) do
  208.             table.insert(data["alarm_tokens"], os.setAlarm(v))
  209.         end
  210.  
  211.         if (UPDATE_TIMER == nil) then
  212.             UPDATE_TIMER = os.startTimer(INFO_UPDATE_SECONDS_SLEEP)
  213.         end
  214.     else
  215.         for _, alarm in pairs(data["alarm_tokens"]) do
  216.             os.cancelAlarm(alarm)
  217.         end
  218.  
  219.         for _, timer in pairs(data["timers"]) do
  220.             os.cancelTimer(timer)
  221.         end
  222.         data["alarm_tokens"] = {}
  223.         data["timers"] = {}
  224.         UPDATE_TIMER = nil
  225.     end
  226. end
  227.  
  228. -- Toggle farm button
  229.  
  230. local toggle_farm_button = api.createButton("   TOGGLE", 13, 9, 12, 3, true, colors.white, colors.red, colors.green, toggleFarm, root_window, cycle_metadata)
  231. api.registerButton(toggle_farm_button)
  232.  
  233. -- Config Callbacks
  234.  
  235. if CONFIG.properties["AUTO_TOGGLE"] and CONFIG.properties["REDSTONE_OUTPUT"] ~= "NONE" then
  236.     local redstone_button = redstone_buttons[CONFIG.properties["REDSTONE_OUTPUT"]]
  237.     redstone_button["on_click"](redstone_button["window"], redstone_button["custom"])
  238.     redstone_button["window"].setBackgroundColor(redstone_button["color_active"])
  239.     redstone_button["window"].clear()
  240.     api.simulateButtonClick(toggle_farm_button)
  241. end
  242.  
  243. -- Start Event Loop
  244. term.redirect(root_window)
  245. root_terminal.setCursorPos(0, 0)
  246. api.eventHandlerPipeline(bussinesEventHandler)
  247.  
Add Comment
Please, Sign In to add comment