The Battle for Wesnoth 1.21.0-dev
 
Loading...
Searching...
No Matches
editor_map.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
19#include "map/map.hpp"
20
21#include <boost/dynamic_bitset.hpp>
22
23namespace editor {
24
26{
28 : editor_exception("Map operation error. Check debug log for details.")
29 {
30 }
31};
32
34{
36 : editor_exception("Map integrity error. Check debug log for details.")
37 {
38 }
39};
40
42{
43 editor_map_load_exception(const std::string& fn, const std::string& msg)
44 : editor_exception(msg), filename(fn)
45 {
46 }
48 std::string filename;
49};
50
52{
53 editor_map_save_exception(const std::string& msg)
54 : editor_exception(msg)
55 {
56 }
58};
59
60
61/**
62 * Exception wrapping utility
63 */
64editor_map_load_exception wrap_exc(const char* type, const std::string& e_msg, const std::string& filename);
65
66/**
67 * This class adds extra editor-specific functionality to a normal gamemap.
68 */
69class editor_map : public gamemap
70{
71public:
72 /**
73 * Empty map constructor
74 */
75 editor_map();
76
77 /**
78 * Create an editor map from a map data string
79 */
80 editor_map(std::string_view data);
81
82 /**
83 * Wrapper around editor_map(cfg, data) that catches possible exceptions
84 * and wraps them in a editor_map_load_exception
85 */
86 static editor_map from_string(std::string_view data);
87
88 /**
89 * Create an editor map with the given dimensions and filler terrain
90 */
91 editor_map(std::size_t width, std::size_t height, const t_translation::terrain_code & filler);
92
93 /**
94 * Create an editor_map by upgrading an existing gamemap. The map data is
95 * copied. Marked "explicit" to avoid potentially harmful automatic conversions.
96 */
97 explicit editor_map(const gamemap& map);
98
99 /**
100 * Get a contiguous set of tiles having the same terrain as the starting location.
101 * Useful for flood fill or magic wand selection
102 * @return a contiguous set of locations that will always contain at least the starting element
103 */
104 std::set<map_location> get_contiguous_terrain_tiles(const map_location& start) const;
105
106 /**
107 * Set labels for staring positions in the given display object.
108 * @return the locations where the labels were added
109 */
110 std::set<map_location> set_starting_position_labels(display& disp);
111
112 /**
113 * @return true when the location is part of the selection, false otherwise
114 */
115 bool in_selection(const map_location& loc) const;
116
117 /**
118 * Add a location to the selection. The location should be valid (i.e. on the map)
119 * @return true if the selected hexes set was modified
120 */
121 bool add_to_selection(const map_location& loc);
122
123 /**
124 * Remove a location to the selection. The location does not actually have to be selected
125 * @return true if the selected hexes set was modified
126 */
128
129 /**
130 * Select the given area.
131 * @param area to select.
132 */
133 void set_selection(const std::set<map_location>& area);
134
135 /**
136 * Return the selection set.
137 */
138 std::set<map_location> selection() const;
139
140 /**
141 * Returns a set of all hexes *not* currently selected.
142 */
143 std::set<map_location> selection_inverse() const;
144
145 /**
146 * Clear the selection
147 */
148 void clear_selection();
149
150 /**
151 * Invert the selection, i.e. select all the map hexes that were not selected.
152 */
153 void invert_selection();
154
155 /**
156 * Select all map hexes
157 */
158 void select_all();
159
160 /**
161 * @return true if the entire map is selected, false otherwise
162 */
163 bool everything_selected() const;
164
165 /**
166 * @return true if at least one location is selected, false otherwise
167 */
168 bool anything_selected() const;
169
170 /**
171 * @return true if at no selections are selected, false otherwise
172 */
173 bool nothing_selected() const;
174
175 /**
176 * @return the number of locations selected.
177 *
178 * @note This is more efficient than checking selection().size() since
179 * it avoids allocating a full map_location set and simply queries the
180 * number of engaged bits in the underlying bitset.
181 */
182 std::size_t num_selected() const;
183
184 /**
185 * Resize the map. If the filler is NONE, the border terrain will be copied
186 * when expanding, otherwise the filler terrain will be inserted there
187 */
188 void resize(int width, int height, int x_offset, int y_offset,
190
191 /**
192 * A sort-of diff operation returning a mask that, when applied to the current editor_map,
193 * will transform it into the target map.
194 */
195 gamemap mask_to(const gamemap& target) const;
196
197 /**
198 * A precondition to several map operations
199 * @return true if this map has the same dimensions as the other map
200 */
201 bool same_size_as(const gamemap& other) const;
202
203private:
204 //helper functions for resizing
205 void expand_right(int count, const t_translation::terrain_code & filler);
206 void expand_left(int count, const t_translation::terrain_code & filler);
207 void expand_top(int count, const t_translation::terrain_code & filler);
208 void expand_bottom(int count, const t_translation::terrain_code & filler);
209 void shrink_right(int count);
210 void shrink_left(int count);
211 void shrink_top(int count);
212 void shrink_bottom(int count);
213
215 {
216 public:
217 explicit selection_mask(const gamemap_base& map)
218 : stride_(map.total_width())
219 , height_(map.total_height())
220 {
221 bitset_.resize(map.total_area());
222 }
223
224 /**
225 * Marks @a loc as selected.
226 * @returns true if the location was previously deselected.
227 */
229 {
230 return bitset_.test_set(get_index(loc), true) == false;
231 }
232
233 /**
234 * Marks @a loc as unselected.
235 * @returns true if the location was previously selected.
236 */
238 {
239 return bitset_.test_set(get_index(loc), false) == true;
240 }
241
242 bool selected(const map_location& loc) const
243 {
244 return bitset_.test(get_index(loc));
245 }
246
248 {
249 bitset_.set();
250 }
251
253 {
254 bitset_.reset();
255 }
256
257 void invert()
258 {
259 bitset_.flip();
260 }
261
263 {
264 auto res = selection_mask{*this};
265 res.invert();
266 return res;
267 }
268
269 static std::set<map_location> get_locations(const selection_mask& mask)
270 {
271 std::set<map_location> res;
272
273 for(std::size_t i = 0; i < mask.bitset_.size(); ++i) {
274 if(mask.bitset_.test(i)) {
275 res.emplace(mask.get_location(i));
276 }
277 }
278
279 return res;
280 }
281
282 /** Read-only access to the underlying bitset. */
283 const boost::dynamic_bitset<uint64_t>& mask() const
284 {
285 return bitset_;
286 }
287
288 private:
289 /** Indexes @a loc to its corresponding bitflag using row-major ordering. */
290 std::size_t get_index(const map_location& loc) const
291 {
292 return static_cast<std::size_t>(loc.wml_y()) * stride_ + loc.wml_x();
293 }
294
295 /** Gets the corresponding map_location for bit index @a i. */
296 map_location get_location(std::size_t i) const
297 {
298 auto pos = std::div(i, stride_);
299 return {pos.rem, pos.quot, wml_loc{}};
300 }
301
302 boost::dynamic_bitset<uint64_t> bitset_;
303
304 int stride_{0};
305 int height_{0};
306 };
307
308 /**
309 * The selected hexes
310 */
312};
313
314
315} //end namespace editor
map_location loc
Definition move.cpp:172
Sort-of-Singleton that many classes, both GUI and non-GUI, use to access the game data.
Definition display.hpp:88
selection_mask(const gamemap_base &map)
boost::dynamic_bitset< uint64_t > bitset_
bool select(const map_location &loc)
Marks loc as selected.
static std::set< map_location > get_locations(const selection_mask &mask)
selection_mask inverted() const
map_location get_location(std::size_t i) const
Gets the corresponding map_location for bit index i.
bool selected(const map_location &loc) const
bool deselect(const map_location &loc)
Marks loc as unselected.
std::size_t get_index(const map_location &loc) const
Indexes loc to its corresponding bitflag using row-major ordering.
const boost::dynamic_bitset< uint64_t > & mask() const
Read-only access to the underlying bitset.
This class adds extra editor-specific functionality to a normal gamemap.
void shrink_left(int count)
bool everything_selected() const
bool add_to_selection(const map_location &loc)
Add a location to the selection.
bool anything_selected() const
void shrink_top(int count)
void expand_left(int count, const t_translation::terrain_code &filler)
selection_mask selection_
The selected hexes.
std::set< map_location > set_starting_position_labels(display &disp)
Set labels for staring positions in the given display object.
void shrink_bottom(int count)
static editor_map from_string(std::string_view data)
Wrapper around editor_map(cfg, data) that catches possible exceptions and wraps them in a editor_map_...
void invert_selection()
Invert the selection, i.e.
void shrink_right(int count)
void select_all()
Select all map hexes.
bool same_size_as(const gamemap &other) const
A precondition to several map operations.
gamemap mask_to(const gamemap &target) const
A sort-of diff operation returning a mask that, when applied to the current editor_map,...
std::set< map_location > selection() const
Return the selection set.
bool nothing_selected() const
void expand_right(int count, const t_translation::terrain_code &filler)
bool in_selection(const map_location &loc) const
bool remove_from_selection(const map_location &loc)
Remove a location to the selection.
void expand_top(int count, const t_translation::terrain_code &filler)
void set_selection(const std::set< map_location > &area)
Select the given area.
std::set< map_location > get_contiguous_terrain_tiles(const map_location &start) const
Get a contiguous set of tiles having the same terrain as the starting location.
void resize(int width, int height, int x_offset, int y_offset, const t_translation::terrain_code &filler=t_translation::NONE_TERRAIN)
Resize the map.
std::set< map_location > selection_inverse() const
Returns a set of all hexes not currently selected.
editor_map()
Empty map constructor.
void clear_selection()
Clear the selection.
void expand_bottom(int count, const t_translation::terrain_code &filler)
std::size_t num_selected() const
int total_area() const
Total square area of the map, including borders.
Definition map.hpp:65
int total_width() const
Real width of the map, including borders.
Definition map.hpp:59
int total_height() const
Real height of the map, including borders.
Definition map.hpp:62
Encapsulates the map of the game.
Definition map.hpp:176
Main (common) editor header.
Manage the empty-palette in the editor.
Definition action.cpp:31
editor_map_load_exception wrap_exc(const char *type, const std::string &e_msg, const std::string &filename)
Exception wrapping utility.
EXIT_STATUS start(bool clear_id, const std::string &filename, bool take_screenshot, const std::string &screenshot_filename)
Main interface for launching the editor from the title screen.
constexpr terrain_code NONE_TERRAIN
std::string_view data
Definition picture.cpp:188
std::string filename
Filename.
editor_map_load_exception(const std::string &fn, const std::string &msg)
editor_map_save_exception(const std::string &msg)
Encapsulates the map of the game.
Definition location.hpp:46
int wml_y() const
Definition location.hpp:187
int wml_x() const
Definition location.hpp:186
A terrain string which is converted to a terrain is a string with 1 or 2 layers the layers are separa...
#define i