The Battle for Wesnoth  1.17.12+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 "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  disp->drawing_buffer_add(layer_, hex, [disp, tex = image::get_texture(symbols_map_[hex])](const rect& dest) {
145  draw::blit(tex, disp->scaled_to_zoom({dest.x, dest.y, tex.w(), tex.h()}));
146  });
147  }
148 }
149 
151 {
152  return (path.size() >= 2);
153 }
154 
156 {
157  if (!valid_path(path_))
158  {
159  WRN_ARR << "arrow::update_symbols called with invalid path";
160  return;
161  }
162 
163  symbols_map_.clear();
165 
166  const std::string mods = "~RC(FF00FF>"+ color_ + ")"; //magenta to current color
167 
168  const std::string dirname = "arrows/";
169  std::string prefix = "";
170  std::string suffix = "";
171  std::string image_filename = "";
172  arrow_path_t::const_iterator const arrow_start_hex = path_.begin();
173  arrow_path_t::const_iterator const arrow_pre_end_hex = path_.end() - 2;
174  arrow_path_t::const_iterator const arrow_end_hex = path_.end() - 1;
175  bool teleport_out = false;
176 
178  for (hex = path_.begin(); hex != path_.end(); ++hex)
179  {
180  prefix = "";
181  suffix = "";
182  image_filename = "";
183  bool start = false;
184  bool pre_end = false;
185  bool end = false;
186 
187  // teleport in if we teleported out last hex
188  bool teleport_in = teleport_out;
189  teleport_out = false;
190 
191  // Determine some special cases
192  if (hex == arrow_start_hex)
193  start = true;
194  if (hex == arrow_pre_end_hex)
195  pre_end = true;
196  else if (hex == arrow_end_hex)
197  end = true;
198  if (hex != arrow_end_hex && !tiles_adjacent(*hex, *(hex + 1)))
199  teleport_out = true;
200 
201  // calculate enter and exit directions, if available
203  if (!start && !teleport_in)
204  {
205  enter_dir = hex->get_relative_dir(*(hex-1));
206  }
208  if (!end && !teleport_out)
209  {
210  exit_dir = hex->get_relative_dir(*(hex+1));
211  }
212 
213  // Now figure out the actual images
214  if (teleport_out)
215  {
216  prefix = "teleport-out";
217  if (enter_dir != map_location::NDIRECTIONS)
218  {
219  suffix = map_location::write_direction(enter_dir);
220  }
221  }
222  else if (teleport_in)
223  {
224  prefix = "teleport-in";
225  if (exit_dir != map_location::NDIRECTIONS)
226  {
227  suffix = map_location::write_direction(exit_dir);
228  }
229  }
230  else if (start)
231  {
232  prefix = "start";
233  suffix = map_location::write_direction(exit_dir);
234  if (pre_end)
235  {
236  suffix = suffix + "_ending";
237  }
238  }
239  else if (end)
240  {
241  prefix = "end";
242  suffix = map_location::write_direction(enter_dir);
243  }
244  else
245  {
246  std::string enter, exit;
247  enter = map_location::write_direction(enter_dir);
248  exit = map_location::write_direction(exit_dir);
249  if (pre_end)
250  {
251  exit = exit + "_ending";
252  }
253 
254  assert(std::abs(enter_dir - exit_dir) > 1); //impossible turn?
255  if (enter_dir < exit_dir)
256  {
257  prefix = enter;
258  suffix = exit;
259  }
260  else //(enter_dir > exit_dir)
261  {
262  prefix = exit;
263  suffix = enter;
264  }
265  }
266 
267  image_filename = dirname + style_ + "/" + prefix;
268  if (!suffix.empty())
269  {
270  image_filename += ("-" + suffix);
271  }
272  image_filename += ".png";
273  assert(!image_filename.empty());
274 
275  image::locator image = image::locator(image_filename, mods);
276  if (!image.file_exists())
277  {
278  ERR_ARR << "Image " << image_filename << " not found.";
280  }
281  symbols_map_[*hex] = image;
282  }
283 }
284 
286 {
287  if(display* disp = display::get_singleton()) {
288  for(const map_location& loc : path) {
289  disp->invalidate(loc);
290  }
291  }
292 }
293 
295 {
296  if(display* disp = display::get_singleton()) {
297  disp->update_arrow(*this);
298  }
299 }
Drawing functions, for drawing things on the screen.
static void invalidate_arrow_path(const arrow_path_t &path)
Invalidates every hex along the given path.
Definition: arrow.cpp:285
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:294
Arrows destined to be drawn on the map.
static display * get_singleton()
Returns the display object if a display object exists.
Definition: display.hpp:98
void hide()
Sets the arrow&#39;s visibility.
Definition: arrow.cpp:51
const arrow_path_t & get_path() const
Definition: arrow.cpp:124
static rect scaled_to_zoom(const SDL_Rect &r)
Scale the width and height of a rect by the current zoom factor.
Definition: display.hpp:262
bool path_contains(const map_location &hex) const
Definition: arrow.cpp:134
virtual void draw_hex(const map_location &hex)
Definition: arrow.cpp:140
arrow_symbols_map_t symbols_map_
Definition: arrow.hpp:104
virtual void set_path(const arrow_path_t &path)
Definition: arrow.cpp:76
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:129
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:1278
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:155
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:28
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:64
virtual void reset()
invalidates and clears the present path, forgets the previous path, clears the symbols map ...
Definition: arrow.cpp:91
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
An abstract description of a rectangle with integer coordinates.
Definition: rect.hpp:46
arrow_path_t path_
Definition: arrow.hpp:100
DIRECTION
Valid directions which can be moved in our hexagonal world.
Definition: location.hpp:40
void blit(const texture &tex, const SDL_Rect &dst)
Draws a texture, or part of a texture, at the given location.
Definition: draw.cpp:301
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:115
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:1128
static bool valid_path(const arrow_path_t &path)
Checks that the path is not of length 0 or 1.
Definition: arrow.cpp:150
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:46
#define WRN_ARR
Definition: arrow.cpp:29
bool hidden_
Definition: arrow.hpp:106