Refactored spawn area

This commit is contained in:
Cooldude2606
2021-04-15 21:55:41 +01:00
parent 7381541aee
commit 0866e9f9c3
2 changed files with 280 additions and 230 deletions

View File

@@ -4,16 +4,23 @@
local Global = require 'utils.global' --- @dep utils.global
local Event = require 'utils.event' --- @dep utils.event
local config = require 'config.spawn_area' --- @dep config.spawn_area
local tiles = config.tiles
local entities = config.entities
local belts = config.afk_belts.locations
local turrets = config.infinite_ammo_turrets.locations
local turrets = config.turrets.locations
Global.register(turrets, function(tbl)
turrets = tbl
end)
-- returns the Spawn force or creates it
-- Apply an offset to a LuaPosition
local function apply_offset(position, offset)
return { x = position.x + (offset.x or offset[1]), y = position.y + (offset.y or offset[2]) }
end
-- Apply the offset to the turrets default position
for _, turret in ipairs(turrets) do
turret.position = apply_offset(turret.position, config.turrets.offset)
end
-- Get or create the force used for entities in spawn
local function get_spawn_force()
local force = game.forces['Spawn']
if force and force.valid then return force end
@@ -23,7 +30,7 @@ local function get_spawn_force()
return force
end
-- protects and entity so players cant do anything to it
-- Protects an entity and sets its force to the spawn force
local function protect_entity(entity, set_force)
if entity and entity.valid then
entity.destructible = false
@@ -35,113 +42,133 @@ local function protect_entity(entity, set_force)
end
end
-- handles the infinite ammo turrets
-- Will spawn all infinite ammo turrets and keep them refilled
local function spawn_turrets()
if config.infinite_ammo_turrets.enabled then
for _, turret_pos in pairs(turrets) do
local surface = game.surfaces[turret_pos.surface]
local pos = turret_pos.position
local turret = surface.find_entity('gun-turret', pos)
-- Makes a new turret if it is not found
if not turret or not turret.valid then
turret = surface.create_entity{name='gun-turret', position=pos, force='Spawn'}
protect_entity(turret, true)
end
-- adds ammo to the turret
local inv = turret.get_inventory(defines.inventory.turret_ammo)
if inv.can_insert{name=config.infinite_ammo_turrets.ammo_type, count=10} then
inv.insert{name=config.infinite_ammo_turrets.ammo_type, count=10}
end
for _, turret_pos in pairs(turrets) do
local surface = game.surfaces[turret_pos.surface]
local pos = turret_pos.position
local turret = surface.find_entity('gun-turret', pos)
-- Makes a new turret if it is not found
if not turret or not turret.valid then
turret = surface.create_entity{name='gun-turret', position=pos, force='Spawn'}
protect_entity(turret, true)
end
-- Adds ammo to the turret
local inv = turret.get_inventory(defines.inventory.turret_ammo)
if inv.can_insert{name=config.turrets.ammo_type, count=10} then
inv.insert{name=config.turrets.ammo_type, count=10}
end
end
end
-- makes a 2x2 afk belt where set in config
-- Makes a 2x2 afk belt at the locations in the config
local function spawn_belts(surface, position)
position = apply_offset(position, config.afk_belts.offset)
local belt_type = config.afk_belts.belt_type
local belt_details = {{-0.5, -0.5, 2}, {0.5, -0.5, 4}, {-0.5, 0.5, 0}, {0.5, 0.5, 6}} -- x, y,dir
for _, belt_set in pairs(belts) do
local o = position
local p = belt_set
for _, belt_set in pairs(config.afk_belts.locations) do
local set_position = apply_offset(position, belt_set)
for _, belt in pairs(belt_details) do
local pos = {x=o.x+p.x+belt[1], y=o.y+p.y+belt[2]}
local belt_entity = surface.create_entity{name='transport-belt', position=pos, force='neutral', direction=belt[3]}
protect_entity(belt_entity)
local pos = apply_offset(set_position, belt)
local belt_entity = surface.create_entity{name=belt_type, position=pos, force='neutral', direction=belt[3]}
if config.afk_belts.protected then protect_entity(belt_entity) end
end
end
end
-- generates an area with no water and removes entities in the decon area
local function spawn_base(surface, position)
local dr = config.corrections.deconstruction_radius
local dr2 = dr^2
local dtile = config.corrections.deconstruction_tile
local pr = config.corrections.pattern_radius
local pr2 = pr^2
local ptile = surface.get_tile(position).name
if ptile == 'deepwater' or ptile == 'water' then ptile = 'grass-1' end
-- Generates extra tiles in a set pattern set out in the config
local function spawn_pattern(surface, position)
position = apply_offset(position, config.pattern.offset)
local tiles_to_make = {}
for x = -pr, pr do -- loop over x
local x2 = x^2
for y = -pr, pr do -- loop over y
local y2 = y^2
local prod = x2+y2
local p = {x=position.x+x, y=position.y+y}
if prod < dr2 then
-- if it is inside the decon radius
table.insert(tiles_to_make, {name=dtile, position=p})
local entities_to_remove = surface.find_entities_filtered{area={{p.x-1, p.y-1}, {p.x, p.y}}}
for _, entity in pairs(entities_to_remove) do
if entity.name ~= 'character' then entity.destroy() end
end
elseif prod < pr2 then
-- if it is inside the pattern radius
table.insert(tiles_to_make, {name=ptile, position=p})
local pattern_tile = config.pattern.pattern_tile
for _, tile in pairs(config.pattern.locations) do
table.insert(tiles_to_make, {name=pattern_tile, position=apply_offset(position, tile)})
end
surface.set_tiles(tiles_to_make)
end
-- Generates extra water as set out in the config
local function spawn_water(surface, position)
position = apply_offset(position, config.water.offset)
local tiles_to_make = {}
local water_tile = config.water.water_tile
for _, tile in pairs(config.water.locations) do
table.insert(tiles_to_make, {name=water_tile, position=apply_offset(position, tile)})
end
surface.set_tiles(tiles_to_make)
end
-- Generates the entities that are in the config
local function spawn_entities(surface, position)
position = apply_offset(position, config.entities.offset)
for _, entity in pairs(config.entities.locations) do
local pos = apply_offset(position, { x=entity[2], y=entity[3] })
entity = surface.create_entity{name=entity[1], position=pos, force='neutral'}
if config.entities.protected then protect_entity(entity) end
entity.operable = config.entities.operable
end
end
-- Generates an area with no water or entities, no water area is larger
local function spawn_area(surface, position)
local dr = config.spawn_area.deconstruction_radius
local dr2 = dr^2
local decon_tile = config.spawn_area.deconstruction_tile
local fr = config.spawn_area.landfill_radius
local fr2 = fr^2
local fill_tile = surface.get_tile(position).name
-- Make sure a non water tile is used for each tile
if surface.get_tile(position).collides_with('player-layer') then fill_tile = 'landfill' end
if decon_tile == nil then decon_tile = fill_tile end
local tiles_to_make = {}
for x = -fr, fr do -- loop over x
local x2 = (x+0.5)^2
for y = -fr, fr do -- loop over y
local y2 = (y+0.5)^2
local dst = x2+y2
local pos = {x=position.x+x, y=position.y+y}
if dst < dr2 then
-- If it is inside the decon radius always set the tile
table.insert(tiles_to_make, {name=decon_tile, position=pos})
elseif dst < fr2 and surface.get_tile(pos).collides_with('player-layer') then
-- If it is inside the fill radius only set the tile if its water
table.insert(tiles_to_make, {name=fill_tile, position=pos})
end
end
end
-- Remove entities then set the tiles
local entities_to_remove = surface.find_entities_filtered{position=position, radius=dr, name='character', invert=true}
for _, entity in pairs(entities_to_remove) do entity.destroy() end
surface.set_tiles(tiles_to_make)
end
-- generates the pattern that is in the config
local function spawn_pattern(surface, position)
local tiles_to_make = {}
local ptile = config.corrections.pattern_tile
local o = config.corrections.offset
local p = {x=position.x+o.x, y=position.y+o.y}
for _, tile in pairs(tiles) do
table.insert(tiles_to_make, {name=ptile, position={tile[1]+p.x, tile[2]+p.y}})
end
surface.set_tiles(tiles_to_make)
-- Only add a event handler if the turrets are enabled
if config.turrets.enabled then
Event.on_nth_tick(config.turrets.refill_time, function()
if game.tick < 10 then return end
spawn_turrets()
end)
end
-- generates the entities that are in the config
local function spawn_entities(surface, position)
local o = config.corrections.offset
local p = {x=position.x+o.x, y=position.y+o.y}
for _, entity in pairs(entities) do
entity = surface.create_entity{name=entity[1], position={entity[2]+p.x, entity[3]+p.y}, force='neutral'}
protect_entity(entity)
entity.operable = true
end
end
local refill_time = 60*60*5 -- 5 minutes
Event.on_nth_tick(refill_time, function()
if game.tick < 10 then return end
spawn_turrets()
end)
-- When the first player joins create the spawn area
Event.add(defines.events.on_player_created, function(event)
if event.player_index ~= 1 then return end
local player = game.players[event.player_index]
local p = {x=0, y=0}
local s = player.surface
spawn_base(s, p)
spawn_pattern(s, p)
get_spawn_force()
spawn_entities(s, p)
spawn_belts(s, p)
spawn_turrets()
spawn_area(s, p)
if config.pattern.enabled then spawn_pattern(s, p) end
if config.water.enabled then spawn_water(s, p) end
if config.afk_belts.enabled then spawn_belts(s, p) end
if config.turrets.enabled then spawn_turrets() end
if config.entities.enabled then spawn_entities(s, p) end
player.teleport(p, s)
end)