The Battle for Wesnoth  1.17.0-dev
game_classification.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2003 - 2018 by David White <dave@whitevine.net>
3  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 #include "game_classification.hpp"
16 
17 #include "config.hpp"
18 #include "log.hpp"
20 #include "game_version.hpp"
21 #include "game_config_manager.hpp"
22 
23 #include <list>
24 
25 static lg::log_domain log_engine("engine");
26 #define ERR_NG LOG_STREAM(err, log_engine)
27 #define WRN_NG LOG_STREAM(warn, log_engine)
28 #define LOG_NG LOG_STREAM(info, log_engine)
29 #define DBG_NG LOG_STREAM(debug, log_engine)
30 
31 /** The default difficulty setting for campaigns. */
32 const std::string DEFAULT_DIFFICULTY("NORMAL");
33 
35  : label(cfg["label"])
36  , version(cfg["version"])
37  , campaign_type(
38  cfg["campaign_type"].to_enum<game_classification::CAMPAIGN_TYPE>(game_classification::CAMPAIGN_TYPE::SCENARIO))
39  , campaign_define(cfg["campaign_define"])
40  , campaign_xtra_defines(utils::split(cfg["campaign_extra_defines"]))
41  , scenario_define(cfg["scenario_define"])
42  , era_define(cfg["era_define"])
43  , mod_defines(utils::split(cfg["mod_defines"]))
44  , active_mods(utils::split(cfg["active_mods"]))
45  , era_id(cfg["era_id"])
46  , campaign(cfg["campaign"])
47  , campaign_name(cfg["campaign_name"])
48  , abbrev(cfg["abbrev"])
49  , end_credits(cfg["end_credits"].to_bool(true))
50  , end_text(cfg["end_text"])
51  , end_text_duration(std::clamp<unsigned>(cfg["end_text_duration"].to_unsigned(0), 0, 5000))
52  , difficulty(cfg["difficulty"].empty() ? DEFAULT_DIFFICULTY : cfg["difficulty"].str())
53  , random_mode(cfg["random_mode"])
54  , oos_debug(cfg["oos_debug"].to_bool(false))
55 {
56 }
57 
59 {
60  config cfg;
61  cfg["label"] = label;
62  cfg["version"] = game_config::wesnoth_version.str();
63  cfg["campaign_type"] = campaign_type.to_string();
64  cfg["campaign_define"] = campaign_define;
65  cfg["campaign_extra_defines"] = utils::join(campaign_xtra_defines);
66  cfg["scenario_define"] = scenario_define;
67  cfg["era_define"] = era_define;
68  cfg["mod_defines"] = utils::join(mod_defines);
69  cfg["active_mods"] = utils::join(active_mods);
70  cfg["era_id"] = era_id;
71  cfg["campaign"] = campaign;
72  cfg["campaign_name"] = campaign_name;
73  cfg["abbrev"] = abbrev;
74  cfg["end_credits"] = end_credits;
75  cfg["end_text"] = end_text;
76  cfg["end_text_duration"] = std::to_string(end_text_duration);
77  cfg["difficulty"] = difficulty;
78  cfg["random_mode"] = random_mode;
79  cfg["oos_debug"] = oos_debug;
80 
81  return cfg;
82 }
83 
85 {
86  if(is_multiplayer()) {
87  return campaign.empty() ? "multiplayer" : "scenario";
88  }
89 
90  if(is_tutorial()) {
91  return "scenario";
92  }
93 
94  return campaign_type.to_string();
95 }
96 
97 namespace
98 {
99 // helper objects for saved_game::expand_mp_events()
100 struct modevents_entry
101 {
102  modevents_entry(const std::string& _type, const std::string& _id)
103  : type(_type)
104  , id(_id)
105  {
106  }
107 
108  std::string type;
109  std::string id;
110 };
111 }
112 
113 std::set<std::string> game_classification::active_addons(const std::string& scenario_id) const
114 {
115  //FIXME: this doesn't include mods from the current scenario.
116  std::list<modevents_entry> mods;
117  std::set<std::string> loaded_resources;
118  std::set<std::string> res;
119 
120  std::transform(active_mods.begin(), active_mods.end(), std::back_inserter(mods),
121  [](const std::string& id) { return modevents_entry("modification", id); }
122  );
123 
124  // We don't want the error message below if there is no era (= if this is a sp game).
125  if(!era_id.empty()) {
126  mods.emplace_back(get_tagname(), scenario_id);
127  }
128 
129  if(!era_id.empty()) {
130  mods.emplace_back("era", era_id);
131  }
132 
133  if(!campaign.empty()) {
134  mods.emplace_back("campaign", campaign);
135  }
136  while(!mods.empty()) {
137 
138  const modevents_entry& current = mods.front();
139  if(current.type == "resource") {
140  if(!loaded_resources.insert(current.id).second) {
141  mods.pop_front();
142  continue;
143  }
144  }
145  if(const config& cfg = game_config_manager::get()->game_config().find_child(current.type, "id", current.id)) {
146  if(!cfg["addon_id"].empty()) {
147  res.insert(cfg["addon_id"]);
148  }
149  for (const config& load_res : cfg.child_range("load_resource")) {
150  mods.emplace_back("resource", load_res["id"].str());
151  }
152  }
153  mods.pop_front( );
154  }
155  return res;
156 }
unsigned int end_text_duration
for how long the end-of-campaign text is shown
bool end_credits
whether to show the standard credits at the end
std::string label
Name of the game (e.g.
Interfaces for manipulating version numbers of engine, add-ons, etc.
std::string join(const T &v, const std::string &s=",")
Generates a new string joining container items in a list.
child_itors child_range(config_key_type key)
Definition: config.cpp:360
std::string campaign_name
The name of the campaign being played.
STL namespace.
const std::string DEFAULT_DIFFICULTY("NORMAL")
The default difficulty setting for campaigns.
Definitions for the interface to Wesnoth Markup Language (WML).
static lg::log_domain log_engine("engine")
static game_config_manager * get()
std::set< std::string > active_addons(const std::string &scenario_id) const
std::string label
What to show in the filter&#39;s drop-down list.
Definition: manager.cpp:216
std::vector< std::string > active_mods
std::string campaign_define
If there is a define the campaign uses to customize data.
std::string end_text
end-of-campaign text
std::string campaign
The id of the campaign being played.
std::string era_define
If there is a define the era uses to customize data.
std::string abbrev
the campaign abbreviation
std::string id
Text to match against addon_info.tags()
Definition: manager.cpp:214
std::vector< std::string > campaign_xtra_defines
more customization of data
Game configuration data as global variables.
Definition: build_info.cpp:58
std::string scenario_define
If there is a define the scenario uses to customize data.
std::vector< std::string > mod_defines
If there are defines the modifications use to customize data.
game_classification()=default
const version_info wesnoth_version(VERSION)
std::string difficulty
The difficulty level the game is being played on.
std::vector< std::string > split(const config_attribute_value &val)
Standard logging facilities (interface).
std::string str() const
Serializes the version number into string form.
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:59
std::string get_tagname() const