The Battle for Wesnoth  1.15.0-dev
map_context.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2008 - 2018 by Tomasz Sniatowski <kailoran@gmail.com>
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 #pragma once
16 
18 #include "game_classification.hpp"
19 #include "map/label.hpp"
20 #include "mp_game_settings.hpp"
21 #include "sound_music_track.hpp"
22 #include "team.hpp"
23 #include "tod_manager.hpp"
24 #include "units/map.hpp"
25 #include "overlay.hpp"
26 #include "display_context.hpp"
27 
28 #include <vector>
29 
30 namespace editor {
31 
33  editor_team_info(const team& t);
34 
35  int side;
36  std::string id;
37  std::string name;
38  int gold;
39  int income;
42  bool fog;
43  bool shroud;
44  team::SHARE_VISION share_vision;
45  team::CONTROLLER controller;
46  bool no_leader;
47  bool hidden;
48 };
49 
50 /**
51  * This class wraps around a map to provide a concise interface for the editor to work with.
52  * The actual map object can change rapidly (be assigned to), the map context persists
53  * data (like the undo stacks) in this case. The functionality is here, not in editor_controller
54  * as e.g. the undo stack is part of the map, not the editor as a whole. This might allow many
55  * maps to be open at the same time.
56  */
58 {
59 public:
60  map_context(const map_context&) = delete;
61  map_context& operator=(const map_context&) = delete;
62 
63  /**
64  * Create a map context from an existing map. The filename is set to be
65  * empty, indicating a new map.
66  * Marked "explicit" to avoid automatic conversions.
67  */
68  explicit map_context(const editor_map& map, bool pure_map, const config& schedule);
69 
70  /**
71  * Create map_context from a map file. If the map cannot be loaded, an
72  * exception will be thrown and the object will not be constructed. If the
73  * map file is a scenario, the map specified in its map_data key will be
74  * loaded, and the stored filename updated accordingly. Maps embedded
75  * inside scenarios do not change the filename, but set the "embedded" flag
76  * instead.
77  */
78  map_context(const config& game_config, const std::string& filename);
79 
80  /**
81  * Map context destructor
82  */
83  virtual ~map_context();
84 
85  /**
86  * Select the nth tod area.
87  * @param index of the tod area to select.
88  */
89  bool select_area(int index);
90 
91  /** Adds a new side to the map */
92  void new_side();
93 
94  /** removes the last side from the scenario */
95  void remove_side() {
96  teams_.pop_back();
97  ++actions_since_save_;
98  }
99 
100  void save_area(const std::set<map_location>& area) {
101  tod_manager_->replace_area_locations(active_area_, area);
102  }
103 
104  void new_area(const std::set<map_location>& area) {
105  tod_manager_->add_time_area("", area, config());
106  active_area_ = tod_manager_->get_area_ids().size() -1;
107  ++actions_since_save_;
108  }
109 
110  void remove_area(int index);
111 
113  return labels_;
114  }
115 
116  void replace_schedule(const std::vector<time_of_day>& schedule);
117 
118  // Import symbols from base class.
121  using display_context::map;
122 
123  /** Const units accessor. */
124  virtual const unit_map& units() const override
125  {
126  return units_;
127  }
128 
129  /** Local non-const overload of @ref units */
131  {
132  return units_;
133  }
134 
135  /** Const teams accessor. */
136  virtual const std::vector<team>& teams() const override
137  {
138  return teams_;
139  }
140 
141  /** Local non-const overload of @ref teams */
142  std::vector<team>& teams()
143  {
144  return teams_;
145  }
146 
147  /** Const map accessor. */
148  virtual const editor_map& map() const override
149  {
150  return map_;
151  }
152 
153  /** Local non-const overload of @ref map */
155  {
156  return map_;
157  }
158 
159  virtual const std::vector<std::string>& hidden_label_categories() const override
160  {
161  return lbl_categories_;
162  }
163 
164  /**
165  * Replace the [time]s of the currently active area.
166  */
167  void replace_local_schedule(const std::vector<time_of_day>& schedule);
168 
169  /**
170  * TODO
171  */
172  void set_starting_time(int time);
173 
174  /**
175  * TODO
176  */
177  void set_local_starting_time(int time) {
178  tod_manager_->set_current_time(time, active_area_);
179  ++actions_since_save_;
180  }
181 
182  const tod_manager* get_time_manager() const {
183  return tod_manager_.get();
184  }
185 
187  return tod_manager_.get();
188  }
189 
191  return mp_settings_;
192  }
194  return game_classification_;
195  }
196 
197  /**
198  *
199  * @return the index of the currently active area.
200  */
201  int get_active_area() const {
202  return active_area_;
203  }
204 
205  void set_active_area(int index) {
206  active_area_ = index;
207  }
208 
209  bool is_in_playlist(std::string track_id) {
210  return music_tracks_.find(track_id) != music_tracks_.end();
211  }
212 
213  void add_to_playlist(const sound::music_track& track) {
214 
215  if (music_tracks_.find(track.id()) == music_tracks_.end())
216  music_tracks_.emplace(track.id(), track);
217  else music_tracks_.erase(track.id());
218  }
219 
220  /**
221  * Draw a terrain on a single location on the map.
222  * Sets the refresh flags accordingly.
223  */
224  void draw_terrain(const t_translation::terrain_code & terrain, const map_location& loc,
225  bool one_layer_only = false);
226 
227  /**
228  * Actual drawing function used by both overloaded variants of draw_terrain.
229  */
230  void draw_terrain_actual(const t_translation::terrain_code & terrain, const map_location& loc,
231  bool one_layer_only = false);
232 
233  /**
234  * Draw a terrain on a set of locations on the map.
235  * Sets the refresh flags accordingly.
236  */
237  void draw_terrain(const t_translation::terrain_code & terrain, const std::set<map_location>& locs,
238  bool one_layer_only = false);
239 
240  /**
241  * Getter for the reload flag. Reload is the highest level of required refreshing,
242  * set when the map size has changed or the map was reassigned.
243  */
244  bool needs_reload() const { return needs_reload_; }
245 
246  /**
247  * Setter for the reload flag
248  */
249  void set_needs_reload(bool value=true) { needs_reload_ = value; }
250 
251  /**
252  * Getter for the terrain rebuild flag. Set whenever any terrain has changed.
253  */
254  bool needs_terrain_rebuild() const { return needs_terrain_rebuild_; }
255 
256  /**
257  * Setter for the terrain rebuild flag
258  */
259  void set_needs_terrain_rebuild(bool value=true) { needs_terrain_rebuild_ = value; }
260 
261  /**
262  * TODO
263  */
264  void set_scenario_setup(const std::string& id, const std::string& name, const std::string& description,
265  int turns, int xp_mod, bool victory_defeated, bool random_time);
266 
267  /**
268  * TODO
269  */
270  void set_side_setup(editor_team_info& info);
271 
272  /**
273  * Getter for the labels reset flag. Set when the labels need to be refreshed.
274  */
275  bool needs_labels_reset() const { return needs_labels_reset_; }
276 
277  /**
278  * Setter for the labels reset flag
279  */
280  void set_needs_labels_reset(bool value=true) { needs_labels_reset_ = value; }
281 
282  const std::set<map_location> changed_locations() const { return changed_locations_; }
283  void clear_changed_locations();
284  void add_changed_location(const map_location& loc);
285  void add_changed_location(const std::set<map_location>& locs);
286  void set_everything_changed();
287  bool everything_changed() const;
288 
289  void set_labels(display& disp);
290 
291  void clear_starting_position_labels(display& disp);
292 
293  void set_starting_position_labels(display& disp);
294 
295  void reset_starting_position_labels(display& disp);
296 
297  const std::string& get_filename() const { return filename_; }
298 
299  void set_filename(const std::string& fn) { filename_ = fn; }
300 
301  const std::string& get_map_data_key() const { return map_data_key_; }
302 
303  const std::string& get_id() const { return scenario_id_; }
304  const std::string& get_description() const { return scenario_description_; }
305  const std::string& get_name() const { return scenario_name_; }
306 
307  const t_string get_default_context_name() const;
308 
309  int get_xp_mod() const { return xp_mod_; }
310 
311  bool random_start_time() const { return random_time_; }
312  bool victory_defeated() const { return victory_defeated_; }
313 
314  bool is_embedded() const { return embedded_; }
315 
316  bool is_pure_map() const { return pure_map_; }
317 
318  void set_embedded(bool v) { embedded_ = v; }
319 
320  /**
321  * Saves the map under the current filename. Filename must be valid.
322  * May throw an exception on failure.
323  */
324  bool save_map();
325 
326  /**
327  * Saves the scenario under the current filename. Filename must be valid.
328  * May throw an exception on failure.
329  */
330  bool save_scenario();
331 
332 
333  void load_scenario(const config& game_config);
334 
335  config to_config();
336 
337  void set_map(const editor_map& map);
338 
339  /**
340  * Performs an action (thus modifying the map). An appropriate undo action is added to
341  * the undo stack. The redo stack is cleared. Note that this may throw, use caution
342  * when calling this with a dereferenced pointer that you own (i.e. use a smart pointer).
343  */
344  void perform_action(const editor_action& action);
345 
346  /**
347  * Performs a partial action, assumes that the top undo action has been modified to
348  * maintain coherent state of the undo stacks, and so a new undo action is not
349  * created.
350  */
351  void perform_partial_action(const editor_action& action);
352 
353  /** @return whether the map was modified since the last save */
354  bool modified() const;
355 
356  /** Clear the modified state */
357  void clear_modified();
358 
359  /** Adds the map to the editor's recent files list. */
360  void add_to_recent_files();
361 
362  /** @return true when undo can be performed, false otherwise */
363  bool can_undo() const;
364 
365  /** @return true when redo can be performed, false otherwise */
366  bool can_redo() const;
367 
368  /** @return a pointer to the last undo action or nullptr if the undo stack is empty */
369  editor_action* last_undo_action();
370 
371  /** @return a pointer to the last redo action or nullptr if the undo stack is empty */
372  editor_action* last_redo_action();
373 
374  /** const version of last_undo_action */
375  const editor_action* last_undo_action() const;
376 
377  /** const version of last_redo_action */
378  const editor_action* last_redo_action() const;
379 
380  /** Un-does the last action, and puts it in the redo stack for a possible redo */
381  void undo();
382 
383  /** Re-does a previously undid action, and puts it back in the undo stack. */
384  void redo();
385 
386  /**
387  * Un-does a single step from a undo action chain. The action is separated
388  * from the chain and it's undo (the redo) is added as a stand-alone action
389  * to the redo stack.
390  * Precondition: the last undo action has to actually be an action chain.
391  */
392  void partial_undo();
393 
394  /**
395  * Clear the undo and redo stacks
396  */
397  void clear_undo_redo();
398 
399 protected:
400  /**
401  * The actual filename of this map. An empty string indicates a new map.
402  */
403  std::string filename_;
404 
405  /**
406  * When a scenario file is loaded, the referenced map is loaded instead.
407  * The verbatim form of the reference is kept here.
408  */
409  std::string map_data_key_;
410 
411  /**
412  * Whether the map context refers to a map embedded in a scenario file.
413  * This distinction is important in order to avoid overwriting the scenario.
414  */
415  bool embedded_;
416 
417  /**
418  * Whether the map context refers to a file containing only the pure map data.
419  */
420  bool pure_map_;
421 
422  /**
423  * The map object of this map_context.
424  */
426 
427  /**
428  * Checks if an action stack reached its capacity and removes the front element if so.
429  */
430  void trim_stack(action_stack& stack);
431 
432  /**
433  * Perform an action at the back of one stack, and then move it to the back of the other stack.
434  * This is the implementation of both undo and redo which only differ in the direction.
435  */
436  void perform_action_between_stacks(action_stack& from, action_stack& to);
437 
438  /**
439  * The undo stack. A double-ended queues due to the need to add items to one end,
440  * and remove from both when performing the undo or when trimming the size. This container owns
441  * all contents, i.e. no action in the stack shall be deleted, and unless otherwise noted the contents
442  * could be deleted at an time during normal operation of the stack. To work on an action, either
443  * remove it from the container or make a copy. Actions are inserted at the back of the container
444  * and disappear from the front when the capacity is exceeded.
445  * @todo Use boost's pointer-owning container?
446  */
448 
449  /**
450  * The redo stack. @see undo_stack_
451  */
453 
454  /**
455  * Action stack (i.e. undo and redo) maximum size
456  */
457  static const std::size_t max_action_stack_size_;
458 
459  /**
460  * Number of actions performed since the map was saved. Zero means the map was not modified.
461  */
463 
464  /**
465  * Cache of set starting position labels. Necessary for removing them.
466  */
467  std::set<map_location> starting_position_label_locs_;
468 
469  /**
470  * Refresh flag indicating the map in this context should be completely reloaded by the display
471  */
473 
474  /**
475  * Refresh flag indicating the terrain in the map has changed and requires a rebuild
476  */
478 
479  /**
480  * Refresh flag indicating the labels in the map have changed
481  */
483 
484  std::set<map_location> changed_locations_;
486 
487 private:
488 
489  std::string scenario_id_, scenario_name_, scenario_description_;
490 
491  int xp_mod_;
492  bool victory_defeated_, random_time_;
493 
495 
498  std::vector<team> teams_;
499  std::vector<std::string> lbl_categories_;
500  std::unique_ptr<tod_manager> tod_manager_;
503 
504  typedef std::map<std::string, sound::music_track> music_map;
505  music_map music_tracks_;
506 
507  typedef std::map<map_location, std::vector<overlay>> overlay_map;
508  overlay_map overlays_;
509 
510 public:
511 
512  overlay_map& get_overlays() { return overlays_; }
513 
514 };
515 
516 
517 } //end namespace editor
int actions_since_save_
Number of actions performed since the map was saved.
action_stack undo_stack_
The undo stack.
std::string map_data_key_
When a scenario file is loaded, the referenced map is loaded instead.
const std::string & get_name() const
editor_map map_
The map object of this map_context.
game_classification game_classification_
std::set< map_location > starting_position_label_locs_
Cache of set starting position labels.
void add_to_playlist(const sound::music_track &track)
const std::string & id() const
bool needs_terrain_rebuild_
Refresh flag indicating the terrain in the map has changed and requires a rebuild.
team::SHARE_VISION share_vision
Definition: map_context.hpp:44
void save_area(const std::set< map_location > &area)
logger & info()
Definition: log.cpp:90
const std::string & get_filename() const
void new_area(const std::set< map_location > &area)
void set_active_area(int index)
map_labels & get_labels()
bool needs_reload_
Refresh flag indicating the map in this context should be completely reloaded by the display...
virtual const std::vector< std::string > & hidden_label_categories() const override
A terrain string which is converted to a terrain is a string with 1 or 2 layers the layers are separa...
Definition: translation.hpp:50
bool needs_reload() const
Getter for the reload flag.
mp_game_settings & get_mp_settings()
int get_xp_mod() const
-file sdl_utils.hpp
std::deque< editor_action_ptr > action_stack
Action stack typedef.
std::string scenario_name_
virtual const gamemap & map() const =0
void set_needs_reload(bool value=true)
Setter for the reload flag.
bool embedded_
Whether the map context refers to a map embedded in a scenario file.
bool needs_labels_reset() const
Getter for the labels reset flag.
const std::string & get_id() const
std::string filename_
Definition: action_wml.cpp:555
overlay_map & get_overlays()
game_classification & get_classification()
bool pure_map_
Whether the map context refers to a file containing only the pure map data.
This class stores all the data for a single &#39;side&#39; (in game nomenclature).
Definition: team.hpp:44
tod_manager * get_time_manager()
std::map< std::string, sound::music_track > music_map
void set_local_starting_time(int time)
TODO.
std::unique_ptr< tod_manager > tod_manager_
std::vector< team > teams_
editor_team_info(const team &t)
Definition: map_context.cpp:37
void remove_side()
removes the last side from the scenario
Definition: map_context.hpp:95
void set_embedded(bool v)
const std::set< map_location > changed_locations() const
bool random_start_time() const
virtual const unit_map & units() const =0
bool is_pure_map() const
Manage the empty-palette in the editor.
Definition: action.cpp:29
static const ::config * terrain
The terrain used to create the cache.
Definition: minimap.cpp:130
bool is_embedded() const
void set_needs_terrain_rebuild(bool value=true)
Setter for the terrain rebuild flag.
bool needs_labels_reset_
Refresh flag indicating the labels in the map have changed.
Encapsulates the map of the game.
Definition: location.hpp:42
const std::string & get_description() const
This class adds extra editor-specific functionality to a normal gamemap.
Definition: editor_map.hpp:69
virtual const std::vector< team > & teams() const =0
Game configuration data as global variables.
Definition: build_info.cpp:49
const tod_manager * get_time_manager() const
editor_map & map()
Local non-const overload of map.
Base class for all editor actions.
Definition: action_base.hpp:40
Internal representation of music tracks.
const std::string & get_map_data_key() const
overlay_map overlays_
This class wraps around a map to provide a concise interface for the editor to work with...
Definition: map_context.hpp:57
std::size_t index(const std::string &str, const std::size_t index)
Codepoint index corresponding to the nth character in a UTF-8 string.
Definition: unicode.cpp:71
action_stack redo_stack_
The redo stack.
std::vector< std::string > lbl_categories_
bool victory_defeated() const
virtual const unit_map & units() const override
Const units accessor.
unit_map & units()
Local non-const overload of units.
int turns()
Definition: game.cpp:558
double t
Definition: astarsearch.cpp:64
virtual const editor_map & map() const override
Const map accessor.
team::CONTROLLER controller
Definition: map_context.hpp:45
int get_active_area() const
void set_needs_labels_reset(bool value=true)
Setter for the labels reset flag.
bool is_in_playlist(std::string track_id)
bool needs_terrain_rebuild() const
Getter for the terrain rebuild flag.
static const std::size_t max_action_stack_size_
Action stack (i.e.
void set_filename(const std::string &fn)
Container associating units to locations.
Definition: map.hpp:99
std::string filename_
The actual filename of this map.
std::map< map_location, std::vector< overlay > > overlay_map
std::vector< team > & teams()
Local non-const overload of teams.
std::set< map_location > changed_locations_
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:92
virtual const std::vector< team > & teams() const override
Const teams accessor.
mp_game_settings mp_settings_