Make Items::getPosition exactly match the DF original in behavior.

develop
Alexander Gavrilov 2012-05-17 19:56:55 +04:00
parent efdb709284
commit 2c0024adc9
3 changed files with 33 additions and 9 deletions

@ -693,7 +693,7 @@ Units module
* ``dfhack.units.getPosition(unit)`` * ``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)`` * ``dfhack.units.getContainer(unit)``
@ -752,7 +752,7 @@ Items module
* ``dfhack.items.getPosition(item)`` * ``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)`` * ``dfhack.items.getGeneralRef(item, type)``

@ -935,7 +935,7 @@ a lua list containing them.</p>
<h3><a class="toc-backref" href="#id16">Units module</a></h3> <h3><a class="toc-backref" href="#id16">Units module</a></h3>
<ul> <ul>
<li><p class="first"><tt class="docutils literal">dfhack.units.getPosition(unit)</tt></p> <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>
<li><p class="first"><tt class="docutils literal">dfhack.units.getContainer(unit)</tt></p> <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> <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> <h3><a class="toc-backref" href="#id17">Items module</a></h3>
<ul> <ul>
<li><p class="first"><tt class="docutils literal">dfhack.items.getPosition(item)</tt></p> <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>
<li><p class="first"><tt class="docutils literal">dfhack.items.getGeneralRef(item, type)</tt></p> <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> <p>Searches for a general_ref with the given type.</p>

@ -69,6 +69,7 @@ using namespace std;
#include "df/general_ref_unit_itemownerst.h" #include "df/general_ref_unit_itemownerst.h"
#include "df/general_ref_contains_itemst.h" #include "df/general_ref_contains_itemst.h"
#include "df/general_ref_contained_in_itemst.h" #include "df/general_ref_contained_in_itemst.h"
#include "df/vermin.h"
using namespace DFHack; using namespace DFHack;
using namespace df::enums; using namespace df::enums;
@ -512,9 +513,12 @@ df::coord Items::getPosition(df::item *item)
{ {
CHECK_NULL_POINTER(item); CHECK_NULL_POINTER(item);
if (item->flags.bits.in_inventory || /* Function reverse-engineered from DF code. */
item->flags.bits.in_chest ||
item->flags.bits.in_building) if (item->flags.bits.removed)
return df::coord();
if (item->flags.bits.in_inventory)
{ {
for (size_t i = 0; i < item->itemrefs.size(); i++) 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); return Units::getPosition(unit);
break; break;
case general_ref_type::BUILDING_HOLDER: /*case general_ref_type::BUILDING_HOLDER:
if (auto bld = ref->getBuilding()) if (auto bld = ref->getBuilding())
return df::coord(bld->centerx, bld->centery, bld->z); return df::coord(bld->centerx, bld->centery, bld->z);
break;*/
default:
break; 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: default:
break; break;
} }
} }
return df::coord();
} }
return item->pos; 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(item);
CHECK_NULL_POINTER(container); CHECK_NULL_POINTER(container);
auto cpos = getPosition(container);
if (!cpos.isValid())
return false;
if (!detachItem(mc, item)) if (!detachItem(mc, item))
return false; return false;
@ -635,7 +659,7 @@ bool DFHack::Items::moveToContainer(MapExtras::MapCache &mc, df::item *item, df:
{ {
delete ref1; delete ref2; delete ref1; delete ref2;
Core::printerr("Could not allocate container refs.\n"); Core::printerr("Could not allocate container refs.\n");
putOnGround(mc, item, getPosition(container)); putOnGround(mc, item, cpos);
return false; return false;
} }