The Battle for Wesnoth 1.21.0-dev
 
Loading...
Searching...
No Matches
arrow.cpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2010 - 2025
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
26static 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
32arrow::arrow(bool hidden)
33 : color_("red")
34 , style_(STYLE_STANDARD)
35 , path_()
36 , previous_path_()
37 , symbols_map_()
38 , hidden_(true)
39{
40 if(!hidden)
41 show();
42}
43
45{
46 hide();
47}
48
50{
51 if(hidden_)
52 return;
53
54 hidden_ = true;
55
56 if(display* disp = display::get_singleton()) {
58 disp->remove_arrow(*this);
59 }
60}
61
63{
64 if(!hidden_)
65 return;
66
67 hidden_ = false;
68
69 if(display* disp = display::get_singleton()) {
70 disp->add_arrow(*this);
71 }
72}
73
75{
76 if (valid_path(path))
77 {
79 path_ = path;
81 if(!hidden_)
82 {
85 }
86 }
87}
88
98
99void arrow::set_color(const std::string& color)
100{
101 color_ = color;
102 if (valid_path(path_))
103 {
105 }
106}
107
108const std::string arrow::STYLE_STANDARD = "standard";
109const std::string arrow::STYLE_HIGHLIGHTED = "highlighted";
110const std::string arrow::STYLE_FOCUS = "focus";
111const std::string arrow::STYLE_FOCUS_INVALID = "focus_invalid";
112
113void arrow::set_style(const std::string& style)
114{
115 style_ = style;
116 if (valid_path(path_))
117 {
119 }
120}
121
123{
124 return path_;
125}
126
128{
129 return previous_path_;
130}
131
132bool arrow::path_contains(const map_location& hex) const
133{
134 bool contains = symbols_map_.find(hex) != symbols_map_.end();
135 return contains;
136}
137
139{
140 if(auto iter = symbols_map_.find(hex); iter != symbols_map_.end()) {
141 return iter->second;
142 } else {
143 return {}; // TODO: optional<locator>? Practically I don't think this path gets hit
144 }
145}
146
148{
149 return (path.size() >= 2);
150}
151
153{
154 if (!valid_path(path_))
155 {
156 WRN_ARR << "arrow::update_symbols called with invalid path";
157 return;
158 }
159
160 symbols_map_.clear();
162
163 const std::string mods = "~RC(FF00FF>"+ color_ + ")"; //magenta to current color
164
165 const std::string dirname = "arrows/";
166 std::string prefix = "";
167 std::string suffix = "";
168 std::string image_filename = "";
169 arrow_path_t::const_iterator const arrow_start_hex = path_.begin();
170 arrow_path_t::const_iterator const arrow_pre_end_hex = path_.end() - 2;
171 arrow_path_t::const_iterator const arrow_end_hex = path_.end() - 1;
172 bool teleport_out = false;
173
174 arrow_path_t::iterator hex;
175 for (hex = path_.begin(); hex != path_.end(); ++hex)
176 {
177 prefix = "";
178 suffix = "";
179 image_filename = "";
180 bool start = false;
181 bool pre_end = false;
182 bool end = false;
183
184 // teleport in if we teleported out last hex
185 bool teleport_in = teleport_out;
186 teleport_out = false;
187
188 // Determine some special cases
189 if (hex == arrow_start_hex)
190 start = true;
191 if (hex == arrow_pre_end_hex)
192 pre_end = true;
193 else if (hex == arrow_end_hex)
194 end = true;
195 if (hex != arrow_end_hex && !tiles_adjacent(*hex, *(hex + 1)))
196 teleport_out = true;
197
198 // calculate enter and exit directions, if available
200 if (!start && !teleport_in)
201 {
202 enter_dir = hex->get_relative_dir(*(hex-1));
203 }
205 if (!end && !teleport_out)
206 {
207 exit_dir = hex->get_relative_dir(*(hex+1));
208 }
209
210 // Now figure out the actual images
211 if (teleport_out)
212 {
213 prefix = "teleport-out";
215 {
216 suffix = map_location::write_direction(enter_dir);
217 }
218 }
219 else if (teleport_in)
220 {
221 prefix = "teleport-in";
223 {
224 suffix = map_location::write_direction(exit_dir);
225 }
226 }
227 else if (start)
228 {
229 prefix = "start";
230 suffix = map_location::write_direction(exit_dir);
231 if (pre_end)
232 {
233 suffix = suffix + "_ending";
234 }
235 }
236 else if (end)
237 {
238 prefix = "end";
239 suffix = map_location::write_direction(enter_dir);
240 }
241 else
242 {
243 std::string enter, exit;
244 enter = map_location::write_direction(enter_dir);
245 exit = map_location::write_direction(exit_dir);
246 if (pre_end)
247 {
248 exit = exit + "_ending";
249 }
250
251 //assert(std::abs(enter_dir - exit_dir) > 1); //impossible turn?
252 if (enter_dir < exit_dir)
253 {
254 prefix = enter;
255 suffix = exit;
256 }
257 else //(enter_dir > exit_dir)
258 {
259 prefix = exit;
260 suffix = enter;
261 }
262 }
263
264 image_filename = dirname + style_ + "/" + prefix;
265 if (!suffix.empty())
266 {
267 image_filename += ("-" + suffix);
268 }
269 image_filename += ".png";
270 assert(!image_filename.empty());
271
272 image::locator image = image::locator(image_filename, mods);
273 if (!image::exists(image))
274 {
275 ERR_ARR << "Image " << image_filename << " not found.";
277 }
278 symbols_map_[*hex] = image;
279 }
280}
281
283{
284 if(display* disp = display::get_singleton()) {
285 for(const map_location& loc : path) {
286 disp->invalidate(loc);
287 }
288 }
289}
290
292{
293 if(display* disp = display::get_singleton()) {
294 disp->update_arrow(*this);
295 }
296}
map_location loc
Definition move.cpp:172
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:104
static void invalidate_arrow_path(const arrow_path_t &path)
Invalidates every hex along the given path.
Definition arrow.cpp:282
void show()
Definition arrow.cpp:62
static const std::string STYLE_FOCUS_INVALID
Definition arrow.hpp:70
void hide()
Sets the arrow's visibility.
Definition arrow.cpp:49
void set_style(const std::string &style)
Definition arrow.cpp:113
arrow_path_t path_
Definition arrow.hpp:98
arrow_path_t previous_path_
Definition arrow.hpp:99
static const std::string STYLE_FOCUS
Definition arrow.hpp:69
bool path_contains(const map_location &hex) const
Definition arrow.cpp:132
void reset()
invalidates and clears the present path, forgets the previous path, clears the symbols map
Definition arrow.cpp:89
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:96
void update_symbols()
Calculate the symbols to place along the arrow path.
Definition arrow.cpp:152
const arrow_path_t & get_previous_path() const
Definition arrow.cpp:127
void notify_arrow_changed()
Definition arrow.cpp:291
~arrow()
Definition arrow.cpp:44
arrow(const arrow &)=delete
const arrow_path_t & get_path() const
Definition arrow.cpp:122
void set_path(const arrow_path_t &path)
Definition arrow.cpp:74
arrow_symbols_map_t symbols_map_
Definition arrow.hpp:102
std::string color_
Definition arrow.hpp:94
image::locator get_image_for_loc(const map_location &hex) const
Definition arrow.cpp:138
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:99
static bool valid_path(const arrow_path_t &path)
Checks that the path is not of length 0 or 1.
Definition arrow.cpp:147
Sort-of-Singleton that many classes, both GUI and non-GUI, use to access the game data.
Definition display.hpp:88
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:59
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:541
Standard logging facilities (interface).
Functions to load and save images from/to disk.
bool exists(const image::locator &i_locator)
Returns true if the given image actually exists, without loading it.
Definition picture.cpp:855
Encapsulates the map of the game.
Definition location.hpp:46
static std::string write_direction(direction dir)
Definition location.cpp:154
direction
Valid directions which can be moved in our hexagonal world.
Definition location.hpp:48