[READ-ONLY] Mirror of https://github.com/thoda-dev/DU-Industry-HUD. A simple HUD for monitoring and managing industry in Dual Universe
dual-universe lua
0

Configure Feed

Select the types of activity you want to include in your feed.

alpha v3.0.9 - item displayed on tranfer unit without schematic count and reverse navigation

Thomas (Aug 18, 2022, 12:28 PM +0200) b5c7fe21 6a652624

+52 -47
+1 -1
Master program/config.json
··· 1 - {"events":[],"handlers":[{"code":"--[[\n DU-Nested-Coroutines by Jericho\n Permit to easier avoid CPU Load Errors\n Source available here: https://github.com/Jericho1060/du-nested-coroutines\n]]--\n\nif coroutine.status(MainCoroutine) == \"dead\" then\n MainCoroutine = coroutine.create(runCoroutines)\nend\nif coroutine.status(MainCoroutine) == \"suspended\" then\n assert(coroutine.resume(MainCoroutine))\nend","filter":{"args":[],"signature":"onUpdate()","slotKey":"-4"},"key":"2"},{"code":"if tonumber(text) then\n if #text > 8 then\n system.print(\"the value should not be higher than 99 999 999.\")\n else\n craft_quantity_digits = {\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\"}\n for i = #text, 1, -1 do\n local c = text:sub(i,i)\n craft_quantity_digits[9-(#text-(i-1))] = c\n end\n end\nelse\n system.print(\"You must type a Number\")\nend","filter":{"args":[{"variable":"*"}],"signature":"onInputText(text)","slotKey":"-4"},"key":"3"},{"code":"Ctrl_pressed = false","filter":{"args":[{"value":"brake"}],"signature":"onActionStop(action)","slotKey":"-4"},"key":"4"},{"code":"if Ctrl_pressed == true then\n if selected_index > 1 then\n selected_index = selected_index - 1\n selected_type = elementsTypes[selected_index]\n selected_machine_index = 1\n page = 1\n Storage.clear()\n craft_quantity_digits = {\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\"}\n selectedElementsId = {}\n hud_machines_rows = {}\n elements = {}\n selectedElementsId = {}\n temp_selectedElementsId = {}\n temp_elements_for_sorting = {}\n temp_elements = {}\n temp_refresh_id_list = {}\n machineLoaded = false\n end\nelse\n if selected_machine_index > 1 then\n selected_machine_index = selected_machine_index - 1\n craft_quantity_digits = {\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\"}\n end\nend","filter":{"args":[{"value":"up"}],"signature":"onActionStart(action)","slotKey":"-4"},"key":"5"},{"code":"if page < maxPage then\n page = page + 1\n selected_machine_index = 1\n Storage.clear()\n hud_machines_rows = {}\n elements = {}\n temp_elements_for_sorting = {}\n temp_elements = {}\n temp_refresh_id_list = {}\nend","filter":{"args":[{"value":"straferight"}],"signature":"onActionStart(action)","slotKey":"-4"},"key":"6"},{"code":"if page > 1 then\n page = page - 1\n selected_machine_index = 1\n Storage.clear()\n hud_machines_rows = {}\n elements = {}\n temp_elements_for_sorting = {}\n temp_elements = {}\n temp_refresh_id_list = {}\nend","filter":{"args":[{"value":"strafeleft"}],"signature":"onActionStart(action)","slotKey":"-4"},"key":"7"},{"code":"hud_displayed = not hud_displayed","filter":{"args":[{"value":"option7"}],"signature":"onActionStart(action)","slotKey":"-4"},"key":"8"},{"code":"if enableRemoteControl == true then \n --Send Command 3\n local selected_machine = elements[selected_machine_index]\n for _,db in pairs(databanks) do\n if command_3:find(\"MAINTAIN\") or command_3:find(\"BATCH\") then\n craft_quantity = \"\"\n for _,digit in pairs(craft_quantity_digits) do\n craft_quantity = craft_quantity .. digit\n end\n command_3 = command_3 .. \"_\" .. craft_quantity\n end\n --selected_machine.command = command_3\n db.setStringValue(selected_machine.id, command_3)\n if command_3:find(\"MAINTAIN\") then command_3 = \"MAINTAIN\" end\n if command_3:find(\"BATCH\") then command_3 = \"BATCH\" end\n end\n if emitter ~= nil then\n emitter.send(channels[elementsTypes[selected_index]:lower()], \"\")\n else\n system.print(\"Emitter not Linked\")\n end\nend","filter":{"args":[{"value":"option3"}],"signature":"onActionStart(action)","slotKey":"-4"},"key":"9"},{"code":"if enableRemoteControl == true then \n --Send Command 12\n local selected_machine = elements[selected_machine_index]\n for _,db in pairs(databanks) do\n if command_2:find(\"MAINTAIN\") or command_2:find(\"BATCH\") then\n craft_quantity = \"\"\n for _,digit in pairs(craft_quantity_digits) do\n craft_quantity = craft_quantity .. digit\n end\n command_2 = command_2 .. \"_\" .. craft_quantity\n end\n --selected_machine.command = command_2\n db.setStringValue(selected_machine.id, command_2)\n if command_2:find(\"MAINTAIN\") then command_2 = \"MAINTAIN\" end\n if command_2:find(\"BATCH\") then command_2 = \"BATCH\" end\n end\n if emitter ~= nil then\n emitter.send(channels[elementsTypes[selected_index]:lower()], \"\")\n else\n system.print(\"Emitter not Linked\")\n end\nend","filter":{"args":[{"value":"option2"}],"signature":"onActionStart(action)","slotKey":"-4"},"key":"10"},{"code":"if enableRemoteControl == true then\n --Send Command 1\n local selected_machine = elements[selected_machine_index]\n for _,db in pairs(databanks) do\n db.setStringValue(selected_machine.id, command_1)\n end\n if emitter ~= nil then\n emitter.send(channels[elementsTypes[selected_index]:lower()], \"\")\n else\n system.print(\"Emitter not Linked\")\n end\nend","filter":{"args":[{"value":"option1"}],"signature":"onActionStart(action)","slotKey":"-4"},"key":"11"},{"code":"if Ctrl_pressed == true then\n if selected_index < #elementsTypes then\n selected_index = selected_index + 1\n selected_type = elementsTypes[selected_index]\n selected_machine_index = 1\n page = 1\n Storage.clear()\n craft_quantity_digits = {\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\"}\n selectedElementsId = {}\n hud_machines_rows = {}\n elements = {}\n selectedElementsId = {}\n temp_selectedElementsId = {}\n temp_elements_for_sorting = {}\n temp_elements = {}\n temp_refresh_id_list = {}\n machineLoaded = false\n end\nelse\n if selected_machine_index < #elements then\n selected_machine_index = selected_machine_index + 1\n craft_quantity_digits = {\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\"}\n end\nend","filter":{"args":[{"value":"down"}],"signature":"onActionStart(action)","slotKey":"-4"},"key":"12"},{"code":"Ctrl_pressed = true","filter":{"args":[{"value":"brake"}],"signature":"onActionStart(action)","slotKey":"-4"},"key":"13"},{"code":"Storage.clear()","filter":{"args":[],"signature":"onStop()","slotKey":"-1"},"key":"0"},{"code":"--[[\n DU Industry HUD By Jericho\n]]\n\nlocal version = \"V 3.0.8 - alpha\"\nlocal log_split = \"=================================================\"\n--printing version in lua chat\nsystem.print(log_split)local a=\"\"local b=math.ceil((50-#version-2)/2)for c=1,b,1 do a=a..'='end;a=a..\" \"..version..\" \"for c=1,b,1 do a=a..'='end;system.print(a)system.print(log_split)\n\n--[[\n\treceivers channels for each type of machine\n]]\nchannel_for_refiner = \"receiver_refiner\" --export: receiver channel to send orders to refiners\nchannel_for_assembly = \"receiver_assembly\" --export: receiver channel to send orders to assembly lines\nchannel_for_smelter = \"receiver_smelters\" --export: receiver channel to send orders to smelters\nchannel_for_chemical = \"receiver_chemical\" --export: receiver channel to send orders to chemical indutries\nchannel_for_electronics = \"receiver_electronics\" --export: receiver channel to send orders to electronic industries\nchannel_for_glass = \"receiver_glass\" --export: receiver channel to send orders to glass furnace\nchannel_for_honeycomb = \"receiver_honeycomb_recycler\" --export: receiver channel to send orders to honeycomb refiniries\nchannel_for_recycler = \"receiver_honeycomb_recycler\" --export: receiver channel to send orders to recylers\nchannel_for_metalwork = \"receiver_metalworks\" --export: receiver channel to send orders to metalworks\nchannel_for_3d_printer = \"receiver_3dprinters\" --export: receiver channel to send orders to 3d printers\nchannel_for_transfer = \"receiver_transfert\" --export: receiver channel to send orders to tranfer units\n\n--[[\n Lua parameters\n]]\nenableRefinerMonitoring = true --export: enable or disable the Refiners monitoring\nenableAssemblyMonitoring = true --export: enable or disable the Assembly lines monitoring\nenableSmelterMonitoring = true --export: enable or disable the Smelters monitoring\nenableChemicalMonitoring = true --export: enable or disable the Chemical industries monitoring\nenableElectronicsMonitoring = true --export: enable or disable the Electronics Industries monitoring\nenableGlassMonitoring = true --export: enable or disable the Glass Furnace monitoring\nenableHoneycombMonitoring = true --export: enable or disable the Honeycomb Refineries monitoring\nenableRecyclerMonitoring = true --export: enable or disable the Recyclers monitoring\nenableMetalworkMonitoring = true --export: enable or disable the Metalworks monitoring\nenable3DPrinterMonitoring = true --export: enable or disable the 3D Printers monitoring\nenableTransferMonitoring = true --export: enable or disable the transfer units monitoring\nenableRemoteControl = true --export: enable the HUD to control machines (start/stop/batch/maintain)\nelementsByPage = 20 --export: maximum amount of elements displayed on a single page\ndateFormat = \"en\" --export: the country code to format the date\nmaxAmountOfElementsLoadedByFrame = 1000 --export: if cpu load errors at start, lower that value\n\n--[[\n\tDO NOT CHANGE THE FOLLOWING\n]]\n\n--Utility functions By jericho, see full source at https://github.com/Jericho1060/DualUniverse\nfunction removeDuplicatesInTable(a)local b={}local c={}for d,e in ipairs(a)do if not b[e]then c[#c+1]=e;b[e]=true end end;return c end;function strSplit(a,b)result={}for c in(a..b):gmatch(\"(.-)\"..b)do table.insert(result,c)end;return result end;function SecondsToClockString(a)local a=tonumber(a)if a==nil or a<=0 then return\"-\"else days=string.format(\"%2.f\",math.floor(a/(3600*24)))hours=string.format(\"%2.f\",math.floor(a/3600-days*24))mins=string.format(\"%2.f\",math.floor(a/60-hours*60-days*24*60))secs=string.format(\"%2.f\",math.floor(a-hours*3600-days*24*60*60-mins*60))str=\"\"if tonumber(days)>0 then str=str..days..\"d \"end;if tonumber(hours)>0 then str=str..hours..\"h \"end;if tonumber(mins)>0 then str=str..mins..\"m \"end;if tonumber(secs)>0 then str=str..secs..\"s\"end;return str end end;function removeQualityInName(a)if not a then return''end;return a:lower():gsub('basic ',''):gsub('uncommon ',''):gsub('advanced ',''):gsub('rare ',''):gsub('exotic ','')end;function has_value(a,b)for c,d in ipairs(a)do if d==b then return true end end;return false end\n\n--time script to get client date and time by Jericho, see full source at https://github.com/Jericho1060/DualUniverse\nfunction DUCurrentDateTime(a)local b=system.getUtcTime()if not a then b=b+system.getUtcOffset()end;local c=24*60*60;local d=365*c;local e=d+c;local f=4*d+c;local g=4;local h=1970;local i={-1,30,58,89,119,150,180,211,242,272,303,333,364}local j={}for k=1,2 do j[k]=i[k]end;for k=3,13 do j[k]=i[k]+1 end;local l,m,n,o,p,q,r,s;local t=i;s=b;l=math.floor(s/f)s=s-l*f;l=l*4+h;if s>=d then l=l+1;s=s-d;if s>=d then l=l+1;s=s-d;if s>=e then l=l+1;s=s-e else t=j end end end;m=math.floor(s/c)s=s-m*c;local n=1;while t[n]<m do n=n+1 end;n=n-1;local o=m-t[n]p=(math.floor(b/c)+g)%7;if p==0 then p=7 end;q=math.floor(s/3600)s=s-q*3600;r=math.floor(s/60)function round(u,v)if v then return utils.round(u/v)*v end;return u>=0 and math.floor(u+0.5)or math.ceil(u-0.5)end;s=round(s-r*60)local w={\"Monday\",\"Tuesday\",\"Wednesday\",\"Thursday\",\"Friday\",\"Saturday\",\"Sunday\"}local x={\"Mon\",\"Tue\",\"Wed\",\"Thu\",\"Fri\",\"Sat\",\"Sun\"}local y={\"January\",\"February\",\"March\",\"April\",\"May\",\"June\",\"July\",\"August\",\"September\",\"October\",\"November\",\"December\"}local z={\"Jan\",\"Feb\",\"Mar\",\"Apr\",\"May\",\"Jun\",\"Jul\",\"Aug\",\"Sep\",\"Oct\",\"Nov\",\"Dec\"}return l,n,o,q,r,s,p,w[p],x[p],y[n],z[n],m+1 end\n \n--databank hub library By Jericho, see full source at https://github.com/Jericho1060/DualUniverse\nbankhub={}function bankhub:new(banks)o={}setmetatable(o,self)self.__index=self;o.banks=banks or{}function o.clear()return o:_clear()end;function o.getNbKeys()return o:_getNbKeys()end;function o.getKeys()return o:_getKeys()end;function o.hasKey(a)return o:_hasKey(a)end;function o.getStringValue(a)return o:_getStringValue(a)end;function o.getIntValue(a)return o:_getIntValue(a)end;function o.getFloatValue(a)return o:_getFloatValue(a)end;return o end;function bankhub:add(b)table.insert(self.banks,b)self.banks_size=#self.banks end;function bankhub:_clear()for c,d in pairs(self.banks)do d.clear()end end;function bankhub:_getNbKeys()local e=0;for c,d in pairs(self.banks)do e=e+d.getNbKeys()end;return e end;function bankhub:_getKeys()local e={}for c,d in pairs(self.banks)do local f=json.decode(d.getKeys())for c,g in pairs(f)do table.insert(e,g)end end;return json.encode(e)end;function bankhub:_hasKey(a)for c,d in pairs(self.banks)do if d.hasKey(a)==1 then return 1 end end;return 0 end;function bankhub:_getStringValue(a)for c,d in pairs(self.banks)do if d.hasKey(a)==1 then return d.getStringValue(a)end end;return nil end;function bankhub:_getIntValue(a)for c,d in pairs(self.banks)do if d.hasKey(a)==1 then return banks.getIntValue(a)end end;return nil end;function bankhub:_getFloatValue(a)for c,d in pairs(self.banks)do if d.hasKey(a)==1 then return banks.getFloatValue(a)end end;return nil end\n\nchannels = {}\nchannels['refiner'] = channel_for_refiner\nchannels['assembly line'] = channel_for_assembly\nchannels['smelter'] = channel_for_smelter\nchannels['chemical industry'] = channel_for_chemical\nchannels['electronics industry'] = channel_for_electronics\nchannels['glass furnace'] = channel_for_glass\nchannels['honeycomb refinery'] = channel_for_honeycomb\nchannels['recycler'] = channel_for_recycler\nchannels['metalwork industry'] = channel_for_metalwork\nchannels['3d printer'] = channel_for_3d_printer\nchannels['transfer unit'] = channel_for_transfer\n\n--[[\n Detecting elements connected on slots\n]]\ndatabanks = {}\ncore = nil\nemitter = nil\nfor slot_name, slot in pairs(unit) do\n if\n type(slot) == \"table\"\n and type(slot.export) == \"table\"\n and slot.getClass\n then\n if slot.getClass():lower() == 'databankunit' then\n table.insert(databanks, slot)\n end\n if slot.getClass():lower():find(\"coreunit\") then\n core = slot\n end\n if slot.getClass():lower() == 'emitterunit' then\n emitter = slot\n end\n end\nend\nif core == nil then\n system.print(\"Connection to the core is missing\")\n unit.exit()\nend\nif emitter == nil then \n enableRemoteControl = false\n system.print(\"Connect an Emitter to enable machine control from industry\")\nend\nif #databanks == 0 then \n enableRemoteControl = false\n system.print(\"No Databank linked\")\nend\n\n--init of bank hub\nStorage = bankhub:new(databanks)\n\n--variable init and loading elements from the core\nelementsId = {}\nelements = {}\nelementsTypes = {}\nmachines_count = {}\nmachines_count.total = 0\ninitIndex = 1\nlistIndex = 1\ninit = false\nchannel_index = 1\nselected_index = 1\nselected_type = nil\nselected_machine_index = 1\nselected_machine = nil\nhud_displayed = true\npage = 1\nmaxPage = 1\nselectedElementsId = {}\nCtrl_pressed = false\ncraft_quantity = \"\"\ncraft_quantity_digits = {\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\"}\nrefresh_id_list = {}\ncraft_selected_digit = 1\ncommand_1 = \"\"\ncommand_2 = \"\"\ncommand_3 = \"\"\nrefreshActivated = true\nhud_help_command = \"\"\nunit.setTimer(\"helperRefresh\",1)\nminOnPage = 0\nmaxOnPage = 0\nelementsIdList = core.getElementIdList()\ntemp_selectedElementsId = {}\ntemp_elements_for_sorting = {}\ntemp_elements = {}\ntemp_refresh_id_list = {}\nmachineLoaded = false\nselected_machine = nil\n\n--init global HUD style\nhud_help_command = ''\nhud_elements_type_list = ''\nhud_machines = ''\nhud_machines_rows = {}\ncontrolHud = ''\n\n--construct pos for AR data\nconstructPos = construct.getWorldPosition()\nconstructRight = construct.getWorldRight()\nconstructForward = construct.getWorldForward()\nconstructUp = construct.getWorldUp()\narhtml = ''\n\n--Boostrap like css for DU by Jericho1060, see full source at https://github.com/Jericho1060/DualUniverse\nbootstrap_css_grid = [[<style>.container {width: 100%;padding-right: 15px;padding-left: 15px;margin-right: auto;margin-left: auto;}.row {position:relative;display: flex;flex-wrap: wrap;margin-right: -15px;margin-left: -15px;}.col-1, .col-2, .col-3, .col-4, .col-5, .col-6, .col-7, .col-8, .col-9, .col-10, .col-11, .col-12, .col {position: relative;width: 100%;padding-right: 15px;padding-left: 15px;}.col {flex-basis: 0;flex-grow: 1;max-width: 100%;}.col-auto {flex: 0 0 auto;width: auto;max-width: 100%;}.col-1 {flex: 0 0 8.333333%;max-width: 8.333333%;}.col-2 {flex: 0 0 16.666667%;max-width: 16.666667%;}.col-3 {flex: 0 0 25%;max-width: 25%;}.col-4 {flex: 0 0 33.333333%;max-width: 33.333333%;}.col-5 {flex: 0 0 41.666667%;max-width: 41.666667%;}.col-6 {flex: 0 0 50%;max-width: 50%;}.col-7 {flex: 0 0 58.333333%;max-width: 58.333333%;}.col-8 {flex: 0 0 66.666667%;max-width: 66.666667%;}.col-9 {flex: 0 0 75%;max-width: 75%;}.col-10 {flex: 0 0 83.333333%;max-width: 83.333333%;}.col-11 {flex: 0 0 91.666667%;max-width: 91.666667%;}.col-12 {flex: 0 0 100%;max-width: 100%;}.offset-12 {margin-left: 100%;}.offset-11 {margin-left: 91.66666667%;}.offset-10 {margin-left: 83.33333333%;}.offset-9 {margin-left: 75%;}.offset-8 {margin-left: 66.66666667%;}.offset-7 {margin-left: 58.33333333%;}.offset-6 {margin-left: 50%;}.offset-5 {margin-left: 41.66666667%;}.offset-4 {margin-left: 33.33333333%;}.offset-3 {margin-left: 25%;}.offset-2 {margin-left: 16.66666667%;}.offset-1 {margin-left: 8.33333333%;}.offset-0 {margin-left: 0%;}</style>]]\nbootstrap_css_colors = [[<style>.text-white {color: #fff !important;}.text-primary {color: #007bff !important;}.text-secondary {color: #6c757d !important;}.text-success {color: #28a745 !important;}.text-info {color: #17a2b8 !important;}.text-warning {color: #ffc107 !important;}.text-danger {color: #dc3545 !important;}.text-light {color: #f8f9fa !important;}.text-dark {color: #343a40 !important;}.text-body {color: #212529 !important;}.text-muted {color: #6c757d !important;}.text-black-50 {color: rgba(0, 0, 0, 0.5) !important;}.text-white-50 {color: rgba(255, 255, 255, 0.5) !important;}.bg-primary {background-color: #007bff !important;}.bg-secondary {background-color: #6c757d !important;}.bg-success {background-color: #28a745 !important;}.bg-info {background-color: #17a2b8 !important;}.bg-warning {background-color: #ffc107 !important;}.bg-danger {background-color: #dc3545 !important;}.bg-light {background-color: #f8f9fa !important;}.bg-dark {background-color: #343a40 !important;}.bg-white {background-color: #fff !important;}.bg-transparent {background-color: transparent !important;}</style>]]\nbootstrap_text_utils = [[<style>.text-left {text-align: left;}.text-right {text-align: right;}.text-center {text-align: center;}.text-justify {text-align: justify;}.text-nowrap {white-space: nowrap;}.text-lowercase {text-transform: lowercase;}.text-uppercase {text-transform: uppercase;}.text-capitalize {text-transform: capitalize;}</style>]]\nbootstrap_css = bootstrap_css_grid .. bootstrap_css_colors .. bootstrap_text_utils\n\nlocal statusList = {\"STOPPED\",\"RUNNING\",\"MISSING INGREDIENT\",\"OUTPUT FULL\",\"NO OUTPUT CONTAINER\",\"PENDING\",\"MISSING SCHEMATIC\",\"SERVER ERROR\"}\nfunction getIndustryStatusClass(status)\n if status == 1 then\n return \"text-info\"\n elseif status == 2 then\n return \"text-success\"\n elseif ((status >= 3) and (status <= 5)) or (status == 7) then\n return \"text-danger\"\n elseif status == 6 then\n return \"text-primary\"\n elseif status == 8 then\n return \"text-warning\"\n end\n return \"\" --default value for other status that can be added\nend\nfunction getIndustryStatusBgClass(status)\n if status then\n if status == 1 then\n return \"bg-info\"\n elseif status == 2 then\n return \"bg-success\"\n elseif ((status >= 3) and (status <= 5)) or (status == 7) then\n return \"bg-danger\"\n elseif status == 6 then\n return \"bg-primary\"\n end\n end\n return \"\" --default value for other status that can be added\nend\n--[[\n Convert a table in local coordinates to a table in world coordinates by Jericho inspired by Koruzarius\n Source : https://github.com/Jericho1060/DualUniverse/blob/master/Vectors/localToWorldPos.lua\n]]--\nfunction ConvertLocalToWorld(a,b,c,d,e)local f={a[1]*c[1],a[1]*c[2],a[1]*c[3]}local g={a[2]*d[1],a[2]*d[2],a[2]*d[3]}local h={a[3]*e[1],a[3]*e[2],a[3]*e[3]}return{f[1]+g[1]+h[1]+b[1],f[2]+g[2]+h[2]+b[2],f[3]+g[3]+h[3]+b[3]}end\n--[[\n Concept based on DU-Nested-Coroutines by Jericho\n Source available here: https://github.com/Jericho1060/du-nested-coroutines\n]]--\n\ncoroutinesTable = {}\nMyCoroutines = {\n function()\n --load all the machines from the core step by step to avoid CPU Load Errors\n if not init then\n local maxForLoop = initIndex + maxAmountOfElementsLoadedByFrame\n if maxForLoop > #elementsIdList then maxForLoop = #elementsIdList end\n system.print(\"Loading elements from \" .. initIndex .. \" to \" .. maxForLoop .. \" on \" .. #elementsIdList)\n \n for i = initIndex, maxForLoop, 1 do\n initIndex = i\n local id = elementsIdList[i]\n elementType = core.getElementDisplayNameById(id):lower()\n if (elementType:find(\"assembly line\") and enableAssemblyMonitoring == true) or\n (elementType:find(\"glass furnace\") and enableGlassMonitoring == true) or\n (elementType:find(\"3d printer\") and enable3DPrinterMonitoring == true) or\n (elementType:find(\"smelter\") and enableSmelterMonitoring == true) or\n (elementType:find(\"recycler\") and enableRecyclerMonitoring == true) or\n (elementType:find(\"refinery\") and enableHoneycombMonitoring == true) or\n (elementType:find(\"refiner\") and enableRefinerMonitoring == true) or\n (elementType:find(\"industry\")\n and (\n (elementType:find(\"chemical\") and enableChemicalMonitoring == true) or\n (elementType:find(\"electronics\") and enableElectronicsMonitoring == true) or\n (elementType:find(\"metalwork\") and enableMetalworkMonitoring == true)\n )\n ) or\n (elementType == \"transfer unit\" and enableTransferMonitoring == true)\n then\n \tlocal formatedType = removeQualityInName(elementType)\n \tif\n (elementType:lower():find(\"container\")\n and elementName:find(containerMonitoringPrefix:lower()))\n or (not elementType:lower():find(\"container\"))\n then\n table.insert(elementsTypes, formatedType)\n end\n if machines_count[formatedType] ~= nil then\n machines_count[formatedType] = machines_count[formatedType] + 1\n else\n machines_count[formatedType] = 1\n end\n table.insert(elementsId, id)\n end\n end\n if initIndex >= #elementsIdList then\n elementsTypes = removeDuplicatesInTable(elementsTypes)\n table.sort(elementsTypes, function(a,b) return a:lower() < b:lower() end)\n selected_type = elementsTypes[1]\n init = true\n system.print(\"All elements loaded\")\n end\n end\n end,\n function()\n local count = 0\n if init then\n if selected_type ~= nil and not machineLoaded then\n local count = machines_count[selected_type:lower()]\n local divider = math.ceil(count / 200)\n local maxForLoop = listIndex + math.ceil(maxAmountOfElementsLoadedByFrame / divider)\n if maxForLoop > #elementsId then maxForLoop = #elementsId end\n for i = listIndex, maxForLoop, 1 do\n listIndex = i\n local id = elementsId[i]\n elementType = core.getElementDisplayNameById(id)\n if selected_type:find(removeQualityInName(elementType)) then\n if\n (elementType:lower():find(\"container\")\n and core.getElementNameById(id):lower():find(containerMonitoringPrefix:lower()))\n or (not elementType:lower():find(\"container\"))\n then\n table.insert(temp_selectedElementsId, id)\n end\n end\n if #temp_selectedElementsId >= count then\n selectedElementsId = temp_selectedElementsId\n temp_selectedElementsId = {}\n maxPage = math.ceil(#selectedElementsId / elementsByPage)\n listIndex = 1\n machineLoaded = true\n if #selectedElementsId ~= count then\n machineLoaded = false\n end\n break\n end\n if listIndex >= #elementsId then\n listIndex = 1\n end\n end\n end\n end\n end,\n function()\n local year, month, day, hour, minute, second = DUCurrentDateTime()\n local dateStr = string.format(\"%02d/%02d/%04d %02d:%02d:%02d\",day,month,year,hour,minute,second)\n hud_help_command = [[<div class=\"hud_help_commands hud_container\">\n <table>\n <tr>\n <th colspan=\"2\">\n ]] .. dateStr .. [[\n </th>\n </tr>\n <tr>\n <td>Show/Hide HUD</td>\n <th style=\"text-align:right;\">Alt+7</th>\n </tr>\n </table>\n </div>]]\n coroutine.yield(coroutinesTable[3])\n end,\n function()\n if init then\n hud_elements_type_list = '<div class=\"hud_list_container hud_container\"><div style=\"text-align:center;border-bottom:1px solid white;\">&#x2191; &nbsp;&nbsp; Ctrl+Arrow Up</div>'\n for i, elementType in pairs(elementsTypes) do\n hud_elements_type_list = hud_elements_type_list .. '<div class=\"elementType'\n if i == selected_index then\n hud_elements_type_list = hud_elements_type_list .. \" selected\"\n end\n local count = 0\n if machines_count[elementType:lower()] ~= nil then count = machines_count[elementType:lower()] end\n hud_elements_type_list = hud_elements_type_list .. '\"><table style=\"width:100%;\"><tr><th style=\"text-align:left;border-bottom:none;\">'.. elementType .. '</th><td style=\"text-align:right;border-bottom:none;\">' .. tostring(count) .. '</td></tr></table></div>'\n end\n hud_elements_type_list = hud_elements_type_list .. '<div style=\"margin-top:10px;text-align:center;font-weight:bold;border-top:1px solid white;\">&#x2193; &nbsp;&nbsp; Ctrl+Arrow Down</div></div>'\n coroutine.yield(coroutinesTable[4])\n end\n end,\n function()\n for i, element in pairs(elements) do\n if #elements > 0 then\n local statusData = core.getElementIndustryInfoById(element.id)\n local schematicId = 0\n local recipeName = \"-\"\n if #statusData.currentProducts > 0 then\n local item = system.getItem(statusData.currentProducts[1].id)\n schematicId = item.schematics[1] or 0\n if item.locDisplayNameWithSize then\n recipeName = item.locDisplayNameWithSize\n end\n end\n local remainingTime = 0\n if (statusData) and (statusData.remainingTime) and (statusData.remainingTime <= (3600*24*365)) then\n remainingTime = statusData.remainingTime\n end\n element.recipeName = recipeName\n element.remainingTime = remainingTime\n element.status = statusData.state\n if remainingTime == 0 and statusData.state == 2 then\n element.status = 8\n end\n element.unitsProduced = statusData.unitsProduced\n local mode = \"\"\n element.maintainProductAmount = statusData.maintainProductAmount\n element.batchesRequested = statusData.batchesRequested\n if statusData.maintainProductAmount > 0 then\n \tmode = \"Maintain \" .. math.floor(statusData.maintainProductAmount)\n elseif statusData.batchesRequested > 0 and statusData.batchesRequested <= 99999999 then\n mode = \"Produce \" .. math.floor(statusData.batchesRequested)\n end\n local status = statusList[element.status] or '-'\n local status_class = getIndustryStatusClass(element.status)\n hud_machines_rows[i] = \"<tr\"\n if selected_machine_index == i then\n hud_machines_rows[i] = hud_machines_rows[i] .. ' class=\"selected\"'\n end\n local machine_id = \"-\"\n if element.id then machine_id = element.id end\n local unitsProduced = 0\n if element.unitsProduced then unitsProduced = element.unitsProduced end\n hud_machines_rows[i] = hud_machines_rows[i] .. '><th>' .. machine_id .. '</th><th><span class=\"' .. status_class .. '\">' .. element.name .. '</span><br><small>' .. element.type .. '</small></th><th>' .. recipeName\n if schematicId > 0 then\n local schematic = system.getItem(schematicId)\n local schematicsRemaining = statusData.schematicsRemaining\n local schematic_color = \"#fff\"\n if schematicsRemaining == 0 then schematic_color = \"text-danger\" end\n hud_machines_rows[i] = hud_machines_rows[i] .. [[<br><small class=\"]] .. schematic_color .. [[\">]] .. schematicsRemaining .. [[ ]] .. schematic.locDisplayNameWithSize .. [[</small>]]\n end\n hud_machines_rows[i] = hud_machines_rows[i] .. '</th><td>' .. unitsProduced .. '</td><th class=\"' .. status_class .. '\">' .. status .. '</th><th>' .. mode .. '</th><td class=\"' .. status_class .. '\">' .. SecondsToClockString(element.remainingTime) .. '</td></tr>'\n else\n break\n end\n end\n end,\n function()\n hud_machines = [[<div class=\"hud_machines_container hud_container\">\n <div style=\"text-align:center;font-weight:bold;border-bottom:1px solid white;\">&#x2191; &nbsp;&nbsp; Arrow Up</div>\n <table class=\"elements_table\" style=\"width:100%\">\n <tr>\n <th>&#x2190; &nbsp;&nbsp; Arrow Left</th>\n <th> Page ]] .. page .. [[/]] .. maxPage .. [[ (from ]] .. minOnPage .. [[ to ]] .. maxOnPage .. [[ on ]] .. #selectedElementsId .. [[)</th>\n <th>Arrow Right &nbsp;&nbsp; &#x2192;</th>\n </tr>\n </table>\n <table class=\"elements_table\" style=\"width:100%;\">\n <tr>\n <th>id</th>\n <th>Machine Name & Type</th>\n <th>Selected Recipe & schematic</th>\n <th>Cycles From Start</th>\n <th>Status</th>\n <th>Mode</th>\n <th>Time Remaining</th>\n </tr>\n ]]\n for i, row in pairs(hud_machines_rows) do\n if row ~= nil then\n hud_machines = hud_machines .. row\n end\n end\n hud_machines = hud_machines .. '</table><table class=\"elements_table\" style=\"width:100%\"><tr><th>&#x2190; &nbsp;&nbsp; Arrow Left</th><th> Page ' .. page .. '/' .. maxPage .. ' (from ' .. minOnPage .. ' to ' .. maxOnPage .. ' on ' .. #selectedElementsId .. ')</th><th>Arrow Right &nbsp;&nbsp; &#x2192;</th></tr></table><div style=\"text-align:center;font-weight:bold;border-top:1px solid white;\">&#x2193; &nbsp;&nbsp; Arrow Down</div></div>'\n coroutine.yield(coroutinesTable[6])\n end,\n function()\n minOnPage = ((page - 1) * elementsByPage) + 1\n maxOnPage = page * elementsByPage\n if maxOnPage > #selectedElementsId then maxOnPage = #selectedElementsId end\n for i,id in pairs(selectedElementsId) do\n elementData = {}\n elementData.id = id\n elementData.name = core.getElementNameById(id)\n table.insert(temp_elements_for_sorting, elementData)\n end\n table.sort(temp_elements_for_sorting, function(a,b) return a.name:lower() < b.name:lower() end)\n for i = minOnPage, maxOnPage, 1 do\n if temp_elements_for_sorting[i] ~= nil then\n elementData = temp_elements_for_sorting[i]\n elementType = core.getElementDisplayNameById(elementData.id)\n elementData.type = elementType\n elementData.name = core.getElementNameById(elementData.id)\n elementData.position = core.getElementPositionById(elementData.id)\n table.insert(temp_refresh_id_list, elementData.id)\n table.insert(temp_elements, elementData)\n else\n temp_refresh_id_list = {}\n temp_elements_for_sorting = {}\n temp_elements = {}\n break\n end\n coroutine.yield(coroutinesTable[7])\n end\n refresh_id_list = temp_refresh_id_list\n temp_refresh_id_list = {}\n elements = temp_elements\n temp_elements_for_sorting = {}\n temp_elements = {}\n end,\n function()\n hud_main_css = [[\n <style>\n \t * {\n \t\t font-size: 1vh !important;\n \t\t font-familly: \"Play-Bold\";\n \t }\n .hud_container {\n border: 1px solid black;\n border-radius:10px;\n background-color: rgba(15,24,29,.75);\n padding:10px;\n }\n .hud_help_commands {\n position: absolute;\n top: ]] .. tostring((10/1080)*100) .. [[vh;\n left: ]] .. tostring((25/1920)*100) .. [[vw;\n text-transform: uppercase;\n font-weight: bold;\n }\n .hud_list_container {\n position: absolute;\n top: ]] .. tostring((100/1080)*100) .. [[vh;\n left: ]] .. tostring((25/1920)*100) .. [[vw;\n text-transform: uppercase;\n font-weight: bold;\n }\n .hud_machine_detail {\n position: absolute;\n top: ]] .. tostring((250/1080)*100) .. [[vh;\n right: ]] .. tostring((25/1920)*100) .. [[vw;\n text-transform: uppercase;\n font-weight: bold;\n }\n .hud_machines_container {\n position: absolute;\n top: ]] .. tostring((100/1080)*100) .. [[vh;\n left: ]] .. tostring((225/1920)*100) .. [[vw;\n }\n .elementType {\n margin-top:10px;\n border-radius:5px;\n }\n .elementType.selected {\n border: 2px solid green;\n background-color: rgba(0,200,0,.45);\n }\n tr.selected td, tr.selected th{\n border-top: 2px solid green;\n border-bottom: 2px solid green;\n background-color: rgba(0,200,0,.1);\n }\n td, th {\n border-bottom:1px solid white;\n padding:5px;\n text-align: center;\n }\n th {\n font-weight: bold;\n }\n .text-success{color:rgb(34,177,76);}\n .text-danger{color:rgb(177,42,42);}\n .text-warning{color:rgb(249,212,123);}\n .text-info{color:#17a2b8;}\n .text-primary{color:#007bff;}\n .text-orangered{color:orangered;}\n .bg-success{background-color:rgb(34,177,76) !important;}\n .bg-danger{background-color:rgb(177,42,42) !important;}\n .bg-warning{background-color:rgb(249,212,123) !important;}\n .bg-info{background-color:#17a2b8 !important;}\n .bg-primary{background-color:#007bff !important;}\n small{font-size:.5em;}\n </style>\n ]]\n if not init then \n hud_elements_type_list = [[\n <div class=\"hud_list_container hud_container\">\n \t<table style=\"width:100%\">\n \t\t<tr>\n \t\t\t<th>LOADING ]] .. math.floor(initIndex*100/#elementsIdList) .. [[% ...</th>\n \t\t</tr>\n \t</table>\n </div>\n ]]\n end\n if hud_displayed then\n system.setScreen(hud_main_css .. hud_help_command .. hud_elements_type_list .. hud_machines .. controlHud .. arhtml)\n else\n system.setScreen(hud_main_css .. hud_help_command .. arhtml)\n end\n end,\n function()\n selected_machine = elements[selected_machine_index]\n end,\n function()\n if selected_machine then\n if prevRecipe == nil then prevRecipe=''end\n if prevStatus == nil then prevStatus=1 end\n if prevName == nil then prevName='' end\n if selected_machine.status then prevStatus = selected_machine.status end\n if selected_machine.recipeName then prevRecipe = selected_machine.recipeName end\n if selected_machine.name then prevName = selected_machine.name end\n local screenpos = library.getPointOnScreen(ConvertLocalToWorld(selected_machine.position, constructPos, constructRight, constructForward, constructUp))\n if screenpos[1] > 1 then screenpos[1] = 1 elseif screenpos[1] < 0 then screenpos[1] = 0 end\n if screenpos[2] > .95 then screenpos[2] = .95 elseif screenpos[2] < 0 then screenpos[2] = 0 end\n arhtml = [[<div style=\"text-align:center;position:absolute;left:]] .. utils.round(screenpos[1]*100) .. [[%;top:]] .. utils.round(screenpos[2]*100) .. [[%;;margin-left:-500px;width:1000px;\"><div style=\"width:fit-content;padding:5px;margin:auto;border:2px solid black;border-radius:10px;background-color:rgba(15,24,29,.75);text-align:center;\" class=\"]] .. getIndustryStatusBgClass(prevStatus) .. [[\">]] .. prevName .. [[<br>]] .. prevRecipe .. [[<br><br><span style=\"font-weight:bold;\">]] .. statusList[prevStatus] .. [[</span></div></div>]]\n end\n end,\n function()\n if enableRemoteControl then\n if selected_machine then\n if prevRecipe == nil then prevRecipe=''end\n if prevStatus == nil then prevStatus=99 end\n if prevMaintainProductAmount == nil then prevMaintainProductAmount = 0 end\n if prevBatchesRequested == nil then prevBatchesRequested = 0 end\n if selected_machine.status then prevStatus = selected_machine.status end\n if selected_machine.recipeName then prevRecipe = selected_machine.recipeName end\n if selected_machine.maintainProductAmount then prevMaintainProductAmount = selected_machine.maintainProductAmount end\n if selected_machine.batchesRequested then prevBatchesRequested = selected_machine.batchesRequested end\n controlHud = [[<div class=\"hud_machine_detail hud_container\">\n <table>\n <tr>\n <th colspan=\"3\">]] .. selected_machine.name .. [[</th>\n </tr>\n <tr>\n <th class=\"]] .. getIndustryStatusClass(prevStatus) .. [[\" colspan=\"3\">]] .. statusList[prevStatus] .. [[</th>\n </tr>\n ]]\n if prevStatus == 1 then\n command_1 = \"START\"\n command_2 = \"BATCH\"\n command_3 = \"MAINTAIN\"\n controlHud = controlHud .. [[\n <tr>\n <th>START</th>\n <th></th>\n <th>ALT+1</th>\n </tr>\n <tr>\n <th style=\"height:65px;\">BATCH</th>\n <th rowspan=\"2\">\n <table>\n <tr>\n <th colspan=\"3\">Quantity:</th>\n </tr>\n <tr>\n <th style=\"font-size:20px;\">\n ]]\n local has_quantity = false\n for k,v in pairs(craft_quantity_digits) do\n if tonumber(v) == nil then v = 0 end\n if tonumber(v) > 0 then\n has_quantity = true\n end\n end\n if not has_quantity then\n local value = \"0\"\n if prevMaintainProductAmount > 0 then\n value = tostring(math.floor(prevMaintainProductAmount))\n elseif prevBatchesRequested > 0 and prevBatchesRequested <= 99999999 then\n value = tostring(math.floor(prevBatchesRequested))\n end\n for i = #value, 1, -1 do\n local c = value:sub(i,i)\n craft_quantity_digits[9-(#value-(i-1))] = c\n end\n end\n for digit_index,digit in pairs(craft_quantity_digits) do\n controlHud = controlHud .. digit\n end\n controlHud = controlHud .. [[\n </th>\n </tr>\n </table>\n </th>\n <th>ALT+2</th>\n </tr>\n <tr>\n <th>MAINTAIN</th>\n <th>ALT+3</th>\n </tr>\n ]]\n else\n command_1 = \"STOP\"\n command_2 = \"SOFT_STOP\"\n command_3 = \"\"\n controlHud = controlHud .. [[\n <tr>\n <th>STOP</th>\n <th>ALT+1</th>\n </tr>\n <tr>\n <th>FINISH AND STOP</th>\n <th>ALT+2</th>\n </tr>\n ]]\n end\n controlHud = controlHud .. '</table></div>'\n end\n end\n end\n}\n\nfunction initCoroutines()\n for _,f in pairs(MyCoroutines) do\n local co = coroutine.create(f)\n table.insert(coroutinesTable, co)\n end\nend\n\ninitCoroutines()\n\nrunCoroutines = function()\n for i,co in ipairs(coroutinesTable) do\n if coroutine.status(co) == \"dead\" then\n coroutinesTable[i] = coroutine.create(MyCoroutines[i])\n end\n if coroutine.status(co) == \"suspended\" then\n assert(coroutine.resume(co))\n end\n end\nend\n\nMainCoroutine = coroutine.create(runCoroutines)\n\n--Enable Display of the HUD\nsystem.showScreen(1)","filter":{"args":[],"signature":"onStart()","slotKey":"-1"},"key":"1"}],"methods":[],"slots":{"0":{"name":"slot1","type":{"events":[],"methods":[]}},"1":{"name":"slot2","type":{"events":[],"methods":[]}},"2":{"name":"slot3","type":{"events":[],"methods":[]}},"3":{"name":"slot4","type":{"events":[],"methods":[]}},"4":{"name":"slot5","type":{"events":[],"methods":[]}},"5":{"name":"slot6","type":{"events":[],"methods":[]}},"6":{"name":"slot7","type":{"events":[],"methods":[]}},"7":{"name":"slot8","type":{"events":[],"methods":[]}},"8":{"name":"slot9","type":{"events":[],"methods":[]}},"9":{"name":"slot10","type":{"events":[],"methods":[]}},"-5":{"name":"library","type":{"events":[],"methods":[]}},"-4":{"name":"system","type":{"events":[],"methods":[]}},"-3":{"name":"player","type":{"events":[],"methods":[]}},"-2":{"name":"construct","type":{"events":[],"methods":[]}},"-1":{"name":"unit","type":{"events":[],"methods":[]}}}} 1 + {"events":[],"handlers":[{"code":"--[[\n DU-Nested-Coroutines by Jericho\n Permit to easier avoid CPU Load Errors\n Source available here: https://github.com/Jericho1060/du-nested-coroutines\n]]--\n\nif coroutine.status(MainCoroutine) == \"dead\" then\n MainCoroutine = coroutine.create(runCoroutines)\nend\nif coroutine.status(MainCoroutine) == \"suspended\" then\n assert(coroutine.resume(MainCoroutine))\nend","filter":{"args":[],"signature":"onUpdate()","slotKey":"-4"},"key":"2"},{"code":"if tonumber(text) then\n if #text > 8 then\n system.print(\"the value should not be higher than 99 999 999.\")\n else\n craft_quantity_digits = {\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\"}\n for i = #text, 1, -1 do\n local c = text:sub(i,i)\n craft_quantity_digits[9-(#text-(i-1))] = c\n end\n end\nelse\n system.print(\"You must type a Number\")\nend","filter":{"args":[{"variable":"*"}],"signature":"onInputText(text)","slotKey":"-4"},"key":"3"},{"code":"Ctrl_pressed = false","filter":{"args":[{"value":"brake"}],"signature":"onActionStop(action)","slotKey":"-4"},"key":"4"},{"code":"if Ctrl_pressed == true then\n if selected_index > 1 then\n selected_index = selected_index - 1\n reloadMachinesOnTypeChange()\n else\n selected_index = #elementsTypes\n reloadMachinesOnTypeChange()\n end\nelse\n if selected_machine_index > 1 then\n selected_machine_index = selected_machine_index - 1\n else\n selected_machine_index = #elements\n end\n craft_quantity_digits = {\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\"}\nend","filter":{"args":[{"value":"up"}],"signature":"onActionStart(action)","slotKey":"-4"},"key":"5"},{"code":"if page < maxPage then\n page = page + 1\n reloadMachinesOnPageChange()\nelseif page ~= 1 then\n page = 1\n reloadMachinesOnPageChange()\nend","filter":{"args":[{"value":"straferight"}],"signature":"onActionStart(action)","slotKey":"-4"},"key":"6"},{"code":"if page > 1 then\n page = page - 1\n reloadMachinesOnPageChange()\nelseif page ~= maxPage then\n page = maxPage\n reloadMachinesOnPageChange()\nend","filter":{"args":[{"value":"strafeleft"}],"signature":"onActionStart(action)","slotKey":"-4"},"key":"7"},{"code":"hud_displayed = not hud_displayed","filter":{"args":[{"value":"option7"}],"signature":"onActionStart(action)","slotKey":"-4"},"key":"8"},{"code":"if enableRemoteControl == true then \n --Send Command 3\n local selected_machine = elements[selected_machine_index]\n for _,db in pairs(databanks) do\n if command_3:find(\"MAINTAIN\") or command_3:find(\"BATCH\") then\n craft_quantity = \"\"\n for _,digit in pairs(craft_quantity_digits) do\n craft_quantity = craft_quantity .. digit\n end\n command_3 = command_3 .. \"_\" .. craft_quantity\n end\n --selected_machine.command = command_3\n db.setStringValue(selected_machine.id, command_3)\n if command_3:find(\"MAINTAIN\") then command_3 = \"MAINTAIN\" end\n if command_3:find(\"BATCH\") then command_3 = \"BATCH\" end\n end\n if emitter ~= nil then\n emitter.send(channels[elementsTypes[selected_index]:lower()], \"\")\n else\n system.print(\"Emitter not Linked\")\n end\nend","filter":{"args":[{"value":"option3"}],"signature":"onActionStart(action)","slotKey":"-4"},"key":"9"},{"code":"if enableRemoteControl == true then \n --Send Command 12\n local selected_machine = elements[selected_machine_index]\n for _,db in pairs(databanks) do\n if command_2:find(\"MAINTAIN\") or command_2:find(\"BATCH\") then\n craft_quantity = \"\"\n for _,digit in pairs(craft_quantity_digits) do\n craft_quantity = craft_quantity .. digit\n end\n command_2 = command_2 .. \"_\" .. craft_quantity\n end\n --selected_machine.command = command_2\n db.setStringValue(selected_machine.id, command_2)\n if command_2:find(\"MAINTAIN\") then command_2 = \"MAINTAIN\" end\n if command_2:find(\"BATCH\") then command_2 = \"BATCH\" end\n end\n if emitter ~= nil then\n emitter.send(channels[elementsTypes[selected_index]:lower()], \"\")\n else\n system.print(\"Emitter not Linked\")\n end\nend","filter":{"args":[{"value":"option2"}],"signature":"onActionStart(action)","slotKey":"-4"},"key":"10"},{"code":"if enableRemoteControl == true then\n --Send Command 1\n local selected_machine = elements[selected_machine_index]\n for _,db in pairs(databanks) do\n db.setStringValue(selected_machine.id, command_1)\n end\n if emitter ~= nil then\n emitter.send(channels[elementsTypes[selected_index]:lower()], \"\")\n else\n system.print(\"Emitter not Linked\")\n end\nend","filter":{"args":[{"value":"option1"}],"signature":"onActionStart(action)","slotKey":"-4"},"key":"11"},{"code":"if Ctrl_pressed == true then\n if selected_index < #elementsTypes then\n selected_index = selected_index + 1\n reloadMachinesOnTypeChange()\n else\n selected_index = 1\n reloadMachinesOnTypeChange()\n end\nelse\n if selected_machine_index < #elements then\n selected_machine_index = selected_machine_index + 1\n else\n selected_machine_index = 1\n end\n craft_quantity_digits = {\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\"}\nend","filter":{"args":[{"value":"down"}],"signature":"onActionStart(action)","slotKey":"-4"},"key":"12"},{"code":"Ctrl_pressed = true","filter":{"args":[{"value":"brake"}],"signature":"onActionStart(action)","slotKey":"-4"},"key":"13"},{"code":"Storage.clear()","filter":{"args":[],"signature":"onStop()","slotKey":"-1"},"key":"0"},{"code":"--[[\n DU Industry HUD By Jericho\n]]\n\nlocal version = \"V 3.0.9 - alpha\"\nlocal log_split = \"=================================================\"\n--printing version in lua chat\nsystem.print(log_split)local a=\"\"local b=math.ceil((50-#version-2)/2)for c=1,b,1 do a=a..'='end;a=a..\" \"..version..\" \"for c=1,b,1 do a=a..'='end;system.print(a)system.print(log_split)\n\n--[[\n\treceivers channels for each type of machine\n]]\nchannel_for_refiner = \"receiver_refiner\" --export: receiver channel to send orders to refiners\nchannel_for_assembly = \"receiver_assembly\" --export: receiver channel to send orders to assembly lines\nchannel_for_smelter = \"receiver_smelters\" --export: receiver channel to send orders to smelters\nchannel_for_chemical = \"receiver_chemical\" --export: receiver channel to send orders to chemical indutries\nchannel_for_electronics = \"receiver_electronics\" --export: receiver channel to send orders to electronic industries\nchannel_for_glass = \"receiver_glass\" --export: receiver channel to send orders to glass furnace\nchannel_for_honeycomb = \"receiver_honeycomb_recycler\" --export: receiver channel to send orders to honeycomb refiniries\nchannel_for_recycler = \"receiver_honeycomb_recycler\" --export: receiver channel to send orders to recylers\nchannel_for_metalwork = \"receiver_metalworks\" --export: receiver channel to send orders to metalworks\nchannel_for_3d_printer = \"receiver_3dprinters\" --export: receiver channel to send orders to 3d printers\nchannel_for_transfer = \"receiver_transfert\" --export: receiver channel to send orders to tranfer units\n\n--[[\n Lua parameters\n]]\nenableRefinerMonitoring = true --export: enable or disable the Refiners monitoring\nenableAssemblyMonitoring = true --export: enable or disable the Assembly lines monitoring\nenableSmelterMonitoring = true --export: enable or disable the Smelters monitoring\nenableChemicalMonitoring = true --export: enable or disable the Chemical industries monitoring\nenableElectronicsMonitoring = true --export: enable or disable the Electronics Industries monitoring\nenableGlassMonitoring = true --export: enable or disable the Glass Furnace monitoring\nenableHoneycombMonitoring = true --export: enable or disable the Honeycomb Refineries monitoring\nenableRecyclerMonitoring = true --export: enable or disable the Recyclers monitoring\nenableMetalworkMonitoring = true --export: enable or disable the Metalworks monitoring\nenable3DPrinterMonitoring = true --export: enable or disable the 3D Printers monitoring\nenableTransferMonitoring = true --export: enable or disable the transfer units monitoring\nenableRemoteControl = true --export: enable the HUD to control machines (start/stop/batch/maintain)\nelementsByPage = 20 --export: maximum amount of elements displayed on a single page\ndateFormat = \"en\" --export: the country code to format the date\nmaxAmountOfElementsLoadedByFrame = 1000 --export: if cpu load errors at start, lower that value\n\n--[[\n\tDO NOT CHANGE THE FOLLOWING\n]]\n\n--Utility functions By jericho, see full source at https://github.com/Jericho1060/DualUniverse\nfunction removeDuplicatesInTable(a)local b={}local c={}for d,e in ipairs(a)do if not b[e]then c[#c+1]=e;b[e]=true end end;return c end;function strSplit(a,b)result={}for c in(a..b):gmatch(\"(.-)\"..b)do table.insert(result,c)end;return result end;function SecondsToClockString(a)local a=tonumber(a)if a==nil or a<=0 then return\"-\"else days=string.format(\"%2.f\",math.floor(a/(3600*24)))hours=string.format(\"%2.f\",math.floor(a/3600-days*24))mins=string.format(\"%2.f\",math.floor(a/60-hours*60-days*24*60))secs=string.format(\"%2.f\",math.floor(a-hours*3600-days*24*60*60-mins*60))str=\"\"if tonumber(days)>0 then str=str..days..\"d \"end;if tonumber(hours)>0 then str=str..hours..\"h \"end;if tonumber(mins)>0 then str=str..mins..\"m \"end;if tonumber(secs)>0 then str=str..secs..\"s\"end;return str end end;function removeQualityInName(a)if not a then return''end;return a:lower():gsub('basic ',''):gsub('uncommon ',''):gsub('advanced ',''):gsub('rare ',''):gsub('exotic ','')end;function has_value(a,b)for c,d in ipairs(a)do if d==b then return true end end;return false end\n\n--time script to get client date and time by Jericho, see full source at https://github.com/Jericho1060/DualUniverse\nfunction DUCurrentDateTime(a)local b=system.getUtcTime()if not a then b=b+system.getUtcOffset()end;local c=24*60*60;local d=365*c;local e=d+c;local f=4*d+c;local g=4;local h=1970;local i={-1,30,58,89,119,150,180,211,242,272,303,333,364}local j={}for k=1,2 do j[k]=i[k]end;for k=3,13 do j[k]=i[k]+1 end;local l,m,n,o,p,q,r,s;local t=i;s=b;l=math.floor(s/f)s=s-l*f;l=l*4+h;if s>=d then l=l+1;s=s-d;if s>=d then l=l+1;s=s-d;if s>=e then l=l+1;s=s-e else t=j end end end;m=math.floor(s/c)s=s-m*c;local n=1;while t[n]<m do n=n+1 end;n=n-1;local o=m-t[n]p=(math.floor(b/c)+g)%7;if p==0 then p=7 end;q=math.floor(s/3600)s=s-q*3600;r=math.floor(s/60)function round(u,v)if v then return utils.round(u/v)*v end;return u>=0 and math.floor(u+0.5)or math.ceil(u-0.5)end;s=round(s-r*60)local w={\"Monday\",\"Tuesday\",\"Wednesday\",\"Thursday\",\"Friday\",\"Saturday\",\"Sunday\"}local x={\"Mon\",\"Tue\",\"Wed\",\"Thu\",\"Fri\",\"Sat\",\"Sun\"}local y={\"January\",\"February\",\"March\",\"April\",\"May\",\"June\",\"July\",\"August\",\"September\",\"October\",\"November\",\"December\"}local z={\"Jan\",\"Feb\",\"Mar\",\"Apr\",\"May\",\"Jun\",\"Jul\",\"Aug\",\"Sep\",\"Oct\",\"Nov\",\"Dec\"}return l,n,o,q,r,s,p,w[p],x[p],y[n],z[n],m+1 end\n \n--databank hub library By Jericho, see full source at https://github.com/Jericho1060/DualUniverse\nbankhub={}function bankhub:new(banks)o={}setmetatable(o,self)self.__index=self;o.banks=banks or{}function o.clear()return o:_clear()end;function o.getNbKeys()return o:_getNbKeys()end;function o.getKeys()return o:_getKeys()end;function o.hasKey(a)return o:_hasKey(a)end;function o.getStringValue(a)return o:_getStringValue(a)end;function o.getIntValue(a)return o:_getIntValue(a)end;function o.getFloatValue(a)return o:_getFloatValue(a)end;return o end;function bankhub:add(b)table.insert(self.banks,b)self.banks_size=#self.banks end;function bankhub:_clear()for c,d in pairs(self.banks)do d.clear()end end;function bankhub:_getNbKeys()local e=0;for c,d in pairs(self.banks)do e=e+d.getNbKeys()end;return e end;function bankhub:_getKeys()local e={}for c,d in pairs(self.banks)do local f=json.decode(d.getKeys())for c,g in pairs(f)do table.insert(e,g)end end;return json.encode(e)end;function bankhub:_hasKey(a)for c,d in pairs(self.banks)do if d.hasKey(a)==1 then return 1 end end;return 0 end;function bankhub:_getStringValue(a)for c,d in pairs(self.banks)do if d.hasKey(a)==1 then return d.getStringValue(a)end end;return nil end;function bankhub:_getIntValue(a)for c,d in pairs(self.banks)do if d.hasKey(a)==1 then return banks.getIntValue(a)end end;return nil end;function bankhub:_getFloatValue(a)for c,d in pairs(self.banks)do if d.hasKey(a)==1 then return banks.getFloatValue(a)end end;return nil end\n\nchannels = {}\nchannels['refiner'] = channel_for_refiner\nchannels['assembly line'] = channel_for_assembly\nchannels['smelter'] = channel_for_smelter\nchannels['chemical industry'] = channel_for_chemical\nchannels['electronics industry'] = channel_for_electronics\nchannels['glass furnace'] = channel_for_glass\nchannels['honeycomb refinery'] = channel_for_honeycomb\nchannels['recycler'] = channel_for_recycler\nchannels['metalwork industry'] = channel_for_metalwork\nchannels['3d printer'] = channel_for_3d_printer\nchannels['transfer unit'] = channel_for_transfer\n\n--[[\n Detecting elements connected on slots\n]]\ndatabanks = {}\ncore = nil\nemitter = nil\nfor slot_name, slot in pairs(unit) do\n if\n type(slot) == \"table\"\n and type(slot.export) == \"table\"\n and slot.getClass\n then\n if slot.getClass():lower() == 'databankunit' then\n table.insert(databanks, slot)\n end\n if slot.getClass():lower():find(\"coreunit\") then\n core = slot\n end\n if slot.getClass():lower() == 'emitterunit' then\n emitter = slot\n end\n end\nend\nif core == nil then\n system.print(\"Connection to the core is missing\")\n unit.exit()\nend\nif emitter == nil then \n enableRemoteControl = false\n system.print(\"Connect an Emitter to enable machine control from industry\")\nend\nif #databanks == 0 then \n enableRemoteControl = false\n system.print(\"No Databank linked\")\nend\n\n--init of bank hub\nStorage = bankhub:new(databanks)\n\n--variable init and loading elements from the core\nelementsId = {}\nelements = {}\nelementsTypes = {}\nmachines_count = {}\nmachines_count.total = 0\ninitIndex = 1\nlistIndex = 1\ninit = false\nchannel_index = 1\nselected_index = 1\nselected_type = nil\nselected_machine_index = 1\nselected_machine = nil\nhud_displayed = true\npage = 1\nmaxPage = 1\nselectedElementsId = {}\nCtrl_pressed = false\ncraft_quantity = \"\"\ncraft_quantity_digits = {\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\"}\nrefresh_id_list = {}\ncraft_selected_digit = 1\ncommand_1 = \"\"\ncommand_2 = \"\"\ncommand_3 = \"\"\nrefreshActivated = true\nhud_help_command = \"\"\nunit.setTimer(\"helperRefresh\",1)\nminOnPage = 0\nmaxOnPage = 0\nelementsIdList = core.getElementIdList()\ntemp_selectedElementsId = {}\ntemp_elements_for_sorting = {}\ntemp_elements = {}\ntemp_refresh_id_list = {}\nmachineLoaded = false\nselected_machine = nil\n\n--init global HUD style\nhud_help_command = ''\nhud_elements_type_list = ''\nhud_machines = ''\nhud_machines_rows = {}\ncontrolHud = ''\n\n--construct pos for AR data\nconstructPos = construct.getWorldPosition()\nconstructRight = construct.getWorldRight()\nconstructForward = construct.getWorldForward()\nconstructUp = construct.getWorldUp()\narhtml = ''\n\n--Boostrap like css for DU by Jericho1060, see full source at https://github.com/Jericho1060/DualUniverse\nbootstrap_css_grid = [[<style>.container {width: 100%;padding-right: 15px;padding-left: 15px;margin-right: auto;margin-left: auto;}.row {position:relative;display: flex;flex-wrap: wrap;margin-right: -15px;margin-left: -15px;}.col-1, .col-2, .col-3, .col-4, .col-5, .col-6, .col-7, .col-8, .col-9, .col-10, .col-11, .col-12, .col {position: relative;width: 100%;padding-right: 15px;padding-left: 15px;}.col {flex-basis: 0;flex-grow: 1;max-width: 100%;}.col-auto {flex: 0 0 auto;width: auto;max-width: 100%;}.col-1 {flex: 0 0 8.333333%;max-width: 8.333333%;}.col-2 {flex: 0 0 16.666667%;max-width: 16.666667%;}.col-3 {flex: 0 0 25%;max-width: 25%;}.col-4 {flex: 0 0 33.333333%;max-width: 33.333333%;}.col-5 {flex: 0 0 41.666667%;max-width: 41.666667%;}.col-6 {flex: 0 0 50%;max-width: 50%;}.col-7 {flex: 0 0 58.333333%;max-width: 58.333333%;}.col-8 {flex: 0 0 66.666667%;max-width: 66.666667%;}.col-9 {flex: 0 0 75%;max-width: 75%;}.col-10 {flex: 0 0 83.333333%;max-width: 83.333333%;}.col-11 {flex: 0 0 91.666667%;max-width: 91.666667%;}.col-12 {flex: 0 0 100%;max-width: 100%;}.offset-12 {margin-left: 100%;}.offset-11 {margin-left: 91.66666667%;}.offset-10 {margin-left: 83.33333333%;}.offset-9 {margin-left: 75%;}.offset-8 {margin-left: 66.66666667%;}.offset-7 {margin-left: 58.33333333%;}.offset-6 {margin-left: 50%;}.offset-5 {margin-left: 41.66666667%;}.offset-4 {margin-left: 33.33333333%;}.offset-3 {margin-left: 25%;}.offset-2 {margin-left: 16.66666667%;}.offset-1 {margin-left: 8.33333333%;}.offset-0 {margin-left: 0%;}</style>]]\nbootstrap_css_colors = [[<style>.text-white {color: #fff !important;}.text-primary {color: #007bff !important;}.text-secondary {color: #6c757d !important;}.text-success {color: #28a745 !important;}.text-info {color: #17a2b8 !important;}.text-warning {color: #ffc107 !important;}.text-danger {color: #dc3545 !important;}.text-light {color: #f8f9fa !important;}.text-dark {color: #343a40 !important;}.text-body {color: #212529 !important;}.text-muted {color: #6c757d !important;}.text-black-50 {color: rgba(0, 0, 0, 0.5) !important;}.text-white-50 {color: rgba(255, 255, 255, 0.5) !important;}.bg-primary {background-color: #007bff !important;}.bg-secondary {background-color: #6c757d !important;}.bg-success {background-color: #28a745 !important;}.bg-info {background-color: #17a2b8 !important;}.bg-warning {background-color: #ffc107 !important;}.bg-danger {background-color: #dc3545 !important;}.bg-light {background-color: #f8f9fa !important;}.bg-dark {background-color: #343a40 !important;}.bg-white {background-color: #fff !important;}.bg-transparent {background-color: transparent !important;}</style>]]\nbootstrap_text_utils = [[<style>.text-left {text-align: left;}.text-right {text-align: right;}.text-center {text-align: center;}.text-justify {text-align: justify;}.text-nowrap {white-space: nowrap;}.text-lowercase {text-transform: lowercase;}.text-uppercase {text-transform: uppercase;}.text-capitalize {text-transform: capitalize;}</style>]]\nbootstrap_css = bootstrap_css_grid .. bootstrap_css_colors .. bootstrap_text_utils\n\nlocal statusList = {\"STOPPED\",\"RUNNING\",\"MISSING INGREDIENT\",\"OUTPUT FULL\",\"NO OUTPUT CONTAINER\",\"PENDING\",\"MISSING SCHEMATIC\",\"SERVER ERROR\"}\nfunction getIndustryStatusClass(status)\n if status == 1 then\n return \"text-info\"\n elseif status == 2 then\n return \"text-success\"\n elseif ((status >= 3) and (status <= 5)) or (status == 7) then\n return \"text-danger\"\n elseif status == 6 then\n return \"text-primary\"\n elseif status == 8 then\n return \"text-warning\"\n end\n return \"\" --default value for other status that can be added\nend\nfunction getIndustryStatusBgClass(status)\n if status then\n if status == 1 then\n return \"bg-info\"\n elseif status == 2 then\n return \"bg-success\"\n elseif ((status >= 3) and (status <= 5)) or (status == 7) then\n return \"bg-danger\"\n elseif status == 6 then\n return \"bg-primary\"\n end\n end\n return \"\" --default value for other status that can be added\nend\n--[[\n Convert a table in local coordinates to a table in world coordinates by Jericho inspired by Koruzarius\n Source : https://github.com/Jericho1060/DualUniverse/blob/master/Vectors/localToWorldPos.lua\n]]--\nfunction ConvertLocalToWorld(a,b,c,d,e)local f={a[1]*c[1],a[1]*c[2],a[1]*c[3]}local g={a[2]*d[1],a[2]*d[2],a[2]*d[3]}local h={a[3]*e[1],a[3]*e[2],a[3]*e[3]}return{f[1]+g[1]+h[1]+b[1],f[2]+g[2]+h[2]+b[2],f[3]+g[3]+h[3]+b[3]}end\n--[[\n Concept based on DU-Nested-Coroutines by Jericho\n Source available here: https://github.com/Jericho1060/du-nested-coroutines\n]]--\n\ncoroutinesTable = {}\nMyCoroutines = {\n function()\n --load all the machines from the core step by step to avoid CPU Load Errors\n if not init then\n local maxForLoop = initIndex + maxAmountOfElementsLoadedByFrame\n if maxForLoop > #elementsIdList then maxForLoop = #elementsIdList end\n system.print(\"Loading elements from \" .. initIndex .. \" to \" .. maxForLoop .. \" on \" .. #elementsIdList)\n \n for i = initIndex, maxForLoop, 1 do\n initIndex = i\n local id = elementsIdList[i]\n elementType = core.getElementDisplayNameById(id):lower()\n if (elementType:find(\"assembly line\") and enableAssemblyMonitoring == true) or\n (elementType:find(\"glass furnace\") and enableGlassMonitoring == true) or\n (elementType:find(\"3d printer\") and enable3DPrinterMonitoring == true) or\n (elementType:find(\"smelter\") and enableSmelterMonitoring == true) or\n (elementType:find(\"recycler\") and enableRecyclerMonitoring == true) or\n (elementType:find(\"refinery\") and enableHoneycombMonitoring == true) or\n (elementType:find(\"refiner\") and enableRefinerMonitoring == true) or\n (elementType:find(\"industry\")\n and (\n (elementType:find(\"chemical\") and enableChemicalMonitoring == true) or\n (elementType:find(\"electronics\") and enableElectronicsMonitoring == true) or\n (elementType:find(\"metalwork\") and enableMetalworkMonitoring == true)\n )\n ) or\n (elementType == \"transfer unit\" and enableTransferMonitoring == true)\n then\n \tlocal formatedType = removeQualityInName(elementType)\n \tif\n (elementType:lower():find(\"container\")\n and elementName:find(containerMonitoringPrefix:lower()))\n or (not elementType:lower():find(\"container\"))\n then\n table.insert(elementsTypes, formatedType)\n end\n if machines_count[formatedType] ~= nil then\n machines_count[formatedType] = machines_count[formatedType] + 1\n else\n machines_count[formatedType] = 1\n end\n table.insert(elementsId, id)\n end\n end\n if initIndex >= #elementsIdList then\n elementsTypes = removeDuplicatesInTable(elementsTypes)\n table.sort(elementsTypes, function(a,b) return a:lower() < b:lower() end)\n selected_type = elementsTypes[1]\n init = true\n system.print(\"All elements loaded\")\n end\n end\n end,\n function()\n local count = 0\n if init then\n if selected_type ~= nil and not machineLoaded then\n local count = machines_count[selected_type:lower()]\n local divider = math.ceil(count / 200)\n local maxForLoop = listIndex + math.ceil(maxAmountOfElementsLoadedByFrame / divider)\n if maxForLoop > #elementsId then maxForLoop = #elementsId end\n for i = listIndex, maxForLoop, 1 do\n listIndex = i\n local id = elementsId[i]\n elementType = core.getElementDisplayNameById(id)\n if selected_type:find(removeQualityInName(elementType)) then\n if\n (elementType:lower():find(\"container\")\n and core.getElementNameById(id):lower():find(containerMonitoringPrefix:lower()))\n or (not elementType:lower():find(\"container\"))\n then\n table.insert(temp_selectedElementsId, id)\n end\n end\n if #temp_selectedElementsId >= count then\n selectedElementsId = temp_selectedElementsId\n temp_selectedElementsId = {}\n maxPage = math.ceil(#selectedElementsId / elementsByPage)\n listIndex = 1\n machineLoaded = true\n if #selectedElementsId ~= count then\n machineLoaded = false\n end\n break\n end\n if listIndex >= #elementsId then\n listIndex = 1\n end\n end\n end\n end\n end,\n function()\n local year, month, day, hour, minute, second = DUCurrentDateTime()\n local dateStr = string.format(\"%02d/%02d/%04d %02d:%02d:%02d\",day,month,year,hour,minute,second)\n hud_help_command = [[<div class=\"hud_help_commands hud_container\">\n <table>\n <tr>\n <th colspan=\"2\">\n ]] .. dateStr .. [[\n </th>\n </tr>\n <tr>\n <td>Show/Hide HUD</td>\n <th style=\"text-align:right;\">Alt+7</th>\n </tr>\n </table>\n </div>]]\n coroutine.yield(coroutinesTable[3])\n end,\n function()\n if init then\n hud_elements_type_list = '<div class=\"hud_list_container hud_container\"><div style=\"text-align:center;border-bottom:1px solid white;\">&#x2191; &nbsp;&nbsp; Ctrl+Arrow Up</div>'\n for i, elementType in pairs(elementsTypes) do\n hud_elements_type_list = hud_elements_type_list .. '<div class=\"elementType'\n if i == selected_index then\n hud_elements_type_list = hud_elements_type_list .. \" selected\"\n end\n local count = 0\n if machines_count[elementType:lower()] ~= nil then count = machines_count[elementType:lower()] end\n hud_elements_type_list = hud_elements_type_list .. '\"><table style=\"width:100%;\"><tr><th style=\"text-align:left;border-bottom:none;\">'.. elementType .. '</th><td style=\"text-align:right;border-bottom:none;\">' .. tostring(count) .. '</td></tr></table></div>'\n end\n hud_elements_type_list = hud_elements_type_list .. '<div style=\"margin-top:10px;text-align:center;font-weight:bold;border-top:1px solid white;\">&#x2193; &nbsp;&nbsp; Ctrl+Arrow Down</div></div>'\n coroutine.yield(coroutinesTable[4])\n end\n end,\n function()\n for i, element in pairs(elements) do\n if #elements > 0 then\n local statusData = core.getElementIndustryInfoById(element.id)\n local schematicId = 0\n local recipeName = \"-\"\n if #statusData.currentProducts > 0 then\n local item = system.getItem(statusData.currentProducts[1].id)\n schematicId = item.schematics[1] or 0\n if item.locDisplayNameWithSize then\n recipeName = item.locDisplayNameWithSize\n end\n end\n local remainingTime = 0\n if (statusData) and (statusData.remainingTime) and (statusData.remainingTime <= (3600*24*365)) then\n remainingTime = statusData.remainingTime\n end\n element.recipeName = recipeName\n element.remainingTime = remainingTime\n element.status = statusData.state\n if remainingTime == 0 and statusData.state == 2 then\n element.status = 8\n end\n element.unitsProduced = statusData.unitsProduced\n local mode = \"\"\n element.maintainProductAmount = statusData.maintainProductAmount\n element.batchesRequested = statusData.batchesRequested\n if statusData.maintainProductAmount > 0 then\n \tmode = \"Maintain \" .. math.floor(statusData.maintainProductAmount)\n elseif statusData.batchesRequested > 0 and statusData.batchesRequested <= 99999999 then\n mode = \"Produce \" .. math.floor(statusData.batchesRequested)\n end\n local status = statusList[element.status] or '-'\n local status_class = getIndustryStatusClass(element.status)\n hud_machines_rows[i] = \"<tr\"\n if selected_machine_index == i then\n hud_machines_rows[i] = hud_machines_rows[i] .. ' class=\"selected\"'\n end\n local machine_id = \"-\"\n if element.id then machine_id = element.id end\n local unitsProduced = 0\n if element.unitsProduced then unitsProduced = element.unitsProduced end\n hud_machines_rows[i] = hud_machines_rows[i] .. '><th>' .. machine_id .. '</th><th><span class=\"' .. status_class .. '\">' .. element.name .. '</span><br><small>' .. element.type .. '</small></th><th>' .. recipeName\n if schematicId > 0 and element.type:lower() ~= 'transfer unit' then\n local schematic = system.getItem(schematicId)\n local schematicsRemaining = statusData.schematicsRemaining\n local schematic_color = \"#fff\"\n if schematicsRemaining == 0 then schematic_color = \"text-danger\" end\n hud_machines_rows[i] = hud_machines_rows[i] .. [[<br><small class=\"]] .. schematic_color .. [[\">]] .. schematicsRemaining .. [[ ]] .. schematic.locDisplayNameWithSize .. [[</small>]]\n end\n hud_machines_rows[i] = hud_machines_rows[i] .. '</th><td>' .. unitsProduced .. '</td><th class=\"' .. status_class .. '\">' .. status .. '</th><th>' .. mode .. '</th><td class=\"' .. status_class .. '\">' .. SecondsToClockString(element.remainingTime) .. '</td></tr>'\n else\n break\n end\n end\n end,\n function()\n hud_machines = [[<div class=\"hud_machines_container hud_container\">\n <div style=\"text-align:center;font-weight:bold;border-bottom:1px solid white;\">&#x2191; &nbsp;&nbsp; Arrow Up</div>\n <table class=\"elements_table\" style=\"width:100%\">\n <tr>\n <th>&#x2190; &nbsp;&nbsp; Arrow Left</th>\n <th> Page ]] .. page .. [[/]] .. maxPage .. [[ (from ]] .. minOnPage .. [[ to ]] .. maxOnPage .. [[ on ]] .. #selectedElementsId .. [[)</th>\n <th>Arrow Right &nbsp;&nbsp; &#x2192;</th>\n </tr>\n </table>\n <table class=\"elements_table\" style=\"width:100%;\">\n <tr>\n <th>id</th>\n <th>Machine Name & Type</th>\n <th>Selected Recipe & schematic</th>\n <th>Cycles From Start</th>\n <th>Status</th>\n <th>Mode</th>\n <th>Time Remaining</th>\n </tr>\n ]]\n for i, row in pairs(hud_machines_rows) do\n if row ~= nil then\n hud_machines = hud_machines .. row\n end\n end\n hud_machines = hud_machines .. '</table><table class=\"elements_table\" style=\"width:100%\"><tr><th>&#x2190; &nbsp;&nbsp; Arrow Left</th><th> Page ' .. page .. '/' .. maxPage .. ' (from ' .. minOnPage .. ' to ' .. maxOnPage .. ' on ' .. #selectedElementsId .. ')</th><th>Arrow Right &nbsp;&nbsp; &#x2192;</th></tr></table><div style=\"text-align:center;font-weight:bold;border-top:1px solid white;\">&#x2193; &nbsp;&nbsp; Arrow Down</div></div>'\n coroutine.yield(coroutinesTable[6])\n end,\n function()\n minOnPage = ((page - 1) * elementsByPage) + 1\n maxOnPage = page * elementsByPage\n if maxOnPage > #selectedElementsId then maxOnPage = #selectedElementsId end\n for i,id in pairs(selectedElementsId) do\n elementData = {}\n elementData.id = id\n elementData.name = core.getElementNameById(id)\n table.insert(temp_elements_for_sorting, elementData)\n end\n table.sort(temp_elements_for_sorting, function(a,b) return a.name:lower() < b.name:lower() end)\n for i = minOnPage, maxOnPage, 1 do\n if temp_elements_for_sorting[i] ~= nil then\n elementData = temp_elements_for_sorting[i]\n elementType = core.getElementDisplayNameById(elementData.id)\n elementData.type = elementType\n elementData.name = core.getElementNameById(elementData.id)\n elementData.position = core.getElementPositionById(elementData.id)\n table.insert(temp_refresh_id_list, elementData.id)\n table.insert(temp_elements, elementData)\n else\n temp_refresh_id_list = {}\n temp_elements_for_sorting = {}\n temp_elements = {}\n break\n end\n coroutine.yield(coroutinesTable[7])\n end\n refresh_id_list = temp_refresh_id_list\n temp_refresh_id_list = {}\n elements = temp_elements\n temp_elements_for_sorting = {}\n temp_elements = {}\n end,\n function()\n hud_main_css = [[\n <style>\n \t * {\n \t\t font-size: 1vh !important;\n \t\t font-familly: \"Play-Bold\";\n \t }\n .hud_container {\n border: 1px solid black;\n border-radius:10px;\n background-color: rgba(15,24,29,.75);\n padding:10px;\n }\n .hud_help_commands {\n position: absolute;\n top: ]] .. tostring((10/1080)*100) .. [[vh;\n left: ]] .. tostring((25/1920)*100) .. [[vw;\n text-transform: uppercase;\n font-weight: bold;\n }\n .hud_list_container {\n position: absolute;\n top: ]] .. tostring((100/1080)*100) .. [[vh;\n left: ]] .. tostring((25/1920)*100) .. [[vw;\n text-transform: uppercase;\n font-weight: bold;\n }\n .hud_machine_detail {\n position: absolute;\n top: ]] .. tostring((250/1080)*100) .. [[vh;\n right: ]] .. tostring((25/1920)*100) .. [[vw;\n text-transform: uppercase;\n font-weight: bold;\n }\n .hud_machines_container {\n position: absolute;\n top: ]] .. tostring((100/1080)*100) .. [[vh;\n left: ]] .. tostring((225/1920)*100) .. [[vw;\n }\n .elementType {\n margin-top:10px;\n border-radius:5px;\n }\n .elementType.selected {\n border: 2px solid green;\n background-color: rgba(0,200,0,.45);\n }\n tr.selected td, tr.selected th{\n border-top: 2px solid green;\n border-bottom: 2px solid green;\n background-color: rgba(0,200,0,.1);\n }\n td, th {\n border-bottom:1px solid white;\n padding:5px;\n text-align: center;\n }\n th {\n font-weight: bold;\n }\n .text-success{color:rgb(34,177,76);}\n .text-danger{color:rgb(177,42,42);}\n .text-warning{color:rgb(249,212,123);}\n .text-info{color:#17a2b8;}\n .text-primary{color:#007bff;}\n .text-orangered{color:orangered;}\n .bg-success{background-color:rgb(34,177,76) !important;}\n .bg-danger{background-color:rgb(177,42,42) !important;}\n .bg-warning{background-color:rgb(249,212,123) !important;}\n .bg-info{background-color:#17a2b8 !important;}\n .bg-primary{background-color:#007bff !important;}\n small{font-size:.5em;}\n </style>\n ]]\n if not init then \n hud_elements_type_list = [[\n <div class=\"hud_list_container hud_container\">\n \t<table style=\"width:100%\">\n \t\t<tr>\n \t\t\t<th>LOADING ]] .. math.floor(initIndex*100/#elementsIdList) .. [[% ...</th>\n \t\t</tr>\n \t</table>\n </div>\n ]]\n end\n if hud_displayed then\n system.setScreen(hud_main_css .. hud_help_command .. hud_elements_type_list .. hud_machines .. controlHud .. arhtml)\n else\n system.setScreen(hud_main_css .. hud_help_command .. arhtml)\n end\n end,\n function()\n selected_machine = elements[selected_machine_index]\n end,\n function()\n if selected_machine then\n if prevRecipe == nil then prevRecipe=''end\n if prevStatus == nil then prevStatus=1 end\n if prevName == nil then prevName='' end\n if selected_machine.status then prevStatus = selected_machine.status end\n if selected_machine.recipeName then prevRecipe = selected_machine.recipeName end\n if selected_machine.name then prevName = selected_machine.name end\n local screenpos = library.getPointOnScreen(ConvertLocalToWorld(selected_machine.position, constructPos, constructRight, constructForward, constructUp))\n if screenpos[1] > 1 then screenpos[1] = 1 elseif screenpos[1] < 0 then screenpos[1] = 0 end\n if screenpos[2] > .95 then screenpos[2] = .95 elseif screenpos[2] < 0 then screenpos[2] = 0 end\n arhtml = [[<div style=\"text-align:center;position:absolute;left:]] .. utils.round(screenpos[1]*100) .. [[%;top:]] .. utils.round(screenpos[2]*100) .. [[%;;margin-left:-500px;width:1000px;\"><div style=\"width:fit-content;padding:5px;margin:auto;border:2px solid black;border-radius:10px;background-color:rgba(15,24,29,.75);text-align:center;\" class=\"]] .. getIndustryStatusBgClass(prevStatus) .. [[\">]] .. prevName .. [[<br>]] .. prevRecipe .. [[<br><br><span style=\"font-weight:bold;\">]] .. statusList[prevStatus] .. [[</span></div></div>]]\n end\n end,\n function()\n if enableRemoteControl then\n if selected_machine then\n if prevRecipe == nil then prevRecipe=''end\n if prevStatus == nil then prevStatus=99 end\n if prevMaintainProductAmount == nil then prevMaintainProductAmount = 0 end\n if prevBatchesRequested == nil then prevBatchesRequested = 0 end\n if selected_machine.status then prevStatus = selected_machine.status end\n if selected_machine.recipeName then prevRecipe = selected_machine.recipeName end\n if selected_machine.maintainProductAmount then prevMaintainProductAmount = selected_machine.maintainProductAmount end\n if selected_machine.batchesRequested then prevBatchesRequested = selected_machine.batchesRequested end\n controlHud = [[<div class=\"hud_machine_detail hud_container\">\n <table>\n <tr>\n <th colspan=\"3\">]] .. selected_machine.name .. [[</th>\n </tr>\n <tr>\n <th class=\"]] .. getIndustryStatusClass(prevStatus) .. [[\" colspan=\"3\">]] .. statusList[prevStatus] .. [[</th>\n </tr>\n ]]\n if prevStatus == 1 then\n command_1 = \"START\"\n command_2 = \"BATCH\"\n command_3 = \"MAINTAIN\"\n controlHud = controlHud .. [[\n <tr>\n <th>START</th>\n <th></th>\n <th>ALT+1</th>\n </tr>\n <tr>\n <th style=\"height:65px;\">BATCH</th>\n <th rowspan=\"2\">\n <table>\n <tr>\n <th colspan=\"3\">Quantity:</th>\n </tr>\n <tr>\n <th style=\"font-size:20px;\">\n ]]\n local has_quantity = false\n for k,v in pairs(craft_quantity_digits) do\n if tonumber(v) == nil then v = 0 end\n if tonumber(v) > 0 then\n has_quantity = true\n end\n end\n if not has_quantity then\n local value = \"0\"\n if prevMaintainProductAmount > 0 then\n value = tostring(math.floor(prevMaintainProductAmount))\n elseif prevBatchesRequested > 0 and prevBatchesRequested <= 99999999 then\n value = tostring(math.floor(prevBatchesRequested))\n end\n for i = #value, 1, -1 do\n local c = value:sub(i,i)\n craft_quantity_digits[9-(#value-(i-1))] = c\n end\n end\n for digit_index,digit in pairs(craft_quantity_digits) do\n controlHud = controlHud .. digit\n end\n controlHud = controlHud .. [[\n </th>\n </tr>\n </table>\n </th>\n <th>ALT+2</th>\n </tr>\n <tr>\n <th>MAINTAIN</th>\n <th>ALT+3</th>\n </tr>\n ]]\n else\n command_1 = \"STOP\"\n command_2 = \"SOFT_STOP\"\n command_3 = \"\"\n controlHud = controlHud .. [[\n <tr>\n <th>STOP</th>\n <th>ALT+1</th>\n </tr>\n <tr>\n <th>FINISH AND STOP</th>\n <th>ALT+2</th>\n </tr>\n ]]\n end\n controlHud = controlHud .. '</table></div>'\n end\n end\n end\n}\n\nfunction initCoroutines()\n for _,f in pairs(MyCoroutines) do\n local co = coroutine.create(f)\n table.insert(coroutinesTable, co)\n end\nend\n\ninitCoroutines()\n\nrunCoroutines = function()\n for i,co in ipairs(coroutinesTable) do\n if coroutine.status(co) == \"dead\" then\n coroutinesTable[i] = coroutine.create(MyCoroutines[i])\n end\n if coroutine.status(co) == \"suspended\" then\n assert(coroutine.resume(co))\n end\n end\nend\n\nMainCoroutine = coroutine.create(runCoroutines)\n\nfunction reloadMachinesOnTypeChange()\n selected_type = elementsTypes[selected_index]\n selected_machine_index = 1\n page = 1\n Storage.clear()\n craft_quantity_digits = {\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\"}\n selectedElementsId = {}\n hud_machines_rows = {}\n elements = {}\n selectedElementsId = {}\n temp_selectedElementsId = {}\n temp_elements_for_sorting = {}\n temp_elements = {}\n temp_refresh_id_list = {}\n machineLoaded = false\nend\n\nfunction reloadMachinesOnPageChange()\n selected_machine_index = 1\n Storage.clear()\n hud_machines_rows = {}\n elements = {}\n temp_elements_for_sorting = {}\n temp_elements = {}\n temp_refresh_id_list = {}\nend\n\n--Enable Display of the HUD\nsystem.showScreen(1)","filter":{"args":[],"signature":"onStart()","slotKey":"-1"},"key":"1"}],"methods":[],"slots":{"0":{"name":"slot1","type":{"events":[],"methods":[]}},"1":{"name":"slot2","type":{"events":[],"methods":[]}},"2":{"name":"slot3","type":{"events":[],"methods":[]}},"3":{"name":"slot4","type":{"events":[],"methods":[]}},"4":{"name":"slot5","type":{"events":[],"methods":[]}},"5":{"name":"slot6","type":{"events":[],"methods":[]}},"6":{"name":"slot7","type":{"events":[],"methods":[]}},"7":{"name":"slot8","type":{"events":[],"methods":[]}},"8":{"name":"slot9","type":{"events":[],"methods":[]}},"9":{"name":"slot10","type":{"events":[],"methods":[]}},"-5":{"name":"library","type":{"events":[],"methods":[]}},"-4":{"name":"system","type":{"events":[],"methods":[]}},"-3":{"name":"player","type":{"events":[],"methods":[]}},"-2":{"name":"construct","type":{"events":[],"methods":[]}},"-1":{"name":"unit","type":{"events":[],"methods":[]}}}}
+7 -15
Master program/source/system/onActionStart_down.lua
··· 1 1 if Ctrl_pressed == true then 2 2 if selected_index < #elementsTypes then 3 3 selected_index = selected_index + 1 4 - selected_type = elementsTypes[selected_index] 5 - selected_machine_index = 1 6 - page = 1 7 - Storage.clear() 8 - craft_quantity_digits = {"0","0","0","0","0","0","0","0"} 9 - selectedElementsId = {} 10 - hud_machines_rows = {} 11 - elements = {} 12 - selectedElementsId = {} 13 - temp_selectedElementsId = {} 14 - temp_elements_for_sorting = {} 15 - temp_elements = {} 16 - temp_refresh_id_list = {} 17 - machineLoaded = false 4 + reloadMachinesOnTypeChange() 5 + else 6 + selected_index = 1 7 + reloadMachinesOnTypeChange() 18 8 end 19 9 else 20 10 if selected_machine_index < #elements then 21 11 selected_machine_index = selected_machine_index + 1 22 - craft_quantity_digits = {"0","0","0","0","0","0","0","0"} 12 + else 13 + selected_machine_index = 1 23 14 end 15 + craft_quantity_digits = {"0","0","0","0","0","0","0","0"} 24 16 end
+4 -7
Master program/source/system/onActionStart_strafeleft.lua
··· 1 1 if page > 1 then 2 2 page = page - 1 3 - selected_machine_index = 1 4 - Storage.clear() 5 - hud_machines_rows = {} 6 - elements = {} 7 - temp_elements_for_sorting = {} 8 - temp_elements = {} 9 - temp_refresh_id_list = {} 3 + reloadMachinesOnPageChange() 4 + elseif page ~= maxPage then 5 + page = maxPage 6 + reloadMachinesOnPageChange() 10 7 end
+4 -7
Master program/source/system/onActionStart_straferight.lua
··· 1 1 if page < maxPage then 2 2 page = page + 1 3 - selected_machine_index = 1 4 - Storage.clear() 5 - hud_machines_rows = {} 6 - elements = {} 7 - temp_elements_for_sorting = {} 8 - temp_elements = {} 9 - temp_refresh_id_list = {} 3 + reloadMachinesOnPageChange() 4 + elseif page ~= 1 then 5 + page = 1 6 + reloadMachinesOnPageChange() 10 7 end
+7 -15
Master program/source/system/onActionStart_up.lua
··· 1 1 if Ctrl_pressed == true then 2 2 if selected_index > 1 then 3 3 selected_index = selected_index - 1 4 - selected_type = elementsTypes[selected_index] 5 - selected_machine_index = 1 6 - page = 1 7 - Storage.clear() 8 - craft_quantity_digits = {"0","0","0","0","0","0","0","0"} 9 - selectedElementsId = {} 10 - hud_machines_rows = {} 11 - elements = {} 12 - selectedElementsId = {} 13 - temp_selectedElementsId = {} 14 - temp_elements_for_sorting = {} 15 - temp_elements = {} 16 - temp_refresh_id_list = {} 17 - machineLoaded = false 4 + reloadMachinesOnTypeChange() 5 + else 6 + selected_index = #elementsTypes 7 + reloadMachinesOnTypeChange() 18 8 end 19 9 else 20 10 if selected_machine_index > 1 then 21 11 selected_machine_index = selected_machine_index - 1 22 - craft_quantity_digits = {"0","0","0","0","0","0","0","0"} 12 + else 13 + selected_machine_index = #elements 23 14 end 15 + craft_quantity_digits = {"0","0","0","0","0","0","0","0"} 24 16 end
+29 -2
Master program/source/unit/onStart.lua
··· 2 2 DU Industry HUD By Jericho 3 3 ]] 4 4 5 - local version = "V 3.0.8 - alpha" 5 + local version = "V 3.0.9 - alpha" 6 6 local log_split = "=================================================" 7 7 --printing version in lua chat 8 8 system.print(log_split)local a=""local b=math.ceil((50-#version-2)/2)for c=1,b,1 do a=a..'='end;a=a.." "..version.." "for c=1,b,1 do a=a..'='end;system.print(a)system.print(log_split) ··· 374 374 local unitsProduced = 0 375 375 if element.unitsProduced then unitsProduced = element.unitsProduced end 376 376 hud_machines_rows[i] = hud_machines_rows[i] .. '><th>' .. machine_id .. '</th><th><span class="' .. status_class .. '">' .. element.name .. '</span><br><small>' .. element.type .. '</small></th><th>' .. recipeName 377 - if schematicId > 0 then 377 + if schematicId > 0 and element.type:lower() ~= 'transfer unit' then 378 378 local schematic = system.getItem(schematicId) 379 379 local schematicsRemaining = statusData.schematicsRemaining 380 380 local schematic_color = "#fff" ··· 674 674 end 675 675 676 676 MainCoroutine = coroutine.create(runCoroutines) 677 + 678 + function reloadMachinesOnTypeChange() 679 + selected_type = elementsTypes[selected_index] 680 + selected_machine_index = 1 681 + page = 1 682 + Storage.clear() 683 + craft_quantity_digits = {"0","0","0","0","0","0","0","0"} 684 + selectedElementsId = {} 685 + hud_machines_rows = {} 686 + elements = {} 687 + selectedElementsId = {} 688 + temp_selectedElementsId = {} 689 + temp_elements_for_sorting = {} 690 + temp_elements = {} 691 + temp_refresh_id_list = {} 692 + machineLoaded = false 693 + end 694 + 695 + function reloadMachinesOnPageChange() 696 + selected_machine_index = 1 697 + Storage.clear() 698 + hud_machines_rows = {} 699 + elements = {} 700 + temp_elements_for_sorting = {} 701 + temp_elements = {} 702 + temp_refresh_id_list = {} 703 + end 677 704 678 705 --Enable Display of the HUD 679 706 system.showScreen(1)