mirror of
https://github.com/Oarcinae/FactorioScenarioMultiplayerSpawn.git
synced 2024-12-12 10:13:58 +02:00
commit
717004cfe5
16
README.md
16
README.md
@ -1,8 +1,7 @@
|
||||
# FactorioScenarioMultiplayerSpawn
|
||||
A custom scenario for allowing separate spawn locations in multiplayer. Designed for Co-op and PvE.
|
||||
|
||||
Only supports 0.15.x at this time!
|
||||
Go to the dev branch for a mostly working 0.16 version: https://github.com/Oarcinae/FactorioScenarioMultiplayerSpawn/tree/dev_0.16
|
||||
0.16 is now stable and well supported!
|
||||
|
||||
## Instructions
|
||||
|
||||
@ -26,8 +25,21 @@ Rename the "FactorioScenarioMultiplayerSpawn" folder to something shorter and mo
|
||||
|
||||
### STEP 3
|
||||
|
||||
#### OPTION 1 (Client Hosted)
|
||||
Start a multiplayer game on your client like normal.
|
||||
|
||||
#### OPTION 2 (Headless)
|
||||
Generate a new map, use that save file to host if you want to.
|
||||
|
||||
#### OPTION 3 (Headless)
|
||||
Place the scenario code in the game's scenario folder, typically something like "..\Factorio\scenarios\FactorioScenarioMultiplayerSpawn\\.."
|
||||
|
||||
Start a new game (generates a random map based on the config in config.lua) from the command line:
|
||||
./factorio --start-server-load-scenario FactorioScenarioMultiplayerSpawn --server-settings my-server-settings.json
|
||||
|
||||
If you want to RESUME from this method, use something like this:
|
||||
./factorio --start-server-load-latest --server-settings my-server-settings.json
|
||||
|
||||
|
||||
## Configuration
|
||||
|
||||
|
218
config.lua
218
config.lua
@ -7,57 +7,54 @@
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Messages
|
||||
-- You will want to change some of these to be your own.
|
||||
-- Make sure SERVER_OWNER_IS_OARC = false
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
-- This stuff is printed in the console. It's probably ignored most of the time.
|
||||
WELCOME_MSG = "[INSERT SERVER OWNER MSG HERE!]"
|
||||
GAME_MODE_MSG = "In the current game mode, a satellite must be launched from an existing far away rocket silo to win!"
|
||||
MODULES_ENABLED = "Mods Enabled: Separate Spawns, RSO, Long-Reach, Autofill, Undecorator, Player List"
|
||||
|
||||
-- This stuff is shown in the welcome GUI. Make sure it's valid.
|
||||
WELCOME_MSG_TITLE = "[INSERT SERVER OWNER MSG HERE!]"
|
||||
WELCOME_MSG1 = "Rules: Be polite. Ask before changing other players's stuff. Have fun!"
|
||||
WELCOME_MSG2 = "This server is running a custom scenario that changes spawn locations."
|
||||
SERVER_MSG = "Rules: Be polite. Ask before changing other players's stuff. Have fun!\n"..
|
||||
"This server is running a custom scenario that changes spawn locations."
|
||||
|
||||
OTHER_MSG1 = "Latest updates in this scenario version (0.5.5):"
|
||||
OTHER_MSG2 = "Regrowth fixes (disabled). Abandoned base removal."
|
||||
-- Optional other messages below:
|
||||
OTHER_MSG3 = "Standard multiplayer spawn allows spawning in far locations."
|
||||
OTHER_MSG4 = "You can be on the main team or your own."
|
||||
OTHER_MSG5 = "If you leave in the first 15 minutes, your base and character will be deleted!"
|
||||
SCENARIO_INFO_MSG = "Latest updates in this scenario version:\n"..
|
||||
"0.16 experimental release. Tweaks to fix spawn issues / text / difficulty.\n"..
|
||||
"This scenario gives you and/or your friends your own starting area.\n"..
|
||||
"You can be on the main team or your own. All teams are friendly.\n"..
|
||||
"If you leave in the first 15 minutes, your base and character will be deleted!"
|
||||
|
||||
SPAWN_WARN_MSG = "Due to the way this scenario works, it may take some time for the land around your new spawn area to generate... Please wait for 10-20 seconds when you select your first spawn."
|
||||
|
||||
WELCOME_MSG3 = "Due to the way this scenario works, it may take some time for the land"
|
||||
WELCOME_MSG4 = "around your new spawn area to generate..."
|
||||
WELCOME_MSG5 = "Please wait for 10-20 seconds when you select your first spawn."
|
||||
WELCOME_MSG6 = "Contact: SteamID:Oarc | oarcinae@gmail.com"
|
||||
CONTACT_MSG = "Contact: SteamID:Oarc | oarcinae@gmail.com | discord.gg/TPYxRrS"
|
||||
|
||||
SPAWN_MSG1 = "Current Spawn Mode: WILDERNESS"
|
||||
SPAWN_MSG2 = "In this mode, there is no default spawn. Everyone starts in the wild!"
|
||||
SPAWN_MSG3 = "Resources are spread out far apart but are quite rich."
|
||||
|
||||
-- These are my specific welcome messages that get used only if I am the user
|
||||
-- that creates the game.
|
||||
SERVER_OWNER_IS_OARC = true -- This should be false for you, it's just a convenience for me.
|
||||
WELCOME_MSG_OARC = "Welcome to Oarc's official server! Join the discord here: discord.gg/TPYxRrS"
|
||||
WELCOME_MSG_TITLE_OARC = "Welcome to Oarc's Server!"
|
||||
-- This should be false for you, it's just a convenience for me.
|
||||
SERVER_OWNER_IS_OARC = false
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Module Enables
|
||||
-- These enables are not fully tested! For example, disable separate spawns
|
||||
-- These enables are not fully tested! For example, disabling separate spawns
|
||||
-- will probably break the frontier rocket silo mode
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
-- Frontier style rocket silo mode
|
||||
FRONTIER_ROCKET_SILO_MODE = true
|
||||
|
||||
-- Separate spawns
|
||||
-- This is the core of the mod. Probably not a good idea to disable it.
|
||||
ENABLE_SEPARATE_SPAWNS = true
|
||||
|
||||
-- Enable Scenario version of RSO
|
||||
-- You can reconfigure the RSO resource settings in the RSO files if you want to
|
||||
-- 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
|
||||
|
||||
-- RSO soft-mod (included in the scenario)
|
||||
ENABLE_RSO = true
|
||||
|
||||
-- Frontier style rocket silo mode
|
||||
FRONTIER_ROCKET_SILO_MODE = true
|
||||
|
||||
-- Enable Undecorator
|
||||
-- Removes decorative items to reduce save file size.
|
||||
ENABLE_UNDECORATOR = true
|
||||
@ -73,23 +70,26 @@ ENABLE_AUTOFILL = true
|
||||
|
||||
-- Enable Playerlist
|
||||
ENABLE_PLAYER_LIST = true
|
||||
PLAYER_LIST_OFFLINE_PLAYERS = true -- List offline players as well.
|
||||
|
||||
-- Enable Gravestone Chests
|
||||
ENABLE_GRAVESTONE_ON_DEATH = false
|
||||
|
||||
-- Items dumped into chest when you leave.
|
||||
-- Items dumped into chest when you leave.
|
||||
ENABLE_GRAVESTONE_ON_LEAVING = false
|
||||
-- If anyone leaves within first X minutes, items get dumped into chest.
|
||||
-- If anyone leaves within first X minutes, items get dumped into chest.
|
||||
ENABLE_GRAVESTONE_ON_LEAVING_TIME_MINS = 15
|
||||
|
||||
-- Enable quick start items
|
||||
ENABLE_POWER_ARMOR_QUICK_START = false
|
||||
|
||||
-- Enable shared vision between teams (all teams are still COOP)
|
||||
-- Enable shared vision between teams (all teams are COOP regardless)
|
||||
ENABLE_SHARED_TEAM_VISION = true
|
||||
|
||||
-- Enable map regrowth, see regrowth_map.lua for more info.
|
||||
-- I'm not a fan of this anymore, but it helps keep the map size down
|
||||
ENABLE_REGROWTH = false
|
||||
|
||||
-- If you have regrowth enabled, this should also be enabled.
|
||||
-- It removes bases for players that join and leave the game quickly.
|
||||
-- This can also be used without enabling regrowth.
|
||||
@ -102,7 +102,7 @@ ENABLE_ABANDONED_BASE_REMOVAL = true
|
||||
---------------------------------------
|
||||
-- Starting Items
|
||||
---------------------------------------
|
||||
-- Items provided to the player the first time they join ("quick start" commented out)
|
||||
-- Items provided to the player the first time they join
|
||||
PLAYER_SPAWN_START_ITEMS = {
|
||||
{name="pistol", count=1},
|
||||
{name="firearm-magazine", count=100},
|
||||
@ -140,23 +140,31 @@ PLAYER_RESPAWN_START_ITEMS = {
|
||||
CHECK_SPAWN_UNGENERATED_CHUNKS_RADIUS = 5
|
||||
|
||||
-- Near Distance in chunks
|
||||
NEAR_MIN_DIST = 25 --50
|
||||
NEAR_MAX_DIST = 100 --125
|
||||
--
|
||||
NEAR_MIN_DIST = 0
|
||||
NEAR_MAX_DIST = 50
|
||||
|
||||
-- Far Distance in chunks
|
||||
FAR_MIN_DIST = 200 --50
|
||||
FAR_MAX_DIST = 300 --125
|
||||
FAR_MIN_DIST = 200
|
||||
FAR_MAX_DIST = 300
|
||||
|
||||
---------------------------------------
|
||||
-- Resource & Spawn Circle Options
|
||||
---------------------------------------
|
||||
|
||||
-- Enable this to have a vanilla style starting spawn for all new spawns.
|
||||
-- This scenario normally gives you a fixed circle with resources.
|
||||
-- USE_VANILLA_STARTING_SPAWN = true
|
||||
-- TODO - Requires pre-allocating spawns...
|
||||
|
||||
-- Allow players to choose to spawn with a moat
|
||||
SPAWN_MOAT_CHOICE_ENABLED = true
|
||||
-- If you change the spawn area size, you might have to adjust this as well
|
||||
MOAT_SIZE_MODIFIER = 1
|
||||
|
||||
-- THIS IS WHAT SETS THE SPAWN CIRCLE SIZE!
|
||||
-- Create a circle of land area for the spawn
|
||||
-- This is the radius (I think?) in TILES.
|
||||
ENFORCE_LAND_AREA_TILE_DIST = 48
|
||||
-- If you make this much bigger than a few chunks, good luck.
|
||||
ENFORCE_LAND_AREA_TILE_DIST = CHUNK_SIZE*1.8
|
||||
|
||||
-- Location of water strip (horizontal)
|
||||
WATER_SPAWN_OFFSET_X = -4
|
||||
@ -199,10 +207,14 @@ START_RESOURCE_URANIUM_POS_Y = -34
|
||||
START_RESOURCE_URANIUM_SIZE = 0 -- Disabled by default.
|
||||
|
||||
-- Specify 2 oil spot locations for starting oil.
|
||||
START_RESOURCE_OIL_A_POS_X = -39
|
||||
START_RESOURCE_OIL_A_POS_Y = -2
|
||||
START_RESOURCE_OIL_B_POS_X = -39
|
||||
START_RESOURCE_OIL_B_POS_Y = 2
|
||||
START_RESOURCE_OIL_NUM_PATCHES = 2
|
||||
-- The first patch
|
||||
START_RESOURCE_OIL_POS_X = -39
|
||||
START_RESOURCE_OIL_POS_Y = -2
|
||||
-- How far each patch is offset from the others and in which direction
|
||||
-- Default (x=0, y=-4) means that patches spawn in a vertical row downwards.
|
||||
START_RESOURCE_OIL_X_OFFSET = 0
|
||||
START_RESOURCE_OIL_Y_OFFSET = -4
|
||||
|
||||
|
||||
-- Force the land area circle at the spawn to be fully grass
|
||||
@ -212,6 +224,7 @@ ENABLE_SPAWN_FORCE_GRASS = true
|
||||
SPAWN_TREE_CIRCLE_ENABLED = true
|
||||
|
||||
-- Set this to true for the spawn area to be surrounded by an octagon of trees
|
||||
-- I don't recommend using this with moatsm
|
||||
SPAWN_TREE_OCTAGON_ENABLED = true
|
||||
|
||||
---------------------------------------
|
||||
@ -220,14 +233,14 @@ SPAWN_TREE_OCTAGON_ENABLED = true
|
||||
|
||||
-- Safe area has no aliens
|
||||
-- +/- this in x and y direction
|
||||
SAFE_AREA_TILE_DIST = CHUNK_SIZE*12
|
||||
SAFE_AREA_TILE_DIST = CHUNK_SIZE*5
|
||||
|
||||
-- Warning area has reduced aliens
|
||||
-- +/- this in x and y direction
|
||||
WARNING_AREA_TILE_DIST = CHUNK_SIZE*20
|
||||
WARNING_AREA_TILE_DIST = CHUNK_SIZE*10
|
||||
|
||||
-- 1 : X (spawners alive : spawners destroyed) in this area
|
||||
WARN_AREA_REDUCTION_RATIO = 15
|
||||
WARN_AREA_REDUCTION_RATIO = 10
|
||||
|
||||
|
||||
---------------------------------------
|
||||
@ -243,11 +256,12 @@ ENABLE_SEPARATE_TEAMS = true
|
||||
MAIN_FORCE = "Main Force"
|
||||
|
||||
-- Enable if people can spawn at the main base
|
||||
ENABLE_DEFAULT_SPAWN = false
|
||||
-- THIS CURRENTLY IS BROKEN! YOU WILL NOT GET ANY RESOURCES IF YOU USE RSO!
|
||||
ENABLE_DEFAULT_SPAWN = false -- DON'T USE THIS
|
||||
|
||||
-- Enable if people can allow others to join their base
|
||||
ENABLE_SHARED_SPAWNS = true
|
||||
MAX_ONLINE_PLAYERS_AT_SHARED_SPAWN = 3
|
||||
MAX_ONLINE_PLAYERS_AT_SHARED_SPAWN = 0
|
||||
|
||||
-- Share local team chat with all teams
|
||||
-- This makes it so you don't have to use /s
|
||||
@ -257,7 +271,7 @@ ENABLE_SHARED_TEAM_CHAT = true
|
||||
---------------------------------------
|
||||
-- Special Action Cooldowns
|
||||
---------------------------------------
|
||||
RESPAWN_COOLDOWN_IN_MINUTES = 60
|
||||
RESPAWN_COOLDOWN_IN_MINUTES = 15
|
||||
RESPAWN_COOLDOWN_TICKS = TICKS_PER_MINUTE * RESPAWN_COOLDOWN_IN_MINUTES
|
||||
|
||||
-- Require playes to be online for at least 5 minutes
|
||||
@ -270,33 +284,47 @@ MIN_ONLINE_TIME = TICKS_PER_MINUTE * MIN_ONLINE_TIME_IN_MINUTES
|
||||
-- Alien Options
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
-- Enable/Disable enemy expansion (Applies to RSO as well!)
|
||||
ENEMY_EXPANSION = false
|
||||
-- Enable/Disable enemy expansion
|
||||
ENEMY_EXPANSION = true
|
||||
|
||||
-- Divide the alien factors by this number to reduce it (or multiply if < 1)
|
||||
-- Divide the alien evolution factors by this number to reduce it (or multiply if < 1)
|
||||
ENEMY_TIME_FACTOR_DISABLE = false -- Set this to true to disable time based evolution completely.
|
||||
ENEMY_TIME_FACTOR_DIVISOR = 10
|
||||
ENEMY_POLLUTION_FACTOR_DISABLE = false -- Set this to true to disable pollution based evolution completely.
|
||||
ENEMY_POLLUTION_FACTOR_DIVISOR = 10
|
||||
ENEMY_DESTROY_FACTOR_DIVISOR = 10
|
||||
|
||||
ENEMY_DESTROY_FACTOR_DISABLE = false -- Set this to true to disable spawner destruction based evolution completely.
|
||||
ENEMY_DESTROY_FACTOR_DIVISOR = 1
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Frontier Rocket Silo Options
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
SILO_CHUNK_DISTANCE_X = 15
|
||||
SILO_DISTANCE_X = SILO_CHUNK_DISTANCE_X*CHUNK_SIZE + CHUNK_SIZE/2
|
||||
SILO_DISTANCE_Y = 16
|
||||
-- Number of silos found in the wild.
|
||||
-- These will spawn in a circle at given distance from the center of the map
|
||||
-- If you set this number too high, you'll have a lot of delay at the start of the game.
|
||||
SILO_NUM_SPAWNS = 3
|
||||
|
||||
-- Should be in the middle of a chunk
|
||||
SILO_POSITION = {x = SILO_DISTANCE_X, y = SILO_DISTANCE_Y}
|
||||
-- How many chunks away from the center of the map should the silo be spawned
|
||||
SILO_CHUNK_DISTANCE = 200
|
||||
|
||||
-- If this is enabled, the static position is ignored.
|
||||
ENABLE_RANDOM_SILO_POSITION = true
|
||||
-- If this is enabled, you get ONE silo at the location specified below.
|
||||
SILO_FIXED_POSITION = false
|
||||
|
||||
-- If you want to set a fixed spawn location for a single silo
|
||||
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)
|
||||
ENABLE_SILO_BEACONS = false
|
||||
ENABLE_SILO_RADAR = false
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Long Reach Options
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
BUILD_DIST_BONUS = 20
|
||||
BUILD_DIST_BONUS = 64
|
||||
REACH_DIST_BONUS = BUILD_DIST_BONUS
|
||||
RESOURCE_DIST_BONUS = 2
|
||||
|
||||
@ -307,19 +335,71 @@ RESOURCE_DIST_BONUS = 2
|
||||
AUTOFILL_TURRET_AMMO_QUANTITY = 10
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Use rso_config and rso_resource_config for RSO config settings
|
||||
-- RSO Soft-Mod Configurations
|
||||
-- Configure these to tweak the RSO values.
|
||||
--------------------------------------------------------------------------------
|
||||
-- Don't touch unless you know what you're doing...
|
||||
-- When using RSO, all resources MUST BE SET TO SIZE=NONE!
|
||||
-- CONFIGURE STUFF INSIDE rso_config.lua
|
||||
-- RSO resources can be very lucky/unlucky...
|
||||
-- don't complain if you can't find a resource.
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
MAP_SETTINGS_RSO_TERRAIN_SEGMENTATION = "very-low" -- Frequency of water
|
||||
MAP_SETTINGS_RSO_WATER = "high" -- Size of water patches
|
||||
MAP_SETTINGS_RSO_PEACEFUL = false -- Peaceful mode for biters/aliens
|
||||
MAP_SETTINGS_RSO_STARTING_AREA = "very-low" -- Does not affect Oarc spawn sizes.
|
||||
-- MAP CONFIGURATION OPTIONS
|
||||
-- Configure these if you are running headless since there is no way to set
|
||||
-- resources otherwise.
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
-- Set this to true if you are creating the scenario at the cmd line.
|
||||
CMD_LINE_MAP_GEN = true
|
||||
|
||||
-- Adjust settings here to set your map stuff.
|
||||
-- "Sizes can be specified as none, very-low, low, normal, high, very-high"
|
||||
global.clMapGen = {}
|
||||
global.clMapGen.terrain_segmentation="normal"
|
||||
global.clMapGen.water="normal"
|
||||
global.clMapGen.starting_area="low"
|
||||
global.clMapGen.peaceful_mode=false
|
||||
global.clMapGen.seed=nil;
|
||||
-- These are my go to default vanilla settings, it's not RSO, but it's okay.
|
||||
global.clMapGen.autoplace_controls = {
|
||||
|
||||
-- Resources and enemies only matter if you are NOT using RSO.
|
||||
["coal"]={frequency="very-low", size= "low", richness= "high"},
|
||||
["copper-ore"]={frequency= "very-low", size= "low", richness= "high"},
|
||||
["crude-oil"]={frequency= "low", size= "low", richness= "high"},
|
||||
["enemy-base"]={frequency= "low", size= "normal", richness= "normal"},
|
||||
["iron-ore"]={frequency= "very-low", size= "low", richness= "high"},
|
||||
["stone"]={frequency= "very-low", size= "low", richness= "high"},
|
||||
["uranium-ore"]={frequency= "low", size= "low", richness= "high"},
|
||||
|
||||
["desert"]={frequency= "low", size= "low", richness= "low"},
|
||||
["dirt"]={frequency= "low", size= "low", richness= "low"},
|
||||
["grass"]={frequency= "normal", size= "normal", richness= "normal"},
|
||||
["sand"]={frequency= "low", size= "low", richness= "low"},
|
||||
["trees"]={frequency= "normal", size= "normal", richness= "normal"}
|
||||
}
|
||||
-- Cliff defaults are 10 and 10, set both to 0 to turn cliffs off I think?
|
||||
global.clMapGen.cliff_settings={cliff_elevation_0=10, cliff_elevation_interval=10, name="cliff"}
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- ANTI-Griefing stuff ( I don't personally maintain this as I don't care for it.)
|
||||
-- These things were added from other people's requests/changes and are disabled by default.
|
||||
--------------------------------------------------------------------------------
|
||||
-- Enable this to disable some basic things like friendly fire, deconstructing from map view, etc.
|
||||
ENABLE_ANTI_GRIEFING = false
|
||||
|
||||
-- Makes blueprint ghosts dissapear if they have been placed longer than this
|
||||
GHOST_TIME_TO_LIVE = 0 * TICKS_PER_MINUTE -- set to 0 for infinite ghost life
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- DEBUG
|
||||
-- DEBUG / Custom stuff
|
||||
--------------------------------------------------------------------------------
|
||||
OARC_DIFFICULTY_CUSTOM = false
|
||||
|
||||
-- DEBUG prints for me
|
||||
global.oarcDebugEnabled = false
|
||||
|
||||
-- These are my specific welcome messages that get used only if I am the user
|
||||
-- that creates the game.
|
||||
WELCOME_MSG_OARC = "Welcome to Oarc's official server! Join the discord here: discord.gg/TPYxRrS"
|
||||
WELCOME_MSG_TITLE_OARC = "Welcome to Oarc's Server!"
|
||||
|
94
control.lua
94
control.lua
@ -27,6 +27,12 @@ require("locale/oarc_utils")
|
||||
require("locale/rso/rso_control")
|
||||
require("locale/frontier_silo")
|
||||
require("locale/tag")
|
||||
require("locale/game_opts")
|
||||
|
||||
-- For Philip. I currently do not use this and need to add proper support for
|
||||
-- commands like this in the future.
|
||||
require("locale/temp/rgcommand")
|
||||
require("locale/temp/helper_commands")
|
||||
|
||||
-- Main Configuration File
|
||||
require("config")
|
||||
@ -86,15 +92,13 @@ script.on_init(function(event)
|
||||
|
||||
-- CreateLobbySurface() -- Currently unused, but have plans for future.
|
||||
|
||||
-- Configures the map settings for enemies
|
||||
-- This controls evolution growth factors and enemy expansion settings.
|
||||
ConfigureAlienStartingParams()
|
||||
|
||||
-- Here I create the game surface. I do this so that I don't have to worry
|
||||
-- about the game menu settings and I can now generate a map from the command
|
||||
-- line more easily!
|
||||
--
|
||||
-- If you are using RSO, map settings are ignored and you MUST configure
|
||||
-- the relevant map settings in config.lua
|
||||
--
|
||||
-- If you disable RSO, the map settings will be set from the ones that you
|
||||
-- choose from the game GUI when you start a new scenario.
|
||||
if ENABLE_RSO then
|
||||
CreateGameSurface(RSO_MODE)
|
||||
else
|
||||
@ -105,36 +109,22 @@ script.on_init(function(event)
|
||||
InitSpawnGlobalsAndForces()
|
||||
end
|
||||
|
||||
if ENABLE_RANDOM_SILO_POSITION then
|
||||
SetRandomSiloPosition()
|
||||
if SILO_FIXED_POSITION then
|
||||
SetFixedSiloPosition(SILO_POSITION)
|
||||
else
|
||||
SetFixedSiloPosition()
|
||||
SetRandomSiloPosition(SILO_NUM_SPAWNS)
|
||||
end
|
||||
|
||||
if FRONTIER_ROCKET_SILO_MODE then
|
||||
ChartRocketSiloArea(game.forces[MAIN_FORCE], game.surfaces[GAME_SURFACE_NAME])
|
||||
GenerateRocketSiloAreas(game.surfaces[GAME_SURFACE_NAME])
|
||||
end
|
||||
|
||||
-- Configures the map settings for enemies
|
||||
-- This controls evolution growth factors and enemy expansion settings.
|
||||
ConfigureAlienStartingParams()
|
||||
|
||||
SetServerWelcomeMessages()
|
||||
|
||||
if ENABLE_REGROWTH or ENABLE_ABANDONED_BASE_REMOVAL then
|
||||
OarcRegrowthInit()
|
||||
end
|
||||
|
||||
--If any (not global.) globals are written to at this point, an error will be thrown.
|
||||
--eg, x = 2 will throw an error because it's not global.x
|
||||
-- setmetatable(_G, {
|
||||
-- __newindex = function(_, n)
|
||||
-- log("Attempt to write to undeclared var " .. n)
|
||||
-- game.print("Attempt to write to undeclared var " .. n)
|
||||
-- end
|
||||
-- })
|
||||
-- -- THIS REQUIRES A LOT OF CHANGES TO RSO SOFT MOD...
|
||||
|
||||
end)
|
||||
|
||||
|
||||
@ -169,12 +159,13 @@ script.on_event(defines.events.on_chunk_generated, function(event)
|
||||
GenerateRocketSiloChunk(event)
|
||||
end
|
||||
|
||||
-- This MUST come after RSO generation!
|
||||
if ENABLE_SEPARATE_SPAWNS then
|
||||
if ENABLE_SEPARATE_SPAWNS and not USE_VANILLA_STARTING_SPAWN then
|
||||
SeparateSpawnsGenerateChunk(event)
|
||||
end
|
||||
|
||||
CreateHoldingPenGenerateChunk(event)
|
||||
if not ENABLE_DEFAULT_SPAWN then
|
||||
CreateHoldingPen(event.surface, event.area, 16, false)
|
||||
end
|
||||
end)
|
||||
|
||||
|
||||
@ -195,8 +186,21 @@ script.on_event(defines.events.on_gui_click, function(event)
|
||||
SpawnOptsGuiClick(event)
|
||||
SpawnCtrlGuiClick(event)
|
||||
SharedSpwnOptsGuiClick(event)
|
||||
BuddySpawnOptsGuiClick(event)
|
||||
BuddySpawnWaitMenuClick(event)
|
||||
BuddySpawnRequestMenuClick(event)
|
||||
SharedSpawnJoinWaitMenuClick(event)
|
||||
end
|
||||
|
||||
GameOptionsGuiClick(event)
|
||||
|
||||
end)
|
||||
|
||||
script.on_event(defines.events.on_gui_checked_state_changed, function (event)
|
||||
if ENABLE_SEPARATE_SPAWNS then
|
||||
SpawnOptsRadioSelect(event)
|
||||
SpawnCtrlGuiOptionsSelect(event)
|
||||
end
|
||||
end)
|
||||
|
||||
|
||||
@ -205,15 +209,18 @@ end)
|
||||
----------------------------------------
|
||||
script.on_event(defines.events.on_player_joined_game, function(event)
|
||||
|
||||
CreateGameOptionsGui(event)
|
||||
|
||||
PlayerJoinedMessages(event)
|
||||
|
||||
if ENABLE_PLAYER_LIST then
|
||||
CreatePlayerListGui(event)
|
||||
end
|
||||
|
||||
if ENABLE_TAGS then
|
||||
CreateTagGui(event)
|
||||
end
|
||||
|
||||
if ENABLE_PLAYER_LIST then
|
||||
CreatePlayerListGui(event)
|
||||
end
|
||||
end)
|
||||
|
||||
script.on_event(defines.events.on_player_created, function(event)
|
||||
@ -272,6 +279,10 @@ script.on_event(defines.events.on_built_entity, function(event)
|
||||
if ENABLE_REGROWTH then
|
||||
OarcRegrowthOffLimitsChunk(event.created_entity.position)
|
||||
end
|
||||
|
||||
if ENABLE_ANTI_GRIEFING then
|
||||
SetItemBlueprintTimeToLive(event)
|
||||
end
|
||||
end)
|
||||
|
||||
|
||||
@ -279,11 +290,6 @@ end)
|
||||
-- Shared vision, charts a small area around other players
|
||||
----------------------------------------
|
||||
script.on_event(defines.events.on_tick, function(event)
|
||||
-- Every few seconds, chart all players to "share vision"
|
||||
if ENABLE_SHARED_TEAM_VISION then
|
||||
ShareVisionBetweenPlayers()
|
||||
end
|
||||
|
||||
if ENABLE_REGROWTH then
|
||||
OarcRegrowthOnTick()
|
||||
end
|
||||
@ -292,6 +298,21 @@ script.on_event(defines.events.on_tick, function(event)
|
||||
OarcRegrowthForceRemovalOnTick()
|
||||
end
|
||||
|
||||
if ENABLE_SEPARATE_SPAWNS then
|
||||
DelayedSpawnOnTick()
|
||||
end
|
||||
|
||||
if FRONTIER_ROCKET_SILO_MODE then
|
||||
DelayedSiloCreationOnTick()
|
||||
end
|
||||
|
||||
end)
|
||||
|
||||
|
||||
script.on_event(defines.events.on_sector_scanned, function (event)
|
||||
if ENABLE_REGROWTH then
|
||||
OarcRegrowthSectorScan(event)
|
||||
end
|
||||
end)
|
||||
|
||||
----------------------------------------
|
||||
@ -300,9 +321,6 @@ end)
|
||||
-- built stuff as permanent.
|
||||
----------------------------------------
|
||||
if ENABLE_REGROWTH then
|
||||
script.on_event(defines.events.on_sector_scanned, function (event)
|
||||
OarcRegrowthSectorScan(event)
|
||||
end)
|
||||
|
||||
script.on_event(defines.events.on_robot_built_entity, function (event)
|
||||
OarcRegrowthOffLimitsChunk(event.created_entity.position)
|
||||
|
@ -1,79 +1,318 @@
|
||||
-- frontier_silo.lua
|
||||
-- Nov 2016
|
||||
-- Jan 2018
|
||||
-- My take on frontier silos for my Oarc scenario
|
||||
|
||||
require("config")
|
||||
require("locale/oarc_utils")
|
||||
|
||||
-- Create a rocket silo
|
||||
local function CreateRocketSilo(surface, chunkArea, force)
|
||||
if CheckIfInArea(global.siloPosition, chunkArea) then
|
||||
--------------------------------------------------------------------------------
|
||||
-- Frontier style rocket silo stuff
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
-- Delete any entities beneat the silo?
|
||||
for _, entity in pairs(surface.find_entities_filtered{area = {{global.siloPosition.x-5, global.siloPosition.y-6},{global.siloPosition.x+6, global.siloPosition.y+6}}}) do
|
||||
entity.destroy()
|
||||
end
|
||||
-- This creates a random silo position, stored to global.siloPosition
|
||||
-- It uses the config setting SILO_CHUNK_DISTANCE and spawns the silo somewhere
|
||||
-- on a circle edge with radius using that distance.
|
||||
function SetRandomSiloPosition(num_silos)
|
||||
if (global.siloPosition == nil) then
|
||||
|
||||
-- Set tiles below the silo
|
||||
local tiles = {}
|
||||
local i = 1
|
||||
for dx = -6,6 do
|
||||
for dy = -7,6 do
|
||||
tiles[i] = {name = "grass", position = {global.siloPosition.x+dx, global.siloPosition.y+dy}}
|
||||
i=i+1
|
||||
end
|
||||
end
|
||||
surface.set_tiles(tiles, false)
|
||||
tiles = {}
|
||||
i = 1
|
||||
for dx = -5,5 do
|
||||
for dy = -6,5 do
|
||||
tiles[i] = {name = "concrete", position = {global.siloPosition.x+dx, global.siloPosition.y+dy}}
|
||||
i=i+1
|
||||
end
|
||||
end
|
||||
surface.set_tiles(tiles, true)
|
||||
global.siloPosition = {}
|
||||
|
||||
-- Create silo and assign to a force
|
||||
local silo = surface.create_entity{name = "rocket-silo", position = {global.siloPosition.x+0.5, global.siloPosition.y}, force = force}
|
||||
silo.destructible = false
|
||||
silo.minable = false
|
||||
random_angle_offset = math.random(0, math.pi * 2)
|
||||
|
||||
-- Make silo safe from being removed.
|
||||
if ENABLE_REGROWTH then
|
||||
OarcRegrowthOffLimits(global.siloPosition, 5)
|
||||
for i=1,num_silos do
|
||||
theta = ((math.pi * 2) / num_silos);
|
||||
angle = (theta * i) + random_angle_offset;
|
||||
|
||||
tx = (SILO_CHUNK_DISTANCE*CHUNK_SIZE * math.cos(angle))
|
||||
ty = (SILO_CHUNK_DISTANCE*CHUNK_SIZE * math.sin(angle))
|
||||
|
||||
table.insert(global.siloPosition, {x=math.floor(tx), y=math.floor(ty)})
|
||||
|
||||
log("Silo position: " .. tx .. ", " .. ty .. ", " .. angle)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Generates the rocket silo during chunk generation event
|
||||
-- Sets the global.siloPosition var to the set in the config file
|
||||
function SetFixedSiloPosition(pos)
|
||||
if (global.siloPosition == nil) then
|
||||
global.siloPosition = {}
|
||||
table.insert(global.siloPosition, SILO_POSITION)
|
||||
end
|
||||
end
|
||||
|
||||
-- Create a rocket silo at the specified positionmmmm
|
||||
-- Also makes sure tiles and entities are cleared if required.
|
||||
local function CreateRocketSilo(surface, siloPosition, force)
|
||||
|
||||
-- Delete any entities beneath the silo?
|
||||
for _, entity in pairs(surface.find_entities_filtered{area = {{siloPosition.x-5,
|
||||
siloPosition.y-6},
|
||||
{siloPosition.x+6,
|
||||
siloPosition.y+6}}}) do
|
||||
entity.destroy()
|
||||
end
|
||||
|
||||
-- Remove nearby enemies again
|
||||
for _, entity in pairs(surface.find_entities_filtered{area = {{siloPosition.x-(CHUNK_SIZE*4),
|
||||
siloPosition.y-(CHUNK_SIZE*4)},
|
||||
{siloPosition.x+(CHUNK_SIZE*4),
|
||||
siloPosition.y+(CHUNK_SIZE*4)}}, force = "enemy"}) do
|
||||
entity.destroy()
|
||||
end
|
||||
|
||||
-- Set tiles below the silo
|
||||
tiles = {}
|
||||
i = 1
|
||||
for dx = -5,5 do
|
||||
for dy = -6,5 do
|
||||
tiles[i] = {name = "concrete", position = {siloPosition.x+dx, siloPosition.y+dy}}
|
||||
i=i+1
|
||||
end
|
||||
end
|
||||
surface.set_tiles(tiles, true)
|
||||
|
||||
-- Create indestructible silo and assign to a force
|
||||
local silo = surface.create_entity{name = "rocket-silo", position = {siloPosition.x+0.5, siloPosition.y}, force = force}
|
||||
silo.destructible = false
|
||||
silo.minable = false
|
||||
|
||||
-- Make silo safe from being removed by regrowth
|
||||
if ENABLE_REGROWTH then
|
||||
OarcRegrowthOffLimits(siloPosition, 5)
|
||||
end
|
||||
|
||||
|
||||
if ENABLE_SILO_BEACONS then
|
||||
PhilipsBeaconsAndShit(surface, siloPosition, game.forces[MAIN_FORCE])
|
||||
end
|
||||
if ENABLE_SILO_RADAR then
|
||||
PhilipsRadarAndShit(surface, siloPosition, game.forces[MAIN_FORCE])
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
-- Generates all rocket silos, should be called after the areas are generated
|
||||
-- Includes a crop circle
|
||||
function GenerateRocketSiloChunk(event)
|
||||
local surface = event.surface
|
||||
local chunkArea = event.area
|
||||
|
||||
local chunkAreaCenter = {x=chunkArea.left_top.x+(CHUNK_SIZE/2),
|
||||
y=chunkArea.left_top.y+(CHUNK_SIZE/2)}
|
||||
local safeArea = {left_top=
|
||||
{x=global.siloPosition.x-150,
|
||||
y=global.siloPosition.y-150},
|
||||
right_bottom=
|
||||
{x=global.siloPosition.x+150,
|
||||
y=global.siloPosition.y+150}}
|
||||
|
||||
|
||||
-- Clear enemies directly next to the rocket
|
||||
if CheckIfInArea(chunkAreaCenter,safeArea) then
|
||||
for _, entity in pairs(surface.find_entities_filtered{area = chunkArea, force = "enemy"}) do
|
||||
entity.destroy()
|
||||
end
|
||||
function GenerateAllSilos(surface)
|
||||
|
||||
-- Create each silo in the list
|
||||
for idx,siloPos in pairs(global.siloPosition) do
|
||||
CreateRocketSilo(surface, siloPos, MAIN_FORCE)
|
||||
end
|
||||
|
||||
-- Create rocket silo
|
||||
CreateRocketSilo(surface, chunkArea, MAIN_FORCE)
|
||||
CreateCropCircle(surface, global.siloPosition, chunkArea, 40)
|
||||
|
||||
end
|
||||
|
||||
function ChartRocketSiloArea(force, surface)
|
||||
force.chart(surface, {{global.siloPosition.x-(CHUNK_SIZE*2), global.siloPosition.y-(CHUNK_SIZE*2)}, {global.siloPosition.x+(CHUNK_SIZE*2), global.siloPosition.y+(CHUNK_SIZE*2)}})
|
||||
-- Generate clean land and trees around silo area on chunk generate event
|
||||
function GenerateRocketSiloChunk(event)
|
||||
|
||||
-- Silo generation can take awhile depending on the number of silos.
|
||||
if (game.tick < SILO_NUM_SPAWNS*10*TICKS_PER_SECOND) then
|
||||
local surface = event.surface
|
||||
local chunkArea = event.area
|
||||
|
||||
local chunkAreaCenter = {x=chunkArea.left_top.x+(CHUNK_SIZE/2),
|
||||
y=chunkArea.left_top.y+(CHUNK_SIZE/2)}
|
||||
|
||||
for idx,siloPos in pairs(global.siloPosition) do
|
||||
local safeArea = {left_top=
|
||||
{x=siloPos.x-(CHUNK_SIZE*4),
|
||||
y=siloPos.y-(CHUNK_SIZE*4)},
|
||||
right_bottom=
|
||||
{x=siloPos.x+(CHUNK_SIZE*4),
|
||||
y=siloPos.y+(CHUNK_SIZE*4)}}
|
||||
|
||||
|
||||
-- Clear enemies directly next to the rocket
|
||||
if CheckIfInArea(chunkAreaCenter,safeArea) then
|
||||
for _, entity in pairs(surface.find_entities_filtered{area = chunkArea, force = "enemy"}) do
|
||||
entity.destroy()
|
||||
end
|
||||
|
||||
-- Remove trees/resources inside the spawn area
|
||||
RemoveInCircle(surface, chunkArea, "tree", siloPos, ENFORCE_LAND_AREA_TILE_DIST+5)
|
||||
RemoveInCircle(surface, chunkArea, "resource", siloPos, ENFORCE_LAND_AREA_TILE_DIST+5)
|
||||
RemoveInCircle(surface, chunkArea, "cliff", siloPos, ENFORCE_LAND_AREA_TILE_DIST+5)
|
||||
RemoveDecorationsArea(surface, chunkArea)
|
||||
|
||||
-- Create rocket silo
|
||||
CreateCropOctagon(surface, siloPos, chunkArea, CHUNK_SIZE*2)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Generate chunks where we plan to place the rocket silos.
|
||||
function GenerateRocketSiloAreas(surface)
|
||||
for idx,siloPos in pairs(global.siloPosition) do
|
||||
if (ENABLE_SILO_VISION) then
|
||||
ChartRocketSiloAreas(surface, game.forces[MAIN_FORCE])
|
||||
end
|
||||
surface.request_to_generate_chunks({siloPos.x, siloPos.y}, 3)
|
||||
end
|
||||
end
|
||||
|
||||
-- Chart chunks where we plan to place the rocket silos.
|
||||
function ChartRocketSiloAreas(surface, force)
|
||||
for idx,siloPos in pairs(global.siloPosition) do
|
||||
force.chart(surface, {{siloPos.x-(CHUNK_SIZE*2),
|
||||
siloPos.y-(CHUNK_SIZE*2)},
|
||||
{siloPos.x+(CHUNK_SIZE*2),
|
||||
siloPos.y+(CHUNK_SIZE*2)}})
|
||||
end
|
||||
end
|
||||
|
||||
global.oarc_silos_generated = false
|
||||
function DelayedSiloCreationOnTick(event)
|
||||
|
||||
-- Delay the creation of the silos so we place them on already generated lands.
|
||||
if (not global.oarc_silos_generated and (game.tick >= SILO_NUM_SPAWNS*10*TICKS_PER_SECOND)) then
|
||||
DebugPrint("Frontier silos generated!")
|
||||
global.oarc_silos_generated = true
|
||||
GenerateAllSilos(game.surfaces[GAME_SURFACE_NAME])
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
function PhilipsBeaconsAndShit(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}
|
||||
beacon.destructible = false
|
||||
beacon.minable = false
|
||||
-- top 2
|
||||
local beacon = surface.create_entity{name = "beacon", position = {siloPos.x-5, siloPos.y-9}, 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}
|
||||
beacon.destructible = false
|
||||
beacon.minable = false
|
||||
-- top 4
|
||||
local beacon = surface.create_entity{name = "beacon", position = {siloPos.x+2, siloPos.y-9}, 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}
|
||||
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}
|
||||
beacon.destructible = false
|
||||
beacon.minable = false
|
||||
-- left 2
|
||||
local beacon = surface.create_entity{name = "beacon", position = {siloPos.x-6, siloPos.y-6}, 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}
|
||||
beacon.destructible = false
|
||||
beacon.minable = false
|
||||
-- left 4
|
||||
local beacon = surface.create_entity{name = "beacon", position = {siloPos.x-6, siloPos.y}, 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}
|
||||
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}
|
||||
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}
|
||||
beacon.destructible = false
|
||||
beacon.minable = false
|
||||
-- right 2
|
||||
local beacon = surface.create_entity{name = "beacon", position = {siloPos.x+6, siloPos.y-6}, 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}
|
||||
beacon.destructible = false
|
||||
beacon.minable = false
|
||||
-- right 4
|
||||
local beacon = surface.create_entity{name = "beacon", position = {siloPos.x+6, siloPos.y}, 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}
|
||||
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}
|
||||
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}
|
||||
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}
|
||||
substation.destructible = false
|
||||
substation.minable = false
|
||||
-- top right
|
||||
local substation = surface.create_entity{name = "substation", position = {siloPos.x+9, siloPos.y-6}, 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}
|
||||
substation.destructible = false
|
||||
substation.minable = false
|
||||
-- bottom right
|
||||
local substation = surface.create_entity{name = "substation", position = {siloPos.x+9, siloPos.y+4}, force = force}
|
||||
substation.destructible = false
|
||||
substation.minable = false
|
||||
|
||||
-- end adding beacons
|
||||
end
|
||||
|
||||
function PhilipsRadarAndShit(surface, siloPos, force)
|
||||
|
||||
local radar = surface.create_entity{name = "solar-panel", position = {siloPos.x-33, 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}
|
||||
radar.destructible = false
|
||||
local radar = surface.create_entity{name = "solar-panel", position = {siloPos.x-30, 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}
|
||||
radar.destructible = false
|
||||
local radar = surface.create_entity{name = "solar-panel", position = {siloPos.x-24, 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}
|
||||
radar.destructible = false
|
||||
local radar = surface.create_entity{name = "solar-panel", position = {siloPos.x-24, siloPos.y}, force = force}
|
||||
radar.destructible = false
|
||||
local radar = surface.create_entity{name = "solar-panel", position = {siloPos.x-24, 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}
|
||||
radar.destructible = false
|
||||
local radar = surface.create_entity{name = "solar-panel", position = {siloPos.x-30, 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}
|
||||
radar.destructible = false
|
||||
local radar = surface.create_entity{name = "radar", position = {siloPos.x-33, siloPos.y}, force = force}
|
||||
radar.destructible = false
|
||||
local substation = surface.create_entity{name = "substation", position = {siloPos.x-28, siloPos.y-1}, force = force}
|
||||
substation.destructible = false
|
||||
local radar = surface.create_entity{name = "accumulator", position = {siloPos.x-30, siloPos.y-1}, force = force}
|
||||
radar.destructible = false
|
||||
local radar = surface.create_entity{name = "accumulator", position = {siloPos.x-30, siloPos.y-3}, force = force}
|
||||
radar.destructible = false
|
||||
local radar = surface.create_entity{name = "accumulator", position = {siloPos.x-30, siloPos.y+1}, force = force}
|
||||
radar.destructible = false
|
||||
local radar = surface.create_entity{name = "accumulator", position = {siloPos.x-28, siloPos.y-3}, force = force}
|
||||
radar.destructible = false
|
||||
local radar = surface.create_entity{name = "accumulator", position = {siloPos.x-28, siloPos.y+1}, force = force}
|
||||
radar.destructible = false
|
||||
local radar = surface.create_entity{name = "accumulator", position = {siloPos.x-26, siloPos.y-1}, force = force}
|
||||
radar.destructible = false
|
||||
local radar = surface.create_entity{name = "accumulator", position = {siloPos.x-26, siloPos.y-3}, force = force}
|
||||
radar.destructible = false
|
||||
local radar = surface.create_entity{name = "accumulator", position = {siloPos.x-26, siloPos.y+1}, force = force}
|
||||
radar.destructible = false
|
||||
end
|
145
locale/game_opts.lua
Normal file
145
locale/game_opts.lua
Normal file
@ -0,0 +1,145 @@
|
||||
-- game_opts.lua
|
||||
-- Jan 2018
|
||||
-- Display current game options, maybe have some admin controls here
|
||||
|
||||
-- Main Configuration File
|
||||
require("config")
|
||||
require("locale/oarc_utils")
|
||||
|
||||
function CreateGameOptionsGui(event)
|
||||
local player = game.players[event.player_index]
|
||||
if player.gui.top.game_options == nil then
|
||||
player.gui.top.add{name="game_options", type="button", caption="Info"}
|
||||
end
|
||||
end
|
||||
|
||||
local function ExpandGameOptionsGui(player)
|
||||
local frame = player.gui.left["game_options_panel"]
|
||||
if (frame) then
|
||||
frame.destroy()
|
||||
else
|
||||
local frame = player.gui.left.add{type="frame",
|
||||
name="game_options_panel",
|
||||
caption="Server Info:",
|
||||
direction="vertical"}
|
||||
|
||||
-- General Server Info:
|
||||
AddLabel(frame, "info_1", global.welcome_msg, my_longer_label_style)
|
||||
AddLabel(frame, "info_2", SERVER_MSG, my_longer_label_style)
|
||||
AddSpacer(frame, "info_spacer1")
|
||||
|
||||
-- Enemy Settings:
|
||||
local enemy_expansion_txt = "disabled"
|
||||
if game.map_settings.enemy_expansion.enabled then enemy_expansion_txt = "enabled" end
|
||||
|
||||
local enemy_text="Server Run Time: " .. formattime_hours_mins(game.tick) .. "\n" ..
|
||||
"Current Evolution: " .. string.format("%.4f", game.forces["enemy"].evolution_factor) .. "\n" ..
|
||||
"Enemy evolution time factor: " .. game.map_settings.enemy_evolution.time_factor .. "\n" ..
|
||||
"Enemy evolution pollution factor: " .. game.map_settings.enemy_evolution.pollution_factor .. "\n" ..
|
||||
"Enemy evolution destroy factor: " .. game.map_settings.enemy_evolution.destroy_factor .. "\n" ..
|
||||
"Enemy expansion is " .. enemy_expansion_txt
|
||||
|
||||
AddLabel(frame, "enemy_info", enemy_text, my_longer_label_style)
|
||||
AddSpacer(frame, "enemy_info_spacer1")
|
||||
|
||||
-- Game Mode:
|
||||
AddLabel(frame, "core_mod_en", "Core game mode (separate spawns) is enabled.", my_longer_label_style)
|
||||
if (not ENABLE_SEPARATE_SPAWNS) then
|
||||
frame.core_mod_en.caption="Core game mode (separate spawns) is DISABLED."
|
||||
frame.core_mod_en.style.font_color=my_color_red
|
||||
end
|
||||
|
||||
-- Soft Mods:
|
||||
local soft_mods_string = "Oarc Core"
|
||||
if (not ENABLE_SEPARATE_SPAWNS) then
|
||||
soft_mods_string = "Oarc Core [DISABLED!]"
|
||||
end
|
||||
if (ENABLE_RSO) then
|
||||
soft_mods_string = soft_mods_string .. ", RSO"
|
||||
end
|
||||
if (ENABLE_UNDECORATOR) then
|
||||
soft_mods_string = soft_mods_string .. ", Undecorator"
|
||||
end
|
||||
if (ENABLE_TAGS) then
|
||||
soft_mods_string = soft_mods_string .. ", Tags"
|
||||
end
|
||||
if (ENABLE_LONGREACH) then
|
||||
soft_mods_string = soft_mods_string .. ", Long Reach"
|
||||
end
|
||||
if (ENABLE_AUTOFILL) then
|
||||
soft_mods_string = soft_mods_string .. ", Auto Fill"
|
||||
end
|
||||
if (ENABLE_PLAYER_LIST) then
|
||||
soft_mods_string = soft_mods_string .. ", Player List"
|
||||
end
|
||||
|
||||
local game_info_str = "Soft Mods Enabled: " .. soft_mods_string
|
||||
|
||||
-- Spawn options:
|
||||
if (ENABLE_SEPARATE_TEAMS) then
|
||||
game_info_str = game_info_str.."\n".."You are allowed to spawn on your own team (have your own research tree). All teams are friendly!"
|
||||
end
|
||||
if (ENABLE_BUDDY_SPAWN) then
|
||||
game_info_str = game_info_str.."\n".."You can chose to spawn alongside a buddy if you spawn together at the same time."
|
||||
end
|
||||
if (ENABLE_SHARED_SPAWNS) then
|
||||
game_info_str = game_info_str.."\n".."Spawn hosts may choose to share their spawn and allow other players to join them."
|
||||
end
|
||||
if (ENABLE_SEPARATE_TEAMS and ENABLE_SHARED_TEAM_VISION) then
|
||||
game_info_str = game_info_str.."\n".."Everyone (all teams) have shared vision."
|
||||
end
|
||||
if (FRONTIER_ROCKET_SILO_MODE) then
|
||||
game_info_str = game_info_str.."\n".."Silos are NOT craftable. There is at least one already located on the map."
|
||||
end
|
||||
if (ENABLE_REGROWTH) then
|
||||
game_info_str = game_info_str.."\n".."Old parts of the map will slowly be deleted over time (chunks without any player buildings)."
|
||||
end
|
||||
if (ENABLE_POWER_ARMOR_QUICK_START) then
|
||||
game_info_str = game_info_str.."\n".."Power armor quick start enabled."
|
||||
end
|
||||
|
||||
AddLabel(frame, "game_info_label", game_info_str, my_longer_label_style)
|
||||
|
||||
if (ENABLE_ABANDONED_BASE_REMOVAL) then
|
||||
AddLabel(frame, "leave_warning_msg", "If you leave within " .. MIN_ONLINE_TIME_IN_MINUTES .. " minutes of joining, your base and character will be deleted.", my_longer_label_style)
|
||||
frame.leave_warning_msg.style.font_color=my_color_red
|
||||
end
|
||||
|
||||
-- Ending Spacer
|
||||
AddSpacer(frame, "end_spacer")
|
||||
|
||||
-- ADMIN CONTROLS
|
||||
if (player.admin) then
|
||||
player_list = {}
|
||||
for _,player in pairs(game.connected_players) do
|
||||
table.insert(player_list, player.name)
|
||||
end
|
||||
frame.add{name = "ban_players_dropdown",
|
||||
type = "drop-down",
|
||||
items = player_list}
|
||||
frame.add{name="ban_player", type="button", caption="Ban Player"}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function GameOptionsGuiClick(event)
|
||||
if not (event and event.element and event.element.valid) then return end
|
||||
local player = game.players[event.element.player_index]
|
||||
local name = event.element.name
|
||||
|
||||
if (name == "game_options") then
|
||||
ExpandGameOptionsGui(player)
|
||||
end
|
||||
|
||||
if (name == "ban_player") then
|
||||
banIndex = event.element.parent.ban_players_dropdown.selected_index
|
||||
|
||||
if (banIndex ~= 0) then
|
||||
banPlayer = event.element.parent.ban_players_dropdown.get_item(banIndex)
|
||||
if (game.players[banPlayer]) then
|
||||
game.ban_player(banPlayer, "Banned for griefing - Banned from admin panel.")
|
||||
DebugPrint("Banning " .. banPlayer)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -25,34 +25,31 @@ my_fixed_width_style = {
|
||||
maximal_width = 450
|
||||
}
|
||||
my_label_style = {
|
||||
minimal_width = 450,
|
||||
maximal_width = 450,
|
||||
maximal_height = 10,
|
||||
-- minimal_width = 450,
|
||||
-- maximal_width = 50,
|
||||
single_line = false,
|
||||
font_color = {r=1,g=1,b=1},
|
||||
top_padding = 0,
|
||||
bottom_padding = 0
|
||||
}
|
||||
my_note_style = {
|
||||
minimal_width = 450,
|
||||
maximal_height = 10,
|
||||
-- minimal_width = 450,
|
||||
single_line = false,
|
||||
font = "default-small-semibold",
|
||||
font_color = {r=1,g=0.5,b=0.5},
|
||||
top_padding = 0,
|
||||
bottom_padding = 0
|
||||
}
|
||||
my_warning_style = {
|
||||
minimal_width = 450,
|
||||
maximal_width = 450,
|
||||
maximal_height = 10,
|
||||
-- minimal_width = 450,
|
||||
-- maximal_width = 450,
|
||||
single_line = false,
|
||||
font_color = {r=1,g=0.1,b=0.1},
|
||||
top_padding = 0,
|
||||
bottom_padding = 0
|
||||
}
|
||||
my_spacer_style = {
|
||||
minimal_width = 450,
|
||||
maximal_width = 450,
|
||||
minimal_height = 20,
|
||||
maximal_height = 20,
|
||||
minimal_height = 10,
|
||||
font_color = {r=0,g=0,b=0},
|
||||
top_padding = 0,
|
||||
bottom_padding = 0
|
||||
@ -71,20 +68,42 @@ my_player_list_admin_style = {
|
||||
minimal_width = 200,
|
||||
top_padding = 0,
|
||||
bottom_padding = 0,
|
||||
maximal_height = 15
|
||||
single_line = false,
|
||||
}
|
||||
my_player_list_style = {
|
||||
font = "default-semibold",
|
||||
minimal_width = 200,
|
||||
top_padding = 0,
|
||||
bottom_padding = 0,
|
||||
maximal_height = 15
|
||||
single_line = false,
|
||||
}
|
||||
my_player_list_offline_style = {
|
||||
-- font = "default-semibold",
|
||||
font_color = {r=0.5,g=0.5,b=0.5},
|
||||
minimal_width = 200,
|
||||
top_padding = 0,
|
||||
bottom_padding = 0,
|
||||
single_line = false,
|
||||
}
|
||||
my_player_list_style_spacer = {
|
||||
maximal_height = 15
|
||||
minimal_height = 20,
|
||||
}
|
||||
my_color_red = {r=1,g=0.1,b=0.1}
|
||||
|
||||
my_longer_label_style = {
|
||||
maximal_width = 600,
|
||||
single_line = false,
|
||||
font_color = {r=1,g=1,b=1},
|
||||
top_padding = 0,
|
||||
bottom_padding = 0
|
||||
}
|
||||
my_longer_warning_style = {
|
||||
maximal_width = 600,
|
||||
single_line = false,
|
||||
font_color = {r=1,g=0.1,b=0.1},
|
||||
top_padding = 0,
|
||||
bottom_padding = 0
|
||||
}
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- General Helper Functions
|
||||
@ -114,6 +133,13 @@ function SendBroadcastMsg(msg)
|
||||
end
|
||||
end
|
||||
|
||||
-- Send a message to a player, safely checks if they exist and are online.
|
||||
function SendMsg(playerName, msg)
|
||||
if ((game.players[playerName] ~= nil) and (game.players[playerName].connected)) then
|
||||
game.players[playerName].print(msg)
|
||||
end
|
||||
end
|
||||
|
||||
-- Special case for ensuring that if I create the server, my messages are
|
||||
-- used instead of the generic insert msg warning.
|
||||
function SetServerWelcomeMessages()
|
||||
@ -150,6 +176,15 @@ function TableLength(T)
|
||||
return count
|
||||
end
|
||||
|
||||
-- Simple function to get distance between two positions.
|
||||
function getDistance(posA, posB)
|
||||
-- Get the length for each of the components x and y
|
||||
local xDist = posB.x - posA.x
|
||||
local yDist = posB.y - posA.y
|
||||
|
||||
return math.sqrt( (xDist ^ 2) + (yDist ^ 2) )
|
||||
end
|
||||
|
||||
-- Chart area for a force
|
||||
function ChartArea(force, position, chunkDist, surface)
|
||||
force.chart(surface,
|
||||
@ -201,6 +236,7 @@ function GiveQuickStartPowerArmor(player)
|
||||
p_armor.put({name = "solar-panel-equipment"})
|
||||
end
|
||||
player.insert{name="construction-robot", count = 100}
|
||||
player.insert{name="belt-immunity-equipment", count = 1}
|
||||
end
|
||||
end
|
||||
|
||||
@ -265,6 +301,17 @@ function ShareChatBetweenForces(player, msg)
|
||||
end
|
||||
end
|
||||
|
||||
-- Merges force2 INTO force1 but keeps all research between both forces.
|
||||
function MergeForcesKeepResearch(force1, force2)
|
||||
for techName,luaTech in pairs(force2.technologies) do
|
||||
if (luaTech.researched) then
|
||||
force1.technologies[techName].researched = true
|
||||
force1.technologies[techName].level = luaTech.level
|
||||
end
|
||||
end
|
||||
game.merge_forces(force2, force1)
|
||||
end
|
||||
|
||||
-- Undecorator
|
||||
function RemoveDecorationsArea(surface, area)
|
||||
surface.destroy_decoratives(area)
|
||||
@ -284,6 +331,27 @@ function ApplyStyle (guiIn, styleIn)
|
||||
end
|
||||
end
|
||||
|
||||
-- Shorter way to add a label with a style
|
||||
function AddLabel(guiIn, name, message, style)
|
||||
guiIn.add{name = name, type = "label",
|
||||
caption=message}
|
||||
ApplyStyle(guiIn[name], style)
|
||||
end
|
||||
|
||||
-- Shorter way to add a spacer
|
||||
function AddSpacer(guiIn, name)
|
||||
guiIn.add{name = name, type = "label",
|
||||
caption=" "}
|
||||
ApplyStyle(guiIn[name], my_spacer_style)
|
||||
end
|
||||
|
||||
-- Shorter way to add a spacer with a decorative line
|
||||
function AddSpacerLine(guiIn, name)
|
||||
guiIn.add{name = name, type = "label",
|
||||
caption="~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"}
|
||||
ApplyStyle(guiIn[name], my_spacer_style)
|
||||
end
|
||||
|
||||
-- Get a random 1 or -1
|
||||
function RandomNegPos()
|
||||
if (math.random(0,1) == 1) then
|
||||
@ -320,15 +388,15 @@ function IsChunkAreaUngenerated(chunkPos, chunkDist, surface)
|
||||
end
|
||||
|
||||
-- Clear out enemies around an area with a certain distance
|
||||
function ClearNearbyEnemies(player, safeDist)
|
||||
function ClearNearbyEnemies(pos, safeDist, surface)
|
||||
local safeArea = {left_top=
|
||||
{x=player.position.x-safeDist,
|
||||
y=player.position.y-safeDist},
|
||||
{x=pos.x-safeDist,
|
||||
y=pos.y-safeDist},
|
||||
right_bottom=
|
||||
{x=player.position.x+safeDist,
|
||||
y=player.position.y+safeDist}}
|
||||
{x=pos.x+safeDist,
|
||||
y=pos.y+safeDist}}
|
||||
|
||||
for _, entity in pairs(player.surface.find_entities_filtered{area = safeArea, force = "enemy"}) do
|
||||
for _, entity in pairs(surface.find_entities_filtered{area = safeArea, force = "enemy"}) do
|
||||
entity.destroy()
|
||||
end
|
||||
end
|
||||
@ -441,7 +509,9 @@ 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
|
||||
entity.destroy()
|
||||
if entity.valid and entity and entity.position then
|
||||
entity.destroy()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -449,8 +519,10 @@ end
|
||||
-- Only if it is within given distance from given position.
|
||||
function RemoveInCircle(surface, area, type, pos, dist)
|
||||
for key, entity in pairs(surface.find_entities_filtered({area=area, type= type})) do
|
||||
if ((pos.x - entity.position.x)^2 + (pos.y - entity.position.y)^2 < dist^2) then
|
||||
entity.destroy()
|
||||
if entity.valid and entity and entity.position then
|
||||
if ((pos.x - entity.position.x)^2 + (pos.y - entity.position.y)^2 < dist^2) then
|
||||
entity.destroy()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -484,10 +556,149 @@ end
|
||||
|
||||
-- Adjust alien params
|
||||
function ConfigureAlienStartingParams()
|
||||
game.map_settings.enemy_evolution.time_factor=0
|
||||
game.map_settings.enemy_evolution.destroy_factor = game.map_settings.enemy_evolution.destroy_factor / ENEMY_DESTROY_FACTOR_DIVISOR
|
||||
game.map_settings.enemy_evolution.pollution_factor = game.map_settings.enemy_evolution.pollution_factor / ENEMY_POLLUTION_FACTOR_DIVISOR
|
||||
|
||||
-- These are the default values for reference:
|
||||
-- "time_factor": 0.000004,
|
||||
-- "destroy_factor": 0.002,
|
||||
-- "pollution_factor": 0.000015
|
||||
|
||||
if ENEMY_TIME_FACTOR_DISABLE then
|
||||
game.map_settings.enemy_evolution.time_factor = 0
|
||||
else
|
||||
game.map_settings.enemy_evolution.time_factor=game.map_settings.enemy_evolution.time_factor / ENEMY_TIME_FACTOR_DIVISOR
|
||||
end
|
||||
|
||||
if ENEMY_POLLUTION_FACTOR_DISABLE then
|
||||
game.map_settings.enemy_evolution.pollution_factor = 0
|
||||
else
|
||||
game.map_settings.enemy_evolution.pollution_factor = game.map_settings.enemy_evolution.pollution_factor / ENEMY_POLLUTION_FACTOR_DIVISOR
|
||||
end
|
||||
|
||||
if ENEMY_DESTROY_FACTOR_DISABLE then
|
||||
game.map_settings.enemy_evolution.destroy_factor = 0
|
||||
else
|
||||
game.map_settings.enemy_evolution.destroy_factor = game.map_settings.enemy_evolution.destroy_factor / ENEMY_DESTROY_FACTOR_DIVISOR
|
||||
end
|
||||
|
||||
game.map_settings.enemy_expansion.enabled = ENEMY_EXPANSION
|
||||
|
||||
if (OARC_DIFFICULTY_CUSTOM) then
|
||||
|
||||
game.map_settings.pollution.diffusion_ratio = 0.08
|
||||
game.map_settings.pollution.ageing = 1
|
||||
|
||||
game.map_settings.enemy_expansion.max_expansion_distance = 20
|
||||
|
||||
game.map_settings.enemy_expansion.settler_group_min_size = 2
|
||||
game.map_settings.enemy_expansion.settler_group_max_size = 10
|
||||
|
||||
game.map_settings.enemy_expansion.min_expansion_cooldown = TICKS_PER_MINUTE*15
|
||||
game.map_settings.enemy_expansion.max_expansion_cooldown = TICKS_PER_MINUTE*60
|
||||
|
||||
game.map_settings.unit_group.min_group_gathering_time = TICKS_PER_MINUTE
|
||||
game.map_settings.unit_group.max_group_gathering_time = 4 * TICKS_PER_MINUTE
|
||||
game.map_settings.unit_group.max_wait_time_for_late_members = 1 * TICKS_PER_MINUTE
|
||||
game.map_settings.unit_group.max_unit_group_size = 15
|
||||
|
||||
-- game.map_settings.pollution.enabled=true,
|
||||
-- -- these are values for 60 ticks (1 simulated second)
|
||||
-- --
|
||||
-- -- amount that is diffused to neighboring chunk
|
||||
-- -- (possibly repeated for other directions as well)
|
||||
-- game.map_settings.pollution.diffusion_ratio=0.02,
|
||||
-- -- this much PUs must be on the chunk to start diffusing
|
||||
-- game.map_settings.pollution.min_to_diffuse=15,
|
||||
-- -- constant modifier a percentage of 1 - the pollution eaten by a chunks tiles
|
||||
-- game.map_settings.pollution.ageing=1,
|
||||
-- -- anything bigger than this is visualised as this value
|
||||
-- game.map_settings.pollution.expected_max_per_chunk=7000,
|
||||
-- -- anything lower than this (but > 0) is visualised as this value
|
||||
-- game.map_settings.pollution.min_to_show_per_chunk=700,
|
||||
-- game.map_settings.pollution.min_pollution_to_damage_trees = 3500,
|
||||
-- game.map_settings.pollution.pollution_with_max_forest_damage = 10000,
|
||||
-- game.map_settings.pollution.pollution_per_tree_damage = 2000,
|
||||
-- game.map_settings.pollution.pollution_restored_per_tree_damage = 500,
|
||||
-- game.map_settings.pollution.max_pollution_to_restore_trees = 1000
|
||||
|
||||
|
||||
-- game.map_settings.enemy_expansion.enabled = true,
|
||||
-- -- Distance in chunks from the furthest base around.
|
||||
-- -- This prevents expansions from reaching too far into the
|
||||
-- -- player's territory
|
||||
-- game.map_settings.enemy_expansion.max_expansion_distance = 7,
|
||||
|
||||
-- game.map_settings.enemy_expansion.friendly_base_influence_radius = 2,
|
||||
-- game.map_settings.enemy_expansion.enemy_building_influence_radius = 2,
|
||||
|
||||
-- -- A candidate chunk's score is given as follows:
|
||||
-- -- player = 0
|
||||
-- -- for neighbour in all chunks within enemy_building_influence_radius from chunk:
|
||||
-- -- player += number of player buildings on neighbour
|
||||
-- -- * building_coefficient
|
||||
-- -- * neighbouring_chunk_coefficient^distance(chunk, neighbour)
|
||||
-- --
|
||||
-- -- base = 0
|
||||
-- -- for neighbour in all chunk within friendly_base_influence_radius from chunk:
|
||||
-- -- base += num of enemy bases on neighbour
|
||||
-- -- * other_base_coefficient
|
||||
-- -- * neighbouring_base_chunk_coefficient^distance(chunk, neighbour)
|
||||
-- --
|
||||
-- -- score(chunk) = 1 / (1 + player + base)
|
||||
-- --
|
||||
-- -- The iteration is over a square region centered around the chunk for which the calculation is done,
|
||||
-- -- and includes the central chunk as well. distance is the Manhattan distance, and ^ signifies exponentiation.
|
||||
-- game.map_settings.enemy_expansion.building_coefficient = 0.1,
|
||||
-- game.map_settings.enemy_expansion.other_base_coefficient = 2.0,
|
||||
-- game.map_settings.enemy_expansion.neighbouring_chunk_coefficient = 0.5,
|
||||
-- game.map_settings.enemy_expansion.neighbouring_base_chunk_coefficient = 0.4;
|
||||
|
||||
-- -- A chunk has to have at most this much percent unbuildable tiles for it to be considered a candidate.
|
||||
-- -- This is to avoid chunks full of water to be marked as candidates.
|
||||
-- game.map_settings.enemy_expansion.max_colliding_tiles_coefficient = 0.9,
|
||||
|
||||
-- -- Size of the group that goes to build new base (in game this is multiplied by the
|
||||
-- -- evolution factor).
|
||||
-- game.map_settings.enemy_expansion.settler_group_min_size = 5,
|
||||
-- game.map_settings.enemy_expansion.settler_group_max_size = 20,
|
||||
|
||||
-- -- Ticks to expand to a single
|
||||
-- -- position for a base is used.
|
||||
-- --
|
||||
-- -- cooldown is calculated as follows:
|
||||
-- -- cooldown = lerp(max_expansion_cooldown, min_expansion_cooldown, -e^2 + 2 * e),
|
||||
-- -- where lerp is the linear interpolation function, and e is the current evolution factor.
|
||||
-- game.map_settings.enemy_expansion.min_expansion_cooldown = 4 * 3600,
|
||||
-- game.map_settings.enemy_expansion.max_expansion_cooldown = 60 * 3600
|
||||
|
||||
-- -- pollution triggered group waiting time is a random time between min and max gathering time
|
||||
-- game.map_settings.unit_group.min_group_gathering_time = 3600,
|
||||
-- game.map_settings.unit_group.max_group_gathering_time = 10 * 3600,
|
||||
-- -- after the gathering is finished the group can still wait for late members,
|
||||
-- -- but it doesn't accept new ones anymore
|
||||
-- game.map_settings.unit_group.max_wait_time_for_late_members = 2 * 3600,
|
||||
-- -- limits for group radius (calculated by number of numbers)
|
||||
-- game.map_settings.unit_group.max_group_radius = 30.0,
|
||||
-- game.map_settings.unit_group.min_group_radius = 5.0,
|
||||
-- -- when a member falls behind the group he can speedup up till this much of his regular speed
|
||||
-- game.map_settings.unit_group.max_member_speedup_when_behind = 1.4,
|
||||
-- -- When a member gets ahead of its group, it will slow down to at most this factor of its speed
|
||||
-- game.map_settings.unit_group.max_member_slowdown_when_ahead = 0.6,
|
||||
-- -- When members of a group are behind, the entire group will slow down to at most this factor of its max speed
|
||||
-- game.map_settings.unit_group.max_group_slowdown_factor = 0.3,
|
||||
-- -- If a member falls behind more than this times the group radius, the group will slow down to max_group_slowdown_factor
|
||||
-- game.map_settings.unit_group.max_group_member_fallback_factor = 3,
|
||||
-- -- If a member falls behind more than this time the group radius, it will be removed from the group.
|
||||
-- game.map_settings.unit_group.member_disown_distance = 10,
|
||||
-- game.map_settings.unit_group.tick_tolerance_when_member_arrives = 60,
|
||||
|
||||
-- -- Maximum number of automatically created unit groups gathering for attack at any time.
|
||||
-- game.map_settings.unit_group.max_gathering_unit_groups = 30,
|
||||
|
||||
-- -- Maximum size of an attack unit group. This only affects automatically-created unit groups; manual groups
|
||||
-- -- created through the API are unaffected.
|
||||
-- game.map_settings.unit_group.max_unit_group_size = 200
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
-- Add Long Reach to Character
|
||||
@ -522,11 +733,22 @@ local function ExpandPlayerListGui(player)
|
||||
scrollFrame.horizontal_scroll_policy = "never"
|
||||
for _,player in pairs(game.connected_players) do
|
||||
local caption_str = player.name.." ["..player.force.name.."]".." ("..formattime_hours_mins(player.online_time)..")"
|
||||
local text = scrollFrame.add{type="label", caption=caption_str, name=player.name.."_plist"}
|
||||
if (player.admin) then
|
||||
ApplyStyle(text, my_player_list_admin_style)
|
||||
AddLabel(scrollFrame, player.name.."_plist", caption_str, my_player_list_admin_style)
|
||||
else
|
||||
ApplyStyle(text, my_player_list_style)
|
||||
AddLabel(scrollFrame, player.name.."_plist", caption_str, my_player_list_style)
|
||||
end
|
||||
end
|
||||
|
||||
-- List offline players
|
||||
if (PLAYER_LIST_OFFLINE_PLAYERS) then
|
||||
AddLabel(scrollFrame, "offline_title_msg", "Offline Players:", my_label_style)
|
||||
for _,player in pairs(game.players) do
|
||||
if (not player.connected) then
|
||||
local caption_str = player.name.." ["..player.force.name.."]".." ("..formattime_hours_mins(player.online_time)..")"
|
||||
local text = scrollFrame.add{type="label", caption=caption_str, name=player.name.."_plist"}
|
||||
ApplyStyle(text, my_player_list_offline_style)
|
||||
end
|
||||
end
|
||||
end
|
||||
local spacer = scrollFrame.add{type="label", caption=" ", name="plist_spacer_plist"}
|
||||
@ -550,6 +772,22 @@ end
|
||||
function AntiGriefing(force)
|
||||
force.zoom_to_world_deconstruction_planner_enabled=false
|
||||
force.friendly_fire=false
|
||||
SetForceGhostTimeToLive(force)
|
||||
end
|
||||
|
||||
function SetForceGhostTimeToLive(force)
|
||||
if GHOST_TIME_TO_LIVE ~= 0 then
|
||||
force.ghost_time_to_live = GHOST_TIME_TO_LIVE+1
|
||||
end
|
||||
end
|
||||
|
||||
function SetItemBlueprintTimeToLive(event)
|
||||
local type = event.created_entity.type
|
||||
if type == "entity-ghost" or type == "tile-ghost" then
|
||||
if GHOST_TIME_TO_LIVE ~= 0 then
|
||||
event.created_entity.time_to_live = GHOST_TIME_TO_LIVE
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
@ -587,7 +825,7 @@ function DropGravestoneChests(player)
|
||||
|
||||
local inv = player.get_inventory(id)
|
||||
|
||||
if (not inv.is_empty()) then
|
||||
if ((#inv > 0) and not inv.is_empty()) then
|
||||
for j = 1, #inv do
|
||||
if inv[j].valid_for_read then
|
||||
|
||||
@ -622,34 +860,6 @@ function DropGravestoneChests(player)
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Frontier style rocket silo stuff
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
-- This creates a random silo position, stored to global.siloPosition
|
||||
-- It uses the config setting SILO_CHUNK_DISTANCE and spawns the silo somewhere
|
||||
-- on a circle edge with radius using that distance.
|
||||
function SetRandomSiloPosition()
|
||||
if (global.siloPosition == nil) then
|
||||
-- Get an X,Y on a circle far away.
|
||||
local distX = math.random(0,SILO_CHUNK_DISTANCE_X)
|
||||
local distY = RandomNegPos() * math.floor(math.sqrt(SILO_CHUNK_DISTANCE_X^2 - distX^2))
|
||||
local distX = RandomNegPos() * distX
|
||||
|
||||
-- Set those values.
|
||||
local siloX = distX*CHUNK_SIZE + CHUNK_SIZE/2
|
||||
local siloY = distY*CHUNK_SIZE + CHUNK_SIZE/2
|
||||
global.siloPosition = {x = siloX, y = siloY}
|
||||
end
|
||||
end
|
||||
|
||||
-- Sets the global.siloPosition var to the set in the config file
|
||||
function SetFixedSiloPosition()
|
||||
if (global.siloPosition == nil) then
|
||||
global.siloPosition = SILO_POSITION
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Autofill Stuff
|
||||
--------------------------------------------------------------------------------
|
||||
@ -713,7 +923,7 @@ function AutoFillVehicle(player, vehicle)
|
||||
|
||||
-- Attempt to transfer some fuel
|
||||
if ((vehicle.name == "car") or (vehicle.name == "tank") or (vehicle.name == "locomotive")) then
|
||||
TransferItemMultipleTypes(mainInv, vehicle, {"rocket-fuel", "solid-fuel", "coal", "raw-wood"}, 50)
|
||||
TransferItemMultipleTypes(mainInv, vehicle, {"nuclear-fuel", "rocket-fuel", "solid-fuel", "coal", "raw-wood"}, 50)
|
||||
end
|
||||
|
||||
-- Attempt to transfer some ammo
|
||||
@ -747,14 +957,14 @@ function CreateCropCircle(surface, centerPos, chunkArea, tileRadius)
|
||||
-- Fill in all unexpected water in a circle
|
||||
if (distVar < tileRadSqr) then
|
||||
if (surface.get_tile(i,j).collides_with("water-tile") or ENABLE_SPAWN_FORCE_GRASS) then
|
||||
table.insert(dirtTiles, {name = "grass", position ={i,j}})
|
||||
table.insert(dirtTiles, {name = "grass-1", position ={i,j}})
|
||||
end
|
||||
end
|
||||
|
||||
-- Create a circle of trees around the spawn point.
|
||||
if ((distVar < tileRadSqr-200) and
|
||||
(distVar > tileRadSqr-300)) then
|
||||
surface.create_entity({name="tree-01", amount=1, position={i, j}})
|
||||
(distVar > tileRadSqr-400)) then
|
||||
surface.create_entity({name="tree-02", amount=1, position={i, j}})
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -773,12 +983,12 @@ function CreateCropOctagon(surface, centerPos, chunkArea, tileRadius)
|
||||
|
||||
local distVar1 = math.floor(math.max(math.abs(centerPos.x - i), math.abs(centerPos.y - j)))
|
||||
local distVar2 = math.floor(math.abs(centerPos.x - i) + math.abs(centerPos.y - j))
|
||||
local distVar = math.max(distVar1, distVar2 * 0.707);
|
||||
local distVar = math.max(distVar1*1.1, distVar2 * 0.707*1.1);
|
||||
|
||||
-- Fill in all unexpected water in a circle
|
||||
if (distVar < tileRadius+2) then
|
||||
if (surface.get_tile(i,j).collides_with("water-tile") or ENABLE_SPAWN_FORCE_GRASS) then
|
||||
table.insert(dirtTiles, {name = "grass", position ={i,j}})
|
||||
table.insert(dirtTiles, {name = "grass-1", position ={i,j}})
|
||||
end
|
||||
end
|
||||
|
||||
@ -806,16 +1016,16 @@ function CreateMoat(surface, centerPos, chunkArea, tileRadius)
|
||||
local distVar = math.floor((centerPos.x - i)^2 + (centerPos.y - j)^2)
|
||||
|
||||
-- Create a circle of water
|
||||
if ((distVar < tileRadSqr+400) and
|
||||
(distVar > tileRadSqr-500)) then
|
||||
if ((distVar < tileRadSqr+(1500*MOAT_SIZE_MODIFIER)) and
|
||||
(distVar > tileRadSqr)) then
|
||||
table.insert(waterTiles, {name = "water", position ={i,j}})
|
||||
end
|
||||
|
||||
-- Enforce land inside the edges of the circle to make sure it's
|
||||
-- a clean transition
|
||||
if ((distVar < tileRadSqr-500) and
|
||||
(distVar > tileRadSqr-1000)) then
|
||||
table.insert(waterTiles, {name = "grass", position ={i,j}})
|
||||
if ((distVar <= tileRadSqr) and
|
||||
(distVar > tileRadSqr-10000)) then
|
||||
table.insert(waterTiles, {name = "grass-1", position ={i,j}})
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -835,6 +1045,9 @@ end
|
||||
-- Function to generate a resource patch, of a certain size/amount at a pos.
|
||||
function GenerateResourcePatch(surface, resourceName, diameter, pos, amount)
|
||||
local midPoint = math.floor(diameter/2)
|
||||
if (diameter == 0) then
|
||||
return
|
||||
end
|
||||
for y=0, diameter do
|
||||
for x=0, diameter do
|
||||
if (not ENABLE_RESOURCE_SHAPE_CIRCLE or ((x-midPoint)^2 + (y-midPoint)^2 < midPoint^2)) then
|
||||
@ -871,11 +1084,15 @@ function GenerateStartingResources(surface, pos)
|
||||
|
||||
-- Tree generation is taken care of in chunk generation
|
||||
|
||||
-- Generate 2 oil patches
|
||||
surface.create_entity({name="crude-oil", amount=START_OIL_AMOUNT,
|
||||
position={pos.x+START_RESOURCE_OIL_A_POS_X, pos.y+START_RESOURCE_OIL_A_POS_Y}})
|
||||
surface.create_entity({name="crude-oil", amount=START_OIL_AMOUNT,
|
||||
position={pos.x+START_RESOURCE_OIL_B_POS_X, pos.y+START_RESOURCE_OIL_B_POS_Y}})
|
||||
-- Generate oil patches
|
||||
oil_patch_x=pos.x+START_RESOURCE_OIL_POS_X
|
||||
oil_patch_y=pos.y+START_RESOURCE_OIL_POS_Y
|
||||
for i=1,START_RESOURCE_OIL_NUM_PATCHES do
|
||||
surface.create_entity({name="crude-oil", amount=START_OIL_AMOUNT,
|
||||
position={oil_patch_x, oil_patch_y}})
|
||||
oil_patch_x=oil_patch_x+START_RESOURCE_OIL_X_OFFSET
|
||||
oil_patch_y=oil_patch_y+START_RESOURCE_OIL_Y_OFFSET
|
||||
end
|
||||
|
||||
-- Generate Stone
|
||||
GenerateResourcePatch(surface, "stone", START_RESOURCE_STONE_SIZE, stonePos, START_STONE_AMOUNT)
|
||||
@ -895,12 +1112,12 @@ end
|
||||
|
||||
|
||||
|
||||
-- Create the spawn areas.
|
||||
-- Clear the spawn areas.
|
||||
-- This should be run inside the chunk generate event and be given a list of all
|
||||
-- unique spawn points.
|
||||
-- This clears enemies in the immediate area, creates a slightly safe area around it,
|
||||
-- And spawns the basic resources as well
|
||||
function CreateSpawnAreas(surface, chunkArea, spawnPointTable)
|
||||
-- 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
|
||||
|
||||
-- Create a bunch of useful area and position variables
|
||||
@ -926,8 +1143,10 @@ function CreateSpawnAreas(surface, chunkArea, spawnPointTable)
|
||||
if CheckIfInArea(chunkAreaCenter,landArea) then
|
||||
|
||||
-- Remove trees/resources inside the spawn area
|
||||
RemoveInCircle(surface, chunkArea, "tree", spawn.pos, ENFORCE_LAND_AREA_TILE_DIST+5)
|
||||
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 (SPAWN_TREE_CIRCLE_ENABLED) then
|
||||
CreateCropCircle(surface, spawn.pos, chunkArea, ENFORCE_LAND_AREA_TILE_DIST)
|
||||
@ -937,7 +1156,7 @@ function CreateSpawnAreas(surface, chunkArea, spawnPointTable)
|
||||
end
|
||||
if (SPAWN_MOAT_CHOICE_ENABLED) then
|
||||
if (spawn.moat) then
|
||||
CreateMoat(surface, spawn.pos, chunkArea, ENFORCE_LAND_AREA_TILE_DIST+10)
|
||||
CreateMoat(surface, spawn.pos, chunkArea, ENFORCE_LAND_AREA_TILE_DIST)
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -945,68 +1164,47 @@ function CreateSpawnAreas(surface, chunkArea, spawnPointTable)
|
||||
-- Provide starting resources
|
||||
-- This is run on the bottom, right chunk of the spawn area which should be
|
||||
-- generated last, so it should work everytime.
|
||||
if CheckIfInArea(spawnPosOffset,chunkArea) then
|
||||
CreateWaterStrip(surface,
|
||||
{x=spawn.pos.x+WATER_SPAWN_OFFSET_X, y=spawn.pos.y+WATER_SPAWN_OFFSET_Y},
|
||||
WATER_SPAWN_LENGTH)
|
||||
GenerateStartingResources(surface, spawn.pos)
|
||||
end
|
||||
-- if CheckIfInArea(spawnPosOffset,chunkArea) then
|
||||
-- CreateWaterStrip(surface,
|
||||
-- {x=spawn.pos.x+WATER_SPAWN_OFFSET_X, y=spawn.pos.y+WATER_SPAWN_OFFSET_Y},
|
||||
-- WATER_SPAWN_LENGTH)
|
||||
-- CreateWaterStrip(surface,
|
||||
-- {x=spawn.pos.x+WATER_SPAWN_OFFSET_X, y=spawn.pos.y+WATER_SPAWN_OFFSET_Y+1},
|
||||
-- WATER_SPAWN_LENGTH)
|
||||
-- GenerateStartingResources(surface, spawn.pos)
|
||||
-- end
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Surface Generation Functions
|
||||
--------------------------------------------------------------------------------
|
||||
-- To use RSO resources, we have to disable vanilla ore generation
|
||||
local surface_autoplace_none = {
|
||||
["coal"]={
|
||||
size="none"
|
||||
},
|
||||
["copper-ore"]={
|
||||
size="none"
|
||||
},
|
||||
["iron-ore"]={
|
||||
size="none"
|
||||
},
|
||||
["stone"]={
|
||||
size="none"
|
||||
},
|
||||
["uranium-ore"]={
|
||||
size="none"
|
||||
},
|
||||
["crude-oil"]={
|
||||
size="none"
|
||||
},
|
||||
["enemy-base"]={
|
||||
size="none"
|
||||
}
|
||||
}
|
||||
|
||||
RSO_MODE = 1
|
||||
VANILLA_MODE = 2
|
||||
|
||||
function CreateLobbySurface()
|
||||
local surface = game.create_surface("Lobby",{width = 1, height = 1})
|
||||
surface.set_tiles({{name = "out-of-map",position = {1,1}}})
|
||||
end
|
||||
|
||||
function CreateGameSurface(mode)
|
||||
local mapSettings = game.surfaces["nauvis"].map_gen_settings
|
||||
|
||||
if CMD_LINE_MAP_GEN then
|
||||
mapSettings.terrain_segmentation = global.clMapGen.terrain_segmentation
|
||||
mapSettings.water = global.clMapGen.water
|
||||
mapSettings.starting_area = global.clMapGen.starting_area
|
||||
mapSettings.peaceful_mode = global.clMapGen.peaceful_mode
|
||||
mapSettings.seed = global.clMapGen.seed
|
||||
mapSettings.autoplace_controls = global.clMapGen.autoplace_controls
|
||||
mapSettings.cliff_settings = global.clMapGen.cliff_settings
|
||||
end
|
||||
|
||||
-- To use RSO resources, we have to disable vanilla ore generation
|
||||
if (mode == RSO_MODE) then
|
||||
mapSettings.terrain_segmentation=MAP_SETTINGS_RSO_TERRAIN_SEGMENTATION
|
||||
mapSettings.water=MAP_SETTINGS_RSO_WATER
|
||||
mapSettings.starting_area=MAP_SETTINGS_RSO_STARTING_AREA
|
||||
mapSettings.peaceful_mode=MAP_SETTINGS_RSO_PEACEFUL
|
||||
mapSettings.seed=math.random(999999999);
|
||||
mapSettings.autoplace_controls = {
|
||||
["coal"]={ size="none" },
|
||||
["copper-ore"]={ size="none" },
|
||||
["iron-ore"]={ size="none" },
|
||||
["stone"]={ size="none" },
|
||||
["uranium-ore"]={ size="none" },
|
||||
["crude-oil"]={ size="none" },
|
||||
["enemy-base"]={ size="none" }
|
||||
}
|
||||
mapSettings.autoplace_controls["coal"].size="none"
|
||||
mapSettings.autoplace_controls["copper-ore"].size="none"
|
||||
mapSettings.autoplace_controls["iron-ore"].size="none"
|
||||
mapSettings.autoplace_controls["stone"].size="none"
|
||||
mapSettings.autoplace_controls["uranium-ore"].size="none"
|
||||
mapSettings.autoplace_controls["crude-oil"].size="none"
|
||||
mapSettings.autoplace_controls["enemy-base"].size="none"
|
||||
end
|
||||
|
||||
local surface = game.create_surface(GAME_SURFACE_NAME,mapSettings)
|
||||
@ -1025,7 +1223,7 @@ function CreateWall(surface, pos)
|
||||
end
|
||||
end
|
||||
|
||||
function CreateHoldingPen(surface, chunkArea)
|
||||
function CreateHoldingPen(surface, chunkArea, sizeTiles, walls)
|
||||
if (((chunkArea.left_top.x == -32) or (chunkArea.left_top.x == 0)) and
|
||||
((chunkArea.left_top.y == -32) or (chunkArea.left_top.y == 0))) then
|
||||
|
||||
@ -1033,6 +1231,7 @@ function CreateHoldingPen(surface, chunkArea)
|
||||
RemoveAliensInArea(surface, chunkArea)
|
||||
RemoveInArea(surface, chunkArea, "tree")
|
||||
RemoveInArea(surface, chunkArea, "resource")
|
||||
RemoveInArea(surface, chunkArea, "cliff")
|
||||
|
||||
-- This loop runs through each tile
|
||||
local grassTiles = {}
|
||||
@ -1040,26 +1239,34 @@ function CreateHoldingPen(surface, chunkArea)
|
||||
for i=chunkArea.left_top.x,chunkArea.right_bottom.x,1 do
|
||||
for j=chunkArea.left_top.y,chunkArea.right_bottom.y,1 do
|
||||
|
||||
-- Fill all area with grass only
|
||||
table.insert(grassTiles, {name = "grass", position ={i,j}})
|
||||
if ((i>-sizeTiles) and (i<(sizeTiles-1)) and (j>-sizeTiles) and (j<(sizeTiles-1))) then
|
||||
|
||||
-- Create the spawn box walls
|
||||
if (j<15 and j>-16) then
|
||||
-- Fill all area with grass only
|
||||
table.insert(grassTiles, {name = "grass-1", position ={i,j}})
|
||||
|
||||
-- Create the spawn box walls
|
||||
if (j<(sizeTiles-1) and j>-sizeTiles) then
|
||||
|
||||
-- Create horizontal sides of center spawn box
|
||||
if (((j>-sizeTiles and j<-(sizeTiles-4)) or (j<(sizeTiles-1) and j>(sizeTiles-5))) and (i<(sizeTiles-1) and i>-sizeTiles)) then
|
||||
if walls then
|
||||
CreateWall(surface, {i,j})
|
||||
else
|
||||
table.insert(waterTiles, {name = "water", position ={i,j}})
|
||||
end
|
||||
end
|
||||
|
||||
-- Create vertical sides of center spawn box
|
||||
if ((i>-sizeTiles and i<-(sizeTiles-4)) or (i<(sizeTiles-1) and i>(sizeTiles-5))) then
|
||||
if walls then
|
||||
CreateWall(surface, {i,j})
|
||||
else
|
||||
table.insert(waterTiles, {name = "water", position ={i,j}})
|
||||
end
|
||||
end
|
||||
|
||||
-- Create horizontal sides of center spawn box
|
||||
if (((j>-16 and j<-12) or (j<15 and j>11)) and (i<15 and i>-16)) then
|
||||
-- CreateWall(surface, {i,j})
|
||||
table.insert(waterTiles, {name = "water", position ={i,j}})
|
||||
end
|
||||
|
||||
-- Create vertical sides of center spawn box
|
||||
if ((i>-16 and i<-12) or (i<15 and i>11)) then
|
||||
-- CreateWall(surface, {i,j})
|
||||
table.insert(waterTiles, {name = "water", position ={i,j}})
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
surface.set_tiles(grassTiles)
|
||||
@ -1067,10 +1274,6 @@ function CreateHoldingPen(surface, chunkArea)
|
||||
end
|
||||
end
|
||||
|
||||
function CreateHoldingPenGenerateChunk(event)
|
||||
CreateHoldingPen(event.surface, event.area)
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- EVENT SPECIFIC FUNCTIONS
|
||||
--------------------------------------------------------------------------------
|
||||
|
@ -1,269 +0,0 @@
|
||||
--[[------------------------------------
|
||||
RandomLua v0.3.1
|
||||
Pure Lua Pseudo-Random Numbers Generator
|
||||
Under the MIT license.
|
||||
copyright(c) 2011 linux-man
|
||||
--]]------------------------------------
|
||||
|
||||
local _M = {}
|
||||
local mod = math.fmod
|
||||
local floor = math.floor
|
||||
local abs = math.abs
|
||||
|
||||
local function normalize(n) --keep numbers at (positive) 32 bits
|
||||
return n % 0x80000000
|
||||
end
|
||||
|
||||
local function bit_and(a, b)
|
||||
local r = 0
|
||||
local m = 0
|
||||
for m = 0, 31 do
|
||||
if (a % 2 == 1) and (b % 2 == 1) then r = r + 2^m end
|
||||
if a % 2 ~= 0 then a = a - 1 end
|
||||
if b % 2 ~= 0 then b = b - 1 end
|
||||
a = a / 2 b = b / 2
|
||||
end
|
||||
return normalize(r)
|
||||
end
|
||||
|
||||
local function bit_or(a, b)
|
||||
local r = 0
|
||||
local m = 0
|
||||
for m = 0, 31 do
|
||||
if (a % 2 == 1) or (b % 2 == 1) then r = r + 2^m end
|
||||
if a % 2 ~= 0 then a = a - 1 end
|
||||
if b % 2 ~= 0 then b = b - 1 end
|
||||
a = a / 2 b = b / 2
|
||||
end
|
||||
return normalize(r)
|
||||
end
|
||||
|
||||
local function bit_xor(a, b)
|
||||
local r = 0
|
||||
local m = 0
|
||||
for m = 0, 31 do
|
||||
if a % 2 ~= b % 2 then r = r + 2^m end
|
||||
if a % 2 ~= 0 then a = a - 1 end
|
||||
if b % 2 ~= 0 then b = b - 1 end
|
||||
a = a / 2 b = b / 2
|
||||
end
|
||||
return normalize(r)
|
||||
end
|
||||
|
||||
local function seed()
|
||||
--return normalize(tonumber(tostring(os.time()):reverse()))
|
||||
return normalize(os.time())
|
||||
end
|
||||
|
||||
--Mersenne twister
|
||||
mersenne_twister = {}
|
||||
mersenne_twister.__index = mersenne_twister
|
||||
|
||||
function mersenne_twister:randomseed(s)
|
||||
if not s then s = seed() end
|
||||
self.mt[0] = normalize(s)
|
||||
for i = 1, 623 do
|
||||
self.mt[i] = normalize(0x6c078965 * bit_xor(self.mt[i-1], floor(self.mt[i-1] / 0x40000000)) + i)
|
||||
end
|
||||
end
|
||||
|
||||
function mersenne_twister:random(a, b)
|
||||
local y
|
||||
if self.index == 0 then
|
||||
for i = 0, 623 do
|
||||
--y = bit_or(floor(self.mt[i] / 0x80000000) * 0x80000000, self.mt[(i + 1) % 624] % 0x80000000)
|
||||
y = self.mt[(i + 1) % 624] % 0x80000000
|
||||
self.mt[i] = bit_xor(self.mt[(i + 397) % 624], floor(y / 2))
|
||||
if y % 2 ~= 0 then self.mt[i] = bit_xor(self.mt[i], 0x9908b0df) end
|
||||
end
|
||||
end
|
||||
y = self.mt[self.index]
|
||||
y = bit_xor(y, floor(y / 0x800))
|
||||
y = bit_xor(y, bit_and(normalize(y * 0x80), 0x9d2c5680))
|
||||
y = bit_xor(y, bit_and(normalize(y * 0x8000), 0xefc60000))
|
||||
y = bit_xor(y, floor(y / 0x40000))
|
||||
self.index = (self.index + 1) % 624
|
||||
if not a then return y / 0x80000000
|
||||
elseif not b then
|
||||
if a == 0 then return y
|
||||
else return 1 + (y % a)
|
||||
end
|
||||
else
|
||||
return a + (y % (b - a + 1))
|
||||
end
|
||||
end
|
||||
|
||||
function _M.twister(s)
|
||||
local temp = {}
|
||||
setmetatable(temp, mersenne_twister)
|
||||
temp.mt = {}
|
||||
temp.index = 0
|
||||
temp:randomseed(s)
|
||||
return temp
|
||||
end
|
||||
|
||||
--Linear Congruential Generator
|
||||
linear_congruential_generator = {}
|
||||
linear_congruential_generator.__index = linear_congruential_generator
|
||||
|
||||
function linear_congruential_generator:random(a, b)
|
||||
local y = (self.a * self.x + self.c) % self.m
|
||||
self.x = y
|
||||
if not a then return y / 0x10000
|
||||
elseif not b then
|
||||
if a == 0 then return y
|
||||
else return 1 + (y % a) end
|
||||
else
|
||||
return a + (y % (b - a + 1))
|
||||
end
|
||||
end
|
||||
|
||||
function linear_congruential_generator:randomseed(s)
|
||||
if not s then s = seed() end
|
||||
self.x = normalize(s)
|
||||
end
|
||||
|
||||
function _M.lcg(s, r)
|
||||
local temp = {}
|
||||
setmetatable(temp, linear_congruential_generator)
|
||||
temp.a, temp.c, temp.m = 1103515245, 12345, 0x10000 --from Ansi C
|
||||
if r then
|
||||
if r == 'nr' then temp.a, temp.c, temp.m = 1664525, 1013904223, 0x10000 --from Numerical Recipes.
|
||||
elseif r == 'mvc' then temp.a, temp.c, temp.m = 214013, 2531011, 0x10000 end--from MVC
|
||||
end
|
||||
temp:randomseed(s)
|
||||
return temp
|
||||
end
|
||||
|
||||
-- Multiply-with-carry
|
||||
multiply_with_carry = {}
|
||||
multiply_with_carry.__index = multiply_with_carry
|
||||
|
||||
function multiply_with_carry:random(a, b)
|
||||
local m = self.m
|
||||
local t = self.a * self.x + self.c
|
||||
local y = t % m
|
||||
self.x = y
|
||||
self.c = floor(t / m)
|
||||
if not a then return y / 0x10000
|
||||
elseif not b then
|
||||
if a == 0 then return y
|
||||
else return 1 + (y % a) end
|
||||
else
|
||||
local diff = 0
|
||||
if a == b then return a end
|
||||
if a < 0 then
|
||||
diff = abs(a)
|
||||
a = a + diff
|
||||
b = b + diff
|
||||
end
|
||||
return a + (y % (b - a + 1)) - diff
|
||||
end
|
||||
end
|
||||
|
||||
function multiply_with_carry:randomseed(s)
|
||||
if not s then s = seed() end
|
||||
self.c = self.ic
|
||||
self.x = normalize(s)
|
||||
end
|
||||
|
||||
function _M.mwc(s, r)
|
||||
local temp = {}
|
||||
setmetatable(temp, multiply_with_carry)
|
||||
temp.a, temp.c, temp.m = 1103515245, 12345, 0x10000 --from Ansi C
|
||||
if r then
|
||||
if r == 'nr' then temp.a, temp.c, temp.m = 1664525, 1013904223, 0x10000 --from Numerical Recipes.
|
||||
elseif r == 'mvc' then temp.a, temp.c, temp.m = 214013, 2531011, 0x10000 end--from MVC
|
||||
end
|
||||
temp.ic = temp.c
|
||||
temp:randomseed(s)
|
||||
return temp
|
||||
end
|
||||
|
||||
function _M.mwvc(s)
|
||||
return _M.mwc(s, 'mvc')
|
||||
end
|
||||
|
||||
local B = 0x10000
|
||||
|
||||
-- rough adaptation of Knuth float generator
|
||||
function _M.krandom( seedobj, fVal1, fVal2 )
|
||||
local ma = seedobj.ma
|
||||
local seed = seedobj.seed
|
||||
local mj, mk
|
||||
if seed < 0 or not ma then
|
||||
ma = {}
|
||||
seedobj.ma = ma
|
||||
mj = normalize( seed )
|
||||
mj = mod( mj, B )
|
||||
ma[55] = mj
|
||||
mk = 1
|
||||
for i = 1, 54 do
|
||||
local ii = mod( 21 * i, 55 )
|
||||
ma[ii] = mk
|
||||
mk = mj - mk
|
||||
if mk < 0 then mk = mk + B end
|
||||
mj = ma[ii]
|
||||
end
|
||||
for k = 1, 4 do
|
||||
for i = 1, 55 do
|
||||
ma[i] = ma[i] - ma[ 1 + mod( i + 30, 55) ]
|
||||
if ma[i] < 0 then ma[i] = ma[i] + B end
|
||||
end
|
||||
end
|
||||
seedobj.inext = 0
|
||||
seedobj.inextp = 31
|
||||
seedobj.seed = 1
|
||||
end -- if
|
||||
local inext = seedobj.inext
|
||||
local inextp = seedobj.inextp
|
||||
inext = inext + 1
|
||||
if inext == 56 then inext = 1 end
|
||||
seedobj.inext = inext
|
||||
inextp = inextp + 1
|
||||
if inextp == 56 then inextp = 1 end
|
||||
seedobj.inextp = inextp
|
||||
mj = ma[ inext ] - ma[ inextp ]
|
||||
if mj < 0 then mj = mj + B end
|
||||
ma[ inext ] = mj
|
||||
local temp_rand = mj / B
|
||||
if fVal2 then
|
||||
return floor( fVal1 + 0.5 + temp_rand * ( fVal2 - fVal1 ) )
|
||||
elseif fVal1 then
|
||||
return floor( temp_rand * fVal1 ) + 1
|
||||
else
|
||||
return temp_rand
|
||||
end
|
||||
end
|
||||
|
||||
-- Sys rand
|
||||
sys_rand = {}
|
||||
sys_rand.__index = sys_rand
|
||||
function sys_rand:random(a, b)
|
||||
local diff = 0
|
||||
if a and b and a == b then math.random(); return a end
|
||||
if a and b then
|
||||
if a < 0 then
|
||||
diff = abs(a)
|
||||
a = a + diff
|
||||
b = b + diff
|
||||
end
|
||||
return math.random(a, b) - diff
|
||||
end
|
||||
if a and a == 0 then return floor(math.random() * 0x10000) end
|
||||
if a then return math.random(a) end
|
||||
return math.random()
|
||||
end
|
||||
|
||||
function sys_rand:randomseed(s)
|
||||
-- ignore
|
||||
return
|
||||
end
|
||||
|
||||
function _M.sys_rand(s)
|
||||
local temp = {}
|
||||
setmetatable(temp, sys_rand)
|
||||
return temp
|
||||
end
|
||||
|
||||
return _M
|
@ -1,104 +1,104 @@
|
||||
--[[--
|
||||
Metaball implementation for LUA by Dark
|
||||
For bruteforce usage, nor efficient nor fast
|
||||
|
||||
Force scales to from inf to 1 at R
|
||||
--]]--
|
||||
local _M = {}
|
||||
local sqrt = math.sqrt
|
||||
local cos = math.cos
|
||||
local sin = math.sin
|
||||
local abs = math.abs
|
||||
local zero_value = 0x80000000
|
||||
|
||||
--Classic ball
|
||||
local MetaBall = {x=0, y=0, radius=0, goo=1, type="MetaBall"}
|
||||
MetaBall.__index = MetaBall
|
||||
_M.MetaBall=MetaBall
|
||||
|
||||
function MetaBall:new(x, y, radius, goo)
|
||||
goo = goo or 1
|
||||
return setmetatable({x=x, y=y, radius=radius, goo=goo}, MetaBall)
|
||||
end
|
||||
|
||||
function MetaBall:force(x, y)
|
||||
--Calculate force at point x y
|
||||
local force = sqrt( (x - self.x)^2 + (y - self.y)^2 )
|
||||
if force == 0 then return zero_value end
|
||||
return (self.radius / force)^self.goo
|
||||
end
|
||||
|
||||
--Ellipse
|
||||
local MetaEllipse = {x=0, y=0, radius=0, angle=0, x_scale=1, y_scale=1, type="MetaEllipse"}
|
||||
MetaEllipse.__index = MetaEllipse
|
||||
_M.MetaEllipse=MetaEllipse
|
||||
|
||||
function MetaEllipse:new(x, y, radius, angle, x_scale, y_scale, goo)
|
||||
angle = angle or 0
|
||||
x_scale = x_scale or 1
|
||||
y_scale = y_scale or 1
|
||||
goo = goo or 1
|
||||
cosa = cos(angle)
|
||||
sina = sin(angle)
|
||||
return setmetatable({x=x, y=y, radius=radius, angle=angle, x_scale=x_scale, y_scale=y_scale, goo=goo, cosa=cosa, sina=sina}, MetaEllipse)
|
||||
end
|
||||
|
||||
function MetaEllipse:force(x, y)
|
||||
--Calculate force at point x y
|
||||
local force = sqrt( (( (x - self.x)*self.cosa + (y - self.y)*self.sina )^2)/(self.x_scale) +
|
||||
(( (y - self.y)*self.cosa - (x - self.x)*self.sina )^2)/(self.y_scale) )
|
||||
if force == 0 then return zero_value end
|
||||
return (self.radius / force)^self.goo
|
||||
end
|
||||
|
||||
--SquareBalls
|
||||
local MetaSquare = {x=0, y=0, radius=0, angle=0, x_scale=1, y_scale=1, type="MetaSquare"}
|
||||
MetaSquare.__index = MetaSquare
|
||||
_M.MetaSquare=MetaSquare
|
||||
|
||||
function MetaSquare:new(x, y, radius, angle, x_scale, y_scale, goo)
|
||||
angle = angle or 0
|
||||
x_scale = x_scale or 1
|
||||
y_scale = y_scale or 1
|
||||
goo = goo or 1
|
||||
cosa = cos(angle)
|
||||
sina = sin(angle)
|
||||
return setmetatable({x=x, y=y, radius=radius, angle=angle, x_scale=x_scale, y_scale=y_scale, goo=goo, cosa=cosa, sina=sina}, MetaSquare)
|
||||
end
|
||||
|
||||
function MetaSquare:force(x, y)
|
||||
--Calculate force at point x y
|
||||
local force = ( abs( (x - self.x)*self.cosa + (y - self.y)*self.sina )/self.x_scale +
|
||||
abs( (y - self.y)*self.cosa - (x - self.x)*self.sina )/self.y_scale )
|
||||
if force == 0 then return zero_value end
|
||||
return (self.radius / force)^self.goo
|
||||
end
|
||||
|
||||
--Donuts
|
||||
local MetaDonut = {x=0, y=0, radius=0, angle=0, x_scale=1, y_scale=1, type="MetaDonut"}
|
||||
MetaDonut.__index = MetaDonut
|
||||
_M.MetaDonut=MetaDonut
|
||||
|
||||
function MetaDonut:new(x, y, out_r, int_r, angle, x_scale, y_scale, goo)
|
||||
angle = angle or 0
|
||||
x_scale = x_scale or 1
|
||||
y_scale = y_scale or 1
|
||||
goo = goo or 1
|
||||
cosa = cos(angle)
|
||||
sina = sin(angle)
|
||||
if int_r >= out_r then error("int_r >= out_r ("..int_r.." > "..out_r); return; end
|
||||
local radius = out_r--(out_r - int_r)*0.5
|
||||
local radius2 = int_r--(radius2 + radius)*0.5
|
||||
return setmetatable({x=x, y=y, radius=radius, radius2=radius2, x_scale=x_scale, y_scale=y_scale, goo=goo, cosa=cosa, sina=sina}, MetaDonut)
|
||||
end
|
||||
|
||||
function MetaDonut:force(x, y)
|
||||
--Calculate force at point x y
|
||||
local force = abs(self.radius - sqrt( (( (x - self.x)*self.cosa + (y - self.y)*self.sina )^2)/(self.x_scale) +
|
||||
(( (y - self.y)*self.cosa - (x - self.x)*self.sina )^2)/(self.y_scale) ))
|
||||
if force == 0 then return zero_value end
|
||||
return (self.radius2 / force)^self.goo
|
||||
|
||||
end
|
||||
|
||||
--[[--
|
||||
Metaball implementation for LUA by Dark
|
||||
For bruteforce usage, nor efficient nor fast
|
||||
|
||||
Force scales to from inf to 1 at R
|
||||
--]]--
|
||||
local _M = {}
|
||||
local sqrt = math.sqrt
|
||||
local cos = math.cos
|
||||
local sin = math.sin
|
||||
local abs = math.abs
|
||||
local zero_value = 0x80000000
|
||||
|
||||
--Classic ball
|
||||
local MetaBall = {x=0, y=0, radius=0, goo=1, type="MetaBall"}
|
||||
MetaBall.__index = MetaBall
|
||||
_M.MetaBall=MetaBall
|
||||
|
||||
function MetaBall:new(x, y, radius, goo)
|
||||
goo = goo or 1
|
||||
return setmetatable({x=x, y=y, radius=radius, goo=goo}, MetaBall)
|
||||
end
|
||||
|
||||
function MetaBall:force(x, y)
|
||||
--Calculate force at point x y
|
||||
local force = sqrt( (x - self.x)^2 + (y - self.y)^2 )
|
||||
if force == 0 then return zero_value end
|
||||
return (self.radius / force)^self.goo
|
||||
end
|
||||
|
||||
--Ellipse
|
||||
local MetaEllipse = {x=0, y=0, radius=0, angle=0, x_scale=1, y_scale=1, type="MetaEllipse"}
|
||||
MetaEllipse.__index = MetaEllipse
|
||||
_M.MetaEllipse=MetaEllipse
|
||||
|
||||
function MetaEllipse:new(x, y, radius, angle, x_scale, y_scale, goo)
|
||||
angle = angle or 0
|
||||
x_scale = x_scale or 1
|
||||
y_scale = y_scale or 1
|
||||
goo = goo or 1
|
||||
cosa = cos(angle)
|
||||
sina = sin(angle)
|
||||
return setmetatable({x=x, y=y, radius=radius, angle=angle, x_scale=x_scale, y_scale=y_scale, goo=goo, cosa=cosa, sina=sina}, MetaEllipse)
|
||||
end
|
||||
|
||||
function MetaEllipse:force(x, y)
|
||||
--Calculate force at point x y
|
||||
local force = sqrt( (( (x - self.x)*self.cosa + (y - self.y)*self.sina )^2)/(self.x_scale) +
|
||||
(( (y - self.y)*self.cosa - (x - self.x)*self.sina )^2)/(self.y_scale) )
|
||||
if force == 0 then return zero_value end
|
||||
return (self.radius / force)^self.goo
|
||||
end
|
||||
|
||||
--SquareBalls
|
||||
local MetaSquare = {x=0, y=0, radius=0, angle=0, x_scale=1, y_scale=1, type="MetaSquare"}
|
||||
MetaSquare.__index = MetaSquare
|
||||
_M.MetaSquare=MetaSquare
|
||||
|
||||
function MetaSquare:new(x, y, radius, angle, x_scale, y_scale, goo)
|
||||
angle = angle or 0
|
||||
x_scale = x_scale or 1
|
||||
y_scale = y_scale or 1
|
||||
goo = goo or 1
|
||||
cosa = cos(angle)
|
||||
sina = sin(angle)
|
||||
return setmetatable({x=x, y=y, radius=radius, angle=angle, x_scale=x_scale, y_scale=y_scale, goo=goo, cosa=cosa, sina=sina}, MetaSquare)
|
||||
end
|
||||
|
||||
function MetaSquare:force(x, y)
|
||||
--Calculate force at point x y
|
||||
local force = ( abs( (x - self.x)*self.cosa + (y - self.y)*self.sina )/self.x_scale +
|
||||
abs( (y - self.y)*self.cosa - (x - self.x)*self.sina )/self.y_scale )
|
||||
if force == 0 then return zero_value end
|
||||
return (self.radius / force)^self.goo
|
||||
end
|
||||
|
||||
--Donuts
|
||||
local MetaDonut = {x=0, y=0, radius=0, angle=0, x_scale=1, y_scale=1, type="MetaDonut"}
|
||||
MetaDonut.__index = MetaDonut
|
||||
_M.MetaDonut=MetaDonut
|
||||
|
||||
function MetaDonut:new(x, y, out_r, int_r, angle, x_scale, y_scale, goo)
|
||||
angle = angle or 0
|
||||
x_scale = x_scale or 1
|
||||
y_scale = y_scale or 1
|
||||
goo = goo or 1
|
||||
cosa = cos(angle)
|
||||
sina = sin(angle)
|
||||
if int_r >= out_r then error("int_r >= out_r ("..int_r.." > "..out_r); return; end
|
||||
local radius = out_r--(out_r - int_r)*0.5
|
||||
local radius2 = int_r--(radius2 + radius)*0.5
|
||||
return setmetatable({x=x, y=y, radius=radius, radius2=radius2, x_scale=x_scale, y_scale=y_scale, goo=goo, cosa=cosa, sina=sina}, MetaDonut)
|
||||
end
|
||||
|
||||
function MetaDonut:force(x, y)
|
||||
--Calculate force at point x y
|
||||
local force = abs(self.radius - sqrt( (( (x - self.x)*self.cosa + (y - self.y)*self.sina )^2)/(self.x_scale) +
|
||||
(( (y - self.y)*self.cosa - (x - self.x)*self.sina )^2)/(self.y_scale) ))
|
||||
if force == 0 then return zero_value end
|
||||
return (self.radius2 / force)^self.goo
|
||||
|
||||
end
|
||||
|
||||
return _M
|
49
locale/rso/prototype_utils.lua
Normal file
49
locale/rso/prototype_utils.lua
Normal file
@ -0,0 +1,49 @@
|
||||
require("locale/rso/rso_config")
|
||||
|
||||
function add_peak(ent, peak)
|
||||
if ent and ent.autoplace then
|
||||
ent.autoplace.peaks[#ent.autoplace.peaks+1] = peak
|
||||
end
|
||||
end
|
||||
|
||||
function change_ocataves(autoplace, octaves)
|
||||
for k,v in pairs(autoplace.peaks) do
|
||||
if v.noise_layer then
|
||||
v.noise_octaves_difference = (v.noise_octaves_difference or 0) + octaves
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function generate_basic_peaks(noise_layer)
|
||||
return {
|
||||
{
|
||||
influence = 0.1
|
||||
},
|
||||
{
|
||||
influence = 0.67,
|
||||
noise_layer = noise_layer,
|
||||
noise_octaves_difference = -2.7,
|
||||
noise_persistence = 0.3
|
||||
}
|
||||
}
|
||||
|
||||
end
|
||||
|
||||
function resetRichness(ent)
|
||||
if ent and ent.autoplace then
|
||||
ent.autoplace.richness_multiplier = 0
|
||||
ent.autoplace.richness_base = 0
|
||||
end
|
||||
end
|
||||
|
||||
function removeAutoplace(ent)
|
||||
if ent then
|
||||
ent.autoplace = nil
|
||||
end
|
||||
end
|
||||
|
||||
function removePeaks(ent)
|
||||
if ent and ent.autoplace then
|
||||
ent.autoplace.peaks = {}
|
||||
end
|
||||
end
|
@ -1,55 +1,57 @@
|
||||
debug_enabled = false
|
||||
|
||||
region_size = 10 -- alternative mean to control how further away resources would be, default - 256 tiles or 8 chunks
|
||||
-- each region is region_size*region_size chunks
|
||||
-- each chunk is 32*32 tiles
|
||||
|
||||
use_donut_shapes = false -- setting this to false will remove donuts from possible resource layouts
|
||||
|
||||
starting_area_size = 0 -- starting area in regions, safe from random nonsense
|
||||
|
||||
absolute_resource_chance = 0.50 -- chance to spawn an resource in a region
|
||||
starting_richness_mult = 1 -- multiply starting area richness for resources
|
||||
global_richness_mult = 1 -- multiply richness for all resources except starting area
|
||||
global_size_mult = 1 -- multiply size for all ores, doesn't affect starting area
|
||||
|
||||
absolute_enemy_chance = 3 -- chance to spawn enemies per sector (can be more then one base if spawned)
|
||||
enemy_base_size_multiplier = 1 -- all base sizes will be multiplied by this - larger number means bigger bases
|
||||
|
||||
multi_resource_active = false -- global switch for multi resource chances
|
||||
multi_resource_richness_factor = 0.60 -- any additional resource is multiplied by this value times resources-1
|
||||
multi_resource_size_factor = 0.90
|
||||
multi_resource_chance_diminish = 0.6 -- diminishing effect factor on multi_resource_chance
|
||||
|
||||
min_amount=250 -- default value for minimum amount of resource in single pile
|
||||
|
||||
richness_distance_factor= 1 -- exponent for richness distance factor calculation
|
||||
fluid_richness_distance_factor = 0.8 -- exponent for richness distance factor calculation for fluids
|
||||
size_distance_factor=0.15 -- exponent for size distance factor calculation
|
||||
|
||||
deterministic = false -- set to false to use system for all decisions math.random
|
||||
|
||||
-- mode is no longer used by generation process - it autodetects endless resources
|
||||
-- endless_resource_mode = false -- if true, the size of each resource is modified by the following modifier. Use with the endless resources mod.
|
||||
endless_resource_mode_sizeModifier = 0.80
|
||||
|
||||
-- This setting isn't used anywhere in the soft mod version of RSO -- OARC
|
||||
-- Just set it from Oarc's config.lua (look for ENEMY_EXPANSION)
|
||||
-- disableEnemyExpansion = false -- allows for disabling of in-game biter base building
|
||||
|
||||
use_RSO_biter_spawning = true -- enables spawning of biters controlled by RSO mod - less enemies around with more space between bases
|
||||
use_vanilla_biter_spawning = false -- enables using of vanilla spawning
|
||||
|
||||
biter_ratio_segment=3 --the ratio components determining how many biters to spitters will be spawned
|
||||
spitter_ratio_segment=1 --eg. 1 and 1 -> equal number of biters and spitters, 10 and 1 -> 10 times as many biters to spitters
|
||||
|
||||
useEnemiesInPeaceMod = false -- additional override for peace mod detection - when set to true it will spawn enemies normally, needs to have enemies enabled in peace mod
|
||||
|
||||
-- Always leave this setting to true in this soft mod scenario version! -- OARC
|
||||
ignoreMapGenSettings = true -- stops the default behaviour of reading map gen settings
|
||||
|
||||
fluidResourcesFactor = 20 -- temporary factor for calculation of resource %-ages for fluids
|
||||
--
|
||||
useResourceCollisionDetection = true -- enables avoidace calculations to reduce ores overlaping of each other
|
||||
resourceCollisionDetectionRatio = 0.8 -- at least this much of ore field needs to be placable to spawn it
|
||||
resourceCollisionFieldSkip = true -- determines if ore field should be skipped completely if placement based on ratio failed
|
||||
debug_enabled = false
|
||||
|
||||
region_size = 10 -- alternative mean to control how further away resources would be, default - 256 tiles or 8 chunks
|
||||
-- each region is region_size*region_size chunks
|
||||
-- each chunk is 32*32 tiles
|
||||
|
||||
use_donut_shapes = false -- setting this to false will remove donuts from possible resource layouts
|
||||
|
||||
starting_area_size = 1 -- starting area in regions, safe from random nonsense
|
||||
|
||||
absolute_resource_chance = 0.40 -- chance to spawn an resource in a region
|
||||
starting_richness_mult = 1 -- multiply starting area richness for resources
|
||||
global_richness_mult = 1 -- multiply richness for all resources except starting area
|
||||
global_size_mult = 1 -- multiply size for all ores, doesn't affect starting area
|
||||
|
||||
absolute_enemy_chance = 3 -- chance to spawn enemies per sector (can be more then one base if spawned)
|
||||
enemy_base_size_multiplier = 1 -- all base sizes will be multiplied by this - larger number means bigger bases
|
||||
|
||||
multi_resource_active = false -- global switch for multi resource chances
|
||||
multi_resource_richness_factor = 0.60 -- any additional resource is multiplied by this value times resources-1
|
||||
multi_resource_size_factor = 0.90
|
||||
multi_resource_chance_diminish = 0.6 -- diminishing effect factor on multi_resource_chance
|
||||
|
||||
min_amount=250 -- default value for minimum amount of resource in single pile
|
||||
|
||||
richness_distance_factor= 0.8 -- exponent for richness distance factor calculation
|
||||
fluid_richness_distance_factor = 0.8 -- exponent for richness distance factor calculation for fluids
|
||||
size_distance_factor=0.3 -- exponent for size distance factor calculation
|
||||
|
||||
deterministic = true -- set to false to use system for all decisions math.random
|
||||
|
||||
-- mode is no longer used by generation process - it autodetects endless resources
|
||||
-- endless_resource_mode = false -- if true, the size of each resource is modified by the following modifier. Use with the endless resources mod.
|
||||
endless_resource_mode_sizeModifier = 0.80
|
||||
|
||||
-- This setting isn't used anywhere in the soft mod version of RSO -- OARC
|
||||
-- Just set it from Oarc's config.lua (look for ENEMY_EXPANSION)
|
||||
-- disableEnemyExpansion = false -- allows for disabling of in-game biter base building
|
||||
|
||||
use_RSO_biter_spawning = true -- enables spawning of biters controlled by RSO mod - less enemies around with more space between bases
|
||||
use_vanilla_biter_spawning = false -- enables using of vanilla spawning
|
||||
|
||||
biter_ratio_segment=3 --the ratio components determining how many biters to spitters will be spawned
|
||||
spitter_ratio_segment=1 --eg. 1 and 1 -> equal number of biters and spitters, 10 and 1 -> 10 times as many biters to spitters
|
||||
|
||||
useEnemiesInPeaceMod = false -- additional override for peace mod detection - when set to true it will spawn enemies normally, needs to have enemies enabled in peace mod
|
||||
|
||||
-- Always leave this setting to true in this soft mod scenario version! -- OARC
|
||||
ignoreMapGenSettings = true -- stops the default behaviour of reading map gen settings
|
||||
--
|
||||
useResourceCollisionDetection = true -- enables avoidace calculations to reduce ores overlaping of each other
|
||||
resourceCollisionDetectionRatio = 0.999 -- threshold to exit placement early
|
||||
resourceCollisionDetectionRatioFallback = 0.75 -- at least this much of ore field needs to be placable to spawn it
|
||||
resourceCollisionFieldSkip = true -- determines if ore field should be skipped completely if placement based on ratio failed
|
||||
|
||||
remove_trees = false
|
||||
reveal_spawn_resources = false
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,171 +1,171 @@
|
||||
|
||||
local function fillVanillaConfig()
|
||||
|
||||
config["iron-ore"] = {
|
||||
type="resource-ore",
|
||||
|
||||
-- general spawn params
|
||||
allotment=100, -- how common resource is
|
||||
spawns_per_region={min=1, max=1}, --number of chunks
|
||||
richness=10000, -- resource_ore has only one richness value - resource-liquid has min/max
|
||||
|
||||
size={min=15, max=25}, -- rough radius of area, too high value can produce square shaped areas
|
||||
min_amount=350,
|
||||
|
||||
-- resource provided at starting location
|
||||
-- probability: 1 = 100% chance to be in starting area
|
||||
-- 0 = resource is not in starting area
|
||||
starting={richness=8000, size=25, probability=1},
|
||||
|
||||
multi_resource_chance=0.20, -- absolute value
|
||||
multi_resource={
|
||||
["iron-ore"] = 2, -- ["resource_name"] = allotment
|
||||
['copper-ore'] = 4,
|
||||
["coal"] = 4,
|
||||
["stone"] = 4,
|
||||
}
|
||||
}
|
||||
|
||||
config["copper-ore"] = {
|
||||
type="resource-ore",
|
||||
|
||||
allotment=90,
|
||||
spawns_per_region={min=1, max=1},
|
||||
richness=10000,
|
||||
size={min=15, max=25},
|
||||
min_amount=350,
|
||||
|
||||
starting={richness=6000, size=25, probability=1},
|
||||
|
||||
multi_resource_chance=0.20,
|
||||
multi_resource={
|
||||
["iron-ore"] = 4,
|
||||
['copper-ore'] = 2,
|
||||
["coal"] = 4,
|
||||
["stone"] = 4,
|
||||
}
|
||||
}
|
||||
|
||||
config["coal"] = {
|
||||
type="resource-ore",
|
||||
|
||||
allotment=80,
|
||||
|
||||
spawns_per_region={min=1, max=1},
|
||||
size={min=15, max=25},
|
||||
richness=8000,
|
||||
min_amount=350,
|
||||
|
||||
starting={richness=6000, size=20, probability=1},
|
||||
|
||||
multi_resource_chance=0.30,
|
||||
multi_resource={
|
||||
["crude-oil"] = 1,
|
||||
["iron-ore"] = 3,
|
||||
['copper-ore'] = 3,
|
||||
}
|
||||
}
|
||||
|
||||
config["stone"] = {
|
||||
type="resource-ore",
|
||||
|
||||
allotment=60,
|
||||
spawns_per_region={min=1, max=1},
|
||||
richness=6000,
|
||||
size={min=15, max=20},
|
||||
min_amount=250,
|
||||
|
||||
starting={richness=5000, size=16, probability=1},
|
||||
|
||||
multi_resource_chance=0.30,
|
||||
multi_resource={
|
||||
["coal"] = 4,
|
||||
["iron-ore"] = 3,
|
||||
['copper-ore'] = 3,
|
||||
}
|
||||
}
|
||||
|
||||
config["uranium-ore"] = {
|
||||
type="resource-ore",
|
||||
|
||||
allotment=50,
|
||||
spawns_per_region={min=1, max=1},
|
||||
richness=10000,
|
||||
size={min=15, max=20},
|
||||
min_amount=500,
|
||||
|
||||
starting={richness=2000, size=10, probability=1},
|
||||
}
|
||||
|
||||
config["crude-oil"] = {
|
||||
type="resource-liquid",
|
||||
minimum_amount=10000,
|
||||
allotment=70,
|
||||
spawns_per_region={min=1, max=2},
|
||||
richness={min=100000, max=200000}, -- richness per resource spawn
|
||||
size={min=3, max=7},
|
||||
|
||||
starting={richness=200000, size=2, probability=1},
|
||||
|
||||
multi_resource_chance=0.20,
|
||||
multi_resource={
|
||||
["coal"] = 4,
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
local function fillEnemies()
|
||||
|
||||
config["enemy-base"] = {
|
||||
type="entity",
|
||||
force="enemy",
|
||||
clear_range = {6, 6},
|
||||
|
||||
spawns_per_region={min=2,max=4},
|
||||
size={min=2,max=4},
|
||||
size_per_region_factor=1,
|
||||
richness=3,
|
||||
|
||||
absolute_probability=absolute_enemy_chance, -- chance to spawn in region
|
||||
probability_distance_factor=1.1, -- relative increase per region
|
||||
max_probability_distance_factor=3, -- absolute value
|
||||
|
||||
along_resource_probability=0.20, -- chance to spawn in resource chunk anyway, absolute value. Can happen once per resource.
|
||||
|
||||
sub_spawn_probability=0.1, -- chance for this entity to spawn anything from sub_spawns table, absolute value
|
||||
sub_spawn_size={min=1, max=2}, -- in same chunk
|
||||
sub_spawn_distance_factor=1.01,
|
||||
sub_spawn_max_distance_factor=1.5,
|
||||
sub_spawns={
|
||||
["small-worm-turret"]={
|
||||
min_distance=0,
|
||||
allotment=200,
|
||||
allotment_distance_factor=0.99,
|
||||
clear_range = {2, 2},
|
||||
},
|
||||
["medium-worm-turret"]={
|
||||
min_distance=10,
|
||||
allotment=100,
|
||||
allotment_distance_factor=1.01,
|
||||
clear_range = {2, 2},
|
||||
},
|
||||
["big-worm-turret"]={
|
||||
min_distance=20,
|
||||
allotment=100,
|
||||
allotment_distance_factor=1.015,
|
||||
clear_range = {2, 2},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
end
|
||||
|
||||
function loadResourceConfig()
|
||||
|
||||
config={}
|
||||
|
||||
fillVanillaConfig()
|
||||
fillEnemies()
|
||||
|
||||
return config
|
||||
|
||||
local function fillVanillaConfig()
|
||||
|
||||
config["iron-ore"] = {
|
||||
type="resource-ore",
|
||||
|
||||
-- general spawn params
|
||||
allotment=90, -- how common resource is
|
||||
spawns_per_region={min=1, max=1}, --number of chunks
|
||||
richness=20000, -- resource_ore has only one richness value - resource-liquid has min/max
|
||||
|
||||
size={min=15, max=25}, -- rough radius of area, too high value can produce square shaped areas
|
||||
min_amount=350,
|
||||
|
||||
-- resource provided at starting location
|
||||
-- probability: 1 = 100% chance to be in starting area
|
||||
-- 0 = resource is not in starting area
|
||||
starting={richness=8000, size=25, probability=1},
|
||||
|
||||
multi_resource_chance=0.20, -- absolute value
|
||||
multi_resource={
|
||||
["iron-ore"] = 2, -- ["resource_name"] = allotment
|
||||
['copper-ore'] = 4,
|
||||
["coal"] = 4,
|
||||
["stone"] = 4,
|
||||
}
|
||||
}
|
||||
|
||||
config["copper-ore"] = {
|
||||
type="resource-ore",
|
||||
|
||||
allotment=80,
|
||||
spawns_per_region={min=1, max=1},
|
||||
richness=20000,
|
||||
size={min=15, max=25},
|
||||
min_amount=350,
|
||||
|
||||
starting={richness=6000, size=25, probability=1},
|
||||
|
||||
multi_resource_chance=0.20,
|
||||
multi_resource={
|
||||
["iron-ore"] = 4,
|
||||
['copper-ore'] = 2,
|
||||
["coal"] = 4,
|
||||
["stone"] = 4,
|
||||
}
|
||||
}
|
||||
|
||||
config["coal"] = {
|
||||
type="resource-ore",
|
||||
|
||||
allotment=80,
|
||||
|
||||
spawns_per_region={min=1, max=1},
|
||||
size={min=15, max=25},
|
||||
richness=16000,
|
||||
min_amount=350,
|
||||
|
||||
starting={richness=6000, size=20, probability=1},
|
||||
|
||||
multi_resource_chance=0.30,
|
||||
multi_resource={
|
||||
["crude-oil"] = 1,
|
||||
["iron-ore"] = 3,
|
||||
['copper-ore'] = 3,
|
||||
}
|
||||
}
|
||||
|
||||
config["stone"] = {
|
||||
type="resource-ore",
|
||||
|
||||
allotment=60,
|
||||
spawns_per_region={min=1, max=1},
|
||||
richness=12000,
|
||||
size={min=15, max=20},
|
||||
min_amount=250,
|
||||
|
||||
starting={richness=5000, size=16, probability=1},
|
||||
|
||||
multi_resource_chance=0.30,
|
||||
multi_resource={
|
||||
["coal"] = 4,
|
||||
["iron-ore"] = 3,
|
||||
['copper-ore'] = 3,
|
||||
}
|
||||
}
|
||||
|
||||
config["uranium-ore"] = {
|
||||
type="resource-ore",
|
||||
|
||||
allotment=50,
|
||||
spawns_per_region={min=1, max=1},
|
||||
richness=10000,
|
||||
size={min=15, max=20},
|
||||
min_amount=500,
|
||||
|
||||
starting={richness=2000, size=10, probability=1},
|
||||
}
|
||||
|
||||
config["crude-oil"] = {
|
||||
type="resource-liquid",
|
||||
minimum_amount=10000,
|
||||
allotment=70,
|
||||
spawns_per_region={min=1, max=1},
|
||||
richness={min=400000, max=1000000}, -- richness per resource spawn
|
||||
size={min=3, max=7},
|
||||
|
||||
starting={richness=400000, size=2, probability=1},
|
||||
|
||||
multi_resource_chance=0.20,
|
||||
multi_resource={
|
||||
["coal"] = 4,
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
local function fillEnemies()
|
||||
|
||||
config["enemy-base"] = {
|
||||
type="entity",
|
||||
force="enemy",
|
||||
clear_range = {6, 6},
|
||||
|
||||
spawns_per_region={min=2,max=4},
|
||||
size={min=2,max=4},
|
||||
size_per_region_factor=0.3,
|
||||
richness=3,
|
||||
|
||||
absolute_probability=absolute_enemy_chance, -- chance to spawn in region
|
||||
probability_distance_factor=1.1, -- relative increase per region
|
||||
max_probability_distance_factor=3, -- absolute value
|
||||
|
||||
along_resource_probability=0.20, -- chance to spawn in resource chunk anyway, absolute value. Can happen once per resource.
|
||||
|
||||
sub_spawn_probability=0.1, -- chance for this entity to spawn anything from sub_spawns table, absolute value
|
||||
sub_spawn_size={min=1, max=2}, -- in same chunk
|
||||
sub_spawn_distance_factor=1.01,
|
||||
sub_spawn_max_distance_factor=1.5,
|
||||
sub_spawns={
|
||||
["small-worm-turret"]={
|
||||
min_distance=0,
|
||||
allotment=200,
|
||||
allotment_distance_factor=0.99,
|
||||
clear_range = {2, 2},
|
||||
},
|
||||
["medium-worm-turret"]={
|
||||
min_distance=10,
|
||||
allotment=100,
|
||||
allotment_distance_factor=1.01,
|
||||
clear_range = {2, 2},
|
||||
},
|
||||
["big-worm-turret"]={
|
||||
min_distance=20,
|
||||
allotment=100,
|
||||
allotment_distance_factor=1.015,
|
||||
clear_range = {2, 2},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
end
|
||||
|
||||
function loadResourceConfig()
|
||||
|
||||
config={}
|
||||
|
||||
fillVanillaConfig()
|
||||
fillEnemies()
|
||||
|
||||
return config
|
||||
end
|
@ -1,5 +1,6 @@
|
||||
-- control.lua
|
||||
-- tag.lua
|
||||
-- Apr 2017
|
||||
-- Allows adding play tags
|
||||
|
||||
function CreateTagGui(event)
|
||||
local player = game.players[event.player_index]
|
||||
|
67
locale/temp/helper_commands.lua
Normal file
67
locale/temp/helper_commands.lua
Normal file
@ -0,0 +1,67 @@
|
||||
-- helper_commands.lua
|
||||
-- Jan 2018
|
||||
-- None of this is my code.
|
||||
|
||||
require("locale/oarc_utils")
|
||||
|
||||
commands.add_command("run", "change player speed bonus", function(command)
|
||||
local player = game.players[command.player_index];
|
||||
if player ~= nil then
|
||||
if (command.parameter ~= nil) then
|
||||
if command.parameter == "fast" then
|
||||
player.character_running_speed_modifier = 1
|
||||
elseif command.parameter == "slow" then
|
||||
player.character_running_speed_modifier = 0
|
||||
else
|
||||
player.print("run fast | slow");
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
commands.add_command("handcraft", "change player speed bonus", function(command)
|
||||
local player = game.players[command.player_index];
|
||||
if player ~= nil then
|
||||
if (command.parameter ~= nil) then
|
||||
if command.parameter == "fast" then
|
||||
player.character_crafting_speed_modifier = 5
|
||||
elseif command.parameter == "slow" then
|
||||
player.character_crafting_speed_modifier = 0
|
||||
else
|
||||
player.print("handcraft fast | slow");
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
commands.add_command("mine", "change player speed bonus", function(command)
|
||||
local player = game.players[command.player_index];
|
||||
if player ~= nil then
|
||||
if (command.parameter ~= nil) then
|
||||
if command.parameter == "fast" then
|
||||
player.character_mining_speed_modifier = 2
|
||||
elseif command.parameter == "slow" then
|
||||
player.character_mining_speed_modifier = 0
|
||||
else
|
||||
player.print("mine fast | slow");
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
commands.add_command("kit", "give a start kit", function(command)
|
||||
local player = game.players[command.player_index];
|
||||
if player ~= nil and player.admin then
|
||||
local target = player
|
||||
if (command.parameter ~= nil) then
|
||||
target = game.players[command.parameter]
|
||||
end
|
||||
if target ~= nil then
|
||||
GivePlayerStarterItems(target);
|
||||
player.print("gave a kit to " .. target.name);
|
||||
target.print("you have been given a start kit");
|
||||
else
|
||||
player.print("no player " .. command.parameter);
|
||||
end
|
||||
end
|
||||
end)
|
49
locale/temp/rgcommand.lua
Normal file
49
locale/temp/rgcommand.lua
Normal file
@ -0,0 +1,49 @@
|
||||
|
||||
local function RemoveTileGhosts()
|
||||
local surface = game.player.surface
|
||||
for c in surface.get_chunks() do
|
||||
for key, entity in pairs(surface.find_entities_filtered({area={{c.x * 32, c.y * 32}, {c.x * 32 + 32, c.y * 32 + 32}}, name= "tile-ghost"})) do
|
||||
entity.destroy()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function RemoveBlueprintedModulesGhosts()
|
||||
local surface = game.player.surface
|
||||
for c in surface.get_chunks() do
|
||||
for key, entity in pairs(surface.find_entities_filtered({area={{c.x * 32, c.y * 32}, {c.x * 32 + 32, c.y * 32 + 32}}, name= "item-request-proxy"})) do
|
||||
entity.destroy()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function RemoveGhostEntities()
|
||||
local surface = game.player.surface
|
||||
for c in surface.get_chunks() do
|
||||
for key, entity in pairs(surface.find_entities_filtered({area={{c.x * 32, c.y * 32}, {c.x * 32 + 32, c.y * 32 + 32}}, name= "entity-ghost"})) do
|
||||
entity.destroy()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
commands.add_command("rg", "remove ghosts", function(command)
|
||||
local player = game.players[command.player_index];
|
||||
if player ~= nil and player.admin then
|
||||
if (command.parameter ~= nil) then
|
||||
if command.parameter == "all" then
|
||||
RemoveTileGhosts()
|
||||
RemoveBlueprintedModulesGhosts()
|
||||
RemoveGhostEntities()
|
||||
elseif command.parameter == "tiles" then
|
||||
RemoveTileGhosts()
|
||||
elseif command.parameter == "modules" then
|
||||
RemoveBlueprintedModulesGhosts()
|
||||
elseif command.parameter == "entities" then
|
||||
RemoveGhostEntities()
|
||||
else
|
||||
player.print("remove all ghostes | tiles | modules | entities");
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
@ -3,7 +3,8 @@
|
||||
--
|
||||
-- Code tracks all chunks generated and allows for deleting inactive chunks
|
||||
-- Relies on some changes to RSO to provide random resource locations the next
|
||||
-- time the land is regenerated.
|
||||
-- time the land is regenerated. -- (THIS IS CURRENTLY NOT WORKING IN 0.16,
|
||||
-- resources always how up in the same spot!)
|
||||
--
|
||||
-- Basic rules of regrowth:
|
||||
-- 1. Area around player is safe for quite a large distance.
|
||||
@ -48,7 +49,7 @@ function OarcRegrowthInit()
|
||||
global.chunk_regrow.min_y = 0
|
||||
global.chunk_regrow.max_y = 0
|
||||
global.chunk_regrow.y_index = 0
|
||||
global.chunk_regrow.force_removal_flag = 0
|
||||
global.chunk_regrow.force_removal_flag = -1000
|
||||
|
||||
OarcRegrowthOffLimits({x=0,y=0}, 10)
|
||||
end
|
||||
@ -320,7 +321,7 @@ 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...")
|
||||
SendBroadcastMsg("Map cleanup in 10 seconds, if you don't want to lose what you found drop a powered radar on it!")
|
||||
end
|
||||
end
|
||||
|
||||
@ -328,7 +329,7 @@ function OarcRegrowthOnTick()
|
||||
if ((game.tick % REGROWTH_CLEANING_INTERVAL_TICKS) == REGROWTH_CLEANING_INTERVAL_TICKS-1) then
|
||||
if (#global.chunk_regrow.removal_list > 100) then
|
||||
OarcRegrowthRemoveAllChunks()
|
||||
SendBroadcastMsg("Map cleanup done...")
|
||||
SendBroadcastMsg("Map cleanup done, sorry for your loss.")
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -339,10 +340,10 @@ end
|
||||
function OarcRegrowthForceRemovalOnTick()
|
||||
-- Catch force remove flag
|
||||
if (game.tick == global.chunk_regrow.force_removal_flag+60) then
|
||||
SendBroadcastMsg("Map cleanup in 10 seconds...")
|
||||
SendBroadcastMsg("Map cleanup in 10 seconds, if you don't want to lose what you found drop a powered radar on it!")
|
||||
end
|
||||
if (game.tick == global.chunk_regrow.force_removal_flag+660) then
|
||||
OarcRegrowthRemoveAllChunks()
|
||||
SendBroadcastMsg("Map cleanup done...")
|
||||
SendBroadcastMsg("Map cleanup done, sorry for your loss.")
|
||||
end
|
||||
end
|
@ -36,7 +36,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.
|
||||
CreateSpawnAreas(surface, chunkArea, global.uniqueSpawns)
|
||||
SetupAndClearSpawnAreas(surface, chunkArea, global.uniqueSpawns)
|
||||
end
|
||||
|
||||
|
||||
@ -53,6 +53,16 @@ function FindUnusedSpawns(event)
|
||||
global.playerSpawns[player.name] = nil
|
||||
end
|
||||
|
||||
-- Remove them from the delayer spawn queue if they are in it
|
||||
for i=#global.delayedSpawns,1,-1 do
|
||||
delayedSpawn = global.delayedSpawns[i]
|
||||
|
||||
if (player.name == delayedSpawn.playerName) then
|
||||
table.remove(global.delayedSpawns, i)
|
||||
DebugPrint("Removing player from delayed spawn queue: " .. player.name)
|
||||
end
|
||||
end
|
||||
|
||||
-- Transfer or remove a shared spawn if player is owner
|
||||
if (global.sharedSpawns[player.name] ~= nil) then
|
||||
|
||||
@ -68,9 +78,21 @@ function FindUnusedSpawns(event)
|
||||
|
||||
-- If a uniqueSpawn was created for the player, mark it as unused.
|
||||
if (global.uniqueSpawns[player.name] ~= nil) then
|
||||
if ENABLE_ABANDONED_BASE_REMOVAL then
|
||||
local spawnPos = global.uniqueSpawns[player.name].pos
|
||||
|
||||
local spawnPos = global.uniqueSpawns[player.name].pos
|
||||
|
||||
-- Check if it was near someone else's base.
|
||||
nearOtherSpawn = false
|
||||
for spawnPlayerName,otherSpawnPos in pairs(global.uniqueSpawns) do
|
||||
if ((spawnPlayerName ~= player.name) and (getDistance(spawnPos, otherSpawnPos.pos) < (ENFORCE_LAND_AREA_TILE_DIST*3))) then
|
||||
DebugPrint("Won't remove base as it's close to another spawn: " .. spawnPlayerName)
|
||||
nearOtherSpawn = true
|
||||
end
|
||||
end
|
||||
|
||||
if (ENABLE_ABANDONED_BASE_REMOVAL and not nearOtherSpawn) then
|
||||
global.uniqueSpawns[player.name] = nil
|
||||
|
||||
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
|
||||
@ -166,8 +188,11 @@ function GetNumberOfAvailableSharedSpawns()
|
||||
local count = 0
|
||||
|
||||
for ownerName,sharedSpawn in pairs(global.sharedSpawns) do
|
||||
if (sharedSpawn.openAccess) then
|
||||
if (GetOnlinePlayersAtSharedSpawn(ownerName) < MAX_ONLINE_PLAYERS_AT_SHARED_SPAWN) then
|
||||
if (sharedSpawn.openAccess and
|
||||
(game.players[ownerName] ~= nil) and
|
||||
game.players[ownerName].connected) then
|
||||
if ((MAX_ONLINE_PLAYERS_AT_SHARED_SPAWN == 0) or
|
||||
(GetOnlinePlayersAtSharedSpawn(ownerName) < MAX_ONLINE_PLAYERS_AT_SHARED_SPAWN)) then
|
||||
count = count+1
|
||||
end
|
||||
end
|
||||
@ -197,12 +222,28 @@ function InitSpawnGlobalsAndForces()
|
||||
if (global.playerCooldowns == nil) then
|
||||
global.playerCooldowns = {}
|
||||
end
|
||||
if (global.waitingBuddies == nil) then
|
||||
global.waitingBuddies = {}
|
||||
end
|
||||
if (global.delayedSpawns == nil) then
|
||||
global.delayedSpawns = {}
|
||||
end
|
||||
if (global.buddySpawnOptions == nil) then
|
||||
global.buddySpawnOptions = {}
|
||||
end
|
||||
|
||||
game.create_force(MAIN_FORCE)
|
||||
game.forces[MAIN_FORCE].set_spawn_position(game.forces["player"].get_spawn_position(GAME_SURFACE_NAME), GAME_SURFACE_NAME)
|
||||
|
||||
if ENABLE_SHARED_TEAM_VISION then
|
||||
game.forces[MAIN_FORCE].share_chart = true
|
||||
end
|
||||
|
||||
SetCeaseFireBetweenAllForces()
|
||||
SetFriendlyBetweenAllForces()
|
||||
-- AntiGriefing(game.forces[MAIN_FORCE])
|
||||
if (ENABLE_ANTI_GRIEFING) then
|
||||
AntiGriefing(game.forces[MAIN_FORCE])
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@ -220,19 +261,72 @@ function ChangePlayerSpawn(player, pos)
|
||||
global.playerCooldowns[player.name] = {setRespawn=game.tick}
|
||||
end
|
||||
|
||||
function SendPlayerToNewSpawnAndCreateIt(player, spawn, moatEnabled)
|
||||
-- Send the player to that position
|
||||
player.teleport(spawn, GAME_SURFACE_NAME)
|
||||
GivePlayerStarterItems(player)
|
||||
ChartArea(player.force, player.position, 4, player.surface)
|
||||
|
||||
function QueuePlayerForDelayedSpawn(playerName, spawn, moatEnabled)
|
||||
|
||||
-- If we get a valid spawn point, setup the area
|
||||
if ((spawn.x ~= 0) and (spawn.y ~= 0)) then
|
||||
global.uniqueSpawns[player.name] = {pos=spawn,moat=moatEnabled}
|
||||
ClearNearbyEnemies(player, SAFE_AREA_TILE_DIST)
|
||||
global.uniqueSpawns[playerName] = {pos=spawn,moat=moatEnabled}
|
||||
|
||||
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})
|
||||
|
||||
DisplayPleaseWaitForSpawnDialog(game.players[playerName], delay_spawn_seconds)
|
||||
|
||||
else
|
||||
DebugPrint("THIS SHOULD NOT EVER HAPPEN! Spawn failed!")
|
||||
SendBroadcastMsg("Failed to create spawn point for: " .. player.name)
|
||||
SendBroadcastMsg("ERROR!! Failed to create spawn point for: " .. playerName)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- Check a table to see if there are any players waiting to spawn
|
||||
-- Check if we are past the delayed tick count
|
||||
-- Spawn the players and remove them from the table.
|
||||
function DelayedSpawnOnTick()
|
||||
if ((game.tick % (30)) == 1) then
|
||||
if ((global.delayedSpawns ~= nil) and (#global.delayedSpawns > 0)) then
|
||||
for i=#global.delayedSpawns,1,-1 do
|
||||
delayedSpawn = global.delayedSpawns[i]
|
||||
|
||||
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)
|
||||
end
|
||||
table.remove(global.delayedSpawns, i)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function SendPlayerToNewSpawnAndCreateIt(playerName, spawn, moatEnabled)
|
||||
|
||||
-- Make sure the area is super safe.
|
||||
ClearNearbyEnemies(spawn, SAFE_AREA_TILE_DIST, game.surfaces[GAME_SURFACE_NAME])
|
||||
|
||||
-- Create the spawn resources here
|
||||
CreateWaterStrip(game.surfaces[GAME_SURFACE_NAME],
|
||||
{x=spawn.x+WATER_SPAWN_OFFSET_X, y=spawn.y+WATER_SPAWN_OFFSET_Y},
|
||||
WATER_SPAWN_LENGTH)
|
||||
CreateWaterStrip(game.surfaces[GAME_SURFACE_NAME],
|
||||
{x=spawn.x+WATER_SPAWN_OFFSET_X, y=spawn.y+WATER_SPAWN_OFFSET_Y+1},
|
||||
WATER_SPAWN_LENGTH)
|
||||
GenerateStartingResources(surface, spawn)
|
||||
|
||||
-- Send the player to that position
|
||||
game.players[playerName].teleport(spawn, GAME_SURFACE_NAME)
|
||||
GivePlayerStarterItems(game.players[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)
|
||||
|
||||
if (game.players[playerName].gui.center.wait_for_spawn_dialog ~= nil) then
|
||||
game.players[playerName].gui.center.wait_for_spawn_dialog.destroy()
|
||||
end
|
||||
end
|
||||
|
||||
@ -275,9 +369,19 @@ function CreatePlayerCustomForce(player)
|
||||
-- Create a new force using the player's name
|
||||
elseif (TableLength(game.forces) < MAX_FORCES) then
|
||||
newForce = game.create_force(player.name)
|
||||
if ENABLE_SHARED_TEAM_VISION then
|
||||
newForce.share_chart = true
|
||||
end
|
||||
-- Chart silo areas if necessary
|
||||
if FRONTIER_ROCKET_SILO_MODE and ENABLE_SILO_VISION then
|
||||
ChartRocketSiloAreas(game.surfaces[GAME_SURFACE_NAME], newForce)
|
||||
end
|
||||
player.force = newForce
|
||||
SetCeaseFireBetweenAllForces()
|
||||
SetFriendlyBetweenAllForces()
|
||||
SetFriendlyBetweenAllForces()
|
||||
if (ENABLE_ANTI_GRIEFING) then
|
||||
AntiGriefing(newForce)
|
||||
end
|
||||
SendBroadcastMsg(player.name.." has started their own team!")
|
||||
else
|
||||
player.force = MAIN_FORCE
|
||||
@ -286,34 +390,3 @@ function CreatePlayerCustomForce(player)
|
||||
|
||||
return newForce
|
||||
end
|
||||
|
||||
-- For each force, if it's a valid force, chart the chunk that all active players
|
||||
-- are in.
|
||||
-- I have no idea how compute intensive this function is. If it starts to lag the game
|
||||
-- we'll have to figure out how to change it.
|
||||
function ShareVisionBetweenPlayers()
|
||||
|
||||
if ((game.tick % (TICKS_PER_SECOND*5)) == 0) then
|
||||
|
||||
for _,force in pairs(game.forces) do
|
||||
if (force ~= nil) then
|
||||
if ((force.name ~= enemy) and
|
||||
(force.name ~= neutral) and
|
||||
(force.name ~= player)) then
|
||||
|
||||
for _,player in pairs(game.connected_players) do
|
||||
force.chart(GAME_SURFACE_NAME,
|
||||
{{player.position.x-CHUNK_SIZE,
|
||||
player.position.y-CHUNK_SIZE},
|
||||
{player.position.x+CHUNK_SIZE,
|
||||
player.position.y+CHUNK_SIZE}})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
global.tick_counter = 0
|
||||
else
|
||||
global.tick_counter = global.tick_counter + 1
|
||||
end
|
||||
end
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user