Micro AIs: add check for valid attacks and error message

This will now check whether the attack intended to be done with
ai.attack is possible and display an error message if it is not.
This commit is contained in:
mattsc 2014-02-27 09:08:16 -08:00
parent ca2eec45b9
commit 70e3fc58bd
16 changed files with 36 additions and 17 deletions

View file

@ -126,6 +126,24 @@ function ai_helper.print_ts_delta(start_time, ...)
return ts, delta
end
----- AI execution helper functions ------
function ai_helper.checked_action_error(action, error_code)
wesnoth.message('Lua AI error', 'If you see this message, something has gone wrong. Please report this on the Wesnoth forums, ideally with a replay and/or savegame.')
wesnoth.message('Lua AI error', action .. ' could not be executed. Error code: ' .. error_code)
end
function ai_helper.checked_attack(ai, attacker, defender, weapon)
local check = ai.check_attack(attacker, defender, weapon)
if (not check.ok) then
ai_helper.checked_action_error('ai.attack', check.status)
return
end
ai.attack(attacker, defender, weapon)
end
----- General functionality and maths helper functions ------
function ai_helper.filter(input, condition)

View file

@ -106,7 +106,7 @@ function ca_big_animals:execution(ai, cfg)
end
end
if target.id then
ai.attack(unit, target)
AH.checked_attack(ai, unit, target)
end
end

View file

@ -1,3 +1,4 @@
local AH = wesnoth.require "ai/lua/ai_helper.lua"
local H = wesnoth.require "lua/helper.lua"
local ca_bottleneck_attack = {}
@ -74,7 +75,7 @@ function ca_bottleneck_attack:execution(ai, cfg, self)
ai.stopunit_attacks(u)
end
else
ai.attack(self.data.attacker, self.data.target, self.data.weapon)
AH.checked_attack(ai, self.data.attacker, self.data.target, self.data.weapon)
end
self.data.attacker, self.data.target, self.data.weapon = nil, nil, nil

View file

@ -504,7 +504,7 @@ function ca_bottleneck_move:execution(ai, cfg, self)
if self.data.lu_defender then
--print("Level-up attack",self.data.unit.id, self.data.lu_defender.id, self.data.lu_weapon)
ai.attack(self.data.unit, self.data.lu_defender, self.data.lu_weapon)
AH.checked_attack(ai, self.data.unit, self.data.lu_defender, self.data.lu_weapon)
end
end

View file

@ -59,7 +59,7 @@ function ca_forest_animals_tusker_attack:execution(ai, cfg)
-- If adjacent, attack
local dist = H.distance_between(attacker.x, attacker.y, target.x, target.y)
if (dist == 1) then
ai.attack(attacker, target)
AH.checked_attack(ai, attacker, target)
else
ai.stopunit_attacks(attacker)
end

View file

@ -67,7 +67,7 @@ function ca_herding_attack_close_enemy:execution(ai, cfg)
--print('Dog moving in to attack')
AH.movefull_stopunit(ai, best_dog, best_hex)
if H.distance_between(best_dog.x, best_dog.y, best_enemy.x, best_enemy.y) == 1 then
ai.attack(best_dog, best_enemy)
AH.checked_attack(ai, best_dog, best_enemy)
end
return
end

View file

@ -27,7 +27,7 @@ local function hunter_attack_weakest_adj_enemy(ai, unit)
if target.id then
--W.message { speaker = unit.id, message = 'Attacking weakest adjacent enemy' }
ai.attack(unit, target)
AH.checked_attack(ai, unit, target)
if target.valid then
return 'attacked'
else
@ -157,7 +157,7 @@ function ca_hunter:execution(ai, cfg)
if cfg.show_messages then
W.message { speaker = unit.id, message = 'Get out of my home!' }
end
ai.attack(unit, enemy)
AH.checked_attack(ai, unit, enemy)
end
end
end

View file

@ -63,7 +63,7 @@ function ca_lurkers:execution(ai, cfg)
local rand = math.random(1, rattack_nt_target:size())
local dst = rattack_nt_target:to_stable_pairs()
AH.movefull_stopunit(ai, me, dst[rand])
ai.attack(dst[rand][1], dst[rand][2], target.x, target.y)
AH.checked_attack(ai, me, target)
attacked = true
break
end

View file

@ -156,7 +156,7 @@ function ca_messenger_attack:execution(ai, cfg, self)
local defender = wesnoth.get_unit(self.data.best_attack.target.x, self.data.best_attack.target.y)
AH.movefull_stopunit(ai, attacker, self.data.best_attack.dst.x, self.data.best_attack.dst.y)
ai.attack(attacker, defender)
AH.checked_attack(ai, attacker, defender)
self.data.best_attack = nil
end

View file

@ -100,7 +100,7 @@ function ca_messenger_move:execution(ai, cfg, self)
end
if max_rating > -9e99 then
ai.attack(messenger, best_tar, best_weapon)
AH.checked_attack(ai, messenger, best_tar, best_weapon)
else
-- Otherwise, always attack enemy on last waypoint
local waypoint_x = AH.split(cfg.waypoint_x, ",")
@ -113,7 +113,7 @@ function ca_messenger_move:execution(ai, cfg, self)
}[1]
if target then
ai.attack(messenger, target)
AH.checked_attack(ai, messenger, target)
end
end

View file

@ -148,7 +148,7 @@ function ca_patrol:execution(ai, cfg, self)
if next(enemies) then
for i,v in ipairs(enemies) do
ai.attack(patrol, v)
AH.checked_attack(ai, patrol, v)
break
end
end

View file

@ -127,7 +127,7 @@ function ca_protect_unit_attack:execution(ai, cfg, self)
local defender = wesnoth.get_unit(self.data.best_attack.target.x, self.data.best_attack.target.y)
AH.movefull_stopunit(ai, attacker, self.data.best_attack.dst.x, self.data.best_attack.dst.y)
ai.attack(attacker, defender)
AH.checked_attack(ai, attacker, defender)
self.data.best_attack = nil
end

View file

@ -79,7 +79,7 @@ function ca_simple_attack:execution(ai, cfg, self)
local defender = wesnoth.get_unit(self.data.attack.target.x, self.data.attack.target.y)
AH.movefull_outofway_stopunit(ai, attacker, self.data.attack.dst.x, self.data.attack.dst.y)
ai.attack(attacker, defender, (cfg.weapon or -1))
AH.checked_attack(ai, attacker, defender, (cfg.weapon or -1))
self.data.attack = nil
end

View file

@ -94,7 +94,7 @@ function ca_stationed_guardian:execution(ai, cfg)
AH.movefull_stopunit(ai, unit, attack_loc)
-- There should be an ai.check_attack_action() here in case something weird is
-- done in a 'moveto' event.
ai.attack(unit, target)
AH.checked_attack(ai, unit, target)
else -- otherwise move toward that enemy
--print("Cannot reach target, moving toward it")
local reach = wesnoth.find_reach(unit)

View file

@ -136,7 +136,7 @@ function ca_wolves_multipacks_attack:execution(ai, cfg)
end
local a_x, a_y, d_x, d_y = attacker.x, attacker.y, defender.x, defender.y
ai.attack(attacker, defender)
AH.checked_attack(ai, attacker, defender)
-- Remove the labels, if one of the units died
if cfg.show_pack_number then
if (not attacker.valid) then W.label { x = a_x, y = a_y, text = "" } end

View file

@ -84,7 +84,7 @@ function ca_zone_guardian:execution(ai, cfg)
if (best_defense ~= -9e99) then
--print("Attack at:",attack_loc[1],attack_loc[2],best_defense)
AH.movefull_stopunit(ai, unit, attack_loc)
ai.attack(unit, target)
AH.checked_attack(ai, unit, target)
else -- otherwise move toward that enemy
--print("Cannot reach target, moving toward it")
local reach = wesnoth.find_reach(unit)