e4s-sdk/gamedata/scripts/sim_faction_brain_human.script
2026-06-17 23:06:51 +03:00

368 lines
No EOL
14 KiB
Text

--'******************************************************
--'* Îáúåêò ãðóïïèðîâêè.
--'******************************************************
local TASK_DISTANCE = 300*300 -- Êâàäðàò ðàäèóñà, â êîòîðîì âûäàþòñÿ òàñêè èãðîêó
class "faction_brain_human"
function faction_brain_human:__init(faction)
self.faction = faction
self.human = true
self.use_issue_order = true
self.use_cover_attack = true
self.use_prepare_phase = true
self.use_delay_attack = false
if self.faction.player_name == "killer" then
self.use_counter_attack = false
else
self.use_counter_attack = true
end
end
-- Ðàññ÷åò òåêóùåé ýêñïàíñèè
function faction_brain_human:calculate_current_expansion()
local faction = self.faction
local relative_power = faction:get_relative_power()
--callstack()
--printf("faction [%s] brain update %s", faction.player_name, relative_power)
for k, expansion in pairs(faction.expansion_level) do
--printf("check %s, current %s", k, faction.current_expansion_level)
if faction.current_expansion_level > k then
-- Åñëè ïðîâåðÿåìûé óðîâåíü ýêñïàíñèè íèæå, ÷åì òåêóùèé
local power_valid = relative_power > expansion.precondition_power
local advance_valid = self:check_sim_targets_advance(expansion)
local cond_valid = xr_logic.pick_section_from_condlist(db.actor, self, expansion.precondition_cond) == "true"
local actor_valid = expansion.precondition_actor_in_faction ~= true or faction.community_player == true
-- Ïðîâåðÿåì âñå ëè óñëîâèÿ âûïîëíÿþòñÿ
if not (cond_valid and power_valid and advance_valid and actor_valid) then
-- Åñëè íå âûïîëíÿþòñÿ - âûäàåì ñîîáùåíèå î ïîòåðè óðîâíÿ, ðåñåòèì êâåñòû, ïðåêðàùàåì ðàáîòó öèêëà.
--printf("LEVEL DOWN %s %s %s %s", self.faction.player_name, tostring(cond_valid), tostring(power_valid), tostring(advance_valid))
if faction.community_player == true then
if db.actor ~= nil and faction.expansion_level[faction.current_expansion_level].level_down_snd ~= nil then
xr_sound.set_sound_play(faction.id, faction.expansion_level[faction.current_expansion_level].level_down_snd, faction.player_name)
end
end
faction.current_expansion_level = k
break
end
elseif faction.current_expansion_level == k then
-- Åñëè ïðîâåðÿåìûé óðîâåíü ðàâåí òåêóùåìó.
-- Ïðîâåðÿåì, âñå ëè óñëîâèÿ âûïîëíÿþòñÿ.
local power_valid = relative_power > expansion.precondition_power
local advance_valid = self:check_sim_targets_advance(expansion)
local cond_valid = xr_logic.pick_section_from_condlist(db.actor, self, expansion.precondition_cond) == "true"
local actor_valid = expansion.precondition_actor_in_faction ~= true or faction.community_player == true
if not (cond_valid and power_valid and advance_valid and actor_valid) then
-- Åñëè íå âûïîëíÿþòñÿ - ïðåêðàùàåì ðàáîòó öèêëà.
break
end
else
-- Åñëè ïðîâåðÿåìûé óðîâåíü âûøå òåêóùåãî.
-- Âûäàåì ñîîáùåíèå î ïîäíÿòèè óðîâíÿ, ðåñåòèì êâåñòû, ïðåêðàùàåì ðàáîòó öèêëà.
--printf("LEVEL UP %s from %s", faction.player_name, faction.current_expansion_level)
if faction.community_player == true then
local old_exp = faction.expansion_level[faction.current_expansion_level]
if db.actor ~= nil and old_exp.level_up_snd ~= nil then
xr_sound.set_sound_play(faction.id, old_exp.level_up_snd, faction.player_name)
end
end
faction.current_expansion_level = k
break
end
end
self:calculate_expansion_targets()
end
-- Ôîðìèðîâàíèå öåëåé íà îñíîâå òåêóùåé ýêñïàíñèè
function faction_brain_human:calculate_expansion_targets()
local faction = self.faction
local relative_power = faction:get_relative_power()
faction.target_smart_value = {}
--printf("faction %s calculate_expansion_targets for %s", faction.player_name, faction.current_expansion_level)
if faction.current_expansion_level == 0 then
return
end
-- Ñïåðâà îïðåäåëÿåì íóæíî ëè íàì áîëüøå ñèëû
self:get_sim_targets_power(relative_power < faction.expansion_level[faction.current_expansion_level].precondition_power)
-- Ïîòîì îïðåäåëÿåì êëþ÷åâûå òî÷êè.
for i = 1,faction.current_expansion_level do
--printf("%s", i)
self:get_sim_targets_advance(faction.expansion_level[i])
end
-- Äîáàâëÿåì ïðîñòî âàæíûå òî÷êè
for k,v in pairs(self.faction.secondary_targets) do
local smart_obj = self.faction.board.smarts_by_names[k]
self:register_target_point(smart_obj, false, false, true)
end
if db.actor ~= nil and self.faction.community_player == true then
self:reset_actor_tasks()
end
--' Ñ÷èòàåì ìàêñèìàëüíûé ïîòîëîê îòðÿäîâ.
faction:calculate_total_squads()
-- Ðàçäàåì öåëè
faction:calculate_squad_tasks()
end
--' Ñîñòàâëÿåò ñïèñîê íóæíûõ äëÿ çàõâàòà ñìàðòîâ, â êîòîðûé âêëþ÷àåò ðåñóðñíûå è òåððèòîðèàëüíûå ñìàðòû.
function faction_brain_human:get_sim_targets_power(need_power_targets)
--printf("faction [%s] check_sim_targets_power [%s]", self.faction.player_name, tostring(need_power_targets))
--' Èòåðèðóåìñÿ ïî âñåì ñìàðòàì, âûèñêèâàåì ïîïàäàþùèå ïîä íàøå îïðåäåëåíèå
--' è óñòàíàâëèâàåì èì ñòàðòîâóþ îöåíêó.
local faction = self.faction
for k,v in pairs(faction.board.smarts) do
if v.smrt.sim_type == "territory" or v.smrt.sim_type == "resource" then
-- Åñëè íå need_power_targets, òî äîáàâëÿåì òîëüêî òå òî÷êè, êîòîðûå óæå ïîä íàøèì êîíòðîëåì.
if need_power_targets or v.smrt.player_name == faction.player_name then
if sim_board.is_point_avail(v.smrt, faction.player_name) then
self:register_target_point(v.smrt, false)
end
end
end
end
end
-- Ïðîâåðÿåì, âñå ëè ó íàñ çàõâà÷åíî èç âàæíûõ òî÷åê. Àâòîìàòîì äîáàâëÿåò èõ â ñïèñîê çàäà÷ (ÍÎ ÍÅ ÊÂÅÑÒÎÂ)
function faction_brain_human:check_sim_targets_advance(expansion)
for k,v in pairs(expansion.precondition_target) do
local smart_obj = self.faction.board.smarts_by_names[v]
if smart_obj.player_name ~= self.faction.player_name then
return false
end
end
for k,v in pairs(expansion.precondition_target_optional) do
local smart_obj = self.faction.board.smarts_by_names[v]
if smart_obj.player_name ~= self.faction.player_name then
return false
end
end
for k,v in pairs(expansion.precondition_target_eliminate) do
local smart_obj = self.faction.board.smarts_by_names[v]
local smart_owner = smart_obj.player_name
--printf(" check target advance %s owner %s", smart_obj:name(), tostring(smart_owner))
if smart_owner ~= "none" then
if game_relations.is_factions_enemies(self.faction.player_name, smart_owner) then
return false
end
end
end
return true
end
-- Ïðîâåðÿåì, âñå ëè ó íàñ çàõâà÷åíî èç âàæíûõ òî÷åê. Àâòîìàòîì äîáàâëÿåò èõ â ñïèñîê çàäà÷ (ÍÎ ÍÅ ÊÂÅÑÒÎÂ)
function faction_brain_human:get_sim_targets_advance(expansion)
for k,v in pairs(expansion.precondition_target) do
local smart_obj = self.faction.board.smarts_by_names[v]
self:register_target_point(smart_obj, true)
end
for k,v in pairs(expansion.precondition_target_optional) do
local smart_obj = self.faction.board.smarts_by_names[v]
self:register_target_point(smart_obj, true)
end
for k,v in pairs(expansion.precondition_target_eliminate) do
local smart_obj = self.faction.board.smarts_by_names[v]
local smart_owner = smart_obj.player_name
if smart_owner ~= "none" then
if game_relations.is_factions_enemies(self.faction.player_name, smart_owner) then
self:register_target_point(smart_obj, false, true)
end
end
end
end
-- Ðåãèñòðèò òàðãåò ñìàðò. Ïðè ýòîì ìîæåò èçìåíèòü åãî êàïàñèòè
function faction_brain_human:register_target_point(smart_obj, advance_point, eliminate, no_task)
local point_capacity = smart_obj.squad_capacity
--printf("faction [%s] register_target_point [%s]", self.faction.player_name, smart_obj:name())
--printf(" name %s == %s", smart_obj.player_name, self.faction.player_name)
if smart_obj.player_name == self.faction.player_name or smart_obj.player_name == "none" then
-- Åñëè òî÷êà óæå çàõâà÷åíà èëè ïóñòàÿ
-- Ïðîâåðÿåì åñòü ëè â ñîñåäíèõ òî÷êàõ âðàãè
local enemy_exist = false
for k,v in pairs(self.faction.board:get_nearest_smarts(smart_obj)) do
if game_relations.is_factions_enemies(v.player_name, self.faction.player_name) then
enemy_exist = true
break
end
end
--printf(" enemy exist %s", tostring(enemy_exist))
-- if not enemy_exist then
-- Åñëè òî÷êà ïðèíàäëåæèò ãðóïïèðîâêå è âîêðóã íåò âðàãîâ - óìåíüøàåì êàïàñèòè äî 1.
-- Îäíàêî åñëè òî÷êà ìåãàâàæíàÿ (åñòü ôëàæîê), òî âñåãäà ñòàðàåìñÿ çàïîëíèòü äî ìàêñèìóìà.
--printf(" important_point %s", tostring(smart_obj.important_point))
if not smart_obj.important_point then
point_capacity = 1
else
if smart_obj.respawn_sector ~= nil then
point_capacity = point_capacity - 1
end
end
-- else
-- Åñëè òî÷êà - ìåñòî ïîÿâëåíèÿ îòðÿäà, òî îñòàâëÿåì îêîøêî â 1, ÷òîáû ìîã ïîÿâèòüñÿ íîâûé îòðÿä.
-- if smart_obj.respawn_sector ~= nil then
-- point_capacity = point_capacity - 1
-- end
-- end
end
self.faction.target_smart_value[smart_obj.id] = {smart = smart_obj, cap = point_capacity, num = 0, smart_name = smart_obj:name(),
smart_id = smart_obj.id, advance_point = advance_point, eliminate = eliminate, no_task = no_task}
--printf(" cap %s", point_capacity)
end
-- Âûäàåì èãðîêó êâåñòû íà îñíîâå âûáðàííûõ öåëåé äëÿ ãðóïïèðîâêè
function faction_brain_human:reset_actor_tasks()
--printf("faction [%s] reset_actor_tasks", self.faction.player_name)
--callstack()
--print_table(self.faction.target_smart_value)
local tm = task_manager.get_task_manager()
local faction = self.faction
self.interfirience_points = {}
-- Òåïåðü îïðåäåëÿåì òî÷êè, êîòîðûå ìåøàþò ïðîéòè íàøèì îòðÿäàì.
for k,squad in pairs(faction.squads) do
-- áåæèì ïî îòðÿäàì
-- Âûáèðàåì êîòîðûå stay_point
local current_action = squad.current_action
if current_action ~= nil then
if current_action.name == "stay_point" then
--printf("CHECK interfirience squad %s next_point_id %s", squad.squad_id, tostring(current_action.next_point_id))
if current_action.next_point_id ~= nil then
-- Áåðåì ó íèõ next_point_id
local point = faction.board.smarts[current_action.next_point_id].smrt
if faction.target_smart_value[current_action.next_point_id] ~= nil then
--printf("found allies [%s] for [%s]", squad.squad_id, point:name())
faction.target_smart_value[current_action.next_point_id].allies_exist = true
else
-- Èç next_point óáèðàåì òî÷êè, êîòîðûå ïîä àòàêîé.
--printf("CHECK interfirience %s under_attack %s", point:name(), tostring(point.combat_manager:point_under_attack()))
if not point.combat_manager:point_under_attack() and
game_relations.is_factions_enemies(squad.player_id, point.player_name)
then
-- Äîáàâëÿåì â ñïèñîê ïîìåõ.
--printf("ADD interfirience point %s", point:name())
self.interfirience_points[point.id] = point
end
end
end
else
-- Íà ñëó÷àé àòàêè áîëåå ñèëüíîãî ïðîòèâíèêà.
local point = faction.board.smarts[current_action.dest_smrt_id].smrt
if faction.target_smart_value[current_action.dest_smrt_id] ~= nil then
--printf("found allies [%s] for [%s]", squad.squad_id, point:name())
faction.target_smart_value[current_action.dest_smrt_id].allies_exist = true
else
--printf("CHECK attack interfirience %s", point:name())
if not point.combat_manager:point_under_attack() and
game_relations.is_factions_enemies(squad.player_id, point.player_name)
then
-- Äîáàâëÿåì â ñïèñîê ïîìåõ.
--printf("ADD attack interfirience point %s", point:name())
self.interfirience_points[point.id] = point
end
end
end
end
end
end
--' Âûäà÷à òàñêà èãðîêó íà òî÷êó äëÿ çàõâàòà
function faction_brain_human:init_player_task(target_data)
--printf("IPT [%s] smart %s", self.faction.player_name, target_data.smart_name)
--if target_data.no_task == true then
-- return
--end
-- Âàæíàÿ ëè òî÷êà.
local advance_point = target_data.advance_point
local eliminate_point = target_data.eliminate
local allies_exist = target_data.allies_exist == true
local smart = target_data.smart
if smart.player_name == self.faction.player_name then
--printf(" my smart")
return
end
if sim_board.faction_cluster[self.faction.player_name] ~= sim_board.sim_level_cluster[smart.smart_level] then
--printf(" cluster")
return
end
local obj_gv = game_graph():vertex(db.actor:game_vertex_id())
local job_gv = game_graph():vertex(smart.m_game_vertex_id )
local empty_point = smart.player_name == "none"
local enemy_point = game_relations.is_factions_enemies(self.faction.player_name, smart.player_name)
local actor_in_radius = db.actor:position():distance_to_sqr(smart.position) <= TASK_DISTANCE
local actor_in_level = obj_gv:level_id() == job_gv:level_id()
-- Îïðåäåëÿåì êàêîé òèï òàñêà, ìû äîëæíû ùàñ âûäàòü
local task_type = nil
--[[if eliminate_point == true then
if enemy_point then
task_type = "eliminate_smart"
end
elseif advance_point then
if actor_in_level then
task_type = "capture_smart"
end
elseif not empty_point then
if enemy_point then
if allies_exist then
task_type = "capture_smart"
else
if actor_in_level and actor_in_radius then
task_type = "eliminate_smart"
end
end
end
end]]--
if task_type == nil then
--printf(" no type")
return
end
local tm = task_manager.get_task_manager()
local faction = self.faction
-- Ñðàâíèâàåì ñ òåêóùèì. Åñëè îíè ðàçíûå, òî äèçàáëèì òåêóùèé òàñê è âûäàåì íîâûé.
local current_faction_task = faction.random_tasks[smart.id]
if current_faction_task ~= nil then
local current_task = tm:get_task_by_entity_id(current_faction_task)
if current_task.type == task_type then
return
end
task.last_check_task = "reversed"
return
end
local task = tm:select_task(task_type, smart, self.faction.player_name)
task.faction = self.faction
self.faction.random_tasks[smart.id] = task.entity_id
if task.status ~= "selected" then
task:give_task(self.faction.player_name)
end
end