Micro AIs: Distinguish attribute and tag parameters and copy all of the latter
(Though currently only Protect Unit and Random Recruiting actually honour multiples of any tag.)
This commit is contained in:
parent
dd02202fc8
commit
32c3abbbaf
10 changed files with 44 additions and 34 deletions
|
@ -2,8 +2,8 @@ local H = wesnoth.require "lua/helper.lua"
|
|||
local MAIH = wesnoth.require("ai/micro_ais/micro_ai_helper.lua")
|
||||
|
||||
function wesnoth.micro_ais.big_animals(cfg)
|
||||
local required_keys = { "filter"}
|
||||
local optional_keys = { "avoid_unit", "filter_location", "filter_location_wander" }
|
||||
local required_keys = { "[filter]"}
|
||||
local optional_keys = { "[avoid_unit]", "[filter_location]", "[filter_location_wander]" }
|
||||
local CA_parms = {
|
||||
ai_id = 'mai_big_animals',
|
||||
{ ca_id = "move", location = 'ca_big_animals.lua', score = cfg.ca_score or 300000 }
|
||||
|
@ -12,7 +12,7 @@ function wesnoth.micro_ais.big_animals(cfg)
|
|||
end
|
||||
|
||||
function wesnoth.micro_ais.wolves(cfg)
|
||||
local required_keys = { "filter", "filter_second" }
|
||||
local required_keys = { "[filter]", "[filter_second]" }
|
||||
local optional_keys = { "attack_only_prey", "avoid_type" }
|
||||
local score = cfg.ca_score or 90000
|
||||
local CA_parms = {
|
||||
|
@ -66,7 +66,7 @@ function wesnoth.micro_ais.wolves(cfg)
|
|||
end
|
||||
|
||||
function wesnoth.micro_ais.herding(cfg)
|
||||
local required_keys = { "filter_location", "filter", "filter_second", "herd_x", "herd_y" }
|
||||
local required_keys = { "[filter_location]", "[filter]", "[filter_second]", "herd_x", "herd_y" }
|
||||
local optional_keys = { "attention_distance", "attack_distance" }
|
||||
local score = cfg.ca_score or 300000
|
||||
local CA_parms = {
|
||||
|
@ -84,7 +84,7 @@ end
|
|||
|
||||
function wesnoth.micro_ais.forest_animals(cfg)
|
||||
local optional_keys = { "rabbit_type", "rabbit_number", "rabbit_enemy_distance", "rabbit_hole_img",
|
||||
"tusker_type", "tusklet_type", "deer_type", "filter_location"
|
||||
"tusker_type", "tusklet_type", "deer_type", "[filter_location]"
|
||||
}
|
||||
local score = cfg.ca_score or 300000
|
||||
local CA_parms = {
|
||||
|
@ -124,7 +124,7 @@ function wesnoth.micro_ais.hunter(cfg)
|
|||
H.wml_error("Hunter [micro_ai] tag requires either id= key or [filter] tag")
|
||||
end
|
||||
local required_keys = { "home_x", "home_y" }
|
||||
local optional_keys = { "id", "filter", "filter_location", "rest_turns", "show_messages" }
|
||||
local optional_keys = { "id", "[filter]", "[filter_location]", "rest_turns", "show_messages" }
|
||||
local CA_parms = {
|
||||
ai_id = 'mai_hunter',
|
||||
{ ca_id = "move", location = 'ca_hunter.lua', score = cfg.ca_score or 300000 }
|
||||
|
|
|
@ -5,7 +5,7 @@ function wesnoth.micro_ais.messenger_escort(cfg)
|
|||
H.wml_error("Messenger [micro_ai] tag requires either id= key or [filter] tag")
|
||||
end
|
||||
local required_keys = { "waypoint_x", "waypoint_y" }
|
||||
local optional_keys = { "id", "enemy_death_chance", "filter", "filter_second", "invert_order", "messenger_death_chance" }
|
||||
local optional_keys = { "id", "enemy_death_chance", "[filter]", "[filter_second]", "invert_order", "messenger_death_chance" }
|
||||
local score = cfg.ca_score or 300000
|
||||
local CA_parms = {
|
||||
ai_id = 'mai_messenger',
|
||||
|
|
|
@ -3,8 +3,8 @@ local W = H.set_wml_action_metatable {}
|
|||
|
||||
function wesnoth.micro_ais.fast_ai(cfg)
|
||||
local optional_keys = {
|
||||
"attack_hidden_enemies", "avoid", "dungeon_mode",
|
||||
"filter", "filter_second", "include_occupied_attack_hexes",
|
||||
"attack_hidden_enemies", "[avoid]", "dungeon_mode",
|
||||
"[filter]", "[filter_second]", "include_occupied_attack_hexes",
|
||||
"leader_additional_threat", "leader_attack_max_units", "leader_weight", "move_cost_factor",
|
||||
"weak_units_first", "skip_combat_ca", "skip_move_ca", "threatened_leader_fights"
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ function wesnoth.micro_ais.stationed_guardian(cfg)
|
|||
H.wml_error("Stationed Guardian [micro_ai] tag requires either id= key or [filter] tag")
|
||||
end
|
||||
local required_keys = { "distance", "station_x", "station_y" }
|
||||
local optional_keys = { "id", "filter", "guard_x", "guard_y" }
|
||||
local optional_keys = { "id", "[filter]", "guard_x", "guard_y" }
|
||||
local CA_parms = {
|
||||
ai_id = 'mai_stationed_guardian',
|
||||
{ ca_id = 'move', location = 'ca_stationed_guardian.lua', score = cfg.ca_score or 300000 }
|
||||
|
@ -17,8 +17,8 @@ function wesnoth.micro_ais.zone_guardian(cfg)
|
|||
if (cfg.action ~= 'delete') and (not cfg.id) and (not H.get_child(cfg, "filter")) then
|
||||
H.wml_error("Zone Guardian [micro_ai] tag requires either id= key or [filter] tag")
|
||||
end
|
||||
local required_keys = { "filter_location" }
|
||||
local optional_keys = { "id", "filter", "filter_location_enemy", "station_x", "station_y" }
|
||||
local required_keys = { "[filter_location]" }
|
||||
local optional_keys = { "id", "[filter]", "[filter_location_enemy]", "station_x", "station_y" }
|
||||
local CA_parms = {
|
||||
ai_id = 'mai_zone_guardian',
|
||||
{ ca_id = 'move', location = 'ca_zone_guardian.lua', score = cfg.ca_score or 300000 }
|
||||
|
@ -31,7 +31,7 @@ function wesnoth.micro_ais.return_guardian(cfg)
|
|||
H.wml_error("Return Guardian [micro_ai] tag requires either id= key or [filter] tag")
|
||||
end
|
||||
local required_keys = { "return_x", "return_y" }
|
||||
local optional_keys = { "id", "filter" }
|
||||
local optional_keys = { "id", "[filter]" }
|
||||
local CA_parms = {
|
||||
ai_id = 'mai_return_guardian',
|
||||
{ ca_id = 'move', location = 'ca_return_guardian.lua', score = cfg.ca_score or 100010 }
|
||||
|
@ -44,7 +44,7 @@ function wesnoth.micro_ais.coward(cfg)
|
|||
H.wml_error("Coward [micro_ai] tag requires either id= key or [filter] tag")
|
||||
end
|
||||
local required_keys = { "distance" }
|
||||
local optional_keys = { "attack_if_trapped", "id", "filter", "filter_second", "seek_x", "seek_y","avoid_x","avoid_y" }
|
||||
local optional_keys = { "attack_if_trapped", "id", "[filter]", "[filter_second]", "seek_x", "seek_y","avoid_x","avoid_y" }
|
||||
local CA_parms = {
|
||||
ai_id = 'mai_coward',
|
||||
{ ca_id = 'move', location = 'ca_coward.lua', score = cfg.ca_score or 300000 }
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
function wesnoth.micro_ais.healer_support(cfg)
|
||||
local optional_keys = { "aggression", "injured_units_only", "max_threats", "filter", "filter_second" }
|
||||
local optional_keys = { "aggression", "injured_units_only", "max_threats", "[filter]", "[filter_second]" }
|
||||
-- Scores for this AI need to be hard-coded, it does not work otherwise
|
||||
local CA_parms = {
|
||||
ai_id = 'mai_healer',
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
function wesnoth.micro_ais.lurkers(cfg)
|
||||
local required_keys = { "filter", "filter_location" }
|
||||
local optional_keys = { "stationary", "filter_location_wander" }
|
||||
local required_keys = { "[filter]", "[filter_location]" }
|
||||
local optional_keys = { "stationary", "[filter_location_wander]" }
|
||||
local CA_parms = {
|
||||
ai_id = 'mai_lurkers',
|
||||
{ ca_id = 'move', location = 'ca_lurkers.lua', score = cfg.ca_score or 300000 }
|
||||
|
@ -11,9 +11,9 @@ end
|
|||
|
||||
-- goto is a keyword, so need to use index operator directly
|
||||
wesnoth.micro_ais["goto"] = function(cfg)
|
||||
local required_keys = { "filter_location" }
|
||||
local required_keys = { "[filter_location]" }
|
||||
local optional_keys = {
|
||||
"avoid_enemies", "filter", "ignore_units", "ignore_enemy_at_goal",
|
||||
"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 = {
|
||||
|
@ -24,7 +24,7 @@ wesnoth.micro_ais["goto"] = function(cfg)
|
|||
end
|
||||
|
||||
function wesnoth.micro_ais.hang_out(cfg)
|
||||
local optional_keys = { "filter", "filter_location", "avoid", "mobilize_condition", "mobilize_on_gold_less_than" }
|
||||
local optional_keys = { "[filter]", "[filter_location]", "[avoid]", "[mobilize_condition]", "mobilize_on_gold_less_than" }
|
||||
local CA_parms = {
|
||||
ai_id = 'mai_hang_out',
|
||||
{ ca_id = 'move', location = 'ca_hang_out.lua', score = cfg.ca_score or 170000 }
|
||||
|
|
|
@ -5,7 +5,7 @@ function wesnoth.micro_ais.patrol(cfg)
|
|||
H.wml_error("Patrol [micro_ai] tag requires either id= key or [filter] tag")
|
||||
end
|
||||
local required_keys = { "waypoint_x", "waypoint_y" }
|
||||
local optional_keys = { "id", "filter", "attack", "one_time_only", "out_and_back" }
|
||||
local optional_keys = { "id", "[filter]", "attack", "one_time_only", "out_and_back" }
|
||||
local CA_parms = {
|
||||
ai_id = 'mai_patrol',
|
||||
{ ca_id = "move", location = 'ca_patrol.lua', score = cfg.ca_score or 300000 }
|
||||
|
|
|
@ -24,9 +24,6 @@ function wesnoth.micro_ais.protect_unit(cfg)
|
|||
end
|
||||
table.insert(unit_ids, u.id)
|
||||
end
|
||||
if #unit_ids == 0 then
|
||||
H.wml_error("Protect Unit Micro AI is missing required [unit] tag")
|
||||
end
|
||||
|
||||
-- Optional key disable_move_leader_to_keep: needs to be dealt with
|
||||
-- separately as it affects a default CA
|
||||
|
@ -74,5 +71,5 @@ function wesnoth.micro_ais.protect_unit(cfg)
|
|||
else
|
||||
MAIH.add_aspects(cfg.side, aspect_parms)
|
||||
end
|
||||
return {}, {}, CA_parms
|
||||
return {"[unit]"}, {}, CA_parms
|
||||
end
|
||||
|
|
|
@ -39,7 +39,7 @@ function wesnoth.micro_ais.recruit_rushers(cfg)
|
|||
end
|
||||
|
||||
function wesnoth.micro_ais.recruit_random(cfg)
|
||||
local optional_keys = { "skip_low_gold_recruiting", "type", "probability" }
|
||||
local optional_keys = { "skip_low_gold_recruiting", "[probability]" }
|
||||
local CA_parms = {
|
||||
ai_id = 'mai_random_recruit',
|
||||
{ ca_id = "move", location = 'ca_recruit_random.lua', score = cfg.ca_score or 180000 }
|
||||
|
|
|
@ -174,19 +174,32 @@ function micro_ai_helper.micro_ai_setup(cfg, CA_parms, required_keys, optional_k
|
|||
|
||||
-- Required keys
|
||||
for _,v in pairs(required_keys) do
|
||||
local child = H.get_child(cfg, v)
|
||||
if (not cfg[v]) and (not child) then
|
||||
H.wml_error("[micro_ai] tag (" .. cfg.ai_type .. ") is missing required parameter: " .. v)
|
||||
if v:match('%[[a-zA-Z0-9_]+%]') then
|
||||
v = v:sub(2,-2)
|
||||
if not H.get_child(cfg, v) then
|
||||
H.wml_error("[micro_ai] tag (" .. cfg.ai_type .. ") is missing required parameter: [" .. v .. "]")
|
||||
end
|
||||
for child in H.child_range(cfg, v) do
|
||||
table.insert(CA_cfg, T[v](child))
|
||||
end
|
||||
else
|
||||
if not cfg[v] then
|
||||
H.wml_error("[micro_ai] tag (" .. cfg.ai_type .. ") is missing required parameter: " .. v .."=")
|
||||
end
|
||||
CA_cfg[v] = cfg[v]
|
||||
end
|
||||
CA_cfg[v] = cfg[v]
|
||||
if child then table.insert(CA_cfg, T[v](child)) end
|
||||
end
|
||||
|
||||
-- Optional keys
|
||||
for _,v in pairs(optional_keys) do
|
||||
CA_cfg[v] = cfg[v]
|
||||
local child = H.get_child(cfg, v)
|
||||
if child then table.insert(CA_cfg, T[v](child)) end
|
||||
if v:match('%[[a-zA-Z0-9_]+%]') then
|
||||
v = v:sub(2,-2)
|
||||
for child in H.child_range(cfg, v) do
|
||||
table.insert(CA_cfg, T[v](child))
|
||||
end
|
||||
else
|
||||
CA_cfg[v] = cfg[v]
|
||||
end
|
||||
end
|
||||
|
||||
-- Finally, set up the candidate actions themselves
|
||||
|
|
Loading…
Add table
Reference in a new issue