The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
arrow.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2010 - 2016 by Gabriel Morin <gabrielmorin (at) gmail (dot) com>
3  Part of the Battle for Wesnoth Project http://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  * Method bodies for the arrow class.
18  */
19 
20 #include "arrow.hpp"
21 
22 #include "game_display.hpp"
23 #include "log.hpp"
24 #include "resources.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 #define SCREEN (static_cast<display*>(resources::screen))
33 
34 arrow::arrow(bool hidden)
35  : layer_(display::LAYER_ARROWS)
36  , color_("red")
37  , style_(STYLE_STANDARD)
38  , path_()
39  , previous_path_()
40  , symbols_map_()
41  , hidden_(true)
42 {
43  if(!hidden)
44  show();
45 }
46 
48 {
49  hide();
50 }
51 
53 {
54  if(hidden_)
55  return;
56  hidden_ = true;
57 
58  if (SCREEN)
59  {
61  SCREEN->remove_arrow(*this);
62  }
63 }
64 
66 {
67  if(!hidden_)
68  return;
69  hidden_ = false;
70 
71  if(SCREEN)
72  SCREEN->add_arrow(*this);
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 
101 {
102  color_ = color;
103  if (valid_path(path_))
104  {
105  update_symbols();
106  }
107 }
108 
109 std::string const arrow::STYLE_STANDARD = "standard";
110 std::string const arrow::STYLE_HIGHLIGHTED = "highlighted";
111 std::string const arrow::STYLE_FOCUS = "focus";
112 std::string const 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(map_location const& 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  {
143  SCREEN->render_image(SCREEN->get_location_x(hex), SCREEN->get_location_y(hex), layer_,
145  }
146 }
147 
149 {
150  if (path.size() >= 2)
151  return true;
152  else
153  return false;
154 }
155 
157 {
158  if (!valid_path(path_))
159  {
160  WRN_ARR << "arrow::update_symbols called with invalid path" << std::endl;
161  return;
162  }
163 
164  symbols_map_.clear();
166 
167  std::string const mods = "~RC(FF00FF>"+ color_ + ")"; //magenta to current color
168 
169  std::string const dirname = "arrows/";
170  std::string prefix = "";
171  std::string suffix = "";
172  std::string image_filename = "";
173  arrow_path_t::const_iterator const arrow_start_hex = path_.begin();
174  arrow_path_t::const_iterator const arrow_pre_end_hex = path_.end() - 2;
175  arrow_path_t::const_iterator const arrow_end_hex = path_.end() - 1;
176  bool teleport_out = false;
177 
179  for (hex = path_.begin(); hex != path_.end(); ++hex)
180  {
181  prefix = "";
182  suffix = "";
183  image_filename = "";
184  bool start = false;
185  bool pre_end = false;
186  bool end = false;
187 
188  // teleport in if we teleported out last hex
189  bool teleport_in = teleport_out;
190  teleport_out = false;
191 
192  // Determine some special cases
193  if (hex == arrow_start_hex)
194  start = true;
195  if (hex == arrow_pre_end_hex)
196  pre_end = true;
197  else if (hex == arrow_end_hex)
198  end = true;
199  if (hex != arrow_end_hex && !tiles_adjacent(*hex, *(hex + 1)))
200  teleport_out = true;
201 
202  // calculate enter and exit directions, if available
204  if (!start && !teleport_in)
205  {
206  enter_dir = hex->get_relative_dir(*(hex-1));
207  }
209  if (!end && !teleport_out)
210  {
211  exit_dir = hex->get_relative_dir(*(hex+1));
212  }
213 
214  // Now figure out the actual images
215  if (teleport_out)
216  {
217  prefix = "teleport-out";
218  if (enter_dir != map_location::NDIRECTIONS)
219  {
220  suffix = map_location::write_direction(enter_dir);
221  }
222  }
223  else if (teleport_in)
224  {
225  prefix = "teleport-in";
226  if (exit_dir != map_location::NDIRECTIONS)
227  {
228  suffix = map_location::write_direction(exit_dir);
229  }
230  }
231  else if (start)
232  {
233  prefix = "start";
234  suffix = map_location::write_direction(exit_dir);
235  if (pre_end)
236  {
237  suffix = suffix + "_ending";
238  }
239  }
240  else if (end)
241  {
242  prefix = "end";
243  suffix = map_location::write_direction(enter_dir);
244  }
245  else
246  {
247  std::string enter, exit;
248  enter = map_location::write_direction(enter_dir);
249  exit = map_location::write_direction(exit_dir);
250  if (pre_end)
251  {
252  exit = exit + "_ending";
253  }
254 
255  assert(abs(enter_dir - exit_dir) > 1); //impossible turn?
256  if (enter_dir < exit_dir)
257  {
258  prefix = enter;
259  suffix = exit;
260  }
261  else //(enter_dir > exit_dir)
262  {
263  prefix = exit;
264  suffix = enter;
265  }
266  }
267 
268  image_filename = dirname + style_ + "/" + prefix;
269  if (suffix != "")
270  {
271  image_filename += ("-" + suffix);
272  }
273  image_filename += ".png";
274  assert(image_filename != "");
275 
276  image::locator image = image::locator(image_filename, mods);
277  if (!image.file_exists())
278  {
279  ERR_ARR << "Image " << image_filename << " not found." << std::endl;
281  }
282  symbols_map_[*hex] = image;
283  }
284 }
285 
287 {
288  if(!SCREEN) return;
289 
290  for (map_location const& loc : path)
291  {
292  SCREEN->invalidate(loc);
293  }
294 }
295 
297 {
298  if(!SCREEN) return;
299 
300  SCREEN->update_arrow(*this);
301 }
surface get_image(const image::locator &i_locator, TYPE type)
function to get the surface corresponding to an image.
Definition: image.cpp:878
std::string style_
represents the subdirectory that holds images for this arrow style
Definition: arrow.hpp:96
virtual void notify_arrow_changed()
Definition: arrow.cpp:296
Arrows destined to be drawn on the map.
static std::string const STYLE_FOCUS
Definition: arrow.hpp:67
void hide()
Sets the arrow's visibility.
Definition: arrow.cpp:52
arrow_path_t const & get_path() const
Definition: arrow.cpp:123
bool file_exists() const
Tests whether the file the locater points at exists.
Definition: image.cpp:628
arrow(bool hidden=false)
Definition: arrow.cpp:34
GLenum GLsizei GLenum GLenum const GLvoid * image
Definition: glew.h:3783
arrow_symbols_map_t symbols_map_
Definition: arrow.hpp:102
static void invalidate_arrow_path(arrow_path_t const &path)
Invalidates every hex along the given path.
Definition: arrow.cpp:286
static std::string const STYLE_FOCUS_INVALID
Definition: arrow.hpp:68
SDL_Color color_
Definition: font.cpp:605
#define SCREEN
Definition: arrow.cpp:32
std::vector< map_location > arrow_path_t
Definition: arrow.hpp:25
bool contains(const tpane::titem &item, const std::string &tag, const ttext_box &text_box)
A filter testing whether a search string is used in a text.
Definition: filter.hpp:66
GLsizei const char ** path
Definition: glew.h:4654
GLuint GLuint end
Definition: glew.h:1221
bool tiles_adjacent(const map_location &a, const map_location &b)
Function which tells if two locations are adjacent.
Definition: location.hpp:314
display::tdrawing_layer layer_
Definition: arrow.hpp:92
bool path_contains(map_location const &hex) const
Definition: arrow.cpp:133
virtual void update_symbols()
Calculate the symbols to place along the arrow path.
Definition: arrow.cpp:156
static bool valid_path(arrow_path_t const &path)
Checks that the path is not of length 0 or 1.
Definition: arrow.cpp:148
static std::string const STYLE_STANDARD
If you add more styles, you should look at move::update_arrow_style()
Definition: arrow.hpp:65
GLuint start
Definition: glew.h:1221
static std::string const STYLE_HIGHLIGHTED
Definition: arrow.hpp:66
#define ERR_ARR
Definition: arrow.cpp:27
GLuint color
Definition: glew.h:5801
arrow_path_t const & get_previous_path() const
Definition: arrow.cpp:128
Encapsulates the map of the game.
Definition: location.hpp:38
std::string color_
Definition: arrow.hpp:94
void show()
Definition: arrow.cpp:65
virtual void reset()
invalidates and clears the present path, forgets the previous path, clears the symbols map ...
Definition: arrow.cpp:90
arrow_path_t path_
Definition: arrow.hpp:98
DIRECTION
Valid directions which can be moved in our hexagonal world.
Definition: location.hpp:40
virtual void set_path(arrow_path_t const &path)
Definition: arrow.cpp:75
virtual void set_color(std::string const &color)
The string color parameter is in the same format expected by the image::locator modifiers parameter...
Definition: arrow.cpp:100
virtual void draw_hex(map_location const &hex)
Definition: arrow.cpp:139
this module manages the cache of images.
Definition: image.cpp:75
static lg::log_domain log_arrows("arrows")
Standard logging facilities (interface).
int style_
Definition: font.cpp:606
void set_style(std::string const &style)
Definition: arrow.cpp:114
std::string::const_iterator iterator
Definition: tokenizer.hpp:21
static std::string write_direction(DIRECTION dir)
Definition: location.cpp:144
GLsizei const GLcharARB ** string
Definition: glew.h:4503
arrow_path_t previous_path_
Definition: arrow.hpp:99
virtual ~arrow()
Definition: arrow.cpp:47
#define WRN_ARR
Definition: arrow.cpp:28
bool hidden_
Definition: arrow.hpp:104