mirror of
https://github.com/ComfyFactory/ComfyFactorio.git
synced 2024-12-30 23:17:53 +02:00
104 lines
3.4 KiB
Lua
104 lines
3.4 KiB
Lua
-- this module respawns fish in all water tiles on every surface with a player on it -- by mewmew --
|
|
-- cpu heavy -- fixed processing rate is 1 chunk per tick
|
|
|
|
local respawn_interval = 7200 --interval in ticks
|
|
global.fish_respawner_water_tiles_per_fish = 32 --amount of water tiles required per fish >> high values = less fish density, low values = high fish density
|
|
global.fish_respawner_max_respawnrate_per_chunk = 1 --maximum amount of fish that will spawn each interval in one chunk
|
|
|
|
local valid_water_tiles = {
|
|
'water',
|
|
'deepwater',
|
|
'water-green',
|
|
'deepwater-green'
|
|
}
|
|
|
|
local event = require 'utils.event'
|
|
local math_random = math.random
|
|
|
|
local function shuffle(tbl)
|
|
local size = #tbl
|
|
for i = size, 1, -1 do
|
|
local rand = math_random(size)
|
|
tbl[i], tbl[rand] = tbl[rand], tbl[i]
|
|
end
|
|
return tbl
|
|
end
|
|
|
|
local function get_surfaces()
|
|
local surfaces = {}
|
|
for _, player in pairs(game.connected_players) do
|
|
if not surfaces[player.surface.index] then
|
|
surfaces[player.surface.index] = player.surface
|
|
end
|
|
end
|
|
return surfaces
|
|
end
|
|
|
|
local function create_new_fish_spawn_schedule()
|
|
global.fish_respawn_chunk_schedule = {}
|
|
|
|
local surfaces = get_surfaces()
|
|
if #surfaces == 0 then
|
|
return
|
|
end
|
|
|
|
for _, surface in pairs(surfaces) do
|
|
for chunk in surface.get_chunks() do
|
|
global.fish_respawn_chunk_schedule[#global.fish_respawn_chunk_schedule + 1] = {chunk = {x = chunk.x, y = chunk.y}, surface_index = surface.index}
|
|
end
|
|
end
|
|
|
|
global.fish_respawn_chunk_schedule = shuffle(global.fish_respawn_chunk_schedule)
|
|
|
|
return global.fish_respawn_chunk_schedule
|
|
end
|
|
|
|
local function respawn_fishes_in_chunk(schedule)
|
|
local surface = game.surfaces[schedule.surface_index]
|
|
local chunk = schedule.chunk
|
|
local chunk_area = {{chunk.x * 32, chunk.y * 32}, {chunk.x * 32 + 32, chunk.y * 32 + 32}}
|
|
|
|
local water_tiles = surface.find_tiles_filtered({area = chunk_area, name = valid_water_tiles})
|
|
if #water_tiles < global.fish_respawner_water_tiles_per_fish then
|
|
return
|
|
end
|
|
|
|
local chunk_fish_count = surface.count_entities_filtered({area = chunk_area, type = 'fish'})
|
|
|
|
local fish_to_spawn = math.floor((#water_tiles - (global.fish_respawner_water_tiles_per_fish * chunk_fish_count)) / global.fish_respawner_water_tiles_per_fish)
|
|
if fish_to_spawn <= 0 then
|
|
return
|
|
end
|
|
|
|
if fish_to_spawn > global.fish_respawner_max_respawnrate_per_chunk then
|
|
fish_to_spawn = global.fish_respawner_max_respawnrate_per_chunk
|
|
end
|
|
|
|
water_tiles = shuffle(water_tiles)
|
|
for _, tile in pairs(water_tiles) do
|
|
if surface.can_place_entity({name = 'fish', position = tile.position}) then
|
|
surface.create_entity({name = 'water-splash', position = tile.position})
|
|
surface.create_entity({name = 'fish', position = tile.position})
|
|
fish_to_spawn = fish_to_spawn - 1
|
|
if fish_to_spawn <= 0 then
|
|
return
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
local function on_tick()
|
|
local i = game.tick % respawn_interval
|
|
if i == 0 then
|
|
create_new_fish_spawn_schedule()
|
|
return
|
|
end
|
|
if not global.fish_respawn_chunk_schedule[i] then
|
|
return
|
|
end
|
|
respawn_fishes_in_chunk(global.fish_respawn_chunk_schedule[i])
|
|
global.fish_respawn_chunk_schedule[i] = nil
|
|
end
|
|
|
|
event.add(defines.events.on_tick, on_tick)
|