mirror of
https://github.com/ComfyFactory/ComfyFactorio.git
synced 2025-01-06 00:23:49 +02:00
356 lines
13 KiB
Lua
356 lines
13 KiB
Lua
local Public = {}
|
|
|
|
local Functions = require 'maps.biter_battles_v2.functions'
|
|
local bb_config = require 'maps.biter_battles_v2.config'
|
|
local table_remove = table.remove
|
|
local table_insert = table.insert
|
|
|
|
local direction_translation = {
|
|
[0] = 4,
|
|
[1] = 5,
|
|
[2] = 6,
|
|
[3] = 7,
|
|
[4] = 0,
|
|
[5] = 1,
|
|
[6] = 2,
|
|
[7] = 3
|
|
}
|
|
|
|
local cliff_orientation_translation = {
|
|
['east-to-none'] = 'west-to-none',
|
|
['east-to-north'] = 'west-to-south',
|
|
['east-to-south'] = 'west-to-north',
|
|
['east-to-west'] = 'west-to-east',
|
|
['north-to-east'] = 'south-to-west',
|
|
['north-to-none'] = 'south-to-none',
|
|
['north-to-south'] = 'south-to-north',
|
|
['north-to-west'] = 'south-to-east',
|
|
['south-to-east'] = 'north-to-west',
|
|
['south-to-none'] = 'north-to-none',
|
|
['south-to-north'] = 'north-to-south',
|
|
['south-to-west'] = 'north-to-east',
|
|
['west-to-east'] = 'east-to-west',
|
|
['west-to-none'] = 'east-to-none',
|
|
['west-to-north'] = 'east-to-south',
|
|
['west-to-south'] = 'east-to-north',
|
|
['none-to-east'] = 'none-to-west',
|
|
['none-to-north'] = 'none-to-south',
|
|
['none-to-south'] = 'none-to-north',
|
|
['none-to-west'] = 'none-to-east'
|
|
}
|
|
|
|
local entity_copy_functions = {
|
|
['tree'] = function(surface, entity, target_position)
|
|
if not surface.can_place_entity({name = entity.name, position = target_position}) then
|
|
return
|
|
end
|
|
entity.clone({position = target_position, surface = surface, force = 'neutral'})
|
|
end,
|
|
['simple-entity'] = function(surface, entity, target_position)
|
|
local mirror_entity = {name = entity.name, position = target_position, direction = direction_translation[entity.direction]}
|
|
if not surface.can_place_entity(mirror_entity) then
|
|
return
|
|
end
|
|
local mirror_entity2 = surface.create_entity(mirror_entity)
|
|
mirror_entity2.graphics_variation = entity.graphics_variation
|
|
end,
|
|
['cliff'] = function(surface, entity, target_position)
|
|
local mirror_entity = {name = entity.name, position = target_position, cliff_orientation = cliff_orientation_translation[entity.cliff_orientation]}
|
|
if not surface.can_place_entity(mirror_entity) then
|
|
return
|
|
end
|
|
surface.create_entity(mirror_entity)
|
|
return
|
|
end,
|
|
['resource'] = function(surface, entity, target_position)
|
|
surface.create_entity({name = entity.name, position = target_position, amount = entity.amount})
|
|
end,
|
|
['corpse'] = function(surface, entity, target_position)
|
|
surface.create_entity({name = entity.name, position = target_position})
|
|
end,
|
|
['unit-spawner'] = function(surface, entity, target_position, force_name)
|
|
local mirror_entity = {name = entity.name, position = target_position, direction = direction_translation[entity.direction], force = force_name .. '_biters'}
|
|
if not surface.can_place_entity(mirror_entity) then
|
|
return
|
|
end
|
|
table_insert(global.unit_spawners[force_name .. '_biters'], surface.create_entity(mirror_entity))
|
|
end,
|
|
['turret'] = function(surface, entity, target_position, force_name)
|
|
local mirror_entity = {name = entity.name, position = target_position, direction = direction_translation[entity.direction], force = force_name .. '_biters'}
|
|
if not surface.can_place_entity(mirror_entity) then
|
|
return
|
|
end
|
|
surface.create_entity(mirror_entity)
|
|
end,
|
|
['rocket-silo'] = function(surface, entity, target_position, force_name)
|
|
if surface.count_entities_filtered({name = 'rocket-silo', area = {{target_position.x - 8, target_position.y - 8}, {target_position.x + 8, target_position.y + 8}}}) > 0 then
|
|
return
|
|
end
|
|
global.rocket_silo[force_name] =
|
|
surface.create_entity({name = entity.name, position = target_position, direction = direction_translation[entity.direction], force = force_name})
|
|
global.rocket_silo[force_name].minable = false
|
|
Functions.add_target_entity(global.rocket_silo[force_name])
|
|
end,
|
|
['ammo-turret'] = function(surface, entity, target_position, force_name)
|
|
local direction = 0
|
|
if force_name == 'south' then
|
|
direction = 4
|
|
end
|
|
local mirror_entity = {name = entity.name, position = target_position, force = force_name, direction = direction}
|
|
if not surface.can_place_entity(mirror_entity) then
|
|
return
|
|
end
|
|
local e = surface.create_entity(mirror_entity)
|
|
Functions.add_target_entity(e)
|
|
local inventory = entity.get_inventory(defines.inventory.turret_ammo)
|
|
if inventory.is_empty() then
|
|
return
|
|
end
|
|
for name, count in pairs(inventory.get_contents()) do
|
|
e.insert({name = name, count = count})
|
|
end
|
|
end,
|
|
['wall'] = function(surface, entity, target_position, force_name)
|
|
local e = entity.clone({position = target_position, surface = surface, force = force_name})
|
|
e.active = true
|
|
end,
|
|
['container'] = function(surface, entity, target_position, force_name)
|
|
local e = entity.clone({position = target_position, surface = surface, force = force_name})
|
|
e.active = true
|
|
end,
|
|
['fish'] = function(surface, entity, target_position)
|
|
local mirror_entity = {name = entity.name, position = target_position}
|
|
if not surface.can_place_entity(mirror_entity) then
|
|
return
|
|
end
|
|
surface.create_entity(mirror_entity)
|
|
end
|
|
}
|
|
|
|
local function process_entity(surface, entity, force_name)
|
|
if not entity.valid then
|
|
return
|
|
end
|
|
if not entity_copy_functions[entity.type] then
|
|
return
|
|
end
|
|
|
|
local match_mirror = bb_config.match_mirror
|
|
|
|
local target_position
|
|
if force_name == 'north' then
|
|
target_position = entity.position
|
|
else
|
|
if match_mirror then
|
|
target_position = {x = entity.position.x, y = entity.position.y * -1}
|
|
else
|
|
target_position = {x = entity.position.x * -1, y = entity.position.y * -1}
|
|
end
|
|
end
|
|
|
|
entity_copy_functions[entity.type](surface, entity, target_position, force_name)
|
|
end
|
|
|
|
local function copy_chunk(chunk)
|
|
local target_surface = game.surfaces.biter_battles
|
|
|
|
local source_surface = game.surfaces.bb_source
|
|
local source_chunk_position = {chunk[1][1], chunk[1][2]}
|
|
local source_left_top = {x = source_chunk_position[1] * 32, y = source_chunk_position[2] * 32}
|
|
local source_area = {{source_left_top.x, source_left_top.y}, {source_left_top.x + 32, source_left_top.y + 32}}
|
|
|
|
local target_chunk_position = chunk[1]
|
|
local target_left_top = {x = target_chunk_position[1] * 32, y = target_chunk_position[2] * 32}
|
|
local target_area = {{target_left_top.x, target_left_top.y}, {target_left_top.x + 32, target_left_top.y + 32}}
|
|
|
|
if not source_surface.is_chunk_generated(source_chunk_position) then
|
|
source_surface.request_to_generate_chunks({x = source_left_top.x + 16, y = source_left_top.y + 16}, 0)
|
|
return
|
|
end
|
|
|
|
local match_mirror = bb_config.match_mirror
|
|
|
|
if chunk[2] == 1 then
|
|
source_surface.clone_area(
|
|
{
|
|
source_area = source_area,
|
|
destination_area = target_area,
|
|
destination_surface = target_surface,
|
|
--destination_force = …,
|
|
clone_tiles = true,
|
|
clone_entities = false,
|
|
clone_decoratives = false,
|
|
clear_destination_entities = false,
|
|
clear_destination_decoratives = false,
|
|
expand_map = false
|
|
}
|
|
)
|
|
chunk[2] = chunk[2] + 1
|
|
return
|
|
end
|
|
|
|
if chunk[2] == 2 then
|
|
for _, entity in pairs(source_surface.find_entities_filtered({area = source_area})) do
|
|
process_entity(target_surface, entity, 'north')
|
|
end
|
|
chunk[2] = chunk[2] + 1
|
|
return
|
|
end
|
|
|
|
local decoratives = {}
|
|
if match_mirror then
|
|
for k, decorative in pairs(source_surface.find_decoratives_filtered {area = source_area}) do
|
|
decoratives[k] = {name = decorative.decorative.name, position = {decorative.position.x, decorative.position.y}, amount = decorative.amount}
|
|
end
|
|
else
|
|
for k, decorative in pairs(source_surface.find_decoratives_filtered {area = source_area}) do
|
|
decoratives[k] = {name = decorative.decorative.name, position = {(decorative.position.x * -1) - 1, (decorative.position.y * -1) - 1}, amount = decorative.amount}
|
|
end
|
|
end
|
|
target_surface.create_decoratives({check_collision = false, decoratives = decoratives})
|
|
|
|
return true
|
|
end
|
|
|
|
local function mirror_chunk(chunk)
|
|
local target_surface = game.surfaces.biter_battles
|
|
local match_mirror = bb_config.match_mirror
|
|
local source_surface = game.surfaces.bb_source
|
|
local source_chunk_position
|
|
if match_mirror then
|
|
source_chunk_position = {chunk[1][1], chunk[1][2] * -1 - 1}
|
|
else
|
|
source_chunk_position = {chunk[1][1] * -1 - 1, chunk[1][2] * -1 - 1}
|
|
end
|
|
|
|
local source_left_top = {x = source_chunk_position[1] * 32, y = source_chunk_position[2] * 32}
|
|
local source_area = {{source_left_top.x, source_left_top.y}, {source_left_top.x + 32, source_left_top.y + 32}}
|
|
|
|
if not source_surface.is_chunk_generated(source_chunk_position) then
|
|
source_surface.request_to_generate_chunks({x = source_left_top.x + 16, y = source_left_top.y + 16}, 0)
|
|
return
|
|
end
|
|
|
|
if chunk[2] == 1 then
|
|
local tiles = {}
|
|
if match_mirror then
|
|
for k, tile in pairs(source_surface.find_tiles_filtered({area = source_area})) do
|
|
tiles[k] = {name = tile.name, position = {tile.position.x, tile.position.y * -1 - 1}}
|
|
end
|
|
else
|
|
for k, tile in pairs(source_surface.find_tiles_filtered({area = source_area})) do
|
|
tiles[k] = {name = tile.name, position = {tile.position.x * -1 - 1, tile.position.y * -1 - 1}}
|
|
end
|
|
end
|
|
target_surface.set_tiles(tiles, true)
|
|
chunk[2] = chunk[2] + 1
|
|
return
|
|
end
|
|
|
|
if chunk[2] == 2 then
|
|
for _, entity in pairs(source_surface.find_entities_filtered({area = source_area})) do
|
|
process_entity(target_surface, entity, 'south')
|
|
end
|
|
chunk[2] = chunk[2] + 1
|
|
return
|
|
end
|
|
|
|
local decoratives = {}
|
|
for k, decorative in pairs(source_surface.find_decoratives_filtered {area = source_area}) do
|
|
decoratives[k] = {name = decorative.decorative.name, position = {decorative.position.x, decorative.position.y * -1}, amount = decorative.amount}
|
|
end
|
|
target_surface.create_decoratives({check_collision = false, decoratives = decoratives})
|
|
|
|
return true
|
|
end
|
|
|
|
local function reveal_chunk(chunk)
|
|
local surface = game.surfaces.biter_battles
|
|
local chunk_position = chunk[1]
|
|
for _, force_name in pairs({'north', 'south'}) do
|
|
local force = game.forces[force_name]
|
|
if force.is_chunk_charted(surface, chunk_position) then
|
|
force.chart(surface, {{chunk_position[1] * 32, chunk_position[2] * 32}, {chunk_position[1] * 32 + 31, chunk_position[2] * 32 + 31}})
|
|
end
|
|
end
|
|
end
|
|
|
|
function Public.add_chunk(event)
|
|
local surface = event.surface
|
|
if surface.name ~= 'biter_battles' then
|
|
return
|
|
end
|
|
local left_top = event.area.left_top
|
|
local terrain_gen = global.terrain_gen
|
|
|
|
if left_top.y < 0 then
|
|
terrain_gen.size_of_chunk_copy = terrain_gen.size_of_chunk_copy + 1
|
|
terrain_gen.chunk_copy[terrain_gen.size_of_chunk_copy] = {{left_top.x / 32, left_top.y / 32}, 1}
|
|
else
|
|
terrain_gen.size_of_chunk_mirror = terrain_gen.size_of_chunk_mirror + 1
|
|
terrain_gen.chunk_mirror[terrain_gen.size_of_chunk_mirror] = {{left_top.x / 32, left_top.y / 32}, 1}
|
|
end
|
|
end
|
|
|
|
local function clear_source_surface(terrain_gen)
|
|
if terrain_gen.counter % 1024 == 1023 then
|
|
terrain_gen.counter = terrain_gen.counter + 1
|
|
local surface = game.surfaces.bb_source
|
|
local c = 0
|
|
for chunk in surface.get_chunks() do
|
|
surface.delete_chunk({chunk.x, chunk.y})
|
|
c = c + 1
|
|
end
|
|
print('Deleted ' .. c .. ' source surface chunks.')
|
|
end
|
|
end
|
|
|
|
local function north_work()
|
|
local terrain_gen = global.terrain_gen
|
|
--luacheck: ignore 512
|
|
for k, chunk in pairs(terrain_gen.chunk_copy) do
|
|
if copy_chunk(chunk) then
|
|
reveal_chunk(chunk)
|
|
table_remove(terrain_gen.chunk_copy, k)
|
|
terrain_gen.size_of_chunk_copy = terrain_gen.size_of_chunk_copy - 1
|
|
terrain_gen.counter = terrain_gen.counter + 1
|
|
end
|
|
break
|
|
end
|
|
clear_source_surface(terrain_gen)
|
|
end
|
|
|
|
local function south_work()
|
|
local terrain_gen = global.terrain_gen
|
|
--luacheck: ignore 512
|
|
for k, chunk in pairs(terrain_gen.chunk_mirror) do
|
|
if mirror_chunk(chunk) then
|
|
reveal_chunk(chunk)
|
|
table_remove(terrain_gen.chunk_mirror, k)
|
|
terrain_gen.size_of_chunk_mirror = terrain_gen.size_of_chunk_mirror - 1
|
|
terrain_gen.counter = terrain_gen.counter + 1
|
|
end
|
|
break
|
|
end
|
|
clear_source_surface(terrain_gen)
|
|
end
|
|
|
|
local works = {
|
|
[1] = north_work,
|
|
[2] = south_work
|
|
}
|
|
|
|
function Public.ticking_work()
|
|
local tick = game.ticks_played
|
|
if tick < 4 then
|
|
return
|
|
end
|
|
local work = works[tick % 2 + 1]
|
|
if global.server_restart_timer then
|
|
return
|
|
end
|
|
work()
|
|
end
|
|
|
|
return Public
|