[Lua.Mapgen] Add a few more ways to pass a location set to f.find_in
These may be less efficient in some cases, and there's even a couple of degenerate cases, but it's definitely easier to use like this. This also adds an example of the original method, using a string to reference a separate list.
This commit is contained in:
parent
4c4b30aaac
commit
19f3682bdf
2 changed files with 63 additions and 7 deletions
|
@ -384,11 +384,24 @@ if wesnoth.kernel_type() == "Mapgen Lua Kernel" then
|
|||
return { "adjacent", f, adjacent = adj, count = count }
|
||||
end,
|
||||
---Match hexes from a separate list.
|
||||
---Specify the list in the second argument to wesnoth.map.filter()
|
||||
---@param terrain string
|
||||
---When passing a locset_ref, specify the list
|
||||
---in the second argument to wesnoth.map.filter()
|
||||
---
|
||||
---For example:
|
||||
---```
|
||||
---local M = wesnoth.map.create(128, 128, 'Gg')
|
||||
---local f = wesnoth.map.filter_tags
|
||||
---local found = M:find(f.find_in("choices"), {choices = {{1,2}, {5,6}}})
|
||||
---```
|
||||
---@param x integer
|
||||
---@param y integer
|
||||
---@return terrain_filter_tag
|
||||
find_in = function(terrain)
|
||||
return { "find_in", terrain }
|
||||
---@overload fun(xs:string, ys:string):terrain_filter_tag
|
||||
---@overload fun(loc:location):terrain_filter_tag
|
||||
---@overload fun(locs:location[]):terrain_filter_tag
|
||||
---@overload fun(locset_ref:string):terrain_filter_tag
|
||||
find_in = function(x, y)
|
||||
return { "find_in", x, y }
|
||||
end,
|
||||
---Match hexes within a given distance
|
||||
---@param r integer
|
||||
|
|
|
@ -467,10 +467,52 @@ public:
|
|||
: set_(nullptr)
|
||||
{
|
||||
LOG_LMG << "creating findin filter";
|
||||
lua_geti(L, -1, 2);
|
||||
std::string id = std::string(luaW_tostring(L, -1));
|
||||
lua_pop(L, 1);
|
||||
int idx = lua_absindex(L, -1);
|
||||
switch(lua_geti(L, idx, 2)) {
|
||||
case LUA_TTABLE:
|
||||
// Also accepts a single location of the form {x,y} or {x=x,y=y}
|
||||
init_from_inline_set(luaW_to_locationset(L, -1));
|
||||
break;
|
||||
case LUA_TNUMBER:
|
||||
lua_geti(L, idx, 3);
|
||||
init_from_single_loc(luaL_checkinteger(L, -2), luaL_checkinteger(L, -1));
|
||||
break;
|
||||
case LUA_TSTRING:
|
||||
if(lua_geti(L, idx, 3) == LUA_TSTRING) {
|
||||
init_from_ranges(luaL_checkstring(L, -2), luaL_checkstring(L, -1));
|
||||
} else {
|
||||
init_from_named_set(L, luaL_checkstring(L, -1), res_index, ks);
|
||||
}
|
||||
break;
|
||||
}
|
||||
lua_settop(L, idx);
|
||||
}
|
||||
|
||||
void init_from_inline_set(const location_set& locs) {
|
||||
inline_ = locs;
|
||||
set_ = &inline_;
|
||||
}
|
||||
|
||||
void init_from_single_loc(int x, int y) {
|
||||
map_location loc(x, y, wml_loc());
|
||||
inline_.insert(loc);
|
||||
set_ = &inline_;
|
||||
}
|
||||
|
||||
void init_from_ranges(const std::string& xs, const std::string& ys) {
|
||||
auto xvals = utils::parse_ranges_unsigned(xs), yvals = utils::parse_ranges_unsigned(ys);
|
||||
// TODO: Probably error if they're different sizes?
|
||||
for(size_t i = 0; i < std::min(xvals.size(), yvals.size()); i++) {
|
||||
for(int x = xvals[i].first; x <= xvals[i].second; x++) {
|
||||
for(int y = yvals[i].first; y <= yvals[i].second; y++) {
|
||||
inline_.insert(map_location(x, y, wml_loc()));
|
||||
}
|
||||
}
|
||||
}
|
||||
set_ = &inline_;
|
||||
}
|
||||
|
||||
void init_from_named_set(lua_State* L, const std::string& id, int res_index, known_sets_t& ks) {
|
||||
//TODO: c++14: use heterogenous lookup.
|
||||
auto insert_res = ks.insert(known_sets_t::value_type{id, {}});
|
||||
if(insert_res.second && res_index > 0) {
|
||||
|
@ -491,6 +533,7 @@ public:
|
|||
return false;
|
||||
}
|
||||
const location_set* set_;
|
||||
location_set inline_;
|
||||
};
|
||||
|
||||
class radius_filter : public filter_impl
|
||||
|
|
Loading…
Add table
Reference in a new issue