The Battle for Wesnoth  1.13.10+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
create_engine.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2013 - 2017 by Andrius Silinskas <silinskas.andrius@gmail.com>
3  Part of the Battle for Wesnoth Project http://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 #pragma once
16 
17 #include "config.hpp"
20 #include "mp_game_settings.hpp"
21 #include "utils/make_enum.hpp"
22 #include "utils/irdya_datetime.hpp"
23 
24 #include <numeric>
25 #include <string>
26 #include <utility>
27 #include <cctype>
28 
29 class CVideo;
30 class saved_game;
31 class gamemap;
32 
33 namespace ng {
34 
35 static bool contains_ignore_case(const std::string& str1, const std::string& str2)
36 {
37  if(str2.size() > str1.size()) {
38  return false;
39  }
40 
41  for(size_t i = 0; i < str1.size() - str2.size() + 1; i++) {
42  bool ok = true;
43  for(size_t j = 0; j < str2.size(); j++) {
44  if(std::tolower(str1[i + j]) != std::tolower(str2[j])) {
45  ok = false;
46  break;
47  }
48  }
49 
50  if(ok) {
51  return true;
52  }
53  }
54 
55  return false;
56 }
57 
58 /** Base class for all level type classes. */
59 class level
60 {
61 public:
62  level(const config& data);
63  virtual ~level() = default;
64 
66  (SCENARIO, "scenario")
67  (USER_MAP, "user_map")
68  (USER_SCENARIO, "user_scenario")
69  (RANDOM_MAP, "random_map")
70  (CAMPAIGN, "campaign")
71  (SP_CAMPAIGN, "sp_campaign")
72  )
73 
74  virtual void set_metadata() = 0;
75 
76  virtual bool can_launch_game() const = 0;
77  virtual bool player_count_filter(int player_count) const = 0;
78 
79  virtual std::string id() const
80  {
81  return data_["id"];
82  }
83 
84  virtual std::string name() const
85  {
86  return data_["name"];
87  }
88 
89  virtual std::string icon() const
90  {
91  return data_["icon"];
92  }
93 
94  virtual std::string description() const
95  {
96  return data_["description"];
97  }
98 
99  virtual bool allow_era_choice() const
100  {
101  return data_["allow_era_choice"].to_bool(true);
102  }
103 
104  void set_data(const config& data)
105  {
106  data_ = data;
107  }
108 
109  const config& data() const
110  {
111  return data_;
112  }
113 
115  {
116  return data_;
117  }
118 
119 protected:
121 
122 private:
123  level(const level&) = delete;
124  void operator=(const level&) = delete;
125 };
126 
127 class scenario : public level
128 {
129 public:
130  scenario(const config& data);
131 
132  bool can_launch_game() const;
133 
134  void set_metadata();
135 
136  int num_players() const
137  {
138  return num_players_;
139  }
140 
141  std::string map_size() const;
142 
143  bool player_count_filter(int player_count) const
144  {
145  return num_players_ == player_count;
146  }
147 
148 protected:
149  void set_sides();
150 
151  std::unique_ptr<gamemap> map_;
152 
154 
155 private:
156  scenario(const scenario&);
157  void operator=(const scenario&);
158 
160 };
161 
162 class user_map : public scenario
163 {
164 public:
165  user_map(const config& data, const std::string& name, gamemap* map);
166 
167  void set_metadata();
168 
169  /** For user maps, the id and name are the same. */
170  std::string id() const
171  {
172  return name_;
173  }
174 
176  {
177  return name_;
178  }
179 
180  std::string description() const;
181 
182 private:
183  user_map(const user_map&) = delete;
184  void operator=(const user_map&) = delete;
185 
187 };
188 
189 class random_map : public scenario
190 {
191 public:
192  random_map(const config& data);
193 
194  const config& generator_data() const
195  {
196  return generator_data_;
197  }
198 
200  {
201  return generator_name_;
202  }
203 
205 
207  {
209  }
210 
211 private:
212  random_map(const random_map&) = delete;
213  void operator=(const random_map&) = delete;
214 
216 
219 };
220 
221 class campaign : public level
222 {
223 public:
224  campaign(const config& data);
225 
226  bool can_launch_game() const;
227 
228  void set_metadata();
229 
230  void mark_if_completed();
231 
232  std::string id() const
233  {
234  return id_;
235  }
236 
237  bool allow_era_choice() const
238  {
239  return allow_era_choice_;
240  }
241 
242  int min_players() const
243  {
244  return min_players_;
245  }
246 
247  int max_players() const
248  {
249  return max_players_;
250  }
251 
252  bool player_count_filter(int player_count) const
253  {
254  return min_players_ <= player_count && max_players_ >= player_count;
255  }
256 
257  std::pair<irdya_date, irdya_date> dates() const
258  {
259  return dates_;
260  }
261 
262 private:
263  campaign(const campaign&) = delete;
264  void operator=(const campaign&) = delete;
265 
271  std::pair<irdya_date, irdya_date> dates_;
272 };
273 
275 {
276 public:
277  create_engine(CVideo& v, saved_game& state);
278 
279  enum MP_EXTRA { ERA, MOD };
280 
282  {
286  const config* cfg;
287  };
288 
289  typedef std::shared_ptr<extras_metadata> extras_metadata_ptr;
290 
291  typedef std::shared_ptr<level> level_ptr;
292  typedef std::shared_ptr<scenario> scenario_ptr;
293  typedef std::shared_ptr<user_map> user_map_ptr;
294  typedef std::shared_ptr<random_map> random_map_ptr;
295  typedef std::shared_ptr<campaign> campaign_ptr;
296 
298 
299  void prepare_for_new_level();
301  void prepare_for_scenario();
302  void prepare_for_campaign(const std::string& difficulty = "");
303  void prepare_for_saved_game();
304  // random maps, user maps
305  void prepare_for_other();
306 
307  /**
308  * select_campaign_difficulty
309  *
310  * Launches difficulty selection gui and returns selected difficulty name.
311  *
312  * The gui can be bypassed by supplying a number from 1 to the number of
313  * difficulties available, corresponding to a choice of difficulty.
314  * This is useful for specifying difficulty via command line.
315  *
316  * @param set_value Preselected difficulty number. The default -1 launches the gui.
317  * @return Selected difficulty. Returns "FAIL" if set_value is invalid,
318  * and "CANCEL" if the gui is canceled.
319  */
320  std::string select_campaign_difficulty(int set_value = -1);
322  {
324  }
325 
326  void apply_level_filter(const std::string& name);
327  void apply_level_filter(int players);
328  void reset_level_filters();
329 
331  {
332  return level_name_filter_;
333  }
334 
335  int player_num_filter() const
336  {
337  return player_count_filter_;
338  }
339 
340  std::vector<level_ptr> get_levels_by_type_unfiltered(level::TYPE type) const;
341  std::vector<level_ptr> get_levels_by_type(level::TYPE type) const;
342 
343  std::vector<size_t> get_filtered_level_indices(level::TYPE type) const;
344 
345  level& current_level() const;
346  const extras_metadata& current_extra(const MP_EXTRA extra_type) const;
347 
349  {
351  }
352 
354  {
355  return current_level_type_;
356  }
357 
358  void set_current_level(const size_t index);
359 
360  void set_current_era_index(const size_t index, bool force = false);
361  void set_current_mod_index(const size_t index)
362  {
364  }
365 
366  size_t current_era_index() const
367  {
368  return current_era_index_;
369  }
370 
371  size_t current_mod_index() const
372  {
373  return current_mod_index_;
374  }
375 
376  const config& curent_era_cfg() const;
377 
378  const std::vector<extras_metadata_ptr>& get_const_extras_by_type(const MP_EXTRA extra_type) const;
379  std::vector<extras_metadata_ptr>& get_extras_by_type(const MP_EXTRA extra_type);
380 
381  bool toggle_current_mod(bool force = false);
382 
383  bool generator_assigned() const;
384  bool generator_has_settings() const;
385  void generator_user_config();
386 
387  int find_level_by_id(const std::string& id) const;
388  int find_extra_by_id(const MP_EXTRA extra_type, const std::string& id) const;
390 
391  const depcheck::manager& dependency_manager() const
392  {
393  return *dependency_manager_;
394  }
395 
396  void init_active_mods();
397 
398  std::vector<std::string>& active_mods();
399  std::vector<extras_metadata_ptr> active_mods_data();
400 
402 
404 
405  /** Returns true if the current level has one or more [side] tags. */
407 
408 private:
409  create_engine(const create_engine&) = delete;
410  void operator=(const create_engine&) = delete;
411 
412  void init_all_levels();
413  void init_extras(const MP_EXTRA extra_type);
414  void apply_level_filters();
415 
416  size_t map_level_index(size_t index) const;
417 
420 
423 
426 
427  struct type_list
428  {
429  explicit type_list() : games(), games_filtered() {}
430 
431  std::vector<level_ptr> games;
432  std::vector<size_t> games_filtered;
433 
434  void apply_filter(const int player_count, const std::string& name_filter)
435  {
436  games_filtered.clear();
437 
438  for(size_t i = 0; i < games.size(); i++) {
439  const bool num_players_match = player_count == 1 || games[i]->player_count_filter(player_count);
440 
441  if(contains_ignore_case(games[i]->name(), name_filter) && num_players_match) {
442  games_filtered.push_back(i);
443  }
444  }
445  }
446 
448  {
449  games_filtered.resize(games.size());
450  std::iota(games_filtered.begin(), games_filtered.end(), 0);
451  }
452  };
453 
454  std::map<level::TYPE, type_list> type_map_;
455 
456  std::vector<std::string> user_map_names_;
457  std::vector<std::string> user_scenario_names_;
458 
459  std::vector<extras_metadata_ptr> eras_;
460  std::vector<extras_metadata_ptr> mods_;
461 
463 
465 
466  // Never nullptr
467  std::unique_ptr<depcheck::manager> dependency_manager_;
468 
469  std::unique_ptr<map_generator> generator_;
470 
472 };
473 
474 } // end namespace ng
void set_current_mod_index(const size_t index)
TYPE
UNSCALED : image will be drawn "as is" without changing size, even in case of redraw SCALED_TO_ZOOM :...
Definition: image.hpp:189
void operator=(const level &)=delete
std::vector< char_t > string
size_t index(const utf8::string &str, const size_t index)
Codepoint index corresponding to the nth character in a UTF-8 string.
Definition: unicode.cpp:71
std::string get_selected_campaign_difficulty() const
saved_game & get_state()
std::vector< extras_metadata_ptr > mods_
bool can_launch_game() const
std::shared_ptr< level > level_ptr
std::shared_ptr< campaign > campaign_ptr
const std::vector< extras_metadata_ptr > & get_const_extras_by_type(const MP_EXTRA extra_type) const
virtual ~level()=default
std::vector< extras_metadata_ptr > & get_extras_by_type(const MP_EXTRA extra_type)
int player_num_filter() const
std::vector< level_ptr > get_levels_by_type(level::TYPE type) const
std::string generator_name() const
level & current_level() const
Definition: video.hpp:29
std::vector< std::string > user_scenario_names_
std::vector< level_ptr > games
virtual bool allow_era_choice() const
std::string id() const
std::vector< level_ptr > get_levels_by_type_unfiltered(level::TYPE type) const
bool generate_whole_scenario_
void operator=(const scenario &)
int min_players() const
std::shared_ptr< scenario > scenario_ptr
size_t current_era_index() const
bool generate_whole_scenario() const
void set_current_era_index(const size_t index, bool force=false)
void set_data(const config &data)
virtual std::string icon() const
void operator=(const campaign &)=delete
void set_current_level(const size_t index)
const config & data() const
config & data()
const mp_game_settings & get_parameters()
void prepare_for_era_and_mods()
Definitions for the interface to Wesnoth Markup Language (WML).
bool current_level_has_side_data()
Returns true if the current level has one or more [side] tags.
bool generator_assigned() const
bool toggle_current_mod(bool force=false)
virtual std::string description() const
campaign(const config &data)
bool can_launch_game() const
std::string select_campaign_difficulty(int set_value=-1)
select_campaign_difficulty
void operator=(const user_map &)=delete
std::map< level::TYPE, type_list > type_map_
virtual std::string id() const
std::vector< extras_metadata_ptr > active_mods_data()
size_t map_level_index(size_t index) const
void set_current_level_type(const level::TYPE type)
std::string selected_campaign_difficulty_
std::string level_name_filter_
bool player_count_filter(int player_count) const
std::pair< irdya_date, irdya_date > dates_
saved_game & state_
void set_metadata()
void prepare_for_campaign(const std::string &difficulty="")
std::unique_ptr< depcheck::manager > dependency_manager_
const extras_metadata & current_extra(const MP_EXTRA extra_type) const
const config & generator_data() const
size_t current_mod_index() const
level::TYPE current_level_type_
Encapsulates the map of the game.
Definition: map.hpp:34
std::shared_ptr< random_map > random_map_ptr
std::unique_ptr< gamemap > map_
std::string image_label_
std::vector< std::string > & active_mods()
std::shared_ptr< user_map > user_map_ptr
void apply_level_filter(const std::string &name)
void init_generated_level_data()
int find_extra_by_id(const MP_EXTRA extra_type, const std::string &id) const
std::string map_hash_
void mark_if_completed()
scenario(const config &data)
std::string id() const
For user maps, the id and name are the same.
bool allow_era_choice() const
void apply_filter(const int player_count, const std::string &name_filter)
bool player_count_filter(int player_count) const
level::TYPE find_level_type_by_id(const std::string &id) const
std::vector< size_t > get_filtered_level_indices(level::TYPE type) const
std::string description() const
level(const config &data)
std::vector< size_t > games_filtered
map_generator * create_map_generator() const
#define i
std::unique_ptr< map_generator > generator_
std::vector< std::string > user_map_names_
void operator=(const create_engine &)=delete
level::TYPE current_level_type() const
std::shared_ptr< extras_metadata > extras_metadata_ptr
std::string name_
std::vector< extras_metadata_ptr > eras_
bool generator_has_settings() const
int max_players() const
random_map(const config &data)
MAKE_ENUM(TYPE,(SCENARIO,"scenario")(USER_MAP,"user_map")(USER_SCENARIO,"user_scenario")(RANDOM_MAP,"random_map")(CAMPAIGN,"campaign")(SP_CAMPAIGN,"sp_campaign")) virtual void set_metadata()=0
const std::string & level_name_filter() const
std::pair< irdya_date, irdya_date > dates() const
Base class for all level type classes.
std::string id_
virtual bool player_count_filter(int player_count) const =0
int num_players() const
static const char * name(const std::vector< SDL_Joystick * > &joysticks, const size_t index)
Definition: joystick.cpp:48
void operator=(const random_map &)=delete
const depcheck::manager & dependency_manager() const
static bool contains_ignore_case(const std::string &str1, const std::string &str2)
const config & curent_era_cfg() const
virtual std::string name() const
std::string generator_name_
int find_level_by_id(const std::string &id) const
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:93
std::string map_size() const
Defines the MAKE_ENUM macro.
user_map(const config &data, const std::string &name, gamemap *map)
create_engine(CVideo &v, saved_game &state)
std::string name() const
virtual bool can_launch_game() const =0
void init_extras(const MP_EXTRA extra_type)