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 
17 #include "editor/editor_common.hpp"
18 
19 #include "map/map.hpp"
20 
21 #include <deque>
22 
23 namespace editor {
24 
25 struct editor_map_operation_exception : public editor_exception
26 {
editor_map_operation_exceptioneditor::editor_map_operation_exception27 	editor_map_operation_exception()
28 	: editor_exception("Map operation error. Check debug log for details.")
29 	{
30 	}
31 };
32 
33 struct editor_map_integrity_error : public editor_exception
34 {
editor_map_integrity_erroreditor::editor_map_integrity_error35 	editor_map_integrity_error()
36 	: editor_exception("Map integrity error. Check debug log for details.")
37 	{
38 	}
39 };
40 
41 struct editor_map_load_exception : public editor_exception
42 {
editor_map_load_exceptioneditor::editor_map_load_exception43 	editor_map_load_exception(const std::string& fn, const std::string& msg)
44 	: editor_exception(msg), filename(fn)
45 	{
46 	}
~editor_map_load_exceptioneditor::editor_map_load_exception47 	~editor_map_load_exception() NOEXCEPT {}
48 	std::string filename;
49 };
50 
51 struct editor_map_save_exception : public editor_exception
52 {
editor_map_save_exceptioneditor::editor_map_save_exception53 	editor_map_save_exception(const std::string& msg)
54 	: editor_exception(msg)
55 	{
56 	}
~editor_map_save_exceptioneditor::editor_map_save_exception57 	~editor_map_save_exception() NOEXCEPT {}
58 };
59 
60 
61 /**
62  * Exception wrapping utility
63  */
64 editor_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  */
69 class editor_map : public gamemap
70 {
71 public:
72 
73 	/**
74 	 * Empty map constructor
75 	 */
76 	explicit editor_map(const config& terrain_cfg);
77 
78 	/**
79 	 * Create an editor map from a map data string
80 	 */
81 	editor_map(const config& terrain_cfg, const std::string& data);
82 
83 	/**
84 	 * Wrapper around editor_map(cfg, data) that catches possible exceptions
85 	 * and wraps them in a editor_map_load_exception
86 	 */
87 	static editor_map from_string(const config& terrain_cfg, const std::string& data);
88 
89 	/**
90 	 * Create an editor map with the given dimensions and filler terrain
91 	 */
92 	editor_map(const config& terrain_cfg, size_t width, size_t height, const t_translation::terrain_code & filler);
93 
94 	/**
95 	 * Create an editor_map by upgrading an existing gamemap. The map data is
96 	 * copied. Marked "explicit" to avoid potentially harmful automatic conversions.
97 	 */
98 	explicit editor_map(const gamemap& map);
99 
100 	/**
101 	 * editor_map destructor
102 	 */
103 	~editor_map();
104 
105 	/**
106 	 * Debugging aid. Check if the widths and heights correspond to the actual map data sizes.
107 	 */
108 	void sanity_check();
109 
110 	/**
111 	 * Get a contiguous set of tiles having the same terrain as the starting location.
112 	 * Useful for flood fill or magic wand selection
113 	 * @return a contiguous set of locations that will always contain at least the starting element
114 	 */
115 	std::set<map_location> get_contiguous_terrain_tiles(const map_location& start) const;
116 
117 	/**
118 	 * Set labels for staring positions in the given display object.
119 	 * @return the locations where the labels were added
120 	 */
121 	std::set<map_location> set_starting_position_labels(display& disp);
122 
123 	/**
124 	 * @return true when the location is part of the selection, false otherwise
125 	 */
126 	bool in_selection(const map_location& loc) const;
127 
128 	/**
129 	 * Add a location to the selection. The location should be valid (i.e. on the map)
130 	 * @return true if the selected hexes set was modified
131 	 */
132 	bool add_to_selection(const map_location& loc);
133 
134 	/**
135 	 * Remove a location to the selection. The location does not actually have to be selected
136 	 * @return true if the selected hexes set was modified
137 	 */
138 	bool remove_from_selection(const map_location& loc);
139 
140 	/**
141 	 * Select the given area.
142 	 * @param area to select.
143 	 */
144 	bool set_selection(const std::set<map_location>& area);
145 
146 	/**
147 	 * Return the selection set.
148 	 */
selection() const149 	const std::set<map_location>& selection() const { return selection_; }
150 
151 	/**
152 	 * Clear the selection
153 	 */
154 	void clear_selection();
155 
156 	/**
157 	 * Invert the selection, i.e. select all the map hexes that were not selected.
158 	 */
159 	void invert_selection();
160 
161 	/**
162 	 * Select all map hexes
163 	 */
164 	void select_all();
165 
166 	/**
167 	 * @return true if the entire map is selected, false otherwise
168 	 */
169 	bool everything_selected() const;
170 
171 	/**
172 	 * Resize the map. If the filler is NONE, the border terrain will be copied
173 	 * when expanding, otherwise the filler terrain will be inserted there
174 	 */
175 	void resize(int width, int height, int x_offset, int y_offset,
176 		const t_translation::terrain_code & filler = t_translation::NONE_TERRAIN);
177 
178 	/**
179 	 * A sort-of diff operation returning a mask that, when applied to the current editor_map,
180 	 * will transform it into the target map.
181 	 */
182 	gamemap mask_to(const gamemap& target) const;
183 
184 	/**
185 	 * A precondition to several map operations
186 	 * @return true if this map has the same dimensions as the other map
187 	 */
188 	bool same_size_as(const gamemap& other) const;
189 
190 protected:
191 	//helper functions for resizing
192 	void expand_right(int count, const t_translation::terrain_code & filler);
193 	void expand_left(int count, const t_translation::terrain_code & filler);
194 	void expand_top(int count, const t_translation::terrain_code & filler);
195 	void expand_bottom(int count, const t_translation::terrain_code & filler);
196 	void shrink_right(int count);
197 	void shrink_left(int count);
198 	void shrink_top(int count);
199 	void shrink_bottom(int count);
200 
201 	/**
202 	 * The selected hexes
203 	 */
204 	std::set<map_location> selection_;
205 };
206 
207 
208 } //end namespace editor
209