The Battle for Wesnoth  1.17.23+dev
arrow.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2010 - 2023
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 "game_display.hpp"
25 #include "log.hpp"
26 
27 static lg::log_domain log_arrows("arrows");
28 #define ERR_ARR LOG_STREAM(err, log_arrows)
29 #define WRN_ARR LOG_STREAM(warn, log_arrows)
30 #define LOG_ARR LOG_STREAM(info, log_arrows)
31 #define DBG_ARR LOG_STREAM(debug, log_arrows)
32 
33 arrow::arrow(bool hidden)
34  : layer_(display::LAYER_ARROWS)
35  , color_("red")
36  , style_(STYLE_STANDARD)
37  , path_()
38  , previous_path_()
39  , symbols_map_()
40  , hidden_(true)
41 {
42  if(!hidden)
43  show();
44 }
45 
47 {
48  hide();
49 }
50 
52 {
53  if(hidden_)
54  return;
55 
56  hidden_ = true;
57 
58  if(display* disp = display::get_singleton()) {
60  disp->remove_arrow(*this);
61  }
62 }
63 
65 {
66  if(!hidden_)
67  return;
68 
69  hidden_ = false;
70 
71  if(display* disp = display::get_singleton()) {
72  disp->add_arrow(*this);
73  }
74 }
75 
77 {
78  if (valid_path(path))
79  {
81  path_ = path;
83  if(!hidden_)
84  {
87  }
88  }
89 }
90 
92 {
95  previous_path_.clear();
96  path_.clear();
97  symbols_map_.clear();
99 }
100 
101 void arrow::set_color(const std::string& color)
102 {
103  color_ = color;
104  if (valid_path(path_))
105  {
106  update_symbols();
107  }
108 }
109 
110 const std::string arrow::STYLE_STANDARD = "standard";
111 const std::string arrow::STYLE_HIGHLIGHTED = "highlighted";
112 const std::string arrow::STYLE_FOCUS = "focus";
113 const std::string arrow::STYLE_FOCUS_INVALID = "focus_invalid";
114 
115 void arrow::set_style(const std::string& style)
116 {
117  style_ = style;
118  if (valid_path(path_))
119  {
120  update_symbols();
121  }
122 }
123 
125 {
126  return path_;
127 }
128 
130 {
131  return previous_path_;
132 }
133 
134 bool arrow::path_contains(const map_location& hex) const
135 {
136  bool contains = symbols_map_.find(hex) != symbols_map_.end();
137  return contains;
138 }
139 
141 {
142  if(path_contains(hex)) {
144  draw::blit(tex, dest);
145  });
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 lg::log_domain log_arrows("arrows")
#define WRN_ARR
Definition: arrow.cpp:29
#define ERR_ARR
Definition: arrow.cpp:28
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:140
static void invalidate_arrow_path(const arrow_path_t &path)
Invalidates every hex along the given path.
Definition: arrow.cpp:284
void show()
Definition: arrow.cpp:64
static const std::string STYLE_FOCUS_INVALID
Definition: arrow.hpp:70
void hide()
Sets the arrow's visibility.
Definition: arrow.cpp:51
void set_style(const std::string &style)
Definition: arrow.cpp:115
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:134
virtual void reset()
invalidates and clears the present path, forgets the previous path, clears the symbols map
Definition: arrow.cpp:91
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:154
const arrow_path_t & get_previous_path() const
Definition: arrow.cpp:129
virtual void notify_arrow_changed()
Definition: arrow.cpp:293
virtual ~arrow()
Definition: arrow.cpp:46
arrow(const arrow &)=delete
const arrow_path_t & get_path() const
Definition: arrow.cpp:124
virtual void set_path(const arrow_path_t &path)
Definition: arrow.cpp:76
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:101
static bool valid_path(const arrow_path_t &path)
Checks that the path is not of length 0 or 1.
Definition: arrow.cpp:149
Sort-of-Singleton that many classes, both GUI and non-GUI, use to access the game data.
Definition: display.hpp:87
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:1288
static display * get_singleton()
Returns the display object if a display object exists.
Definition: display.hpp:101
Generic locator abstracting the location of an image.
Definition: picture.hpp:64
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:503
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:311
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:86
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:985
bool contains(const Container &container, const Value &value)
Returns true iff value is found in container.
Definition: general.hpp:84
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:141
An abstract description of a rectangle with integer coordinates.
Definition: rect.hpp:47