modify overwrites_specials in engine and utils.cfg macro

This commit is contained in:
newfrenchy83 2021-04-18 15:23:24 +02:00 committed by Pentarctagon
parent d4ce159c8d
commit 3db6b8b9d0
4 changed files with 72 additions and 35 deletions

View file

@ -554,7 +554,7 @@
value={CTH_NUMBER}
cumulative=no
affect_self=yes
overwrite_specials=yes
overwrite_specials=both_sides
[filter_opponent]
{SECOND_FILTER}
[/filter_opponent]
@ -607,7 +607,7 @@
value={CTH_NUMBER}
cumulative=no
affect_self=yes
overwrite_specials=yes
overwrite_specials=both_sides
[filter_opponent]
{SECOND_FILTER}
[/filter_opponent]

View file

@ -159,11 +159,7 @@ battle_context_unit_stats::battle_context_unit_stats(nonempty_unit_const_ptr up,
}
// Handle plague.
unit_ability_list plague_specials = weapon->get_specials("plague");
unit_ability_list alt_plague_specials = weapon->get_specials_and_abilities("plague");
if(!alt_plague_specials.empty() && plague_specials.empty()){
plague_specials = alt_plague_specials;
}
unit_ability_list plague_specials = weapon->get_specials_and_abilities("plague");
plagues = !opp.get_state("unplagueable") && !plague_specials.empty() &&
opp.undead_variation() != "null" && !resources::gameboard->map().is_village(opp_loc);

View file

@ -1115,62 +1115,96 @@ unit_ability_list attack_type::get_weapon_ability(const std::string& ability) co
if(self_) {
abil_list.append((*self_).get_abilities(ability, self_loc_));
for(unit_ability_list::iterator i = abil_list.begin(); i != abil_list.end();) {
if(!((*i->ability_cfg)["overwrite_specials"].to_bool() && special_active(*i->ability_cfg, AFFECT_SELF, ability, true, "filter_student"))) {
if(!special_active(*i->ability_cfg, AFFECT_SELF, ability, true, "filter_student")) {
i = abil_list.erase(i);
} else {
++i;
}
}
if(abil_list.empty()){
abil_list.append((*self_).get_abilities(ability, self_loc_));
for(unit_ability_list::iterator i = abil_list.begin(); i != abil_list.end();) {
if(!special_active(*i->ability_cfg, AFFECT_SELF, ability, true, "filter_student")) {
i = abil_list.erase(i);
} else {
++i;
}
}
}
}
if(other_) {
abil_other_list.append((*other_).get_abilities(ability, other_loc_));
for(unit_ability_list::iterator i = abil_other_list.begin(); i != abil_other_list.end();) {
if(!((*i->ability_cfg)["overwrite_specials"].to_bool() && special_active_impl(other_attack_, shared_from_this(), *i->ability_cfg, AFFECT_OTHER, ability, true, "filter_student"))) {
if(!special_active_impl(other_attack_, shared_from_this(), *i->ability_cfg, AFFECT_OTHER, ability, true, "filter_student")) {
i = abil_other_list.erase(i);
} else {
++i;
}
}
if(abil_other_list.empty()){
abil_other_list.append((*other_).get_abilities(ability, other_loc_));
for(unit_ability_list::iterator i = abil_other_list.begin(); i != abil_other_list.end();) {
if(!special_active_impl(other_attack_, shared_from_this(), *i->ability_cfg, AFFECT_OTHER, ability, true, "filter_student")) {
i = abil_other_list.erase(i);
} else {
++i;
}
}
}
}
abil_list.append(abil_other_list);
if(!abil_list.empty()){
abil_list = overwrite_special_checking(ability, abil_list, abil_list, "filter_student");
}
return abil_list;
}
unit_ability_list attack_type::get_specials_and_abilities(const std::string& special) const
{
unit_ability_list abil_list = get_weapon_ability(special);
for(unit_ability_list::iterator i = abil_list.begin(); i != abil_list.end();) {
if((*i->ability_cfg)["overwrite_specials"].to_bool()) {
return abil_list;
unit_ability_list spe_list = get_specials(special);
if(!spe_list.empty()){
spe_list = overwrite_special_checking(special, spe_list, abil_list);
if(special == "plague" && !spe_list.empty()){
return spe_list;
}
++i;
abil_list.append(spe_list);
}
abil_list.append(get_specials(special));
return abil_list;
}
static bool overwrite_special_affects(const config& special)
{
const std::string& apply_to = special["overwrite_specials"];
return (apply_to == "one_side" || apply_to == "both_sides");
}
unit_ability_list attack_type::overwrite_special_checking(const std::string& ability, unit_ability_list temp_list, const unit_ability_list& abil_list, const std::string& filter_self) const
{
bool overwrite_self = false;
bool overwrite_either = false;
for(const auto& i : abil_list) {
if((*i.ability_cfg)["overwrite_specials"] == "both_sides") {
overwrite_either = true;
break;
}
if(overwrite_special_affects(*i.ability_cfg) && (special_active(*i.ability_cfg, AFFECT_SELF, ability, true, "filter_student") || special_active_impl(other_attack_, shared_from_this(), *i.ability_cfg, AFFECT_OTHER, ability, true, "filter_student"))) {
overwrite_self = true;
}
}
if(!overwrite_either && !overwrite_self){
return temp_list;
} else if(overwrite_either){
for(unit_ability_list::iterator i = temp_list.begin(); i != temp_list.end();) {
bool overwrite = false;
if(filter_self == "filter_student"){
overwrite = overwrite_special_affects(*i->ability_cfg);
}
if(!overwrite && (special_active(*i->ability_cfg, AFFECT_SELF, ability, true, filter_self) || special_active_impl(other_attack_, shared_from_this(), *i->ability_cfg, AFFECT_OTHER, ability, true, filter_self))) {
i = temp_list.erase(i);
} else {
++i;
}
}
} else if(overwrite_self){
for(unit_ability_list::iterator i = temp_list.begin(); i != temp_list.end();) {
bool overwrite = false;
if(filter_self == "filter_student"){
overwrite = overwrite_special_affects(*i->ability_cfg);
}
if(!overwrite && special_active(*i->ability_cfg, AFFECT_SELF, ability, true, filter_self)) {
i = temp_list.erase(i);
} else {
++i;
}
}
}
return temp_list;
}
/**
* Gets the children of parent (which should be the abilities for an
* attack_type) and places the ones whose tag or id= matches @a id into

View file

@ -125,6 +125,13 @@ private:
// Configured as a bit field, in case that is useful.
enum AFFECTS { AFFECT_SELF=1, AFFECT_OTHER=2, AFFECT_EITHER=3 };
/** overwrite_special_checking : return an unit_ability_list list after checking presence or not of overwrite_specials
* @param ability The special ability type who is being checked.
* @param temp_list the list checked and returned.
* @param abil_list list checked for verify presence of overwrite_specials .
* @param filter_self name of [filter_"self/student"] if is abilities or specials who are checked
*/
unit_ability_list overwrite_special_checking(const std::string& ability, unit_ability_list temp_list, const unit_ability_list& abil_list, const std::string& filter_self = "filter_self") const;
/** check_self_abilities : return an boolean value for checking of activities of abilities used like weapon
* @return True if the special @a special is active.
* @param cfg the config to one special ability checked.