diff --git a/data/ai/lua/ca_castle_switch.lua b/data/ai/lua/ca_castle_switch.lua index 842c64c8dc3..37e90267361 100644 --- a/data/ai/lua/ca_castle_switch.lua +++ b/data/ai/lua/ca_castle_switch.lua @@ -58,7 +58,10 @@ end local ca_castle_switch = {} -function ca_castle_switch:evaluation(cfg, data, filter_own) +function ca_castle_switch:evaluation(cfg, data, filter_own, recruiting_leader) + -- @recruiting_leader is passed from the recuit_rushers CA for the leader_takes_village() + -- evaluation. If it is set, we do the castle switch evaluation only for that leader + local start_time, ca_name = wesnoth.get_time_stamp() / 1000., 'castle_switch' if AH.print_eval() then AH.print_ts(' - Evaluating castle_switch CA:') end @@ -67,12 +70,19 @@ function ca_castle_switch:evaluation(cfg, data, filter_own) return 0 end - local leaders = AH.get_units_with_moves({ - side = wesnoth.current.side, - canrecruit = 'yes', - formula = '(movement_left = total_movement) and (hitpoints = max_hitpoints)', - { "and", filter_own } - }, true) + local leaders + if recruiting_leader then + -- Note that doing this might set the stored castle switch information to a different leader. + -- This is fine though, the order in which these are done is not particularly important. + leaders = { recruiting_leader } + else + leaders = AH.get_units_with_moves({ + side = wesnoth.current.side, + canrecruit = 'yes', + formula = '(movement_left = total_movement) and (hitpoints = max_hitpoints)', + { "and", filter_own } + }, true) + end if (not leaders[1]) then -- CA is irrelevant if no leader or the leader may have moved from another CA @@ -85,7 +95,9 @@ function ca_castle_switch:evaluation(cfg, data, filter_own) local avoid_map = AH.get_avoid_map(ai, nil, true) - if data.CS_leader and wesnoth.sides[wesnoth.current.side].gold >= cheapest_unit_cost then + if data.CS_leader and wesnoth.sides[wesnoth.current.side].gold >= cheapest_unit_cost + and ((not recruiting_leader) or (recruiting_leader.id == data.CS_leader.id)) + then -- If the saved score is the low score, check whether there are still other units on the keep if (CS_leader_score == low_score) then CS_leader_score = other_units_on_keep(data.CS_leader) diff --git a/data/ai/lua/ca_recruit_rushers.lua b/data/ai/lua/ca_recruit_rushers.lua index 3a0d695ad3c..9651086061d 100644 --- a/data/ai/lua/ca_recruit_rushers.lua +++ b/data/ai/lua/ca_recruit_rushers.lua @@ -17,8 +17,8 @@ local dummy_engine = { data = {} } local params = { score_function = (function() return 196000 end) } if ca_castle_switch then params.min_turn_1_recruit = (function() return ca_castle_switch:evaluation({}, dummy_engine.data) > 0 end) - params.leader_takes_village = (function() - if ca_castle_switch:evaluation({}, dummy_engine.data) > 0 then + params.leader_takes_village = (function(leader) + if ca_castle_switch:evaluation({}, dummy_engine.data, nil, leader) > 0 then local take_village = #(wesnoth.get_villages { x = dummy_engine.data.CS_leader_target[1], y = dummy_engine.data.CS_leader_target[2] diff --git a/data/ai/lua/generic_recruit_engine.lua b/data/ai/lua/generic_recruit_engine.lua index d770d265e18..a3a9aed3085 100644 --- a/data/ai/lua/generic_recruit_engine.lua +++ b/data/ai/lua/generic_recruit_engine.lua @@ -928,7 +928,7 @@ return { data.castle.assigned_villages_x = {} data.castle.assigned_villages_y = {} - if not ai.aspects.passive_leader and (not params.leader_takes_village or params.leader_takes_village()) then + if not ai.aspects.passive_leader and (not params.leader_takes_village or params.leader_takes_village(leader)) then -- skip one village for the leader for i,v in ipairs(villages) do local path, cost = wesnoth.find_path(leader, v[1], v[2], {max_cost = leader.max_moves+1})