--[[-- Gui Module - Science Info - Adds a science info gui that shows production usage and net for the different science packs as well as an eta @gui Science-Info @alias science_info ]] local Gui = require 'expcore.gui' --- @dep expcore.gui local Event = require 'utils.event' --- @dep utils.event local format_time = ext_require('expcore.common','format_time') --- @dep expcore.common local config = require 'config.science' --- @dep config.science local Production = require 'modules.control.production' --- @dep modules.control.production local null_time_short = {'science-info.eta-time',format_time(0,{hours=true,minutes=true,seconds=true,time=true,null=true})} local null_time_long = format_time(0,{hours=true,minutes=true,seconds=true,long=true,null=true}) --[[ Generates the main structure for the gui element > container >> header >> scroll >>> non_made >>> table >> footer (when eta is enabled) >>> eta-label >>> eta >>>> label ]] local function generate_container(element) Gui.set_padding(element,1,2,2,2) element.style.minimal_width = 200 -- main container which contains the other elements local container = element.add{ name='container', type='frame', direction='vertical', style='window_content_frame_packed' } Gui.set_padding(container) -- main header for the gui Gui.create_header( container, {'science-info.main-caption'}, {'science-info.main-tooltip'} ) -- table that stores all the data local flow_table = Gui.create_scroll_table(container,4,185) -- message to say that you have not made any packs yet local non_made = flow_table.parent.add{ name='non_made', type='label', caption={'science-info.no-packs'} } non_made.style.width = 200 non_made.style.single_line = false local eta if config.show_eta then -- footer used to store the eta local footer = container.add{ name='footer', type='frame', style='subheader_frame' } Gui.set_padding(footer,2,2,4,4) footer.style.horizontally_stretchable = true -- label for the footer footer.add{ name='eta-label', type='label', caption={'science-info.eta-caption'}, tooltip={'science-info.eta-tooltip'}, style='heading_1_label' } -- data for the footer local right_align = Gui.create_alignment(footer,'eta') eta = right_align.add{ name='label', type='label', caption=null_time_short, tooltip=null_time_long, style='heading_1_label' } end return flow_table, eta end --[[ Adds two labels where one is right aligned and the other is a unit element > "name" >> label > spm-"name" ]] local function add_data_label(element,name,value,secondary,tooltip) local data_colour = Production.get_color(config.color_clamp, value, secondary) local surfix,caption = Production.format_number(value) if element[name] then local data = element[name].label data.caption = caption data.tooltip = tooltip data.style.font_color = data_colour local label = element['spm-'..name] label.caption = {'science-info.unit',surfix} label.tooltip = tooltip label.style.font_color = data_colour else -- right aligned number local right_align = Gui.create_alignment(element,name) local data = right_align.add{ name='label', type='label', caption=caption, tooltip=tooltip } data.style.font_color = data_colour -- adds the unit onto the end local label = element.add{ name='spm-'..name, type='label', caption={'science-info.unit',surfix}, tooltip=tooltip } label.style.font_color = data_colour end end --[[ Adds a science pack to the list element > icon-"science_pack" > delta-"science_pack" >> table >>> pos-"science_pack" (add_data_label) >>> neg-"science_pack" (add_data_label) > net-"science_pack" (add_data_label) ]] local function generate_science_pack(player,element,science_pack) local total = Production.get_production_total(player.force, science_pack) local minute = Production.get_production(player.force, science_pack, defines.flow_precision_index.one_minute) if total.made > 0 then element.parent.non_made.visible = false local icon_style = 'quick_bar_slot_button' local flux = Production.get_fluctuations(player.force, science_pack, defines.flow_precision_index.one_minute) if flux.net > -config.color_flux/2 then icon_style = 'green_slot_button' elseif flux.net < -config.color_flux then icon_style = 'red_slot_button' elseif minute.made > 0 then icon_style = 'selected_slot_button' end local icon = element['icon-'..science_pack] if icon then icon.style = icon_style icon.style.height = 55 if icon_style == 'quick_bar_slot_button' then icon.style.width = 36 Gui.set_padding(icon,0,0,-2,-2) end else icon = element.add{ name='icon-'..science_pack, type='sprite-button', sprite='item/'..science_pack, tooltip={'item-name.'..science_pack}, style=icon_style } icon.style.height = 55 if icon_style == 'quick_bar_slot_button' then icon.style.width = 36 Gui.set_padding(icon,0,0,-2,-2) end end local delta = element['delta-'..science_pack] if not delta then delta = element.add{ name='delta-'..science_pack, type='frame', style='bordered_frame' } Gui.set_padding(delta,0,0,3,3) local delta_table = delta.add{ name='table', type='table', column_count=2 } Gui.set_padding(delta_table) end add_data_label(delta.table,'pos-'..science_pack,minute.made,nil,{'science-info.pos-tooltip',total.made}) add_data_label(delta.table,'neg-'..science_pack,-minute.used,nil,{'science-info.neg-tooltip',total.used}) add_data_label(element,'net-'..science_pack,minute.net,minute.made+minute.used,{'science-info.net-tooltip',total.net}) end end --- Updates the eta label that was created with generate_container local function update_eta(player,element) if not config.show_eta then return end local force = player.force local research = force.current_research if not research then element.caption = null_time_short element.tooltip = null_time_long else local progress = force.research_progress local remaining = research.research_unit_count*(1-progress) local limit local stats = player.force.item_production_statistics for _,ingredient in pairs(research.research_unit_ingredients) do local pack_name = ingredient.name local required = ingredient.amount * remaining local time = Production.get_consumsion_eta(force, pack_name, defines.flow_precision_index.one_minute, required) if not limit or limit < time then limit = time end end if not limit or limit == -1 then element.caption = null_time_short element.tooltip = null_time_long else element.caption = {'science-info.eta-time',format_time(limit,{hours=true,minutes=true,seconds=true,time=true})} element.tooltip = format_time(limit,{hours=true,minutes=true,seconds=true,long=true}) end end end --- Registers the science info -- @element science_info local science_info = Gui.new_left_frame('gui/science-info') :set_sprites('entity/lab') :set_direction('vertical') :set_tooltip{'science-info.main-tooltip'} :on_creation(function(player,element) local table, eta = generate_container(element) for _,science_pack in ipairs(config) do generate_science_pack(player,table,science_pack) end update_eta(player,eta) end) :on_update(function(player,element) local container = element.container local table = container.scroll.table local eta = container.footer.eta.label for _,science_pack in ipairs(config) do generate_science_pack(player,table,science_pack) end update_eta(player,eta) end) --- Updates the gui every 1 second Event.on_nth_tick(60,science_info 'update_all') return science_info