diff options
| author | Alexander Gavrilov | 2012-05-06 11:22:55 +0400 |
|---|---|---|
| committer | Alexander Gavrilov | 2012-05-06 11:22:55 +0400 |
| commit | b70130cf3684d8adbf36023b27aec0f10b213cc7 (patch) | |
| tree | 945c51c426e963a868965b43441e3a99298f8e96 | |
| parent | 05e8083c8443ba604d0402b07824e4a05b86288c (diff) | |
| download | dfhack-b70130cf3684d8adbf36023b27aec0f10b213cc7.tar.gz dfhack-b70130cf3684d8adbf36023b27aec0f10b213cc7.tar.bz2 dfhack-b70130cf3684d8adbf36023b27aec0f10b213cc7.tar.xz | |
Add a couple more building api functions.
| -rw-r--r-- | LUA_API.rst | 16 | ||||
| -rw-r--r-- | Lua API.html | 14 | ||||
| -rw-r--r-- | library/LuaApi.cpp | 74 | ||||
| -rw-r--r-- | library/include/modules/Buildings.h | 13 | ||||
| -rw-r--r-- | library/modules/Buildings.cpp | 45 |
5 files changed, 140 insertions, 22 deletions
diff --git a/LUA_API.rst b/LUA_API.rst index 93866437..681caef5 100644 --- a/LUA_API.rst +++ b/LUA_API.rst @@ -873,10 +873,16 @@ Buildings module Returns *width, height, centerx, centery*. -* ``dfhack.buildings.findAtTile(pos)`` +* ``dfhack.buildings.findAtTile(pos)``, or ``findAtTile(x,y,z)`` Scans the buildings for the one located at the given tile. - Does not work on civzones. Warning: linear scan. + Does not work on civzones. Warning: linear scan if the map + tile indicates there are buildings at it. + +* ``dfhack.buildings.findCivzonesAt(pos)``, or ``findCivzonesAt(x,y,z)`` + + Scans civzones, and returns a lua sequence of those that touch + the given tile, or *nil* if none. * ``dfhack.buildings.getCorrectSize(width, height, type, subtype, custom, direction)`` @@ -894,6 +900,10 @@ Buildings module Returns the number of tiles included by extents, or defval. +* ``dfhack.buildings.containsTile(building, x, y[, room])`` + + Checks if the building contains the specified tile, either directly, or as room. + * ``dfhack.buildings.hasSupport(pos,size)`` Checks if a bridge constructed at specified position would have @@ -911,7 +921,7 @@ Low-level building creation functions; Configures an object returned by ``allocInstance``, using specified parameters wherever appropriate. If the building has fixed size along any dimension, the corresponding input parameter will be ignored. - Returns *nil* if the building cannot be placed, or *true, width, + Returns *false* if the building cannot be placed, or *true, width, height, rect_area, true_area*. Returned width and height are the final values used by the building; true_area is less than rect_area if any tiles were removed from designation. diff --git a/Lua API.html b/Lua API.html index b96d1215..094b522c 100644 --- a/Lua API.html +++ b/Lua API.html @@ -1081,9 +1081,14 @@ burrows, or the presence of invaders.</p> <li><p class="first"><tt class="docutils literal">dfhack.buildings.getSize(building)</tt></p> <p>Returns <em>width, height, centerx, centery</em>.</p> </li> -<li><p class="first"><tt class="docutils literal">dfhack.buildings.findAtTile(pos)</tt></p> +<li><p class="first"><tt class="docutils literal">dfhack.buildings.findAtTile(pos)</tt>, or <tt class="docutils literal">findAtTile(x,y,z)</tt></p> <p>Scans the buildings for the one located at the given tile. -Does not work on civzones. Warning: linear scan.</p> +Does not work on civzones. Warning: linear scan if the map +tile indicates there are buildings at it.</p> +</li> +<li><p class="first"><tt class="docutils literal">dfhack.buildings.findCivzonesAt(pos)</tt>, or <tt class="docutils literal">findCivzonesAt(x,y,z)</tt></p> +<p>Scans civzones, and returns a lua sequence of those that touch +the given tile, or <em>nil</em> if none.</p> </li> <li><p class="first"><tt class="docutils literal">dfhack.buildings.getCorrectSize(width, height, type, subtype, custom, direction)</tt></p> <p>Computes correct dimensions for the specified building type and orientation, @@ -1098,6 +1103,9 @@ are removed from extents. If <tt class="docutils literal">allow_occupied</tt>, t <li><p class="first"><tt class="docutils literal">dfhack.buildings.countExtentTiles(extents,defval)</tt></p> <p>Returns the number of tiles included by extents, or defval.</p> </li> +<li><p class="first"><tt class="docutils literal">dfhack.buildings.containsTile(building, x, y[, room])</tt></p> +<p>Checks if the building contains the specified tile, either directly, or as room.</p> +</li> <li><p class="first"><tt class="docutils literal">dfhack.buildings.hasSupport(pos,size)</tt></p> <p>Checks if a bridge constructed at specified position would have support from terrain, and thus won't collapse if retracted.</p> @@ -1113,7 +1121,7 @@ at specified position. Returns the object, or <em>nil</em> in case of an error.< <p>Configures an object returned by <tt class="docutils literal">allocInstance</tt>, using specified parameters wherever appropriate. If the building has fixed size along any dimension, the corresponding input parameter will be ignored. -Returns <em>nil</em> if the building cannot be placed, or <em>true, width, +Returns <em>false</em> if the building cannot be placed, or <em>true, width, height, rect_area, true_area</em>. Returned width and height are the final values used by the building; true_area is less than rect_area if any tiles were removed from designation.</p> diff --git a/library/LuaApi.cpp b/library/LuaApi.cpp index 6a8100a3..bf2ec936 100644 --- a/library/LuaApi.cpp +++ b/library/LuaApi.cpp @@ -74,6 +74,7 @@ distribution. #include "df/dfhack_material_category.h" #include "df/job_material_category.h" #include "df/burrow.h" +#include "df/building_civzonest.h" #include <lua.h> #include <lauxlib.h> @@ -109,6 +110,37 @@ int Lua::PushPosXYZ(lua_State *state, df::coord pos) } } +static df::coord2d CheckCoordXY(lua_State *state, int base, bool vararg = false) +{ + df::coord2d p; + if (vararg && lua_gettop(state) <= base) + Lua::CheckDFAssign(state, &p, base); + else + { + p = df::coord2d( + luaL_checkint(state, base), + luaL_checkint(state, base+1) + ); + } + return p; +} + +static df::coord CheckCoordXYZ(lua_State *state, int base, bool vararg = false) +{ + df::coord p; + if (vararg && lua_gettop(state) <= base) + Lua::CheckDFAssign(state, &p, base); + else + { + p = df::coord( + luaL_checkint(state, base), + luaL_checkint(state, base+1), + luaL_checkint(state, base+2) + ); + } + return p; +} + /************************************************** * Per-world persistent configuration storage API * **************************************************/ @@ -729,20 +761,8 @@ static const LuaWrapper::FunctionReg dfhack_maps_module[] = { static int maps_getTileBlock(lua_State *L) { - df::map_block *block; - if (lua_gettop(L) == 1) - { - df::coord pos; - Lua::CheckDFAssign(L, &pos, 1); - block = Maps::getTileBlock(pos); - } - else - { - block = Maps::getTileBlock( - luaL_checkint(L, 1), luaL_checkint(L, 2), luaL_checkint(L, 3) - ); - } - Lua::PushDFObject(L, block); + auto pos = CheckCoordXYZ(L, 1, true); + Lua::PushDFObject(L, Maps::getTileBlock(pos)); return 1; } @@ -791,17 +811,39 @@ static const luaL_Reg dfhack_burrows_funcs[] = { /***** Buildings module *****/ +static bool buildings_containsTile(df::building *bld, int x, int y, bool room) { + return Buildings::containsTile(bld, df::coord2d(x,y), room); +} + static const LuaWrapper::FunctionReg dfhack_buildings_module[] = { - WRAPM(Buildings, findAtTile), WRAPM(Buildings, allocInstance), WRAPM(Buildings, checkFreeTiles), WRAPM(Buildings, countExtentTiles), + WRAPN(containsTile, buildings_containsTile), WRAPM(Buildings, hasSupport), WRAPM(Buildings, constructWithItems), WRAPM(Buildings, constructWithFilters), { NULL, NULL } }; +static int buildings_findAtTile(lua_State *L) +{ + auto pos = CheckCoordXYZ(L, 1, true); + Lua::PushDFObject(L, Buildings::findAtTile(pos)); + return 1; +} + +static int buildings_findCivzonesAt(lua_State *L) +{ + auto pos = CheckCoordXYZ(L, 1, true); + std::vector<df::building_civzonest*> pvec; + if (Buildings::findCivzonesAt(&pvec, pos)) + Lua::PushVector(L, pvec); + else + lua_pushnil(L); + return 1; +} + static int buildings_getCorrectSize(lua_State *state) { df::coord2d size(luaL_optint(state, 1, 1), luaL_optint(state, 2, 1)); @@ -844,6 +886,8 @@ static int buildings_setSize(lua_State *state) } static const luaL_Reg dfhack_buildings_funcs[] = { + { "findAtTile", buildings_findAtTile }, + { "findCivzonesAt", buildings_findCivzonesAt }, { "getCorrectSize", buildings_getCorrectSize }, { "setSize", buildings_setSize }, { NULL, NULL } diff --git a/library/include/modules/Buildings.h b/library/include/modules/Buildings.h index 9e529b6c..9bb3ba00 100644 --- a/library/include/modules/Buildings.h +++ b/library/include/modules/Buildings.h @@ -39,6 +39,7 @@ namespace df struct job_item; struct item; struct building_extents; + struct building_civzonest; } namespace DFHack @@ -91,13 +92,18 @@ DFHACK_EXPORT bool Read (const uint32_t index, t_building & building); */ DFHACK_EXPORT bool ReadCustomWorkshopTypes(std::map <uint32_t, std::string> & btypes); -/* +/** * Find the building located at the specified tile. * Does not work on civzones. */ DFHACK_EXPORT df::building *findAtTile(df::coord pos); /** + * Find civzones located at the specified tile. + */ +DFHACK_EXPORT bool findCivzonesAt(std::vector<df::building_civzonest*> *pvec, df::coord pos); + +/** * Allocates a building object using this type and position. */ DFHACK_EXPORT df::building *allocInstance(df::coord pos, df::building_type type, int subtype = -1, int custom = -1); @@ -123,6 +129,11 @@ DFHACK_EXPORT bool checkFreeTiles(df::coord pos, df::coord2d size, DFHACK_EXPORT int countExtentTiles(df::building_extents *ext, int defval = -1); /** + * Checks if the building contains the specified tile. + */ +DFHACK_EXPORT bool containsTile(df::building *bld, df::coord2d tile, bool room = false); + +/** * Checks if the area has support from the terrain. */ DFHACK_EXPORT bool hasSupport(df::coord pos, df::coord2d size); diff --git a/library/modules/Buildings.cpp b/library/modules/Buildings.cpp index 0512e9f0..2c516267 100644 --- a/library/modules/Buildings.cpp +++ b/library/modules/Buildings.cpp @@ -58,6 +58,7 @@ using namespace DFHack; #include "df/building_trapst.h" #include "df/building_bridgest.h" #include "df/building_coffinst.h" +#include "df/building_civzonest.h" #include "df/building_furnacest.h" #include "df/building_workshopst.h" #include "df/building_screw_pumpst.h" @@ -153,6 +154,25 @@ df::building *Buildings::findAtTile(df::coord pos) return NULL; } +bool Buildings::findCivzonesAt(std::vector<df::building_civzonest*> *pvec, df::coord pos) +{ + pvec->clear(); + + auto &vec = world->buildings.other[buildings_other_id::ANY_ZONE]; + + for (size_t i = 0; i < vec.size(); i++) + { + auto bld = strict_virtual_cast<df::building_civzonest>(vec[i]); + + if (!bld || bld->z != pos.z || !containsTile(bld, pos)) + continue; + + pvec->push_back(bld); + } + + return !pvec->empty(); +} + df::building *Buildings::allocInstance(df::coord pos, df::building_type type, int subtype, int custom) { if (!building_next_id) @@ -464,6 +484,31 @@ int Buildings::countExtentTiles(df::building_extents *ext, int defval) return cnt; } +bool Buildings::containsTile(df::building *bld, df::coord2d tile, bool room) +{ + CHECK_NULL_POINTER(bld); + + if (room) + { + if (!bld->is_room || !bld->room.extents) + return false; + } + else + { + if (tile.x < bld->x1 || tile.x > bld->x2 || tile.y < bld->y1 || tile.y >= bld->y2) + return false; + } + + if (bld->room.extents && (room || bld->isExtentShaped())) + { + uint8_t *etile = getExtentTile(bld->room, tile); + if (!etile || !*etile) + return false; + } + + return true; +} + bool Buildings::hasSupport(df::coord pos, df::coord2d size) { for (int dx = -1; dx <= size.x; dx++) |
