diff options
| -rw-r--r-- | LUA_API.rst | 4 | ||||
| -rw-r--r-- | Lua API.html | 4 | ||||
| -rw-r--r-- | library/modules/Items.cpp | 34 |
3 files changed, 33 insertions, 9 deletions
diff --git a/LUA_API.rst b/LUA_API.rst index bd2d33cb..9ecd2e55 100644 --- a/LUA_API.rst +++ b/LUA_API.rst @@ -693,7 +693,7 @@ Units module * ``dfhack.units.getPosition(unit)`` - Returns true *x,y,z* of the unit; may be not equal to unit.pos if caged. + Returns true *x,y,z* of the unit, or *nil* if invalid; may be not equal to unit.pos if caged. * ``dfhack.units.getContainer(unit)`` @@ -752,7 +752,7 @@ Items module * ``dfhack.items.getPosition(item)`` - Returns true *x,y,z* of the item; may be not equal to item.pos if in inventory. + Returns true *x,y,z* of the item, or *nil* if invalid; may be not equal to item.pos if in inventory. * ``dfhack.items.getGeneralRef(item, type)`` diff --git a/Lua API.html b/Lua API.html index d44d82ba..7ce777c4 100644 --- a/Lua API.html +++ b/Lua API.html @@ -935,7 +935,7 @@ a lua list containing them.</p> <h3><a class="toc-backref" href="#id16">Units module</a></h3> <ul> <li><p class="first"><tt class="docutils literal">dfhack.units.getPosition(unit)</tt></p> -<p>Returns true <em>x,y,z</em> of the unit; may be not equal to unit.pos if caged.</p> +<p>Returns true <em>x,y,z</em> of the unit, or <em>nil</em> if invalid; may be not equal to unit.pos if caged.</p> </li> <li><p class="first"><tt class="docutils literal">dfhack.units.getContainer(unit)</tt></p> <p>Returns the container (cage) item or <em>nil</em>.</p> @@ -982,7 +982,7 @@ or raws. The <tt class="docutils literal">ignore_noble</tt> boolean disables the <h3><a class="toc-backref" href="#id17">Items module</a></h3> <ul> <li><p class="first"><tt class="docutils literal">dfhack.items.getPosition(item)</tt></p> -<p>Returns true <em>x,y,z</em> of the item; may be not equal to item.pos if in inventory.</p> +<p>Returns true <em>x,y,z</em> of the item, or <em>nil</em> if invalid; may be not equal to item.pos if in inventory.</p> </li> <li><p class="first"><tt class="docutils literal">dfhack.items.getGeneralRef(item, type)</tt></p> <p>Searches for a general_ref with the given type.</p> diff --git a/library/modules/Items.cpp b/library/modules/Items.cpp index f1d495bf..335d7d8f 100644 --- a/library/modules/Items.cpp +++ b/library/modules/Items.cpp @@ -69,6 +69,7 @@ using namespace std; #include "df/general_ref_unit_itemownerst.h" #include "df/general_ref_contains_itemst.h" #include "df/general_ref_contained_in_itemst.h" +#include "df/vermin.h" using namespace DFHack; using namespace df::enums; @@ -512,9 +513,12 @@ df::coord Items::getPosition(df::item *item) { CHECK_NULL_POINTER(item); - if (item->flags.bits.in_inventory || - item->flags.bits.in_chest || - item->flags.bits.in_building) + /* Function reverse-engineered from DF code. */ + + if (item->flags.bits.removed) + return df::coord(); + + if (item->flags.bits.in_inventory) { for (size_t i = 0; i < item->itemrefs.size(); i++) { @@ -532,15 +536,31 @@ df::coord Items::getPosition(df::item *item) return Units::getPosition(unit); break; - case general_ref_type::BUILDING_HOLDER: + /*case general_ref_type::BUILDING_HOLDER: if (auto bld = ref->getBuilding()) return df::coord(bld->centerx, bld->centery, bld->z); + break;*/ + + default: break; + } + } + + for (size_t i = 0; i < item->specific_refs.size(); i++) + { + df::specific_ref *ref = item->specific_refs[i]; + + switch (ref->type) + { + case specific_ref_type::VERMIN_ESCAPED_PET: + return ref->vermin->pos; default: break; } } + + return df::coord(); } return item->pos; @@ -625,6 +645,10 @@ bool DFHack::Items::moveToContainer(MapExtras::MapCache &mc, df::item *item, df: CHECK_NULL_POINTER(item); CHECK_NULL_POINTER(container); + auto cpos = getPosition(container); + if (!cpos.isValid()) + return false; + if (!detachItem(mc, item)) return false; @@ -635,7 +659,7 @@ bool DFHack::Items::moveToContainer(MapExtras::MapCache &mc, df::item *item, df: { delete ref1; delete ref2; Core::printerr("Could not allocate container refs.\n"); - putOnGround(mc, item, getPosition(container)); + putOnGround(mc, item, cpos); return false; } |
