Further simplification of overwrite_specials attribute code (#7144)

Using the first loop to define three boolean variables is more complicated than simply eliminating from the 'overwrite_specials' list the abilities not carrying the attribute then; if an ability with the attribute is present define a double for loop inside each other, where for each ability with overwrite_specials the type of ability removal from the returned list is defined at that time (one_side or both_sides).

I eventually want to be able to be even more selective about the abilities that can be removed or not and extend the use of the attribute beyond chance_to_hit. When (and if) these two PRs will be merged in master, I will have to add 3-4 lines of hardcoding to implement the filtering). Building a list instead of splicing the existing one is incompatible with this project.
This commit is contained in:
newfrenchy83 2022-11-20 15:17:02 +01:00 committed by GitHub
parent 40a64b5cbf
commit 337f88091d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 37 additions and 41 deletions

View File

@ -1297,48 +1297,41 @@ static bool overwrite_special_affects(const config& special)
return (apply_to == "one_side" || apply_to == "both_sides");
}
unit_ability_list attack_type::overwrite_special_checking(const std::string& ability, const unit_ability_list& temp_list, const unit_ability_list& abil_list, const std::string& filter_self, bool is_special) const
unit_ability_list attack_type::overwrite_special_checking(const std::string& ability, unit_ability_list input, unit_ability_list overwriters, const std::string& filter_self, bool is_special) const
{
bool overwrite_self = false;
bool overwrite_opponent = false;
bool overwrite_either = false;
for(const auto& i : abil_list) {
if((*i.ability_cfg)["overwrite_specials"] == "both_sides") {
overwrite_either = true;
break;
}
if((*i.ability_cfg)["overwrite_specials"] == "one_side" && special_active_impl(shared_from_this(), other_attack_, *i.ability_cfg, AFFECT_SELF, ability, filter_self) && !overwrite_self) {
overwrite_self = true;
}
if((*i.ability_cfg)["overwrite_specials"] == "one_side" && special_active_impl(other_attack_, shared_from_this(), *i.ability_cfg, AFFECT_OTHER, ability, filter_self) && !overwrite_opponent) {
overwrite_opponent = true;
for(unit_ability_list::iterator i = overwriters.begin(); i != overwriters.end();) {
if(!overwrite_special_affects(*i->ability_cfg)) {
i = overwriters.erase(i);
} else {
++i;
}
}
if(!overwrite_either && !overwrite_self && !overwrite_opponent){
return temp_list;
if(overwriters.empty()){
return input;
}
if(!overwrite_either && overwrite_self && overwrite_opponent){
overwrite_either = true;
}
// At this point we need to return a changed list, so create a non-const one to return
unit_ability_list overwrite_list;
for(const auto& i : temp_list) {
bool overwrite = false;
if(overwrite_either){
overwrite = !is_special && overwrite_special_affects(*i.ability_cfg);
} else if(overwrite_self){
overwrite = (!is_special && overwrite_special_affects(*i.ability_cfg)) || special_active_impl(other_attack_, shared_from_this(), *i.ability_cfg, AFFECT_OTHER, ability, filter_self);
} else if(overwrite_opponent){
overwrite = (!is_special && overwrite_special_affects(*i.ability_cfg)) || special_active_impl(shared_from_this(), other_attack_, *i.ability_cfg, AFFECT_SELF, ability, filter_self);
}
if(overwrite) {
overwrite_list.emplace_back(i);
for(const auto& i : overwriters) {
bool affect_side = ((*i.ability_cfg)["overwrite_specials"] == "one_side");
for(unit_ability_list::iterator j = input.begin(); j != input.end();) {
bool is_overwritable = (is_special || !overwrite_special_affects(*j->ability_cfg));
bool one_side_overwritable = true;
if(affect_side && is_overwritable){
if(special_active_impl(shared_from_this(), other_attack_, *i.ability_cfg, AFFECT_SELF, ability, filter_self)){
one_side_overwritable = special_active_impl(shared_from_this(), other_attack_, *j->ability_cfg, AFFECT_SELF, ability, filter_self);
}
else if(special_active_impl(other_attack_, shared_from_this(), *i.ability_cfg, AFFECT_OTHER, ability, filter_self)){
one_side_overwritable = special_active_impl(other_attack_, shared_from_this(), *j->ability_cfg, AFFECT_OTHER, ability, filter_self);
}
}
is_overwritable = is_overwritable && one_side_overwritable;
if(is_overwritable) {
j = input.erase(j);
} else {
++j;
}
}
}
return overwrite_list;
return input;
}
/**

View File

@ -127,14 +127,17 @@ 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
/**
* Filter a list of abilities or weapon specials, removing any entries that are overridden by
* the overwrite_specials attributes of a second list.
*
* @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
* @param is_special for determine if list is a special or a ability.
* @param input list to check, a filtered copy of this list is returned by the function.
* @param overwriters list that may have overwrite_specials attributes.
* @param filter_self name of [filter_"self/student"] if is abilities or specials who are checked.
* @param is_special if true, input contains weapon specials; if false, it contains abilities.
*/
unit_ability_list overwrite_special_checking(const std::string& ability, const unit_ability_list& temp_list, const unit_ability_list& abil_list, const std::string& filter_self, bool is_special) const;
unit_ability_list overwrite_special_checking(const std::string& ability, unit_ability_list input, unit_ability_list overwriters, const std::string& filter_self, bool is_special) 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.