diff --git a/locale/en/gui.cfg b/locale/en/gui.cfg index 37f894dc..f9c56b85 100644 --- a/locale/en/gui.cfg +++ b/locale/en/gui.cfg @@ -251,7 +251,7 @@ display-ffrlm=Robot Lifetime display-ffrlm-tooltip=Force following robots lifetime modifier [vlayer] -main-tooltip=Vlayer +main-tooltip=Vlayer GUI display-item-solar=[img=entity/solar-panel] Solar Panel display-item-accumulator=[img=entity/accumulator] Accumulator display-current-production=[virtual-signal=signal-P] Current Production @@ -272,13 +272,14 @@ control-refresh=Refresh List control-see=See Interface control-build=Build Interface control-remove=Remove Interface -result-interface=The vlayer interface on __1__ -result-energy=__1__ built a vlayer energy interface on __2__ -result-unable=Unable to build vlayer entity -result-circuit=__1__ built a vlayer circuit on __2__ -result-storage-input=__1__ built a vlayer storage input on __2__ -result-storage-output=__1__ built a vlayer storage output on __2__ -result-remove=__1__ removed a vlayer __2__ on __3__ +result-build=built +result-remove=removed +result-interface-location=__1__ interface was located at __2__ +interface-result=__1__ __2__ __4__ interface at __3__ +result-unable=Unable to build __1__ interface, because of __2__ +result-multiple=Multiple steel chest detected +result-limit=Max limit exceeded +result-space=Not enough space control-type-energy=Energy control-type-circuit=Circuit control-type-storage-input=Storage Input diff --git a/locale/zh-CN/gui.cfg b/locale/zh-CN/gui.cfg index 109cb221..60a9f77d 100644 --- a/locale/zh-CN/gui.cfg +++ b/locale/zh-CN/gui.cfg @@ -251,7 +251,7 @@ display-ffrlm=機械人生命 display-ffrlm-tooltip=勢力戰鬥機械人生命時間 [vlayer] -main-tooltip=Vlayer +main-tooltip=Vlayer 介面 display-item-solar=[img=entity/solar-panel] 太陽能板 display-item-accumulator=[img=entity/accumulator] 蓄電池 display-current-production=[virtual-signal=signal-P] 現時產能 @@ -272,13 +272,14 @@ control-refresh=刷新列表 control-see=查看介面 control-build=建造介面 control-remove=拆除介面 -result-interface=介面在 __1__ -result-energy=__1__ 在 __2__ 建造了電力介面 -result-unable=無法建造介面 -result-circuit=__1__ 在 __2__ 建造了回路介面 -result-storage-input=__1__ 在 __2__ 建造了放入箱介面 -result-storage-output=__1__ 在 __2__ 建造了提取箱介面 -result-remove=__1__ 在 __3__ 拆除了 __2__ 介面 +result-build=建造了 +result-remove=拆除了 +result-interface-location=__1__ 介面在 __2__ +interface-result=__1__ 在 __2__ __3__ __4__ 介面 +result-unable=無法建造 __1__ 介面,因 __2__ +result-multiple=檢測到多個鋼箱 +result-limit=超出最大限制 +result-space=空間不足 control-type-energy=電力 control-type-circuit=回路 control-type-storage-input=放入箱 diff --git a/locale/zh-TW/gui.cfg b/locale/zh-TW/gui.cfg index 109cb221..60a9f77d 100644 --- a/locale/zh-TW/gui.cfg +++ b/locale/zh-TW/gui.cfg @@ -251,7 +251,7 @@ display-ffrlm=機械人生命 display-ffrlm-tooltip=勢力戰鬥機械人生命時間 [vlayer] -main-tooltip=Vlayer +main-tooltip=Vlayer 介面 display-item-solar=[img=entity/solar-panel] 太陽能板 display-item-accumulator=[img=entity/accumulator] 蓄電池 display-current-production=[virtual-signal=signal-P] 現時產能 @@ -272,13 +272,14 @@ control-refresh=刷新列表 control-see=查看介面 control-build=建造介面 control-remove=拆除介面 -result-interface=介面在 __1__ -result-energy=__1__ 在 __2__ 建造了電力介面 -result-unable=無法建造介面 -result-circuit=__1__ 在 __2__ 建造了回路介面 -result-storage-input=__1__ 在 __2__ 建造了放入箱介面 -result-storage-output=__1__ 在 __2__ 建造了提取箱介面 -result-remove=__1__ 在 __3__ 拆除了 __2__ 介面 +result-build=建造了 +result-remove=拆除了 +result-interface-location=__1__ 介面在 __2__ +interface-result=__1__ 在 __2__ __3__ __4__ 介面 +result-unable=無法建造 __1__ 介面,因 __2__ +result-multiple=檢測到多個鋼箱 +result-limit=超出最大限制 +result-space=空間不足 control-type-energy=電力 control-type-circuit=回路 control-type-storage-input=放入箱 diff --git a/modules/control/vlayer.lua b/modules/control/vlayer.lua index 5592a3d9..8fb1d45b 100644 --- a/modules/control/vlayer.lua +++ b/modules/control/vlayer.lua @@ -24,7 +24,7 @@ local vlayer_data = { used_surface_area = 0, production = 0, discharge = 0, - capacity = 0, + capacity = 0 }, storage = { items = {}, @@ -439,13 +439,15 @@ function vlayer.get_statistics() return { total_surface_area = vlayer_data.properties.total_surface_area, used_surface_area = vlayer_data.properties.used_surface_area, - remaining_surface_area = math.max(vlayer_data.properties.total_surface_area - vlayer_data.properties.used_surface_area, 0), + 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(), energy_capacity = vlayer_data.properties.capacity * mega, energy_storage = vlayer_data.storage.energy, - day = math.floor(game.tick / vlayer_data.surface.ticks_per_day), - time = math.floor(vlayer_data.surface.daytime * vlayer_data.surface.ticks_per_day) + day_time = math.floor(vlayer_data.surface.daytime * vlayer_data.surface.ticks_per_day), + day_length = vlayer_data.surface.ticks_per_day, + tick = game.tick } end @@ -460,12 +462,14 @@ function vlayer.get_circuits() total_surface_area = 'signal-A', used_surface_area = 'signal-U', remaining_surface_area = 'signal-R', + production_multiplier = 'signal-M', energy_production = 'signal-P', energy_sustained = 'signal-S', energy_capacity = 'signal-C', energy_storage = 'signal-E', - day = 'signal-D', - time = 'signal-T', + day_time = 'signal-D', + day_length = 'signal-L', + tick = 'signal-T', } end @@ -515,6 +519,9 @@ local function handle_circuit_interfaces() if stat_name:find('energy') then circuit_oc.set_signal(signal_index, {signal={type='virtual', name=signal_name}, count=math.floor(stats[stat_name] / mega)}) + elseif stat_name == 'production_multiplier' then + circuit_oc.set_signal(signal_index, {signal={type='virtual', name=signal_name}, count=math.floor(stats[stat_name] * 10000)}) + else circuit_oc.set_signal(signal_index, {signal={type='virtual', name=signal_name}, count=math.floor(stats[stat_name])}) end diff --git a/modules/gui/vlayer.lua b/modules/gui/vlayer.lua index 40d5bd48..6ac8baf9 100644 --- a/modules/gui/vlayer.lua +++ b/modules/gui/vlayer.lua @@ -10,8 +10,20 @@ local Event = require 'utils.event' --- @dep utils.event local format_number = require('util').format_number --- @dep util local config = require 'config.vlayer' --- @dep config.vlayer local vlayer = require 'modules.control.vlayer' +local Selection = require 'modules.control.selection' --- @dep modules.control.selection +local SelectionConvertArea = 'VlayerConvertChest' + +--- Align an aabb to the grid by expanding it +local function aabb_align_expand(aabb) + return { + left_top = {x = math.floor(aabb.left_top.x), y = math.floor(aabb.left_top.y)}, + right_bottom = {x = math.ceil(aabb.right_bottom.x), y = math.ceil(aabb.right_bottom.y)} + } +end local vlayer_container +local vlayer_gui_control_type +local vlayer_gui_control_list local vlayer_control_type_list = { [1] = 'energy', @@ -59,26 +71,67 @@ local function format_energy(amount, unit) return formatted .. ' ' .. suffix .. unit end -local function vlayer_convert_chest(player) - local entities = player.surface.find_entities_filtered{position=player.position, radius=8, name='steel-chest', force=player.force, limit=1} +--- When an area is selected to add protection to the area +Selection.on_selection(SelectionConvertArea, function(event) + local area = aabb_align_expand(event.area) + local player = game.get_player(event.player_index) - if (not entities or #entities == 0) then - player.print{'vlayer.steel-chest-detect'} - return + if not player then + return nil end - local entity = entities[1] - local pos = entity.position - local circuit = entity.circuit_connected_entities + local entities = player.surface.find_entities_filtered{area=area, name='steel-chest', force=player.force} + local frame = Gui.get_left_element(player, vlayer_container) + local disp = frame.container['vlayer_st_2'].disp.table + local target = vlayer_control_type_list[disp[vlayer_gui_control_type.name].selected_index] - if (not entity.get_inventory(defines.inventory.chest).is_empty()) then + if #entities == 0 then + player.print{'vlayer.steel-chest-detect'} + return nil + + elseif #entities > 1 then + player.print{'vlayer.result-unable', {'vlayer.control-type-' .. target:gsub('_', '-')}, {'vlayer.result-multiple'}} + return nil + end + + if not entities[1] then + return nil + end + + local e = entities[1] + local e_pos = {x=string.format('%.1f', e.position.x), y=string.format('%.1f', e.position.y)} + local e_circ = e.circuit_connected_entities + + if not e.get_inventory(defines.inventory.chest).is_empty() then player.print{'vlayer.steel-chest-empty'} return nil end - entity.destroy() - return {pos={x=string.format('%.1f', pos.x), y=string.format('%.1f', pos.y)}, circuit=circuit} -end + if (vlayer.get_interface_counts()[target] >= config.interface_limit[target]) then + player.print{'vlayer.result-unable', {'vlayer.control-type-' .. target:gsub('_', '-')}, {'vlayer.result-limit'}} + return nil + end + + e.destroy() + + if target == 'energy' then + if not vlayer.create_energy_interface(player.surface, e_pos, player) then + player.print{'vlayer.result-unable', {'vlayer.control-type-energy'}, {'vlayer.result-space'}} + return nil + end + + elseif target == 'circuit' then + vlayer.create_circuit_interface(player.surface, e_pos, e_circ, player) + + elseif target == 'storage_input' then + vlayer.create_input_interface(player.surface, e_pos, e_circ, player) + + elseif target == 'storage_output' then + vlayer.create_output_interface(player.surface, e_pos, e_circ, player) + end + + game.print{'vlayer.interface-result', player.name, pos_to_gps_string(e_pos), {'vlayer.result-build'}, {'vlayer.control-type-' .. target:gsub('_', '-')}} +end) --- Display label for the number of solar panels -- @element vlayer_gui_display_item_solar_name @@ -264,9 +317,6 @@ Gui.element(function(_, parent, name) return vlayer_set end) -local vlayer_gui_control_type -local vlayer_gui_control_list - local function vlayer_gui_list_refresh(player) local frame = Gui.get_left_element(player, vlayer_container) local disp = frame.container['vlayer_st_2'].disp.table @@ -303,14 +353,11 @@ end) vlayer_gui_control_list = Gui.element{ type = 'drop-down', - name = Gui.unique_static_name, - items = {''}, - selected_index = 1 + name = Gui.unique_static_name }:style{ width = 160 } - --- A button to refresh the remove list -- @element vlayer_gui_control_refresh local vlayer_gui_control_refresh = @@ -336,9 +383,19 @@ Gui.element{ }: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 - local pos = vlayer.get_interfaces()[vlayer_control_type_list[target]][n].position - player.zoom_to_world(pos, 2) - game.print{'vlayer.result-interface', pos_to_gps_string(pos)} + + if target and vlayer_control_type_list[target] and n then + local i = vlayer.get_interfaces() + + if i and i[vlayer_control_type_list[target]] and i[vlayer_control_type_list[target]][n] then + local pos = i[vlayer_control_type_list[target]][n].position + + if pos then + player.zoom_to_world(pos, 2) + player.print{'vlayer.result-interface-location', {'vlayer.control-type-' .. vlayer_control_type_list[target]:gsub('_', '-')}, pos_to_gps_string(pos)} + end + end + end end) --- A button used to build the vlayer interface @@ -350,64 +407,12 @@ Gui.element{ caption = {'vlayer.control-build'} }:style{ width = 160 -}:on_click(function(player, element, _) - local target = vlayer_control_type_list[element.parent[vlayer_gui_control_type.name].selected_index] - - if target == 'energy' then - if (vlayer.get_interface_counts().energy < config.interface_limit.energy) then - local res = vlayer_convert_chest(player) - - if res then - if vlayer.create_energy_interface(player.surface, res.pos, player) then - game.print{'vlayer.result-energy', player.name, pos_to_gps_string(res.pos)} - - else - player.print{'vlayer.result-unable'} - end - end - - else - player.print{'vlayer.result-unable'} - end - - elseif target == 'circuit' then - if (vlayer.get_interface_counts().circuit < config.interface_limit.circuit) then - local res = vlayer_convert_chest(player) - - if res then - vlayer.create_circuit_interface(player.surface, res.pos, res.circuit, player) - game.print{'vlayer.result-circuit', player.name, pos_to_gps_string(res.pos)} - end - - else - player.print{'vlayer.result-unable'} - end - - elseif target == 'storage_input' then - if (vlayer.get_interface_counts().storage_input < config.interface_limit.storage_input) then - local res = vlayer_convert_chest(player) - - if res then - vlayer.create_input_interface(player.surface, res.pos, res.circuit, player) - game.print{'vlayer.result-storage-input', player.name, pos_to_gps_string(res.pos)} - end - - else - player.print{'vlayer.result-unable'} - end - - elseif target == 'storage_output' then - if (vlayer.get_interface_counts().storage_output < config.interface_limit.storage_output) then - local res = vlayer_convert_chest(player) - - if res then - vlayer.create_output_interface(player.surface, res.pos, res.circuit, player) - game.print{'vlayer.result-storage-output', player.name, pos_to_gps_string(res.pos)} - end - - else - player.print{'vlayer.result-unable'} - end +}:on_click(function(player, _, _) + if Selection.is_selecting(player, SelectionConvertArea) then + Selection.stop(player) + else + Selection.start(player, SelectionConvertArea) + player.print{'expcom-waterfill.entered-area-selection'} end vlayer_gui_list_refresh(player) @@ -426,10 +431,16 @@ Gui.element{ local target = element.parent[vlayer_gui_control_type.name].selected_index local n = element.parent[vlayer_gui_control_list.name].selected_index - if n then - local t = vlayer.get_interfaces()[vlayer_control_type_list[target]] - local interface_type, interface_position = vlayer.remove_interface(t[n].surface, t[n].position) - game.print{'vlayer.result-remove', player.name, interface_type, pos_to_gps_string(interface_position)} + if target and vlayer_control_type_list[target] and n 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(' ', '-')}} + end + end end vlayer_gui_list_refresh(player) @@ -460,17 +471,8 @@ Gui.element(function(definition, parent) local container = Gui.container(parent, definition.name, 320) vlayer_display_set(container, 'vlayer_st_1') - vlayer_control_set(container, 'vlayer_st_2') - - local disp = container['vlayer_st_2'].disp.table - local visible = Roles.player_allowed(player, 'gui/vlayer-edit') - - disp[vlayer_gui_control_type.name].visible = visible - disp[vlayer_gui_control_list.name].visible = visible - disp[vlayer_gui_control_refresh.name].visible = visible - disp[vlayer_gui_control_see.name].visible = visible - disp[vlayer_gui_control_build.name].visible = visible - disp[vlayer_gui_control_remove.name].visible = visible + local control_set = vlayer_control_set(container, 'vlayer_st_2') + control_set.visible = Roles.player_allowed(player, 'gui/vlayer-edit') return container.parent end)