Update the item owner modification api and export it to lua.

develop
Alexander Gavrilov 2012-04-11 20:10:31 +04:00
parent 0c2b78b96b
commit 5d5502ae34
9 changed files with 93 additions and 81 deletions

@ -696,6 +696,19 @@ Units module
Adds or removes the unit from the burrow. Adds or removes the unit from the burrow.
Items module
------------
* ``dfhack.items.getOwner(item)``
Returns the owner unit or *nil*.
* ``dfhack.items.setOwner(item,unit)``
Replaces the owner of the item. If unit is *nil*, removes ownership.
Returns *false* in case of error.
Maps module Maps module
----------- -----------

@ -340,7 +340,8 @@ ul.auto-toc {
<li><a class="reference internal" href="#gui-module" id="id14">Gui module</a></li> <li><a class="reference internal" href="#gui-module" id="id14">Gui module</a></li>
<li><a class="reference internal" href="#job-module" id="id15">Job module</a></li> <li><a class="reference internal" href="#job-module" id="id15">Job module</a></li>
<li><a class="reference internal" href="#units-module" id="id16">Units module</a></li> <li><a class="reference internal" href="#units-module" id="id16">Units module</a></li>
<li><a class="reference internal" href="#maps-module" id="id17">Maps module</a></li> <li><a class="reference internal" href="#items-module" id="id17">Items module</a></li>
<li><a class="reference internal" href="#maps-module" id="id18">Maps module</a></li>
</ul> </ul>
</li> </li>
</ul> </ul>
@ -925,8 +926,20 @@ a lua list containing them.</p>
</li> </li>
</ul> </ul>
</div> </div>
<div class="section" id="items-module">
<h3><a class="toc-backref" href="#id17">Items module</a></h3>
<ul>
<li><p class="first"><tt class="docutils literal">dfhack.items.getOwner(item)</tt></p>
<p>Returns the owner unit or <em>nil</em>.</p>
</li>
<li><p class="first"><tt class="docutils literal">dfhack.items.setOwner(item,unit)</tt></p>
<p>Replaces the owner of the item. If unit is <em>nil</em>, removes ownership.
Returns <em>false</em> in case of error.</p>
</li>
</ul>
</div>
<div class="section" id="maps-module"> <div class="section" id="maps-module">
<h3><a class="toc-backref" href="#id17">Maps module</a></h3> <h3><a class="toc-backref" href="#id18">Maps module</a></h3>
<ul> <ul>
<li><p class="first"><tt class="docutils literal">dfhack.maps.getSize()</tt></p> <li><p class="first"><tt class="docutils literal">dfhack.maps.getSize()</tt></p>
<p>Returns map size in blocks: <em>x, y, z</em></p> <p>Returns map size in blocks: <em>x, y, z</em></p>

@ -42,6 +42,7 @@ distribution.
#include "modules/Job.h" #include "modules/Job.h"
#include "modules/Translation.h" #include "modules/Translation.h"
#include "modules/Units.h" #include "modules/Units.h"
#include "modules/Items.h"
#include "modules/Materials.h" #include "modules/Materials.h"
#include "modules/Maps.h" #include "modules/Maps.h"
@ -609,6 +610,12 @@ static const LuaWrapper::FunctionReg dfhack_units_module[] = {
{ NULL, NULL } { NULL, NULL }
}; };
static const LuaWrapper::FunctionReg dfhack_items_module[] = {
WRAPM(Items, getOwner),
WRAPM(Items, setOwner),
{ NULL, NULL }
};
static bool maps_isBlockBurrowTile(df::burrow *burrow, df::map_block *block, int x, int y) static bool maps_isBlockBurrowTile(df::burrow *burrow, df::map_block *block, int x, int y)
{ {
return Maps::isBlockBurrowTile(burrow, block, df::coord2d(x,y)); return Maps::isBlockBurrowTile(burrow, block, df::coord2d(x,y));
@ -666,5 +673,6 @@ void OpenDFHackApi(lua_State *state)
OpenModule(state, "gui", dfhack_gui_module); OpenModule(state, "gui", dfhack_gui_module);
OpenModule(state, "job", dfhack_job_module, dfhack_job_funcs); OpenModule(state, "job", dfhack_job_module, dfhack_job_funcs);
OpenModule(state, "units", dfhack_units_module); OpenModule(state, "units", dfhack_units_module);
OpenModule(state, "items", dfhack_items_module);
OpenModule(state, "maps", dfhack_maps_module, dfhack_maps_funcs); OpenModule(state, "maps", dfhack_maps_module, dfhack_maps_funcs);
} }

@ -425,6 +425,9 @@ namespace df
static compound_identity *get() { return &T::_identity; } static compound_identity *get() { return &T::_identity; }
}; };
template<class T>
inline T* allocate() { return (T*)identity_traits<T>::get()->allocate(); }
template<class T> template<class T>
struct enum_traits {}; struct enum_traits {};

@ -122,16 +122,17 @@ DFHACK_EXPORT bool copyItem(df::item * source, dfh_item & target);
/// write copied item back to its origin /// write copied item back to its origin
DFHACK_EXPORT bool writeItem(const dfh_item & item); DFHACK_EXPORT bool writeItem(const dfh_item & item);
/// who owns this item we already read? /// Retrieve the owner of the item.
DFHACK_EXPORT int32_t getItemOwnerID(const df::item * item); DFHACK_EXPORT df::unit *getOwner(df::item *item);
DFHACK_EXPORT df::unit *getItemOwner(const df::item * item); /// Set the owner of the item. Pass NULL as unit to remove the owner.
DFHACK_EXPORT bool setOwner(df::item *item, df::unit *unit);
/// which item is it contained in? /// which item is it contained in?
DFHACK_EXPORT int32_t getItemContainerID(const df::item * item); DFHACK_EXPORT int32_t getItemContainerID(const df::item * item);
DFHACK_EXPORT df::item *getItemContainer(const df::item * item); DFHACK_EXPORT df::item *getItemContainer(const df::item * item);
/// which items does it contain? /// which items does it contain?
DFHACK_EXPORT bool getContainedItems(const df::item * item, /*output*/ std::vector<int32_t> &items); DFHACK_EXPORT bool getContainedItems(const df::item * item, /*output*/ std::vector<int32_t> &items);
/// wipe out the owner records
DFHACK_EXPORT bool removeItemOwner(df::item * item);
/// read item references, filtered by class /// read item references, filtered by class
DFHACK_EXPORT bool readItemRefs(const df::item * item, const df::general_ref_type type, DFHACK_EXPORT bool readItemRefs(const df::item * item, const df::general_ref_type type,
/*output*/ std::vector<int32_t> &values); /*output*/ std::vector<int32_t> &values);

@ -185,9 +185,6 @@ DFHACK_EXPORT bool ReadJob(const df::unit * unit, std::vector<t_material> & mat)
DFHACK_EXPORT bool ReadInventoryByIdx(const uint32_t index, std::vector<df::item *> & item); DFHACK_EXPORT bool ReadInventoryByIdx(const uint32_t index, std::vector<df::item *> & item);
DFHACK_EXPORT bool ReadInventoryByPtr(const df::unit * unit, std::vector<df::item *> & item); DFHACK_EXPORT bool ReadInventoryByPtr(const df::unit * unit, std::vector<df::item *> & item);
DFHACK_EXPORT bool ReadOwnedItemsByIdx(const uint32_t index, std::vector<int32_t> & item);
DFHACK_EXPORT bool ReadOwnedItemsByPtr(const df::unit * unit, std::vector<int32_t> & item);
DFHACK_EXPORT int32_t FindIndexById(int32_t id); DFHACK_EXPORT int32_t FindIndexById(int32_t id);
/* Getters */ /* Getters */
@ -196,9 +193,6 @@ DFHACK_EXPORT int32_t GetDwarfCivId ( void );
DFHACK_EXPORT void CopyNameTo(df::unit *creature, df::language_name * target); DFHACK_EXPORT void CopyNameTo(df::unit *creature, df::language_name * target);
DFHACK_EXPORT bool RemoveOwnedItemByIdx(const uint32_t index, int32_t id);
DFHACK_EXPORT bool RemoveOwnedItemByPtr(df::unit * unit, int32_t id);
DFHACK_EXPORT void setNickname(df::unit *unit, std::string nick); DFHACK_EXPORT void setNickname(df::unit *unit, std::string nick);
DFHACK_EXPORT df::language_name *getVisibleName(df::unit *unit); DFHACK_EXPORT df::language_name *getVisibleName(df::unit *unit);

@ -41,6 +41,7 @@ using namespace std;
#include "modules/Units.h" #include "modules/Units.h"
#include "ModuleFactory.h" #include "ModuleFactory.h"
#include "Core.h" #include "Core.h"
#include "Error.h"
#include "MiscUtils.h" #include "MiscUtils.h"
#include "df/world.h" #include "df/world.h"
@ -63,6 +64,7 @@ using namespace std;
#include "df/trapcomp_flags.h" #include "df/trapcomp_flags.h"
#include "df/job_item.h" #include "df/job_item.h"
#include "df/general_ref.h" #include "df/general_ref.h"
#include "df/general_ref_unit_itemownerst.h"
using namespace DFHack; using namespace DFHack;
using namespace df::enums; using namespace df::enums;
@ -415,28 +417,62 @@ bool Items::copyItem(df::item * itembase, DFHack::dfh_item &item)
return true; return true;
} }
int32_t Items::getItemOwnerID(const df::item * item) df::unit *Items::getOwner(df::item * item)
{ {
CHECK_NULL_POINTER(item);
for (size_t i = 0; i < item->itemrefs.size(); i++) for (size_t i = 0; i < item->itemrefs.size(); i++)
{ {
df::general_ref *ref = item->itemrefs[i]; df::general_ref *ref = item->itemrefs[i];
if (ref->getType() == general_ref_type::UNIT_ITEMOWNER) if (strict_virtual_cast<df::general_ref_unit_itemownerst>(ref))
return ref->getID(); return ref->getUnit();
} }
return -1;
return NULL;
} }
df::unit *Items::getItemOwner(const df::item * item) bool Items::setOwner(df::item *item, df::unit *unit)
{ {
for (size_t i = 0; i < item->itemrefs.size(); i++) CHECK_NULL_POINTER(item);
for (int i = item->itemrefs.size()-1; i >= 0; i--)
{ {
df::general_ref *ref = item->itemrefs[i]; df::general_ref *ref = item->itemrefs[i];
if (ref->getType() == general_ref_type::UNIT_ITEMOWNER)
return ref->getUnit(); if (!strict_virtual_cast<df::general_ref_unit_itemownerst>(ref))
continue;
if (auto cur = ref->getUnit())
{
if (cur == unit)
return true;
erase_from_vector(cur->owned_items, item->id);
} }
return NULL;
delete ref;
vector_erase_at(item->itemrefs, i);
}
if (unit)
{
auto ref = df::allocate<df::general_ref_unit_itemownerst>();
if (!ref)
return false;
item->flags.bits.owned = true;
ref->unit_id = unit->id;
insert_into_vector(unit->owned_items, item->id);
item->itemrefs.push_back(ref);
}
else
item->flags.bits.owned = false;
return true;
} }
int32_t Items::getItemContainerID(const df::item * item) int32_t Items::getItemContainerID(const df::item * item)
{ {
for (size_t i = 0; i < item->itemrefs.size(); i++) for (size_t i = 0; i < item->itemrefs.size(); i++)
@ -477,27 +513,3 @@ bool Items::readItemRefs(const df::item * item, df::general_ref_type type, std::
return !values.empty(); return !values.empty();
} }
bool Items::removeItemOwner(df::item * item)
{
for (size_t i = 0; i < item->itemrefs.size(); i++)
{
df::general_ref *ref = item->itemrefs[i];
if (ref->getType() != general_ref_type::UNIT_ITEMOWNER)
continue;
df::unit *unit = ref->getUnit();
if (unit == NULL || !Units::RemoveOwnedItemByPtr(unit, item->id))
{
cerr << "RemoveOwnedItemIdx: CREATURE " << ref->getID() << " ID " << item->id << " FAILED!" << endl;
return false;
}
delete ref;
item->itemrefs.erase(item->itemrefs.begin() + i--);
}
item->flags.bits.owned = 0;
return true;
}

@ -495,37 +495,6 @@ bool Units::ReadInventoryByPtr(const df::unit * unit, std::vector<df::item *> &
return true; return true;
} }
bool Units::ReadOwnedItemsByIdx(const uint32_t index, std::vector<int32_t> & item)
{
if(index >= world->units.all.size()) return false;
df::unit * temp = world->units.all[index];
return ReadOwnedItemsByPtr(temp, item);
}
bool Units::ReadOwnedItemsByPtr(const df::unit * unit, std::vector<int32_t> & items)
{
if(!isValid()) return false;
if(!unit) return false;
items = unit->owned_items;
return true;
}
bool Units::RemoveOwnedItemByIdx(const uint32_t index, int32_t id)
{
if(index >= world->units.all.size()) return false;
df::unit * temp = world->units.all[index];
return RemoveOwnedItemByPtr(temp, id);
}
bool Units::RemoveOwnedItemByPtr(df::unit * unit, int32_t id)
{
if(!isValid()) return false;
if(!unit) return false;
vector <int32_t> & vec = unit->owned_items;
vec.erase(std::remove(vec.begin(), vec.end(), id), vec.end());
return true;
}
void Units::CopyNameTo(df::unit * creature, df::language_name * target) void Units::CopyNameTo(df::unit * creature, df::language_name * target)
{ {
Translation::copyName(&creature->name, target); Translation::copyName(&creature->name, target);

@ -98,8 +98,7 @@ command_result df_cleanowned (color_ostream &out, vector <string> & parameters)
if (!item->flags.bits.owned) if (!item->flags.bits.owned)
{ {
int32_t owner = Items::getItemOwnerID(item); if (Items::getOwner(item))
if (owner >= 0)
{ {
out.print("Fixing a misflagged item: \t"); out.print("Fixing a misflagged item: \t");
confiscate = true; confiscate = true;
@ -168,14 +167,14 @@ command_result df_cleanowned (color_ostream &out, vector <string> & parameters)
item->getWear() item->getWear()
); );
df::unit *owner = Items::getItemOwner(item); df::unit *owner = Items::getOwner(item);
if (owner) if (owner)
out.print(", owner %s", Translation::TranslateName(&owner->name,false).c_str()); out.print(", owner %s", Translation::TranslateName(&owner->name,false).c_str());
if (!dry_run) if (!dry_run)
{ {
if (!Items::removeItemOwner(item)) if (!Items::setOwner(item,NULL))
out.print("(unsuccessfully) "); out.print("(unsuccessfully) ");
if (dump) if (dump)
item->flags.bits.dump = 1; item->flags.bits.dump = 1;