From 68f588ec1abd20e2f11980625bb0d0bc37c3d262 Mon Sep 17 00:00:00 2001 From: Thomas Date: Tue, 20 Jun 2023 20:12:47 +0200 Subject: [PATCH] v4.10 - new JSON package --- config.json | 2 +- source/unit/onStart.lua | 28 +++++++++++++++------------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/config.json b/config.json index d5bc8cd..9faf1b1 100644 --- a/config.json +++ b/config.json @@ -1 +1 @@ -{"events":[],"handlers":[{"code":"if coroutine.status(MainCoroutine) == \"dead\" then\n MainCoroutine = coroutine.create(runCoroutines)\nend\nif coroutine.status(MainCoroutine) == \"suspended\" then\n assert(coroutine.resume(MainCoroutine))\nend","filter":{"args":[],"signature":"onUpdate()","slotKey":"-4"},"key":"2"},{"code":"if databank ~= nil then\n databank.setStringValue(\"options\", json.encode(options))\nend","filter":{"args":[],"signature":"onStop()","slotKey":"-1"},"key":"0"},{"code":"--[[\n\tLUA PARAMETERS\n]]\nuseDatabankValues = false --export: if checked and if values were saved in databank, parmaters will be loaded from the databank, if not, following ones will be used\n\nPrefixScreen1 = \"s1_\" --export: the prefix used to enable container monitoring and display on the 1st screen\nPrefixScreen2 = \"s2_\" --export: the prefix used to enable container monitoring and display on the 2nd screen\nPrefixScreen3 = \"s3_\" --export: the prefix used to enable container monitoring and display on the 3rd screen\nPrefixScreen4 = \"s4_\" --export: the prefix used to enable container monitoring and display on the 4th screen\nPrefixScreen5 = \"s5_\" --export: the prefix used to enable container monitoring and display on the 5th screen\nPrefixScreen6 = \"s6_\" --export: the prefix used to enable container monitoring and display on the 6th screen\nPrefixScreen7 = \"s7_\" --export: the prefix used to enable container monitoring and display on the 7th screen\nPrefixScreen8 = \"s8_\" --export: the prefix used to enable container monitoring and display on the 8th screen\nPrefixScreen9 = \"s9_\" --export: the prefix used to enable container monitoring and display on the 9th screen\n\nscreenTitle1 = \"-\" --export: the title display on the 1st screen, not displayed if empty or equal to \"-\"\nscreenTitle2 = \"-\" --export: the title display on the 2nd screen, not displayed if empty or equal to \"-\"\nscreenTitle3 = \"-\" --export: the title display on the 3rd screen, not displayed if empty or equal to \"-\"\nscreenTitle4 = \"-\" --export: the title display on the 4th screen, not displayed if empty or equal to \"-\"\nscreenTitle5 = \"-\" --export: the title display on the 5th screen, not displayed if empty or equal to \"-\"\nscreenTitle6 = \"-\" --export: the title display on the 6th screen, not displayed if empty or equal to \"-\"\nscreenTitle7 = \"-\" --export: the title display on the 7th screen, not displayed if empty or equal to \"-\"\nscreenTitle8 = \"-\" --export: the title display on the 8th screen, not displayed if empty or equal to \"-\"\nscreenTitle9 = \"-\" --export: the title display on the 9th screen, not displayed if empty or equal to \"-\"\n\ncontainerProficiencyLvl = 5 --export: Talent level for Container Proficiency\ncontainerOptimizationLvl = 5 --export: Talent level for Container Optimization\ngroupByItemName = true --export: if enabled, this will group all entries with the same item name\n\nVolumeRoundedDecimals = 2 --export: maximum of decimals displayed for the volume value\nQuantityRoundedDecimals = 2 --export: maximum of decimals displayed for the quantity value\nPercentRoundedDecimals = 2 --export: maximum of decimals displayed for the percent fill value\nfontSize = 15 --export: the size of the text for all the screen\nmaxAmountOfElementsLoadedByTick = 5000 --export: the maximum number of element loaded by tick of the coroutine on script startup\nmaxAmountOfElementsRefreshedByTick = 200 --export: the maximum number of element refreshed by tick of the coroutine when refreshing values\n\nshowTierColors=true --export: show a diffenrent color for each tier (https://du-lua.dev/#/utils for help on the color values)\nT1Color= '0.43,0.65,0.71' --export: the rgb values for the T2 color\nT2Color= '0.14,0.7,0.3' --export: the rgb values for the T2 color\nT3Color= '0.26,0.63,1' --export: the rgb values for the T2 color\nT4Color= '0.66,0.28,0.66' --export: the rgb values for the T2 color\nT5Color= '1,0.62,0.24' --export: the rgb values for the T2 color\nshowTierOnName = true --export: show the tier of the item with the item name\nshowVolume = true --export: show or hide the column Volume\nvolumePosition= 55 --export: the position in percent of width for the column Volume\nshowQuantity = true --export: show or hide the column Quantity\nquantityPosition= 75 --export: the position in percent of width for the column Quantity\n\nverticalMode = true --export: rotate the screen 90deg (bottom on right)\nverticalModeBottomSide = \"right\" --export: when vertical mode is enabled, on which side the bottom of the screen is positioned (\"left\" or \"right\")\ndefaultSorting = \"none\" --export: the default sorting of items on the screen: \"none\": like in the container, \"items-asc\": ascending sorting on the name, \"items-desc\": descending sorting on the name, \"quantity-asc\": ascending on the quantity, \"quantity-desc\": descending on the quantity, \"percent-asc\": ascending on the percent fill, \"percent-desc\": descending on the percent fill\n\n--[[\n\tINIT\n]]\n\nlocal version = '4.9.0'\n\nsystem.print(\"----------------------------------\")\nsystem.print(\"DU-Storage-Monitoring version \" .. version)\nsystem.print(\"----------------------------------\")\n\noptions = {}\noptions.containerMonitoringPrefix_screen1 = PrefixScreen1\noptions.containerMonitoringPrefix_screen2 = PrefixScreen2\noptions.containerMonitoringPrefix_screen3 = PrefixScreen3\noptions.containerMonitoringPrefix_screen4 = PrefixScreen4\noptions.containerMonitoringPrefix_screen5 = PrefixScreen5\noptions.containerMonitoringPrefix_screen6 = PrefixScreen6\noptions.containerMonitoringPrefix_screen7 = PrefixScreen7\noptions.containerMonitoringPrefix_screen8 = PrefixScreen8\noptions.containerMonitoringPrefix_screen9 = PrefixScreen9\noptions.screenTitle1 = screenTitle1\noptions.screenTitle2 = screenTitle2\noptions.screenTitle3 = screenTitle3\noptions.screenTitle4 = screenTitle4\noptions.screenTitle5 = screenTitle5\noptions.screenTitle6 = screenTitle6\noptions.screenTitle7 = screenTitle7\noptions.screenTitle8 = screenTitle8\noptions.screenTitle9 = screenTitle9\noptions.container_proficiency_lvl = containerProficiencyLvl\noptions.container_optimization_lvl = containerOptimizationLvl\noptions.groupByItemName = groupByItemName\noptions.VolumeRoundedDecimals = VolumeRoundedDecimals\noptions.QuantityRoundedDecimals = QuantityRoundedDecimals\noptions.PercentRoundedDecimals = PercentRoundedDecimals\noptions.fontSize = fontSize\noptions.maxAmountOfElementsLoadedByTick = maxAmountOfElementsLoadedByTick\noptions.maxAmountOfElementsRefreshedByTick = maxAmountOfElementsRefreshedByTick\noptions.showVolume = showVolume\noptions.volumePosition = volumePosition\noptions.showQuantity = showQuantity\noptions.showTierOnName = showTierOnName\noptions.showTierColors = showTierColors\noptions.T1Color = T1Color\noptions.T2Color = T2Color\noptions.T3Color = T3Color\noptions.T4Color = T4Color\noptions.T5Color = T5Color\noptions.quantityPosition = quantityPosition\noptions.verticalMode = verticalMode\noptions.verticalModeBottomSide = verticalModeBottomSide\noptions.defaultSorting = defaultSorting\n\n\n--[[\n\tsplit a string on a delimiter By jericho\n]]\nfunction strSplit(a,b)result={}for c in(a..b):gmatch(\"(.-)\"..b)do table.insert(result,c)end;return result end\n\n--[[\n return RGB colors calculated from a gradient between two colors\n]]\nfunction getRGBGradient(a,b,c,d,e,f,g,h,i,j)a=-1*math.cos(a*math.pi)/2+0.5;local k=0;local l=0;local m=0;if a>=.5 then a=(a-0.5)*2;k=e-a*(e-h)l=f-a*(f-i)m=g-a*(g-j)else a=a*2;k=b-a*(b-e)l=c-a*(c-f)m=d-a*(d-g)end;return k,l,m end\n\n--[[\n\tformatting numbers by adding a space between thousands by Jericho\n]]\nfunction format_number(a)local b=a;while true do b,k=string.gsub(b,\"^(-?%d+)(%d%d%d)\",'%1 %2')if k==0 then break end end;local c=string.sub(b,-2)if c=='.0'then b=string.sub(b,1,b:len()-2)end;return b end\n\ncore = nil\ndatabank = nil\nscreens = {}\nfor slot_name, slot in pairs(unit) do\n if\n type(slot) == \"table\"\n and type(slot.export) == \"table\"\n and slot.getClass\n then\n if slot.getClass():lower():find(\"coreunit\") then\n core = slot\n end\n if slot.getClass():lower() == 'screenunit' then\n slot.slotname = slot_name\n table.insert(screens,slot)\n end\n if slot.getClass():lower() == 'databankunit' then\n databank = slot\n end\n end\nend\n\nif #screens == 0 then\n system.print(\"No Screen Detected\")\nelse\n --sorting screens by slotname to be sure the display is not changing\n table.sort(screens, function(a,b) return a.slotname < b.slotname end)\n local plural = \"\"\n if #screens > 1 then plural = \"s\" end\n system.print(#screens .. \" screen\" .. plural .. \" Connected\")\nend\nif core == nil then\n system.print(\"No Core Detected\")\nelse\n system.print(\"Core Connected\")\nend\nif databank == nil then\n system.print(\"No Databank Detected\")\nelse\n system.print(\"Databank Connected\")\n if (databank.hasKey(\"options\")) and (useDatabankValues == true) then\n local db_options = json.decode(databank.getStringValue(\"options\"))\n for key, value in pairs(options) do\n if db_options[key] then options[key] = db_options[key] end\n end\n system.print(\"Options Loaded From Databank\")\n else\n system.print(\"Options Loaded From LUA Parameters\")\n end\nend\nprefixes = {\n options.containerMonitoringPrefix_screen1,\n options.containerMonitoringPrefix_screen2,\n options.containerMonitoringPrefix_screen3,\n options.containerMonitoringPrefix_screen4,\n options.containerMonitoringPrefix_screen5,\n options.containerMonitoringPrefix_screen6,\n options.containerMonitoringPrefix_screen7,\n options.containerMonitoringPrefix_screen8,\n options.containerMonitoringPrefix_screen9\n}\ntitles = {\n options.screenTitle1,\n options.screenTitle2,\n options.screenTitle3,\n options.screenTitle4,\n options.screenTitle5,\n options.screenTitle6,\n options.screenTitle7,\n options.screenTitle8,\n options.screenTitle9\n}\n\n\nlocal sorting=0\nif options.defaultSorting==\"items-asc\" then sorting = 1\nelseif options.defaultSorting==\"items-desc\" then sorting = 2\nelseif options.defaultSorting==\"quantity-asc\" then sorting = 3\nelseif options.defaultSorting==\"quantity-desc\" then sorting = 4\nelseif options.defaultSorting==\"percent-asc\" then sorting = 5\nelseif options.defaultSorting==\"percent-desc\" then sorting = 6\nend\n\nfunction getRenderScript(data, screenTitle)\n local rs = [[\n local vmode = ]] .. tostring(options.verticalMode) .. [[\n\n local vmode_side = \"]] .. options.verticalModeBottomSide .. [[\"\n if sorting == nil then sorting = ]] .. sorting .. [[ end\n ]]\n if data == nil then\n rs = rs .. [[local json = require('dkjson')\n local input = getInput() or json.encode(nil)\n local data = json.decode(input)\n if data ~= nil and data[7] then\n items = {}\n page = 1\n screenTitle = data[6] or \"\"\n else\n if items == nil then items = {} end\n if page == nil then page = 1 end\n if screenTitle == nil then\n screenTitle = \"-\"\n if data then\n screenTitle = data[6] or \"\"\n end\n end\n end\n ]]\n end\n rs = rs .. [[local images = {}\n ]]\n if data == nil then\n rs = rs .. [[if data ~= {} and data ~= nil then\n items[data[11] ] = {data[1],data[2],data[3],data[4],data[5],data[8],data[10],data[12]}\n setOutput(#items)\n data = nil\n end\n ]]\n else\n rs = rs .. 'items=' .. data .. [[\n \n ]]\n if screenTitle ~= nil then\n rs = rs .. \"screenTitle='\" .. screenTitle .. [['\n ]]\n end\n end\n rs = rs .. [[local rx,ry = getResolution()\n local cx, cy = getCursor()\n if vmode then\n ry,rx = getResolution()\n cy, cx = getCursor()\n cx = rx - cx\n if vmode_side == \"right\" then\n cy = ry - cy\n cx = rx - cx\n end\n end\n local back=createLayer()\n local front=createLayer()\n font_size = ]] .. options.fontSize .. [[\n\n local mini=loadFont('Play',12)\n local small=loadFont('Play',14)\n local smallBold=loadFont('Play-Bold',18)\n local itemName=loadFont('Play-Bold',font_size)\n local medV=loadFont('Play-Bold', 25)\n local bigV=loadFont('Play-Bold', 30)\n local big=loadFont('Play',38)\n setBackgroundColor( 15/255,24/255,29/255)\n setDefaultStrokeColor( back,Shape_Line,0,0,0,0.5)\n setDefaultShadow( back,Shape_Line,6,0,0,0,0.5)\n setDefaultFillColor( front,Shape_BoxRounded,249/255,212/255,123/255,1)\n setDefaultFillColor( front,Shape_Text,0,0,0,1)\n setDefaultFillColor( front,Shape_Box,0.075,0.125,0.156,1)\n setDefaultFillColor( front,Shape_Text,0.710,0.878,0.941,1)\n function format_number(a)local b=a;while true do b,k=string.gsub(b,\"^(-?%d+)(%d%d%d)\",'%1 %2')if k==0 then break end end;local c=string.sub(b,-2)if c=='.0'then b=string.sub(b,1,b:len()-2)end;return b end\n function round(a,b)if b==nil then b=0 end;return math.floor(a*10^b+0.5)/10^b end\n function getRGBGradient(a,b,c,d,e,f,g,h,i,j)a=-1*math.cos(a*math.pi)/2+0.5;local k=0;local l=0;local m=0;if a>=.5 then a=(a-0.5)*2;k=e-a*(e-h)l=f-a*(f-i)m=g-a*(g-j)else a=a*2;k=b-a*(b-e)l=c-a*(c-f)m=d-a*(d-g)end;return k,l,m end\n function renderHeader(title, subtitle)\n local h_factor = 12\n local h = 35\n if subtitle ~= nil and subtitle ~= \"\" and subtitle ~= \"-\" then\n h = 50\n end\n addLine( back,0,h+12,rx,h+12)\n addBox(front,0,12,rx,h)\n if subtitle ~= nil and subtitle ~= \"\" and subtitle ~= \"-\" then\n addText(front,big,subtitle,44,50)\n setNextTextAlign(front, AlignH_Right, AlignV_Middle)\n addText(front,smallBold,title,rx-44,40)\n else\n addText(front,smallBold,title,44,35)\n end\n end\n local storageBar = createLayer()\n setDefaultFillColor(storageBar,Shape_Text,110/255,166/255,181/255,1)\n setDefaultFillColor(storageBar,Shape_Box,0.075,0.125,0.156,1)\n setDefaultFillColor(storageBar,Shape_Line,1,1,1,1)\n local storageDark = createLayer()\n setDefaultFillColor(storageDark,Shape_Text,63/255,92/255,102/255,1)\n setDefaultFillColor(storageDark,Shape_Box,13/255,24/255,28/255,1)\n local buttonHover = createLayer()\n setDefaultFillColor(buttonHover,Shape_Box,249/255,212/255,123/255,1)\n setDefaultFillColor(buttonHover,Shape_Text,0,0,0,1)\n local colorLayer = createLayer()\n local imagesLayer = createLayer()\n if vmode then\n local r = 90\n local tx = ry\n local ty = 0\n if vmode_side == \"left\" then\n r = r + 180\n tx = 0\n ty = rx\n end\n setLayerTranslation(back, tx,ty)\n setLayerRotation(back, math.rad(r))\n setLayerTranslation(front, tx, ty)\n setLayerRotation(front, math.rad(r))\n setLayerTranslation(storageBar, tx, ty)\n setLayerRotation(storageBar, math.rad(r))\n setLayerTranslation(colorLayer, tx, ty)\n setLayerRotation(colorLayer, math.rad(r))\n setLayerTranslation(imagesLayer, tx, ty)\n setLayerRotation(imagesLayer, math.rad(r))\n setLayerTranslation(buttonHover, tx, ty)\n setLayerRotation(buttonHover, math.rad(r))\n setLayerTranslation(storageDark, tx, ty)\n setLayerRotation(storageDark, math.rad(r))\n end\n function renderResistanceBar(title, tier, quantity, volume, max, percent, icon_path, item_id, x, y, w, h, withTitle, withIcon)\n local colorPercent = percent\n if percent > 100 then colorPercent = 100 end\n local r,g,b = getRGBGradient(colorPercent/100,177/255,42/255,42/255,249/255,212/255,123/255,34/255,177/255,76/255)\n local quantity_x_pos = font_size * 6.7\n local percent_x_pos = font_size * 2\n addBox(storageBar,x,y,w,h)\n if withTitle then\n local title_item_layer = storageBar\n local title_item = 'ITEMS'\n local title_item_width = 50\n if sorting > 0 and sorting <= 2 then\n if sorting == 1 then\n title_item_width = 90\n title_item = 'ITEMS - ASC'\n elseif sorting == 2 then\n title_item_width = 95\n title_item = 'ITEMS - DESC'\n end\n title_item_layer = buttonHover\n end\n if cx >= (x-5) and cx <= (x+title_item_width-5) and cy >= (y-19) and cy <= (y-19+h/1.5) then\n title_item_layer = buttonHover\n if getCursorPressed() then\n if sorting == 0 or sorting > 2 then sorting = 1\n elseif sorting == 1 then sorting = 2\n elseif sorting == 2 then sorting = 0\n end\n end\n end\n addBox(title_item_layer, x-5, y-19, title_item_width, h/1.5)\n setNextTextAlign(title_item_layer, AlignH_Left, AlignV_Bottom)\n addText(title_item_layer, small, title_item, x, y-5)\n if ]] .. tostring(options.showVolume) .. [[ then\n setNextTextAlign(storageDark, AlignH_Center, AlignV_Bottom)\n addText(storageDark, small, \"VOLUME\", x+(w*]] .. tostring(options.volumePosition/100) .. [[), y-5)\n end\n if ]] .. tostring(options.showQuantity) .. [[ then\n local title_quantity_layer = storageBar\n local title_quantity = 'QUANTITY'\n local title_quantity_width = 75\n if sorting >= 3 and sorting <= 4 then\n if sorting == 3 then\n title_quantity_width = 105\n title_quantity = 'QUANTITY - ASC'\n elseif sorting == 4 then\n title_quantity_width = 115\n title_quantity = 'QUANTITY - DESC'\n end\n title_quantity_layer = buttonHover\n end\n local title_quantity_x = x+(w*]] .. tostring(options.quantityPosition/100) .. [[)\n if cx >= (title_quantity_x-title_quantity_width/2) and cx <= (title_quantity_x+title_quantity_width/2) and cy >= (y-19) and cy <= (y-19+h/1.5) then\n title_quantity_layer = buttonHover\n if getCursorPressed() then\n if sorting < 3 or sorting > 4 then sorting = 3\n elseif sorting == 3 then sorting = 4\n elseif sorting == 4 then sorting = 0\n end\n end\n end\n addBox(title_quantity_layer, title_quantity_x-title_quantity_width/2, y-19, title_quantity_width, h/1.5)\n setNextTextAlign(title_quantity_layer, AlignH_Center, AlignV_Bottom)\n addText(title_quantity_layer, small, title_quantity, title_quantity_x, y-5)\n end\n local title_percent_layer = storageBar\n local title_percent = 'STORAGE'\n local title_percent_width = 75\n if sorting >= 5 and sorting <= 6 then\n if sorting == 5 then\n title_percent_width = 105\n title_percent = 'STORAGE - ASC'\n elseif sorting == 6 then\n title_percent_width = 115\n title_percent = 'STORAGE - DESC'\n end\n title_percent_layer = buttonHover\n end\n if cx >= (rx-x+5-title_percent_width) and cx <= (rx-x+5) and cy >= (y-19) and cy <= (y-19+h/1.5) then\n title_percent_layer = buttonHover\n if getCursorPressed() then\n if sorting < 5 then sorting = 5\n elseif sorting == 5 then sorting = 6\n elseif sorting == 6 then sorting = 0\n end\n end\n end\n addBox(title_percent_layer, rx-x+5-title_percent_width, y-19, title_percent_width, h/1.5)\n setNextTextAlign(title_percent_layer, AlignH_Right, AlignV_Bottom)\n addText(title_percent_layer, small, title_percent, rx-x, y-5)\n end\n local pos_y = y+(h/2)-2\n if icon_path and images[icon_path] then\n addImage(imagesLayer, images[icon_path], x+10, y+font_size*.1, font_size*1.3, font_size*1.2)\n end\n setNextTextAlign(storageBar, AlignH_Left, AlignV_Middle)\n local n = title\n if ]] .. tostring(options.showTierOnName) .. [[ then\n n = 'T' .. tier .. ' / ' .. n\n end]]\n if options.showTierColors then\n rs = rs .. [[\n if tier == 1 then\n setNextFillColor(storageBar, ]] .. options.T1Color .. [[, 1)\n elseif tier == 2 then\n setNextFillColor(storageBar, ]] .. options.T2Color .. [[, 1)\n elseif tier == 3 then\n setNextFillColor(storageBar, ]] .. options.T3Color .. [[, 1)\n elseif tier == 4 then\n setNextFillColor(storageBar, ]] .. options.T4Color .. [[, 1)\n elseif tier == 5 then\n setNextFillColor(storageBar, ]] .. options.T5Color .. [[, 1)\n end]]\n end\n rs = rs .. [[\n addText(storageBar, itemName, n, x+20+font_size, pos_y)\n setNextFillColor(colorLayer, r, g, b, 1)\n addBox(colorLayer,x,y+h-3,w*(colorPercent)/100,3)\n if ]] .. tostring(options.showVolume) .. [[ then\n setNextTextAlign(storageDark, AlignH_Center, AlignV_Middle)\n local unit = 'L'\n if max >= 100000 then\n max = round(max/1000,]] .. options.VolumeRoundedDecimals .. [[)\n volume = round(volume/1000, ]] .. options.VolumeRoundedDecimals .. [[)\n unit='kL'\n end\n addText(storageDark, itemName, format_number(volume) .. ' ' .. unit .. ' / ' .. format_number(max) .. ' ' .. unit, x+(w*]] .. tostring(options.volumePosition/100) .. [[), pos_y)\n end\n if ]] .. tostring(options.showQuantity) .. [[ then\n setNextTextAlign(storageBar, AlignH_Center, AlignV_Middle)\n addText(storageBar, itemName, format_number(quantity), x+(w*]] .. tostring(options.quantityPosition/100) .. [[), pos_y)\n end\n setNextFillColor(colorLayer, r, g, b, 1)\n setNextTextAlign(colorLayer, AlignH_Right, AlignV_Middle)\n addText(colorLayer, itemName, format_number(percent) ..\"%\", rx-x-5, pos_y)\n end\n local main_title = 'STORAGE MONITORING v]] .. version .. [['\n if ]] .. tostring(options.verticalMode) .. [[ and screenTitle ~= nil and screenTitle ~= \"\" and screenTitle ~= \"-\" then\n main_title = 'v]] .. version .. [['\n end\n renderHeader(main_title, screenTitle)\n\n start_h = 75\n if screenTitle ~= nil and screenTitle ~= \"\" and screenTitle ~= \"-\" then\n start_h = 100\n end\n local sorted_items = {}\n for i,v in pairs(items) do\n table.insert(sorted_items, v)\n end\n if sorting == 1 then table.sort(sorted_items, function(a, b) return a[1] < b[1] end)\n elseif sorting == 2 then table.sort(sorted_items, function(a, b) return a[1] > b[1] end)\n elseif sorting == 3 then table.sort(sorted_items, function(a, b) return a[2] < b[2] end)\n elseif sorting == 4 then table.sort(sorted_items, function(a, b) return a[2] > b[2] end)\n elseif sorting == 5 then table.sort(sorted_items, function(a, b) return a[4] < b[4] end)\n elseif sorting == 6 then table.sort(sorted_items, function(a, b) return a[4] > b[4] end)\n end\n local h = font_size + font_size / 2\n local loadedImages = 0\n if data ~= {} then\n for _,item in ipairs(sorted_items) do\n if item[1] and images[item[5] ] == nil and loadedImages <= 15 then\n loadedImages = loadedImages + 1\n images[item[5] ] = loadImage(item[5])\n end\n end\n end\n for i,container in ipairs(sorted_items) do\n renderResistanceBar(container[1], container[8], container[2], container[3], container[7], container[4], container[5], container[6], 44, start_h, rx-88, h, i==1, i<=16)\n start_h = start_h+h+5\n end\n requestAnimationFrame(10)\n ]]\n return rs\nend\n\nlocal renderScript = getRenderScript()\n\nfor _,s in pairs(screens) do\n s.setRenderScript(renderScript)\nend\n\nelementsIdList = {}\nif core ~= nil then\n elementsIdList = core.getElementIdList()\nend\nstorageIdList= {}\ninitIndex = 0\ninitFinished = false\nscreens_displayed = false\n\n--Nested Coroutines by Jericho\ncoroutinesTable = {}\n--all functions here will become a coroutine\nMyCoroutines = {\n function()\n if not initFinished then\n system.print(\"Loading contructs elements (\" .. #elementsIdList .. \" elements detected)\")\n for i = 1, #elementsIdList, 1 do\n initIndex = i\n local id = elementsIdList[i]\n local elementType = core.getElementDisplayNameById(id):lower()\n if elementType:lower():find(\"container\") then\n table.insert(storageIdList, id)\n end\n if (i%options.maxAmountOfElementsLoadedByTick) == 0 then\n system.print(i .. ' elements scanned on ' .. #elementsIdList .. ' with ' .. #storageIdList .. \" identified\")\n coroutine.yield(coroutinesTable[1])\n end\n end\n if initIndex == #elementsIdList then\n system.print(#elementsIdList .. \" scanned with \" .. #storageIdList .. \" storage elements identified\")\n initFinished = true\n end\n end\n end,\n function()\n if not screens_displayed then\n local html = ''\n local storage_elements = {}\n for elemindex,id in ipairs(storageIdList) do\n local elementType = core.getElementDisplayNameById(id)\n if elementType:lower():find(\"container\") then\n local elementName = core.getElementNameById(id)\n if elementName:lower():find(prefixes[1]:lower())\n or elementName:lower():find(prefixes[2]:lower())\n or elementName:lower():find(prefixes[3]:lower())\n or elementName:lower():find(prefixes[4]:lower())\n or elementName:lower():find(prefixes[5]:lower())\n or elementName:lower():find(prefixes[6]:lower())\n or elementName:lower():find(prefixes[7]:lower())\n or elementName:lower():find(prefixes[8]:lower())\n or elementName:lower():find(prefixes[9]:lower())\n then\n local container = {}\n local splitted = strSplit(elementName, '_')\n local name = splitted[2]\n local ingredient = system.getItem(name)\n local container_size = \"XS\"\n local container_amount = 1\n local container_empty_mass = 0\n local container_volume = 0\n local contentQuantity = 0\n local percent_fill = 0\n if not elementType:lower():find(\"hub\") then\n local containerMaxHP = core.getElementMaxHitPointsById(id)\n if containerMaxHP > 68000 then\n container_size = \"XXL\"\n container_empty_mass = 88410\n container_volume = 512000 * (options.container_proficiency_lvl * 0.1) + 512000\n elseif containerMaxHP > 33000 then\n container_size = \"XL\"\n container_empty_mass = 44210\n container_volume = 256000 * (options.container_proficiency_lvl * 0.1) + 256000\n elseif containerMaxHP > 17000 then\n container_size = \"L\"\n container_empty_mass = 14842.7\n container_volume = 128000 * (options.container_proficiency_lvl * 0.1) + 128000\n elseif containerMaxHP > 7900 then\n container_size = \"M\"\n container_empty_mass = 7421.35\n container_volume = 64000 * (options.container_proficiency_lvl * 0.1) + 64000\n elseif containerMaxHP > 900 then\n container_size = \"S\"\n container_empty_mass = 1281.31\n container_volume = 8000 * (options.container_proficiency_lvl * 0.1) + 8000\n else\n container_size = \"XS\"\n container_empty_mass = 229.09\n container_volume = 1000 * (options.container_proficiency_lvl * 0.1) + 1000\n end\n else\n if splitted[3] then\n container_size = splitted[3]\n end\n if splitted[4] then\n container_amount = splitted[4]\n end\n local volume = 0\n container_volume_list = {xxl=512000, xl=256000, l=128000, m=64000, s=8000, xs=1000}\n container_size = container_size:lower()\n if container_volume_list[container_size] then\n volume = container_volume_list[container_size]\n end\n container_volume = (volume * options.container_proficiency_lvl * 0.1 + volume) * tonumber(container_amount)\n container_empty_mass = 55.8\n end\n local totalMass = core.getElementMassById(id)\n local contentMassKg = totalMass - container_empty_mass\n container.id = id\n container.itemid = ingredient.id\n container.realName = elementName\n container.prefix = splitted[1] .. \"_\"\n container.name = name\n container.ingredient = ingredient\n container.quantity = contentMassKg / (ingredient.unitMass - (ingredient.unitMass * (options.container_optimization_lvl * 0.05)))\n container.maxvolume = container_volume\n container.percent = utils.round((ingredient.unitVolume * container.quantity) * 100 / container_volume)\n if ingredient.name == \"InvalidItem\" then\n container.percent = 0\n container.quantity = 0\n end\n container.volume = container.quantity * ingredient.unitVolume\n if container.percent > 100 then container.percent = 100 end\n table.insert(storage_elements, container)\n end\n end\n if (elemindex%options.maxAmountOfElementsRefreshedByTick) == 0 then\n coroutine.yield(coroutinesTable[2])\n end\n end\n \n -- group by name and screen\n local groupped = {}\n if groupByItemName then\n for _,v in pairs(storage_elements) do\n local prefix = v.prefix:lower()\n if groupped[prefix .. v.itemid] then\n groupped[prefix .. v.itemid].quantity = groupped[prefix .. v.itemid].quantity + v.quantity\n groupped[prefix .. v.itemid].volume = groupped[prefix .. v.itemid].volume + v.volume\n groupped[prefix .. v.itemid].maxvolume = groupped[prefix .. v.itemid].maxvolume + v.maxvolume\n groupped[prefix .. v.itemid].percent = groupped[prefix .. v.itemid].volume * 100 / groupped[prefix .. v.itemid].maxvolume\n else\n groupped[prefix .. v.itemid] = v\n end\n end\n else\n groupped = storage_elements\n end\n \n -- sorting by tier\n local tiers = {}\n tiers[1] = {} --tier 0 (thx to Belorion#3127 for pointing Oxygen and Hydrogen are Tier 0 and not 1)\n tiers[2] = {} --tier 1\n tiers[3] = {} --tier 2\n tiers[4] = {} --tier 3\n tiers[5] = {} --tier 4\n tiers[6] = {} --tier 5\n \n for _,v in pairs(groupped) do\n table.insert(tiers[v.ingredient.tier+1],v)\n end\n \n -- sorting by name\n for k,v in pairs(tiers) do\n table.sort(tiers[k], function(a,b) return a.ingredient.locDisplayNameWithSize:lower() < b.ingredient.locDisplayNameWithSize:lower() end)\n end\n \n if #screens > 0 and not screens_displayed then\n for index, screen in pairs(screens) do\n local prefix = prefixes[index]\n local title = titles[index]\n local refreshScreen=true\n local i = 1\n local items_data_for_screen = {}\n for tier_k,tier in pairs(tiers) do\n for _,container in pairs(tier) do\n if container.prefix:lower():find(prefix:lower()) then\n local item_name = container.ingredient.locDisplayNameWithSize\n if container.ingredient.name == 'InvalidItem' then\n item_name = 'Invalid Item Id'\n end\n local storage_data = {\n item_name,\n utils.round(container.quantity * (10 ^ options.QuantityRoundedDecimals)) / (10 ^ options.QuantityRoundedDecimals),\n utils.round(container.volume),\n utils.round(container.percent * (10 ^ options.PercentRoundedDecimals)) / (10 ^ options.PercentRoundedDecimals),\n container.ingredient.iconPath,\n title,\n refreshScreen,\n container.ingredient.id,\n screens_displayed,\n utils.round(container.maxvolume),\n i,\n container.ingredient.tier,\n }\n table.insert(items_data_for_screen,storage_data)\n local to_send=json.encode(storage_data)\n screen.setScriptInput(to_send)\n refreshScreen = false\n while tonumber(screen.getScriptOutput()) ~= i do\n coroutine.yield(coroutinesTable[2])\n end\n i = i+1\n end\n end\n end\n local str_data = '{'\n for i,v in ipairs(items_data_for_screen) do\n str_data = str_data .. '{\"' .. tostring(v[1]) .. '\",' .. tostring(v[2]) .. ',' .. tostring(v[3]) .. ',' .. tostring(v[4]) .. ',\"' .. tostring(v[5]) .. '\",' .. tostring(v[8]) .. ',' .. tostring(v[10]) .. ',' .. tostring(v[12]) .. '}'\n if i < #items_data_for_screen then str_data = str_data .. ',' end\n end\n str_data = str_data .. '}'\n local fullRS = getRenderScript(str_data, title)\n if fullRS:len() < 50000 then --if all can stay on screen then\n screen.setRenderScript(fullRS) \n end\n end\n screens_displayed = true\n end\n unit.exit()\n coroutine.yield(coroutinesTable[2])\n else\n coroutine.yield(coroutinesTable[2])\n end\n end\n}\n\nfunction initCoroutines()\n for _,f in pairs(MyCoroutines) do\n local co = coroutine.create(f)\n table.insert(coroutinesTable, co)\n end\nend\n\ninitCoroutines()\n\nrunCoroutines = function()\n for i,co in ipairs(coroutinesTable) do\n if coroutine.status(co) == \"dead\" then\n coroutinesTable[i] = coroutine.create(MyCoroutines[i])\n end\n if coroutine.status(co) == \"suspended\" then\n assert(coroutine.resume(co))\n end\n end\nend\n\nMainCoroutine = coroutine.create(runCoroutines)\n\nsystem.showScreen(true)","filter":{"args":[],"signature":"onStart()","slotKey":"-1"},"key":"1"}],"methods":[],"slots":{"0":{"name":"slot1","type":{"events":[],"methods":[]}},"1":{"name":"slot2","type":{"events":[],"methods":[]}},"2":{"name":"slot3","type":{"events":[],"methods":[]}},"3":{"name":"slot4","type":{"events":[],"methods":[]}},"4":{"name":"slot5","type":{"events":[],"methods":[]}},"5":{"name":"slot6","type":{"events":[],"methods":[]}},"6":{"name":"slot7","type":{"events":[],"methods":[]}},"7":{"name":"slot8","type":{"events":[],"methods":[]}},"8":{"name":"slot9","type":{"events":[],"methods":[]}},"9":{"name":"slot10","type":{"events":[],"methods":[]}},"-5":{"name":"library","type":{"events":[],"methods":[]}},"-4":{"name":"system","type":{"events":[],"methods":[]}},"-3":{"name":"player","type":{"events":[],"methods":[]}},"-2":{"name":"construct","type":{"events":[],"methods":[]}},"-1":{"name":"unit","type":{"events":[],"methods":[]}}}} +{"slots":{"0":{"name":"slot1","type":{"events":[],"methods":[]}},"1":{"name":"slot2","type":{"events":[],"methods":[]}},"2":{"name":"slot3","type":{"events":[],"methods":[]}},"3":{"name":"slot4","type":{"events":[],"methods":[]}},"4":{"name":"slot5","type":{"events":[],"methods":[]}},"5":{"name":"slot6","type":{"events":[],"methods":[]}},"6":{"name":"slot7","type":{"events":[],"methods":[]}},"7":{"name":"slot8","type":{"events":[],"methods":[]}},"8":{"name":"slot9","type":{"events":[],"methods":[]}},"9":{"name":"slot10","type":{"events":[],"methods":[]}},"-1":{"name":"unit","type":{"events":[],"methods":[]}},"-3":{"name":"player","type":{"events":[],"methods":[]}},"-2":{"name":"construct","type":{"events":[],"methods":[]}},"-4":{"name":"system","type":{"events":[],"methods":[]}},"-5":{"name":"library","type":{"events":[],"methods":[]}}},"handlers":[{"code":"if databank ~= nil then\n databank.setStringValue(\"options\", json.encode(options))\nend","filter":{"args":[],"signature":"onStop()","slotKey":"-1"},"key":"0"},{"code":"--[[\n\tLUA PARAMETERS\n]]\nuseDatabankValues = false --export: if checked and if values were saved in databank, parmaters will be loaded from the databank, if not, following ones will be used\n\nPrefixScreen1 = \"s1_\" --export: the prefix used to enable container monitoring and display on the 1st screen\nPrefixScreen2 = \"s2_\" --export: the prefix used to enable container monitoring and display on the 2nd screen\nPrefixScreen3 = \"s3_\" --export: the prefix used to enable container monitoring and display on the 3rd screen\nPrefixScreen4 = \"s4_\" --export: the prefix used to enable container monitoring and display on the 4th screen\nPrefixScreen5 = \"s5_\" --export: the prefix used to enable container monitoring and display on the 5th screen\nPrefixScreen6 = \"s6_\" --export: the prefix used to enable container monitoring and display on the 6th screen\nPrefixScreen7 = \"s7_\" --export: the prefix used to enable container monitoring and display on the 7th screen\nPrefixScreen8 = \"s8_\" --export: the prefix used to enable container monitoring and display on the 8th screen\nPrefixScreen9 = \"s9_\" --export: the prefix used to enable container monitoring and display on the 9th screen\n\nscreenTitle1 = \"-\" --export: the title display on the 1st screen, not displayed if empty or equal to \"-\"\nscreenTitle2 = \"-\" --export: the title display on the 2nd screen, not displayed if empty or equal to \"-\"\nscreenTitle3 = \"-\" --export: the title display on the 3rd screen, not displayed if empty or equal to \"-\"\nscreenTitle4 = \"-\" --export: the title display on the 4th screen, not displayed if empty or equal to \"-\"\nscreenTitle5 = \"-\" --export: the title display on the 5th screen, not displayed if empty or equal to \"-\"\nscreenTitle6 = \"-\" --export: the title display on the 6th screen, not displayed if empty or equal to \"-\"\nscreenTitle7 = \"-\" --export: the title display on the 7th screen, not displayed if empty or equal to \"-\"\nscreenTitle8 = \"-\" --export: the title display on the 8th screen, not displayed if empty or equal to \"-\"\nscreenTitle9 = \"-\" --export: the title display on the 9th screen, not displayed if empty or equal to \"-\"\n\ncontainerProficiencyLvl = 5 --export: Talent level for Container Proficiency\ncontainerOptimizationLvl = 5 --export: Talent level for Container Optimization\ngroupByItemName = true --export: if enabled, this will group all entries with the same item name\n\nVolumeRoundedDecimals = 2 --export: maximum of decimals displayed for the volume value\nQuantityRoundedDecimals = 2 --export: maximum of decimals displayed for the quantity value\nPercentRoundedDecimals = 2 --export: maximum of decimals displayed for the percent fill value\nfontSize = 15 --export: the size of the text for all the screen\nmaxAmountOfElementsLoadedByTick = 5000 --export: the maximum number of element loaded by tick of the coroutine on script startup\nmaxAmountOfElementsRefreshedByTick = 200 --export: the maximum number of element refreshed by tick of the coroutine when refreshing values\n\nshowTierColors=true --export: show a diffenrent color for each tier (https://du-lua.dev/#/utils for help on the color values)\nT1Color= '0.43,0.65,0.71' --export: the rgb values for the T2 color\nT2Color= '0.14,0.7,0.3' --export: the rgb values for the T2 color\nT3Color= '0.26,0.63,1' --export: the rgb values for the T2 color\nT4Color= '0.66,0.28,0.66' --export: the rgb values for the T2 color\nT5Color= '1,0.62,0.24' --export: the rgb values for the T2 color\nshowTierOnName = true --export: show the tier of the item with the item name\nshowVolume = true --export: show or hide the column Volume\nvolumePosition= 55 --export: the position in percent of width for the column Volume\nshowQuantity = true --export: show or hide the column Quantity\nquantityPosition= 75 --export: the position in percent of width for the column Quantity\n\nverticalMode = true --export: rotate the screen 90deg (bottom on right)\nverticalModeBottomSide = \"right\" --export: when vertical mode is enabled, on which side the bottom of the screen is positioned (\"left\" or \"right\")\ndefaultSorting = \"none\" --export: the default sorting of items on the screen: \"none\": like in the container, \"items-asc\": ascending sorting on the name, \"items-desc\": descending sorting on the name, \"quantity-asc\": ascending on the quantity, \"quantity-desc\": descending on the quantity, \"percent-asc\": ascending on the percent fill, \"percent-desc\": descending on the percent fill\n\n--[[\n\tINIT\n]]\n\nlocal version = '4.10.0'\n\nsystem.print(\"----------------------------------\")\nsystem.print(\"DU-Storage-Monitoring version \" .. version)\nsystem.print(\"----------------------------------\")\n\noptions = {}\noptions.containerMonitoringPrefix_screen1 = PrefixScreen1\noptions.containerMonitoringPrefix_screen2 = PrefixScreen2\noptions.containerMonitoringPrefix_screen3 = PrefixScreen3\noptions.containerMonitoringPrefix_screen4 = PrefixScreen4\noptions.containerMonitoringPrefix_screen5 = PrefixScreen5\noptions.containerMonitoringPrefix_screen6 = PrefixScreen6\noptions.containerMonitoringPrefix_screen7 = PrefixScreen7\noptions.containerMonitoringPrefix_screen8 = PrefixScreen8\noptions.containerMonitoringPrefix_screen9 = PrefixScreen9\noptions.screenTitle1 = screenTitle1\noptions.screenTitle2 = screenTitle2\noptions.screenTitle3 = screenTitle3\noptions.screenTitle4 = screenTitle4\noptions.screenTitle5 = screenTitle5\noptions.screenTitle6 = screenTitle6\noptions.screenTitle7 = screenTitle7\noptions.screenTitle8 = screenTitle8\noptions.screenTitle9 = screenTitle9\noptions.container_proficiency_lvl = containerProficiencyLvl\noptions.container_optimization_lvl = containerOptimizationLvl\noptions.groupByItemName = groupByItemName\noptions.VolumeRoundedDecimals = VolumeRoundedDecimals\noptions.QuantityRoundedDecimals = QuantityRoundedDecimals\noptions.PercentRoundedDecimals = PercentRoundedDecimals\noptions.fontSize = fontSize\noptions.maxAmountOfElementsLoadedByTick = maxAmountOfElementsLoadedByTick\noptions.maxAmountOfElementsRefreshedByTick = maxAmountOfElementsRefreshedByTick\noptions.showVolume = showVolume\noptions.volumePosition = volumePosition\noptions.showQuantity = showQuantity\noptions.showTierOnName = showTierOnName\noptions.showTierColors = showTierColors\noptions.T1Color = T1Color\noptions.T2Color = T2Color\noptions.T3Color = T3Color\noptions.T4Color = T4Color\noptions.T5Color = T5Color\noptions.quantityPosition = quantityPosition\noptions.verticalMode = verticalMode\noptions.verticalModeBottomSide = verticalModeBottomSide\noptions.defaultSorting = defaultSorting\n\n\n--[[\n\tsplit a string on a delimiter By jericho\n]]\nfunction strSplit(a,b)result={}for c in(a..b):gmatch(\"(.-)\"..b)do table.insert(result,c)end;return result end\n\n--[[\n return RGB colors calculated from a gradient between two colors\n]]\nfunction getRGBGradient(a,b,c,d,e,f,g,h,i,j)a=-1*math.cos(a*math.pi)/2+0.5;local k=0;local l=0;local m=0;if a>=.5 then a=(a-0.5)*2;k=e-a*(e-h)l=f-a*(f-i)m=g-a*(g-j)else a=a*2;k=b-a*(b-e)l=c-a*(c-f)m=d-a*(d-g)end;return k,l,m end\n\n--[[\n\tformatting numbers by adding a space between thousands by Jericho\n]]\nfunction format_number(a)local b=a;while true do b,k=string.gsub(b,\"^(-?%d+)(%d%d%d)\",'%1 %2')if k==0 then break end end;local c=string.sub(b,-2)if c=='.0'then b=string.sub(b,1,b:len()-2)end;return b end\n\ncore = nil\ndatabank = nil\nscreens = {}\nfor slot_name, slot in pairs(unit) do\n if\n type(slot) == \"table\"\n and type(slot.export) == \"table\"\n and slot.getClass\n then\n if slot.getClass():lower():find(\"coreunit\") then\n core = slot\n end\n if slot.getClass():lower() == 'screenunit' then\n slot.slotname = slot_name\n table.insert(screens,slot)\n end\n if slot.getClass():lower() == 'databankunit' then\n databank = slot\n end\n end\nend\n\nif #screens == 0 then\n system.print(\"No Screen Detected\")\nelse\n --sorting screens by slotname to be sure the display is not changing\n table.sort(screens, function(a,b) return a.slotname < b.slotname end)\n local plural = \"\"\n if #screens > 1 then plural = \"s\" end\n system.print(#screens .. \" screen\" .. plural .. \" Connected\")\nend\nif core == nil then\n system.print(\"No Core Detected\")\nelse\n system.print(\"Core Connected\")\nend\nif databank == nil then\n system.print(\"No Databank Detected\")\nelse\n system.print(\"Databank Connected\")\n if (databank.hasKey(\"options\")) and (useDatabankValues == true) then\n local db_options = json.decode(databank.getStringValue(\"options\"))\n for key, value in pairs(options) do\n if db_options[key] then options[key] = db_options[key] end\n end\n system.print(\"Options Loaded From Databank\")\n else\n system.print(\"Options Loaded From LUA Parameters\")\n end\nend\nprefixes = {\n options.containerMonitoringPrefix_screen1,\n options.containerMonitoringPrefix_screen2,\n options.containerMonitoringPrefix_screen3,\n options.containerMonitoringPrefix_screen4,\n options.containerMonitoringPrefix_screen5,\n options.containerMonitoringPrefix_screen6,\n options.containerMonitoringPrefix_screen7,\n options.containerMonitoringPrefix_screen8,\n options.containerMonitoringPrefix_screen9\n}\ntitles = {\n options.screenTitle1,\n options.screenTitle2,\n options.screenTitle3,\n options.screenTitle4,\n options.screenTitle5,\n options.screenTitle6,\n options.screenTitle7,\n options.screenTitle8,\n options.screenTitle9\n}\n\n\nlocal sorting=0\nif options.defaultSorting==\"items-asc\" then sorting = 1\nelseif options.defaultSorting==\"items-desc\" then sorting = 2\nelseif options.defaultSorting==\"quantity-asc\" then sorting = 3\nelseif options.defaultSorting==\"quantity-desc\" then sorting = 4\nelseif options.defaultSorting==\"percent-asc\" then sorting = 5\nelseif options.defaultSorting==\"percent-desc\" then sorting = 6\nend\n\nfunction getRenderScript(data, screenTitle)\n local rs = [[\n local vmode = ]] .. tostring(options.verticalMode) .. [[\n\n local vmode_side = \"]] .. options.verticalModeBottomSide .. [[\"\n if sorting == nil then sorting = ]] .. sorting .. [[ end\n ]]\n if data == nil then\n rs = rs .. [[local json = require('json')\n local input = getInput() or json.encode(nil)\n local data = json.decode(input)\n if data ~= nil and data[7] then\n items = {}\n page = 1\n screenTitle = data[6] or \"\"\n else\n if items == nil then items = {} end\n if page == nil then page = 1 end\n if screenTitle == nil then\n screenTitle = \"-\"\n if data then\n screenTitle = data[6] or \"\"\n end\n end\n end\n ]]\n end\n rs = rs .. [[local images = {}\n ]]\n if data == nil then\n rs = rs .. [[if data ~= {} and data ~= nil then\n items[data[11] ] = {data[1],data[2],data[3],data[4],data[5],data[8],data[10],data[12]}\n setOutput(#items)\n data = nil\n end\n ]]\n else\n rs = rs .. 'items=' .. data .. [[\n \n ]]\n if screenTitle ~= nil then\n rs = rs .. \"screenTitle='\" .. screenTitle .. [['\n ]]\n end\n end\n rs = rs .. [[local rx,ry = getResolution()\n local cx, cy = getCursor()\n if vmode then\n ry,rx = getResolution()\n cy, cx = getCursor()\n cx = rx - cx\n if vmode_side == \"right\" then\n cy = ry - cy\n cx = rx - cx\n end\n end\n local back=createLayer()\n local front=createLayer()\n font_size = ]] .. options.fontSize .. [[\n\n local mini=loadFont('Play',12)\n local small=loadFont('Play',14)\n local smallBold=loadFont('Play-Bold',18)\n local itemName=loadFont('Play-Bold',font_size)\n local medV=loadFont('Play-Bold', 25)\n local bigV=loadFont('Play-Bold', 30)\n local big=loadFont('Play',38)\n setBackgroundColor( 15/255,24/255,29/255)\n setDefaultStrokeColor( back,Shape_Line,0,0,0,0.5)\n setDefaultShadow( back,Shape_Line,6,0,0,0,0.5)\n setDefaultFillColor( front,Shape_BoxRounded,249/255,212/255,123/255,1)\n setDefaultFillColor( front,Shape_Text,0,0,0,1)\n setDefaultFillColor( front,Shape_Box,0.075,0.125,0.156,1)\n setDefaultFillColor( front,Shape_Text,0.710,0.878,0.941,1)\n function format_number(a)local b=a;while true do b,k=string.gsub(b,\"^(-?%d+)(%d%d%d)\",'%1 %2')if k==0 then break end end;local c=string.sub(b,-2)if c=='.0'then b=string.sub(b,1,b:len()-2)end;return b end\n function round(a,b)if b==nil then b=0 end;return math.floor(a*10^b+0.5)/10^b end\n function getRGBGradient(a,b,c,d,e,f,g,h,i,j)a=-1*math.cos(a*math.pi)/2+0.5;local k=0;local l=0;local m=0;if a>=.5 then a=(a-0.5)*2;k=e-a*(e-h)l=f-a*(f-i)m=g-a*(g-j)else a=a*2;k=b-a*(b-e)l=c-a*(c-f)m=d-a*(d-g)end;return k,l,m end\n function renderHeader(title, subtitle)\n local h_factor = 12\n local h = 35\n if subtitle ~= nil and subtitle ~= \"\" and subtitle ~= \"-\" then\n h = 50\n end\n addLine( back,0,h+12,rx,h+12)\n addBox(front,0,12,rx,h)\n if subtitle ~= nil and subtitle ~= \"\" and subtitle ~= \"-\" then\n addText(front,big,subtitle,44,50)\n setNextTextAlign(front, AlignH_Right, AlignV_Middle)\n addText(front,smallBold,title,rx-44,40)\n else\n addText(front,smallBold,title,44,35)\n end\n end\n local storageBar = createLayer()\n setDefaultFillColor(storageBar,Shape_Text,110/255,166/255,181/255,1)\n setDefaultFillColor(storageBar,Shape_Box,0.075,0.125,0.156,1)\n setDefaultFillColor(storageBar,Shape_Line,1,1,1,1)\n local storageDark = createLayer()\n setDefaultFillColor(storageDark,Shape_Text,63/255,92/255,102/255,1)\n setDefaultFillColor(storageDark,Shape_Box,13/255,24/255,28/255,1)\n local buttonHover = createLayer()\n setDefaultFillColor(buttonHover,Shape_Box,249/255,212/255,123/255,1)\n setDefaultFillColor(buttonHover,Shape_Text,0,0,0,1)\n local colorLayer = createLayer()\n local imagesLayer = createLayer()\n if vmode then\n local r = 90\n local tx = ry\n local ty = 0\n if vmode_side == \"left\" then\n r = r + 180\n tx = 0\n ty = rx\n end\n setLayerTranslation(back, tx,ty)\n setLayerRotation(back, math.rad(r))\n setLayerTranslation(front, tx, ty)\n setLayerRotation(front, math.rad(r))\n setLayerTranslation(storageBar, tx, ty)\n setLayerRotation(storageBar, math.rad(r))\n setLayerTranslation(colorLayer, tx, ty)\n setLayerRotation(colorLayer, math.rad(r))\n setLayerTranslation(imagesLayer, tx, ty)\n setLayerRotation(imagesLayer, math.rad(r))\n setLayerTranslation(buttonHover, tx, ty)\n setLayerRotation(buttonHover, math.rad(r))\n setLayerTranslation(storageDark, tx, ty)\n setLayerRotation(storageDark, math.rad(r))\n end\n function renderResistanceBar(title, tier, quantity, volume, max, percent, icon_path, item_id, x, y, w, h, withTitle, withIcon)\n local colorPercent = percent\n if percent > 100 then colorPercent = 100 end\n local r,g,b = getRGBGradient(colorPercent/100,177/255,42/255,42/255,249/255,212/255,123/255,34/255,177/255,76/255)\n local quantity_x_pos = font_size * 6.7\n local percent_x_pos = font_size * 2\n addBox(storageBar,x,y,w,h)\n if withTitle then\n local title_item_layer = storageBar\n local title_item = 'ITEMS'\n local title_item_width = 50\n if sorting > 0 and sorting <= 2 then\n if sorting == 1 then\n title_item_width = 90\n title_item = 'ITEMS - ASC'\n elseif sorting == 2 then\n title_item_width = 95\n title_item = 'ITEMS - DESC'\n \n end\n title_item_layer = buttonHover\n end\n if cx >= (x-5) and cx <= (x+title_item_width-5) and cy >= (y-19) and cy <= (y-19+h/1.5) then\n title_item_layer = buttonHover\n if getCursorPressed() then\n if sorting == 0 or sorting > 2 then sorting = 1\n elseif sorting == 1 then sorting = 2\n elseif sorting == 2 then sorting = 0\n end\n end\n end\n addBox(title_item_layer, x-5, y-19, title_item_width, h/1.5)\n setNextTextAlign(title_item_layer, AlignH_Left, AlignV_Bottom)\n addText(title_item_layer, small, title_item, x, y-5)\n if ]] .. tostring(options.showVolume) .. [[ then\n setNextTextAlign(storageDark, AlignH_Center, AlignV_Bottom)\n addText(storageDark, small, \"VOLUME\", x+(w*]] .. tostring(options.volumePosition/100) .. [[), y-5)\n end\n if ]] .. tostring(options.showQuantity) .. [[ then\n local title_quantity_layer = storageBar\n local title_quantity = 'QUANTITY'\n local title_quantity_width = 75\n if sorting >= 3 and sorting <= 4 then\n if sorting == 3 then\n title_quantity_width = 105\n title_quantity = 'QUANTITY - ASC'\n elseif sorting == 4 then\n title_quantity_width = 115\n title_quantity = 'QUANTITY - DESC'\n end\n title_quantity_layer = buttonHover\n end\n local title_quantity_x = x+(w*]] .. tostring(options.quantityPosition/100) .. [[)\n if cx >= (title_quantity_x-title_quantity_width/2) and cx <= (title_quantity_x+title_quantity_width/2) and cy >= (y-19) and cy <= (y-19+h/1.5) then\n title_quantity_layer = buttonHover\n if getCursorPressed() then\n if sorting < 3 or sorting > 4 then sorting = 3\n elseif sorting == 3 then sorting = 4\n elseif sorting == 4 then sorting = 0\n end\n end\n end\n addBox(title_quantity_layer, title_quantity_x-title_quantity_width/2, y-19, title_quantity_width, h/1.5)\n setNextTextAlign(title_quantity_layer, AlignH_Center, AlignV_Bottom)\n addText(title_quantity_layer, small, title_quantity, title_quantity_x, y-5)\n end\n local title_percent_layer = storageBar\n local title_percent = 'STORAGE'\n local title_percent_width = 75\n if sorting >= 5 and sorting <= 6 then\n if sorting == 5 then\n title_percent_width = 105\n title_percent = 'STORAGE - ASC'\n elseif sorting == 6 then\n title_percent_width = 115\n title_percent = 'STORAGE - DESC'\n \n end\n title_percent_layer = buttonHover\n end\n if cx >= (rx-x+5-title_percent_width) and cx <= (rx-x+5) and cy >= (y-19) and cy <= (y-19+h/1.5) then\n title_percent_layer = buttonHover\n if getCursorPressed() then\n if sorting < 5 then sorting = 5\n elseif sorting == 5 then sorting = 6\n elseif sorting == 6 then sorting = 0\n end\n end\n end\n addBox(title_percent_layer, rx-x+5-title_percent_width, y-19, title_percent_width, h/1.5)\n setNextTextAlign(title_percent_layer, AlignH_Right, AlignV_Bottom)\n addText(title_percent_layer, small, title_percent, rx-x, y-5)\n end\n local pos_y = y+(h/2)-2\n if icon_path and images[icon_path] then\n addImage(imagesLayer, images[icon_path], x+10, y+font_size*.1, font_size*1.3, font_size*1.2)\n end\n setNextTextAlign(storageBar, AlignH_Left, AlignV_Middle)\n local n = title\n if ]] .. tostring(options.showTierOnName) .. [[ then\n n = 'T' .. tier .. ' / ' .. n\n end]]\n if options.showTierColors then\n rs = rs .. [[\n if tier == 1 then\n setNextFillColor(storageBar, ]] .. options.T1Color .. [[, 1)\n elseif tier == 2 then\n setNextFillColor(storageBar, ]] .. options.T2Color .. [[, 1)\n elseif tier == 3 then\n setNextFillColor(storageBar, ]] .. options.T3Color .. [[, 1)\n elseif tier == 4 then\n setNextFillColor(storageBar, ]] .. options.T4Color .. [[, 1)\n elseif tier == 5 then\n setNextFillColor(storageBar, ]] .. options.T5Color .. [[, 1)\n end]]\n end\n rs = rs .. [[\n addText(storageBar, itemName, n, x+20+font_size, pos_y)\n setNextFillColor(colorLayer, r, g, b, 1)\n addBox(colorLayer,x,y+h-3,w*(colorPercent)/100,3)\n if ]] .. tostring(options.showVolume) .. [[ then\n setNextTextAlign(storageDark, AlignH_Center, AlignV_Middle)\n local unit = 'L'\n if max >= 100000 then\n max = round(max/1000,]] .. options.VolumeRoundedDecimals .. [[)\n volume = round(volume/1000, ]] .. options.VolumeRoundedDecimals .. [[)\n unit='kL'\n end\n addText(storageDark, itemName, format_number(volume) .. ' ' .. unit .. ' / ' .. format_number(max) .. ' ' .. unit, x+(w*]] .. tostring(options.volumePosition/100) .. [[), pos_y)\n end\n if ]] .. tostring(options.showQuantity) .. [[ then\n setNextTextAlign(storageBar, AlignH_Center, AlignV_Middle)\n addText(storageBar, itemName, format_number(quantity), x+(w*]] .. tostring(options.quantityPosition/100) .. [[), pos_y)\n end\n setNextFillColor(colorLayer, r, g, b, 1)\n setNextTextAlign(colorLayer, AlignH_Right, AlignV_Middle)\n addText(colorLayer, itemName, format_number(percent) ..\"%\", rx-x-5, pos_y)\n end\n local main_title = 'STORAGE MONITORING v]] .. version .. [['\n if ]] .. tostring(options.verticalMode) .. [[ and screenTitle ~= nil and screenTitle ~= \"\" and screenTitle ~= \"-\" then\n main_title = 'v]] .. version .. [['\n end\n renderHeader(main_title, screenTitle)\n\n start_h = 75\n if screenTitle ~= nil and screenTitle ~= \"\" and screenTitle ~= \"-\" then\n start_h = 100\n end\n local sorted_items = {}\n for i,v in pairs(items) do\n table.insert(sorted_items, v)\n end\n if sorting == 1 then table.sort(sorted_items, function(a, b) return a[1] < b[1] end)\n elseif sorting == 2 then table.sort(sorted_items, function(a, b) return a[1] > b[1] end)\n elseif sorting == 3 then table.sort(sorted_items, function(a, b) return a[2] < b[2] end)\n elseif sorting == 4 then table.sort(sorted_items, function(a, b) return a[2] > b[2] end)\n elseif sorting == 5 then table.sort(sorted_items, function(a, b) return a[4] < b[4] end)\n elseif sorting == 6 then table.sort(sorted_items, function(a, b) return a[4] > b[4] end)\n end\n local h = font_size + font_size / 2\n local loadedImages = 0\n if data ~= {} then\n for _,item in ipairs(sorted_items) do\n if item[1] and images[item[5] ] == nil and loadedImages <= 15 then\n loadedImages = loadedImages + 1\n images[item[5] ] = loadImage(item[5])\n end\n end\n end\n for i,container in ipairs(sorted_items) do\n renderResistanceBar(container[1], container[8], container[2], container[3], container[7], container[4], container[5], container[6], 44, start_h, rx-88, h, i==1, i<=16)\n start_h = start_h+h+5\n end\n requestAnimationFrame(10)\n ]]\n return rs\nend\n\nlocal renderScript = getRenderScript()\n\nfor _,s in pairs(screens) do\n s.setRenderScript(renderScript)\nend\n\nelementsIdList = {}\nif core ~= nil then\n elementsIdList = core.getElementIdList()\nend\nstorageIdList= {}\ninitIndex = 0\ninitFinished = false\nscreens_displayed = false\n\n--Nested Coroutines by Jericho\ncoroutinesTable = {}\n--all functions here will become a coroutine\nMyCoroutines = {\n function()\n if not initFinished then\n system.print(\"Loading contructs elements (\" .. #elementsIdList .. \" elements detected)\")\n for i = 1, #elementsIdList, 1 do\n initIndex = i\n local id = elementsIdList[i]\n local elementType = core.getElementDisplayNameById(id):lower()\n if elementType:lower():find(\"container\") then\n table.insert(storageIdList, id)\n end\n if (i%options.maxAmountOfElementsLoadedByTick) == 0 then\n system.print(i .. ' elements scanned on ' .. #elementsIdList .. ' with ' .. #storageIdList .. \" identified\")\n coroutine.yield(coroutinesTable[1])\n end\n end\n if initIndex == #elementsIdList then\n system.print(#elementsIdList .. \" scanned with \" .. #storageIdList .. \" storage elements identified\")\n initFinished = true\n end\n end\n end,\n function()\n if not screens_displayed then\n local html = ''\n local storage_elements = {}\n for elemindex,id in ipairs(storageIdList) do\n local elementType = core.getElementDisplayNameById(id)\n if elementType:lower():find(\"container\") then\n local elementName = core.getElementNameById(id)\n if elementName:lower():find(prefixes[1]:lower())\n or elementName:lower():find(prefixes[2]:lower())\n or elementName:lower():find(prefixes[3]:lower())\n or elementName:lower():find(prefixes[4]:lower())\n or elementName:lower():find(prefixes[5]:lower())\n or elementName:lower():find(prefixes[6]:lower())\n or elementName:lower():find(prefixes[7]:lower())\n or elementName:lower():find(prefixes[8]:lower())\n or elementName:lower():find(prefixes[9]:lower())\n then\n local container = {}\n local splitted = strSplit(elementName, '_')\n local name = splitted[2]\n local ingredient = system.getItem(name)\n local container_size = \"XS\"\n local container_amount = 1\n local container_empty_mass = 0\n local container_volume = 0\n local contentQuantity = 0\n local percent_fill = 0\n if not elementType:lower():find(\"hub\") then\n local containerMaxHP = core.getElementMaxHitPointsById(id)\n if containerMaxHP > 68000 then\n container_size = \"XXL\"\n container_empty_mass = 88410\n container_volume = 512000 * (options.container_proficiency_lvl * 0.1) + 512000\n elseif containerMaxHP > 33000 then\n container_size = \"XL\"\n container_empty_mass = 44210\n container_volume = 256000 * (options.container_proficiency_lvl * 0.1) + 256000\n elseif containerMaxHP > 17000 then\n container_size = \"L\"\n container_empty_mass = 14842.7\n container_volume = 128000 * (options.container_proficiency_lvl * 0.1) + 128000\n elseif containerMaxHP > 7900 then\n container_size = \"M\"\n container_empty_mass = 7421.35\n container_volume = 64000 * (options.container_proficiency_lvl * 0.1) + 64000\n elseif containerMaxHP > 900 then\n container_size = \"S\"\n container_empty_mass = 1281.31\n container_volume = 8000 * (options.container_proficiency_lvl * 0.1) + 8000\n else\n container_size = \"XS\"\n container_empty_mass = 229.09\n container_volume = 1000 * (options.container_proficiency_lvl * 0.1) + 1000\n end\n else\n if splitted[3] then\n container_size = splitted[3]\n end\n if splitted[4] then\n container_amount = splitted[4]\n end\n local volume = 0\n container_volume_list = {xxl=512000, xl=256000, l=128000, m=64000, s=8000, xs=1000}\n container_size = container_size:lower()\n if container_volume_list[container_size] then\n volume = container_volume_list[container_size]\n end\n container_volume = (volume * options.container_proficiency_lvl * 0.1 + volume) * tonumber(container_amount)\n container_empty_mass = 55.8\n end\n local totalMass = core.getElementMassById(id)\n local contentMassKg = totalMass - container_empty_mass\n container.id = id\n container.itemid = ingredient.id\n container.realName = elementName\n container.prefix = splitted[1] .. \"_\"\n container.name = name\n container.ingredient = ingredient\n container.quantity = contentMassKg / (ingredient.unitMass - (ingredient.unitMass * (options.container_optimization_lvl * 0.05)))\n container.maxvolume = container_volume\n container.percent = utils.round((ingredient.unitVolume * container.quantity) * 100 / container_volume)\n if ingredient.name == \"InvalidItem\" then\n container.percent = 0\n container.quantity = 0\n end\n container.volume = container.quantity * ingredient.unitVolume\n if container.percent > 100 then container.percent = 100 end\n table.insert(storage_elements, container)\n end\n end\n if (elemindex%options.maxAmountOfElementsRefreshedByTick) == 0 then\n coroutine.yield(coroutinesTable[2])\n end\n end\n \n -- group by name and screen\n local groupped = {}\n if groupByItemName then\n for _,v in pairs(storage_elements) do\n local prefix = v.prefix:lower()\n if groupped[prefix .. v.itemid] then\n groupped[prefix .. v.itemid].quantity = groupped[prefix .. v.itemid].quantity + v.quantity\n groupped[prefix .. v.itemid].volume = groupped[prefix .. v.itemid].volume + v.volume\n groupped[prefix .. v.itemid].maxvolume = groupped[prefix .. v.itemid].maxvolume + v.maxvolume\n groupped[prefix .. v.itemid].percent = groupped[prefix .. v.itemid].volume * 100 / groupped[prefix .. v.itemid].maxvolume\n else\n groupped[prefix .. v.itemid] = v\n end\n end\n else\n groupped = storage_elements\n end\n \n -- sorting by tier\n local tiers = {}\n tiers[1] = {} --tier 0 (thx to Belorion#3127 for pointing Oxygen and Hydrogen are Tier 0 and not 1)\n tiers[2] = {} --tier 1\n tiers[3] = {} --tier 2\n tiers[4] = {} --tier 3\n tiers[5] = {} --tier 4\n tiers[6] = {} --tier 5\n \n for _,v in pairs(groupped) do\n table.insert(tiers[v.ingredient.tier+1],v)\n end\n \n -- sorting by name\n for k,v in pairs(tiers) do\n table.sort(tiers[k], function(a,b) return a.ingredient.locDisplayNameWithSize:lower() < b.ingredient.locDisplayNameWithSize:lower() end)\n end\n \n if #screens > 0 and not screens_displayed then\n for index, screen in pairs(screens) do\n local prefix = prefixes[index]\n local title = titles[index]\n local refreshScreen=true\n local i = 1\n local items_data_for_screen = {}\n for tier_k,tier in pairs(tiers) do\n for _,container in pairs(tier) do\n if container.prefix:lower():find(prefix:lower()) then\n local item_name = container.ingredient.locDisplayNameWithSize\n if container.ingredient.name == 'InvalidItem' then\n item_name = 'Invalid Item Id'\n end\n local storage_data = {\n item_name,\n utils.round(container.quantity * (10 ^ options.QuantityRoundedDecimals)) / (10 ^ options.QuantityRoundedDecimals),\n utils.round(container.volume),\n utils.round(container.percent * (10 ^ options.PercentRoundedDecimals)) / (10 ^ options.PercentRoundedDecimals),\n container.ingredient.iconPath,\n title,\n refreshScreen,\n container.ingredient.id,\n screens_displayed,\n utils.round(container.maxvolume),\n i,\n container.ingredient.tier,\n }\n table.insert(items_data_for_screen,storage_data)\n local to_send=json.encode(storage_data)\n screen.setScriptInput(to_send)\n refreshScreen = false\n while tonumber(screen.getScriptOutput()) ~= i do\n coroutine.yield(coroutinesTable[2])\n end\n i = i+1\n end\n end\n end\n local str_data = '{'\n for i,v in ipairs(items_data_for_screen) do\n str_data = str_data .. '{\"' .. tostring(v[1]) .. '\",' .. tostring(v[2]) .. ',' .. tostring(v[3]) .. ',' .. tostring(v[4]) .. ',\"' .. tostring(v[5]) .. '\",' .. tostring(v[8]) .. ',' .. tostring(v[10]) .. ',' .. tostring(v[12]) .. '}'\n if i < #items_data_for_screen then str_data = str_data .. ',' end\n end\n str_data = str_data .. '}'\n local fullRS = getRenderScript(str_data, title)\n if fullRS:len() < 50000 then --if all can stay on screen then\n screen.setRenderScript(fullRS) \n end\n end\n screens_displayed = true\n end\n unit.exit()\n coroutine.yield(coroutinesTable[2])\n else\n coroutine.yield(coroutinesTable[2])\n end\n end\n}\n\nfunction initCoroutines()\n for _,f in pairs(MyCoroutines) do\n local co = coroutine.create(f)\n table.insert(coroutinesTable, co)\n end\nend\n\ninitCoroutines()\n\nrunCoroutines = function()\n for i,co in ipairs(coroutinesTable) do\n if coroutine.status(co) == \"dead\" then\n coroutinesTable[i] = coroutine.create(MyCoroutines[i])\n end\n if coroutine.status(co) == \"suspended\" then\n assert(coroutine.resume(co))\n end\n end\nend\n\nMainCoroutine = coroutine.create(runCoroutines)\n\nsystem.showScreen(true)","filter":{"args":[],"signature":"onStart()","slotKey":"-1"},"key":"1"},{"code":"if coroutine.status(MainCoroutine) == \"dead\" then\n MainCoroutine = coroutine.create(runCoroutines)\nend\nif coroutine.status(MainCoroutine) == \"suspended\" then\n assert(coroutine.resume(MainCoroutine))\nend","filter":{"args":[],"signature":"onUpdate()","slotKey":"-4"},"key":"2"}],"methods":[],"events":[]} \ No newline at end of file diff --git a/source/unit/onStart.lua b/source/unit/onStart.lua index 5da4267..d802ae7 100644 --- a/source/unit/onStart.lua +++ b/source/unit/onStart.lua @@ -54,7 +54,7 @@ defaultSorting = "none" --export: the default sorting of items on the screen: "n INIT ]] -local version = '4.9.0' +local version = '4.10.0' system.print("----------------------------------") system.print("DU-Storage-Monitoring version " .. version) @@ -210,7 +210,7 @@ function getRenderScript(data, screenTitle) if sorting == nil then sorting = ]] .. sorting .. [[ end ]] if data == nil then - rs = rs .. [[local json = require('dkjson') + rs = rs .. [[local json = require('json') local input = getInput() or json.encode(nil) local data = json.decode(input) if data ~= nil and data[7] then @@ -349,6 +349,7 @@ function getRenderScript(data, screenTitle) elseif sorting == 2 then title_item_width = 95 title_item = 'ITEMS - DESC' + end title_item_layer = buttonHover end @@ -406,6 +407,7 @@ function getRenderScript(data, screenTitle) elseif sorting == 6 then title_percent_width = 115 title_percent = 'STORAGE - DESC' + end title_percent_layer = buttonHover end @@ -431,8 +433,8 @@ function getRenderScript(data, screenTitle) if ]] .. tostring(options.showTierOnName) .. [[ then n = 'T' .. tier .. ' / ' .. n end]] - if options.showTierColors then - rs = rs .. [[ + if options.showTierColors then + rs = rs .. [[ if tier == 1 then setNextFillColor(storageBar, ]] .. options.T1Color .. [[, 1) elseif tier == 2 then @@ -444,8 +446,8 @@ function getRenderScript(data, screenTitle) elseif tier == 5 then setNextFillColor(storageBar, ]] .. options.T5Color .. [[, 1) end]] - end - rs = rs .. [[ + end + rs = rs .. [[ addText(storageBar, itemName, n, x+20+font_size, pos_y) setNextFillColor(colorLayer, r, g, b, 1) addBox(colorLayer,x,y+h-3,w*(colorPercent)/100,3) @@ -642,7 +644,7 @@ MyCoroutines = { coroutine.yield(coroutinesTable[2]) end end - + -- group by name and screen local groupped = {} if groupByItemName then @@ -660,7 +662,7 @@ MyCoroutines = { else groupped = storage_elements end - + -- sorting by tier local tiers = {} tiers[1] = {} --tier 0 (thx to Belorion#3127 for pointing Oxygen and Hydrogen are Tier 0 and not 1) @@ -669,16 +671,16 @@ MyCoroutines = { tiers[4] = {} --tier 3 tiers[5] = {} --tier 4 tiers[6] = {} --tier 5 - + for _,v in pairs(groupped) do table.insert(tiers[v.ingredient.tier+1],v) end - + -- sorting by name for k,v in pairs(tiers) do table.sort(tiers[k], function(a,b) return a.ingredient.locDisplayNameWithSize:lower() < b.ingredient.locDisplayNameWithSize:lower() end) end - + if #screens > 0 and not screens_displayed then for index, screen in pairs(screens) do local prefix = prefixes[index] @@ -726,7 +728,7 @@ MyCoroutines = { str_data = str_data .. '}' local fullRS = getRenderScript(str_data, title) if fullRS:len() < 50000 then --if all can stay on screen then - screen.setRenderScript(fullRS) + screen.setRenderScript(fullRS) end end screens_displayed = true @@ -761,4 +763,4 @@ end MainCoroutine = coroutine.create(runCoroutines) -system.showScreen(true) +system.showScreen(true) \ No newline at end of file