diff --git a/exp_scenario/module/gui/vlayer.lua b/exp_scenario/module/gui/vlayer.lua index 7ff088bb..f56b7e31 100644 --- a/exp_scenario/module/gui/vlayer.lua +++ b/exp_scenario/module/gui/vlayer.lua @@ -15,8 +15,11 @@ local SelectArea = Selection.connect("ExpGui_Vlayer") local floor = math.floor local ceil = math.ceil local max = math.max +local min = math.min local format_string = string.format +local gui_width = 500 + --- @class ExpGui_Vlayer.elements local Elements = {} @@ -32,7 +35,7 @@ end --- Statistics shown as progress bars, in display order --- @type { name: string, caption: LocalisedString, tooltip: LocalisedString }[] local stats = {} -for _, name in ipairs{ "sustained", "production", "capacity", "surface-area" } do +for _, name in ipairs{ "sustained", "production", "capacity", "limit", "surface-area" } do stats[#stats + 1] = { name = name, caption = { "exp-gui_vlayer.caption-stat-" .. name }, @@ -89,7 +92,7 @@ Elements.stat_label = Gui.define("vlayer/stat_label") style = "heading_2_label", } :style{ - width = 250, + width = gui_width / 2, } --[[@as any]] --- Bar showing a statistic as a fraction with the values as its caption @@ -103,7 +106,7 @@ Elements.stat_bar = Gui.define("vlayer/stat_bar") style = "electric_satisfaction_statistics_progressbar", } :style{ - width = 250, + width = gui_width / 2, font = "heading-2", } --[[@as any]] @@ -129,7 +132,7 @@ Elements.stats_table = Gui.define("vlayer/stats_table") :track_all_elements() :draw(function(def, parent) --- @cast def ExpGui_Vlayer.elements.stats_table - local stats_table = Gui.elements.scroll_table(parent, 400, 2, "stats") + local stats_table = Gui.elements.scroll_table(parent, gui_width, 2, "stats") local stat_bars = {} for _, stat in ipairs(stats) do Elements.stat_label(stats_table, stat.caption, stat.tooltip) @@ -140,14 +143,16 @@ Elements.stats_table = Gui.define("vlayer/stats_table") end) --[[@as any]] --- Calculate the display data of every statistic, the same for every player +--- @param s_index number Surface index --- @return table -function Elements.stats_table.calculate_display_data() - local statistics = Vlayer.get_statistics(game.surfaces["nauvis"].index) - local items = Vlayer.get_items(game.surfaces["nauvis"].index) - local allocated = Vlayer.get_allocated_items(game.surfaces["nauvis"].index) +function Elements.stats_table.calculate_display_data(s_index) + local statistics = Vlayer.get_statistics(s_index) + local items = Vlayer.get_items(s_index) + local allocated = Vlayer.get_allocated_items(s_index) local sustained = ceil(statistics.energy_sustained) / max(statistics.energy_total_production, 1) local production = ceil(statistics.energy_production) / max(ceil(statistics.energy_max), 1) local capacity = statistics.energy_storage / max(statistics.energy_capacity, 1) + local limit = statistics.energy_input_limit / max(statistics.energy_output_limit, 1) local surface_area = statistics.remaining_surface_area / max(statistics.total_surface_area, 1) return { sustained = { @@ -165,8 +170,13 @@ function Elements.stats_table.calculate_display_data() caption = format_energy(statistics.energy_storage, "J") .. " / " .. format_energy(statistics.energy_capacity, "J"), tooltip = format_string("%.1f %%", capacity * 100), }, + limit = { + value = min(limit, 1), + caption = format_energy(statistics.energy_input_limit, "W") .. " / " .. format_energy(statistics.energy_output_limit, "W"), + tooltip = format_string("%.1f %%", limit * 100), + }, ["surface-area"] = { - value = math.min(math.max(surface_area / 0.1, 0), 1), + value = min(max(surface_area / 0.1, 0), 1), caption = format_number(statistics.remaining_surface_area, false), tooltip = format_string("%.1f %%", surface_area * 100), }, @@ -184,12 +194,44 @@ end --- Refresh the tables of every online player function Elements.stats_table.refresh_online() - local display_data = Elements.stats_table.calculate_display_data() + local elements = Elements.controls.data[controls] + local display_data = Elements.stats_table.calculate_display_data(game.surfaces[elements.surface_dropdown.items[elements.surface_dropdown.selected_index]].index) for _, stats_table in Elements.stats_table:online_elements() do Elements.stats_table.refresh(stats_table, display_data) end end +--- Dropdown listing the surfaces available in vlayer +--- @class ExpGui_Vlayer.elements.surface_dropdown: ExpElement +--- @overload fun(parent: LuaGuiElement, controls: LuaGuiElement): LuaGuiElement +Elements.surface_dropdown = Gui.define("vlayer/surface_dropdown") + :draw{ + type = "drop-down", + } + :style{ + width = gui_width / 2, + } + :element_data{ + controls = Gui.from_argument(1), + } + :on_selection_state_changed(function(def, _, surface_dropdown) + --- @cast def ExpGui_Vlayer.elements.type_dropdown + Elements.controls.refresh_interfaces(def.data[surface_dropdown].controls) + end) --[[@as any]] + +--- Refresh the listed interfaces +--- @param surface_dropdown LuaGuiElement +--- @param surfaces LuaSurface[] +function Elements.surface_dropdown.refresh(surface_dropdown, surfaces) + local items = {} + local index = 1 + for _, surface in pairs(surfaces) do + items[index] = surface.name + index = index + 1 + end + surface_dropdown.items = items +end + --- @class ExpGui_Vlayer.elements.type_dropdown.element_data --- @field controls LuaGuiElement @@ -204,7 +246,7 @@ Elements.type_dropdown = Gui.define("vlayer/type_dropdown") selected_index = 1, } :style{ - width = 250, + width = gui_width / 2, } :element_data{ controls = Gui.from_argument(1), @@ -229,7 +271,7 @@ Elements.interface_dropdown = Gui.define("vlayer/interface_dropdown") type = "drop-down", } :style{ - width = 250, + width = gui_width / 2, } :element_data{ controls = Gui.from_argument(1), @@ -267,6 +309,30 @@ function Elements.interface_dropdown.get_selected(interface_dropdown, interfaces return nil end +--- Button which opens the map at the selected interface +--- @class ExpGui_Vlayer.elements.view_button: ExpElement +--- @field data table +--- @overload fun(parent: LuaGuiElement, controls: LuaGuiElement): LuaGuiElement +Elements.view_button = Gui.define("vlayer/view_button") + :draw{ + type = "button", + caption = { "exp-gui_vlayer.caption-view" }, + } + :style{ + width = gui_width / 2, + } + :element_data{ + controls = Gui.from_argument(1), + } + :on_click(function(def, player, view_button) + --- @cast def ExpGui_Vlayer.elements.view_button + local controls = def.data[view_button].controls + local interface_type, interface = Elements.controls.get_selected_interface(controls) + if not interface then return end + player.set_controller{ type = defines.controllers.remote, position = interface.position, surface = interface.surface } + player.print{ "exp-gui_vlayer.message-located", type_captions[interface_type], gps_string(interface.position, interface.surface) } + end) --[[@as any]] + --- @class ExpGui_Vlayer.elements.control_button.element_data --- @field controls LuaGuiElement @@ -280,7 +346,7 @@ Elements.build_button = Gui.define("vlayer/build_button") caption = { "exp-gui_vlayer.caption-build" }, } :style{ - width = 250, + width = gui_width / 2, } :on_click(function(_, player) if SelectArea:stop(player) then @@ -302,7 +368,7 @@ Elements.remove_button = Gui.define("vlayer/remove_button") caption = { "exp-gui_vlayer.caption-remove" }, } :style{ - width = 250, + width = gui_width / 2, } :element_data{ controls = Gui.from_argument(1), @@ -330,16 +396,19 @@ Elements.controls = Gui.define("vlayer/controls") :track_all_elements() :draw(function(def, parent) --- @cast def ExpGui_Vlayer.elements.controls - local controls = Gui.elements.scroll_table(parent, 500, 2, "controls") + local controls = Gui.elements.scroll_table(parent, gui_width, 2, "controls") local player = Gui.get_player(parent) local can_edit = Roles.player_has_permission(player, "exp_scenario.gui.vlayer_edit") + local surface_dropdown = Elements.surface_dropdown(controls, controls) local type_dropdown = Elements.type_dropdown(controls, controls) local interface_dropdown = Elements.interface_dropdown(controls, controls) + Elements.view_button(controls, controls) Elements.build_button(controls).visible = can_edit Elements.remove_button(controls, controls).visible = can_edit def.data[controls] = { + surface_dropdown = surface_dropdown, type_dropdown = type_dropdown, interface_dropdown = interface_dropdown, } @@ -360,7 +429,7 @@ end function Elements.controls.get_selected_interface(controls) local elements = Elements.controls.data[controls] local interface_type = Elements.type_dropdown.get_selected(elements.type_dropdown) - local interfaces = Vlayer.get_interfaces(game.surfaces["nauvis"].index)[interface_type] + local interfaces = Vlayer.get_interfaces(elements.surface_dropdown.items[elements.surface_dropdown.selected_index])[interface_type] return interface_type, Elements.interface_dropdown.get_selected(elements.interface_dropdown, interfaces) end @@ -369,7 +438,7 @@ end function Elements.controls.refresh_interfaces(controls) local elements = Elements.controls.data[controls] local interface_type = Elements.type_dropdown.get_selected(elements.type_dropdown) - Elements.interface_dropdown.refresh(elements.interface_dropdown, Vlayer.get_interfaces(game.surfaces["nauvis"].index)[interface_type]) + Elements.interface_dropdown.refresh(elements.interface_dropdown, Vlayer.get_interfaces(game.surfaces[elements.surface_dropdown.items[elements.surface_dropdown.selected_index]].index)[interface_type]) end --- Refresh the listed interfaces of every online player, used when an interface is built or removed @@ -396,10 +465,11 @@ end --- @overload fun(parent: LuaGuiElement): LuaGuiElement Elements.container = Gui.define("vlayer/container") :draw(function(_, parent) - local container = Gui.elements.container(parent, 400) + local container = Gui.elements.container(parent, gui_width) local stats_table = Elements.stats_table(container) - Elements.stats_table.refresh(stats_table, Elements.stats_table.calculate_display_data()) Elements.controls(container) + local elements = Elements.controls.data[controls] + Elements.stats_table.refresh(stats_table, Elements.stats_table.calculate_display_data(game.surfaces[elements.surface_dropdown.items[elements.surface_dropdown.selected_index]].index)) return Gui.elements.container.get_root_element(container) end) --[[@as any]] @@ -443,7 +513,7 @@ local function on_area_selected(event) return end - if config.interface_limit[interface_type] >= 0 and #Vlayer.get_interfaces(game.surfaces["nauvis"].index)[interface_type] >= config.interface_limit[interface_type] then + if config.interface_limit[interface_type] >= 0 and #Vlayer.get_interfaces(surface.index)[interface_type] >= config.interface_limit[interface_type] then player.print({ "exp-gui_vlayer.message-limit", type_captions[interface_type] }, Colors.orange_red) return end @@ -478,11 +548,11 @@ local function refresh_player_permissions(event) end --- Refresh the dropdown list when surface is updated -local function update_surface(event) +local function update_surface() -- global surface will have its data point to the main surface - if config.global_surface then - return - end + if config.global_surface then return end + local elements = Elements.controls.data[controls] + Elements.surface_dropdown.refresh(elements.surface_dropdown, game.surfaces) end local e = defines.events @@ -494,6 +564,11 @@ return feature:guard{ [e.on_surface_created] = update_surface, [e.on_surface_renamed] = update_surface, [e.on_surface_imported] = update_surface, + [Feature.events.on_config_updated] = function(event) + if event.feature_name == feature.name and event.path == "global_surface" then + update_surface() + end + end, }, on_nth_tick = { [60] = Elements.stats_table.refresh_online, diff --git a/exp_scenario/module/locale/en.cfg b/exp_scenario/module/locale/en.cfg index 573dcc83..1d4adc2d 100644 --- a/exp_scenario/module/locale/en.cfg +++ b/exp_scenario/module/locale/en.cfg @@ -470,23 +470,20 @@ caption-view-footer=Task details [exp-gui_vlayer] tooltip-main=Virtual Layer selection-name=vlayer -caption-stat-solar=[img=entity/solar-panel] Solar Panels -tooltip-stat-solar=Solar panels in use out of those stored -caption-stat-accumulator=[img=entity/accumulator] Accumulators -tooltip-stat-accumulator=Accumulators in use out of those stored -caption-stat-surface-area=[virtual-signal=signal-R] Remaining Surface -tooltip-stat-surface-area=Remaining surface area, insert landfill to increase it caption-stat-sustained=[virtual-signal=signal-S] Sustained Production tooltip-stat-sustained=Power production averaged over a day, out of what every stored solar panel could give caption-stat-production=[virtual-signal=signal-P] Current Production tooltip-stat-production=Power production right now, out of the production in full daylight caption-stat-capacity=[virtual-signal=signal-E] Battery Charge tooltip-stat-capacity=Stored energy out of the accumulator capacity +caption-stat-limit=[virtual-signal=signal-I] Flow limit +tooltip-stat-limit=Input and Output limit of the storage system +caption-stat-surface-area=[virtual-signal=signal-R] Remaining Surface +tooltip-stat-surface-area=Remaining surface area, insert landfill to increase it type-energy=Energy type-circuit=Circuit type-storage-input=Storage Input type-storage-output=Storage Output -caption-refresh=Refresh List caption-view=View Interface caption-build=Build Interface caption-remove=Remove Interface diff --git a/exp_scenario/module/locale/zh-CN.cfg b/exp_scenario/module/locale/zh-CN.cfg index f65d672d..920f1f36 100644 --- a/exp_scenario/module/locale/zh-CN.cfg +++ b/exp_scenario/module/locale/zh-CN.cfg @@ -489,23 +489,20 @@ tooltip-goto-disabled=你不在傳送陣, 請移至任意傳送陣 [exp-gui_vlayer] tooltip-main=Vlayer 介面 selection-name=vlayer -caption-stat-solar=[img=entity/solar-panel] 太陽能板 -tooltip-stat-solar=使用中的太陽能板數量 / 儲存的太陽能板數量 -caption-stat-accumulator=[img=entity/accumulator] 蓄電池 -tooltip-stat-accumulator=使用中的蓄電池數量 / 儲存的蓄電池數量 -caption-stat-surface-area=[virtual-signal=signal-R] 餘下土地 -tooltip-stat-surface-area=餘下土地。 放入堆填來增加 caption-stat-sustained=[virtual-signal=signal-S] 持續產能 tooltip-stat-sustained=持續電力產能 caption-stat-production=[virtual-signal=signal-P] 現時產能 tooltip-stat-production=現時電力產能 caption-stat-capacity=[virtual-signal=signal-E] 電池電量 tooltip-stat-capacity=現時電池電量 / 電池最大容量 +caption-stat-limit=[virtual-signal=signal-I] 流量限制 +tooltip-stat-limit=儲存系統的輸入和輸出限制 +caption-stat-surface-area=[virtual-signal=signal-R] 餘下土地 +tooltip-stat-surface-area=餘下土地。 放入堆填來增加 type-energy=電力 type-circuit=回路 type-storage-input=放入箱 type-storage-output=提取箱 -caption-refresh=刷新列表 caption-view=查看介面 caption-build=建造介面 caption-remove=拆除介面 diff --git a/exp_scenario/module/locale/zh-TW.cfg b/exp_scenario/module/locale/zh-TW.cfg index f65d672d..920f1f36 100644 --- a/exp_scenario/module/locale/zh-TW.cfg +++ b/exp_scenario/module/locale/zh-TW.cfg @@ -489,23 +489,20 @@ tooltip-goto-disabled=你不在傳送陣, 請移至任意傳送陣 [exp-gui_vlayer] tooltip-main=Vlayer 介面 selection-name=vlayer -caption-stat-solar=[img=entity/solar-panel] 太陽能板 -tooltip-stat-solar=使用中的太陽能板數量 / 儲存的太陽能板數量 -caption-stat-accumulator=[img=entity/accumulator] 蓄電池 -tooltip-stat-accumulator=使用中的蓄電池數量 / 儲存的蓄電池數量 -caption-stat-surface-area=[virtual-signal=signal-R] 餘下土地 -tooltip-stat-surface-area=餘下土地。 放入堆填來增加 caption-stat-sustained=[virtual-signal=signal-S] 持續產能 tooltip-stat-sustained=持續電力產能 caption-stat-production=[virtual-signal=signal-P] 現時產能 tooltip-stat-production=現時電力產能 caption-stat-capacity=[virtual-signal=signal-E] 電池電量 tooltip-stat-capacity=現時電池電量 / 電池最大容量 +caption-stat-limit=[virtual-signal=signal-I] 流量限制 +tooltip-stat-limit=儲存系統的輸入和輸出限制 +caption-stat-surface-area=[virtual-signal=signal-R] 餘下土地 +tooltip-stat-surface-area=餘下土地。 放入堆填來增加 type-energy=電力 type-circuit=回路 type-storage-input=放入箱 type-storage-output=提取箱 -caption-refresh=刷新列表 caption-view=查看介面 caption-build=建造介面 caption-remove=拆除介面