diff --git a/data/ai/micro_ais/cas/ca_messenger_move.lua b/data/ai/micro_ais/cas/ca_messenger_move.lua index 7f616691b91..c7eee242c62 100644 --- a/data/ai/micro_ais/cas/ca_messenger_move.lua +++ b/data/ai/micro_ais/cas/ca_messenger_move.lua @@ -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)