diff --git a/data/ai/micro_ais/cas/ca_wolves_move.lua b/data/ai/micro_ais/cas/ca_wolves_move.lua index fae25dc56399..bb82f11e093b 100644 --- a/data/ai/micro_ais/cas/ca_wolves_move.lua +++ b/data/ai/micro_ais/cas/ca_wolves_move.lua @@ -22,7 +22,18 @@ local ca_wolves_move = {} function ca_wolves_move:evaluation(cfg) if (not get_wolves(cfg)[1]) then return 0 end - if (not get_prey(cfg)[1]) then return 0 end + + local avoid_map = AH.get_avoid_map(ai, nil, true) + local prey = get_prey(cfg) + local prey_found = false + for _,prey_unit in ipairs(prey) do + if (not avoid_map:get(prey_unit.x, prey_unit.y)) then + prey_found = true + break + end + end + if (not prey_found) then return 0 end + return cfg.ca_score end @@ -30,18 +41,23 @@ function ca_wolves_move:execution(cfg) local wolves = get_wolves(cfg) local prey = get_prey(cfg) + -- Only default AI [avoid] tag makes sense for the wolves since attacks are done by RCA AI + local avoid_map = AH.get_avoid_map(ai, nil, true) + local avoid_units = AH.get_attackable_enemies({ type = cfg.avoid_type }) - local avoid_map = BC.get_attack_map(avoid_units).units + local avoid_enemies_map = BC.get_attack_map(avoid_units).units -- Find prey that is closest to the wolves local min_dist, target = math.huge for _,prey_unit in ipairs(prey) do - local dist = 0 - for _,wolf in ipairs(wolves) do - dist = dist + M.distance_between(wolf.x, wolf.y, prey_unit.x, prey_unit.y) - end - if (dist < min_dist) then - min_dist, target = dist, prey_unit + if (not avoid_map:get(prey_unit.x, prey_unit.y)) then + local dist = 0 + for _,wolf in ipairs(wolves) do + dist = dist + M.distance_between(wolf.x, wolf.y, prey_unit.x, prey_unit.y) + end + if (dist < min_dist) then + min_dist, target = dist, prey_unit + end end end @@ -61,12 +77,12 @@ function ca_wolves_move:execution(cfg) if (height - y <= 5) then rating = rating - (6 - (height - y)) / 1.4 end -- Hexes that avoid_type units can reach get a massive penalty - if avoid_map:get(x, y) then rating = rating - 1000 end + if avoid_enemies_map:get(x, y) then rating = rating - 1000 end return rating - end) + end, { avoid_map = avoid_map }) - local move_result = AH.movefull_stopunit(ai, wolves[1], wolf1) + local move_result = AH.movefull_stopunit(ai, wolves[1], wolf1 or { wolf1.x, wolf1.y }) -- If the wolf was ambushed, return and reconsider; also if an event removed a wolf if (AH.is_incomplete_move(move_result)) then return end for _,check_wolf in ipairs(wolves) do @@ -90,12 +106,12 @@ function ca_wolves_move:execution(cfg) rating = rating - (dist_t - dist_1t)^2 -- Hexes that avoid_type units can reach get a massive penalty - if avoid_map:get(x, y) then rating = rating - 1000 end + if avoid_enemies_map:get(x, y) then rating = rating - 1000 end return rating - end) + end, { avoid_map = avoid_map }) - local move_result = AH.movefull_stopunit(ai, wolves[i], move) + local move_result = AH.movefull_stopunit(ai, wolves[i], move or { wolves[i].x, wolves[i].y }) -- If the wolf was ambushed, return and reconsider; also if an event removed a wolf if (AH.is_incomplete_move(move_result)) then return end for _,check_wolf in ipairs(wolves) do diff --git a/data/ai/micro_ais/cas/ca_wolves_wander.lua b/data/ai/micro_ais/cas/ca_wolves_wander.lua index 51923a071f9e..3f8d75fbf4e0 100644 --- a/data/ai/micro_ais/cas/ca_wolves_wander.lua +++ b/data/ai/micro_ais/cas/ca_wolves_wander.lua @@ -21,20 +21,23 @@ end function ca_wolves_wander:execution(cfg) local wolves = get_wolves(cfg) + -- Only default AI [avoid] tag makes sense for the wolves + local avoid_map = AH.get_avoid_map(ai, nil, true) + -- Number of wolves that can reach each hex local reach_map = LS.create() for _,wolf in ipairs(wolves) do - local r = AH.get_reachable_unocc(wolf) + local r = AH.get_reachable_unocc(wolf, { avoid_map = avoid_map }) reach_map:union_merge(r, function(x, y, v1, v2) return (v1 or 0) + (v2 or 0) end) end local avoid_units = AH.get_attackable_enemies({ type = cfg.avoid_type }) - local avoid_map = BC.get_attack_map(avoid_units).units + local avoid_enemies_map = BC.get_attack_map(avoid_units).units local max_rating, goal_hex = - math.huge reach_map:iter( function (x, y, v) local rating = v + math.random(99)/100. - if avoid_map:get(x, y) then rating = rating - 1000 end + if avoid_enemies_map:get(x, y) then rating = rating - 1000 end if (rating > max_rating) then max_rating, goal_hex = rating, { x, y } @@ -47,11 +50,11 @@ function ca_wolves_wander:execution(cfg) -- For each wolf, we need to check that goal hex is reachable, and out of harm's way local best_hex = AH.find_best_move(wolf, function(x, y) local rating = -wesnoth.map.distance_between(x, y, goal_hex[1], goal_hex[2]) - if avoid_map:get(x, y) then rating = rating - 1000 end + if avoid_enemies_map:get(x, y) then rating = rating - 1000 end return rating - end) + end, { avoid_map = avoid_map }) - local move_result = AH.movefull_stopunit(ai, wolf, best_hex) + local move_result = AH.movefull_stopunit(ai, wolf, best_hex or { wolf.x, wolf.y }) -- If the wolf was ambushed, return and reconsider; also if an event removed a wolf if (AH.is_incomplete_move(move_result)) then return end for _,check_wolf in ipairs(wolves) do