diff --git a/docs/changelog.txt b/docs/changelog.txt index 1c0dbd9f2..aaa508018 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -67,9 +67,11 @@ Template for new versions: ## API - ``Gui::revealInDwarfmodeMap``: gained ``highlight`` parameter to control setting the tile highlight on the zoom target +- ``Maps::getWalkableGroup``: get the walkability group of a tile ## Lua - ``dfhack.gui.revealInDwarfmodeMap``: gained ``highlight`` parameter to control setting the tile highlight on the zoom target +- ``dfhack.maps.getWalkableGroup``: get the walkability group of a tile ## Removed diff --git a/docs/dev/Lua API.rst b/docs/dev/Lua API.rst index 4a103ef5e..202454040 100644 --- a/docs/dev/Lua API.rst +++ b/docs/dev/Lua API.rst @@ -1912,10 +1912,11 @@ Maps module Returns the plant struct that owns the tile at the specified position. -* ``dfhack.maps.canWalkBetween(pos1, pos2)`` +* ``dfhack.maps.getWalkableGroup(pos)`` - Checks if a dwarf may be able to walk between the two tiles, - using a pathfinding cache maintained by the game. + Returns the walkability group for the given tile position. A return value of + ``0`` indicates that the tile is not walkable. The data comes from a + pathfinding cache maintained by DF. .. note:: This cache is only updated when the game is unpaused, and thus @@ -1924,6 +1925,10 @@ Maps module take into account anything that depends on the actual units, like burrows, or the presence of invaders. +* ``dfhack.maps.canWalkBetween(pos1, pos2)`` + + Checks if both positions are walkable and also share a walkability group. + * ``dfhack.maps.hasTileAssignment(tilemask)`` Checks if the tile_bitmask object is not *nil* and contains any set bits; returns *true* or *false*. diff --git a/library/LuaApi.cpp b/library/LuaApi.cpp index 5469ab2cc..1fd4b5ecf 100644 --- a/library/LuaApi.cpp +++ b/library/LuaApi.cpp @@ -2239,6 +2239,7 @@ static const LuaWrapper::FunctionReg dfhack_maps_module[] = { WRAPM(Maps, enableBlockUpdates), WRAPM(Maps, getGlobalInitFeature), WRAPM(Maps, getLocalInitFeature), + WRAPM(Maps, getWalkableGroup), WRAPM(Maps, canWalkBetween), WRAPM(Maps, spawnFlow), WRAPN(hasTileAssignment, hasTileAssignment), diff --git a/library/include/modules/Maps.h b/library/include/modules/Maps.h index 2b7d768d0..9bb1dda25 100644 --- a/library/include/modules/Maps.h +++ b/library/include/modules/Maps.h @@ -339,6 +339,7 @@ extern DFHACK_EXPORT bool SortBlockEvents(df::map_block *block, extern DFHACK_EXPORT bool RemoveBlockEvent(int32_t x, int32_t y, int32_t z, df::block_square_event * which ); extern DFHACK_EXPORT bool RemoveBlockEvent(uint32_t x, uint32_t y, uint32_t z, df::block_square_event * which ); // todo: deprecate me +DFHACK_EXPORT uint16_t getWalkableGroup(df::coord pos); DFHACK_EXPORT bool canWalkBetween(df::coord pos1, df::coord pos2); DFHACK_EXPORT bool canStepBetween(df::coord pos1, df::coord pos2); diff --git a/library/modules/Maps.cpp b/library/modules/Maps.cpp index 2e831075d..a05474fa5 100644 --- a/library/modules/Maps.cpp +++ b/library/modules/Maps.cpp @@ -622,16 +622,15 @@ bool Maps::ReadGeology(vector > *layer_mats, vector return true; } +uint16_t Maps::getWalkableGroup(df::coord pos) { + auto block = getTileBlock(pos); + return block ? index_tile(block->walkable, pos) : 0; +} + bool Maps::canWalkBetween(df::coord pos1, df::coord pos2) { - auto block1 = getTileBlock(pos1); - auto block2 = getTileBlock(pos2); - - if (!block1 || !block2) - return false; - - auto tile1 = index_tile(block1->walkable, pos1); - auto tile2 = index_tile(block2->walkable, pos2); + auto tile1 = getWalkableGroup(pos1); + auto tile2 = getWalkableGroup(pos2); return tile1 && tile1 == tile2; } diff --git a/plugins/buildingplan/buildingplan_cycle.cpp b/plugins/buildingplan/buildingplan_cycle.cpp index c43834b36..0a3f0d867 100644 --- a/plugins/buildingplan/buildingplan_cycle.cpp +++ b/plugins/buildingplan/buildingplan_cycle.cpp @@ -12,7 +12,6 @@ #include "df/item.h" #include "df/item_slabst.h" #include "df/job.h" -#include "df/map_block.h" #include "df/world.h" #include @@ -48,14 +47,10 @@ struct BadFlags { // up or down (e.g. for stairs). For now, just return if the item is on a walkable tile. static bool isAccessible(color_ostream& out, df::item* item) { df::coord item_pos = Items::getPosition(item); - df::map_block* block = Maps::getTileBlock(item_pos); - bool is_walkable = false; - if (block) { - uint16_t walkability_group = index_tile(block->walkable, item_pos); - is_walkable = walkability_group != 0; - TRACE(cycle, out).print("item %d in walkability_group %u at (%d,%d,%d) is %saccessible from job site\n", - item->id, walkability_group, item_pos.x, item_pos.y, item_pos.z, is_walkable ? "(probably) " : "not "); - } + uint16_t walkability_group = Maps::getWalkableGroup(item_pos); + bool is_walkable = walkability_group != 0; + TRACE(cycle, out).print("item %d in walkability_group %u at (%d,%d,%d) is %saccessible from job site\n", + item->id, walkability_group, item_pos.x, item_pos.y, item_pos.z, is_walkable ? "(probably) " : "not "); return is_walkable; }