00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "global.hpp"
00020
00021 #include <sstream>
00022 #include "config_adapter.hpp"
00023 #include "game_errors.hpp"
00024 #include "game_preferences.hpp"
00025 #include "gamestatus.hpp"
00026 #include "gettext.hpp"
00027 #include "log.hpp"
00028 #include "team.hpp"
00029 #include "wml_exception.hpp"
00030
00031 #define LOG_NG LOG_STREAM(info, engine)
00032 #define ERR_NG LOG_STREAM(err, engine)
00033
00034 std::string get_unique_saveid(const config& cfg, std::set<std::string>& seen_save_ids)
00035 {
00036 std::string save_id = cfg["save_id"];
00037
00038 if(save_id.empty()) {
00039 save_id=cfg["id"];
00040 }
00041
00042 if(save_id.empty()) {
00043 save_id="Unknown";
00044 }
00045
00046
00047 while(seen_save_ids.count(save_id)) {
00048 save_id += "_";
00049 }
00050
00051 return save_id;
00052 }
00053
00054 void get_player_info(const config& cfg, game_state& gamestate,
00055 std::string save_id, std::vector<team>& teams,
00056 const config& level, gamemap& map, unit_map& units,
00057 gamestatus& game_status, bool snapshot, bool replay)
00058 {
00059 player_info *player = NULL;
00060
00061 if(map.empty()) {
00062 throw game::load_game_failed("Map not found");
00063 }
00064
00065 if(cfg["controller"] == "human" ||
00066 cfg["controller"] == "network" ||
00067 cfg["persistent"] == "1") {
00068 player = gamestate.get_player(save_id);
00069
00070 if(player == NULL && !save_id.empty()) {
00071 player = &gamestate.players[save_id];
00072 }
00073 }
00074
00075 LOG_NG << "initializing team...\n";
00076
00077 std::string gold = cfg["gold"];
00078 if(gold.empty())
00079 gold = "100";
00080
00081 LOG_NG << "found gold: '" << gold << "'\n";
00082
00083 int ngold = lexical_cast_default<int>(gold);
00084
00085
00086
00087
00088
00089 if ( (player != NULL) && (!snapshot) && (!replay) ) {
00090 if(player->gold_add) {
00091 ngold += player->gold;
00092 } else if(player->gold >= ngold) {
00093 ngold = player->gold;
00094 }
00095 }
00096
00097 LOG_NG << "set gold to '" << ngold << "'\n";
00098
00099 team temp_team(cfg, ngold);
00100 teams.push_back(temp_team);
00101
00102
00103
00104
00105 int side = lexical_cast_default<int>(cfg["side"], 1);
00106 if(player != NULL) {
00107 for(std::vector<unit>::iterator it = player->available_units.begin();
00108 it != player->available_units.end(); ++it) {
00109 it->set_side(side);
00110 }
00111 }
00112
00113
00114
00115 if(teams.back().objectives().empty())
00116 teams.back().set_objectives(level["objectives"]);
00117
00118
00119 if(!utils::string_bool(cfg["no_leader"]) && cfg["controller"] != "null") {
00120 unit new_unit(&units, &map, &game_status, &teams, cfg, true);
00121
00122
00123
00124 if(player != NULL) {
00125 for(std::vector<unit>::iterator it = player->available_units.begin();
00126 it != player->available_units.end(); ++it) {
00127 if(it->can_recruit()) {
00128 new_unit = *it;
00129 new_unit.set_game_context(&units, &map, &game_status, &teams);
00130 player->available_units.erase(it);
00131 break;
00132 }
00133 }
00134 }
00135
00136
00137
00138 gamemap::location start_pos(cfg, &gamestate);
00139
00140 if(cfg["x"].empty() && cfg["y"].empty()) {
00141 start_pos = map.starting_position(side);
00142 }
00143
00144 if(!start_pos.valid() || !map.on_board(start_pos)) {
00145 throw game::load_game_failed(
00146 "Invalid starting position (" +
00147 lexical_cast<std::string>(start_pos.x+1) +
00148 "," + lexical_cast<std::string>(start_pos.y+1) +
00149 ") for the leader of side " +
00150 lexical_cast<std::string>(side) + ".");
00151 }
00152
00153 utils::string_map symbols;
00154 symbols["side"] = lexical_cast<std::string>(side);
00155 VALIDATE(units.count(start_pos) == 0,
00156 t_string(vgettext("Duplicate side definition for side '$side|' found.", symbols)));
00157
00158 units.add(new std::pair<gamemap::location,unit>(map.starting_position(new_unit.side()), new_unit));
00159 LOG_NG << "initializing side '" << cfg["side"] << "' at "
00160 << start_pos << '\n';
00161 }
00162
00163
00164
00165 if(player != NULL && player->can_recruit.empty() == false) {
00166 std::copy(player->can_recruit.begin(),player->can_recruit.end(),
00167 std::inserter(teams.back().recruits(),teams.back().recruits().end()));
00168 }
00169
00170 if(player != NULL) {
00171 player->can_recruit = teams.back().recruits();
00172 }
00173
00174
00175 const config::child_list& starting_units = cfg.get_children("unit");
00176
00177
00178
00179
00180
00181
00182 if (player && snapshot){
00183 player->available_units.clear();
00184 }
00185 for(config::child_list::const_iterator su = starting_units.begin(); su != starting_units.end(); ++su) {
00186 unit new_unit(&units, &map, &game_status,&teams,**su,true);
00187
00188 new_unit.set_side(side);
00189
00190 const std::string& x = (**su)["x"];
00191 const std::string& y = (**su)["y"];
00192
00193 gamemap::location loc(**su, &gamestate);
00194 if(x.empty() && y.empty()) {
00195 if(player) {
00196 player->available_units.push_back(new_unit);
00197 LOG_NG << "inserting unit on recall list for side " << new_unit.side() << "\n";
00198 } else {
00199 throw game::load_game_failed(
00200 "Attempt to create a unit on the recall list for side " +
00201 lexical_cast<std::string>(side) +
00202 ", which does not have a recall list.");
00203 }
00204 } else if(!loc.valid() || !map.on_board(loc)) {
00205 throw game::load_game_failed(
00206 "Invalid starting position (" +
00207 lexical_cast<std::string>(loc.x+1) +
00208 "," + lexical_cast<std::string>(loc.y+1) +
00209 ") for a unit on side " +
00210 lexical_cast<std::string>(side) + ".");
00211 } else {
00212 if (units.find(loc) != units.end()) {
00213 ERR_NG << "[unit] trying to overwrite existing unit at " << loc << "\n";
00214 } else {
00215 units.add(new std::pair<gamemap::location,unit>(loc,new_unit));
00216 LOG_NG << "inserting unit for side " << new_unit.side() << "\n";
00217 }
00218 }
00219 }
00220 }
00221
00222 int get_first_human_team(const config::child_list::const_iterator& cfg, const config::child_list& unit_cfg){
00223 int result = -1;
00224 const std::string& controller = (**cfg)["controller"];
00225 if (controller == preferences::client_type() && (**cfg)["id"] == preferences::login()) {
00226 result = cfg - unit_cfg.begin();
00227 } else if((**cfg)["controller"] == "human") {
00228 result = cfg - unit_cfg.begin();
00229 }
00230 return result;
00231 }
00232
00233
00234 const config* get_theme(const config& game_config, std::string theme_name){
00235 const config* theme_cfg = NULL;
00236 if(theme_name != "") {
00237 theme_cfg = game_config.find_child("theme","name",theme_name);
00238 }
00239
00240 if(theme_cfg == NULL) {
00241 theme_cfg = game_config.find_child("theme","name",preferences::theme());
00242 }
00243
00244 return theme_cfg;
00245 }
00246