The Battle for Wesnoth  1.17.4+dev
game_classification.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2003 - 2022
3  by David White <dave@whitevine.net>
4  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY.
12 
13  See the COPYING file for more details.
14 */
15 
16 #include "game_classification.hpp"
17 
18 #include "config.hpp"
19 #include "log.hpp"
21 #include "game_version.hpp"
22 #include "game_config_manager.hpp"
23 
24 #include <list>
25 
26 static lg::log_domain log_engine("engine");
27 #define ERR_NG LOG_STREAM(err, log_engine)
28 #define WRN_NG LOG_STREAM(warn, log_engine)
29 #define LOG_NG LOG_STREAM(info, log_engine)
30 #define DBG_NG LOG_STREAM(debug, log_engine)
31 
32 /** The default difficulty setting for campaigns. */
33 const std::string DEFAULT_DIFFICULTY("NORMAL");
34 
36  : label(cfg["label"])
37  , version(cfg["version"])
38  , type(campaign_type::get_enum(cfg["campaign_type"].str()).value_or(campaign_type::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::get_string(type);
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() ? campaign_type::multiplayer : campaign_type::scenario;
88  }
89 
90  if(is_tutorial()) {
91  return campaign_type::scenario;
92  }
93 
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  for(const auto& mod : active_mods) {
121  mods.emplace_back("modification", mod);
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  } else {
153  ERR_NG << "Unable to find config for content " << current.id << " of type " << current.type;
154  }
155  mods.pop_front( );
156  }
157 
158  DBG_NG << "Active content for game set to:" << std::endl;
159  for(const std::string& mod : res) {
160  DBG_NG << mod << std::endl;
161  }
162 
163  return res;
164 }
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:344
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:217
The base template for associating string values with enum values.
Definition: enum_base.hpp:31
std::vector< std::string > active_mods
#define ERR_NG
#define DBG_NG
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:215
campaign_type::type type
std::vector< std::string > campaign_xtra_defines
more customization of data
Game configuration data as global variables.
Definition: build_info.cpp:60
static std::string get_string(typename T::type key)
Uses the int value of the provided enum to get the associated index of the values array in the implem...
Definition: enum_base.hpp:42
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:60
std::string get_tagname() const