34 #define ERR_CF LOG_STREAM(err, log_config)
41 std::ostream &
operator<<(std::ostream &
s,
const std::vector<map_location>& v) {
42 std::vector<map_location>::const_iterator
i = v.begin();
43 for(;
i!= v.end(); ++
i) {
44 s <<
"(" << *
i <<
") ";
74 std::hash<std::size_t>
h;
75 return h( (
static_cast<uint32_t
>(a.
x) << 16) ^
static_cast<uint32_t
>(a.
y) );
90 const std::size_t open = str.find_first_of(
'('), close = str.find_last_of(
')');
91 if (open != std::string::npos && close != std::string::npos) {
92 std::string sub = str.substr(open + 1, close - open - 1);
99 const std::size_t
start = str[0] ==
'-' ? 1 : 0;
100 const std::size_t end = str.find_first_of(
':');
101 const std::string& main_dir = str.substr(
start, end -
start);
104 if (main_dir ==
"n") {
106 }
else if (main_dir ==
"ne") {
108 }
else if (main_dir ==
"se") {
110 }
else if (main_dir ==
"s") {
112 }
else if (main_dir ==
"sw") {
114 }
else if (main_dir ==
"nw") {
124 if (end != std::string::npos) {
125 const std::string rel_dir = str.substr(end + 1);
126 if (rel_dir ==
"cw") {
128 }
else if (rel_dir ==
"ccw") {
141 std::vector<map_location::direction> to_return;
143 std::vector<std::string>::const_iterator
i, i_end=dir_strs.end();
144 for(
i = dir_strs.begin();
i != i_end; ++
i) {
148 to_return.push_back(temp);
158 return std::string(
"n");
160 return std::string(
"ne");
162 return std::string(
"nw");
164 return std::string(
"s");
166 return std::string(
"se");
168 return std::string(
"sw");
170 return std::string();
181 return _(
"North East");
183 return _(
"North West");
187 return _(
"South East");
189 return _(
"South West");
191 return std::string();
200 std::string xs = cfg[
"x"], ys = cfg[
"y"];
208 if(xs.empty() ==
false && xs !=
"recall") {
211 }
catch(
const std::invalid_argument&) {
212 ERR_CF <<
"Invalid map coordinate: " << xs;
216 if(ys.empty() ==
false && ys !=
"recall") {\
219 }
catch(
const std::invalid_argument&) {
220 ERR_CF <<
"Invalid map coordinate: " << ys;
247 if (
loc.
x%2==0 &&
x%2==1) dy--;
251 int dist = std::abs(dx);
252 int dist_diag_SW_NE = std::abs(dy + (dx + (dy>0?0:1) )/2);
253 int dist_diag_SE_NW = std::abs(dy - (dx - (dy>0?0:1) )/2);
258 if (dist_diag_SE_NW < dist) {
261 dist = dist_diag_SE_NW;
263 if (dist_diag_SW_NE < dist) {
291 }
else if (temp.
x >
x) {
293 }
else if (temp.
x <
x) {
303 auto vec =
cubic_location{me_as_cube.
q - c_as_cube.q, me_as_cube.r - c_as_cube.r, me_as_cube.s - c_as_cube.s};
309 static const int rotations[6][3] = {{1,2,3}, {-2,-3,-1}, {3,1,2}, {-1,-2,-3}, {2,3,1}, {-3,-1,-2}};
310 int vec_temp[3] = {vec.q, vec.r, vec.s}, vec_temp2[3];
311 int i = ((k % 6) + 6) % 6;
312 assert(
i >= 0 &&
i < 6);
313 #define sgn(x) ((x) < 0 ? -1 : 1)
314 for(
int j = 0; j < 3; j++) vec_temp2[j] =
sgn(rotations[
i][j]) * vec_temp[abs(rotations[
i][j])-1];
316 vec.q = vec_temp2[0] + c_as_cube.q;
317 vec.r = vec_temp2[1] + c_as_cube.r;
318 vec.s = vec_temp2[2] + c_as_cube.s;
327 if(xlocs.size() == 0 && ylocs.size() == 0) {
335 if(xlocs.size() != ylocs.size() && xlocs.size() && ylocs.size()) {
336 ERR_CF <<
"Different size lists when pairing coordinate ranges: " << xloc <<
" vs " << yloc;
340 for(;
i < xlocs.size() &&
i < ylocs.size(); ++
i) {
344 if(xr.first <=
x+1 &&
x+1 <= xr.second
345 && yr.first <=
y+1 &&
y+1 <= yr.second) {
349 for(;
i < xlocs.size(); ++
i) {
351 if(xr.first <=
x+1 &&
x+1 <= xr.second) {
355 for(;
i < ylocs.size(); ++
i) {
357 if(yr.first <=
y+1 &&
y+1 <= yr.second) {
378 int x_factor = (
static_cast<unsigned int> (dir) <= 2u) ? 1 : -1;
380 unsigned int tmp_y =
static_cast<unsigned int> (dir) - 2;
381 int y_factor = (tmp_y <= 2u) ? 1 : -1;
384 return map_location(
x + x_factor *
n,
y + y_factor * ((
n + ((
x & 1) == 1)) / 2));
386 return map_location(
x + x_factor *
n,
y + y_factor * ((
n + ((
x & 1) == 0)) / 2));
414 std::stringstream x, y;
415 std::set<map_location>::const_iterator
423 for(++
i;
i != locs.end(); ++
i) {
424 if(
i->wml_x() != first->wml_x() ||
i->wml_y() - 1 != last->wml_y()) {
425 if (last->wml_y() != first->wml_y()) {
426 y <<
"-" << (last->wml_y());
428 x <<
"," << (
i->wml_x());
429 y <<
"," << (
i->wml_y());
435 if(last->wml_y() != first->wml_y())
436 y <<
"-" << (last->wml_y());
449 const std::vector<std::string> xvals =
utils::split(cfg[
"x"]);
450 const std::vector<std::string> yvals =
utils::split(cfg[
"y"]);
452 if (xvals.size() != yvals.size()) {
453 throw std::invalid_argument(
"Number of x and y coordinates do not match.");
456 std::transform(xvals.begin(), xvals.end(), yvals.begin(), std::back_inserter(locs), &
read_locations_helper);
461 std::stringstream x, y;
463 std::vector<map_location>::const_iterator
i = locs.begin(),
466 for(;
i != end; ++
i) {
485 res->
y = a.
y - (((a.
x & 1) == 0) ? 1 : 0);
488 res->
y = a.
y + (((a.
x & 1) == 1) ? 1 : 0);
494 res->
y = a.
y + (((a.
x & 1) == 1) ? 1 : 0);
497 res->
y = a.
y - (((a.
x & 1) == 0) ? 1 : 0);
502 std::array<map_location, 6> res;
520 return (a.
x & 1) == 0;
530 return (
b.x & 1) == 0;
537 return ((a.
x -
b.x) == 1) || ((a.
x -
b.x) == - 1);
552 const std::size_t hdistance = std::abs(a.
x -
b.x);
554 const std::size_t vpenalty = ( (((a.
x & 1)==0) && ((
b.x & 1)==1) && (a.
y <
b.y))
555 || (((
b.x & 1)==0) && ((a.
x & 1)==1) && (
b.y < a.
y)) ) ? 1 : 0;
567 return std::max<int>(hdistance, std::abs(a.
y -
b.y) + vpenalty + hdistance/2);
Variant for storing WML attributes.
A config object defines a single node in a WML file, with access to child nodes.
Definitions for the interface to Wesnoth Markup Language (WML).
static std::string _(const char *str)
std::size_t hash_value(const map_location &a)
void get_adjacent_tiles(const map_location &a, map_location *res)
Function which, given a location, will place all adjacent locations in res.
static bool is_vertically_higher_than(const map_location &m1, const map_location &m2)
static map_location read_locations_helper(const std::string &xi, const std::string &yi)
std::size_t distance_between(const map_location &a, const map_location &b)
Function which gives the number of hexes between two tiles (i.e.
void write_locations(const std::vector< map_location > &locs, config &cfg)
Write a vector of locations into a config adding keys x=x1,x2,..,xn and y=y1,y2,.....
std::ostream & operator<<(std::ostream &s, const map_location &l)
Dumps a position on a stream, for debug purposes.
void read_locations(const config &cfg, std::vector< map_location > &locs)
Parse x,y keys of a config into a vector of locations.
bool tiles_adjacent(const map_location &a, const map_location &b)
Function which tells if two locations are adjacent.
void write_location_range(const std::set< map_location > &locs, config &cfg)
Write a set of locations into a config using ranges, adding keys x=x1,..,xn and y=y1a-y1b,...
static lg::log_domain log_config("config")
Standard logging facilities (interface).
General math utility functions.
constexpr bool is_even(T num)
constexpr bool is_odd(T num)
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 interpolate_variables_into_string(const std::string &str, const string_map *const symbols)
Function which will interpolate variables, starting with '$' in the string 'str' with the equivalent ...
int stoi(std::string_view str)
Same interface as std::stoi and meant as a drop in replacement, except:
std::pair< int, int > parse_range(std::string_view str)
Recognises the following patterns, and returns a {min, max} pair.
std::vector< std::string > split(const config_attribute_value &val)
Represents a map location in cubic hexagonal coordinates.
Encapsulates the map of the game.
static map_location from_cubic(cubic_location h)
static std::string write_direction(direction dir)
static std::vector< direction > parse_directions(const std::string &str)
Parse_directions takes a comma-separated list, and filters out any invalid directions.
static std::vector< direction > all_directions()
map_location get_direction(direction dir, unsigned int n=1u) const
map_location rotate_right_around_center(const map_location ¢er, int k) const
static constexpr direction get_opposite_direction(direction d)
cubic_location to_cubic() const
direction
Valid directions which can be moved in our hexagonal world.
direction get_relative_dir(const map_location &loc, map_location::RELATIVE_DIR_MODE mode) const
static const map_location & null_location()
static direction parse_direction(const std::string &str)
static std::string write_translated_direction(direction dir)
void write(config &cfg) const
bool matches_range(const std::string &xloc, const std::string &yloc) const
static constexpr direction rotate_direction(direction d, int steps=1)
Returns the direction one would face having taken steps clockwise around an undefined center.
static map_location::direction n
static map_location::direction s