Fix some errors.

This commit is contained in:
Dominic Bolin 2006-03-26 01:27:10 +00:00
parent 61afac527c
commit 72b0cf9bdb
8 changed files with 841 additions and 1118 deletions

View File

@ -302,7 +302,7 @@ battle_stats evaluate_battle_stats(const gamemap& map,
battle_stats_strings *strings)
{
battle_stats res;
LOG_NG << "Evaluating battle stats...\n";
res.attack_with = attack_with;
if (strings)
@ -333,6 +333,7 @@ battle_stats evaluate_battle_stats(const gamemap& map,
double best_defend_rating = 0.0;
int defend_with = -1;
res.ndefends = 0;
LOG_NG << "Finding defender weapon...\n";
for(int defend_option = 0; defend_option != int(defender_attacks.size()); ++defend_option) {
if(defender_attacks[defend_option].range() == attack.range()) {
if (defender_attacks[defend_option].defense_weight() > 0) {
@ -424,7 +425,8 @@ battle_stats evaluate_battle_stats(const gamemap& map,
}
res.defend_with = defend_with;
attack_type& defend = defender_attacks[defend_with];
int defend_weapon = defend_with == -1 ? 0 : defend_with;
attack_type& defend = defender_attacks[defend_weapon];
attack.set_specials_context(attacker,defender,&gamedata,&units,&map,&state,&teams,true,&defend);
defend.set_specials_context(attacker,defender,&gamedata,&units,&map,&state,&teams,false,&attack);
@ -444,6 +446,7 @@ battle_stats evaluate_battle_stats(const gamemap& map,
LOG_NG << "getting weapon specials...\n";
static const std::string to_the_death_string("berserk");
res.rounds = attack.get_specials(to_the_death_string).highest("rounds");
@ -901,6 +904,7 @@ battle_stats evaluate_battle_stats(const gamemap& map,
}
strings->attack_calculations.push_back(str.str());
}
LOG_NG << "done...\n";
return res;
}
@ -947,6 +951,7 @@ void attack(display& gui, const gamemap& map,
battle_stats stats = evaluate_battle_stats(map, teams, attacker,
defender, attack_with,
units, state, info);
LOG_NG << "getting attack statistics\n";
statistics::attack_context attack_stats(a->second,d->second,stats);

View File

@ -596,7 +596,7 @@ gamemap::location ai::move_unit(location from, location to, std::map<location,pa
get_adjacent_tiles(res,locs.data());
for(adjacent_tiles_array::const_iterator adj_i = locs.begin(); adj_i != locs.end(); ++adj_i) {
const unit_map::const_iterator itor = units_.find(*adj_i);
if(i->second.attacks_left() && itor != units_.end() && current_team().is_enemy(itor->second.side()) &&
if(itor != units_.end() && current_team().is_enemy(itor->second.side()) &&
itor->second.get_state("stoned") != "true") {
battle_stats stats;
const int weapon = choose_weapon(res,itor->first,stats,0);
@ -1414,7 +1414,7 @@ bool ai::move_to_targets(std::map<gamemap::location,paths>& possible_moves, move
const unit_map::const_iterator un_it = units_.find(arrived_at);
//if we're going to attack someone
if(un_it->second.attacks_left() && u_it != units_.end() && u_it->second.get_state("stoned") != "true" && weapon != -1) {
if(u_it != units_.end() && u_it->second.get_state("stoned") != "true" && weapon != -1) {
attack_enemy(move.second,target,weapon);
}

View File

@ -293,7 +293,6 @@ Units cannot be killed by poison alone. The poison will not reduce it below 1 HP
const std::vector<std::string>& specials = at_it->special_tooltips();
if(! specials.empty()) {
for(std::vector<std::string>::const_iterator sp_it = specials.begin(); sp_it != specials.end(); ++sp_it) {
str << gettext(sp_it->c_str());
str<<"\n";

View File

@ -984,6 +984,10 @@ void unit::read(const config& cfg)
advance_to(&i->second);
max_attacks_ = 1;
}
for(config::const_child_itors range = cfg.child_range("attack");
range.first != range.second; ++range.first) {
attacks_.push_back(attack_type(**range.first,id(),image_fighting((**range.first)["range"] == "ranged" ? attack_type::LONG_RANGE : attack_type::SHORT_RANGE)));
}
}
void unit::write(config& cfg) const
@ -2070,367 +2074,6 @@ const movement_animation& unit::move_animation(const std::string terrain,gamemap
}
/*
*
* [abilities]
* ...
*
* [heals]
* value=4
* max_value=8
* cumulative=no
* affect_allies=yes
* name= _ "heals"
// * name_inactive=null
* description= _ "Heals:
Allows the unit to heal adjacent friendly units at the beginning of each turn.
A unit cared for by a healer may heal up to 4 HP per turn.
A poisoned unit cannot be cured of its poison by a healer, and must seek the care of a village or a unit that can cure."
// * description_inactive=null
* icon="misc/..."
// * icon_inactive=null
* [adjacent_description]
* name= _ "heals"
// * name_inactive=null
* description= _ "Heals:
Allows the unit to heal adjacent friendly units at the beginning of each turn.
A unit cared for by a healer may heal up to 4 HP per turn.
A poisoned unit cannot be cured of its poison by a healer, and must seek the care of a village or a unit that can cure."
// * description_inactive=null
* icon="misc/..."
// * icon_inactive=null
* [/adjacent_description]
*
* affect_self=yes
* [filter] // SUF
* ...
* [/filter]
* [filter_location]
* terrain=f
* tod=lawful
* [/filter_location]
* [filter_self] // SUF
* ...
* [/filter_self]
* [filter_adjacent] // SUF
* adjacent=n,ne,nw
* ...
* [/filter_adjacent]
* [filter_adjacent_location]
* adjacent=n,ne,nw
* ...
* [/filter_adjacent]
* [affect_adjacent]
* adjacent=n,ne,nw
* [filter] // SUF
* ...
* [/filter]
* [/affect_adjacent]
* [affect_adjacent]
* adjacent=s,se,sw
* [filter] // SUF
* ...
* [/filter]
* [/affect_adjacent]
*
* [/heals]
*
* ...
* [/abilities]
*
*/
bool unit::get_ability_bool(const std::string& ability, const gamemap::location& loc) const
{
const config* abilities = cfg_.child("abilities");
if(abilities) {
const config::child_list& list = abilities->get_children(ability);
for(config::child_list::const_iterator i = list.begin(); i != list.end(); ++i) {
if(ability_active(ability,**i,loc) && ability_affects_self(ability,**i,loc)) {
return true;
}
}
}
wassert(units_ != NULL);
wassert(teams_ != NULL);
gamemap::location adjacent[6];
get_adjacent_tiles(loc,adjacent);
for(int i = 0; i != 6; ++i) {
const unit_map::const_iterator it = units_->find(adjacent[i]);
if(it != units_->end() &&
it->second.get_state("stoned") != "true") {
const config* adj_abilities = it->second.cfg_.child("abilities");
if(adj_abilities) {
const config::child_list& list = adj_abilities->get_children(ability);
for(config::child_list::const_iterator j = list.begin(); j != list.end(); ++j) {
if(((**j)["affect_allies"]=="yes" && !(*teams_)[side()-1].is_enemy(it->second.side()))
|| ((**j)["affect_enemies"]=="yes" && (*teams_)[side()-1].is_enemy(it->second.side())) &&
ability_active(ability,**j,loc) && ability_affects_adjacent(ability,**j,i,loc)) {
return true;
}
}
}
}
}
return false;
}
unit_ability_list unit::get_abilities(const std::string& ability, const gamemap::location& loc) const
{
unit_ability_list res;
const config* abilities = cfg_.child("abilities");
if(abilities) {
const config::child_list& list = abilities->get_children(ability);
for(config::child_list::const_iterator i = list.begin(); i != list.end(); ++i) {
if(ability_active(ability,**i,loc) && ability_affects_self(ability,**i,loc)) {
res.cfgs.push_back(std::pair<config*,gamemap::location>(*i,loc));
}
}
}
wassert(units_ != NULL);
gamemap::location adjacent[6];
get_adjacent_tiles(loc,adjacent);
for(int i = 0; i != 6; ++i) {
const unit_map::const_iterator it = units_->find(adjacent[i]);
if(it != units_->end() &&
it->second.get_state("stoned") != "true") {
const config* adj_abilities = it->second.cfg_.child("abilities");
if(adj_abilities) {
const config::child_list& list = adj_abilities->get_children(ability);
for(config::child_list::const_iterator j = list.begin(); j != list.end(); ++j) {
if(((**j)["affect_allies"]=="yes" && !(*teams_)[side()-1].is_enemy(it->second.side()))
|| ((**j)["affect_enemies"]=="yes" && (*teams_)[side()-1].is_enemy(it->second.side())) &&
ability_active(ability,**j,loc) && ability_affects_adjacent(ability,**j,i,loc)) {
res.cfgs.push_back(std::pair<config*,gamemap::location>(*j,loc));
}
}
}
}
}
return res;
}
std::vector<std::string> unit::unit_ability_tooltips() const
{
std::vector<std::string> res;
const config* abilities = cfg_.child("abilities");
if(abilities) {
const config::child_map& list_map = abilities->all_children();
for(config::child_map::const_iterator i = list_map.begin(); i != list_map.end(); ++i) {
for(config::child_list::const_iterator j = i->second.begin(); j != i->second.end(); ++j) {
res.push_back((**j)["name"].str());
res.push_back((**j)["description"].str());
}
}
}
return res;
}
std::vector<std::string> unit::ability_tooltips(const gamemap::location& loc) const
{
std::vector<std::string> res;
const config* abilities = cfg_.child("abilities");
if(abilities) {
const config::child_map& list_map = abilities->all_children();
for(config::child_map::const_iterator i = list_map.begin(); i != list_map.end(); ++i) {
for(config::child_list::const_iterator j = i->second.begin(); j != i->second.end(); ++j) {
if(ability_active(i->first,**j,loc)) {
if((**j)["name"] != "") {
res.push_back((**j)["name"].str());
res.push_back((**j)["description"].str());
}
} else {
if((**j)["name_inactive"] != "") {
res.push_back((**j)["name_inactive"].str());
res.push_back((**j)["description_inactive"].str());
}
}
}
}
}
wassert(units_ != NULL);
gamemap::location adjacent[6];
get_adjacent_tiles(loc,adjacent);
for(int i = 0; i != 6; ++i) {
const unit_map::const_iterator it = units_->find(adjacent[i]);
if(it != units_->end() &&
it->second.get_state("stoned") != "true") {
const config* adj_abilities = it->second.cfg_.child("abilities");
if(adj_abilities) {
const config::child_map& list_map = adj_abilities->all_children();
for(config::child_map::const_iterator k = list_map.begin(); k != list_map.end(); ++k) {
for(config::child_list::const_iterator j = k->second.begin(); j != k->second.end(); ++j) {
if(((**j)["affect_allies"]=="yes" && !(*teams_)[side()-1].is_enemy(it->second.side()))
|| ((**j)["affect_enemies"]=="yes" && (*teams_)[side()-1].is_enemy(it->second.side()))) {
const config* adj_desc = (*j)->child("adjacent_description");
if(ability_affects_adjacent(k->first,**j,i,loc)) {
if(adj_desc) {
if(ability_active(k->first,**j,loc)) {
if((**j)["name"] != "") {
res.push_back((**j)["name"].str());
res.push_back((**j)["description"].str());
}
} else {
if((**j)["name_inactive"] != "") {
res.push_back((**j)["name_inactive"].str());
res.push_back((**j)["description_inactive"].str());
}
}
} else {
if(ability_active(k->first,**j,loc)) {
if((*adj_desc)["name"] != "") {
res.push_back((*adj_desc)["name"].str());
res.push_back((*adj_desc)["description"].str());
}
} else {
if((*adj_desc)["name_inactive"] != "") {
res.push_back((*adj_desc)["name_inactive"].str());
res.push_back((*adj_desc)["description_inacive"].str());
}
}
}
}
}
}
}
}
}
}
return res;
}
bool unit::ability_active(const std::string& ability,const config& cfg,const gamemap::location& loc) const
{
if(cfg.child("filter_self") != NULL) {
if(!matches_filter(*cfg.child("filter_self"),loc,ability=="illuminates")) {
return false;
}
}
wassert(units_ != NULL);
gamemap::location adjacent[6];
get_adjacent_tiles(loc,adjacent);
int index=-1;
const config::child_list& adj_filt = cfg.get_children("filter_adjacent");
for(config::child_list::const_iterator i = adj_filt.begin(); i != adj_filt.end(); ++i) {
std::vector<std::string> dirs = utils::split((**i)["adjacent"]);
if(dirs.size()==1 && dirs.front()=="") {
} else {
for(std::vector<std::string>::const_iterator j = dirs.begin(); j != dirs.end(); ++j) {
if(*j=="n") {
index=0;
} else if(*j=="ne") {
index=1;
} else if(*j=="se") {
index=2;
} else if(*j=="s") {
index=3;
} else if(*j=="sw") {
index=4;
} else if(*j=="nw") {
index=5;
} else {
index=-1;
}
if(index != -1) {
units_map::const_iterator unit = units_->find(adjacent[index]);
if(unit == units_->end()) {
return false;
}
if(!unit->second.matches_filter(**i,unit->first,ability=="illuminates")) {
return false;
}
}
}
}
}
index=-1;
const config::child_list& adj_filt_loc = cfg.get_children("filter_adjacent_location");
for(config::child_list::const_iterator i = adj_filt_loc.begin(); i != adj_filt_loc.end(); ++i) {
std::vector<std::string> dirs = utils::split((**i)["adjacent"]);
if(dirs.size()==1 && dirs.front()=="") {
} else {
for(std::vector<std::string>::const_iterator j = dirs.begin(); j != dirs.end(); ++j) {
if(*j=="n") {
index=0;
} else if(*j=="ne") {
index=1;
} else if(*j=="se") {
index=2;
} else if(*j=="s") {
index=3;
} else if(*j=="sw") {
index=4;
} else if(*j=="nw") {
index=5;
} else {
index=-1;
}
if(index != -1) {
wassert(map_ != NULL);
wassert(gamestatus_ != NULL);
if(!map_->terrain_matches_filter(adjacent[index],**i,*gamestatus_,*units_,ability=="illuminates")) {
return false;
}
}
}
}
}
return true;
}
bool unit::ability_affects_adjacent(const std::string& ability,const config& cfg,int dir,const gamemap::location& loc) const
{
// wassert("not done" == "done");
wassert(dir >=0 && dir <= 5);
static const std::string adjacent_names[6] = {"n","ne","se","s","sw","nw"};
const config::child_list& affect_adj = cfg.get_children("affect_adjacent");
bool passed = false;
for(config::child_list::const_iterator i = affect_adj.begin(); i != affect_adj.end(); ++i) {
std::vector<std::string> dirs = utils::split((**i)["adjacent"]);
if(std::find(dirs.begin(),dirs.end(),adjacent_names[dir]) != dirs.end()) {
if((*i)->child("filter") != NULL) {
if(matches_filter(*(*i)->child("filter"),loc,ability=="illuminates")) {
passed = true;
} else {
return false;
}
} else {
passed = true;
}
}
}
return passed;
}
bool unit::ability_affects_self(const std::string& ability,const config& cfg,const gamemap::location& loc) const
{
if(cfg.child("filter")==NULL) {
if(cfg["affect_self"] == "yes") {
return true;
} else {
return false;
}
}
if(cfg["affect_self"] == "yes") {
return matches_filter(*cfg.child("filter"),loc,ability=="illuminates");
} else {
return false;
}
}
void unit::apply_modifications()
{
@ -2483,495 +2126,6 @@ void unit::apply_modifications()
bool unit_ability_list::empty() const
{
return cfgs.empty();
}
std::pair<int,gamemap::location> unit_ability_list::highest(const std::string& key, int def) const
{
gamemap::location best_loc;
int abs_max = def;
int flat = def;
int stack = 0;
for(std::vector<std::pair<config*,gamemap::location> >::const_iterator i = cfgs.begin(); i != cfgs.end(); ++i) {
if((*i->first)["cumulative"]=="yes") {
stack += lexical_cast_default<int>((*i->first)[key]);
if(lexical_cast_default<int>((*i->first)[key]) > abs_max) {
abs_max = lexical_cast_default<int>((*i->first)[key]);
best_loc = i->second;
}
} else {
flat = maximum<int>(flat,lexical_cast_default<int>((*i->first)[key]));
if(lexical_cast_default<int>((*i->first)[key]) > abs_max) {
abs_max = lexical_cast_default<int>((*i->first)[key]);
best_loc = i->second;
}
}
}
return std::pair<int,gamemap::location>(flat + stack,best_loc);
}
std::pair<int,gamemap::location> unit_ability_list::lowest(const std::string& key, int def) const
{
gamemap::location best_loc;
int abs_max = def;
int flat = def;
int stack = 0;
for(std::vector<std::pair<config*,gamemap::location> >::const_iterator i = cfgs.begin(); i != cfgs.end(); ++i) {
if((*i->first)["cumulative"]=="yes") {
stack += lexical_cast_default<int>((*i->first)[key]);
if(lexical_cast_default<int>((*i->first)[key]) < abs_max) {
abs_max = lexical_cast_default<int>((*i->first)[key]);
best_loc = i->second;
}
} else {
flat = minimum<int>(flat,lexical_cast_default<int>((*i->first)[key]));
if(lexical_cast_default<int>((*i->first)[key]) < abs_max) {
abs_max = lexical_cast_default<int>((*i->first)[key]);
best_loc = i->second;
}
}
}
return std::pair<int,gamemap::location>(flat + stack,best_loc);
}
/*
*
* [special]
* [swarm]
* name= _ "swarm"
* name_inactive= _ ""
* description= _ ""
* description_inactive= _ ""
* cumulative=no
* apply_to=self #self,opponent,defender,attacker
* #active_on=defend .. offense
*
* attacks_max=4
* attacks_min=2
*
* [filter_self] // SUF
* ...
* [/filter_self]
* [filter_opponent] // SUF
* [filter_attacker] // SUF
* [filter_defender] // SUF
* [filter_adjacent] // SAUF
* [filter_adjacent_location] // SAUF + locs
* [/swarm]
* [/special]
*
*/
bool attack_type::get_special_bool(const std::string& special,bool force) const
{
const config* specials = cfg_.child("specials");
if(specials) {
const config::child_list& list = specials->get_children(special);
for(config::child_list::const_iterator i = list.begin(); i != list.end(); ++i) {
if(force || special_active(**i,true)) {
return true;
}
}
}
if(!force && other_attack_ != NULL) {
specials = other_attack_->cfg_.child("specials");
if(specials) {
const config::child_list& list = specials->get_children(special);
for(config::child_list::const_iterator i = list.begin(); i != list.end(); ++i) {
if(other_attack_->special_active(**i,false)) {
return true;
}
}
}
}
return false;
}
weapon_special_list attack_type::get_specials(const std::string& special) const
{
weapon_special_list res;
const config* specials = cfg_.child("specials");
if(specials) {
const config::child_list& list = specials->get_children(special);
for(config::child_list::const_iterator i = list.begin(); i != list.end(); ++i) {
if(special_active(**i,true)) {
res.cfgs.push_back(*i);
}
}
}
if(other_attack_ != NULL) {
specials = other_attack_->cfg_.child("specials");
if(specials) {
const config::child_list& list = specials->get_children(special);
for(config::child_list::const_iterator i = list.begin(); i != list.end(); ++i) {
if(other_attack_->special_active(**i,false)) {
res.cfgs.push_back(*i);
}
}
}
}
return res;
}
std::vector<std::string> attack_type::special_tooltips() const
{
std::vector<std::string> res;
const config* specials = cfg_.child("specials");
if(specials) {
const config::child_map& list_map = specials->all_children();
for(config::child_map::const_iterator i = list_map.begin(); i != list_map.end(); ++i) {
for(config::child_list::const_iterator j = i->second.begin(); j != i->second.end(); ++j) {
if(special_active(**j,true)) {
if((**j)["name"] != "") {
res.push_back((**j)["name"]);
res.push_back((**j)["description"]);
}
} else {
if((**j)["name_inactive"] != "") {
res.push_back((**j)["name_inactive"]);
res.push_back((**j)["description_inactive"]);
}
}
}
}
}
return res;
}
std::string attack_type::weapon_specials(bool force) const
{
std::string res;
const config* specials = cfg_.child("specials");
if(specials) {
const config::child_map& list_map = specials->all_children();
for(config::child_map::const_iterator i = list_map.begin(); i != list_map.end(); ++i) {
for(config::child_list::const_iterator j = i->second.begin(); j != i->second.end(); ++j) {
if(force || special_active(**j,true)) {
if((**j)["name"] != "") {
res += (**j)["name"];
res += ",";
}
} else {
if((**j)["name_inactive"] != "") {
res += (**j)["name_inactive"];
res += ",";
}
}
}
}
}
return res.substr(0,res.size()-1);
}
bool attack_type::special_active(const config& cfg,bool self) const
{
unit_map::const_iterator att = unitmap_->find(aloc_);
unit_map::const_iterator def = unitmap_->find(dloc_);
wassert(unitmap_ != NULL);
if(self) {
if(!special_affects_self(cfg)) {
return false;
}
} else {
if(!special_affects_opponent(cfg)) {
return false;
}
}
if(attacker_) {
if(cfg["active_on"] != "" && cfg["active_on"] != "attacker") {
return false;
}
if(cfg.child("filter_self") != NULL) {
if(att == unitmap_->end() || !att->second.matches_filter(*cfg.child("filter_self"),aloc_)) {
return false;
}
if(cfg.child("filter_self")->child("filter_weapon") != NULL) {
if(!matches_filter(*cfg.child("filter_self")->child("filter_weapon"),0,true)) {
return false;
}
}
}
if(cfg.child("filter_opponent") != NULL) {
if(def == unitmap_->end() || !def->second.matches_filter(*cfg.child("filter_opponent"),dloc_)) {
return false;
}
if(cfg.child("filter_opponent")->child("filter_weapon") != NULL) {
if(!other_attack_ || other_attack_->matches_filter(*cfg.child("filter_opponent")->child("filter_weapon"),0,true)) {
return false;
}
}
}
} else {
if(cfg["active_on"] != "" && cfg["active_on"] != "defender") {
return false;
}
if(cfg.child("filter_self") != NULL) {
if(def == unitmap_->end() || !def->second.matches_filter(*cfg.child("filter_self"),dloc_)) {
return false;
}
if(cfg.child("filter_self")->child("filter_weapon") != NULL) {
if(!matches_filter(*cfg.child("filter_self")->child("filter_weapon"),0,true)) {
return false;
}
}
}
if(cfg.child("filter_opponent") != NULL) {
if(att == unitmap_->end() || !att->second.matches_filter(*cfg.child("filter_opponent"),aloc_)) {
return false;
}
if(cfg.child("filter_opponent")->child("filter_weapon") != NULL) {
if(!other_attack_ || !other_attack_->matches_filter(*cfg.child("filter_opponent")->child("filter_weapon"),0,true)) {
return false;
}
}
}
}
if(cfg.child("filter_attacker") != NULL) {
if(att == unitmap_->end() || !att->second.matches_filter(*cfg.child("filter_attacker"),aloc_)) {
return false;
}
if(attacker_) {
if(cfg.child("filter_attacker")->child("filter_weapon") != NULL) {
if(!matches_filter(*cfg.child("filter_attacker")->child("filter_weapon"),0,true)) {
return false;
}
}
} else {
if(cfg.child("filter_attacker")->child("filter_weapon") != NULL) {
if(!other_attack_ || !other_attack_->matches_filter(*cfg.child("filter_attacker")->child("filter_weapon"),0,true)) {
return false;
}
}
}
}
if(cfg.child("filter_defender") != NULL) {
if(def == unitmap_->end() || !def->second.matches_filter(*cfg.child("filter_defender"),dloc_)) {
return false;
}
if(!attacker_) {
if(cfg.child("filter_defender")->child("filter_weapon") != NULL) {
if(!matches_filter(*cfg.child("filter_defender")->child("filter_weapon"),0,true)) {
return false;
}
}
} else {
if(cfg.child("filter_defender")->child("filter_weapon") != NULL) {
if(!other_attack_ || !other_attack_->matches_filter(*cfg.child("filter_defender")->child("filter_weapon"),0,true)) {
return false;
}
}
}
}
gamemap::location adjacent[6];
if(attacker_) {
get_adjacent_tiles(aloc_,adjacent);
} else {
get_adjacent_tiles(dloc_,adjacent);
}
int index=-1;
const config::child_list& adj_filt = cfg.get_children("filter_adjacent");
for(config::child_list::const_iterator i = adj_filt.begin(); i != adj_filt.end(); ++i) {
std::vector<std::string> dirs = utils::split((**i)["adjacent"]);
if(dirs.size()==1 && dirs.front()=="") {
} else {
for(std::vector<std::string>::const_iterator j = dirs.begin(); j != dirs.end(); ++j) {
if(*j=="n") {
index=0;
} else if(*j=="ne") {
index=1;
} else if(*j=="se") {
index=2;
} else if(*j=="s") {
index=3;
} else if(*j=="sw") {
index=4;
} else if(*j=="nw") {
index=5;
} else {
index=-1;
}
if(index != -1) {
units_map::const_iterator unit = unitmap_->find(adjacent[index]);
if(unit == unitmap_->end()) {
return false;
}
if(!unit->second.matches_filter(**i,unit->first)) {
return false;
}
}
}
}
}
index=-1;
const config::child_list& adj_filt_loc = cfg.get_children("filter_adjacent_location");
for(config::child_list::const_iterator i = adj_filt_loc.begin(); i != adj_filt_loc.end(); ++i) {
std::vector<std::string> dirs = utils::split((**i)["adjacent"]);
if(dirs.size()==1 && dirs.front()=="") {
} else {
for(std::vector<std::string>::const_iterator j = dirs.begin(); j != dirs.end(); ++j) {
if(*j=="n") {
index=0;
} else if(*j=="ne") {
index=1;
} else if(*j=="se") {
index=2;
} else if(*j=="s") {
index=3;
} else if(*j=="sw") {
index=4;
} else if(*j=="nw") {
index=5;
} else {
index=-1;
}
if(index != -1) {
wassert(map_ != NULL);
wassert(game_status_ != NULL);
if(!map_->terrain_matches_filter(adjacent[index],**i,*game_status_,*unitmap_)) {
return false;
}
}
}
}
}
return true;
}
bool attack_type::special_affects_opponent(const config& cfg) const
{
if(cfg["apply_to"]=="opponent") {
return true;
}
if(cfg["apply_to"]!="") {
if(attacker_ && cfg["apply_to"] == "defender") {
return true;
}
if(!attacker_ && cfg["apply_to"] == "attacker") {
return true;
}
}
return false;
}
bool attack_type::special_affects_self(const config& cfg) const
{
if(cfg["apply_to"]=="self" || cfg["apply_to"]=="") {
return true;
}
if(attacker_ && cfg["apply_to"] == "attacker") {
return true;
}
if(!attacker_ && cfg["apply_to"] == "defender") {
return true;
}
return false;
}
void attack_type::set_specials_context(const gamemap::location& aloc,const gamemap::location& dloc,
const game_data* gamedata, unit_map* unitmap,
const gamemap* map, const gamestatus* game_status,
const std::vector<team>* teams, bool attacker,attack_type* other_attack)
{
aloc_ = aloc;
dloc_ = dloc;
gamedata_ = gamedata;
unitmap_ = unitmap;
map_ = map;
game_status_ = game_status;
teams_ = teams;
attacker_ = attacker;
other_attack_ = other_attack;
}
void attack_type::set_specials_context(const gamemap::location& loc,const unit& un)
{
aloc_ = loc;
dloc_ = gamemap::location();
gamedata_ = un.gamedata_;
unitmap_ = un.units_;
map_ = un.map_;
game_status_ = un.gamestatus_;
teams_ = un.teams_;
attacker_ = true;
other_attack_ = NULL;
}
weapon_special_list& weapon_special_list::operator +(const weapon_special_list& w)
{
std::copy(w.cfgs.begin(),w.cfgs.end(),std::insert_iterator<config::child_list>(cfgs,cfgs.end()));
return *this;
}
bool weapon_special_list::empty() const
{
return cfgs.empty();
}
int weapon_special_list::highest(const std::string& key, int def) const
{
int flat = def;
int stack = 0;
for(config::child_list::const_iterator i = cfgs.begin(); i != cfgs.end(); ++i) {
if((**i)["cumulative"]=="yes") {
stack += lexical_cast_default<int>((**i)[key]);
} else {
flat = maximum<int>(flat,lexical_cast_default<int>((**i)[key]));
}
}
return flat + stack;
}
int weapon_special_list::lowest(const std::string& key, int def) const
{
int flat = def;
int stack = 0;
for(config::child_list::const_iterator i = cfgs.begin(); i != cfgs.end(); ++i) {
if((**i)["cumulative"]=="yes") {
stack += lexical_cast_default<int>((**i)[key]);
} else {
flat = minimum<int>(flat,lexical_cast_default<int>((**i)[key]));
}
}
return flat + stack;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,100 +0,0 @@
/* $Id$ */
/*
Copyright (C) 2006 by Benoit Timbert <benoit.timbert@free.fr>
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.
See the COPYING file for more details.
*/
#ifndef UNIT_ABILITIES_H_INCLUDED
#define UNIT_ABILITIES_H_INCLUDED
#include "config.hpp"
#include <string>
#include <vector>
class ability
{
public:
ability(const config* cfg);
class filter
{
public:
filter();
bool matches_filter(const std::string& terrain, int lawful_bonus) const;
void add_filters(const config* cfg);
void unfilter();
private:
std::vector<config> filters;
};
const std::string description() const;
ability::filter filter;
private:
std::string description_;
};
class heals_ability : public ability
{
public :
heals_ability(const config* cfg);
const int amount() const;
const int max() const;
void set_heal(int amount, int max);
private :
int amount_;
int max_;
};
class regenerates_ability : public ability
{
public :
regenerates_ability(const config* cfg);
const int regeneration() const;
void set_regeneration(int reg);
private :
int regeneration_;
};
class leadership_ability : public ability
{
public :
leadership_ability(const config* cfg);
const int perlevel_bonus() const;
void set_leadership(int perlevel_bonus);
private :
int perlevel_bonus_;
};
class illuminates_ability : public ability
{
public :
illuminates_ability(const config* cfg);
const int level() const;
void set_illumination(int level=1);
private :
int level_;
};
class steadfast_ability : public ability
{
public :
steadfast_ability(const config* cfg);
const int bonus() const;
const int max() const;
const bool use_percent() const;
void set_steadfast(int bonus=100, int max=50, bool use_percent=true);
private :
int bonus_;
int max_;
bool use_percent_;
};
#endif

View File

@ -257,7 +257,8 @@ bool attack_type::apply_modification(const config& cfg,std::string* description,
}
if(set_special.empty() == false) {
wassert("not done" == "done");
// Uh. Fix me?
// wassert("not done" == "done");
}
if(increase_damage.empty() == false) {

View File

@ -34,8 +34,6 @@ class weapon_special_list
{
public:
weapon_special_list& operator +(const weapon_special_list& w);
bool empty() const;
int highest(const std::string& key, int def=0) const;