add filter_attacker and filter_defender to abilities
To complete the resemblance to the real weapon specials, I add these two tags Closes #3743
This commit is contained in:
parent
dbb222813c
commit
16927f9508
3 changed files with 43 additions and 15 deletions
|
@ -1587,16 +1587,30 @@ bool unit::abilities_filter_matches(const config& cfg, bool attacker, int res) c
|
|||
|
||||
//functions for emulate weapon specials.
|
||||
//filter opponent and affect self/opponent/both option.
|
||||
bool unit::ability_filter_opponent(const std::string& ability,const config& cfg,const map_location& loc) const
|
||||
bool unit::ability_filter_fighter(const std::string& ability, const std::string& filter_attacker , const config& cfg, const map_location& loc) const
|
||||
{
|
||||
const config &filter = cfg.child("filter_opponent");
|
||||
const config &filter = cfg.child(filter_attacker);
|
||||
if(!filter) {
|
||||
return true;
|
||||
}
|
||||
return unit_filter(vconfig(filter)).set_use_flat_tod(ability == "illuminates").matches(*this, loc);
|
||||
}
|
||||
|
||||
bool leadership_affects_self(const std::string& ability,const unit_map& units, const map_location& loc, const_attack_ptr weapon,const_attack_ptr opp_weapon)
|
||||
static bool ability_apply_filter(const unit_map::const_iterator un,const unit_map::const_iterator up,const std::string& ability,const config& cfg, const unit_map& units, const map_location& loc, const map_location& opp_loc, bool attacker )
|
||||
{
|
||||
if(!up->ability_filter_fighter(ability, "filter_opponent", cfg, opp_loc)){
|
||||
return true;
|
||||
}
|
||||
if((attacker && !un->ability_filter_fighter(ability, "filter_attacker", cfg, loc)) || (!attacker && !up->ability_filter_fighter(ability, "filter_attacker", cfg, opp_loc))){
|
||||
return true;
|
||||
}
|
||||
if((!attacker && !un->ability_filter_fighter(ability, "filter_defender", cfg, loc)) || (attacker && !up->ability_filter_fighter(ability, "filter_defender", cfg, opp_loc))){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool leadership_affects_self(const std::string& ability,const unit_map& units, const map_location& loc, bool attacker, const_attack_ptr weapon,const_attack_ptr opp_weapon)
|
||||
{
|
||||
const unit_map::const_iterator un = units.find(loc);
|
||||
if(un == units.end()) {
|
||||
|
@ -1609,12 +1623,18 @@ bool leadership_affects_self(const std::string& ability,const unit_map& units, c
|
|||
if(apply_to.empty() || apply_to == "both" || apply_to == "self") {
|
||||
return true;
|
||||
}
|
||||
if(attacker && apply_to == "attacker") {
|
||||
return true;
|
||||
}
|
||||
if(!attacker && apply_to == "defender") {
|
||||
return true;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool leadership_affects_opponent(const std::string& ability,const unit_map& units, const map_location& loc, const_attack_ptr weapon,const_attack_ptr opp_weapon)
|
||||
bool leadership_affects_opponent(const std::string& ability,const unit_map& units, const map_location& loc, bool attacker, const_attack_ptr weapon,const_attack_ptr opp_weapon)
|
||||
{
|
||||
const unit_map::const_iterator un = units.find(loc);
|
||||
if(un == units.end()) {
|
||||
|
@ -1627,6 +1647,12 @@ bool leadership_affects_opponent(const std::string& ability,const unit_map& unit
|
|||
if(apply_to == "both" || apply_to == "opponent") {
|
||||
return true;
|
||||
}
|
||||
if(attacker && apply_to == "defender") {
|
||||
return true;
|
||||
}
|
||||
if(!attacker && apply_to == "attacker") {
|
||||
return true;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
return false;
|
||||
|
@ -1644,13 +1670,15 @@ std::pair<int, bool> ability_leadership(const std::string& ability,const unit_ma
|
|||
unit_ability_list abil = un->get_abilities(ability, weapon, opp_weapon);
|
||||
for(unit_ability_list::iterator i = abil.begin(); i != abil.end();) {
|
||||
const config &filter = (*i->first).child("filter_opponent");
|
||||
const config &filter_attacker = (*i->first).child("filter_attacker");
|
||||
const config &filter_defender = (*i->first).child("filter_defender");
|
||||
bool show_result = false;
|
||||
if(up == units.end() && !filter) {
|
||||
if(up == units.end() && !filter && !filter_attacker && !filter_defender) {
|
||||
show_result = un->abilities_filter_matches(*i->first, attacker, abil_value);
|
||||
} else if(up == units.end() && filter) {
|
||||
} else if(up == units.end() && (filter || filter_attacker || filter_defender)) {
|
||||
return {abil_value, false};
|
||||
} else {
|
||||
show_result = !(!un->abilities_filter_matches(*i->first, attacker, abil_value) || !up->ability_filter_opponent(ability, *i->first, opp_loc));
|
||||
show_result = !(!un->abilities_filter_matches(*i->first, attacker, abil_value) || ability_apply_filter(un, up, ability, *i->first, units, loc, opp_loc, attacker));
|
||||
}
|
||||
|
||||
if(!show_result) {
|
||||
|
@ -1679,7 +1707,7 @@ bool bool_leadership(const std::string& ability,const unit_map& units, const map
|
|||
unit_ability_list abil = un->get_abilities(ability, weapon, opp_weapon);
|
||||
for(unit_ability_list::iterator i = abil.begin(); i != abil.end();) {
|
||||
const std::string& active_on = (*i->first)["active_on"];
|
||||
if(!(active_on.empty() || (attacker && active_on == "offense") || (!attacker && active_on == "defense")) || !up->ability_filter_opponent(ability, *i->first, opp_loc)) {
|
||||
if(!(active_on.empty() || (attacker && active_on == "offense") || (!attacker && active_on == "defense")) || ability_apply_filter(un, up, ability, *i->first, units, loc, opp_loc, attacker)) {
|
||||
i = abil.erase(i);
|
||||
} else {
|
||||
++i;
|
||||
|
@ -1697,11 +1725,11 @@ bool attack_type::bool_ability(const std::string& ability) const
|
|||
bool abil_bool= get_special_bool(ability);
|
||||
const unit_map& units = display::get_singleton()->get_units();
|
||||
|
||||
if(leadership_affects_self(ability, units, self_loc_, shared_from_this(), other_attack_)) {
|
||||
if(leadership_affects_self(ability, units, self_loc_, is_attacker_, shared_from_this(), other_attack_)) {
|
||||
abil_bool = get_special_bool(ability) || bool_leadership(ability, units, self_loc_, other_loc_, is_attacker_, shared_from_this(), other_attack_);
|
||||
}
|
||||
|
||||
if(leadership_affects_opponent(ability, units, other_loc_, other_attack_, shared_from_this())) {
|
||||
if(leadership_affects_opponent(ability, units, other_loc_, !is_attacker_, other_attack_, shared_from_this())) {
|
||||
abil_bool = get_special_bool(ability) || bool_leadership(ability, units, other_loc_, self_loc_, !is_attacker_, other_attack_, shared_from_this());
|
||||
}
|
||||
return abil_bool;
|
||||
|
@ -1712,11 +1740,11 @@ std::pair<int, bool> attack_type::combat_ability(const std::string& ability, int
|
|||
{
|
||||
const unit_map& units = display::get_singleton()->get_units();
|
||||
|
||||
if(leadership_affects_self(ability, units, self_loc_, shared_from_this(), other_attack_)) {
|
||||
if(leadership_affects_self(ability, units, self_loc_, is_attacker_, shared_from_this(), other_attack_)) {
|
||||
return ability_leadership(ability, units, self_loc_, other_loc_, is_attacker_, abil_value, backstab_pos, shared_from_this(), other_attack_);
|
||||
}
|
||||
|
||||
if(leadership_affects_opponent(ability, units, other_loc_, other_attack_, shared_from_this())) {
|
||||
if(leadership_affects_opponent(ability, units, other_loc_, !is_attacker_, other_attack_, shared_from_this())) {
|
||||
return ability_leadership(ability, units, other_loc_,self_loc_, !is_attacker_, abil_value, backstab_pos, other_attack_, shared_from_this());
|
||||
}
|
||||
return {abil_value, false};
|
||||
|
|
|
@ -279,8 +279,8 @@ void attack_unit_and_advance(const map_location& attacker,
|
|||
* Returns the bonus percentage (possibly 0 if there's no leader adjacent).
|
||||
*/
|
||||
int under_leadership(const unit &u, const map_location& loc, const_attack_ptr weapon, const_attack_ptr opp_weapon = nullptr);
|
||||
bool leadership_affects_self(const std::string& ability,const unit_map& units, const map_location& loc, const_attack_ptr weapon=nullptr,const_attack_ptr opp_weapon=nullptr);
|
||||
bool leadership_affects_opponent(const std::string& ability,const unit_map& units, const map_location& loc, const_attack_ptr weapon=nullptr,const_attack_ptr opp_weapon=nullptr);
|
||||
bool leadership_affects_self(const std::string& ability,const unit_map& units, const map_location& loc, bool attacker=true, const_attack_ptr weapon=nullptr,const_attack_ptr opp_weapon=nullptr);
|
||||
bool leadership_affects_opponent(const std::string& ability,const unit_map& units, const map_location& loc, bool attacker=true, const_attack_ptr weapon=nullptr,const_attack_ptr opp_weapon=nullptr);
|
||||
std::pair<int, bool> ability_leadership(const std::string& ability, const unit_map& units, const map_location& loc, const map_location& opp_loc, bool attacker=true, int abil_value=0, bool backstab_pos=false, const_attack_ptr weapon=nullptr, const_attack_ptr opp_weapon=nullptr);
|
||||
bool bool_leadership(const std::string& ability,const unit_map& units, const map_location& loc, const map_location& opp_loc, bool attacker=true, const_attack_ptr weapon=nullptr, const_attack_ptr opp_weapon=nullptr);
|
||||
|
||||
|
|
|
@ -1610,7 +1610,7 @@ public:
|
|||
void remove_ability_by_id(const std::string& ability);
|
||||
|
||||
bool abilities_filter_matches(const config& cfg, bool attacker, int res) const;
|
||||
bool ability_filter_opponent(const std::string& ability,const config& cfg,const map_location& loc) const;
|
||||
bool ability_filter_fighter(const std::string& ability, const std::string& filter_attacker , const config& cfg,const map_location& loc) const;
|
||||
|
||||
private:
|
||||
/**
|
||||
|
|
Loading…
Add table
Reference in a new issue