1
0
mirror of https://github.com/Oarcinae/FactorioScenarioMultiplayerSpawn.git synced 2025-03-03 14:42:27 +02:00

I have a close to complete vanilla spawn solution. Needs testing and tweaking though...

This commit is contained in:
Oarcinae 2019-03-19 16:46:31 -04:00
parent f04cf2c35b
commit d07f767389
5 changed files with 229 additions and 118 deletions

View File

@ -47,8 +47,11 @@ ENABLE_SEPARATE_SPAWNS = true
-- Enable this to have a vanilla style starting spawn.
-- This scenario normally gives you a fixed circle with resources.
-- WORK IN PROGRESS - STILL IN DEV - BUGGY A.F.
-- WORK IN PROGRESS
ENABLE_VANILLA_SPAWNS = true
VANILLA_SPAWN_COUNT = 8 -- num total spawns pre-assigned (minimum number)
VANILLA_SPAWN_SPACING = 2000 -- num tiles between each spawn.
-- This allows 2 players to spawn next to each other in the wilderness,
-- each with their own starting point. It adds more GUI selection options.

View File

@ -44,8 +44,8 @@ require("config")
require("lib/separate_spawns")
require("lib/separate_spawns_guis")
-- In this case, we are using the default surface.
GAME_SURFACE_NAME="nauvis"
-- Create a new surface so we can modify map settings at the start.
GAME_SURFACE_NAME="oarc"
--------------------------------------------------------------------------------
-- ALL EVENT HANLDERS ARE HERE IN ONE PLACE!
@ -57,24 +57,10 @@ GAME_SURFACE_NAME="nauvis"
----------------------------------------
script.on_init(function(event)
-- Create new game surface
CreateGameSurface()
-- local game_settings = game.surfaces[GAME_SURFACE_NAME].map_gen_settings
-- game_settings.starting_points = {{x=-3000, y=-3000},
-- {x=-3000, y=3000},
-- {x=3000, y=-3000},
-- {x=3000, y=3000}}
-- game_settings.property_expression_names.elevation = "0_17-island"
-- game.surfaces[GAME_SURFACE_NAME].map_gen_settings = game_settings
-- -- Delete the starting chunks that make it into the game before settings are changed.
-- for chunk in game.surfaces[GAME_SURFACE_NAME].get_chunks() do
-- -- Don't delete the chunk that might contain players lol.
-- -- This is really only a problem for launching AS the host. Not headless
-- if ((not chunk.x == 0) and (not chunk.y == 0)) then
-- game.surfaces[GAME_SURFACE_NAME].delete_chunk({x=chunk.x, y=chunk.y})
-- end
-- end
-- MUST be before other stuff, but after surface creation.
if ENABLE_SEPARATE_SPAWNS then
InitSpawnGlobalsAndForces()
end

View File

@ -422,6 +422,29 @@ function RemoveInCircle(surface, area, type, pos, dist)
end
end
-- Create another surface so that we can modify map settings and not have a screwy nauvis map.
function CreateGameSurface()
-- Get starting surface settings.
local nauvis_settings = game.surfaces["nauvis"].map_gen_settings
if ENABLE_VANILLA_SPAWNS then
nauvis_settings.starting_points = CreateVanillaSpawns(VANILLA_SPAWN_COUNT, VANILLA_SPAWN_SPACING)
-- DeleteAllChunksExceptCenter(game.surfaces[GAME_SURFACE_NAME])
-- ISLAND MAP GEN -- WARNING
-- nauvis_settings.property_expression_names.elevation = "0_17-island"
-- ISLAND MAP GEN -- WARNING
end
-- Create new game surface
game.create_surface(GAME_SURFACE_NAME, nauvis_settings)
end
--------------------------------------------------------------------------------
-- Functions for removing/modifying enemies
--------------------------------------------------------------------------------
-- Convenient way to remove aliens, just provide an area
function RemoveAliensInArea(surface, area)
for _, entity in pairs(surface.find_entities_filtered{area = area, force = "enemy"}) do

View File

@ -43,7 +43,7 @@ function SeparateSpawnsGenerateChunk(event)
-- This handles chunk generation near player spawns
-- If it is near a player spawn, it does a few things like make the area
-- safe and provide a guaranteed area of land and water tiles.
SetupAndClearSpawnAreas(surface, chunkArea, global.uniqueSpawns)
SetupAndClearSpawnAreas(surface, chunkArea)
end
@ -136,55 +136,58 @@ end
-- unique spawn points.
-- This clears enemies in the immediate area, creates a slightly safe area around it,
-- It no LONGER generates the resources though as that is now handled in a delayed event!
function SetupAndClearSpawnAreas(surface, chunkArea, spawnPointTable)
for name,spawn in pairs(spawnPointTable) do
function SetupAndClearSpawnAreas(surface, chunkArea)
for name,spawn in pairs(global.uniqueSpawns) do
-- Create a bunch of useful area and position variables
local landArea = GetAreaAroundPos(spawn.pos, ENFORCE_LAND_AREA_TILE_DIST+CHUNK_SIZE)
local safeArea = GetAreaAroundPos(spawn.pos, SAFE_AREA_TILE_DIST)
local warningArea = GetAreaAroundPos(spawn.pos, WARNING_AREA_TILE_DIST)
local reducedArea = GetAreaAroundPos(spawn.pos, REDUCED_DANGER_AREA_TILE_DIST)
local chunkAreaCenter = {x=chunkArea.left_top.x+(CHUNK_SIZE/2),
y=chunkArea.left_top.y+(CHUNK_SIZE/2)}
local spawnPosOffset = {x=spawn.pos.x+ENFORCE_LAND_AREA_TILE_DIST,
y=spawn.pos.y+ENFORCE_LAND_AREA_TILE_DIST}
if (not spawn.vanilla) then
-- Make chunks near a spawn safe by removing enemies
if CheckIfInArea(chunkAreaCenter,safeArea) then
RemoveAliensInArea(surface, chunkArea)
-- Create a warning area with heavily reduced enemies
elseif CheckIfInArea(chunkAreaCenter,warningArea) then
ReduceAliensInArea(surface, chunkArea, WARN_AREA_REDUCTION_RATIO)
-- DowngradeWormsInArea(surface, chunkArea, 100, 100, 100)
RemoveWormsInArea(surface, chunkArea, false, true, true, true) -- remove all non-small worms.
-- Create a bunch of useful area and position variables
local landArea = GetAreaAroundPos(spawn.pos, ENFORCE_LAND_AREA_TILE_DIST+CHUNK_SIZE)
local safeArea = GetAreaAroundPos(spawn.pos, SAFE_AREA_TILE_DIST)
local warningArea = GetAreaAroundPos(spawn.pos, WARNING_AREA_TILE_DIST)
local reducedArea = GetAreaAroundPos(spawn.pos, REDUCED_DANGER_AREA_TILE_DIST)
local chunkAreaCenter = {x=chunkArea.left_top.x+(CHUNK_SIZE/2),
y=chunkArea.left_top.y+(CHUNK_SIZE/2)}
local spawnPosOffset = {x=spawn.pos.x+ENFORCE_LAND_AREA_TILE_DIST,
y=spawn.pos.y+ENFORCE_LAND_AREA_TILE_DIST}
-- Create a third area with moderatly reduced enemies
elseif CheckIfInArea(chunkAreaCenter,reducedArea) then
ReduceAliensInArea(surface, chunkArea, REDUCED_DANGER_AREA_REDUCTION_RATIO)
-- DowngradeWormsInArea(surface, chunkArea, 50, 100, 100)
RemoveWormsInArea(surface, chunkArea, false, false, true, true) -- remove all huge/behemoth worms.
end
-- Make chunks near a spawn safe by removing enemies
if CheckIfInArea(chunkAreaCenter,safeArea) then
RemoveAliensInArea(surface, chunkArea)
-- Create a warning area with heavily reduced enemies
elseif CheckIfInArea(chunkAreaCenter,warningArea) then
ReduceAliensInArea(surface, chunkArea, WARN_AREA_REDUCTION_RATIO)
-- DowngradeWormsInArea(surface, chunkArea, 100, 100, 100)
RemoveWormsInArea(surface, chunkArea, false, true, true, true) -- remove all non-small worms.
-- If the chunk is within the main land area, then clear trees/resources
-- and create the land spawn areas (guaranteed land with a circle of trees)
if CheckIfInArea(chunkAreaCenter,landArea) then
-- Remove trees/resources inside the spawn area
RemoveInCircle(surface, chunkArea, "tree", spawn.pos, ENFORCE_LAND_AREA_TILE_DIST)
RemoveInCircle(surface, chunkArea, "resource", spawn.pos, ENFORCE_LAND_AREA_TILE_DIST+5)
RemoveInCircle(surface, chunkArea, "cliff", spawn.pos, ENFORCE_LAND_AREA_TILE_DIST+5)
-- RemoveDecorationsArea(surface, chunkArea)
if (OARC_CFG.gen_settings.tree_circle) then
CreateCropCircle(surface, spawn.pos, chunkArea, ENFORCE_LAND_AREA_TILE_DIST)
-- Create a third area with moderatly reduced enemies
elseif CheckIfInArea(chunkAreaCenter,reducedArea) then
ReduceAliensInArea(surface, chunkArea, REDUCED_DANGER_AREA_REDUCTION_RATIO)
-- DowngradeWormsInArea(surface, chunkArea, 50, 100, 100)
RemoveWormsInArea(surface, chunkArea, false, false, true, true) -- remove all huge/behemoth worms.
end
if (OARC_CFG.gen_settings.tree_octagon) then
CreateCropOctagon(surface, spawn.pos, chunkArea, ENFORCE_LAND_AREA_TILE_DIST)
end
if (SPAWN_MOAT_CHOICE_ENABLED) then
if (spawn.moat) then
CreateMoat(surface, spawn.pos, chunkArea, ENFORCE_LAND_AREA_TILE_DIST)
-- If the chunk is within the main land area, then clear trees/resources
-- and create the land spawn areas (guaranteed land with a circle of trees)
if CheckIfInArea(chunkAreaCenter,landArea) then
-- Remove trees/resources inside the spawn area
RemoveInCircle(surface, chunkArea, "tree", spawn.pos, ENFORCE_LAND_AREA_TILE_DIST)
RemoveInCircle(surface, chunkArea, "resource", spawn.pos, ENFORCE_LAND_AREA_TILE_DIST+5)
RemoveInCircle(surface, chunkArea, "cliff", spawn.pos, ENFORCE_LAND_AREA_TILE_DIST+5)
-- RemoveDecorationsArea(surface, chunkArea)
if (OARC_CFG.gen_settings.tree_circle) then
CreateCropCircle(surface, spawn.pos, chunkArea, ENFORCE_LAND_AREA_TILE_DIST)
end
if (OARC_CFG.gen_settings.tree_octagon) then
CreateCropOctagon(surface, spawn.pos, chunkArea, ENFORCE_LAND_AREA_TILE_DIST)
end
if (SPAWN_MOAT_CHOICE_ENABLED) then
if (spawn.moat) then
CreateMoat(surface, spawn.pos, chunkArea, ENFORCE_LAND_AREA_TILE_DIST)
end
end
end
end
@ -368,12 +371,12 @@ function InitSpawnGlobalsAndForces()
-- This is the most important table. It is a list of all the unique spawn points.
-- This is what chunk generation checks against.
-- Each entry looks like this: {pos={x,y},moat=bool,vanilla=bool}
if (global.uniqueSpawns == nil) then
global.uniqueSpawns = {}
end
-- My attempt at trying to support vanilla spawns
--
-- List of available vanilla spawns
if (global.vanillaSpawns == nil) then
global.vanillaSpawns = {}
end
@ -451,18 +454,18 @@ function ChangePlayerSpawn(player, pos)
global.playerCooldowns[player.name] = {setRespawn=game.tick}
end
function QueuePlayerForDelayedSpawn(playerName, spawn, moatEnabled)
function QueuePlayerForDelayedSpawn(playerName, spawn, moatEnabled, vanillaSpawn)
-- If we get a valid spawn point, setup the area
if ((spawn.x ~= 0) and (spawn.y ~= 0)) then
global.uniqueSpawns[playerName] = {pos=spawn,moat=moatEnabled}
global.uniqueSpawns[playerName] = {pos=spawn,moat=moatEnabled,vanilla=vanillaSpawn}
local delay_spawn_seconds = 5*(math.ceil(ENFORCE_LAND_AREA_TILE_DIST/CHUNK_SIZE))
game.players[playerName].print("Generating your spawn now, please wait a few for " .. delay_spawn_seconds .. " seconds...")
game.players[playerName].surface.request_to_generate_chunks(spawn, 4)
delayedTick = game.tick + delay_spawn_seconds*TICKS_PER_SECOND
table.insert(global.delayedSpawns, {playerName=playerName, spawn=spawn, moatEnabled=moatEnabled, delayedTick=delayedTick})
table.insert(global.delayedSpawns, {playerName=playerName, pos=spawn, moat=moatEnabled, vanilla=vanillaSpawn, delayedTick=delayedTick})
DisplayPleaseWaitForSpawnDialog(game.players[playerName], delay_spawn_seconds)
@ -485,7 +488,7 @@ function DelayedSpawnOnTick()
if (delayedSpawn.delayedTick < game.tick) then
-- TODO, add check here for if chunks around spawn are generated surface.is_chunk_generated(chunkPos)
if (game.players[delayedSpawn.playerName] ~= nil) then
SendPlayerToNewSpawnAndCreateIt(delayedSpawn.playerName, delayedSpawn.spawn, delayedSpawn.moatEnabled)
SendPlayerToNewSpawnAndCreateIt(delayedSpawn)
end
table.remove(global.delayedSpawns, i)
end
@ -494,30 +497,35 @@ function DelayedSpawnOnTick()
end
end
function SendPlayerToNewSpawnAndCreateIt(playerName, spawn, moatEnabled)
function SendPlayerToNewSpawnAndCreateIt(delayedSpawn)
-- DOUBLE CHECK and make sure the area is super safe.
ClearNearbyEnemies(spawn, SAFE_AREA_TILE_DIST, game.surfaces[GAME_SURFACE_NAME])
ClearNearbyEnemies(delayedSpawn.pos, SAFE_AREA_TILE_DIST, game.surfaces[GAME_SURFACE_NAME])
-- Create the spawn resources here
local water_data = OARC_CFG.water
CreateWaterStrip(game.surfaces[GAME_SURFACE_NAME],
{x=spawn.x+water_data.x_offset, y=spawn.y+water_data.y_offset},
water_data.length)
CreateWaterStrip(game.surfaces[GAME_SURFACE_NAME],
{x=spawn.x+water_data.x_offset, y=spawn.y+water_data.y_offset+1},
water_data.length)
GenerateStartingResources(game.surfaces[GAME_SURFACE_NAME], spawn)
if (not delayedSpawn.vanilla) then
-- Create the spawn resources here
local water_data = OARC_CFG.water
CreateWaterStrip(game.surfaces[GAME_SURFACE_NAME],
{x=delayedSpawn.pos.x+water_data.x_offset, y=delayedSpawn.pos.y+water_data.y_offset},
water_data.length)
CreateWaterStrip(game.surfaces[GAME_SURFACE_NAME],
{x=delayedSpawn.pos.x+water_data.x_offset, y=delayedSpawn.pos.y+water_data.y_offset+1},
water_data.length)
GenerateStartingResources(game.surfaces[GAME_SURFACE_NAME], delayedSpawn.pos)
end
-- Send the player to that position
game.players[playerName].teleport(spawn, GAME_SURFACE_NAME)
GivePlayerStarterItems(game.players[playerName])
local player = game.players[delayedSpawn.playerName]
player.teleport(delayedSpawn.pos, GAME_SURFACE_NAME)
GivePlayerStarterItems(game.players[delayedSpawn.playerName])
-- Chart the area.
ChartArea(game.players[playerName].force, game.players[playerName].position, math.ceil(ENFORCE_LAND_AREA_TILE_DIST/CHUNK_SIZE), game.players[playerName].surface)
ChartArea(player.force, delayedSpawn.pos, math.ceil(ENFORCE_LAND_AREA_TILE_DIST/CHUNK_SIZE), player.surface)
if (game.players[playerName].gui.center.wait_for_spawn_dialog ~= nil) then
game.players[playerName].gui.center.wait_for_spawn_dialog.destroy()
if (player.gui.center.wait_for_spawn_dialog ~= nil) then
player.gui.center.wait_for_spawn_dialog.destroy()
end
end
@ -584,3 +592,57 @@ function CreatePlayerCustomForce(player)
return newForce
end
-- Function to generate some map_gen_settings.starting_points
-- You should only use this at the start of the game really.
function CreateVanillaSpawns(count, spacing)
local points = {}
-- Get an ODD number from the square of the input count.
-- Always rounding up so we don't end up with less points that requested.
local sqrt_count = math.ceil(math.sqrt(count))
if (sqrt_count % 2 == 0) then
sqrt_count = sqrt_count + 1
end
-- Need to know how much to offset the grid.
local sqrt_half = math.floor((sqrt_count-1)/2)
log("sqrt_half " .. sqrt_half)
if (sqrt_count < 1) then
DebugPrint("CreateVanillaSpawns less than 1!!")
return
end
if (global.vanillaSpawns == nil) then
global.vanillaSpawns = {}
end
-- This should give me points centered around 0,0 I think.
for i=-sqrt_half,sqrt_half,1 do
for j=-sqrt_half,sqrt_half,1 do
if (i~=0 or j~=0) then -- EXCEPT don't put 0,0
table.insert(points, {x=i*spacing,y=j*spacing})
table.insert(global.vanillaSpawns, {x=i*spacing,y=j*spacing})
end
end
end
-- Do something with the return value.
return points
end
-- Useful when combined with something like CreateVanillaSpawns
-- Where it helps ensure ALL chunks generated use new map_gen_settings.
function DeleteAllChunksExceptCenter(surface)
-- Delete the starting chunks that make it into the game before settings are changed.
for chunk in surface.get_chunks() do
-- Don't delete the chunk that might contain players lol.
-- This is really only a problem for launching AS the host. Not headless
if ((chunk.x ~= 0) and (chunk.y ~= 0)) then
surface.delete_chunk({chunk.x, chunk.y})
end
end
end

View File

@ -114,14 +114,15 @@ function DisplaySpawnOptions(player)
caption="Vanilla Spawn"}
local normal_spawn_text = "This is the default spawn behavior of a vanilla game. You join the default team in the center of the map."
AddLabel(sGui, "normal_spawn_lbl1", normal_spawn_text, my_label_style)
AddSpacerLine(sGui, "normal_spawn_spacer")
-- AddSpacerLine(sGui, "normal_spawn_spacer")
end
-- The main spawning options. Solo near and solo far.
-- If enable, you can also choose to be on your own team.
local soloSpawnFlow = sGui.add{name = "spawn_solo_flow",
type = "flow",
direction="vertical"}
type = "frame",
direction="vertical",
style = "bordered_frame"}
-- Radio buttons to pick your team.
if (ENABLE_SEPARATE_TEAMS) then
@ -135,6 +136,10 @@ function DisplaySpawnOptions(player)
state=false}
end
-- OPTIONS frame
AddLabel(soloSpawnFlow, "options_spawn_lbl1",
"Additional spawn options can be selected here. Not all are compatible with each other.", my_label_style)
-- Allow players to spawn with a moat around their area.
if (SPAWN_MOAT_CHOICE_ENABLED) then
soloSpawnFlow.add{name = "isolated_spawn_moat_option_checkbox",
@ -142,6 +147,12 @@ function DisplaySpawnOptions(player)
caption="Surround your spawn with a moat",
state=false}
end
if (ENABLE_VANILLA_SPAWNS) then
soloSpawnFlow.add{name = "isolated_spawn_vanilla_option_checkbox",
type = "checkbox",
caption="Use a pre-set vanilla spawn point",
state=false}
end
-- Isolated spawn options. The core gameplay of this scenario.
local soloSpawnbuttons = soloSpawnFlow.add{name = "spawn_solo_flow",
@ -159,42 +170,48 @@ function DisplaySpawnOptions(player)
style = "confirm_button"}
AddLabel(soloSpawnFlow, "isolated_spawn_lbl1",
"You are spawned in a new area, with some starting resources.", my_label_style)
AddSpacerLine(soloSpawnFlow, "isolated_spawn_spacer")
-- Spawn options to join another player's base.
local sharedSpawnFrame = sGui.add{name = "spawn_shared_flow",
type = "frame",
direction="vertical",
style = "bordered_frame"}
if ENABLE_SHARED_SPAWNS then
local numAvailSpawns = GetNumberOfAvailableSharedSpawns()
if (numAvailSpawns > 0) then
sGui.add{name = "join_other_spawn",
sharedSpawnFrame.add{name = "join_other_spawn",
type = "button",
caption="Join Someone (" .. numAvailSpawns .. " available)"}
local join_spawn_text = "You are spawned in someone else's base. This requires at least 1 person to have allowed access to their base. This choice is final and you will not be able to create your own spawn later."
AddLabel(sGui, "join_other_spawn_lbl1", join_spawn_text, my_label_style)
AddLabel(sharedSpawnFrame, "join_other_spawn_lbl1", join_spawn_text, my_label_style)
else
AddLabel(sGui, "join_other_spawn_lbl1", "There are currently no shared bases availble to spawn at.", my_label_style)
sGui.add{name = "join_other_spawn_check",
AddLabel(sharedSpawnFrame, "join_other_spawn_lbl1", "There are currently no shared bases availble to spawn at.", my_label_style)
sharedSpawnFrame.add{name = "join_other_spawn_check",
type = "button",
caption="Check Again"}
end
else
AddLabel(soloSpawnFlow, "join_other_spawn_lbl1",
AddLabel(sharedSpawnFrame, "join_other_spawn_lbl1",
"Shared spawns are disabled in this mode.", my_warning_style)
end
-- New awesome buddy spawning system
-- Awesome buddy spawning system
local buddySpawnFrame = sGui.add{name = "spawn_buddy_flow",
type = "frame",
direction="vertical",
style = "bordered_frame"}
if ENABLE_SHARED_SPAWNS and ENABLE_BUDDY_SPAWN then
AddSpacerLine(sGui, "buddy_spawn_msg_spacer")
sGui.add{name = "buddy_spawn",
-- AddSpacerLine(buddySpawnFrame, "buddy_spawn_msg_spacer")
buddySpawnFrame.add{name = "buddy_spawn",
type = "button",
caption="Buddy Spawn"}
AddLabel(sGui, "buddy_spawn_lbl1",
AddLabel(buddySpawnFrame, "buddy_spawn_lbl1",
"The buddy system requires 2 players in this menu at the same time, you spawn beside each other, each with your own resources.", my_label_style)
end
-- Some final notes
AddSpacerLine(sGui, "note_spacer1")
if (MAX_ONLINE_PLAYERS_AT_SHARED_SPAWN > 0) then
AddLabel(sGui, "max_players_lbl2",
"If you create your own spawn point you can allow up to " .. MAX_ONLINE_PLAYERS_AT_SHARED_SPAWN-1 .. " other online players to join.",
@ -207,12 +224,11 @@ function DisplaySpawnOptions(player)
end
-- This just updates the radio buttons when players click them.
-- This just updates the radio buttons/checkboxes when players click them.
function SpawnOptsRadioSelect(event)
if not (event and event.element and event.element.valid) then return end
local elemName = event.element.name
if (elemName == "isolated_spawn_main_team_radio") then
event.element.parent.isolated_spawn_new_team_radio.state=false
elseif (elemName == "isolated_spawn_new_team_radio") then
@ -230,6 +246,11 @@ function SpawnOptsRadioSelect(event)
event.element.parent.buddy_spawn_new_team_radio.state=false
end
if (elemName == "isolated_spawn_moat_option_checkbox") then
event.element.parent.isolated_spawn_vanilla_option_checkbox.state = false;
elseif (elemName == "isolated_spawn_vanilla_option_checkbox") then
event.element.parent.isolated_spawn_moat_option_checkbox.state = false;
end
end
@ -248,6 +269,8 @@ function SpawnOptsGuiClick(event)
return -- Gui event unrelated to this gui.
end
local pgcs = player.gui.center.spawn_opts
local joinMainTeamRadio, joinOwnTeamRadio, moatChoice = false
-- Check if a valid button on the gui was pressed
@ -261,18 +284,22 @@ function SpawnOptsGuiClick(event)
if (ENABLE_SEPARATE_TEAMS) then
joinMainTeamRadio =
player.gui.center.spawn_opts.spawn_solo_flow.isolated_spawn_main_team_radio.state
pgcs.spawn_solo_flow.isolated_spawn_main_team_radio.state
joinOwnTeamRadio =
player.gui.center.spawn_opts.spawn_solo_flow.isolated_spawn_new_team_radio.state
pgcs.spawn_solo_flow.isolated_spawn_new_team_radio.state
else
joinMainTeamRadio = true
joinOwnTeamRadio = false
end
if (SPAWN_MOAT_CHOICE_ENABLED) then
moatChoice =
player.gui.center.spawn_opts.spawn_solo_flow.isolated_spawn_moat_option_checkbox.state
pgcs.spawn_solo_flow.isolated_spawn_moat_option_checkbox.state
end
player.gui.center.spawn_opts.destroy()
if (ENABLE_VANILLA_SPAWNS) then
vanillaChoice =
pgcs.spawn_solo_flow.isolated_spawn_vanilla_option_checkbox.state
end
pgcs.destroy()
else
return -- Do nothing, no valid element item was clicked.
end
@ -295,11 +322,21 @@ function SpawnOptsGuiClick(event)
local newForce = CreatePlayerCustomForce(player)
end
-- Find coordinates of a good place to spawn
if (elemName == "isolated_spawn_far") then
newSpawn = FindUngeneratedCoordinates(FAR_MIN_DIST,FAR_MAX_DIST, player.surface)
elseif (elemName == "isolated_spawn_near") then
newSpawn = FindUngeneratedCoordinates(NEAR_MIN_DIST,NEAR_MAX_DIST, player.surface)
-- Find an unused vanilla spawn
if (vanillaChoice) then
rand_index = math.random(#global.vanillaSpawns)
newSpawn.x = global.vanillaSpawns[rand_index].x
newSpawn.y = global.vanillaSpawns[rand_index].y
table.remove(global.vanillaSpawns, rand_index)
-- Default OARC-type pre-set layout spawn.
else
-- Find coordinates of a good place to spawn
if (elemName == "isolated_spawn_far") then
newSpawn = FindUngeneratedCoordinates(FAR_MIN_DIST,FAR_MAX_DIST, player.surface)
elseif (elemName == "isolated_spawn_near") then
newSpawn = FindUngeneratedCoordinates(NEAR_MIN_DIST,NEAR_MAX_DIST, player.surface)
end
end
-- If that fails, find a random map edge in a rand direction.
@ -308,11 +345,11 @@ function SpawnOptsGuiClick(event)
DebugPrint("Resorting to find map edge! x=" .. newSpawn.x .. ",y=" .. newSpawn.y)
end
-- Create that spawn in the global vars
-- Create that player's spawn in the global vars
ChangePlayerSpawn(player, newSpawn)
-- Send the player there
QueuePlayerForDelayedSpawn(player.name, newSpawn, moatChoice)
QueuePlayerForDelayedSpawn(player.name, newSpawn, moatChoice, vanillaChoice)
if (elemName == "isolated_spawn_near") then
SendBroadcastMsg(player.name .. " is joining the game from a distance!")
elseif (elemName == "isolated_spawn_far") then
@ -744,7 +781,7 @@ function DisplayBuddySpawnOptions(player)
-- Warnings and explanations...
buddy_info_msg="To use this, make sure you and your buddy are in this menu at the same time. Only one of you must send the request. Select your buddy from the list (refresh if your buddy's name is not visible) and select your spawn options. Click one of the request buttons to send the request. The other buddy can then accept (or deny) the request. This will allow you both to spawn next to each other, each with your own spawn area. Once a buddy accepts a spawn request, it is final!"
AddLabel(buddyGui, "buddy_info_msg", buddy_info_msg, my_label_style)
AddSpacerLine(buddyGui, "buddy_info_spacer")
-- AddSpacerLine(buddyGui, "buddy_info_spacer")
buddyList = {}
for _,buddyName in pairs(global.waitingBuddies) do
@ -1134,8 +1171,8 @@ function BuddySpawnRequestMenuClick(event)
ChangePlayerSpawn(game.players[requesterName], buddySpawn)
-- Send the player there
QueuePlayerForDelayedSpawn(player.name, newSpawn, requesterOptions.moatChoice)
QueuePlayerForDelayedSpawn(requesterName, buddySpawn, requesterOptions.moatChoice)
QueuePlayerForDelayedSpawn(player.name, newSpawn, requesterOptions.moatChoice, false)
QueuePlayerForDelayedSpawn(requesterName, buddySpawn, requesterOptions.moatChoice, false)
SendBroadcastMsg(requesterName .. " and " .. player.name .. " are joining the game together!")
-- Create the button at the top left for setting respawn point and sharing base.