Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,10 @@ Template for new versions:
## Documentation

## API
- ``Units::isUnitInBox``, ``Units::getUnitsInBox``: add versions accepting pos arguments

## Lua
- ``dfhack.units.isUnitInBox``, ``dfhack.units.getUnitsInBox``: add versions accepting pos arguments

## Removed

Expand Down
6 changes: 3 additions & 3 deletions docs/dev/Lua API.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1610,18 +1610,18 @@ Units module
The unit is of Great Danger. This includes megabeasts, titans,
forgotten beasts, and demons.

* ``dfhack.units.isUnitInBox(unit, pos1, pos2)``
* ``dfhack.units.isUnitInBox(unit,x1,y1,z1,x2,y2,z2)``

Returns true if the unit is within a box defined by the
specified coordinates.

``dfhack.units.getUnitsInBox(pos1, pos2[, filter])``
* ``dfhack.units.getUnitsInBox(x1,y1,z1,x2,y2,z2[,filter])``

Returns a table of all units within the specified coordinates.
If the ``filter`` argument is given, only units where ``filter(unit)``
returns true will be included. Note that ``pos2xyz()`` cannot currently
be used to convert coordinate objects to the arguments required by
this function.
returns true will be included.

* ``dfhack.units.getUnitByNobleRole(role_name)``

Expand Down
59 changes: 41 additions & 18 deletions library/LuaApi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2162,32 +2162,55 @@ static int units_getNoblePositions(lua_State *L) {

static int units_isUnitInBox(lua_State *state) {
auto u = Lua::CheckDFObject<df::unit>(state, 1);
int x1 = luaL_checkint(state, 2);
int y1 = luaL_checkint(state, 3);
int z1 = luaL_checkint(state, 4);
int x2 = luaL_checkint(state, 5);
int y2 = luaL_checkint(state, 6);
int z2 = luaL_checkint(state, 7);

lua_pushboolean(state, Units::isUnitInBox(u, x1, y1, z1, x2, y2, z2));
if (lua_gettop(state) > 3) {
int x1 = luaL_checkint(state, 2);
int y1 = luaL_checkint(state, 3);
int z1 = luaL_checkint(state, 4);
int x2 = luaL_checkint(state, 5);
int y2 = luaL_checkint(state, 6);
int z2 = luaL_checkint(state, 7);
lua_pushboolean(state, Units::isUnitInBox(u, x1, y1, z1, x2, y2, z2));
}
else {
df::coord pos1, pos2;
Lua::CheckDFAssign(state, &pos1, 2);
Lua::CheckDFAssign(state, &pos2, 3);
lua_pushboolean(state, Units::isUnitInBox(u, pos1, pos2));
}
return 1;
}

static int units_getUnitsInBox(lua_State *state) {
vector<df::unit *> units;
int x1 = luaL_checkint(state, 1);
int y1 = luaL_checkint(state, 2);
int z1 = luaL_checkint(state, 3);
int x2 = luaL_checkint(state, 4);
int y2 = luaL_checkint(state, 5);
int z2 = luaL_checkint(state, 6);
cuboid box;

int max_arg = lua_gettop(state);
if (max_arg > 3) {
int x1 = luaL_checkint(state, 1);
int y1 = luaL_checkint(state, 2);
int z1 = luaL_checkint(state, 3);
int x2 = luaL_checkint(state, 4);
int y2 = luaL_checkint(state, 5);
int z2 = luaL_checkint(state, 6);
box = cuboid(x1,y1,z1,x2,y2,z2);
}
else {
df::coord pos1, pos2;
Lua::CheckDFAssign(state, &pos1, 1);
Lua::CheckDFAssign(state, &pos2, 2);
box = cuboid(pos1, pos2);
}

int fn_arg = max_arg > 3 ? 7 : 3;
bool ok = false;
if (lua_gettop(state) < 7 || lua_isnil(state, 7)) // Default filter
ok = Units::getUnitsInBox(units, x1, y1, z1, x2, y2, z2);
if (max_arg < fn_arg || lua_isnil(state, fn_arg)) // Default filter
ok = Units::getUnitsInBox(units, box);
else {
luaL_checktype(state, 7, LUA_TFUNCTION);
ok = Units::getUnitsInBox(units, x1, y1, z1, x2, y2, z2, [&state](df::unit *unit) {
luaL_checktype(state, fn_arg, LUA_TFUNCTION);
if (max_arg > fn_arg) // Something after filter on stack
luaL_argerror(state, fn_arg+1, "too many arguments!");

ok = Units::getUnitsInBox(units, box, [&state](df::unit *unit) {
lua_dup(state); // Copy function
Lua::PushDFObject(state, unit);
lua_call(state, 1, 1);
Expand Down
4 changes: 4 additions & 0 deletions library/include/modules/Units.h
Original file line number Diff line number Diff line change
Expand Up @@ -179,13 +179,17 @@ DFHACK_EXPORT bool isGreatDanger(df::unit *unit);
DFHACK_EXPORT bool isUnitInBox(df::unit *u, const cuboid &box);
DFHACK_EXPORT inline bool isUnitInBox(df::unit *u, int16_t x1, int16_t y1, int16_t z1,
int16_t x2, int16_t y2, int16_t z2) { return isUnitInBox(u, cuboid(x1, y1, z1, x2, y2, z2)); }
DFHACK_EXPORT inline bool isUnitInBox(df::unit *u, df::coord pos1, df::coord pos2) { return isUnitInBox(u, cuboid(pos1, pos2)); }

// Fill vector with units in box matching filter.
DFHACK_EXPORT bool getUnitsInBox(std::vector<df::unit *> &units, const cuboid &box,
std::function<bool(df::unit *)> filter = [](df::unit *u) { return true; });
DFHACK_EXPORT inline bool getUnitsInBox(std::vector<df::unit *> &units, int16_t x1, int16_t y1, int16_t z1,
int16_t x2, int16_t y2, int16_t z2, std::function<bool(df::unit *)> filter = [](df::unit *u) { return true; })
{ return getUnitsInBox(units, cuboid(x1, y1, z1, x2, y2, z2), filter); }
DFHACK_EXPORT inline bool getUnitsInBox(std::vector<df::unit *> &units, df::coord pos1, df::coord pos2,
std::function<bool(df::unit *)> filter = [](df::unit *u) { return true; })
{ return getUnitsInBox(units, cuboid(pos1, pos2), filter); }

// Noble string must be in form "CAPTAIN_OF_THE_GUARD", etc.
DFHACK_EXPORT bool getUnitsByNobleRole(std::vector<df::unit *> &units, std::string noble);
Expand Down
Loading