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 saved_game;
30 class gamemap;
31 
32 namespace ng {
33 
34 static bool contains_ignore_case(const std::string& str1, const std::string& str2)
35 {
36  if(str2.size() > str1.size()) {
37  return false;
38  }
39 
40  for(size_t i = 0; i < str1.size() - str2.size() + 1; i++) {
41  bool ok = true;
42  for(size_t j = 0; j < str2.size(); j++) {
43  if(std::tolower(str1[i + j]) != std::tolower(str2[j])) {
44  ok = false;
45  break;
46  }
47  }
48 
49  if(ok) {
50  return true;
51  }
52  }
53 
54  return false;
55 }
56 
57 /** Base class for all level type classes. */
58 class level
59 {
60 public:
61  level(const config& data);
62  virtual ~level() = default;
63 
65  (SCENARIO, "scenario")
66  (USER_MAP, "user_map")
67  (USER_SCENARIO, "user_scenario")
68  (RANDOM_MAP, "random_map")
69  (CAMPAIGN, "campaign")
70  (SP_CAMPAIGN, "sp_campaign")
71  )
72 
73  virtual void set_metadata() = 0;
74 
75  virtual bool can_launch_game() const = 0;
76  virtual bool player_count_filter(int player_count) const = 0;
77 
78  virtual std::string id() const
79  {
80  return data_["id"];
81  }
82 
83  virtual std::string name() const
84  {
85  return data_["name"];
86  }
87 
88  virtual std::string icon() const
89  {
90  return data_["icon"];
91  }
92 
93  virtual std::string description() const
94  {
95  return data_["description"];
96  }
97 
98  virtual bool allow_era_choice() const
99  {
100  return data_["allow_era_choice"].to_bool(true);
101  }
102 
103  void set_data(const config& data)
104  {
105  data_ = data;
106  }
107 
108  const config& data() const
109  {
110  return data_;
111  }
112 
114  {
115  return data_;
116  }
117 
118 protected:
120 
121 private:
122  level(const level&) = delete;
123  void operator=(const level&) = delete;
124 };
125 
126 class scenario : public level
127 {
128 public:
129  scenario(const config& data);
130 
131  bool can_launch_game() const;
132 
133  void set_metadata();
134 
135  int num_players() const
136  {
137  return num_players_;
138  }
139 
140  std::string map_size() const;
141 
142  bool player_count_filter(int player_count) const
143  {
144  return num_players_ == player_count;
145  }
146 
147 protected:
148  void set_sides();
149 
150  std::unique_ptr<gamemap> map_;
151 
153 
154 private:
155  scenario(const scenario&);
156  void operator=(const scenario&);
157 
159 };
160 
161 class user_map : public scenario
162 {
163 public:
164  user_map(const config& data, const std::string& name, gamemap* map);
165 
166  void set_metadata();
167 
168  /** For user maps, the id and name are the same. */
169  std::string id() const
170  {
171  return name_;
172  }
173 
175  {
176  return name_;
177  }
178 
179  std::string description() const;
180 
181 private:
182  user_map(const user_map&) = delete;
183  void operator=(const user_map&) = delete;
184 
186 };
187 
188 class random_map : public scenario
189 {
190 public:
191  random_map(const config& data);
192 
193  const config& generator_data() const
194  {
195  return generator_data_;
196  }
197 
199  {
200  return generator_name_;
201  }
202 
204 
206  {
208  }
209 
210 private:
211  random_map(const random_map&) = delete;
212  void operator=(const random_map&) = delete;
213 
215 
218 };
219 
220 class campaign : public level
221 {
222 public:
223  campaign(const config& data);
224 
225  bool can_launch_game() const;
226 
227  void set_metadata();
228 
229  void mark_if_completed();
230 
231  std::string id() const
232  {
233  return id_;
234  }
235 
236  bool allow_era_choice() const
237  {
238  return allow_era_choice_;
239  }
240 
241  int min_players() const
242  {
243  return min_players_;
244  }
245 
246  int max_players() const
247  {
248  return max_players_;
249  }
250 
251  bool player_count_filter(int player_count) const
252  {
253  return min_players_ <= player_count && max_players_ >= player_count;
254  }
255 
256  std::pair<irdya_date, irdya_date> dates() const
257  {
258  return dates_;
259  }
260 
261 private:
262  campaign(const campaign&) = delete;
263  void operator=(const campaign&) = delete;
264 
270  std::pair<irdya_date, irdya_date> dates_;
271 };
272 
274 {
275 public:
276  explicit create_engine(saved_game& state);
277 
278  enum MP_EXTRA { ERA, MOD };
279 
281  {
285  const config* cfg;
286  };
287 
288  typedef std::shared_ptr<extras_metadata> extras_metadata_ptr;
289 
290  typedef std::shared_ptr<level> level_ptr;
291  typedef std::shared_ptr<scenario> scenario_ptr;
292  typedef std::shared_ptr<user_map> user_map_ptr;
293  typedef std::shared_ptr<random_map> random_map_ptr;
294  typedef std::shared_ptr<campaign> campaign_ptr;
295 
297 
298  void prepare_for_new_level();
300  void prepare_for_scenario();
301  void prepare_for_campaign(const std::string& difficulty = "");
302  void prepare_for_saved_game();
303  // random maps, user maps
304  void prepare_for_other();
305 
306  /**
307  * select_campaign_difficulty
308  *
309  * Launches difficulty selection gui and returns selected difficulty name.
310  *
311  * The gui can be bypassed by supplying a number from 1 to the number of
312  * difficulties available, corresponding to a choice of difficulty.
313  * This is useful for specifying difficulty via command line.
314  *
315  * @param set_value Preselected difficulty number. The default -1 launches the gui.
316  * @return Selected difficulty. Returns "FAIL" if set_value is invalid,
317  * and "CANCEL" if the gui is canceled.
318  */
319  std::string select_campaign_difficulty(int set_value = -1);
321  {
323  }
324 
325  void apply_level_filter(const std::string& name);
326  void apply_level_filter(int players);
327  void reset_level_filters();
328 
330  {
331  return level_name_filter_;
332  }
333 
334  int player_num_filter() const
335  {
336  return player_count_filter_;
337  }
338 
339  std::vector<level_ptr> get_levels_by_type_unfiltered(level::TYPE type) const;
340  std::vector<level_ptr> get_levels_by_type(level::TYPE type) const;
341 
342  std::vector<size_t> get_filtered_level_indices(level::TYPE type) const;
343 
344  level& current_level() const;
345  const extras_metadata& current_era() const;
346 
348  {
350  }
351 
353  {
354  return current_level_type_;
355  }
356 
357  void set_current_level(const size_t index);
358 
359  void set_current_era_index(const size_t index, bool force = false);
360 
361  size_t current_era_index() const
362  {
363  return current_era_index_;
364  }
365 
366  const config& curent_era_cfg() const;
367 
368  const std::vector<extras_metadata_ptr>& get_const_extras_by_type(const MP_EXTRA extra_type) const;
369  std::vector<extras_metadata_ptr>& get_extras_by_type(const MP_EXTRA extra_type);
370 
371  bool toggle_mod(int index, bool force = false);
372 
373  bool generator_assigned() const;
374  bool generator_has_settings() const;
375  void generator_user_config();
376 
377  std::pair<level::TYPE, int> find_level_by_id(const std::string& id) const;
378  int find_extra_by_id(const MP_EXTRA extra_type, const std::string& id) const;
379 
380  const depcheck::manager& dependency_manager() const
381  {
382  return *dependency_manager_;
383  }
384 
385  void init_active_mods();
386 
387  std::vector<std::string>& active_mods();
388  std::vector<extras_metadata_ptr> active_mods_data();
389 
391 
393 
394  /** Returns true if the current level has one or more [side] tags. */
396 
397 private:
398  create_engine(const create_engine&) = delete;
399  void operator=(const create_engine&) = delete;
400 
401  void init_all_levels();
402  void init_extras(const MP_EXTRA extra_type);
403  void apply_level_filters();
404 
405  size_t map_level_index(size_t index) const;
406 
409 
411 
414 
415  struct type_list
416  {
417  explicit type_list() : games(), games_filtered() {}
418 
419  std::vector<level_ptr> games;
420  std::vector<size_t> games_filtered;
421 
422  void apply_filter(const int player_count, const std::string& name_filter)
423  {
424  games_filtered.clear();
425 
426  for(size_t i = 0; i < games.size(); i++) {
427  const bool num_players_match = player_count == 1 || games[i]->player_count_filter(player_count);
428 
429  if(contains_ignore_case(games[i]->name(), name_filter) && num_players_match) {
430  games_filtered.push_back(i);
431  }
432  }
433  }
434 
436  {
437  games_filtered.resize(games.size());
438  std::iota(games_filtered.begin(), games_filtered.end(), 0);
439  }
440  };
441 
442  std::map<level::TYPE, type_list> type_map_;
443 
444  std::vector<std::string> user_map_names_;
445  std::vector<std::string> user_scenario_names_;
446 
447  std::vector<extras_metadata_ptr> eras_;
448  std::vector<extras_metadata_ptr> mods_;
449 
451 
452  // Never nullptr
453  std::unique_ptr<depcheck::manager> dependency_manager_;
454 
455  std::unique_ptr<map_generator> generator_;
456 
458 
459  /** Reference to the main game config. */
461 };
462 
463 } // end namespace ng
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
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
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 toggle_mod(int index, bool force=false)
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 config & generator_data() const
level::TYPE current_level_type_
Encapsulates the map of the game.
Definition: map.hpp:34
std::shared_ptr< random_map > random_map_ptr
create_engine(saved_game &state)
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
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
const extras_metadata & current_era() const
size_t i
Definition: function.cpp:933
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_
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)
std::pair< level::TYPE, int > find_level_by_id(const std::string &id) const
std::string name() const
const config & game_config_
Reference to the main game config.
virtual bool can_launch_game() const =0
void init_extras(const MP_EXTRA extra_type)