Micro AIs: fix some MAIs not working under shroud

This is done by ignoring shroud for path finding (while still taking
hidden units into account correctly), consistent with default Wesnoth
AI behavior.
This commit is contained in:
mattsc 2016-12-09 18:59:52 -08:00
parent 36b2b4e9a7
commit 3236a4b085
8 changed files with 22 additions and 18 deletions

View file

@ -149,7 +149,7 @@ function ca_assassin_move:execution(cfg)
-- We need to pick the farthest reachable hex along that path -- We need to pick the farthest reachable hex along that path
local farthest_hex = path[1] local farthest_hex = path[1]
for i = 2,#path do for i = 2,#path do
local sub_path, sub_cost = wesnoth.find_path(unit, path[i][1], path[i][2]) local sub_path, sub_cost = AH.find_path_with_shroud(unit, path[i][1], path[i][2])
if sub_cost <= unit.moves then if sub_cost <= unit.moves then
local unit_in_way = wesnoth.get_unit(path[i][1], path[i][2]) local unit_in_way = wesnoth.get_unit(path[i][1], path[i][2])
if (not AH.is_visible_unit(wesnoth.current.side, unit_in_way)) then if (not AH.is_visible_unit(wesnoth.current.side, unit_in_way)) then

View file

@ -26,7 +26,7 @@ local function bottleneck_is_my_territory(map, enemy_map)
-- Find lowest movement cost to own front-line hexes -- Find lowest movement cost to own front-line hexes
local min_cost, best_path = 9e99 local min_cost, best_path = 9e99
map:iter(function(xm, ym, v) map:iter(function(xm, ym, v)
local path, cost = wesnoth.find_path(dummy_unit, xm, ym, { ignore_units = true }) local path, cost = AH.find_path_with_shroud(dummy_unit, xm, ym, { ignore_units = true })
if (cost < min_cost) then if (cost < min_cost) then
min_cost, best_path = cost, path min_cost, best_path = cost, path
end end
@ -35,7 +35,7 @@ local function bottleneck_is_my_territory(map, enemy_map)
-- And the same to the enemy front line -- And the same to the enemy front line
local min_cost_enemy, best_path_enemy = 9e99 local min_cost_enemy, best_path_enemy = 9e99
enemy_map:iter(function(xm, ym, v) enemy_map:iter(function(xm, ym, v)
local path, cost = wesnoth.find_path(dummy_unit, xm, ym, { ignore_units = true }) local path, cost = AH.find_path_with_shroud(dummy_unit, xm, ym, { ignore_units = true })
if (cost < min_cost_enemy) then if (cost < min_cost_enemy) then
min_cost_enemy, best_path_enemy = cost, path min_cost_enemy, best_path_enemy = cost, path
end end

View file

@ -147,8 +147,8 @@ function ca_fast_move:execution(cfg)
for _,unit_info in ipairs(goal) do for _,unit_info in ipairs(goal) do
if (not unit_info.cost) then if (not unit_info.cost) then
local _,cost = local _,cost =
wesnoth.find_path( AH.find_path_with_shroud(
units[unit_info.i_unit].x, units[unit_info.i_unit].y, units[unit_info.i_unit],
goal.x, goal.y, goal.x, goal.y,
{ ignore_units = true } { ignore_units = true }
) )
@ -172,13 +172,13 @@ function ca_fast_move:execution(cfg)
-- We now want the hex that is 2 steps beyond the next hop for the unit -- We now want the hex that is 2 steps beyond the next hop for the unit
-- on its way toward the goal, ignoring any unit along the way -- on its way toward the goal, ignoring any unit along the way
local path = wesnoth.find_path(unit, goal.x, goal.y, { ignore_units = true }) local path = AH.find_path_with_shroud(unit, goal.x, goal.y, { ignore_units = true })
-- Use current unit position as default -- Use current unit position as default
local short_goal, index = { unit.x, unit.y }, 1 local short_goal, index = { unit.x, unit.y }, 1
for i = 2,#path do for i = 2,#path do
local _, sub_cost = wesnoth.find_path(unit, path[i][1], path[i][2], { ignore_units = true }) local _, sub_cost = AH.find_path_with_shroud(unit, path[i][1], path[i][2], { ignore_units = true })
if (sub_cost <= unit.moves) then if (sub_cost <= unit.moves) then
short_goal, index = path[i], i short_goal, index = path[i], i
@ -254,7 +254,7 @@ function ca_fast_move:execution(cfg)
if (pre_rating.rating <= max_rating) then break end if (pre_rating.rating <= max_rating) then break end
unit.x, unit.y = pre_rating.x, pre_rating.y unit.x, unit.y = pre_rating.x, pre_rating.y
local _,cost = wesnoth.find_path(unit, short_goal[1], short_goal[2]) local _,cost = AH.find_path_with_shroud(unit, short_goal[1], short_goal[2])
local rating = - cost + pre_rating.other_rating local rating = - cost + pre_rating.other_rating

View file

@ -65,6 +65,10 @@ function ca_forest_animals_new_rabbit:execution(cfg)
.. "' }, x1, y1)" .. "' }, x1, y1)"
ai.synced_command(command, x, y) ai.synced_command(command, x, y)
end end
if wesnoth.sides[wesnoth.current.side].shroud then
wesnoth.wml_actions.redraw { side = wesnoth.current.side }
end
end end
return ca_forest_animals_new_rabbit return ca_forest_animals_new_rabbit

View file

@ -152,7 +152,7 @@ function ca_goto:execution(cfg, data)
enemy_at_goal = nil enemy_at_goal = nil
end end
end end
path, cost = wesnoth.find_path(unit, loc[1], loc[2], { ignore_units = cfg.ignore_units }) path, cost = AH.find_path_with_shroud(unit, loc[1], loc[2], { ignore_units = cfg.ignore_units })
if enemy_at_goal then if enemy_at_goal then
wesnoth.put_unit(enemy_at_goal) wesnoth.put_unit(enemy_at_goal)
--- Give massive penalty for this goal hex --- Give massive penalty for this goal hex
@ -193,13 +193,13 @@ function ca_goto:execution(cfg, data)
-- rather than using ai_helper.next_hop for standard pathfinding -- rather than using ai_helper.next_hop for standard pathfinding
-- Also, straight-line does not produce a path, so we do that first -- Also, straight-line does not produce a path, so we do that first
if not best_path then if not best_path then
best_path = wesnoth.find_path(best_unit, closest_hex[1], closest_hex[2]) best_path = AH.find_path_with_shroud(best_unit, closest_hex[1], closest_hex[2])
end end
-- Now go through the hexes along that path, use normal path finding -- Now go through the hexes along that path, use normal path finding
closest_hex = best_path[1] closest_hex = best_path[1]
for i = 2,#best_path do for i = 2,#best_path do
local sub_path, sub_cost = wesnoth.find_path(best_unit, best_path[i][1], best_path[i][2], cfg) local sub_path, sub_cost = AH.find_path_with_shroud(best_unit, best_path[i][1], best_path[i][2], cfg)
if sub_cost <= best_unit.moves then if sub_cost <= best_unit.moves then
local unit_in_way = wesnoth.get_unit(best_path[i][1], best_path[i][2]) local unit_in_way = wesnoth.get_unit(best_path[i][1], best_path[i][2])
if (not AH.is_visible_unit(wesnoth.current.side, unit_in_way)) then if (not AH.is_visible_unit(wesnoth.current.side, unit_in_way)) then

View file

@ -10,7 +10,7 @@ local function messenger_find_enemies_in_way(messenger, goal_x, goal_y)
-- @goal_x,@goal_y: coordinates of the goal toward which the messenger moves -- @goal_x,@goal_y: coordinates of the goal toward which the messenger moves
-- Returns proxy table for the first unit found, or nil if none was found -- Returns proxy table for the first unit found, or nil if none was found
local path, cost = wesnoth.find_path(messenger, goal_x, goal_y, { ignore_units = true }) local path, cost = AH.find_path_with_shroud(messenger, goal_x, goal_y, { ignore_units = true })
if cost >= 42424242 then return end if cost >= 42424242 then return end
-- The second path hex is the first that is important for the following analysis -- The second path hex is the first that is important for the following analysis
@ -23,7 +23,7 @@ local function messenger_find_enemies_in_way(messenger, goal_x, goal_y)
-- After that, go through adjacent hexes of all the other path hexes -- After that, go through adjacent hexes of all the other path hexes
for i = 2,#path do for i = 2,#path do
local sub_path, sub_cost = wesnoth.find_path(messenger, path[i][1], path[i][2], { ignore_units = true }) local sub_path, sub_cost = AH.find_path_with_shroud(messenger, path[i][1], path[i][2], { ignore_units = true })
if (sub_cost <= messenger.moves) then if (sub_cost <= messenger.moves) then
for xa,ya in H.adjacent_tiles(path[i][1], path[i][2]) do for xa,ya in H.adjacent_tiles(path[i][1], path[i][2]) do
local enemy = wesnoth.get_unit(xa, ya) local enemy = wesnoth.get_unit(xa, ya)

View file

@ -30,10 +30,10 @@ function ca_messenger_move:execution(cfg)
if (not next_hop) then next_hop = { messenger.x, messenger.y } end if (not next_hop) then next_hop = { messenger.x, messenger.y } end
-- Compare this to the "ideal path" -- Compare this to the "ideal path"
local path = wesnoth.find_path(messenger, x, y, { ignore_units = 'yes' }) local path = AH.find_path_with_shroud(messenger, x, y, { ignore_units = 'yes' })
local optimum_hop, optimum_cost = { messenger.x, messenger.y }, 0 local optimum_hop, optimum_cost = { messenger.x, messenger.y }, 0
for _,step in ipairs(path) do for _,step in ipairs(path) do
local sub_path, sub_cost = wesnoth.find_path(messenger, step[1], step[2]) local sub_path, sub_cost = AH.find_path_with_shroud(messenger, step[1], step[2])
if sub_cost > messenger.moves then if sub_cost > messenger.moves then
break break
else else
@ -61,14 +61,14 @@ function ca_messenger_move:execution(cfg)
if unit_in_way then wesnoth.extract_unit(unit_in_way) end if unit_in_way then wesnoth.extract_unit(unit_in_way) end
wesnoth.put_unit(messenger, next_hop[1], next_hop[2]) wesnoth.put_unit(messenger, next_hop[1], next_hop[2])
local _, cost1 = wesnoth.find_path(messenger, x, y, { ignore_units = 'yes' }) local _, cost1 = AH.find_path_with_shroud(messenger, x, y, { ignore_units = 'yes' })
local unit_in_way2 = wesnoth.get_unit(optimum_hop[1], optimum_hop[2]) local unit_in_way2 = wesnoth.get_unit(optimum_hop[1], optimum_hop[2])
if (unit_in_way2 == messenger) then unit_in_way2 = nil end if (unit_in_way2 == messenger) then unit_in_way2 = nil end
if unit_in_way2 then wesnoth.extract_unit(unit_in_way2) end if unit_in_way2 then wesnoth.extract_unit(unit_in_way2) end
wesnoth.put_unit(messenger, optimum_hop[1], optimum_hop[2]) wesnoth.put_unit(messenger, optimum_hop[1], optimum_hop[2])
local _, cost2 = wesnoth.find_path(messenger, x, y, { ignore_units = 'yes' }) local _, cost2 = AH.find_path_with_shroud(messenger, x, y, { ignore_units = 'yes' })
wesnoth.put_unit(messenger, x_current, y_current) wesnoth.put_unit(messenger, x_current, y_current)
if unit_in_way then wesnoth.put_unit(unit_in_way) end if unit_in_way then wesnoth.put_unit(unit_in_way) end

View file

@ -8,7 +8,7 @@ function ca_protect_unit_finish:evaluation(cfg)
for u in H.child_range(cfg, "unit") do for u in H.child_range(cfg, "unit") do
local unit = AH.get_units_with_moves { id = u.id }[1] local unit = AH.get_units_with_moves { id = u.id }[1]
if unit then if unit then
local path, cost = wesnoth.find_path(unit, u.goal_x, u.goal_y) local path, cost = AH.find_path_with_shroud(unit, u.goal_x, u.goal_y)
if (cost <= unit.moves) and ((unit.x ~= u.goal_x) or (unit.y ~= u.goal_y)) then if (cost <= unit.moves) and ((unit.x ~= u.goal_x) or (unit.y ~= u.goal_y)) then
PU_unit = unit PU_unit = unit
PU_goal = { u.goal_x, u.goal_y } PU_goal = { u.goal_x, u.goal_y }