mirror of
https://github.com/Oarcinae/FactorioScenarioMultiplayerSpawn.git
synced 2025-01-26 03:20:21 +02:00
Merge pull request #74 from Oarcinae/vanilla_spawns_dev
Vanilla spawns dev
This commit is contained in:
commit
b224512816
25
config.lua
25
config.lua
@ -45,6 +45,13 @@ SERVER_OWNER_IS_OARC = false
|
||||
-- This is the core of the mod. Probably not a good idea to disable it.
|
||||
ENABLE_SEPARATE_SPAWNS = true
|
||||
|
||||
-- Enable this to have a vanilla style starting spawn.
|
||||
-- This changes the experience pretty drastically.
|
||||
-- If you enable this, you will NOT get the option to spawn using the "pre-fab"
|
||||
-- fixed layout spawns. This is because the spawn types just don't balance well with
|
||||
-- each other.
|
||||
ENABLE_VANILLA_SPAWNS = false
|
||||
|
||||
-- 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.
|
||||
ENABLE_BUDDY_SPAWN = true
|
||||
@ -100,6 +107,7 @@ ENABLE_RESEARCH_QUEUE = true
|
||||
-- Adjust enemy spawning based on distance to spawns. All it does it make things
|
||||
-- more balanced based on your distance and makes the game a little easier.
|
||||
-- No behemoth worms everywhere just because you spawned far away.
|
||||
-- Might want to disable this if you're using ENABLE_VANILLA_SPAWNS
|
||||
OARC_MODIFIED_ENEMY_SPAWNING = true
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
@ -153,7 +161,18 @@ NEAR_MAX_DIST = 50
|
||||
-- Far Distance in chunks
|
||||
FAR_MIN_DIST = 200
|
||||
FAR_MAX_DIST = 300
|
||||
|
||||
|
||||
---------------------------------------
|
||||
-- Vanilla spawn point options
|
||||
-- (only applicable if ENABLE_VANILLA_SPAWNS is enabled.)
|
||||
---------------------------------------
|
||||
|
||||
-- Num total spawns pre-assigned (minimum number)
|
||||
VANILLA_SPAWN_COUNT = 100
|
||||
|
||||
-- Num tiles between each spawn. (I recommend at least 1000)
|
||||
VANILLA_SPAWN_SPACING = 2000
|
||||
|
||||
---------------------------------------
|
||||
-- Resource & Spawn Circle Options
|
||||
---------------------------------------
|
||||
@ -388,7 +407,7 @@ SILO_POSITION = {x = 0, y = 100}
|
||||
-- Set this to false so that you have to search for the silo's.
|
||||
ENABLE_SILO_VISION = true
|
||||
|
||||
-- Add beacons around the silo (Philip's modm)
|
||||
-- Add beacons around the silo (Philip's mod)
|
||||
ENABLE_SILO_BEACONS = false
|
||||
ENABLE_SILO_RADAR = false
|
||||
|
||||
@ -420,7 +439,7 @@ GHOST_TIME_TO_LIVE = 0 * TICKS_PER_MINUTE -- set to 0 for infinite ghost life
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
-- DEBUG prints for me in game.
|
||||
global.oarcDebugEnabled = true
|
||||
global.oarcDebugEnabled = false
|
||||
|
||||
-- These are my specific welcome messages that get used only if I am the user
|
||||
-- that creates the game.
|
||||
|
11
control.lua
11
control.lua
@ -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,7 +57,10 @@ GAME_SURFACE_NAME="nauvis"
|
||||
----------------------------------------
|
||||
script.on_init(function(event)
|
||||
|
||||
-- Create new game surface
|
||||
CreateGameSurface()
|
||||
|
||||
-- MUST be before other stuff, but after surface creation.
|
||||
if ENABLE_SEPARATE_SPAWNS then
|
||||
InitSpawnGlobalsAndForces()
|
||||
end
|
||||
@ -91,10 +94,12 @@ script.on_event(defines.events.on_rocket_launched, function(event)
|
||||
end)
|
||||
|
||||
|
||||
local first_chunk_generated_flag = false
|
||||
----------------------------------------
|
||||
-- Chunk Generation
|
||||
----------------------------------------
|
||||
script.on_event(defines.events.on_chunk_generated, function(event)
|
||||
|
||||
if ENABLE_REGROWTH then
|
||||
OarcRegrowthChunkGenerate(event.area.left_top)
|
||||
end
|
||||
@ -175,7 +180,7 @@ script.on_event(defines.events.on_player_created, function(event)
|
||||
|
||||
-- Move the player to the game surface immediately.
|
||||
-- May change this to Lobby in the future.
|
||||
game.players[event.player_index].teleport(game.forces[MAIN_FORCE].get_spawn_position(GAME_SURFACE_NAME), GAME_SURFACE_NAME)
|
||||
game.players[event.player_index].teleport({x=0,y=0}, GAME_SURFACE_NAME)
|
||||
|
||||
if ENABLE_LONGREACH then
|
||||
GivePlayerLongReach(game.players[event.player_index])
|
||||
|
@ -77,6 +77,11 @@ local function CreateRocketSilo(surface, siloPosition, force)
|
||||
silo.destructible = false
|
||||
silo.minable = false
|
||||
|
||||
-- TAG it on the main force at least.
|
||||
game.forces[MAIN_FORCE].add_chart_tag(game.surfaces[GAME_SURFACE_NAME],
|
||||
{position=siloPosition, text="Rocket Silo",
|
||||
icon={type="item",name="rocket-silo"}})
|
||||
|
||||
-- Make silo safe from being removed by regrowth
|
||||
if ENABLE_REGROWTH then
|
||||
OarcRegrowthOffLimits(siloPosition, 5)
|
||||
@ -84,10 +89,10 @@ local function CreateRocketSilo(surface, siloPosition, force)
|
||||
|
||||
|
||||
if ENABLE_SILO_BEACONS then
|
||||
PhilipsBeaconsAndShit(surface, siloPosition, game.forces[MAIN_FORCE])
|
||||
PhilipsBeacons(surface, siloPosition, game.forces[MAIN_FORCE])
|
||||
end
|
||||
if ENABLE_SILO_RADAR then
|
||||
PhilipsRadarAndShit(surface, siloPosition, game.forces[MAIN_FORCE])
|
||||
PhilipsRadar(surface, siloPosition, game.forces[MAIN_FORCE])
|
||||
end
|
||||
|
||||
end
|
||||
@ -174,145 +179,145 @@ function DelayedSiloCreationOnTick(surface)
|
||||
end
|
||||
|
||||
|
||||
function PhilipsBeaconsAndShit(surface, siloPos, force)
|
||||
function PhilipsBeacons(surface, siloPos, force)
|
||||
|
||||
-- Add Beacons
|
||||
-- x = right, left; y = up, down
|
||||
-- top 1 left 1
|
||||
local beacon = surface.create_entity{name = "beacon", position = {siloPos.x-8, siloPos.y-9}, force = force}
|
||||
local beacon = surface.create_entity{name = "beacon", position = {siloPos.x-8, siloPos.y-8}, force = force}
|
||||
beacon.destructible = false
|
||||
beacon.minable = false
|
||||
-- top 2
|
||||
local beacon = surface.create_entity{name = "beacon", position = {siloPos.x-5, siloPos.y-9}, force = force}
|
||||
local beacon = surface.create_entity{name = "beacon", position = {siloPos.x-5, siloPos.y-8}, force = force}
|
||||
beacon.destructible = false
|
||||
beacon.minable = false
|
||||
-- top 3
|
||||
local beacon = surface.create_entity{name = "beacon", position = {siloPos.x-2, siloPos.y-9}, force = force}
|
||||
local beacon = surface.create_entity{name = "beacon", position = {siloPos.x-2, siloPos.y-8}, force = force}
|
||||
beacon.destructible = false
|
||||
beacon.minable = false
|
||||
-- top 4
|
||||
local beacon = surface.create_entity{name = "beacon", position = {siloPos.x+2, siloPos.y-9}, force = force}
|
||||
local beacon = surface.create_entity{name = "beacon", position = {siloPos.x+2, siloPos.y-8}, force = force}
|
||||
beacon.destructible = false
|
||||
beacon.minable = false
|
||||
-- top 5
|
||||
local beacon = surface.create_entity{name = "beacon", position = {siloPos.x+5, siloPos.y-9}, force = force}
|
||||
local beacon = surface.create_entity{name = "beacon", position = {siloPos.x+5, siloPos.y-8}, force = force}
|
||||
beacon.destructible = false
|
||||
beacon.minable = false
|
||||
-- top 6 right 1
|
||||
local beacon = surface.create_entity{name = "beacon", position = {siloPos.x+8, siloPos.y-9}, force = force}
|
||||
local beacon = surface.create_entity{name = "beacon", position = {siloPos.x+8, siloPos.y-8}, force = force}
|
||||
beacon.destructible = false
|
||||
beacon.minable = false
|
||||
-- left 2
|
||||
local beacon = surface.create_entity{name = "beacon", position = {siloPos.x-6, siloPos.y-6}, force = force}
|
||||
local beacon = surface.create_entity{name = "beacon", position = {siloPos.x-8, siloPos.y-5}, force = force}
|
||||
beacon.destructible = false
|
||||
beacon.minable = false
|
||||
-- left 3
|
||||
local beacon = surface.create_entity{name = "beacon", position = {siloPos.x-6, siloPos.y-3}, force = force}
|
||||
local beacon = surface.create_entity{name = "beacon", position = {siloPos.x-8, siloPos.y-2}, force = force}
|
||||
beacon.destructible = false
|
||||
beacon.minable = false
|
||||
-- left 4
|
||||
local beacon = surface.create_entity{name = "beacon", position = {siloPos.x-6, siloPos.y}, force = force}
|
||||
local beacon = surface.create_entity{name = "beacon", position = {siloPos.x-8, siloPos.y+2}, force = force}
|
||||
beacon.destructible = false
|
||||
beacon.minable = false
|
||||
-- left 5
|
||||
local beacon = surface.create_entity{name = "beacon", position = {siloPos.x-6, siloPos.y+3}, force = force}
|
||||
local beacon = surface.create_entity{name = "beacon", position = {siloPos.x-8, siloPos.y+5}, force = force}
|
||||
beacon.destructible = false
|
||||
beacon.minable = false
|
||||
-- left 6 bottom 1
|
||||
local beacon = surface.create_entity{name = "beacon", position = {siloPos.x-8, siloPos.y+6}, force = force}
|
||||
local beacon = surface.create_entity{name = "beacon", position = {siloPos.x-8, siloPos.y+8}, force = force}
|
||||
beacon.destructible = false
|
||||
beacon.minable = false
|
||||
-- left 7 bottom 2
|
||||
local beacon = surface.create_entity{name = "beacon", position = {siloPos.x-5, siloPos.y+6}, force = force}
|
||||
local beacon = surface.create_entity{name = "beacon", position = {siloPos.x-5, siloPos.y+8}, force = force}
|
||||
beacon.destructible = false
|
||||
beacon.minable = false
|
||||
-- right 2
|
||||
local beacon = surface.create_entity{name = "beacon", position = {siloPos.x+6, siloPos.y-6}, force = force}
|
||||
local beacon = surface.create_entity{name = "beacon", position = {siloPos.x+8, siloPos.y-5}, force = force}
|
||||
beacon.destructible = false
|
||||
beacon.minable = false
|
||||
-- right 3
|
||||
local beacon = surface.create_entity{name = "beacon", position = {siloPos.x+6, siloPos.y-3}, force = force}
|
||||
local beacon = surface.create_entity{name = "beacon", position = {siloPos.x+8, siloPos.y-2}, force = force}
|
||||
beacon.destructible = false
|
||||
beacon.minable = false
|
||||
-- right 4
|
||||
local beacon = surface.create_entity{name = "beacon", position = {siloPos.x+6, siloPos.y}, force = force}
|
||||
local beacon = surface.create_entity{name = "beacon", position = {siloPos.x+8, siloPos.y+2}, force = force}
|
||||
beacon.destructible = false
|
||||
beacon.minable = false
|
||||
-- right 5
|
||||
local beacon = surface.create_entity{name = "beacon", position = {siloPos.x+6, siloPos.y+3}, force = force}
|
||||
local beacon = surface.create_entity{name = "beacon", position = {siloPos.x+8, siloPos.y+5}, force = force}
|
||||
beacon.destructible = false
|
||||
beacon.minable = false
|
||||
-- right 6 bottom 3
|
||||
local beacon = surface.create_entity{name = "beacon", position = {siloPos.x+5, siloPos.y+6}, force = force}
|
||||
local beacon = surface.create_entity{name = "beacon", position = {siloPos.x+5, siloPos.y+8}, force = force}
|
||||
beacon.destructible = false
|
||||
beacon.minable = false
|
||||
-- right 7 bottom 4
|
||||
local beacon = surface.create_entity{name = "beacon", position = {siloPos.x+8, siloPos.y+6}, force = force}
|
||||
local beacon = surface.create_entity{name = "beacon", position = {siloPos.x+8, siloPos.y+8}, force = force}
|
||||
beacon.destructible = false
|
||||
beacon.minable = false
|
||||
-- substations
|
||||
-- top left
|
||||
local substation = surface.create_entity{name = "substation", position = {siloPos.x-8, siloPos.y-6}, force = force}
|
||||
local substation = surface.create_entity{name = "substation", position = {siloPos.x-5, siloPos.y-5}, force = force}
|
||||
substation.destructible = false
|
||||
substation.minable = false
|
||||
-- top right
|
||||
local substation = surface.create_entity{name = "substation", position = {siloPos.x+9, siloPos.y-6}, force = force}
|
||||
local substation = surface.create_entity{name = "substation", position = {siloPos.x+6, siloPos.y-5}, force = force}
|
||||
substation.destructible = false
|
||||
substation.minable = false
|
||||
-- bottom left
|
||||
local substation = surface.create_entity{name = "substation", position = {siloPos.x-8, siloPos.y+4}, force = force}
|
||||
local substation = surface.create_entity{name = "substation", position = {siloPos.x-5, siloPos.y+6}, force = force}
|
||||
substation.destructible = false
|
||||
substation.minable = false
|
||||
-- bottom right
|
||||
local substation = surface.create_entity{name = "substation", position = {siloPos.x+9, siloPos.y+4}, force = force}
|
||||
local substation = surface.create_entity{name = "substation", position = {siloPos.x+6, siloPos.y+6}, force = force}
|
||||
substation.destructible = false
|
||||
substation.minable = false
|
||||
|
||||
-- end adding beacons
|
||||
end
|
||||
|
||||
function PhilipsRadarAndShit(surface, siloPos, force)
|
||||
function PhilipsRadar(surface, siloPos, force)
|
||||
|
||||
local radar = surface.create_entity{name = "solar-panel", position = {siloPos.x-33, siloPos.y+3}, force = force}
|
||||
local radar = surface.create_entity{name = "solar-panel", position = {siloPos.x-43, siloPos.y+3}, force = force}
|
||||
radar.destructible = false
|
||||
local radar = surface.create_entity{name = "solar-panel", position = {siloPos.x-33, siloPos.y-3}, force = force}
|
||||
local radar = surface.create_entity{name = "solar-panel", position = {siloPos.x-43, siloPos.y-3}, force = force}
|
||||
radar.destructible = false
|
||||
local radar = surface.create_entity{name = "solar-panel", position = {siloPos.x-30, siloPos.y-6}, force = force}
|
||||
local radar = surface.create_entity{name = "solar-panel", position = {siloPos.x-40, siloPos.y-6}, force = force}
|
||||
radar.destructible = false
|
||||
local radar = surface.create_entity{name = "solar-panel", position = {siloPos.x-27, siloPos.y-6}, force = force}
|
||||
local radar = surface.create_entity{name = "solar-panel", position = {siloPos.x-37, siloPos.y-6}, force = force}
|
||||
radar.destructible = false
|
||||
local radar = surface.create_entity{name = "solar-panel", position = {siloPos.x-24, siloPos.y-6}, force = force}
|
||||
local radar = surface.create_entity{name = "solar-panel", position = {siloPos.x-34, siloPos.y-6}, force = force}
|
||||
radar.destructible = false
|
||||
local radar = surface.create_entity{name = "solar-panel", position = {siloPos.x-24, siloPos.y-3}, force = force}
|
||||
local radar = surface.create_entity{name = "solar-panel", position = {siloPos.x-34, siloPos.y-3}, force = force}
|
||||
radar.destructible = false
|
||||
local radar = surface.create_entity{name = "solar-panel", position = {siloPos.x-24, siloPos.y}, force = force}
|
||||
local radar = surface.create_entity{name = "solar-panel", position = {siloPos.x-34, siloPos.y}, force = force}
|
||||
radar.destructible = false
|
||||
local radar = surface.create_entity{name = "solar-panel", position = {siloPos.x-24, siloPos.y+3}, force = force}
|
||||
local radar = surface.create_entity{name = "solar-panel", position = {siloPos.x-34, siloPos.y+3}, force = force}
|
||||
radar.destructible = false
|
||||
local radar = surface.create_entity{name = "solar-panel", position = {siloPos.x-33, siloPos.y-6}, force = force}
|
||||
local radar = surface.create_entity{name = "solar-panel", position = {siloPos.x-43, siloPos.y-6}, force = force}
|
||||
radar.destructible = false
|
||||
local radar = surface.create_entity{name = "solar-panel", position = {siloPos.x-30, siloPos.y+3}, force = force}
|
||||
local radar = surface.create_entity{name = "solar-panel", position = {siloPos.x-40, siloPos.y+3}, force = force}
|
||||
radar.destructible = false
|
||||
local radar = surface.create_entity{name = "solar-panel", position = {siloPos.x-27, siloPos.y+3}, force = force}
|
||||
local radar = surface.create_entity{name = "solar-panel", position = {siloPos.x-37, siloPos.y+3}, force = force}
|
||||
radar.destructible = false
|
||||
local radar = surface.create_entity{name = "radar", position = {siloPos.x-33, siloPos.y}, force = force}
|
||||
local radar = surface.create_entity{name = "radar", position = {siloPos.x-43, siloPos.y}, force = force}
|
||||
radar.destructible = false
|
||||
local substation = surface.create_entity{name = "substation", position = {siloPos.x-28, siloPos.y-1}, force = force}
|
||||
local substation = surface.create_entity{name = "substation", position = {siloPos.x-38, siloPos.y-1}, force = force}
|
||||
substation.destructible = false
|
||||
local radar = surface.create_entity{name = "accumulator", position = {siloPos.x-30, siloPos.y-1}, force = force}
|
||||
local radar = surface.create_entity{name = "accumulator", position = {siloPos.x-40, siloPos.y-1}, force = force}
|
||||
radar.destructible = false
|
||||
local radar = surface.create_entity{name = "accumulator", position = {siloPos.x-30, siloPos.y-3}, force = force}
|
||||
local radar = surface.create_entity{name = "accumulator", position = {siloPos.x-40, siloPos.y-3}, force = force}
|
||||
radar.destructible = false
|
||||
local radar = surface.create_entity{name = "accumulator", position = {siloPos.x-30, siloPos.y+1}, force = force}
|
||||
local radar = surface.create_entity{name = "accumulator", position = {siloPos.x-40, siloPos.y+1}, force = force}
|
||||
radar.destructible = false
|
||||
local radar = surface.create_entity{name = "accumulator", position = {siloPos.x-28, siloPos.y-3}, force = force}
|
||||
local radar = surface.create_entity{name = "accumulator", position = {siloPos.x-38, siloPos.y-3}, force = force}
|
||||
radar.destructible = false
|
||||
local radar = surface.create_entity{name = "accumulator", position = {siloPos.x-28, siloPos.y+1}, force = force}
|
||||
local radar = surface.create_entity{name = "accumulator", position = {siloPos.x-38, siloPos.y+1}, force = force}
|
||||
radar.destructible = false
|
||||
local radar = surface.create_entity{name = "accumulator", position = {siloPos.x-26, siloPos.y-1}, force = force}
|
||||
local radar = surface.create_entity{name = "accumulator", position = {siloPos.x-36, siloPos.y-1}, force = force}
|
||||
radar.destructible = false
|
||||
local radar = surface.create_entity{name = "accumulator", position = {siloPos.x-26, siloPos.y-3}, force = force}
|
||||
local radar = surface.create_entity{name = "accumulator", position = {siloPos.x-36, siloPos.y-3}, force = force}
|
||||
radar.destructible = false
|
||||
local radar = surface.create_entity{name = "accumulator", position = {siloPos.x-26, siloPos.y+1}, force = force}
|
||||
local radar = surface.create_entity{name = "accumulator", position = {siloPos.x-36, siloPos.y+1}, force = force}
|
||||
radar.destructible = false
|
||||
end
|
@ -401,6 +401,11 @@ function GetAreaAroundPos(pos, dist)
|
||||
y=pos.y+dist}}
|
||||
end
|
||||
|
||||
-- Gets chunk position of a tile.
|
||||
function GetChunkPosFromTilePos(tile_pos)
|
||||
return {x=math.floor(tile_pos.x/32), y=math.floor(tile_pos.y/32)}
|
||||
end
|
||||
|
||||
-- Removes the entity type from the area given
|
||||
function RemoveInArea(surface, area, type)
|
||||
for key, entity in pairs(surface.find_entities_filtered({area=area, type= type})) do
|
||||
@ -422,6 +427,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
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
-- Generic Utility Includes
|
||||
require("lib/oarc_utils")
|
||||
require("config")
|
||||
|
||||
|
||||
-- Default timeout of generated chunks
|
||||
@ -321,7 +322,11 @@ function OarcRegrowthOnTick()
|
||||
-- Send a broadcast warning before it happens.
|
||||
if ((game.tick % REGROWTH_CLEANING_INTERVAL_TICKS) == REGROWTH_CLEANING_INTERVAL_TICKS-601) then
|
||||
if (#global.chunk_regrow.removal_list > 100) then
|
||||
SendBroadcastMsg("Map cleanup in 10 seconds, if you don't want to lose what you found drop a powered radar on it!")
|
||||
if (ENABLE_REGROWTH) then
|
||||
SendBroadcastMsg("Map cleanup in 10 seconds, if you don't want to lose what you found drop a powered radar on it!")
|
||||
else
|
||||
SendBroadcastMsg("Map cleanup in 10 seconds. Cleaning up an abadoned base!")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -340,10 +345,19 @@ end
|
||||
function OarcRegrowthForceRemovalOnTick()
|
||||
-- Catch force remove flag
|
||||
if (game.tick == global.chunk_regrow.force_removal_flag+60) then
|
||||
SendBroadcastMsg("Map cleanup in 10 seconds, if you don't want to lose what you found drop a powered radar on it!")
|
||||
if (ENABLE_REGROWTH) then
|
||||
SendBroadcastMsg("Map cleanup in 10 seconds, if you don't want to lose what you found drop a powered radar on it!")
|
||||
else
|
||||
SendBroadcastMsg("Map cleanup in 10 seconds. Cleaning up an abadoned base!")
|
||||
end
|
||||
end
|
||||
if (game.tick == global.chunk_regrow.force_removal_flag+660) then
|
||||
OarcRegrowthRemoveAllChunks()
|
||||
SendBroadcastMsg("Map cleanup done, sorry for your loss.")
|
||||
|
||||
if (ENABLE_REGROWTH) then
|
||||
SendBroadcastMsg("Map cleanup done, sorry for your loss.")
|
||||
else
|
||||
SendBroadcastMsg("Abandoned base cleanup complete.")
|
||||
end
|
||||
end
|
||||
end
|
@ -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
|
||||
|
||||
|
||||
@ -62,6 +62,11 @@ function FindUnusedSpawns(event)
|
||||
delayedSpawn = global.delayedSpawns[i]
|
||||
|
||||
if (player.name == delayedSpawn.playerName) then
|
||||
if (delayedSpawn.vanilla) then
|
||||
log("Returning a vanilla spawn back to available.")
|
||||
table.insert(global.vanillaSpawns, {x=delayedSpawn.pos.x,y=delayedSpawn.pos.y})
|
||||
end
|
||||
|
||||
table.remove(global.delayedSpawns, i)
|
||||
DebugPrint("Removing player from delayed spawn queue: " .. player.name)
|
||||
end
|
||||
@ -95,16 +100,22 @@ function FindUnusedSpawns(event)
|
||||
end
|
||||
|
||||
if (ENABLE_ABANDONED_BASE_REMOVAL and not nearOtherSpawn) then
|
||||
global.uniqueSpawns[player.name] = nil
|
||||
if (global.uniqueSpawns[player.name].vanilla) then
|
||||
log("Returning a vanilla spawn back to available.")
|
||||
table.insert(global.vanillaSpawns, {x=spawnPos.x,y=spawnPos.y})
|
||||
end
|
||||
|
||||
SendBroadcastMsg(player.name .. "'s base was marked for immediate clean up because they left within "..MIN_ONLINE_TIME_IN_MINUTES.." minutes of joining.")
|
||||
OarcRegrowthMarkForRemoval(spawnPos, 10)
|
||||
global.chunk_regrow.force_removal_flag = game.tick
|
||||
else
|
||||
-- table.insert(global.unusedSpawns, global.uniqueSpawns[player.name]) -- Not used/implemented right now.
|
||||
global.uniqueSpawns[player.name] = nil
|
||||
SendBroadcastMsg(player.name .. " base was freed up because they left within "..MIN_ONLINE_TIME_IN_MINUTES.." minutes of joining.")
|
||||
end
|
||||
|
||||
SendBroadcastMsg(player.name .. "'s base was marked for immediate clean up because they left within "..MIN_ONLINE_TIME_IN_MINUTES.." minutes of joining.")
|
||||
OarcRegrowthMarkForRemoval(spawnPos, 10)
|
||||
global.chunk_regrow.force_removal_flag = game.tick
|
||||
|
||||
else
|
||||
-- table.insert(global.unusedSpawns, global.uniqueSpawns[player.name]) -- Not used/implemented right now.
|
||||
global.uniqueSpawns[player.name] = nil
|
||||
SendBroadcastMsg(player.name .. " base was freed up because they left within "..MIN_ONLINE_TIME_IN_MINUTES.." minutes of joining.")
|
||||
end
|
||||
end
|
||||
|
||||
-- remove that player's cooldown setting
|
||||
@ -136,55 +147,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,10 +382,16 @@ 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
|
||||
|
||||
-- List of available vanilla spawns
|
||||
if (global.vanillaSpawns == nil) then
|
||||
global.vanillaSpawns = {}
|
||||
end
|
||||
|
||||
-- This keeps a list of any player that has shared their base.
|
||||
-- Each entry contains information about if it's open, spawn pos, and players in the group.
|
||||
if (global.sharedSpawns == nil) then
|
||||
@ -411,7 +431,7 @@ function InitSpawnGlobalsAndForces()
|
||||
-- Name a new force to be the default force.
|
||||
-- This is what any new player is assigned to when they join, even before they spawn.
|
||||
local main_force = game.create_force(MAIN_FORCE)
|
||||
main_force.set_spawn_position(game.forces["player"].get_spawn_position(GAME_SURFACE_NAME), GAME_SURFACE_NAME)
|
||||
main_force.set_spawn_position({x=0,y=0}, GAME_SURFACE_NAME)
|
||||
|
||||
-- Share vision with other forces.
|
||||
if ENABLE_SHARED_TEAM_VISION then
|
||||
@ -445,18 +465,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}
|
||||
if ((spawn.x ~= 0) or (spawn.y ~= 0)) then
|
||||
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].print("Generating your spawn now, please wait for at least " .. 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)
|
||||
|
||||
@ -479,7 +499,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
|
||||
@ -488,30 +508,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
|
||||
|
||||
@ -578,3 +603,112 @@ 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
|
||||
|
||||
-- Find a vanilla spawn as close as possible to the given target_distance
|
||||
function FindUnusedVanillaSpawn(surface, target_distance)
|
||||
local best_key = nil
|
||||
local best_distance = nil
|
||||
|
||||
for k,v in pairs(global.vanillaSpawns) do
|
||||
|
||||
-- Check if chunks nearby are not generated.
|
||||
local chunk_pos = GetChunkPosFromTilePos(v)
|
||||
if IsChunkAreaUngenerated(chunk_pos, 10, surface) then
|
||||
|
||||
-- Is this our first valid find?
|
||||
if ((best_key == nil) or (best_distance == nil)) then
|
||||
best_key = k
|
||||
best_distance = math.abs(math.sqrt((v.x^2) + (v.y^2)) - target_distance)
|
||||
|
||||
-- Check if it is closer to target_distance than previous option.
|
||||
else
|
||||
local new_distance = math.abs(math.sqrt((v.x^2) + (v.y^2)) - target_distance)
|
||||
if (new_distance < best_distance) then
|
||||
best_key = k
|
||||
best_distance = math.sqrt((v.x^2) + (v.y^2))
|
||||
end
|
||||
end
|
||||
|
||||
-- If it's not a valid spawn anymore, let's remove it.
|
||||
else
|
||||
log("Removing vanilla spawn due to chunks generated: x=" .. v.x .. ",y=" .. v.y)
|
||||
table.remove(global.vanillaSpawns, k)
|
||||
end
|
||||
end
|
||||
|
||||
local spawn_pos = {x=0,y=0}
|
||||
if ((best_key ~= nil) and (global.vanillaSpawns[best_key] ~= nil)) then
|
||||
spawn_pos.x = global.vanillaSpawns[best_key].x
|
||||
spawn_pos.y = global.vanillaSpawns[best_key].y
|
||||
table.remove(global.vanillaSpawns, best_key)
|
||||
end
|
||||
DebugPrint("Found unused vanilla spawn: x=" .. spawn_pos.x .. ",y=" .. spawn_pos.y)
|
||||
return spawn_pos
|
||||
end
|
||||
|
||||
|
||||
function ValidateVanillaSpawns(surface)
|
||||
for k,v in pairs(global.vanillaSpawns) do
|
||||
|
||||
-- Check if chunks nearby are not generated.
|
||||
local chunk_pos = GetChunkPosFromTilePos(v)
|
||||
if not IsChunkAreaUngenerated(chunk_pos, 10, surface) then
|
||||
log("Removing vanilla spawn due to chunks generated: x=" .. v.x .. ",y=" .. v.y)
|
||||
table.remove(global.vanillaSpawns, k)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -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,13 +136,23 @@ 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
|
||||
if (SPAWN_MOAT_CHOICE_ENABLED and not ENABLE_VANILLA_SPAWNS) then
|
||||
soloSpawnFlow.add{name = "isolated_spawn_moat_option_checkbox",
|
||||
type = "checkbox",
|
||||
caption="Surround your spawn with a moat",
|
||||
state=false}
|
||||
end
|
||||
-- if (ENABLE_VANILLA_SPAWNS and (#global.vanillaSpawns > 0)) then
|
||||
-- soloSpawnFlow.add{name = "isolated_spawn_vanilla_option_checkbox",
|
||||
-- type = "checkbox",
|
||||
-- caption="Use a pre-set vanilla spawn point. " .. #global.vanillaSpawns .. " available.",
|
||||
-- state=false}
|
||||
-- end
|
||||
|
||||
-- Isolated spawn options. The core gameplay of this scenario.
|
||||
local soloSpawnbuttons = soloSpawnFlow.add{name = "spawn_solo_flow",
|
||||
@ -157,44 +168,59 @@ function DisplaySpawnOptions(player)
|
||||
type = "button",
|
||||
caption="Solo Spawn (Far)",
|
||||
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")
|
||||
|
||||
|
||||
if (ENABLE_VANILLA_SPAWNS) then
|
||||
AddLabel(soloSpawnFlow, "isolated_spawn_lbl1",
|
||||
"You are spawned in your own starting area (vanilla style).", my_label_style)
|
||||
AddLabel(soloSpawnFlow, "vanilla_spawn_lbl2",
|
||||
"There are " .. #global.vanillaSpawns .. " vanilla spawns available.", my_label_style)
|
||||
else
|
||||
AddLabel(soloSpawnFlow, "isolated_spawn_lbl1",
|
||||
"You are spawned in a new area, with pre-set starting resources.", my_label_style)
|
||||
end
|
||||
|
||||
-- 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
|
||||
if ENABLE_SHARED_SPAWNS and ENABLE_BUDDY_SPAWN then
|
||||
AddSpacerLine(sGui, "buddy_spawn_msg_spacer")
|
||||
sGui.add{name = "buddy_spawn",
|
||||
type = "button",
|
||||
caption="Buddy Spawn"}
|
||||
AddLabel(sGui, "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)
|
||||
-- Awesome buddy spawning system
|
||||
if (not ENABLE_VANILLA_SPAWNS) then
|
||||
if ENABLE_SHARED_SPAWNS and ENABLE_BUDDY_SPAWN then
|
||||
local buddySpawnFrame = sGui.add{name = "spawn_buddy_flow",
|
||||
type = "frame",
|
||||
direction="vertical",
|
||||
style = "bordered_frame"}
|
||||
|
||||
-- AddSpacerLine(buddySpawnFrame, "buddy_spawn_msg_spacer")
|
||||
buddySpawnFrame.add{name = "buddy_spawn",
|
||||
type = "button",
|
||||
caption="Buddy Spawn"}
|
||||
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
|
||||
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 +233,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 +255,12 @@ function SpawnOptsRadioSelect(event)
|
||||
event.element.parent.buddy_spawn_new_team_radio.state=false
|
||||
end
|
||||
|
||||
-- ENABLE_VANILLA_SPAWNS
|
||||
-- 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,7 +279,9 @@ function SpawnOptsGuiClick(event)
|
||||
return -- Gui event unrelated to this gui.
|
||||
end
|
||||
|
||||
local joinMainTeamRadio, joinOwnTeamRadio, moatChoice = false
|
||||
local pgcs = player.gui.center.spawn_opts
|
||||
|
||||
local joinMainTeamRadio, joinOwnTeamRadio, moatChoice, vanillaChoice = false
|
||||
|
||||
-- Check if a valid button on the gui was pressed
|
||||
-- and delete the GUI
|
||||
@ -261,18 +294,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
|
||||
if (SPAWN_MOAT_CHOICE_ENABLED and not ENABLE_VANILLA_SPAWNS and
|
||||
(pgcs.spawn_solo_flow.isolated_spawn_moat_option_checkbox ~= nil)) then
|
||||
moatChoice = pgcs.spawn_solo_flow.isolated_spawn_moat_option_checkbox.state
|
||||
end
|
||||
player.gui.center.spawn_opts.destroy()
|
||||
-- if (ENABLE_VANILLA_SPAWNS and
|
||||
-- (pgcs.spawn_solo_flow.isolated_spawn_vanilla_option_checkbox ~= nil)) 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,24 +332,39 @@ 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
|
||||
if (ENABLE_VANILLA_SPAWNS) then
|
||||
if (elemName == "isolated_spawn_far") then
|
||||
newSpawn = FindUnusedVanillaSpawn(game.surfaces[GAME_SURFACE_NAME],
|
||||
FAR_MAX_DIST*CHUNK_SIZE)
|
||||
elseif (elemName == "isolated_spawn_near") then
|
||||
newSpawn = FindUnusedVanillaSpawn(game.surfaces[GAME_SURFACE_NAME],
|
||||
NEAR_MIN_DIST*CHUNK_SIZE)
|
||||
end
|
||||
|
||||
-- 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.
|
||||
if ((newSpawn.x == 0) and (newSpawn.x == 0)) then
|
||||
if ((newSpawn.x == 0) and (newSpawn.y == 0)) then
|
||||
newSpawn = FindMapEdge(GetRandomVector(), player.surface)
|
||||
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)
|
||||
QueuePlayerForDelayedSpawn(player.name, newSpawn, moatChoice, ENABLE_VANILLA_SPAWNS)
|
||||
if (elemName == "isolated_spawn_near") then
|
||||
SendBroadcastMsg(player.name .. " is joining the game from a distance!")
|
||||
elseif (elemName == "isolated_spawn_far") then
|
||||
@ -744,7 +796,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 +1186,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.
|
||||
|
Loading…
x
Reference in New Issue
Block a user