Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix retreat injured CA taking allied villages #6792

Merged
merged 3 commits into from
Jun 24, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
20 changes: 17 additions & 3 deletions data/ai/lua/retreat.lua
Original file line number Diff line number Diff line change
Expand Up @@ -154,8 +154,6 @@ function retreat_functions.get_retreat_injured_units(healees, regen_amounts, avo
local max_rating, best_loc, best_unit = - math.huge, nil, nil
for i,u in ipairs(healees) do
local possible_locations = wesnoth.paths.find_reach(u)
-- TODO: avoid ally's villages (may be preferable to lower rating so they will
-- be used if unit is very injured)
if (not regen_amounts[i]) then
-- Unit cannot self heal, make the terrain do it for us if possible
local location_subset = {}
Expand All @@ -169,7 +167,23 @@ function retreat_functions.get_retreat_injured_units(healees, regen_amounts, avo
end
local curing = 0
if heal_amount > 0 then
curing = 2
-- Do not take villages from an allied side
local owner = wesnoth.map.get_owner(loc)
if owner
and (owner ~= wesnoth.current.side)
and (not wesnoth.sides.is_enemy(wesnoth.current.side, owner))
then
-- If allow_ally_villages is true, injured units are allowed to take ally villages.
-- However, they should do so with lower priority, which we do by halving the heal and cure amounts.
if ai.aspects.allow_ally_villages then
heal_amount = heal_amount / 2
curing = 1
else
heal_amount = 0
end
else
curing = 2
end
end
local healer_values = healing_locs:get(loc[1], loc[2]) or {0, 0}
heal_amount = math.max(heal_amount, healer_values[1])
Expand Down
1 change: 1 addition & 0 deletions data/ai/utils/default_config.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@

{DEFAULT_ASPECT_EMPTY advancements}
{DEFAULT_ASPECT_VALUE aggression 0.4}
{DEFAULT_ASPECT_VALUE allow_ally_villages no}
[aspect]
id=attacks
engine=cpp
Expand Down
2 changes: 1 addition & 1 deletion data/schema/ai/aspect_complex.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
super="{BASE}~real"
[/case]
[case]
value=leader_ignores_keep,passive_leader,passive_leader_shares_keep,simple_targeting,support_villages
value=allow_ally_villages,leader_ignores_keep,passive_leader,passive_leader_shares_keep,simple_targeting,support_villages
super="{BASE}~bool"
[/case]
[case]
Expand Down
1 change: 1 addition & 0 deletions data/schema/ai/aspect_simple.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
{SIMPLE_KEY engine string}
# Simple scalar aspects
{AI_ASPECT_KEY aggression s_real}
{AI_ASPECT_KEY allow_ally_villages s_bool}
{AI_ASPECT_KEY caution s_real}
{AI_ASPECT_KEY grouping ai_grouping}
{AI_ASPECT_KEY leader_aggression s_real}
Expand Down
1 change: 1 addition & 0 deletions data/schema/ai/modify.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@
[/elseif]
# Okay, now the hard part. Basically need two entries for every possible type of aspect!
{AI_MODIFY_MATCH_ASPECT aggression real}
{AI_MODIFY_MATCH_ASPECT allow_ally_villages bool}
{AI_MODIFY_MATCH_ASPECT caution real}
{AI_MODIFY_MATCH_ASPECT leader_aggression real}
{AI_MODIFY_MATCH_ASPECT leader_value real}
Expand Down
2 changes: 1 addition & 1 deletion data/tools/emacs_mode/wesnoth-wml-data.el
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@
("rulebase"))
("ai"
("team_formula" "register_candidate_action" "candidate_action" "not" "protect_area" "aspect" "leader_goal" "avoid" "vars" "modify_ai" "engine" "goal" "stage")
("priority" "formula" "eval_list" "_stage" "_aspect" "leader" "loop_formula" "y" "x" "passive_leader_shares_keep" "leader_aggression" "number_of_possible_recruits_to_force_recruit" "time_of_day" "ai_algorithm" "retreat_enemy_weight" "retreat_factor" "scout_village_targeting" "turns" "attack_depth" "grouping" "villages_per_scout" "leader_value" "village_value" "leader_shares_keep" "passive_leader" "recruitment_pattern" "simple_targeting" "recruitment_ignore_bad_combat" "recruitment_ignore_bad_movement" "caution" "aggression" "version" "description" "id"))
("priority" "formula" "eval_list" "_stage" "_aspect" "leader" "loop_formula" "y" "x" "passive_leader_shares_keep" "leader_aggression" "number_of_possible_recruits_to_force_recruit" "time_of_day" "ai_algorithm" "retreat_enemy_weight" "retreat_factor" "scout_village_targeting" "turns" "attack_depth" "grouping" "villages_per_scout" "leader_value" "village_value" "leader_shares_keep" "passive_leader" "recruitment_pattern" "simple_targeting" "recruitment_ignore_bad_combat" "recruitment_ignore_bad_movement" "caution" "allow_ally_villages" "aggression" "version" "description" "id"))
("side"
("leader" "variables" "goal" "village" "unit" "ai" "modifications")
("recall_cost" "village_support" "gold_lock" "faction_from_recruit" "income_lock" "team_lock" "disallow_observers" "variation" "ai_special" "hitpoints" "overlays" "ai_algorithm" "generate_name" "random_traits" "extra_recruit" "y" "x" "allow_player" "faction" "image" "experience" "race" "facing" "moves" "color" "share_maps" "share_view" "shroud" "fog" "profile" "scroll_to_leader" "village_gold" "unrenamable" "gender" "save_id" "income" "no_leader" "gold" "recruit" "canrecruit" "user_team_name" "team_name" "persistent" "max_moves" "type" "id" "name" "hidden" "controller" "side"))
Expand Down
10 changes: 10 additions & 0 deletions src/ai/contexts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ readonly_context_impl::readonly_context_impl(side_context &context, const config
known_aspects_(),
advancements_(),
aggression_(),
allow_ally_villages_(),
aspects_(),
attacks_(),
avoid_(),
Expand Down Expand Up @@ -213,6 +214,7 @@ readonly_context_impl::readonly_context_impl(side_context &context, const config

add_known_aspect("advancements", advancements_);
add_known_aspect("aggression",aggression_);
add_known_aspect("allow_ally_villages",allow_ally_villages_);
add_known_aspect("attacks",attacks_);
add_known_aspect("avoid",avoid_);
add_known_aspect("caution",caution_);
Expand Down Expand Up @@ -514,6 +516,14 @@ double readonly_context_impl::get_aggression() const
return 0;
}

bool readonly_context_impl::get_allow_ally_villages() const
{
if (allow_ally_villages_) {
return allow_ally_villages_->get();
}
return false;
}

const aspect_map& readonly_context_impl::get_aspects() const
{
return aspects_;
Expand Down
10 changes: 10 additions & 0 deletions src/ai/contexts.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,8 @@ class readonly_context : public virtual side_context {

virtual double get_aggression() const = 0;

virtual bool get_allow_ally_villages() const = 0;

virtual const aspect_map& get_aspects() const = 0;

virtual aspect_map& get_aspects() = 0;
Expand Down Expand Up @@ -553,6 +555,11 @@ class readonly_context_proxy : public virtual readonly_context, public virtual s
return target_->get_aggression();
}

virtual bool get_allow_ally_villages() const override
{
return target_->get_allow_ally_villages();
}

virtual const aspect_map& get_aspects() const override
{
return target_->get_aspects();
Expand Down Expand Up @@ -1137,6 +1144,8 @@ class readonly_context_impl : public virtual side_context_proxy, public readonly

virtual double get_aggression() const override;

virtual bool get_allow_ally_villages() const override;

virtual const aspect_map& get_aspects() const override;

virtual aspect_map& get_aspects() override;
Expand Down Expand Up @@ -1282,6 +1291,7 @@ class readonly_context_impl : public virtual side_context_proxy, public readonly

typesafe_aspect_ptr<unit_advancements_aspect> advancements_;
typesafe_aspect_ptr<double> aggression_;
typesafe_aspect_ptr<bool> allow_ally_villages_;
aspect_map aspects_;
typesafe_aspect_ptr<attacks_vector> attacks_;
mutable typesafe_aspect_ptr<terrain_filter> avoid_;
Expand Down
4 changes: 4 additions & 0 deletions src/ai/formula/ai.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,10 @@ variant formula_ai::get_value(const std::string& key) const
{
return variant(get_aggression()*1000,variant::DECIMAL_VARIANT);

} else if(key == "allow_ally_villages")
{
return visit_helper(get_allow_ally_villages());

} else if(key == "avoid")
{
std::set<map_location> av_locs;
Expand Down
2 changes: 2 additions & 0 deletions src/ai/manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -265,11 +265,13 @@ const std::string holder::get_ai_overview()
auto plsk = this->ai_->get_passive_leader_shares_keep();
// In order to display booleans as yes/no rather than 1/0 or true/false
config cfg;
cfg["allow_ally_villages"] = this->ai_->get_allow_ally_villages();
cfg["simple_targeting"] = this->ai_->get_simple_targeting();
cfg["support_villages"] = this->ai_->get_support_villages();
std::stringstream s;
s << "advancements: " << this->ai_->get_advancements().get_value() << std::endl;
s << "aggression: " << this->ai_->get_aggression() << std::endl;
s << "allow_ally_villages: " << cfg["allow_ally_villages"] << std::endl;
s << "caution: " << this->ai_->get_caution() << std::endl;
s << "grouping: " << this->ai_->get_grouping() << std::endl;
s << "leader_aggression: " << this->ai_->get_leader_aggression() << std::endl;
Expand Down
12 changes: 12 additions & 0 deletions src/ai/registry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,9 @@ static register_aspect_factory< composite_aspect< unit_advancements_aspect >>
static register_aspect_factory< composite_aspect<double>>
aggression__composite_aspect_factory("aggression*composite_aspect");

static register_aspect_factory< composite_aspect<bool>>
allow_ally_villages__composite_aspect_factory("allow_ally_villages*composite_aspect");

static register_aspect_factory< composite_aspect< attacks_vector >>
attacks__composite_aspect_factory("attacks*composite_aspect");

Expand Down Expand Up @@ -266,6 +269,9 @@ static register_aspect_factory< standard_aspect< unit_advancements_aspect >>
static register_aspect_factory< standard_aspect<double>>
aggression__standard_aspect_factory("aggression*standard_aspect");

static register_aspect_factory< standard_aspect<bool>>
allow_ally_villages__standard_aspect_factory("allow_ally_villages*standard_aspect");

static register_aspect_factory< ai_default_rca::aspect_attacks >
attacks__testing_ai_default_aspect_attacks_factory("attacks*ai_default_rca::aspect_attacks");

Expand Down Expand Up @@ -347,6 +353,9 @@ static register_aspect_factory< standard_aspect< unit_advancements_aspect >>
static register_aspect_factory< standard_aspect<double>>
aggression__standard_aspect_factory2("aggression*");

static register_aspect_factory< standard_aspect<bool>>
allow_ally_villages__standard_aspect_factory2("allow_ally_villages*");

static register_aspect_factory< ai_default_rca::aspect_attacks >
attacks__testing_ai_default_aspect_attacks_factory2("attacks*");

Expand Down Expand Up @@ -424,6 +433,9 @@ static register_lua_aspect_factory< lua_aspect< unit_advancements_aspect >>
static register_lua_aspect_factory< lua_aspect<double>>
aggression__lua_aspect_factory("aggression*lua_aspect");

static register_lua_aspect_factory< lua_aspect<bool>>
allow_ally_villages__lua_aspect_factory("allow_ally_villages*lua_aspect");

static register_lua_aspect_factory< aspect_attacks_lua >
attacks__lua_aspect_factory("attacks*lua_aspect");

Expand Down