1
0
mirror of https://github.com/Oarcinae/FactorioScenarioMultiplayerSpawn.git synced 2024-12-12 10:13:58 +02:00

Have the basics of a Fulgora spawn working. Looks like shit, but best I can do for now.

This commit is contained in:
Oarcinae 2024-10-29 09:44:20 -04:00
parent 0747e722dd
commit 305786da57
9 changed files with 479 additions and 183 deletions

View File

@ -1,4 +1,11 @@
---------------------------------------------------------------------------------------------------
Version: 2.1.10
Date: ????
Major Features:
- Adding support for secondary spawns on Fulgora.
Bugfixes:
- Fixed a crash if surface only had 1 basic-solid resource to place.
---------------------------------------------------------------------------------------------------
Version: 2.1.9
Date: 2024-11-06
Bugfixes:

View File

@ -1,6 +1,6 @@
{
"name": "oarc-mod",
"version": "2.1.9",
"version": "2.1.10",
"factorio_version": "2.0",
"title": "Oarc Multiplayer Spawn",
"author": "Oarcinae",

View File

@ -15,6 +15,8 @@
]]
require("lib/planet_configs/nauvis")
require("lib/planet_configs/fulgora")
---@alias SpawnShapeChoice "circle" | "octagon" | "square"
SPAWN_SHAPE_CHOICE_CIRCLE = "circle"
@ -28,148 +30,6 @@ RESOURCES_SHAPE_CHOICE_SQUARE = "square"
MAX_CRASHED_SHIP_RESOURCES_ITEMS = 5
MAX_CRASHED_SHIP_WRECKAGE_ITEMS = 1
-- THIS is used as the default starting items on all surfaces if no other settings are provided!
---@type OarcConfigStartingItems
NAUVIS_STARTER_ITEMS =
{
player_start_items = {
["iron-plate"] = 8,
["wood"] = 1,
["pistol"] = 1,
["firearm-magazine"] = 10,
["burner-mining-drill"] = 1,
["stone-furnace"] = 1
},
player_respawn_items = {
["pistol"] = 1,
["firearm-magazine"] = 10
},
crashed_ship = true,
crashed_ship_resources = {
["firearm-magazine"] = 8 -- Max of 5 inventory slots!
},
crashed_ship_wreakage = {
["iron-plate"] = 8 -- I don't recommend more than 1 item type here!
},
}
-- THIS is used as the default spawn config on all surfaces if no other settings are provided!
---@type OarcConfigSpawn
NAUVIS_SPAWN_CONFIG =
{
-- Safe Spawn Area Options
-- The default settings here are balanced for my recommended map gen settings (close to train world).
safe_area =
{
-- Safe area has no aliens
-- This is the radius in chunks of safe area.
safe_radius = 6,
-- Warning area has significantly reduced aliens
-- This is the radius in chunks of warning area.
warn_radius = 12,
-- 1 : X (spawners alive : spawners destroyed) in this area
warn_reduction = 20,
-- Danger area has slightly reduced aliens
-- This is the radius in chunks of danger area.
danger_radius = 32,
-- 1 : X (spawners alive : spawners destroyed) in this area
danger_reduction = 5,
},
-- Location of water strip within the spawn area (2 horizontal rows)
-- The offset is from the TOP (NORTH) of the spawn area.
water = {
x_offset = -4,
y_offset = 10,
length = 8,
},
-- Location of shared power pole within the spawn area (if enabled)
-- The offset is from the RIGHT (WEST) of the spawn area.
shared_power_pole_position = {
x_offset=-10,
y_offset=0
},
-- Location of shared chest within the spawn area (if enabled)
-- The offset is from the RIGHT (WEST) of the spawn area.
shared_chest_position = {
x_offset=-10,
y_offset=1
},
-- Solid resource tiles
-- If you are running with mods that add or change resources, you'll want to customize this.
-- Offsets only are applicable if auto placement is disabled. Offsets are from CENTER of spawn area.
solid_resources = {
["iron-ore"] = {
amount = 1500,
size = 21,
-- These are only used if not using automatic placing.
x_offset = -29,
y_offset = 16
},
["copper-ore"] = {
amount = 1200,
size = 21,
-- These are only used if not using automatic placing.
x_offset = -28,
y_offset = -3
},
["stone"] = {
amount = 1200,
size = 21,
-- These are only used if not using automatic placing.
x_offset = -27,
y_offset = -34
},
["coal"] = {
amount = 1200,
size = 21,
-- These are only used if not using automatic placing.
x_offset = -27,
y_offset = -20
}
},
-- Fluid resource patches like oil
-- If you are running with mods that add or change resources, you'll want to customize this.
-- The offset is from the BOTTOM (SOUTH) of the spawn area.
fluid_resources =
{
["crude-oil"] =
{
num_patches = 2,
amount = 900000,
spacing = 6, -- Spacing between each patch, only used for automatic placing.
-- These are only used if not using automatic placing.
-- Starting position offset (relative to bottom/south of spawn area)
x_offset_start = -3,
y_offset_start = -10,
-- Additional position offsets for each new oil patch (relative to previous oil patch)
x_offset_next = 6,
y_offset_next = 0
}
},
}
---@type OarcConfigSurface
NAUVIS_SURFACE_CONFIG =
{
starting_items = NAUVIS_STARTER_ITEMS,
spawn_config = NAUVIS_SPAWN_CONFIG
}
---This only matters if you have the coin shop enabled.
---@type OarcStoreList
OARC_SHOP_ITEMS =
@ -507,10 +367,10 @@ OCFG = {
-- starting_items = NAUVIS_STARTER_ITEMS,
-- spawn_config = NAUVIS_SPAWN_CONFIG
-- },
-- ["fulgora"] = {
-- starting_items = NAUVIS_STARTER_ITEMS,
-- spawn_config = NAUVIS_SPAWN_CONFIG
-- },
["fulgora"] = {
starting_items = FULGORA_STARTER_ITEMS,
spawn_config = FULGORA_SPAWN_CONFIG
},
-- ["gleba"] = {
-- starting_items = NAUVIS_STARTER_ITEMS,
-- spawn_config = NAUVIS_SPAWN_CONFIG
@ -641,6 +501,11 @@ OCFG = {
---@field player_respawn_items table Items provided after EVERY respawn (disabled by default)
---@class OarcConfigSpawn
---@field fill_tile string Fill tile for the spawn area (grass on Nauvis)
---@field liquid_tile string Moat and liquid strip for the spawn area (water on Nauvis)
---@field tree_entity string Tree ring entity for the spawn area (tree-02 on Nauvis)
---@field random_entities table Random entities to place around the spawn area (like rocks on nauvis, ruins on fulgora)
---@field radius_modifier number Radius modifier for the spawn area (1.0 is default)
---@field safe_area OarcConfigSpawnSafeArea How safe is the spawn area?
---@field water OarcConfigSpawnWater Water strip settings
---@field shared_power_pole_position OarcOffsetPosition Location of shared power pole relative to spawn center (if enabled)

View File

@ -86,8 +86,8 @@ function CreateHoldingPenChunks(event)
PlaceResourcesInSemiCircleHoldingPen(surface, {x=0,y=0}, 0.2, 0.1)
CreateWaterStrip(surface, {x=-2,y=-11}, 4)
CreateWaterStrip(surface, {x=-2,y=-10}, 4)
CreateTileStrip(surface, {x=-2,y=-11}, 4, "water")
CreateTileStrip(surface, {x=-2,y=-10}, 4, "water")
surface.create_entity({
name = "crude-oil",

View File

@ -232,3 +232,94 @@ function DudeWheresMyCargoPod(player)
player.print({ "oarc-teleport-success" })
end
end
---Allow players to reroll their spawn point, dangerous because this doesn't do a lot of checks.
---@param player LuaPlayer
---@return nil
function RerollSpawn(player)
-- Make sure character is valid
if not player.character then
log("ERROR - RerollSpawn - No valid character for player: " .. player.name)
return
end
-- Ensure we still have their previous spawn choices
local spawn_choices = storage.spawn_choices[player.name]
if (spawn_choices == nil) then
log("ERROR - RerollSpawn - No spawn choices for player: " .. player.name)
return
end
local surface = player.character.surface
-- Confirm there is AN existing spawn point for this player on this surface
if (storage.unique_spawns[surface.name] == nil or storage.unique_spawns[surface.name][player.name] == nil) then
log("ERROR - RerollSpawn - Can't reroll? No existing spawn for " .. player.name)
return
end
-- Save a copy of the previous spawn point
local old_spawn_point = table.deepcopy(storage.unique_spawns[surface.name][player.name])
-- Find a new spawn point
local spawn_position = FindUngeneratedCoordinates(surface, spawn_choices.distance, 3)
-- If that fails, just throw a warning and don't spawn them. They can try again.
if ((spawn_position.x == 0) and (spawn_position.y == 0)) then
player.print({ "oarc-no-ungenerated-land-error" })
return
end
-- Remove the old spawn point
if (storage.ocfg.regrowth.enable_abandoned_base_cleanup) then
log("Removing base: " .. spawn_position.x .. "," .. spawn_position.y .. " on surface: " .. old_spawn_point.surface_name)
-- Clear an area around the spawn that SHOULD not include any other bases.
local clear_radius = storage.ocfg.gameplay.minimum_distance_to_existing_chunks - 2 -- Bring in a bit for safety.
RegrowthMarkAreaForRemoval(old_spawn_point.surface_name, old_spawn_point.position, clear_radius)
TriggerCleanup()
-- Trigger event
script.raise_event("oarc-mod-on-spawn-remove-request", {spawn_data = old_spawn_point})
end
-- Add new spawn point for the new surface
SetPlayerRespawn(player.name, surface.name, spawn_position, false) -- Do not reset cooldown
QueuePlayerForDelayedSpawn(player.name, surface.name, spawn_position, spawn_choices.moat, old_spawn_point.primary, nil)
-- Send them to the holding pen
SafeTeleport(player, game.surfaces[HOLDING_PEN_SURFACE_NAME], {x=0,y=0})
-- Announce
SendBroadcastMsg({"", { "oarc-player-new-secondary", player.name, surface.name }, " ", GetGPStext(surface.name, spawn_position)})
end
---Test out placing fulgoran stuff
-- fulgurite-small
-- fulgurite
-- fulgoran-ruin-attractor
-- fulgoran-ruin-small
-- fulgoran-ruin-medium
-- fulgoran-ruin-colossal
-- fulgoran-ruin-stonehenge
-- fulgoran-ruin-vault
-- if (tree_entity == nil) then return end
-- --Create trees (needs to be done after setting tiles!)
-- for i = chunkArea.left_top.x, chunkArea.right_bottom.x, 1 do
-- for j = chunkArea.left_top.y, chunkArea.right_bottom.y, 1 do
-- local distSqr = math.floor((centerPos.x - i) ^ 2 + (centerPos.y - j) ^ 2)
-- if ((distSqr < tree_radius_sqr_outer) and (distSqr > tree_radius_sqr_inner)) then
-- local random_tree_index = math.random(1, #tree_entity)
-- local pos = surface.find_non_colliding_position(tree_entity[random_tree_index], { i, j }, 2, 0.5)
-- if (pos ~= nil) then
-- surface.create_entity({ name = tree_entity[random_tree_index], amount = 1, position = pos })
-- end
-- -- surface.create_entity({ name = "tree-02", amount = 1, position = { i, j } })
-- end
-- end
-- end

View File

@ -295,6 +295,18 @@ function TableRemoveOneUsingPairs(t, val)
end
end
---Gets a random point within a circle of a given radius and center point.
---@param radius number
---@param center MapPosition
---@return MapPosition
function GetRandomPointWithinCircle(radius, center)
local angle = math.random() * 2 * math.pi
local distance = math.random() * radius
local x = center.x + distance * math.cos(angle)
local y = center.y + distance * math.sin(angle)
return {x=x, y=y}
end
-- -- Get a random KEY from a table.
-- function GetRandomKeyFromTable(t)
-- local keyset = {}
@ -1355,6 +1367,11 @@ function CreateCropCircle(surface, centerPos, chunkArea, tileRadius, fillTile, m
local tree_radius_sqr_inner = ((tileRadius - 1 - tree_width) ^ 2) -- 1 less to make sure trees are inside the spawn area
local tree_radius_sqr_outer = ((tileRadius - 1) ^ 2)
local surface_config = storage.ocfg.surfaces_config[surface.name]
local liquid_tile = surface_config.spawn_config.liquid_tile
local fish_enabled = (liquid_tile == "water")
local dirtTiles = {}
for i = chunkArea.left_top.x, chunkArea.right_bottom.x, 1 do
for j = chunkArea.left_top.y, chunkArea.right_bottom.y, 1 do
@ -1382,10 +1399,10 @@ function CreateCropCircle(surface, centerPos, chunkArea, tileRadius, fillTile, m
-- This will leave the tiles "as is" on the left and right of the spawn which has the effect of creating
-- land connections if the spawn is on or near land.
elseif ((distSqr < moat_radius_sqr) and (distSqr > tile_radius_sqr)) then
table.insert(dirtTiles, { name = "water", position = { i, j } })
table.insert(dirtTiles, { name = liquid_tile, position = { i, j } })
--5% chance of fish in water
if (math.random(1,20) == 1) then
if fish_enabled and (math.random(1,20) == 1) then
surface.create_entity({name="fish", position={i + 0.5, j + 0.5}})
end
end
@ -1396,11 +1413,18 @@ function CreateCropCircle(surface, centerPos, chunkArea, tileRadius, fillTile, m
surface.set_tiles(dirtTiles)
--Create trees (needs to be done after setting tiles!)
local tree_entity = surface_config.spawn_config.tree_entity
if (tree_entity == nil) then return end
for i = chunkArea.left_top.x, chunkArea.right_bottom.x, 1 do
for j = chunkArea.left_top.y, chunkArea.right_bottom.y, 1 do
local distSqr = math.floor((centerPos.x - i) ^ 2 + (centerPos.y - j) ^ 2)
if ((distSqr < tree_radius_sqr_outer) and (distSqr > tree_radius_sqr_inner)) then
surface.create_entity({ name = "tree-02", amount = 1, position = { i, j } })
local pos = surface.find_non_colliding_position(tree_entity, { i, j }, 2, 0.5)
if (pos ~= nil) then
surface.create_entity({ name = tree_entity, amount = 1, position = pos })
end
-- surface.create_entity({ name = "tree-02", amount = 1, position = { i, j } })
end
end
end
@ -1462,6 +1486,7 @@ function CreateCropOctagon(surface, centerPos, chunkArea, tileRadius, fillTile,
end
surface.set_tiles(dirtTiles)
if (tree_entity == nil) then return end
--Create trees (needs to be done after setting tiles!)
for i = chunkArea.left_top.x, chunkArea.right_bottom.x, 1 do
for j = chunkArea.left_top.y, chunkArea.right_bottom.y, 1 do
@ -1532,6 +1557,7 @@ function CreateCropSquare(surface, centerPos, chunkArea, tileRadius, fillTile, m
surface.set_tiles(dirtTiles)
if (tree_entity == nil) then return end
--Create trees (needs to be done after setting tiles!)
for i = chunkArea.left_top.x, chunkArea.right_bottom.x, 1 do
for j = chunkArea.left_top.y, chunkArea.right_bottom.y, 1 do
@ -1578,14 +1604,16 @@ function CreateMoat(surface, centerPos, chunkArea, tileRadius, moatTile, bridge,
surface.set_tiles(tiles)
end
-- Create a horizontal line of water
-- Create a horizontal line of tiles (typically used for water)
---@param surface LuaSurface
---@param leftPos TilePosition
---@param length integer
function CreateWaterStrip(surface, leftPos, length)
---@param tile_name string
---@return nil
function CreateTileStrip(surface, leftPos, length, tile_name)
local waterTiles = {}
for i = 0, length-1, 1 do
table.insert(waterTiles, { name = "water", position = { leftPos.x + i, leftPos.y } })
table.insert(waterTiles, { name = tile_name, position = { leftPos.x + i, leftPos.y } })
end
surface.set_tiles(waterTiles)
end
@ -1620,6 +1648,64 @@ function GenerateResourcePatch(surface, resourceName, diameter, position, amount
end
end
--- Function to generate a resource patch, of a certain size/amount at a pos.
---@param surface LuaSurface
---@param position MapPosition
---@return nil
function PlaceRandomEntities(surface, position)
local spawn_config = storage.ocfg.surfaces_config[surface.name].spawn_config
local random_entities = spawn_config.random_entities
if (random_entities == nil) then return end
local tree_width = storage.ocfg.spawn_general.tree_width_tiles
local radius = storage.ocfg.spawn_general.spawn_radius_tiles * spawn_config.radius_modifier - tree_width
--Iterate through the random entities and place them
for _, entry in pairs(random_entities) do
local entity_name = entry.name
for i = 1, entry.count do
local random_pos = GetRandomPointWithinCircle(radius, position)
local open_pos = surface.find_non_colliding_position(entity_name, random_pos, tree_width, 0.5)
if (open_pos ~= nil) then
surface.create_entity({
name = entity_name,
position = open_pos
})
end
end
end
end
--- Randomly place lightning attractors specific for Fulgora. This should space them out so they don't overlap too much.
---@param surface LuaSurface
---@param position MapPosition
---@return nil
function PlaceFulgoranLightningAttractors(surface, position, count)
local spawn_config = storage.ocfg.surfaces_config[surface.name].spawn_config
local radius = storage.ocfg.spawn_general.spawn_radius_tiles * spawn_config.radius_modifier
-- HARDCODED FOR NOW
local ATTRACTOR_NAME = "fulgoran-ruin-attractor"
local ATTRACTOR_RADIUS = 20
--Iterate through and place them and use the largest available entity
for i = 1, count do
local random_pos = GetRandomPointWithinCircle(radius, position)
local open_pos = surface.find_non_colliding_position("crash-site-spaceship", random_pos, 1, 0.5)
if (open_pos ~= nil) then
surface.create_entity({
name = ATTRACTOR_NAME,
position = open_pos
})
end
end
end
-- --------------------------------------------------------------------------------
-- -- Holding pen for new players joining the map
-- --------------------------------------------------------------------------------

View File

@ -0,0 +1,34 @@
-- THIS is used as the default starting items on all surfaces if no other settings are provided!
---@type OarcConfigStartingItems
FULGORA_STARTER_ITEMS = table.deepcopy(NO_STARTER_ITEMS)
---@type OarcConfigSpawn
FULGORA_SPAWN_CONFIG = table.deepcopy(NAUVIS_SPAWN_CONFIG)
FULGORA_SPAWN_CONFIG.fill_tile = "fulgoran-paving"
FULGORA_SPAWN_CONFIG.liquid_tile = "oil-ocean-deep"
FULGORA_SPAWN_CONFIG.tree_entity = nil
FULGORA_SPAWN_CONFIG.random_entities = {
{name = "fulgoran-ruin-vault", count = 2},
{name = "fulgoran-ruin-stonehenge", count = 5},
{name = "fulgoran-ruin-colossal", count = 5},
{name = "fulgoran-ruin-medium", count = 20},
{name = "fulgoran-ruin-small", count = 30},
{name = "fulgurite", count = 20},
{name = "fulgurite-small", count = 30},
}
-- I think Fulgora should be smaller in general.
FULGORA_SPAWN_CONFIG.radius_modifier = 0.7
FULGORA_SPAWN_CONFIG.solid_resources =
{
["scrap"] = {
amount = 10000,
size = 25,
-- These are only used if not using automatic placing.
x_offset = -29,
y_offset = 16
}
}
FULGORA_SPAWN_CONFIG.fluid_resources = { }

View File

@ -0,0 +1,180 @@
-- THIS is used as the default starting items on all surfaces if no other settings are provided!
---@type OarcConfigStartingItems
NAUVIS_STARTER_ITEMS =
{
player_start_items = {
["iron-plate"] = 8,
["wood"] = 1,
["pistol"] = 1,
["firearm-magazine"] = 10,
["burner-mining-drill"] = 1,
["stone-furnace"] = 1
},
player_respawn_items = {
["pistol"] = 1,
["firearm-magazine"] = 10
},
crashed_ship = true,
crashed_ship_resources = {
["firearm-magazine"] = 8 -- Max of 5 inventory slots!
},
crashed_ship_wreakage = {
["iron-plate"] = 8 -- I don't recommend more than 1 item type here!
},
}
-- THIS is used when disabling starter items on a surface?
---@type OarcConfigStartingItems
NO_STARTER_ITEMS =
{
player_start_items = { },
player_respawn_items = {
["pistol"] = 1,
["firearm-magazine"] = 10
},
crashed_ship = false,
crashed_ship_resources = {
-- ["firearm-magazine"] = 8 -- Max of 5 inventory slots!
},
crashed_ship_wreakage = {
-- ["iron-plate"] = 8 -- I don't recommend more than 1 item type here!
},
}
-- THIS is used as the default spawn config on all surfaces if no other settings are provided!
---@type OarcConfigSpawn
NAUVIS_SPAWN_CONFIG =
{
-- Used to fill in area that collides with water layer, IF force grass is enabled.
fill_tile = "grass-1",
-- Used to fill in the moat and the liquid strip at the top of the circle if no moat.
liquid_tile = "water",
-- Used to circle the base. Set to nil to disable.
tree_entity = "tree-02",
-- Random entities to place around the base.
random_entities = {
{name = "big-rock", count = 5},
{name = "huge-rock", count = 5},
{name = "dead-grey-trunk", count = 5},
{name = "big-sand-rock", count = 5},
},
-- Used to modify the size of the base.
radius_modifier = 1,
-- Safe Spawn Area Options
-- The default settings here are balanced for my recommended map gen settings (close to train world).
safe_area =
{
-- Safe area has no aliens
-- This is the radius in chunks of safe area.
safe_radius = 6,
-- Warning area has significantly reduced aliens
-- This is the radius in chunks of warning area.
warn_radius = 12,
-- 1 : X (spawners alive : spawners destroyed) in this area
warn_reduction = 20,
-- Danger area has slightly reduced aliens
-- This is the radius in chunks of danger area.
danger_radius = 32,
-- 1 : X (spawners alive : spawners destroyed) in this area
danger_reduction = 5,
},
-- Location of water strip within the spawn area (2 horizontal rows)
-- The offset is from the TOP (NORTH) of the spawn area.
water = {
x_offset = -4,
y_offset = 10,
length = 8,
},
-- Location of shared power pole within the spawn area (if enabled)
-- The offset is from the RIGHT (WEST) of the spawn area.
shared_power_pole_position = {
x_offset=-10,
y_offset=0
},
-- Location of shared chest within the spawn area (if enabled)
-- The offset is from the RIGHT (WEST) of the spawn area.
shared_chest_position = {
x_offset=-10,
y_offset=1
},
-- Solid resource tiles
-- If you are running with mods that add or change resources, you'll want to customize this.
-- Offsets only are applicable if auto placement is disabled. Offsets are from CENTER of spawn area.
solid_resources = {
["iron-ore"] = {
amount = 1500,
size = 21,
-- These are only used if not using automatic placing.
x_offset = -29,
y_offset = 16
},
["copper-ore"] = {
amount = 1200,
size = 21,
-- These are only used if not using automatic placing.
x_offset = -28,
y_offset = -3
},
["stone"] = {
amount = 1200,
size = 21,
-- These are only used if not using automatic placing.
x_offset = -27,
y_offset = -34
},
["coal"] = {
amount = 1200,
size = 21,
-- These are only used if not using automatic placing.
x_offset = -27,
y_offset = -20
}
},
-- Fluid resource patches like oil
-- If you are running with mods that add or change resources, you'll want to customize this.
-- The offset is from the BOTTOM (SOUTH) of the spawn area.
fluid_resources =
{
["crude-oil"] =
{
num_patches = 2,
amount = 900000,
spacing = 6, -- Spacing between each patch, only used for automatic placing.
-- These are only used if not using automatic placing.
-- Starting position offset (relative to bottom/south of spawn area)
x_offset_start = -3,
y_offset_start = -10,
-- Additional position offsets for each new oil patch (relative to previous oil patch)
x_offset_next = 6,
y_offset_next = 0
}
},
}
---@type OarcConfigSurface
NAUVIS_SURFACE_CONFIG =
{
starting_items = NAUVIS_STARTER_ITEMS,
spawn_config = NAUVIS_SPAWN_CONFIG
}

View File

@ -367,7 +367,7 @@ function GenerateStartingResources(surface, position)
for i = 1, r_data.num_patches do
surface.create_entity({
name = "crude-oil",
name = r_name,
amount = r_data.amount,
position = { oil_patch_x, oil_patch_y }
})
@ -416,25 +416,41 @@ function PlaceResourcesInSemiCircle(surface, position, size_mod, amount_mod)
local shuffled_list = FYShuffle(r_list)
-- This places resources in a semi-circle
local surface_config = storage.ocfg.surfaces_config[surface.name]
local angle_offset_radians = math.rad(storage.ocfg.resource_placement.angle_offset)
local angle_final_radians = math.rad(storage.ocfg.resource_placement.angle_final)
local num_resources = table_size(storage.ocfg.surfaces_config[surface.name].spawn_config.solid_resources)
local theta = ((angle_final_radians - angle_offset_radians) / (num_resources-1));
local count = 0
local radius = storage.ocfg.spawn_general.spawn_radius_tiles * surface_config.spawn_config.radius_modifier - storage.ocfg.resource_placement.distance_to_edge
local radius = storage.ocfg.spawn_general.spawn_radius_tiles - storage.ocfg.resource_placement.distance_to_edge
for _, r_name in pairs(shuffled_list) do
local angle = (theta * count) + angle_offset_radians;
-- Special case for only one resource, place it in the middle of the semi-circle.
if (num_resources == 1) then
local r_name = shuffled_list[1]
local angle = ((angle_final_radians - angle_offset_radians) / 2) + angle_offset_radians;
local tx = (radius * math.cos(angle)) + position.x
local ty = (radius * math.sin(angle)) + position.y
local pos = { x = math.floor(tx), y = math.floor(ty) }
local resourceConfig = storage.ocfg.surfaces_config[surface.name].spawn_config.solid_resources[r_name]
local resourceConfig = surface_config.spawn_config.solid_resources[r_name]
GenerateResourcePatch(surface, r_name, resourceConfig.size * size_mod, pos, resourceConfig.amount * amount_mod)
count = count + 1
else
local theta = ((angle_final_radians - angle_offset_radians) / (num_resources-1));
local count = 0
for _, r_name in pairs(shuffled_list) do
local angle = (theta * count) + angle_offset_radians;
local tx = (radius * math.cos(angle)) + position.x
local ty = (radius * math.sin(angle)) + position.y
local pos = { x = math.floor(tx), y = math.floor(ty) }
local resourceConfig = storage.ocfg.surfaces_config[surface.name].spawn_config.solid_resources[r_name]
GenerateResourcePatch(surface, r_name, resourceConfig.size * size_mod, pos, resourceConfig.amount * amount_mod)
count = count + 1
end
end
end
@ -493,12 +509,14 @@ function SendPlayerToNewSpawnAndCreateIt(delayed_spawn)
x = delayed_spawn.position.x,
y = delayed_spawn.position.y - storage.ocfg.spawn_general.spawn_radius_tiles
}
CreateWaterStrip(game.surfaces[delayed_spawn.surface],
CreateTileStrip(game.surfaces[delayed_spawn.surface],
{ x = reference_pos.x + water_data.x_offset, y = reference_pos.y + water_data.y_offset },
water_data.length)
CreateWaterStrip(game.surfaces[delayed_spawn.surface],
water_data.length,
spawn_config.liquid_tile)
CreateTileStrip(game.surfaces[delayed_spawn.surface],
{ x = reference_pos.x + water_data.x_offset, y = reference_pos.y + water_data.y_offset + 1 },
water_data.length)
water_data.length,
spawn_config.liquid_tile)
end
-- Create the spawn resources here
@ -526,10 +544,29 @@ function SendPlayerToNewSpawnAndCreateIt(delayed_spawn)
CreateSharedChest(game.surfaces[delayed_spawn.surface], chest_position)
end
-- Place randomized entities
if (delayed_spawn.surface == "fulgora") then
PlaceFulgoranLightningAttractors(game.surfaces[delayed_spawn.surface], delayed_spawn.position, 10)
end
PlaceRandomEntities(game.surfaces[delayed_spawn.surface], delayed_spawn.position)
-- Send the player to that position
local player = game.players[delayed_spawn.playerName]
SendPlayerToSpawn(delayed_spawn.surface, player, delayed_spawn.primary)
GivePlayerStarterItems(player)
-- Only primary spawns get starter items and a crashed ship.
if delayed_spawn.primary then
GivePlayerStarterItems(player)
-- Create crash site if configured
if (ocfg.surfaces_config[delayed_spawn.surface].starting_items.crashed_ship) then
crash_site.create_crash_site(game.surfaces[delayed_spawn.surface],
{ x = delayed_spawn.position.x + 15, y = delayed_spawn.position.y - 25 },
ocfg.surfaces_config[delayed_spawn.surface].starting_items.crashed_ship_resources,
ocfg.surfaces_config[delayed_spawn.surface].starting_items.crashed_ship_wreakage)
end
end
-- Render some welcoming text...
DisplayWelcomeGroundTextAtSpawn(player, delayed_spawn.surface, delayed_spawn.position)
@ -543,19 +580,13 @@ function SendPlayerToNewSpawnAndCreateIt(delayed_spawn)
player.gui.screen.wait_for_spawn_dialog.destroy()
end
-- Create crash site if configured
if (ocfg.surfaces_config[delayed_spawn.surface].starting_items.crashed_ship) then
crash_site.create_crash_site(game.surfaces[delayed_spawn.surface],
{ x = delayed_spawn.position.x + 15, y = delayed_spawn.position.y - 25 },
ocfg.surfaces_config[delayed_spawn.surface].starting_items.crashed_ship_resources,
ocfg.surfaces_config[delayed_spawn.surface].starting_items.crashed_ship_wreakage)
end
-- Trigger the event that the spawn was created.
script.raise_event("oarc-mod-on-spawn-created", {spawn_data = storage.unique_spawns[delayed_spawn.surface][delayed_spawn.playerName]})
-- Trigger the event that player was spawned too.
script.raise_event("oarc-mod-on-player-spawned", {player_index = player.index})
if delayed_spawn.primary then
script.raise_event("oarc-mod-on-player-spawned", {player_index = player.index})
end
end
---Displays some welcoming text at the spawn point on the ground. Fades out over time.
@ -623,6 +654,8 @@ function SetupAndClearSpawnAreas(surface, chunkArea)
--[[@type OarcConfigSpawnGeneral]]
local general_spawn_config = storage.ocfg.spawn_general
local surface_config = storage.ocfg.surfaces_config[surface.name]
local chunkAreaCenter = {
x = chunkArea.left_top.x + (CHUNK_SIZE / 2),
y = chunkArea.left_top.y + (CHUNK_SIZE / 2)
@ -645,15 +678,15 @@ function SetupAndClearSpawnAreas(surface, chunkArea)
-- Remove trees/resources inside the spawn area
if (general_spawn_config.shape == SPAWN_SHAPE_CHOICE_CIRCLE) or (general_spawn_config.shape == SPAWN_SHAPE_CHOICE_OCTAGON) then
RemoveInCircle(surface, chunkArea, {"resource", "cliff", "tree"}, spawn.position, general_spawn_config.spawn_radius_tiles + 5)
RemoveInCircle(surface, chunkArea, {"resource", "cliff", "tree", "lightning-attractor", "simple-entity"}, spawn.position, general_spawn_config.spawn_radius_tiles + 5)
elseif (general_spawn_config.shape == SPAWN_SHAPE_CHOICE_SQUARE) then
RemoveInSquare(surface, chunkArea, {"resource", "cliff", "tree"}, spawn.position, general_spawn_config.spawn_radius_tiles + 5)
RemoveInSquare(surface, chunkArea, {"resource", "cliff", "tree", "lightning-attractor", "simple-entity"}, spawn.position, general_spawn_config.spawn_radius_tiles + 5)
end
-- Fill in the spawn area with landfill and create a circle of trees around it.
local fill_tile = "landfill"
if general_spawn_config.force_grass then
fill_tile = "grass-1"
fill_tile = surface_config.spawn_config.fill_tile
end
if (general_spawn_config.shape == SPAWN_SHAPE_CHOICE_CIRCLE) then
@ -661,7 +694,7 @@ function SetupAndClearSpawnAreas(surface, chunkArea)
surface,
spawn.position,
chunkArea,
general_spawn_config.spawn_radius_tiles,
general_spawn_config.spawn_radius_tiles * surface_config.spawn_config.radius_modifier,
fill_tile,
spawn.moat,
storage.ocfg.gameplay.enable_moat_bridging
@ -736,7 +769,7 @@ function DowngradeResourcesDistanceBasedOnChunkGenerate(surface, chunkArea)
if (new_amount < 1) then
entity.destroy()
else
if (entity.name ~= "crude-oil") then
if (entity.prototype.resource_category ~= "basic-fluid") then
entity.amount = math.min(new_amount, ore_per_tile_cap)
else
entity.amount = new_amount