mirror of
https://github.com/Oarcinae/FactorioScenarioMultiplayerSpawn.git
synced 2024-12-04 09:43:00 +02:00
Merge pull request #196 from Oarcinae/153-add-a-way-to-configure-primary-spawns-only-allowed-on-a-single-surface-and-secondary-spawns-on-other-surfaces
153 add a way to configure primary spawns only allowed on a single surface and secondary spawns on other surfaces
This commit is contained in:
commit
8a9d7c0f23
@ -339,7 +339,7 @@ end)
|
||||
local oarc_mod_interface =
|
||||
{
|
||||
get_mod_settings = function()
|
||||
return OCFG
|
||||
return global.ocfg
|
||||
end
|
||||
}
|
||||
|
||||
|
@ -302,7 +302,7 @@ OCFG = {
|
||||
-- Default setting for enabling spawning on other surfaces other than the default_surface.
|
||||
-- This is a STARTUP setting, so it can't be changed in game!!
|
||||
-- This is a STARTUP setting, so it can't be changed in game!!
|
||||
default_allow_spawning_on_other_surfaces = true,
|
||||
default_allow_spawning_on_other_surfaces = false,
|
||||
|
||||
-- The name of the main force.
|
||||
-- This is a STARTUP setting, so it can't be changed in game!!
|
||||
|
@ -83,20 +83,24 @@ function CreateSurfaceSettingsSection(container, player)
|
||||
local surface_table = container.add {
|
||||
type = "table",
|
||||
name = "surface_table",
|
||||
column_count = 3,
|
||||
column_count = 4,
|
||||
style = "bordered_table",
|
||||
}
|
||||
|
||||
--- Add the header row
|
||||
AddLabel(surface_table, nil, {"oarc-settings-tab-surface-column-header"}, "caption_label")
|
||||
AddLabel(surface_table, nil, {"oarc-settings-tab-surface-spawning-enabled"}, "caption_label")
|
||||
AddLabel(surface_table, nil, {"oarc-settings-tab-surface-secondary-enabled"}, "caption_label")
|
||||
AddLabel(surface_table, nil, {"oarc-settings-tab-surface-regrowth-enabled"}, "caption_label")
|
||||
|
||||
--- Add the rows
|
||||
for name, allowed in pairs(global.oarc_surfaces --[[@as table<string, boolean>]]) do
|
||||
for name, allowed in pairs(global.oarc_surfaces) do
|
||||
AddLabel(surface_table, nil, name, my_label_style)
|
||||
AddSurfaceCheckboxSetting(surface_table, name, "spawn_enabled", allowed, player.admin,
|
||||
AddSurfaceCheckboxSetting(surface_table, name, "spawn_enabled", allowed.primary, player.admin,
|
||||
{ "oarc-settings-tab-surface-checkbox-tooltip" })
|
||||
AddSurfaceCheckboxSetting(surface_table, name, "secondary_enabled", allowed.secondary, player.admin,
|
||||
{ "oarc-settings-tab-surface-secondary-checkbox-tooltip" })
|
||||
|
||||
local regrowth_enabled = TableContains(global.rg.active_surfaces, name)
|
||||
AddSurfaceCheckboxSetting(surface_table, name, "regrowth_enabled", regrowth_enabled, player.admin,
|
||||
{"oarc-settings-tab-surface-regrowth-checkbox-tooltip"})
|
||||
@ -540,14 +544,19 @@ function SettingsSurfaceControlsTabGuiClick(event)
|
||||
|
||||
if (setting_name == "spawn_enabled") then
|
||||
local surface_name = gui_elem.tags.surface --[[@as string]]
|
||||
global.oarc_surfaces[surface_name] = gui_elem.state
|
||||
global.oarc_surfaces[surface_name].primary = gui_elem.state
|
||||
|
||||
if (#GetAllowedSurfaces() == 0) then
|
||||
log("Warning - GetAllowedSurfaces() - No surfaces found! Forcing default surface!")
|
||||
global.oarc_surfaces[global.ocfg.gameplay.default_surface] = true
|
||||
global.oarc_surfaces[global.ocfg.gameplay.default_surface].primary = true
|
||||
event.element.parent[global.ocfg.gameplay.default_surface.."_spawn_enabled"].state = true
|
||||
end
|
||||
|
||||
|
||||
elseif (setting_name == "secondary_enabled") then
|
||||
local surface_name = gui_elem.tags.surface --[[@as string]]
|
||||
global.oarc_surfaces[surface_name].secondary = gui_elem.state
|
||||
|
||||
|
||||
elseif (setting_name == "regrowth_enabled") then
|
||||
local surface_name = gui_elem.tags.surface --[[@as string]]
|
||||
|
||||
|
@ -20,7 +20,7 @@ ABANDONED_FORCE_NAME = "_ABANDONED_"
|
||||
function InitSpawnGlobalsAndForces()
|
||||
|
||||
-- Contains a table of entries for each surface. This tracks which surfaces allow spawning?
|
||||
--[[@type table<string, boolean>]]
|
||||
--[[@type table<string, OarcSurfaceSpawnSetting>]]
|
||||
global.oarc_surfaces = {}
|
||||
for _, surface in pairs(game.surfaces) do
|
||||
SeparateSpawnsInitSurface(surface.name)
|
||||
@ -134,11 +134,14 @@ function SeparateSpawnsInitSurface(surface_name)
|
||||
|
||||
-- Add the surface to the list of surfaces that allow spawns with value from config.
|
||||
if global.ocfg.gameplay.default_allow_spawning_on_other_surfaces then
|
||||
global.oarc_surfaces[surface_name] = true
|
||||
global.oarc_surfaces[surface_name] = { primary = true, secondary = true }
|
||||
|
||||
-- Otherwise only allow the default surface (by default)
|
||||
else
|
||||
global.oarc_surfaces[surface_name] = (surface_name == global.ocfg.gameplay.default_surface)
|
||||
global.oarc_surfaces[surface_name] = {
|
||||
primary = (surface_name == global.ocfg.gameplay.default_surface),
|
||||
secondary = false
|
||||
}
|
||||
end
|
||||
|
||||
-- Make sure it has a surface configuration entry!
|
||||
@ -213,7 +216,7 @@ function SeparateSpawnsPlayerRespawned(event)
|
||||
if (player.surface.name == HOLDING_PEN_SURFACE_NAME) then return end
|
||||
|
||||
-- If the mod isn't active on this surface, then ignore it.
|
||||
if (not global.oarc_surfaces[surface_name]) then return end
|
||||
if (global.oarc_surfaces[surface_name] == nil) then return end
|
||||
|
||||
SendPlayerToSpawn(surface_name, player)
|
||||
GivePlayerRespawnItems(player)
|
||||
@ -239,16 +242,22 @@ function SeparateSpawnsPlayerChangedSurface(event)
|
||||
if (not global.ocfg.gameplay.enable_secondary_spawns) then return end
|
||||
|
||||
local player = game.players[event.player_index]
|
||||
local surface_name = player.surface.name
|
||||
|
||||
-- Check if player has been init'd yet. If not, then ignore it.
|
||||
if (global.player_respawns[player.name] == nil) then return end
|
||||
|
||||
-- If the mod isn't active on this surface, then ignore it.
|
||||
if (not global.oarc_surfaces[player.surface.name]) then return end
|
||||
if (global.oarc_surfaces[surface_name] == nil) then return end
|
||||
|
||||
-- If this is their first time on the planet, create a secondary spawn point for them.
|
||||
-- TODO: Check for buddy and shared spawn hosts?
|
||||
if (global.unique_spawns[player.surface.name] == nil) or (global.unique_spawns[player.surface.name][player.name] == nil) then
|
||||
-- If the mod is configured to not allow secondary spawns here, then ignore it.
|
||||
if (not global.oarc_surfaces[surface_name].secondary) then return end
|
||||
|
||||
-- Check if there is already a spawn for them on this surface
|
||||
-- Could be a buddy spawn, or a shared spawn, or a unique spawn.
|
||||
local player_spawn = FindPlayerSpawnOnSurface(player.name, surface_name)
|
||||
|
||||
if (player_spawn == nil) then
|
||||
log("WARNING - THIS IS NOT FULLY IMPLEMENTED YET!!")
|
||||
SecondarySpawn(player, player.surface)
|
||||
end
|
||||
@ -793,6 +802,19 @@ function FindPlayerHomeSpawn(player_name)
|
||||
end
|
||||
end
|
||||
|
||||
---Find the spawn of a player, if one exists, on a specific surface.
|
||||
---@param player_name string
|
||||
---@param surface_name string
|
||||
---@return OarcUniqueSpawn?
|
||||
function FindPlayerSpawnOnSurface(player_name, surface_name)
|
||||
if (global.unique_spawns[surface_name] == nil) then return nil end
|
||||
for _,spawn in pairs(global.unique_spawns[surface_name]) do
|
||||
if ((spawn.host_name == player_name) or TableContains(spawn.joiners, player_name)) then
|
||||
return spawn
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
---Searches all unique spawns for a list of secondary ones for a player.
|
||||
---@param player_name string
|
||||
---@return table<string, OarcUniqueSpawn> -- Indexed by surface name!
|
||||
@ -865,12 +887,10 @@ function CleanupPlayerGlobals(player_name)
|
||||
for index, joiner in pairs(spawn.joiners) do
|
||||
if (player_name == joiner) then
|
||||
global.unique_spawns[surface_index][player_index].joiners[index] = nil
|
||||
goto LOOP_BREAK -- Nest loop break. Assumes only one entry per player is possible.
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
::LOOP_BREAK::
|
||||
|
||||
-- Clear their personal spawn point info
|
||||
if (global.player_respawns[player_name] ~= nil) then
|
||||
@ -1274,11 +1294,32 @@ function SecondarySpawn(player, surface)
|
||||
player.print({ "oarc-no-ungenerated-land-error" })
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
-- Add new spawn point for the new surface
|
||||
SetPlayerRespawn(player.name, surface.name, spawn_position, false) -- Do not reset cooldown
|
||||
QueuePlayerForDelayedSpawn(player.name, surface.name, spawn_position, spawn_choices.moat, false, nil)
|
||||
|
||||
-- TODO: Temporary for space age, buddies get a single spawn point for secondary spawns.
|
||||
if (spawn_choices.buddy) then
|
||||
SetPlayerRespawn(spawn_choices.buddy, surface.name, spawn_position, false)
|
||||
|
||||
-- Add buddy to the shared spawn?
|
||||
global.unique_spawns[surface.name][player.name].joiners = { spawn_choices.buddy }
|
||||
|
||||
log("Buddy secondary spawn NOT IMPLEMENTED YET!")
|
||||
end
|
||||
|
||||
-- -- If it is a buddy spawn, we need to setup both areas TOGETHER
|
||||
-- if spawn_choices.buddy then
|
||||
-- -- The x_offset must be big enough to ensure the spawns DO NOT overlap!
|
||||
-- local x_offset = (global.ocfg.spawn_general.spawn_radius_tiles * 2)
|
||||
-- if (spawn_choices.moat) then
|
||||
-- x_offset = x_offset + 10
|
||||
-- end
|
||||
-- local buddy_spawn_position = { x = spawn_position.x + x_offset, y = spawn_position.y }
|
||||
-- SetPlayerRespawn(spawn_choices.buddy, spawn_choices.surface, buddy_spawn_position, true)
|
||||
-- end
|
||||
|
||||
-- Send them to the holding pen
|
||||
SafeTeleport(player, game.surfaces[HOLDING_PEN_SURFACE_NAME], {x=0,y=0})
|
||||
|
||||
@ -1350,7 +1391,7 @@ end
|
||||
---@param player_name string
|
||||
---@return boolean
|
||||
function PlayerHasDelayedSpawn(player_name)
|
||||
for _,delayedSpawn in pairs(global.delayed_spawns --[[@as OarcDelayedSpawnsTable]]) do
|
||||
for _,delayedSpawn in pairs(global.delayed_spawns) do
|
||||
if (delayedSpawn.playerName == player_name) then
|
||||
return true
|
||||
end
|
||||
@ -1358,13 +1399,13 @@ function PlayerHasDelayedSpawn(player_name)
|
||||
return false
|
||||
end
|
||||
|
||||
---Get the list of surfaces that are allowed for spawning.
|
||||
---Get the list of surfaces that are allowed for primary spawning.
|
||||
---@return string[]
|
||||
function GetAllowedSurfaces()
|
||||
---@type string[]
|
||||
local surfaceList = {}
|
||||
for surfaceName,allowed in pairs(global.oarc_surfaces --[[@as table<string, boolean>]]) do
|
||||
if allowed then
|
||||
for surfaceName, allowed in pairs(global.oarc_surfaces) do
|
||||
if allowed.primary then
|
||||
table.insert(surfaceList, surfaceName)
|
||||
end
|
||||
end
|
||||
@ -1475,7 +1516,18 @@ SPAWN_TEAM_CHOICE = {
|
||||
---@alias OarcDelayedSpawnsTable table<string, OarcDelayedSpawn>
|
||||
|
||||
---This contains the spawn choices for a player in the spawn menu.
|
||||
---@alias OarcSpawnChoices { surface: string, team: SpawnTeamChoice, moat: boolean, buddy: string?, distance: integer, host: string?, buddy_team: boolean }
|
||||
---Class representing the spawn choices for a player in the spawn menu.
|
||||
---@class OarcSpawnChoices
|
||||
---@field surface string The surface on which the player wants to spawn.
|
||||
---@field team SpawnTeamChoice The team choice for the player. Main team or own team.
|
||||
---@field moat boolean Whether the player wants a moat around their spawn.
|
||||
---@field buddy string? The buddy player name if the player wants to spawn with a buddy.
|
||||
---@field distance integer The distance from the center of the map where the player wants to spawn.
|
||||
---@field host string? The host player name if the player wants to join a shared spawn.
|
||||
---@field buddy_team boolean Whether the player wants to join a buddy's team. This means both players will be on the same team.
|
||||
|
||||
---Table of [OarcSpawnChoices](lua://OarcSpawnChoices) indexed by player name.
|
||||
---@alias OarcSpawnChoicesTable table<string, OarcSpawnChoices>
|
||||
|
||||
---Primary means a player can spawn for the first time on this surface, secondary they can land here and also receive a custom spawn area.
|
||||
---@alias OarcSurfaceSpawnSetting { primary: boolean, secondary: boolean}
|
||||
|
@ -1122,7 +1122,10 @@ function AcceptBuddyRequest(player, requesting_buddy_name)
|
||||
local requesting_buddy = game.players[requesting_buddy_name]
|
||||
local surface = game.surfaces[spawn_choices.surface]
|
||||
|
||||
global.spawn_choices[player.name].host = nil -- N/A for buddy spawns so clear it.
|
||||
-- Copy the buddy's spawn choices to the accepting player
|
||||
spawn_choices.host = nil -- N/A for buddy spawns so clear it.
|
||||
global.spawn_choices[player.name] = table.deepcopy(spawn_choices)
|
||||
global.spawn_choices[player.name].buddy = requesting_buddy_name
|
||||
|
||||
-- Find coordinates of a good place to spawn
|
||||
local spawn_position = FindUngeneratedCoordinates(surface, spawn_choices.distance, 3)
|
||||
@ -1159,12 +1162,12 @@ function AcceptBuddyRequest(player, requesting_buddy_name)
|
||||
x_offset = x_offset + 10
|
||||
end
|
||||
buddySpawn = { x = spawn_position.x + x_offset, y = spawn_position.y }
|
||||
SetPlayerRespawn(player.name, spawn_choices.surface, spawn_position, true)
|
||||
SetPlayerRespawn(requesting_buddy_name, spawn_choices.surface, buddySpawn, true)
|
||||
SetPlayerRespawn(player.name, spawn_choices.surface, buddySpawn, true)
|
||||
SetPlayerRespawn(requesting_buddy_name, spawn_choices.surface, spawn_position, true)
|
||||
|
||||
-- Send the player there
|
||||
QueuePlayerForDelayedSpawn(player.name, spawn_choices.surface, spawn_position, spawn_choices.moat, true, requesting_buddy_name)
|
||||
QueuePlayerForDelayedSpawn(requesting_buddy_name, spawn_choices.surface, buddySpawn, spawn_choices.moat, true, player.name)
|
||||
QueuePlayerForDelayedSpawn(player.name, spawn_choices.surface, buddySpawn, spawn_choices.moat, true, requesting_buddy_name)
|
||||
QueuePlayerForDelayedSpawn(requesting_buddy_name, spawn_choices.surface, spawn_position, spawn_choices.moat, true, player.name)
|
||||
SendBroadcastMsg({"", {"oarc-buddies-are-joining", requesting_buddy_name, player.name, spawn_choices.surface}, " ", GetGPStext(spawn_choices.surface, spawn_position)})
|
||||
|
||||
-- Unlock spawn control gui tab
|
||||
|
@ -221,9 +221,11 @@ oarc-settings-tab-description=This tab contains the same mod settings in the mod
|
||||
oarc-settings-tab-text-field-enter-tooltip=[color=red]You must press ENTER after typing in a text field to save the value![/color]
|
||||
oarc-settings-tab-title-surface=Surface Settings
|
||||
oarc-settings-tab-surface-checkbox-tooltip=Enabling this will allow custom spawn areas (the main feature of this mod) on this surface. You need at least one of these enabled for the mod to work.
|
||||
oarc-settings-tab-surface-secondary-checkbox-tooltip=Enabling this will give players custom secondary spawns when they first travel to this surface. [color=red]This feature is currently a work in progress.[/color]
|
||||
oarc-settings-tab-surface-regrowth-checkbox-tooltip=Enabling this will allow the regrowth and world eater features to work on this surface, if those are enabled.
|
||||
oarc-settings-tab-surface-column-header=Surface
|
||||
oarc-settings-tab-surface-spawning-enabled=Custom Spawns
|
||||
oarc-settings-tab-surface-spawning-enabled=Home
|
||||
oarc-settings-tab-surface-secondary-enabled=Secondary
|
||||
oarc-settings-tab-surface-regrowth-enabled=Regrowth
|
||||
oarc-settings-tab-title-export=Import/Export Settings
|
||||
oarc-settings-tab-export-button=Export
|
||||
|
Loading…
Reference in New Issue
Block a user