wesnoth/data/ai/micro_ais/cas/ca_simple_attack.lua
mattsc b302289402 Micro AIs: correctly deal with hidden and petrified enemies
Previously, the Micro AI behavior was inconsistent at best when it came
to dealing with these units and could even result in AI errors when an
AI unit was ambushed or a petrified unit was in the way of a move. Now,
both types of units are properly "ignored" and the AI moves have been
made robust against unexpected events such as ambushes. Incidentally,
the latter also makes the AI more robust against WML events doing
things the AI cannot know about (such as removing units).
2016-10-16 19:59:19 -07:00

64 lines
1.9 KiB
Lua

local H = wesnoth.require "lua/helper.lua"
local AH = wesnoth.require "ai/lua/ai_helper.lua"
local BC = wesnoth.require "ai/lua/battle_calcs.lua"
local LS = wesnoth.require "lua/location_set.lua"
local ca_simple_attack, best_attack = {}
function ca_simple_attack:evaluation(cfg)
local units = AH.get_units_with_attacks {
side = wesnoth.current.side,
{ "and", H.get_child(cfg, "filter") }
}
if (not units[1]) then return 0 end
-- If cfg.filter_second is set, set up a map (location set)
-- of enemies that it is okay to attack
local enemy_filter = H.get_child(cfg, "filter_second")
local enemy_map
if enemy_filter then
local enemies = AH.get_attackable_enemies(enemy_filter)
if (not enemies[1]) then return 0 end
enemy_map = LS.create()
for _,enemy in ipairs(enemies) do enemy_map:insert(enemy.x, enemy.y) end
end
-- Now find the best of the possible attacks
local attacks = AH.get_attacks(units, { include_occupied = true })
if (not attacks[1]) then return 0 end
local max_rating = -9e99
for _, att in ipairs(attacks) do
local valid_target = true
if enemy_filter and (not enemy_map:get(att.target.x, att.target.y)) then
valid_target = false
end
if valid_target then
local attacker = wesnoth.get_unit(att.src.x, att.src.y)
local enemy = wesnoth.get_unit(att.target.x, att.target.y)
local dst = { att.dst.x, att.dst.y }
local rating = BC.attack_rating(attacker, enemy, dst)
if (rating > max_rating) then
max_rating, best_attack = rating, att
end
end
end
if best_attack then
return cfg.ca_score
end
return 0
end
function ca_simple_attack:execution(cfg)
AH.robust_move_and_attack(ai, best_attack.src, best_attack.dst, best_attack.target, cfg)
best_attack = nil
end
return ca_simple_attack