mirror of
https://github.com/Refactorio/RedMew.git
synced 2024-12-12 10:04:40 +02:00
213 lines
7.6 KiB
Lua
213 lines
7.6 KiB
Lua
-- Map by Jayefuu and grilled ham, concept by claude47, 2018-12-02
|
|
|
|
-- SETUP INSTRUCTIONS:
|
|
-- This map preset will remove biters everywhere except near the ores.
|
|
|
|
-- Add market with /market
|
|
-- Hover over the market and run:
|
|
-- /silent-command game.player.selected.add_market_item{price={{MARKET_ITEM, 100}}, offer={type="give-item", item="landfill"}}
|
|
|
|
|
|
local b = require 'map_gen.shared.builders'
|
|
local math = require "utils.math"
|
|
local Perlin = require 'map_gen.shared.perlin_noise'
|
|
local Event = require 'utils.event'
|
|
local degrees = math.rad
|
|
local enemy_seed = 420420
|
|
|
|
local function value(base, mult, pow)
|
|
return function(x, y)
|
|
local d_sq = x * x + y * y
|
|
return base + mult * d_sq ^ (pow / 2) -- d ^ pow
|
|
end
|
|
end
|
|
|
|
local function no_resources(_, _, world, tile)
|
|
for _, e in ipairs(
|
|
world.surface.find_entities_filtered(
|
|
{type = 'resource', area = {{world.x, world.y}, {world.x + 1, world.y + 1}}}
|
|
)
|
|
) do
|
|
e.destroy()
|
|
end
|
|
return tile
|
|
end
|
|
|
|
local names = {
|
|
'biter-spawner',
|
|
'spitter-spawner',
|
|
'small-worm-turret',
|
|
'medium-worm-turret',
|
|
'big-worm-turret'
|
|
}
|
|
|
|
-- removes spawners when called so we can place our own
|
|
local function no_spawners(_, _, world, tile)
|
|
for _, e in ipairs(
|
|
world.surface.find_entities_filtered(
|
|
{force = 'enemy', name = names, position = {world.x, world.y}}
|
|
)
|
|
) do
|
|
e.destroy()
|
|
end
|
|
return tile
|
|
end
|
|
|
|
local spiral = b.circular_spiral(80, 90)
|
|
spiral = b.any {spiral, b.translate(b.circle(128), 12, -12)}
|
|
|
|
local wide_spiral = b.circular_spiral(60, 90) -- looks prettier, for use with starting ore and water
|
|
wide_spiral = b.any {wide_spiral, b.translate(b.circle(128), 12, -12)}
|
|
|
|
-- provides a shortcut between the spirals, at the cost of expensive landfill from the market
|
|
local function water_cross(x,y)
|
|
local abs_x = math.abs(x)
|
|
local abs_y = math.abs(y)
|
|
return not (abs_x > 4 and abs_y > 4)
|
|
end
|
|
water_cross = b.change_tile(water_cross, true, 'water')
|
|
|
|
-- make a spiral starting ore patch
|
|
local start_ore_patch = b.scale(wide_spiral, 0.1)
|
|
local function constant(amount)
|
|
return function()
|
|
return amount
|
|
end
|
|
end
|
|
local iron = b.resource(start_ore_patch, 'iron-ore', constant(500))
|
|
local copper = b.resource(start_ore_patch, 'copper-ore', constant(500))
|
|
local stone = b.resource(start_ore_patch, 'stone', constant(500))
|
|
local coal = b.resource(start_ore_patch, 'coal', constant(500))
|
|
start_ore_patch = b.segment_pattern {iron, copper, stone, coal}
|
|
local start_ore_bounds = b.circle(32)
|
|
start_ore_patch = b.choose(start_ore_bounds, start_ore_patch, b.empty_shape)
|
|
start_ore_patch = b.translate(start_ore_patch, 0, 32)
|
|
|
|
-- make some starting water
|
|
local start_water = b.scale(wide_spiral, 0.1)
|
|
start_water = b.choose(b.circle(26), start_water, b.empty_shape)
|
|
start_water = b.change_tile(start_water, true, 'water')
|
|
start_water = b.translate(start_water,0,-130)
|
|
|
|
-- ore generation
|
|
local patch = b.circle(18)
|
|
local small_patch = b.circle(12)
|
|
local patches = b.single_x_pattern(patch, 90)
|
|
local patches_wide = b.single_x_pattern(patch, 180)
|
|
local patches_wide_small = b.single_x_pattern(small_patch, 180)
|
|
|
|
local iron_patches = b.resource(patches, 'iron-ore', value(500, 0.8, 1.075))
|
|
local copper_patches = b.resource(patches, 'copper-ore', value(400, 0.75, 1.1))
|
|
local coal_patches = b.resource(patches_wide, 'coal', value(650, 0.75, 1.1))
|
|
local stone_patches = b.resource(patches_wide, 'stone', value(400, 0.75, 1.1))
|
|
local oil_patches = b.resource(b.throttle_world_xy(patches_wide_small,1,6,1,6), 'crude-oil', value(33000, 50, 1.05))
|
|
local uranium_patches = b.resource(patches_wide_small, 'uranium-ore', value(200, 0.75, 1.1))
|
|
|
|
local function ore_arm_bounds(x, _)
|
|
return x < 20
|
|
end
|
|
|
|
iron_patches = b.translate(b.choose(ore_arm_bounds, iron_patches, b.empty_shape),-160,0)
|
|
copper_patches = b.translate(b.choose(ore_arm_bounds, copper_patches, b.empty_shape),-210,0)
|
|
stone_patches = b.translate(b.choose(ore_arm_bounds, stone_patches, b.empty_shape),-230,0)
|
|
uranium_patches = b.translate(b.choose(ore_arm_bounds, uranium_patches, b.empty_shape),-320,0)
|
|
coal_patches = b.translate(b.choose(ore_arm_bounds, coal_patches, b.empty_shape),-180,0)
|
|
oil_patches = b.translate(b.choose(ore_arm_bounds, oil_patches, b.empty_shape),-270,0)
|
|
|
|
spiral = b.change_tile(spiral, true, 'grass-1')
|
|
spiral = b.apply_entity(spiral, b.rotate(coal_patches,degrees(45)))
|
|
spiral = b.apply_entity(spiral, b.rotate(oil_patches,degrees(45))) -- oil and coal have double spacing so they are interleaved
|
|
spiral = b.apply_entity(spiral, b.rotate(iron_patches,degrees(45+90)))
|
|
spiral = b.apply_entity(spiral, b.rotate(stone_patches,degrees(45+180)))
|
|
spiral = b.apply_entity(spiral, b.rotate(uranium_patches,degrees(45+180))) -- stone and uranium have double spacing so they are interleaved
|
|
spiral = b.apply_entity(spiral, b.rotate(copper_patches,degrees(45+270)))
|
|
|
|
-- Re-add the spawners we removed at the beginning so we can apply a pattern (cross) to their positions, aligning them with the ores
|
|
local worm_names = {'small-worm-turret', 'medium-worm-turret', 'big-worm-turret'}
|
|
local spawner_names = {'biter-spawner', 'spitter-spawner'}
|
|
local factor = 16 / (1024 * 32)
|
|
local max_chance = 1 / 4
|
|
|
|
local scale_factor = 4
|
|
local sf = 1 / scale_factor
|
|
local m = 1 / 600
|
|
local function enemy(x, y, world)
|
|
local d = math.sqrt(world.x * world.x + world.y * world.y)
|
|
|
|
if d < 80 then
|
|
return nil
|
|
end
|
|
|
|
local threshold = 1 - d * m
|
|
threshold = math.max(threshold, 0.5) -- -0.125)
|
|
|
|
x, y = x * sf, y * sf
|
|
if Perlin.noise(x, y, enemy_seed) > threshold then
|
|
if math.random(8) <= 2 then
|
|
local lvl
|
|
if d < 300 then
|
|
lvl = 1
|
|
elseif d < 650 then
|
|
lvl = 2
|
|
else
|
|
lvl = 3
|
|
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
|
|
end
|
|
|
|
-- Maltese cross shape so the biter patches get wider the further from base
|
|
local gradient = 0.1
|
|
local tiles_half = (50) * 0.5
|
|
local function enemy_cross(x,y)
|
|
local abs_x = math.abs(x)
|
|
local abs_y = math.abs(y)
|
|
return not (abs_x > (tiles_half+(abs_y*gradient)) and abs_y > (tiles_half+(abs_x*gradient)))
|
|
end
|
|
enemy_cross = b.rotate(enemy_cross,degrees(45))
|
|
enemy = b.choose(enemy_cross,enemy,b.empty_shape)
|
|
|
|
water_cross = b.fish(water_cross, 0.01)
|
|
local map = b.any{
|
|
start_water,
|
|
spiral,
|
|
water_cross
|
|
}
|
|
map = b.apply_entity(map,start_ore_patch)
|
|
map = b.apply_effect(map, no_resources)
|
|
map = b.apply_effect(map, no_spawners) -- remove all spawners and worms
|
|
map = b.apply_entity(map, enemy) -- add the enemies we generated
|
|
|
|
local function on_init()
|
|
local player_force = game.forces.player
|
|
local enemy_force = game.forces.enemy
|
|
player_force.technologies["landfill"].enabled = false -- disable landfill
|
|
enemy_force.set_ammo_damage_modifier('melee', 1) -- +100% biter damage
|
|
enemy_force.set_ammo_damage_modifier('biological', 0.5) -- +50% spitter/worm damage
|
|
game.map_settings.enemy_expansion.enabled = false -- turn off expansion to compensave for harder biters
|
|
end
|
|
|
|
Event.on_init(on_init)
|
|
|
|
return map
|