1
0
mirror of https://github.com/ComfyFactory/ComfyFactorio.git synced 2025-01-10 00:43:27 +02:00
ComfyFactorio/maps/biter_battles_v2/mirror_terrain.lua

290 lines
11 KiB
Lua
Raw Normal View History

2020-01-22 09:30:41 +02:00
local Public = {}
2019-03-13 18:09:06 +02:00
local Functions = require "maps.biter_battles_v2.functions"
local table_remove = table.remove
local table_insert = table.insert
2019-03-13 18:09:06 +02:00
local direction_translation = {
[0] = 4,
[1] = 5,
[2] = 6,
[3] = 7,
[4] = 0,
[5] = 1,
[6] = 2,
[7] = 3
}
local cliff_orientation_translation = {
2019-03-13 21:22:21 +02:00
["east-to-none"] = "west-to-none",
["east-to-north"] = "west-to-south",
2019-03-13 18:51:49 +02:00
["east-to-south"] = "west-to-north",
["east-to-west"] = "west-to-east",
2019-03-13 21:22:21 +02:00
["north-to-east"] = "south-to-west",
["north-to-none"] = "south-to-none",
["north-to-south"] = "south-to-north",
2019-03-13 18:51:49 +02:00
["north-to-west"] = "south-to-east",
["south-to-east"] = "north-to-west",
2019-03-13 21:22:21 +02:00
["south-to-none"] = "north-to-none",
["south-to-north"] = "north-to-south",
["south-to-west"] = "north-to-east",
2019-03-13 21:22:21 +02:00
["west-to-east"] = "east-to-west",
2019-03-13 18:51:49 +02:00
["west-to-none"] = "east-to-none",
2019-03-13 21:22:21 +02:00
["west-to-north"] = "east-to-south",
["west-to-south"] = "east-to-north",
2019-03-13 18:51:49 +02:00
["none-to-east"] = "none-to-west",
2019-03-13 21:22:21 +02:00
["none-to-north"] = "none-to-south",
2019-03-13 18:51:49 +02:00
["none-to-south"] = "none-to-north",
2019-03-13 21:22:21 +02:00
["none-to-west"] = "none-to-east"
2019-03-13 18:09:06 +02:00
}
local entity_copy_functions = {
["tree"] = function(surface, entity, target_position, force_name)
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, force_name)
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_entity = surface.create_entity(mirror_entity)
mirror_entity.graphics_variation = entity.graphics_variation
end,
["cliff"] = function(surface, entity, target_position, force_name)
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, force_name)
surface.create_entity({name = entity.name, position = target_position, amount = entity.amount})
end,
["corpse"] = function(surface, entity, target_position, force_name)
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)
2020-04-16 13:22:15 +02:00
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)
2020-04-16 13:22:15 +02:00
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)
2020-04-16 13:22:15 +02:00
local e = entity.clone({position = target_position, surface = surface, force = force_name})
e.active = true
end,
["container"] = function(surface, entity, target_position, force_name)
2020-04-16 13:22:15 +02:00
local e = entity.clone({position = target_position, surface = surface, force = force_name})
e.active = true
end,
["fish"] = function(surface, entity, target_position, force_name)
2020-04-16 13:22:15 +02:00
local mirror_entity = {name = entity.name, position = target_position}
if not surface.can_place_entity(mirror_entity) then return end
local e = surface.create_entity(mirror_entity)
end,
2019-09-08 00:21:02 +02:00
}
local function process_entity(surface, entity, force_name)
2019-10-05 04:18:18 +02:00
if not entity.valid then return end
if not entity_copy_functions[entity.type] then return end
local target_position
if force_name == "north" then
target_position = entity.position
else
target_position = {x = entity.position.x * -1, y = entity.position.y * -1}
end
entity_copy_functions[entity.type](surface, entity, target_position, force_name)
2019-03-13 18:09:06 +02:00
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
2019-12-31 03:34:02 +02:00
end
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")
2019-03-19 05:05:32 +02:00
end
chunk[2] = chunk[2] + 1
return
end
2020-04-21 15:13:19 +02:00
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}, amount = decorative.amount}
2019-03-19 05:05:32 +02:00
end
2020-04-21 15:13:19 +02:00
target_surface.create_decoratives({check_collision = false, decoratives = decoratives})
return true
2019-03-19 05:05:32 +02:00
end
local function mirror_chunk(chunk)
local target_surface = game.surfaces.biter_battles
local source_surface = game.surfaces.bb_source
local source_chunk_position = {chunk[1][1] * -1 - 1, chunk[1][2] * -1 - 1}
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
2020-04-21 15:13:19 +02:00
local tiles = {}
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
2020-04-21 15:13:19 +02:00
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
2020-04-21 15:13:19 +02:00
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 * -1) - 1, (decorative.position.y * -1) - 1}, amount = decorative.amount}
2019-03-17 19:19:40 +02:00
end
2020-04-21 15:13:19 +02:00
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
2019-12-31 03:34:02 +02:00
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
2020-04-17 15:38:16 +02:00
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
2019-03-17 19:19:40 +02:00
end
2020-04-17 15:38:16 +02:00
local function north_work()
local terrain_gen = global.terrain_gen
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
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,
2020-04-21 15:13:19 +02:00
[2] = south_work,
2020-04-17 15:38:16 +02:00
}
function Public.ticking_work()
2020-04-21 15:13:19 +02:00
local work = works[game.ticks_played % 2 + 1]
2020-04-17 15:38:16 +02:00
if not work then return end
2020-04-21 15:13:19 +02:00
if global.server_restart_timer then return end
2020-04-17 15:38:16 +02:00
work()
end
2020-01-22 09:30:41 +02:00
return Public