------- Village Hunt CA -------------- -- Give extra priority to seeking villages if we have less than our share. -- Our share is defined as being slightly more than the total/the number of sides, -- but only in the area not prohibited by an [avoid] directive. local AH = wesnoth.require "ai/lua/ai_helper.lua" local LS = wesnoth.require "location_set" local VH_unit, VH_dst = {}, {} local ca_village_hunt = {} function ca_village_hunt:evaluation(cfg, data, filter_own) local start_time, ca_name = wesnoth.ms_since_init() / 1000., 'village_hunt' if AH.print_eval() then AH.print_ts(' - Evaluating village_hunt CA:') end local avoid_map1 = LS.of_pairs(ai.aspects.avoid) local all_villages, villages = wesnoth.map.find{gives_income = true}, {} for _,village in ipairs(all_villages) do if (not avoid_map1:get(village[1], village[2])) then table.insert(villages, village) end end if (not villages[1]) then if AH.print_eval() then AH.done_eval_messages(start_time, ca_name) end return 0 end local n_my_villages, n_allied_villages = 0, 0 for _,village in ipairs(villages) do local owner = wesnoth.map.get_owner(village) or -1 if (owner == wesnoth.current.side) then n_my_villages = n_my_villages + 1 end if (owner ~= -1) and (not wesnoth.sides.is_enemy(owner, wesnoth.current.side)) then n_allied_villages = n_allied_villages + 1 end end if (n_my_villages > #villages / #wesnoth.sides) then if AH.print_eval() then AH.done_eval_messages(start_time, ca_name) end return 0 end if (n_allied_villages == #villages) then if AH.print_eval() then AH.done_eval_messages(start_time, ca_name) end return 0 end local units = AH.get_units_with_moves({ side = wesnoth.current.side, canrecruit = 'no', { "and", filter_own } }, true) if (not units[1]) then if AH.print_eval() then AH.done_eval_messages(start_time, ca_name) end return 0 end local avoid_map2 = AH.get_avoid_map(ai, nil, true) VH_unit = nil for _,unit in ipairs(units) do local best_cost = AH.no_path for i,v in ipairs(villages) do if not wesnoth.map.matches(v, { {"filter_owner", { {"ally_of", { side = wesnoth.current.side }} }} }) then local path, cost = AH.find_path_with_avoid(unit, v[1], v[2], avoid_map2) if (cost < best_cost) then local dst = AH.next_hop(unit, nil, nil, { path = path, avoid_map = avoid_map2 }) if (dst[1] ~= unit.x) or (dst[2] ~= unit.y) then best_cost = cost VH_unit = unit VH_dst = dst end end end end end if (not VH_unit) then if AH.print_eval() then AH.done_eval_messages(start_time, ca_name) end return 0 end if AH.print_eval() then AH.done_eval_messages(start_time, ca_name) end return 30000 end function ca_village_hunt:execution(cfg, data, filter_own) if AH.print_exec() then AH.print_ts(' Executing village_hunt CA') end AH.robust_move_and_attack(ai, VH_unit, VH_dst) VH_unit, VH_dst = nil, nil end return ca_village_hunt