Add api for manipulating burrows to the core.

develop
Alexander Gavrilov 2012-04-11 19:42:05 +04:00
parent 61245711f7
commit 0c2b78b96b
13 changed files with 331 additions and 13 deletions

@ -687,6 +687,15 @@ Units module
The unit is capable of rational action, i.e. not dead, insane or zombie.
* ``dfhack.units.isInBurrow(unit,burrow)``
Checks if the unit is in the burrow.
* ``dfhack.units.setInBurrow(unit,burrow,enable)``
Adds or removes the unit from the burrow.
Maps module
-----------
@ -717,3 +726,27 @@ Maps module
* ``dfhack.maps.getLocalInitFeature(region_coord2d,index)``
Returns the local feature object with the given region coords and index.
* ``dfhack.maps.findBurrowByName(name)``
Returns the burrow pointer or *nil*.
* ``dfhack.maps.listBurrowBlocks(burrow)``
Returns a table of map block pointers.
* ``dfhack.maps.isBurrowTile(burrow,tile_coord)``
Checks if the tile is in burrow.
* ``dfhack.maps.setBurrowTile(burrow,tile_coord,enable)``
Adds or removes the tile from the burrow. Returns *false* if invalid coords.
* ``dfhack.maps.isBlockBurrowTile(burrow,block,x,y)``
Checks if the tile within the block is in burrow.
* ``dfhack.maps.setBlockBurrowTile(burrow,block,x,y,enable)``
Adds or removes the tile from the burrow. Returns *false* if invalid coords.

@ -917,6 +917,12 @@ a lua list containing them.</p>
<li><p class="first"><tt class="docutils literal">dfhack.units.isSane(unit)</tt></p>
<p>The unit is capable of rational action, i.e. not dead, insane or zombie.</p>
</li>
<li><p class="first"><tt class="docutils literal">dfhack.units.isInBurrow(unit,burrow)</tt></p>
<p>Checks if the unit is in the burrow.</p>
</li>
<li><p class="first"><tt class="docutils literal">dfhack.units.setInBurrow(unit,burrow,enable)</tt></p>
<p>Adds or removes the unit from the burrow.</p>
</li>
</ul>
</div>
<div class="section" id="maps-module">
@ -943,6 +949,24 @@ a lua list containing them.</p>
<li><p class="first"><tt class="docutils literal">dfhack.maps.getLocalInitFeature(region_coord2d,index)</tt></p>
<p>Returns the local feature object with the given region coords and index.</p>
</li>
<li><p class="first"><tt class="docutils literal">dfhack.maps.findBurrowByName(name)</tt></p>
<p>Returns the burrow pointer or <em>nil</em>.</p>
</li>
<li><p class="first"><tt class="docutils literal">dfhack.maps.listBurrowBlocks(burrow)</tt></p>
<p>Returns a table of map block pointers.</p>
</li>
<li><p class="first"><tt class="docutils literal">dfhack.maps.isBurrowTile(burrow,tile_coord)</tt></p>
<p>Checks if the tile is in burrow.</p>
</li>
<li><p class="first"><tt class="docutils literal">dfhack.maps.setBurrowTile(burrow,tile_coord,enable)</tt></p>
<p>Adds or removes the tile from the burrow. Returns <em>false</em> if invalid coords.</p>
</li>
<li><p class="first"><tt class="docutils literal">dfhack.maps.isBlockBurrowTile(burrow,block,x,y)</tt></p>
<p>Checks if the tile within the block is in burrow.</p>
</li>
<li><p class="first"><tt class="docutils literal">dfhack.maps.setBlockBurrowTile(burrow,block,x,y,enable)</tt></p>
<p>Adds or removes the tile from the burrow. Returns <em>false</em> if invalid coords.</p>
</li>
</ul>
</div>
</div>

@ -63,6 +63,7 @@ distribution.
#include "df/inorganic_raw.h"
#include "df/dfhack_material_category.h"
#include "df/job_material_category.h"
#include "df/burrow.h"
#include <lua.h>
#include <lauxlib.h>
@ -71,6 +72,18 @@ distribution.
using namespace DFHack;
using namespace DFHack::LuaWrapper;
template<class T>
void push_pointer_vector(lua_State *state, const std::vector<T*> &pvec)
{
lua_createtable(state,pvec.size(),0);
for (size_t i = 0; i < pvec.size(); i++)
{
Lua::PushDFObject(state, pvec[i]);
lua_rawseti(state, -2, i+1);
}
}
/**************************************************
* Per-world persistent configuration storage API *
**************************************************/
@ -571,14 +584,7 @@ static int job_listNewlyCreated(lua_State *state)
if (Job::listNewlyCreated(&pvec, &nxid))
{
lua_pushinteger(state, nxid);
lua_newtable(state);
for (size_t i = 0; i < pvec.size(); i++)
{
Lua::PushDFObject(state, pvec[i]);
lua_rawseti(state, -2, i+1);
}
push_pointer_vector(state, pvec);
return 2;
}
else
@ -598,18 +604,55 @@ static const LuaWrapper::FunctionReg dfhack_units_module[] = {
WRAPM(Units, isDead),
WRAPM(Units, isAlive),
WRAPM(Units, isSane),
WRAPM(Units, isInBurrow),
WRAPM(Units, setInBurrow),
{ NULL, NULL }
};
static bool maps_isBlockBurrowTile(df::burrow *burrow, df::map_block *block, int x, int y)
{
return Maps::isBlockBurrowTile(burrow, block, df::coord2d(x,y));
}
static bool maps_setBlockBurrowTile(df::burrow *burrow, df::map_block *block, int x, int y, bool enable)
{
return Maps::setBlockBurrowTile(burrow, block, df::coord2d(x,y), enable);
}
static const LuaWrapper::FunctionReg dfhack_maps_module[] = {
WRAPN(getBlock, (df::map_block* (*)(int32_t,int32_t,int32_t))Maps::getBlock),
WRAPN(getTileBlock, (df::map_block* (*)(df::coord))Maps::getTileBlock),
WRAPM(Maps, getRegionBiome),
WRAPM(Maps, getGlobalInitFeature),
WRAPM(Maps, getLocalInitFeature),
WRAPM(Maps, findBurrowByName),
WRAPN(isBlockBurrowTile, maps_isBlockBurrowTile),
WRAPN(setBlockBurrowTile, maps_setBlockBurrowTile),
WRAPM(Maps, isBurrowTile),
WRAPM(Maps, setBurrowTile),
{ NULL, NULL }
};
static int maps_listBurrowBlocks(lua_State *state)
{
luaL_checkany(state, 1);
auto ptr = Lua::GetDFObject<df::burrow>(state, 1);
if (!ptr)
luaL_argerror(state, 1, "invalid burrow type");
std::vector<df::map_block*> pvec;
Maps::listBurrowBlocks(&pvec, ptr);
push_pointer_vector(state, pvec);
return 1;
}
static const luaL_Reg dfhack_maps_funcs[] = {
{ "listBurrowBlocks", maps_listBurrowBlocks },
{ NULL, NULL }
};
/************************
* Main Open function *
************************/
@ -623,5 +666,5 @@ void OpenDFHackApi(lua_State *state)
OpenModule(state, "gui", dfhack_gui_module);
OpenModule(state, "job", dfhack_job_module, dfhack_job_funcs);
OpenModule(state, "units", dfhack_units_module);
OpenModule(state, "maps", dfhack_maps_module);
OpenModule(state, "maps", dfhack_maps_module, dfhack_maps_funcs);
}

@ -139,6 +139,14 @@ INSTANTIATE_WRAPPERS(3, (OSTREAM_ARG,A1,A2,A3), (out,vA1,vA2,vA3),
INSTANTIATE_RETURN_TYPE((A1,A2,A3,A4))
INSTANTIATE_WRAPPERS(4, (A1,A2,A3,A4), (vA1,vA2,vA3,vA4),
LOAD_ARG(A1); LOAD_ARG(A2); LOAD_ARG(A3); LOAD_ARG(A4);)
INSTANTIATE_WRAPPERS(4, (OSTREAM_ARG,A1,A2,A3,A4), (out,vA1,vA2,vA3,vA4),
LOAD_OSTREAM(out); LOAD_ARG(A1); LOAD_ARG(A2); LOAD_ARG(A3); LOAD_ARG(A4);)
#undef FW_TARGS
#define FW_TARGS class A1, class A2, class A3, class A4, class A5
INSTANTIATE_RETURN_TYPE((A1,A2,A3,A4,A5))
INSTANTIATE_WRAPPERS(5, (A1,A2,A3,A4,A5), (vA1,vA2,vA3,vA4,vA5),
LOAD_ARG(A1); LOAD_ARG(A2); LOAD_ARG(A3); LOAD_ARG(A4); LOAD_ARG(A5);)
#undef FW_TARGS
#undef FW_TARGSC

@ -207,6 +207,22 @@ unsigned insert_into_vector(std::vector<CT*> &vec, FT CT::*field, CT *obj, bool
return pos;
}
template<typename FT>
bool erase_from_vector(std::vector<FT> &vec, FT key)
{
int pos = binsearch_index(vec, key);
vector_erase_at(vec, pos);
return pos >= 0;
}
template<typename CT, typename FT>
bool erase_from_vector(std::vector<CT*> &vec, FT CT::*field, FT key)
{
int pos = binsearch_index(vec, field, key);
vector_erase_at(vec, pos);
return pos >= 0;
}
template <typename CT, typename KT>
CT *binsearch_in_vector(const std::vector<CT*> &vec, KT value)
{

@ -0,0 +1,19 @@
inline bool getassignment( const df::coord2d &xy )
{
return getassignment(xy.x,xy.y);
}
inline bool getassignment( int x, int y )
{
return (tile_bitmask[y] & (1 << x));
}
inline void setassignment( const df::coord2d &xy, bool bit )
{
return setassignment(xy.x,xy.y, bit);
}
inline void setassignment( int x, int y, bool bit )
{
if(bit)
tile_bitmask[y] |= (1 << x);
else
tile_bitmask[y] &= ~(1 << x);
}

@ -15,5 +15,5 @@ inline void setassignment( int x, int y, bool bit )
if(bit)
tile_bitmask[y] |= (1 << x);
else
tile_bitmask[y] &= 0xFFFF ^ (1 << x);
tile_bitmask[y] &= ~(1 << x);
}

@ -38,7 +38,7 @@ distribution.
#include "modules/Materials.h"
#include "df/world.h"
#include "df/feature_init.h"
#include "df/world_data.h"
#include "df/map_block.h"
#include "df/block_square_event.h"
#include "df/block_square_event_mineralst.h"
@ -49,13 +49,20 @@ distribution.
#include "df/tile_liquid.h"
#include "df/tile_dig_designation.h"
#include "df/tile_traffic.h"
#include "df/world_data.h"
#include "df/feature_init.h"
/**
* \defgroup grp_maps Maps module and its types
* @ingroup grp_modules
*/
namespace df
{
struct burrow;
struct world_data;
struct block_burrow;
}
namespace DFHack
{
/***************************************************************************
@ -249,6 +256,26 @@ extern DFHACK_EXPORT bool SortBlockEvents(df::map_block *block,
/// remove a block event from the block by address
extern DFHACK_EXPORT bool RemoveBlockEvent(uint32_t x, uint32_t y, uint32_t z, df::block_square_event * which );
/*
* BURROWS
*/
DFHACK_EXPORT df::burrow *findBurrowByName(std::string name);
void listBurrowBlocks(std::vector<df::map_block*> *pvec, df::burrow *burrow);
df::block_burrow *getBlockBurrowMask(df::burrow *burrow, df::map_block *block, bool create = false);
bool isBlockBurrowTile(df::burrow *burrow, df::map_block *block, df::coord2d tile);
bool setBlockBurrowTile(df::burrow *burrow, df::map_block *block, df::coord2d tile, bool enable);
inline bool isBurrowTile(df::burrow *burrow, df::coord tile) {
return isBlockBurrowTile(burrow, getTileBlock(tile), tile);
}
inline bool setBurrowTile(df::burrow *burrow, df::coord tile, bool enable) {
return setBlockBurrowTile(burrow, getTileBlock(tile), tile, enable);
}
}
}
#endif

@ -36,6 +36,7 @@ distribution.
namespace df
{
struct nemesis_record;
struct burrow;
}
/**
@ -206,6 +207,10 @@ DFHACK_EXPORT df::nemesis_record *getNemesis(df::unit *unit);
DFHACK_EXPORT bool isDead(df::unit *unit);
DFHACK_EXPORT bool isAlive(df::unit *unit);
DFHACK_EXPORT bool isSane(df::unit *unit);
DFHACK_EXPORT bool isInBurrow(df::unit *unit, df::burrow *burrow);
DFHACK_EXPORT void setInBurrow(df::unit *unit, df::burrow *burrow, bool enable);
}
}
#endif

@ -80,6 +80,12 @@ function printall(table)
end
end
function copyall(table)
local rv = {}
for k,v in pairs(table) do rv[k] = v end
return rv
end
function dfhack.persistent:__tostring()
return "<persistent "..self.entry_id..":"..self.key.."=\""
..self.value.."\":"..table.concat(self.ints,",")..">"

@ -47,6 +47,10 @@ using namespace std;
#include "df/world_geo_biome.h"
#include "df/world_geo_layer.h"
#include "df/feature_init.h"
#include "df/world_data.h"
#include "df/burrow.h"
#include "df/block_burrow.h"
#include "df/block_burrow_link.h"
using namespace DFHack;
using namespace df::enums;
@ -681,3 +685,97 @@ MapExtras::Block *MapExtras::MapCache::BlockAt(DFCoord blockcoord)
}
}
df::burrow *Maps::findBurrowByName(std::string name)
{
auto &vec = df::burrow::get_vector();
for (size_t i = 0; i < vec.size(); i++)
if (vec[i]->name == name)
return vec[i];
return NULL;
}
void Maps::listBurrowBlocks(std::vector<df::map_block*> *pvec, df::burrow *burrow)
{
CHECK_NULL_POINTER(burrow);
pvec->clear();
pvec->reserve(burrow->block_x.size());
df::coord base(world->map.region_x*3,world->map.region_y*3,world->map.region_z);
for (size_t i = 0; i < burrow->block_x.size(); i++)
{
df::coord pos(burrow->block_x[i], burrow->block_y[i], burrow->block_z[i]);
auto block = getBlock(pos - base);
if (block)
pvec->push_back(block);
}
}
df::block_burrow *Maps::getBlockBurrowMask(df::burrow *burrow, df::map_block *block, bool create)
{
CHECK_NULL_POINTER(burrow);
CHECK_NULL_POINTER(block);
int32_t id = burrow->id;
df::block_burrow_link *prev = &block->block_burrows;
df::block_burrow_link *link = prev->next;
for (; link; prev = link, link = link->next)
if (link->item->id == id)
return link->item;
if (create)
{
link = new df::block_burrow_link;
link->item = new df::block_burrow;
link->item->id = burrow->id;
memset(link->item->tile_bitmask,0,sizeof(link->item->tile_bitmask));
link->item->link = link;
link->next = NULL;
link->prev = prev;
prev->next = link;
df::coord base(world->map.region_x*3,world->map.region_y*3,world->map.region_z);
df::coord pos = base + block->map_pos/16;
burrow->block_x.push_back(pos.x);
burrow->block_y.push_back(pos.y);
burrow->block_z.push_back(pos.z);
return link->item;
}
return NULL;
}
bool Maps::isBlockBurrowTile(df::burrow *burrow, df::map_block *block, df::coord2d tile)
{
CHECK_NULL_POINTER(burrow);
if (!block) return false;
auto mask = getBlockBurrowMask(burrow, block);
return mask ? mask->getassignment(tile & 15) : false;
}
bool Maps::setBlockBurrowTile(df::burrow *burrow, df::map_block *block, df::coord2d tile, bool enable)
{
CHECK_NULL_POINTER(burrow);
if (!block) return false;
auto mask = getBlockBurrowMask(burrow, block, enable);
if (mask)
mask->setassignment(tile & 15, enable);
return true;
}

@ -44,6 +44,7 @@ using namespace std;
#include "modules/Translation.h"
#include "ModuleFactory.h"
#include "Core.h"
#include "MiscUtils.h"
#include "df/world.h"
#include "df/ui.h"
@ -54,6 +55,7 @@ using namespace std;
#include "df/historical_figure.h"
#include "df/historical_figure_info.h"
#include "df/assumed_identity.h"
#include "df/burrow.h"
using namespace DFHack;
using namespace df::enums;
@ -652,3 +654,40 @@ bool DFHack::Units::isSane(df::unit *unit)
return true;
}
bool DFHack::Units::isInBurrow(df::unit *unit, df::burrow *burrow)
{
CHECK_NULL_POINTER(unit);
CHECK_NULL_POINTER(burrow);
return binsearch_index(unit->burrows, burrow->id) >= 0;
}
void DFHack::Units::setInBurrow(df::unit *unit, df::burrow *burrow, bool enable)
{
using df::global::ui;
CHECK_NULL_POINTER(unit);
CHECK_NULL_POINTER(burrow);
if (enable)
{
insert_into_vector(unit->burrows, burrow->id);
insert_into_vector(burrow->units, unit->id);
}
else
{
erase_from_vector(unit->burrows, burrow->id);
erase_from_vector(burrow->units, unit->id);
}
// Sync ui if active
if (ui && ui->main.mode == ui_sidebar_mode::Burrows &&
ui->burrows.in_add_units_mode && ui->burrows.sel_id == burrow->id)
{
int idx = linear_index(ui->burrows.list_units, unit);
if (idx >= 0)
ui->burrows.sel_units[idx] = enable;
}
}

@ -1 +1 @@
Subproject commit baeee2ce115e0b3432e5b66b843e8883e5f03b34
Subproject commit 27fec9797d7d1215bd3f5530b44a55a9d394fe75