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::Units *Creatures = c->getUnits(); DFHack::Translation *Tran = c->getTranslation(); uint32_t num_creatures; bool ok = true; ok &= Materials->ReadAllMaterials(); ok &= Creatures->Start(num_creatures); ok &= Tran->Start(); vector<df_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++) { df_item * item = p_items[i]; bool confiscate = false; bool dump = false; if (!item->flags.owned) { int32_t owner = Items->getItemOwnerID(item); if (owner >= 0) { c->con.print("Fixing a misflagged item: \t"); confiscate = true; } else { continue; } } std::string name = Items->getItemClass(item); if (item->flags.rotten) { c->con.print("Confiscating a rotten item: \t"); confiscate = true; } else if (item->flags.on_ground) { int32_t type = item->getType(); if(type == Items::MEAT || type == Items::FISH || type == Items::VERMIN || type == Items::PET || type == Items::PLANT || type == Items::CHEESE || type == Items::FOOD ) { confiscate = true; if(dump_scattered) { c->con.print("Dumping a dropped item: \t"); dump = true; } else { c->con.print("Confiscating a dropped item: \t"); } } else if(dump_scattered) { c->con.print("Confiscating and dumping litter: \t"); confiscate = true; dump = true; } } else if (item->getWear() >= wear_dump_level) { c->con.print("Confiscating and dumping a worn item: \t"); confiscate = true; dump = true; } else if (confiscate_all) { c->con.print("Confiscating: \t"); confiscate = true; } if (confiscate) { std::string description; item->getItemDescription(&description, 0); c->con.print( "0x%x %s (wear %d)", item, description.c_str(), item->getWear() ); int32_t owner = Items->getItemOwnerID(item); int32_t owner_index = Creatures->FindIndexById(owner); std::string info; if (owner_index >= 0) { DFHack::df_unit * temp = Creatures->GetCreature(owner_index); info = temp->name.first_name; if (!temp->name.nick_name.empty()) info += std::string(" '") + temp->name.nick_name + "'"; info += " "; info += Tran->TranslateName(&temp->name,false); c->con.print(", owner %s", info.c_str()); } if (!dry_run) { if (!Items->removeItemOwner(item, Creatures)) c->con.print("(unsuccessfully) "); if (dump) item->flags.dump = 1; } c->con.print("\n"); } } c->Resume(); return CR_OK; }
void printCreature(DFHack::Context * DF, const DFHack::t_creature & creature, int index) { DFHack::Translation *Tran = DF->getTranslation(); DFHack::VersionInfo *mem = DF->getMemoryInfo(); string type="(no type)"; if (Materials->raceEx[creature.race].rawname[0]) { type = toCaps(Materials->raceEx[creature.race].rawname); } string name="(no name)"; if(creature.name.nickname[0]) { name = creature.name.nickname; } else { if(creature.name.first_name[0]) { name = toCaps(creature.name.first_name); string transName = Tran->TranslateName(creature.name,false); if(!transName.empty()) { name += " " + toCaps(transName); } } } string profession=""; try { profession = mem->getProfession(creature.profession); } catch (exception& e) { cout << "Error retrieving creature profession: " << e.what() << endl; } if(creature.custom_profession[0]) { profession = creature.custom_profession; } string job="No Job"; if(creature.current_job.active) { job=mem->getJob(creature.current_job.jobId); int p=job.size(); while (p>0 && (job[p]==' ' || job[p]=='\t')) p--; if (p <= 1) { stringstream ss; ss << creature.current_job.jobId; job = ss.str(); } } if (showfirstlineonly) { printf("%3d", index); printf(" %-17s", type.c_str()); printf(" %-32s", name.c_str()); printf(" %-16s", toCaps(profession).c_str()); printf(" %-30s", job.c_str()); printf(" %5d", creature.happiness); if (showdead) { printf(" %-5s", creature.flags1.bits.dead ? "Dead" : "Alive"); } printf("\n"); return; } else { printf("ID: %d", index); printf(", %s", type.c_str()); printf(", %s", name.c_str()); printf(", %s", toCaps(profession).c_str()); printf(", Job: %s", job.c_str()); printf(", Happiness: %d", creature.happiness); printf("\n"); } if((creature.mood != NO_MOOD) && (creature.mood<=MAX_MOOD)) { cout << "Creature is in a strange mood (mood=" << creature.mood << "), skill: " << mem->getSkill(creature.mood_skill) << endl; vector<DFHack::t_material> mymat; if(Creatures->ReadJob(&creature, mymat)) { for(unsigned int i = 0; i < mymat.size(); i++) { printf("\t%s(%d)\t%d %d %d - %.8x\n", Materials->getDescription(mymat[i]).c_str(), mymat[i].itemType, mymat[i].subType, mymat[i].subIndex, mymat[i].index, mymat[i].flags); } } } if(creature.has_default_soul) { // Print out skills int skillid; int skillrating; int skillexperience; string skillname; cout << setiosflags(ios::left); for(unsigned int i = 0; i < creature.defaultSoul.numSkills; i++) { skillid = creature.defaultSoul.skills[i].id; bool is_social = is_in(skillid, social_skills, sizeof(social_skills)/sizeof(social_skills[0])); if (!is_social || (is_social && showsocial)) { skillrating = creature.defaultSoul.skills[i].rating; skillexperience = creature.defaultSoul.skills[i].experience; try { skillname = mem->getSkill(skillid); } catch(DFHack::Error::AllMemdef &e) { skillname = "Unknown skill"; cout << e.what() << endl; } if (skillrating > 0 || skillexperience > 0) { cout << "(Skill " << int(skillid) << ") " << setw(16) << skillname << ": " << skillrating << "/" << skillexperience << endl; } } } for(unsigned int i = 0; i < NUM_CREATURE_LABORS; i++) { if(!creature.labors[i]) continue; string laborname; try { laborname = mem->getLabor(i); } catch(exception &e) { laborname = "(Undefined)"; } bool is_labor = is_in(i, hauler_labors, sizeof(hauler_labors)/sizeof(hauler_labors[0])); if (!is_labor || (is_labor && showhauler)) cout << "(Labor " << i << ") " << setw(16) << laborname << endl; } } if (showallflags) { DFHack::t_creaturflags1 f1 = creature.flags1; DFHack::t_creaturflags2 f2 = creature.flags2; if(f1.bits.had_mood) { cout<<toCaps("Flag: had_mood") << endl; } if(f1.bits.marauder) { cout<<toCaps("Flag: marauder") << endl; } if(f1.bits.drowning) { cout<<toCaps("Flag: drowning") << endl; } if(f1.bits.merchant) { cout<<toCaps("Flag: merchant") << endl; } if(f1.bits.forest) { cout<<toCaps("Flag: forest") << endl; } if(f1.bits.left) { cout<<toCaps("Flag: left") << endl; } if(f1.bits.rider) { cout<<toCaps("Flag: rider") << endl; } if(f1.bits.incoming) { cout<<toCaps("Flag: incoming") << endl; } if(f1.bits.diplomat) { cout<<toCaps("Flag: diplomat") << endl; } if(f1.bits.zombie) { cout<<toCaps("Flag: zombie") << endl; } if(f1.bits.skeleton) { cout<<toCaps("Flag: skeleton") << endl; } if(f1.bits.can_swap) { cout<<toCaps("Flag: can_swap") << endl; } if(f1.bits.on_ground) { cout<<toCaps("Flag: on_ground") << endl; } if(f1.bits.projectile) { cout<<toCaps("Flag: projectile") << endl; } if(f1.bits.active_invader) { cout<<toCaps("Flag: active_invader") << endl; } if(f1.bits.hidden_in_ambush) { cout<<toCaps("Flag: hidden_in_ambush") << endl; } if(f1.bits.invader_origin) { cout<<toCaps("Flag: invader_origin") << endl; } if(f1.bits.coward) { cout<<toCaps("Flag: coward") << endl; } if(f1.bits.hidden_ambusher) { cout<<toCaps("Flag: hidden_ambusher") << endl; } if(f1.bits.invades) { cout<<toCaps("Flag: invades") << endl; } if(f1.bits.check_flows) { cout<<toCaps("Flag: check_flows") << endl; } if(f1.bits.ridden) { cout<<toCaps("Flag: ridden") << endl; } if(f1.bits.caged) { cout<<toCaps("Flag: caged") << endl; } if(f1.bits.tame) { cout<<toCaps("Flag: tame") << endl; } if(f1.bits.chained) { cout<<toCaps("Flag: chained") << endl; } if(f1.bits.royal_guard) { cout<<toCaps("Flag: royal_guard") << endl; } if(f1.bits.fortress_guard) { cout<<toCaps("Flag: fortress_guard") << endl; } if(f1.bits.suppress_wield) { cout<<toCaps("Flag: suppress_wield") << endl; } if(f1.bits.important_historical_figure) { cout<<toCaps("Flag: important_historical_figure") << endl; } if(f2.bits.swimming) { cout<<toCaps("Flag: swimming") << endl; } if(f2.bits.sparring) { cout<<toCaps("Flag: sparring") << endl; } if(f2.bits.no_notify) { cout<<toCaps("Flag: no_notify") << endl; } if(f2.bits.unused) { cout<<toCaps("Flag: unused") << endl; } if(f2.bits.calculated_nerves) { cout<<toCaps("Flag: calculated_nerves") << endl; } if(f2.bits.calculated_bodyparts) { cout<<toCaps("Flag: calculated_bodyparts") << endl; } if(f2.bits.important_historical_figure) { cout<<toCaps("Flag: important_historical_figure") << endl; } if(f2.bits.killed) { cout<<toCaps("Flag: killed") << endl; } if(f2.bits.cleanup_1) { cout<<toCaps("Flag: cleanup_1") << endl; } if(f2.bits.cleanup_2) { cout<<toCaps("Flag: cleanup_2") << endl; } if(f2.bits.cleanup_3) { cout<<toCaps("Flag: cleanup_3") << endl; } if(f2.bits.for_trade) { cout<<toCaps("Flag: for_trade") << endl; } if(f2.bits.trade_resolved) { cout<<toCaps("Flag: trade_resolved") << endl; } if(f2.bits.has_breaks) { cout<<toCaps("Flag: has_breaks") << endl; } if(f2.bits.gutted) { cout<<toCaps("Flag: gutted") << endl; } if(f2.bits.circulatory_spray) { cout<<toCaps("Flag: circulatory_spray") << endl; } if(f2.bits.locked_in_for_trading) { cout<<toCaps("Flag: locked_in_for_trading") << endl; } if(f2.bits.slaughter) { cout<<toCaps("Flag: slaughter") << endl; } if(f2.bits.underworld) { cout<<toCaps("Flag: underworld") << endl; } if(f2.bits.resident) { cout<<toCaps("Flag: resident") << endl; } if(f2.bits.cleanup_4) { cout<<toCaps("Flag: cleanup_4") << endl; } if(f2.bits.calculated_insulation) { cout<<toCaps("Flag: calculated_insulation") << endl; } if(f2.bits.visitor_uninvited) { cout<<toCaps("Flag: visitor_uninvited") << endl; } if(f2.bits.visitor) { cout<<toCaps("Flag: visitor") << endl; } if(f2.bits.calculated_inventory) { cout<<toCaps("Flag: calculated_inventory") << endl; } if(f2.bits.vision_good) { cout<<toCaps("Flag: vision_good") << endl; } if(f2.bits.vision_damaged) { cout<<toCaps("Flag: vision_damaged") << endl; } if(f2.bits.vision_missing) { cout<<toCaps("Flag: vision_missing") << endl; } if(f2.bits.breathing_good) { cout<<toCaps("Flag: breathing_good") << endl; } if(f2.bits.breathing_problem) { cout<<toCaps("Flag: breathing_problem") << endl; } if(f2.bits.roaming_wilderness_population_source) { cout<<toCaps("Flag: roaming_wilderness_population_source") << endl; } if(f2.bits.roaming_wilderness_population_source_not_a_map_feature) { cout<<toCaps("Flag: roaming_wilderness_population_source_not_a_map_feature") << endl; } } else { /* FLAGS 1 */ if(creature.flags1.bits.dead) { cout << "Flag: Dead" << endl; } if(creature.flags1.bits.on_ground) { cout << "Flag: On the ground" << endl; } if(creature.flags1.bits.tame) { cout << "Flag: Tame" << endl; } if(creature.flags1.bits.royal_guard) { cout << "Flag: Royal guard" << endl; } if(creature.flags1.bits.fortress_guard) { cout << "Flag: Fortress guard" << endl; } /* FLAGS 2 */ if(creature.flags2.bits.killed) { cout << "Flag: Killed by kill function" << endl; } if(creature.flags2.bits.resident) { cout << "Flag: Resident" << endl; } if(creature.flags2.bits.gutted) { cout << "Flag: Gutted" << endl; } if(creature.flags2.bits.slaughter) { cout << "Flag: Marked for slaughter" << endl; } if(creature.flags2.bits.underworld) { cout << "Flag: From the underworld" << endl; } if(creature.flags1.bits.had_mood && (creature.mood == -1 || creature.mood == 8 ) ) { string artifact_name = Tran->TranslateName(creature.artifact_name,false); cout << "Artifact: " << artifact_name << endl; } } cout << endl; }
void printCreature(DFHack::Context * DF, const DFHack::t_creature & creature) { uint32_t dayoflife; cout << "address: " << hex << creature.origin << dec << ", creature race: " << creature.race << "/" << Materials->raceEx[creature.race].rawname << "[" << Materials->raceEx[creature.race].tile_character << "," << Materials->raceEx[creature.race].tilecolor.fore << "," << Materials->raceEx[creature.race].tilecolor.back << "," << Materials->raceEx[creature.race].tilecolor.bright << "]" << ", position: " << creature.x << "x " << creature.y << "y "<< creature.z << "z" << endl; bool addendl = false; if(creature.name.first_name[0]) { cout << "first name: " << creature.name.first_name; addendl = true; } if(creature.name.nickname[0]) { cout << ", nick name: " << creature.name.nickname; addendl = true; } DFHack::Translation *Tran = DF->getTranslation(); DFHack::VersionInfo *mem = DF->getMemoryInfo(); string transName = Tran->TranslateName(creature.name,false); if(!transName.empty()) { cout << ", trans name: " << transName; addendl=true; } transName = Tran->TranslateName(creature.name,true); if(!transName.empty()) { cout << ", last name: " << transName; addendl=true; } if(creature.civ) { cout << ", civilization: " << creature.civ; addendl = true; } /* cout << ", likes: "; for(uint32_t i = 0;i<creature.numLikes; i++) { if(printLike(creature.likes[i],mat,itemTypes)) { cout << ", "; } } */ if(addendl) { cout << endl; addendl = false; } cout << ", profession: " << mem->getProfession(creature.profession) << "(" << (int) creature.profession << ")"; if(creature.custom_profession[0]) { cout << ", custom profession: " << creature.custom_profession; } /* if(creature.current_job.active) { cout << ", current job: " << mem->getJob(creature.current_job.jobId); } */ cout << endl; dayoflife = creature.birth_year*12*28 + creature.birth_time/1200; cout << "Born on the year " << creature.birth_year << ", month " << (creature.birth_time/1200/28) << ", day " << ((creature.birth_time/1200) % 28 + 1) << ", " << dayoflife << " days lived." << endl; cout << "Appearance : "; for(unsigned int i = 0; i<creature.nbcolors ; i++) { cout << Materials->raceEx[creature.race].castes[creature.caste].ColorModifier[i].part << " "; uint32_t color = Materials->raceEx[creature.race].castes[creature.caste].ColorModifier[i].colorlist[creature.color[i]]; if(color<Materials->color.size()) cout << Materials->color[color].name << "[" << (unsigned int) (Materials->color[color].r*255) << ":" << (unsigned int) (Materials->color[color].v*255) << ":" << (unsigned int) (Materials->color[color].b*255) << "]"; else cout << Materials->alldesc[color].id; if( Materials->raceEx[creature.race].castes[creature.caste].ColorModifier[i].startdate > 0 ) { if( (Materials->raceEx[creature.race].castes[creature.caste].ColorModifier[i].startdate <= dayoflife) && (Materials->raceEx[creature.race].castes[creature.caste].ColorModifier[i].enddate > dayoflife) ) cout << "[active]"; else cout << "[inactive]"; } cout << " - "; } cout << endl; cout << "happiness: " << creature.happiness << ", strength: " << creature.strength.level << ", agility: " << creature.agility.level << ", toughness: " << creature.toughness.level << ", endurance: " << creature.endurance.level << ", recuperation: " << creature.recuperation.level << ", disease resistance: " << creature.disease_resistance.level //<< ", money: " << creature.money << ", id: " << creature.id; /* if(creature.squad_leader_id != -1) { cout << ", squad_leader_id: " << creature.squad_leader_id; } if(creature.mood != -1){ cout << ", mood: " << creature.mood << " "; }*/ cout << ", sex: "; if(creature.sex == 0) { cout << "Female"; } else { cout <<"Male"; } cout << endl; if((creature.mood != -1) && (creature.mood<5)) { cout << "mood: " << creature.mood << ", skill: " << mem->getSkill(creature.mood_skill) << endl; vector<DFHack::t_material> mymat; if(Creatures->ReadJob(&creature, mymat)) { for(unsigned int i = 0; i < mymat.size(); i++) { printf("\t%s(%d)\t%d %d %d - %.8x\n", Materials->getDescription(mymat[i]).c_str(), mymat[i].itemType, mymat[i].subType, mymat[i].subIndex, mymat[i].index, mymat[i].flags); } } } //std::vector<uint32_t> inventory; // FIXME: TOO BAD... /* if( Creatures->ReadInventoryPtr(creature.origin, inventory) ) { DFHack::Items * Items = DF->getItems(); printf("\tInventory:\n"); for(unsigned int i = 0; i < inventory.size(); i++) { printf("\t\t%s\n", Items->getItemDescription(inventory[i], Materials).c_str()); } } */ /* if(creature.pregnancy_timer > 0) cout << "gives birth in " << creature.pregnancy_timer/1200 << " days. "; cout << "Blood: " << creature.blood_current << "/" << creature.blood_max << " bleeding: " << creature.bleed_rate; */ cout << endl; if(creature.has_default_soul) { //skills cout << "Skills" << endl; for(unsigned int i = 0; i < creature.defaultSoul.numSkills;i++) { if(i > 0) { cout << ", "; } cout << mem->getSkill(creature.defaultSoul.skills[i].id) << ": " << creature.defaultSoul.skills[i].rating; } cout << endl; cout << "Traits" << endl; for(uint32_t i = 0; i < 30;i++) { string trait = mem->getTrait (i, creature.defaultSoul.traits[i]); if(!trait.empty()) cout << trait << ", "; } cout << endl; // labors cout << "Labors" << endl; for(unsigned int i = 0; i < NUM_CREATURE_LABORS;i++) { if(!creature.labors[i]) continue; string laborname; try { laborname = mem->getLabor(i); } catch(exception &) { break; } cout << laborname << ", "; } cout << endl; } /* * FLAGS 1 */ cout << "flags1: "; print_bits(creature.flags1.whole, cout); cout << endl; if(creature.flags1.bits.dead) { cout << "dead "; } if(creature.flags1.bits.on_ground) { cout << "on the ground, "; } if(creature.flags1.bits.skeleton) { cout << "skeletal "; } if(creature.flags1.bits.zombie) { cout << "zombie "; } if(creature.flags1.bits.tame) { cout << "tame "; } if(creature.flags1.bits.royal_guard) { cout << "royal_guard "; } if(creature.flags1.bits.fortress_guard) { cout << "fortress_guard "; } /* * FLAGS 2 */ cout << endl << "flags2: "; print_bits(creature.flags2.whole, cout); cout << endl; if(creature.flags2.bits.killed) { cout << "killed by kill function, "; } if(creature.flags2.bits.resident) { cout << "resident, "; } if(creature.flags2.bits.gutted) { cout << "gutted, "; } if(creature.flags2.bits.slaughter) { cout << "marked for slaughter, "; } if(creature.flags2.bits.underworld) { cout << "from the underworld, "; } cout << endl; if(creature.flags1.bits.had_mood && (creature.mood == -1 || creature.mood == 8 ) ) { string artifact_name = Tran->TranslateName(creature.artifact_name,false); cout << "artifact: " << artifact_name << endl; } cout << endl; }