Advertisement
Guest User

Minecolonies_Monitor

a guest
Mar 11th, 2024
33
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.53 KB | None | 0 0
  1. ----------------------------------------------------------------------------
  2. -- INITIALIZATION
  3. ----------------------------------------------------------------------------
  4.  
  5. -- Initialize Monitor
  6. local monitor = peripheral.find("monitor")
  7. if not monitor then error("Monitor not found.") end
  8. monitor.setTextScale(0.5)
  9. monitor.setBackgroundColor(colors.black)
  10. monitor.clear()
  11. monitor.setCursorPos(1, 1)
  12. monitor.setCursorBlink(false)
  13. print("Monitor initialized.")
  14.  
  15. -- Open a Rednet connection
  16. rednet.open("left")
  17.  
  18. ----------------------------------------------------------------------------
  19. -- FUNCTIONS
  20. ----------------------------------------------------------------------------
  21. -- Table.Empty
  22.  
  23. function table.empty (self)
  24. for _, _ in pairs(self) do
  25. return false
  26. end
  27. return true
  28. end
  29.  
  30. -- Prints strings left, centered, or right justified at a specific row and
  31. -- specific foreground/background color. Really cool
  32. function mPrintRowJustified(mon, y, pos, text, ...)
  33. local w, h = mon.getSize()
  34. local fg = mon.getTextColor()
  35. local bg = mon.getBackgroundColor()
  36.  
  37. local x
  38. if pos == "left" then
  39. x = 1
  40. elseif pos == "center" then
  41. x = math.floor((w - #text) / 2)
  42. elseif pos == "right" then
  43. x = w - #text
  44. end
  45.  
  46. if select("#", ...) > 0 then
  47. mon.setTextColor(select(1, ...))
  48. end
  49. if select("#", ...) > 1 then
  50. mon.setBackgroundColor(select(2, ...))
  51. else
  52. mon.setBackgroundColor(colors.black)
  53. end
  54.  
  55. mon.setCursorPos(x, y)
  56. mon.write(text)
  57. mon.setTextColor(fg)
  58. end
  59.  
  60. -- Function to update the time display on the monitor
  61. function displayTimer(mon, t)
  62. now = os.time()
  63.  
  64. cycle = "Day"
  65. cycle_Col = colors.orange
  66. if now >= 4 and now < 6 then
  67. cycle = "Sunrise"
  68. cycle_Col = colors.orange
  69. elseif now >= 6 and now < 18 then
  70. cycle = "Day"
  71. cycle_Col = colors.yellow
  72. elseif now >= 18 and now < 19.5 then
  73. cycle = "Sunset"
  74. cycle_Col = colors.orange
  75. elseif now >= 19.5 or now < 5 then
  76. cycle = "Night"
  77. cycle_Col = colors.blue
  78. end
  79.  
  80. timer_Col = colors.orange
  81. if t < 15 then timer_Col = colors.yellow end
  82. if t < 5 then timer_Col = colors.red end
  83.  
  84. mPrintRowJustified(mon, 1, "left", string.format("Time: %s [%s] ", textutils.formatTime(now, false), cycle), cycle_Col)
  85. if cycle ~= "Night" then mPrintRowJustified(mon, 1, "right", string.format(" Remaining: %ss", t), timer_Col)
  86. else mPrintRowJustified(mon, 1, "right", " Remaining: PAUSED", colors.red) end
  87. end
  88.  
  89. -- Draws a line with coloured whitespaces (lol)
  90. function drawLine (mon, x, y, length, size, color_Bar)
  91. for yPos = y, y + size - 1 do
  92. mon.setBackgroundColor(color_Bar)
  93. mon.setCursorPos(x, yPos)
  94. mon.write(string.rep(" ", length))
  95. end
  96. end
  97.  
  98. -- Draws a progress bar for displaying happiness and other stuff
  99. function drawProgressBar (mon, x, y, length, size, min_Val, max_Val, color_Bar, color_Bg)
  100. drawLine(mon, x, y, length, size, color_Bg)
  101. local bar_Size = math.floor((min_Val/max_Val) * length)
  102. drawLine(mon, x, y, bar_Size, size, color_Bar)
  103. end
  104.  
  105. -- Function to receive and display basic Colony Info
  106. function displayColonyBasic (mon)
  107. local senderId, message, protocol = rednet.receive("Colony ID Protocol")
  108. col_ID = message
  109. mPrintRowJustified(mon, 3, "left", string.format("Colony ID: %s ", col_ID), colors.white)
  110.  
  111. senderId, message, protocol = rednet.receive("Colony Name Protocol")
  112. col_Name = message
  113. mPrintRowJustified(mon, 3, "center", string.format(" %s ", col_Name), colors.white)
  114.  
  115. senderId, message, protocol = rednet.receive("Colony Citizen Count Protocol")
  116. col_Citizen_Count = message
  117. mPrintRowJustified(mon, 3, "right", string.format("Citizens: %s", col_Citizen_Count), colors.white)
  118.  
  119. senderId, message, protocol = rednet.receive("Colony Under Attack Protocol")
  120. col_isUnderAttack = message
  121.  
  122. -- For Happiness Bar we need the monitor size
  123. local w, h = mon.getSize()
  124. senderId, message, protocol = rednet.receive("Colony Happiness Protocol")
  125. col_Happiness = message
  126. if not col_isUnderAttack then
  127. happiness_Col = colors.green
  128. if col_Happiness >= 0 and col_Happiness < 3 then
  129. happiness_Col = colors.red
  130. elseif col_Happiness >= 3 and col_Happiness < 6 then
  131. happiness_Col = colors.yellow
  132. elseif col_Happiness >= 6 then
  133. happiness_Col = colors.green
  134. end
  135. drawProgressBar(mon, 5, 6, w - 8, 1, col_Happiness, 10, happiness_Col, colors.gray)
  136. mPrintRowJustified(mon, 5, "center", string.format("Happiness: %s / 10", math.floor(col_Happiness)), colors.white)
  137. else
  138. drawProgressBar(mon, 5, 6, w - 8, 1, 10, 10, colors.red, colors.gray)
  139. mPrintRowJustified(mon, 5, "center", "Colony Under Attack!", colors.white)
  140. end
  141. end
  142.  
  143. --[[
  144. Create Colonist Data
  145. @desc Build a table of Colonist making the request
  146. @return table
  147. ]]
  148. function createColonistData(colonist)
  149. title_words = {}
  150. words_in_name = 0
  151. colonist_job = ""
  152. word_count = 1
  153.  
  154. for word in colonist:gmatch("%S+") do
  155. table.insert(title_words, word)
  156. words_in_name = words_in_name + 1
  157. end
  158.  
  159. if words_in_name >= 3 then colonist_name = title_words[words_in_name-2] .. " " .. title_words[words_in_name]
  160. else colonist_name = colonist end
  161.  
  162. repeat
  163. if colonist_job ~= "" then colonist_job = colonist_job .. " " end
  164. colonist_job = colonist_job .. title_words[word_count]
  165. word_count = word_count + 1
  166. until word_count > words_in_name - 3
  167.  
  168. return { fullName = colonist, titleWords = title_words, job = colonist_job, name = colonist_name, wordsInName = words_in_name }
  169. end
  170.  
  171. --[[
  172. Get Work Request List (from colony)
  173. @desc Build a table of the work request data from the colony
  174. @return table
  175. ]]
  176. function getWorkRequestList()
  177. requestList = {}
  178.  
  179. local senderId, message, protocol = rednet.receive("Colony Requests Protocol")
  180. col_Requests = message
  181. workRequests = col_Requests
  182.  
  183. for w in pairs(workRequests) do
  184. name = workRequests[w].name -- the name of the count/item being requested
  185. colonist = createColonistData(workRequests[w].target)
  186. desc = workRequests[w].desc -- the request description
  187. item = {}
  188. -- create the filter item for the transfer request through the bridge
  189. if workRequests[w].items and workRequests[w].items[1] then
  190. if not workRequests[w].items[1].nbt or table.empty(workRequests[w].items[1].nbt) then
  191. item = { name = workRequests[w].items[1].name, count = workRequests[w].count, displayName = workRequests[w].items[1].displayName}
  192. else
  193. item = { name = workRequests[w].items[1].name, count = workRequests[w].count, displayName = workRequests[w].items[1].displayName, nbt = workRequests[w].items[1].nbt}
  194. end
  195. end
  196. -- how many items are needed to fulfill this request?
  197. needed = workRequests[w].count
  198.  
  199. local newRecord = {}
  200. newRecord.name = name
  201. newRecord.desc = desc
  202. newRecord.needed = needed
  203. newRecord.item = item
  204. newRecord.colonist = colonist
  205. table.insert(requestList, newRecord)
  206. end
  207. return requestList
  208. end
  209.  
  210. --[[
  211. Display List
  212. @desc Update the monitor with the work request items currently in the system
  213. @return void
  214. ]]
  215. function displayList(mon, listName, itemList)
  216. -- show the list header first
  217. mPrintRowJustified(mon, row, "center", listName, colors.white)
  218. row = row + 1
  219. for e in pairs(itemList) do
  220. record = itemList[e]
  221. text = string.format("%s", record.name)
  222. mPrintRowJustified(mon, row, "left", text, record.color)
  223. mPrintRowJustified(mon, row, "right", " " .. record.colonist, record.color)
  224. row = row + 1
  225. end
  226. -- add a space at the end of the list
  227. row = row + 1
  228. end
  229.  
  230. function scanWorkRequests(mon, bridge, direction)
  231. builder_list = {}
  232. nonbuilder_list = {}
  233. equipment_list = {}
  234. requestList = getWorkRequestList()
  235.  
  236. for j, data in ipairs(requestList) do
  237. color = colors.blue
  238. provided = 0
  239. -- ---------------------------------------------------------------------
  240. -- Build the newList data
  241. -- ---------------------------------------------------------------------
  242. -- create the target text
  243. expectedList = "Builder"
  244. colonist = data.colonist.name
  245. if not string.find(data.colonist.fullName, "Builder") then
  246. expectedList = ""
  247. colonist = data.colonist.job .. " " .. data.colonist.name
  248. if data.colonist.wordsInName < 3 then
  249. colonist = data.colonist.name
  250. end
  251. end
  252.  
  253. -- create the name
  254. listName = data.name
  255. if string.find(data.desc, "level") then
  256. expectedList = "Equipment"
  257. level = "Any Level"
  258. if string.find(data.desc, "with maximal level: Leather") then level = "Leather" end
  259. if string.find(data.desc, "with maximal level: Gold") then level = "Gold" end
  260. if string.find(data.desc, "with maximal level: Chain") then level = "Chain" end
  261. if string.find(data.desc, "with maximal level: Wood or Gold") then level = "Wood or Gold" end
  262. if string.find(data.desc, "with maximal level: Stone") then level = "Stone" end
  263. if string.find(data.desc, "with maximal level: Iron") then level = "Iron" end
  264. if string.find(data.desc, "with maximal level: Diamond") then level = "Diamond" end
  265. listName = level .. " " .. data.name
  266. if level == "Any Level" then listName = data.name .. " of any level" end
  267. end
  268.  
  269. -- create the new list table defining what is inserted into a specific list
  270. newList = { name=listName, colonist=colonist, needed=data.needed, provided=provided, color=color}
  271.  
  272. if expectedList == "Equipment" then
  273. table.insert(equipment_list, newList)
  274. elseif expectedList == "Builder" then
  275. table.insert(builder_list, newList)
  276. else
  277. table.insert(nonbuilder_list, newList)
  278. end
  279. -- ---------------------------------------------------------------------
  280. end
  281.  
  282. -- Show the various lists on the attached monitor.
  283. mon.clear()
  284. row = 8
  285. if not table.empty(builder_list) then displayList(mon, "Builder Requests", builder_list) end
  286. if not table.empty(nonbuilder_list) then displayList(mon, "Nonbuilder Requests", nonbuilder_list) end
  287. if not table.empty(equipment_list) then displayList(mon, "Equipment", equipment_list) end
  288.  
  289. -- no requests
  290. if row == 8 then
  291. mPrintRowJustified(mon, row, "center", "No Open Requests", colors.white)
  292. end
  293. end
  294.  
  295. ----------------------------------------------------------------------------
  296. -- MAIN
  297. ----------------------------------------------------------------------------
  298.  
  299. -- Scan for requests periodically. This will catch any updates that were
  300. -- triggered from the previous scan. Right-clicking on the monitor will
  301. -- trigger an immediate scan and reset the timer.
  302.  
  303. local time_between_runs = 30
  304. local current_Run = time_between_runs
  305. monitor.clear()
  306. scanWorkRequests(monitor)
  307. displayColonyBasic(monitor)
  308. displayTimer(monitor, current_Run)
  309. local TIMER = os.startTimer(1)
  310.  
  311. while true do
  312. local e = {os.pullEvent()}
  313. if e[1] == "timer" and e[2] == TIMER then
  314. now = os.time()
  315. if now >= 6 and now < 19.5 then
  316. current_Run = current_Run - 1
  317. if current_Run <= 0 then
  318. monitor.clear()
  319. scanWorkRequests(monitor)
  320. displayColonyBasic(monitor)
  321. current_Run = time_between_runs
  322. end
  323. end
  324. displayTimer(monitor, current_Run)
  325. TIMER = os.startTimer(1)
  326. elseif e[1] == "monitor_touch" then
  327. os.cancelTimer(TIMER)
  328. monitor.clear()
  329. scanWorkRequests(monitor)
  330.  
  331. current_Run = time_between_runs
  332. displayColonyBasic(monitor)
  333. displayTimer(monitor, current_Run)
  334. TIMER = os.startTimer(1)
  335. end
  336. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement