The Battle for Wesnoth  1.17.6+dev
arrow.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2010 - 2022
3  by Gabriel Morin <gabrielmorin (at) gmail (dot) 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 /**
17  * @file
18  * Method bodies for the arrow class.
19  */
20 
21 #include "arrow.hpp"
22 
23 #include "game_display.hpp"
24 #include "log.hpp"
25 
26 static lg::log_domain log_arrows("arrows");
27 #define ERR_ARR LOG_STREAM(err, log_arrows)
28 #define WRN_ARR LOG_STREAM(warn, log_arrows)
29 #define LOG_ARR LOG_STREAM(info, log_arrows)
30 #define DBG_ARR LOG_STREAM(debug, log_arrows)
31 
32 arrow::arrow(bool hidden)
33  : layer_(display::LAYER_ARROWS)
34  , color_("red")
35  , style_(STYLE_STANDARD)
36  , path_()
37  , previous_path_()
38  , symbols_map_()
39  , hidden_(true)
40 {
41  if(!hidden)
42  show();
43 }
44 
46 {
47  hide();
48 }
49 
51 {
52  if(hidden_)
53  return;
54 
55  hidden_ = true;
56 
57  if(display* disp = display::get_singleton()) {
59  disp->remove_arrow(*this);
60  }
61 }
62 
64 {
65  if(!hidden_)
66  return;
67 
68  hidden_ = false;
69 
70  if(display* disp = display::get_singleton()) {
71  disp->add_arrow(*this);
72  }
73 }
74 
76 {
77  if (valid_path(path))
78  {
80  path_ = path;
82  if(!hidden_)
83  {
86  }
87  }
88 }
89 
91 {
94  previous_path_.clear();
95  path_.clear();
96  symbols_map_.clear();
98 }
99 
100 void arrow::set_color(const std::string& color)
101 {
102  color_ = color;
103  if (valid_path(path_))
104  {
105  update_symbols();
106  }
107 }
108 
109 const std::string arrow::STYLE_STANDARD = "standard";
110 const std::string arrow::STYLE_HIGHLIGHTED = "highlighted";
111 const std::string arrow::STYLE_FOCUS = "focus";
112 const std::string arrow::STYLE_FOCUS_INVALID = "focus_invalid";
113 
114 void arrow::set_style(const std::string& style)
115 {
116  style_ = style;
117  if (valid_path(path_))
118  {
119  update_symbols();
120  }
121 }
122 
124 {
125  return path_;
126 }
127 
129 {
130  return previous_path_;
131 }
132 
133 bool arrow::path_contains(const map_location& hex) const
134 {
135  bool contains = symbols_map_.find(hex) != symbols_map_.end();
136  return contains;
137 }
138 
140 {
141  if(path_contains(hex))
142  {
144  disp->render_image(disp->get_location_x(hex), disp->get_location_y(hex), layer_,
145  hex, symbols_map_[hex]);
146  }
147 }
148 
150 {
151  return (path.size() >= 2);
152 }
153 
155 {
156  if (!valid_path(path_))
157  {
158  WRN_ARR << "arrow::update_symbols called with invalid path";
159  return;
160  }
161 
162  symbols_map_.clear();
164 
165  const std::string mods = "~RC(FF00FF>"+ color_ + ")"; //magenta to current color
166 
167  const std::string dirname = "arrows/";
168  std::string prefix = "";
169  std::string suffix = "";
170  std::string image_filename = "";
171  arrow_path_t::const_iterator const arrow_start_hex = path_.begin();
172  arrow_path_t::const_iterator const arrow_pre_end_hex = path_.end() - 2;
173  arrow_path_t::const_iterator const arrow_end_hex = path_.end() - 1;
174  bool teleport_out = false;
175 
177  for (hex = path_.begin(); hex != path_.end(); ++hex)
178  {
179  prefix = "";
180  suffix = "";
181  image_filename = "";
182  bool start = false;
183  bool pre_end = false;
184  bool end = false;
185 
186  // teleport in if we teleported out last hex
187  bool teleport_in = teleport_out;
188  teleport_out = false;
189 
190  // Determine some special cases
191  if (hex == arrow_start_hex)
192  start = true;
193  if (hex == arrow_pre_end_hex)
194  pre_end = true;
195  else if (hex == arrow_end_hex)
196  end = true;
197  if (hex != arrow_end_hex && !tiles_adjacent(*hex, *(hex + 1)))
198  teleport_out = true;
199 
200  // calculate enter and exit directions, if available
202  if (!start && !teleport_in)
203  {
204  enter_dir = hex->get_relative_dir(*(hex-1));
205  }
207  if (!end && !teleport_out)
208  {
209  exit_dir = hex->get_relative_dir(*(hex+1));
210  }
211 
212  // Now figure out the actual images
213  if (teleport_out)
214  {
215  prefix = "teleport-out";
216  if (enter_dir != map_location::NDIRECTIONS)
217  {
218  suffix = map_location::write_direction(enter_dir);
219  }
220  }
221  else if (teleport_in)
222  {
223  prefix = "teleport-in";
224  if (exit_dir != map_location::NDIRECTIONS)
225  {
226  suffix = map_location::write_direction(exit_dir);
227  }
228  }
229  else if (start)
230  {
231  prefix = "start";
232  suffix = map_location::write_direction(exit_dir);
233  if (pre_end)
234  {
235  suffix = suffix + "_ending";
236  }
237  }
238  else if (end)
239  {
240  prefix = "end";
241  suffix = map_location::write_direction(enter_dir);
242  }
243  else
244  {
245  std::string enter, exit;
246  enter = map_location::write_direction(enter_dir);
247  exit = map_location::write_direction(exit_dir);
248  if (pre_end)
249  {
250  exit = exit + "_ending";
251  }
252 
253  assert(std::abs(enter_dir - exit_dir) > 1); //impossible turn?
254  if (enter_dir < exit_dir)
255  {
256  prefix = enter;
257  suffix = exit;
258  }
259  else //(enter_dir > exit_dir)
260  {
261  prefix = exit;
262  suffix = enter;
263  }
264  }
265 
266  image_filename = dirname + style_ + "/" + prefix;
267  if (!suffix.empty())
268  {
269  image_filename += ("-" + suffix);
270  }
271  image_filename += ".png";
272  assert(!image_filename.empty());
273 
274  image::locator image = image::locator(image_filename, mods);
275  if (!image.file_exists())
276  {
277  ERR_ARR << "Image " << image_filename << " not found.";
279  }
280  symbols_map_[*hex] = image;
281  }
282 }
283 
285 {
286  if(display* disp = display::get_singleton()) {
287  for(const map_location& loc : path) {
288  disp->invalidate(loc);
289  }
290  }
291 }
292 
294 {
295  if(display* disp = display::get_singleton()) {
296  disp->update_arrow(*this);
297  }
298 }
static void invalidate_arrow_path(const arrow_path_t &path)
Invalidates every hex along the given path.
Definition: arrow.cpp:284
std::string style_
represents the subdirectory that holds images for this arrow style
Definition: arrow.hpp:98
virtual void notify_arrow_changed()
Definition: arrow.cpp:293
Arrows destined to be drawn on the map.
static display * get_singleton()
Returns the display object if a display object exists.
Definition: display.hpp:97
void hide()
Sets the arrow&#39;s visibility.
Definition: arrow.cpp:50
const arrow_path_t & get_path() const
Definition: arrow.cpp:123
bool path_contains(const map_location &hex) const
Definition: arrow.cpp:133
virtual void draw_hex(const map_location &hex)
Definition: arrow.cpp:139
arrow_symbols_map_t symbols_map_
Definition: arrow.hpp:104
virtual void set_path(const arrow_path_t &path)
Definition: arrow.cpp:75
std::vector< map_location > arrow_path_t
Definition: arrow.hpp:25
arrow(const arrow &)=delete
bool contains(const Container &container, const Value &value)
Returns true iff value is found in container.
Definition: general.hpp:84
static const std::string STYLE_HIGHLIGHTED
Definition: arrow.hpp:68
static const std::string STYLE_FOCUS
Definition: arrow.hpp:69
const arrow_path_t & get_previous_path() const
Definition: arrow.cpp:128
EXIT_STATUS start(const std::string &filename, bool take_screenshot, const std::string &screenshot_filename)
Main interface for launching the editor from the title screen.
Definition: editor_main.cpp:30
display::drawing_layer layer_
Definition: arrow.hpp:94
virtual void update_symbols()
Calculate the symbols to place along the arrow path.
Definition: arrow.cpp:154
static const std::string STYLE_FOCUS_INVALID
Definition: arrow.hpp:70
std::string path
Definition: game_config.cpp:39
#define ERR_ARR
Definition: arrow.cpp:27
Generic locator abstracting the location of an image.
Definition: picture.hpp:62
Encapsulates the map of the game.
Definition: location.hpp:38
bool tiles_adjacent(const map_location &a, const map_location &b)
Function which tells if two locations are adjacent.
Definition: location.cpp:503
std::string color_
Definition: arrow.hpp:96
void show()
Definition: arrow.cpp:63
virtual void reset()
invalidates and clears the present path, forgets the previous path, clears the symbols map ...
Definition: arrow.cpp:90
virtual void set_color(const std::string &color)
The string color parameter is in the same format expected by the image::locator modifiers parameter...
Definition: arrow.cpp:100
int get_location_y(const map_location &loc) const
Definition: display.cpp:745
void render_image(int x, int y, const display::drawing_layer drawing_layer, const map_location &loc, const image::locator &i_locator, bool hreverse=false, bool greyscale=false, uint8_t alpha=SDL_ALPHA_OPAQUE, double highlight=0.0, color_t blendto={0, 0, 0}, double blend_ratio=0, double submerged=0.0, bool vreverse=false)
Draw an image at a certain location.
Definition: display.cpp:1561
arrow_path_t path_
Definition: arrow.hpp:100
DIRECTION
Valid directions which can be moved in our hexagonal world.
Definition: location.hpp:40
int get_location_x(const map_location &loc) const
Functions to get the on-screen positions of hexes.
Definition: display.cpp:740
Functions to load and save images from/to disk.
static lg::log_domain log_arrows("arrows")
Standard logging facilities (interface).
static const std::string STYLE_STANDARD
If you add more styles, you should look at move::update_arrow_style()
Definition: arrow.hpp:67
void set_style(const std::string &style)
Definition: arrow.cpp:114
static bool valid_path(const arrow_path_t &path)
Checks that the path is not of length 0 or 1.
Definition: arrow.cpp:149
static std::string write_direction(DIRECTION dir)
Definition: location.cpp:141
std::string::const_iterator iterator
Definition: tokenizer.hpp:25
arrow_path_t previous_path_
Definition: arrow.hpp:101
virtual ~arrow()
Definition: arrow.cpp:45
#define WRN_ARR
Definition: arrow.cpp:28
bool hidden_
Definition: arrow.hpp:106