1
0
mirror of https://github.com/Refactorio/RedMew.git synced 2025-01-18 03:21:47 +02:00

Refactor all the danger ore maps

This commit is contained in:
James Gillham 2020-09-02 12:26:19 +01:00
parent fb7a2f4136
commit 0ad994dca2
36 changed files with 2089 additions and 2686 deletions

View File

@ -1,367 +1 @@
local b = require 'map_gen.shared.builders'
local Generate = require 'map_gen.shared.generate'
local Perlin = require 'map_gen.shared.perlin_noise'
local Event = require 'utils.event'
local Global = require 'utils.global'
local math = require 'utils.math'
local table = require 'utils.table'
local RS = require 'map_gen.shared.redmew_surface'
local MGSP = require 'resources.map_gen_settings'
local ores_init = require 'map_gen.maps.danger_bobangels_ores.ore'
local RocketLaunched = require 'map_gen.maps.danger_bobangels_ores.rocket_launched'
local concat = table.concat
local format = string.format
local ScenarioInfo = require 'features.gui.info'
ScenarioInfo.set_map_name('Danger Bobs & Angels Ore Quadrants')
ScenarioInfo.set_map_description(
[[
Clear the ore to expand the base,
focus mining efforts on specific quadrants to ensure
proper material ratios, expand the map with pollution!
]]
)
ScenarioInfo.add_map_extra_info(
[[
This map is split in 6 sectors. Each sector has a main resource.
You may not build the factory on ore patches. Exceptions:
[item=burner-mining-drill] [item=electric-mining-drill] [item=pumpjack] [item=small-electric-pole] [item=medium-electric-pole] [item=big-electric-pole] [item=substation] [item=car] [item=tank]
[item=basic-transport-belt] [item=transport-belt] [item=fast-transport-belt] [item=express-transport-belt] [item=turbo-transport-belt] [item=ultimate-transport-belt] [item=basic-underground-belt] [item=underground-belt] [item=fast-underground-belt] [item=express-underground-belt] [item=turbo-underground-belt] [item=ultimate-underground-belt]
The map size is restricted to the pollution generated. A significant amount of
pollution must affect a section of the map before it is revealed. Pollution
does not affect biter evolution.]]
)
ScenarioInfo.set_map_description(
[[
Clear the ore to expand the base,
focus mining efforts on specific sector to ensure
proper material ratios, expand the map with pollution!
]]
)
require 'map_gen.maps.danger_bobangels_ores.banned_entities'
global.config.lazy_bastard.enabled = false
local ores_names = {
'angels-ore1', -- Saphirite
'angels-ore2', -- Jivolite
'angels-ore3', -- stiratite
'angels-ore4', -- Crotinium
'angels-ore5', -- rubyte
'angels-ore6', -- bobmonium
'angels-fissure',
'angels-natural-gas', -- gas well
'coal',
'thorium-ore',
'crude-oil'
}
local ore_oil_none = {}
for _, v in ipairs(ores_names) do
ore_oil_none[v] = {
frequency = 1,
richness = 1,
size = 0
}
end
ore_oil_none = {autoplace_controls = ore_oil_none}
RS.set_first_player_position_check_override(true)
RS.set_spawn_island_tile('grass-1')
RS.set_map_gen_settings(
{
MGSP.grass_only,
MGSP.enable_water,
{
terrain_segmentation = 'normal',
water = 'normal'
},
MGSP.starting_area_very_low,
ore_oil_none,
MGSP.enemy_none,
MGSP.cliff_none
}
)
Generate.enable_register_events = false
local perlin_noise = Perlin.noise
local fast_remove = table.fast_remove
local spawn_circle = b.circle(80)
local water_scale = 1 / 96
local water_threshold = 0.5
local deepwater_threshold = 0.55
local non_water_zone = b.circle(102)
local tree_scale = 1 / 64
local tree_threshold = -0.25
local tree_chance = 0.125
local start_chunks_half_size = 4
local start_size = start_chunks_half_size * 64
local ores
local pollution_increment = 2
global.min_pollution = 300
global.max_pollution = 10000
local enemy_seed
local water_seed
local tree_seed
local chunk_list = {index = 1}
local surface
Global.register_init(
{chunk_list = chunk_list},
function(tbl)
local s = RS.get_surface()
tbl.seed = s.map_gen_settings.seed
tbl.surface = s
game.difficulty_settings.technology_price_multiplier = 20
game.forces.player.technologies['logistics-0'].researched = true
game.forces.player.technologies.automation.researched = true
game.forces.player.technologies['mining-productivity-1'].enabled = false
game.forces.player.technologies['mining-productivity-2'].enabled = false
game.forces.player.technologies['mining-productivity-3'].enabled = false
game.forces.player.technologies['mining-productivity-4'].enabled = false
game.map_settings.enemy_evolution.time_factor = 0.000007
game.map_settings.enemy_evolution.destroy_factor = 0.000010
game.map_settings.enemy_evolution.pollution_factor = 0.000000 -- Pollution has no affect on evolution
game.draw_resource_selection = false
tbl.random = game.create_random_generator(tbl.seed)
end,
function(tbl)
local seed = tbl.seed
enemy_seed = seed * 6
water_seed = seed * 7
tree_seed = seed * 8
chunk_list = tbl.chunk_list
surface = tbl.surface
local ores_shapes = ores_init(seed)
local random = tbl.random
random.re_seed(seed)
table.shuffle_table(ores_shapes, random)
ores = b.segment_weighted_pattern(ores_shapes)
end
)
local worm_names = {'small-worm-turret', 'medium-worm-turret', 'big-worm-turret', 'behemoth-worm-turret'}
local spawner_names = {'biter-spawner', 'spitter-spawner'}
local factor = 10 / (768 * 32)
local max_chance = 1 / 6
local scale_factor = 32
local sf = 1 / scale_factor
local m = 1 / 850
local function enemy(x, y, world)
if global.win_condition_biters_disabled == true then
return nil
end
local d = math.sqrt(world.x * world.x + world.y * world.y)
if d < 64 then
return nil
end
local threshold = 1 - d * m
threshold = math.max(threshold, 0.35)
x, y = x * sf, y * sf
if perlin_noise(x, y, enemy_seed) <= threshold then
return
end
if math.random(8) == 1 then
local lvl
if d < 400 then
lvl = 1
elseif d < 650 then
lvl = 2
elseif d < 900 then
lvl = 3
else
lvl = 4
end
local chance = math.min(max_chance, d * factor)
if math.random() < chance then
local worm_id
if d > 1000 then
local power = 1000 / d
worm_id = math.ceil((math.random() ^ power) * lvl)
else
worm_id = math.random(lvl)
end
return {name = worm_names[worm_id]}
end
else
local chance = math.min(max_chance, d * factor)
if math.random() < chance then
local spawner_id = math.random(2)
return {name = spawner_names[spawner_id]}
end
end
end
local function water_shape(x, y)
if non_water_zone(x, y) then
return false
end
local water_noise = perlin_noise(x * water_scale, y * water_scale, water_seed)
if water_noise >= deepwater_threshold then
return 'deepwater'
elseif water_noise >= water_threshold then
return 'water'
else
return false
end
end
local trees = {
'tree-01',
'tree-02',
'tree-02-red',
'tree-03',
'tree-04',
'tree-05',
'tree-06',
'tree-06-brown',
'tree-07',
'tree-08',
'tree-08-brown',
'tree-08-red',
'tree-09',
'tree-09-brown',
'tree-09-red'
}
local trees_count = #trees
local function tree_shape(x, y)
local tree_noise = perlin_noise(x * tree_scale, y * tree_scale, tree_seed)
if tree_noise > tree_threshold or math.random() > tree_chance then
return nil
end
return {name = trees[math.random(trees_count)]}
end
local water = b.circle(16)
water = b.change_tile(water, true, 'water')
water = b.any {b.rectangle(32, 4), b.rectangle(4, 32), water}
local start = b.if_else(water, spawn_circle)
start = b.change_map_gen_collision_tile(start, 'water-tile', 'grass-1')
local function ores_shape(x, y, world)
return ores(x, y, world)
end
local map = b.any {start, water_shape, ores_shape}
map = b.apply_entity(map, enemy)
map = b.apply_entity(map, tree_shape)
map = b.fish(map, 0.025)
local bounds = b.rectangle(start_size, start_size)
local function on_chunk(event)
if surface ~= event.surface then
return
end
local left_top = event.area.left_top
local x, y = left_top.x, left_top.y
if bounds(x + 0.5, y + 0.5) then
Generate.do_chunk(event)
else
local tiles = {}
for x1 = x, x + 31 do
for y1 = y, y + 31 do
tiles[#tiles + 1] = {name = 'out-of-map', position = {x1, y1}}
end
end
surface.set_tiles(tiles, true)
chunk_list[#chunk_list + 1] = {left_top = left_top, id = nil}
end
end
local function on_tick()
local index = chunk_list.index
if index > #chunk_list then
chunk_list.index = 1
return
end
local data = chunk_list[index]
local pos = data.left_top
local x, y = pos.x, pos.y
local pollution = surface.get_pollution(pos)
local current_min_pollution = global.min_pollution
if pollution > current_min_pollution then
fast_remove(chunk_list, index)
local id = data.id
if id then
rendering.destroy(id)
end
local area = {left_top = pos, right_bottom = {x + 32, y + 32}}
local event = {surface = surface, area = area}
Generate.schedule_chunk(event)
RocketLaunched.chunk_unlocked(event)
if current_min_pollution < global.max_pollution then
global.min_pollution = current_min_pollution + pollution_increment
end
return
else
local text = concat {format('%i', pollution), ' / ', current_min_pollution}
local complete = pollution / current_min_pollution
local color = {r = 1 - complete, g = complete, b = 0}
local id = data.id
if not id then
data.id =
rendering.draw_text {
text = text,
surface = surface,
target = {x + 16, y + 16},
color = color,
scale = 5
}
else
rendering.set_text(id, text)
rendering.set_color(id, color)
end
end
chunk_list.index = index + 1
end
Event.add(defines.events.on_chunk_generated, on_chunk)
Event.on_nth_tick(1, on_tick)
return map
return require 'map_gen.maps.danger_ores.presets.danger_bobangels_ores'

View File

@ -1,85 +0,0 @@
-- This module prevents all but the allowed items from being built on top of resources
local RestrictEntities = require 'map_gen.shared.entity_placement_restriction'
local Event = require 'utils.event'
--- Items explicitly allowed on ores
RestrictEntities.add_allowed(
{
'basic-transport-belt',
'transport-belt',
'fast-transport-belt',
'express-transport-belt',
'turbo-transport-belt',
'ultimate-transport-belt',
'basic-underground-belt',
'underground-belt',
'fast-underground-belt',
'express-underground-belt',
'turbo-underground-belt',
'ultimate-underground-belt',
'small-electric-pole',
'medium-electric-pole',
'medium-electric-pole-2',
'medium-electric-pole-3',
'medium-electric-pole-4',
'big-electric-pole',
'big-electric-pole-2',
'big-electric-pole-3',
'big-electric-pole-4',
'substation',
'substation-2',
'substation-3',
'substation-4',
'electric-mining-drill',
'bob-mining-drill-1',
'bob-mining-drill-2',
'bob-mining-drill-3',
'bob-mining-drill-4',
'bob-area-mining-drill-1',
'bob-area-mining-drill-2',
'bob-area-mining-drill-3',
'bob-area-mining-drill-4',
'burner-mining-drill',
'pumpjack',
'bob-pumpjack-1',
'bob-pumpjack-2',
'bob-pumpjack-3',
'bob-pumpjack-4',
'water-miner-1',
'water-miner-2',
'water-miner-3',
'water-miner-4',
'water-miner-5',
'car',
'tank',
'bob-tank-2',
'bob-tank-3',
'thermal-water-extractor'
}
)
--- The logic for checking that there are resources under the entity's position
RestrictEntities.set_keep_alive_callback(
function(entity)
-- Some entities have a bounding_box area of zero, eg robots.
local area = entity.bounding_box
local left_top, right_bottom = area.left_top, area.right_bottom
if left_top.x == right_bottom.x and left_top.y == right_bottom.y then
return true
end
local count = entity.surface.count_entities_filtered {area = area, type = 'resource', limit = 1}
if count == 0 then
return true
end
end
)
--- Warning for players when their entities are destroyed
local function on_destroy(event)
local p = event.player
if p and p.valid then
p.print('You cannot build that on top of ores, only belts, mining drills, and power poles are allowed.')
end
end
Event.add(RestrictEntities.events.on_restricted_entity_destroyed, on_destroy)

View File

@ -1,289 +0,0 @@
local b = require 'map_gen.shared.builders'
local Perlin = require 'map_gen.shared.perlin_noise'
local table = require 'utils.table'
local Debug = require 'utils.debug'
local random = math.random
local floor = math.floor
local value = b.euclidean_value
local binary_search = table.binary_search
local bnot = bit32.bnot
local perlin_noise = Perlin.noise
local mixed_ores = true
local tile_scale = 1 / 64
local spawn_zone = b.circle(85)
local density_scale = 1 / 48
local density_threshold = 0.5
local density_multiplier = 50
local ores = {
['angels-ore1'] = { -- Saphirite
['tiles'] = {
[1] = 'grass-1',
[2] = 'grass-2',
[3] = 'grass-3',
[4] = 'grass-4'
},
['start'] = value(125, 0),
['non_mixed_value'] = value(0, 0.5),
['weight'] = 15,
['ratios'] = {}
},
['angels-ore2'] = { -- Jivolite
['tiles'] = {
[1] = 'dirt-1',
[2] = 'dirt-2',
[3] = 'dirt-3'
},
['start'] = value(125, 0),
['non_mixed_value'] = value(0, 0.5),
['weight'] = 10,
['ratios'] = {}
},
['angels-ore3'] = { -- Stiratite
['tiles'] = {
[1] = 'red-desert-0',
[2] = 'red-desert-1',
[3] = 'red-desert-2',
[4] = 'red-desert-3'
},
['start'] = value(125, 0),
['non_mixed_value'] = value(0, 0.5),
['weight'] = 10,
['ratios'] = {}
},
['angels-ore4'] = { -- crotinnium
['tiles'] = {
[1] = 'grass-3',
[2] = 'grass-4'
},
['start'] = value(125, 0),
['non_mixed_value'] = value(0, 0.5),
['weight'] = 10,
['ratios'] = {}
},
['angels-ore5'] = { -- rubyte
['tiles'] = {
[1] = 'grass-1',
[2] = 'grass-2'
},
['start'] = value(125, 0),
['non_mixed_value'] = value(0, 0.5),
['weight'] = 10,
['ratios'] = {}
},
['angels-ore6'] = { -- bobmonium-ore
['tiles'] = {
[1] = 'sand-1',
[2] = 'sand-2',
[3] = 'sand-3'
},
['start'] = value(125, 0),
['non_mixed_value'] = value(0, 0.5),
['weight'] = 10,
['ratios'] = {}
},
['coal'] = {
['tiles'] = {
[1] = 'dirt-5',
[2] = 'dirt-6',
[3] = 'dirt-7'
},
['start'] = value(125, 0),
['non_mixed_value'] = value(0, 0.5),
['weight'] = 10,
['ratios'] = {}
}
}
-- Build ratios based on global weights
local ratio_mixed = 80 -- % purity in the ore
local oil_scale = 1 / 64
local oil_threshold = 0.6
local oil_shape = b.throttle_world_xy(b.full_shape, 1, 7, 1, 7)
local oil_resource = b.resource(oil_shape, 'crude-oil', value(250000, 150))
local fissure_scale = 1 / 100
local fissure_threshold = 0.6
local fissure_shape = b.throttle_world_xy(b.full_shape, 1, 7, 1, 7)
local fissure_resource = b.resource(fissure_shape, 'angels-fissure', value(25000, 150))
local gas_well_scale = 1 / 64
local gas_well_threshold = 0.6
local gas_well_shape = b.throttle_world_xy(b.full_shape, 1, 7, 1, 7)
local gas_well_resource = b.resource(gas_well_shape, 'angels-natural-gas', value(25000, 150))
local thorium_scale = 1 / 72
local thorium_threshold = 0.63
local thorium_resource = b.resource(b.full_shape, 'thorium-ore', value(200, 1))
local function init(seed)
local oil_seed = seed * 2
local uranium_seed = seed * 3
local density_seed = seed * 4
local thorium_seed = seed * 5
local fissure_seed = seed * 6
local gas_well_seed = seed * 7
local function tile_builder(tiles)
local count = #tiles / 2
return function(x, y)
x, y = x * tile_scale, y * tile_scale
local v = perlin_noise(x, y, seed)
v = ((v + 1) * count) + 1
v = floor(v)
return tiles[v]
end
end
local function ore_builder(ore_name, amount, ratios, weighted)
local start_ore = b.resource(b.full_shape, ore_name, amount)
local total = weighted.total
return function(x, y, world)
if spawn_zone(x, y) then
return start_ore(x, y, world)
end
local oil_x, oil_y = x * oil_scale, y * oil_scale
local oil_noise = perlin_noise(oil_x, oil_y, oil_seed)
if oil_noise > oil_threshold then
return oil_resource(x, y, world)
end
local fissure_x, fissure_y = x * fissure_scale, y * fissure_scale
local fissure_noise = perlin_noise(fissure_x, fissure_y, fissure_seed)
if fissure_noise > fissure_threshold then
return fissure_resource(x, y, world)
end
local gas_well_x, gas_well_y = x * gas_well_scale, y * gas_well_scale
local gas_well_noise = perlin_noise(gas_well_x, gas_well_y, gas_well_seed)
if gas_well_noise > gas_well_threshold then
return gas_well_resource(x, y, world)
end
local thorium_x, thorium_y = x * thorium_scale, y * thorium_scale
local thorium_noise = perlin_noise(thorium_x, thorium_y, thorium_seed)
if thorium_noise > thorium_threshold then
return thorium_resource(x, y, world)
end
local i = random() * total
local index = binary_search(weighted, i)
if index < 0 then
index = bnot(index)
end
local resource = ratios[index].resource
local entity = resource(x, y, world)
local density_x, density_y = x * density_scale, y * density_scale
local density_noise = perlin_noise(density_x, density_y, density_seed)
if density_noise > density_threshold then
entity.amount = entity.amount * density_multiplier
end
entity.enable_tree_removal = false
return entity
end
end
local function non_mixed_ore_builder(ore_name, amount)
local resource = b.resource(b.full_shape, ore_name, amount)
return function(x, y, world)
if spawn_zone(x, y) then
return resource(x, y, world)
end
local oil_x, oil_y = x * oil_scale, y * oil_scale
local oil_noise = perlin_noise(oil_x, oil_y, oil_seed)
if oil_noise > oil_threshold then
return oil_resource(x, y, world)
end
local fissure_x, fissure_y = x * fissure_scale, y * fissure_scale
local fissure_noise = perlin_noise(fissure_x, fissure_y, fissure_seed)
if fissure_noise > fissure_threshold then
return fissure_resource(x, y, world)
end
local gas_well_x, gas_well_y = x * gas_well_scale, y * gas_well_scale
local gas_well_noise = perlin_noise(gas_well_x, gas_well_y, gas_well_seed)
if gas_well_noise > gas_well_threshold then
return gas_well_resource(x, y, world)
end
local thorium_x, thorium_y = x * thorium_scale, y * thorium_scale
local thorium_noise = perlin_noise(thorium_x, thorium_y, thorium_seed)
if thorium_noise > thorium_threshold then
return thorium_resource(x, y, world)
end
local entity = resource(x, y, world)
local density_x, density_y = x * density_scale, y * density_scale
local density_noise = perlin_noise(density_x, density_y, density_seed)
if density_noise > density_threshold then
entity.amount = entity.amount * density_multiplier
end
entity.enable_tree_removal = false
return entity
end
end
local shapes = {}
for ore_name, v in pairs(ores) do
local tiles = v.tiles
local land = tile_builder(tiles)
local ore
if mixed_ores then
local ratios = {
{resource = b.resource(b.full_shape, ore_name, value(0, 0.5)), weight = ( ratio_mixed ) }
}
local other_ratios = 0
for ore2_name, v2 in pairs(ores) do
if ore2_name ~= ore_name then
other_ratios = other_ratios + v2.weight
end
end
local pos = 0
for ore2_name, v2 in pairs(ores) do
Debug.print('Attempting to add ' .. ore2_name .. ' to ratio')
pos = pos + 1
if ore2_name ~= ore_name then
table.insert(ratios, {resource = b.resource(b.full_shape, ore2_name, value(0, 0.5)), weight = ( ( 100 - ratio_mixed) * ( v2.weight / other_ratios ) ) })
end
end
local weighted = b.prepare_weighted_array(ratios)
local amount = v.start
Debug.print('Number of mixed ores in ratio ' .. #ratios)
ore = ore_builder(ore_name, amount, ratios, weighted)
else
local amount = v.non_mixed_value
ore = non_mixed_ore_builder(ore_name, amount)
end
local shape = b.apply_entity(land, ore)
shapes[#shapes + 1] = {shape = shape, weight = v.weight}
end
return shapes
end
return init

View File

@ -1,221 +0,0 @@
local Event = require 'utils.event'
local Global = require 'utils.global'
local Queue = require 'utils.queue'
local AlienEvolutionProgress = require 'utils.alien_evolution_progress'
local RS = require 'map_gen.shared.redmew_surface'
local Task = require 'utils.task'
local Token = require 'utils.token'
local recent_chunks = Queue.new() -- Keeps track of recently revealed chunks
local recent_chunks_max = 5 -- Maximum number of chunks to track
local ticks_between_waves = 60 * 30 - recent_chunks_max
local enemy_factor = 5
local max_enemies_per_wave_per_chunk = 60
local Public = {}
global.win_condition_evolution_rocket_maxed = -1
global.win_condition_biters_disabled = false
global.win_condition_extra_rockets = 10000
Global.register(
recent_chunks,
function(tbl)
recent_chunks = tbl
end
)
local function give_command(group, data)
local target = data.target
if target and target.valid then
local command = {
type = defines.command.attack,
target = target,
distraction = defines.distraction.by_damage
}
group.set_command(command)
group.start_moving()
else
local command = {
type = defines.command.attack_area,
destination = data.position,
radius = 32,
distraction = defines.distraction.by_damage
}
local members = group.members
for i = 1, #members do
local entitiy = members[i]
entitiy.set_command(command)
end
end
end
local do_waves
local do_wave
do_waves =
Token.register(
function(data)
Task.queue_task(do_wave, data, 10)
end
)
do_wave =
Token.register(
function(data)
local wave = data.wave
local last_wave = data.last_wave
--game.print('wave: ' .. wave .. '/' .. last_wave)
local chunk_index = data.chunk_index
local chunk = data.chunks[chunk_index]
if not chunk then
data.wave = wave + 1
data.chunk_index = 1
Task.set_timeout_in_ticks(ticks_between_waves, do_waves, data)
return false
end
local spawner = data.spawner
local aliens = AlienEvolutionProgress.get_aliens(spawner, game.forces.enemy.evolution_factor)
local left_top = chunk.area.left_top
local center = {left_top.x + 16, left_top.y + 16}
local surface = chunk.surface
local find_non_colliding_position = surface.find_non_colliding_position
local create_entity = surface.create_entity
local group = surface.create_unit_group {position = center}
local add_member = group.add_member
for name, count in pairs(aliens) do
for i = 1, count do
local pos = find_non_colliding_position(name, center, 32, 1)
if pos then
local e = {name = name, position = pos, force = 'enemy', center = center, radius = 16, 1}
local ent = create_entity(e)
add_member(ent)
end
end
end
give_command(group, data)
if chunk_index < recent_chunks_max then
data.chunk_index = chunk_index + 1
return true
end
if wave < last_wave then
data.wave = wave + 1
data.chunk_index = 1
Task.set_timeout_in_ticks(ticks_between_waves, do_waves, data)
end
return false
end
)
local function start_waves(event)
local num_enemies = enemy_factor * game.forces.player.get_item_launched('satellite')
local number_of_waves = math.ceil(num_enemies / max_enemies_per_wave_per_chunk)
local num_enemies_per_wave_per_chunk = math.ceil(num_enemies / number_of_waves)
local target = event.rocket_silo
local position
if target and target.valid then
position = target.position
else
position = {0, 0}
end
local data = {
spawner = AlienEvolutionProgress.create_spawner_request(num_enemies_per_wave_per_chunk),
wave = 1,
last_wave = number_of_waves,
chunk_index = 1,
chunks = Queue.to_array(recent_chunks),
target = target,
position = position
}
Task.set_timeout_in_ticks(1, do_waves, data)
game.print('Warning incomming biter attack! Number of waves: ' .. number_of_waves)
end
local function rocket_launched(event)
local entity = event.rocket
if not entity or not entity.valid or not entity.force == 'player' then
return
end
local inventory = entity.get_inventory(defines.inventory.rocket)
if not inventory or not inventory.valid then
return
end
local satellite_count = game.forces.player.get_item_launched('satellite')
if satellite_count == 0 then
return
end
-- Increase enemy_evolution
local current_evolution = game.forces.enemy.evolution_factor
local message
if global.win_condition_biters_disabled == false then
if (satellite_count % 5) == 0 and global.win_condition_evolution_rocket_maxed == -1 then
message =
'Continued launching of satellites has angered the local biter population, evolution increasing...'
game.print(message)
current_evolution = current_evolution + 0.05
end
if current_evolution >= 1 and global.win_condition_evolution_rocket_maxed == -1 then
current_evolution = 1
global.win_condition_evolution_rocket_maxed = satellite_count
message =
'Biters at maximum evolution! Protect the base for an additional ' .. global.win_condition_extra_rockets .. ' rockets to wipe them out forever.'
game.print(message)
end
game.forces.enemy.evolution_factor = current_evolution
if
global.win_condition_evolution_rocket_maxed > 0 and
satellite_count >= (global.win_condition_evolution_rocket_maxed + global.win_condition_extra_rockets)
then
message = 'Congratulations! Biters have been wiped from the map!'
game.print(message)
global.win_condition_biters_disabled = true
for key, enemy_entity in pairs(RS.get_surface().find_entities_filtered({force = 'enemy'})) do
enemy_entity.destroy()
end
else
start_waves(event)
end
end
end
function Public.chunk_unlocked(chunk)
Queue.push(recent_chunks, chunk)
while Queue.size(recent_chunks) > 10 do
Queue.pop(recent_chunks)
end
end
Event.add(defines.events.on_rocket_launched, rocket_launched)
return Public

View File

@ -1,376 +1 @@
local b = require 'map_gen.shared.builders'
local Generate = require 'map_gen.shared.generate'
local Perlin = require 'map_gen.shared.perlin_noise'
local Event = require 'utils.event'
local Global = require 'utils.global'
local math = require 'utils.math'
local table = require 'utils.table'
local RS = require 'map_gen.shared.redmew_surface'
local MGSP = require 'resources.map_gen_settings'
local ores_init = require 'map_gen.maps.danger_bobs_ores.ore'
local RocketLaunched = require 'map_gen.maps.danger_bobs_ores.rocket_launched'
local concat = table.concat
local format = string.format
local ScenarioInfo = require 'features.gui.info'
ScenarioInfo.set_map_name('Danger Ore Quadrants')
ScenarioInfo.set_map_description(
[[
Clear the ore to expand the base,
focus mining efforts on specific quadrants to ensure
proper material ratios, expand the map with pollution!
]]
)
ScenarioInfo.add_map_extra_info(
[[
This map is split in 17 sectors. Each sector has a main resource.
You may not build the factory on ore patches. Exceptions:
[item=burner-mining-drill] [item=electric-mining-drill] [item=pumpjack] [item=small-electric-pole] [item=medium-electric-pole] [item=big-electric-pole] [item=substation] [item=car] [item=tank]
[item=basic-transport-belt] [item=transport-belt] [item=fast-transport-belt] [item=express-transport-belt] [item=turbo-transport-belt] [item=ultimate-transport-belt] [item=basic-underground-belt] [item=underground-belt] [item=fast-underground-belt] [item=express-underground-belt] [item=turbo-underground-belt] [item=ultimate-underground-belt]
The map size is restricted to the pollution generated. A significant amount of
pollution must affect a section of the map before it is revealed. Pollution
does not affect biter evolution.]]
)
ScenarioInfo.set_map_description(
[[
Clear the ore to expand the base,
focus mining efforts on specific sector to ensure
proper material ratios, expand the map with pollution!
]]
)
require 'map_gen.maps.danger_bobs_ores.banned_entities'
global.config.lazy_bastard.enabled = false
local ores_names = {
'coal',
'copper-ore',
'crude-oil',
'iron-ore',
'stone',
'uranium-ore',
'bauxite-ore',
'cobalt-ore',
'gem-ore',
'gold-ore',
'lead-ore',
'nickel-ore',
'quartz',
'rutile-ore',
'silver-ore',
'sulfur',
'tin-ore',
'tungsten-ore',
'zinc-ore',
'thorium-ore'
}
local ore_oil_none = {}
for _, v in ipairs(ores_names) do
ore_oil_none[v] = {
frequency = 1,
richness = 1,
size = 0
}
end
ore_oil_none = {autoplace_controls = ore_oil_none}
RS.set_first_player_position_check_override(true)
RS.set_spawn_island_tile('grass-1')
RS.set_map_gen_settings(
{
MGSP.grass_only,
MGSP.enable_water,
{
terrain_segmentation = 'normal',
water = 'normal'
},
MGSP.starting_area_very_low,
ore_oil_none,
MGSP.enemy_none,
MGSP.cliff_none
}
)
Generate.enable_register_events = false
local perlin_noise = Perlin.noise
local fast_remove = table.fast_remove
local spawn_circle = b.circle(80)
local water_scale = 1 / 96
local water_threshold = 0.5
local deepwater_threshold = 0.55
local non_water_zone = b.circle(102)
local tree_scale = 1 / 64
local tree_threshold = -0.25
local tree_chance = 0.125
local start_chunks_half_size = 4
local start_size = start_chunks_half_size * 64
local ores
local pollution_increment = 4
global.min_pollution = 400
global.max_pollution = 20000
local enemy_seed
local water_seed
local tree_seed
local chunk_list = {index = 1}
local surface
Global.register_init(
{chunk_list = chunk_list},
function(tbl)
local s = RS.get_surface()
tbl.seed = s.map_gen_settings.seed
tbl.surface = s
game.difficulty_settings.technology_price_multiplier = 5
game.forces.player.technologies.logistics.researched = true
game.forces.player.technologies.automation.researched = true
game.forces.player.technologies['mining-productivity-1'].enabled = false
game.forces.player.technologies['mining-productivity-2'].enabled = false
game.forces.player.technologies['mining-productivity-3'].enabled = false
game.forces.player.technologies['mining-productivity-4'].enabled = false
game.map_settings.enemy_evolution.time_factor = 0.000007
game.map_settings.enemy_evolution.destroy_factor = 0.000010
game.map_settings.enemy_evolution.pollution_factor = 0.000000 -- Pollution has no affect on evolution
game.draw_resource_selection = false
tbl.random = game.create_random_generator(tbl.seed)
end,
function(tbl)
local seed = tbl.seed
enemy_seed = seed * 6
water_seed = seed * 7
tree_seed = seed * 8
chunk_list = tbl.chunk_list
surface = tbl.surface
local ores_shapes = ores_init(seed)
local random = tbl.random
random.re_seed(seed)
table.shuffle_table(ores_shapes, random)
ores = b.segment_weighted_pattern(ores_shapes)
end
)
local worm_names = {'small-worm-turret', 'medium-worm-turret', 'big-worm-turret', 'behemoth-worm-turret'}
local spawner_names = {'biter-spawner', 'spitter-spawner'}
local factor = 10 / (768 * 32)
local max_chance = 1 / 6
local scale_factor = 32
local sf = 1 / scale_factor
local m = 1 / 850
local function enemy(x, y, world)
if global.win_condition_biters_disabled == true then
return nil
end
local d = math.sqrt(world.x * world.x + world.y * world.y)
if d < 64 then
return nil
end
local threshold = 1 - d * m
threshold = math.max(threshold, 0.35)
x, y = x * sf, y * sf
if perlin_noise(x, y, enemy_seed) <= threshold then
return
end
if math.random(8) == 1 then
local lvl
if d < 400 then
lvl = 1
elseif d < 650 then
lvl = 2
elseif d < 900 then
lvl = 3
else
lvl = 4
end
local chance = math.min(max_chance, d * factor)
if math.random() < chance then
local worm_id
if d > 1000 then
local power = 1000 / d
worm_id = math.ceil((math.random() ^ power) * lvl)
else
worm_id = math.random(lvl)
end
return {name = worm_names[worm_id]}
end
else
local chance = math.min(max_chance, d * factor)
if math.random() < chance then
local spawner_id = math.random(2)
return {name = spawner_names[spawner_id]}
end
end
end
local function water_shape(x, y)
if non_water_zone(x, y) then
return false
end
local water_noise = perlin_noise(x * water_scale, y * water_scale, water_seed)
if water_noise >= deepwater_threshold then
return 'deepwater'
elseif water_noise >= water_threshold then
return 'water'
else
return false
end
end
local trees = {
'tree-01',
'tree-02',
'tree-02-red',
'tree-03',
'tree-04',
'tree-05',
'tree-06',
'tree-06-brown',
'tree-07',
'tree-08',
'tree-08-brown',
'tree-08-red',
'tree-09',
'tree-09-brown',
'tree-09-red'
}
local trees_count = #trees
local function tree_shape(x, y)
local tree_noise = perlin_noise(x * tree_scale, y * tree_scale, tree_seed)
if tree_noise > tree_threshold or math.random() > tree_chance then
return nil
end
return {name = trees[math.random(trees_count)]}
end
local water = b.circle(16)
water = b.change_tile(water, true, 'water')
water = b.any {b.rectangle(32, 4), b.rectangle(4, 32), water}
local start = b.if_else(water, spawn_circle)
start = b.change_map_gen_collision_tile(start, 'water-tile', 'grass-1')
local function ores_shape(x, y, world)
return ores(x, y, world)
end
local map = b.any {start, water_shape, ores_shape}
map = b.apply_entity(map, enemy)
map = b.apply_entity(map, tree_shape)
map = b.fish(map, 0.025)
local bounds = b.rectangle(start_size, start_size)
local function on_chunk(event)
if surface ~= event.surface then
return
end
local left_top = event.area.left_top
local x, y = left_top.x, left_top.y
if bounds(x + 0.5, y + 0.5) then
Generate.do_chunk(event)
else
local tiles = {}
for x1 = x, x + 31 do
for y1 = y, y + 31 do
tiles[#tiles + 1] = {name = 'out-of-map', position = {x1, y1}}
end
end
surface.set_tiles(tiles, true)
chunk_list[#chunk_list + 1] = {left_top = left_top, id = nil}
end
end
local function on_tick()
local index = chunk_list.index
if index > #chunk_list then
chunk_list.index = 1
return
end
local data = chunk_list[index]
local pos = data.left_top
local x, y = pos.x, pos.y
local pollution = surface.get_pollution(pos)
local current_min_pollution = global.min_pollution
if pollution > current_min_pollution then
fast_remove(chunk_list, index)
local id = data.id
if id then
rendering.destroy(id)
end
local area = {left_top = pos, right_bottom = {x + 32, y + 32}}
local event = {surface = surface, area = area}
Generate.schedule_chunk(event)
RocketLaunched.chunk_unlocked(event)
if current_min_pollution < global.max_pollution then
global.min_pollution = current_min_pollution + pollution_increment
end
return
else
local text = concat {format('%i', pollution), ' / ', current_min_pollution}
local complete = pollution / current_min_pollution
local color = {r = 1 - complete, g = complete, b = 0}
local id = data.id
if not id then
data.id =
rendering.draw_text {
text = text,
surface = surface,
target = {x + 16, y + 16},
color = color,
scale = 5
}
else
rendering.set_text(id, text)
rendering.set_color(id, color)
end
end
chunk_list.index = index + 1
end
Event.add(defines.events.on_chunk_generated, on_chunk)
Event.on_nth_tick(1, on_tick)
return map
return require 'map_gen.maps.danger_ores.presets.danger_bobs_ores'

View File

@ -1,84 +0,0 @@
-- This module prevents all but the allowed items from being built on top of resources
local RestrictEntities = require 'map_gen.shared.entity_placement_restriction'
local Event = require 'utils.event'
--- Items explicitly allowed on ores
RestrictEntities.add_allowed(
{
'basic-transport-belt',
'transport-belt',
'fast-transport-belt',
'express-transport-belt',
'turbo-transport-belt',
'ultimate-transport-belt',
'basic-underground-belt',
'underground-belt',
'fast-underground-belt',
'express-underground-belt',
'turbo-underground-belt',
'ultimate-underground-belt',
'small-electric-pole',
'medium-electric-pole',
'medium-electric-pole-2',
'medium-electric-pole-3',
'medium-electric-pole-4',
'big-electric-pole',
'big-electric-pole-2',
'big-electric-pole-3',
'big-electric-pole-4',
'substation',
'substation-2',
'substation-3',
'substation-4',
'electric-mining-drill',
'bob-mining-drill-1',
'bob-mining-drill-2',
'bob-mining-drill-3',
'bob-mining-drill-4',
'bob-area-mining-drill-1',
'bob-area-mining-drill-2',
'bob-area-mining-drill-3',
'bob-area-mining-drill-4',
'burner-mining-drill',
'pumpjack',
'bob-pumpjack-1',
'bob-pumpjack-2',
'bob-pumpjack-3',
'bob-pumpjack-4',
'water-miner-1',
'water-miner-2',
'water-miner-3',
'water-miner-4',
'water-miner-5',
'car',
'tank',
'bob-tank-2',
'bob-tank-3'
}
)
--- The logic for checking that there are resources under the entity's position
RestrictEntities.set_keep_alive_callback(
function(entity)
-- Some entities have a bounding_box area of zero, eg robots.
local area = entity.bounding_box
local left_top, right_bottom = area.left_top, area.right_bottom
if left_top.x == right_bottom.x and left_top.y == right_bottom.y then
return true
end
local count = entity.surface.count_entities_filtered {area = area, type = 'resource', limit = 1}
if count == 0 then
return true
end
end
)
--- Warning for players when their entities are destroyed
local function on_destroy(event)
local p = event.player
if p and p.valid then
p.print('You cannot build that on top of ores, only belts, mining drills, and power poles are allowed.')
end
end
Event.add(RestrictEntities.events.on_restricted_entity_destroyed, on_destroy)

View File

@ -1,219 +0,0 @@
local Event = require 'utils.event'
local Global = require 'utils.global'
local Queue = require 'utils.queue'
local AlienEvolutionProgress = require 'utils.alien_evolution_progress'
local RS = require 'map_gen.shared.redmew_surface'
local Task = require 'utils.task'
local Token = require 'utils.token'
local recent_chunks = Queue.new() -- Keeps track of recently revealed chunks
local recent_chunks_max = 5 -- Maximum number of chunks to track
local ticks_between_waves = 60 * 30 - recent_chunks_max
local enemy_factor = 5
local max_enemies_per_wave_per_chunk = 60
local Public = {}
global.win_condition_evolution_rocket_maxed = -1
global.win_condition_biters_disabled = false
Global.register(
recent_chunks,
function(tbl)
recent_chunks = tbl
end
)
local function give_command(group, data)
local target = data.target
if target and target.valid then
local command = {
type = defines.command.attack,
target = target,
distraction = defines.distraction.by_damage
}
group.set_command(command)
group.start_moving()
else
local command = {
type = defines.command.attack_area,
destination = data.position,
radius = 32,
distraction = defines.distraction.by_damage
}
local members = group.members
for i = 1, #members do
local entitiy = members[i]
entitiy.set_command(command)
end
end
end
local do_waves
local do_wave
do_waves =
Token.register(
function(data)
Task.queue_task(do_wave, data, 10)
end
)
do_wave =
Token.register(
function(data)
local wave = data.wave
local last_wave = data.last_wave
--game.print('wave: ' .. wave .. '/' .. last_wave)
local chunk_index = data.chunk_index
local chunk = data.chunks[chunk_index]
if not chunk then
data.wave = wave + 1
data.chunk_index = 1
Task.set_timeout_in_ticks(ticks_between_waves, do_waves, data)
return false
end
local spawner = data.spawner
local aliens = AlienEvolutionProgress.get_aliens(spawner, game.forces.enemy.evolution_factor)
local left_top = chunk.area.left_top
local center = {left_top.x + 16, left_top.y + 16}
local surface = chunk.surface
local find_non_colliding_position = surface.find_non_colliding_position
local create_entity = surface.create_entity
local group = surface.create_unit_group {position = center}
local add_member = group.add_member
for name, count in pairs(aliens) do
for i = 1, count do
local pos = find_non_colliding_position(name, center, 32, 1)
if pos then
local e = {name = name, position = pos, force = 'enemy', center = center, radius = 16, 1}
local ent = create_entity(e)
add_member(ent)
end
end
end
give_command(group, data)
if chunk_index < recent_chunks_max then
data.chunk_index = chunk_index + 1
return true
end
if wave < last_wave then
data.wave = wave + 1
data.chunk_index = 1
Task.set_timeout_in_ticks(ticks_between_waves, do_waves, data)
end
return false
end
)
local function start_waves(event)
local num_enemies = enemy_factor * game.forces.player.get_item_launched('satellite')
local number_of_waves = math.ceil(num_enemies / max_enemies_per_wave_per_chunk)
local num_enemies_per_wave_per_chunk = math.ceil(num_enemies / number_of_waves)
local target = event.rocket_silo
local position
if target and target.valid then
position = target.position
else
position = {0, 0}
end
local data = {
spawner = AlienEvolutionProgress.create_spawner_request(num_enemies_per_wave_per_chunk),
wave = 1,
last_wave = number_of_waves,
chunk_index = 1,
chunks = Queue.to_array(recent_chunks),
target = target,
position = position
}
Task.set_timeout_in_ticks(1, do_waves, data)
game.print('Warning incomming biter attack! Number of waves: ' .. number_of_waves)
end
local function rocket_launched(event)
local entity = event.rocket
if not entity or not entity.valid or not entity.force == 'player' then
return
end
local inventory = entity.get_inventory(defines.inventory.rocket)
if not inventory or not inventory.valid then
return
end
local satellite_count = game.forces.player.get_item_launched('satellite')
if satellite_count == 0 then
return
end
-- Increase enemy_evolution
local current_evolution = game.forces.enemy.evolution_factor
local message
if global.win_condition_biters_disabled == false then
if (satellite_count % 5) == 0 and global.win_condition_evolution_rocket_maxed == -1 then
message =
'Continued launching of satellites has angered the local biter population, evolution increasing...'
game.print(message)
current_evolution = current_evolution + 0.05
end
if current_evolution >= 1 and global.win_condition_evolution_rocket_maxed == -1 then
current_evolution = 1
global.win_condition_evolution_rocket_maxed = satellite_count
message =
'Biters at maximum evolution! Protect the base for an additional 100 rockets to wipe them out forever.'
game.print(message)
end
game.forces.enemy.evolution_factor = current_evolution
if
global.win_condition_evolution_rocket_maxed > 0 and
satellite_count >= (global.win_condition_evolution_rocket_maxed + 100)
then
message = 'Congratulations! Biters have been wiped from the map!'
game.print(message)
global.win_condition_biters_disabled = true
for key, enemy_entity in pairs(RS.get_surface().find_entities_filtered({force = 'enemy'})) do
enemy_entity.destroy()
end
else
start_waves(event)
end
end
end
function Public.chunk_unlocked(chunk)
Queue.push(recent_chunks, chunk)
while Queue.size(recent_chunks) > 10 do
Queue.pop(recent_chunks)
end
end
Event.add(defines.events.on_rocket_launched, rocket_launched)
return Public

View File

@ -1,194 +1 @@
local b = require 'map_gen.shared.builders'
local Perlin = require 'map_gen.shared.perlin_noise'
local Global = require 'utils.global'
local math = require 'utils.math'
local table = require 'utils.table'
local RS = require 'map_gen.shared.redmew_surface'
local MGSP = require 'resources.map_gen_settings'
require 'map_gen.shared.danger_ore_banned_entities'
local ScenarioInfo = require 'features.gui.info'
--setting map info
ScenarioInfo.set_map_name('Danger Ores')
ScenarioInfo.set_map_description(
[[
Clear the ore to expand the base:
build extensive mining efforts, create large smelting arrays,
use proper material ratios, and defend from enemies!
]]
)
ScenarioInfo.add_map_extra_info(
[[You may not build the factory on ore patches. Exceptions:
[item=burner-mining-drill] [item=electric-mining-drill] [item=pumpjack] [item=small-electric-pole] [item=medium-electric-pole] [item=big-electric-pole] [item=substation] [item=car] [item=tank]
[item=transport-belt] [item=fast-transport-belt] [item=express-transport-belt] [item=underground-belt] [item=fast-underground-belt] [item=express-underground-belt] ]]
)
local oil_seed
local uranium_seed
local density_seed
local oil_scale = 1 / 64
local oil_threshold = 0.6
local uranium_scale = 1 / 128
local uranium_threshold = 0.65
local density_scale = 1 / 48
local density_threshold = 0.5
local density_multiplier = 50
RS.set_first_player_position_check_override(true)
RS.set_spawn_island_tile('grass-1')
RS.set_map_gen_settings(
{
MGSP.ore_oil_none,
MGSP.cliff_none
}
)
Global.register_init(
{},
function(tbl)
tbl.seed = RS.get_surface().map_gen_settings.seed
end,
function(tbl)
local seed = tbl.seed
oil_seed = seed
uranium_seed = seed * 2
density_seed = seed * 3
game.map_settings.enemy_evolution.time_factor = 0.000002
game.map_settings.enemy_evolution.destroy_factor = 0.0009
game.map_settings.enemy_evolution.pollution_factor = 0.0000015
end
)
local value = b.euclidean_value
local oil_shape = b.throttle_world_xy(b.full_shape, 1, 8, 1, 8)
local oil_resource = b.resource(oil_shape, 'crude-oil', value(150000, 100))
local uranium_resource = b.resource(b.full_shape, 'uranium-ore', value(200, 1))
local ores = {
{resource = b.resource(b.full_shape, 'iron-ore', value(25, 0.5)), weight = 6},
{resource = b.resource(b.full_shape, 'copper-ore', value(25, 0.5)), weight = 4},
{resource = b.resource(b.full_shape, 'stone', value(25, 0.5)), weight = 1},
{resource = b.resource(b.full_shape, 'coal', value(25, 0.5)), weight = 2}
}
local weighted_ores = b.prepare_weighted_array(ores)
local total_ores = weighted_ores.total
local spawn_zone = b.circle(64)
local ore_circle = b.circle(68)
local start_ores = {
b.resource(ore_circle, 'iron-ore', value(500, 0)),
b.resource(ore_circle, 'copper-ore', value(250, 0)),
b.resource(ore_circle, 'coal', value(500, 0)),
b.resource(ore_circle, 'stone', value(250, 0))
}
local start_segment = b.segment_pattern(start_ores)
local function ore(x, y, world)
if spawn_zone(x, y) then
return
end
local start_ore = start_segment(x, y, world)
if start_ore then
return start_ore
end
local oil_x, oil_y = x * oil_scale, y * oil_scale
local oil_noise = Perlin.noise(oil_x, oil_y, oil_seed)
if oil_noise > oil_threshold then
return oil_resource(x, y, world)
end
local uranium_x, uranium_y = x * uranium_scale, y * uranium_scale
local uranium_noise = Perlin.noise(uranium_x, uranium_y, uranium_seed)
if uranium_noise > uranium_threshold then
return uranium_resource(x, y, world)
end
local i = math.random() * total_ores
local index = table.binary_search(weighted_ores, i)
if (index < 0) then
index = bit32.bnot(index)
end
local resource = ores[index].resource
local entity = resource(x, y, world)
local density_x, density_y = x * density_scale, y * density_scale
local density_noise = Perlin.noise(density_x, density_y, density_seed)
if density_noise > density_threshold then
entity.amount = entity.amount * density_multiplier
end
entity.enable_tree_removal = false
return entity
end
local worms = {
'small-worm-turret',
'medium-worm-turret',
'big-worm-turret',
'behemoth-worm-turret'
}
local max_worm_chance = 1 / 384
local worm_chance_factor = 1 / (192 * 512)
local function enemy(_, _, world)
local wx, wy = world.x, world.y
local d = math.sqrt(wx * wx + wy * wy)
local worm_chance = d - 128
if worm_chance > 0 then
worm_chance = worm_chance * worm_chance_factor
worm_chance = math.min(worm_chance, max_worm_chance)
if math.random() < worm_chance then
if d < 384 then
return {name = 'small-worm-turret'}
else
local max_lvl
local min_lvl
if d < 768 then
max_lvl = 2
min_lvl = 1
elseif d < 960 then
max_lvl = 3
min_lvl = 2
else
max_lvl = 4
min_lvl = 3
end
local lvl = math.random() ^ (768 / d) * max_lvl
lvl = math.ceil(lvl)
lvl = math.clamp(lvl, min_lvl, 4)
return {name = worms[lvl]}
end
end
end
end
local water = b.circle(8)
water = b.change_tile(water, true, 'water')
water = b.any {b.rectangle(16, 4), b.rectangle(4, 16), water}
local start = b.if_else(water, b.full_shape)
start = b.change_map_gen_collision_tile(start, 'water-tile', 'grass-1')
local map = b.choose(ore_circle, start, b.full_shape)
map = b.apply_entity(map, ore)
map = b.apply_entity(map, enemy)
return map
return require 'map_gen.maps.danger_ores.presets.danger_ores'

View File

@ -0,0 +1,52 @@
return {
'basic-transport-belt',
'transport-belt',
'fast-transport-belt',
'express-transport-belt',
'turbo-transport-belt',
'ultimate-transport-belt',
'basic-underground-belt',
'underground-belt',
'fast-underground-belt',
'express-underground-belt',
'turbo-underground-belt',
'ultimate-underground-belt',
'small-electric-pole',
'medium-electric-pole',
'medium-electric-pole-2',
'medium-electric-pole-3',
'medium-electric-pole-4',
'big-electric-pole',
'big-electric-pole-2',
'big-electric-pole-3',
'big-electric-pole-4',
'substation',
'substation-2',
'substation-3',
'substation-4',
'electric-mining-drill',
'bob-mining-drill-1',
'bob-mining-drill-2',
'bob-mining-drill-3',
'bob-mining-drill-4',
'bob-area-mining-drill-1',
'bob-area-mining-drill-2',
'bob-area-mining-drill-3',
'bob-area-mining-drill-4',
'burner-mining-drill',
'pumpjack',
'bob-pumpjack-1',
'bob-pumpjack-2',
'bob-pumpjack-3',
'bob-pumpjack-4',
'water-miner-1',
'water-miner-2',
'water-miner-3',
'water-miner-4',
'water-miner-5',
'car',
'tank',
'bob-tank-2',
'bob-tank-3',
'spidertron'
}

View File

@ -1,33 +1,7 @@
local b = require 'map_gen.shared.builders'
local Perlin = require 'map_gen.shared.perlin_noise'
local table = require 'utils.table'
local random = math.random
local floor = math.floor
local value = b.euclidean_value
local binary_search = table.binary_search
local bnot = bit32.bnot
local perlin_noise = Perlin.noise
local mixed_ores = true
local tile_scale = 1 / 64
local spawn_zone = b.circle(85)
local oil_scale = 1 / 64
local oil_threshold = 0.6
local uranium_scale = 1 / 72
local uranium_threshold = 0.63
local thorium_scale = 1 / 72
local thorium_threshold = 0.63
local density_scale = 1 / 48
local density_threshold = 0.5
local density_multiplier = 50
local ores = {
return {
['iron-ore'] = {
['tiles'] = {
[1] = 'grass-1',
@ -36,7 +10,6 @@ local ores = {
[4] = 'grass-4'
},
['start'] = value(125, 0),
['non_mixed_value'] = value(0, 0.5),
['weight'] = 15,
['ratios'] = {
{resource = b.resource(b.full_shape, 'iron-ore', value(0, 0.5)), weight = 120},
@ -66,7 +39,6 @@ local ores = {
[4] = 'red-desert-3'
},
['start'] = value(125, 0),
['non_mixed_value'] = value(0, 0.5),
['weight'] = 10,
['ratios'] = {
{resource = b.resource(b.full_shape, 'iron-ore', value(0, 0.5)), weight = 20},
@ -99,7 +71,6 @@ local ores = {
[7] = 'dirt-7'
},
['start'] = value(125, 0),
['non_mixed_value'] = value(0, 0.5),
['weight'] = 10,
['ratios'] = {
{resource = b.resource(b.full_shape, 'iron-ore', value(0, 0.5)), weight = 20},
@ -128,7 +99,6 @@ local ores = {
[3] = 'sand-3'
},
['start'] = value(125, 0),
['non_mixed_value'] = value(0, 0.5),
['weight'] = 10,
['ratios'] = {
{resource = b.resource(b.full_shape, 'iron-ore', value(0, 0.5)), weight = 20},
@ -158,7 +128,6 @@ local ores = {
[4] = 'grass-4'
},
['start'] = value(125, 0),
['non_mixed_value'] = value(0, 0.5),
['weight'] = 2,
['ratios'] = {
{resource = b.resource(b.full_shape, 'iron-ore', value(0, 0.5)), weight = 20},
@ -188,7 +157,6 @@ local ores = {
[4] = 'red-desert-3'
},
['start'] = value(125, 0),
['non_mixed_value'] = value(0, 0.5),
['weight'] = 0.05,
['ratios'] = {
{resource = b.resource(b.full_shape, 'iron-ore', value(0, 0.5)), weight = 20},
@ -221,7 +189,6 @@ local ores = {
[7] = 'dirt-7'
},
['start'] = value(125, 0),
['non_mixed_value'] = value(0, 0.5),
['weight'] = 0.05,
['ratios'] = {
{resource = b.resource(b.full_shape, 'iron-ore', value(0, 0.5)), weight = 20},
@ -250,7 +217,6 @@ local ores = {
[3] = 'sand-3'
},
['start'] = value(125, 0),
['non_mixed_value'] = value(0, 0.5),
['weight'] = 1,
['ratios'] = {
{resource = b.resource(b.full_shape, 'iron-ore', value(0, 0.5)), weight = 20},
@ -280,7 +246,6 @@ local ores = {
[4] = 'grass-4'
},
['start'] = value(125, 0),
['non_mixed_value'] = value(0, 0.5),
['weight'] = 2,
['ratios'] = {
{resource = b.resource(b.full_shape, 'iron-ore', value(0, 0.5)), weight = 20},
@ -310,7 +275,6 @@ local ores = {
[4] = 'red-desert-3'
},
['start'] = value(125, 0),
['non_mixed_value'] = value(0, 0.5),
['weight'] = 2,
['ratios'] = {
{resource = b.resource(b.full_shape, 'iron-ore', value(0, 0.5)), weight = 20},
@ -343,7 +307,6 @@ local ores = {
[7] = 'dirt-7'
},
['start'] = value(125, 0),
['non_mixed_value'] = value(0, 0.5),
['weight'] = 2,
['ratios'] = {
{resource = b.resource(b.full_shape, 'iron-ore', value(0, 0.5)), weight = 20},
@ -372,7 +335,6 @@ local ores = {
[3] = 'sand-3'
},
['start'] = value(125, 0),
['non_mixed_value'] = value(0, 0.5),
['weight'] = 1,
['ratios'] = {
{resource = b.resource(b.full_shape, 'iron-ore', value(0, 0.5)), weight = 20},
@ -402,7 +364,6 @@ local ores = {
[4] = 'grass-4'
},
['start'] = value(125, 0),
['non_mixed_value'] = value(0, 0.5),
['weight'] = 1,
['ratios'] = {
{resource = b.resource(b.full_shape, 'iron-ore', value(0, 0.5)), weight = 20},
@ -432,7 +393,6 @@ local ores = {
[4] = 'red-desert-3'
},
['start'] = value(125, 0),
['non_mixed_value'] = value(0, 0.5),
['weight'] = 1,
['ratios'] = {
{resource = b.resource(b.full_shape, 'iron-ore', value(0, 0.5)), weight = 20},
@ -465,7 +425,6 @@ local ores = {
[7] = 'dirt-7'
},
['start'] = value(125, 0),
['non_mixed_value'] = value(0, 0.5),
['weight'] = 2,
['ratios'] = {
{resource = b.resource(b.full_shape, 'iron-ore', value(0, 0.5)), weight = 20},
@ -494,7 +453,6 @@ local ores = {
[3] = 'sand-3'
},
['start'] = value(125, 0),
['non_mixed_value'] = value(0, 0.5),
['weight'] = 1,
['ratios'] = {
{resource = b.resource(b.full_shape, 'iron-ore', value(0, 0.5)), weight = 20},
@ -524,7 +482,6 @@ local ores = {
[4] = 'grass-4'
},
['start'] = value(125, 0),
['non_mixed_value'] = value(0, 0.5),
['weight'] = 2,
['ratios'] = {
{resource = b.resource(b.full_shape, 'iron-ore', value(0, 0.5)), weight = 20},
@ -547,141 +504,3 @@ local ores = {
}
}
}
local oil_shape = b.throttle_world_xy(b.full_shape, 1, 7, 1, 7)
local oil_resource = b.resource(oil_shape, 'crude-oil', value(250000, 150))
local uranium_resource = b.resource(b.full_shape, 'uranium-ore', value(200, 1))
local thorium_resource = b.resource(b.full_shape, 'thorium-ore', value(200, 1))
local function init(seed)
local oil_seed = seed * 2
local uranium_seed = seed * 3
local density_seed = seed * 4
local thorium_seed = seed * 5
local function tile_builder(tiles)
local count = #tiles / 2
return function(x, y)
x, y = x * tile_scale, y * tile_scale
local v = perlin_noise(x, y, seed)
v = ((v + 1) * count) + 1
v = floor(v)
return tiles[v]
end
end
local function ore_builder(ore_name, amount, ratios, weighted)
local start_ore = b.resource(b.full_shape, ore_name, amount)
local total = weighted.total
return function(x, y, world)
if spawn_zone(x, y) then
return start_ore(x, y, world)
end
local oil_x, oil_y = x * oil_scale, y * oil_scale
local oil_noise = perlin_noise(oil_x, oil_y, oil_seed)
if oil_noise > oil_threshold then
return oil_resource(x, y, world)
end
local uranium_x, uranium_y = x * uranium_scale, y * uranium_scale
local uranium_noise = perlin_noise(uranium_x, uranium_y, uranium_seed)
if uranium_noise > uranium_threshold then
return uranium_resource(x, y, world)
end
local thorium_x, thorium_y = x * thorium_scale, y * thorium_scale
local thorium_noise = perlin_noise(thorium_x, thorium_y, thorium_seed)
if thorium_noise > thorium_threshold then
return thorium_resource(x, y, world)
end
local i = random() * total
local index = binary_search(weighted, i)
if index < 0 then
index = bnot(index)
end
local resource = ratios[index].resource
local entity = resource(x, y, world)
local density_x, density_y = x * density_scale, y * density_scale
local density_noise = perlin_noise(density_x, density_y, density_seed)
if density_noise > density_threshold then
entity.amount = entity.amount * density_multiplier
end
entity.enable_tree_removal = false
return entity
end
end
local function non_mixed_ore_builder(ore_name, amount)
local resource = b.resource(b.full_shape, ore_name, amount)
return function(x, y, world)
if spawn_zone(x, y) then
return resource(x, y, world)
end
local oil_x, oil_y = x * oil_scale, y * oil_scale
local oil_noise = perlin_noise(oil_x, oil_y, oil_seed)
if oil_noise > oil_threshold then
return oil_resource(x, y, world)
end
local uranium_x, uranium_y = x * uranium_scale, y * uranium_scale
local uranium_noise = perlin_noise(uranium_x, uranium_y, uranium_seed)
if uranium_noise > uranium_threshold then
return uranium_resource(x, y, world)
end
local thorium_x, thorium_y = x * thorium_scale, y * thorium_scale
local thorium_noise = perlin_noise(thorium_x, thorium_y, thorium_seed)
if thorium_noise > thorium_threshold then
return thorium_resource(x, y, world)
end
local entity = resource(x, y, world)
local density_x, density_y = x * density_scale, y * density_scale
local density_noise = perlin_noise(density_x, density_y, density_seed)
if density_noise > density_threshold then
entity.amount = entity.amount * density_multiplier
end
entity.enable_tree_removal = false
return entity
end
end
local shapes = {}
for ore_name, v in pairs(ores) do
local tiles = v.tiles
local land = tile_builder(tiles)
local ore
if mixed_ores then
local ratios = v.ratios
local weighted = b.prepare_weighted_array(ratios)
local amount = v.start
ore = ore_builder(ore_name, amount, ratios, weighted)
else
local amount = v.non_mixed_value
ore = non_mixed_ore_builder(ore_name, amount)
end
local shape = b.apply_entity(land, ore)
shapes[#shapes + 1] = {shape = shape, weight = v.weight}
end
return shapes
end
return init

View File

@ -0,0 +1,234 @@
local b = require 'map_gen.shared.builders'
local value = b.euclidean_value
return {
['iron-ore'] = {
['tiles'] = {
[1] = 'grass-1',
[2] = 'grass-2',
[3] = 'grass-3',
[4] = 'grass-4'
},
['start'] = value(125, 0),
['weight'] = 15,
['ratios'] = {
{resource = b.resource(b.full_shape, 'iron-ore', value(0, 0.5)), weight = 120}
}
},
['copper-ore'] = {
['tiles'] = {
[1] = 'red-desert-0',
[2] = 'red-desert-1',
[3] = 'red-desert-2',
[4] = 'red-desert-3'
},
['start'] = value(125, 0),
['weight'] = 10,
['ratios'] = {
{resource = b.resource(b.full_shape, 'copper-ore', value(0, 0.5)), weight = 120}
}
},
['coal'] = {
['tiles'] = {
[1] = 'dirt-1',
[2] = 'dirt-2',
[3] = 'dirt-3',
[4] = 'dirt-4',
[5] = 'dirt-5',
[6] = 'dirt-6',
[7] = 'dirt-7'
},
['start'] = value(125, 0),
['weight'] = 10,
['ratios'] = {
{resource = b.resource(b.full_shape, 'coal', value(0, 0.5)), weight = 120}
}
},
['stone'] = {
['tiles'] = {
[1] = 'sand-1',
[2] = 'sand-2',
[3] = 'sand-3'
},
['start'] = value(125, 0),
['weight'] = 10,
['ratios'] = {
{resource = b.resource(b.full_shape, 'stone', value(0, 0.5)), weight = 120}
}
},
['bauxite-ore'] = {
['tiles'] = {
[1] = 'grass-1',
[2] = 'grass-2',
[3] = 'grass-3',
[4] = 'grass-4'
},
['start'] = value(125, 0),
['weight'] = 2,
['ratios'] = {
{resource = b.resource(b.full_shape, 'bauxite-ore', value(0, 0.5)), weight = 120}
}
},
['cobalt-ore'] = {
['tiles'] = {
[1] = 'red-desert-0',
[2] = 'red-desert-1',
[3] = 'red-desert-2',
[4] = 'red-desert-3'
},
['start'] = value(125, 0),
['weight'] = 0.05,
['ratios'] = {
{resource = b.resource(b.full_shape, 'cobalt-ore', value(0, 0.5)), weight = 120}
}
},
['gem-ore'] = {
['tiles'] = {
[1] = 'dirt-1',
[2] = 'dirt-2',
[3] = 'dirt-3',
[4] = 'dirt-4',
[5] = 'dirt-5',
[6] = 'dirt-6',
[7] = 'dirt-7'
},
['start'] = value(125, 0),
['weight'] = 0.05,
['ratios'] = {
{resource = b.resource(b.full_shape, 'gem-ore', value(0, 0.5)), weight = 120}
}
},
['gold-ore'] = {
['tiles'] = {
[1] = 'sand-1',
[2] = 'sand-2',
[3] = 'sand-3'
},
['start'] = value(125, 0),
['weight'] = 1,
['ratios'] = {
{resource = b.resource(b.full_shape, 'gold-ore', value(0, 0.5)), weight = 120}
}
},
['lead-ore'] = {
['tiles'] = {
[1] = 'grass-1',
[2] = 'grass-2',
[3] = 'grass-3',
[4] = 'grass-4'
},
['start'] = value(125, 0),
['weight'] = 2,
['ratios'] = {
{resource = b.resource(b.full_shape, 'lead-ore', value(0, 0.5)), weight = 120}
}
},
['nickel-ore'] = {
['tiles'] = {
[1] = 'red-desert-0',
[2] = 'red-desert-1',
[3] = 'red-desert-2',
[4] = 'red-desert-3'
},
['start'] = value(125, 0),
['weight'] = 2,
['ratios'] = {
{resource = b.resource(b.full_shape, 'nickel-ore', value(0, 0.5)), weight = 120}
}
},
['quartz'] = {
['tiles'] = {
[1] = 'dirt-1',
[2] = 'dirt-2',
[3] = 'dirt-3',
[4] = 'dirt-4',
[5] = 'dirt-5',
[6] = 'dirt-6',
[7] = 'dirt-7'
},
['start'] = value(125, 0),
['weight'] = 2,
['ratios'] = {
{resource = b.resource(b.full_shape, 'quartz', value(0, 0.5)), weight = 120}
}
},
['rutile-ore'] = {
['tiles'] = {
[1] = 'sand-1',
[2] = 'sand-2',
[3] = 'sand-3'
},
['start'] = value(125, 0),
['weight'] = 1,
['ratios'] = {
{resource = b.resource(b.full_shape, 'rutile-ore', value(0, 0.5)), weight = 120}
}
},
['silver-ore'] = {
['tiles'] = {
[1] = 'grass-1',
[2] = 'grass-2',
[3] = 'grass-3',
[4] = 'grass-4'
},
['start'] = value(125, 0),
['weight'] = 1,
['ratios'] = {
{resource = b.resource(b.full_shape, 'silver-ore', value(0, 0.5)), weight = 120}
}
},
['sulfur'] = {
['tiles'] = {
[1] = 'red-desert-0',
[2] = 'red-desert-1',
[3] = 'red-desert-2',
[4] = 'red-desert-3'
},
['start'] = value(125, 0),
['weight'] = 1,
['ratios'] = {
{resource = b.resource(b.full_shape, 'sulfur', value(0, 0.5)), weight = 120}
}
},
['tin-ore'] = {
['tiles'] = {
[1] = 'dirt-1',
[2] = 'dirt-2',
[3] = 'dirt-3',
[4] = 'dirt-4',
[5] = 'dirt-5',
[6] = 'dirt-6',
[7] = 'dirt-7'
},
['start'] = value(125, 0),
['weight'] = 2,
['ratios'] = {
{resource = b.resource(b.full_shape, 'tin-ore', value(0, 0.5)), weight = 120}
}
},
['tungsten-ore'] = {
['tiles'] = {
[1] = 'sand-1',
[2] = 'sand-2',
[3] = 'sand-3'
},
['start'] = value(125, 0),
['weight'] = 1,
['ratios'] = {
{resource = b.resource(b.full_shape, 'tungsten-ore', value(0, 0.5)), weight = 120}
}
},
['zinc-ore'] = {
['tiles'] = {
[1] = 'grass-1',
[2] = 'grass-2',
[3] = 'grass-3',
[4] = 'grass-4'
},
['start'] = value(125, 0),
['weight'] = 2,
['ratios'] = {
{resource = b.resource(b.full_shape, 'zinc-ore', value(0, 0.5)), weight = 120}
}
}
}

View File

@ -0,0 +1,22 @@
local b = require 'map_gen.shared.builders'
local value = b.euclidean_value
local oil_shape = b.throttle_world_xy(b.full_shape, 1, 7, 1, 7)
return {
{
scale = 1 / 64,
threshold = 0.6,
resource = b.resource(oil_shape, 'crude-oil', value(250000, 150))
},
{
scale = 1 / 72,
threshold = 0.63,
resource = b.resource(b.full_shape, 'uranium-ore', value(200, 1))
},
{
scale = 1 / 72,
threshold = 0.63,
resource = b.resource(b.full_shape, 'thorium-ore', value(200, 1))
}
}

View File

@ -0,0 +1,53 @@
return {
'basic-transport-belt',
'transport-belt',
'fast-transport-belt',
'express-transport-belt',
'turbo-transport-belt',
'ultimate-transport-belt',
'basic-underground-belt',
'underground-belt',
'fast-underground-belt',
'express-underground-belt',
'turbo-underground-belt',
'ultimate-underground-belt',
'small-electric-pole',
'medium-electric-pole',
'medium-electric-pole-2',
'medium-electric-pole-3',
'medium-electric-pole-4',
'big-electric-pole',
'big-electric-pole-2',
'big-electric-pole-3',
'big-electric-pole-4',
'substation',
'substation-2',
'substation-3',
'substation-4',
'electric-mining-drill',
'bob-mining-drill-1',
'bob-mining-drill-2',
'bob-mining-drill-3',
'bob-mining-drill-4',
'bob-area-mining-drill-1',
'bob-area-mining-drill-2',
'bob-area-mining-drill-3',
'bob-area-mining-drill-4',
'burner-mining-drill',
'pumpjack',
'bob-pumpjack-1',
'bob-pumpjack-2',
'bob-pumpjack-3',
'bob-pumpjack-4',
'water-miner-1',
'water-miner-2',
'water-miner-3',
'water-miner-4',
'water-miner-5',
'car',
'tank',
'bob-tank-2',
'bob-tank-3',
'spidertron',
'thermal-water-extractor'
}

View File

@ -0,0 +1,107 @@
local b = require 'map_gen.shared.builders'
local value = b.euclidean_value
local ratio_mixed = 80 -- % purity in the ore
local main_value = value(0, 0.5)
local ores = {
['angels-ore1'] = {
-- Saphirite
['tiles'] = {
[1] = 'grass-1',
[2] = 'grass-2',
[3] = 'grass-3',
[4] = 'grass-4'
},
['start'] = value(125, 0),
['weight'] = 15,
['ratios'] = {}
},
['angels-ore2'] = {
-- Jivolite
['tiles'] = {
[1] = 'dirt-1',
[2] = 'dirt-2',
[3] = 'dirt-3'
},
['start'] = value(125, 0),
['weight'] = 10,
['ratios'] = {}
},
['angels-ore3'] = {
-- Stiratite
['tiles'] = {
[1] = 'red-desert-0',
[2] = 'red-desert-1',
[3] = 'red-desert-2',
[4] = 'red-desert-3'
},
['start'] = value(125, 0),
['weight'] = 10,
['ratios'] = {}
},
['angels-ore4'] = {
-- crotinnium
['tiles'] = {
[1] = 'grass-3',
[2] = 'grass-4'
},
['start'] = value(125, 0),
['weight'] = 10,
['ratios'] = {}
},
['angels-ore5'] = {
-- rubyte
['tiles'] = {
[1] = 'grass-1',
[2] = 'grass-2'
},
['start'] = value(125, 0),
['weight'] = 10,
['ratios'] = {}
},
['angels-ore6'] = {
-- bobmonium-ore
['tiles'] = {
[1] = 'sand-1',
[2] = 'sand-2',
[3] = 'sand-3'
},
['start'] = value(125, 0),
['weight'] = 10,
['ratios'] = {}
},
['coal'] = {
['tiles'] = {
[1] = 'dirt-5',
[2] = 'dirt-6',
[3] = 'dirt-7'
},
['start'] = value(125, 0),
['weight'] = 10,
['ratios'] = {}
}
}
for ore_name, ore_data in pairs(ores) do
local ratios = {
{resource = b.resource(b.full_shape, ore_name, main_value), weight = ratio_mixed}
}
local sum_other_weights = 0
for name, data in pairs(ores) do
if name ~= ore_name then
sum_other_weights = sum_other_weights + data.weight
end
end
for name, data in pairs(ores) do
if name ~= ore_name then
local weight = (100 - ratio_mixed) * (data.weight / sum_other_weights)
ratios[#ratios + 1] = {resource = b.resource(b.full_shape, name, value(0, 0.5)), weight = weight}
end
end
ore_data.ratios = ratios
end
return ores

View File

@ -0,0 +1,95 @@
local b = require 'map_gen.shared.builders'
local value = b.euclidean_value
return {
['angels-ore1'] = {
-- Saphirite
['tiles'] = {
[1] = 'grass-1',
[2] = 'grass-2',
[3] = 'grass-3',
[4] = 'grass-4'
},
['start'] = value(125, 0),
['weight'] = 15,
['ratios'] = {
{resource = b.resource(b.full_shape, 'angels-ore1', value(0, 0.5)), weight = 1}
}
},
['angels-ore2'] = {
-- Jivolite
['tiles'] = {
[1] = 'dirt-1',
[2] = 'dirt-2',
[3] = 'dirt-3'
},
['start'] = value(125, 0),
['weight'] = 10,
['ratios'] = {
{resource = b.resource(b.full_shape, 'angels-ore2', value(0, 0.5)), weight = 1}
}
},
['angels-ore3'] = {
-- Stiratite
['tiles'] = {
[1] = 'red-desert-0',
[2] = 'red-desert-1',
[3] = 'red-desert-2',
[4] = 'red-desert-3'
},
['start'] = value(125, 0),
['weight'] = 10,
['ratios'] = {
{resource = b.resource(b.full_shape, 'angels-ore3', value(0, 0.5)), weight = 1}
}
},
['angels-ore4'] = {
-- crotinnium
['tiles'] = {
[1] = 'grass-3',
[2] = 'grass-4'
},
['start'] = value(125, 0),
['weight'] = 10,
['ratios'] = {
{resource = b.resource(b.full_shape, 'angels-ore4', value(0, 0.5)), weight = 1}
}
},
['angels-ore5'] = {
-- rubyte
['tiles'] = {
[1] = 'grass-1',
[2] = 'grass-2'
},
['start'] = value(125, 0),
['weight'] = 10,
['ratios'] = {
{resource = b.resource(b.full_shape, 'angels-ore5', value(0, 0.5)), weight = 1}
}
},
['angels-ore6'] = {
-- bobmonium-ore
['tiles'] = {
[1] = 'sand-1',
[2] = 'sand-2',
[3] = 'sand-3'
},
['start'] = value(125, 0),
['weight'] = 10,
['ratios'] = {
{resource = b.resource(b.full_shape, 'angels-ore6', value(0, 0.5)), weight = 1}
}
},
['coal'] = {
['tiles'] = {
[1] = 'dirt-5',
[2] = 'dirt-6',
[3] = 'dirt-7'
},
['start'] = value(125, 0),
['weight'] = 10,
['ratios'] = {
{resource = b.resource(b.full_shape, 'coal', value(0, 0.5)), weight = 1}
}
}
}

View File

@ -0,0 +1,22 @@
local b = require 'map_gen.shared.builders'
local value = b.euclidean_value
local oil_shape = b.throttle_world_xy(b.full_shape, 1, 7, 1, 7)
return {
{
scale = 1 / 64,
threshold = 0.6,
resource = b.resource(oil_shape, 'crude-oil', value(250000, 150))
},
{
scale = 1 / 100,
threshold = 0.6,
resource = b.resource(oil_shape, 'angels-fissure', value(1250, 1))
},
{
scale = 1 / 64,
threshold = 0.6,
resource = b.resource(oil_shape, 'angels-natural-gas', value(1250, 1))
}
}

View File

@ -0,0 +1,18 @@
return {
'transport-belt',
'fast-transport-belt',
'express-transport-belt',
'underground-belt',
'fast-underground-belt',
'express-underground-belt',
'small-electric-pole',
'medium-electric-pole',
'big-electric-pole',
'substation',
'electric-mining-drill',
'burner-mining-drill',
'pumpjack',
'car',
'tank',
'spidertron'
}

View File

@ -0,0 +1,71 @@
local b = require 'map_gen.shared.builders'
local value = b.euclidean_value
return {
['copper-ore'] = {
['tiles'] = {
[1] = 'red-desert-0',
[2] = 'red-desert-1',
[3] = 'red-desert-2',
[4] = 'red-desert-3'
},
['start'] = value(125, 0),
['weight'] = 1,
['ratios'] = {
{resource = b.resource(b.full_shape, 'iron-ore', value(0, 0.5)), weight = 20},
{resource = b.resource(b.full_shape, 'copper-ore', value(0, 0.5)), weight = 60},
{resource = b.resource(b.full_shape, 'stone', value(0, 0.5)), weight = 2},
{resource = b.resource(b.full_shape, 'coal', value(0, 0.5)), weight = 20}
}
},
['coal'] = {
['tiles'] = {
[1] = 'dirt-1',
[2] = 'dirt-2',
[3] = 'dirt-3',
[4] = 'dirt-4',
[5] = 'dirt-5',
[6] = 'dirt-6',
[7] = 'dirt-7'
},
['start'] = value(125, 0),
['weight'] = 1,
['ratios'] = {
{resource = b.resource(b.full_shape, 'iron-ore', value(0, 0.5)), weight = 20},
{resource = b.resource(b.full_shape, 'copper-ore', value(0, 0.5)), weight = 20},
{resource = b.resource(b.full_shape, 'stone', value(0, 0.5)), weight = 2},
{resource = b.resource(b.full_shape, 'coal', value(0, 0.5)), weight = 40}
}
},
['iron-ore'] = {
['tiles'] = {
[1] = 'grass-1',
[2] = 'grass-2',
[3] = 'grass-3',
[4] = 'grass-4'
},
['start'] = value(125, 0),
['weight'] = 1,
['ratios'] = {
{resource = b.resource(b.full_shape, 'iron-ore', value(0, 0.5)), weight = 60},
{resource = b.resource(b.full_shape, 'copper-ore', value(0, 0.5)), weight = 20},
{resource = b.resource(b.full_shape, 'stone', value(0, 0.5)), weight = 2},
{resource = b.resource(b.full_shape, 'coal', value(0, 0.5)), weight = 20}
}
},
['stone'] = {
['tiles'] = {
[1] = 'sand-1',
[2] = 'sand-2',
[3] = 'sand-3'
},
['start'] = value(125, 0),
['weight'] = 1,
['ratios'] = {
{resource = b.resource(b.full_shape, 'iron-ore', value(0, 0.5)), weight = 20},
{resource = b.resource(b.full_shape, 'copper-ore', value(0, 0.5)), weight = 20},
{resource = b.resource(b.full_shape, 'stone', value(0, 0.5)), weight = 30},
{resource = b.resource(b.full_shape, 'coal', value(0, 0.5)), weight = 20}
}
}
}

View File

@ -0,0 +1,59 @@
local b = require 'map_gen.shared.builders'
local value = b.euclidean_value
return {
['copper-ore'] = {
['tiles'] = {
[1] = 'red-desert-0',
[2] = 'red-desert-1',
[3] = 'red-desert-2',
[4] = 'red-desert-3'
},
['start'] = value(125, 0),
['weight'] = 1,
['ratios'] = {
{resource = b.resource(b.full_shape, 'copper-ore', value(0, 0.5)), weight = 1}
}
},
['coal'] = {
['tiles'] = {
[1] = 'dirt-1',
[2] = 'dirt-2',
[3] = 'dirt-3',
[4] = 'dirt-4',
[5] = 'dirt-5',
[6] = 'dirt-6',
[7] = 'dirt-7'
},
['start'] = value(125, 0),
['weight'] = 1,
['ratios'] = {
{resource = b.resource(b.full_shape, 'coal', value(0, 0.5)), weight = 1}
}
},
['iron-ore'] = {
['tiles'] = {
[1] = 'grass-1',
[2] = 'grass-2',
[3] = 'grass-3',
[4] = 'grass-4'
},
['start'] = value(125, 0),
['weight'] = 1,
['ratios'] = {
{resource = b.resource(b.full_shape, 'iron-ore', value(0, 0.5)), weight = 1}
}
},
['stone'] = {
['tiles'] = {
[1] = 'sand-1',
[2] = 'sand-2',
[3] = 'sand-3'
},
['start'] = value(125, 0),
['weight'] = 1,
['ratios'] = {
{resource = b.resource(b.full_shape, 'stone', value(0, 0.5)), weight = 1}
}
}
}

View File

@ -0,0 +1,17 @@
local b = require 'map_gen.shared.builders'
local value = b.euclidean_value
local oil_shape = b.throttle_world_xy(b.full_shape, 1, 7, 1, 7)
return {
{
scale = 1 / 64,
threshold = 0.6,
resource = b.resource(oil_shape, 'crude-oil', value(250000, 150))
},
{
scale = 1 / 72,
threshold = 0.63,
resource = b.resource(b.full_shape, 'uranium-ore', value(200, 1))
}
}

View File

@ -0,0 +1,37 @@
-- This module prevents all but the allowed items from being built on top of resources
local RestrictEntities = require 'map_gen.shared.entity_placement_restriction'
local Event = require 'utils.event'
local Token = require 'utils.token'
return function(allowed_entities)
--- Items explicitly allowed on ores
RestrictEntities.add_allowed(allowed_entities)
--- The logic for checking that there are resources under the entity's position
RestrictEntities.set_keep_alive_callback(
Token.register(
function(entity)
-- Some entities have a bounding_box area of zero, eg robots.
local area = entity.bounding_box
local left_top, right_bottom = area.left_top, area.right_bottom
if left_top.x == right_bottom.x and left_top.y == right_bottom.y then
return true
end
local count = entity.surface.count_entities_filtered {area = area, type = 'resource', limit = 1}
if count == 0 then
return true
end
end
)
)
--- Warning for players when their entities are destroyed
local function on_destroy(event)
local p = event.player
if p and p.valid then
p.print('You cannot build that on top of ores, only belts, mining drills, and power poles are allowed.')
end
end
Event.add(RestrictEntities.events.on_restricted_entity_destroyed, on_destroy)
end

View File

@ -0,0 +1,19 @@
local Perlin = require 'map_gen.shared.perlin_noise'
local seed_provider = require 'map_gen.maps.danger_ores.modules.seed_provider'
local perlin_noise = Perlin.noise
return function(config)
local scale = config.dense_patches_scale or 1 / 48
local threshold = config.dense_patches_threshold or 0.5
local multiplier = config.dense_patches_multiplier or 50
local seed = config.dense_patches_seed or seed_provider()
return function(x, y, entity)
x, y = x * scale, y * scale
local noise = perlin_noise(x, y, seed)
if noise > threshold then
entity.amount = entity.amount * multiplier
end
end
end

View File

@ -0,0 +1,75 @@
local Perlin = require 'map_gen.shared.perlin_noise'
local math = require 'utils.math'
local seed_provider = require 'map_gen.maps.danger_ores.modules.seed_provider'
local sqrt = math.sqrt
local max = math.max
local min = math.min
local ceil = math.ceil
local perlin_noise = Perlin.noise
local random = math.random
return function(config, shared_globals)
local worm_names =
config.worm_names or {'small-worm-turret', 'medium-worm-turret', 'big-worm-turret', 'behemoth-worm-turret'}
local spawner_names = config.spawner_names or {'biter-spawner', 'spitter-spawner'}
local factor = config.enemy_factor or 10 / (768 * 32)
local max_chance = config.enemy_max_chance or 1 / 6
local scale_factor = config.enemy_scale_factor or 32
local seed = config.enemy_seed or seed_provider()
local sf = 1 / scale_factor
local m = 1 / 850
return function(x, y, world)
if shared_globals.biters_disabled then
return nil
end
local d = sqrt(world.x * world.x + world.y * world.y)
if d < 64 then
return nil
end
local threshold = 1 - d * m
threshold = max(threshold, 0.35)
x, y = x * sf, y * sf
if perlin_noise(x, y, seed) <= threshold then
return
end
if random(8) == 1 then
local lvl
if d < 400 then
lvl = 1
elseif d < 650 then
lvl = 2
elseif d < 900 then
lvl = 3
else
lvl = 4
end
local chance = min(max_chance, d * factor)
if random() < chance then
local worm_id
if d > 1000 then
local power = 1000 / d
worm_id = ceil((random() ^ power) * lvl)
else
worm_id = random(lvl)
end
return {name = worm_names[worm_id]}
end
else
local chance = min(max_chance, d * factor)
if random() < chance then
local spawner_id = random(2)
return {name = spawner_names[spawner_id]}
end
end
end
end

View File

@ -0,0 +1,147 @@
local Global = require 'utils.global'
local b = require 'map_gen.shared.builders'
local Perlin = require 'map_gen.shared.perlin_noise'
local table = require 'utils.table'
local math = require 'utils.math'
local seed_provider = require 'map_gen.maps.danger_ores.modules.seed_provider'
local binary_search = table.binary_search
local perlin_noise = Perlin.noise
local floor = math.floor
local random = math.random
local bnot = bit32.bnot
local function spawn_builder(config)
local spawn_circle = config.spawn_shape or b.circle(64)
local water = b.circle(16)
water = b.change_tile(water, true, 'water')
water = b.any {b.rectangle(32, 4), b.rectangle(4, 32), water}
local start = b.if_else(water, spawn_circle)
return b.change_map_gen_collision_tile(start, 'water-tile', 'grass-1')
end
local function tile_builder_factory(config)
local tile_builder_scale = config.tile_builder_scale or 1 / 64
local seed = seed_provider()
return function(tiles)
local half = #tiles / 2
return function(x, y)
x, y = x * tile_builder_scale, y * tile_builder_scale
local v = perlin_noise(x, y, seed)
v = (v + 1) * half + 1
v = floor(v)
return tiles[v]
end
end
end
local function no_op()
end
local function empty_builder()
return b.empty_shape
end
return function(config, shared_globals)
local start_ore_shape
local resource_patches
local dense_patches
local function ore_builder(ore_name, amount, ratios, weighted)
local start_ore = b.resource(b.full_shape, ore_name, amount)
local total = weighted.total
return function(x, y, world)
if start_ore_shape(x, y) then
return start_ore(x, y, world)
end
local resource_patches_entity = resource_patches(x, y, world)
if resource_patches_entity ~= false then
return resource_patches_entity
end
local i = random() * total
local index = binary_search(weighted, i)
if index < 0 then
index = bnot(index)
end
local resource = ratios[index].resource
local entity = resource(x, y, world)
dense_patches(x, y, entity)
entity.enable_tree_removal = false
return entity
end
end
local map
Global.register_init(
{},
function(tbl)
tbl.seed = seed_provider()
tbl.random = game.create_random_generator(tbl.seed)
end,
function(tbl)
local spawn_shape = spawn_builder(config)
local water_shape = (config.water or empty_builder)(config)
local tile_builder = tile_builder_factory(config)
local trees_shape = (config.trees or no_op)(config)
local enemy_shape = (config.enemy or no_op)(config, shared_globals)
local fish_spawn_rate = config.fish_spawn_rate
local main_ores = config.main_ores
start_ore_shape = config.start_ore_shape or b.circle(68)
resource_patches = (config.resource_patches or no_op)(config) or b.empty_shape
dense_patches = (config.dense_patches or no_op)(config) or no_op
local shapes = {}
for ore_name, ore_data in pairs(main_ores) do
local tiles = ore_data.tiles
local land = tile_builder(tiles)
local ratios = ore_data.ratios
local weighted = b.prepare_weighted_array(ratios)
local amount = ore_data.start
local ore = ore_builder(ore_name, amount, ratios, weighted)
local shape = b.apply_entity(land, ore)
shapes[#shapes + 1] = {shape = shape, weight = ore_data.weight}
end
if config.main_ores_shuffle_order then
local random_gen = tbl.random
random_gen.re_seed(tbl.seed)
table.shuffle_table(shapes, random_gen)
end
local ores = b.segment_weighted_pattern(shapes)
map = b.any {spawn_shape, water_shape, ores}
if enemy_shape then
map = b.apply_entity(map, enemy_shape)
end
if trees_shape then
map = b.apply_entity(map, trees_shape)
end
if fish_spawn_rate then
map = b.fish(map, fish_spawn_rate)
end
end
)
return function(x, y, world)
return map(x, y, world)
end
end

View File

@ -0,0 +1,41 @@
local Perlin = require 'map_gen.shared.perlin_noise'
local seed_provider = require 'map_gen.maps.danger_ores.modules.seed_provider'
local perlin_noise = Perlin.noise
return function(config)
local resource_patches = config.resource_patches_config
local entities = {}
for _, data in pairs(resource_patches) do
local scale = data.scale
local threshold = data.threshold
local resource = data.resource
local seed = data.seed or seed_provider()
local function entity_shape(x, y, world)
x, y = x * scale, y * scale
local noise = perlin_noise(x, y, seed)
if noise > threshold then
return resource(x, y, world)
end
return false
end
entities[#entities + 1] = entity_shape
end
return function(x, y, world)
for i = 1, #entities do
local e = entities[i](x, y, world)
if e ~= false then
return e
end
end
return false
end
end

View File

@ -0,0 +1,239 @@
local Event = require 'utils.event'
local Generate = require 'map_gen.shared.generate'
local Global = require 'utils.global'
local Queue = require 'utils.queue'
local AlienEvolutionProgress = require 'utils.alien_evolution_progress'
local RS = require 'map_gen.shared.redmew_surface'
local Task = require 'utils.task'
local Token = require 'utils.token'
local Server = require 'features.server'
return function(config, shared_globals)
local recent_chunks = Queue.new() -- Keeps track of recently revealed chunks
local recent_chunks_max = config.recent_chunks_max or 10 -- Maximum number of chunks to track
local ticks_between_waves = config.ticks_between_waves or 60 * 30
local enemy_factor = config.enemy_factor or 5
local max_enemies_per_wave_per_chunk = config.max_enemies_per_wave_per_chunk or 60
local win_data = {
evolution_rocket_maxed = -1,
extra_rockets = config.extra_rockets or 100
}
shared_globals.biters_disabled = false
_G.rocket_launched_win_data = win_data
Global.register(
{recent_chunks = recent_chunks, win_data = win_data},
function(tbl)
recent_chunks = tbl.recent_chunks
win_data = tbl.win_data
end
)
local function give_command(group, data)
local target = data.target
if target and target.valid then
local command = {
type = defines.command.attack,
target = target,
distraction = defines.distraction.by_damage
}
group.set_command(command)
group.start_moving()
else
local command = {
type = defines.command.attack_area,
destination = data.position,
radius = 32,
distraction = defines.distraction.by_damage
}
local members = group.members
for i = 1, #members do
local entitiy = members[i]
entitiy.set_command(command)
end
end
end
local do_waves
local do_wave
do_waves =
Token.register(
function(data)
Task.queue_task(do_wave, data, 10)
end
)
do_wave =
Token.register(
function(data)
if shared_globals.biters_disabled then
return false
end
local wave = data.wave
local last_wave = data.last_wave
--game.print('wave: ' .. wave .. '/' .. last_wave)
local chunk_index = data.chunk_index
local chunk = data.chunks[chunk_index]
if not chunk then
data.wave = wave + 1
data.chunk_index = 1
Task.set_timeout_in_ticks(ticks_between_waves, do_waves, data)
return false
end
local spawner = data.spawner
local aliens = AlienEvolutionProgress.get_aliens(spawner, game.forces.enemy.evolution_factor)
local left_top = chunk.area.left_top
local center = {left_top.x + 16, left_top.y + 16}
local surface = chunk.surface
local find_non_colliding_position = surface.find_non_colliding_position
local create_entity = surface.create_entity
local group = surface.create_unit_group {position = center}
local add_member = group.add_member
for name, count in pairs(aliens) do
for i = 1, count do
local pos = find_non_colliding_position(name, center, 32, 1)
if pos then
local e = {name = name, position = pos, force = 'enemy', center = center, radius = 16, 1}
local ent = create_entity(e)
add_member(ent)
end
end
end
give_command(group, data)
if chunk_index < recent_chunks_max then
data.chunk_index = chunk_index + 1
return true
end
if wave < last_wave then
data.wave = wave + 1
data.chunk_index = 1
Task.set_timeout_in_ticks(ticks_between_waves, do_waves, data)
end
return false
end
)
local function start_waves(event)
local num_enemies = enemy_factor * game.forces.player.get_item_launched('satellite')
local number_of_waves = math.ceil(num_enemies / max_enemies_per_wave_per_chunk)
local num_enemies_per_wave_per_chunk = math.ceil(num_enemies / number_of_waves)
local target = event.rocket_silo
local position
if target and target.valid then
position = target.position
else
position = {0, 0}
end
local data = {
spawner = AlienEvolutionProgress.create_spawner_request(num_enemies_per_wave_per_chunk),
wave = 1,
last_wave = number_of_waves,
chunk_index = 1,
chunks = Queue.to_array(recent_chunks),
target = target,
position = position
}
Task.set_timeout_in_ticks(1, do_waves, data)
game.print('Warning incomming biter attack! Number of waves: ' .. number_of_waves)
end
local function rocket_launched(event)
local entity = event.rocket
if not entity or not entity.valid or not entity.force == 'player' then
return
end
local inventory = entity.get_inventory(defines.inventory.rocket)
if not inventory or not inventory.valid then
return
end
local satellite_count = game.forces.player.get_item_launched('satellite')
if satellite_count == 0 then
return
end
if shared_globals.biters_disabled then
return
end
-- Increase enemy_evolution
local current_evolution = game.forces.enemy.evolution_factor
if (satellite_count % 5) == 0 and win_data.evolution_rocket_maxed == -1 then
local message =
'Continued launching of satellites has angered the local biter population, evolution increasing...'
game.print(message)
Server.to_discord_bold(message)
current_evolution = current_evolution + 0.05
game.forces.enemy.evolution_factor = current_evolution
end
if current_evolution < 1 then
start_waves(event)
return
end
if win_data.evolution_rocket_maxed == -1 then
win_data.evolution_rocket_maxed = satellite_count
end
local remaining_satellites = win_data.evolution_rocket_maxed + win_data.extra_rockets - satellite_count
if remaining_satellites > 0 then
local message =
'Biters at maximum evolution! Protect the base for an additional ' ..
remaining_satellites .. ' rockets to wipe them out forever.'
game.print(message)
Server.to_discord_bold(message)
start_waves(event)
return
end
local win_message = 'Congratulations! Biters have been wiped from the map!'
game.print(win_message)
Server.to_discord_bold(win_message)
shared_globals.biters_disabled = true
for key, enemy_entity in pairs(RS.get_surface().find_entities_filtered({force = 'enemy'})) do
enemy_entity.destroy()
end
end
local function chunk_unlocked(chunk)
Queue.push(recent_chunks, chunk)
while Queue.size(recent_chunks) > recent_chunks_max do
Queue.pop(recent_chunks)
end
end
Event.add(defines.events.on_rocket_launched, rocket_launched)
Event.add(Generate.events.on_chunk_generated, chunk_unlocked)
end

View File

@ -0,0 +1,13 @@
local RS = require 'map_gen.shared.redmew_surface'
local seed = nil
local count = 0
return function()
if seed == nil then
seed = RS.get_surface().map_gen_settings.seed
end
count = count + 1
return seed * count
end

View File

@ -0,0 +1,124 @@
local b = require 'map_gen.shared.builders'
local Generate = require 'map_gen.shared.generate'
local Event = require 'utils.event'
local Global = require 'utils.global'
local RS = require 'map_gen.shared.redmew_surface'
local table = require 'utils.table'
local fast_remove = table.fast_remove
local concat = table.concat
local format = string.format
local rendering = rendering
return function(config)
Generate.enable_register_events = false
local start_size = config.start_size
local pollution_data = {
min_pollution = config.min_pollution or 400,
max_pollution = config.max_pollution or 3500,
pollution_increment = config.pollution_increment or 2.5
}
_G.terraforming_pollution_data = pollution_data
local chunk_list = {index = 1}
local surface
Global.register_init(
{chunk_list = chunk_list, pollution_data = pollution_data},
function(tbl)
tbl.surface = RS.get_surface()
end,
function(tbl)
chunk_list = tbl.chunk_list
pollution_data = tbl.pollution_data
surface = tbl.surface
end
)
local bounds = b.rectangle(start_size, start_size)
local function on_chunk(event)
if surface ~= event.surface then
return
end
local left_top = event.area.left_top
local x, y = left_top.x, left_top.y
if bounds(x + 0.5, y + 0.5) then
Generate.do_chunk(event)
else
local tiles = {}
for x1 = x, x + 31 do
for y1 = y, y + 31 do
tiles[#tiles + 1] = {name = 'out-of-map', position = {x1, y1}}
end
end
surface.set_tiles(tiles, true)
chunk_list[#chunk_list + 1] = {left_top = left_top, id = nil}
end
end
local function on_tick()
local index = chunk_list.index
if index > #chunk_list then
chunk_list.index = 1
return
end
local data = chunk_list[index]
local pos = data.left_top
local x, y = pos.x, pos.y
local pollution = surface.get_pollution(pos)
local current_min_pollution = pollution_data.min_pollution
if pollution > current_min_pollution then
fast_remove(chunk_list, index)
local id = data.id
if id then
rendering.destroy(id)
end
local area = {left_top = pos, right_bottom = {x + 32, y + 32}}
local event = {surface = surface, area = area}
Generate.schedule_chunk(event)
if current_min_pollution < pollution_data.max_pollution then
pollution_data.min_pollution = current_min_pollution + pollution_data.pollution_increment
end
return
else
local text = concat {format('%i', pollution), ' / ', current_min_pollution}
local complete = pollution / current_min_pollution
local color = {r = 1 - complete, g = complete, b = 0}
local id = data.id
if not id then
data.id =
rendering.draw_text {
text = text,
surface = surface,
target = {x + 16, y + 16},
color = color,
scale = 5
}
else
rendering.set_text(id, text)
rendering.set_color(id, color)
end
end
chunk_list.index = index + 1
end
Event.add(defines.events.on_chunk_generated, on_chunk)
Event.on_nth_tick(1, on_tick)
end

View File

@ -0,0 +1,42 @@
local Perlin = require 'map_gen.shared.perlin_noise'
local math = require 'utils.math'
local seed_provider = require 'map_gen.maps.danger_ores.modules.seed_provider'
local perlin_noise = Perlin.noise
local random = math.random
local trees = {
'tree-01',
'tree-02',
'tree-02-red',
'tree-03',
'tree-04',
'tree-05',
'tree-06',
'tree-06-brown',
'tree-07',
'tree-08',
'tree-08-brown',
'tree-08-red',
'tree-09',
'tree-09-brown',
'tree-09-red'
}
local trees_count = #trees
return function(config)
local scale = config.trees_scale or 1 / 64
local threshold = config.trees_threshold or -0.25
local chance = config.trees_chance or 0.125
local seed = config.trees_seed or seed_provider()
return function(x, y)
local tree_noise = perlin_noise(x * scale, y * scale, seed)
if tree_noise > threshold or random() > chance then
return nil
end
return {name = trees[random(trees_count)]}
end
end

View File

@ -0,0 +1,28 @@
local Perlin = require 'map_gen.shared.perlin_noise'
local seed_provider = require 'map_gen.maps.danger_ores.modules.seed_provider'
local b = require 'map_gen.shared.builders'
local perlin_noise = Perlin.noise
return function(config)
local scale = config.water_scale or 1 / 96
local water_threshold = config.water_threshold or 0.5
local deepwater_threshold = config.deepwater_threshold or 0.55
local no_water_shape = config.no_water_shape or b.circle(96)
local seed = config.water_seed or seed_provider()
return function(x, y)
if no_water_shape(x, y) then
return false
end
local water_noise = perlin_noise(x * scale, y * scale, seed)
if water_noise >= deepwater_threshold then
return 'deepwater'
elseif water_noise >= water_threshold then
return 'water'
end
return false
end
end

View File

@ -0,0 +1,158 @@
local RS = require 'map_gen.shared.redmew_surface'
local MGSP = require 'resources.map_gen_settings'
local Event = require 'utils.event'
local b = require 'map_gen.shared.builders'
local Token = require 'utils.token'
local ScenarioInfo = require 'features.gui.info'
ScenarioInfo.set_map_name('Danger Bobs & Angels Ore Quadrants')
ScenarioInfo.set_map_description(
[[
Clear the ore to expand the base,
focus mining efforts on specific quadrants to ensure
proper material ratios, expand the map with pollution!
]]
)
ScenarioInfo.add_map_extra_info(
[[
This map is split in 6 sectors. Each sector has a main resource.
You may not build the factory on ore patches. Exceptions:
[item=burner-mining-drill] [item=electric-mining-drill] [item=pumpjack] [item=small-electric-pole] [item=medium-electric-pole] [item=big-electric-pole] [item=substation] [item=car] [item=tank]
[item=basic-transport-belt] [item=transport-belt] [item=fast-transport-belt] [item=express-transport-belt] [item=turbo-transport-belt] [item=ultimate-transport-belt] [item=basic-underground-belt] [item=underground-belt] [item=fast-underground-belt] [item=express-underground-belt] [item=turbo-underground-belt] [item=ultimate-underground-belt]
The map size is restricted to the pollution generated. A significant amount of
pollution must affect a section of the map before it is revealed. Pollution
does not affect biter evolution.]]
)
ScenarioInfo.set_map_description(
[[
Clear the ore to expand the base,
focus mining efforts on specific sector to ensure
proper material ratios, expand the map with pollution!
]]
)
local shared_globals = {}
Token.register_global(shared_globals)
_G.danger_ore_shared_globals = shared_globals
local map = require 'map_gen.maps.danger_ores.modules.map'
local main_ores_config = require 'map_gen.maps.danger_ores.config.bobangels_ores'
local resource_patches = require 'map_gen.maps.danger_ores.modules.resource_patches'
local resource_patches_config = require 'map_gen.maps.danger_ores.config.bobangels_resource_patches'
local water = require 'map_gen.maps.danger_ores.modules.water'
local trees = require 'map_gen.maps.danger_ores.modules.trees'
local enemy = require 'map_gen.maps.danger_ores.modules.enemy'
local dense_patches = require 'map_gen.maps.danger_ores.modules.dense_patches'
local banned_entities = require 'map_gen.maps.danger_ores.modules.banned_entities'
local allowed_entities = require 'map_gen.maps.danger_ores.config.bobangels_allowed_entities'
banned_entities(allowed_entities)
local ores_names = {
'angels-ore1', -- Saphirite
'angels-ore2', -- Jivolite
'angels-ore3', -- stiratite
'angels-ore4', -- Crotinium
'angels-ore5', -- rubyte
'angels-ore6', -- bobmonium
'angels-fissure',
'angels-natural-gas', -- gas well
'coal',
'crude-oil'
}
local ore_oil_none = {}
for _, v in pairs(ores_names) do
ore_oil_none[v] = {
frequency = 1,
richness = 1,
size = 0
}
end
ore_oil_none = {autoplace_controls = ore_oil_none}
RS.set_map_gen_settings(
{
MGSP.grass_only,
MGSP.enable_water,
{
terrain_segmentation = 'normal',
water = 'normal'
},
MGSP.starting_area_very_low,
ore_oil_none,
MGSP.enemy_none,
MGSP.cliff_none
}
)
Event.on_init(
function()
game.draw_resource_selection = false
game.forces.player.technologies['mining-productivity-1'].enabled = false
game.forces.player.technologies['mining-productivity-2'].enabled = false
game.forces.player.technologies['mining-productivity-3'].enabled = false
game.forces.player.technologies['mining-productivity-4'].enabled = false
game.difficulty_settings.technology_price_multiplier = 5
game.forces.player.technologies.logistics.researched = true
game.forces.player.technologies.automation.researched = true
game.map_settings.enemy_evolution.time_factor = 0.000007 -- default 0.000004
game.map_settings.enemy_evolution.destroy_factor = 0.000010 -- default 0.002
game.map_settings.enemy_evolution.pollution_factor = 0.000000 -- Pollution has no affect on evolution default 0.0000009
end
)
local terraforming = require 'map_gen.maps.danger_ores.modules.terraforming'
terraforming(
{
start_size = 8 * 32,
min_pollution = 400,
max_pollution = 20000,
pollution_increment = 4
}
)
local rocket_launched = require 'map_gen.maps.danger_ores.modules.rocket_launched'
rocket_launched(
{
recent_chunks_max = 10,
ticks_between_waves = 60 * 30,
enemy_factor = 5,
max_enemies_per_wave_per_chunk = 60,
extra_rockets = 100
},
shared_globals
)
local config = {
spawn_shape = b.circle(80),
start_ore_shape = b.circle(86),
main_ores = main_ores_config,
main_ores_shuffle_order = true,
resource_patches = resource_patches,
resource_patches_config = resource_patches_config,
water = water,
water_scale = 1 / 96,
water_threshold = 0.5,
deepwater_threshold = 0.55,
no_water_shape = b.circle(102),
trees = trees,
trees_scale = 1 / 64,
trees_threshold = -0.25,
trees_chance = 0.125,
enemy = enemy,
enemy_factor = 10 / (768 * 32),
enemy_max_chance = 1 / 6,
enemy_scale_factor = 32,
fish_spawn_rate = 0.025,
dense_patches = dense_patches,
dense_patches_scale = 1 / 48,
dense_patches_threshold = 0.5,
dense_patches_multiplier = 50
}
return map(config, shared_globals)

View File

@ -0,0 +1,169 @@
local RS = require 'map_gen.shared.redmew_surface'
local MGSP = require 'resources.map_gen_settings'
local Event = require 'utils.event'
local b = require 'map_gen.shared.builders'
local Token = require 'utils.token'
local ScenarioInfo = require 'features.gui.info'
ScenarioInfo.set_map_name('Terraforming Danger Ore')
ScenarioInfo.set_map_description(
[[
Clear the ore to expand the base,
focus mining efforts on specific quadrants to ensure
proper material ratios, expand the map with pollution!
]]
)
ScenarioInfo.add_map_extra_info(
[[
This map is split in four quadrants. Each quadrant has a main resource.
[item=iron-ore] north east, [item=copper-ore] south west, [item=coal] north west, [item=stone] south east
You may not build the factory on ore patches. Exceptions:
[item=burner-mining-drill] [item=electric-mining-drill] [item=pumpjack] [item=small-electric-pole] [item=medium-electric-pole] [item=big-electric-pole] [item=substation] [item=car] [item=tank]
[item=transport-belt] [item=fast-transport-belt] [item=express-transport-belt] [item=underground-belt] [item=fast-underground-belt] [item=express-underground-belt]
The map size is restricted to the pollution generated. A significant amount of
pollution must affect a section of the map before it is revealed. Pollution
does not affect biter evolution.]]
)
ScenarioInfo.set_map_description(
[[
Clear the ore to expand the base,
focus mining efforts on specific quadrants to ensure
proper material ratios, expand the map with pollution!
]]
)
local shared_globals = {}
Token.register_global(shared_globals)
_G.danger_ore_shared_globals = shared_globals
local map = require 'map_gen.maps.danger_ores.modules.map'
local main_ores_config = require 'map_gen.maps.danger_ores.config.bob_ores'
local resource_patches = require 'map_gen.maps.danger_ores.modules.resource_patches'
local resource_patches_config = require 'map_gen.maps.danger_ores.config.bob_resource_patches'
local water = require 'map_gen.maps.danger_ores.modules.water'
local trees = require 'map_gen.maps.danger_ores.modules.trees'
local enemy = require 'map_gen.maps.danger_ores.modules.enemy'
local dense_patches = require 'map_gen.maps.danger_ores.modules.dense_patches'
local banned_entities = require 'map_gen.maps.danger_ores.modules.banned_entities'
local allowed_entities = require 'map_gen.maps.danger_ores.config.bob_allowed_entities'
banned_entities(allowed_entities)
local ores_names = {
'coal',
'copper-ore',
'crude-oil',
'iron-ore',
'stone',
'uranium-ore',
'bauxite-ore',
'cobalt-ore',
'gem-ore',
'gold-ore',
'lead-ore',
'nickel-ore',
'quartz',
'rutile-ore',
'silver-ore',
'sulfur',
'tin-ore',
'tungsten-ore',
'zinc-ore',
'thorium-ore'
}
local ore_oil_none = {}
for _, v in pairs(ores_names) do
ore_oil_none[v] = {
frequency = 1,
richness = 1,
size = 0
}
end
ore_oil_none = {autoplace_controls = ore_oil_none}
RS.set_map_gen_settings(
{
MGSP.grass_only,
MGSP.enable_water,
{
terrain_segmentation = 'normal',
water = 'normal'
},
MGSP.starting_area_very_low,
ore_oil_none,
MGSP.enemy_none,
MGSP.cliff_none
}
)
Event.on_init(
function()
game.draw_resource_selection = false
game.forces.player.technologies['mining-productivity-1'].enabled = false
game.forces.player.technologies['mining-productivity-2'].enabled = false
game.forces.player.technologies['mining-productivity-3'].enabled = false
game.forces.player.technologies['mining-productivity-4'].enabled = false
game.difficulty_settings.technology_price_multiplier = 5
game.forces.player.technologies.logistics.researched = true
game.forces.player.technologies.automation.researched = true
game.map_settings.enemy_evolution.time_factor = 0.000007 -- default 0.000004
game.map_settings.enemy_evolution.destroy_factor = 0.000010 -- default 0.002
game.map_settings.enemy_evolution.pollution_factor = 0.000000 -- Pollution has no affect on evolution default 0.0000009
end
)
local terraforming = require 'map_gen.maps.danger_ores.modules.terraforming'
terraforming(
{
start_size = 8 * 32,
min_pollution = 400,
max_pollution = 20000,
pollution_increment = 4
}
)
local rocket_launched = require 'map_gen.maps.danger_ores.modules.rocket_launched'
rocket_launched(
{
recent_chunks_max = 10,
ticks_between_waves = 60 * 30,
enemy_factor = 5,
max_enemies_per_wave_per_chunk = 60,
extra_rockets = 100
},
shared_globals
)
local config = {
spawn_shape = b.circle(80),
start_ore_shape = b.circle(86),
main_ores = main_ores_config,
main_ores_shuffle_order = true,
resource_patches = resource_patches,
resource_patches_config = resource_patches_config,
water = water,
water_scale = 1 / 96,
water_threshold = 0.5,
deepwater_threshold = 0.55,
no_water_shape = b.circle(102),
trees = trees,
trees_scale = 1 / 64,
trees_threshold = -0.25,
trees_chance = 0.125,
enemy = enemy,
enemy_factor = 10 / (768 * 32),
enemy_max_chance = 1 / 6,
enemy_scale_factor = 32,
fish_spawn_rate = 0.025,
dense_patches = dense_patches,
dense_patches_scale = 1 / 48,
dense_patches_threshold = 0.5,
dense_patches_multiplier = 50
}
return map(config, shared_globals)

View File

@ -0,0 +1,74 @@
local RS = require 'map_gen.shared.redmew_surface'
local MGSP = require 'resources.map_gen_settings'
local Event = require 'utils.event'
local b = require 'map_gen.shared.builders'
local Token = require 'utils.token'
local ScenarioInfo = require 'features.gui.info'
ScenarioInfo.set_map_name('Danger Ores')
ScenarioInfo.set_map_description(
[[
Clear the ore to expand the base:
build extensive mining efforts, create large smelting arrays,
use proper material ratios, and defend from enemies!
]]
)
ScenarioInfo.add_map_extra_info(
[[You may not build the factory on ore patches. Exceptions:
[item=burner-mining-drill] [item=electric-mining-drill] [item=pumpjack] [item=small-electric-pole] [item=medium-electric-pole] [item=big-electric-pole] [item=substation] [item=car] [item=tank]
[item=transport-belt] [item=fast-transport-belt] [item=express-transport-belt] [item=underground-belt] [item=fast-underground-belt] [item=express-underground-belt] ]]
)
local shared_globals = {}
Token.register_global(shared_globals)
_G.danger_ore_shared_globals = shared_globals
local map = require 'map_gen.maps.danger_ores.modules.map'
local main_ores_config = require 'map_gen.maps.danger_ores.config.vanilla_ores'
local resource_patches = require 'map_gen.maps.danger_ores.modules.resource_patches'
local resource_patches_config = require 'map_gen.maps.danger_ores.config.vanilla_resource_patches'
local dense_patches = require 'map_gen.maps.danger_ores.modules.dense_patches'
local banned_entities = require 'map_gen.maps.danger_ores.modules.banned_entities'
local allowed_entities = require 'map_gen.maps.danger_ores.config.vanilla_allowed_entities'
banned_entities(allowed_entities)
RS.set_map_gen_settings(
{
MGSP.ore_oil_none,
MGSP.cliff_none
}
)
Event.on_init(
function()
game.draw_resource_selection = false
game.forces.player.technologies['mining-productivity-1'].enabled = false
game.forces.player.technologies['mining-productivity-2'].enabled = false
game.forces.player.technologies['mining-productivity-3'].enabled = false
game.forces.player.technologies['mining-productivity-4'].enabled = false
game.difficulty_settings.technology_price_multiplier = 20
game.forces.player.technologies.logistics.researched = true
game.forces.player.technologies.automation.researched = true
game.map_settings.enemy_evolution.time_factor = 0.000002 -- default 0.000004
game.map_settings.enemy_evolution.destroy_factor = 0.0009 -- default 0.002
game.map_settings.enemy_evolution.pollution_factor = 0.0000015 -- default 0.0000009
end
)
local config = {
spawn_shape = b.circle(64),
start_ore_shape = b.circle(68),
main_ores = main_ores_config,
--main_ores_shuffle_order = true,
resource_patches = resource_patches,
resource_patches_config = resource_patches_config,
dense_patches = dense_patches,
dense_patches_scale = 1 / 48,
dense_patches_threshold = 0.5,
dense_patches_multiplier = 50
}
return map(config, shared_globals)

View File

@ -0,0 +1,156 @@
local RS = require 'map_gen.shared.redmew_surface'
local MGSP = require 'resources.map_gen_settings'
local Event = require 'utils.event'
local b = require 'map_gen.shared.builders'
local Token = require 'utils.token'
local ScenarioInfo = require 'features.gui.info'
ScenarioInfo.set_map_name('Terraforming Danger Ore')
ScenarioInfo.set_map_description(
[[
Clear the ore to expand the base,
focus mining efforts on specific quadrants to ensure
proper material ratios, expand the map with pollution!
]]
)
ScenarioInfo.add_map_extra_info(
[[
This map is split in four quadrants. Each quadrant has a main resource.
[item=iron-ore] north east, [item=copper-ore] south west, [item=coal] north west, [item=stone] south east
You may not build the factory on ore patches. Exceptions:
[item=burner-mining-drill] [item=electric-mining-drill] [item=pumpjack] [item=small-electric-pole] [item=medium-electric-pole] [item=big-electric-pole] [item=substation] [item=car] [item=tank]
[item=transport-belt] [item=fast-transport-belt] [item=express-transport-belt] [item=underground-belt] [item=fast-underground-belt] [item=express-underground-belt]
The map size is restricted to the pollution generated. A significant amount of
pollution must affect a section of the map before it is revealed. Pollution
does not affect biter evolution.]]
)
ScenarioInfo.set_map_description(
[[
Clear the ore to expand the base,
focus mining efforts on specific quadrants to ensure
proper material ratios, expand the map with pollution!
]]
)
ScenarioInfo.set_new_info(
[[
2019-04-24:
- Stone ore density reduced by 1/2
- Ore quadrants randomized
- Increased time factor of biter evolution from 5 to 7
- Added win conditions (+5% evolution every 5 rockets until 100%, +100 rockets until biters are wiped)
2019-03-30:
- Uranium ore patch threshold increased slightly
- Bug fix: Cars and tanks can now be placed onto ore!
- Starting minimum pollution to expand map set to 650
View current pollution via Debug Settings [F4] show-pollution-values,
then open map and turn on pollution via the red box.
- Starting water at spawn increased from radius 8 to radius 16 circle.
2019-03-27:
- Ore arranged into quadrants to allow for more controlled resource gathering.
]]
)
local shared_globals = {}
Token.register_global(shared_globals)
_G.danger_ore_shared_globals = shared_globals
local map = require 'map_gen.maps.danger_ores.modules.map'
local main_ores_config = require 'map_gen.maps.danger_ores.config.vanilla_ores'
local resource_patches = require 'map_gen.maps.danger_ores.modules.resource_patches'
local resource_patches_config = require 'map_gen.maps.danger_ores.config.vanilla_resource_patches'
local water = require 'map_gen.maps.danger_ores.modules.water'
local trees = require 'map_gen.maps.danger_ores.modules.trees'
local enemy = require 'map_gen.maps.danger_ores.modules.enemy'
local dense_patches = require 'map_gen.maps.danger_ores.modules.dense_patches'
local banned_entities = require 'map_gen.maps.danger_ores.modules.banned_entities'
local allowed_entities = require 'map_gen.maps.danger_ores.config.vanilla_allowed_entities'
banned_entities(allowed_entities)
RS.set_map_gen_settings(
{
MGSP.grass_only,
MGSP.enable_water,
{
terrain_segmentation = 'normal',
water = 'normal'
},
MGSP.starting_area_very_low,
MGSP.ore_oil_none,
MGSP.enemy_none,
MGSP.cliff_none
}
)
Event.on_init(
function()
game.draw_resource_selection = false
game.forces.player.technologies['mining-productivity-1'].enabled = false
game.forces.player.technologies['mining-productivity-2'].enabled = false
game.forces.player.technologies['mining-productivity-3'].enabled = false
game.forces.player.technologies['mining-productivity-4'].enabled = false
game.difficulty_settings.technology_price_multiplier = 20
game.forces.player.technologies.logistics.researched = true
game.forces.player.technologies.automation.researched = true
game.map_settings.enemy_evolution.time_factor = 0.000007 -- default 0.000004
game.map_settings.enemy_evolution.destroy_factor = 0.000010 -- default 0.002
game.map_settings.enemy_evolution.pollution_factor = 0.000000 -- Pollution has no affect on evolution default 0.0000009
end
)
local terraforming = require 'map_gen.maps.danger_ores.modules.terraforming'
terraforming(
{
start_size = 8 * 32,
min_pollution = 400,
max_pollution = 3500,
pollution_increment = 2.5
}
)
local rocket_launched = require 'map_gen.maps.danger_ores.modules.rocket_launched'
rocket_launched(
{
recent_chunks_max = 10,
ticks_between_waves = 60 * 30,
enemy_factor = 2,
max_enemies_per_wave_per_chunk = 60,
extra_rockets = 100
},
shared_globals
)
local config = {
spawn_shape = b.circle(64),
start_ore_shape = b.circle(68),
main_ores = main_ores_config,
--main_ores_shuffle_order = true,
resource_patches = resource_patches,
resource_patches_config = resource_patches_config,
water = water,
water_scale = 1 / 96,
water_threshold = 0.5,
deepwater_threshold = 0.55,
trees = trees,
trees_scale = 1 / 64,
trees_threshold = -0.25,
trees_chance = 0.125,
enemy = enemy,
enemy_factor = 10 / (768 * 32),
enemy_max_chance = 1 / 6,
enemy_scale_factor = 32,
fish_spawn_rate = 0.025,
dense_patches = dense_patches,
dense_patches_scale = 1 / 48,
dense_patches_threshold = 0.5,
dense_patches_multiplier = 50
}
return map(config, shared_globals)

View File

@ -1,669 +1 @@
local b = require 'map_gen.shared.builders'
local Generate = require 'map_gen.shared.generate'
local Perlin = require 'map_gen.shared.perlin_noise'
local Event = require 'utils.event'
local Global = require 'utils.global'
local math = require 'utils.math'
local table = require 'utils.table'
local RS = require 'map_gen.shared.redmew_surface'
local MGSP = require 'resources.map_gen_settings'
local ScenarioInfo = require 'features.gui.info'
ScenarioInfo.set_map_name('Danger Ore Quadrants')
ScenarioInfo.set_map_description(
[[
Clear the ore to expand the base,
focus mining efforts on specific quadrants to ensure
proper material ratios, expand the map with pollution!
]]
)
ScenarioInfo.add_map_extra_info(
[[
This map is split in four quadrants. Each quadrant has a main resource.
[item=iron-ore] north east, [item=copper-ore] south west, [item=coal] north west, [item=stone] south east
You may not build the factory on ore patches. Exceptions:
[item=burner-mining-drill] [item=electric-mining-drill] [item=pumpjack] [item=small-electric-pole] [item=medium-electric-pole] [item=big-electric-pole] [item=substation] [item=car] [item=tank]
[item=transport-belt] [item=fast-transport-belt] [item=express-transport-belt] [item=underground-belt] [item=fast-underground-belt] [item=express-underground-belt]
The map size is restricted to the pollution generated. A significant amount of
pollution must affect a section of the map before it is revealed. Pollution
does not affect biter evolution.]]
)
ScenarioInfo.set_map_description(
[[
Clear the ore to expand the base,
focus mining efforts on specific quadrants to ensure
proper material ratios, expand the map with pollution!
]]
)
ScenarioInfo.set_new_info(
[[
2019-04-24:
- Stone ore density reduced by 1/2
- Ore quadrants randomized
- Increased time factor of biter evolution from 5 to 7
- Added win conditions (+5% evolution every 5 rockets until 100%, +100 rockets until biters are wiped)
2019-03-30:
- Uranium ore patch threshold increased slightly
- Bug fix: Cars and tanks can now be placed onto ore!
- Starting minimum pollution to expand map set to 650
View current pollution via Debug Settings [F4] show-pollution-values,
then open map and turn on pollution via the red box.
- Starting water at spawn increased from radius 8 to radius 16 circle.
2019-03-27:
- Ore arranged into quadrants to allow for more controlled resource gathering.
]]
)
require 'map_gen.shared.danger_ore_banned_entities'
global.config.lazy_bastard.enabled = false
RS.set_first_player_position_check_override(true)
RS.set_spawn_island_tile('grass-1')
RS.set_map_gen_settings(
{
MGSP.grass_only,
MGSP.enable_water,
{
terrain_segmentation = 'normal',
water = 'normal'
},
MGSP.starting_area_very_low,
MGSP.ore_oil_none,
MGSP.enemy_none,
MGSP.cliff_none
}
)
local perlin_noise = Perlin.noise
local fast_remove = table.fast_remove
Generate.enable_register_events = false
local oil_seed
local uranium_seed
local density_seed
local enemy_seed
local water_seed
local tree_seed
local oil_scale = 1 / 64
local oil_threshold = 0.6
local uranium_scale = 1 / 72
local uranium_threshold = 0.63
local density_scale = 1 / 48
local density_threshold = 0.5
local density_multiplier = 50
local water_scale = 1 / 96
local water_threshold = 0.5
local deepwater_threshold = 0.55
local tree_scale = 1 / 64
local tree_threshold = -0.25
local tree_chance = 0.125
local start_chunks_half_size = 3
local max_pollution = 2500
local pollution_increment = 2
global.min_pollution = 300
local chunk_list = {index = 1}
local surface
local start_size = start_chunks_half_size * 64
local value = b.euclidean_value
local quadrant_config = {
['iron-ore'] = {
['tiles'] = {
[1] = 'grass-1',
[2] = 'grass-2',
[3] = 'grass-3',
[4] = 'grass-4'
},
['ratios'] = {
{resource = b.resource(b.full_shape, 'iron-ore', value(0, 0.5)), weight = 60},
{resource = b.resource(b.full_shape, 'copper-ore', value(0, 0.5)), weight = 20},
{resource = b.resource(b.full_shape, 'stone', value(0, 0.5)), weight = 2},
{resource = b.resource(b.full_shape, 'coal', value(0, 0.5)), weight = 20}
}
},
['copper-ore'] = {
['tiles'] = {
[1] = 'red-desert-0',
[2] = 'red-desert-1',
[3] = 'red-desert-2',
[4] = 'red-desert-3'
},
['ratios'] = {
{resource = b.resource(b.full_shape, 'iron-ore', value(0, 0.5)), weight = 20},
{resource = b.resource(b.full_shape, 'copper-ore', value(0, 0.5)), weight = 60},
{resource = b.resource(b.full_shape, 'stone', value(0, 0.5)), weight = 2},
{resource = b.resource(b.full_shape, 'coal', value(0, 0.5)), weight = 20}
}
},
['coal'] = {
['tiles'] = {
[1] = 'dirt-1',
[2] = 'dirt-2',
[3] = 'dirt-3',
[4] = 'dirt-4',
[5] = 'dirt-5',
[6] = 'dirt-6',
[7] = 'dirt-7'
},
['ratios'] = {
{resource = b.resource(b.full_shape, 'iron-ore', value(0, 0.5)), weight = 20},
{resource = b.resource(b.full_shape, 'copper-ore', value(0, 0.5)), weight = 20},
{resource = b.resource(b.full_shape, 'stone', value(0, 0.5)), weight = 2},
{resource = b.resource(b.full_shape, 'coal', value(0, 0.5)), weight = 40}
}
},
['stone'] = {
['tiles'] = {
[1] = 'sand-1',
[2] = 'sand-2',
[3] = 'sand-3'
},
['ratios'] = {
{resource = b.resource(b.full_shape, 'iron-ore', value(0, 0.5)), weight = 20},
{resource = b.resource(b.full_shape, 'copper-ore', value(0, 0.5)), weight = 20},
{resource = b.resource(b.full_shape, 'stone', value(0, 0.5)), weight = 30},
{resource = b.resource(b.full_shape, 'coal', value(0, 0.5)), weight = 20}
}
}
}
local tile_quadrants = {
[1] = 'stone',
[2] = 'iron-ore',
[3] = 'copper-ore',
[4] = 'coal'
}
local tiles_pos_x_pos_y
local tiles_pos_x_pos_y_count
local tiles_pos_x_neg_y
local tiles_pos_x_neg_y_count
local tiles_neg_x_pos_y
local tiles_neg_x_pos_y_count
local tiles_neg_x_neg_y
local tiles_neg_x_neg_y_count
local ores_pos_x_pos_y
local ores_pos_x_neg_y
local ores_neg_x_pos_y
local ores_neg_x_neg_y
local weighted_ores_pos_x_pos_y
local weighted_ores_pos_x_neg_y
local weighted_ores_neg_x_pos_y
local weighted_ores_neg_x_neg_y
local total_ores_pos_x_pos_y
local total_ores_pos_x_neg_y
local total_ores_neg_x_pos_y
local total_ores_neg_x_neg_y
local ore_circle = b.circle(68)
local start_ores
local start_segment
Global.register_init(
{chunk_list = chunk_list},
function(tbl)
local s = RS.get_surface()
tbl.seed = s.map_gen_settings.seed
tbl.surface = s
game.difficulty_settings.technology_price_multiplier = 20
game.forces.player.technologies.logistics.researched = true
game.forces.player.technologies.automation.researched = true
game.forces.player.technologies['mining-productivity-1'].enabled = false
game.forces.player.technologies['mining-productivity-2'].enabled = false
game.forces.player.technologies['mining-productivity-3'].enabled = false
game.forces.player.technologies['mining-productivity-4'].enabled = false
game.map_settings.enemy_evolution.time_factor = 0.000007
game.map_settings.enemy_evolution.destroy_factor = 0.000010
game.map_settings.enemy_evolution.pollution_factor = 0.000000 -- Pollution has no affect on evolution
game.draw_resource_selection = false
tbl.random = game.create_random_generator(tbl.seed)
end,
function(tbl)
local seed = tbl.seed
oil_seed = seed
uranium_seed = seed * 2
density_seed = seed * 3
enemy_seed = seed * 4
water_seed = seed * 5
tree_seed = seed * 6
chunk_list = tbl.chunk_list
surface = tbl.surface
local random = tbl.random
random.re_seed(seed)
table.shuffle_table(tile_quadrants, random)
tiles_pos_x_pos_y = quadrant_config[tile_quadrants[1]]['tiles']
tiles_pos_x_pos_y_count = #quadrant_config[tile_quadrants[1]]['tiles']
tiles_pos_x_neg_y = quadrant_config[tile_quadrants[2]]['tiles']
tiles_pos_x_neg_y_count = #quadrant_config[tile_quadrants[2]]['tiles']
tiles_neg_x_pos_y = quadrant_config[tile_quadrants[3]]['tiles']
tiles_neg_x_pos_y_count = #quadrant_config[tile_quadrants[3]]['tiles']
tiles_neg_x_neg_y = quadrant_config[tile_quadrants[4]]['tiles']
tiles_neg_x_neg_y_count = #quadrant_config[tile_quadrants[4]]['tiles']
ores_pos_x_pos_y = quadrant_config[tile_quadrants[1]]['ratios']
ores_pos_x_neg_y = quadrant_config[tile_quadrants[2]]['ratios']
ores_neg_x_pos_y = quadrant_config[tile_quadrants[3]]['ratios']
ores_neg_x_neg_y = quadrant_config[tile_quadrants[4]]['ratios']
weighted_ores_pos_x_pos_y = b.prepare_weighted_array(ores_pos_x_pos_y)
weighted_ores_pos_x_neg_y = b.prepare_weighted_array(ores_pos_x_neg_y)
weighted_ores_neg_x_pos_y = b.prepare_weighted_array(ores_neg_x_pos_y)
weighted_ores_neg_x_neg_y = b.prepare_weighted_array(ores_neg_x_neg_y)
total_ores_pos_x_pos_y = weighted_ores_pos_x_pos_y.total
total_ores_pos_x_neg_y = weighted_ores_pos_x_neg_y.total
total_ores_neg_x_pos_y = weighted_ores_neg_x_pos_y.total
total_ores_neg_x_neg_y = weighted_ores_neg_x_neg_y.total
start_ores = {
b.resource(ore_circle, tile_quadrants[2], value(125, 0)),
b.resource(ore_circle, tile_quadrants[4], value(125, 0)),
b.resource(ore_circle, tile_quadrants[3], value(125, 0)),
b.resource(ore_circle, tile_quadrants[1], value(125, 0))
}
start_segment = b.segment_pattern(start_ores)
end
)
local oil_shape = b.throttle_world_xy(b.full_shape, 1, 7, 1, 7)
local oil_resource = b.resource(oil_shape, 'crude-oil', value(250000, 150))
local uranium_resource = b.resource(b.full_shape, 'uranium-ore', value(200, 1))
local spawn_zone = b.circle(64)
local function ore(x, y, world)
if spawn_zone(x, y) then
return
end
local start_ore = start_segment(x, y, world)
if start_ore then
return start_ore
end
local oil_x, oil_y = x * oil_scale, y * oil_scale
local oil_noise = perlin_noise(oil_x, oil_y, oil_seed)
if oil_noise > oil_threshold then
return oil_resource(x, y, world)
end
local uranium_x, uranium_y = x * uranium_scale, y * uranium_scale
local uranium_noise = perlin_noise(uranium_x, uranium_y, uranium_seed)
if uranium_noise > uranium_threshold then
return uranium_resource(x, y, world)
end
local i
local index
local resource
if x > 0 and y > 0 then
i = math.random() * total_ores_pos_x_pos_y
index = table.binary_search(weighted_ores_pos_x_pos_y, i)
if (index < 0) then
index = bit32.bnot(index)
end
resource = ores_pos_x_pos_y[index].resource
elseif x > 0 and y < 0 then
i = math.random() * total_ores_pos_x_neg_y
index = table.binary_search(weighted_ores_pos_x_neg_y, i)
if (index < 0) then
index = bit32.bnot(index)
end
resource = ores_pos_x_neg_y[index].resource
elseif x < 0 and y > 0 then
i = math.random() * total_ores_neg_x_pos_y
index = table.binary_search(weighted_ores_neg_x_pos_y, i)
if (index < 0) then
index = bit32.bnot(index)
end
resource = ores_neg_x_pos_y[index].resource
else
i = math.random() * total_ores_neg_x_neg_y
index = table.binary_search(weighted_ores_neg_x_neg_y, i)
if (index < 0) then
index = bit32.bnot(index)
end
resource = ores_neg_x_neg_y[index].resource
end
local entity = resource(x, y, world)
local density_x, density_y = x * density_scale, y * density_scale
local density_noise = perlin_noise(density_x, density_y, density_seed)
if density_noise > density_threshold then
entity.amount = entity.amount * density_multiplier
end
entity.enable_tree_removal = false
return entity
end
local worm_names = {'small-worm-turret', 'medium-worm-turret', 'big-worm-turret', 'behemoth-worm-turret'}
local spawner_names = {'biter-spawner', 'spitter-spawner'}
local factor = 10 / (768 * 32)
local max_chance = 1 / 6
local scale_factor = 32
local sf = 1 / scale_factor
local m = 1 / 850
global.win_condition_evolution_rocket_maxed = -1
global.win_condition_biters_disabled = false
local function enemy(x, y, world)
if global.win_condition_biters_disabled == true then
return nil
end
local d = math.sqrt(world.x * world.x + world.y * world.y)
if d < 64 then
return nil
end
local threshold = 1 - d * m
threshold = math.max(threshold, 0.35)
x, y = x * sf, y * sf
if perlin_noise(x, y, enemy_seed) <= threshold then
return
end
if math.random(8) == 1 then
local lvl
if d < 400 then
lvl = 1
elseif d < 650 then
lvl = 2
elseif d < 900 then
lvl = 3
else
lvl = 4
end
local chance = math.min(max_chance, d * factor)
if math.random() < chance then
local worm_id
if d > 1000 then
local power = 1000 / d
worm_id = math.ceil((math.random() ^ power) * lvl)
else
worm_id = math.random(lvl)
end
return {name = worm_names[worm_id]}
end
else
local chance = math.min(max_chance, d * factor)
if math.random() < chance then
local spawner_id = math.random(2)
return {name = spawner_names[spawner_id]}
end
end
end
local function water_shape(x, y)
local water_noise = perlin_noise(x * water_scale, y * water_scale, water_seed)
if water_noise >= deepwater_threshold then
return 'deepwater'
elseif water_noise >= water_threshold then
return 'water'
else
-- Control the tiles at X quadrant
if x > 31 and y > 31 then
-- southeast
return tiles_pos_x_pos_y[math.ceil(math.random(tiles_pos_x_pos_y_count))]
elseif x > 0 and y < 31 and y > 0 then
-- southeast to northeast
if math.random(100) < 50 + y * 2 then
return tiles_pos_x_pos_y[math.ceil(math.random(tiles_pos_x_pos_y_count))]
else
return tiles_pos_x_neg_y[math.ceil(math.random(tiles_pos_x_neg_y_count))]
end
elseif x > 0 and y >= 0 then
-- southeast to southwest
if math.random(100) < 50 + x * 2 then
return tiles_pos_x_pos_y[math.ceil(math.random(tiles_pos_x_pos_y_count))]
else
return tiles_neg_x_pos_y[math.ceil(math.random(tiles_neg_x_pos_y_count))]
end
elseif x > 31 and y < -31 then
-- northeast
return tiles_pos_x_neg_y[math.ceil(math.random(tiles_pos_x_neg_y_count))]
elseif x > 0 and x < 31 and y <= 0 then
-- northeast to northwest
if math.random(100) < 50 + x * 2 then
return tiles_pos_x_neg_y[math.ceil(math.random(tiles_pos_x_neg_y_count))]
else
return tiles_neg_x_neg_y[math.ceil(math.random(tiles_neg_x_neg_y_count))]
end
elseif x > 0 and y < 0 then
-- northeast to southeast
if math.random(100) < 50 - y * 2 then
return tiles_pos_x_neg_y[math.ceil(math.random(tiles_pos_x_neg_y_count))]
else
return tiles_pos_x_pos_y[math.ceil(math.random(tiles_pos_x_pos_y_count))]
end
elseif x < -31 and y < -31 then
-- northwest
return tiles_neg_x_neg_y[math.ceil(math.random(tiles_neg_x_neg_y_count))]
elseif x > -31 and x < 0 and y <= 0 then
-- northwest to northeast
if math.random(100) < 50 - x * 2 then
return tiles_neg_x_neg_y[math.ceil(math.random(tiles_neg_x_neg_y_count))]
else
return tiles_pos_x_neg_y[math.ceil(math.random(tiles_pos_x_neg_y_count))]
end
elseif x < 0 and y > -31 and y < 0 then
-- northwest to southwest
if math.random(100) < (50 - y * 2) then
return tiles_neg_x_neg_y[math.ceil(math.random(tiles_neg_x_neg_y_count))]
else
return tiles_neg_x_pos_y[math.ceil(math.random(tiles_neg_x_pos_y_count))]
end
elseif x < -31 and y > 31 then
-- southwest
return tiles_neg_x_pos_y[math.ceil(math.random(tiles_neg_x_pos_y_count))]
elseif x < 0 and y > 0 and y < 32 then
-- southwest to northwest
if math.random(100) < (50 + y * 2) then
return tiles_neg_x_pos_y[math.ceil(math.random(tiles_neg_x_pos_y_count))]
else
return tiles_neg_x_neg_y[math.ceil(math.random(tiles_neg_x_neg_y_count))]
end
elseif x < 0 and y > 0 then
-- southwest to southeast
if math.random(100) < 50 - x * 2 then
return tiles_neg_x_pos_y[math.ceil(math.random(tiles_neg_x_pos_y_count))]
else
return tiles_pos_x_pos_y[math.ceil(math.random(tiles_pos_x_pos_y_count))]
end
end
end
end
local trees = {
'tree-01',
'tree-02',
'tree-02-red',
'tree-03',
'tree-04',
'tree-05',
'tree-06',
'tree-06-brown',
'tree-07',
'tree-08',
'tree-08-brown',
'tree-08-red',
'tree-09',
'tree-09-brown',
'tree-09-red'
}
local trees_count = #trees
local function tree_shape(x, y)
local tree_noise = perlin_noise(x * tree_scale, y * tree_scale, tree_seed)
if tree_noise > tree_threshold or math.random() > tree_chance then
return nil
end
return {name = trees[math.random(trees_count)]}
end
local water = b.circle(16)
water = b.change_tile(water, true, 'water')
water = b.any {b.rectangle(32, 4), b.rectangle(4, 32), water}
local start = b.if_else(water, b.full_shape)
start = b.change_map_gen_collision_tile(start, 'water-tile', 'grass-1')
local map = b.choose(ore_circle, start, water_shape)
map = b.apply_entity(map, ore)
map = b.apply_entity(map, enemy)
map = b.apply_entity(map, tree_shape)
map = b.fish(map, 0.025)
local bounds = b.rectangle(start_size, start_size)
local function rocket_launched(event)
local entity = event.rocket
if not entity or not entity.valid or not entity.force == 'player' then
return
end
local inventory = entity.get_inventory(defines.inventory.rocket)
if not inventory or not inventory.valid then
return
end
local satellite_count = game.forces.player.get_item_launched('satellite')
if satellite_count == 0 then
return
end
-- Increase enemy_evolution
local current_evolution = game.forces.enemy.evolution_factor
local message
if global.win_condition_biters_disabled == false then
if (satellite_count % 5) == 0 and global.win_condition_evolution_rocket_maxed == -1 then
message =
'Continued launching of satellites has angered the local biter population, evolution increasing...'
game.print(message)
current_evolution = current_evolution + 0.05
end
if current_evolution >= 1 and global.win_condition_evolution_rocket_maxed == -1 then
current_evolution = 1
global.win_condition_evolution_rocket_maxed = satellite_count
message =
'Biters at maximum evolution! Protect the base for an additional 100 rockets to wipe them out forever.'
game.print(message)
end
game.forces.enemy.evolution_factor = current_evolution
if global.win_condition_evolution_rocket_maxed > 0 and satellite_count >= (global.win_condition_evolution_rocket_maxed + 100) then
message = 'Congratulations! Biters have been wiped from the map!'
game.print(message)
global.win_condition_biters_disabled = true
for key, enemy_entity in pairs(surface.find_entities_filtered({force = 'enemy'})) do
enemy_entity.destroy()
end
end
end
end
local function on_chunk(event)
if surface ~= event.surface then
return
end
local left_top = event.area.left_top
local x, y = left_top.x, left_top.y
if bounds(x + 0.5, y + 0.5) then
Generate.do_chunk(event)
else
local tiles = {}
for x1 = x, x + 31 do
for y1 = y, y + 31 do
tiles[#tiles + 1] = {name = 'out-of-map', position = {x1, y1}}
end
end
surface.set_tiles(tiles, true)
chunk_list[#chunk_list + 1] = left_top
end
end
local function on_tick()
local index = chunk_list.index
if index > #chunk_list then
chunk_list.index = 1
return
end
local pos = chunk_list[index]
local pollution = surface.get_pollution(pos)
local current_min_pollution = global.min_pollution
if pollution > current_min_pollution then
fast_remove(chunk_list, index)
local area = {left_top = pos, right_bottom = {pos.x + 32, pos.y + 32}}
local event = {surface = surface, area = area}
Generate.schedule_chunk(event)
if current_min_pollution < max_pollution then
global.min_pollution = current_min_pollution + pollution_increment
end
return
end
chunk_list.index = index + 1
end
Event.add(defines.events.on_chunk_generated, on_chunk)
Event.add(defines.events.on_rocket_launched, rocket_launched)
Event.on_nth_tick(1, on_tick)
return map
return require 'map_gen.maps.danger_ores.presets.terraforming_danger_ore'

View File

@ -3,6 +3,7 @@ local Token = require 'utils.token'
local Event = require 'utils.event'
local insert = table.insert
local raise_event = script.raise_event
local tiles_per_tick
local regen_decoratives
@ -15,6 +16,12 @@ local Public = {}
-- Set to false by modules that want to control the on_chunk_generated event themselves.
Public.enable_register_events = true
local on_chunk_generated = Event.generate_event_name('generate_on_chunk_generated')
Public.events = {
on_chunk_generated = on_chunk_generated
}
local function do_tile_inner(tiles, tile, pos)
if not tile then
insert(tiles, {name = 'out-of-map', position = pos})
@ -210,6 +217,7 @@ local function map_gen_action(data)
return true
elseif state == 36 then
run_chart_update(data)
raise_event(on_chunk_generated, data)
return false
end
end
@ -234,6 +242,7 @@ function Public.schedule_chunk(event)
area = area,
top_x = area.left_top.x,
top_y = area.left_top.y,
position = event.position,
surface = surface,
tiles = {},
hidden_tiles = {},
@ -260,6 +269,7 @@ function Public.do_chunk(event)
area = area,
top_x = area.left_top.x,
top_y = area.left_top.y,
position = event.position,
surface = surface,
tiles = {},
hidden_tiles = {},
@ -275,6 +285,8 @@ function Public.do_chunk(event)
do_place_hidden_tiles(data)
do_place_entities(data)
do_place_decoratives(data)
raise_event(on_chunk_generated, data)
end
--- Sets the variables for the generate functions, should only be called from map_loader