The Battle for Wesnoth  1.19.0+dev
arrow.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2010 - 2024
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 "draw.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)) {
143  draw::blit(tex, dest);
144  });
145  }
146 }
147 
149 {
150  return (path.size() >= 2);
151 }
152 
154 {
155  if (!valid_path(path_))
156  {
157  WRN_ARR << "arrow::update_symbols called with invalid path";
158  return;
159  }
160 
161  symbols_map_.clear();
163 
164  const std::string mods = "~RC(FF00FF>"+ color_ + ")"; //magenta to current color
165 
166  const std::string dirname = "arrows/";
167  std::string prefix = "";
168  std::string suffix = "";
169  std::string image_filename = "";
170  arrow_path_t::const_iterator const arrow_start_hex = path_.begin();
171  arrow_path_t::const_iterator const arrow_pre_end_hex = path_.end() - 2;
172  arrow_path_t::const_iterator const arrow_end_hex = path_.end() - 1;
173  bool teleport_out = false;
174 
176  for (hex = path_.begin(); hex != path_.end(); ++hex)
177  {
178  prefix = "";
179  suffix = "";
180  image_filename = "";
181  bool start = false;
182  bool pre_end = false;
183  bool end = false;
184 
185  // teleport in if we teleported out last hex
186  bool teleport_in = teleport_out;
187  teleport_out = false;
188 
189  // Determine some special cases
190  if (hex == arrow_start_hex)
191  start = true;
192  if (hex == arrow_pre_end_hex)
193  pre_end = true;
194  else if (hex == arrow_end_hex)
195  end = true;
196  if (hex != arrow_end_hex && !tiles_adjacent(*hex, *(hex + 1)))
197  teleport_out = true;
198 
199  // calculate enter and exit directions, if available
201  if (!start && !teleport_in)
202  {
203  enter_dir = hex->get_relative_dir(*(hex-1));
204  }
206  if (!end && !teleport_out)
207  {
208  exit_dir = hex->get_relative_dir(*(hex+1));
209  }
210 
211  // Now figure out the actual images
212  if (teleport_out)
213  {
214  prefix = "teleport-out";
215  if (enter_dir != map_location::NDIRECTIONS)
216  {
217  suffix = map_location::write_direction(enter_dir);
218  }
219  }
220  else if (teleport_in)
221  {
222  prefix = "teleport-in";
223  if (exit_dir != map_location::NDIRECTIONS)
224  {
225  suffix = map_location::write_direction(exit_dir);
226  }
227  }
228  else if (start)
229  {
230  prefix = "start";
231  suffix = map_location::write_direction(exit_dir);
232  if (pre_end)
233  {
234  suffix = suffix + "_ending";
235  }
236  }
237  else if (end)
238  {
239  prefix = "end";
240  suffix = map_location::write_direction(enter_dir);
241  }
242  else
243  {
244  std::string enter, exit;
245  enter = map_location::write_direction(enter_dir);
246  exit = map_location::write_direction(exit_dir);
247  if (pre_end)
248  {
249  exit = exit + "_ending";
250  }
251 
252  assert(std::abs(enter_dir - exit_dir) > 1); //impossible turn?
253  if (enter_dir < exit_dir)
254  {
255  prefix = enter;
256  suffix = exit;
257  }
258  else //(enter_dir > exit_dir)
259  {
260  prefix = exit;
261  suffix = enter;
262  }
263  }
264 
265  image_filename = dirname + style_ + "/" + prefix;
266  if (!suffix.empty())
267  {
268  image_filename += ("-" + suffix);
269  }
270  image_filename += ".png";
271  assert(!image_filename.empty());
272 
273  image::locator image = image::locator(image_filename, mods);
274  if (!image.file_exists())
275  {
276  ERR_ARR << "Image " << image_filename << " not found.";
278  }
279  symbols_map_[*hex] = image;
280  }
281 }
282 
284 {
285  if(display* disp = display::get_singleton()) {
286  for(const map_location& loc : path) {
287  disp->invalidate(loc);
288  }
289  }
290 }
291 
293 {
294  if(display* disp = display::get_singleton()) {
295  disp->update_arrow(*this);
296  }
297 }
static lg::log_domain log_arrows("arrows")
#define WRN_ARR
Definition: arrow.cpp:28
#define ERR_ARR
Definition: arrow.cpp:27
Arrows destined to be drawn on the map.
std::vector< map_location > arrow_path_t
Definition: arrow.hpp:25
bool hidden_
Definition: arrow.hpp:106
virtual void draw_hex(const map_location &hex)
Definition: arrow.cpp:139
static void invalidate_arrow_path(const arrow_path_t &path)
Invalidates every hex along the given path.
Definition: arrow.cpp:283
void show()
Definition: arrow.cpp:63
static const std::string STYLE_FOCUS_INVALID
Definition: arrow.hpp:70
void hide()
Sets the arrow's visibility.
Definition: arrow.cpp:50
void set_style(const std::string &style)
Definition: arrow.cpp:114
arrow_path_t path_
Definition: arrow.hpp:100
arrow_path_t previous_path_
Definition: arrow.hpp:101
static const std::string STYLE_FOCUS
Definition: arrow.hpp:69
bool path_contains(const map_location &hex) const
Definition: arrow.cpp:133
virtual void reset()
invalidates and clears the present path, forgets the previous path, clears the symbols map
Definition: arrow.cpp:90
display::drawing_layer layer_
Definition: arrow.hpp:94
static const std::string STYLE_STANDARD
If you add more styles, you should look at move::update_arrow_style()
Definition: arrow.hpp:67
static const std::string STYLE_HIGHLIGHTED
Definition: arrow.hpp:68
std::string style_
represents the subdirectory that holds images for this arrow style
Definition: arrow.hpp:98
virtual void update_symbols()
Calculate the symbols to place along the arrow path.
Definition: arrow.cpp:153
const arrow_path_t & get_previous_path() const
Definition: arrow.cpp:128
virtual void notify_arrow_changed()
Definition: arrow.cpp:292
virtual ~arrow()
Definition: arrow.cpp:45
arrow(const arrow &)=delete
const arrow_path_t & get_path() const
Definition: arrow.cpp:123
virtual void set_path(const arrow_path_t &path)
Definition: arrow.cpp:75
arrow_symbols_map_t symbols_map_
Definition: arrow.hpp:104
std::string color_
Definition: arrow.hpp:96
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
static bool valid_path(const arrow_path_t &path)
Checks that the path is not of length 0 or 1.
Definition: arrow.cpp:148
Sort-of-Singleton that many classes, both GUI and non-GUI, use to access the game data.
Definition: display.hpp:88
void drawing_buffer_add(const drawing_layer layer, const map_location &loc, decltype(draw_helper::do_draw) draw_func)
Add an item to the drawing buffer.
Definition: display.cpp:1287
static display * get_singleton()
Returns the display object if a display object exists.
Definition: display.hpp:102
Generic locator abstracting the location of an image.
Definition: picture.hpp:63
Drawing functions, for drawing things on the screen.
bool tiles_adjacent(const map_location &a, const map_location &b)
Function which tells if two locations are adjacent.
Definition: location.cpp:502
Standard logging facilities (interface).
void blit(const texture &tex, const SDL_Rect &dst)
Draws a texture, or part of a texture, at the given location.
Definition: draw.cpp:310
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.
std::string path
Definition: filesystem.cpp:84
Functions to load and save images from/to disk.
texture get_texture(const image::locator &i_locator, TYPE type, bool skip_cache)
Returns an image texture suitable for hardware-accelerated rendering.
Definition: picture.cpp:960
bool contains(const Container &container, const Value &value)
Returns true iff value is found in container.
Definition: general.hpp:83
std::string::const_iterator iterator
Definition: tokenizer.hpp:25
Encapsulates the map of the game.
Definition: location.hpp:38
DIRECTION
Valid directions which can be moved in our hexagonal world.
Definition: location.hpp:40
static std::string write_direction(DIRECTION dir)
Definition: location.cpp:140
An abstract description of a rectangle with integer coordinates.
Definition: rect.hpp:47