/* * Confiscates and dumps garbage owned by dwarfs. */ #include #include #include #include #include #include using namespace std; #include #include #include #include int main (int argc, char *argv[]) { bool temporary_terminal = TemporaryTerminal(); bool dump_scattered = false; bool confiscate_all = false; bool dry_run = 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 'd': dry_run = true; break; case 'l': dump_scattered = true; break; case 'a': confiscate_all = true; break; case 'x': wear_dump_level = 1; break; case 'X': wear_dump_level = 2; break; } } } DFHack::Process * p; unsigned int i; DFHack::ContextManager DFMgr("Memory.xml"); DFHack::Context * DF; try { DF = DFMgr.getSingleContext(); DF->Attach(); } catch (exception& e) { cerr << e.what() << endl; if(temporary_terminal) cin.ignore(); return 1; } DFHack::VersionInfo * mem = DF->getMemoryInfo(); DFHack::Materials *Materials = DF->getMaterials(); DFHack::Items *Items = DF->getItems(); DFHack::Creatures *Creatures = DF->getCreatures(); DFHack::Translation *Tran = DF->getTranslation(); Materials->ReadAllMaterials(); uint32_t num_creatures; Creatures->Start(num_creatures); Tran->Start(); 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;ireadItem(curItem, itm); bool confiscate = false; bool dump = false; if (!itm.base.flags.owned) { int32_t owner = Items->getItemOwnerID(itm); if (owner >= 0) { printf("Fixing a misflagged item: "); confiscate = true; } else continue; } std::string name = Items->getItemClass(itm.matdesc.itemType); if (itm.base.flags.rotten) { printf("Confiscating a rotten item: \t"); confiscate = true; } else if (itm.base.flags.on_ground && (name == "food" || name == "meat" || name == "plant")) { printf("Confiscating a dropped foodstuff: \t"); confiscate = true; } else if (itm.wear_level >= wear_dump_level) { printf("Confiscating and dumping a worn item: \t"); confiscate = true; dump = true; } else if (dump_scattered && itm.base.flags.on_ground) { printf("Confiscating and dumping litter: \t"); confiscate = true; dump = true; } else if (confiscate_all) { printf("Confiscating: \t"); confiscate = true; } if (confiscate) { if (!dry_run) { if (!Items->removeItemOwner(itm, Creatures)) printf("(unsuccessfully) "); if (dump) itm.base.flags.dump = 1; Items->writeItem(itm); } printf( "%s (wear %d)", Items->getItemDescription(itm, Materials).c_str(), itm.wear_level ); int32_t owner = Items->getItemOwnerID(itm); int32_t owner_index = Creatures->FindIndexById(owner); std::string info; if (owner_index >= 0) { DFHack::t_creature temp; Creatures->ReadCreature(owner_index,temp); temp.name.first_name[0] = toupper(temp.name.first_name[0]); info = temp.name.first_name; if (temp.name.nickname[0]) info += std::string(" '") + temp.name.nickname + "'"; info += " "; info += Tran->TranslateName(temp.name,false); printf(", owner %s", info.c_str()); } printf("\n"); /* printf( "%5d: %08x %08x (%d,%d,%d) #%08x [%d] %s - %s %s\n", i, itm.origin, itm.base.flags.whole, itm.base.x, itm.base.y, itm.base.z, itm.base.vtable, itm.wear_level, Items->getItemClass(itm.matdesc.itemType).c_str(), Items->getItemDescription(itm, Materials).c_str(), info.c_str() ); */ } } if(temporary_terminal) { cout << "Done. Press any key to continue" << endl; cin.ignore(); } return 0; }