1
0
mirror of https://github.com/Oarcinae/FactorioScenarioMultiplayerSpawn.git synced 2026-04-24 20:44:46 +02:00
Files

1115 lines
40 KiB
Lua

--This file will let admins configure the "surfaces_config" table that is NOT available in the mod settings.
---Creates the tab content, used by AddOarcGuiTab
---@param tab_container LuaGuiElement
---@param player LuaPlayer
---@return nil
function CreateSurfaceConfigTab(tab_container, player)
local note = AddLabel(tab_container, nil, { "oarc-surface-settings-info" }, my_note_style)
note.style.maximal_width = 600
local warn = AddLabel(tab_container, nil, { "oarc-surface-settings-warning" }, my_warning_style)
warn.style.maximal_width = 600
-- Drop down to select surface that you want to configure
local selected_surface_name = CreateSurfaceDropdown(tab_container)
-- AddSpacer(tab_container)
local content = tab_container.add {
type = "flow",
direction = "vertical",
name = "surface_config_content_flow"
}
content.style.maximal_height = 600
CreateSurfaceConfigContent(content, selected_surface_name)
end
---Create surface config content section below the surface selection dropdown
---@param container LuaGuiElement
---@param surface_name string
---@return nil
function CreateSurfaceConfigContent(container, surface_name)
-- Vertical scroll pane with dividers for each section for the surface config
local scroll_pane = container.add {
type = "scroll-pane",
direction = "vertical",
vertical_scroll_policy = "always",
}
scroll_pane.style.top_margin = 10
-- Localized
AddLabel(scroll_pane, nil, {"oarc-label-starting-respawn-items"}, my_label_header2_style)
local starting_items_flow = scroll_pane.add { type = "flow", direction = "horizontal" }
CreateItemsSection(starting_items_flow, surface_name, {"oarc-label-starting-items"}, "player_start_items")
CreateItemsSection(starting_items_flow, surface_name, {"oarc-label-respawn-items"}, "player_respawn_items")
AddSpacerLine(scroll_pane)
AddLabel(scroll_pane, nil, {"oarc-label-crashed-ship-items"}, my_label_header2_style)
CreateCrashSiteEnable(scroll_pane, surface_name)
local crash_site_flow = scroll_pane.add { type = "flow", direction = "horizontal" }
CreateItemsSection(crash_site_flow, surface_name, {"oarc-label-crashed-ship-max"}, "crashed_ship_resources", MAX_CRASHED_SHIP_RESOURCES_ITEMS)
CreateItemsSection(crash_site_flow, surface_name, {"oarc-label-ship-wreckage-max"}, "crashed_ship_wreakage", MAX_CRASHED_SHIP_WRECKAGE_ITEMS)
AddSpacerLine(scroll_pane)
AddLabel(scroll_pane, nil, {"oarc-label-spawn-area-resources"}, my_label_header2_style)
local spawn_config_flow = scroll_pane.add { type = "flow", direction = "horizontal" }
CreateSolidResourcesConfig(spawn_config_flow, surface_name)
CreateFluidResourcesConfig(spawn_config_flow, surface_name)
AddSpacerLine(scroll_pane)
AddLabel(scroll_pane, nil, {"oarc-label-spawn-area-misc"}, my_label_header2_style)
local misc_config_flow = scroll_pane.add { type = "flow", direction = "horizontal" }
CreateMiscConfig(misc_config_flow, surface_name)
CreateSafeAreaConfig(misc_config_flow, surface_name)
end
---Create a checkbox to enable/disable the crashed ship
---@param container LuaGuiElement
---@param surface_name string
---@return nil
function CreateCrashSiteEnable(container, surface_name)
local crashed_ship_enabled = storage.ocfg.surfaces_config[surface_name].starting_items.crashed_ship
local crashed_ship_flow = container.add {
type = "flow",
direction = "horizontal"
}
crashed_ship_flow.style.vertical_align = "center"
AddLabel(crashed_ship_flow, nil, {"oarc-crash-site-enable-label"}, "caption_label")
local crashed_ship_enabled_checkbox = crashed_ship_flow.add {
type = "checkbox",
state = crashed_ship_enabled,
tags = {
action = "oarc_surface_config_tab",
setting = "crashed_ship_enabled",
surface_name = surface_name
},
tooltip = {"oarc-crash-site-enable-tooltip"}
}
end
---Create surface dropdown selection
---@param container LuaGuiElement
---@return string --The default selected surface name
function CreateSurfaceDropdown(container)
local surface_names = {}
for surface_name,_ in pairs(storage.ocfg.surfaces_config) do
table.insert(surface_names, surface_name)
end
table.sort(surface_names)
local selected_surface_name = surface_names[1]
local horizontal_flow = container.add {
type = "flow",
direction = "horizontal"
}
horizontal_flow.style.vertical_align = "center"
AddLabel(horizontal_flow, nil, {"oarc-select-surface-label"}, "caption_label")
local surface_dropdown = horizontal_flow.add {
type = "drop-down",
name = "surface_dropdown",
items = surface_names,
selected_index = 1,
tags = {
action = "oarc_surface_config_tab",
setting = "surface_dropdown"
},
tooltip = {"oarc-select-surface-tooltip"}
}
local dragger = horizontal_flow.add{ type="empty-widget", style="draggable_space_header" }
dragger.style.horizontally_stretchable = true
-- A button to revert config to default (from OCFG hardcoded.)
local revert_button = horizontal_flow.add {
type = "button",
caption = {"oarc-revert-button"},
tooltip = {"oarc-revert-tooltip"},
style = "red_button",
tags = {
action = "oarc_surface_config_tab",
setting = "revert_to_default"
}
}
-- Add button to copy nauvis config to current selected surface (if not nauvis)
local copy_button = horizontal_flow.add {
type = "button",
caption = {"oarc-copy-nauvis-button"},
tooltip = {"oarc-copy-nauvis-tooltip"},
style = "red_button",
tags = {
action = "oarc_surface_config_tab",
setting = "copy_nauvis"
}
}
return selected_surface_name
end
---Create an items selection section
---@param container LuaGuiElement
---@param surface_name string
---@param header LocalisedString
---@param setting_name string
---@param max_count integer?
---@return nil
function CreateItemsSection(container, surface_name, header, setting_name, max_count)
local items = storage.ocfg.surfaces_config[surface_name].starting_items[setting_name]
if (items == nil) then
error("No items found for setting: " .. setting_name .. " for surface: " .. surface_name)
end
if (max_count and (table_size(items) > max_count)) then
-- This would only happen with a bad config.
error("Too many items in starting items list!?")
end
local vertical_flow = container.add {
type = "frame",
direction = "vertical",
-- style = "inside_shallow_frame"
}
vertical_flow.style.padding = 5
vertical_flow.style.horizontally_stretchable = false
vertical_flow.style.vertically_stretchable = true
AddLabel(vertical_flow, nil, header, my_label_header2_style)
local table = vertical_flow.add {
type = "table",
column_count = 3,
-- style = "bordered_table",
tags = {
surface_name = surface_name,
setting = setting_name,
max_count = max_count or 0
}
}
--Add headers
AddLabel(table, nil, "Item", my_label_style)
AddLabel(table, nil, "Count", my_label_style)
AddLabel(table, nil, "", my_label_style)
for item_name, item_count in pairs(items) do
SurfaceConfigItemListDisplayRow(table, item_name, item_count)
end
-- Add a button to add another row
if (max_count == nil) or (max_count == 0) or (table_size(items) < max_count) then
SurfaceConfigItemListAddRowButton(table)
end
end
---Adds a row to a table with an item and count
---@param table LuaGuiElement
---@param item_name string?
---@param item_count integer?
---@return nil
function SurfaceConfigItemListDisplayRow(table, item_name, item_count)
-- Create choose elem button
local button = table.add {
type = "choose-elem-button",
elem_type = "item",
item = item_name,
tags = {
action = "oarc_surface_config_tab",
elem_button = true,
item_name = item_name or ""
},
}
button.style.width = 28
button.style.height = 28
-- Create number textfield
local textfield = table.add {
type = "textfield",
text = tostring(item_count or 0),
numeric = true,
allow_decimal = false,
tooltip = {"oarc-settings-tab-text-field-enter-tooltip" },
tags = {
action = "oarc_surface_config_tab",
item_number_textfield = true,
item_name = item_name or ""
}
}
if (item_name == "") then
textfield.style = "invalid_value_textfield"
end
textfield.style.width = 40
-- Create a button to remove the row
local remove_button = table.add {
type = "sprite-button",
sprite = "utility/deconstruction_mark",
tooltip = { "oarc-remove-item" },
tags = {
action = "oarc_surface_config_tab",
remove_row_button = true,
item_name = item_name or ""
}
}
remove_button.style.width = 28
remove_button.style.height = 28
end
---Add the add row button to the table
---@param table LuaGuiElement
---@return nil
function SurfaceConfigItemListAddRowButton(table)
-- Add a button to add another row
local add_row_button = table.add {
type = "choose-elem-button",
elem_type = "entity",
-- type = "sprite-button",
-- sprite = "utility/check_mark_green",
tooltip = {"oarc-add-item-tooltip"},
tags = {
action = "oarc_surface_config_tab",
add_row_button = true
}
}
add_row_button.style.width = 28
add_row_button.style.height = 28
end
---Create the safe area config section
---@param container LuaGuiElement
---@param surface_name string
---@return nil
function CreateSafeAreaConfig(container, surface_name)
local safe_area_flow = container.add {
type = "frame",
direction = "vertical",
-- style = "inside_shallow_frame"
}
safe_area_flow.style.padding = 5
safe_area_flow.style.horizontally_stretchable = false
safe_area_flow.style.vertically_stretchable = true
local header = AddLabel(safe_area_flow, nil, { "oarc-safe-area-config" }, my_label_header2_style)
header.tooltip = { "oarc-safe-area-tooltip" }
CreateSpawnConfigIntegerField(safe_area_flow, surface_name, { "oarc-safe-area-radius" }, "safe_area", "safe_radius", { "oarc-safe-radius-tooltip" })
CreateSpawnConfigIntegerField(safe_area_flow, surface_name, { "oarc-warn-area-radius" }, "safe_area", "warn_radius", { "oarc-warn-radius-tooltip" })
CreateSpawnConfigIntegerField(safe_area_flow, surface_name, { "oarc-warn-area-reduction" }, "safe_area", "warn_reduction", { "oarc-warn-reduction-tooltip" })
CreateSpawnConfigIntegerField(safe_area_flow, surface_name, { "oarc-danger-area-radius" }, "safe_area", "danger_radius", { "oarc-danger-radius-tooltip" })
CreateSpawnConfigIntegerField(safe_area_flow, surface_name, { "oarc-danger-area-reduction" }, "safe_area", "danger_reduction", { "oarc-danger-reduction-tooltip" })
end
---Create an integer textfield with a label
---@param container LuaGuiElement
---@param surface_name string
---@param label LocalisedString
---@param setting_name string
---@param entry_name string
---@param tooltip LocalisedString
---@return nil
function CreateSpawnConfigIntegerField(container, surface_name, label, setting_name, entry_name, tooltip)
local value = storage.ocfg.surfaces_config[surface_name].spawn_config[setting_name][entry_name]
local flow = container.add {
type = "flow",
direction = "horizontal"
}
AddLabel(flow, nil, label, my_label_style)
local dragger = flow.add{ type="empty-widget", style="draggable_space_header" }
dragger.style.horizontally_stretchable = true
-- Create number textfield
local textfield = flow.add {
type = "textfield",
text = tostring(value),
tooltip = tooltip,
numeric = true,
allow_decimal = false,
tags = {
action = "oarc_surface_config_tab",
surface_name = surface_name,
setting = setting_name,
entry = entry_name,
spawn_config_textfield = true
}
}
textfield.style.width = 50
end
---Create the solid resources config section
---@param container LuaGuiElement
---@param surface_name string
---@return nil
function CreateSolidResourcesConfig(container, surface_name)
local solid_resources = storage.ocfg.surfaces_config[surface_name].spawn_config.solid_resources
local solid_resources_flow = container.add {
type = "frame",
direction = "vertical",
-- style = "inside_shallow_frame"
}
solid_resources_flow.style.padding = 5
solid_resources_flow.style.horizontally_stretchable = false
solid_resources_flow.style.vertically_stretchable = true
local header = AddLabel(solid_resources_flow, nil, { "oarc-solid-resources-config" }, my_label_header2_style)
header.tooltip = { "oarc-solid-resources-tooltip" }
-- Create a table to display the resources
local table = solid_resources_flow.add {
type = "table",
column_count = 4,
tags = {
surface_name = surface_name,
setting = "solid_resources"
}
}
--Add headers
AddLabel(table, nil, "Type", my_label_style)
AddLabel(table, nil, "Amount", my_label_style)
AddLabel(table, nil, "Size", my_label_style)
AddLabel(table, nil, "", my_label_style)
for resource_name, resource_data in pairs(solid_resources) do
SolidResourcesConfigDisplayRow(table, resource_name, resource_data.amount, resource_data.size)
end
SurfaceConfigSolidResourcesAddRowButton(table)
end
---Create the fluid resources config section
---@param container LuaGuiElement
---@param surface_name string
---@return nil
function CreateFluidResourcesConfig(container, surface_name)
local fluid_resources = storage.ocfg.surfaces_config[surface_name].spawn_config.fluid_resources
local fluid_resources_flow = container.add {
type = "frame",
direction = "vertical",
-- style = "inside_shallow_frame"
}
fluid_resources_flow.style.padding = 5
fluid_resources_flow.style.horizontally_stretchable = false
fluid_resources_flow.style.vertically_stretchable = true
local header = AddLabel(fluid_resources_flow, nil, { "oarc-fluid-resources-config" }, my_label_header2_style)
header.tooltip = { "oarc-fluid-resources-tooltip" }
-- Create a table to display the resources
local fluid_table = fluid_resources_flow.add {
type = "table",
column_count = 4,
tags = {
surface_name = surface_name,
setting = "fluid_resources"
}
}
--Add headers
AddLabel(fluid_table, nil, { "oarc-fluid-type" }, my_label_style)
AddLabel(fluid_table, nil, { "oarc-fluid-count" }, my_label_style)
AddLabel(fluid_table, nil, { "oarc-fluid-amount" }, my_label_style)
AddLabel(fluid_table, nil, "", my_label_style)
for resource_name, resource_data in pairs(fluid_resources) do
FluidResourcesConfigDisplayRow(fluid_table, resource_name, resource_data.num_patches, resource_data.amount)
end
SurfaceConfigFluidResourcesAddRowButton(fluid_table)
end
---Create the water strip config section
---@param container LuaGuiElement
---@param surface_name string
---@return nil
function CreateMiscConfig(container, surface_name)
local misc_flow = container.add {
type = "frame",
direction = "vertical",
-- style = "inside_shallow_frame"
}
misc_flow.style.padding = 5
misc_flow.style.horizontally_stretchable = false
AddLabel(misc_flow, nil, { "oarc-misc-config" }, my_label_header2_style)
AddLabel(misc_flow, nil, { "oarc-liquid" }, my_player_list_style)
CreateSpawnConfigIntegerField(misc_flow, surface_name, { "oarc-liquid-length" }, "water", "length", { "oarc-liquid-length-tooltip" })
CreateSpawnConfigIntegerField(misc_flow, surface_name, { "oarc-liquid-x-offset" }, "water", "x_offset", { "oarc-liquid-x-offset-tooltip" })
CreateSpawnConfigIntegerField(misc_flow, surface_name, { "oarc-liquid-y-offset" }, "water", "y_offset", { "oarc-liquid-y-offset-tooltip" })
AddSpacerLine(misc_flow)
AddLabel(misc_flow, nil, { "oarc-shared-chest" }, my_player_list_style)
CreateSpawnConfigIntegerField(misc_flow, surface_name, { "oarc-chest-x-offset" }, "shared_chest_position", "x_offset", { "oarc-chest-x-offset-tooltip" })
CreateSpawnConfigIntegerField(misc_flow, surface_name, { "oarc-chest-y-offset" }, "shared_chest_position", "y_offset", { "oarc-chest-y-offset-tooltip" })
AddSpacerLine(misc_flow)
AddLabel(misc_flow, nil, { "oarc-shared-power-pole" }, my_player_list_style)
CreateSpawnConfigIntegerField(misc_flow, surface_name, { "oarc-power-x-offset" }, "shared_power_pole_position", "x_offset", { "oarc-power-x-offset-tooltip" })
CreateSpawnConfigIntegerField(misc_flow, surface_name, { "oarc-power-y-offset" }, "shared_power_pole_position", "y_offset", { "oarc-power-y-offset-tooltip" })
end
---Adds a row to a table with a resource, amount, and size
---@param table LuaGuiElement
---@param resource_name string?
---@param amount integer
---@param size integer
---@return nil
function SolidResourcesConfigDisplayRow(table, resource_name, amount, size)
-- Create choose elem button
local button = table.add {
type = "choose-elem-button",
elem_type = "entity",
elem_filters = {{filter = "type", type = "resource"}},
tags = {
action = "oarc_surface_config_tab",
resource_elem_button = true,
resource_name = resource_name or ""
},
}
button.elem_value = resource_name
button.style.width = 28
button.style.height = 28
-- Create number textfield
local amount_textfield = table.add {
type = "textfield",
text = tostring(amount),
numeric = true,
allow_decimal = false,
tags = {
action = "oarc_surface_config_tab",
resource_amount_textfield = true,
resource_name = resource_name or ""
}
}
amount_textfield.style.width = 50
-- Create number textfield
local size_textfield = table.add {
type = "textfield",
text = tostring(size),
numeric = true,
allow_decimal = false,
tags = {
action = "oarc_surface_config_tab",
resource_size_textfield = true,
resource_name = resource_name or ""
}
}
size_textfield.style.width = 50
-- Create a button to remove the row
local remove_button = table.add {
type = "sprite-button",
sprite = "utility/deconstruction_mark",
tooltip = { "oarc-remove-resource" },
tags = {
action = "oarc_surface_config_tab",
resource_remove_row_button = true,
resource_name = resource_name or ""
}
}
remove_button.style.width = 28
remove_button.style.height = 28
end
---Add the add row button to the table for solid resources
---@param table LuaGuiElement
---@return nil
function SurfaceConfigSolidResourcesAddRowButton(table)
-- Add a button to add another row
local add_row_button = table.add {
type = "choose-elem-button",
elem_type = "entity",
-- type = "sprite-button",
-- sprite = "utility/check_mark_green",
tooltip = { "oarc-add-item" },
tags = {
action = "oarc_surface_config_tab",
resource_add_row_button = true
}
}
add_row_button.style.width = 28
add_row_button.style.height = 28
end
---Adds a row to a table with a fluid resource, amount, count, spacing, and vertical offset
---@param table LuaGuiElement
---@param resource_name string?
---@param count integer
---@param amount integer
---@return nil
function FluidResourcesConfigDisplayRow(table, resource_name, count, amount)
-- Create choose elem button
local button = table.add {
type = "choose-elem-button",
elem_type = "entity",
elem_filters = {{filter = "type", type = "resource"}},
tags = {
action = "oarc_surface_config_tab",
fluid_resource_elem_button = true,
resource_name = resource_name or ""
},
}
button.elem_value = resource_name
button.style.width = 28
button.style.height = 28
-- Number of fluid patches
local count_textfield = table.add {
type = "textfield",
text = tostring(count),
numeric = true,
allow_decimal = false,
tags = {
action = "oarc_surface_config_tab",
fluid_resource_count_textfield = true,
resource_name = resource_name or ""
}
}
count_textfield.style.width = 40
-- Amount of fluid per patch
local amount_textfield = table.add {
type = "textfield",
text = tostring(amount),
numeric = true,
allow_decimal = false,
tags = {
action = "oarc_surface_config_tab",
fluid_resource_amount_textfield = true,
resource_name = resource_name or ""
}
}
amount_textfield.style.width = 60
-- Create a button to remove the row
local remove_button = table.add {
type = "sprite-button",
sprite = "utility/deconstruction_mark",
tooltip = { "oarc-remove-resource" },
tags = {
action = "oarc_surface_config_tab",
resource_remove_row_button = true,
resource_name = resource_name or ""
}
}
remove_button.style.width = 28
remove_button.style.height = 28
end
---Add the add row button to the table for fluid resources
---@param table LuaGuiElement
---@return nil
function SurfaceConfigFluidResourcesAddRowButton(table)
-- Add a button to add another row
local add_row_button = table.add {
type = "choose-elem-button",
elem_type = "entity",
-- type = "sprite-button",
-- sprite = "utility/check_mark_green",
tooltip = { "oarc-add-item" },
tags = {
action = "oarc_surface_config_tab",
fluid_resource_add_row_button = true
}
}
add_row_button.style.width = 28
add_row_button.style.height = 28
end
--[[
_____ _____ _ _ _____ _ _ _ _ _ ___ _ ___ ___ ___
| __\ \ / / __| \| |_ _| | || | /_\ | \| | \| | | __| _ \/ __|
| _| \ V /| _|| .` | | | | __ |/ _ \| .` | |) | |__| _|| /\__ \
|___| \_/ |___|_|\_| |_| |_||_/_/ \_\_|\_|___/|____|___|_|_\|___/
]]
---Handle the surface dropdown selection
---@param event EventData.on_gui_selection_state_changed
---@return nil
function SurfaceConfigTabGuiSelect(event)
if not event.element.valid then return end
local player = game.players[event.player_index]
local tags = event.element.tags
if (tags.action ~= "oarc_surface_config_tab") then
return
end
if (tags.setting == "surface_dropdown") then
local selected_surface_name = event.element.items[event.element.selected_index] --[[@as string]]
local content_flow = event.element.parent.parent["surface_config_content_flow"]
if (content_flow == nil) then
error("Content flow is nil? This shouldn't happen on surface dropdown select! " .. selected_surface_name)
end
-- Recreate the content section
content_flow.clear()
CreateSurfaceConfigContent(content_flow, selected_surface_name)
end
end
---Handle on_gui_text_changed events
---@param event EventData.on_gui_text_changed
---@return nil
function SurfaceConfigTabGuiTextChanged(event)
if not event.element.valid then return end
local player = game.players[event.player_index]
local tags = event.element.tags
if (tags.action ~= "oarc_surface_config_tab") then
return
end
if (tags.item_number_textfield or tags.fluid_resource_count_textfield) then
event.element.style = "invalid_value_textfield"
event.element.style.width = 40
elseif (tags.resource_amount_textfield or tags.resource_size_textfield or tags.spawn_config_textfield) then
event.element.style = "invalid_value_textfield"
event.element.style.width = 50
elseif tags.fluid_resource_amount_textfield then
event.element.style = "invalid_value_textfield"
event.element.style.width = 60
end
end
---Handle on_gui_confirmed events
---@param event EventData.on_gui_confirmed
---@return nil
function SurfaceConfigTabGuiConfirmed(event)
if not event.element.valid then return end
local player = game.players[event.player_index]
local tags = event.element.tags
if (tags.action ~= "oarc_surface_config_tab") then
return
end
if (tags.item_number_textfield) then
local parent = event.element.parent
local surface_name = parent.tags.surface_name --[[@as string]]
local setting_name = parent.tags.setting --[[@as string]]
local item_name = tags.item_name --[[@as string]]
-- Check if an item is selected first.
if (tags.item_name == "") then
SendErrorMsg(player, "Please select an item first!")
event.element.text = "0"
return
end
-- Update the count
local count = tonumber(event.element.text) or 0
storage.ocfg.surfaces_config[surface_name].starting_items[setting_name][item_name] = count
event.element.style = "textbox"
event.element.style.width = 40
elseif (tags.resource_amount_textfield or tags.resource_size_textfield) then
local parent = event.element.parent
local surface_name = parent.tags.surface_name --[[@as string]]
local setting_name = parent.tags.setting --[[@as string]]
local resource_name = tags.resource_name --[[@as string]]
-- Check if an item is selected first.
if (tags.resource_name == "") then
SendErrorMsg(player, "Please select a resource first!")
event.element.text = "0"
return
end
-- Update the count
local count = tonumber(event.element.text) or 0
if (tags.resource_amount_textfield) then
storage.ocfg.surfaces_config[surface_name].spawn_config[setting_name][resource_name].amount = count
elseif (tags.resource_size_textfield) then
storage.ocfg.surfaces_config[surface_name].spawn_config[setting_name][resource_name].size = count
end
event.element.style = "textbox"
event.element.style.width = 50
elseif (tags.fluid_resource_count_textfield or tags.fluid_resource_amount_textfield) then
local parent = event.element.parent
local surface_name = parent.tags.surface_name --[[@as string]]
local setting_name = parent.tags.setting --[[@as string]]
local resource_name = tags.resource_name --[[@as string]]
-- Check if an item is selected first.
if (tags.resource_name == "") then
SendErrorMsg(player, "Please select a resource first!")
event.element.text = "0"
return
end
-- Update the count
local count = tonumber(event.element.text) or 0
event.element.style = "textbox"
if (tags.fluid_resource_count_textfield) then
storage.ocfg.surfaces_config[surface_name].spawn_config[setting_name][resource_name].num_patches = count
event.element.style.width = 40
elseif (tags.fluid_resource_amount_textfield) then
storage.ocfg.surfaces_config[surface_name].spawn_config[setting_name][resource_name].amount = count
event.element.style.width = 60
end
elseif (tags.spawn_config_textfield) then
local surface_name = tags.surface_name --[[@as string]]
local setting_name = tags.setting --[[@as string]]
local entry_name = tags.entry --[[@as string]]
local value = tonumber(event.element.text) or 0
storage.ocfg.surfaces_config[surface_name].spawn_config[setting_name][entry_name] = value
event.element.style = "textbox"
event.element.style.width = 50
end
end
---Handle elem changed events
---@param event EventData.on_gui_elem_changed
---@return nil
function SurfaceConfigTabGuiElemChanged(event)
if not event.element.valid then return end
local player = game.players[event.player_index]
local tags = event.element.tags
if (tags.action ~= "oarc_surface_config_tab") then
return
end
if (tags.elem_button) then
local new_item_name = event.element.elem_value --[[@as string]]
if (new_item_name == nil) then
return
end
local old_item_name = tags.item_name --[[@as string]]
-- if the new item name is the same as the old item name, do nothing.
if (new_item_name == tags.item_name) then
return
end
-- otherwise, check if the new item name is already in the list.
local parent = event.element.parent
local surface_name = parent.tags.surface_name --[[@as string]]
local setting_name = parent.tags.setting --[[@as string]]
if (storage.ocfg.surfaces_config[surface_name].starting_items[setting_name][new_item_name]) then
SendErrorMsg(player, "Item already exists in list! " .. new_item_name)
event.element.elem_value = nil
return
end
-- Update the item name in the list, keep the old count.
if (old_item_name ~= "") then
storage.ocfg.surfaces_config[surface_name].starting_items[setting_name][new_item_name] = storage.ocfg.surfaces_config[surface_name].starting_items[setting_name][old_item_name]
storage.ocfg.surfaces_config[surface_name].starting_items[setting_name][old_item_name] = nil
else
storage.ocfg.surfaces_config[surface_name].starting_items[setting_name][new_item_name] = 0
end
-- Update all tags with the new item name.
for _, child in pairs(event.element.parent.children) do
if (child.tags.item_name == old_item_name) then
local tags_copy = child.tags
tags_copy.item_name = new_item_name
child.tags = tags_copy
end
end
elseif (tags.resource_elem_button) then
local new_resource_name = event.element.elem_value --[[@as string]]
if (new_resource_name == nil) then
return
end
if (prototypes.entity[new_resource_name].resource_category ~= "basic-solid") then
SendErrorMsg(player, "Resource must be a solid resource! " .. new_resource_name)
event.element.elem_value = nil
return
end
local old_resource_name = tags.resource_name --[[@as string]]
-- if the new resource name is the same as the old resource name, do nothing.
if (new_resource_name == tags.resource_name) then
return
end
-- otherwise, check if the new resource name is already in the list.
local parent = event.element.parent
local surface_name = parent.tags.surface_name --[[@as string]]
local setting_name = parent.tags.setting --[[@as string]]
if (storage.ocfg.surfaces_config[surface_name].spawn_config[setting_name][new_resource_name]) then
SendErrorMsg(player, "Resource already exists in list! " .. new_resource_name)
event.element.elem_value = nil
return
end
-- Update the resource name in the list, keep the old amount and size.
if (old_resource_name ~= "") then
storage.ocfg.surfaces_config[surface_name].spawn_config[setting_name][new_resource_name] = storage.ocfg.surfaces_config[surface_name].spawn_config[setting_name][old_resource_name]
storage.ocfg.surfaces_config[surface_name].spawn_config[setting_name][old_resource_name] = nil
else
storage.ocfg.surfaces_config[surface_name].spawn_config[setting_name][new_resource_name] = {amount=0, size=0, x_offset=0, y_offset=0}
end
-- Update all tags with the new resource name.
for _, child in pairs(event.element.parent.children) do
if (child.tags.resource_name == old_resource_name) then
local tags_copy = child.tags
tags_copy.resource_name = new_resource_name
child.tags = tags_copy
end
end
elseif (tags.fluid_resource_elem_button) then
local new_resource_name = event.element.elem_value --[[@as string]]
if (new_resource_name == nil) then
return
end
if (prototypes.entity[new_resource_name].resource_category ~= "basic-fluid") then
SendErrorMsg(player, "Resource must be a fluid resource! " .. new_resource_name)
event.element.elem_value = nil
return
end
local old_resource_name = tags.resource_name --[[@as string]]
-- if the new resource name is the same as the old resource name, do nothing.
if (new_resource_name == tags.resource_name) then
return
end
-- otherwise, check if the new resource name is already in the list.
local parent = event.element.parent
local surface_name = parent.tags.surface_name --[[@as string]]
local setting_name = parent.tags.setting --[[@as string]]
if (storage.ocfg.surfaces_config[surface_name].spawn_config[setting_name][new_resource_name]) then
SendErrorMsg(player, "Resource already exists in list! " .. new_resource_name)
event.element.elem_value = nil
return
end
-- Update the resource name in the list, keep the old amount and size.
if (old_resource_name ~= "") then
storage.ocfg.surfaces_config[surface_name].spawn_config[setting_name][new_resource_name] = storage.ocfg.surfaces_config[surface_name].spawn_config[setting_name][old_resource_name]
storage.ocfg.surfaces_config[surface_name].spawn_config[setting_name][old_resource_name] = nil
else
storage.ocfg.surfaces_config[surface_name].spawn_config[setting_name][new_resource_name] = {num_patches=0, amount=0, x_offset=0, y_offset=0}
end
-- Update all tags with the new resource name.
for _, child in pairs(event.element.parent.children) do
if (child.tags.resource_name == old_resource_name) then
local tags_copy = child.tags
tags_copy.resource_name = new_resource_name
child.tags = tags_copy
end
end
end
end
---Handle the surface config tab button clicks
---@param event EventData.on_gui_click
---@return nil
function SurfaceConfigTabGuiClick(event)
if not event.element.valid then return end
local player = game.players[event.player_index]
local tags = event.element.tags
if (tags.action ~= "oarc_surface_config_tab") then
return
end
if (tags.remove_row_button) then
local parent = event.element.parent
local surface_name = parent.tags.surface_name --[[@as string]]
local setting_name = parent.tags.setting --[[@as string]]
local item_name = tags.item_name --[[@as string]]
local max_count = parent.tags.max_count --[[@as integer]]
-- Nil the entry
storage.ocfg.surfaces_config[surface_name].starting_items[setting_name][item_name] = nil
-- Delete the row by removing the child elements from the table.
local parent = event.element.parent --[[@as LuaGuiElement]] -- Ass(u)me that the parent is a table.
for _, child in pairs(parent.children) do
if (child.tags and child.tags.item_name == tags.item_name) then
child.destroy()
end
end
-- Only add the add row if we haven't reached the max count AND the children count is 1 more than % 3.
local table_modulo_3 = #parent.children % 3
if table_modulo_3 == 0 then
SurfaceConfigItemListAddRowButton(parent)
end
elseif (tags.add_row_button) then
local parent = event.element.parent
local surface_name = parent.tags.surface_name --[[@as string]]
local setting_name = parent.tags.setting --[[@as string]]
local max_count = parent.tags.max_count --[[@as integer]]
if (parent == nil) then
error("Parent is nil? This shouldn't happen on add row button click! " .. setting_name)
end
-- Delete the button and add a new row and then add the button back.
event.element.destroy()
SurfaceConfigItemListDisplayRow(parent)
-- Only add the add row if we haven't reached the max count.
local item_count = (#parent.children - 3) / 3
if (max_count == nil) or (max_count == 0) or (item_count < max_count) then
SurfaceConfigItemListAddRowButton(parent)
end
elseif (tags.setting == "crashed_ship_enabled") then
local surface_name = tags.surface_name --[[@as string]]
storage.ocfg.surfaces_config[surface_name].starting_items.crashed_ship = event.element.state
elseif (tags.setting == "revert_to_default") then
local surface_name = event.element.parent["surface_dropdown"].items[event.element.parent["surface_dropdown"].selected_index] --[[@as string]]
CompatSend(player, "Revert to default: " .. surface_name)
storage.ocfg.surfaces_config[surface_name].starting_items = table.deepcopy(NAUVIS_STARTER_ITEMS)
storage.ocfg.surfaces_config[surface_name].spawn_config = table.deepcopy(NAUVIS_SPAWN_CONFIG)
-- Recreate the content section
local content_flow = event.element.parent.parent["surface_config_content_flow"]
if (content_flow == nil) then
error("Content flow is nil? This shouldn't happen on revert to default! " .. surface_name)
end
content_flow.clear()
CreateSurfaceConfigContent(content_flow, surface_name)
elseif (tags.setting == "copy_nauvis") then
local surface_name = event.element.parent["surface_dropdown"].items[event.element.parent["surface_dropdown"].selected_index] --[[@as string]]
if (surface_name == "nauvis") then
SendErrorMsg(player, "Already on nauvis, select a different surface to copy nauvis settings to!")
return
end
CompatSend(player, "Copy nauvis to " .. surface_name)
storage.ocfg.surfaces_config[surface_name].starting_items = storage.ocfg.surfaces_config["nauvis"].starting_items
storage.ocfg.surfaces_config[surface_name].spawn_config = storage.ocfg.surfaces_config["nauvis"].spawn_config
-- Recreate the content section
local content_flow = event.element.parent.parent["surface_config_content_flow"]
if (content_flow == nil) then
error("Content flow is nil? This shouldn't happen on copy nauvis! " .. surface_name)
end
content_flow.clear()
CreateSurfaceConfigContent(content_flow, surface_name)
elseif (tags.resource_remove_row_button) then
local resource_name = tags.resource_name --[[@as string]]
local parent = event.element.parent
local surface_name = parent.tags.surface_name --[[@as string]]
local setting_name = parent.tags.setting --[[@as string]]
-- Nil the entry
storage.ocfg.surfaces_config[surface_name].spawn_config[setting_name][resource_name] = nil
-- Delete the row by removing the child elements from the table.
for _, child in pairs(parent.children) do
if (child.tags.resource_name == resource_name) then
child.destroy()
end
end
elseif (tags.resource_add_row_button) then
local parent = event.element.parent
local setting_name = parent.tags.setting --[[@as string]]
if (parent == nil) then
error("Parent is nil? This shouldn't happen on add row button click! " .. setting_name)
end
-- Delete the button and add a new row and then add the button back.
event.element.destroy()
SolidResourcesConfigDisplayRow(parent, nil, 0, 0)
-- Add the add row button back.
SurfaceConfigSolidResourcesAddRowButton(parent)
elseif (tags.fluid_resource_add_row_button) then
local parent = event.element.parent
local setting_name = parent.tags.setting --[[@as string]]
if (parent == nil) then
error("Parent is nil? This shouldn't happen on add row button click! " .. setting_name)
end
-- Delete the button and add a new row and then add the button back.
event.element.destroy()
FluidResourcesConfigDisplayRow(parent, nil, 0, 0)
-- Add the add row button back.
SurfaceConfigFluidResourcesAddRowButton(parent)
end
end