mirror of
https://github.com/ComfyFactory/ComfyFactorio.git
synced 2025-01-24 03:47:58 +02:00
Improve main_attack performance by 15x
This commit is contained in:
parent
b0f8078661
commit
fe898b9252
@ -34,6 +34,12 @@ local threat_values = {
|
||||
["spitter-spawner"] = 16
|
||||
}
|
||||
|
||||
-- these areas are for north
|
||||
local left_spawner_area = {left_top = {-2000, -1200}, right_bottom = {-800, -700}}
|
||||
local right_spawner_area = {left_top = {800, -1200}, right_bottom = {2000, -700}}
|
||||
local middle_spawner_area = {left_top = {-600, -1000}, right_bottom = {600, -400}}
|
||||
local whole_spawner_area = {left_top = {-2048, -1400}, right_bottom = {2048, -400}}
|
||||
|
||||
local function get_active_biter_count(biter_force_name)
|
||||
local count = 0
|
||||
for _, biter in pairs(global.active_biters[biter_force_name]) do
|
||||
@ -51,11 +57,17 @@ local unit_evo_limits = {
|
||||
["big-biter"] = 2,
|
||||
}
|
||||
|
||||
function Public.set_biter_raffle_table()
|
||||
local surface = game.surfaces["biter_battles"]
|
||||
local biter_force_name = global.next_attack .. "_biters"
|
||||
local biters = surface.find_entities_filtered({type = "unit", force = biter_force_name})
|
||||
if not biters[5] then return end
|
||||
local function set_biter_raffle_table(surface, biter_force_name)
|
||||
-- It's fine to only sample the middle
|
||||
local area = middle_spawner_area
|
||||
|
||||
-- If south_biters: Mirror area along x-axis
|
||||
if biter_force_name == "south_biters" then
|
||||
area = {left_top = {area.left_top[1], -1*area.right_bottom[2]}, right_bottom = {area.right_bottom[1], -1*area.left_top[2]}}
|
||||
end
|
||||
|
||||
local biters = surface.find_entities_filtered({type = "unit", force = biter_force_name, area = area})
|
||||
if not biters[1] then return end
|
||||
global.biter_raffle[biter_force_name] = {}
|
||||
local raffle = global.biter_raffle[biter_force_name]
|
||||
local i = 1
|
||||
@ -166,15 +178,66 @@ Public.send_near_biters_to_silo = function()
|
||||
end
|
||||
|
||||
local function get_random_close_spawner(surface, biter_force_name)
|
||||
local spawners = surface.find_entities_filtered({type = "unit-spawner", force = biter_force_name})
|
||||
-- Here we have two options:
|
||||
-- 1. Random the area (left, middle, right) => smaller area to search
|
||||
-- 2. Search the whole area => larger area => if it's not cached we get a lag spike (~20ms)
|
||||
|
||||
--
|
||||
-- Option 1
|
||||
--
|
||||
local rand_value = math_random(1, 10)
|
||||
|
||||
-- assume north_biters first
|
||||
local area = nil
|
||||
if rand_value == 1 then
|
||||
area_name = "left"
|
||||
area = left_spawner_area
|
||||
elseif rand_value == 2 then
|
||||
area_name = "right"
|
||||
area = right_spawner_area
|
||||
else
|
||||
area_name = "middle"
|
||||
area = middle_spawner_area
|
||||
end
|
||||
|
||||
--
|
||||
-- Option 2
|
||||
--
|
||||
|
||||
-- area = whole_spawner_area
|
||||
-- area_name = whole
|
||||
|
||||
-- After here it's the same
|
||||
|
||||
-- If south_biters: Mirror area along x-axis
|
||||
if biter_force_name == "south_biters" then
|
||||
area_name = area_name .. "_south"
|
||||
area = {left_top = {area.left_top[1], -1*area.right_bottom[2]}, right_bottom = {area.right_bottom[1], -1*area.left_top[2]}}
|
||||
end
|
||||
|
||||
-- If possible get the spawners from cache
|
||||
-- TODO: If a spawner was destroyed, we still have it in cache, this is fine for now as we just use spawner.position
|
||||
local spawners = nil
|
||||
if not global.cached_spawners then global.cached_spawners = {} end
|
||||
if global.cached_spawners[area_name] then
|
||||
spawners = global.cached_spawners[area_name]
|
||||
else
|
||||
spawners = surface.find_entities_filtered({type = "unit-spawner", force = biter_force_name, area = area})
|
||||
global.cached_spawners[area_name] = spawners
|
||||
end
|
||||
|
||||
if not spawners[1] then return false end
|
||||
|
||||
|
||||
local spawner = spawners[math_random(1,#spawners)]
|
||||
-- game.forces["north"].add_chart_tag("biter_battles", {icon={type="virtual", name="signal-green"}, position=spawner.position})
|
||||
for i = 1, 5, 1 do
|
||||
local spawner_2 = spawners[math_random(1,#spawners)]
|
||||
-- game.forces["north"].add_chart_tag("biter_battles", {icon={type="virtual", name="signal-green"}, position=spawner_2.position})
|
||||
if spawner_2.position.x ^ 2 + spawner_2.position.y ^ 2 < spawner.position.x ^ 2 + spawner.position.y ^ 2 then spawner = spawner_2 end
|
||||
end
|
||||
|
||||
-- rendering.draw_rectangle{color={g=1}, width=5, filled=false, left_top=area.left_top, right_bottom=area.right_bottom, surface="biter_battles"}
|
||||
-- game.forces["north"].add_chart_tag("biter_battles", {icon={type="virtual", name="signal-blue"}, position=spawner.position})
|
||||
return spawner
|
||||
end
|
||||
|
||||
@ -330,7 +393,7 @@ local function create_attack_group(surface, force_name, biter_force_name)
|
||||
if global.bb_debug then game.print("No spawner found for team " .. force_name) end
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
local nearest_player_unit = surface.find_nearest_enemy({position = spawner.position, max_distance = 2048, force = biter_force_name})
|
||||
if not nearest_player_unit then nearest_player_unit = global.rocket_silo[force_name] end
|
||||
|
||||
@ -345,20 +408,36 @@ local function create_attack_group(surface, force_name, biter_force_name)
|
||||
global.unit_groups[unit_group.group_number] = unit_group
|
||||
end
|
||||
|
||||
Public.main_attack = function()
|
||||
Public.pre_main_attack = function()
|
||||
local surface = game.surfaces["biter_battles"]
|
||||
local force_name = global.next_attack
|
||||
|
||||
|
||||
if not global.training_mode or (global.training_mode and #game.forces[force_name].connected_players > 0) then
|
||||
local biter_force_name = force_name .. "_biters"
|
||||
local wave_amount = math.ceil(get_threat_ratio(biter_force_name) * 7)
|
||||
|
||||
for c = 1, wave_amount, 1 do
|
||||
create_attack_group(surface, force_name, biter_force_name)
|
||||
end
|
||||
if global.bb_debug then game.print(wave_amount .. " unit groups designated for " .. force_name .. " biters.") end
|
||||
global.main_attack_wave_amount = math.ceil(get_threat_ratio(biter_force_name) * 7)
|
||||
|
||||
set_biter_raffle_table(surface, biter_force_name)
|
||||
|
||||
if global.bb_debug then game.print(global.main_attack_wave_amount .. " unit groups designated for " .. force_name .. " biters.") end
|
||||
else
|
||||
global.main_attack_wave_amount = 0
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
Public.perform_main_attack = function()
|
||||
if global.main_attack_wave_amount > 0 then
|
||||
local surface = game.surfaces["biter_battles"]
|
||||
local force_name = global.next_attack
|
||||
local biter_force_name = force_name .. "_biters"
|
||||
|
||||
create_attack_group(surface, force_name, biter_force_name)
|
||||
global.main_attack_wave_amount = global.main_attack_wave_amount - 1
|
||||
end
|
||||
end
|
||||
|
||||
Public.post_main_attack = function()
|
||||
global.main_attack_wave_amount = 0
|
||||
if global.next_attack == "north" then
|
||||
global.next_attack = "south"
|
||||
else
|
||||
@ -420,4 +499,12 @@ function Public.subtract_threat(entity)
|
||||
return true
|
||||
end
|
||||
|
||||
return Public
|
||||
-- Invalidate the cache if a new chunk was generated
|
||||
-- TODO: This can be more precise
|
||||
Public.on_chunk_generated = function(event)
|
||||
if event.area.right_bottom.x < -2048 then return end
|
||||
if event.area.left_top.x > 2048 then return end
|
||||
global.cached_spawners = {}
|
||||
end
|
||||
|
||||
return Public
|
||||
|
@ -94,32 +94,43 @@ end
|
||||
local tick_minute_functions = {
|
||||
[300 * 1] = Ai.raise_evo,
|
||||
[300 * 2] = Ai.destroy_inactive_biters,
|
||||
[300 * 3] = Ai.set_biter_raffle_table,
|
||||
[300 * 4] = Ai.main_attack,
|
||||
[300 * 5] = Ai.send_near_biters_to_silo,
|
||||
[300 * 6] = Ai.wake_up_sleepy_groups,
|
||||
[300 * 3 + 30 * 0] = Ai.pre_main_attack, -- setup for main_attack
|
||||
[300 * 3 + 30 * 1] = Ai.perform_main_attack, -- call perform_main_attack 7 times on different ticks
|
||||
[300 * 3 + 30 * 2] = Ai.perform_main_attack, -- some of these might do nothing (if there are no wave left)
|
||||
[300 * 3 + 30 * 3] = Ai.perform_main_attack,
|
||||
[300 * 3 + 30 * 4] = Ai.perform_main_attack,
|
||||
[300 * 3 + 30 * 5] = Ai.perform_main_attack,
|
||||
[300 * 3 + 30 * 6] = Ai.perform_main_attack,
|
||||
[300 * 3 + 30 * 7] = Ai.perform_main_attack,
|
||||
[300 * 3 + 30 * 8] = Ai.post_main_attack,
|
||||
[300 * 4] = Ai.send_near_biters_to_silo,
|
||||
[300 * 5] = Ai.wake_up_sleepy_groups,
|
||||
[300 * 7] = Game_over.restart_idle_map,
|
||||
}
|
||||
|
||||
local function on_tick(event)
|
||||
Mirror_terrain.ticking_work()
|
||||
|
||||
local tick = game.tick
|
||||
|
||||
local tick = game.tick
|
||||
|
||||
if tick % 60 ~= 0 then return end
|
||||
global.bb_threat["north_biters"] = global.bb_threat["north_biters"] + global.bb_threat_income["north_biters"]
|
||||
global.bb_threat["south_biters"] = global.bb_threat["south_biters"] + global.bb_threat_income["south_biters"]
|
||||
if tick % 60 == 0 then
|
||||
global.bb_threat["north_biters"] = global.bb_threat["north_biters"] + global.bb_threat_income["north_biters"]
|
||||
global.bb_threat["south_biters"] = global.bb_threat["south_biters"] + global.bb_threat_income["south_biters"]
|
||||
end
|
||||
|
||||
if tick % 180 == 0 then Gui.refresh() end
|
||||
|
||||
if tick % 300 ~= 0 then return end
|
||||
Gui.spy_fish()
|
||||
if global.bb_game_won_by_team then
|
||||
Game_over.reveal_map()
|
||||
Game_over.server_restart()
|
||||
return
|
||||
if tick % 300 == 0 then
|
||||
Gui.spy_fish()
|
||||
|
||||
if global.bb_game_won_by_team then
|
||||
Game_over.reveal_map()
|
||||
Game_over.server_restart()
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
if tick % 30 ~= 0 then return end
|
||||
local key = tick % 3600
|
||||
if tick_minute_functions[key] then tick_minute_functions[key]() end
|
||||
end
|
||||
@ -169,9 +180,10 @@ Event.add(defines.events.on_research_finished, on_research_finished)
|
||||
Event.add(defines.events.on_robot_built_entity, on_robot_built_entity)
|
||||
Event.add(defines.events.on_robot_built_tile, on_robot_built_tile)
|
||||
Event.add(defines.events.on_tick, on_tick)
|
||||
Event.add(defines.events.on_chunk_generated, Ai.on_chunk_generated)
|
||||
Event.on_init(on_init)
|
||||
|
||||
Event.add_event_filter(defines.events.on_entity_damaged, { filter = "name", name = "rocket-silo" })
|
||||
|
||||
require "maps.biter_battles_v2.spec_spy"
|
||||
require "maps.biter_battles_v2.difficulty_vote"
|
||||
require "maps.biter_battles_v2.difficulty_vote"
|
||||
|
Loading…
x
Reference in New Issue
Block a user