int main ( int argc, char** argv ) { DFHack::memory_info *mem; DFHack::Process *proc; uint32_t creature_pregnancy_offset; //bool femaleonly = 0; bool showcreatures = 0; int maxpreg = 1000; // random start value, since its not required and im not sure how to set it to infinity list<string> s_creatures; // parse input, handle this nice and neat before we get to the connecting argstream as(argc,argv); as // >>option('f',"female",femaleonly,"Impregnate females only") >>option('s',"show",showcreatures,"Show creature list (read only)") >>parameter('m',"max",maxpreg,"The maximum limit of pregnancies ", false) >>values<string>(back_inserter(s_creatures), "any number of creatures") >>help(); // make the creature list unique s_creatures.unique(); if (!as.isOk()) { cout << as.errorLog(); return(0); } else if (as.helpRequested()) { cout<<as.usage()<<endl; return(1); } else if(showcreatures==1) { } else if (s_creatures.size() == 0 && showcreatures != 1) { cout << as.usage() << endl << "---------------------------------------" << endl; cout << "Creature list empty, assuming CATs" << endl; s_creatures.push_back("CAT"); } 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; } proc = DF->getProcess(); mem = DF->getMemoryInfo(); DFHack::Materials *Mats = DF->getMaterials(); DFHack::Creatures *Cre = DF->getCreatures(); creature_pregnancy_offset = mem->getOffset("creature_pregnancy"); if(!Mats->ReadCreatureTypesEx()) { cerr << "Can't get the creature types." << endl; #ifndef LINUX_BUILD cin.ignore(); #endif return 1; } uint32_t numCreatures; if(!Cre->Start(numCreatures)) { cerr << "Can't get creatures" << endl; #ifndef LINUX_BUILD cin.ignore(); #endif return 1; } int totalcount=0; int totalchanged=0; string sextype; // shows all the creatures and returns. int maxlength = 0; map<string, vector <t_creature> > male_counts; map<string, vector <t_creature> > female_counts; // classify for(uint32_t i =0;i < numCreatures;i++) { DFHack::t_creature creature; Cre->ReadCreature(i,creature); DFHack::t_creaturetype & crt = Mats->raceEx[creature.race]; string castename = crt.castes[creature.sex].rawname; if(castename == "FEMALE") { female_counts[Mats->raceEx[creature.race].rawname].push_back(creature); male_counts[Mats->raceEx[creature.race].rawname].size(); } else // male, other, etc. { male_counts[Mats->raceEx[creature.race].rawname].push_back(creature); female_counts[Mats->raceEx[creature.race].rawname].size(); //auto initialize the females as well } } // print (optional) if (showcreatures == 1) { cout << "Type\t\tMale #\tFemale #" << endl; for(map<string, vector <t_creature> >::iterator it1 = male_counts.begin();it1!=male_counts.end();it1++) { cout << it1->first << "\t\t" << it1->second.size() << "\t" << female_counts[it1->first].size() << endl; } } // process for (list<string>::iterator it = s_creatures.begin(); it != s_creatures.end(); ++it) { std::string clinput = *it; std::transform(clinput.begin(), clinput.end(), clinput.begin(), ::toupper); vector <t_creature> &females = female_counts[clinput]; uint32_t sz_fem = females.size(); totalcount += sz_fem; for(uint32_t i = 0; i < sz_fem && totalchanged != maxpreg; i++) { t_creature & female = females[i]; uint32_t preg_timer = proc->readDWord(female.origin + creature_pregnancy_offset); if(preg_timer != 0) { proc->writeDWord(female.origin + creature_pregnancy_offset, rand() % 100 + 1); totalchanged++; } } } cout << totalchanged << " pregnancies accelerated. Total creatures checked: " << totalcount << "." << endl; Cre->Finish(); DF->Detach(); #ifndef LINUX_BUILD cout << "Done. Press any key to continue" << endl; cin.ignore(); #endif return 0; }
int main (int numargs, char ** args) { DFHack::ContextManager DFMgr("Memory.xml"); DFHack::Context *DF = DFMgr.getSingleContext(); DFHack::Process * p; try { DF->Attach(); } catch (exception& e) { cerr << e.what() << endl; #ifndef LINUX_BUILD cin.ignore(); #endif return 1; } p = DF->getProcess(); string check = ""; if(numargs == 2) check = args[1]; DFHack::Creatures * Creatures = DF->getCreatures(); Materials = DF->getMaterials(); DFHack::Translation * Tran = DF->getTranslation(); uint32_t numCreatures; if(!Creatures->Start(numCreatures)) { cerr << "Can't get creatures" << endl; #ifndef LINUX_BUILD cin.ignore(); #endif return 1; } if(!numCreatures) { cerr << "No creatures to print" << endl; #ifndef LINUX_BUILD cin.ignore(); #endif return 1; } mem = DF->getMemoryInfo(); if(!Materials->ReadInorganicMaterials()) { cerr << "Can't get the inorganics types." << endl; return 1; } if(!Materials->ReadCreatureTypesEx()) { cerr << "Can't get the creature types." << endl; return 1; } if(!Tran->Start()) { cerr << "Can't get name tables" << endl; return 1; } vector<uint32_t> addrs; //DF.InitViewAndCursor(); for(uint32_t i = 0; i < numCreatures; i++) { DFHack::t_creature temp; unsigned int current_job; unsigned int mat_start; unsigned int mat_end; unsigned int j,k; unsigned int matptr; Creatures->ReadCreature(i,temp); if(temp.mood>=0) { current_job = p->readDWord(temp.origin + 0x390); if(current_job == 0) continue; mat_start = p->readDWord(current_job + 0xa4 + 4*3); mat_end = p->readDWord(current_job + 0xa4 + 4*4); for(j=mat_start;j<mat_end;j+=4) { matptr = p->readDWord(j); for(k=0;k<4;k++) printf("%.4X ", p->readWord(matptr + k*2)); for(k=0;k<3;k++) printf("%.8X ", p->readDWord(matptr + k*4 + 0x8)); for(k=0;k<2;k++) printf("%.4X ", p->readWord(matptr + k*2 + 0x14)); for(k=0;k<3;k++) printf("%.8X ", p->readDWord(matptr + k*4 + 0x18)); for(k=0;k<4;k++) printf("%.2X ", p->readByte(matptr + k + 0x24)); for(k=0;k<6;k++) printf("%.8X ", p->readDWord(matptr + k*4 + 0x28)); for(k=0;k<4;k++) printf("%.2X ", p->readByte(matptr + k + 0x40)); for(k=0;k<9;k++) printf("%.8X ", p->readDWord(matptr + k*4 + 0x44)); printf(" [%p]\n", matptr); } } } Creatures->Finish(); DF->Detach(); return 0; }
DFhackCExport command_result df_cleanowned (Core * c, vector <string> & parameters) { bool dump_scattered = false; bool confiscate_all = false; bool dry_run = false; int wear_dump_level = 65536; for(std::size_t i = 0; i < parameters.size(); i++) { string & param = parameters[i]; if(param == "dryrun") dry_run = true; else if(param == "scattered") dump_scattered = true; else if(param == "all") confiscate_all = true; else if(param == "x") wear_dump_level = 1; else if(param == "X") wear_dump_level = 2; else if(param == "?" || param == "help") { c->con.print("This tool lets you confiscate and dump all the garbage\n" "dwarves ultimately accumulate.\n" "By default, only rotten and dropped food is confiscated.\n" "Options:\n" " dryrun - don't actually do anything, just print what would be done.\n" " scattered - confiscate owned items on the ground\n" " all - confiscate everything\n" " x - confiscate & dump 'x' and worse damaged items\n" " X - confiscate & dump 'X' and worse damaged items\n" " ? - this help\n" "Example:\n" " confiscate scattered X\n" " This will confiscate rotten and dropped food, garbage on the floors\n" " and any worn items wit 'X' damage and above.\n" ); return CR_OK; } else { c->con.printerr("Parameter '%s' is not valid. See 'cleanowned help'.\n",param.c_str()); return CR_FAILURE; } } c->Suspend(); DFHack::Materials *Materials = c->getMaterials(); DFHack::Items *Items = c->getItems(); DFHack::Creatures *Creatures = c->getCreatures(); DFHack::Translation *Tran = c->getTranslation(); uint32_t num_creatures; bool ok = true; ok &= Materials->ReadAllMaterials(); ok &= Creatures->Start(num_creatures); ok &= Tran->Start(); vector<t_item *> p_items; ok &= Items->readItemVector(p_items); if(!ok) { c->con.printerr("Can't continue due to offset errors.\n"); c->Resume(); return CR_FAILURE; } c->con.print("Found total %d items.\n", p_items.size()); for (std::size_t i=0; i < p_items.size(); i++) { t_item * curItem = p_items[i]; DFHack::dfh_item itm; Items->readItem(curItem, itm); bool confiscate = false; bool dump = false; if (!itm.base->flags.owned) { int32_t owner = Items->getItemOwnerID(itm); if (owner >= 0) { c->con.print("Fixing a misflagged item: "); confiscate = true; } else { continue; } } std::string name = Items->getItemClass(itm.matdesc.itemType); if (itm.base->flags.rotten) { c->con.print("Confiscating a rotten item: \t"); confiscate = true; } else if (itm.base->flags.on_ground && (name == "food" || name == "meat" || name == "plant")) { c->con.print("Confiscating a dropped foodstuff: \t"); confiscate = true; } else if (itm.wear_level >= wear_dump_level) { c->con.print("Confiscating and dumping a worn item: \t"); confiscate = true; dump = true; } else if (dump_scattered && itm.base->flags.on_ground) { c->con.print("Confiscating and dumping litter: \t"); confiscate = true; dump = true; } else if (confiscate_all) { c->con.print("Confiscating: \t"); confiscate = true; } if (confiscate) { c->con.print( "0x%x %s (wear %d)", itm.base, 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); c->con.print(", owner %s", info.c_str()); } if (!dry_run) { if (!Items->removeItemOwner(itm, Creatures)) c->con.print("(unsuccessfully) "); if (dump) itm.base->flags.dump = 1; } c->con.print("\n"); } } c->Resume(); return CR_OK; }