00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "global.hpp"
00019
00020 #include "game_events.hpp"
00021 #include "game_errors.hpp"
00022 #include "gamestatus.hpp"
00023 #include "log.hpp"
00024 #include "network.hpp"
00025 #include "team.hpp"
00026 #include "util.hpp"
00027 #include "serialization/string_utils.hpp"
00028
00029 #include <algorithm>
00030 #include <cassert>
00031 #include <cstdlib>
00032 #include <sstream>
00033
00034 #define LOG_NG LOG_STREAM(info, engine)
00035
00036 namespace {
00037 std::vector<team>* teams = NULL;
00038 }
00039
00040
00041 const int team::default_team_gold = 100;
00042
00043 teams_manager::teams_manager(std::vector<team>& teams_list)
00044 {
00045 teams = &teams_list;
00046 }
00047
00048 teams_manager::~teams_manager()
00049 {
00050 teams = NULL;
00051 }
00052
00053 bool teams_manager::is_observer()
00054 {
00055 for(std::vector<team>::const_iterator i = teams->begin(); i != teams->end(); ++i) {
00056 if(i->is_human() || i->is_persistent()) {
00057 return false;
00058 }
00059 }
00060
00061 return true;
00062 }
00063
00064 team::target::target(const config& cfg)
00065 : criteria(cfg), value(atof(cfg["value"].c_str()))
00066 {
00067 }
00068
00069 void team::target::write(config& cfg) const
00070 {
00071 cfg = criteria;
00072 }
00073
00074 team::team_info::team_info(const config& cfg) :
00075 name(cfg["name"]),
00076 gold(cfg["gold"]),
00077 start_gold(),
00078 income(cfg["income"]),
00079 income_per_village(),
00080 can_recruit(),
00081 global_recruitment_pattern(),
00082 recruitment_pattern(utils::split(cfg["recruitment_pattern"])),
00083 enemies(),
00084 team_name(cfg["team_name"]),
00085 user_team_name(cfg["user_team_name"]),
00086 save_id(cfg["save_id"]),
00087 current_player(cfg["current_player"]),
00088 countdown_time(cfg["countdown_time"]),
00089 action_bonus_count(lexical_cast_default<int>(cfg["action_bonus_count"])),
00090 flag(cfg["flag"]),
00091 flag_icon(cfg["flag_icon"]),
00092 description(cfg["id"]),
00093 objectives(cfg["objectives"]),
00094 objectives_changed(utils::string_bool(cfg["objectives_changed"])),
00095 controller(),
00096 persistent(),
00097 ai_algorithm(cfg["ai_algorithm"]),
00098 ai_params(),
00099 ai_memory_(),
00100 villages_per_scout(),
00101 leader_value(0.0),
00102 village_value(0.0),
00103 targets(),
00104 share_maps(false),
00105 share_view(false),
00106 disallow_observers(utils::string_bool(cfg["disallow_observers"])),
00107 allow_player(utils::string_bool(cfg["allow_player"], true)),
00108 no_leader(utils::string_bool(cfg["no_leader"])),
00109 music(cfg["music"]),
00110 colour(cfg["colour"].size() ? cfg["colour"] : cfg["side"])
00111 {
00112 config global_ai_params;
00113 const config::child_list& ai_parameters = cfg.get_children("ai");
00114 for(config::child_list::const_iterator aiparam = ai_parameters.begin(); aiparam != ai_parameters.end(); ++aiparam) {
00115 ai_params.push_back(**aiparam);
00116
00117 if((**aiparam)["turns"].empty() && (**aiparam)["time_of_day"].empty()) {
00118 global_ai_params.append(**aiparam);
00119 }
00120 }
00121
00122 const config::child_list& ai_mems = cfg.get_children("ai_memory");
00123 for(config::child_list::const_iterator aimem = ai_mems.begin(); aimem != ai_mems.end(); ++aimem) {
00124 ai_memory_.append(**aimem);
00125 }
00126
00127
00128
00129 if (!cfg["start_gold"].empty())
00130 start_gold = cfg["start_gold"];
00131 else if (!this->gold.empty())
00132 start_gold = this->gold;
00133 else
00134 start_gold = str_cast(default_team_gold);
00135
00136 if(team_name.empty()) {
00137 team_name = cfg["side"];
00138 }
00139
00140 if(save_id.empty()) {
00141 save_id = description;
00142 }
00143 if (current_player.empty()) {
00144 current_player = save_id;
00145 }
00146
00147 int side = atoi(cfg["side"].c_str());
00148
00149 const std::string temp_rgb_str = cfg["team_rgb"];
00150 std::map<std::string, color_range>::iterator global_rgb = game_config::team_rgb_range.find(cfg["side"]);
00151
00152 if(!temp_rgb_str.empty()){
00153 std::vector<Uint32> temp_rgb = string2rgb(temp_rgb_str);
00154 team_color_range_[side] = color_range(temp_rgb);
00155 }else if(global_rgb != game_config::team_rgb_range.end()){
00156 team_color_range_[side] = global_rgb->second;
00157 }
00158
00159 const std::string& village_income = cfg["village_gold"];
00160 if(village_income.empty())
00161 income_per_village = game_config::village_income;
00162 else
00163 income_per_village = lexical_cast_default<int>(village_income, game_config::village_income);
00164
00165 const std::string& enemies_list = cfg["enemy"];
00166 if(!enemies_list.empty()) {
00167 std::vector<std::string> venemies = utils::split(enemies_list);
00168 for(std::vector<std::string>::const_iterator i = venemies.begin(); i != venemies.end(); ++i) {
00169 enemies.push_back(atoi(i->c_str()));
00170 }
00171 }
00172
00173 std::string control = cfg["controller"];
00174 if (control == "human")
00175 controller = HUMAN;
00176 else if (control == "network")
00177 controller = NETWORK;
00178 else if (control == "null")
00179 {
00180 disallow_observers = utils::string_bool(cfg["disallow_observers"],true);
00181 controller = EMPTY;
00182 }
00183 else
00184 controller = AI;
00185
00186 std::string persist = cfg["persistent"];
00187 if (persist.empty()) persistent = controller == HUMAN;
00188 else persistent = persist == "1";
00189
00190 if(ai_algorithm.empty()) {
00191 ai_algorithm = global_ai_params["ai_algorithm"];
00192 }
00193
00194 std::string scouts_val = cfg["villages_per_scout"];
00195
00196 if(scouts_val.empty()) {
00197 scouts_val = global_ai_params["villages_per_scout"];
00198 }
00199
00200 if(scouts_val.empty()) {
00201 villages_per_scout = 4;
00202 } else {
00203 villages_per_scout = atoi(scouts_val.c_str());
00204 }
00205
00206 std::string leader_val = cfg["leader_value"];
00207
00208 if(leader_val.empty()) {
00209 leader_val = global_ai_params["leader_value"];
00210 }
00211
00212 if(leader_val.empty()) {
00213 leader_value = 3.0;
00214 } else {
00215 leader_value = atof(leader_val.c_str());
00216 }
00217
00218 std::string village_val = cfg["village_value"];
00219
00220 if(village_val.empty()) {
00221 village_val = global_ai_params["village_value"];
00222 }
00223
00224 if(village_val.empty()) {
00225 village_value = 1.0;
00226 } else {
00227 village_value = atof(village_val.c_str());
00228 }
00229
00230 std::vector<std::string> recruits = utils::split(cfg["recruit"]);
00231 for(std::vector<std::string>::const_iterator i = recruits.begin(); i != recruits.end(); ++i) {
00232 can_recruit.insert(*i);
00233 }
00234
00235 if(recruitment_pattern.empty()) {
00236 recruitment_pattern =
00237 utils::split(global_ai_params["recruitment_pattern"]);
00238 }
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250 global_recruitment_pattern = recruitment_pattern;
00251
00252
00253 config::const_child_itors tgts;
00254 for(tgts = cfg.child_range("target"); tgts.first != tgts.second; ++tgts.first) {
00255 targets.push_back(target(**tgts.first));
00256 }
00257
00258 for(tgts = global_ai_params.child_range("target"); tgts.first != tgts.second; ++tgts.first) {
00259 targets.push_back(target(**tgts.first));
00260 }
00261
00262
00263
00264 share_view = utils::string_bool(cfg["share_view"]);
00265 share_maps = !share_view && utils::string_bool(cfg["share_maps"],true);
00266
00267 LOG_NG << "team_info::team_info(...): team_name: " << team_name
00268 << ", share_maps: " << share_maps << ", share_view: " << share_view << ".\n";
00269 }
00270
00271 void team::team_info::write(config& cfg) const
00272 {
00273 for(std::vector<config>::const_iterator ai = ai_params.begin(); ai != ai_params.end(); ++ai) {
00274 cfg.add_child("ai",*ai);
00275 }
00276 if(!ai_memory_.empty()) cfg.add_child("ai_memory",ai_memory_);
00277 cfg["ai_algorithm"] = ai_algorithm;
00278
00279 cfg["gold"] = gold;
00280 cfg["start_gold"] = start_gold;
00281 cfg["income"] = income;
00282 cfg["name"] = name;
00283 cfg["team_name"] = team_name;
00284 cfg["user_team_name"] = user_team_name;
00285 cfg["save_id"] = save_id;
00286 cfg["current_player"] = current_player;
00287 cfg["flag"] = flag;
00288 cfg["flag_icon"] = flag_icon;
00289 cfg["id"] = description;
00290 cfg["objectives"] = objectives;
00291 cfg["objectives_changed"] = objectives_changed ? "yes" : "no";
00292 cfg["countdown_time"]= countdown_time;
00293 cfg["action_bonus_count"]= str_cast(action_bonus_count);
00294 cfg["village_gold"] = str_cast(income_per_village);
00295 cfg["disallow_observers"] = disallow_observers ? "yes" : "no";
00296 cfg["allow_player"] = allow_player ? "yes" : "no";
00297 cfg["no_leader"] = no_leader ? "yes" : "no";
00298
00299 std::stringstream enemies_str;
00300 for(std::vector<int>::const_iterator en = enemies.begin(); en != enemies.end(); ++en) {
00301 enemies_str << *en;
00302 if(en+1 != enemies.end())
00303 enemies_str << ",";
00304 }
00305
00306 cfg["enemy"] = enemies_str.str();
00307
00308 switch(controller) {
00309 case AI: cfg["controller"] = "ai"; break;
00310 case HUMAN: cfg["controller"] = "human"; break;
00311 case NETWORK: cfg["controller"] = "network"; break;
00312 case EMPTY: cfg["controller"] = "null"; break;
00313 default: assert(false); return;
00314 }
00315
00316 cfg["persistent"] = persistent ? "1" : "0";
00317 cfg["villages_per_scout"] = str_cast(villages_per_scout);
00318 cfg["leader_value"] = str_cast(leader_value);
00319 cfg["village_value"] = str_cast(village_value);
00320
00321 for(std::vector<target>::const_iterator tg = targets.begin(); tg != targets.end(); ++tg) {
00322 tg->write(cfg.add_child("target"));
00323 }
00324
00325 std::stringstream can_recruit_str;
00326 for(std::set<std::string>::const_iterator cr = can_recruit.begin(); cr != can_recruit.end(); ++cr) {
00327 if(cr != can_recruit.begin())
00328 can_recruit_str << ",";
00329
00330 can_recruit_str << *cr;
00331 }
00332
00333 cfg["recruit"] = can_recruit_str.str();
00334
00335 std::stringstream recruit_pattern_str;
00336 std::vector<std::string> rp = global_recruitment_pattern;
00337 for(std::vector<std::string>::const_iterator p = rp.begin(); p != rp.end(); ++p) {
00338 if(p != rp.begin())
00339 recruit_pattern_str << ",";
00340
00341 recruit_pattern_str << *p;
00342 }
00343
00344 cfg["recruitment_pattern"] = recruit_pattern_str.str();
00345
00346 cfg["share_maps"] = share_maps ? "yes" : "no";
00347 cfg["share_view"] = share_view ? "yes" : "no";
00348
00349 if(music.empty() == false)
00350 cfg["music"] = music;
00351
00352 cfg["colour"] = lexical_cast_default<std::string>(colour);
00353 }
00354
00355 void team::merge_shroud_map_data(const std::string& shroud_data)
00356 {
00357 shroud_.merge(shroud_data);
00358 }
00359
00360 team::team(const config& cfg, int gold) :
00361 gold_(gold),
00362 villages_(),
00363 shroud_(),
00364 fog_(),
00365 auto_shroud_updates_(true),
00366 info_(cfg),
00367 countdown_time_(0),
00368 action_bonus_count_(0),
00369 aiparams_(),
00370 aggression_(0.0),
00371 caution_(0.0),
00372 enemies_(),
00373 seen_(),
00374 ally_shroud_(),
00375 ally_fog_()
00376 {
00377 fog_.set_enabled( utils::string_bool(cfg["fog"]) );
00378 shroud_.set_enabled( utils::string_bool(cfg["shroud"]) );
00379 shroud_.read(cfg["shroud_data"]);
00380
00381 LOG_NG << "team::team(...): team_name: " << info_.team_name
00382 << ", shroud: " << uses_shroud() << ", fog: " << uses_fog() << ".\n";
00383
00384
00385
00386 if(info_.gold.empty() == false)
00387 {
00388 gold_ = maximum(gold,::atoi(info_.gold.c_str()));
00389 if (gold_ != ::atoi(info_.gold.c_str()))
00390 info_.start_gold = str_cast(gold) + " (" + info_.start_gold + ")";
00391 }
00392
00393
00394 const config::child_list& villages = cfg.get_children("village");
00395 for(config::child_list::const_iterator v = villages.begin(); v != villages.end(); ++v) {
00396 villages_.insert(gamemap::location(**v,game_events::get_state_of_game()));
00397 }
00398
00399 countdown_time_=lexical_cast_default<int>(cfg["countdown_time"],0);
00400 action_bonus_count_=lexical_cast_default<int>(cfg["action_bonus_count"],0);
00401 }
00402
00403 void team::write(config& cfg) const
00404 {
00405 info_.write(cfg);
00406 cfg["shroud"] = uses_shroud() ? "yes" : "no";
00407 cfg["fog"] = uses_fog() ? "yes" : "no";
00408 cfg["gold"] = str_cast(gold_);
00409
00410
00411 for(std::set<gamemap::location>::const_iterator t = villages_.begin(); t != villages_.end(); ++t) {
00412 t->write(cfg.add_child("village"));
00413 }
00414
00415 cfg["shroud_data"] = shroud_.write();
00416
00417 cfg["countdown_time"] = str_cast(countdown_time_);
00418 cfg["action_bonus_count"] = str_cast(action_bonus_count_);
00419 }
00420
00421 bool team::get_village(const gamemap::location& loc)
00422 {
00423 villages_.insert(loc);
00424 return game_events::fire("capture",loc);
00425 }
00426
00427 void team::lose_village(const gamemap::location& loc)
00428 {
00429 if(owns_village(loc)) {
00430 villages_.erase(villages_.find(loc));
00431 }
00432 }
00433
00434 void team::set_time_of_day(int turn, const time_of_day& tod)
00435 {
00436 aiparams_.clear();
00437 for(std::vector<config>::const_iterator i = info_.ai_params.begin(); i != info_.ai_params.end(); ++i) {
00438 const std::string& time_of_day = (*i)["time_of_day"];
00439 if(time_of_day.empty() == false) {
00440 const std::vector<std::string>& times = utils::split(time_of_day);
00441 if(std::count(times.begin(),times.end(),tod.id) == 0) {
00442 continue;
00443 }
00444 }
00445
00446 const std::string& turns = (*i)["turns"];
00447 if(turns.empty() == false) {
00448 bool matched = false;
00449
00450 const std::vector<std::string>& turns_list = utils::split(turns);
00451 for(std::vector<std::string>::const_iterator j = turns_list.begin(); j != turns_list.end(); ++j) {
00452 const std::pair<int,int> range = utils::parse_range(*j);
00453 if(turn >= range.first && turn <= range.second) {
00454 matched = true;
00455 break;
00456 }
00457 }
00458
00459 if(!matched) {
00460 continue;
00461 }
00462 }
00463
00464 aiparams_.append(*i);
00465 }
00466
00467
00468
00469 info_.recruitment_pattern = utils::split(aiparams_["recruitment_pattern"]);
00470 if (info_.recruitment_pattern.empty())
00471 info_.recruitment_pattern = info_.global_recruitment_pattern;
00472 aggression_ = lexical_cast_default<double>(aiparams_["aggression"],0.5);
00473 caution_ = lexical_cast_default<double>(aiparams_["caution"],0.25);
00474 }
00475
00476 bool team::calculate_enemies(size_t index) const
00477 {
00478 if(teams == NULL || index >= teams->size()) {
00479 return false;
00480 }
00481
00482 while(enemies_.size() <= index) {
00483 enemies_.push_back(calculate_is_enemy(enemies_.size()));
00484 }
00485
00486 return enemies_.back();
00487 }
00488
00489 bool team::calculate_is_enemy(size_t index) const
00490 {
00491
00492 if(&(*teams)[index] == this) {
00493 return false;
00494 }
00495
00496
00497
00498 if(info_.team_name.empty() == false) {
00499 return (*teams)[index].info_.team_name != info_.team_name;
00500 }
00501
00502
00503 if(info_.enemies.empty())
00504 return true;
00505
00506 return std::find(info_.enemies.begin(),info_.enemies.end(),int(index+1)) != info_.enemies.end();
00507 }
00508
00509 void team::change_controller(const std::string& controller)
00510 {
00511 team::team_info::CONTROLLER cid;
00512 if (controller == "human")
00513 cid = team::team_info::HUMAN;
00514 else if (controller == "network")
00515 cid = team::team_info::NETWORK;
00516 else if (controller == "null")
00517 cid = team::team_info::EMPTY;
00518 else
00519 cid = team::team_info::AI;
00520
00521 info_.controller = cid;
00522 }
00523
00524 void team::change_team(const std::string& name, const std::string& user_name)
00525 {
00526 info_.team_name = name;
00527 if (!user_name.empty())
00528 {
00529 info_.user_team_name = user_name;
00530 }
00531 else
00532 {
00533 info_.user_team_name = name;
00534 }
00535
00536
00537 if(teams != NULL) {
00538 for(std::vector<team>::const_iterator i = teams->begin(); i != teams->end(); ++i) {
00539 i->enemies_.clear();
00540 }
00541 }
00542 }
00543
00544 void team::set_objectives(const t_string& new_objectives, bool silently)
00545 {
00546 info_.objectives = new_objectives;
00547 if(!silently)
00548 info_.objectives_changed = true;
00549 }
00550
00551 void team::set_ai_memory(const config& ai_mem){
00552
00553
00554
00555 info_.ai_memory_=ai_mem;
00556 }
00557
00558 void team::set_ai_parameters(const config::child_list& ai_parameters)
00559 {
00560 info_.ai_params.clear();
00561 config::child_list::const_iterator i;
00562 for (i = ai_parameters.begin(); i != ai_parameters.end(); ++i) {
00563 info_.ai_params.push_back(**i);
00564 }
00565 }
00566
00567 bool team::shrouded(const gamemap::location& loc) const
00568 {
00569 if(!teams)
00570 return shroud_.value(loc.x+1,loc.y+1);
00571
00572 return shroud_.shared_value(ally_shroud(*teams),loc.x+1,loc.y+1);
00573 }
00574
00575 bool team::fogged(const gamemap::location& loc) const
00576 {
00577 if(shrouded(loc)) return true;
00578
00579 if(!teams)
00580 return fog_.value(loc.x+1,loc.y+1);
00581
00582 return fog_.shared_value(ally_fog(*teams),loc.x+1,loc.y+1);
00583 }
00584
00585 const std::vector<const team::shroud_map*>& team::ally_shroud(const std::vector<team>& teams) const
00586 {
00587 if(ally_shroud_.empty()) {
00588 for(size_t i = 0; i < teams.size(); ++i) {
00589 if(!is_enemy(i + 1) && (&(teams[i]) == this || teams[i].share_view() || teams[i].share_maps())) {
00590 ally_shroud_.push_back(&(teams[i].shroud_));
00591 }
00592 }
00593 }
00594
00595 return ally_shroud_;
00596 }
00597
00598 const std::vector<const team::shroud_map*>& team::ally_fog(const std::vector<team>& teams) const
00599 {
00600 if(ally_fog_.empty()) {
00601 for(size_t i = 0; i < teams.size(); ++i) {
00602 if(!is_enemy(i + 1) && (&(teams[i]) == this || teams[i].share_view())) {
00603 ally_fog_.push_back(&(teams[i].fog_));
00604 }
00605 }
00606 }
00607
00608 return ally_fog_;
00609 }
00610
00611 bool team::knows_about_team(size_t index) const
00612 {
00613 const team& t = (*teams)[index];
00614
00615
00616 if(this == &t) return true;
00617
00618
00619 if(!uses_shroud() && !uses_fog()) return true;
00620
00621
00622 if(is_enemy(index+1)) return false;
00623
00624
00625 if(network::nconnections() > 0) return true;
00626
00627
00628 if(share_maps() && t.uses_shroud()) return true;
00629
00630
00631 if(share_view() && (t.uses_fog() || t.uses_shroud())) return true;
00632
00633 return false;
00634 }
00635
00636 bool team::copy_ally_shroud()
00637 {
00638 if(!teams || !share_maps())
00639 return false;
00640
00641 return shroud_.copy_from(ally_shroud(*teams));
00642 }
00643
00644 int team::nteams()
00645 {
00646 if(teams == NULL) {
00647 return 0;
00648 } else {
00649 return teams->size();
00650 }
00651 }
00652
00653 bool is_observer()
00654 {
00655 if(teams == NULL) {
00656 return true;
00657 }
00658
00659 for(std::vector<team>::const_iterator i = teams->begin(); i != teams->end(); ++i) {
00660 if(i->is_human()) {
00661 return false;
00662 }
00663 }
00664
00665 return true;
00666 }
00667
00668 void validate_side(int side)
00669 {
00670 if(teams == NULL) {
00671 return;
00672 }
00673
00674 if(side < 1 || side > int(teams->size())) {
00675 throw game::game_error("invalid side(" + str_cast(side) + ") found in unit definition");
00676 }
00677 }
00678
00679 bool team::shroud_map::clear(size_t x, size_t y)
00680 {
00681 if(enabled_ == false)
00682 return false;
00683
00684 if(x >= data_.size())
00685 data_.resize(x+1);
00686
00687 if(y >= data_[x].size())
00688 data_[x].resize(y+1);
00689
00690 if(data_[x][y] == false) {
00691 data_[x][y] = true;
00692 return true;
00693 } else {
00694 return false;
00695 }
00696 }
00697
00698 void team::shroud_map::place(size_t x, size_t y)
00699 {
00700 if(enabled_ == false)
00701 return;
00702
00703 if(x < data_.size() && y < data_[x].size()) {
00704 data_[x][y] = false;
00705 }
00706 }
00707
00708 void team::shroud_map::reset()
00709 {
00710 if(enabled_ == false)
00711 return;
00712
00713 for(std::vector<std::vector<bool> >::iterator i = data_.begin(); i != data_.end(); ++i) {
00714 std::fill(i->begin(),i->end(),false);
00715 }
00716 }
00717
00718 bool team::shroud_map::value(size_t x, size_t y) const
00719 {
00720 if(enabled_ == false)
00721 return false;
00722
00723 if(x >= data_.size())
00724 return true;
00725
00726 if(y >= data_[x].size())
00727 return true;
00728
00729 if(data_[x][y])
00730 return false;
00731 else
00732 return true;
00733 }
00734
00735 bool team::shroud_map::shared_value(const std::vector<const shroud_map*>& maps, size_t x, size_t y) const
00736 {
00737 if(enabled_ == false)
00738 return false;
00739
00740 for(std::vector<const shroud_map*>::const_iterator i = maps.begin(); i != maps.end(); ++i) {
00741 if((*i)->enabled_ == true && (*i)->value(x,y) == false)
00742 return false;
00743 }
00744 return true;
00745 }
00746
00747 std::string team::shroud_map::write() const
00748 {
00749 std::stringstream shroud_str;
00750 for(std::vector<std::vector<bool> >::const_iterator sh = data_.begin(); sh != data_.end(); ++sh) {
00751 shroud_str << '|';
00752
00753 for(std::vector<bool>::const_iterator i = sh->begin(); i != sh->end(); ++i) {
00754 shroud_str << (*i ? '1' : '0');
00755 }
00756
00757 shroud_str << '\n';
00758 }
00759
00760 return shroud_str.str();
00761 }
00762
00763 void team::shroud_map::read(const std::string& str)
00764 {
00765 data_.clear();
00766 for(std::string::const_iterator sh = str.begin(); sh != str.end(); ++sh) {
00767 if(*sh == '|')
00768 data_.resize(data_.size()+1);
00769
00770 if(data_.empty() == false) {
00771 if(*sh == '1')
00772 data_.back().push_back(true);
00773 else if(*sh == '0')
00774 data_.back().push_back(false);
00775 }
00776 }
00777 }
00778
00779 void team::shroud_map::merge(const std::string& str)
00780 {
00781 int x=0, y=0;
00782 for(std::string::const_iterator sh = str.begin(); sh != str.end(); ++sh) {
00783 if(*sh == '|' && sh != str.begin()) {
00784 y=0;
00785 x++;
00786 } else if(*sh == '1') {
00787 clear(x,y);
00788 y++;
00789 } else if(*sh == '0') {
00790 y++;
00791 }
00792 }
00793 }
00794
00795 bool team::shroud_map::copy_from(const std::vector<const shroud_map*>& maps)
00796 {
00797 if(enabled_ == false)
00798 return false;
00799
00800 bool cleared = false;
00801 for(std::vector<const shroud_map*>::const_iterator i = maps.begin(); i != maps.end(); ++i) {
00802 if((*i)->enabled_ == false)
00803 continue;
00804
00805 const std::vector<std::vector<bool> >& v = (*i)->data_;
00806 for(size_t x = 0; x != v.size(); ++x) {
00807 for(size_t y = 0; y != v[x].size(); ++y) {
00808 if(v[x][y]) {
00809 cleared |= clear(x,y);
00810 }
00811 }
00812 }
00813 }
00814 return cleared;
00815 }
00816
00817 std::map<int, color_range> team::team_color_range_;
00818
00819 const color_range team::get_side_color_range(int side){
00820 std::string index = get_side_colour_index(side);
00821 std::map<std::string, color_range>::iterator gp=game_config::team_rgb_range.find(index);
00822
00823 if(gp != game_config::team_rgb_range.end()){
00824 return(gp->second);
00825 }
00826
00827 return(color_range(0x00FF0000,0x00FFFFFF,0x00000000,0x00FF0000));
00828 }
00829
00830 const SDL_Color team::get_minimap_colour(int side)
00831 {
00832
00833
00834 return int_to_color(get_side_color_range(side).rep());
00835 }
00836
00837 std::string team::get_side_colour_index(int side)
00838 {
00839 size_t index = size_t(side-1);
00840
00841 if(teams != NULL && index < teams->size()) {
00842 const std::string side_map = (*teams)[index].map_colour_to();
00843 if(side_map.size()) {
00844 return side_map;
00845 }
00846 }
00847 std::stringstream id;
00848 id<<side;
00849 return id.str();
00850 }
00851
00852 std::string team::get_side_highlight(int side)
00853 {
00854 return rgb2highlight(get_side_color_range(side+1).mid());
00855 }
00856
00857 void team::log_recruitable(){
00858 LOG_NG << "Adding recruitable units: \n";
00859 for (std::set<std::string>::const_iterator it = info_.can_recruit.begin();
00860 it != info_.can_recruit.end(); it++) {
00861 LOG_NG << *it << std::endl;
00862 }
00863 LOG_NG << "Added all recruitable units\n";
00864 }
00865
00866 namespace player_teams {
00867 int village_owner(const gamemap::location& loc)
00868 {
00869 if(! teams) {
00870 return -1;
00871 }
00872 for(size_t i = 0; i != teams->size(); ++i) {
00873 if((*teams)[i].owns_village(loc))
00874 return i;
00875 }
00876 return -1;
00877 }
00878 }