diff --git a/data/game.cfg b/data/game.cfg index 3516f679fb9..3c44013a193 100644 --- a/data/game.cfg +++ b/data/game.cfg @@ -22,7 +22,6 @@ {terrain_generator.cfg} {campaigns} -{~campaigns} {help.cfg} diff --git a/src/config.cpp b/src/config.cpp index 364802e13d6..ccffacfdf9a 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -61,6 +61,22 @@ void config::append(const config& cfg) } } +void config::merge_children(const std::string& key) +{ + config merged_children; + const child_list& children = get_children(key); + if(children.size() < 2) { + return; + } + + for(child_list::const_iterator i = children.begin(); i != children.end(); ++i) { + merged_children.append(**i); + } + + clear_children(key); + add_child(key,merged_children); +} + config::child_itors config::child_range(const std::string& key) { child_map::iterator i = children.find(key); diff --git a/src/config.hpp b/src/config.hpp index 2c42082f104..8fa15611648 100644 --- a/src/config.hpp +++ b/src/config.hpp @@ -124,6 +124,10 @@ public: //latter config object will clobber attributes in this one. void append(const config& cfg); + //all children with the given key will be merged into the first element + //with that key + void merge_children(const std::string& key); + //resets the translated values of all strings contained in this object void reset_translation() const; diff --git a/src/game.cpp b/src/game.cpp index 419c056f7a7..44c60bd525a 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -1279,6 +1279,39 @@ void game_controller::read_game_cfg(preproc_map& defines, config& cfg, bool use_ std::string error_log; read(cfg, *stream, &error_log); + + //load user campaigns + const std::string user_campaign_dir = get_user_data_dir() + "/data/campaigns/"; + std::vector user_campaigns, error_campaigns; + get_files_in_dir(user_campaign_dir,&user_campaigns,NULL,ENTIRE_FILE_PATH); + for(std::vector::const_iterator uc = user_campaigns.begin(); uc != user_campaigns.end(); ++uc) { + try { + scoped_istream stream = preprocess_file(*uc,&defines); + + config user_campaign_cfg; + read(user_campaign_cfg,*stream,NULL); + cfg.append(user_campaign_cfg); + } catch(config::error&) { + std::cerr << "error processing user campaign '" << *uc << "'\n"; + error_campaigns.push_back(*uc); + } catch(io_exception&) { + std::cerr << "error reading user campaign '" << *uc << "'\n"; + error_campaigns.push_back(*uc); + } + } + + if(error_campaigns.empty() == false) { + std::stringstream msg; + msg << _("The following add-on campaign(s) had errors and could not be loaded:"); + for(std::vector::const_iterator i = error_campaigns.begin(); i != error_campaigns.end(); ++i) { + msg << "\n" << *i; + } + + gui::show_error_message(disp(),msg.str()); + } + + cfg.merge_children("units"); + if(!error_log.empty()) { gui::show_error_message(disp(), _("Warning: Errors occurred while loading game configuration files: '") + @@ -1511,6 +1544,12 @@ int play_game(int argc, char** argv) return 0; } + res = game.init_video(); + if(res == false) { + std::cerr << "could not initialize display\n"; + return 0; + } + #ifdef WIN32 res = game.init_config(); if(res == false) { @@ -1519,12 +1558,6 @@ int play_game(int argc, char** argv) } #endif - res = game.init_video(); - if(res == false) { - std::cerr << "could not initialize display\n"; - return 0; - } - res = game.init_language(); if(res == false) { std::cerr << "could not initialize the language\n"; @@ -1620,6 +1653,10 @@ int play_game(int argc, char** argv) return 0; } +void f() { + throw config::error(""); +} + int main(int argc, char** argv) { try {