2019-02-08 04:05:30 +02:00
local b = require ' map_gen.shared.builders '
local Perlin = require ' map_gen.shared.perlin_noise '
local Global = require ' utils.global '
local Event = require ' utils.event '
local math = require ' utils.math '
local table = require ' utils.table '
local Task = require ' utils.task '
local Token = require ' utils.token '
local Utils = require ' utils.core '
local RS = require ' map_gen.shared.redmew_surface '
local DayNight = require ' map_gen.shared.day_night '
local ScenarioInfo = require ' features.gui.info '
local Toast = require ' features.gui.toast '
local Retailer = require ' features.retailer '
local MGSP = require ' resources.map_gen_settings '
local market_items = require ' resources.market_items '
local noise = Perlin.noise
local remove = table.remove
local insert = table.insert
local format = string.format
local config = global.config
2019-02-16 20:58:27 +02:00
local tech_cost = 1000
2019-02-08 04:05:30 +02:00
-- Startup bonus
local toast_duration = 15 -- secs
2019-02-16 20:58:27 +02:00
local startup_bonus = 50 -- mining multiplier
local timeout_duration = ( 20 * 60 ) / ( 1000 / tech_cost ) -- at 1000x tech cost these are 20 min timeouts meaning the bonuses are gone at 2hr
local evo_multiplier = ( 1 / tech_cost ) * 25
2019-02-08 04:05:30 +02:00
-- Multipliers added as the last number to make it easier to read/understand the deviation from norms
local map_settings = {
pollution = {
2019-02-16 20:58:27 +02:00
enabled = false
2019-02-08 04:05:30 +02:00
} ,
enemy_evolution = {
enabled = true ,
2019-02-16 20:58:27 +02:00
time_factor = ( 0.000004 * evo_multiplier ) ,
destroy_factor = ( 0.002 * evo_multiplier ) ,
pollution_factor = ( 0.000015 * evo_multiplier )
2019-02-08 04:05:30 +02:00
} ,
enemy_expansion = {
2019-02-16 20:58:27 +02:00
enabled = false
2019-02-08 04:05:30 +02:00
}
}
-- Setup
-- Enable infinite storage chest
config.infinite_storage_chest . enabled = true
config.infinite_storage_chest . cost = 35
-- Enable hydra
config.hail_hydra . enabled = true
config.hail_hydra . hydras = {
-- spitters
[ ' small-spitter ' ] = { [ ' small-spitter ' ] = 0.1 } ,
[ ' medium-spitter ' ] = { [ ' small-spitter ' ] = 0.2 , [ ' medium-spitter ' ] = 0.1 } ,
[ ' big-spitter ' ] = { [ ' small-spitter ' ] = 0.3 , [ ' medium-spitter ' ] = 0.2 , [ ' big-spitter ' ] = 0.1 } ,
[ ' behemoth-spitter ' ] = { [ ' small-spitter ' ] = 0.4 , [ ' medium-spitter ' ] = 0.3 , [ ' big-spitter ' ] = 0.2 , [ ' behemoth-spitter ' ] = 0.1 } ,
-- biters
[ ' small-biter ' ] = { [ ' small-biter ' ] = 0.2 } ,
[ ' medium-biter ' ] = { [ ' small-biter ' ] = 0.4 , [ ' medium-biter ' ] = 0.2 } ,
[ ' big-biter ' ] = { [ ' small-biter ' ] = 0.6 , [ ' medium-biter ' ] = 0.4 , [ ' big-biter ' ] = 0.4 } ,
[ ' behemoth-biter ' ] = { [ ' small-biter ' ] = 0.8 , [ ' medium-biter ' ] = 0.6 , [ ' big-biter ' ] = 0.4 , [ ' behemoth-biter ' ] = 0.2 } ,
-- worms
[ ' small-worm-turret ' ] = { [ ' small-biter ' ] = 2.5 , [ ' medium-biter ' ] = 0.05 } ,
[ ' medium-worm-turret ' ] = { [ ' small-biter ' ] = 5 , [ ' medium-biter ' ] = 2.5 , [ ' big-biter ' ] = 0.05 } ,
[ ' big-worm-turret ' ] = { [ ' small-biter ' ] = 10 , [ ' medium-biter ' ] = 5 , [ ' big-biter ' ] = 2.5 , [ ' behemoth-biter ' ] = 0.05 }
}
-- Scenario info
2019-02-16 20:58:27 +02:00
local map_extra_info = [ [
- There are infinite ores in every direction .
- You have done basic research into how to build a factory .
- The market does not offer what it normally does .
- The biters are plentiful , but seem slow to evolve .
2019-02-08 04:05:30 +02:00
- The sun ' s position seems unchanging.
] ]
ScenarioInfo.set_map_name ( ' The 1000 Yard Stare ' )
ScenarioInfo.set_map_description ( ' Resources are not an issue as you march your way through the tech tree. ' )
ScenarioInfo.add_map_extra_info ( map_extra_info .. ' - Your miners and your hands will work extra hard when you first arrive \n But they will tire over time. ' )
-- Redmew surface
RS.set_first_player_position_check_override ( true )
RS.set_spawn_island_tile ( ' sand-1 ' )
RS.set_map_gen_settings (
{
MGSP.ore_oil_none ,
MGSP.cliff_none ,
MGSP.starting_area_very_low ,
MGSP.enemy_very_high ,
MGSP.sand_only
}
)
2019-02-16 21:03:58 +02:00
RS.set_difficulty_settings ( { { technology_price_multiplier = tech_cost } } )
2019-02-08 04:05:30 +02:00
RS.set_map_settings ( { map_settings } )
-- Setup market inventory
2019-02-18 08:17:14 +02:00
config.market . create_standard_market = false
2019-02-08 04:05:30 +02:00
if config.market . enabled then
local items_to_add = {
{ name = ' modular-armor ' , stack_limit = 1 , player_limit = 1 , price = 50 } ,
{ name = ' power-armor ' , stack_limit = 1 , player_limit = 1 , price = 2000 } ,
{ name = ' fusion-reactor-equipment ' , stack_limit = 1 , player_limit = 1 , price = 300 } ,
{ name = ' energy-shield-equipment ' , stack_limit = 1 , player_limit = 1 , price = 350 } ,
{ name = ' defender-capsule ' , stack_limit = 25 , player_limit = 25 , price = 1 } ,
{ name = ' distractor-capsule ' , stack_limit = 50 , player_limit = 50 , price = 10 } ,
{ name = ' destroyer-capsule ' , price = 50 }
}
local items_to_drop = {
' tank-cannon ' ,
' tank-machine-gun ' ,
' artillery-wagon-cannon ' ,
' artillery-turret ' ,
' artillery-targeting-remote ' ,
' defender-capsule ' ,
' destroyer-capsule ' ,
' programmable-speaker ' ,
' personal-laser-defense-equipment '
}
-- Remove items_to_drop from marker
for i = # market_items , 1 , - 1 do
local name = market_items [ i ] . name
if table.array_contains ( items_to_drop , name ) then
remove ( market_items , i )
end
end
-- Add items_to_add to market
for i = 1 , # items_to_add do
insert ( market_items , items_to_add [ i ] )
end
end
--- A timeout loop that decreases the mining bonus until < 1 then eliminates it and enables the productivity research
local timeout_token
local function decrease_boost ( )
local force = game.forces . player
force.mining_drill_productivity_bonus = force.mining_drill_productivity_bonus / 2
force.manual_mining_speed_modifier = force.manual_mining_speed_modifier / 2
force.manual_crafting_speed_modifier = force.manual_crafting_speed_modifier / 2
if force.mining_drill_productivity_bonus < 1 then
force.mining_drill_productivity_bonus = 0
force.manual_mining_speed_modifier = 0
force.manual_crafting_speed_modifier = 0
force.technologies [ ' mining-productivity-1 ' ] . enabled = true
Toast.toast_all_players ( toast_duration , ' Your hands and all miners seem to have returned to their normal speeds. ' )
Utils.print_admins ( ' The mining and crafting bonuses are finished. Mining productivity research has been unlocked (lol). ' , nil )
ScenarioInfo.set_map_extra_info ( map_extra_info )
return
end
Toast.toast_all_players ( toast_duration , ' Your hands and the miners seem to be slowing. ' )
Utils.print_admins ( format ( ' The mining bonuses are now only %sx, crafting bonus is %sx ' , force.mining_drill_productivity_bonus , force.manual_crafting_speed_modifier ) , nil )
Task.set_timeout ( timeout_duration , timeout_token , nil )
end
timeout_token = Token.register ( decrease_boost )
-- Initial techs, setting day_night cycle, placing market
Event.on_init (
function ( )
local force = game.forces . player
local surface = RS.get_surface ( )
local pos = { 0 , - 15 }
-- Techs
force.technologies [ ' automation ' ] . researched = true
force.technologies [ ' turrets ' ] . researched = true
force.technologies [ ' military ' ] . researched = true
2019-02-10 21:35:18 +02:00
force.technologies [ ' logistics ' ] . researched = true
2019-02-12 23:47:09 +02:00
if config.redmew_qol . enabled and config.redmew_qol . loaders then
2019-02-10 21:35:18 +02:00
force.recipes [ ' loader ' ] . enabled = true
end
2019-02-08 04:05:30 +02:00
-- DayNight call
DayNight.set_fixed_brightness ( 1 , RS.get_surface ( ) )
if config.market . enabled then
config.market . create_standard_market = false
-- Market creation
local market = surface.create_entity ( { name = ' market ' , position = pos } )
market.destructible = false
Retailer.add_market ( ' items ' , market )
if table.size ( Retailer.get_items ( ' items ' ) ) == 0 then
for _ , prototype in pairs ( market_items ) do
Retailer.set_item ( ' items ' , prototype )
end
end
force.add_chart_tag ( surface , { icon = { type = ' item ' , name = config.market . currency } , position = pos , text = ' Market ' } )
end
-- Startup bonus
force.technologies [ ' mining-productivity-1 ' ] . enabled = false
force.mining_drill_productivity_bonus = startup_bonus
force.manual_mining_speed_modifier = startup_bonus
force.manual_crafting_speed_modifier = startup_bonus / 10
Task.set_timeout ( timeout_duration , timeout_token , nil )
end
)
-- Map
-- Constants
local value = 4294967294
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
-- Local Globals
local oil_seed
local uranium_seed
local density_seed
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
end
)
-- Functions
local function constant ( amount )
return function ( )
return amount
end
end
local oil_shape = b.throttle_world_xy ( b.full_shape , 1 , 8 , 1 , 8 )
local oil_resource = b.resource ( oil_shape , ' crude-oil ' , constant ( value ) )
local uranium_resource = b.resource ( b.full_shape , ' uranium-ore ' , constant ( value ) )
local ores = {
{ resource = b.resource ( b.full_shape , ' iron-ore ' , constant ( value ) ) , weight = 6 } ,
{ resource = b.resource ( b.full_shape , ' copper-ore ' , constant ( value ) ) , weight = 4 } ,
{ resource = b.resource ( b.full_shape , ' stone ' , constant ( value ) ) , weight = 1 } ,
{ resource = b.resource ( b.full_shape , ' coal ' , constant ( value ) ) , weight = 2 }
}
local weighted_ores = b.prepare_weighted_array ( ores )
local total_ores = weighted_ores.total
local ore_circle = b.circle ( 12 )
local start_ores = {
b.resource ( ore_circle , ' iron-ore ' , constant ( value ) ) ,
b.resource ( ore_circle , ' copper-ore ' , constant ( value ) ) ,
b.resource ( ore_circle , ' coal ' , constant ( value ) ) ,
b.resource ( ore_circle , ' stone ' , constant ( value ) )
}
local bigger_circle = b.circle ( 100 ) -- To exclude water from the start area.
ore_circle =
b.any {
ore_circle ,
bigger_circle
}
local start_segment = b.segment_pattern ( start_ores )
local function ore ( x , y , world )
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 = 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 = 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 = 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 '
}
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
else
max_lvl = 3
min_lvl = 2
end
local lvl = math.random ( ) ^ ( 768 / d ) * max_lvl
lvl = math.ceil ( lvl )
lvl = math.clamp ( lvl , min_lvl , 3 )
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