38 #define ERR_CF LOG_STREAM(err, log_config)
41 #define WRN_MP LOG_STREAM(warn, log_mp_create_engine)
42 #define DBG_MP LOG_STREAM(debug, log_mp_create_engine)
62 return map_.get() !=
nullptr;
67 const std::string& map_data =
data_[
"map_data"];
74 data_[
"description"] =
_(
"Map could not be loaded: ") +
e.message;
76 ERR_CF <<
"map could not be loaded: " <<
e.message;
78 data_[
"description"] =
_(
"Map could not be loaded.");
80 ERR_CF <<
"map could not be loaded: " <<
e.dev_message;
90 if(
map_.get() !=
nullptr) {
103 if(
map_.get() !=
nullptr) {
106 const int map_positions =
map_->num_valid_starting_positions();
109 for(
int pos = 0; pos < map_positions; ++pos) {
111 side[
"side"] = pos + 1;
112 side[
"team_name"] =
"Team " + std::to_string(pos + 1);
113 side[
"canrecruit"] =
true;
114 side[
"controller"] = side_controller::human;
120 if(
scenario[
"allow_player"].to_bool(
true)) {
145 if(!
data_[
"description"].empty()) {
146 return data_[
"description"];
150 return _(
"Custom map.");
156 , generate_whole_scenario_(data_.has_attribute(
"scenario_generation"))
157 , generator_name_(generate_whole_scenario_ ? data_[
"scenario_generation"] : data_[
"map_generation"])
162 data_[
"description"] =
"Error: Random map found with missing generator information. Scenario should have a [generator] child.";
163 data_[
"error_message"] =
"missing [generator] tag";
171 data_[
"description"] =
"Error: Random map found with missing generator information. Scenario should have a [generator] child.";
172 data_[
"error_message"] =
"couldn't find 'scenario_generation' or 'map_generation' attribute";
184 , allow_era_choice_(
level::allow_era_choice())
211 int min =
data_[
"min_players"].to_int(1);
212 int max =
data_[
"max_players"].to_int(1);
231 : current_level_type_()
232 , current_level_index_(0)
233 , current_era_index_(0)
234 , level_name_filter_()
235 , player_count_filter_(1)
238 , user_scenario_names_()
242 , dependency_manager_(nullptr)
243 , generator_(nullptr)
244 , selected_campaign_difficulty_()
255 DBG_MP <<
"restoring game config";
275 DBG_MP <<
"initializing all levels, eras and mods";
296 DBG_MP <<
"initializing generated level data";
304 WRN_MP <<
"Tried to initialized generated level data on a level that wasn't a random map";
311 DBG_MP <<
"** replacing map **";
321 DBG_MP <<
"** replacing scenario **";
327 if(!
data.has_attribute(
"modify_placing")) {
328 data[
"modify_placing"] =
true;
331 const std::string& description = cur_lev->
data()[
"description"];
332 data[
"description"] = description;
340 data[
"error_message"] =
e.what();
367 DBG_MP <<
"preparing mp_game_settings for new level";
383 DBG_MP <<
"preparing data for scenario by reloading game config";
394 DBG_MP <<
"preparing data for campaign by reloading game config";
396 if(!difficulty.empty()) {
417 config {
"next_scenario", current_level_data[
"first_scenario"]}
424 std::vector<std::string> difficulties;
427 difficulties.push_back(
d[
"define"]);
431 if(difficulties.empty()) {
436 if(difficulties.size() == 1) {
437 return difficulties[0];
442 if(set_value != -1) {
443 if(set_value >
static_cast<int>(difficulties.size())) {
444 PLAIN_LOG <<
"incorrect difficulty number: [" <<
445 set_value <<
"]. maximum is [" << difficulties.size() <<
"].\n";
447 }
else if(set_value < 1) {
448 PLAIN_LOG <<
"incorrect difficulty number: [" <<
449 set_value <<
"]. minimum is [1].\n";
452 return difficulties[set_value - 1];
469 DBG_MP <<
"preparing mp_game_settings for saved game";
480 DBG_MP <<
"prepare_for_other";
501 type.second.reset_filter();
521 }
catch (
const std::out_of_range&) {
529 assert(current_random_map);
580 for(
const auto&
game :
type.second.games) {
581 if(
game->id() ==
id) {
582 return {
type.first,
i};
589 return {level_type::type::sp_campaign, -1};
596 if(extra->id ==
id) {
619 std::vector<extras_metadata_ptr> data_vec;
620 std::copy_if(mods.begin(), mods.end(), std::back_inserter(data_vec), [
this](
const extras_metadata_ptr& mod) {
621 return dependency_manager_->is_modification_active(mod->id);
630 return *
eras_[era_index]->cfg;
635 DBG_MP <<
"getting parameter values";
647 config gen_mp_data = *generic_multiplayer;
650 int dep_index_offset = 0;
653 config user_map_data = gen_mp_data;
660 std::unique_ptr<gamemap> map;
662 map.reset(
new gamemap(user_map_data[
"map_data"]));
666 user_map_data[
"description"] =
_(
"Map could not be loaded: ") +
e.message;
668 ERR_CF <<
"map could not be loaded: " <<
e.message;
686 dep_index_offset = 0;
693 ERR_CF <<
"Caught a config error while parsing user made (editor) scenarios:\n" <<
e.message;
699 if(new_scenario->id().empty())
continue;
701 type_map_[level_type::type::user_scenario].games.push_back(std::move(new_scenario));
705 depinfo[
"id"] =
data[
"id"];
706 depinfo[
"name"] =
data[
"name"];
714 if(!
data[
"allow_new_game"].to_bool(
true))
717 if(!
data[
"campaign_id"].empty())
720 if(
data.has_attribute(
"map_generation") ||
data.has_attribute(
"scenario_generation")) {
730 if(
data[
"id"].empty()) {
731 if(
data[
"name"].empty()) {
732 ERR_CF <<
"Found a [campaign] with neither a name nor an id attribute, ignoring it";
734 ERR_CF <<
"Ignoring a [campaign] with no id attribute, but name '" <<
data[
"name"] <<
"'";
739 const std::string&
type =
data[
"type"];
742 if(
type ==
"mp" || (
type ==
"hybrid" &&
mp)) {
748 new_sp_campaign->mark_if_completed();
750 type_map_[level_type::type::sp_campaign].games.push_back(std::move(new_sp_campaign));
754 auto& sp_campaigns =
type_map_[level_type::type::sp_campaign].games;
757 std::stable_sort(sp_campaigns.begin(), sp_campaigns.end(),
759 return a->data()[
"rank"].to_int(1000) < b->data()[
"rank"].to_int(1000);
767 const std::string extra_name = (extra_type ==
ERA) ?
"era" :
"modification";
770 ? component_availability::type::mp
771 : component_availability::type::hybrid;
773 std::set<std::string> found_ids;
779 if((
type != component_availability::type::mp ||
mp) && (
type != component_availability::type::sp || !
mp) )
781 if(found_ids.insert(extra[
"id"]).second) {
783 new_extras_metadata->id = extra[
"id"].str();
784 new_extras_metadata->name = extra[
"name"].str();
785 new_extras_metadata->description = extra[
"description"].str();
786 new_extras_metadata->cfg = &extra;
788 extras.push_back(std::move(new_extras_metadata));
791 ERR_CF <<
"found " << extra_name <<
" with id=" << extra[
"id"] <<
" twice";
806 std::vector<level_ptr> levels;
808 levels.push_back(lvl);
818 std::vector<level_ptr> levels;
819 for(std::size_t
level : g_list.games_filtered) {
820 levels.push_back(g_list.games[
level]);
831 const std::vector<create_engine::extras_metadata_ptr>&
837 std::vector<create_engine::extras_metadata_ptr>&
A config object defines a single node in a WML file, with access to child nodes.
config & mandatory_child(config_key_type key, int n=0)
Returns the nth child with the given key, or throws an error if there is none.
bool has_child(config_key_type key) const
Determine whether a config has a child or not.
bool has_attribute(config_key_type key) const
child_itors child_range(config_key_type key)
config & add_child(config_key_type key)
std::vector< std::string > campaign_xtra_defines
more customization of data
std::vector< std::string > mod_defines
If there are defines the modifications use to customize data.
std::string scenario_define
If there is a define the scenario uses to customize data.
std::string difficulty
The difficulty level the game is being played on.
std::string era_define
If there is a define the era uses to customize data.
std::chrono::milliseconds end_text_duration
for how long the end-of-campaign text is shown
std::vector< std::string > active_mods
bool end_credits
whether to show the standard credits at the end
std::string campaign_define
If there is a define the campaign uses to customize data.
std::string campaign
The id of the campaign being played.
std::string abbrev
the campaign abbreviation
bool is_multiplayer() const
std::string end_text
end-of-campaign text
std::string campaign_name
The name of the campaign being played.
static game_config_manager * get()
void load_game_config_for_game(const game_classification &classification, const std::string &scenario_id)
void load_game_config_for_create(bool is_mp, bool is_test=false)
optional_const_config optional_child(config_key_type key) const
optional_const_config find_child(config_key_type key, const std::string &name, const std::string &value) const
config_array_view child_range(config_key_type key) const
const config & find_mandatory_child(config_key_type key, const std::string &name, const std::string &value) const
Encapsulates the map of the game.
std::string selected_difficulty() const
Returns the selected difficulty define after displaying.
bool show(const unsigned auto_close_time=0)
Shows the window.
std::pair< utils::irdya_date, utils::irdya_date > dates_
campaign(const config &data)
bool can_launch_game() const
std::string level_name_filter_
int find_extra_by_id(const MP_EXTRA extra_type, const std::string &id) const
void reset_level_filters()
create_engine(saved_game &state)
std::shared_ptr< campaign > campaign_ptr
std::vector< std::size_t > get_filtered_level_indices(level_type::type type) const
bool toggle_mod(const std::string &id, bool force=false)
void set_current_era_index(const std::size_t index, bool force=false)
std::string select_campaign_difficulty(int set_value=-1)
select_campaign_difficulty
std::vector< level_ptr > get_levels_by_type(level_type::type type) const
std::string selected_campaign_difficulty_
bool generator_has_settings() const
std::vector< std::string > & active_mods()
std::vector< std::string > user_map_names_
bool current_level_has_side_data()
Returns true if the current level has one or more [side] tags.
bool generator_assigned() const
std::map< level_type::type, type_list > type_map_
void init_extras(const MP_EXTRA extra_type)
std::vector< extras_metadata_ptr > & get_extras_by_type(const MP_EXTRA extra_type)
const std::vector< extras_metadata_ptr > & get_const_extras_by_type(const MP_EXTRA extra_type) const
void apply_level_filter(const std::string &name)
void prepare_for_new_level()
const extras_metadata & current_era() const
std::size_t current_era_index_
const config & curent_era_cfg() const
std::vector< extras_metadata_ptr > mods_
std::unique_ptr< depcheck::manager > dependency_manager_
std::vector< std::string > user_scenario_names_
std::vector< extras_metadata_ptr > active_mods_data()
std::shared_ptr< level > level_ptr
void apply_level_filters()
const game_config_view & game_config_
Reference to the main game config.
std::unique_ptr< map_generator > generator_
std::pair< level_type::type, int > find_level_by_id(const std::string &id) const
bool is_campaign() const
Wrapper to simplify the is-type-campaign-or-sp-campaign check.
std::vector< extras_metadata_ptr > eras_
void prepare_for_campaign(const std::string &difficulty="")
std::vector< level_ptr > get_levels_by_type_unfiltered(level_type::type type) const
const mp_game_settings & get_parameters()
std::shared_ptr< extras_metadata > extras_metadata_ptr
void prepare_for_saved_game()
void set_current_level(const std::size_t index)
void generator_user_config()
void prepare_for_era_and_mods()
void init_generated_level_data()
level_type::type current_level_type_
void prepare_for_scenario()
std::size_t current_level_index_
level & current_level() const
std::shared_ptr< scenario > scenario_ptr
Note to all triers: It's not guaranteed that the specified component will be selected (if the user de...
Base class for all level type classes.
const config & data() const
void set_data(const config &data)
virtual bool allow_era_choice() const
level(const config &data)
bool generate_whole_scenario() const
const config & generator_data() const
random_map(const config &data)
std::string generator_name() const
map_generator * create_map_generator() const
std::unique_ptr< gamemap > map_
scenario(const config &data)
std::string map_size() const
bool can_launch_game() const
user_map(const config &data, const std::string &name, gamemap *map)
std::string description() const
bool is_campaign_completed(const std::string &campaign_id)
game_classification & classification()
bool is_mid_game_save() const
void expand_scenario()
copies the content of a [scenario] with the correct id attribute from the game config into this objec...
void set_carryover_sides_start(config carryover_sides_start)
std::string get_scenario_id() const
static void post_scenario_generation(const config &old_scenario, config &generated_scenario)
copies attributes & tags from the 'outer' [scenario] to the scenario that is generated by scenario_ge...
mp_game_settings & mp_settings()
Multiplayer parameters for this game.
void set_scenario(config scenario)
void check_require_scenario()
Add addon_id information if needed.
void expand_random_scenario()
takes care of generate_map=, generate_scenario=, map= attributes This should be called before expandi...
static irdya_date read_date(const std::string &date)
static lg::log_domain log_mp_create_engine("mp/create/engine")
static lg::log_domain log_config("config")
Declarations for File-IO.
static std::string _(const char *str)
Standard logging facilities (interface).
map_generator * create_map_generator(const std::string &name, const config &cfg, const config *vars)
std::string get_legacy_editor_dir()
void get_files_in_dir(const std::string &dir, std::vector< std::string > *files, std::vector< std::string > *dirs, name_mode mode, filter_mode filter, reorder_mode reorder, file_tree_checksum *checksum)
Get a list of all files and/or directories in a given directory.
std::string read_map(const std::string &name)
const std::string unicode_multiplication_sign
Game configuration data as global variables.
static bool is_active(const widget *wgt)
Main entry points of multiplayer mode.
std::size_t index(std::string_view str, const std::size_t index)
Codepoint index corresponding to the nth character in a UTF-8 string.
std::vector< std::string > split(const config_attribute_value &val)
filesystem::scoped_istream preprocess_file(const std::string &fname, preproc_map *defines)
Function to use the WML preprocessor on a file.
void read(config &cfg, std::istream &in, abstract_validator *validator)
saved_game_mode::type saved_game
static constexpr utils::optional< enum_type > get_enum(const std::string_view value)
Converts a string into its enum equivalent.
Helper class, don't construct this directly.
Add a special kind of assert to validate whether the input from WML doesn't contain any problems that...