From 109d20d2517d69e3a25ff8a49e033a5565de1fb4 Mon Sep 17 00:00:00 2001 From: Alexander Gavrilov Date: Sun, 10 Apr 2011 23:25:41 +0400 Subject: [PATCH] Add an experimental program for cleaning up garbage owned by dwarfs. As noted by Quietust on the forum, cleaning the owned flag from the items does not actually remove the owner, but the item ceases to be protected from manipulation by other dwarfs. This should be enough to work around various bugs, like untouchable rotten food producing miasma, or dwarfs littering the place with worn objects. --- tools/playground/CMakeLists.txt | 2 + tools/playground/cleanowned.cpp | 132 ++++++++++++++++++++++++++++++++ 2 files changed, 134 insertions(+) create mode 100644 tools/playground/cleanowned.cpp diff --git a/tools/playground/CMakeLists.txt b/tools/playground/CMakeLists.txt index b44cb9c9b..7bc5ad1e9 100644 --- a/tools/playground/CMakeLists.txt +++ b/tools/playground/CMakeLists.txt @@ -80,6 +80,8 @@ DFHACK_TOOL(dfprinttiletypes printtiletypes.cpp) # Will have many options in the future. DFHACK_TOOL(dfhellhole hellhole.cpp) +DFHACK_TOOL(dfcleanowned cleanowned.cpp) + # this needs the C bindings IF(BUILD_DFHACK_C_BINDINGS) # for trying out some 'stuff' diff --git a/tools/playground/cleanowned.cpp b/tools/playground/cleanowned.cpp new file mode 100644 index 000000000..ddd54de69 --- /dev/null +++ b/tools/playground/cleanowned.cpp @@ -0,0 +1,132 @@ +/* + * Confiscates and dumps garbage owned by dwarfs. + */ + +#include +#include +#include +#include +#include +#include +using namespace std; + +#include +#include +#include + +DFHack::Materials * Materials; +DFHack::Items * Items; + +int main (int argc, char *argv[]) +{ + bool dump_scattered = false; + int wear_dump_level = 65536; + + for(int i = 1; i < argc; i++) + { + char *arg = argv[i]; + if (arg[0] != '-') + continue; + + for (; *arg; arg++) { + switch (arg[0]) { + case 'j': + dump_scattered = true; + break; + case 'x': + wear_dump_level = 1; + break; + case 'X': + wear_dump_level = 2; + break; + } + } + } + + DFHack::Process * p; + unsigned int i,j; + DFHack::ContextManager DFMgr("Memory.xml"); + DFHack::Context * DF; + try + { + DF = DFMgr.getSingleContext(); + DF->Attach(); + } + catch (exception& e) + { + cerr << e.what() << endl; +#ifndef LINUX_BUILD + cin.ignore(); +#endif + return 1; + } + + DFHack::VersionInfo * mem = DF->getMemoryInfo(); + Materials = DF->getMaterials(); + Items = DF->getItems(); + + Materials->ReadAllMaterials(); + p = DF->getProcess(); + DFHack::OffsetGroup* itemGroup = mem->getGroup("Items"); + unsigned vector_addr = itemGroup->getAddress("items_vector"); + DFHack::DfVector p_items (p, vector_addr); + uint32_t size = p_items.size(); + + printf("Found total %d items.\n", size); + + for (i=0;igetItemData(curItem, itm); + + if (!itm.header.flags.bits.owned) + continue; + + bool confiscate = false; + bool dump = false; + + if (itm.header.flags.bits.rotten) + { + printf("Confiscating a rotten item.\n"); + confiscate = true; + } + else if (itm.wear_level >= wear_dump_level) + { + printf("Confiscating and dumping a worn item.\n"); + confiscate = true; + dump = true; + } + else if (dump_scattered && itm.header.flags.bits.on_ground) + { + printf("Confiscating and dumping an untidily placed item.\n"); + confiscate = true; + dump = true; + } + + if (confiscate) + { + itm.header.flags.bits.owned = 0; + if (dump) + itm.header.flags.bits.dump = 1; + + Items->setItemFlags(curItem, itm.header.flags); + + printf( + "%5d: %08x %08x (%d,%d,%d) #%08x [%d] %s - %s\n", + i, curItem, itm.header.flags.whole, + itm.header.x, itm.header.y, itm.header.z, + p->readDWord(curItem), + itm.wear_level, + Items->getItemClass(itm.matdesc.itemType).c_str(), + Items->getItemDescription(curItem, Materials).c_str() + ); + } + } + +#ifndef LINUX_BUILD + cout << "Done. Press any key to continue" << endl; + cin.ignore(); +#endif + return 0; +}