Goto Micro AI: add [avoid] tag functionality
This includes both adding an [avoid] tag to the MAI itself, and taking the default AI [avoid] tag into account. If both are given, the former takes precedence over the latter.
This commit is contained in:
parent
f11700119a
commit
7579d181c0
2 changed files with 26 additions and 10 deletions
|
@ -6,17 +6,23 @@ local MAIUV = wesnoth.require "ai/micro_ais/micro_ai_unit_variables.lua"
|
|||
local MAISD = wesnoth.require "ai/micro_ais/micro_ai_self_data.lua"
|
||||
local M = wesnoth.map
|
||||
|
||||
local function custom_cost(x, y, unit, enemy_map, enemy_attack_map, multiplier)
|
||||
local function custom_cost(x, y, unit, avoid_map, enemy_map, enemy_attack_map, multiplier)
|
||||
local terrain = wesnoth.get_terrain(x, y)
|
||||
local move_cost = unit:movement(terrain)
|
||||
|
||||
move_cost = move_cost + (enemy_map:get(x,y) or 0)
|
||||
move_cost = move_cost + (enemy_attack_map.units:get(x,y) or 0) * multiplier
|
||||
if avoid_map and avoid_map:get(x, y) then
|
||||
move_cost = move_cost + AH.no_path
|
||||
end
|
||||
|
||||
if enemy_map then
|
||||
move_cost = move_cost + (enemy_map:get(x,y) or 0)
|
||||
move_cost = move_cost + (enemy_attack_map.units:get(x,y) or 0) * multiplier
|
||||
end
|
||||
|
||||
return move_cost
|
||||
end
|
||||
|
||||
local ca_goto, GO_units, GO_locs = {}
|
||||
local ca_goto, GO_units, GO_locs, GO_avoid_map = {}
|
||||
|
||||
function ca_goto:evaluation(cfg, data)
|
||||
-- If cfg.release_all_units_at_goal is set, check whether the goal has
|
||||
|
@ -48,6 +54,16 @@ function ca_goto:evaluation(cfg, data)
|
|||
local all_locs = AH.get_locations_no_borders(wml.get_child(cfg, "filter_location"))
|
||||
if (#all_locs == 0) then return 0 end
|
||||
|
||||
-- Exclude locations specified in an [avoid] tag in either the Micro AI or the default AI
|
||||
GO_avoid_map = AH.get_avoid_map(ai, wml.get_child(cfg, "avoid"), true)
|
||||
local valid_locs = {} -- Copying to new table is faster than deleting elements
|
||||
for _,loc in ipairs(all_locs) do
|
||||
if (not GO_avoid_map:get(loc[1], loc[2])) then
|
||||
table.insert(valid_locs, loc)
|
||||
end
|
||||
end
|
||||
if (#valid_locs == 0) then return 0 end
|
||||
|
||||
-- If 'unique_goals' is set, check whether there are locations left to go to.
|
||||
-- This does not have to be a persistent variable
|
||||
local locs = {}
|
||||
|
@ -62,14 +78,14 @@ function ca_goto:evaluation(cfg, data)
|
|||
end
|
||||
|
||||
-- Now on to the current turn
|
||||
for _,loc in ipairs(all_locs) do
|
||||
for _,loc in ipairs(valid_locs) do
|
||||
local str = 'goal_taken_' .. wesnoth.current.turn .. '_' .. loc[1] .. '_' .. loc[2]
|
||||
if (not MAISD.get_mai_self_data(data, cfg.ai_id, str)) then
|
||||
table.insert(locs, loc)
|
||||
end
|
||||
end
|
||||
else
|
||||
locs = all_locs
|
||||
locs = valid_locs
|
||||
end
|
||||
if (not locs[1]) then return 0 end
|
||||
|
||||
|
@ -125,7 +141,7 @@ function ca_goto:execution(cfg, data)
|
|||
-- This is mostly here to keep unit in place when no better hexes are available
|
||||
r = r - M.distance_between(x, y, unit.x, unit.y) / 1000.
|
||||
return r
|
||||
end, { no_random = true })
|
||||
end, { avoid_map = GO_avoid_map, no_random = true })
|
||||
|
||||
if (rating > max_rating) then
|
||||
max_rating = rating
|
||||
|
@ -133,10 +149,10 @@ function ca_goto:execution(cfg, data)
|
|||
end
|
||||
else -- Otherwise find the best path to take
|
||||
local path, cost
|
||||
if cfg.avoid_enemies then
|
||||
if GO_avoid_map or cfg.avoid_enemies then
|
||||
path, cost = wesnoth.find_path(unit, loc[1], loc[2],
|
||||
function(x, y, current_cost)
|
||||
return custom_cost(x, y, unit, enemy_map, enemy_attack_map, cfg.avoid_enemies)
|
||||
return custom_cost(x, y, unit, GO_avoid_map, enemy_map, enemy_attack_map, cfg.avoid_enemies)
|
||||
end
|
||||
)
|
||||
else
|
||||
|
|
|
@ -23,7 +23,7 @@ end
|
|||
wesnoth.micro_ais["goto"] = function(cfg)
|
||||
local required_keys = { "[filter_location]" }
|
||||
local optional_keys = {
|
||||
"avoid_enemies", "[filter]", "ignore_units", "ignore_enemy_at_goal",
|
||||
"[avoid]", "avoid_enemies", "[filter]", "ignore_units", "ignore_enemy_at_goal",
|
||||
"release_all_units_at_goal", "release_unit_at_goal", "unique_goals", "use_straight_line"
|
||||
}
|
||||
local CA_parms = {
|
||||
|
|
Loading…
Add table
Reference in a new issue