The Battle for Wesnoth  1.15.12+dev
action.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 /**
16  * @file
17  * Editor action classes. Some important points:
18  * - This is a polymorphic hierarchy of classes, so actions are usually passed around
19  * as editor_action pointers
20  * - The pointers can, in general, be null. Always check for null before doing anything.
21  * The helper functions perform_ that take a pointer do that.
22  * - The perform() functions can throw when an error occurs. Use smart pointers if you
23  * need to ensure the pointer is deleted.
24  */
25 
26 #pragma once
27 
30 
31 namespace editor
32 {
33 /**
34  * Replace contents of the entire map,
35  * Useful as a fallback undo method when something else would be impractical
36  */
38 {
39 public:
41  : m_(m)
42  {
43  }
44 
45  std::unique_ptr<editor_action> clone() const override;
46  void perform_without_undo(map_context& m) const override;
47  const std::string& get_name() const override;
48 
49 protected:
51 };
52 
53 /**
54  * Base class for actions that:
55  * 1) operate on an area
56  * 2) can be used as undo for a click-drag operation
57  * 3) can be extended so one undo action undos several actual drag actions
58  */
60 {
61 public:
63  {
64  }
65 
66  /**
67  * The crux of the extendable contract. This member function must be
68  * implemented so that the undo behavior is consistent, exactly the
69  * same as would be with separate undo actions for every part of
70  * the drag.
71  */
72  virtual void extend(const editor_map& map, const std::set<map_location>& locs) = 0;
73 
74  const std::string& get_name() const override
75  {
76  static const std::string name("extendable");
77  return name;
78  }
79 };
80 
81 /**
82  * Container action wrapping several actions into one.
83  * The actions are performed in the order they are added,
84  * i.e. in the usual iteration order through the container.
85  */
87 {
88 public:
89  /**
90  * Create an empty action chain
91  */
93  : actions_()
94  {
95  }
96 
98 
99  editor_action_chain& operator=(const editor_action_chain& other);
100 
101  /** Inherited from editor_action, implemented by IMPLEMENT_ACTION. */
102  std::unique_ptr<editor_action> clone() const override;
103 
104  /**
105  * Create an action chain from a deque of action pointers.
106  * Note: the action chain assumes ownership of the pointers.
107  */
108  explicit editor_action_chain(std::deque<std::unique_ptr<editor_action>> actions)
109  : actions_(std::move(actions))
110  {
111  }
112 
113  /**
114  * The destructor deletes all the owned action pointers
115  */
116  ~editor_action_chain() override = default;
117 
118  /**
119  * Go through the chain and add up all the action counts
120  */
121  int action_count() const override;
122 
123  /**
124  * Add an action at the end of the chain
125  */
126  void append_action(std::unique_ptr<editor_action> a);
127 
128  /**
129  * Add an action at the beginning of the chain
130  */
131  void prepend_action(std::unique_ptr<editor_action> a);
132 
133  /**
134  * @return true when there are no actions in the chain. Empty
135  * action chains should usually be discarded as to not keep
136  * "empty" actions around.
137  */
138  bool empty() const;
139 
140  /**
141  * Remove the last added action and return it, transferring
142  * ownership to the caller
143  */
144  std::unique_ptr<editor_action> pop_last_action();
145 
146  /**
147  * Remove the first added action and return it, transferring
148  * ownership to the caller
149  */
150  std::unique_ptr<editor_action> pop_first_action();
151 
152  /**
153  * Perform all the actions in order and create a undo action chain
154  */
155  std::unique_ptr<editor_action> perform(map_context& m) const override;
156 
157  /**
158  * Perform all the actions in order
159  */
160  void perform_without_undo(map_context& m) const override;
161 
162  const std::string& get_name() const override;
163 
164 protected:
165  /**
166  * The action pointers owned by this action chain
167  */
168  std::deque<std::unique_ptr<editor_action>> actions_;
169 };
170 
171 /**
172  * Base class for actions which act on a specified location (and possibly on other locations
173  * that can be derived from the staring hex)
174  */
176 {
177 public:
179  : loc_(loc)
180  {
181  }
182 
183  const std::string& get_name() const override
184  {
185  static const std::string name("location");
186  return name;
187  }
188 
189 protected:
191 };
192 
193 /** Base class for actions which in addition to acting on a hex,
194  * act with one terrain type, i.e. paint-related actions.
195  */
197 {
198 public:
201  , t_(t)
202  {
203  }
204 
205  const std::string& get_name() const override
206  {
207  static const std::string name("location_terrain");
208  return name;
209  }
210 
211 protected:
213 };
214 
215 /**
216  * Base class for area-affecting actions
217  */
219 {
220 public:
221  editor_action_area(const std::set<map_location>& area)
222  : area_(area)
223  {
224  }
225 
226  void extend(const editor_map& map, const std::set<map_location>& locs) override;
227 
228  const std::string& get_name() const override
229  {
230  static const std::string name("area");
231  return name;
232  }
233 
234 protected:
235  std::set<map_location> area_;
236 };
237 
238 /**
239  * Paste a map fragment into the map. No offset is used.
240  */
242 {
243 public:
245  : offset_(offset)
246  , paste_(paste)
247  {
248  }
249 
250  std::unique_ptr<editor_action> clone() const override;
251  std::unique_ptr<editor_action> perform(map_context& mc) const override;
252  void perform_without_undo(map_context& mc) const override;
253  void extend(const editor_map& map, const std::set<map_location>& locs) override;
254  const std::string& get_name() const override;
255 
256 protected:
259 };
260 
261 /**
262  * Paint the same terrain on a number of locations on the map.
263  */
265 {
266 public:
268  const std::set<map_location>& area, const t_translation::terrain_code& t, bool one_layer = false)
269  : editor_action_area(area)
270  , t_(t)
271  , one_layer_(one_layer)
272  {
273  }
274 
275  std::unique_ptr<editor_action> clone() const override;
276  std::unique_ptr<editor_action> perform(map_context& mc) const override;
277  void perform_without_undo(map_context& mc) const override;
278  const std::string& get_name() const override;
279 
280 protected:
282 
284 };
285 
286 /**
287  * Flood fill. Somewhat redundant with paint_area.
288  */
290 {
291 public:
292  editor_action_fill(map_location loc, const t_translation::terrain_code& t, bool one_layer = false)
294  , one_layer_(one_layer)
295  {
296  }
297 
298  std::unique_ptr<editor_action> clone() const override;
299  std::unique_ptr<editor_action> perform(map_context& mc) const override;
300  void perform_without_undo(map_context& mc) const override;
301  const std::string& get_name() const override;
302 
303 protected:
305 };
306 
307 /**
308  * Set starting position action, sets location ids (both for starting locations
309  * and for non-starting locations).
310  */
312 {
313 public:
316  , loc_id_(loc_id)
317  {
318  }
319 
320  std::unique_ptr<editor_action> clone() const override;
321  std::unique_ptr<editor_action> perform(map_context& mc) const override;
322  void perform_without_undo(map_context& mc) const override;
323  const std::string& get_name() const override;
324 
325 protected:
326  std::string loc_id_;
327 };
328 
329 /**
330  * Resize the map. The offsets specify, indirectly, the direction of expanding/shrinking,
331  * and fill=NONE enables copying of edge terrain instead of filling.
332  */
334 {
335 public:
337  int y_size,
338  int x_offset,
339  int y_offset,
341  : x_size_(x_size)
342  , y_size_(y_size)
343  , x_offset_(x_offset)
344  , y_offset_(y_offset)
345  , fill_(fill)
346  {
347  }
348 
349  std::unique_ptr<editor_action> clone() const override;
350  void perform_without_undo(map_context& mc) const override;
351  const std::string& get_name() const override;
352 
353 protected:
354  int x_size_;
355  int y_size_;
358 
360 };
361 
363 {
364 public:
366  : mask_(mask)
367  {
368  }
369 
370  std::unique_ptr<editor_action> clone() const override;
371  void perform_without_undo(map_context& mc) const override;
372  const std::string& get_name() const override;
373 
374 private:
376 };
377 
379 {
380 public:
382  : target_(target)
383  {
384  }
385 
386  std::unique_ptr<editor_action> clone() const override;
387  void perform_without_undo(map_context& mc) const override;
388  const std::string& get_name() const override;
389 
390 private:
392 };
393 
394 /**
395  * Randomize terrain in an area
396  */
398 {
399 public:
400  editor_action_shuffle_area(const std::set<map_location>& area)
401  : editor_action_area(area)
402  {
403  }
404 
405  std::unique_ptr<editor_action> clone() const override;
406  std::unique_ptr<editor_action> perform(map_context& mc) const override;
407  void perform_without_undo(map_context& mc) const override;
408  const std::string& get_name() const override;
409 };
410 
411 } // end namespace editor
Randomize terrain in an area.
Definition: action.hpp:397
A map fragment – a collection of locations and information abut them.
const terrain_code NONE_TERRAIN
Definition: translation.hpp:58
static const map_location & ZERO()
Definition: location.hpp:74
editor_action_paint_area(const std::set< map_location > &area, const t_translation::terrain_code &t, bool one_layer=false)
Definition: action.hpp:267
const std::string & get_name() const override
Definition: action.hpp:183
Base class for actions which act on a specified location (and possibly on other locations that can be...
Definition: action.hpp:175
#define a
const std::string & get_name() const override
Definition: action.hpp:205
Base class for area-affecting actions.
Definition: action.hpp:218
A terrain string which is converted to a terrain is a string with 1 or 2 layers the layers are separa...
Definition: translation.hpp:49
Paste a map fragment into the map.
Definition: action.hpp:241
STL namespace.
Base class for editor actions.
Container action wrapping several actions into one.
Definition: action.hpp:86
Replace contents of the entire map, Useful as a fallback undo method when something else would be imp...
Definition: action.hpp:37
editor_action_starting_position(map_location loc, std::string loc_id)
Definition: action.hpp:314
editor_action_create_mask(const editor_map &target)
Definition: action.hpp:381
Set starting position action, sets location ids (both for starting locations and for non-starting loc...
Definition: action.hpp:311
const std::string & get_name() const override
Definition: action.hpp:228
map_location loc_
std::deque< std::unique_ptr< editor_action > > actions_
The action pointers owned by this action chain.
Definition: action.hpp:168
void perform_without_undo(map_context &m) const override
Perform the action without creating an undo action.
Definition: action.cpp:72
Encapsulates the map of the game.
Definition: map.hpp:170
editor_action_apply_mask(const gamemap &mask)
Definition: action.hpp:365
Base class for actions which in addition to acting on a hex, act with one terrain type...
Definition: action.hpp:196
Manage the empty-palette in the editor.
Definition: action.cpp:29
Paint the same terrain on a number of locations on the map.
Definition: action.hpp:264
editor_action_shuffle_area(const std::set< map_location > &area)
Definition: action.hpp:400
Encapsulates the map of the game.
Definition: location.hpp:37
editor_action_fill(map_location loc, const t_translation::terrain_code &t, bool one_layer=false)
Definition: action.hpp:292
editor_action_whole_map(const editor_map &m)
Definition: action.hpp:40
editor_action_location(map_location loc)
Definition: action.hpp:178
virtual int action_count() const
Definition: action.cpp:53
This class adds extra editor-specific functionality to a normal gamemap.
Definition: editor_map.hpp:69
editor_action_paste(const map_fragment &paste, const map_location &offset=map_location::ZERO())
Definition: action.hpp:244
t_translation::terrain_code t_
Definition: action.hpp:212
Base class for all editor actions.
Definition: action_base.hpp:40
editor_action_resize_map(int x_size, int y_size, int x_offset, int y_offset, const t_translation::terrain_code &fill=t_translation::NONE_TERRAIN)
Definition: action.hpp:336
Base class for actions that: 1) operate on an area 2) can be used as undo for a click-drag operation ...
Definition: action.hpp:59
This class wraps around a map to provide a concise interface for the editor to work with...
Definition: map_context.hpp:59
virtual std::unique_ptr< editor_action > perform(map_context &) const
Perform the action, returning an undo action that, when performed, shall reverse any effects of this ...
Definition: action.cpp:63
t_translation::terrain_code fill_
Definition: action.hpp:359
editor_action_chain(std::deque< std::unique_ptr< editor_action >> actions)
Create an action chain from a deque of action pointers.
Definition: action.hpp:108
double t
Definition: astarsearch.cpp:64
const std::string & get_name() const override
Definition: action.hpp:74
t_translation::terrain_code t_
Definition: action.hpp:281
editor_action_chain()
Create an empty action chain.
Definition: action.hpp:92
std::unique_ptr< editor_action > clone() const override
Action cloning.
editor_action_area(const std::set< map_location > &area)
Definition: action.hpp:221
std::set< map_location > area_
Definition: action.hpp:235
editor_action_location_terrain(map_location loc, const t_translation::terrain_code &t)
Definition: action.hpp:199
const std::string & get_name() const override