From d81de5e4c70aaa8e3f30e81f112610352abc5972 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Tue, 22 Jun 2021 20:01:10 -0700 Subject: [PATCH 01/10] Add getPlantAtCoords function to Maps namespace Derived from disassembly of DF code. Returns a pointer to plant struct that owns the tile at position. Useful for finding a tree from one of its branches. Lua API support. --- library/include/modules/Maps.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/library/include/modules/Maps.h b/library/include/modules/Maps.h index f33abf4e0..c3267dfbb 100644 --- a/library/include/modules/Maps.h +++ b/library/include/modules/Maps.h @@ -40,6 +40,7 @@ distribution. #include "df/block_flags.h" #include "df/feature_type.h" #include "df/flow_type.h" +#include "df/plant.h" #include "df/tile_dig_designation.h" #include "df/tile_liquid.h" #include "df/tile_traffic.h" @@ -335,6 +336,13 @@ extern DFHACK_EXPORT bool RemoveBlockEvent(uint32_t x, uint32_t y, uint32_t z, d DFHACK_EXPORT bool canWalkBetween(df::coord pos1, df::coord pos2); DFHACK_EXPORT bool canStepBetween(df::coord pos1, df::coord pos2); +/** + * Get the plant that owns the tile at the specified position + */ +extern DFHACK_EXPORT df::plant *getPlantAtCoords(int32_t x, int32_t y, int32_t z); + +inline df::plant *getPlantAtCoords(df::coord pos) { return getPlantAtCoords(pos.x, pos.y, pos.z); } + DFHACK_EXPORT df::enums::biome_type::biome_type GetBiomeType(int world_coord_x, int world_coord_y); DFHACK_EXPORT df::enums::biome_type::biome_type GetBiomeTypeWithRef(int world_coord_x, int world_coord_y, int world_ref_y_coord); From b64e28253f827981442290b8d14103fdf84d1ff3 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Tue, 22 Jun 2021 20:03:18 -0700 Subject: [PATCH 02/10] Update Maps.cpp --- library/modules/Maps.cpp | 48 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/library/modules/Maps.cpp b/library/modules/Maps.cpp index 361ada0f1..75ba35c51 100644 --- a/library/modules/Maps.cpp +++ b/library/modules/Maps.cpp @@ -55,11 +55,13 @@ using namespace std; #include "df/burrow.h" #include "df/feature_init.h" #include "df/flow_info.h" +#include "df/map_block_column.h" #include "df/plant.h" +#include "df/plant_tree_info.h" +#include "df/plant_tree_tile.h" #include "df/region_map_entry.h" #include "df/world.h" #include "df/world_data.h" -#include "df/world_data.h" #include "df/world_geo_biome.h" #include "df/world_geo_layer.h" #include "df/world_region_details.h" @@ -713,6 +715,50 @@ bool Maps::canStepBetween(df::coord pos1, df::coord pos2) return false; } +/* +* Plants +*/ +df::plant *Maps::getPlantAtCoords(int32_t x, int32_t y, int32_t z) +{ + if (x < 0 || x >= world->map.x_count || y < 0 || y >= world->map.y_count || !world->map.column_index) + return NULL; + + df::map_block_column *mbc = world->map.column_index[(x / 48) * 3][(y / 48) * 3]; + if (!mbc) + return NULL; + + int32_t x_mod_48 = x % 48; + int32_t y_mod_48 = y % 48; + for (size_t i = 0; i < mbc->plants.size(); i++) + { + df::plant *p = mbc->plants[i]; + if (p->pos.x == x && p->pos.y == y && p->pos.z == z) + return p; + + df::plant_tree_info *t = p->tree_info; + if (!t) + continue; + + int32_t x_index = t->dim_x / 2 - p->pos.x % 48 + x_mod_48; + int32_t y_index = t->dim_y / 2 - p->pos.y % 48 + y_mod_48; + int32_t z_dis = z - p->pos.z; + if (x_index < 0 || x_index >= t->dim_x || y_index < 0 || y_index >= t->dim_y || z_dis >= t->body_height) + continue; + + if (z_dis < 0) + { + if (z_dis < -(t->roots_depth)) + continue; + else if ((t->roots[-1 - z_dis][x_index + y_index * t->dim_x].whole & 0x7F) != 0) //any non-blocked tree_tile + return p; + } + else if ((t->body[z_dis][x_index + y_index * t->dim_x].whole & 0x7F) != 0) + return p; + } + + return NULL; +} + /* The code below is a heavily refactored version of code found at https://github.com/ragundo/exportmaps/blob/master/cpp/df_utils/biome_type.cpp. */ From bc841f595e29b50e395d82051ab1081fdea7486c Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Tue, 22 Jun 2021 20:05:45 -0700 Subject: [PATCH 03/10] Update LuaApi.cpp --- library/LuaApi.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/library/LuaApi.cpp b/library/LuaApi.cpp index 11346ebaa..e04b0f256 100644 --- a/library/LuaApi.cpp +++ b/library/LuaApi.cpp @@ -1923,6 +1923,13 @@ static int maps_getTileBiomeRgn(lua_State *L) return Lua::PushPosXY(L, Maps::getTileBiomeRgn(pos)); } +static int maps_getPlantAtCoords(lua_State *L) +{ + auto pos = CheckCoordXYZ(L, 1, true); + Lua::PushDFObject(L, Maps::getPlantAtCoords(pos)); + return 1; +} + static const luaL_Reg dfhack_maps_funcs[] = { { "isValidTilePos", maps_isValidTilePos }, { "isTileVisible", maps_isTileVisible }, @@ -1932,6 +1939,7 @@ static const luaL_Reg dfhack_maps_funcs[] = { { "getTileFlags", maps_getTileFlags }, { "getRegionBiome", maps_getRegionBiome }, { "getTileBiomeRgn", maps_getTileBiomeRgn }, + { "getPlantAtCoords", maps_getPlantAtCoords }, { NULL, NULL } }; From 60fe864426fc45ca34674c97013ef8a92c26af3c Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Tue, 22 Jun 2021 20:10:25 -0700 Subject: [PATCH 04/10] Update Lua API.rst --- docs/Lua API.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/Lua API.rst b/docs/Lua API.rst index f45fe243b..37d1450f7 100644 --- a/docs/Lua API.rst +++ b/docs/Lua API.rst @@ -1558,6 +1558,10 @@ Maps module Returns *x, y* for use with ``getRegionBiome``. +* ``dfhack.maps.getPlantAtCoords(pos)``, or ``getPlantAtCoords(x,y,z)`` + + Returns the plant struct that owns the tile at the specified position. + * ``dfhack.maps.canWalkBetween(pos1, pos2)`` Checks if a dwarf may be able to walk between the two tiles, From 7f61c24181b62d151ac60e11212fd43b1a9ba7b2 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Tue, 22 Jun 2021 20:13:35 -0700 Subject: [PATCH 05/10] Authors.rst: Bumber -> Ryan Williams --- docs/Authors.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Authors.rst b/docs/Authors.rst index f924fe692..3ea92c6e7 100644 --- a/docs/Authors.rst +++ b/docs/Authors.rst @@ -30,7 +30,6 @@ Benjamin Seiller bseiller RedDwarfStepper billw2012 billw2012 BrickViking brickviking brndd brndd burneddi -Bumber Bumber64 Caldfir caldfir Carter Bray Qartar Chris Dombroski cdombroski @@ -152,6 +151,7 @@ rubybrowncoat rubybrowncoat Rumrusher rumrusher RusAnon RusAnon Ryan Bennitt ryanbennitt +Ryan Williams Bumber64 Bumber sami scamtank scamtank Sebastian Wolfertz Enkrod From a67a5d8283e74a7173bc99de0d1adfa616c6ceb4 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Wed, 23 Jun 2021 22:58:24 -0700 Subject: [PATCH 06/10] Rename getPlantAtCoords to getPlantAtTile --- docs/Lua API.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Lua API.rst b/docs/Lua API.rst index 37d1450f7..ca54f3922 100644 --- a/docs/Lua API.rst +++ b/docs/Lua API.rst @@ -1558,7 +1558,7 @@ Maps module Returns *x, y* for use with ``getRegionBiome``. -* ``dfhack.maps.getPlantAtCoords(pos)``, or ``getPlantAtCoords(x,y,z)`` +* ``dfhack.maps.getPlantAtTile(pos)``, or ``getPlantAtTile(x,y,z)`` Returns the plant struct that owns the tile at the specified position. From 818ff7a946761a76806a54227576cf6995bc2faa Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Wed, 23 Jun 2021 22:59:39 -0700 Subject: [PATCH 07/10] Rename getPlantAtCoords to getPlantAtTile --- library/LuaApi.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/LuaApi.cpp b/library/LuaApi.cpp index e04b0f256..f6a49c2aa 100644 --- a/library/LuaApi.cpp +++ b/library/LuaApi.cpp @@ -1923,10 +1923,10 @@ static int maps_getTileBiomeRgn(lua_State *L) return Lua::PushPosXY(L, Maps::getTileBiomeRgn(pos)); } -static int maps_getPlantAtCoords(lua_State *L) +static int maps_getPlantAtTile(lua_State *L) { auto pos = CheckCoordXYZ(L, 1, true); - Lua::PushDFObject(L, Maps::getPlantAtCoords(pos)); + Lua::PushDFObject(L, Maps::getPlantAtTile(pos)); return 1; } @@ -1939,7 +1939,7 @@ static const luaL_Reg dfhack_maps_funcs[] = { { "getTileFlags", maps_getTileFlags }, { "getRegionBiome", maps_getRegionBiome }, { "getTileBiomeRgn", maps_getTileBiomeRgn }, - { "getPlantAtCoords", maps_getPlantAtCoords }, + { "getPlantAtTile", maps_getPlantAtTile }, { NULL, NULL } }; From c5fb28a13cb6b18fcc88573b4a4f663f375683a3 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Wed, 23 Jun 2021 23:00:30 -0700 Subject: [PATCH 08/10] Rename getPlantAtCoords to getPlantAtTile --- library/include/modules/Maps.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/include/modules/Maps.h b/library/include/modules/Maps.h index c3267dfbb..50aca8e9d 100644 --- a/library/include/modules/Maps.h +++ b/library/include/modules/Maps.h @@ -339,9 +339,9 @@ DFHACK_EXPORT bool canStepBetween(df::coord pos1, df::coord pos2); /** * Get the plant that owns the tile at the specified position */ -extern DFHACK_EXPORT df::plant *getPlantAtCoords(int32_t x, int32_t y, int32_t z); +extern DFHACK_EXPORT df::plant *getPlantAtTile(int32_t x, int32_t y, int32_t z); -inline df::plant *getPlantAtCoords(df::coord pos) { return getPlantAtCoords(pos.x, pos.y, pos.z); } +inline df::plant *getPlantAtTile(df::coord pos) { return getPlantAtTile(pos.x, pos.y, pos.z); } DFHACK_EXPORT df::enums::biome_type::biome_type GetBiomeType(int world_coord_x, int world_coord_y); DFHACK_EXPORT df::enums::biome_type::biome_type GetBiomeTypeWithRef(int world_coord_x, int world_coord_y, int world_ref_y_coord); From c5e7a54d9739395f041d899445b12a4ee1ae92db Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Wed, 23 Jun 2021 23:03:22 -0700 Subject: [PATCH 09/10] Rename to getPlantAtTile; remove extra variables --- library/modules/Maps.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/library/modules/Maps.cpp b/library/modules/Maps.cpp index 75ba35c51..b4289ddf6 100644 --- a/library/modules/Maps.cpp +++ b/library/modules/Maps.cpp @@ -718,7 +718,7 @@ bool Maps::canStepBetween(df::coord pos1, df::coord pos2) /* * Plants */ -df::plant *Maps::getPlantAtCoords(int32_t x, int32_t y, int32_t z) +df::plant *Maps::getPlantAtTile(int32_t x, int32_t y, int32_t z) { if (x < 0 || x >= world->map.x_count || y < 0 || y >= world->map.y_count || !world->map.column_index) return NULL; @@ -727,8 +727,6 @@ df::plant *Maps::getPlantAtCoords(int32_t x, int32_t y, int32_t z) if (!mbc) return NULL; - int32_t x_mod_48 = x % 48; - int32_t y_mod_48 = y % 48; for (size_t i = 0; i < mbc->plants.size(); i++) { df::plant *p = mbc->plants[i]; @@ -739,8 +737,8 @@ df::plant *Maps::getPlantAtCoords(int32_t x, int32_t y, int32_t z) if (!t) continue; - int32_t x_index = t->dim_x / 2 - p->pos.x % 48 + x_mod_48; - int32_t y_index = t->dim_y / 2 - p->pos.y % 48 + y_mod_48; + int32_t x_index = (t->dim_x / 2) - (p->pos.x % 48) + (x % 48); + int32_t y_index = (t->dim_y / 2) - (p->pos.y % 48) + (y % 48); int32_t z_dis = z - p->pos.z; if (x_index < 0 || x_index >= t->dim_x || y_index < 0 || y_index >= t->dim_y || z_dis >= t->body_height) continue; From 35d32645fcc289e7e7d12ae395587bb384ba060e Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Wed, 23 Jun 2021 23:12:53 -0700 Subject: [PATCH 10/10] Added getPlantAtTile to Lua API --- docs/changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/changelog.txt b/docs/changelog.txt index 2da577260..8327fbc83 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -61,6 +61,7 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: ## API - Added ``dfhack.units.teleport(unit, pos)`` +- Added ``dfhack.maps.getPlantAtTile(x, y, z)`` and ``dfhack.maps.getPlantAtTile(pos)`` ## Documentation - Added more client library implementations to the `remote interface docs `