mirror of
https://github.com/ComfyFactory/ComfyFactorio.git
synced 2025-01-08 00:39:30 +02:00
806 lines
29 KiB
Lua
806 lines
29 KiB
Lua
--luacheck: ignore
|
|
local Public = {}
|
|
local LootRaffle = require 'utils.functions.loot_raffle'
|
|
local BiterRaffle = require 'utils.functions.biter_raffle'
|
|
local bb_config = require 'maps.biter_battles_v2.config'
|
|
|
|
local table_insert = table.insert
|
|
local math_floor = math.floor
|
|
local math_random = math.random
|
|
local math_abs = math.abs
|
|
local math_sqrt = math.sqrt
|
|
|
|
local GetNoise = require 'utils.get_noise'
|
|
local simplex_noise = require 'utils.simplex_noise'.d2
|
|
local spawn_circle_size = 39
|
|
local ores = {'copper-ore', 'iron-ore', 'stone', 'coal'}
|
|
local rocks = {'sand-rock-big', 'sand-rock-big', 'rock-big', 'rock-big', 'rock-big', 'rock-big', 'rock-huge'}
|
|
|
|
local chunk_tile_vectors = {}
|
|
for x = 0, 31, 1 do
|
|
for y = 0, 31, 1 do
|
|
chunk_tile_vectors[#chunk_tile_vectors + 1] = {x, y}
|
|
end
|
|
end
|
|
local size_of_chunk_tile_vectors = #chunk_tile_vectors
|
|
|
|
local loading_chunk_vectors = {}
|
|
for k, v in pairs(chunk_tile_vectors) do
|
|
if v[1] == 0 or v[1] == 31 or v[2] == 0 or v[2] == 31 then
|
|
table_insert(loading_chunk_vectors, v)
|
|
end
|
|
end
|
|
|
|
local wrecks = {
|
|
'crash-site-spaceship-wreck-big-1',
|
|
'crash-site-spaceship-wreck-big-2',
|
|
'crash-site-spaceship-wreck-medium-1',
|
|
'crash-site-spaceship-wreck-medium-2',
|
|
'crash-site-spaceship-wreck-medium-3'
|
|
}
|
|
local size_of_wrecks = #wrecks
|
|
local valid_wrecks = {}
|
|
for _, wreck in pairs(wrecks) do
|
|
valid_wrecks[wreck] = true
|
|
end
|
|
local loot_blacklist = {
|
|
['automation-science-pack'] = true,
|
|
['logistic-science-pack'] = true,
|
|
['military-science-pack'] = true,
|
|
['chemical-science-pack'] = true,
|
|
['production-science-pack'] = true,
|
|
['utility-science-pack'] = true,
|
|
['space-science-pack'] = true,
|
|
['loader'] = true,
|
|
['fast-loader'] = true,
|
|
['express-loader'] = true
|
|
}
|
|
|
|
local function shuffle(tbl)
|
|
local size = #tbl
|
|
for i = size, 1, -1 do
|
|
local rand = math_random(size)
|
|
tbl[i], tbl[rand] = tbl[rand], tbl[i]
|
|
end
|
|
return tbl
|
|
end
|
|
|
|
local function get_noise(name, pos)
|
|
local seed = game.surfaces['bb_source'].map_gen_settings.seed
|
|
local noise_seed_add = 25000
|
|
if name == 1 then
|
|
local noise = simplex_noise(pos.x * 0.0042, pos.y * 0.0042, seed)
|
|
seed = seed + noise_seed_add
|
|
noise = noise + simplex_noise(pos.x * 0.031, pos.y * 0.031, seed) * 0.08
|
|
seed = seed + noise_seed_add
|
|
noise = noise + simplex_noise(pos.x * 0.1, pos.y * 0.1, seed) * 0.025
|
|
return noise
|
|
end
|
|
|
|
if name == 2 then
|
|
local noise = simplex_noise(pos.x * 0.011, pos.y * 0.011, seed)
|
|
seed = seed + noise_seed_add
|
|
noise = noise + simplex_noise(pos.x * 0.08, pos.y * 0.08, seed) * 0.2
|
|
return noise
|
|
end
|
|
|
|
if name == 3 then
|
|
local noise = simplex_noise(pos.x * 0.005, pos.y * 0.005, seed)
|
|
noise = noise + simplex_noise(pos.x * 0.02, pos.y * 0.02, seed) * 0.3
|
|
noise = noise + simplex_noise(pos.x * 0.15, pos.y * 0.15, seed) * 0.025
|
|
return noise
|
|
end
|
|
end
|
|
|
|
local function create_mirrored_tile_chain(surface, tile, count, straightness)
|
|
if not surface then
|
|
return
|
|
end
|
|
if not tile then
|
|
return
|
|
end
|
|
if not count then
|
|
return
|
|
end
|
|
|
|
local position = {x = tile.position.x, y = tile.position.y}
|
|
|
|
local modifiers = {
|
|
{x = 0, y = -1},
|
|
{x = -1, y = 0},
|
|
{x = 1, y = 0},
|
|
{x = 0, y = 1},
|
|
{x = -1, y = 1},
|
|
{x = 1, y = -1},
|
|
{x = 1, y = 1},
|
|
{x = -1, y = -1}
|
|
}
|
|
modifiers = shuffle(modifiers)
|
|
|
|
for a = 1, count, 1 do
|
|
local tile_placed = false
|
|
|
|
if math_random(0, 100) > straightness then
|
|
modifiers = shuffle(modifiers)
|
|
end
|
|
for b = 1, 4, 1 do
|
|
local pos = {x = position.x + modifiers[b].x, y = position.y + modifiers[b].y}
|
|
if surface.get_tile(pos).name ~= tile.name then
|
|
surface.set_tiles({{name = 'landfill', position = pos}}, true)
|
|
surface.set_tiles({{name = tile.name, position = pos}}, true)
|
|
--surface.set_tiles({{name = "landfill", position = {pos.x * -1, (pos.y * -1) - 1}}}, true)
|
|
--surface.set_tiles({{name = tile.name, position = {pos.x * -1, (pos.y * -1) - 1}}}, true)
|
|
position = {x = pos.x, y = pos.y}
|
|
tile_placed = true
|
|
break
|
|
end
|
|
end
|
|
|
|
if not tile_placed then
|
|
position = {x = position.x + modifiers[1].x, y = position.y + modifiers[1].y}
|
|
end
|
|
end
|
|
end
|
|
|
|
local function get_replacement_tile(surface, position)
|
|
for i = 1, 128, 1 do
|
|
local vectors = {{0, i}, {0, i * -1}, {i, 0}, {i * -1, 0}}
|
|
table.shuffle_table(vectors)
|
|
for k, v in pairs(vectors) do
|
|
local tile = surface.get_tile(position.x + v[1], position.y + v[2])
|
|
if not tile.collides_with('resource-layer') then
|
|
if tile.name ~= 'stone-path' then
|
|
return tile.name
|
|
end
|
|
end
|
|
end
|
|
end
|
|
return 'grass-1'
|
|
end
|
|
|
|
local function draw_noise_ore_patch(position, name, surface, radius, richness)
|
|
if not position then
|
|
return
|
|
end
|
|
if not name then
|
|
return
|
|
end
|
|
if not surface then
|
|
return
|
|
end
|
|
if not radius then
|
|
return
|
|
end
|
|
if not richness then
|
|
return
|
|
end
|
|
local seed = game.surfaces['bb_source'].map_gen_settings.seed
|
|
local noise_seed_add = 25000
|
|
local richness_part = richness / radius
|
|
for y = radius * -3, radius * 3, 1 do
|
|
for x = radius * -3, radius * 3, 1 do
|
|
local pos = {x = x + position.x + 0.5, y = y + position.y + 0.5}
|
|
local noise_1 = simplex_noise(pos.x * 0.0125, pos.y * 0.0125, seed)
|
|
local noise_2 = simplex_noise(pos.x * 0.1, pos.y * 0.1, seed + 25000)
|
|
local noise = noise_1 + noise_2 * 0.12
|
|
local distance_to_center = math_sqrt(x ^ 2 + y ^ 2)
|
|
local a = richness - richness_part * distance_to_center
|
|
if distance_to_center < radius - math_abs(noise * radius * 0.85) and a > 1 then
|
|
if surface.can_place_entity({name = name, position = pos, amount = a}) then
|
|
surface.create_entity {name = name, position = pos, amount = a}
|
|
for _, e in pairs(surface.find_entities_filtered({position = pos, name = {'wooden-chest', 'stone-wall', 'gun-turret'}})) do
|
|
e.destroy()
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function is_within_spawn_circle(pos)
|
|
if math_abs(pos.x) > spawn_circle_size then
|
|
return false
|
|
end
|
|
if math_abs(pos.y) > spawn_circle_size then
|
|
return false
|
|
end
|
|
if math_sqrt(pos.x ^ 2 + pos.y ^ 2) > spawn_circle_size then
|
|
return false
|
|
end
|
|
return true
|
|
end
|
|
|
|
local river_y_1 = bb_config.border_river_width * -1.5
|
|
local river_y_2 = bb_config.border_river_width * 1.5
|
|
local river_width_half = math_floor(bb_config.border_river_width * -0.5)
|
|
function is_horizontal_border_river(pos)
|
|
if pos.y < river_y_1 then
|
|
return false
|
|
end
|
|
if pos.y > river_y_2 then
|
|
return false
|
|
end
|
|
if pos.y >= river_width_half - (math_abs(get_noise(1, pos)) * 4) then
|
|
return true
|
|
end
|
|
return false
|
|
end
|
|
|
|
local function generate_starting_area(pos, distance_to_center, surface)
|
|
-- assert(distance_to_center >= spawn_circle_size) == true
|
|
local spawn_wall_radius = 116
|
|
local noise_multiplier = 15
|
|
local min_noise = -noise_multiplier * 1.25
|
|
|
|
-- Avoid calculating noise, see comment below
|
|
if (distance_to_center + min_noise - spawn_wall_radius) > 4.5 then
|
|
return
|
|
end
|
|
|
|
local noise = get_noise(2, pos) * noise_multiplier
|
|
local distance_from_spawn_wall = distance_to_center + noise - spawn_wall_radius
|
|
-- distance_from_spawn_wall is the difference between the distance_to_center (with added noise)
|
|
-- and our spawn_wall radius (spawn_wall_radius=116), i.e. how far are we from the ring with radius spawn_wall_radius.
|
|
-- The following shows what happens depending on distance_from_spawn_wall:
|
|
-- min max
|
|
-- N/A -10 => replace water
|
|
-- if noise_2 > -0.5:
|
|
-- -1.75 0 => wall
|
|
-- else:
|
|
-- -6 -3 => 1/16 chance of turret or turret-remnants
|
|
-- -1.95 0 => wall
|
|
-- 0 4.5 => chest-remnants with 1/3, chest with 1/(distance_from_spawn_wall+2)
|
|
--
|
|
-- => We never do anything for (distance_to_center + min_noise - spawn_wall_radius) > 4.5
|
|
|
|
if distance_from_spawn_wall < 0 then
|
|
if math_random(1, 100) > 23 then
|
|
for _, tree in pairs(surface.find_entities_filtered({type = 'tree', area = {{pos.x, pos.y}, {pos.x + 1, pos.y + 1}}})) do
|
|
tree.destroy()
|
|
end
|
|
end
|
|
end
|
|
|
|
if distance_from_spawn_wall < -10 and not is_horizontal_border_river(pos) then
|
|
local tile_name = surface.get_tile(pos).name
|
|
if tile_name == 'water' or tile_name == 'deepwater' then
|
|
surface.set_tiles({{name = get_replacement_tile(surface, pos), position = pos}}, true)
|
|
end
|
|
return
|
|
end
|
|
|
|
if surface.can_place_entity({name = 'wooden-chest', position = pos}) and surface.can_place_entity({name = 'coal', position = pos}) then
|
|
local noise_2 = get_noise(3, pos)
|
|
if noise_2 < 0.40 then
|
|
if noise_2 > -0.40 then
|
|
if distance_from_spawn_wall > -1.75 and distance_from_spawn_wall < 0 then
|
|
local e = surface.create_entity({name = 'stone-wall', position = pos, force = 'neutral'})
|
|
e.active = false
|
|
end
|
|
else
|
|
if distance_from_spawn_wall > -1.95 and distance_from_spawn_wall < 0 then
|
|
local e = surface.create_entity({name = 'stone-wall', position = pos, force = 'neutral'})
|
|
e.active = false
|
|
elseif distance_from_spawn_wall > 0 and distance_from_spawn_wall < 4.5 then
|
|
local name = 'wooden-chest'
|
|
local r_max = math_floor(math.abs(distance_from_spawn_wall)) + 2
|
|
if math_random(1, 3) == 1 and not is_horizontal_border_river(pos) then
|
|
name = name .. '-remnants'
|
|
end
|
|
if math_random(1, r_max) == 1 then
|
|
local e = surface.create_entity({name = name, position = pos, force = 'neutral'})
|
|
e.active = false
|
|
end
|
|
elseif distance_from_spawn_wall > -6 and distance_from_spawn_wall < -3 then
|
|
if math_random(1, 16) == 1 then
|
|
if surface.can_place_entity({name = 'gun-turret', position = pos}) then
|
|
local e = surface.create_entity({name = 'gun-turret', position = pos, force = 'neutral'})
|
|
e.insert({name = 'firearm-magazine', count = math_random(6, 12)})
|
|
e.active = false
|
|
end
|
|
else
|
|
if math_random(1, 24) == 1 and not is_horizontal_border_river(pos) then
|
|
if surface.can_place_entity({name = 'gun-turret', position = pos}) then
|
|
surface.create_entity({name = 'gun-turret-remnants', position = pos, force = 'neutral'})
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
local function generate_river(surface, left_top_x, left_top_y)
|
|
if left_top_y ~= -32 then
|
|
return
|
|
end
|
|
for x = 0, 31, 1 do
|
|
for y = 0, 31, 1 do
|
|
local pos = {x = left_top_x + x, y = left_top_y + y}
|
|
local distance_to_center = math_sqrt(pos.x ^ 2 + pos.y ^ 2)
|
|
if is_horizontal_border_river(pos) and distance_to_center > spawn_circle_size - 2 then
|
|
surface.set_tiles({{name = 'deepwater', position = pos}})
|
|
if math_random(1, 64) == 1 then
|
|
local e = surface.create_entity({name = 'fish', position = pos})
|
|
e.active = false
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
local scrap_vectors = {}
|
|
for x = -8, 8, 1 do
|
|
for y = -8, 8, 1 do
|
|
if math_sqrt(x ^ 2 + y ^ 2) <= 8 then
|
|
scrap_vectors[#scrap_vectors + 1] = {x, y}
|
|
end
|
|
end
|
|
end
|
|
local size_of_scrap_vectors = #scrap_vectors
|
|
|
|
local function generate_extra_worm_turrets(surface, left_top)
|
|
local chunk_distance_to_center = math_sqrt(left_top.x ^ 2 + left_top.y ^ 2)
|
|
if bb_config.bitera_area_distance > chunk_distance_to_center then
|
|
return
|
|
end
|
|
|
|
local amount = (chunk_distance_to_center - bb_config.bitera_area_distance) * 0.0005
|
|
if amount < 0 then
|
|
return
|
|
end
|
|
local floor_amount = math_floor(amount)
|
|
local r = math.round(amount - floor_amount, 3) * 1000
|
|
if math_random(0, 999) <= r then
|
|
floor_amount = floor_amount + 1
|
|
end
|
|
|
|
if floor_amount > 64 then
|
|
floor_amount = 64
|
|
end
|
|
|
|
for _ = 1, floor_amount, 1 do
|
|
local worm_turret_name = BiterRaffle.roll('worm', chunk_distance_to_center * 0.00015)
|
|
local v = chunk_tile_vectors[math_random(1, size_of_chunk_tile_vectors)]
|
|
local position = surface.find_non_colliding_position(worm_turret_name, {left_top.x + v[1], left_top.y + v[2]}, 8, 1)
|
|
if position then
|
|
local worm = surface.create_entity({name = worm_turret_name, position = position, force = 'enemy'})
|
|
worm.active = false
|
|
|
|
-- add some scrap
|
|
for c = 1, math_random(0, 4), 1 do
|
|
local vector = scrap_vectors[math_random(1, size_of_scrap_vectors)]
|
|
local position = {worm.position.x + vector[1], worm.position.y + vector[2]}
|
|
local name = wrecks[math_random(1, size_of_wrecks)]
|
|
position = surface.find_non_colliding_position(name, position, 16, 1)
|
|
if position then
|
|
local e = surface.create_entity({name = name, position = position, force = 'neutral'})
|
|
e.active = false
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
local bitera_area_distance = bb_config.bitera_area_distance * -1
|
|
local biter_area_angle = 0.45
|
|
|
|
local function is_biter_area(position)
|
|
local a = bitera_area_distance - (math_abs(position.x) * biter_area_angle)
|
|
if position.y - 70 > a then
|
|
return false
|
|
end
|
|
if position.y + 70 < a then
|
|
return true
|
|
end
|
|
if position.y + (get_noise(3, position) * 64) > a then
|
|
return false
|
|
end
|
|
return true
|
|
end
|
|
|
|
local function draw_biter_area(surface, left_top_x, left_top_y)
|
|
if not is_biter_area({x = left_top_x, y = left_top_y - 96}) then
|
|
return
|
|
end
|
|
|
|
local seed = game.surfaces['bb_source'].map_gen_settings.seed
|
|
|
|
local out_of_map = {}
|
|
local tiles = {}
|
|
local i = 1
|
|
|
|
for x = 0, 31, 1 do
|
|
for y = 0, 31, 1 do
|
|
local position = {x = left_top_x + x, y = left_top_y + y}
|
|
if is_biter_area(position) then
|
|
local index = math_floor(GetNoise('bb_biterland', position, seed) * 48) % 7 + 1
|
|
out_of_map[i] = {name = 'out-of-map', position = position}
|
|
tiles[i] = {name = 'dirt-' .. index, position = position}
|
|
i = i + 1
|
|
end
|
|
end
|
|
end
|
|
|
|
surface.set_tiles(out_of_map, false)
|
|
surface.set_tiles(tiles, true)
|
|
|
|
for _ = 1, 4, 1 do
|
|
local v = chunk_tile_vectors[math_random(1, size_of_chunk_tile_vectors)]
|
|
local position = {x = left_top_x + v[1], y = left_top_y + v[2]}
|
|
if is_biter_area(position) and surface.can_place_entity({name = 'spitter-spawner', position = position}) then
|
|
if math_random(1, 4) == 1 then
|
|
local e = surface.create_entity({name = 'spitter-spawner', position = position, force = 'enemy'})
|
|
e.active = false
|
|
else
|
|
local e = surface.create_entity({name = 'biter-spawner', position = position, force = 'enemy'})
|
|
e.active = false
|
|
end
|
|
end
|
|
end
|
|
|
|
local e = (math_abs(left_top_y) - bb_config.bitera_area_distance) * 0.0015
|
|
for _ = 1, math_random(5, 10), 1 do
|
|
local v = chunk_tile_vectors[math_random(1, size_of_chunk_tile_vectors)]
|
|
local position = {x = left_top_x + v[1], y = left_top_y + v[2]}
|
|
local worm_turret_name = BiterRaffle.roll('worm', e)
|
|
if is_biter_area(position) and surface.can_place_entity({name = worm_turret_name, position = position}) then
|
|
surface.create_entity({name = worm_turret_name, position = position, force = 'enemy'})
|
|
end
|
|
end
|
|
end
|
|
|
|
local function mixed_ore(surface, left_top_x, left_top_y)
|
|
local seed = game.surfaces['bb_source'].map_gen_settings.seed
|
|
|
|
local noise = GetNoise('bb_ore', {x = left_top_x + 16, y = left_top_y + 16}, seed)
|
|
|
|
--Draw noise text values to determine which chunks are valid for mixed ore.
|
|
--rendering.draw_text{text = noise, surface = game.surfaces.biter_battles, target = {x = left_top_x + 16, y = left_top_y + 16}, color = {255, 255, 255}, scale = 2, font = "default-game"}
|
|
|
|
--Skip chunks that are too far off the ore noise value.
|
|
if noise < 0.42 then
|
|
return
|
|
end
|
|
|
|
--Draw the mixed ore patches.
|
|
for x = 0, 31, 1 do
|
|
for y = 0, 31, 1 do
|
|
local pos = {x = left_top_x + x, y = left_top_y + y}
|
|
if surface.can_place_entity({name = 'iron-ore', position = pos}) then
|
|
local noise = GetNoise('bb_ore', pos, seed)
|
|
if noise > 0.72 then
|
|
local amount = math_random(800, 1000) + math_sqrt(pos.x ^ 2 + pos.y ^ 2) * 3
|
|
local i = math_floor(noise * 25 + math_abs(pos.x) * 0.05) % 4 + 1
|
|
surface.create_entity({name = ores[i], position = pos, amount = amount})
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
if left_top_y == -32 and math_abs(left_top_x) <= 32 then
|
|
for _, e in pairs(surface.find_entities_filtered({area = {{-12, -12}, {12, 12}}})) do
|
|
e.destroy()
|
|
end
|
|
end
|
|
end
|
|
|
|
function Public.generate(event)
|
|
local surface = event.surface
|
|
local left_top = event.area.left_top
|
|
local left_top_x = left_top.x
|
|
local left_top_y = left_top.y
|
|
|
|
if surface.name == 'biter_battles' then
|
|
local tiles = {}
|
|
if math_abs(left_top_x) > 64 or math_abs(left_top_y) > 64 then
|
|
for k, v in pairs(loading_chunk_vectors) do
|
|
tiles[k] = {name = 'out-of-map', position = {left_top_x + v[1], left_top_y + v[2]}}
|
|
end
|
|
end
|
|
surface.set_tiles(tiles, false)
|
|
return
|
|
end
|
|
|
|
if surface.name ~= 'bb_source' then
|
|
return
|
|
end
|
|
|
|
if left_top_y == 0 then
|
|
local tiles = {}
|
|
local i = 0
|
|
for x = 0, 31, 1 do
|
|
for y = 0, 31, 1 do
|
|
i = i + 1
|
|
tiles[i] = {name = 'out-of-map', position = {left_top_x + x, left_top_y + y}}
|
|
end
|
|
end
|
|
surface.set_tiles(tiles, false)
|
|
return
|
|
end
|
|
|
|
if left_top_y > 0 then
|
|
return
|
|
end
|
|
|
|
mixed_ore(surface, left_top_x, left_top_y)
|
|
generate_river(surface, left_top_x, left_top_y)
|
|
draw_biter_area(surface, left_top_x, left_top_y)
|
|
generate_extra_worm_turrets(surface, left_top)
|
|
end
|
|
|
|
function Public.draw_spawn_circle(surface)
|
|
local tiles = {}
|
|
for x = spawn_circle_size * -1, -1, 1 do
|
|
for y = spawn_circle_size * -1, -1, 1 do
|
|
local pos = {x = x, y = y}
|
|
local distance_to_center = math_sqrt(pos.x ^ 2 + pos.y ^ 2)
|
|
if distance_to_center <= spawn_circle_size then
|
|
table_insert(tiles, {name = 'deepwater', position = pos})
|
|
|
|
if distance_to_center < 9.5 then
|
|
table_insert(tiles, {name = 'refined-concrete', position = pos})
|
|
if distance_to_center < 7 then
|
|
table_insert(tiles, {name = 'sand-1', position = pos})
|
|
end
|
|
-- else
|
|
--
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
for i = 1, #tiles, 1 do
|
|
table_insert(tiles, {name = tiles[i].name, position = {tiles[i].position.x * -1 - 1, tiles[i].position.y}})
|
|
end
|
|
|
|
surface.set_tiles(tiles, true)
|
|
|
|
for i = 1, #tiles, 1 do
|
|
if tiles[i].name == 'deepwater' then
|
|
if math_random(1, 48) == 1 then
|
|
local e = surface.create_entity({name = 'fish', position = tiles[i].position})
|
|
e.active = false
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function Public.fill_water_tiles(surface)
|
|
local chunk_r = 8
|
|
local r = chunk_r * 32
|
|
|
|
for x = r * -1, r, 1 do
|
|
for y = r * -1, -4, 1 do
|
|
local pos = {x = x, y = y}
|
|
local distance_to_center = math_sqrt(pos.x ^ 2 + pos.y ^ 2)
|
|
if distance_to_center < 550 and not is_horizontal_border_river(pos) then
|
|
local tile_name = surface.get_tile(pos).name
|
|
if tile_name == 'water' or tile_name == 'deepwater' then
|
|
surface.set_tiles({{name = get_replacement_tile(surface, pos), position = pos}}, true)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function Public.draw_spawn_area(surface)
|
|
local chunk_r = 4
|
|
local r = chunk_r * 32
|
|
|
|
for x = r * -1, r, 1 do
|
|
for y = r * -1, -4, 1 do
|
|
local pos = {x = x, y = y}
|
|
local distance_to_center = math_sqrt(pos.x ^ 2 + pos.y ^ 2)
|
|
generate_starting_area(pos, distance_to_center, surface)
|
|
end
|
|
end
|
|
|
|
surface.destroy_decoratives({})
|
|
surface.regenerate_decorative()
|
|
end
|
|
|
|
function Public.generate_additional_spawn_ore(surface)
|
|
local r = 130
|
|
local area = {{r * -1, r * -1}, {r, 0}}
|
|
local ores = {}
|
|
ores['iron-ore'] = surface.count_entities_filtered({name = 'iron-ore', area = area})
|
|
ores['copper-ore'] = surface.count_entities_filtered({name = 'copper-ore', area = area})
|
|
ores['coal'] = surface.count_entities_filtered({name = 'coal', area = area})
|
|
ores['stone'] = surface.count_entities_filtered({name = 'stone', area = area})
|
|
for ore, ore_count in pairs(ores) do
|
|
if ore_count < 1000 or ore_count == nil then
|
|
local pos = {}
|
|
for a = 1, 32, 1 do
|
|
pos = {x = -96 + math_random(0, 192), y = -20 - math_random(0, 96)}
|
|
if surface.can_place_entity({name = 'coal', position = pos, amount = 1}) then
|
|
break
|
|
end
|
|
end
|
|
draw_noise_ore_patch(pos, ore, surface, math_random(18, 24), math_random(1500, 2000))
|
|
end
|
|
end
|
|
end
|
|
|
|
function Public.generate_additional_rocks(surface)
|
|
local r = 130
|
|
if surface.count_entities_filtered({type = 'simple-entity', area = {{r * -1, r * -1}, {r, 0}}}) >= 12 then
|
|
return
|
|
end
|
|
local position = {x = -96 + math_random(0, 192), y = -40 - math_random(0, 96)}
|
|
local rocks = {'rock-huge', 'rock-big', 'rock-big', 'rock-big', 'sand-rock-big'}
|
|
for _ = 1, math_random(6, 10) do
|
|
local name = rocks[math_random(1, 5)]
|
|
local p = surface.find_non_colliding_position(name, {position.x + (-10 + math_random(0, 20)), position.y + (-10 + math_random(0, 20))}, 16, 1)
|
|
if p and p.y < -16 then
|
|
surface.create_entity({name = name, position = p})
|
|
end
|
|
end
|
|
end
|
|
|
|
function Public.generate_silo(surface)
|
|
local pos = {x = -32 + math_random(0, 64), y = -72}
|
|
local mirror_position = {x = pos.x * -1, y = pos.y * -1}
|
|
|
|
for _, t in pairs(surface.find_tiles_filtered({area = {{pos.x - 6, pos.y - 6}, {pos.x + 6, pos.y + 6}}, name = {'water', 'deepwater'}})) do
|
|
surface.set_tiles({{name = get_replacement_tile(surface, t.position), position = t.position}})
|
|
end
|
|
for _, t in pairs(surface.find_tiles_filtered({area = {{mirror_position.x - 6, mirror_position.y - 6}, {mirror_position.x + 6, mirror_position.y + 6}}, name = {'water', 'deepwater'}})) do
|
|
surface.set_tiles({{name = get_replacement_tile(surface, t.position), position = t.position}})
|
|
end
|
|
|
|
local silo =
|
|
surface.create_entity(
|
|
{
|
|
name = 'rocket-silo',
|
|
position = pos,
|
|
force = 'neutral'
|
|
}
|
|
)
|
|
silo.minable = false
|
|
silo.active = false
|
|
|
|
for i = 1, 32, 1 do
|
|
create_mirrored_tile_chain(surface, {name = 'stone-path', position = silo.position}, 32, 10)
|
|
end
|
|
|
|
local p = silo.position
|
|
for _, entity in pairs(surface.find_entities({{p.x - 4, p.y - 4}, {p.x + 4, p.y + 4}})) do
|
|
if entity.type == 'simple-entity' or entity.type == 'tree' or entity.type == 'resource' then
|
|
entity.destroy()
|
|
end
|
|
end
|
|
|
|
if bb_config.spawn_turrets_at_silo then
|
|
local turret1 = surface.create_entity({name = 'gun-turret', position = {x = pos.x, y = pos.y - 5}, force = 'neutral'})
|
|
turret1.insert({name = 'firearm-magazine', count = 10})
|
|
turret1.active = false
|
|
local turret2 = surface.create_entity({name = 'gun-turret', position = {x = pos.x + 2, y = pos.y - 5}, force = 'neutral'})
|
|
turret2.insert({name = 'firearm-magazine', count = 10})
|
|
turret2.active = false
|
|
end
|
|
end
|
|
--[[
|
|
function Public.generate_spawn_goodies(surface)
|
|
local tiles = surface.find_tiles_filtered({name = "stone-path"})
|
|
table.shuffle_table(tiles)
|
|
local budget = 1500
|
|
local min_roll = 30
|
|
local max_roll = 600
|
|
local blacklist = {
|
|
["automation-science-pack"] = true,
|
|
["logistic-science-pack"] = true,
|
|
["military-science-pack"] = true,
|
|
["chemical-science-pack"] = true,
|
|
["production-science-pack"] = true,
|
|
["utility-science-pack"] = true,
|
|
["space-science-pack"] = true,
|
|
["loader"] = true,
|
|
["fast-loader"] = true,
|
|
["express-loader"] = true,
|
|
}
|
|
local container_names = {"wooden-chest", "wooden-chest", "iron-chest"}
|
|
for k, tile in pairs(tiles) do
|
|
if budget <= 0 then return end
|
|
if surface.can_place_entity({name = "wooden-chest", position = tile.position, force = "neutral"}) then
|
|
local v = math_random(min_roll, max_roll)
|
|
local item_stacks = LootRaffle.roll(v, 4, blacklist)
|
|
local container = surface.create_entity({name = container_names[math_random(1, 3)], position = tile.position, force = "neutral"})
|
|
for _, item_stack in pairs(item_stacks) do container.insert(item_stack) end
|
|
budget = budget - v
|
|
end
|
|
end
|
|
end
|
|
]]
|
|
function Public.minable_wrecks(event)
|
|
local entity = event.entity
|
|
if not entity then
|
|
return
|
|
end
|
|
if not entity.valid then
|
|
return
|
|
end
|
|
if not valid_wrecks[entity.name] then
|
|
return
|
|
end
|
|
|
|
local surface = entity.surface
|
|
local player = game.players[event.player_index]
|
|
|
|
local loot_worth = math_floor(math_abs(entity.position.x * 0.02)) + math_random(16, 32)
|
|
local blacklist = LootRaffle.get_tech_blacklist(math_abs(entity.position.x * 0.0001) + 0.10)
|
|
for k, v in pairs(blacklist) do
|
|
print(k)
|
|
end
|
|
for k, v in pairs(loot_blacklist) do
|
|
blacklist[k] = true
|
|
end
|
|
local item_stacks = LootRaffle.roll(loot_worth, math_random(1, 3), blacklist)
|
|
|
|
for k, stack in pairs(item_stacks) do
|
|
local amount = stack.count
|
|
local name = stack.name
|
|
|
|
local inserted_count = player.insert({name = name, count = amount})
|
|
if inserted_count ~= amount then
|
|
local amount_to_spill = amount - inserted_count
|
|
surface.spill_item_stack(entity.position, {name = name, count = amount_to_spill}, true)
|
|
end
|
|
|
|
surface.create_entity(
|
|
{
|
|
name = 'flying-text',
|
|
position = {entity.position.x, entity.position.y - 0.5 * k},
|
|
text = '+' .. amount .. ' [img=item/' .. name .. ']',
|
|
color = {r = 0.98, g = 0.66, b = 0.22}
|
|
}
|
|
)
|
|
end
|
|
end
|
|
|
|
--Landfill Restriction
|
|
function Public.restrict_landfill(surface, inventory, tiles)
|
|
for _, t in pairs(tiles) do
|
|
local distance_to_center = math_sqrt(t.position.x ^ 2 + t.position.y ^ 2)
|
|
local check_position = t.position
|
|
if check_position.y > 0 then
|
|
check_position = {x = check_position.x * -1, y = (check_position.y * -1) - 1}
|
|
end
|
|
if is_horizontal_border_river(check_position) or distance_to_center < spawn_circle_size then
|
|
surface.set_tiles({{name = t.old_tile.name, position = t.position}}, true)
|
|
inventory.insert({name = 'landfill', count = 1})
|
|
end
|
|
end
|
|
end
|
|
|
|
--Construction Robot Restriction
|
|
local robot_build_restriction = {
|
|
['north'] = function(y)
|
|
if y >= -10 then
|
|
return true
|
|
end
|
|
end,
|
|
['south'] = function(y)
|
|
if y <= 10 then
|
|
return true
|
|
end
|
|
end
|
|
}
|
|
|
|
function Public.deny_construction_bots(event)
|
|
if not robot_build_restriction[event.robot.force.name] then
|
|
return
|
|
end
|
|
if not robot_build_restriction[event.robot.force.name](event.created_entity.position.y) then
|
|
return
|
|
end
|
|
local inventory = event.robot.get_inventory(defines.inventory.robot_cargo)
|
|
inventory.insert({name = event.created_entity.name, count = 1})
|
|
event.robot.surface.create_entity({name = 'explosion', position = event.created_entity.position})
|
|
game.print('Team ' .. event.robot.force.name .. "'s construction drone had an accident.", {r = 200, g = 50, b = 100})
|
|
event.created_entity.destroy()
|
|
end
|
|
|
|
return Public
|