From 82a0e52a3eeb55d62dd51cf92b5b1b26d0cc4c66 Mon Sep 17 00:00:00 2001
From: Alexander Gavrilov
Date: Thu, 26 Apr 2012 18:51:39 +0400
Subject: [PATCH] Add api to check the walkable cache, and update flow_forbid
in liquids.
---
LUA_API.rst | 10 +++++++++
Lua API.html | 9 ++++++++
library/LuaApi.cpp | 41 +++++++++++++++++++++-------------
library/include/LuaTools.h | 5 +++++
library/include/modules/Maps.h | 2 ++
library/modules/Maps.cpp | 14 ++++++++++++
plugins/liquids.cpp | 4 ++++
7 files changed, 70 insertions(+), 15 deletions(-)
diff --git a/LUA_API.rst b/LUA_API.rst
index 38b0e2025..d2afacd42 100644
--- a/LUA_API.rst
+++ b/LUA_API.rst
@@ -795,6 +795,16 @@ Maps module
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
--------------
diff --git a/Lua API.html b/Lua API.html
index 3e08b3bef..fd2004b8d 100644
--- a/Lua API.html
+++ b/Lua API.html
@@ -1015,6 +1015,15 @@ Returns false in case of error.
dfhack.maps.getLocalInitFeature(region_coord2d,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.
+
diff --git a/library/LuaApi.cpp b/library/LuaApi.cpp
index 507494669..8855a50da 100644
--- a/library/LuaApi.cpp
+++ b/library/LuaApi.cpp
@@ -80,6 +80,17 @@ distribution.
using namespace DFHack;
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)
{
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 WRAPN(name, function) { #name, df::wrap_function(function,true) }
+/***** Translation module *****/
+
static const LuaWrapper::FunctionReg dfhack_module[] = {
WRAPM(Translation, TranslateName),
{ NULL, NULL }
};
+/***** Gui module *****/
+
static const LuaWrapper::FunctionReg dfhack_gui_module[] = {
WRAPM(Gui, getSelectedWorkshopJob),
WRAPM(Gui, getSelectedJob),
@@ -573,6 +588,8 @@ static const LuaWrapper::FunctionReg dfhack_gui_module[] = {
{ NULL, NULL }
};
+/***** Job module *****/
+
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; }
@@ -609,6 +626,7 @@ static const luaL_Reg dfhack_job_funcs[] = {
{ NULL, NULL }
};
+/***** Units module *****/
static const LuaWrapper::FunctionReg dfhack_units_module[] = {
WRAPM(Units, getContainer),
@@ -635,21 +653,7 @@ static int units_getNoblePositions(lua_State *state)
std::vector np;
if (Units::getNoblePositions(&np, Lua::CheckDFObject(state,1)))
- {
- 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);
- }
- }
+ Lua::PushVector(state, np);
else
lua_pushnil(state);
@@ -662,6 +666,8 @@ static const luaL_Reg dfhack_units_funcs[] = {
{ NULL, NULL }
};
+/***** Items module *****/
+
static bool items_moveToGround(df::item *item, df::coord pos)
{
MapExtras::MapCache mc;
@@ -702,12 +708,15 @@ static const luaL_Reg dfhack_items_funcs[] = {
{ NULL, NULL }
};
+/***** Maps module *****/
+
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, canWalkBetween),
{ NULL, NULL }
};
@@ -715,6 +724,8 @@ static const luaL_Reg dfhack_maps_funcs[] = {
{ NULL, NULL }
};
+/***** Burrows module *****/
+
static bool burrows_isAssignedBlockTile(df::burrow *burrow, df::map_block *block, int x, int y)
{
return Burrows::isAssignedBlockTile(burrow, block, df::coord2d(x,y));
diff --git a/library/include/LuaTools.h b/library/include/LuaTools.h
index a41b58d1c..1ca79d331 100644
--- a/library/include/LuaTools.h
+++ b/library/include/LuaTools.h
@@ -36,6 +36,10 @@ distribution.
namespace DFHack {
class function_identity_base;
+
+ namespace Units {
+ struct NoblePosition;
+ }
}
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::coord2d &obj) { PushDFObject(state, &obj); }
+ void Push(lua_State *state, const Units::NoblePosition &pos);
template inline void Push(lua_State *state, T *ptr) {
PushDFObject(state, ptr);
}
diff --git a/library/include/modules/Maps.h b/library/include/modules/Maps.h
index b6077a85e..332954cda 100644
--- a/library/include/modules/Maps.h
+++ b/library/include/modules/Maps.h
@@ -255,6 +255,8 @@ 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 );
+
+DFHACK_EXPORT bool canWalkBetween(df::coord pos1, df::coord pos2);
}
}
#endif
diff --git a/library/modules/Maps.cpp b/library/modules/Maps.cpp
index e7d49deda..ddf5d5069 100644
--- a/library/modules/Maps.cpp
+++ b/library/modules/Maps.cpp
@@ -387,6 +387,20 @@ bool Maps::ReadGeology(vector > *layer_mats, vector
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(block1->walkable, pos1);
+ auto tile2 = MapExtras::index_tile(block2->walkable, pos2);
+
+ return tile1 && tile1 == tile2;
+}
+
#define COPY(a,b) memcpy(&a,&b,sizeof(a))
MapExtras::Block::Block(MapCache *parent, DFCoord _bcoord) : parent(parent)
diff --git a/plugins/liquids.cpp b/plugins/liquids.cpp
index 8ca66daf5..f644398f5 100644
--- a/plugins/liquids.cpp
+++ b/plugins/liquids.cpp
@@ -388,6 +388,7 @@ command_result df_liquids_execute(color_ostream &out)
mcache.setTemp2At(*iter,10015);
df::tile_designation des = mcache.designationAt(*iter);
des.bits.flow_size = 0;
+ des.bits.flow_forbid = false;
mcache.setDesignationAt(*iter, des);
iter ++;
}
@@ -494,6 +495,9 @@ command_result df_liquids_execute(color_ostream &out)
mcache.setTemp1At(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);
}
seen_blocks.insert(mcache.BlockAt(current / 16));