From 6491c57bffb93901947db7e00c4e36b276733caa Mon Sep 17 00:00:00 2001 From: PHIDIAS Date: Tue, 10 Sep 2024 07:09:18 +0900 Subject: [PATCH] Add progress bars to vlayer (#325) * Update vlayer.lua * Update vlayer.lua * Update vlayer.lua * Update vlayer.lua * Update vlayer.lua * Update vlayer.lua * Update vlayer.lua * Update vlayer.lua * Update vlayer.lua * Update vlayer.lua --- modules/control/vlayer.lua | 64 +++++++-- modules/gui/vlayer.lua | 266 +++++++++++++++++++------------------ 2 files changed, 193 insertions(+), 137 deletions(-) diff --git a/modules/control/vlayer.lua b/modules/control/vlayer.lua index 8fb1d45b..81313270 100644 --- a/modules/control/vlayer.lua +++ b/modules/control/vlayer.lua @@ -71,6 +71,39 @@ function vlayer.get_items() return vlayer_data.storage.items end +--- Get all unallocated items in storage +-- @treturn table a dictionary of all unallocated items stored in the vlayer +function vlayer.get_unallocated_items() + return vlayer_data.storage.unallocated +end + +--- Get all allocated items in storage +-- @treturn table a dictionary of all allocated items stored in the vlayer +function vlayer.get_allocated_items() + local r = {} + + for k, v in pairs(vlayer_data.storage.items) do + r[k] = v + + if vlayer_data.storage.unallocated[k] then + r[k] = r[k] - vlayer_data.storage.unallocated[k] + end + end + + return r +end + +--- Get the actual defecit of land +local function get_actual_land_defecit() + local n = vlayer_data.properties.total_surface_area - vlayer_data.properties.used_surface_area + + for k, v in pairs(vlayer.get_unallocated_items()) do + n = n - (config.allowed_items[k].required_area * v) + end + + return n +end + --- Get interface counts -- @treturn table a dictionary of the vlayer interface counts function vlayer.get_interface_counts() @@ -282,6 +315,7 @@ function vlayer.remove_item(item_name, count) -- Remove the item from allocated storage vlayer_data.storage.items[item_name] = vlayer_data.storage.items[item_name] - remove_count vlayer.allocate_item(item_name, -remove_count) + return remove_unallocated + remove_count end @@ -309,6 +343,7 @@ function vlayer.create_input_interface(surface, position, circuit, last_user) interface.destructible = false interface.minable = false interface.operable = true + return interface end @@ -371,6 +406,7 @@ function vlayer.create_output_interface(surface, position, circuit, last_user) interface.destructible = false interface.minable = false interface.operable = true + return interface end @@ -424,6 +460,7 @@ local function handle_unallocated() -- Allocate items in an equal distribution local surplus_area = vlayer_data.properties.total_surface_area - vlayer_data.properties.used_surface_area + for item_name, count in pairs(vlayer_data.storage.unallocated) do local allocation_count = math.min(count, math.floor(count * surplus_area / unallocated_area)) @@ -436,13 +473,17 @@ end --- Get the statistics for the vlayer function vlayer.get_statistics() + local vdp = vlayer_data.properties.production * mega + local gdm = get_production_multiplier() + return { total_surface_area = vlayer_data.properties.total_surface_area, used_surface_area = vlayer_data.properties.used_surface_area, - remaining_surface_area = vlayer_data.properties.total_surface_area - vlayer_data.properties.used_surface_area, - production_multiplier = get_production_multiplier(), - energy_production = vlayer_data.properties.production * mega * get_production_multiplier(), - energy_sustained = vlayer_data.properties.production * mega * get_sustained_multiplier(), + remaining_surface_area = get_actual_land_defecit(), + production_multiplier = gdm, + energy_max = vdp, + energy_production = vdp * gdm, + energy_sustained = vdp * get_sustained_multiplier(), energy_capacity = vlayer_data.properties.capacity * mega, energy_storage = vlayer_data.storage.energy, day_time = math.floor(vlayer_data.surface.daytime * vlayer_data.surface.ticks_per_day), @@ -497,6 +538,7 @@ function vlayer.create_circuit_interface(surface, position, circuit, last_user) interface.destructible = false interface.minable = false interface.operable = true + return interface end @@ -576,6 +618,7 @@ function vlayer.create_energy_interface(surface, position, last_user) interface.power_production = 0 interface.power_usage = 0 interface.energy = 0 + return interface end @@ -602,7 +645,7 @@ local function handle_energy_interfaces() local discharge_rate = 2 * (production + vlayer_data.properties.discharge * mega) / #vlayer_data.entity_interfaces.energy local fill_to = math.min(discharge_rate, math.floor(available_energy / #vlayer_data.entity_interfaces.energy)) - for index, interface in pairs(vlayer_data.entity_interfaces.energy) do + for _, interface in pairs(vlayer_data.entity_interfaces.energy) do interface.electric_buffer_size = math.max(discharge_rate, interface.energy) -- prevent energy loss local delta = fill_to - interface.energy -- positive means storage to interface vlayer_data.storage.energy = vlayer_data.storage.energy - delta @@ -620,7 +663,8 @@ local function handle_energy_interfaces() local max_burning = (vlayer_data.properties.capacity * mega / 2) - vlayer_data.storage.energy if v.count > 0 and max_burning > 0 then - local to_burn = math.min(v.count, max_burning / v.value) + local to_burn = math.min(v.count, math.floor(max_burning / v.value)) + vlayer_data.storage.energy = vlayer_data.storage.energy + (to_burn * v.value) vlayer_data.storage.power_items[k].count = vlayer_data.storage.power_items[k].count - to_burn end @@ -656,23 +700,27 @@ function vlayer.remove_interface(surface, position) move_items_stack(interface.get_inventory(defines.inventory.chest).get_contents()) table.remove_element(vlayer_data.entity_interfaces.storage_input, interface) interface.destroy() - return 'storage input', pos + + return 'storage-input', pos elseif name == 'logistic-chest-requester' then move_items_stack(interface.get_inventory(defines.inventory.chest).get_contents()) table.remove_element(vlayer_data.entity_interfaces.storage_output, interface) interface.destroy() - return 'storage output', pos + + return 'storage-output', pos elseif name == 'constant-combinator' then table.remove_element(vlayer_data.entity_interfaces.circuit, interface) interface.destroy() + return 'circuit', pos elseif name == 'electric-energy-interface' then vlayer_data.storage.energy = vlayer_data.storage.energy + interface.energy table.remove_element(vlayer_data.entity_interfaces.energy, interface) interface.destroy() + return 'energy', pos end end diff --git a/modules/gui/vlayer.lua b/modules/gui/vlayer.lua index 6ac8baf9..928663f1 100644 --- a/modules/gui/vlayer.lua +++ b/modules/gui/vlayer.lua @@ -140,19 +140,21 @@ Gui.element{ type = 'label', name = 'vlayer_display_item_solar_name', caption = {'vlayer.display-item-solar'}, - style = 'heading_1_label' + style = 'heading_2_label' }:style{ width = 200 } local vlayer_gui_display_item_solar_count = Gui.element{ - type = 'label', + type = 'progressbar', name = 'vlayer_display_item_solar_count', - caption = '0', - style = 'heading_1_label' + caption = '', + value = 0, + style = 'electric_satisfaction_statistics_progressbar' }:style{ - width = 120 + width = 200, + font = 'heading-2' } --- Display label for the number of accumulators @@ -162,111 +164,21 @@ Gui.element{ type = 'label', name = 'vlayer_display_item_accumulator_name', caption = {'vlayer.display-item-accumulator'}, - style = 'heading_1_label' + style = 'heading_2_label' }:style{ width = 200 } local vlayer_gui_display_item_accumulator_count = Gui.element{ - type = 'label', + type = 'progressbar', name = 'vlayer_display_item_accumulator_count', - caption = '0', - style = 'heading_1_label' + caption = '', + value = 0, + style = 'electric_satisfaction_statistics_progressbar' }:style{ - width = 120 -} - ---- Display label for the current energy production --- @element vlayer_gui_display_signal_production_name -local vlayer_gui_display_signal_production_name = -Gui.element{ - type = 'label', - name = 'vlayer_display_signal_peak_name', - caption = {'vlayer.display-current-production'}, - tooltip = {'vlayer.display-current-production-tooltip'}, - style = 'heading_1_label' -}:style{ - width = 200 -} - -local vlayer_gui_display_signal_production_count = -Gui.element{ - type = 'label', - name = 'vlayer_display_signal_peak_solar_count', - caption = '0', - style = 'heading_1_label' -}:style{ - width = 120 -} - ---- Display label for the sustained energy production --- @element vlayer_gui_display_signal_sustained_name -local vlayer_gui_display_signal_sustained_name = -Gui.element{ - type = 'label', - name = 'vlayer_display_signal_sustained_name', - caption = {'vlayer.display-sustained-production'}, - tooltip = {'vlayer.display-sustained-production-tooltip'}, - style = 'heading_1_label' -}:style{ - width = 200 -} - -local vlayer_gui_display_signal_sustained_count = -Gui.element{ - type = 'label', - name = 'vlayer_display_signal_sustained_count', - caption = '0', - style = 'heading_1_label' -}:style{ - width = 120 -} - ---- Display label for the sustained energy capacity --- @element vlayer_gui_display_signal_capacity_name -local vlayer_gui_display_signal_capacity_name = -Gui.element{ - type = 'label', - name = 'vlayer_display_signal_max_name', - caption = {'vlayer.display-max-capacity'}, - tooltip = {'vlayer.display-max-capacity-tooltip'}, - style = 'heading_1_label' -}:style{ - width = 200 -} - -local vlayer_gui_display_signal_capacity_count = -Gui.element{ - type = 'label', - name = 'vlayer_display_signal_max_count', - caption = '0', - style = 'heading_1_label' -}:style{ - width = 120 -} - ---- Display label for the current energy in storage --- @element vlayer_gui_display_signal_current_name -local vlayer_gui_display_signal_current_name = -Gui.element{ - type = 'label', - name = 'vlayer_display_signal_current_name', - caption = {'vlayer.display-current-capacity'}, - tooltip = {'vlayer.display-current-capacity-tooltip'}, - style = 'heading_1_label' -}:style{ - width = 200 -} - -local vlayer_gui_display_signal_current_count = -Gui.element{ - type = 'label', - name = 'vlayer_display_signal_current_count', - caption = '0', - style = 'heading_1_label' -}:style{ - width = 120 + width = 200, + font = 'heading-2' } --- Display label for the remaining surface area @@ -277,7 +189,7 @@ Gui.element{ name = 'vlayer_display_signal_remaining_surface_area_name', caption = {'vlayer.display-remaining-surface-area'}, tooltip = {'vlayer.display-remaining-surface-area-tooltip'}, - style = 'heading_1_label' + style = 'heading_2_label' }:style{ width = 200 } @@ -287,9 +199,86 @@ Gui.element{ type = 'label', name = 'vlayer_display_signal_remaining_surface_area_count', caption = '0', - style = 'heading_1_label' + style = 'heading_2_label' }:style{ - width = 120 + width = 200, + height = 28, + horizontal_align = 'right' +} + +--- Display label for the sustained energy production +-- @element vlayer_gui_display_signal_sustained_name +local vlayer_gui_display_signal_sustained_name = +Gui.element{ + type = 'label', + name = 'vlayer_display_signal_sustained_name', + caption = {'vlayer.display-sustained-production'}, + tooltip = {'vlayer.display-sustained-production-tooltip'}, + style = 'heading_2_label' +}:style{ + width = 200 +} + +local vlayer_gui_display_signal_sustained_count = +Gui.element{ + type = 'label', + name = 'vlayer_display_signal_sustained_count', + caption = '0', + style = 'heading_2_label' +}:style{ + width = 200, + height = 28, + horizontal_align = 'right' +} + +--- Display label for the current energy production +-- @element vlayer_gui_display_signal_production_name +local vlayer_gui_display_signal_production_name = +Gui.element{ + type = 'label', + name = 'vlayer_display_signal_production_name', + caption = {'vlayer.display-current-production'}, + tooltip = {'vlayer.display-current-production-tooltip'}, + style = 'heading_2_label' +}:style{ + width = 200 +} + +local vlayer_gui_display_signal_production_count = +Gui.element{ + type = 'progressbar', + name = 'vlayer_display_signal_production_count', + caption = '', + value = 0, + style = 'electric_satisfaction_statistics_progressbar' +}:style{ + width = 200, + font = 'heading-2' +} + +--- Display label for the sustained energy capacity +-- @element vlayer_gui_display_signal_capacity_name +local vlayer_gui_display_signal_capacity_name = +Gui.element{ + type = 'label', + name = 'vlayer_display_signal_capacity_name', + caption = {'vlayer.display-current-capacity'}, + tooltip = {'vlayer.display-current-capacity-tooltip'}, + style = 'heading_2_label' +}:style{ + width = 200 +} + +local vlayer_gui_display_signal_capacity_count = +Gui.element{ + type = 'progressbar', + name = 'vlayer_display_signal_capacity_count', + caption = '', + value = 0, + style = 'electric_satisfaction_statistics_progressbar' +}:style{ + width = 200, + font = 'heading-2' } --- A vertical flow containing all the displays labels and their counts @@ -297,7 +286,7 @@ Gui.element{ local vlayer_display_set = Gui.element(function(_, parent, name) local vlayer_set = parent.add{type='flow', direction='vertical', name=name} - local disp = Gui.scroll_table(vlayer_set, 320, 2, 'disp') + local disp = Gui.scroll_table(vlayer_set, 400, 2, 'disp') vlayer_gui_display_item_solar_name(disp) vlayer_gui_display_item_solar_count(disp) @@ -305,14 +294,12 @@ Gui.element(function(_, parent, name) vlayer_gui_display_item_accumulator_count(disp) vlayer_gui_display_signal_remaining_surface_area_name(disp) vlayer_gui_display_signal_remaining_surface_area_count(disp) - vlayer_gui_display_signal_production_name(disp) - vlayer_gui_display_signal_production_count(disp) vlayer_gui_display_signal_sustained_name(disp) vlayer_gui_display_signal_sustained_count(disp) + vlayer_gui_display_signal_production_name(disp) + vlayer_gui_display_signal_production_count(disp) vlayer_gui_display_signal_capacity_name(disp) vlayer_gui_display_signal_capacity_count(disp) - vlayer_gui_display_signal_current_name(disp) - vlayer_gui_display_signal_current_count(disp) return vlayer_set end) @@ -343,7 +330,7 @@ Gui.element{ items = {{'vlayer.control-type-energy'}, {'vlayer.control-type-circuit'}, {'vlayer.control-type-storage-input'}, {'vlayer.control-type-storage-output'}}, selected_index = 1 }:style{ - width = 160 + width = 200 }:on_selection_changed(function(player, _, _) vlayer_gui_list_refresh(player) end) @@ -355,7 +342,7 @@ Gui.element{ type = 'drop-down', name = Gui.unique_static_name }:style{ - width = 160 + width = 200 } --- A button to refresh the remove list @@ -366,7 +353,7 @@ Gui.element{ name = Gui.unique_static_name, caption = {'vlayer.control-refresh'} }:style{ - width = 160 + width = 200 }:on_click(function(player, _, _) vlayer_gui_list_refresh(player) end) @@ -379,12 +366,12 @@ Gui.element{ name = Gui.unique_static_name, caption = {'vlayer.control-see'} }:style{ - width = 160 + width = 200 }:on_click(function(player, element, _) local target = element.parent[vlayer_gui_control_type.name].selected_index local n = element.parent[vlayer_gui_control_list.name].selected_index - if target and vlayer_control_type_list[target] and n then + if target and vlayer_control_type_list[target] and n > 0 then local i = vlayer.get_interfaces() if i and i[vlayer_control_type_list[target]] and i[vlayer_control_type_list[target]][n] then @@ -406,7 +393,7 @@ Gui.element{ name = Gui.unique_static_name, caption = {'vlayer.control-build'} }:style{ - width = 160 + width = 200 }:on_click(function(player, _, _) if Selection.is_selecting(player, SelectionConvertArea) then Selection.stop(player) @@ -426,19 +413,19 @@ Gui.element{ name = Gui.unique_static_name, caption = {'vlayer.control-remove'} }:style{ - width = 160 + width = 200 }:on_click(function(player, element, _) local target = element.parent[vlayer_gui_control_type.name].selected_index local n = element.parent[vlayer_gui_control_list.name].selected_index - if target and vlayer_control_type_list[target] and n then + if target and vlayer_control_type_list[target] and n > 0 then local i = vlayer.get_interfaces() if i and i[vlayer_control_type_list[target]] then local interface_type, interface_position = vlayer.remove_interface(i[vlayer_control_type_list[target]][n].surface, i[vlayer_control_type_list[target]][n].position) if interface_type then - game.print{'vlayer.interface-result', player.name, pos_to_gps_string(interface_position), {'vlayer.result-remove'}, {'vlayer.control-type-' .. interface_type:gsub(' ', '-')}} + game.print{'vlayer.interface-result', player.name, pos_to_gps_string(interface_position), {'vlayer.result-remove'}, {'vlayer.control-type-' .. interface_type}} end end end @@ -451,7 +438,7 @@ end) local vlayer_control_set = Gui.element(function(_, parent, name) local vlayer_set = parent.add{type='flow', direction='vertical', name=name} - local disp = Gui.scroll_table(vlayer_set, 320, 2, 'disp') + local disp = Gui.scroll_table(vlayer_set, 400, 2, 'disp') vlayer_gui_control_type(disp) vlayer_gui_control_list(disp) @@ -468,7 +455,7 @@ end) vlayer_container = Gui.element(function(definition, parent) local player = Gui.get_player_from_element(parent) - local container = Gui.container(parent, definition.name, 320) + local container = Gui.container(parent, definition.name, 400) vlayer_display_set(container, 'vlayer_st_1') local control_set = vlayer_control_set(container, 'vlayer_st_2') @@ -499,14 +486,31 @@ Event.add(Roles.events.on_role_unassigned, role_update_event) Event.on_nth_tick(config.update_tick_gui, function(_) local stats = vlayer.get_statistics() local items = vlayer.get_items() + local items_alloc = vlayer.get_allocated_items() + local vlayer_display = { - [vlayer_gui_display_item_solar_count.name] = format_number(items['solar-panel']), - [vlayer_gui_display_item_accumulator_count.name] = format_number(items['accumulator']), - [vlayer_gui_display_signal_remaining_surface_area_count.name] = format_number(stats.remaining_surface_area), - [vlayer_gui_display_signal_production_count.name] = format_energy(stats.energy_production, 'W'), - [vlayer_gui_display_signal_sustained_count.name] = format_energy(stats.energy_sustained, 'W'), - [vlayer_gui_display_signal_capacity_count.name] = format_energy(stats.energy_capacity, 'J'), - [vlayer_gui_display_signal_current_count.name] = format_energy(stats.energy_storage, 'J'), + [vlayer_gui_display_item_solar_count.name] = { + val = (items_alloc['solar-panel'] / math.max(items['solar-panel'], 1)), + cap = format_number(items_alloc['solar-panel']) .. ' / ' .. format_number(items['solar-panel']) + }, + [vlayer_gui_display_item_accumulator_count.name] = { + val = (items_alloc['accumulator'] / math.max(items['accumulator'], 1)), + cap = format_number(items_alloc['accumulator']) .. ' / ' .. format_number(items['accumulator']) + }, + [vlayer_gui_display_signal_remaining_surface_area_count.name] = { + cap = format_number(stats.remaining_surface_area) + }, + [vlayer_gui_display_signal_sustained_count.name] = { + cap = format_energy(stats.energy_sustained, 'W') + }, + [vlayer_gui_display_signal_production_count.name] = { + val = (stats.energy_production / math.max(stats.energy_max, 1)), + cap = format_energy(stats.energy_production, 'W') .. ' / ' .. format_energy(stats.energy_max, 'W') + }, + [vlayer_gui_display_signal_capacity_count.name] = { + val = (stats.energy_storage / math.max(stats.energy_capacity, 1)), + cap = format_energy(stats.energy_storage, 'J') .. ' / ' .. format_energy(stats.energy_capacity, 'J') + } } for _, player in pairs(game.connected_players) do @@ -514,7 +518,11 @@ Event.on_nth_tick(config.update_tick_gui, function(_) local disp = frame.container['vlayer_st_1'].disp.table for k, v in pairs(vlayer_display) do - disp[k].caption = v + disp[k].caption = v.cap + + if v.val then + disp[k].value = v.val + end end end end)