diff --git a/config/gui/autofill.lua b/config/gui/autofill.lua index 60cc91a8..da9069f0 100644 --- a/config/gui/autofill.lua +++ b/config/gui/autofill.lua @@ -1,98 +1,212 @@ --- This file contains all the different settings for the autofill system and gui -- @config Autofill -return { +local table = require 'overrides.table' --- @dep overrides.table + +local ammo = 'ammo' +local fuel = 'fuel' +local shell = 'shell' + +local car = 'car' +local tank = 'tank' +local spidertron = 'spidertron' +local locomotive = 'locomotive' +local gun_turret = 'gun-turret' +local stone_furnace = 'stone-furnace' +local steel_furnace = 'steel-furnace' + +local config = { -- General config icon = 'item/piercing-rounds-magazine', --- @setting icon that will be used for the toolbar - entities = { - ['car'] = { - [defines.inventory.fuel] = { - type = 'fuel', - inventory = defines.inventory.fuel, - enabled = true - }, - [defines.inventory.car_ammo] = { - type = 'ammo', - inventory = defines.inventory.car_ammo, - enabled = true - } - }, - ['locomotive'] = { - [defines.inventory.fuel] = { - type = 'fuel', - inventory = defines.inventory.fuel, - enabled = true - } - }, - ['tank'] = { - [defines.inventory.fuel] = { - type = 'fuel', - inventory = defines.inventory.fuel, - enabled = true - }, - [defines.inventory.car_ammo] = { - type = 'ammo', - inventory = defines.inventory.car_ammo, - enabled = true - } - }, - ['gun-turret'] = { - [defines.inventory.turret_ammo] = { - type = 'ammo', - inventory = defines.inventory.turret_ammo, - enabled = true - } - } + categories = { + ammo = ammo, + fuel = fuel, + shell = shell }, - default_settings = { - { - type = 'ammo', - inventories = {defines.inventory.car_ammo, defines.inventory.turret_ammo}, - item = 'uranium-rounds-magazine', - amount = 10, - enabled = false - }, - { - type = 'ammo', - inventories = {defines.inventory.car_ammo, defines.inventory.turret_ammo}, - item = 'piercing-rounds-magazine', - amount = 10, - enabled = false - }, - { - type = 'ammo', - inventories = {defines.inventory.car_ammo, defines.inventory.turret_ammo}, - item = 'firearm-magazine', - amount = 10, - enabled = false - }, - { - type = 'fuel', - inventories = {defines.inventory.fuel}, - item = 'nuclear-fuel', - amount = 1, - enabled = false - }, - { - type = 'fuel', - inventories = {defines.inventory.fuel}, - item = 'rocket-fuel', - amount = 10, - enabled = false - }, - { - type = 'fuel', - inventories = {defines.inventory.fuel}, - item = 'solid-fuel', - amount = 10, - enabled = false - }, - { - type = 'fuel', - inventories = {defines.inventory.fuel}, - item = 'coal', - amount = 10, - enabled = false - } + entities = { + car = car, + tank = tank, + spidertron = spidertron, + locomotive = locomotive, + gun_turret = gun_turret, + stone_furnace = stone_furnace, + steel_furnace = steel_furnace + }, + default_entities = {} +} + +local default_autofill_item_settings = { + { + category = config.categories.ammo, + entity = {config.entities.car, config.entities.tank, config.entities.gun_turret}, + type = {defines.inventory.car_ammo, defines.inventory.turret_ammo}, + name = 'uranium-rounds-magazine', + amount = 10, + enabled = false + }, + { + category = config.categories.ammo, + entity = {config.entities.car, config.entities.tank, config.entities.gun_turret}, + type = {defines.inventory.car_ammo, defines.inventory.turret_ammo}, + name = 'piercing-rounds-magazine', + amount = 10, + enabled = false + }, + { + category = config.categories.ammo, + entity = {config.entities.car, config.entities.tank, config.entities.gun_turret}, + type = {defines.inventory.car_ammo, defines.inventory.turret_ammo}, + name = 'firearm-magazine', + amount = 10, + enabled = false + }, + { + category = config.categories.ammo, + entity = {config.entities.tank}, + type = {defines.inventory.car_ammo}, + name = 'flamethrower-ammo', + amount = 10, + enabled = false + }, + { + category = config.categories.shell, + entity = {config.entities.tank}, + type = {defines.inventory.car_ammo}, + name = 'cannon-shell', + amount = 10, + enabled = false + }, + { + category = config.categories.shell, + entity = {config.entities.tank}, + type = {defines.inventory.car_ammo}, + name = 'explosive-cannon-shell', + amount = 10, + enabled = false + }, + { + category = config.categories.shell, + entity = {config.entities.tank}, + type = {defines.inventory.car_ammo}, + name = 'uranium-cannon-shell', + amount = 10, + enabled = false + }, + { + category = config.categories.shell, + entity = {config.entities.tank}, + type = {defines.inventory.car_ammo}, + name = 'explosive-uranium-cannon-shell', + amount = 10, + enabled = false + }, + { + category = config.categories.ammo, + entity = {config.entities.spidertron}, + type = {defines.inventory.car_ammo}, + name = 'rocket', + amount = 10, + enabled = false + }, + { + category = config.categories.ammo, + entity = {config.entities.spidertron}, + type = {defines.inventory.car_ammo}, + name = 'explosive-rocket', + amount = 10, + enabled = false + }, + { + category = config.categories.ammo, + entity = {config.entities.spidertron}, + type = {defines.inventory.car_ammo}, + name = 'atomic-bomb', + amount = 10, + enabled = false + }, + { + category = config.categories.fuel, + entity = {config.entities.car, config.entities.tank, config.entities.locomotive, config.entities.stone_furnace, config.entities.steel_furnace}, + type = {defines.inventory.fuel}, + name = 'nuclear-fuel', + amount = 1, + enabled = false + }, + { + category = config.categories.fuel, + entity = {config.entities.car, config.entities.tank, config.entities.locomotive, config.entities.stone_furnace, config.entities.steel_furnace}, + type = {defines.inventory.fuel}, + name = 'rocket-fuel', + amount = 10, + enabled = false + }, + { + category = config.categories.fuel, + entity = {config.entities.car, config.entities.tank, config.entities.locomotive, config.entities.stone_furnace, config.entities.steel_furnace}, + type = {defines.inventory.fuel}, + name = 'solid-fuel', + amount = 10, + enabled = false + }, + { + category = config.categories.fuel, + entity = {config.entities.car, config.entities.tank, config.entities.locomotive, config.entities.stone_furnace, config.entities.steel_furnace}, + type = {defines.inventory.fuel}, + name = 'coal', + amount = 10, + enabled = false } -} \ No newline at end of file +} + +local function get_items_by_type(entity, type) + local items = entity.items + for _, item in pairs(default_autofill_item_settings) do + if table.contains(item.entity, entity.entity) then + if table.contains(item.type, type) then + items[item.name] = { + entity = entity.entity, + category = item.category, + type = type, + name = item.name, + amount = item.amount, + enabled = item.enabled + } + end + end + end + return items +end + +local default_entities = config.default_entities + +local function generate_default_setting(entity_name, type, enabled) + if not default_entities[entity_name] then + default_entities[entity_name] = { + entity = entity_name, + enabled = enabled, + items = {} + } + end + get_items_by_type(default_entities[entity_name], type) +end + +generate_default_setting(config.entities.car, defines.inventory.fuel, true) +generate_default_setting(config.entities.car, defines.inventory.car_ammo, true) + +generate_default_setting(config.entities.locomotive, defines.inventory.fuel, true) + +generate_default_setting(config.entities.tank, defines.inventory.fuel, true) +generate_default_setting(config.entities.tank, defines.inventory.car_ammo, true) + +generate_default_setting(config.entities.spidertron, defines.inventory.car_ammo, true) + +generate_default_setting(config.entities.gun_turret, defines.inventory.turret_ammo, true) + +generate_default_setting(config.entities.stone_furnace, defines.inventory.fuel, true) + +generate_default_setting(config.entities.steel_furnace, defines.inventory.fuel, true) + +-- Cleanup temporary table +default_autofill_item_settings = nil + +return config \ No newline at end of file diff --git a/locale/en/gui.cfg b/locale/en/gui.cfg index 4d6ab0be..6cebaa17 100644 --- a/locale/en/gui.cfg +++ b/locale/en/gui.cfg @@ -83,13 +83,12 @@ discard-tooltip=Remove task [autofill] main-tooltip=Autofill settings -ammo-caption=Ammo Autofill -ammo-tooltip=Autofill settings when playing entities with a ammo slot -fuel-caption=Fuel Autofill -fuel-tooltip=Autofill settings when placing entities with a fuel slot +toggle-section-tooltip=Expand Section +toggle-section-collapse-tooltip=Collapse Section +toggle-entity-tooltip=Toggle the autofill of __1__ entity (overwrites autofill settings of the entity) toggle-tooltip=Toggle the autofill of __1__ into the __2__ slot of entities -amount-tooltip=Amount of items it will try and put into the __1__ slot of entities -confirmed=Set autofill amount to __1__ for __2__ +amount-tooltip=Amount of items it will try and put into the __1__ slot of __2__ +confirmed=Set autofill amount to __1__ __2__ for __3__ filled=Autofilled the __1__ with __2__ __3__ [warp-list] main-caption=Warp List diff --git a/modules/gui/autofill.lua b/modules/gui/autofill.lua index 9fdc3736..a675e147 100644 --- a/modules/gui/autofill.lua +++ b/modules/gui/autofill.lua @@ -25,99 +25,232 @@ local function rich_img(type, value) return '[img='..type..'/'..value..']' end ---- Draw a section header and main scroll --- @element autofill_section_container -local section = -Gui.element(function(_, parent, section_name, table_size) - -- Draw the header for the section - Gui.header( - parent, - {'autofill.'..section_name..'-caption'}, - {'autofill.'..section_name..'-tooltip'}, - true, - section_name..'-header' - ) - -- Table used to display the settings - local scroll_table = Gui.scroll_table(parent, 215, table_size, section_name..'-scroll-table') - return scroll_table -end) - -local toggle_item_button = -Gui.element(function(event_trigger, parent, setting) - return parent.add{ - name = event_trigger, - type = 'sprite-button', - sprite = 'item/'..setting.item, - tooltip = {'autofill.toggle-tooltip', rich_img('item', setting.item), setting.type}, - style = 'shortcut_bar_button_red' - } -end) -:style(Gui.sprite_style(32, nil, { right_margin = -3 })) -:on_click(function(player, element) - for _, setting in pairs(autofill_player_settings[player.name]) do - if 'item/'..setting.item == element.sprite then - if setting.enabled then - setting.enabled = false - element.style = 'shortcut_bar_button_red' - else - setting.enabled = true - element.style = 'shortcut_bar_button_green' +-- Button to toggle a section dropdown +-- @element toggle_section +local toggle_section = +Gui.element{ + type = 'sprite-button', + sprite = 'utility/expand_dark', + hovered_sprite = 'utility/expand', + tooltip = {'autofill.toggle-section-tooltip'} +} +toggle_section +:style(Gui.sprite_style(20)) +:on_click(function(_, element, _) + local header_flow = element.parent + local flow_name = header_flow.caption + local flow = header_flow.parent.parent[flow_name] + if Gui.toggle_visible_state(flow) then + element.sprite = 'utility/collapse_dark' + element.hovered_sprite = 'utility/collapse' + element.tooltip = {'autofill.toggle-section-collapse-tooltip'} + else + element.sprite = 'utility/expand_dark' + element.hovered_sprite = 'utility/expand' + element.tooltip = {'autofill.toggle-section-tooltip'} + end + local event = {} + for _, child in pairs(element.parent.parent.children) do + if child.alignment and child.alignment[toggle_section.name] then + if element.parent.name ~= child.name then + event.element = child.alignment[toggle_section.name] + toggle_section:raise_custom_event(event) end end end end) +-- Used to assign an event to the header label to trigger a toggle +-- @element header_toggle +local header_toggle = Gui.element() +:on_click(function(_, element, event) + event.element = element.parent.alignment[toggle_section.name] + toggle_section:raise_custom_event(event) +end) +-- Used to assign an event to the header label to trigger a toggle +-- @element header_toggle +local entity_toggle = Gui.element(function(event_trigger, parent, entity_name) + return parent.add{ + name = event_trigger, + type = 'sprite-button', + sprite = 'item/'..entity_name, + tooltip = {'autofill.toggle-entity-tooltip', rich_img('item', entity_name)}, + style = 'shortcut_bar_button_green' + } +end) +:style(Gui.sprite_style(22)) +:on_click(function(player, element, _) + local entity_name = string.sub(element.parent.parent.name, 0, -(1 + string.len('-header'))) + if not autofill_player_settings[player.name] then return end + local setting = autofill_player_settings[player.name][entity_name] + if not setting then return end + if setting.enabled then + setting.enabled = false + element.style = 'shortcut_bar_button_red' + else + setting.enabled = true + element.style = 'shortcut_bar_button_green' + end +end) + +--- Draw a section header and main scroll +-- @element autofill_section_container +local section = +Gui.element(function(_, parent, section_name, table_size) + -- Draw the header for the section + local header = Gui.header( + parent, + {'entity-name.'..section_name}, + {'autofill.toggle-section-tooltip'}, + true, + section_name..'-header', + header_toggle.name + ) + -- Right aligned button to toggle the section + header.caption = section_name + entity_toggle(header, section_name) + toggle_section(header) + + -- Table used to display the settings + local scroll_table = Gui.scroll_table(parent, 999, table_size, section_name) + scroll_table.parent.visible = false + + return scroll_table +end) + + + +local toggle_item_button = +Gui.element(function(event_trigger, parent, item) + return parent.add{ + name = event_trigger, + type = 'sprite-button', + sprite = 'item/'..item.name, + tooltip = {'autofill.toggle-tooltip', rich_img('item', item.name), item.category}, + style = 'shortcut_bar_button_red' + } +end) +:style(Gui.sprite_style(32, nil, { right_margin = -3 })) +:on_click(function(player, element) + local item_name = string.sub(element.parent.name, 1 + string.len('toggle-setting-'), -1) + local entity_name = element.parent.parent.parent.parent.parent.parent.name + if not autofill_player_settings[player.name] then return end + local setting = autofill_player_settings[player.name][entity_name] + if not setting then return end + local item = setting.items[item_name] + if not item then return end + if item.enabled then + item.enabled = false + element.style = 'shortcut_bar_button_red' + else + item.enabled = true + element.style = 'shortcut_bar_button_green' + end +end) + local amount_textfield = -Gui.element(function(event_trigger, parent, setting) +Gui.element(function(event_trigger, parent, item) return parent.add{ name = event_trigger, type = 'textfield', - text = setting.amount, - tooltip = {'autofill.amount-tooltip', setting.type}, + text = item.amount, + tooltip = {'autofill.amount-tooltip', item.category, rich_img('item', item.entity) }, clear_and_focus_on_right_click = true } end) :style{ - maximal_width = 90, - height = 32, + maximal_width = 40, + height = 31, padding = -2 } :on_confirmed(function(player, element, _) - local parent_name = element.parent.name - for _, setting in pairs(autofill_player_settings[player.name]) do - if 'amount-setting-'..setting.item == parent_name then - setting.amount = tonumber(element.text) - player.print({'autofill.confirmed', setting.amount, '[img=item/'..setting.item..']'}) - end - end + local item_name = string.sub(element.parent.name, 1 + string.len('toggle-setting-'), -1) + local entity_name = element.parent.parent.parent.parent.parent.parent.name + if not autofill_player_settings[player.name] then return end + local setting = autofill_player_settings[player.name][entity_name] + if not setting then return end + local item = setting.items[item_name] + if not item then return end + item.amount = tonumber(element.text) + player.print({'autofill.confirmed', item.amount, rich_img('item', item.name), rich_img('entity', entity_name) }) end) local add_autofill_setting = -Gui.element(function(_, parent, setting) - local toggle_flow = parent.add{ type = 'flow', name = 'toggle-setting-'..setting.item } - local amount_flow = parent.add{ type = 'flow', name = 'amount-setting-'..setting.item } +Gui.element(function(_, parent, item) + local toggle_flow = parent.add{ type = 'flow', name = 'toggle-setting-'..item.name } + local amount_flow = parent.add{ type = 'flow', name = 'amount-setting-'..item.name } toggle_flow.style.padding = 0 amount_flow.style.padding = 0 - toggle_item_button(toggle_flow, setting) - amount_textfield(amount_flow, setting) + toggle_item_button(toggle_flow, item) + amount_textfield(amount_flow, item) end) +local toggle_item_button_empty = +Gui.element(function(_, parent, i) + return parent.add{ + name = 'toggle-setting-empty-frame-'..i, + type = 'sprite-button' + } +end) +:style(Gui.sprite_style(32, nil, { right_margin = -3 })) + + +local amount_textfield_empty = +Gui.element(function(_, parent, i) + return parent.add{ + name = 'amount-setting-empty-frame-'..i, + type = 'textfield' + } +end) +:style{ maximal_width = 40, height = 31, padding = -2 } + +local add_empty_autofill_setting = +Gui.element(function(_, parent, i) + local toggle_flow = parent.add{ type = 'flow', name = 'toggle-setting-empty-'..i } + local amount_flow = parent.add{ type = 'flow', name = 'amount-setting-empty-'..i } + toggle_flow.style.padding = 0 + amount_flow.style.padding = 0 + local toggle_element = toggle_item_button_empty(toggle_flow, i) + toggle_element.enabled = false + local amount_element = amount_textfield_empty(amount_flow, i) + amount_element.enabled = false +end) + + --- Main gui container for the left flow -- @element autofill_container autofill_container = Gui.element(function(event_trigger, parent) -- Draw the internal container - local container = Gui.container(parent, event_trigger, 100) - + local container = Gui.container(parent, event_trigger) + container.parent.style.minimal_width = 245 -- Draw the header - local ammo_table = section(container, 'ammo', 2) - local fuel_table = section(container, 'fuel', 2) + for _, setting in pairs(config.default_entities) do + local table_sizes = {} + local tables = {} + local entity_table = section(container, setting.entity, 3) + for _, category in pairs(config.categories) do + if not table_sizes[category] then table_sizes[category] = 0 end + local alignment = Gui.alignment(entity_table, category..'-'..setting.entity, 'center', 'top') + alignment.style.padding = 0 + local category_table = Gui.scroll_table(alignment, 999, 2, category) + category_table.parent.style.padding = 0 + tables[category] = category_table + for _, item in pairs(setting.items) do + if item.category == category then + add_autofill_setting(category_table, item) + table_sizes[category] = table_sizes[category] + 1 + end + end + end - for _, setting in pairs(config.default_settings) do - if setting.type == 'ammo' then - add_autofill_setting(ammo_table, setting) - elseif setting.type == 'fuel' then - add_autofill_setting(fuel_table, setting) + local t = table.get_values(table_sizes) + table.sort(t) + local biggest = t[#t] + for category, size in pairs(table_sizes) do + for i=biggest-size,1,-1 do + add_empty_autofill_setting(tables[category], i) + end end end @@ -134,8 +267,10 @@ Gui.left_toolbar_button(config.icon, {'autofill.main-tooltip'}, autofill_contain Event.add(defines.events.on_player_created, function(event) local player = game.players[event.player_index] if not autofill_player_settings[player.name] then - autofill_player_settings[player.name] = table.deep_copy(config.default_settings) + autofill_player_settings[player.name] = table.deep_copy(config.default_entities) end + + print(game.table_to_json(autofill_player_settings[player.name])) end) local function entity_build(event) @@ -146,54 +281,46 @@ local function entity_build(event) end -- Check if the entity is in the config and enabled local entity = event.created_entity - local entity_configs = config.entities[entity.name] - if not entity_configs then - return - end + + -- Check if player has settings + if not autofill_player_settings[player.name] then return end + + -- Check if autofill for the entity is enabled + if not autofill_player_settings[player.name][entity.name] then return end + -- Get the inventory of the player local player_inventory = player.get_main_inventory() local text_position = { x = entity.position.x, y = entity.position.y } - -- Loop over all possible item settings to insert into the entity - for _, setting in pairs(autofill_player_settings[player.name]) do - if not setting.enabled then - goto end_setting - end - -- Loop over possible inventories for this setting to put into the vehicle - for _, inventory in pairs(setting.inventories) do - -- Check in the configs if the inventory type exists and is enabled for this vehicle - if not entity_configs[inventory] or not entity_configs[inventory].enabled then - goto end_inventory - end + -- Loop over all possible items to insert into the entity + for _, item in pairs(autofill_player_settings[player.name][entity.name].items) do + -- Check if the item is enabled or goto next item + if not item.enabled then goto end_item end - -- Get the inventory of the entity - local entity_inventory = entity.get_inventory(inventory) - if not entity_inventory then - goto end_inventory - end + -- Get the inventory of the entity or goto next item + local entity_inventory = entity.get_inventory(item.type) + if not entity_inventory then goto end_item end - local item = setting.item - local preferd_amount = setting.amount - local item_amount = player_inventory.get_item_count(item) - if item_amount ~= 0 then - local inserted - text_position.y = text_position.y - 0.2 - if item_amount >= preferd_amount then - if not entity_inventory.can_insert({name=item, count=preferd_amount}) then - goto end_inventory - end - inserted = entity_inventory.insert({name=item, count=preferd_amount}) - player_inventory.remove({name=item, count=inserted}) - print_text(entity.surface, text_position, {'autofill.filled', rich_img('entity', entity.name), inserted, rich_img('item', item) }, { r = 0, g = 255, b = 0, a = 1}) - else - inserted = entity_inventory.insert({name=item, count=item_amount}) - player_inventory.remove({name=item, count=inserted}) - print_text(entity.surface, text_position, {'autofill.filled', rich_img('entity', entity.name), inserted, rich_img('item', item) }, { r = 255, g = 165, b = 0, a = 1}) + local preferd_amount = item.amount + local item_amount = player_inventory.get_item_count(item.name) + if item_amount ~= 0 then + local inserted + text_position.y = text_position.y - 0.2 + if item_amount >= preferd_amount then + -- Can item be inserted? no, goto next item! + if not entity_inventory.can_insert({name=item.name, count=preferd_amount}) then + goto end_item end + inserted = entity_inventory.insert({name=item.name, count=preferd_amount}) + player_inventory.remove({name=item.name, count=inserted}) + print_text(entity.surface, text_position, {'autofill.filled', rich_img('entity', entity.name), inserted, rich_img('item', item.name) }, { r = 0, g = 255, b = 0, a = 1}) + else + inserted = entity_inventory.insert({name=item.name, count=item_amount}) + player_inventory.remove({name=item.name, count=inserted}) + print_text(entity.surface, text_position, {'autofill.filled', rich_img('entity', entity.name), inserted, rich_img('item', item.name) }, { r = 255, g = 165, b = 0, a = 1}) end - ::end_inventory:: end - ::end_setting:: + ::end_item:: end end