Messenger MAI: fix bug with escort units blocking the messenger
When there were lots of escort units, they previously quite frequently blocked the messenger’s way, preventing him from making progress even when it was possible. Escort units now specifically move out of the way if they do not need to attack enemy units in the messenger’s way.
This commit is contained in:
parent
9e6b780306
commit
2d458b642a
1 changed files with 34 additions and 4 deletions
|
@ -21,21 +21,34 @@ function ca_messenger_move:execution(ai, cfg, self)
|
|||
local messenger = wesnoth.get_units{ id = cfg.id, formula = '$this_unit.moves > 0' }[1]
|
||||
|
||||
local x, y = messenger_next_waypoint(messenger, cfg, self)
|
||||
|
||||
if (messenger.x ~= x) or (messenger.y ~= y) then
|
||||
x, y = wesnoth.find_vacant_tile( x, y, messenger)
|
||||
local wp = AH.get_closest_location(
|
||||
{ x, y },
|
||||
{ { "not", { { "filter", { { "not", { side = wesnoth.current.side } } } } } } },
|
||||
messenger
|
||||
)
|
||||
x, y = wp[1], wp[2]
|
||||
end
|
||||
local next_hop = AH.next_hop(messenger, x, y)
|
||||
|
||||
local next_hop = AH.next_hop(messenger, x, y, { ignore_own_units = true } )
|
||||
if (not next_hop) then next_hop = { messenger.x, messenger.y } end
|
||||
|
||||
-- Compare this to the "ideal path"
|
||||
local path, cost = wesnoth.find_path(messenger, x, y, { ignore_units = 'yes' })
|
||||
local opt_hop, opt_cost = {messenger.x, messenger.y}, 0
|
||||
local opt_hop, opt_cost = { messenger.x, messenger.y }, 0
|
||||
for i, p in ipairs(path) do
|
||||
local sub_path, sub_cost = wesnoth.find_path(messenger, p[1], p[2])
|
||||
if sub_cost > messenger.moves then
|
||||
if sub_cost > messenger.moves then
|
||||
break
|
||||
else
|
||||
local unit_in_way = wesnoth.get_unit(p[1], p[2])
|
||||
|
||||
if unit_in_way and (unit_in_way.side == messenger.side) then
|
||||
local reach = AH.get_reachable_unocc(unit_in_way)
|
||||
if (reach:size() > 1) then unit_in_way = nil end
|
||||
end
|
||||
|
||||
if not unit_in_way then
|
||||
opt_hop, nh_cost = p, sub_cost
|
||||
end
|
||||
|
@ -45,11 +58,24 @@ function ca_messenger_move:execution(ai, cfg, self)
|
|||
--print(next_hop[1], next_hop[2], opt_hop[1], opt_hop[2])
|
||||
-- Now compare how long it would take from the end of both of these options
|
||||
local x1, y1 = messenger.x, messenger.y
|
||||
|
||||
local unit_in_way = wesnoth.get_unit(next_hop[1], next_hop[2])
|
||||
if (unit_in_way == messenger) then unit_in_way = nil end
|
||||
if unit_in_way then wesnoth.extract_unit(unit_in_way) end
|
||||
|
||||
wesnoth.put_unit(next_hop[1], next_hop[2], messenger)
|
||||
local tmp, cost1 = wesnoth.find_path(messenger, x, y, {ignore_units = 'yes'})
|
||||
|
||||
local unit_in_way2 = wesnoth.get_unit(opt_hop[1], opt_hop[2])
|
||||
if (unit_in_way2 == messenger) then unit_in_way2 = nil end
|
||||
if unit_in_way2 then wesnoth.extract_unit(unit_in_way2) end
|
||||
|
||||
wesnoth.put_unit(opt_hop[1], opt_hop[2], messenger)
|
||||
local tmp, cost2 = wesnoth.find_path(messenger, x, y, {ignore_units = 'yes'})
|
||||
|
||||
wesnoth.put_unit(x1, y1, messenger)
|
||||
if unit_in_way then wesnoth.put_unit(unit_in_way) end
|
||||
if unit_in_way2 then wesnoth.put_unit(unit_in_way2) end
|
||||
--print(cost1, cost2)
|
||||
|
||||
-- If cost2 is significantly less, that means that the other path might overall be faster
|
||||
|
@ -58,6 +84,10 @@ function ca_messenger_move:execution(ai, cfg, self)
|
|||
--print(next_hop[1], next_hop[2])
|
||||
|
||||
if next_hop and ((next_hop[1] ~= messenger.x) or (next_hop[2] ~= messenger.y)) then
|
||||
local unit_in_way = wesnoth.get_unit(next_hop[1], next_hop[2])
|
||||
if unit_in_way then AH.move_unit_out_of_way(ai, unit_in_way) end
|
||||
if (not messenger) or (not messenger.valid) then return end
|
||||
|
||||
AH.checked_move(ai, messenger, next_hop[1], next_hop[2])
|
||||
else
|
||||
AH.checked_stopunit_moves(ai, messenger)
|
||||
|
|
Loading…
Add table
Reference in a new issue