2024-09-11 12:49:23 -04:00
-- This file is used to validate the config.lua file and handle any mod settings conflicts.
2024-09-23 22:48:08 -04:00
-- DON'T JUDGE ME! I wanted to try and make a nice in game setting GUI since the native mod settings GUI is so limited.
2024-08-16 01:40:16 -04:00
2024-08-23 21:52:48 -04:00
---Provides a way to look up the config settings key from the mod settings key.
2024-10-18 14:01:26 -04:00
---@alias OarcSettingsLookup { mod_key: string, ocfg_keys: table<integer, string>, type: string, text: LocalisedString?, caption: LocalisedString?, tooltip: LocalisedString? }
2024-08-23 21:52:48 -04:00
---@type table<string, OarcSettingsLookup>
OCFG_KEYS =
{
2024-09-24 22:28:45 -04:00
[ " server_info_HEADER " ] = { mod_key = " " , ocfg_keys = { " " } , type = " header " , text = { " oarc-settings-section-header-server-info " } } ,
2024-08-23 21:52:48 -04:00
[ " server_info.welcome_msg_title " ] = { mod_key = " oarc-mod-welcome-msg-title " , ocfg_keys = { " server_info " , " welcome_msg_title " } , type = " string " } ,
[ " server_info.welcome_msg " ] = { mod_key = " oarc-mod-welcome-msg " , ocfg_keys = { " server_info " , " welcome_msg " } , type = " string " } ,
2024-09-07 07:00:29 -04:00
[ " server_info.discord_invite " ] = { mod_key = " oarc-mod-discord-invite " , ocfg_keys = { " server_info " , " discord_invite " } , type = " string " } ,
2024-08-23 21:52:48 -04:00
2024-09-24 22:28:45 -04:00
[ " gameplay_HEADER " ] = { mod_key = " " , ocfg_keys = { " " } , type = " header " , text = { " oarc-settings-section-header-gameplay " } } ,
2024-09-25 13:12:01 -04:00
[ " gameplay_spawn_choices_SUBHEADER " ] = { mod_key = " " , ocfg_keys = { " " } , type = " subheader " , text = { " oarc-settings-section-subheader-spawn-choices " } } ,
2024-08-23 21:52:48 -04:00
[ " gameplay.enable_main_team " ] = { mod_key = " oarc-mod-enable-main-team " , ocfg_keys = { " gameplay " , " enable_main_team " } , type = " boolean " } ,
[ " gameplay.enable_separate_teams " ] = { mod_key = " oarc-mod-enable-separate-teams " , ocfg_keys = { " gameplay " , " enable_separate_teams " } , type = " boolean " } ,
2024-11-11 12:00:10 -05:00
-- STARTUP ["gameplay.default_enable_secondary_spawns_on_other_surfaces"] = {mod_key = "oarc-mod-default-enable-secondary-spawns-on-other-surfaces" , ocfg_keys = {"gameplay", "default_enable_secondary_spawns_on_other_surfaces"}, type = "boolean"},
2024-08-23 21:52:48 -04:00
[ " gameplay.allow_moats_around_spawns " ] = { mod_key = " oarc-mod-allow-moats-around-spawns " , ocfg_keys = { " gameplay " , " allow_moats_around_spawns " } , type = " boolean " } ,
[ " gameplay.enable_moat_bridging " ] = { mod_key = " oarc-mod-enable-moat-bridging " , ocfg_keys = { " gameplay " , " enable_moat_bridging " } , type = " boolean " } ,
[ " gameplay.minimum_distance_to_existing_chunks " ] = { mod_key = " oarc-mod-minimum-distance-to-existing-chunks " , ocfg_keys = { " gameplay " , " minimum_distance_to_existing_chunks " } , type = " integer " } ,
2024-08-24 21:06:43 -04:00
[ " gameplay.near_spawn_distance " ] = { mod_key = " oarc-mod-near-spawn-distance " , ocfg_keys = { " gameplay " , " near_spawn_distance " } , type = " integer " } ,
[ " gameplay.far_spawn_distance " ] = { mod_key = " oarc-mod-far-spawn-distance " , ocfg_keys = { " gameplay " , " far_spawn_distance " } , type = " integer " } ,
2024-08-23 21:52:48 -04:00
[ " gameplay.enable_buddy_spawn " ] = { mod_key = " oarc-mod-enable-buddy-spawn " , ocfg_keys = { " gameplay " , " enable_buddy_spawn " } , type = " boolean " } ,
[ " gameplay.enable_shared_spawns " ] = { mod_key = " oarc-mod-enable-shared-spawns " , ocfg_keys = { " gameplay " , " enable_shared_spawns " } , type = " boolean " } ,
[ " gameplay.number_of_players_per_shared_spawn " ] = { mod_key = " oarc-mod-number-of-players-per-shared-spawn " , ocfg_keys = { " gameplay " , " number_of_players_per_shared_spawn " } , type = " integer " } ,
[ " gameplay.default_surface " ] = { mod_key = " oarc-mod-default-surface " , ocfg_keys = { " gameplay " , " default_surface " } , type = " string " } ,
2024-09-25 13:12:01 -04:00
-- STARTUP ["gameplay.main_force_name"] = {mod_key = "oarc-mod-main-force-name" , ocfg_keys = {"gameplay", "main_force_name"}, type = "string"},
2024-08-23 21:52:48 -04:00
2024-09-25 13:12:01 -04:00
[ " gameplay_difficulty_scaling_SUBHEADER " ] = { mod_key = " " , ocfg_keys = { " " } , type = " subheader " , text = { " oarc-settings-section-subheader-difficulty-scaling " } } ,
[ " gameplay.enable_offline_protection " ] = { mod_key = " oarc-mod-enable-offline-protection " , ocfg_keys = { " gameplay " , " enable_offline_protection " } , type = " boolean " } ,
2024-08-23 21:52:48 -04:00
[ " gameplay.scale_resources_around_spawns " ] = { mod_key = " oarc-mod-scale-resources-around-spawns " , ocfg_keys = { " gameplay " , " scale_resources_around_spawns " } , type = " boolean " } ,
[ " gameplay.modified_enemy_spawning " ] = { mod_key = " oarc-mod-modified-enemy-spawning " , ocfg_keys = { " gameplay " , " modified_enemy_spawning " } , type = " boolean " } ,
2024-09-25 13:12:01 -04:00
[ " gameplay_misc_SUBHEADER " ] = { mod_key = " " , ocfg_keys = { " " } , type = " subheader " , text = { " oarc-settings-section-subheader-gameplay-misc " } } ,
[ " gameplay.enable_friendly_fire " ] = { mod_key = " oarc-mod-enable-friendly-fire " , ocfg_keys = { " gameplay " , " enable_friendly_fire " } , type = " boolean " } ,
2024-08-23 21:52:48 -04:00
[ " gameplay.minimum_online_time " ] = { mod_key = " oarc-mod-minimum-online-time " , ocfg_keys = { " gameplay " , " minimum_online_time " } , type = " integer " } ,
[ " gameplay.respawn_cooldown_min " ] = { mod_key = " oarc-mod-respawn-cooldown-min " , ocfg_keys = { " gameplay " , " respawn_cooldown_min " } , type = " integer " } ,
2024-09-25 13:12:01 -04:00
[ " gameplay_sharing_SUBHEADER " ] = { mod_key = " " , ocfg_keys = { " " } , type = " subheader " , text = { " oarc-settings-section-subheader-sharing " } } ,
[ " gameplay.enable_shared_team_vision " ] = { mod_key = " oarc-mod-enable-shared-team-vision " , ocfg_keys = { " gameplay " , " enable_shared_team_vision " } , type = " boolean " } ,
[ " gameplay.enable_shared_team_chat " ] = { mod_key = " oarc-mod-enable-shared-team-chat " , ocfg_keys = { " gameplay " , " enable_shared_team_chat " } , type = " boolean " } ,
2024-10-25 19:56:04 -04:00
[ " gameplay.enable_friendly_teams " ] = { mod_key = " oarc-mod-enable-friendly-teams " , ocfg_keys = { " gameplay " , " enable_friendly_teams " } , type = " boolean " } ,
[ " gameplay.enable_cease_fire " ] = { mod_key = " oarc-mod-enable-cease-fire " , ocfg_keys = { " gameplay " , " enable_cease_fire " } , type = " boolean " } ,
2024-09-20 21:39:01 -04:00
[ " gameplay.enable_shared_power " ] = { mod_key = " oarc-mod-enable-shared-power " , ocfg_keys = { " gameplay " , " enable_shared_power " } , type = " boolean " } ,
[ " gameplay.enable_shared_chest " ] = { mod_key = " oarc-mod-enable-shared-chest " , ocfg_keys = { " gameplay " , " enable_shared_chest " } , type = " boolean " } ,
2024-10-12 21:57:46 -04:00
[ " gameplay.enable_coin_shop " ] = { mod_key = " oarc-mod-enable-coin-shop " , ocfg_keys = { " gameplay " , " enable_coin_shop " } , type = " boolean " } ,
2024-09-24 22:28:45 -04:00
[ " regrowth_HEADER " ] = { mod_key = " " , ocfg_keys = { " " } , type = " header " , text = { " oarc-settings-section-header-regrowth " } } ,
[ " regrowth_SUBHEADER " ] = { mod_key = " " , ocfg_keys = { " " } , type = " subheader " , text = { " oarc-settings-section-subheader-regrowth-warning " } } ,
2024-08-23 21:52:48 -04:00
[ " regrowth.enable_regrowth " ] = { mod_key = " oarc-mod-enable-regrowth " , ocfg_keys = { " regrowth " , " enable_regrowth " } , type = " boolean " } ,
[ " regrowth.enable_world_eater " ] = { mod_key = " oarc-mod-enable-world-eater " , ocfg_keys = { " regrowth " , " enable_world_eater " } , type = " boolean " } ,
[ " regrowth.enable_abandoned_base_cleanup " ] = { mod_key = " oarc-mod-enable-abandoned-base-cleanup " , ocfg_keys = { " regrowth " , " enable_abandoned_base_cleanup " } , type = " boolean " } ,
2024-09-10 11:40:19 -04:00
[ " regrowth.cleanup_interval " ] = { mod_key = " oarc-mod-regrowth-cleanup-interval-min " , ocfg_keys = { " regrowth " , " cleanup_interval " } , type = " integer " } ,
2024-09-23 22:48:08 -04:00
2024-09-24 22:28:45 -04:00
[ " general_spawn_HEADER " ] = { mod_key = " " , ocfg_keys = { " " } , type = " header " , text = { " oarc-settings-section-header-general-spawn " } } ,
2024-09-23 22:48:08 -04:00
[ " spawn_general.spawn_radius_tiles " ] = { mod_key = " oarc-mod-spawn-general-radius-tiles " , ocfg_keys = { " spawn_general " , " spawn_radius_tiles " } , type = " integer " } ,
[ " spawn_general.moat_width_tiles " ] = { mod_key = " oarc-mod-spawn-general-moat-width-tiles " , ocfg_keys = { " spawn_general " , " moat_width_tiles " } , type = " integer " } ,
[ " spawn_general.tree_width_tiles " ] = { mod_key = " oarc-mod-spawn-general-tree-width-tiles " , ocfg_keys = { " spawn_general " , " tree_width_tiles " } , type = " integer " } ,
[ " spawn_general.resources_shape " ] = { mod_key = " oarc-mod-spawn-general-enable-resources-circle-shape " , ocfg_keys = { " spawn_general " , " resources_shape " } , type = " string-list " } ,
2024-11-08 23:00:12 -05:00
[ " spawn_general.force_tiles " ] = { mod_key = " oarc-mod-spawn-general-enable-force-tiles " , ocfg_keys = { " spawn_general " , " force_tiles " } , type = " boolean " } ,
2024-09-23 22:48:08 -04:00
[ " spawn_general.shape " ] = { mod_key = " oarc-mod-spawn-general-shape " , ocfg_keys = { " spawn_general " , " shape " } , type = " string-list " } ,
2024-09-24 22:28:45 -04:00
[ " resource_placement_HEADER " ] = { mod_key = " " , ocfg_keys = { " " } , type = " header " , text = { " oarc-settings-section-header-resource-placement " } } ,
2024-09-23 22:48:08 -04:00
[ " resource_placement.enabled " ] = { mod_key = " oarc-mod-resource-placement-enabled " , ocfg_keys = { " resource_placement " , " enabled " } , type = " boolean " } ,
2024-09-24 22:28:45 -04:00
[ " resource_placement.size_multiplier " ] = { mod_key = " oarc-mod-resource-placement-size-multiplier " , ocfg_keys = { " resource_placement " , " size_multiplier " } , type = " double " } ,
[ " resource_placement.amount_multiplier " ] = { mod_key = " oarc-mod-resource-placement-amount-multiplier " , ocfg_keys = { " resource_placement " , " amount_multiplier " } , type = " double " } ,
[ " resource_placement_circle_SUBHEADER " ] = { mod_key = " " , ocfg_keys = { " " } , type = " subheader " , text = { " oarc-settings-section-subheader-resource-placement-circular " } } ,
2024-09-23 22:48:08 -04:00
[ " resource_placement.distance_to_edge " ] = { mod_key = " oarc-mod-resource-placement-distance-to-edge " , ocfg_keys = { " resource_placement " , " distance_to_edge " } , type = " integer " } ,
2024-10-19 13:21:35 -04:00
[ " resource_placement.angle_offset " ] = { mod_key = " oarc-mod-resource-placement-degrees-offset " , ocfg_keys = { " resource_placement " , " angle_offset " } , type = " integer " } ,
[ " resource_placement.angle_final " ] = { mod_key = " oarc-mod-resource-placement-degrees-final " , ocfg_keys = { " resource_placement " , " angle_final " } , type = " integer " } ,
2024-09-24 22:28:45 -04:00
[ " resource_placement_square_SUBHEADER " ] = { mod_key = " " , ocfg_keys = { " " } , type = " subheader " , text = { " oarc-settings-section-subheader-resource-placement-square " } } ,
2024-09-23 22:48:08 -04:00
[ " resource_placement.vertical_offset " ] = { mod_key = " oarc-mod-resource-placement-vertical-offset " , ocfg_keys = { " resource_placement " , " vertical_offset " } , type = " integer " } ,
[ " resource_placement.horizontal_offset " ] = { mod_key = " oarc-mod-resource-placement-horizontal-offset " , ocfg_keys = { " resource_placement " , " horizontal_offset " } , type = " integer " } ,
[ " resource_placement.linear_spacing " ] = { mod_key = " oarc-mod-resource-placement-linear-spacing " , ocfg_keys = { " resource_placement " , " linear_spacing " } , type = " integer " } ,
2024-10-18 14:01:26 -04:00
2024-10-18 20:05:11 -04:00
-- These are settings that aren't included in the games mod settings but are still nice to have easy access to.
2024-11-06 23:53:52 +08:00
[ " non_mod_settings_HEADER " ] = { mod_key = " " , ocfg_keys = { " " } , type = " header " , text = { " oarc-non-mod-settings-header " } } ,
[ " coin_generation_SUBHEADER " ] = { mod_key = " " , ocfg_keys = { " " } , type = " subheader " , text = { " oarc-coin-generation-subheader " } } ,
[ " coin_generation.enabled " ] = { mod_key = " " , ocfg_keys = { " coin_generation " , " enabled " } , type = " boolean " , caption = { " oarc-coin-generation-caption " } , tooltip = { " oarc-coin-generation-tooltip " } } ,
[ " coin_generation.auto_decon_coins " ] = { mod_key = " " , ocfg_keys = { " coin_generation " , " auto_decon_coins " } , type = " boolean " , caption = { " oarc-auto-decon-coins-caption " } , tooltip = { " oarc-auto-decon-coins-tooltip " } } ,
[ " gameplay.enable_player_self_reset " ] = { mod_key = " " , ocfg_keys = { " gameplay " , " enable_player_self_reset " } , type = " boolean " , caption = { " oarc-player-self-reset-caption " } , tooltip = { " oarc-player-self-reset-tooltip " } } ,
2024-12-05 21:21:13 -05:00
[ " gameplay.scale_spawner_damage " ] = { mod_key = " " , ocfg_keys = { " gameplay " , " scale_spawner_damage " } , type = " boolean " , caption = { " oarc-scale-spawner-damage-caption " } , tooltip = { " oarc-scale-spawner-damage-tooltip " } } ,
[ " spawn_general.remove_decoratives " ] = { mod_key = " " , ocfg_keys = { " spawn_general " , " remove_decoratives " } , type = " boolean " , caption = { " oarc-remove-decoratives-caption " } , tooltip = { " oarc-remove-decoratives-tooltip " } } ,
2024-12-09 11:16:12 -05:00
[ " resource_placement.random_order " ] = { mod_key = " " , ocfg_keys = { " resource_placement " , " random_order " } , type = " boolean " , caption = { " oarc-resource-placement-random-order-caption " } , tooltip = { " oarc-resource-placement-random-order-tooltip " } } ,
2024-11-06 23:53:52 +08:00
2024-08-23 21:52:48 -04:00
}
2024-09-09 14:20:52 -04:00
---Easy reverse lookup for mod settings keys.
---@type table<string, string>
2024-10-13 09:31:47 -04:00
local OCFG_MOD_KEYS = { }
2024-09-09 14:20:52 -04:00
2024-10-13 09:31:47 -04:00
---Create the reverse lookup table.
---@return nil
function SetupOCFGModKeys ( )
for key , entry in pairs ( OCFG_KEYS ) do
if ( entry.type ~= " header " ) and ( entry.type ~= " subheader " ) then
OCFG_MOD_KEYS [ entry.mod_key ] = key
end
end
end
2024-09-09 14:20:52 -04:00
2024-08-16 01:40:16 -04:00
function ValidateAndLoadConfig ( )
2024-10-13 09:31:47 -04:00
SetupOCFGModKeys ( )
2024-09-09 14:20:52 -04:00
-- Check that each of the OCFG_MOD_KEYS has a corresponding OCFG_KEYS entry.
for mod_key , ocfg_key in pairs ( OCFG_MOD_KEYS ) do
if ( OCFG_KEYS [ ocfg_key ] == nil ) then
error ( " OCFG_MOD_KEYS entry does not have a corresponding OCFG_KEYS entry: " .. mod_key .. " -> " .. ocfg_key )
end
end
-- And check the opposite.
for ocfg_key , entry in pairs ( OCFG_KEYS ) do
2024-09-24 22:28:45 -04:00
if ( entry.type ~= " header " ) and ( entry.type ~= " subheader " ) and ( OCFG_MOD_KEYS [ entry.mod_key ] == nil ) then
2024-09-09 14:20:52 -04:00
error ( " OCFG_KEYS entry does not have a corresponding OCFG_MOD_KEYS entry: " .. ocfg_key .. " -> " .. entry.mod_key )
end
end
2024-09-22 23:04:52 -04:00
-- Load the template config into the global table.
2024-08-16 01:40:16 -04:00
---@class OarcConfig
2024-10-19 20:48:20 -04:00
storage.ocfg = table.deepcopy ( OCFG )
2024-08-16 01:40:16 -04:00
2024-09-24 22:28:45 -04:00
-- Check that each entry in OCFG matches the default value of the mod setting. This is just for my own sanity.
-- Helps make sure mod default settings and my internal config are in sync.
for _ , entry in pairs ( OCFG_KEYS ) do
2024-10-18 14:01:26 -04:00
if ( entry.mod_key ~= " " ) then
2024-09-24 22:28:45 -04:00
local mod_key = entry.mod_key
local oarc_key = entry.ocfg_keys
2024-10-21 13:48:42 -04:00
local mod_value = prototypes.mod_setting [ mod_key ] . default_value
2024-09-24 22:28:45 -04:00
local oarc_value = GetGlobalOarcConfigUsingKeyTable ( oarc_key )
if ( mod_value ~= oarc_value ) then
error ( " OCFG value does not match mod setting: " .. mod_key .. " = " .. tostring ( mod_value ) .. " -> " .. serpent.block ( oarc_key ) .. " = " .. tostring ( oarc_value ) )
end
end
end
2024-09-22 23:04:52 -04:00
CacheModSettings ( ) -- Get all mod settings and overwrite the defaults in OARC_CFG.
2024-08-16 01:40:16 -04:00
2024-09-22 23:04:52 -04:00
GetScenarioOverrideSettings ( ) -- Get any scenario settings and overwrite both the mod settings and OARC_CFG.
2024-08-16 01:40:16 -04:00
2024-10-19 20:48:20 -04:00
SyncModSettingsToOCFG ( ) -- Make sure mod settings are in sync with storage.ocfg table.
2024-10-07 11:52:55 -04:00
2024-09-22 23:04:52 -04:00
ValidateSettings ( ) -- These are validation checks that can't be done within the mod settings natively.
2024-09-06 21:10:29 -04:00
end
2024-10-07 11:52:55 -04:00
---DO some basic validation checks on the config settings.
---@return nil
2024-09-06 21:10:29 -04:00
function ValidateSettings ( )
2024-10-07 11:52:55 -04:00
-- Verify the major sections exist. Not exhaustive but should catch missing sections.
2024-10-19 20:48:20 -04:00
if ( storage.ocfg [ " server_info " ] == nil ) then
2024-10-07 11:52:55 -04:00
log ( " ERROR - Missing server_info section in config! Loading defaults instead! " )
2024-12-02 12:49:56 -05:00
SendBroadcastMsg ( " ERROR - Missing server_info section in config! Loading defaults instead! " , { color = { r = 1 , g = 0.2 , b = 0.2 } , sound_path = " utility/cannot_build " } )
2024-10-19 20:48:20 -04:00
storage.ocfg . server_info = table.deepcopy ( OCFG.server_info )
2024-10-07 11:52:55 -04:00
end
2024-10-19 20:48:20 -04:00
if ( storage.ocfg [ " gameplay " ] == nil ) then
2024-10-07 11:52:55 -04:00
log ( " ERROR - Missing gameplay section in config! Loading defaults instead! " )
2024-12-02 12:49:56 -05:00
SendBroadcastMsg ( " ERROR - Missing gameplay section in config! Loading defaults instead! " , { color = { r = 1 , g = 0.2 , b = 0.2 } , sound_path = " utility/cannot_build " } )
2024-10-19 20:48:20 -04:00
storage.ocfg . gameplay = table.deepcopy ( OCFG.gameplay )
2024-10-07 11:52:55 -04:00
end
2024-10-19 20:48:20 -04:00
if ( storage.ocfg [ " regrowth " ] == nil ) then
2024-10-07 11:52:55 -04:00
log ( " ERROR - Missing regrowth section in config! Loading defaults instead! " )
2024-12-02 12:49:56 -05:00
SendBroadcastMsg ( " ERROR - Missing regrowth section in config! Loading defaults instead! " , { color = { r = 1 , g = 0.2 , b = 0.2 } , sound_path = " utility/cannot_build " } )
2024-10-19 20:48:20 -04:00
storage.ocfg . regrowth = table.deepcopy ( OCFG.regrowth )
2024-10-07 11:52:55 -04:00
end
2024-10-19 20:48:20 -04:00
if ( storage.ocfg [ " spawn_general " ] == nil ) then
2024-10-07 11:52:55 -04:00
log ( " ERROR - Missing spawn_general section in config! Loading defaults instead! " )
2024-12-02 12:49:56 -05:00
SendBroadcastMsg ( " ERROR - Missing spawn_general section in config! Loading defaults instead! " , { color = { r = 1 , g = 0.2 , b = 0.2 } , sound_path = " utility/cannot_build " } )
2024-10-19 20:48:20 -04:00
storage.ocfg . spawn_general = table.deepcopy ( OCFG.spawn_general )
2024-10-07 11:52:55 -04:00
end
2024-10-19 20:48:20 -04:00
if ( storage.ocfg [ " resource_placement " ] == nil ) then
2024-10-07 11:52:55 -04:00
log ( " ERROR - Missing resource_placement section in config! Loading defaults instead! " )
2024-12-02 12:49:56 -05:00
SendBroadcastMsg ( " ERROR - Missing resource_placement section in config! Loading defaults instead! " , { color = { r = 1 , g = 0.2 , b = 0.2 } , sound_path = " utility/cannot_build " } )
2024-10-19 20:48:20 -04:00
storage.ocfg . resource_placement = table.deepcopy ( OCFG.resource_placement )
2024-10-07 11:52:55 -04:00
end
2024-10-19 20:48:20 -04:00
if ( storage.ocfg [ " surfaces_config " ] == nil ) then
2024-10-07 11:52:55 -04:00
log ( " ERROR - Missing surfaces_config section in config! Loading defaults instead! " )
2024-12-02 12:49:56 -05:00
SendBroadcastMsg ( " ERROR - Missing surfaces_config section in config! Loading defaults instead! " , { color = { r = 1 , g = 0.2 , b = 0.2 } , sound_path = " utility/cannot_build " } )
2024-10-19 20:48:20 -04:00
storage.ocfg . surfaces_config = table.deepcopy ( OCFG.surfaces_config )
2024-10-07 11:52:55 -04:00
end
2024-10-19 20:48:20 -04:00
if ( storage.ocfg [ " surfaces_blacklist " ] == nil ) then
2024-10-07 11:52:55 -04:00
log ( " ERROR - Missing surfaces_blacklist section in config! Loading defaults instead! " )
2024-12-02 12:49:56 -05:00
SendBroadcastMsg ( " ERROR - Missing surfaces_blacklist section in config! Loading defaults instead! " , { color = { r = 1 , g = 0.2 , b = 0.2 } , sound_path = " utility/cannot_build " } )
2024-10-19 20:48:20 -04:00
storage.ocfg . surfaces_blacklist = table.deepcopy ( OCFG.surfaces_blacklist )
2024-10-07 11:52:55 -04:00
end
2024-10-19 20:48:20 -04:00
if ( storage.ocfg [ " surfaces_blacklist_match " ] == nil ) then
2024-10-07 11:52:55 -04:00
log ( " ERROR - Missing surfaces_blacklist_match section in config! Loading defaults instead! " )
2024-12-02 12:49:56 -05:00
SendBroadcastMsg ( " ERROR - Missing surfaces_blacklist_match section in config! Loading defaults instead! " , { color = { r = 1 , g = 0.2 , b = 0.2 } , sound_path = " utility/cannot_build " } )
2024-10-19 20:48:20 -04:00
storage.ocfg . surfaces_blacklist_match = table.deepcopy ( OCFG.surfaces_blacklist_match )
2024-10-07 11:52:55 -04:00
end
2024-10-19 20:48:20 -04:00
if ( storage.ocfg [ " shop_items " ] == nil ) then
2024-10-12 21:57:46 -04:00
log ( " ERROR - Missing shop_items section in config! Loading defaults instead! " )
2024-12-02 12:49:56 -05:00
SendBroadcastMsg ( " ERROR - Missing shop_items section in config! Loading defaults instead! " , { color = { r = 1 , g = 0.2 , b = 0.2 } , sound_path = " utility/cannot_build " } )
2024-10-19 20:48:20 -04:00
storage.ocfg . shop_items = table.deepcopy ( OCFG.shop_items )
2024-10-12 21:57:46 -04:00
end
2024-10-07 11:52:55 -04:00
2024-08-16 01:40:16 -04:00
-- Validate enable_main_team and enable_separate_teams.
-- Force enable_main_team if both are disabled.
2024-10-19 20:48:20 -04:00
if ( not storage.ocfg . gameplay.enable_main_team and not storage.ocfg . gameplay.enable_separate_teams ) then
2024-08-16 01:40:16 -04:00
log ( " Both main force and separate teams are disabled! Enabling main force. Please check your mod settings or config! " )
2024-10-19 20:48:20 -04:00
storage.ocfg . gameplay.enable_main_team = true
2024-09-06 21:10:29 -04:00
settings.global [ " oarc-mod-enable-main-team " ] = { value = true }
2024-12-02 12:49:56 -05:00
SendBroadcastMsg ( { " oarc-teams-both-disabled-msg " } , { color = { r = 1 , g = 0.2 , b = 0.2 } , sound_path = " utility/cannot_build " } )
2024-08-16 01:40:16 -04:00
end
2024-08-23 21:52:48 -04:00
-- Validate minimum is less than maximums
2024-10-19 20:48:20 -04:00
if ( storage.ocfg . gameplay.near_spawn_distance >= storage.ocfg . gameplay.far_spawn_distance ) then
2024-08-23 21:52:48 -04:00
log ( " Near spawn min distance is greater than or equal to near spawn max distance! Please check your mod settings or config! " )
2024-10-19 20:48:20 -04:00
storage.ocfg . gameplay.far_spawn_distance = storage.ocfg . gameplay.near_spawn_distance + 1
settings.global [ " oarc-mod-far-spawn-distance " ] = { value = storage.ocfg . gameplay.far_spawn_distance }
2024-12-02 12:49:56 -05:00
SendBroadcastMsg ( { " oarc-spawn-distance-invalid-msg " } , { color = { r = 1 , g = 0.2 , b = 0.2 } , sound_path = " utility/cannot_build " } )
2024-08-23 21:52:48 -04:00
end
2024-08-24 21:06:43 -04:00
-- Validate that regrowth is enabled if world eater is enabled.
2024-10-19 20:48:20 -04:00
if ( storage.ocfg . regrowth.enable_world_eater and not storage.ocfg . regrowth.enable_regrowth ) then
2024-08-24 21:06:43 -04:00
log ( " World eater is enabled but regrowth is not! Disabling world eater. Please check your mod settings or config! " )
2024-10-19 20:48:20 -04:00
storage.ocfg . regrowth.enable_world_eater = false
2024-09-06 21:10:29 -04:00
settings.global [ " oarc-mod-enable-world-eater " ] = { value = false }
2024-12-02 12:49:56 -05:00
SendBroadcastMsg ( { " oarc-world-eater-invalid-msg " } , { color = { r = 1 , g = 0.2 , b = 0.2 } , sound_path = " utility/cannot_build " } )
2024-08-23 21:52:48 -04:00
end
2024-09-10 11:40:19 -04:00
-- Validate that default surface exists.
2024-10-19 20:48:20 -04:00
if ( game.surfaces [ storage.ocfg . gameplay.default_surface ] == nil ) then
2024-09-10 11:40:19 -04:00
log ( " Default surface does not exist! Please check your mod settings or config! " )
2024-10-19 20:48:20 -04:00
storage.ocfg . gameplay.default_surface = " nauvis "
2024-09-10 11:40:19 -04:00
settings.global [ " oarc-mod-default-surface " ] = { value = " nauvis " }
2024-12-02 12:49:56 -05:00
SendBroadcastMsg ( { " oarc-default-surface-invalid-msg " } , { color = { r = 1 , g = 0.2 , b = 0.2 } , sound_path = " utility/cannot_build " } )
2024-09-10 11:40:19 -04:00
end
2024-09-14 13:59:28 -04:00
-- Validate that a "nauvis" surface config exists (nauvis is the default config fallback)
-- This should only break with a bad scenario custom config.
2024-10-19 20:48:20 -04:00
if ( storage.ocfg . surfaces_config [ " nauvis " ] == nil ) then
2024-09-14 13:59:28 -04:00
error ( " nauvis surface config does not exist! Please check your mod settings or config! " )
end
2024-10-06 15:28:16 -04:00
-- Very for each surface config that the item counts are valid.
2024-10-19 20:48:20 -04:00
for surface_name , surface_config in pairs ( storage.ocfg . surfaces_config ) do
2024-10-06 15:28:16 -04:00
if ( table_size ( surface_config.starting_items . crashed_ship_resources ) > MAX_CRASHED_SHIP_RESOURCES_ITEMS ) then
error ( " Too many items in crashed_ship_resources for surface: " .. surface_name )
end
if ( table_size ( surface_config.starting_items . crashed_ship_wreakage ) > MAX_CRASHED_SHIP_WRECKAGE_ITEMS ) then
2024-10-07 11:52:55 -04:00
error ( " Too many items in crashed_ship_wreakage for surface: " .. surface_name )
2024-10-06 15:28:16 -04:00
end
end
2024-08-16 01:40:16 -04:00
end
-- Read in the mod settings and copy them to the OARC_CFG table, overwriting the defaults in config.lua.
function CacheModSettings ( )
2024-09-22 23:04:52 -04:00
2024-08-16 01:40:16 -04:00
log ( " Copying mod settings to OCFG table... " )
2024-08-23 21:52:48 -04:00
-- Copy the global settings from the mod settings.
-- Find the matching OARC setting and update it.
for _ , entry in pairs ( OCFG_KEYS ) do
2024-10-18 14:01:26 -04:00
if ( entry.mod_key ~= " " ) then
2024-09-06 21:10:29 -04:00
SetGlobalOarcConfigUsingKeyTable ( entry.ocfg_keys , settings.global [ entry.mod_key ] . value )
end
2024-08-23 21:52:48 -04:00
end
2024-09-11 12:49:23 -04:00
-- Special case for startup settings
2024-11-11 12:00:10 -05:00
storage.ocfg . gameplay.default_enable_secondary_spawns_on_other_surfaces = settings.startup [ " oarc-mod-default-enable-secondary-spawns-on-other-surfaces " ] . value --[[@as boolean]]
2024-10-19 20:48:20 -04:00
storage.ocfg . gameplay.main_force_name = settings.startup [ " oarc-mod-main-force-name " ] . value --[[@as string]]
2024-08-16 01:40:16 -04:00
end
2024-10-07 11:52:55 -04:00
---Get the scenario settings from the scenario if it exists.
---@return nil
2024-08-16 01:40:16 -04:00
function GetScenarioOverrideSettings ( )
if remote.interfaces [ " oarc_scenario " ] then
2024-09-22 23:04:52 -04:00
log ( " Getting scenario override settings... " )
2024-08-16 01:40:16 -04:00
local scenario_settings = remote.call ( " oarc_scenario " , " get_scenario_settings " )
-- Overwrite the non mod settings with the scenario settings.
2024-10-19 20:48:20 -04:00
storage.ocfg = scenario_settings
2024-10-07 11:52:55 -04:00
else
log ( " No scenario settings found. " )
end
end
2024-08-23 14:16:11 -04:00
2024-10-07 11:52:55 -04:00
---Syncs all mod settings to the OARC config table.
---@return nil
function SyncModSettingsToOCFG ( )
2024-10-19 20:48:20 -04:00
-- Override the mod settings with the the storage.ocfg settings.
2024-10-07 11:52:55 -04:00
for _ , entry in pairs ( OCFG_KEYS ) do
2024-10-18 14:01:26 -04:00
if ( entry.mod_key ~= " " ) then
2024-10-07 11:52:55 -04:00
local mod_key = entry.mod_key
local oarc_key = entry.ocfg_keys
local scenario_value = GetGlobalOarcConfigUsingKeyTable ( oarc_key )
if ( scenario_value ~= nil ) then
local ok , result = pcall ( function ( ) settings.global [ mod_key ] = { value = scenario_value } end )
if not ok then
error ( " Error setting mod setting: " .. mod_key .. " = " .. tostring ( scenario_value ) .. " \n " .. " If you see this, you probably picked an invalid value for a setting override in the custom scenario. " )
2024-09-22 23:04:52 -04:00
end
end
end
2024-08-16 01:40:16 -04:00
end
2024-10-07 11:52:55 -04:00
2024-08-23 14:16:11 -04:00
end
---Handles the event when a mod setting is changed in the mod settings menu.
---@param event EventData.on_runtime_mod_setting_changed
---@return nil
function RuntimeModSettingChanged ( event )
2024-09-09 14:20:52 -04:00
if ( event.setting_type ~= " runtime-global " ) then
return
end
log ( " on_runtime_mod_setting_changed: " .. event.setting .. " = " .. tostring ( settings.global [ event.setting ] . value ) )
2024-08-23 14:16:11 -04:00
2024-08-23 21:52:48 -04:00
-- Find the matching OARC setting and update it.
local found_setting = false
2024-09-09 14:20:52 -04:00
if ( OCFG_MOD_KEYS [ event.setting ] ~= nil ) then
local oarc_setting_index = OCFG_MOD_KEYS [ event.setting ]
local oarc_setting_table = OCFG_KEYS [ oarc_setting_index ]
SetGlobalOarcConfigUsingKeyTable ( oarc_setting_table.ocfg_keys , settings.global [ event.setting ] . value )
found_setting = true
2024-08-23 21:52:48 -04:00
end
if ( not found_setting ) then
2024-08-23 14:16:11 -04:00
error ( " Unknown oarc-mod setting changed: " .. event.setting )
2024-09-10 11:40:19 -04:00
else
ValidateSettings ( )
ApplyRuntimeChanges ( OCFG_MOD_KEYS [ event.setting ] )
2024-08-23 14:16:11 -04:00
end
2024-10-13 09:31:47 -04:00
--Exception for coin shop, update the GUI if the setting is changed
if ( event.setting == " oarc-mod-enable-coin-shop " ) then
2024-10-19 20:48:20 -04:00
local new_value = storage.ocfg . gameplay.enable_coin_shop
2024-10-13 09:31:47 -04:00
AddRemoveOarcGuiTabForAllPlayers ( OARC_ITEM_SHOP_TAB_NAME , settings.global [ event.setting ] . value --[[@as boolean]] , true )
end
2024-11-17 14:14:28 -05:00
--Exception for regrowth, refresh the content tab so the checkboxes get updated
if ( event.setting == " oarc-mod-enable-regrowth " ) then
for _ , player in pairs ( game.players ) do
OarcGuiRefreshContent ( player )
end
end
2024-08-23 21:52:48 -04:00
end
2024-11-28 13:30:11 -05:00
---A probably quite stupid function to let me lookup and set the storage.ocfg entries using a key table.
2024-08-23 21:52:48 -04:00
---@param key_table table<integer, string>
---@param value any
function SetGlobalOarcConfigUsingKeyTable ( key_table , value )
local number_of_keys = # key_table
if ( number_of_keys == 1 ) then
2024-10-19 20:48:20 -04:00
storage.ocfg [ key_table [ 1 ] ] = value
2024-08-23 21:52:48 -04:00
elseif ( number_of_keys == 2 ) then
2024-10-19 20:48:20 -04:00
storage.ocfg [ key_table [ 1 ] ] [ key_table [ 2 ] ] = value
2024-08-23 21:52:48 -04:00
elseif ( number_of_keys == 3 ) then
2024-10-19 20:48:20 -04:00
storage.ocfg [ key_table [ 1 ] ] [ key_table [ 2 ] ] [ key_table [ 3 ] ] = value
2024-08-23 21:52:48 -04:00
else
error ( " Invalid key_table length: " .. number_of_keys .. " \n " .. serpent.block ( key_table ) )
end
2024-11-28 13:30:11 -05:00
-- Hopefully I'm not missing any other entry points where storage.ocfg might be changed.
script.raise_event ( " oarc-mod-on-config-changed " , { } )
2024-08-23 21:52:48 -04:00
end
2024-10-19 20:48:20 -04:00
---An equally stupid function to let me lookup the storage.ocfg entries using a key table.
2024-08-23 21:52:48 -04:00
---@param key_table table<integer, string>
---@return any
function GetGlobalOarcConfigUsingKeyTable ( key_table )
local number_of_keys = # key_table
if ( number_of_keys == 1 ) then
2024-10-19 20:48:20 -04:00
if ( storage.ocfg [ key_table [ 1 ] ] == nil ) then
2024-09-20 21:39:01 -04:00
error ( " Invalid key_table 1: " .. serpent.block ( key_table ) )
end
2024-10-19 20:48:20 -04:00
return storage.ocfg [ key_table [ 1 ] ]
2024-08-23 21:52:48 -04:00
elseif ( number_of_keys == 2 ) then
2024-10-19 20:48:20 -04:00
if ( storage.ocfg [ key_table [ 1 ] ] == nil ) or ( storage.ocfg [ key_table [ 1 ] ] [ key_table [ 2 ] ] == nil ) then
2024-09-20 21:39:01 -04:00
error ( " Invalid key_table 2: " .. serpent.block ( key_table ) )
end
2024-10-19 20:48:20 -04:00
return storage.ocfg [ key_table [ 1 ] ] [ key_table [ 2 ] ]
2024-08-23 21:52:48 -04:00
elseif ( number_of_keys == 3 ) then
2024-10-19 20:48:20 -04:00
if ( storage.ocfg [ key_table [ 1 ] ] == nil ) or
2024-11-06 23:53:52 +08:00
( storage.ocfg [ key_table [ 1 ] ] [ key_table [ 2 ] ] == nil ) or
2024-10-19 20:48:20 -04:00
( storage.ocfg [ key_table [ 1 ] ] [ key_table [ 2 ] ] [ key_table [ 3 ] ] == nil ) then
2024-09-20 21:39:01 -04:00
error ( " Invalid key_table 3: " .. serpent.block ( key_table ) )
end
2024-10-19 20:48:20 -04:00
return storage.ocfg [ key_table [ 1 ] ] [ key_table [ 2 ] ] [ key_table [ 3 ] ]
2024-08-23 21:52:48 -04:00
else
error ( " Invalid key_table length: " .. number_of_keys .. " \n " .. serpent.block ( key_table ) )
end
2024-09-10 11:40:19 -04:00
end
---Handles any runtime changes that need more than just the setting change.
---@param oarc_setting_index string
---@return nil
function ApplyRuntimeChanges ( oarc_setting_index )
2024-10-25 19:56:04 -04:00
-- Handle changing enable_shared_team_vision
2024-09-10 11:40:19 -04:00
if ( oarc_setting_index == " gameplay.enable_shared_team_vision " ) then
for _ , force in pairs ( game.forces ) do
2024-10-18 14:01:26 -04:00
if ( not TableContains ( ENEMY_FORCES_NAMES_INCL_NEUTRAL , force.name ) ) then
2024-10-19 20:48:20 -04:00
force.share_chart = storage.ocfg . gameplay.enable_shared_team_vision
2024-09-10 11:40:19 -04:00
end
end
2024-10-25 19:56:04 -04:00
-- Handle changing enable_friendly_fire
2024-09-10 11:40:19 -04:00
elseif ( oarc_setting_index == " gameplay.enable_friendly_fire " ) then
for _ , force in pairs ( game.forces ) do
2024-10-18 14:01:26 -04:00
if ( not TableContains ( ENEMY_FORCES_NAMES_INCL_NEUTRAL , force.name ) ) then
2024-10-19 20:48:20 -04:00
force.friendly_fire = storage.ocfg . gameplay.enable_friendly_fire
2024-09-10 11:40:19 -04:00
end
end
2024-10-25 19:56:04 -04:00
-- Handle changing enable_friendly_teams or enable_cease_fire
elseif ( oarc_setting_index == " gameplay.enable_friendly_teams " ) or
( oarc_setting_index == " gameplay.enable_cease_fire " ) then
2024-10-27 20:11:59 -04:00
ConfigurePlayerForceRelationships ( storage.ocfg . gameplay.enable_cease_fire ,
storage.ocfg . gameplay.enable_friendly_teams )
2024-09-10 11:40:19 -04:00
end
2024-11-06 23:53:52 +08:00
end