The Battle for Wesnoth  1.19.0+dev
lua_map_location_ops.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2014 - 2024
3  by Chris Beck <render787@gmail.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 
17 #include "scripting/lua_common.hpp"
18 #include "scripting/push_check.hpp"
19 
20 #include "map/location.hpp"
21 #include "pathutils.hpp"
22 
23 #include <string>
24 #include <utility>
25 
26 
27 namespace lua_map_location {
28 
29 /**
30  * Expose map_location::get_direction function to lua
31  * Arg 1: a location
32  * Arg 2: a direction
33  * Arg 3: (optional) number of steps
34  */
35 int intf_get_direction(lua_State* L)
36 {
37  map_location l;
38  if(!luaW_tolocation(L, 1, l)) {
39  return luaL_argerror(L, 1, "get_direction: first argument(S) must be a location");
40  }
41  int nargs = lua_gettop(L);
42  if (nargs < 2) {
43  luaL_error(L, "get_direction: not missing direction argument");
44  return 0;
45  }
46 
47  int n = 1;
48  if (nargs == 3) {
49  n = luaL_checkinteger(L, -1);
50  lua_pop(L,1);
51  }
52 
54  if (lua_isstring(L, -1)) {
55  d = map_location::parse_direction(luaL_checkstring(L,-1));
56  lua_pop(L,1);
57  } else {
58  std::string msg("get_direction: second argument should be a direction string, instead found a ");
59  msg += lua_typename(L, lua_type(L, -1));
60  return luaL_argerror(L, -1, msg.c_str());
61  }
62 
63  map_location result = l.get_direction(d, n);
64  luaW_pushlocation(L, result);
65  return 1;
66 }
67 
68 /**
69  * Expose map_location::vector_sum to lua
70  */
71 int intf_vector_sum(lua_State* L)
72 {
73  map_location l1, l2;
74  if(!luaW_tolocation(L, 1, l1) || !luaW_tolocation(L, 2, l2)) {
75  lua_pushstring(L, "vector_sum: requires two locations");
76  return lua_error(L);
77  }
78 
80  return 1;
81 }
82 
83 /**
84  * Expose map_location::vector_difference to lua
85  */
86 int intf_vector_diff(lua_State* L)
87 {
88  map_location l1, l2;
89  if(!luaW_tolocation(L, 1, l1) || !luaW_tolocation(L, 2, l2)) {
90  lua_pushstring(L, "vector_diff: requires two locations");
91  return lua_error(L);
92  }
93 
95  return 1;
96 }
97 
98 /**
99  * Expose map_location::vector_negation to lua
100  * - Arg 1: Location
101  * - Ret: Negated vector
102  */
103 int intf_vector_negation(lua_State* L)
104 {
105  map_location l1;
106  if(!luaW_tolocation(L, 1, l1)) {
107  return luaL_argerror(L, 1, "expected a location");
108  }
109 
111  return 1;
112 }
113 
114 /**
115  * Expose map_location::rotate_right_around_center to lua
116  */
118 {
119  int k = luaL_checkinteger(L, -1);
120  lua_pop(L,1);
121  map_location center, loc;
122  if(!luaW_tolocation(L, 1, loc) || !luaW_tolocation(L, 2, center)) {
123  lua_pushstring(L, "rotate_right_around_center: requires two locations");
124  return lua_error(L);
125  }
126 
128  return 1;
129 }
130 
131 /**
132  * Expose map_location tiles_adjacent
133  * - Args 1, 2: Two locations
134  * - Ret: True if the locations are adjacent
135  */
136 int intf_tiles_adjacent(lua_State* L)
137 {
138  map_location l1, l2;
139  if(!luaW_tolocation(L, 1, l1) || !luaW_tolocation(L, 2, l2)) {
140  lua_pushstring(L, "tiles_adjacent: requires two locations");
141  return lua_error(L);
142  }
143 
144  lua_pushboolean(L, tiles_adjacent(l1,l2));
145  return 1;
146 }
147 
148 /**
149  * Expose map_location get_adjacent_tiles
150  * - Arg 1: A location
151  * - Ret 1 - 6: The adjacent locations
152  */
153 int intf_get_adjacent_tiles(lua_State* L)
154 {
155  map_location l1;
156  if(!luaW_tolocation(L, 1, l1)) {
157  return luaL_argerror(L, 1, "expected a location");
158  }
159 
160  for(const map_location& adj : get_adjacent_tiles(l1)) {
161  luaW_pushlocation(L, adj);
162  }
163 
164  return 6;
165 }
166 
167 /**
168  * Expose map_location get_tiles_in_radius
169  * - Arg 1: A location
170  * - Ret: The locations
171  */
172 int intf_get_tiles_in_radius(lua_State* L)
173 {
174  map_location l1;
175  if(!luaW_tolocation(L, 1, l1)) {
176  return luaL_argerror(L, 1, "expected a location");
177  }
178  int radius = luaL_checkinteger(L, 2);
179 
180  std::vector<map_location> locs;
181  get_tiles_in_radius(l1, radius, locs);
182  lua_push(L, locs);
183 
184  return 1;
185 }
186 
187 /**
188  * Expose map_location distance_between
189  * - Args 1, 2: Two locations
190  * - Ret: The distance between the two locations
191  */
192 int intf_distance_between(lua_State* L)
193 {
194  map_location l1, l2;
195  if(!luaW_tolocation(L, 1, l1) || !luaW_tolocation(L, 2, l2)) {
196  lua_pushstring(L, "distance_between: requires two locations");
197  return lua_error(L);
198  }
199 
200  lua_pushinteger(L, distance_between(l1,l2));
201  return 1;
202 }
203 
204 /**
205  * Expose map_location get_in_basis_N_NE
206  */
207 int intf_get_in_basis_N_NE(lua_State* L)
208 {
209  map_location l1;
210  if(!luaW_tolocation(L, 1, l1)) {
211  return luaL_argerror(L, 1, "expected a location");
212  }
213 
214  std::pair<int, int> r = l1.get_in_basis_N_NE();
215  lua_pushinteger(L, r.first);
216  lua_pushinteger(L, r.second);
217  return 2;
218 }
219 
220 /**
221  * Expose map_location get_relative_dir
222  * - Args 1, 2: Two locations
223  * - Ret: The direction of location 2 from location 1
224  */
225 int intf_get_relative_dir(lua_State* L)
226 {
227  map_location l1, l2;
228  if(!luaW_tolocation(L, 1, l1) || !luaW_tolocation(L, 2, l2)) {
229  lua_pushstring(L, "get_relative_dir: requires two locations");
230  return lua_error(L);
231  }
232 
233  const std::string dir = map_location::write_direction(l1.get_relative_dir(l2));
234  lua_pushlstring(L, dir.c_str(), dir.length());
235  return 1;
236 }
237 
238 } // end namespace lua_map_location
void get_adjacent_tiles(const map_location &a, map_location *res)
Function which, given a location, will place all adjacent locations in res.
Definition: location.cpp:474
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.
Definition: location.cpp:545
bool tiles_adjacent(const map_location &a, const map_location &b)
Function which tells if two locations are adjacent.
Definition: location.cpp:502
void luaW_pushlocation(lua_State *L, const map_location &ml)
Converts a map location object to a Lua table pushed at the top of the stack.
Definition: lua_common.cpp:730
bool luaW_tolocation(lua_State *L, int index, map_location &loc)
Converts an optional table or pair of integers to a map location object.
Definition: lua_common.cpp:741
int intf_get_relative_dir(lua_State *L)
Expose map_location get_relative_dir.
int intf_vector_negation(lua_State *L)
Expose map_location::vector_negation to lua.
int intf_distance_between(lua_State *L)
Expose map_location distance_between.
int intf_get_in_basis_N_NE(lua_State *L)
Expose map_location get_in_basis_N_NE.
int intf_tiles_adjacent(lua_State *L)
Expose map_location tiles_adjacent.
int intf_vector_diff(lua_State *L)
Expose map_location::vector_difference to lua.
int intf_vector_sum(lua_State *L)
Expose map_location::vector_sum to lua.
int intf_rotate_right_around_center(lua_State *L)
Expose map_location::rotate_right_around_center to lua.
int intf_get_tiles_in_radius(lua_State *L)
Expose map_location get_tiles_in_radius.
int intf_get_adjacent_tiles(lua_State *L)
Expose map_location get_adjacent_tiles.
int intf_get_direction(lua_State *L)
Expose map_location::get_direction function to lua Arg 1: a location Arg 2: a direction Arg 3: (optio...
static void msg(const char *act, debug_info &i, const char *to="", const char *result="")
Definition: debugger.cpp:109
void get_tiles_in_radius(const map_location &center, const int radius, std::vector< map_location > &result)
Function that will add to result all locations within radius tiles of center (excluding center itself...
Definition: pathutils.cpp:56
void lua_push(lua_State *L, const T &val)
Definition: push_check.hpp:373
Encapsulates the map of the game.
Definition: location.hpp:38
map_location & vector_sum_assign(const map_location &a)
Definition: location.hpp:121
map_location & vector_difference_assign(const map_location &a)
Definition: location.hpp:129
static DIRECTION parse_direction(const std::string &str)
Definition: location.cpp:65
map_location vector_negation() const
Definition: location.hpp:111
std::pair< int, int > get_in_basis_N_NE() const
Definition: location.cpp:287
DIRECTION
Valid directions which can be moved in our hexagonal world.
Definition: location.hpp:40
map_location get_direction(DIRECTION dir, unsigned int n=1u) const
Definition: location.cpp:359
DIRECTION get_relative_dir(const map_location &loc, map_location::RELATIVE_DIR_MODE mode) const
Definition: location.cpp:226
map_location rotate_right_around_center(const map_location &center, int k) const
Definition: location.cpp:306
static std::string write_direction(DIRECTION dir)
Definition: location.cpp:140
static map_location::DIRECTION n
#define d