1
0
mirror of https://github.com/Refactorio/RedMew.git synced 2024-12-14 10:13:13 +02:00
RedMew/map_gen/maps/1000x.lua
2020-11-24 16:39:22 +00:00

389 lines
13 KiB
Lua

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
local decs_amount = 255 -- Change to make decoratives more "opaque" (Min 0, Max 255)
local tech_cost = 1000
-- Startup bonus
local toast_duration = 15 -- secs
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
-- Multipliers added as the last number to make it easier to read/understand the deviation from norms
local map_settings = {
pollution = {
enabled = false
},
enemy_evolution = {
enabled = true,
time_factor = (0.000004 * evo_multiplier),
destroy_factor = (0.002 * evo_multiplier),
pollution_factor = (0.000015 * evo_multiplier)
},
enemy_expansion = {
enabled = false
}
}
-- 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
--Special thanks to the following beta testers for their help with the map and map info: T-A-R
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.
- 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\nBut 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
}
)
RS.set_difficulty_settings({{technology_price_multiplier = tech_cost}})
RS.set_map_settings({map_settings})
-- Setup market inventory
config.market.create_standard_market = false
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}
-- Removes ore count from map view
game.draw_resource_selection = false
-- Techs
force.technologies['automation'].researched = true
force.technologies['gun-turret'].researched = true
force.technologies['military'].researched = true
force.technologies['logistics'].researched = true
if config.redmew_qol.enabled and config.redmew_qol.loaders then
force.recipes['loader'].enabled = true
end
-- 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)
local function decs()
if math.random(1, 99) >= 50 then
return {name = 'green-carpet-grass', amount = decs_amount}
else
return {name = 'brown-carpet-grass', amount = decs_amount}
end
end
decs = b.throttle_world_xy(decs, 1, 2, 1, 2)
map = b.apply_decorative(map, decs)
return map