The Battle for Wesnoth 1.21.0-dev
 
Loading...
Searching...
No Matches
map_context.hpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2008 - 2025
3 by Tomasz Sniatowski <kailoran@gmail.com>
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#pragma once
17
18#include "display_context.hpp"
21#include "map/label.hpp"
22#include "mp_game_settings.hpp"
23#include "overlay.hpp"
24#include "side_controller.hpp"
25#include "sound_music_track.hpp"
26#include "team.hpp"
27#include "tod_manager.hpp"
28#include "units/map.hpp"
30
31#include <vector>
32
33class map_generator;
34
35namespace editor {
36
38 editor_team_info(const team& t);
39
40 int side;
41 std::string id;
42 std::string name;
43 std::string recruit_list;
44 int gold;
45 int income;
48 bool fog;
49 bool shroud;
50 team_shared_vision::type share_vision;
51 side_controller::type controller;
53 bool hidden;
54};
55
56/**
57 * This class wraps around a map to provide a concise interface for the editor to work with.
58 * The actual map object can change rapidly (be assigned to), the map context persists
59 * data (like the undo stacks) in this case. The functionality is here, not in editor_controller
60 * as e.g. the undo stack is part of the map, not the editor as a whole. This might allow many
61 * maps to be open at the same time.
62 */
64{
65public:
66 map_context(const map_context&) = delete;
68
69 /**
70 * Create a map context from an existing map. The filename is set to be
71 * empty, indicating a new map.
72 * Marked "explicit" to avoid automatic conversions.
73 */
74 explicit map_context(const editor_map& map, bool pure_map, const std::string& addon_id);
75
76 /**
77 * Create map_context from a map file. If the map cannot be loaded, an
78 * exception will be thrown and the object will not be constructed. If the
79 * map file is a scenario, the map specified in its map_data key will be
80 * loaded, and the stored filename updated accordingly. Maps embedded
81 * inside scenarios do not change the filename, but set the "embedded" flag
82 * instead.
83 */
84 map_context(const std::string& filename, const std::string& addon_id);
85
86 /**
87 * Map context destructor
88 */
89 virtual ~map_context();
90
91 /**
92 * Select the nth tod area.
93 * @param index of the tod area to select.
94 */
95 void select_area(int index);
96
97 /** Adds a new side to the map */
98 void new_side();
99
100 /** removes the last side from the scenario */
101 void remove_side() {
102 teams_.pop_back();
104 }
105
106 void save_area(const std::set<map_location>& area) {
107 tod_manager_->replace_area_locations(active_area_, area);
108 }
109
110 void new_area(const std::set<map_location>& area) {
111 tod_manager_->add_time_area("", area, config());
112 active_area_ = tod_manager_->get_area_ids().size() -1;
114 }
115
116 void remove_area(int index);
117
119 return labels_;
120 }
121
122 void replace_schedule(const std::vector<time_of_day>& schedule);
123
124 // Import symbols from base class.
128
129 /** Const units accessor. */
130 virtual const unit_map& units() const override
131 {
132 return units_;
133 }
134
135 /** Local non-const overload of @ref units */
137 {
138 return units_;
139 }
140
141 /** Const teams accessor. */
142 virtual const std::vector<team>& teams() const override
143 {
144 return teams_;
145 }
146
147 /** Local non-const overload of @ref teams */
148 std::vector<team>& teams()
149 {
150 return teams_;
151 }
152
153 /** Const map accessor. */
154 virtual const editor_map& map() const override
155 {
156 return map_;
157 }
158
159 /** Local non-const overload of @ref map */
161 {
162 return map_;
163 }
164
165 virtual const std::vector<std::string>& hidden_label_categories() const override
166 {
167 return lbl_categories_;
168 }
169
170 virtual std::vector<std::string>& hidden_label_categories() override
171 {
172 return lbl_categories_;
173 }
174
175 /**
176 * Replace the [time]s of the currently active area.
177 */
178 void replace_local_schedule(const std::vector<time_of_day>& schedule);
179
180 void set_starting_time(int time);
181
182 void set_local_starting_time(int time) {
183 tod_manager_->set_current_time(time, active_area_);
185 }
186
188 return tod_manager_.get();
189 }
190
192 return tod_manager_.get();
193 }
194
201
202 /**
203 * @return the index of the currently active area.
204 */
205 int get_active_area() const {
206 return active_area_;
207 }
208
209 void set_active_area(int index) {
210 active_area_ = index;
211 }
212
213 /** Checks whether the given track is part of current playlist. */
214 bool playlist_contains(const std::shared_ptr<sound::music_track>& track) const;
215
216 /** Remove the given track from the current playlist if present, else appends it. */
217 void toggle_track(const std::shared_ptr<sound::music_track>& track);
218
219 /**
220 * Draw a terrain on a single location on the map.
221 * Sets the refresh flags accordingly.
222 */
223 void draw_terrain(const t_translation::terrain_code & terrain, const map_location& loc,
224 bool one_layer_only = false);
225
226 /**
227 * Actual drawing function used by both overloaded variants of draw_terrain.
228 */
230 bool one_layer_only = false);
231
232 /**
233 * Draw a terrain on a set of locations on the map.
234 * Sets the refresh flags accordingly.
235 */
236 void draw_terrain(const t_translation::terrain_code & terrain, const std::set<map_location>& locs,
237 bool one_layer_only = false);
238
239 /**
240 * Getter for the reload flag. Reload is the highest level of required refreshing,
241 * set when the map size has changed or the map was reassigned.
242 */
243 bool needs_reload() const { return needs_reload_; }
244
245 /**
246 * Setter for the reload flag
247 */
249
250 /**
251 * Getter for the terrain rebuild flag. Set whenever any terrain has changed.
252 */
254
255 /**
256 * Setter for the terrain rebuild flag
257 */
259
260 void set_scenario_setup(const std::string& id, const std::string& name, const std::string& description,
261 int turns, int xp_mod, bool victory_defeated, bool random_time);
262
264
265 /**
266 * Getter for the labels reset flag. Set when the labels need to be refreshed.
267 */
269
270 /**
271 * Setter for the labels reset flag
272 */
274
275 const std::set<map_location> changed_locations() const { return changed_locations_; }
278 void add_changed_location(const std::set<map_location>& locs);
280 bool everything_changed() const;
281
283
285
287
288 const std::string& get_filename() const { return filename_; }
289
290 void set_filename(const std::string& fn) { filename_ = fn; }
291
292 const std::string& get_id() const { return scenario_id_; }
293 const std::string& get_description() const { return scenario_description_; }
294 const std::string& get_name() const { return scenario_name_; }
295
297
298 utils::optional<int> get_xp_mod() const { return xp_mod_; }
299
300 bool random_start_time() const { return random_time_; }
302
303 bool is_embedded() const { return embedded_; }
304
305 bool is_pure_map() const { return pure_map_; }
306
307 void set_embedded(bool v) { embedded_ = v; }
308
309 /**
310 * Saves the map under the current filename. Filename must be valid.
311 * May throw an exception on failure.
312 */
313 void save_map();
314
315 /**
316 * Saves the scenario under the current filename. Filename must be valid.
317 * May throw an exception on failure.
318 */
319 void save_scenario();
320
321 /**
322 * Save custom time of day schedule in the utils directory.
323 */
324 void save_schedule(const std::string& schedule_id, const std::string& schedule_name);
325
326 /**
327 * Convert an old-style editor scenario config to a config with a top level [multiplayer] tag.
328 *
329 * @param old_scenario the original scenario config
330 * @return the converted scenario config
331 */
333 bool load_scenario();
334
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 */
370
371 /** @return a pointer to the last redo action or nullptr if the undo stack is empty */
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 void set_addon_id(const std::string& addon_id)
400 {
401 addon_id_ = addon_id;
402 }
403
405 {
406 return last_map_generator_;
407 }
408
410 {
411 last_map_generator_ = generator;
412 }
413
414protected:
415 /**
416 * The actual filename of this map. An empty string indicates a new map.
417 */
418 std::string filename_;
419
420 /**
421 * When a scenario file is loaded, the referenced map is loaded instead.
422 * The verbatim form of the reference is kept here.
423 */
424 std::string map_data_key_;
425
426 /**
427 * Whether the map context refers to a map embedded in a scenario file.
428 * This distinction is important in order to avoid overwriting the scenario.
429 */
431
432 /**
433 * Whether the map context refers to a file containing only the pure map data.
434 */
436
437 /**
438 * The map object of this map_context.
439 */
441
442 /**
443 * Checks if an action stack reached its capacity and removes the front element if so.
444 */
445 void trim_stack(action_stack& stack);
446
447 /**
448 * Perform an action at the back of one stack, and then move it to the back of the other stack.
449 * This is the implementation of both undo and redo which only differ in the direction.
450 */
452
453 /**
454 * The undo stack. A double-ended queue due to the need to add items to one end,
455 * and remove from both when performing the undo or when trimming the size. This container owns
456 * all contents, i.e. no action in the stack shall be deleted, and unless otherwise noted the contents
457 * could be deleted at an time during normal operation of the stack. To work on an action, either
458 * remove it from the container or make a copy. Actions are inserted at the back of the container
459 * and disappear from the front when the capacity is exceeded.
460 * @todo Use boost's pointer-owning container?
461 */
463
464 /**
465 * The redo stack. @see undo_stack_
466 */
468
469 /**
470 * Action stack (i.e. undo and redo) maximum size
471 */
472 static const std::size_t max_action_stack_size_;
473
474 /**
475 * Number of actions performed since the map was saved. Zero means the map was not modified.
476 */
478
479 /**
480 * Refresh flag indicating the map in this context should be completely reloaded by the display
481 */
483
484 /**
485 * Refresh flag indicating the terrain in the map has changed and requires a rebuild
486 */
488
489 /**
490 * Refresh flag indicating the labels in the map have changed
491 */
493
495
496 std::set<map_location> changed_locations_;
497
498 /**
499 * Cache of set starting position labels. Necessary for removing them.
500 */
501 std::set<map_location> starting_position_label_locs_;
502
503private:
504 std::string addon_id_;
505 utils::optional<config> previous_cfg_;
507
508 utils::optional<int> xp_mod_;
509 utils::optional<bool> victory_defeated_;
511
513
516 std::vector<team> teams_;
517 std::vector<std::string> lbl_categories_;
518 std::unique_ptr<tod_manager> tod_manager_;
521
522 std::list<std::shared_ptr<sound::music_track>> music_tracks_;
523
524 typedef std::map<map_location, std::vector<overlay>> overlay_map;
526
528
529public:
530
532 void set_overlays(overlay_map overlays) { overlays_ = std::move(overlays); }
533};
534
535
536} //end namespace editor
map_location loc
Definition move.cpp:172
double t
A config object defines a single node in a WML file, with access to child nodes.
Definition config.hpp:157
Abstract class for exposing game data that doesn't depend on the GUI, however which for historical re...
virtual const gamemap & map() const =0
virtual const std::vector< team > & teams() const =0
virtual const unit_map & units() const =0
Sort-of-Singleton that many classes, both GUI and non-GUI, use to access the game data.
Definition display.hpp:88
Base class for all editor actions.
This class adds extra editor-specific functionality to a normal gamemap.
This class wraps around a map to provide a concise interface for the editor to work with.
game_classification game_classification_
std::set< map_location > starting_position_label_locs_
Cache of set starting position labels.
std::string filename_
The actual filename of this map.
void save_area(const std::set< map_location > &area)
void new_area(const std::set< map_location > &area)
utils::optional< config > previous_cfg_
void perform_partial_action(const editor_action &action)
Performs a partial action, assumes that the top undo action has been modified to maintain coherent st...
bool playlist_contains(const std::shared_ptr< sound::music_track > &track) const
Checks whether the given track is part of current playlist.
void remove_side()
removes the last side from the scenario
mp_game_settings mp_settings_
void set_active_area(int index)
void set_last_used_generator(map_generator *generator)
bool pure_map_
Whether the map context refers to a file containing only the pure map data.
map_generator * last_used_generator() const
bool needs_terrain_rebuild_
Refresh flag indicating the terrain in the map has changed and requires a rebuild.
const std::string & get_id() const
action_stack redo_stack_
The redo stack.
std::unique_ptr< tod_manager > tod_manager_
void set_local_starting_time(int time)
bool embedded_
Whether the map context refers to a map embedded in a scenario file.
int get_active_area() const
void set_needs_labels_reset(bool value=true)
Setter for the labels reset flag.
mp_game_settings & get_mp_settings()
tod_manager * get_time_manager()
map_labels & get_labels()
void set_needs_reload(bool value=true)
Setter for the reload flag.
std::string scenario_name_
bool needs_labels_reset_
Refresh flag indicating the labels in the map have changed.
void toggle_track(const std::shared_ptr< sound::music_track > &track)
Remove the given track from the current playlist if present, else appends it.
virtual std::vector< std::string > & hidden_label_categories() override
void clear_starting_position_labels(display &disp)
std::vector< std::string > lbl_categories_
editor_map map_
The map object of this map_context.
const std::set< map_location > changed_locations() const
void new_side()
Adds a new side to the map.
static const std::size_t max_action_stack_size_
Action stack (i.e.
action_stack undo_stack_
The undo stack.
editor_action * last_undo_action()
std::string map_data_key_
When a scenario file is loaded, the referenced map is loaded instead.
void redo()
Re-does a previously undid action, and puts it back in the undo stack.
const std::string & get_filename() const
std::set< map_location > changed_locations_
void set_starting_time(int time)
void draw_terrain(const t_translation::terrain_code &terrain, const map_location &loc, bool one_layer_only=false)
Draw a terrain on a single location on the map.
virtual const editor_map & map() const override
Const map accessor.
bool random_start_time() const
void set_map(const editor_map &map)
void set_side_setup(editor_team_info &info)
virtual const unit_map & units() const override
Const units accessor.
void trim_stack(action_stack &stack)
Checks if an action stack reached its capacity and removes the front element if so.
int actions_since_save_
Number of actions performed since the map was saved.
std::string scenario_description_
void save_scenario()
Saves the scenario under the current filename.
bool needs_reload_
Refresh flag indicating the map in this context should be completely reloaded by the display.
unit_map & units()
Local non-const overload of units.
std::vector< team > teams_
void set_overlays(overlay_map overlays)
void perform_action_between_stacks(action_stack &from, action_stack &to)
Perform an action at the back of one stack, and then move it to the back of the other stack.
game_classification & get_classification()
void perform_action(const editor_action &action)
Performs an action (thus modifying the map).
void undo()
Un-does the last action, and puts it in the redo stack for a possible redo.
void replace_schedule(const std::vector< time_of_day > &schedule)
utils::optional< bool > victory_defeated_
virtual const std::vector< std::string > & hidden_label_categories() const override
std::vector< team > & teams()
Local non-const overload of teams.
void remove_area(int index)
const tod_manager * get_time_manager() const
void select_area(int index)
Select the nth tod area.
void set_addon_id(const std::string &addon_id)
void clear_undo_redo()
Clear the undo and redo stacks.
bool is_embedded() const
virtual ~map_context()
Map context destructor.
overlay_map & get_overlays()
std::list< std::shared_ptr< sound::music_track > > music_tracks_
void draw_terrain_actual(const t_translation::terrain_code &terrain, const map_location &loc, bool one_layer_only=false)
Actual drawing function used by both overloaded variants of draw_terrain.
map_context(const map_context &)=delete
bool needs_labels_reset() const
Getter for the labels reset flag.
utils::optional< int > xp_mod_
void add_to_recent_files()
Adds the map to the editor's recent files list.
std::map< map_location, std::vector< overlay > > overlay_map
std::string scenario_id_
void replace_local_schedule(const std::vector< time_of_day > &schedule)
Replace the [time]s of the currently active area.
void save_map()
Saves the map under the current filename.
void reset_starting_position_labels(display &disp)
void set_embedded(bool v)
editor_action * last_redo_action()
map_context & operator=(const map_context &)=delete
void partial_undo()
Un-does a single step from a undo action chain.
bool needs_reload() const
Getter for the reload flag.
const std::string & get_name() const
void set_needs_terrain_rebuild(bool value=true)
Setter for the terrain rebuild flag.
map_generator * last_map_generator_
virtual const std::vector< team > & teams() const override
Const teams accessor.
config convert_scenario(const config &old_scenario)
Convert an old-style editor scenario config to a config with a top level [multiplayer] tag.
bool everything_changed() const
const t_string get_default_context_name() const
const std::string & get_description() const
void set_starting_position_labels(display &disp)
editor_map & map()
Local non-const overload of map.
bool needs_terrain_rebuild() const
Getter for the terrain rebuild flag.
void clear_modified()
Clear the modified state.
utils::optional< int > get_xp_mod() const
bool is_pure_map() const
bool victory_defeated() const
void set_filename(const std::string &fn)
void set_scenario_setup(const std::string &id, const std::string &name, const std::string &description, int turns, int xp_mod, bool victory_defeated, bool random_time)
void add_changed_location(const map_location &loc)
void save_schedule(const std::string &schedule_id, const std::string &schedule_name)
Save custom time of day schedule in the utils directory.
This class stores all the data for a single 'side' (in game nomenclature).
Definition team.hpp:74
Container associating units to locations.
Definition map.hpp:98
Manage the empty-palette in the editor.
Definition action.cpp:31
std::deque< std::unique_ptr< editor_action > > action_stack
Action stack typedef.
std::unique_ptr< MIX_Audio, decltype(&MIX_DestroyAudio)> value
Definition sound.cpp:139
std::string filename
Filename.
side_controller::type controller
team_shared_vision::type share_vision
Encapsulates the map of the game.
Definition location.hpp:46
A terrain string which is converted to a terrain is a string with 1 or 2 layers the layers are separa...