diff --git a/README.md b/README.md index c8ec2bf..d5653a5 100644 --- a/README.md +++ b/README.md @@ -80,11 +80,13 @@ By rightclicking on the board, advanced, edit lua parameters, you can customize - `containerProficiencyLvl`: Talent level for Container Proficiency - `containerOptimizationLvl`: Talent level for Container Optimization - `groupByItemName`: if enabled, this will group all entries with the same item name (enabled by default) +- `VolumeRoundedDecimals`: maximum of decimals displayed for the volume value - `QuantityRoundedDecimals`: maximum of decimals displayed for the quantity value - `PercentRoundedDecimals`: maximum of decimals displayed for the percent fill value - `fontSize`: the size of the text for all the screens - `maxAmountOfElementsLoadedByTick`: the maximum number of element loaded by tick of the coroutine on script startup (lower that value if you encounter cpu load errors on startup, default to 5000) - `maxAmountOfElementsRefreshedByTick`: the maximum number of element refreshed by tick of the coroutine when refreshing values (lower that value if you have cpu load errors after all emlements are loaded, default to 200) +- `showTierOnName`: show the tier of the item with the item name - `showVolume`: show or hide the column Volume - `volumePosition`: the position in percent of width for the column Volume - `showQuantity`: show or hide the column Quantity diff --git a/config.json b/config.json index cee6e8c..928656a 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\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\nshowVolume = true --export: show or hide the column Volume\nvolumePosition= 50 --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 = false --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.7.1'\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.QuantityRoundedDecimals = QuantityRoundedDecimals\noptions.PercentRoundedDecimals = PercentRoundedDecimals\noptions.fontSize = fontSize\noptions.maxAmountOfElementsLoadedByTick = maxAmountOfElementsLoadedByTick\noptions.maxAmountOfElementsRefreshedByTick = maxAmountOfElementsRefreshedByTick\noptions.showVolume = showVolume\noptions.volumePosition = volumePosition\noptions.showQuantity = showQuantity\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]}\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 then return utils.round(a/b)*b end;return a>=0 and math.floor(a+0.5)or math.ceil(a-0.5)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, 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 addText(storageBar, itemName, title, 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 addText(storageDark, itemName, format_number(volume) .. ' L /' .. format_number(max) .. ' L', 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[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 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.name:lower() < b.ingredient.name: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 }\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]) .. '}'\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":[]}}}} +{"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\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.8.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.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(showTierOnName) .. [[ then\n n = 'T' .. tier .. ' / ' .. n\n end\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 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.name:lower() < b.ingredient.name: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":[]}}}} diff --git a/source/unit/onStart.lua b/source/unit/onStart.lua index 121a682..4814ae7 100644 --- a/source/unit/onStart.lua +++ b/source/unit/onStart.lua @@ -27,18 +27,20 @@ containerProficiencyLvl = 5 --export: Talent level for Container Proficiency containerOptimizationLvl = 5 --export: Talent level for Container Optimization groupByItemName = true --export: if enabled, this will group all entries with the same item name +VolumeRoundedDecimals = 2 --export: maximum of decimals displayed for the volume value QuantityRoundedDecimals = 2 --export: maximum of decimals displayed for the quantity value PercentRoundedDecimals = 2 --export: maximum of decimals displayed for the percent fill value fontSize = 15 --export: the size of the text for all the screen maxAmountOfElementsLoadedByTick = 5000 --export: the maximum number of element loaded by tick of the coroutine on script startup maxAmountOfElementsRefreshedByTick = 200 --export: the maximum number of element refreshed by tick of the coroutine when refreshing values +showTierOnName = true --export: show the tier of the item with the item name showVolume = true --export: show or hide the column Volume -volumePosition= 50 --export: the position in percent of width for the column Volume +volumePosition= 55 --export: the position in percent of width for the column Volume showQuantity = true --export: show or hide the column Quantity quantityPosition= 75 --export: the position in percent of width for the column Quantity -verticalMode = false --export: rotate the screen 90deg (bottom on right) +verticalMode = true --export: rotate the screen 90deg (bottom on right) verticalModeBottomSide = "right" --export: when vertical mode is enabled, on which side the bottom of the screen is positioned ("left" or "right") defaultSorting = "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 @@ -46,7 +48,7 @@ defaultSorting = "none" --export: the default sorting of items on the screen: "n INIT ]] -local version = '4.7.1' +local version = '4.8.0' system.print("----------------------------------") system.print("DU-Storage-Monitoring version " .. version) @@ -74,6 +76,7 @@ options.screenTitle9 = screenTitle9 options.container_proficiency_lvl = containerProficiencyLvl options.container_optimization_lvl = containerOptimizationLvl options.groupByItemName = groupByItemName +options.VolumeRoundedDecimals = VolumeRoundedDecimals options.QuantityRoundedDecimals = QuantityRoundedDecimals options.PercentRoundedDecimals = PercentRoundedDecimals options.fontSize = fontSize @@ -82,6 +85,7 @@ options.maxAmountOfElementsRefreshedByTick = maxAmountOfElementsRefreshedByTick options.showVolume = showVolume options.volumePosition = volumePosition options.showQuantity = showQuantity +options.showTierOnName = showTierOnName options.quantityPosition = quantityPosition options.verticalMode = verticalMode options.verticalModeBottomSide = verticalModeBottomSide @@ -217,7 +221,7 @@ function getRenderScript(data, screenTitle) ]] if data == nil then rs = rs .. [[if data ~= {} and data ~= nil then - items[data[11] ] = {data[1],data[2],data[3],data[4],data[5],data[8],data[10]} + items[data[11] ] = {data[1],data[2],data[3],data[4],data[5],data[8],data[10],data[12]} setOutput(#items) data = nil end @@ -261,7 +265,7 @@ function getRenderScript(data, screenTitle) setDefaultFillColor( front,Shape_Box,0.075,0.125,0.156,1) setDefaultFillColor( front,Shape_Text,0.710,0.878,0.941,1) 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 - function round(a,b)if b then return utils.round(a/b)*b end;return a>=0 and math.floor(a+0.5)or math.ceil(a-0.5)end + function round(a,b)if b==nil then b=0 end;return math.floor(a*10^b+0.5)/10^b end 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 function renderHeader(title, subtitle) local h_factor = 12 @@ -315,7 +319,7 @@ function getRenderScript(data, screenTitle) setLayerTranslation(storageDark, tx, ty) setLayerRotation(storageDark, math.rad(r)) end - function renderResistanceBar(title, quantity, volume, max, percent, icon_path, item_id, x, y, w, h, withTitle, withIcon) + function renderResistanceBar(title, tier, quantity, volume, max, percent, icon_path, item_id, x, y, w, h, withTitle, withIcon) local colorPercent = percent if percent > 100 then colorPercent = 100 end 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) @@ -411,12 +415,22 @@ function getRenderScript(data, screenTitle) addImage(imagesLayer, images[icon_path], x+10, y+font_size*.1, font_size*1.3, font_size*1.2) end setNextTextAlign(storageBar, AlignH_Left, AlignV_Middle) - addText(storageBar, itemName, title, x+20+font_size, pos_y) + local n = title + if ]] .. tostring(showTierOnName) .. [[ then + n = 'T' .. tier .. ' / ' .. n + end + 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) if ]] .. tostring(options.showVolume) .. [[ then setNextTextAlign(storageDark, AlignH_Center, AlignV_Middle) - addText(storageDark, itemName, format_number(volume) .. ' L /' .. format_number(max) .. ' L', x+(w*]] .. tostring(options.volumePosition/100) .. [[), pos_y) + local unit = 'L' + if max >= 100000 then + max = round(max/1000,]] .. options.VolumeRoundedDecimals .. [[) + volume = round(volume/1000, ]] .. options.VolumeRoundedDecimals .. [[) + unit='kL' + end + addText(storageDark, itemName, format_number(volume) .. ' ' .. unit .. ' / ' .. format_number(max) .. ' ' .. unit, x+(w*]] .. tostring(options.volumePosition/100) .. [[), pos_y) end if ]] .. tostring(options.showQuantity) .. [[ then setNextTextAlign(storageBar, AlignH_Center, AlignV_Middle) @@ -458,7 +472,7 @@ function getRenderScript(data, screenTitle) end end for i,container in ipairs(sorted_items) do - renderResistanceBar(container[1], container[2], container[3], container[7], container[4], container[5], container[6], 44, start_h, rx-88, h, i==1, i<=16) + 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) start_h = start_h+h+5 end requestAnimationFrame(10) @@ -662,7 +676,8 @@ MyCoroutines = { container.ingredient.id, screens_displayed, utils.round(container.maxvolume), - i + i, + container.ingredient.tier, } table.insert(items_data_for_screen,storage_data) local to_send=json.encode(storage_data) @@ -677,7 +692,7 @@ MyCoroutines = { end local str_data = '{' for i,v in ipairs(items_data_for_screen) do - 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]) .. '}' + 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]) .. '}' if i < #items_data_for_screen then str_data = str_data .. ',' end end str_data = str_data .. '}'