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:
parent
ca2eec45b9
commit
70e3fc58bd
16 changed files with 36 additions and 17 deletions
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Add table
Reference in a new issue