Add api to check the walkable cache, and update flow_forbid in liquids.

develop
Alexander Gavrilov 2012-04-26 18:51:39 +04:00
parent 16ee049664
commit 82a0e52a3e
7 changed files with 70 additions and 15 deletions

@ -795,6 +795,16 @@ Maps module
Returns the local feature object with the given region coords and index. Returns the local feature object with the given region coords and index.
* ``dfhack.maps.canWalkBetween(pos1, pos2)``
Checks if a dwarf may be able to walk between the two tiles,
using a pathfinding cache maintained by the game. Note that
this cache is only updated when the game is unpaused, and thus
can get out of date if doors are forbidden or unforbidden, or
tools like liquids or tiletypes are used. It also cannot possibly
take into account anything that depends on the actual units, like
burrows, or the presence of invaders.
Burrows module Burrows module
-------------- --------------

@ -1015,6 +1015,15 @@ Returns <em>false</em> in case of error.</p>
<li><p class="first"><tt class="docutils literal">dfhack.maps.getLocalInitFeature(region_coord2d,index)</tt></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> <p>Returns the local feature object with the given region coords and index.</p>
</li> </li>
<li><p class="first"><tt class="docutils literal">dfhack.maps.canWalkBetween(pos1, pos2)</tt></p>
<p>Checks if a dwarf may be able to walk between the two tiles,
using a pathfinding cache maintained by the game. Note that
this cache is only updated when the game is unpaused, and thus
can get out of date if doors are forbidden or unforbidden, or
tools like liquids or tiletypes are used. It also cannot possibly
take into account anything that depends on the actual units, like
burrows, or the presence of invaders.</p>
</li>
</ul> </ul>
</div> </div>
<div class="section" id="burrows-module"> <div class="section" id="burrows-module">

@ -80,6 +80,17 @@ distribution.
using namespace DFHack; using namespace DFHack;
using namespace DFHack::LuaWrapper; using namespace DFHack::LuaWrapper;
void Lua::Push(lua_State *state, const Units::NoblePosition &pos)
{
lua_createtable(state, 0, 3);
Lua::PushDFObject(state, pos.entity);
lua_setfield(state, -2, "entity");
Lua::PushDFObject(state, pos.assignment);
lua_setfield(state, -2, "assignment");
Lua::PushDFObject(state, pos.position);
lua_setfield(state, -2, "position");
}
int Lua::PushPosXYZ(lua_State *state, df::coord pos) int Lua::PushPosXYZ(lua_State *state, df::coord pos)
{ {
if (!pos.isValid()) if (!pos.isValid())
@ -558,11 +569,15 @@ static void OpenModule(lua_State *state, const char *mname,
#define WRAP(function) { #function, df::wrap_function(function,true) } #define WRAP(function) { #function, df::wrap_function(function,true) }
#define WRAPN(name, function) { #name, df::wrap_function(function,true) } #define WRAPN(name, function) { #name, df::wrap_function(function,true) }
/***** Translation module *****/
static const LuaWrapper::FunctionReg dfhack_module[] = { static const LuaWrapper::FunctionReg dfhack_module[] = {
WRAPM(Translation, TranslateName), WRAPM(Translation, TranslateName),
{ NULL, NULL } { NULL, NULL }
}; };
/***** Gui module *****/
static const LuaWrapper::FunctionReg dfhack_gui_module[] = { static const LuaWrapper::FunctionReg dfhack_gui_module[] = {
WRAPM(Gui, getSelectedWorkshopJob), WRAPM(Gui, getSelectedWorkshopJob),
WRAPM(Gui, getSelectedJob), WRAPM(Gui, getSelectedJob),
@ -573,6 +588,8 @@ static const LuaWrapper::FunctionReg dfhack_gui_module[] = {
{ NULL, NULL } { NULL, NULL }
}; };
/***** Job module *****/
static bool jobEqual(df::job *job1, df::job *job2) { return *job1 == *job2; } static bool jobEqual(df::job *job1, df::job *job2) { return *job1 == *job2; }
static bool jobItemEqual(df::job_item *job1, df::job_item *job2) { return *job1 == *job2; } static bool jobItemEqual(df::job_item *job1, df::job_item *job2) { return *job1 == *job2; }
@ -609,6 +626,7 @@ static const luaL_Reg dfhack_job_funcs[] = {
{ NULL, NULL } { NULL, NULL }
}; };
/***** Units module *****/
static const LuaWrapper::FunctionReg dfhack_units_module[] = { static const LuaWrapper::FunctionReg dfhack_units_module[] = {
WRAPM(Units, getContainer), WRAPM(Units, getContainer),
@ -635,21 +653,7 @@ static int units_getNoblePositions(lua_State *state)
std::vector<Units::NoblePosition> np; std::vector<Units::NoblePosition> np;
if (Units::getNoblePositions(&np, Lua::CheckDFObject<df::unit>(state,1))) if (Units::getNoblePositions(&np, Lua::CheckDFObject<df::unit>(state,1)))
{ Lua::PushVector(state, np);
lua_createtable(state, np.size(), 0);
for (size_t i = 0; i < np.size(); i++)
{
lua_createtable(state, 0, 3);
Lua::PushDFObject(state, np[i].entity);
lua_setfield(state, -2, "entity");
Lua::PushDFObject(state, np[i].assignment);
lua_setfield(state, -2, "assignment");
Lua::PushDFObject(state, np[i].position);
lua_setfield(state, -2, "position");
lua_rawseti(state, -2, i+1);
}
}
else else
lua_pushnil(state); lua_pushnil(state);
@ -662,6 +666,8 @@ static const luaL_Reg dfhack_units_funcs[] = {
{ NULL, NULL } { NULL, NULL }
}; };
/***** Items module *****/
static bool items_moveToGround(df::item *item, df::coord pos) static bool items_moveToGround(df::item *item, df::coord pos)
{ {
MapExtras::MapCache mc; MapExtras::MapCache mc;
@ -702,12 +708,15 @@ static const luaL_Reg dfhack_items_funcs[] = {
{ NULL, NULL } { NULL, NULL }
}; };
/***** Maps module *****/
static const LuaWrapper::FunctionReg dfhack_maps_module[] = { static const LuaWrapper::FunctionReg dfhack_maps_module[] = {
WRAPN(getBlock, (df::map_block* (*)(int32_t,int32_t,int32_t))Maps::getBlock), WRAPN(getBlock, (df::map_block* (*)(int32_t,int32_t,int32_t))Maps::getBlock),
WRAPN(getTileBlock, (df::map_block* (*)(df::coord))Maps::getTileBlock), WRAPN(getTileBlock, (df::map_block* (*)(df::coord))Maps::getTileBlock),
WRAPM(Maps, getRegionBiome), WRAPM(Maps, getRegionBiome),
WRAPM(Maps, getGlobalInitFeature), WRAPM(Maps, getGlobalInitFeature),
WRAPM(Maps, getLocalInitFeature), WRAPM(Maps, getLocalInitFeature),
WRAPM(Maps, canWalkBetween),
{ NULL, NULL } { NULL, NULL }
}; };
@ -715,6 +724,8 @@ static const luaL_Reg dfhack_maps_funcs[] = {
{ NULL, NULL } { NULL, NULL }
}; };
/***** Burrows module *****/
static bool burrows_isAssignedBlockTile(df::burrow *burrow, df::map_block *block, int x, int y) static bool burrows_isAssignedBlockTile(df::burrow *burrow, df::map_block *block, int x, int y)
{ {
return Burrows::isAssignedBlockTile(burrow, block, df::coord2d(x,y)); return Burrows::isAssignedBlockTile(burrow, block, df::coord2d(x,y));

@ -36,6 +36,10 @@ distribution.
namespace DFHack { namespace DFHack {
class function_identity_base; class function_identity_base;
namespace Units {
struct NoblePosition;
}
} }
namespace DFHack {namespace Lua { namespace DFHack {namespace Lua {
@ -243,6 +247,7 @@ namespace DFHack {namespace Lua {
} }
inline void Push(lua_State *state, df::coord &obj) { PushDFObject(state, &obj); } inline void Push(lua_State *state, df::coord &obj) { PushDFObject(state, &obj); }
inline void Push(lua_State *state, df::coord2d &obj) { PushDFObject(state, &obj); } inline void Push(lua_State *state, df::coord2d &obj) { PushDFObject(state, &obj); }
void Push(lua_State *state, const Units::NoblePosition &pos);
template<class T> inline void Push(lua_State *state, T *ptr) { template<class T> inline void Push(lua_State *state, T *ptr) {
PushDFObject(state, ptr); PushDFObject(state, ptr);
} }

@ -255,6 +255,8 @@ extern DFHACK_EXPORT bool SortBlockEvents(df::map_block *block,
/// remove a block event from the block by address /// 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 ); extern DFHACK_EXPORT bool RemoveBlockEvent(uint32_t x, uint32_t y, uint32_t z, df::block_square_event * which );
DFHACK_EXPORT bool canWalkBetween(df::coord pos1, df::coord pos2);
} }
} }
#endif #endif

@ -387,6 +387,20 @@ bool Maps::ReadGeology(vector<vector<int16_t> > *layer_mats, vector<df::coord2d>
return true; return true;
} }
bool Maps::canWalkBetween(df::coord pos1, df::coord pos2)
{
auto block1 = getTileBlock(pos1);
auto block2 = getTileBlock(pos2);
if (!block1 || !block2)
return false;
auto tile1 = MapExtras::index_tile<uint16_t>(block1->walkable, pos1);
auto tile2 = MapExtras::index_tile<uint16_t>(block2->walkable, pos2);
return tile1 && tile1 == tile2;
}
#define COPY(a,b) memcpy(&a,&b,sizeof(a)) #define COPY(a,b) memcpy(&a,&b,sizeof(a))
MapExtras::Block::Block(MapCache *parent, DFCoord _bcoord) : parent(parent) MapExtras::Block::Block(MapCache *parent, DFCoord _bcoord) : parent(parent)

@ -388,6 +388,7 @@ command_result df_liquids_execute(color_ostream &out)
mcache.setTemp2At(*iter,10015); mcache.setTemp2At(*iter,10015);
df::tile_designation des = mcache.designationAt(*iter); df::tile_designation des = mcache.designationAt(*iter);
des.bits.flow_size = 0; des.bits.flow_size = 0;
des.bits.flow_forbid = false;
mcache.setDesignationAt(*iter, des); mcache.setDesignationAt(*iter, des);
iter ++; iter ++;
} }
@ -494,6 +495,9 @@ command_result df_liquids_execute(color_ostream &out)
mcache.setTemp1At(current,10015); mcache.setTemp1At(current,10015);
mcache.setTemp2At(current,10015); mcache.setTemp2At(current,10015);
} }
// mark the tile passable or impassable like the game does
des.bits.flow_forbid = des.bits.flow_size &&
(des.bits.liquid_type == tile_liquid::Magma || des.bits.flow_size > 3);
mcache.setDesignationAt(current,des); mcache.setDesignationAt(current,des);
} }
seen_blocks.insert(mcache.BlockAt(current / 16)); seen_blocks.insert(mcache.BlockAt(current / 16));