···66bankhub = {}
7788function bankhub:new(banks)
99- o = {}
1010- setmetatable(o, self);
1111- self.__index = self;
1212- o.banks = banks or {}
99+ o = {}
1010+ setmetatable(o, self);
1111+ self.__index = self;
1212+ o.banks = banks or {}
13131414- -- 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
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
22222323- return o
2323+ return o
2424end
2525--- Adds another databank to the raid.
2626--- @param object The databank unit to add.
2727function bankhub:add(element)
2828- table.insert( self.banks, element)
2929- self.banks_size = #self.banks
2828+ table.insert( self.banks, element)
2929+ self.banks_size = #self.banks
3030end
3131--- Clears the databank array
3232function bankhub:_clear()
3333- for _,bank in pairs(self.banks) do bank.clear() end
3333+ for _,bank in pairs(self.banks) do bank.clear() end
3434end
3535--- Returns the number of keys in the entire databank table
3636--- @return integer number of total keys
3737function bankhub:_getNbKeys()
3838- local res = 0
3939- for _,bank in pairs(self.banks) do res = res + bank.getNbKeys() end
4040- return res
3838+ local res = 0
3939+ for _,bank in pairs(self.banks) do res = res + bank.getNbKeys() end
4040+ return res
4141end
42424343--- Returns all the keys in the databank array
···6565--- @param string key
6666--- @return string returns value or nil
6767function bankhub:_getStringValue(key)
6868- for _,bank in pairs(self.banks) do
6969- if (bank.hasKey(key) == 1) then
7070- return bank.getStringValue(key)
6868+ for _,bank in pairs(self.banks) do
6969+ if (bank.hasKey(key) == 1) then
7070+ return bank.getStringValue(key)
7171+ end
7172 end
7272- end
7373- return nil
7373+ return nil
7474end
75757676--- Returns the integer value of the key if existing
7777--- @param string key
7878--- @return number returns value or nil
7979function bankhub:_getIntValue(key)
8080- for _,bank in pairs(self.banks) do
8181- if (bank.hasKey(key) == 1) then
8282- return banks.getIntValue(key)
8080+ for _,bank in pairs(self.banks) do
8181+ if (bank.hasKey(key) == 1) then
8282+ return banks.getIntValue(key)
8383+ end
8384 end
8484- end
8585- return nil
8585+ return nil
8686end
87878888--- Returns the float value of the key if existing
8989--- @param string key
9090--- @return number returns value or nil
9191function bankhub:_getFloatValue(key)
9292- for _,bank in pairs(self.banks) do
9393- if (bank.hasKey(key) == 1) then
9494- return banks.getFloatValue(key)
9292+ for _,bank in pairs(self.banks) do
9393+ if (bank.hasKey(key) == 1) then
9494+ return banks.getFloatValue(key)
9595+ end
9596 end
9696- end
9797- return nil
9797+ return nil
9898end
+36-15
Master program/source/library/start_2.lua
···3131 By Jericho
3232]]
3333function SecondsToClockString(seconds)
3434- local seconds = tonumber(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
35693636- 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
7070+ return false
5071end
+8-17
Master program/source/library/start_3.lua
···11--[[
22- Industry Icons Library By Baby Dragon (Discord: [BOO] Baby Dragon#6186)
22+ Clock script from Leodr, modified and updated by Jericho
33+ original script: https://github.com/leodr99/DU-quick_n_dirty-scripts/blob/main/clock/clock.lua
34]]
44-Icons_Base_Url = "assets.prod.novaquark.com/"
55-Icons = {}
66-Icons['refiner'] = Icons_Base_Url .. "94277/0888fb10-596a-44bb-aabc-c560ae38c644.png"
77-Icons['assembly line'] = Icons_Base_Url .. "94277/6e4b89a5-967f-408d-b15a-d1d011362c99.png"
88-Icons['smelter'] = Icons_Base_Url .. "94277/8192839e-88e8-45f0-8871-6efa47721dba.png"
99-Icons['chemical industry'] = Icons_Base_Url .. "94277/9abda2cf-895e-4814-9641-05447d4487e0.png"
1010-Icons['electronics industry'] = Icons_Base_Url .. "30036/8b9b65c4-52d9-474a-bf96-b54484036374.png"
1111-Icons['glass furnace'] = Icons_Base_Url .. "94277/136a6ba3-dbc3-4aed-9095-a3185bb7415f.png"
1212-Icons['honeycomb refinery'] = Icons_Base_Url .. "66035/8daa2d79-7899-425d-82a7-b8296043dd71.png"
1313-Icons['recycler'] = Icons_Base_Url .. "94277/3a0e13ad-4c64-4b3b-9220-9e8784ca88a0.png"
1414-Icons['metalwork industry'] = Icons_Base_Url .. "30036/b560b54b-3cfc-4818-8b19-306d6ec5972d.png"
1515-Icons['3d printer'] = Icons_Base_Url .. "66035/f5a14aaf-4cda-4b20-8685-d74197922f5d.png"
1616-Icons['transfer unit'] = Icons_Base_Url .. "66035/3dce9941-26ab-41ca-90ee-b55975c35a50.png"
1717-Icons['container'] = Icons_Base_Url .. "30036/153c9b47-1065-4ff5-a32e-08fc970ba197.png"
1818-Icons['container L'] = Icons_Base_Url .. "30036/2d99f857-9095-4dc8-8034-48847111904f.png"
1919-Icons['container hub'] = Icons_Base_Url .. "66035/7edb7051-d34a-41da-a100-ba924edc8faf.png"55+--Globals
66+local outputTime = false --for debug
77+local summertime = false --export: summer time enabled
88+--
99+--//functions
1010+function epochTime()function rZ(a)if string.len(a)<=1 then return\"0\"..a else return a end end;function dPoint(b)if not(b==math.floor(b))then return true else return false end end;function lYear(year)if not dPoint(year/4)then if dPoint(year/100)then return true else if not dPoint(year/400)then return true else return false end end else return false end end;local c=5;local d=3600;local e=86400;local f=31536000;local g=31622400;local h=2419200;local i=2505600;local j=2592000;local k=2678400;local l={4,6,9,11}local m={1,3,5,7,8,10,12}local n=0;local o=1506816000;local p={\"Tur,\",\"Fri,\",\"Sat,\",\"Sun,\",\"Mon,\",\"Tue,\",\"Wed,\"}local q=system.getTime()if summertime==true then q=q+3600 end;now=math.floor(q+o)year=1970;secs=0;n=0;while secs+g<now or secs+f<now do if lYear(year+1)then if secs+g<now then secs=secs+g;year=year+1;n=n+366 end else if secs+f<now then secs=secs+f;year=year+1;n=n+365 end end end;secondsRemaining=now-secs;monthSecs=0;yearlYear=lYear(year)month=1;while monthSecs+h<secondsRemaining or monthSecs+j<secondsRemaining or monthSecs+k<secondsRemaining do if month==1 then if monthSecs+k<secondsRemaining then month=2;monthSecs=monthSecs+k;n=n+31 else break end end;if month==2 then if not yearlYear then if monthSecs+h<secondsRemaining then month=3;monthSecs=monthSecs+h;n=n+28 else break end else if monthSecs+i<secondsRemaining then month=3;monthSecs=monthSecs+i;n=n+29 else break end end end;if month==3 then if monthSecs+k<secondsRemaining then month=4;monthSecs=monthSecs+k;n=n+31 else break end end;if month==4 then if monthSecs+j<secondsRemaining then month=5;monthSecs=monthSecs+j;n=n+30 else break end end;if month==5 then if monthSecs+k<secondsRemaining then month=6;monthSecs=monthSecs+k;n=n+31 else break end end;if month==6 then if monthSecs+j<secondsRemaining then month=7;monthSecs=monthSecs+j;n=n+30 else break end end;if month==7 then if monthSecs+k<secondsRemaining then month=8;monthSecs=monthSecs+k;n=n+31 else break end end;if month==8 then if monthSecs+k<secondsRemaining then month=9;monthSecs=monthSecs+k;n=n+31 else break end end;if month==9 then if monthSecs+j<secondsRemaining then month=10;monthSecs=monthSecs+j;n=n+30 else break end end;if month==10 then if monthSecs+k<secondsRemaining then month=11;monthSecs=monthSecs+k;n=n+31 else break end end;if month==11 then if monthSecs+j<secondsRemaining then month=12;monthSecs=monthSecs+j;n=n+30 else break end end end;day=1;daySecs=0;daySecsRemaining=secondsRemaining-monthSecs;while daySecs+e<daySecsRemaining do day=day+1;daySecs=daySecs+e;n=n+1 end;hour=0;hourSecs=0;hourSecsRemaining=daySecsRemaining-daySecs;while hourSecs+d<hourSecsRemaining do hour=hour+1;hourSecs=hourSecs+d end;minute=0;minuteSecs=0;minuteSecsRemaining=hourSecsRemaining-hourSecs;while minuteSecs+60<minuteSecsRemaining do minute=minute+1;minuteSecs=minuteSecs+60 end;second=math.floor(now%60)year=rZ(year)month=rZ(month)day=rZ(day)hour=rZ(hour)minute=rZ(minute)second=rZ(second)remanderForDOW=n%7;DOW=p[remanderForDOW]if outputTime then str=\"Year: \"..year..\", Month: \"..month..\", Day: \"..day..\", Hour: \"..hour..\", Minute: \"..minute..\", Second: \"..second..\", Day of Week: \"..DOW;system.print(str)end;return year,month,day,hour,minute,second,DOW end
···11---[[
22- Custom JSON Parser and Encoder to use less CPU
33- Original script from : https://gist.github.com/tylerneylon/59f4bcf316be525b30ab
44- Modified for DualUniverse by jericho
55-]]
66-77-MyJson = {}
88-99-1010--- Internal functions.
1111-1212-local function kind_of(obj)
1313- if type(obj) ~= 'table' then return type(obj) end
1414- local i = 1
1515- for _ in pairs(obj) do
1616- if obj[i] ~= nil then i = i + 1 else return 'table' end
1717- end
1818- if i == 1 then return 'table' else return 'array' end
1919-end
2020-2121-local function escape_str(s)
2222- local in_char = {'\\', '"', '/', '\b', '\f', '\n', '\r', '\t'}
2323- local out_char = {'\\', '"', '/', 'b', 'f', 'n', 'r', 't'}
2424- for i, c in ipairs(in_char) do
2525- s = s:gsub(c, '\\' .. out_char[i])
2626- end
2727- return s
2828-end
2929-3030--- Returns pos, did_find; there are two cases:
3131--- 1. Delimiter found: pos = pos after leading space + delim; did_find = true.
3232--- 2. Delimiter not found: pos = pos after leading space; did_find = false.
3333--- This throws an error if err_if_missing is true and the delim is not found.
3434-local function skip_delim(str, pos, delim, err_if_missing)
3535- pos = pos + #str:match('^%s*', pos)
3636- if str:sub(pos, pos) ~= delim then
3737- if err_if_missing then
3838- error('Expected ' .. delim .. ' near position ' .. pos)
3939- end
4040- return pos, false
4141- end
4242- return pos + 1, true
4343-end
4444-4545--- Expects the given pos to be the first character after the opening quote.
4646--- Returns val, pos; the returned pos is after the closing quote character.
4747-local function parse_str_val(str, pos, val)
4848- val = val or ''
4949- local early_end_error = 'End of input found while parsing string.'
5050- if pos > #str then error(early_end_error) end
5151- local c = str:sub(pos, pos)
5252- if c == '"' then return val, pos + 1 end
5353- if c ~= '\\' then return parse_str_val(str, pos + 1, val .. c) end
5454- -- We must have a \ character.
5555- local esc_map = {b = '\b', f = '\f', n = '\n', r = '\r', t = '\t'}
5656- local nextc = str:sub(pos + 1, pos + 1)
5757- if not nextc then error(early_end_error) end
5858- return parse_str_val(str, pos + 2, val .. (esc_map[nextc] or nextc))
5959-end
6060-6161--- Returns val, pos; the returned pos is after the number's final character.
6262-local function parse_num_val(str, pos)
6363- local num_str = str:match('^-?%d+%.?%d*[eE]?[+-]?%d*', pos)
6464- local val = tonumber(num_str)
6565- if not val then error('Error parsing number at position ' .. pos .. '.') end
6666- return val, pos + #num_str
6767-end
6868-6969-7070--- Public values and functions.
7171-7272-function MyJson.stringify(obj, as_key)
7373- local s = {} -- We'll build the string as an array of strings to be concatenated.
7474- local kind = kind_of(obj) -- This is 'array' if it's an array or type(obj) otherwise.
7575- if kind == 'array' then
7676- if as_key then error('Can\'t encode array as key.') end
7777- s[#s + 1] = '['
7878- for i, val in ipairs(obj) do
7979- if i > 1 then s[#s + 1] = ', ' end
8080- s[#s + 1] = MyJson.stringify(val)
8181- end
8282- s[#s + 1] = ']'
8383- elseif kind == 'table' then
8484- if as_key then error('Can\'t encode table as key.') end
8585- s[#s + 1] = '{'
8686- for k, v in pairs(obj) do
8787- if #s > 1 then s[#s + 1] = ', ' end
8888- s[#s + 1] = MyJson.stringify(k, true)
8989- s[#s + 1] = ':'
9090- s[#s + 1] = MyJson.stringify(v)
9191- end
9292- s[#s + 1] = '}'
9393- elseif kind == 'string' then
9494- return '"' .. escape_str(obj) .. '"'
9595- elseif kind == 'number' then
9696- if as_key then return '"' .. tostring(obj) .. '"' end
9797- return tostring(obj)
9898- elseif kind == 'boolean' then
9999- return tostring(obj)
100100- elseif kind == 'nil' then
101101- return 'null'
102102- else
103103- error('Unjsonifiable type: ' .. kind .. '.')
104104- end
105105- return table.concat(s)
106106-end
107107-108108-MyJson.null = {} -- This is a one-off table to represent the null value.
109109-110110-function MyJson.parse(str, pos, end_delim)
111111- pos = pos or 1
112112- if pos > #str then error('Reached unexpected end of input.') end
113113- local pos = pos + #str:match('^%s*', pos) -- Skip whitespace.
114114- local first = str:sub(pos, pos)
115115- if first == '{' then -- Parse an object.
116116- local obj, key, delim_found = {}, true, true
117117- pos = pos + 1
118118- while true do
119119- key, pos = MyJson.parse(str, pos, '}')
120120- if key == nil then return obj, pos end
121121- if not delim_found then error('Comma missing between object items.') end
122122- pos = skip_delim(str, pos, ':', true) -- true -> error if missing.
123123- obj[key], pos = MyJson.parse(str, pos)
124124- pos, delim_found = skip_delim(str, pos, ',')
125125- end
126126- elseif first == '[' then -- Parse an array.
127127- local arr, val, delim_found = {}, true, true
128128- pos = pos + 1
129129- while true do
130130- val, pos = MyJson.parse(str, pos, ']')
131131- if val == nil then return arr, pos end
132132- if not delim_found then error('Comma missing between array items.') end
133133- arr[#arr + 1] = val
134134- pos, delim_found = skip_delim(str, pos, ',')
135135- end
136136- elseif first == '"' then -- Parse a string.
137137- return parse_str_val(str, pos + 1)
138138- elseif first == '-' or first:match('%d') then -- Parse a number.
139139- return parse_num_val(str, pos)
140140- elseif first == end_delim then -- End of an object or array.
141141- return nil, pos + 1
142142- else -- Parse true, false, or null.
143143- local literals = {['true'] = true, ['false'] = false, ['null'] = MyJson.null}
144144- for lit_str, lit_val in pairs(literals) do
145145- local lit_end = pos + #lit_str - 1
146146- if str:sub(pos, lit_end) == lit_str then return lit_val, lit_end + 1 end
147147- end
148148- local pos_info_str = 'position ' .. pos .. ': ' .. str:sub(pos, pos + 10)
149149- error('Invalid json syntax starting at ' .. pos_info_str)
150150- end
151151-end
···11---Send Command 2
22-local selected_machine = elements[selected_machine_index]
33-for _,db in pairs(databanks) do
44- if db.hasKey(selected_machine.id) == 1 then
11+if enableRemoteControl == true then
22+ --Send Command 12
33+ local selected_machine = elements[selected_machine_index]
44+ for _,db in pairs(databanks) do
55 if command_2:find("MAINTAIN") or command_2:find("BATCH") then
66 craft_quantity = ""
77 for _,digit in pairs(craft_quantity_digits) do
···99 end
1010 command_2 = command_2 .. "_" .. craft_quantity
1111 end
1212- selected_machine.command = command_2
1313- db.setStringValue(selected_machine.id, MyJson.stringify(selected_machine))
1212+ --selected_machine.command = command_2
1313+ db.setStringValue(selected_machine.id, command_2)
1414 if command_2:find("MAINTAIN") then command_2 = "MAINTAIN" end
1515 if command_2:find("BATCH") then command_2 = "BATCH" end
1616+ end
1717+ if emitter ~= nil then
1818+ emitter.send(channels[elementsTypes[selected_index]:lower()], "")
1919+ else
2020+ system.print("Emitter not Linked")
1621 end
1722end
···11---Send Command 3
22-local selected_machine = elements[selected_machine_index]
33-for _,db in pairs(databanks) do
44- if db.hasKey(selected_machine.id) == 1 then
11+if enableRemoteControl == true then
22+ --Send Command 3
33+ local selected_machine = elements[selected_machine_index]
44+ for _,db in pairs(databanks) do
55 if command_3:find("MAINTAIN") or command_3:find("BATCH") then
66 craft_quantity = ""
77 for _,digit in pairs(craft_quantity_digits) do
···99 end
1010 command_3 = command_3 .. "_" .. craft_quantity
1111 end
1212- selected_machine.command = command_3
1313- db.setStringValue(selected_machine.id, MyJson.stringify(selected_machine))
1212+ --selected_machine.command = command_3
1313+ db.setStringValue(selected_machine.id, command_3)
1414 if command_3:find("MAINTAIN") then command_3 = "MAINTAIN" end
1515 if command_3:find("BATCH") then command_3 = "BATCH" end
1616+ end
1717+ if emitter ~= nil then
1818+ emitter.send(channels[elementsTypes[selected_index]:lower()], "")
1919+ else
2020+ system.print("Emitter not Linked")
1621 end
1722end
···11+system.print(text)
22+if tonumber(text) then
33+ if #text > 8 then
44+ system.print("the value should not be higher than 99 999 999.")
55+ else
66+ for i = #text, 1, -1 do
77+ local c = text:sub(i,i)
88+ craft_quantity_digits[9-(#text-(i-1))] = c
99+ end
1010+ end
1111+else
1212+ system.print("You must type a Number")
1313+end
+87-55
Master program/source/system/update.lua
···68686969if initIndex >= #elementsIdList then
7070 unit.stopTimer("init")
7171+ --system.print(MyJson.stringify(allTypes))
7172 if not isTimerStarted then
7273 isTimerStarted = true
7374 unit.setTimer("buildLists",1)
···8586 hud_machines = ""
8687 hud_machine_detail = ""
87888989+ minOnPage = ((page - 1) * elementsByPage) + 1
9090+ maxOnPage = page * elementsByPage
9191+9292+ elements = {}
9393+ refresh_id_list = {}
9494+ local temp_elements_for_sorting = {}
9595+ for i,id in pairs(selectedElementsId) do
9696+ elementData = {}
9797+ elementData.id = id
9898+ elementData.name = core.getElementNameById(id)
9999+ table.insert(temp_elements_for_sorting, elementData)
100100+ end
101101+ table.sort(temp_elements_for_sorting, function(a,b) return a.name:lower() < b.name:lower() end)
102102+ for i,elementData in pairs(temp_elements_for_sorting) do
103103+ if i >= minOnPage and i <= maxOnPage then
104104+ elementType = core.getElementTypeById(elementData.id)
105105+ --if Storage.hasKey(elementData.id) == 1 then
106106+ -- elementData = MyJson.parse(Storage.getStringValue(elementData.id))
107107+ --end
108108+ elementData.type = elementType
109109+ elementData.name = core.getElementNameById(elementData.id)
110110+ elementData.position = core.getElementPositionById(elementData.id)
111111+ --elementData.status = core.getElementIndustryStatus(elementData.id)
112112+113113+ table.insert(refresh_id_list, elementData.id)
114114+ table.insert(elements, elementData)
115115+ end
116116+ end
117117+88118 if hud_displayed == true then
89119 selected_type = elementsTypes[selected_index]
9090- elements = {}
9191- refresh_id_list = {}
921209393- local minOnPage = ((page - 1) * elementsByPage) + 1
9494- local maxOnPage = page * elementsByPage
9595- local temp_elements_for_sorting = {}
9696- for i,id in pairs(selectedElementsId) do
9797- elementData = {}
9898- elementData.id = id
9999- elementData.name = core.getElementNameById(id)
100100- table.insert(temp_elements_for_sorting, elementData)
101101- end
102102- table.sort(temp_elements_for_sorting, function(a,b) return a.name:lower() < b.name:lower() end)
103103- for i,elementData in pairs(temp_elements_for_sorting) do
104104- if i >= minOnPage and i <= maxOnPage then
105105- elementType = core.getElementTypeById(elementData.id)
106106- if Storage.hasKey(elementData.id) == 1 then
107107- elementData = MyJson.parse(Storage.getStringValue(elementData.id))
108108- end
109109- elementData.type = elementType
110110- elementData.name = core.getElementNameById(elementData.id)
111111- elementData.position = core.getElementPositionById(elementData.id)
112112- table.insert(refresh_id_list, elementData.id)
113113- table.insert(elements, elementData)
114114- end
115115- end
116121 hud_elements_type_list = [[<div class="hud_list_container hud_container">
117122 <div style="text-align:center;font-weight:bold;border-bottom:1px solid white;">↑ Ctrl+Arrow Up</div>
118123 ]]
119124 for i, elementType in pairs(elementsTypes) do
125125+ --system.print(elementType)
120126 hud_elements_type_list = hud_elements_type_list .. [[<div class="elementType]]
121127 if i == selected_index then
122128 hud_elements_type_list = hud_elements_type_list .. " selected"
···126132 hud_elements_type_list = hud_elements_type_list .. [[">
127133 <table style="width:100%;">
128134 <tr>
129129- <!--<th style="border-bottom:none;">
130130- <img src="]] .. Icons[elementType:lower()] .. [[" style="width:20px;">
131131- </th>-->
132135 <th style="text-align:left;border-bottom:none;">]].. elementType .. [[</th>
133133- <td style="text-align:right;border-bottom:none;">]] .. count .. [[</td>
136136+ <td style="text-align:right;border-bottom:none;">]] .. tostring(count) .. [[</td>
134137 </tr>
135138 </table>
136139 </div>
···263266 <tr>
264267 <th>id</th>
265268 <th>Machine Name</th>
269269+ <th>Selected Recipe</th>
266270 <th>Cycles From Start</th>
267267- <th>Efficiency</th>
268271 <th>Status</th>
269269- <th>Uptime</th>
272272+ <th>Mode</th>
273273+ <th>Time Remaining</th>
270274 </tr>
271275 ]]
272276 for i, element in pairs(elements) do
277277+ local statusData = json.decode(core.getElementIndustryStatus(element.id))
278278+ local recipeName = "-"
279279+ if loadedRecipes[statusData.schematicId] then
280280+ recipeName = loadedRecipes[statusData.schematicId]
281281+ else
282282+ if has_value(recipeToLoad,statusData.schematicId) == false then
283283+ table.insert(recipeToLoad, statusData.schematicId)
284284+ end
285285+ end
286286+ local remainingTime = 0
287287+ if (statusData) and (statusData.remainingTime) and (statusData.remainingTime <= (3600*24*365)) then
288288+ remainingTime = statusData.remainingTime
289289+ end
290290+ element.recipeName = recipeName
291291+ element.remainingTime = remainingTime
292292+ element.status = statusData.state
293293+ element.unitsProduced = statusData.unitsProduced
294294+ local mode = ""
295295+ element.maintainProductAmount = statusData.maintainProductAmount
296296+ element.batchesRequested = statusData.batchesRequested
297297+ if statusData.maintainProductAmount > 0 then
298298+ mode = "Maintain " .. statusData.maintainProductAmount
299299+ elseif statusData.batchesRequested > 0 and statusData.batchesRequested <= 99999999 then
300300+ mode = "Produce " .. statusData.batchesRequested
301301+ end
273302 local status = "-"
274303 if element.status then status = element.status end
275304 local status_class = ""
···278307 if status:lower():find("jammed") then status_class = "text-danger" end
279308 if status:lower():find("pending") then status_class = "text-primary" end
280309 status = status:gsub("JAMMED_", ""):gsub("_", " ")
281281- local cyclesFromStart = "-"
282282- if element.cyclesFromStart then cyclesFromStart = element.cyclesFromStart end
283283- local efficiency = "-"
284284- if element.efficiency then efficiency = math.floor(element.efficiency*100) end
285285- local uptime = 0
286286- if element.uptime then uptime = math.floor(element.uptime) end
287310 hud_machines = hud_machines .. [[<tr]]
288311 if selected_machine_index == i then
289312 hud_machines = hud_machines .. [[ class="selected"]]
290313 end
291314 local machine_id = "-"
292315 if element.id then machine_id = element.id end
316316+ local unitsProduced = 0
317317+ if element.unitsProduced then unitsProduced = element.unitsProduced end
293318 hud_machines = hud_machines .. [[>
294319 <th>]] .. machine_id .. [[</th>
295320 <th class="]] .. status_class .. [[">]] .. element.name .. [[</th>
296296- <td>]] .. cyclesFromStart .. [[</td>
297297- <td>]] .. efficiency .. [[%</td>
321321+ <th>]] .. recipeName .. [[</th>
322322+ <td>]] .. unitsProduced .. [[</td>
298323 <th class="]] .. status_class .. [[">]] .. status .. [[</th>
299299- <td class="]] .. status_class .. [[">]] .. SecondsToClockString(uptime) .. [[</td>
324324+ <th>]] .. mode .. [[</th>
325325+ <td class="]] .. status_class .. [[">]] .. SecondsToClockString(element.remainingTime) .. [[</td>
300326 </tr>
301327 ]]
302328 end
···369395 core.moveSticker(markers[9], x, y + offset2 + offsetFromCenter, z + offset15)
370396 core.moveSticker(markers[10], x, y + offset2 + offsetFromCenter, z + offset15)
371397 end
372372- if not selected_machine.type:lower():find("container") then
398398+ if (not selected_machine.type:lower():find("container")) and (enableRemoteControl == true) then
373399 local status = "-"
374400 if selected_machine.status then status = selected_machine.status end
375401 local status_class = ""
···412438 <th rowspan="2">
413439 <table>
414440 <tr>
415415- <th colspan="3">↑ Alt+Arrow Up</th>
416416- </tr>
417417- <tr>
418441 <th colspan="3">Quantity:</th>
419442 </tr>
420443 <tr>
421421- <th>← Alt+<br>Arrow Left</th>
422444 <th style="font-size:20px;">
423445 ]]
424424- for digit_index,digit in pairs(craft_quantity_digits) do
425425- if digit_index == (#craft_quantity_digits - craft_selected_digit + 1) then
426426- hud_machine_detail = hud_machine_detail .. [[<span class="text-success">]]
446446+ local has_quantity = false
447447+ for k,v in pairs(craft_quantity_digits) do
448448+ if tonumber(v) > 0 then
449449+ has_quantity = true
427450 end
428428- hud_machine_detail = hud_machine_detail .. digit
429429- if digit_index == (#craft_quantity_digits - craft_selected_digit + 1) then
430430- hud_machine_detail = hud_machine_detail .. [[</span>]]
451451+ end
452452+ if not has_quantity then
453453+ local value = "0"
454454+ if selected_machine.maintainProductAmount > 0 then
455455+ --mode = "Maintain " .. selected_machine.maintainProductAmount
456456+ value = tostring(selected_machine.maintainProductAmount)
457457+ elseif selected_machine.batchesRequested > 0 and selected_machine.batchesRequested <= 99999999 then
458458+ --mode = "Produce " .. selected_machine.batchesRequested
459459+ value = tostring(selected_machine.batchesRequested)
431460 end
461461+ for i = #value, 1, -1 do
462462+ local c = value:sub(i,i)
463463+ craft_quantity_digits[9-(#value-(i-1))] = c
464464+ end
465465+ end
466466+ for digit_index,digit in pairs(craft_quantity_digits) do
467467+ hud_machine_detail = hud_machine_detail .. digit
432468 end
433469 hud_machine_detail = hud_machine_detail .. [[
434470 </th>
435435- <th>Alt+ →<br>Arrow Right</th>
436471 </tr>
437437- <tr>
438438- <th colspan="3" style="border-bottom:none;">↓ Alt+Arrow Down</th>
439439- </tr>
440472 </table>
441473 </th>
442474 <th>ALT+2</th>
+38-22
Master program/source/unit/start.lua
···22 receivers channels for each type of machine
33]]
4455-channel_for_refiner = "receiver_refiner" --export: receiver channel for updating refiners
66-channel_for_assembly = "receiver_assembly" --export: receiver channel for updating assembly lines
77-channel_for_smelter = "receiver_smelters" --export: receiver channel for updating smelters
88-channel_for_chemical = "receiver_chemical" --export: receiver channel for updating chemical indutries
99-channel_for_electronics = "receiver_electronics" --export: receiver channel for updating electronic industries
1010-channel_for_glass = "receiver_glass" --export: receiver channel for updating glass furnace
1111-channel_for_honeycomb = "receiver_honeycomb_recycler" --export: receiver channel for updating honeycomb refiniries
1212-channel_for_recycler = "receiver_honeycomb_recycler" --export: receiver channel for updating recylers
1313-channel_for_metalwork = "receiver_metalworks" --export: receiver channel for updating metalworks
1414-channel_for_3d_printer = "receiver_3dprinters" --export: receiver channel for updating 3d printers
1515-channel_for_transfer = "receiver_transfert" --export: receiver channel for updating tranfer units
1616-container_proficiency_lvl = 0 --export: Talent level for Container Proficiency
1717-container_fill_red_level = 10 --export: The percent fill below gauge will be red
1818-container_fill_yellow_level = 50 --export: The percent fill below gauge will be yellow
55+channel_for_refiner = "receiver_refiner" --export: receiver channel to send orders to refiners
66+channel_for_assembly = "receiver_assembly" --export: receiver channel to send orders to assembly lines
77+channel_for_smelter = "receiver_smelters" --export: receiver channel to send orders to smelters
88+channel_for_chemical = "receiver_chemical" --export: receiver channel to send orders to chemical indutries
99+channel_for_electronics = "receiver_electronics" --export: receiver channel to send orders to electronic industries
1010+channel_for_glass = "receiver_glass" --export: receiver channel to send orders to glass furnace
1111+channel_for_honeycomb = "receiver_honeycomb_recycler" --export: receiver channel to send orders to honeycomb refiniries
1212+channel_for_recycler = "receiver_honeycomb_recycler" --export: receiver channel to send orders to recylers
1313+channel_for_metalwork = "receiver_metalworks" --export: receiver channel to send orders to metalworks
1414+channel_for_3d_printer = "receiver_3dprinters" --export: receiver channel to send orders to 3d printers
1515+channel_for_transfer = "receiver_transfert" --export: receiver channel to send orders to tranfer units
1616+1717+container_proficiency_lvl = 0 ---export: Talent level for Container Proficiency
1818+container_fill_red_level = 10 ---export: The percent fill below gauge will be red
1919+container_fill_yellow_level = 50 ---export: The percent fill below gauge will be yellow
2020+1921enableRefinerMonitoring = true --export: enable or disable the Refiners monitoring
2022enableAssemblyMonitoring = true --export: enable or disable the Assembly lines monitoring
2123enableSmelterMonitoring = true --export: enable or disable the Smelters monitoring
···2729enableMetalworkMonitoring = true --export: enable or disable the Metalworks monitoring
2830enable3DPrinterMonitoring = true --export: enable or disable the 3D Printers monitoring
2931enableTransferMonitoring = true --export: enable or disable the transfer units monitoring
3030-enableContainerMonitoring = true --export: enable or disable the containers and hubs monitoring
3131-containerMonitoringPrefix = "MONIT_" --export: the prefix used to enable container monitoring
3232-refreshSpeed = 1 --export: the refresh speed of data in seconds
3232+enableContainerMonitoring = false ---export: enable or disable the containers and hubs monitoring
3333+enableRemoteControl = true --export: enable the HUD to control machines (start/stop/batch/maintain)
3434+containerMonitoringPrefix = "MONIT_" ---export: the prefix used to enable container monitoring
3335elementsByPage = 20 --export: maximum amount of elements displayed on a single page
3436dateFormat = "en" --export: the country code to format the date
3535-maxAmountOfElementsLoadedBySecond = 2500 --export: if cpu load errors at start, lower that value
3737+maxAmountOfElementsLoadedBySecond = 2000 --export: if cpu load errors at start, lower that value
3838+maxAmountOfRecipeLoadedBySecond = 10 --export: if cpu load errors on page load, lower that value
36393740--[[
3841 DO NOT CHANGE THE FOLLOWING
···7174 end
7275 end
7376end
7777+7878+if emitter == nil then
7979+ enableRemoteControl = false
8080+ system.print("Connect an Emitter to enable machine control from industry")
8181+end
8282+if #databanks == 0 then
8383+ enableRemoteControl = false
8484+ system.print("No Databank linked")
8585+end
7486Storage = bankhub:new(databanks)
75877688elementsId = {}
···8193coreOffset = 16
8294initIndex = 1
8395listIndex = 1
9696+elementsIdList = {}
8497if core ~= nil and Storage then
8598 elementsIdList = core.getElementIdList()
8686- --system.print(#elementsIdList)
8799 unit.setTimer("init",1)
88100end
8910190102elementsTypes = removeDuplicatesInTable(elementsTypes)
9110392104system.showScreen(1)
9393-unit.setTimer("refreshData", refreshSpeed)
94105channel_index = 1
95106selected_index = 1
96107selected_machine_index = 1
···99110maxPage = 1
100111selectedElementsId = {}
101112Ctrl_pressed = false
102102-Alt_pressed = false
103113craft_quantity = ""
104114craft_quantity_digits = {"0","0","0","0","0","0","0","0"}
105115refresh_id_list = {}
···110120markers = {}
111121refreshActivated = true
112122hud_help_command = ""
113113-unit.setTimer("helperRefresh",1)123123+unit.setTimer("helperRefresh",1)
124124+minOnPage = 0
125125+maxOnPage = 0
126126+recipeToLoad = {}
127127+loadedRecipes = {}
128128+129129+unit.setTimer("recipeUpdate", 1)
+4-1
Master program/source/unit/stop.lua
···11-Storage.clear()11+Storage.clear()
22+for _,m in pairs(markers) do
33+ core.deleteSticker(m)
44+end
+6-5
Master program/source/unit/tick_buildLists.lua
···11-local maxForLoop = initIndex + maxAmountOfElementsLoadedBySecond
11+local maxForLoop = listIndex + maxAmountOfElementsLoadedBySecond
22if maxForLoop > #elementsId then maxForLoop = #elementsId end
3344selectedElementsId = {}
55elementsTypes = {}
66for i = listIndex, maxForLoop, 1 do
77- --for _,id in pairs(elementsId) do
87 listIndex = i
98 local id = elementsId[i]
109 elementType = core.getElementTypeById(id)
1110 local elementName = core.getElementNameById(id):lower()
1211 if
1313- (elementType:lower():find("container") and elementName:find(containerMonitoringPrefix:lower()))
1212+ (elementType:lower():find("container")
1313+ and elementName:find(containerMonitoringPrefix:lower()))
1414 or (not elementType:lower():find("container"))
1515 then
1616- table.insert(elementsTypes, elementType)
1616+ local formatedName = removeQualityInName(elementType)
1717+ table.insert(elementsTypes, formatedName)
1718 end
1818- if selected_type == elementType then
1919+ if selected_type == removeQualityInName(elementType) then
1920 if
2021 (elementType:lower():find("container") and elementName:find(containerMonitoringPrefix:lower()))
2122 or (not elementType:lower():find("container"))
···11--load all the machines from the core step by step to avoid CPU Load Errors
2233-maxAmountOfElementsLoadedBySecond = 2500 --export: if cpu load errors at start, lower that value
44-53local maxForLoop = initIndex + maxAmountOfElementsLoadedBySecond
64if maxForLoop > #elementsIdList then maxForLoop = #elementsIdList end
77---system.print("init --- " .. initIndex .. " --- " .. maxForLoop)
55+system.print("Loading elements from " .. initIndex .. " to " .. maxForLoop .. " on " .. #elementsIdList)
8697for i = initIndex, maxForLoop, 1 do
1010- initIndex = i
1111- local id = elementsIdList[i]
1212- elementType = core.getElementTypeById(id):lower()
1313- if (elementType == "assembly line" and enableAssemblyMonitoring == true) or
1414- (elementType == "glass furnace" and enableGlassMonitoring == true) or
1515- (elementType == "3d printer" and enable3DPrinterMonitoring == true) or
1616- (elementType == "smelter" and enableSmelterMonitoring == true) or
1717- (elementType == "recycler" and enableRecyclerMonitoring == true) or
1818- (elementType:find("refinery") and enableHoneycombMonitoring == true) or
1919- (elementType == "refiner" and enableRefinerMonitoring == true) or
2020- (elementType:find("industry")
2121- and (
88+ initIndex = i
99+ local id = elementsIdList[i]
1010+ elementType = core.getElementTypeById(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 (
2220 (elementType:find("chemical") and enableChemicalMonitoring == true) or
2323- (elementType:find("electronics") and enableElectronicsMonitoring == true) or
2424- (elementType:find("metalwork") and enableMetalworkMonitoring == true)
2525- )
2121+ (elementType:find("electronics") and enableElectronicsMonitoring == true) or
2222+ (elementType:find("metalwork") and enableMetalworkMonitoring == true)
2323+ )
2624 ) or
2727- (elementType == "transfer unit" and enableTransferMonitoring == true) or
2525+ (elementType == "transfer unit" and enableTransferMonitoring == true) --[[or
2826 (elementType:find("container") and enableContainerMonitoring == true)
2929- then
3030- if machines_count[elementType:lower()] ~= nil then
3131- machines_count[elementType:lower()] = machines_count[elementType:lower()] + 1
3232- else
3333- machines_count[elementType:lower()] = 1
3434- end
3535- table.insert(elementsId, id)
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
3634 end
3737- if elementType:find("core") then
3838- --thx to Archaego for the idea of getting the core size by HP
3939- --thx to Rutik for the offset values
4040- local hp = core.getElementHitPointsById(id)
4141- if hp > 10000 then
4242- coreOffset = 128
4343- elseif hp > 1000 then
4444- coreOffset = 64
4545- elseif hp > 150 then
4646- coreOffset = 32
4747- end
3535+ table.insert(elementsId, id)
3636+ end
3737+ if elementType:find("core") then
3838+ --thx to Archaego for the idea of getting the core size by HP
3939+ --thx to Rutiik for the offset values
4040+ local hp = core.getElementHitPointsById(id)
4141+ if hp > 10000 then
4242+ coreOffset = 128
4343+ elseif hp > 1000 then
4444+ coreOffset = 64
4545+ elseif hp > 150 then
4646+ coreOffset = 32
4847 end
4949- end4848+ end
4949+end
+22
Master program/source/unit/tick_recipeUpdate.lua
···11+if recipeListIndex == nil then recipeListIndex = 1 end
22+local maxForLoop = recipeListIndex + maxAmountOfRecipeLoadedBySecond
33+if maxForLoop > #recipeToLoad then maxForLoop = #recipeToLoad end
44+--system.print("recipeUpdate " .. recipeListIndex .. "/" .. maxForLoop)
55+for i = recipeListIndex, maxForLoop, 1 do
66+ recipeListIndex = i
77+ if (loadedRecipes[recipeToLoad[i]] == nil) and (tonumber(recipeToLoad[i]) > 0) then
88+ --system.print(recipeToLoad[i])
99+ local recipe = json.decode(core.getSchematicInfo(recipeToLoad[i]))
1010+ if (recipe.products) then
1111+ if #recipe.products > 0 then
1212+ recipeName = recipe.products[1].name
1313+ end
1414+ end
1515+ loadedRecipes[recipeToLoad[i]] = recipeName
1616+ end
1717+end
1818+if recipeListIndex >= #recipeToLoad then
1919+ recipeToLoad = {}
2020+ recipeListIndex = 1
2121+end
2222+--system.print(json.encode(loadedRecipes))
-10
Master program/source/unit/tick_refreshData.lua
···11-if emitter ~= nil and #elementsTypes > 0 then
22- for _,db in pairs(databanks) do
33- for _,id in pairs(refresh_id_list) do
44- db.setIntValue("refresh_" .. tostring(id), 1)
55- end
66- end
77- if refreshActivated == true then
88- emitter.send(channels[elementsTypes[selected_index]:lower()], "")
99- end
1010-end