mirror of
https://github.com/ComfyFactory/ComfyFactorio.git
synced 2025-01-10 00:43:27 +02:00
00e1f84dad
biter raffle replaced outposts are no longer safe attack group strength is reduced up to 50% for far away outposts biters seek a random target as side target, before making their way to the silo side targets are more likely chosen near the center of the map variety in unit group types (biter only, spitters only, mixed) unit groups spawn more close to their nests
289 lines
11 KiB
Lua
289 lines
11 KiB
Lua
local Public = {}
|
|
|
|
local Functions = require "maps.biter_battles_v2.functions"
|
|
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, 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)
|
|
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, force_name)
|
|
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,
|
|
}
|
|
|
|
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 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)
|
|
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
|
|
|
|
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
|
|
|
|
for _, decorative in pairs(source_surface.find_decoratives_filtered{area = source_area}) do
|
|
target_surface.create_decoratives{
|
|
check_collision = false,
|
|
decoratives = {{name = decorative.decorative.name, position = decorative.position, amount = decorative.amount}}
|
|
}
|
|
end
|
|
|
|
return true
|
|
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
|
|
for _, tile in pairs(source_surface.find_tiles_filtered({area = source_area})) do
|
|
target_surface.set_tiles({{name = tile.name, position = {x = tile.position.x * -1 - 1 , y = (tile.position.y * -1) - 1}}}, true)
|
|
end
|
|
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
|
|
|
|
for _, decorative in pairs(source_surface.find_decoratives_filtered{area = source_area}) do
|
|
target_surface.create_decoratives{
|
|
check_collision = false,
|
|
decoratives = {{name = decorative.decorative.name, position = {x = (decorative.position.x * -1) - 1, y = (decorative.position.y * -1) - 1}, amount = decorative.amount}}
|
|
}
|
|
end
|
|
|
|
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
|
|
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,
|
|
[3] = south_work,
|
|
}
|
|
|
|
function Public.ticking_work()
|
|
local work = works[game.tick % 4]
|
|
if not work then return end
|
|
work()
|
|
end
|
|
|
|
return Public |