1
0
mirror of https://github.com/Refactorio/RedMew.git synced 2024-12-16 10:19:27 +02:00
RedMew/map_gen/maps/crash_site/features/sandworms.lua
2021-01-28 09:19:36 +00:00

132 lines
5.5 KiB
Lua

-- This module starts spawning worms every 5 to 10 minutes (approx) when a roboport is placed.
-- Makes it necessary to defend roboports and limits the usefulness of large roboport networks
local Event = require 'utils.event'
local Global = require 'utils.global'
local Task = require 'utils.task'
local Token = require 'utils.token'
local set_timeout_in_ticks = Task.set_timeout_in_ticks
local min_worm_period_secs = 300 -- 5 minutes
local max_worm_period_secs = 900 -- 15 minutes
local max_worm_spawn_radius = 30
local roboports = {}
Global.register({roboports = roboports}, function(tbl)
roboports = tbl.roboports
end)
local sandworms = {
['small-worm-turret'] = {evo_min = 0, evo_max = 0.4},
['medium-worm-turret'] = {evo_min = 0.4, evo_max = 0.6},
['big-worm-turret'] = {evo_min = 0.6, evo_max = 0.9},
['behemoth-worm-turret'] = {evo_min = 0.9, evo_max = 1}
}
local sandworm_biters = {
['small-worm-turret'] = {['small-biter'] = {min = 2.5, max = 3.5}, ['medium-biter'] = {min = 1.0, max = 2}},
['medium-worm-turret'] = {['small-biter'] = {min = 2.5, max = 6.5}, ['medium-biter'] = {min = 1.0, max = 5}},
['big-worm-turret'] = {
['small-biter'] = {min = 2.5, max = 4},
['medium-biter'] = {min = 1.5, max = 2.2},
['medium-spitter'] = {min = 1.5, max = 2.2},
['big-biter'] = {min = 1.5, max = 2.2}
},
['behemoth-worm-turret'] = {
['small-biter'] = {min = 4, max = 5.2},
['medium-biter'] = {min = 2.5, max = 3.8},
['big-biter'] = {min = 1.2, max = 2.4},
['big-spitter'] = {min = 1.2, max = 2.4},
['behemoth-biter'] = {min = 1.2, max = 2.4}
}
}
local function spawn_sandworms(entity)
local evolution = game.forces["enemy"].evolution_factor
for index, worm_type in pairs(sandworms) do
-- Determine which worm type to spawn based on the evolution
if (evolution > worm_type.evo_min) and (evolution <= worm_type.evo_max) then
local s = entity.surface
local worm_position = {
entity.position.x + math.random(max_worm_spawn_radius * -1, max_worm_spawn_radius),
entity.position.y + math.random(max_worm_spawn_radius * -1, max_worm_spawn_radius)
}
local free_worm_position = s.find_non_colliding_position(index, worm_position, 20, 1)
if not free_worm_position then
return
end
s.create_entity {name = index, position = free_worm_position, force = "enemy"}
-- For the appropriate worm for each evolution region, spawn some accompanying biters to attack the roboport
for worm, biters in pairs(sandworm_biters) do
if worm == index then
for biter, data in pairs(biters) do
local amount = math.random(data.min, data.max)
local extra_chance = amount % 1
if extra_chance > 0 then
if math.random(0,1) <= extra_chance then
amount = math.ceil(amount)
else
amount = math.floor(amount)
end
end
for _ = 1, amount do
local pos = s.find_non_colliding_position(biter, free_worm_position, 20, 1)
if pos then
local spawned_biter = s.create_entity {name = biter, position = pos, force = "enemy"}
spawned_biter.set_command({type = defines.command.attack, target = entity})
end
end
end
end
end
end
end
end
local thump_text_callback
thump_text_callback = Token.register(function(entity)
if not entity.valid then
return
end
local s = entity.surface
local entity_position = entity.position
s.create_entity{name="flying-text", position={(entity_position.x + math.random(-3,3)),(entity_position.y + math.random(0,3))}, text="*thump*", color={r=0.6,g=0.4,b=0}}
end)
local worm_callback
worm_callback = Token.register(function(entity)
if entity.valid then -- stops the callback if the roboport has been removed
spawn_sandworms(entity)
local callback_timer = math.random(min_worm_period_secs * 60, max_worm_period_secs * 60)
set_timeout_in_ticks(callback_timer, worm_callback, entity)
for i = 1, 5 do -- repeat thump text 30 seconds before worm will arrive to give players visual reminder they need to protect roboports
set_timeout_in_ticks(callback_timer-1800+(120*i), thump_text_callback, entity)
end
end
end)
local function start_worm_attacks(entity)
if not entity.valid then
return
end
local callback_timer = math.random(min_worm_period_secs * 60, max_worm_period_secs * 60)
set_timeout_in_ticks(callback_timer, worm_callback, entity)
for i = 1, 5 do
set_timeout_in_ticks(120*i, thump_text_callback, entity)
end
end
Event.add(defines.events.on_robot_built_entity, function(event)
if event.created_entity.valid and event.created_entity.name == 'roboport' then
start_worm_attacks(event.created_entity)
end
end)
Event.add(defines.events.on_built_entity, function(event)
if event.created_entity.valid and event.created_entity.name == 'roboport' then
start_worm_attacks(event.created_entity)
local player = game.get_player(event.player_index)
player.print("A sandworm approaches.....")
end
end)