The Battle for Wesnoth  1.17.21+dev
lua_map_location_ops.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2014 - 2023
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 #include "lua/lauxlib.h"
27 
28 namespace lua_map_location {
29 
30 /**
31  * Expose map_location::get_direction function to lua
32  * Arg 1: a location
33  * Arg 2: a direction
34  * Arg 3: (optional) number of steps
35  */
36 int intf_get_direction(lua_State* L)
37 {
38  map_location l;
39  if(!luaW_tolocation(L, 1, l)) {
40  return luaL_argerror(L, 1, "get_direction: first argument(S) must be a location");
41  }
42  int nargs = lua_gettop(L);
43  if (nargs < 2) {
44  luaL_error(L, "get_direction: not missing direction argument");
45  return 0;
46  }
47 
48  int n = 1;
49  if (nargs == 3) {
50  n = luaL_checkinteger(L, -1);
51  lua_pop(L,1);
52  }
53 
55  if (lua_isstring(L, -1)) {
56  d = map_location::parse_direction(luaL_checkstring(L,-1));
57  lua_pop(L,1);
58  } else {
59  std::string msg("get_direction: second argument should be a direction string, instead found a ");
60  msg += lua_typename(L, lua_type(L, -1));
61  return luaL_argerror(L, -1, msg.c_str());
62  }
63 
64  map_location result = l.get_direction(d, n);
65  luaW_pushlocation(L, result);
66  return 1;
67 }
68 
69 /**
70  * Expose map_location::vector_sum to lua
71  */
72 int intf_vector_sum(lua_State* L)
73 {
74  map_location l1, l2;
75  if(!luaW_tolocation(L, 1, l1) || !luaW_tolocation(L, 2, l2)) {
76  lua_pushstring(L, "vector_sum: requires two locations");
77  return lua_error(L);
78  }
79 
81  return 1;
82 }
83 
84 /**
85  * Expose map_location::vector_difference to lua
86  */
87 int intf_vector_diff(lua_State* L)
88 {
89  map_location l1, l2;
90  if(!luaW_tolocation(L, 1, l1) || !luaW_tolocation(L, 2, l2)) {
91  lua_pushstring(L, "vector_diff: requires two locations");
92  return lua_error(L);
93  }
94 
96  return 1;
97 }
98 
99 /**
100  * Expose map_location::vector_negation to lua
101  * - Arg 1: Location
102  * - Ret: Negated vector
103  */
104 int intf_vector_negation(lua_State* L)
105 {
106  map_location l1;
107  if(!luaW_tolocation(L, 1, l1)) {
108  return luaL_argerror(L, 1, "expected a location");
109  }
110 
112  return 1;
113 }
114 
115 /**
116  * Expose map_location::rotate_right_around_center to lua
117  */
119 {
120  int k = luaL_checkinteger(L, -1);
121  lua_pop(L,1);
122  map_location center, loc;
123  if(!luaW_tolocation(L, 1, loc) || !luaW_tolocation(L, 2, center)) {
124  lua_pushstring(L, "rotate_right_around_center: requires two locations");
125  return lua_error(L);
126  }
127 
129  return 1;
130 }
131 
132 /**
133  * Expose map_location tiles_adjacent
134  * - Args 1, 2: Two locations
135  * - Ret: True if the locations are adjacent
136  */
137 int intf_tiles_adjacent(lua_State* L)
138 {
139  map_location l1, l2;
140  if(!luaW_tolocation(L, 1, l1) || !luaW_tolocation(L, 2, l2)) {
141  lua_pushstring(L, "tiles_adjacent: requires two locations");
142  return lua_error(L);
143  }
144 
145  lua_pushboolean(L, tiles_adjacent(l1,l2));
146  return 1;
147 }
148 
149 /**
150  * Expose map_location get_adjacent_tiles
151  * - Arg 1: A location
152  * - Ret 1 - 6: The adjacent locations
153  */
154 int intf_get_adjacent_tiles(lua_State* L)
155 {
156  map_location l1;
157  if(!luaW_tolocation(L, 1, l1)) {
158  return luaL_argerror(L, 1, "expected a location");
159  }
160 
161  for(const map_location& adj : get_adjacent_tiles(l1)) {
162  luaW_pushlocation(L, adj);
163  }
164 
165  return 6;
166 }
167 
168 /**
169  * Expose map_location get_tiles_in_radius
170  * - Arg 1: A location
171  * - Ret: The locations
172  */
173 int intf_get_tiles_in_radius(lua_State* L)
174 {
175  map_location l1;
176  if(!luaW_tolocation(L, 1, l1)) {
177  return luaL_argerror(L, 1, "expected a location");
178  }
179  int radius = luaL_checkinteger(L, 2);
180 
181  std::vector<map_location> locs;
182  get_tiles_in_radius(l1, radius, locs);
183  lua_push(L, locs);
184 
185  return 1;
186 }
187 
188 /**
189  * Expose map_location distance_between
190  * - Args 1, 2: Two locations
191  * - Ret: The distance between the two locations
192  */
193 int intf_distance_between(lua_State* L)
194 {
195  map_location l1, l2;
196  if(!luaW_tolocation(L, 1, l1) || !luaW_tolocation(L, 2, l2)) {
197  lua_pushstring(L, "distance_between: requires two locations");
198  return lua_error(L);
199  }
200 
201  lua_pushinteger(L, distance_between(l1,l2));
202  return 1;
203 }
204 
205 /**
206  * Expose map_location get_in_basis_N_NE
207  */
208 int intf_get_in_basis_N_NE(lua_State* L)
209 {
210  map_location l1;
211  if(!luaW_tolocation(L, 1, l1)) {
212  return luaL_argerror(L, 1, "expected a location");
213  }
214 
215  std::pair<int, int> r = l1.get_in_basis_N_NE();
216  lua_pushinteger(L, r.first);
217  lua_pushinteger(L, r.second);
218  return 2;
219 }
220 
221 /**
222  * Expose map_location get_relative_dir
223  * - Args 1, 2: Two locations
224  * - Ret: The direction of location 2 from location 1
225  */
226 int intf_get_relative_dir(lua_State* L)
227 {
228  map_location l1, l2;
229  if(!luaW_tolocation(L, 1, l1) || !luaW_tolocation(L, 2, l2)) {
230  lua_pushstring(L, "get_relative_dir: requires two locations");
231  return lua_error(L);
232  }
233 
234  const std::string dir = map_location::write_direction(l1.get_relative_dir(l2));
235  lua_pushlstring(L, dir.c_str(), dir.length());
236  return 1;
237 }
238 
239 } // 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:475
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:546
bool tiles_adjacent(const map_location &a, const map_location &b)
Function which tells if two locations are adjacent.
Definition: location.cpp:503
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:733
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:744
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:110
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:66
map_location vector_negation() const
Definition: location.hpp:111
std::pair< int, int > get_in_basis_N_NE() const
Definition: location.cpp:288
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:360
DIRECTION get_relative_dir(const map_location &loc, map_location::RELATIVE_DIR_MODE mode) const
Definition: location.cpp:227
map_location rotate_right_around_center(const map_location &center, int k) const
Definition: location.cpp:307
static std::string write_direction(DIRECTION dir)
Definition: location.cpp:141
static map_location::DIRECTION n
#define d