The Battle for Wesnoth  1.15.2+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  virtual std::vector<std::string>& hidden_label_categories() override
165  {
166  return lbl_categories_;
167  }
168 
169  /**
170  * Replace the [time]s of the currently active area.
171  */
172  void replace_local_schedule(const std::vector<time_of_day>& schedule);
173 
174  /**
175  * TODO
176  */
177  void set_starting_time(int time);
178 
179  /**
180  * TODO
181  */
182  void set_local_starting_time(int time) {
183  tod_manager_->set_current_time(time, active_area_);
184  ++actions_since_save_;
185  }
186 
187  const tod_manager* get_time_manager() const {
188  return tod_manager_.get();
189  }
190 
192  return tod_manager_.get();
193  }
194 
196  return mp_settings_;
197  }
199  return game_classification_;
200  }
201 
202  /**
203  *
204  * @return the index of the currently active area.
205  */
206  int get_active_area() const {
207  return active_area_;
208  }
209 
210  void set_active_area(int index) {
211  active_area_ = index;
212  }
213 
214  bool is_in_playlist(std::string track_id) {
215  return music_tracks_.find(track_id) != music_tracks_.end();
216  }
217 
218  void add_to_playlist(const sound::music_track& track) {
219 
220  if (music_tracks_.find(track.id()) == music_tracks_.end())
221  music_tracks_.emplace(track.id(), track);
222  else music_tracks_.erase(track.id());
223  }
224 
225  /**
226  * Draw a terrain on a single location on the map.
227  * Sets the refresh flags accordingly.
228  */
229  void draw_terrain(const t_translation::terrain_code & terrain, const map_location& loc,
230  bool one_layer_only = false);
231 
232  /**
233  * Actual drawing function used by both overloaded variants of draw_terrain.
234  */
235  void draw_terrain_actual(const t_translation::terrain_code & terrain, const map_location& loc,
236  bool one_layer_only = false);
237 
238  /**
239  * Draw a terrain on a set of locations on the map.
240  * Sets the refresh flags accordingly.
241  */
242  void draw_terrain(const t_translation::terrain_code & terrain, const std::set<map_location>& locs,
243  bool one_layer_only = false);
244 
245  /**
246  * Getter for the reload flag. Reload is the highest level of required refreshing,
247  * set when the map size has changed or the map was reassigned.
248  */
249  bool needs_reload() const { return needs_reload_; }
250 
251  /**
252  * Setter for the reload flag
253  */
254  void set_needs_reload(bool value=true) { needs_reload_ = value; }
255 
256  /**
257  * Getter for the terrain rebuild flag. Set whenever any terrain has changed.
258  */
259  bool needs_terrain_rebuild() const { return needs_terrain_rebuild_; }
260 
261  /**
262  * Setter for the terrain rebuild flag
263  */
264  void set_needs_terrain_rebuild(bool value=true) { needs_terrain_rebuild_ = value; }
265 
266  /**
267  * TODO
268  */
269  void set_scenario_setup(const std::string& id, const std::string& name, const std::string& description,
270  int turns, int xp_mod, bool victory_defeated, bool random_time);
271 
272  /**
273  * TODO
274  */
275  void set_side_setup(editor_team_info& info);
276 
277  /**
278  * Getter for the labels reset flag. Set when the labels need to be refreshed.
279  */
280  bool needs_labels_reset() const { return needs_labels_reset_; }
281 
282  /**
283  * Setter for the labels reset flag
284  */
285  void set_needs_labels_reset(bool value=true) { needs_labels_reset_ = value; }
286 
287  const std::set<map_location> changed_locations() const { return changed_locations_; }
288  void clear_changed_locations();
289  void add_changed_location(const map_location& loc);
290  void add_changed_location(const std::set<map_location>& locs);
291  void set_everything_changed();
292  bool everything_changed() const;
293 
294  void set_labels(display& disp);
295 
296  void clear_starting_position_labels(display& disp);
297 
298  void set_starting_position_labels(display& disp);
299 
300  void reset_starting_position_labels(display& disp);
301 
302  const std::string& get_filename() const { return filename_; }
303 
304  void set_filename(const std::string& fn) { filename_ = fn; }
305 
306  const std::string& get_map_data_key() const { return map_data_key_; }
307 
308  const std::string& get_id() const { return scenario_id_; }
309  const std::string& get_description() const { return scenario_description_; }
310  const std::string& get_name() const { return scenario_name_; }
311 
312  const t_string get_default_context_name() const;
313 
314  int get_xp_mod() const { return xp_mod_; }
315 
316  bool random_start_time() const { return random_time_; }
317  bool victory_defeated() const { return victory_defeated_; }
318 
319  bool is_embedded() const { return embedded_; }
320 
321  bool is_pure_map() const { return pure_map_; }
322 
323  void set_embedded(bool v) { embedded_ = v; }
324 
325  /**
326  * Saves the map under the current filename. Filename must be valid.
327  * May throw an exception on failure.
328  */
329  bool save_map();
330 
331  /**
332  * Saves the scenario under the current filename. Filename must be valid.
333  * May throw an exception on failure.
334  */
335  bool save_scenario();
336 
337 
338  void load_scenario(const config& game_config);
339 
340  config to_config();
341 
342  void set_map(const editor_map& map);
343 
344  /**
345  * Performs an action (thus modifying the map). An appropriate undo action is added to
346  * the undo stack. The redo stack is cleared. Note that this may throw, use caution
347  * when calling this with a dereferenced pointer that you own (i.e. use a smart pointer).
348  */
349  void perform_action(const editor_action& action);
350 
351  /**
352  * Performs a partial action, assumes that the top undo action has been modified to
353  * maintain coherent state of the undo stacks, and so a new undo action is not
354  * created.
355  */
356  void perform_partial_action(const editor_action& action);
357 
358  /** @return whether the map was modified since the last save */
359  bool modified() const;
360 
361  /** Clear the modified state */
362  void clear_modified();
363 
364  /** Adds the map to the editor's recent files list. */
365  void add_to_recent_files();
366 
367  /** @return true when undo can be performed, false otherwise */
368  bool can_undo() const;
369 
370  /** @return true when redo can be performed, false otherwise */
371  bool can_redo() const;
372 
373  /** @return a pointer to the last undo action or nullptr if the undo stack is empty */
374  editor_action* last_undo_action();
375 
376  /** @return a pointer to the last redo action or nullptr if the undo stack is empty */
377  editor_action* last_redo_action();
378 
379  /** const version of last_undo_action */
380  const editor_action* last_undo_action() const;
381 
382  /** const version of last_redo_action */
383  const editor_action* last_redo_action() const;
384 
385  /** Un-does the last action, and puts it in the redo stack for a possible redo */
386  void undo();
387 
388  /** Re-does a previously undid action, and puts it back in the undo stack. */
389  void redo();
390 
391  /**
392  * Un-does a single step from a undo action chain. The action is separated
393  * from the chain and it's undo (the redo) is added as a stand-alone action
394  * to the redo stack.
395  * Precondition: the last undo action has to actually be an action chain.
396  */
397  void partial_undo();
398 
399  /**
400  * Clear the undo and redo stacks
401  */
402  void clear_undo_redo();
403 
404 protected:
405  /**
406  * The actual filename of this map. An empty string indicates a new map.
407  */
408  std::string filename_;
409 
410  /**
411  * When a scenario file is loaded, the referenced map is loaded instead.
412  * The verbatim form of the reference is kept here.
413  */
414  std::string map_data_key_;
415 
416  /**
417  * Whether the map context refers to a map embedded in a scenario file.
418  * This distinction is important in order to avoid overwriting the scenario.
419  */
420  bool embedded_;
421 
422  /**
423  * Whether the map context refers to a file containing only the pure map data.
424  */
425  bool pure_map_;
426 
427  /**
428  * The map object of this map_context.
429  */
431 
432  /**
433  * Checks if an action stack reached its capacity and removes the front element if so.
434  */
435  void trim_stack(action_stack& stack);
436 
437  /**
438  * Perform an action at the back of one stack, and then move it to the back of the other stack.
439  * This is the implementation of both undo and redo which only differ in the direction.
440  */
441  void perform_action_between_stacks(action_stack& from, action_stack& to);
442 
443  /**
444  * The undo stack. A double-ended queues due to the need to add items to one end,
445  * and remove from both when performing the undo or when trimming the size. This container owns
446  * all contents, i.e. no action in the stack shall be deleted, and unless otherwise noted the contents
447  * could be deleted at an time during normal operation of the stack. To work on an action, either
448  * remove it from the container or make a copy. Actions are inserted at the back of the container
449  * and disappear from the front when the capacity is exceeded.
450  * @todo Use boost's pointer-owning container?
451  */
453 
454  /**
455  * The redo stack. @see undo_stack_
456  */
458 
459  /**
460  * Action stack (i.e. undo and redo) maximum size
461  */
462  static const std::size_t max_action_stack_size_;
463 
464  /**
465  * Number of actions performed since the map was saved. Zero means the map was not modified.
466  */
468 
469  /**
470  * Cache of set starting position labels. Necessary for removing them.
471  */
472  std::set<map_location> starting_position_label_locs_;
473 
474  /**
475  * Refresh flag indicating the map in this context should be completely reloaded by the display
476  */
478 
479  /**
480  * Refresh flag indicating the terrain in the map has changed and requires a rebuild
481  */
483 
484  /**
485  * Refresh flag indicating the labels in the map have changed
486  */
488 
489  std::set<map_location> changed_locations_;
491 
492 private:
493 
494  std::string scenario_id_, scenario_name_, scenario_description_;
495 
496  int xp_mod_;
497  bool victory_defeated_, random_time_;
498 
500 
503  std::vector<team> teams_;
504  std::vector<std::string> lbl_categories_;
505  std::unique_ptr<tod_manager> tod_manager_;
508 
509  typedef std::map<std::string, sound::music_track> music_map;
510  music_map music_tracks_;
511 
512  typedef std::map<map_location, std::vector<overlay>> overlay_map;
513  overlay_map overlays_;
514 
515 public:
516 
517  overlay_map& get_overlays() { return overlays_; }
518 
519 };
520 
521 
522 } //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 std::vector< std::string > & hidden_label_categories() override
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:569
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:68
virtual const std::vector< team > & teams() const override
Const teams accessor.
mp_game_settings mp_settings_