1
0
mirror of https://github.com/Oarcinae/FactorioScenarioMultiplayerSpawn.git synced 2025-02-11 13:15:30 +02:00

Fixed some issues with regrowth missing vehicles. Added regrowth refresh around spidertrons and on exiting any vehicle. Added more info to the ingame settings GUI with subheaders. Added checks to ensure mod default settings match internal example config. Reduced refresh area for regrowth around players to reduce UPS impact. Added more info about template scenario in config file.

This commit is contained in:
Oarcinae 2024-09-24 22:28:45 -04:00
parent fe4b6212ec
commit 4000063d6f
11 changed files with 139 additions and 37 deletions

View File

@ -176,6 +176,9 @@ script.on_event(defines.events.on_built_entity, function(event)
RegrowthMarkAreaSafeGivenTilePos(event.created_entity.surface.name, event.created_entity.position, 2, false)
end
-- For tracking spidertrons...
RegrowthOnBuiltEntity(event)
-- if global.ocfg.enable_anti_grief then
-- SetItemBlueprintTimeToLive(event)
-- end
@ -195,6 +198,14 @@ script.on_event(defines.events.on_player_built_tile, function (event)
end
end)
--If a player gets in or out of a vehicle, mark the area as safe so we don't delete the vehicle by accident.
--Only world eater will clean up these chunks over time if it is enabled.
script.on_event(defines.events.on_player_driving_changed_state, function (event)
if global.ocfg.regrowth.enable_regrowth then
RegrowthMarkAreaSafeGivenTilePos(event.entity.surface.name, event.entity.position, 1, false)
end
end)
----------------------------------------
-- On script_raised_built. This should help catch mods that
-- place items that don't count as player_built and robot_built.

View File

@ -8,7 +8,6 @@ Not specific:
Minor:
- Add refresh chunks around spidertrons based on their vision
- If dead when resetting spawn... possibly delay the opening of the welcome GUI or block spawning until character is spawned?
- Expose old enemy scaling as an option? And/or remove unnecessary checks/logs
- Refresh players in admin controls when dropdown is clicked
@ -138,4 +137,5 @@ Other Ideas, Not Committed:
- Run the profiler
- Pull out general spawn config from surfaces config
- Redo resource placement to be simpler (and make a linear layout for square base)
- Default to selecting SELF in admin controls player dropdown?
- Default to selecting SELF in admin controls player dropdown?
- Add refresh chunks around spidertrons based on their vision

View File

@ -4,13 +4,18 @@
| |\/| | (_) | |) | \ \/\/ / _ \| / .` || || .` | (_ |
|_| |_|\___/|___/ \_/\_/_/ \_\_|_\_|\_|___|_|\_|\___|
DO NOT EDIT THIS FILE! If you want to customize this, edit the config-scenario.lua file and load that scenario!
DO NOT EDIT THIS FILE!
DO NOT EDIT THIS FILE!
DO NOT EDIT THIS FILE!
If you want to customize settings at init, edit the control.lua file in the scenarios/OARC folder and load that scenario!
]]
-- More settings are available here than are provided in the mod settings menu.
-- Additionally, many settings are exposed in the game itself and can be chanced once you launch.
-- For convenience you can provide you own config-scenario.lua file in the scenarios/OARC folder to override these settings.
-- Additionally, many settings are exposed in the game itself and can be changed in game.
-- For convenience you, you can edit the control.lua file in the scenarios/OARC folder to override settings as well.
-- That method is useful for headless server hosting where it's hard to configure mod settings.
---@alias SpawnShapeChoice "circle" | "octagon" | "square"
SPAWN_SHAPE_CHOICE_CIRCLE = "circle"
@ -160,9 +165,9 @@ OCFG = {
-- Server Info - This stuff is shown in the welcome GUI and Info panel.
---@type OarcConfigServerInfo
server_info = {
welcome_msg_title = "YOUR SERVER TITLE HERE",
welcome_msg = "YOUR WELCOME MSG HERE",
discord_invite = "YOUR DISCORD INVITE HERE"
welcome_msg_title = "Insert Server Title Here!",
welcome_msg = "Insert Server Welcome Message Here!",
discord_invite = "Insert Discord Invite Here!"
},
-- General gameplay related settings that I didn't want to expose in the mod settings since these should
@ -192,7 +197,7 @@ OCFG = {
-- If there is a moat, this makes a small path to land to avoid "turtling", but if the spawn
-- is in the middle of water, it won't do anything.
enable_moat_bridging = true,
enable_moat_bridging = false,
-- This is the radius, in chunks, that a spawn area is from any other generated
-- chunks. It ensures the spawn area isn't too near generated/explored/existing
@ -202,7 +207,7 @@ OCFG = {
-- The range in which a player can select how close to the center of the map they want to spawn.
near_spawn_distance = 100,
far_spawn_distance = 1000,
far_spawn_distance = 500,
-- This allows 2 players to spawn next to each other, each with their own starting area.
enable_buddy_spawn = true,
@ -224,7 +229,7 @@ OCFG = {
number_of_players_per_shared_spawn = 3,
-- I like keeping this off... set to true if you want to shoot your own chests and stuff.
enable_friendly_fire = true,
enable_friendly_fire = false,
-- The default starting surface.
default_surface = "nauvis",
@ -256,7 +261,7 @@ OCFG = {
minimum_online_time = 15,
-- Respawn cooldown in minutes.
respawn_cooldown_min = 15,
respawn_cooldown_min = 5,
-- Enable shared power between bases.
-- Creates a special power pole for cross surface connections.

View File

@ -2,17 +2,17 @@
-- 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.
---Provides a way to look up the config settings key from the mod settings key.
---@alias OarcSettingsLookup { mod_key: string, ocfg_keys: table<integer, string>, type: string }
---@alias OarcSettingsLookup { mod_key: string, ocfg_keys: table<integer, string>, type: string, text: LocalisedString? }
---@type table<string, OarcSettingsLookup>
OCFG_KEYS =
{
["Server Info"] = {mod_key = "" , ocfg_keys = {""}, type = "header"},
["server_info_HEADER"] = {mod_key = "" , ocfg_keys = {""}, type = "header", text = {"oarc-settings-section-header-server-info"}},
["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"},
["server_info.discord_invite"] = {mod_key = "oarc-mod-discord-invite" , ocfg_keys = {"server_info", "discord_invite"}, type = "string"},
["Gameplay"] = {mod_key = "" , ocfg_keys = {""}, type = "header"},
["gameplay_HEADER"] = {mod_key = "" , ocfg_keys = {""}, type = "header", text = {"oarc-settings-section-header-gameplay"}},
["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"},
-- STARTUP ["gameplay.enable_spawning_on_other_surfaces"] = {mod_key = "oarc-mod-default-allow-spawning-on-other-surfaces" , ocfg_keys = {"gameplay", "enable_spawning_on_other_surfaces"}, type = "boolean"},
@ -44,13 +44,14 @@ OCFG_KEYS =
["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"},
["Regrowth"] = {mod_key = "" , ocfg_keys = {""}, type = "header"},
["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"}},
["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"},
["regrowth.cleanup_interval"] = {mod_key = "oarc-mod-regrowth-cleanup-interval-min" , ocfg_keys = {"regrowth", "cleanup_interval"}, type = "integer"},
["General Spawn Area Config"] = {mod_key = "" , ocfg_keys = {""}, type = "header"},
["general_spawn_HEADER"] = {mod_key = "" , ocfg_keys = {""}, type = "header", text = {"oarc-settings-section-header-general-spawn"}},
["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"},
@ -58,16 +59,20 @@ OCFG_KEYS =
["spawn_general.force_grass"] = {mod_key = "oarc-mod-spawn-general-enable-force-grass" , ocfg_keys = {"spawn_general", "force_grass"}, type = "boolean"},
["spawn_general.shape"] = {mod_key = "oarc-mod-spawn-general-shape" , ocfg_keys = {"spawn_general", "shape"}, type = "string-list"},
["Starting Resources Placement"] = {mod_key = "" , ocfg_keys = {""}, type = "header"},
["resource_placement_HEADER"] = {mod_key = "" , ocfg_keys = {""}, type = "header", text = {"oarc-settings-section-header-resource-placement"}},
["resource_placement.enabled"] = {mod_key = "oarc-mod-resource-placement-enabled" , ocfg_keys = {"resource_placement", "enabled"}, type = "boolean"},
["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"}},
["resource_placement.distance_to_edge"] = {mod_key = "oarc-mod-resource-placement-distance-to-edge" , ocfg_keys = {"resource_placement", "distance_to_edge"}, type = "integer"},
["resource_placement.angle_offset"] = {mod_key = "oarc-mod-resource-placement-angle-offset" , ocfg_keys = {"resource_placement", "angle_offset"}, type = "double"},
["resource_placement.angle_final"] = {mod_key = "oarc-mod-resource-placement-angle-final" , ocfg_keys = {"resource_placement", "angle_final"}, type = "double"},
["resource_placement_square_SUBHEADER"] = {mod_key = "" , ocfg_keys = {""}, type = "subheader", text = {"oarc-settings-section-subheader-resource-placement-square"}},
["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"},
["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"}
}
---Easy reverse lookup for mod settings keys.
@ -143,7 +148,7 @@ function ValidateAndLoadConfig()
end
-- And check the opposite.
for ocfg_key,entry in pairs(OCFG_KEYS) do
if (entry.type ~= "header") and (OCFG_MOD_KEYS[entry.mod_key] == nil) then
if (entry.type ~= "header") and (entry.type ~= "subheader") and (OCFG_MOD_KEYS[entry.mod_key] == nil) then
error("OCFG_KEYS entry does not have a corresponding OCFG_MOD_KEYS entry: " .. ocfg_key .. " -> " .. entry.mod_key)
end
end
@ -152,6 +157,20 @@ function ValidateAndLoadConfig()
---@class OarcConfig
global.ocfg = OCFG
-- 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
if (entry.type ~= "header") and (entry.type ~= "subheader") then
local mod_key = entry.mod_key
local oarc_key = entry.ocfg_keys
local mod_value = game.mod_setting_prototypes[mod_key].default_value
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
CacheModSettings() -- Get all mod settings and overwrite the defaults in OARC_CFG.
GetScenarioOverrideSettings() -- Get any scenario settings and overwrite both the mod settings and OARC_CFG.
@ -209,7 +228,7 @@ function CacheModSettings()
-- Copy the global settings from the mod settings.
-- Find the matching OARC setting and update it.
for _,entry in pairs(OCFG_KEYS) do
if (entry.type ~= "header") then
if (entry.type ~= "header") and (entry.type ~= "subheader") then
SetGlobalOarcConfigUsingKeyTable(entry.ocfg_keys, settings.global[entry.mod_key].value)
end
end

View File

@ -49,7 +49,9 @@ function CreateModSettingsSection(container, player)
for index,entry in pairs(OCFG_KEYS) do
if (entry.type == "header") then
AddSpacerLine(container)
AddLabel(container, nil, index, "caption_label")
AddLabel(container, nil, entry.text, "caption_label")
elseif (entry.type == "subheader") then
AddLabel(container, nil, entry.text, "bold_label")
elseif (entry.type == "boolean") then
AddCheckboxSetting(container, index, entry, player.admin)
elseif (entry.type == "string") then

View File

@ -26,10 +26,10 @@ function CreateHoldingPenSurface()
holding_pen_surface.show_clouds = false
holding_pen_surface.generate_with_lab_tiles = true
RenderPermanentGroundText(holding_pen_surface, {x=9,y=-7}, 5, "O", {0.9, 0.7, 0.3, 0.8}, "center")
RenderPermanentGroundText(holding_pen_surface, {x=9,y=-4}, 5, "A", {0.9, 0.7, 0.3, 0.8}, "center")
RenderPermanentGroundText(holding_pen_surface, {x=9,y=-1}, 5, "R", {0.9, 0.7, 0.3, 0.8}, "center")
RenderPermanentGroundText(holding_pen_surface, {x=9,y=2}, 5, "C", {0.9, 0.7, 0.3, 0.8}, "center")
RenderPermanentGroundText(holding_pen_surface, {x=9,y=-7}, 5, "O", {0.9, 0.7, 0.3, 0.5}, "center")
RenderPermanentGroundText(holding_pen_surface, {x=9,y=-4}, 5, "A", {0.9, 0.7, 0.3, 0.5}, "center")
RenderPermanentGroundText(holding_pen_surface, {x=9,y=-1}, 5, "R", {0.9, 0.7, 0.3, 0.5}, "center")
RenderPermanentGroundText(holding_pen_surface, {x=9,y=2}, 5, "C", {0.9, 0.7, 0.3, 0.5}, "center")
end
---Creates a holding pen area

View File

@ -25,7 +25,7 @@ REGROWTH_FLAG_PERMANENT = -3
--- Radius in chunks around a player to mark as safe.
REGROWTH_ACTIVE_AREA_AROUND_PLAYER = 4
REGROWTH_ACTIVE_AREA_AROUND_PLAYER = 2
---The removal list contains chunks that are marked for removal. Each entry is a table with the following fields:
---@alias RemovalListEntry { pos : ChunkPosition, force: boolean, surface: string }
@ -48,7 +48,12 @@ function RegrowthInit()
global.rg.we_current_surface = nil
global.rg.we_current_surface_index = 1
---@type table<integer, RemovalListEntry>
---@type LuaEntity[]
global.rg.spidertrons = {} -- List of all spidertrons in the game
global.rg_spidertron_index = 1
---@type RemovalListEntry[]
global.rg.removal_list = {}
for surface_name,_ in pairs(game.surfaces) do
@ -528,6 +533,9 @@ function RegrowthOnTick()
RefreshPlayerArea()
end
-- Refresh a single spidertron every tick
RefreshSpidertronArea()
-- Every tick, check a few points in the 2d array of the only active surface
for i = 1, 20 do
RegrowthSingleStepArray()
@ -662,4 +670,53 @@ function CheckIfChunkHasAnyPlayerEntities(surface_name, chunk)
end
return false
end
---When an entity is built, if it is a spidertron we add it to our list
---@param event EventData.on_built_entity
---@return nil
function RegrowthOnBuiltEntity(event)
if (event.created_entity and event.created_entity.valid and event.created_entity.type == "spider-vehicle") then
table.insert(global.rg.spidertrons, event.created_entity)
log("Added spidertron to regrowth tracking")
if global.rg.spidertron_chunk_radius == nil then
global.rg.spidertron_chunk_radius = game.entity_prototypes["spidertron"].chunk_exploration_radius
end
end
end
---On tick, we refresh a single spidertron's area.
---@return nil
function RefreshSpidertronArea()
if (#global.rg.spidertrons > 0) then
local spidertron = global.rg.spidertrons[global.rg_spidertron_index]
if (spidertron and spidertron.valid) then
--Check if this surface is active.
local surface_name = spidertron.surface.name
if (global.rg[surface_name] ~= nil) and (global.rg[surface_name].active) then
RefreshArea(spidertron.surface.name, spidertron.position, global.rg.spidertron_chunk_radius, 0)
end
UpdateSpidertronIndex() -- Go to next valid spidertron on the next tick
else
table.remove(global.rg.spidertrons, global.rg_spidertron_index)
log("Removed spidertron from regrowth tracking")
end
end
end
---Updates the spidertron index to the next one in the list.
---@return nil
function UpdateSpidertronIndex()
global.rg_spidertron_index = global.rg_spidertron_index + 1
if (global.rg_spidertron_index > #global.rg.spidertrons) then
global.rg_spidertron_index = 1
end
end

View File

@ -101,7 +101,7 @@ oarc-mod-enable-shared-chest=This gives players a special chest they can use to
oarc-mod-enable-regrowth=Enables regrowth. This slowly removes inactive chunks over time. Any chunk with player structures will not be removed. This helps to keep the map (and file size) smaller over time.
oarc-mod-enable-world-eater=Enables world eater. This requires regrowth. This slowly checks all chunks for a lack of player structures and entities and marks them for removal. This helps to keep the map (and file size) smaller over time. This is more of an experimental feature, use at your own risk.
oarc-mod-enable-abandoned-base-cleanup=Abandoned bases will be cleaned up if players leave within a short time of joining. This does NOT require regrowth to be enabled.
oarc-mod-enable-abandoned-base-cleanup=Abandoned bases will be cleaned up if players leave within a short time of joining. [color=red]This does NOT require regrowth or world eater to be enabled.[/color]
oarc-mod-regrowth-cleanup-interval-min=This is the interval in minutes that the regrowth cleanup will run. Whenever a map cleanup happens, the game freezes for a second, so you don't want to run this too often! Abandoned base cleanup happens immediately when a player leaves and is not affected by this setting.
oarc-mod-spawn-general-radius-tiles=This is the radius of the spawn area in tiles. I would not make this much smaller then 2 chunks (64) and not too huge unless you want spawns to take a long time to generate.

View File

@ -211,8 +211,16 @@ oarc-settings-tab-surface-spawning-enabled=Custom Spawns
oarc-settings-tab-surface-regrowth-enabled=Regrowth
oarc-settings-section-header-server-info=Server Info
oarc-settings-section-header-gameplay=Gameplay
oarc-settings-section-header-regrowth=Regrowth
oarc-settings-section-header-general-spawn=General Spawn Area Config
oarc-settings-section-header-resource-placement=Starting Resources Placement
oarc-settings-section-subheader-resource-placement-circular=For circle/octagon spawns
oarc-settings-section-subheader-resource-placement-square=For square spawns
oarc-settings-section-subheader-regrowth-warning=These features can help reduce save file size but can be more UPS intensive.\n
oarc-shared-power-pole-helper-txt=This connects to a shared electric network for all players.
oarc-shared-chest-helper-txt=This connects to a shared storage chest for all players.

View File

@ -1,3 +1,3 @@
scenario-name=OARC-TEMPLATE
description=This is an EMPTY template scenario! It is provided as a way to override the default freeplay scenario if you want to. Additionally, experienced server hosts can configure all settings from a file instead of through the mod settings. Please read the control.lua file inside the scenario for notes.
description=This is an EMPTY TEMPLATE scenario! It is provided as an example of how to override the default freeplay scenario if you want to. Additionally, experienced server hosts can configure all settings from a file instead of through the mod settings. Please read the control.lua file inside the scenario for notes.

View File

@ -72,7 +72,7 @@ data:extend({
type = "bool-setting",
name = "oarc-mod-enable-moat-bridging",
setting_type = "runtime-global",
default_value = true,
default_value = false,
order = "b5"
},
@ -143,7 +143,7 @@ data:extend({
type = "int-setting",
name = "oarc-mod-number-of-players-per-shared-spawn",
setting_type = "runtime-global",
default_value = 4,
default_value = 3,
minimum_value = 2,
maximum_value = 10,
order = "d6"
@ -217,7 +217,7 @@ data:extend({
type = "int-setting",
name = "oarc-mod-respawn-cooldown-min",
setting_type = "runtime-global",
default_value = 15,
default_value = 5,
minimum_value = 0,
maximum_value = 60,
order = "f4"
@ -243,7 +243,7 @@ data:extend({
type = "bool-setting",
name = "oarc-mod-enable-regrowth",
setting_type = "runtime-global",
default_value = true,
default_value = false,
order = "g1"
},
{
@ -276,7 +276,7 @@ data:extend({
setting_type = "runtime-global",
default_value = 64,
minimum_value = 32,
maximum_value = 6400,
maximum_value = 320,
order = "h1"
},
{