···11---[[
22- Databank HUB
33- Inspired by the original BankRaid Script written by ilodev
44- Modified to act like a databank hub by Jericho (read and clear only)
55-]]
66-bankhub = {}
77-88-function bankhub:new(banks)
99- o = {}
1010- setmetatable(o, self);
1111- self.__index = self;
1212- o.banks = banks or {}
1313-1414- -- databank shortcuts to allow in-game syntax.
1515- function o.clear() return o:_clear() end
1616- function o.getNbKeys() return o:_getNbKeys() end
1717- function o.getKeys() return o:_getKeys() end
1818- function o.hasKey(key) return o:_hasKey(key) end
1919- function o.getStringValue(key) return o:_getStringValue(key) end
2020- function o.getIntValue(key) return o:_getIntValue(key) end
2121- function o.getFloatValue(key) return o:_getFloatValue(key) end
2222-2323- return o
2424-end
2525---- Adds another databank to the raid.
2626---- @param object The databank unit to add.
2727-function bankhub:add(element)
2828- table.insert( self.banks, element)
2929- self.banks_size = #self.banks
3030-end
3131---- Clears the databank array
3232-function bankhub:_clear()
3333- for _,bank in pairs(self.banks) do bank.clear() end
3434-end
3535---- Returns the number of keys in the entire databank table
3636---- @return integer number of total keys
3737-function bankhub:_getNbKeys()
3838- local res = 0
3939- for _,bank in pairs(self.banks) do res = res + bank.getNbKeys() end
4040- return res
4141-end
4242-4343---- Returns all the keys in the databank array
4444---- @return string json encoded string of keys
4545-function bankhub:_getKeys()
4646- local res = {}
4747- for _,bank in pairs(self.banks) do
4848- local keys = json.decode(bank.getKeys())
4949- for _,k in pairs(keys) do table.insert(res, k) end
5050- end
5151- return json.encode(res)
5252-end
5353-5454---- Checks if a key exists in the databank array
5555---- @param string key
5656---- @return boolean returns 1 if the array holds this key.
5757-function bankhub:_hasKey(key)
5858- for _,bank in pairs(self.banks) do
5959- if (bank.hasKey(key) == 1) then return 1 end
6060- end
6161- return 0
6262-end
6363-6464---- Returns the value of the key if existing
6565---- @param string key
6666---- @return string returns value or nil
6767-function bankhub:_getStringValue(key)
6868- for _,bank in pairs(self.banks) do
6969- if (bank.hasKey(key) == 1) then
7070- return bank.getStringValue(key)
7171- end
7272- end
7373- return nil
7474-end
7575-7676---- Returns the integer value of the key if existing
7777---- @param string key
7878---- @return number returns value or nil
7979-function bankhub:_getIntValue(key)
8080- for _,bank in pairs(self.banks) do
8181- if (bank.hasKey(key) == 1) then
8282- return banks.getIntValue(key)
8383- end
8484- end
8585- return nil
8686-end
8787-8888---- Returns the float value of the key if existing
8989---- @param string key
9090---- @return number returns value or nil
9191-function bankhub:_getFloatValue(key)
9292- for _,bank in pairs(self.banks) do
9393- if (bank.hasKey(key) == 1) then
9494- return banks.getFloatValue(key)
9595- end
9696- end
9797- return nil
9898-end
-71
Master program/source/library/onStart_2.lua
···11---[[
22- Remove duplicate elements in a lua table
33- By Jericho
44-]]
55-function removeDuplicatesInTable(data)
66- local hash = {}
77- local res = {}
88- for _,v in ipairs(data) do
99- if (not hash[v]) then
1010- res[#res+1] = v
1111- hash[v] = true
1212- end
1313- end
1414- return res
1515-end
1616-1717---[[
1818- split a string on a delimiter
1919- By jericho
2020-]]
2121-function strSplit(s, delimiter)
2222- result = {};
2323- for match in (s..delimiter):gmatch("(.-)"..delimiter) do
2424- table.insert(result, match);
2525- end
2626- return result;
2727-end
2828-2929---[[
3030- Convert timestamp in a string representing a dureation in days, hours, minutes and seconds
3131- By Jericho
3232-]]
3333-function SecondsToClockString(seconds)
3434- local seconds = tonumber(seconds)
3535-3636- if seconds == nil or seconds <= 0 then
3737- return "-";
3838- else
3939- days = string.format("%2.f", math.floor(seconds/(3600*24)));
4040- hours = string.format("%2.f", math.floor(seconds/3600 - (days*24)));
4141- mins = string.format("%2.f", math.floor(seconds/60 - (hours*60) - (days*24*60)));
4242- secs = string.format("%2.f", math.floor(seconds - hours*3600 - (days*24*60*60) - mins *60));
4343- str = ""
4444- if tonumber(days) > 0 then str = str .. days.."d " end
4545- if tonumber(hours) > 0 then str = str .. hours.."h " end
4646- if tonumber(mins) > 0 then str = str .. mins.."m " end
4747- if tonumber(secs) > 0 then str = str .. secs .."s" end
4848- return str
4949- end
5050-end
5151-5252---[[
5353- remove the quality if exist in a string
5454-]]
5555-function removeQualityInName(name)
5656- if not name then return '' end
5757- return name:lower():gsub('basic ', ''):gsub('uncommon ', ''):gsub('advanced ', ''):gsub('rare ', ''):gsub('exotic ', '')
5858-end
5959-6060---[[
6161- check if a value exist in a table
6262-]]
6363-function has_value (tab, val)
6464- for index, value in ipairs(tab) do
6565- if value == val then
6666- return true
6767- end
6868- end
6969-7070- return false
7171-end
-63
Master program/source/library/onStart_3.lua
···11---[[
22- Jericho's time script -- https://github.com/Jericho1060
33- Display IRL date and time in game
44- https://github.com/Jericho1060/DualUniverse/edit/master/TimeScript/TimeScript.lua
55-]]--
66-77-function DUCurrentDateTime(utc)
88- local t = system.getUtcTime()
99- if not utc then t = t + system.getUtcOffset() end
1010- local DSEC=24*60*60
1111- local YSEC=365*DSEC
1212- local LSEC=YSEC+DSEC
1313- local FSEC=4*YSEC+DSEC
1414- local BASE_DOW=4
1515- local BASE_YEAR=1970
1616- local _days={-1, 30, 58, 89, 119, 150, 180, 211, 242, 272, 303, 333, 364}
1717- local _lpdays={}
1818- for i=1,2 do _lpdays[i]=_days[i] end
1919- for i=3,13 do _lpdays[i]=_days[i]+1 end
2020- local y,j,m,d,w,h,n,s
2121- local mdays=_days
2222- s=t
2323- y=math.floor(s/FSEC)
2424- s=s-y*FSEC
2525- y=y*4+BASE_YEAR
2626- if s>=YSEC then
2727- y=y+1
2828- s=s-YSEC
2929- if s>=YSEC then
3030- y=y+1
3131- s=s-YSEC
3232- if s>=LSEC then
3333- y=y+1
3434- s=s-LSEC
3535- else
3636- mdays=_lpdays
3737- end
3838- end
3939- end
4040- j=math.floor(s/DSEC)
4141- s=s-j*DSEC
4242- local m=1
4343- while mdays[m]<j do m=m+1 end
4444- m=m-1
4545- local d=j-mdays[m]
4646- w=(math.floor(t/DSEC)+BASE_DOW)%7
4747- if w == 0 then w = 7 end
4848- h=math.floor(s/3600)
4949- s=s-h*3600
5050- n=math.floor(s/60)
5151- function round(a,b)if b then return utils.round(a/b)*b end;return a>=0 and math.floor(a+0.5)or math.ceil(a-0.5)end
5252- s=round(s-n*60)
5353- local weekDaysNames = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"}
5454- local weekDaysShortNames = {"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"}
5555- local monthNames = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}
5656- local monthShortNames = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}
5757- return y,m,d,h,n,s,w,weekDaysNames[w],weekDaysShortNames[w],monthNames[m],monthShortNames[m],j+1
5858-end
5959-6060---[[
6161- local year, month, day, hour, minute, second, weekDayIndex, weekDayName, weekDayShortName, monthName, monthShortName, daysFromYearStart = DUCurrentDateTime()
6262- system.print(string.format("%02d/%02d/%04d %02d:%02d:%02d",day,month,year,hour,minute,second))
6363-]]
···11if enableRemoteControl == true then
22- system.print("command 1")
32 --Send Command 1
43 local selected_machine = elements[selected_machine_index]
54 for _,db in pairs(databanks) do
66- --selected_machine.command = command_1
75 db.setStringValue(selected_machine.id, command_1)
86 end
97 if emitter ~= nil then
···119 else
1210 system.print("Emitter not Linked")
1311 end
1414-end1212+end
···11-local statusList = {"STOPPED","RUNNING","MISSING INGREDIENT","OUTPUT FULL","NO OUTPUT CONTAINER","PENDING","MISSING SCHEMATIC"}
22-function getIndustryStatusClass(status)
33- if status == 1 then
44- return "text-info"
55- elseif status == 2 then
66- return "text-success"
77- elseif ((status >= 3) and (status <= 5)) or (status == 7) then
88- return "text-danger"
99- elseif status == 6 then
1010- return "text-primary"
1111- end
1212- return "" --default value for other status that can be added
1313-end
1414-1515-hud_main_css = [[
1616- <style>
1717- * {
1818- font-size: ]] .. tostring(contentFontSize) .. [[px;
1919- }
2020- .hud_container {
2121- border: 2px solid orange;
2222- border-radius:10px;
2323- background-color: rgba(0,0,0,.75);
2424- padding:10px;
2525- }
2626- .hud_help_commands {
2727- position: absolute;
2828- top: ]] .. tostring((10/1080)*100) .. [[vh;
2929- left: ]] .. tostring((50/1920)*100) .. [[vw;
3030- text-transform: uppercase;
3131- font-weight: bold;
3232- }
3333- .hud_list_container {
3434- position: absolute;
3535- top: ]] .. tostring((125/1080)*100) .. [[vh;
3636- left: ]] .. tostring((50/1920)*100) .. [[vw;
3737- text-transform: uppercase;
3838- font-weight: bold;
3939- }
4040- .hud_machine_detail {
4141- position: absolute;
4242- top: ]] .. tostring((250/1080)*100) .. [[vh;
4343- right: ]] .. tostring((50/1920)*100) .. [[vw;
4444- text-transform: uppercase;
4545- font-weight: bold;
4646- }
4747- .hud_machines_container {
4848- position: absolute;
4949- top: ]] .. tostring((125/1080)*100) .. [[vh;
5050- left: ]] .. tostring((300/1920)*100) .. [[vw;
5151- }
5252- .elementType {
5353- margin-top:10px;
5454- border-radius:5px;
5555- }
5656- .elementType.selected {
5757- border: 2px solid green;
5858- background-color: rgba(0,200,0,.45);
5959- }
6060- tr.selected td, tr.selected th{
6161- border: 2px solid green;
6262- background-color: rgba(0,200,0,.1);
6363- }
6464- td, th {
6565- border-bottom:1px solid white;
6666- padding:5px;
6767- text-align: center;
6868- }
6969- th {
7070- font-weight: bold;
7171- }
7272- .text-success{color: #28a745;}
7373- .text-danger{color:#dc3545;}
7474- .text-warning{color:#ffc107;}
7575- .text-info{color:#17a2b8;}
7676- .text-primary{color:#007bff;}
7777- .text-orangered{color:orangered;}
7878- .bg-success{background-color: #28a745;}
7979- .bg-danger{background-color:#dc3545;}
8080- .bg-warning{background-color:#ffc107;}
8181- .bg-info{background-color:#17a2b8;}
8282- .bg-primary{background-color:#007bff;}
8383- </style>
8484-]]
8585-8686-if initIndex >= #elementsIdList then
8787- unit.stopTimer("init")
8888- --system.print(MyJson.stringify(allTypes))
8989- if not isTimerStarted then
9090- isTimerStarted = true
9191- unit.setTimer("buildLists",1)
9292- system.setScreen(hud_main_css .. hud_help_command .. [[
9393- <div class="hud_list_container hud_container">
9494- <table style="width:100%">
9595- <tr>
9696- <th>LOADING ]] .. math.floor(initIndex*100/#elementsIdList) .. [[% ...</th>
9797- </tr>
9898- </table>
9999- </div>
100100- ]])
101101- else
102102- hud_elements_type_list = ""
103103- hud_machines = ""
104104- hud_machine_detail = ""
11+--[[
22+ DU-Nested-Coroutines by Jericho
33+ Permit to easier avoid CPU Load Errors
44+ Source available here: https://github.com/Jericho1060/du-nested-coroutines
55+]]--
1056106106- minOnPage = ((page - 1) * elementsByPage) + 1
107107- maxOnPage = page * elementsByPage
108108-109109- elements = {}
110110- refresh_id_list = {}
111111- local temp_elements_for_sorting = {}
112112- for i,id in pairs(selectedElementsId) do
113113- elementData = {}
114114- elementData.id = id
115115- elementData.name = core.getElementNameById(id)
116116- table.insert(temp_elements_for_sorting, elementData)
117117- end
118118- table.sort(temp_elements_for_sorting, function(a,b) return a.name:lower() < b.name:lower() end)
119119- for i,elementData in pairs(temp_elements_for_sorting) do
120120- if i >= minOnPage and i <= maxOnPage then
121121- elementType = core.getElementDisplayNameById(elementData.id)
122122- elementData.type = elementType
123123- elementData.name = core.getElementNameById(elementData.id)
124124- elementData.position = core.getElementPositionById(elementData.id)
125125-126126- table.insert(refresh_id_list, elementData.id)
127127- table.insert(elements, elementData)
128128- end
129129- end
130130-131131- if hud_displayed == true then
132132- selected_type = elementsTypes[selected_index]
133133-134134- hud_elements_type_list = [[<div class="hud_list_container hud_container">
135135- <div style="text-align:center;font-weight:bold;border-bottom:1px solid white;">↑ Ctrl+Arrow Up</div>
136136- ]]
137137- for i, elementType in pairs(elementsTypes) do
138138- --system.print(elementType)
139139- hud_elements_type_list = hud_elements_type_list .. [[<div class="elementType]]
140140- if i == selected_index then
141141- hud_elements_type_list = hud_elements_type_list .. " selected"
142142- end
143143- local count = 0
144144- if machines_count[elementType:lower()] ~= nil then count = machines_count[elementType:lower()] end
145145- hud_elements_type_list = hud_elements_type_list .. [[">
146146- <table style="width:100%;">
147147- <tr>
148148- <th style="text-align:left;border-bottom:none;">]].. elementType .. [[</th>
149149- <td style="text-align:right;border-bottom:none;">]] .. tostring(count) .. [[</td>
150150- </tr>
151151- </table>
152152- </div>
153153- ]]
154154- end
155155- hud_elements_type_list = hud_elements_type_list .. [[<div style="margin-top:10px;text-align:center;font-weight:bold;border-top:1px solid white;">↓ Ctrl+Arrow Down</div></div>]]
156156- local minOnPage = ((page - 1) * elementsByPage) + 1
157157- if maxOnPage > #selectedElementsId then maxOnPage = #selectedElementsId end
158158- hud_machines = [[<div class="hud_machines_container hud_container">
159159- <div style="text-align:center;font-weight:bold;border-bottom:1px solid white;">↑ Arrow Up</div>
160160- <table class="elements_table" style="width:100%">
161161- <tr>
162162- <th>← Arrow Left</th>
163163- <th> Page ]] .. page .. [[/]] .. maxPage .. [[ (from ]] .. minOnPage .. [[ to ]] .. maxOnPage .. [[)</th>
164164- <th>Arrow Right →</th>
165165- </tr>
166166- </table>
167167- <table class="elements_table" style="width:100%;">]]
168168- if selected_index > 0 and #elementsTypes > 0 and elementsTypes[selected_index]:lower():find("container") then
169169- hud_machines = hud_machines .. [[
170170- <tr>
171171- <th>id</th>
172172- <th>Container Name</th>
173173- <th>Item Name</th>
174174- <th>Container Size</th>
175175- <th>Item Type</th>
176176- <th>Unit Mass</th>
177177- <th>Total Mass</th>
178178- <th>Amount of Items</th>
179179- ]]
180180- if not elementsTypes[selected_index]:lower():find("hub") then
181181- hud_machines = hud_machines .. [[
182182- <th>Container Fill</th>
183183- ]]
184184- end
185185- hud_machines = hud_machines .. [[</tr>
186186- ]]
187187- for i, element in pairs(elements) do
188188- local splittedName = strSplit(element.name, "_")
189189- local itemName = splittedName[2]
190190- if not itemName then itemName = "-" end
191191- local machine_id = "-"
192192- if element.id then machine_id = element.id end
193193- local container_size = "hub"
194194- local container_empty_mass = getIngredient("Container Hub").mass
195195- local container_volume = 0
196196- local contentQuantity = 0
197197- local ingredient = getIngredient(cleanName(itemName))
198198- if not element.type:lower():find("hub") then
199199- local containerMaxHP = core.getElementMaxHitPointsById(element.id)
200200- if containerMaxHP > 17000 then
201201- container_size = "L"
202202- container_empty_mass = getIngredient("Container L").mass
203203- container_volume = 128000 * (container_proficiency_lvl * 0.1) + 128000
204204- elseif containerMaxHP > 7900 then
205205- container_size = "M"
206206- container_empty_mass = getIngredient("Container M").mass
207207- container_volume = 64000 * (container_proficiency_lvl * 0.1) + 64000
208208- elseif containerMaxHP > 900 then
209209- container_size = "S"
210210- container_empty_mass = getIngredient("Container S").mass
211211- container_volume = 8000 * (container_proficiency_lvl * 0.1) + 8000
212212- else
213213- container_size = "XS"
214214- container_empty_mass = getIngredient("Container XS").mass
215215- container_volume = 1000 * (container_proficiency_lvl * 0.1) + 1000
216216- end
217217- end
218218- local totalMass = core.getElementMassById(element.id)
219219- local contentMassKg = totalMass - container_empty_mass
220220- local contentMass = contentMassKg
221221- local contentMassUnit = "Kg"
222222- if contentMass > 1000 then
223223- contentMass = contentMass/1000
224224- contentMassUnit = "T"
225225- end
226226- contentMass = utils.round(contentMass*100)/100
227227- contentQuantity = contentMassKg / ingredient.mass
228228- local contentPercent = 0
229229- if (not element.type:lower():find("hub")) --not a hub
230230- and (not ingredient.type:lower():find("error")) --not item not found
231231- then
232232- contentPercent = math.floor((ingredient.volume * contentQuantity)*100/container_volume)
233233- end
234234- hud_machines = hud_machines .. [[<tr]]
235235- if selected_machine_index == i then
236236- hud_machines = hud_machines .. [[ class="selected"]]
237237- end
238238- hud_machines = hud_machines .. [[>
239239- <th>]] .. machine_id .. [[</th>
240240- <th>]] .. itemName .. [[</th>
241241- <th>]] .. ingredient.name .. [[</th>
242242- <td>]] .. container_size .. [[</td>
243243- <td>]] .. ingredient.type .. [[</td>
244244- <td>]] .. ingredient.mass .. [[</td>
245245- <td>]] .. contentMass .. " " .. contentMassUnit .. [[</td>
246246- <td>]] .. utils.round(contentQuantity*100)/100 .. [[</td>
247247- ]]
248248- if not element.type:lower():find("hub") then
249249- local gauge_color_class = "bg-success"
250250- local text_color_class = ""
251251- if contentPercent < container_fill_red_level then
252252- gauge_color_class = "bg-danger"
253253- elseif contentPercent < container_fill_yellow_level then
254254- gauge_color_class = "bg-warning"
255255- text_color_class = "text-orangered"
256256- end
257257- if ingredient.type:lower():find("error") then
258258- hud_machines = hud_machines .. [[
259259- <th style="position:relative;width: ]] .. tostring((150/1920)*100) .. [[vw;">
260260- -
261261- </th>
262262- </tr>
263263- ]]
264264- else
265265- hud_machines = hud_machines .. [[
266266- <th style="position:relative;width: ]] .. tostring((150/1920)*100) .. [[vw;">
267267- <div class="]] .. gauge_color_class .. [[" style="width:]] .. contentPercent .. [[%;"> </div>
268268- <div class="]] .. text_color_class .. [[" style="position:absolute;width:100%;top:0;padding-top:5px;font-weight:bold;">
269269- ]] .. contentPercent .. [[%
270270- </div>
271271- </th>
272272- </tr>
273273- ]]
274274- end
275275- end
276276- end
277277- else
278278- hud_machines = hud_machines .. [[
279279- <tr>
280280- <th>id</th>
281281- <th>Machine Name</th>
282282- <th>Selected Recipe</th>
283283- <th>Cycles From Start</th>
284284- <th>Status</th>
285285- <th>Mode</th>
286286- <th>Time Remaining</th>
287287- </tr>
288288- ]]
289289- for i, element in pairs(elements) do
290290- local statusData = core.getElementIndustryInfoById(element.id)
291291- local recipeName = "-"
292292- if #statusData.currentProducts > 0 then
293293- local item = system.getItem(statusData.currentProducts[1].id)
294294- if item.locDisplayNameWithSize then
295295- recipeName = item.locDisplayNameWithSize
296296- end
297297- end
298298-299299- local remainingTime = 0
300300- if (statusData) and (statusData.remainingTime) and (statusData.remainingTime <= (3600*24*365)) then
301301- remainingTime = statusData.remainingTime
302302- end
303303- element.recipeName = recipeName
304304- element.remainingTime = remainingTime
305305- element.status = statusData.state
306306- element.unitsProduced = statusData.unitsProduced
307307- local mode = ""
308308- element.maintainProductAmount = statusData.maintainProductAmount
309309- element.batchesRequested = statusData.batchesRequested
310310- if statusData.maintainProductAmount > 0 then
311311- mode = "Maintain " .. math.floor(statusData.maintainProductAmount)
312312- elseif statusData.batchesRequested > 0 and statusData.batchesRequested <= 99999999 then
313313- mode = "Produce " .. math.floor(statusData.batchesRequested)
314314- end
315315- local status = statusList[element.status] or '-'
316316- local status_class = getIndustryStatusClass(element.status)
317317- hud_machines = hud_machines .. [[<tr]]
318318- if selected_machine_index == i then
319319- hud_machines = hud_machines .. [[ class="selected"]]
320320- end
321321- local machine_id = "-"
322322- if element.id then machine_id = element.id end
323323- local unitsProduced = 0
324324- if element.unitsProduced then unitsProduced = element.unitsProduced end
325325- hud_machines = hud_machines .. [[>
326326- <th>]] .. machine_id .. [[</th>
327327- <th class="]] .. status_class .. [[">]] .. element.name .. [[</th>
328328- <th>]] .. recipeName .. [[</th>
329329- <td>]] .. unitsProduced .. [[</td>
330330- <th class="]] .. status_class .. [[">]] .. status .. [[</th>
331331- <th>]] .. mode .. [[</th>
332332- <td class="]] .. status_class .. [[">]] .. SecondsToClockString(element.remainingTime) .. [[</td>
333333- </tr>
334334- ]]
335335- end
336336- end
337337- hud_machines = hud_machines .. [[</table>
338338- <table class="elements_table" style="width:100%">
339339- <tr>
340340- <th>← Arrow Left</th>
341341- <th> Page ]] .. page .. [[/]] .. maxPage .. [[ (from ]] .. minOnPage .. [[ to ]] .. maxOnPage .. [[)</th>
342342- <th>Arrow Right →</th>
343343- </tr>
344344- </table>
345345- <div style="text-align:center;font-weight:bold;border-top:1px solid white;">↓ Arrow Down</div>
346346- </div>]]
347347- if #elements > 0 then
348348- local selected_machine = elements[selected_machine_index]
349349- local position = vec3(selected_machine.position)
350350- local x = position.x
351351- local y = position.y
352352- local z = position.z
353353- local offset1 = 1
354354- local offset15 = 1.5
355355- local offset2 = 2
356356- local offset25 = 2.5
357357- local offsetFromCenter = 0
358358- if selected_machine.type:lower():find("container") then
359359- offset1 = 0
360360- offset15 = 0
361361- offset2 = 0
362362- offset25 = 0
363363- end
364364- if selected_machine.type:lower() == "container" then
365365- local containerMaxHP = core.getElementMaxHitPointsById(selected_machine.id)
366366- if containerMaxHP > 17000 then
367367- offsetFromCenter = 4
368368- elseif containerMaxHP > 7900 then
369369- offsetFromCenter = 2
370370- elseif containerMaxHP > 900 then
371371- offsetFromCenter = 1
372372- else
373373- offsetFromCenter = 0.5
374374- end
375375- end
376376- if #markers == 0 then
377377- table.insert(markers, core.spawnArrowSticker(x, y, z, "down"))
378378- table.insert(markers, core.spawnArrowSticker(x, y, z, "down"))
379379- core.rotateSticker(markers[2],0,0,90)
380380- table.insert(markers, core.spawnArrowSticker(x, y, z + offset15, "north"))
381381- table.insert(markers, core.spawnArrowSticker(x, y, z + offset15, "north"))
382382- core.rotateSticker(markers[4],90,90,0)
383383- table.insert(markers, core.spawnArrowSticker(x, y, z + offset15, "south"))
384384- table.insert(markers, core.spawnArrowSticker(x, y, z + offset15, "south"))
385385- core.rotateSticker(markers[6],90,-90,0)
386386- table.insert(markers, core.spawnArrowSticker(x, y, z + offset15, "east"))
387387- table.insert(markers, core.spawnArrowSticker(x, y, z + offset15, "east"))
388388- core.rotateSticker(markers[8],90,0,90)
389389- table.insert(markers, core.spawnArrowSticker(x, y, z + offset15, "west"))
390390- table.insert(markers, core.spawnArrowSticker(x, y, z + offset15, "west"))
391391- core.rotateSticker(markers[10],-90,0,90)
392392- else
393393- core.moveSticker(markers[1], x, y, z + offset25 + offsetFromCenter)
394394- core.moveSticker(markers[2], x, y, z + offset25 + offsetFromCenter)
395395- core.moveSticker(markers[3], x + offset1 + offsetFromCenter, y, z + offset15)
396396- core.moveSticker(markers[4], x + offset1 + offsetFromCenter, y, z + offset15)
397397- core.moveSticker(markers[5], x - offset1 - offsetFromCenter, y, z + offset15)
398398- core.moveSticker(markers[6], x - offset1 - offsetFromCenter, y, z + offset15)
399399- core.moveSticker(markers[7], x, y - offset2 - offsetFromCenter, z + offset15)
400400- core.moveSticker(markers[8], x, y - offset2 - offsetFromCenter, z + offset15)
401401- core.moveSticker(markers[9], x, y + offset2 + offsetFromCenter, z + offset15)
402402- core.moveSticker(markers[10], x, y + offset2 + offsetFromCenter, z + offset15)
403403- end
404404- if (not selected_machine.type:lower():find("container")) and (enableRemoteControl == true) then
405405- local machines_actions = {}
406406- local status = statusList[selected_machine.status] or '-'
407407- local status_class = getIndustryStatusClass(selected_machine.status)
408408- hud_machine_detail = [[<div class="hud_machine_detail hud_container">
409409- <table>
410410- <tr>
411411- <th colspan="3">]] .. selected_machine.name .. [[</th>
412412- </tr>
413413- <tr>
414414- <th class="]] .. status_class .. [[" colspan="3">]] .. status .. [[</th>
415415- </tr>
416416- ]]
417417- if status == "-" then
418418- command_1 = ""
419419- command_2 = ""
420420- command_3 = ""
421421- hud_machine_detail = hud_machine_detail .. [[
422422- <tr>
423423- <td>Machine Not Connected</td>
424424- </tr>
425425- ]]
426426- elseif status:lower():find("stopped") then
427427- command_1 = "START"
428428- command_2 = "BATCH"
429429- command_3 = "MAINTAIN"
430430- hud_machine_detail = hud_machine_detail .. [[
431431- <tr>
432432- <th>START</th>
433433- <th></th>
434434- <th>ALT+1</th>
435435- </tr>
436436- <tr>
437437- <th style="height:65px;">BATCH</th>
438438- <th rowspan="2">
439439- <table>
440440- <tr>
441441- <th colspan="3">Quantity:</th>
442442- </tr>
443443- <tr>
444444- <th style="font-size:20px;">
445445- ]]
446446- local has_quantity = false
447447- for k,v in pairs(craft_quantity_digits) do
448448- if tonumber(v) == nil then v = 0 end
449449- if tonumber(v) > 0 then
450450- has_quantity = true
451451- end
452452- end
453453- if not has_quantity then
454454- local value = "0"
455455- if selected_machine.maintainProductAmount > 0 then
456456- --mode = "Maintain " .. selected_machine.maintainProductAmount
457457- value = tostring(math.floor(selected_machine.maintainProductAmount))
458458- elseif selected_machine.batchesRequested > 0 and selected_machine.batchesRequested <= 99999999 then
459459- --mode = "Produce " .. selected_machine.batchesRequested
460460- value = tostring(math.floor(selected_machine.batchesRequested))
461461- end
462462- for i = #value, 1, -1 do
463463- local c = value:sub(i,i)
464464- craft_quantity_digits[9-(#value-(i-1))] = c
465465- end
466466- end
467467- for digit_index,digit in pairs(craft_quantity_digits) do
468468- hud_machine_detail = hud_machine_detail .. digit
469469- end
470470- hud_machine_detail = hud_machine_detail .. [[
471471- </th>
472472- </tr>
473473- </table>
474474- </th>
475475- <th>ALT+2</th>
476476- </tr>
477477- <tr>
478478- <th>MAINTAIN</th>
479479- <th>ALT+3</th>
480480- </tr>
481481- ]]
482482- else
483483- command_1 = "STOP"
484484- command_2 = "SOFT_STOP"
485485- command_3 = ""
486486- hud_machine_detail = hud_machine_detail .. [[
487487- <tr>
488488- <th>STOP</th>
489489- <th>ALT+1</th>
490490- </tr>
491491- <tr>
492492- <th>FINISH AND STOP</th>
493493- <th>ALT+2</th>
494494- </tr>
495495- ]]
496496-497497- end
498498- hud_machine_detail = hud_machine_detail .. [[</table></div>]]
499499- end
500500- end
501501- end
502502- system.setScreen(hud_main_css .. hud_help_command .. hud_elements_type_list .. hud_machines .. hud_machine_detail)
503503- end
504504-505505-else
506506- system.setScreen(hud_main_css .. hud_help_command .. [[
507507- <div class="hud_list_container hud_container">
508508- <table style="width:100%">
509509- <tr>
510510- <th>LOADING ]] .. math.floor(initIndex*100/#elementsIdList) .. [[% ...</th>
511511- </tr>
512512- </table>
513513- </div>
514514- ]])
515515-end77+if coroutine.status(MainCoroutine) == "dead" then
88+ MainCoroutine = coroutine.create(runCoroutines)
99+end
1010+if coroutine.status(MainCoroutine) == "suspended" then
1111+ assert(coroutine.resume(MainCoroutine))
1212+end
+570-32
Master program/source/unit/onStart.lua
···11--[[
22- receivers channels for each type of machine
22+ DU Industry HUD By Jericho
33]]
4455-local version = "V 2.3.3"
55+local version = "V 3.0.5 - alpha"
66+local log_split = "================================================="
77+--printing version in lua chat
88+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)
6977-system.print("==================================================")
88-local print_version_str = ""
99-local print_version_number = math.ceil((50-#version-2)/2)
1010-for i=1, print_version_number, 1 do print_version_str = print_version_str .. '=' end
1111-print_version_str = print_version_str .. " " .. version .. " "
1212-for i=1, print_version_number, 1 do print_version_str = print_version_str .. '=' end
1313-system.print(print_version_str)
1414-system.print("==================================================")
1515-1010+--[[
1111+ receivers channels for each type of machine
1212+]]
1613channel_for_refiner = "receiver_refiner" --export: receiver channel to send orders to refiners
1714channel_for_assembly = "receiver_assembly" --export: receiver channel to send orders to assembly lines
1815channel_for_smelter = "receiver_smelters" --export: receiver channel to send orders to smelters
···2522channel_for_3d_printer = "receiver_3dprinters" --export: receiver channel to send orders to 3d printers
2623channel_for_transfer = "receiver_transfert" --export: receiver channel to send orders to tranfer units
27242828-container_proficiency_lvl = 0 --: Talent level for Container Proficiency
2929-container_fill_red_level = 10 --: The percent fill below gauge will be red
3030-container_fill_yellow_level = 50 --t: The percent fill below gauge will be yellow
3131-2525+--[[
2626+ Lua parameters
2727+]]
3228enableRefinerMonitoring = true --export: enable or disable the Refiners monitoring
3329enableAssemblyMonitoring = true --export: enable or disable the Assembly lines monitoring
3430enableSmelterMonitoring = true --export: enable or disable the Smelters monitoring
···4036enableMetalworkMonitoring = true --export: enable or disable the Metalworks monitoring
4137enable3DPrinterMonitoring = true --export: enable or disable the 3D Printers monitoring
4238enableTransferMonitoring = true --export: enable or disable the transfer units monitoring
4343-enableContainerMonitoring = false --: enable or disable the containers and hubs monitoring
4439enableRemoteControl = true --export: enable the HUD to control machines (start/stop/batch/maintain)
4545-containerMonitoringPrefix = "MONIT_" --: the prefix used to enable container monitoring
4640elementsByPage = 20 --export: maximum amount of elements displayed on a single page
4741dateFormat = "en" --export: the country code to format the date
4848-maxAmountOfElementsLoadedBySecond = 2000 --export: if cpu load errors at start, lower that value
4949-maxAmountOfRecipeLoadedBySecond = 10 --export: if cpu load errors on page load, lower that value
5050-contentFontSize = 15 --export: size of the font of the content of all pannels in pixels
4242+maxAmountOfElementsLoadedByFrame = 1000 --export: if cpu load errors at start, lower that value
51435244--[[
5345 DO NOT CHANGE THE FOLLOWING
5446]]
55474848+--Utility functions By jericho, see full source at https://github.com/Jericho1060/DualUniverse
4949+function 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
5050+5151+--time script to get client date and time by Jericho, see full source at https://github.com/Jericho1060/DualUniverse
5252+function 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
5353+5454+--databank hub library By Jericho, see full source at https://github.com/Jericho1060/DualUniverse
5555+bankhub={}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
5656+5657channels = {}
5758channels['refiner'] = channel_for_refiner
5859channels['assembly line'] = channel_for_assembly
···6667channels['3d printer'] = channel_for_3d_printer
6768channels['transfer unit'] = channel_for_transfer
68697070+--[[
7171+ Detecting elements connected on slots
7272+]]
6973databanks = {}
7074core = nil
7175emitter = nil
···8690 end
8791 end
8892end
8989-9393+if core == nil then
9494+ system.print("Connection to the core is missing")
9595+ unit.exit()
9696+end
9097if emitter == nil then
9198 enableRemoteControl = false
9299 system.print("Connect an Emitter to enable machine control from industry")
···95102 enableRemoteControl = false
96103 system.print("No Databank linked")
97104end
105105+106106+--init of bank hub
98107Storage = bankhub:new(databanks)
99108109109+--variable init and loading elements from the core
100110elementsId = {}
101111elements = {}
102112elementsTypes = {}
···104114machines_count.total = 0
105115initIndex = 1
106116listIndex = 1
107107-elementsIdList = {}
108108-if core ~= nil and Storage then
109109- elementsIdList = core.getElementIdList()
110110- unit.setTimer("init",1)
111111-end
112112-113113-elementsTypes = removeDuplicatesInTable(elementsTypes)
114114-115115-system.showScreen(1)
117117+init = false
116118channel_index = 1
117119selected_index = 1
120120+selected_type = nil
118121selected_machine_index = 1
122122+selected_machine = nil
119123hud_displayed = true
120124page = 1
121125maxPage = 1
···128132command_1 = ""
129133command_2 = ""
130134command_3 = ""
131131-markers = {}
132135refreshActivated = true
133136hud_help_command = ""
134137unit.setTimer("helperRefresh",1)
135138minOnPage = 0
136136-maxOnPage = 0139139+maxOnPage = 0
140140+elementsIdList = core.getElementIdList()
141141+temp_selectedElementsId = {}
142142+temp_elements_for_sorting = {}
143143+temp_elements = {}
144144+temp_refresh_id_list = {}
145145+machineLoaded = false
146146+selected_machine = nil
147147+148148+--init global HUD style
149149+hud_help_command = ''
150150+hud_elements_type_list = ''
151151+hud_machines = ''
152152+hud_machines_rows = {}
153153+controlHud = ''
154154+155155+--construct pos for AR data
156156+constructPos = construct.getWorldPosition()
157157+constructRight = construct.getWorldRight()
158158+constructForward = construct.getWorldForward()
159159+constructUp = construct.getWorldUp()
160160+arhtml = ''
161161+162162+--Boostrap like css for DU by Jericho1060, see full source at https://github.com/Jericho1060/DualUniverse
163163+bootstrap_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>]]
164164+bootstrap_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>]]
165165+bootstrap_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>]]
166166+bootstrap_css = bootstrap_css_grid .. bootstrap_css_colors .. bootstrap_text_utils
167167+168168+local statusList = {"STOPPED","RUNNING","MISSING INGREDIENT","OUTPUT FULL","NO OUTPUT CONTAINER","PENDING","MISSING SCHEMATIC"}
169169+function getIndustryStatusClass(status)
170170+ if status == 1 then
171171+ return "text-info"
172172+ elseif status == 2 then
173173+ return "text-success"
174174+ elseif ((status >= 3) and (status <= 5)) or (status == 7) then
175175+ return "text-danger"
176176+ elseif status == 6 then
177177+ return "text-primary"
178178+ end
179179+ return "" --default value for other status that can be added
180180+end
181181+function getIndustryStatusBgClass(status)
182182+ if status then
183183+ if status == 1 then
184184+ return "bg-info"
185185+ elseif status == 2 then
186186+ return "bg-success"
187187+ elseif ((status >= 3) and (status <= 5)) or (status == 7) then
188188+ return "bg-danger"
189189+ elseif status == 6 then
190190+ return "bg-primary"
191191+ end
192192+ end
193193+ return "" --default value for other status that can be added
194194+end
195195+--[[
196196+ Convert a table in local coordinates to a table in world coordinates by Jericho inspired by Koruzarius
197197+ Source : https://github.com/Jericho1060/DualUniverse/blob/master/Vectors/localToWorldPos.lua
198198+]]--
199199+function 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
200200+--[[
201201+ Concept based on DU-Nested-Coroutines by Jericho
202202+ Source available here: https://github.com/Jericho1060/du-nested-coroutines
203203+]]--
204204+205205+coroutinesTable = {}
206206+MyCoroutines = {
207207+ function()
208208+ --load all the machines from the core step by step to avoid CPU Load Errors
209209+ if not init then
210210+ local maxForLoop = initIndex + maxAmountOfElementsLoadedByFrame
211211+ if maxForLoop > #elementsIdList then maxForLoop = #elementsIdList end
212212+ system.print("Loading elements from " .. initIndex .. " to " .. maxForLoop .. " on " .. #elementsIdList)
213213+214214+ for i = initIndex, maxForLoop, 1 do
215215+ initIndex = i
216216+ local id = elementsIdList[i]
217217+ elementType = core.getElementDisplayNameById(id):lower()
218218+ if (elementType:find("assembly line") and enableAssemblyMonitoring == true) or
219219+ (elementType:find("glass furnace") and enableGlassMonitoring == true) or
220220+ (elementType:find("3d printer") and enable3DPrinterMonitoring == true) or
221221+ (elementType:find("smelter") and enableSmelterMonitoring == true) or
222222+ (elementType:find("recycler") and enableRecyclerMonitoring == true) or
223223+ (elementType:find("refinery") and enableHoneycombMonitoring == true) or
224224+ (elementType:find("refiner") and enableRefinerMonitoring == true) or
225225+ (elementType:find("industry")
226226+ and (
227227+ (elementType:find("chemical") and enableChemicalMonitoring == true) or
228228+ (elementType:find("electronics") and enableElectronicsMonitoring == true) or
229229+ (elementType:find("metalwork") and enableMetalworkMonitoring == true)
230230+ )
231231+ ) or
232232+ (elementType == "transfer unit" and enableTransferMonitoring == true)
233233+ then
234234+ local formatedType = removeQualityInName(elementType)
235235+ if
236236+ (elementType:lower():find("container")
237237+ and elementName:find(containerMonitoringPrefix:lower()))
238238+ or (not elementType:lower():find("container"))
239239+ then
240240+ table.insert(elementsTypes, formatedType)
241241+ end
242242+ if machines_count[formatedType] ~= nil then
243243+ machines_count[formatedType] = machines_count[formatedType] + 1
244244+ else
245245+ machines_count[formatedType] = 1
246246+ end
247247+ table.insert(elementsId, id)
248248+ end
249249+ end
250250+ if initIndex >= #elementsIdList then
251251+ elementsTypes = removeDuplicatesInTable(elementsTypes)
252252+ table.sort(elementsTypes, function(a,b) return a:lower() < b:lower() end)
253253+ selected_type = elementsTypes[1]
254254+ init = true
255255+ system.print("All elements loaded")
256256+ end
257257+ end
258258+ end,
259259+ function()
260260+ local count = 0
261261+ if init then
262262+ if selected_type ~= nil and not machineLoaded then
263263+ local count = machines_count[selected_type:lower()]
264264+ local divider = math.ceil(count / 200)
265265+ local maxForLoop = listIndex + math.ceil(maxAmountOfElementsLoadedByFrame / divider)
266266+ if maxForLoop > #elementsId then maxForLoop = #elementsId end
267267+ for i = listIndex, maxForLoop, 1 do
268268+ listIndex = i
269269+ local id = elementsId[i]
270270+ elementType = core.getElementDisplayNameById(id)
271271+ if selected_type:find(removeQualityInName(elementType)) then
272272+ if
273273+ (elementType:lower():find("container")
274274+ and core.getElementNameById(id):lower():find(containerMonitoringPrefix:lower()))
275275+ or (not elementType:lower():find("container"))
276276+ then
277277+ table.insert(temp_selectedElementsId, id)
278278+ end
279279+ end
280280+ if #temp_selectedElementsId >= count then
281281+ selectedElementsId = temp_selectedElementsId
282282+ temp_selectedElementsId = {}
283283+ maxPage = math.ceil(#selectedElementsId / elementsByPage)
284284+ listIndex = 1
285285+ machineLoaded = true
286286+ if #selectedElementsId ~= count then
287287+ machineLoaded = false
288288+ end
289289+ break
290290+ end
291291+ if listIndex >= #elementsId then
292292+ listIndex = 1
293293+ end
294294+ end
295295+ end
296296+ end
297297+ end,
298298+ function()
299299+ local year, month, day, hour, minute, second = DUCurrentDateTime()
300300+ local dateStr = string.format("%02d/%02d/%04d %02d:%02d:%02d",day,month,year,hour,minute,second)
301301+ hud_help_command = [[<div class="hud_help_commands hud_container">
302302+ <table>
303303+ <tr>
304304+ <th colspan="2">
305305+ ]] .. dateStr .. [[
306306+ </th>
307307+ </tr>
308308+ <tr>
309309+ <td>Show/Hide HUD</td>
310310+ <th style="text-align:right;">Alt+7</th>
311311+ </tr>
312312+ </table>
313313+ </div>]]
314314+ coroutine.yield(coroutinesTable[3])
315315+ end,
316316+ function()
317317+ if init then
318318+ hud_elements_type_list = '<div class="hud_list_container hud_container"><div style="text-align:center;border-bottom:1px solid white;">↑ Ctrl+Arrow Up</div>'
319319+ for i, elementType in pairs(elementsTypes) do
320320+ hud_elements_type_list = hud_elements_type_list .. '<div class="elementType'
321321+ if i == selected_index then
322322+ hud_elements_type_list = hud_elements_type_list .. " selected"
323323+ end
324324+ local count = 0
325325+ if machines_count[elementType:lower()] ~= nil then count = machines_count[elementType:lower()] end
326326+ 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>'
327327+ end
328328+ hud_elements_type_list = hud_elements_type_list .. '<div style="margin-top:10px;text-align:center;font-weight:bold;border-top:1px solid white;">↓ Ctrl+Arrow Down</div></div>'
329329+ coroutine.yield(coroutinesTable[4])
330330+ end
331331+ end,
332332+ function()
333333+ for i, element in pairs(elements) do
334334+ if #elements > 0 then
335335+ local statusData = core.getElementIndustryInfoById(element.id)
336336+ local schematicId = statusData.schematicId or 0
337337+ local recipeName = "-"
338338+ if #statusData.currentProducts > 0 then
339339+ local item = system.getItem(statusData.currentProducts[1].id)
340340+ if schematicId == 0 then
341341+ schematicId = item.schematics[1] or 0
342342+ end
343343+ if item.locDisplayNameWithSize then
344344+ recipeName = item.locDisplayNameWithSize
345345+ end
346346+ end
347347+ local remainingTime = 0
348348+ if (statusData) and (statusData.remainingTime) and (statusData.remainingTime <= (3600*24*365)) then
349349+ remainingTime = statusData.remainingTime
350350+ end
351351+ element.recipeName = recipeName
352352+ element.remainingTime = remainingTime
353353+ element.status = statusData.state
354354+ element.unitsProduced = statusData.unitsProduced
355355+ local mode = ""
356356+ element.maintainProductAmount = statusData.maintainProductAmount
357357+ element.batchesRequested = statusData.batchesRequested
358358+ if statusData.maintainProductAmount > 0 then
359359+ mode = "Maintain " .. math.floor(statusData.maintainProductAmount)
360360+ elseif statusData.batchesRequested > 0 and statusData.batchesRequested <= 99999999 then
361361+ mode = "Produce " .. math.floor(statusData.batchesRequested)
362362+ end
363363+ local status = statusList[element.status] or '-'
364364+ local status_class = getIndustryStatusClass(element.status)
365365+ hud_machines_rows[i] = "<tr"
366366+ if selected_machine_index == i then
367367+ hud_machines_rows[i] = hud_machines_rows[i] .. ' class="selected"'
368368+ end
369369+ local machine_id = "-"
370370+ if element.id then machine_id = element.id end
371371+ local unitsProduced = 0
372372+ if element.unitsProduced then unitsProduced = element.unitsProduced end
373373+ 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
374374+ if schematicId > 0 then
375375+ local schematic = system.getItem(schematicId)
376376+ local schematicsRemaining = statusData.schematicsRemaining
377377+ local schematic_color = "#fff"
378378+ if schematicsRemaining == 0 then schematic_color = "text-danger" end
379379+ hud_machines_rows[i] = hud_machines_rows[i] .. [[<br><small class="]] .. schematic_color .. [[">]] .. schematicsRemaining .. [[ ]] .. schematic.locDisplayNameWithSize .. [[</small>]]
380380+ end
381381+ 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>'
382382+ else
383383+ break
384384+ end
385385+ coroutine.yield(coroutinesTable[5])
386386+ end
387387+ end,
388388+ function()
389389+ hud_machines = [[<div class="hud_machines_container hud_container">
390390+ <div style="text-align:center;font-weight:bold;border-bottom:1px solid white;">↑ Arrow Up</div>
391391+ <table class="elements_table" style="width:100%">
392392+ <tr>
393393+ <th>← Arrow Left</th>
394394+ <th> Page ]] .. page .. [[/]] .. maxPage .. [[ (from ]] .. minOnPage .. [[ to ]] .. maxOnPage .. [[ on ]] .. #selectedElementsId .. [[)</th>
395395+ <th>Arrow Right →</th>
396396+ </tr>
397397+ </table>
398398+ <table class="elements_table" style="width:100%;">
399399+ <tr>
400400+ <th>id</th>
401401+ <th>Machine Name & Type</th>
402402+ <th>Selected Recipe & schematic</th>
403403+ <th>Cycles From Start</th>
404404+ <th>Status</th>
405405+ <th>Mode</th>
406406+ <th>Time Remaining</th>
407407+ </tr>
408408+ ]]
409409+ for i, row in pairs(hud_machines_rows) do
410410+ if row ~= nil then
411411+ hud_machines = hud_machines .. row
412412+ end
413413+ end
414414+ hud_machines = hud_machines .. '</table><table class="elements_table" style="width:100%"><tr><th>← Arrow Left</th><th> Page ' .. page .. '/' .. maxPage .. ' (from ' .. minOnPage .. ' to ' .. maxOnPage .. ' on ' .. #selectedElementsId .. ')</th><th>Arrow Right →</th></tr></table><div style="text-align:center;font-weight:bold;border-top:1px solid white;">↓ Arrow Down</div></div>'
415415+ coroutine.yield(coroutinesTable[6])
416416+ end,
417417+ function()
418418+ minOnPage = ((page - 1) * elementsByPage) + 1
419419+ maxOnPage = page * elementsByPage
420420+ if maxOnPage > #selectedElementsId then maxOnPage = #selectedElementsId end
421421+ for i,id in pairs(selectedElementsId) do
422422+ elementData = {}
423423+ elementData.id = id
424424+ elementData.name = core.getElementNameById(id)
425425+ table.insert(temp_elements_for_sorting, elementData)
426426+ end
427427+ table.sort(temp_elements_for_sorting, function(a,b) return a.name:lower() < b.name:lower() end)
428428+ for i = minOnPage, maxOnPage, 1 do
429429+ if temp_elements_for_sorting[i] ~= nil then
430430+ elementData = temp_elements_for_sorting[i]
431431+ elementType = core.getElementDisplayNameById(elementData.id)
432432+ elementData.type = elementType
433433+ elementData.name = core.getElementNameById(elementData.id)
434434+ elementData.position = core.getElementPositionById(elementData.id)
435435+ table.insert(temp_refresh_id_list, elementData.id)
436436+ table.insert(temp_elements, elementData)
437437+ else
438438+ temp_refresh_id_list = {}
439439+ temp_elements_for_sorting = {}
440440+ temp_elements = {}
441441+ break
442442+ end
443443+ coroutine.yield(coroutinesTable[7])
444444+ end
445445+ refresh_id_list = temp_refresh_id_list
446446+ temp_refresh_id_list = {}
447447+ elements = temp_elements
448448+ temp_elements_for_sorting = {}
449449+ temp_elements = {}
450450+ end,
451451+ function()
452452+ hud_main_css = [[
453453+ <style>
454454+ * {
455455+ font-size: 1vh !important;
456456+ font-familly: "Play-Bold";
457457+ }
458458+ .hud_container {
459459+ border: 1px solid black;
460460+ border-radius:10px;
461461+ background-color: rgba(15,24,29,.75);
462462+ padding:10px;
463463+ }
464464+ .hud_help_commands {
465465+ position: absolute;
466466+ top: ]] .. tostring((10/1080)*100) .. [[vh;
467467+ left: ]] .. tostring((25/1920)*100) .. [[vw;
468468+ text-transform: uppercase;
469469+ font-weight: bold;
470470+ }
471471+ .hud_list_container {
472472+ position: absolute;
473473+ top: ]] .. tostring((100/1080)*100) .. [[vh;
474474+ left: ]] .. tostring((25/1920)*100) .. [[vw;
475475+ text-transform: uppercase;
476476+ font-weight: bold;
477477+ }
478478+ .hud_machine_detail {
479479+ position: absolute;
480480+ top: ]] .. tostring((250/1080)*100) .. [[vh;
481481+ right: ]] .. tostring((25/1920)*100) .. [[vw;
482482+ text-transform: uppercase;
483483+ font-weight: bold;
484484+ }
485485+ .hud_machines_container {
486486+ position: absolute;
487487+ top: ]] .. tostring((100/1080)*100) .. [[vh;
488488+ left: ]] .. tostring((225/1920)*100) .. [[vw;
489489+ }
490490+ .elementType {
491491+ margin-top:10px;
492492+ border-radius:5px;
493493+ }
494494+ .elementType.selected {
495495+ border: 2px solid green;
496496+ background-color: rgba(0,200,0,.45);
497497+ }
498498+ tr.selected td, tr.selected th{
499499+ border: 2px solid green;
500500+ background-color: rgba(0,200,0,.1);
501501+ }
502502+ td, th {
503503+ border-bottom:1px solid white;
504504+ padding:5px;
505505+ text-align: center;
506506+ }
507507+ th {
508508+ font-weight: bold;
509509+ }
510510+ .text-success{color:rgb(34,177,76);}
511511+ .text-danger{color:rgb(177,42,42);}
512512+ .text-warning{color:rgb(249,212,123);}
513513+ .text-info{color:#17a2b8;}
514514+ .text-primary{color:#007bff;}
515515+ .text-orangered{color:orangered;}
516516+ .bg-success{background-color:rgb(34,177,76) !important;}
517517+ .bg-danger{background-color:rgb(177,42,42) !important;}
518518+ .bg-warning{background-color:rgb(249,212,123) !important;}
519519+ .bg-info{background-color:#17a2b8 !important;}
520520+ .bg-primary{background-color:#007bff !important;}
521521+ small{font-size:.5em;}
522522+ </style>
523523+ ]]
524524+ if not init then
525525+ hud_elements_type_list = [[
526526+ <div class="hud_list_container hud_container">
527527+ <table style="width:100%">
528528+ <tr>
529529+ <th>LOADING ]] .. math.floor(initIndex*100/#elementsIdList) .. [[% ...</th>
530530+ </tr>
531531+ </table>
532532+ </div>
533533+ ]]
534534+ end
535535+ if hud_displayed then
536536+ system.setScreen(hud_main_css .. hud_help_command .. hud_elements_type_list .. hud_machines .. controlHud .. arhtml)
537537+ else
538538+ system.setScreen(hud_main_css .. hud_help_command .. arhtml)
539539+ end
540540+ end,
541541+ function()
542542+ selected_machine = elements[selected_machine_index]
543543+ end,
544544+ function()
545545+ if selected_machine then
546546+ if prevRecipe == nil then prevRecipe=''end
547547+ if prevStatus == nil then prevStatus=99 end
548548+ if selected_machine.status then prevStatus = selected_machine.status end
549549+ if selected_machine.recipeName then prevRecipe = selected_machine.recipeName end
550550+ local screenpos = library.getPointOnScreen(ConvertLocalToWorld(selected_machine.position, constructPos, constructRight, constructForward, constructUp))
551551+ if screenpos[1] > 1 then screenpos[1] = 1 elseif screenpos[1] < 0 then screenpos[1] = 0 end
552552+ if screenpos[2] > .95 then screenpos[2] = .95 elseif screenpos[2] < 0 then screenpos[2] = 0 end
553553+ 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) .. [[">]] .. selected_machine.name .. [[<br>]] .. (selected_machine.recipeName or prevRecipe) .. [[<br><br><span style="font-weight:bold;">]] .. statusList[prevStatus] .. [[</span></div></div>]]
554554+ end
555555+ end,
556556+ function()
557557+ if enableRemoteControl then
558558+ if selected_machine then
559559+ if prevRecipe == nil then prevRecipe=''end
560560+ if prevStatus == nil then prevStatus=99 end
561561+ if prevMaintainProductAmount == nil then prevMaintainProductAmount = 0 end
562562+ if prevBatchesRequested == nil then prevBatchesRequested = 0 end
563563+ if selected_machine.status then prevStatus = selected_machine.status end
564564+ if selected_machine.recipeName then prevRecipe = selected_machine.recipeName end
565565+ if selected_machine.maintainProductAmount then prevMaintainProductAmount = selected_machine.maintainProductAmount end
566566+ if selected_machine.batchesRequested then prevBatchesRequested = selected_machine.batchesRequested end
567567+ controlHud = [[<div class="hud_machine_detail hud_container">
568568+ <table>
569569+ <tr>
570570+ <th colspan="3">]] .. selected_machine.name .. [[</th>
571571+ </tr>
572572+ <tr>
573573+ <th class="]] .. getIndustryStatusClass(prevStatus) .. [[" colspan="3">]] .. statusList[prevStatus] .. [[</th>
574574+ </tr>
575575+ ]]
576576+ if prevStatus == 1 then
577577+ command_1 = "START"
578578+ command_2 = "BATCH"
579579+ command_3 = "MAINTAIN"
580580+ controlHud = controlHud .. [[
581581+ <tr>
582582+ <th>START</th>
583583+ <th></th>
584584+ <th>ALT+1</th>
585585+ </tr>
586586+ <tr>
587587+ <th style="height:65px;">BATCH</th>
588588+ <th rowspan="2">
589589+ <table>
590590+ <tr>
591591+ <th colspan="3">Quantity:</th>
592592+ </tr>
593593+ <tr>
594594+ <th style="font-size:20px;">
595595+ ]]
596596+ local has_quantity = false
597597+ for k,v in pairs(craft_quantity_digits) do
598598+ if tonumber(v) == nil then v = 0 end
599599+ if tonumber(v) > 0 then
600600+ has_quantity = true
601601+ end
602602+ end
603603+ if not has_quantity then
604604+ local value = "0"
605605+ if prevMaintainProductAmount > 0 then
606606+ value = tostring(math.floor(prevMaintainProductAmount))
607607+ elseif prevBatchesRequested > 0 and prevBatchesRequested <= 99999999 then
608608+ value = tostring(math.floor(prevBatchesRequested))
609609+ end
610610+ for i = #value, 1, -1 do
611611+ local c = value:sub(i,i)
612612+ craft_quantity_digits[9-(#value-(i-1))] = c
613613+ end
614614+ end
615615+ for digit_index,digit in pairs(craft_quantity_digits) do
616616+ controlHud = controlHud .. digit
617617+ end
618618+ controlHud = controlHud .. [[
619619+ </th>
620620+ </tr>
621621+ </table>
622622+ </th>
623623+ <th>ALT+2</th>
624624+ </tr>
625625+ <tr>
626626+ <th>MAINTAIN</th>
627627+ <th>ALT+3</th>
628628+ </tr>
629629+ ]]
630630+ else
631631+ command_1 = "STOP"
632632+ command_2 = "SOFT_STOP"
633633+ command_3 = ""
634634+ controlHud = controlHud .. [[
635635+ <tr>
636636+ <th>STOP</th>
637637+ <th>ALT+1</th>
638638+ </tr>
639639+ <tr>
640640+ <th>FINISH AND STOP</th>
641641+ <th>ALT+2</th>
642642+ </tr>
643643+ ]]
644644+ end
645645+ controlHud = controlHud .. '</table></div>'
646646+ end
647647+ end
648648+ end
649649+}
650650+651651+function initCoroutines()
652652+ for _,f in pairs(MyCoroutines) do
653653+ local co = coroutine.create(f)
654654+ table.insert(coroutinesTable, co)
655655+ end
656656+end
657657+658658+initCoroutines()
659659+660660+runCoroutines = function()
661661+ for i,co in ipairs(coroutinesTable) do
662662+ if coroutine.status(co) == "dead" then
663663+ coroutinesTable[i] = coroutine.create(MyCoroutines[i])
664664+ end
665665+ if coroutine.status(co) == "suspended" then
666666+ assert(coroutine.resume(co))
667667+ end
668668+ end
669669+end
670670+671671+MainCoroutine = coroutine.create(runCoroutines)
672672+673673+--Enable Display of the HUD
674674+system.showScreen(1)
-3
Master program/source/unit/onStop.lua
···11Storage.clear()
22-for _,m in pairs(markers) do
33- core.deleteSticker(m)
44-end
-30
Master program/source/unit/onTimer_buildLists.lua
···11-local maxForLoop = listIndex + maxAmountOfElementsLoadedBySecond
22-if maxForLoop > #elementsId then maxForLoop = #elementsId end
33-44-for i = listIndex, maxForLoop, 1 do
55- listIndex = i
66- local id = elementsId[i]
77- elementType = core.getElementDisplayNameById(id)
88- local elementName = core.getElementNameById(id):lower()
99- if
1010- (elementType:lower():find("container")
1111- and elementName:find(containerMonitoringPrefix:lower()))
1212- or (not elementType:lower():find("container"))
1313- then
1414- local formatedName = removeQualityInName(elementType)
1515- table.insert(elementsTypes, formatedName)
1616- end
1717- if selected_type == removeQualityInName(elementType) then
1818- if
1919- (elementType:lower():find("container") and elementName:find(containerMonitoringPrefix:lower()))
2020- or (not elementType:lower():find("container"))
2121- then
2222- table.insert(selectedElementsId, id)
2323- end
2424- end
2525-end
2626-elementsTypes = removeDuplicatesInTable(elementsTypes)
2727-selectedElementsId = removeDuplicatesInTable(selectedElementsId)
2828-table.sort(elementsTypes, function(a,b) return a:lower() < b:lower() end)
2929-maxPage = math.ceil(#selectedElementsId / elementsByPage)
3030-if listIndex >= #elementsId then listIndex = 1 end
···11---load all the machines from the core step by step to avoid CPU Load Errors
22-33-local maxForLoop = initIndex + maxAmountOfElementsLoadedBySecond
44-if maxForLoop > #elementsIdList then maxForLoop = #elementsIdList end
55-system.print("Loading elements from " .. initIndex .. " to " .. maxForLoop .. " on " .. #elementsIdList)
66-77-for i = initIndex, maxForLoop, 1 do
88- initIndex = i
99- local id = elementsIdList[i]
1010- elementType = core.getElementDisplayNameById(id):lower()
1111- if (elementType:find("assembly line") and enableAssemblyMonitoring == true) or
1212- (elementType:find("glass furnace") and enableGlassMonitoring == true) or
1313- (elementType:find("3d printer") and enable3DPrinterMonitoring == true) or
1414- (elementType:find("smelter") and enableSmelterMonitoring == true) or
1515- (elementType:find("recycler") and enableRecyclerMonitoring == true) or
1616- (elementType:find("refinery") and enableHoneycombMonitoring == true) or
1717- (elementType:find("refiner") and enableRefinerMonitoring == true) or
1818- (elementType:find("industry")
1919- and (
2020- (elementType:find("chemical") and enableChemicalMonitoring == true) or
2121- (elementType:find("electronics") and enableElectronicsMonitoring == true) or
2222- (elementType:find("metalwork") and enableMetalworkMonitoring == true)
2323- )
2424- ) or
2525- (elementType == "transfer unit" and enableTransferMonitoring == true) --[[or
2626- (elementType:find("container") and enableContainerMonitoring == true)
2727- ]]--
2828- then
2929- local formatedType = removeQualityInName(elementType)
3030- if machines_count[formatedType] ~= nil then
3131- machines_count[formatedType] = machines_count[formatedType] + 1
3232- else
3333- machines_count[formatedType] = 1
3434- end
3535- table.insert(elementsId, id)
3636- end
3737- end