local H = wesnoth.require "lua/helper.lua" local AH = wesnoth.require "ai/lua/ai_helper.lua" local ca_swarm_move = {} function ca_swarm_move:evaluation(ai, cfg) local units = wesnoth.get_units { side = wesnoth.current.side } for _,unit in ipairs(units) do if (unit.moves > 0) then return cfg.ca_score end end return 0 end function ca_swarm_move:execution(ai, cfg) local enemy_distance = cfg.enemy_distance or 5 local vision_distance = cfg.vision_distance or 12 -- If no close enemies, swarm will move semi-randomly, staying close together, but away from enemies local all_units = wesnoth.get_units { side = wesnoth.current.side } local units, units_no_moves = {}, {} for _,unit in ipairs(all_units) do if (unit.moves > 0) then table.insert(units, unit) else table.insert(units_no_moves, unit) end end local enemies = wesnoth.get_units { { "filter_side", { { "enemy_of", {side = wesnoth.current.side } } } } } -- Pick one unit at random, swarm does not move systematically local unit = units[math.random(#units)] -- Find best place for that unit to move to local best_hex = AH.find_best_move(unit, function(x, y) local rating = 0 -- Only units within 'vision_distance' count for rejoining local close_units_no_moves = {} for _,unit_noMP in ipairs(units_no_moves) do if (H.distance_between(unit.x, unit.y, unit_noMP.x, unit_noMP.y) <= vision_distance) then table.insert(close_units_no_moves, unit_noMP) end end -- If all units on the side have moves left, simply go to a hex far away if (not close_units_no_moves[1]) then rating = rating + H.distance_between(x, y, unit.x, unit.y) else -- Otherwise, minimize distance from units that have already moved for _,close_unit in ipairs(close_units_no_moves) do rating = rating - H.distance_between(x, y, close_unit.x, close_unit.y) end end -- We also try to stay out of attack range of any enemy for _,enemy in ipairs(enemies) do local dist = H.distance_between(x, y, enemy.x, enemy.y) if (dist < enemy_distance) then rating = rating - (enemy_distance - dist) * 10. end end return rating end) AH.movefull_stopunit(ai, unit, best_hex) end return ca_swarm_move