int main (int numargs, const char ** args) { map<string, string> buildCommands; buildCommands["building_stockpilest"]=""; buildCommands["building_zonest"]=""; buildCommands["building_construction_blueprintst"]=""; buildCommands["building_wagonst"]=""; buildCommands["building_armor_standst"]="a"; buildCommands["building_bedst"]="b"; buildCommands["building_seatst"]="c"; buildCommands["building_burial_receptaclest"]="n"; buildCommands["building_doorst"]="d"; buildCommands["building_floodgatest"]="x"; buildCommands["building_floor_hatchst"]="H"; buildCommands["building_wall_gratest"]="W"; buildCommands["building_floor_gratest"]="G"; buildCommands["building_vertical_barsst"]="B"; buildCommands["building_floor_barsst"]="alt-b"; buildCommands["building_cabinetst"]="f"; buildCommands["building_containerst"]="h"; buildCommands["building_shopst"]=""; buildCommands["building_workshopst"]=""; buildCommands["building_alchemists_laboratoryst"]="wa"; buildCommands["building_carpenters_workshopst"]="wc"; buildCommands["building_farmers_workshopst"]="ww"; buildCommands["building_masons_workshopst"]="wm"; buildCommands["building_craftdwarfs_workshopst"]="wr"; buildCommands["building_jewelers_workshopst"]="wj"; buildCommands["building_metalsmiths_workshopst"]="wf"; buildCommands["building_magma_forgest"]=""; buildCommands["building_bowyers_workshopst"]="wb"; buildCommands["building_mechanics_workshopst"]="wt"; buildCommands["building_siege_workshopst"]="ws"; buildCommands["building_butchers_shopst"]="wU"; buildCommands["building_leather_worksst"]="we"; buildCommands["building_tanners_shopst"]="wn"; buildCommands["building_clothiers_shopst"]="wk"; buildCommands["building_fisheryst"]="wh"; buildCommands["building_stillst"]="wl"; buildCommands["building_loomst"]="wo"; buildCommands["building_quernst"]="wq"; buildCommands["building_kennelsst"]="k"; buildCommands["building_kitchenst"]="wz"; buildCommands["building_asheryst"]="wy"; buildCommands["building_dyers_shopst"]="wd"; buildCommands["building_millstonest"]="wM"; buildCommands["building_farm_plotst"]="p"; buildCommands["building_weapon_rackst"]="r"; buildCommands["building_statuest"]="s"; buildCommands["building_tablest"]="t"; buildCommands["building_paved_roadst"]="o"; buildCommands["building_bridgest"]="g"; buildCommands["building_wellst"]="l"; buildCommands["building_siege enginest"]="i"; buildCommands["building_catapultst"]="ic"; buildCommands["building_ballistast"]="ib"; buildCommands["building_furnacest"]=""; buildCommands["building_wood_furnacest"]="ew"; buildCommands["building_smelterst"]="es"; buildCommands["building_glass_furnacest"]="ek"; buildCommands["building_kilnst"]="ek"; buildCommands["building_magma_smelterst"]="es"; buildCommands["building_magma_glass_furnacest"]="ek"; buildCommands["building_magma_kilnst"]="ek"; buildCommands["building_glass_windowst"]="y"; buildCommands["building_gem_windowst"]="Y"; buildCommands["building_tradedepotst"]="D"; buildCommands["building_mechanismst"]=""; buildCommands["building_leverst"]="Tl"; buildCommands["building_pressure_platest"]="Tp"; buildCommands["building_cage_trapst"]="Tc"; buildCommands["building_stonefall_trapst"]="Ts"; buildCommands["building_weapon_trapst"]="Tw"; buildCommands["building_spikest"]=""; buildCommands["building_animal_trapst"]="m"; buildCommands["building_screw_pumpst"]="Ms"; buildCommands["building_water_wheelst"]="Mw"; buildCommands["building_windmillst"]="Mm"; buildCommands["building_gear_assemblyst"]="Mg"; buildCommands["building_horizontal_axlest"]="Mh"; buildCommands["building_vertical_axlest"]="Mv"; buildCommands["building_supportst"]="S"; buildCommands["building_cagest"]="j"; buildCommands["building_archery_targetst"]="A"; buildCommands["building_restraintst"]="v"; DFHack::ContextManager DFMgr("Memory.xml"); DFHack::Context *DF = DFMgr.getSingleContext(); try { DF->Attach(); } catch (std::exception& e) { std::cerr << e.what() << std::endl; #ifndef LINUX_BUILD cin.ignore(); #endif return 1; } DFHack::Gui *Gui = DF->getGui(); DFHack::VersionInfo* mem = DF->getMemoryInfo(); DFHack::Process * p = DF->getProcess(); OffsetGroup * OG_Maps = mem->getGroup("Maps"); OffsetGroup * OG_MapBlock = OG_Maps->getGroup("block"); OffsetGroup * OG_LocalFt = OG_Maps->getGroup("features")->getGroup("local"); uint32_t designations = OG_MapBlock->getOffset("designation"); uint32_t block_feature1 = OG_MapBlock->getOffset("feature_local"); uint32_t block_feature2 = OG_MapBlock->getOffset("feature_global"); uint32_t region_x_offset = OG_Maps->getAddress("region_x"); uint32_t region_y_offset = OG_Maps->getAddress("region_y"); uint32_t region_z_offset = OG_Maps->getAddress("region_z"); uint32_t feature1_start_ptr = OG_LocalFt->getAddress("start_ptr"); int32_t regionX, regionY, regionZ; // read position of the region inside DF world p->readDWord (region_x_offset, (uint32_t &)regionX); p->readDWord (region_y_offset, (uint32_t &)regionY); p->readDWord (region_z_offset, (uint32_t &)regionZ); while(1){ int32_t cx1,cy1,cz1; cx1 = -30000; while(cx1 == -30000) { DF->ForceResume(); cout << "Set cursor at first position, then press any key"; cin.ignore(); DF->Suspend(); Gui->getCursorCoords(cx1,cy1,cz1); } uint32_t tx1,ty1,tz1; tx1 = cx1/16; ty1 = cy1/16; tz1 = cz1; int32_t cx2,cy2,cz2; cx2 = -30000; while(cx2 == -30000) { DF->Resume(); cout << "Set cursor at second position, then press any key"; cin.ignore(); DF->Suspend(); Gui->getCursorCoords(cx2,cy2,cz2); } uint32_t tx2,ty2,tz2; tx2 = cx2/16; ty2 = cy2/16; tz2 = cz2; sort(tx1,tx2); sort(ty1,ty2); sort(tz1,tz2); sort(cx1,cx2); sort(cy1,cy2); sort(cz1,cz2); vector <vector<vector<string> > >dig(cz2-cz1+1,vector<vector<string> >(cy2-cy1+1,vector<string>(cx2-cx1+1))); vector <vector<vector<string> > >build(cz2-cz1+1,vector<vector<string> >(cy2-cy1+1,vector<string>(cx2-cx1+1))); mapblock40d block; DFHack::Maps *Maps = DF->getMaps(); Maps->Start(); for(uint32_t y = ty1;y<=ty2;y++) { for(uint32_t x = tx1;x<=tx2;x++) { for(uint32_t z = tz1;z<=tz2;z++) { if(Maps->isValidBlock(x,y,z)) { if(Maps->ReadBlock40d(x,y,z,&block)) { int ystart,yend,xstart,xend; ystart=xstart=0; yend=xend=15; if(y == ty2) { yend = cy2 % 16; } if(y == ty1) { ystart = cy1 % 16; } if(x == tx2) { xend = cx2 % 16; } if(x == tx1) { xstart = cx1 % 16; } int zidx = z-tz1; for(int yy = ystart; yy <= yend;yy++) { int yidx = yy+(16*(y-ty1)-(cy1%16)); for(int xx = xstart; xx <= xend;xx++) { int xidx = xx+(16*(x-tx1)-(cx1%16)); int16_t tt = block.tiletypes[xx][yy]; DFHack::TileShape ts = DFHack::tileShape(tt); if(DFHack::isOpenTerrain(tt) || DFHack::isFloorTerrain(tt)) { dig[zidx][yidx][xidx] = "d"; } else if(DFHack::STAIR_DOWN == ts) { dig [zidx][yidx][xidx] = "j"; build [zidx][yidx][xidx] = "Cd"; } else if(DFHack::STAIR_UP == ts) { dig [zidx][yidx][xidx] = "u"; build [zidx][yidx][xidx] = "Cu"; } else if(DFHack::STAIR_UPDOWN == ts) { dig [zidx][yidx][xidx] = "i"; build [zidx][yidx][xidx] = "Cx"; } else if(DFHack::isRampTerrain(tt)) { dig [zidx][yidx][xidx] = "r"; build [zidx][yidx][xidx] = "Cr"; } else if(DFHack::isWallTerrain(tt)) { build [zidx][yidx][xidx] = "Cw"; } } yidx++; } } } } } } DFHack::Buildings * Bld = DF->getBuildings(); std::map <uint32_t, std::string> custom_workshop_types; uint32_t numBuildings; if(Bld->Start(numBuildings)) { Bld->ReadCustomWorkshopTypes(custom_workshop_types); for(uint32_t i = 0; i < numBuildings; i++) { DFHack::t_building temp; Bld->Read(i, temp); if(temp.type != 0xFFFFFFFF) // check if type isn't invalid { std::string typestr; mem->resolveClassIDToClassname(temp.type, typestr); if(temp.z == cz1 && cx1 <= temp.x1 && cx2 >= temp.x2 && cy1 <= temp.y1 && cy2 >= temp.y2) { string currStr = build[temp.z-cz1][temp.y1-cy1][temp.x1-cx1]; stringstream stream; string newStr = buildCommands[typestr]; if(temp.x1 != temp.x2) { stream << "(" << temp.x2-temp.x1+1 << "x" << temp.y2-temp.y1+1 << ")"; newStr += stream.str(); } build[temp.z-cz1][temp.y1-cy1][temp.x1-cx1] = newStr + currStr; } } } } // for testing purposes //ofstream outfile("test.txt"); // printVecOfVec(outfile, dig,'\t'); // outfile << endl; // printVecOfVec(outfile, build,'\t'); // outfile << endl; // outfile.close(); int32_t cx3,cy3,cz3,cx4,cy4,cz4; uint32_t tx3,ty3,tz3,tx4,ty4,tz4; char result; while(1){ cx3 = -30000; while(cx3 == -30000){ DF->Resume(); cout << "Set cursor at new position, then press any key:"; result = cin.get(); DF->Suspend(); Gui->getCursorCoords(cx3,cy3,cz3); } if(result == 'q'){ break; } cx4 = cx3+cx2-cx1; cy4 = cy3+cy2-cy1; cz4 = cz3+cz2-cz1; tx3=cx3/16; ty3=cy3/16; tz3=cz3; tx4=cx4/16; ty4=cy4/16; tz4=cz4; DFHack::WindowIO * Win = DF->getWindowIO(); designations40d designationBlock; for(uint32_t y = ty3;y<=ty4;y++) { for(uint32_t x = tx3;x<=tx4;x++) { for(uint32_t z = tz3;z<=tz4;z++) { Maps->Start(); Maps->ReadBlock40d(x,y,z,&block); Maps->ReadDesignations(x,y,z,&designationBlock); int ystart,yend,xstart,xend; ystart=xstart=0; yend=xend=15; if(y == ty4){ yend = cy4 % 16; } if(y == ty3){ ystart = cy3 % 16; } if(x == tx4){ xend = cx4 % 16; } if(x == tx3){ xstart = cx3 % 16; } int zidx = z-tz3; for(int yy = ystart; yy <= yend;yy++){ int yidx = yy+(16*(y-ty3)-(cy3%16)); for(int xx = xstart; xx <= xend;xx++){ int xidx = xx+(16*(x-tx3)-(cx3%16)); if(dig[zidx][yidx][xidx] != ""){ char test = dig[zidx][yidx][xidx].c_str()[0]; switch (test){ case 'd': designationBlock[xx][yy].bits.dig = DFHack::designation_default; break; case 'i': designationBlock[xx][yy].bits.dig = DFHack::designation_ud_stair; break; case 'u': designationBlock[xx][yy].bits.dig = DFHack::designation_u_stair; break; case 'j': designationBlock[xx][yy].bits.dig = DFHack::designation_d_stair; break; case 'r': designationBlock[xx][yy].bits.dig = DFHack::designation_ramp; break; } } } yidx++; } Maps->Start(); Maps->WriteDesignations(x,y,z,&designationBlock); } } } } } DF->Detach(); #ifndef LINUX_BUILD std::cout << "Done. Press any key to continue" << std::endl; cin.ignore(); #endif return 0; }
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; }
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; }
Maps::Maps(DFContextShared* _d) { d = new Private; d->d = _d; Process *p = d->owner = _d->p; d->Inited = d->Started = false; d->block = NULL; DFHack::VersionInfo * mem = p->getDescriptor(); Server::Maps::maps_offsets &off = d->offsets; // get the offsets once here OffsetGroup *OG_Maps = mem->getGroup("Maps"); { off.map_offset = OG_Maps->getAddress ("map_data"); off.x_count_offset = OG_Maps->getAddress ("x_count_block"); off.y_count_offset = OG_Maps->getAddress ("y_count_block"); off.z_count_offset = OG_Maps->getAddress ("z_count_block"); off.region_x_offset = OG_Maps->getAddress ("region_x"); off.region_y_offset = OG_Maps->getAddress ("region_y"); off.region_z_offset = OG_Maps->getAddress ("region_z"); off.world_size_x = OG_Maps->getAddress ("world_size_x"); off.world_size_y = OG_Maps->getAddress ("world_size_y"); OffsetGroup *OG_MapBlock = OG_Maps->getGroup("block"); { off.tile_type_offset = OG_MapBlock->getOffset ("type"); off.designation_offset = OG_MapBlock->getOffset ("designation"); off.occupancy_offset = OG_MapBlock->getOffset("occupancy"); off.biome_stuffs = OG_MapBlock->getOffset ("biome_stuffs"); off.veinvector = OG_MapBlock->getOffset ("vein_vector"); off.local_feature_offset = OG_MapBlock->getOffset ("feature_local"); off.global_feature_offset = OG_MapBlock->getOffset ("feature_global"); off.temperature1_offset = OG_MapBlock->getOffset ("temperature1"); off.temperature2_offset = OG_MapBlock->getOffset ("temperature2"); } OffsetGroup *OG_Geology = OG_Maps->getGroup("geology"); { off.world_regions = OG_Geology->getAddress ("ptr2_region_array"); off.region_size = OG_Geology->getHexValue ("region_size"); off.region_geo_index_offset = OG_Geology->getOffset ("region_geo_index_off"); off.geolayer_geoblock_offset = OG_Geology->getOffset ("geolayer_geoblock_offset"); off.world_geoblocks_vector = OG_Geology->getAddress ("geoblock_vector"); off.type_inside_geolayer = OG_Geology->getOffset ("type_inside_geolayer"); } d->OG_global_features = OG_Maps->getGroup("features")->getGroup("global"); d->OG_local_features = OG_Maps->getGroup("features")->getGroup("local"); } d->OG_vector = mem->getGroup("vector"); // these can (will) fail and will be found when looking at the actual veins later // basically a cache off.vein_ice_vptr = 0; mem->resolveClassnameToVPtr("block_square_event_frozen_liquid", off.vein_ice_vptr); off.vein_mineral_vptr = 0; mem->resolveClassnameToVPtr("block_square_event_mineral",off.vein_mineral_vptr); // upload offsets to SHM server if possible d->maps_module = 0; if(p->getModuleIndex("Maps2010",1,d->maps_module)) { // supply the module with offsets so it can work with them Server::Maps::maps_offsets *off2 = SHMDATA(Server::Maps::maps_offsets); memcpy(off2, &(d->offsets), sizeof(Server::Maps::maps_offsets)); full_barrier const uint32_t cmd = Server::Maps::MAP_INIT + (d->maps_module << 16); p->SetAndWait(cmd); } d->Inited = true; }
Maps::Maps(DFContextShared* _d) { d = new Private; d->d = _d; Process *p = d->owner = _d->p; d->Inited = d->FeaturesStarted = d->Started = false; d->block = NULL; d->usesWorldDataPtr = false; DFHack::VersionInfo * mem = p->getDescriptor(); Private::t_offsets &off = d->offsets; d->hasFeatures = d->hasGeology = d->hasVeggies = true; // get the offsets once here OffsetGroup *OG_Maps = mem->getGroup("Maps"); try { off.world_data = OG_Maps->getAddress("world_data"); d->usesWorldDataPtr = true; //cout << "uses world ptr" << endl; }catch(Error::AllMemdef &){} { off.map_offset = OG_Maps->getAddress ("map_data"); off.x_count_offset = OG_Maps->getAddress ("x_count_block"); off.y_count_offset = OG_Maps->getAddress ("y_count_block"); off.z_count_offset = OG_Maps->getAddress ("z_count_block"); off.region_x_offset = OG_Maps->getAddress ("region_x"); off.region_y_offset = OG_Maps->getAddress ("region_y"); off.region_z_offset = OG_Maps->getAddress ("region_z"); if(d->usesWorldDataPtr) { off.world_size_x = OG_Maps->getOffset ("world_size_x_from_wdata"); off.world_size_y = OG_Maps->getOffset ("world_size_y_from_wdata"); } else { off.world_size_x = OG_Maps->getAddress ("world_size_x"); off.world_size_y = OG_Maps->getAddress ("world_size_y"); } OffsetGroup *OG_MapBlock = OG_Maps->getGroup("block"); { off.tile_type_offset = OG_MapBlock->getOffset ("type"); off.designation_offset = OG_MapBlock->getOffset ("designation"); off.occupancy_offset = OG_MapBlock->getOffset("occupancy"); off.biome_stuffs = OG_MapBlock->getOffset ("biome_stuffs"); off.veinvector = OG_MapBlock->getOffset ("vein_vector"); off.local_feature_offset = OG_MapBlock->getOffset ("feature_local"); off.global_feature_offset = OG_MapBlock->getOffset ("feature_global"); off.temperature1_offset = OG_MapBlock->getOffset ("temperature1"); off.temperature2_offset = OG_MapBlock->getOffset ("temperature2"); } try { off.mystery = OG_MapBlock->getOffset ("mystery_offset"); } catch(Error::AllMemdef &) { off.mystery = 0; } try { OffsetGroup *OG_Geology = OG_Maps->getGroup("geology"); if(d->usesWorldDataPtr) { off.world_regions = OG_Geology->getOffset ("ptr2_region_array_from_wdata"); off.world_geoblocks_vector = OG_Geology->getOffset ("geoblock_vector_from_wdata"); } else { off.world_regions = OG_Geology->getAddress ("ptr2_region_array"); off.world_geoblocks_vector = OG_Geology->getAddress ("geoblock_vector"); } off.region_size = OG_Geology->getHexValue ("region_size"); off.region_geo_index_offset = OG_Geology->getOffset ("region_geo_index_off"); off.geolayer_geoblock_offset = OG_Geology->getOffset ("geolayer_geoblock_offset"); off.type_inside_geolayer = OG_Geology->getOffset ("type_inside_geolayer"); } catch(Error::AllMemdef &) { d->hasGeology = false; } OffsetGroup *OG_global_features = OG_Maps->getGroup("features")->getGroup("global"); OffsetGroup *OG_local_features = OG_Maps->getGroup("features")->getGroup("local"); try { if(d->usesWorldDataPtr) { off.local_f_start = OG_local_features->getOffset("start_ptr_from_wdata"); off.global_vector = OG_global_features->getOffset("vector_from_wdata"); } else { off.local_f_start = OG_local_features->getAddress("start_ptr"); off.global_vector = OG_global_features->getAddress("vector"); } off.local_material = OG_local_features->getOffset("material"); off.local_submaterial = OG_local_features->getOffset("submaterial"); off.global_funcptr = OG_global_features->getOffset("funcptr"); off.global_material = OG_global_features->getOffset("material"); off.global_submaterial = OG_global_features->getOffset("submaterial"); } catch(Error::AllMemdef &) { d->hasFeatures = false; } try { OffsetGroup * OG_Veg = d->d->offset_descriptor->getGroup("Vegetation"); off.vegvector = OG_MapBlock->getOffset ("vegetation_vector"); off.tree_desc_offset = OG_Veg->getOffset ("tree_desc_offset"); } catch(Error::AllMemdef &) { d->hasVeggies = false; } } d->OG_vector = mem->getGroup("vector"); // these can (will) fail and will be found when looking at the actual veins later // basically a cache off.vein_ice_vptr = 0; mem->resolveClassnameToVPtr("block_square_event_frozen_liquid", off.vein_ice_vptr); off.vein_mineral_vptr = 0; mem->resolveClassnameToVPtr("block_square_event_mineral",off.vein_mineral_vptr); off.vein_spatter_vptr = 0; mem->resolveClassnameToVPtr("block_square_event_material_spatterst",off.vein_spatter_vptr); off.vein_grass_vptr = 0; mem->resolveClassnameToVPtr("block_square_event_grassst",off.vein_grass_vptr); off.vein_worldconstruction_vptr = 0; mem->resolveClassnameToVPtr("block_square_event_world_constructionst",off.vein_worldconstruction_vptr); d->Inited = true; }
int main (void) { string select; DFHack::ContextManager DFMgr("Memory.xml"); DFHack::Context * DF = DFMgr.getSingleContext(); try { DF->Attach(); } catch (exception& e) { cerr << e.what() << endl; #ifndef LINUX_BUILD cin.ignore(); #endif return 1; } DFHack::Process * p = DF->getProcess(); vector <DFHack::t_memrange> selected_ranges; getRanges(p,selected_ranges); DFHack::VersionInfo *minfo = DF->getMemoryInfo(); DFHack::OSType os = minfo->getOS(); string prompt = "Select search type: 1=number(default), 2=vector by length, 3=vector>object>string,\n" " 4=string, 5=automated offset search, 6=vector by address in its array,\n" " 7=pointer vector by address of an object, 8=vector>first object>string\n" " 9=string buffers, 10=known data, 11=backpointers, 12=data+backpointers\n"; int mode; do { getNumber(prompt,mode, 1, false); } while (mode < 1 || mode > 12 ); switch (mode) { case 1: DF->Detach(); FindIntegers(DFMgr, selected_ranges); break; case 2: DF->Detach(); FindVectorByLength(DFMgr, selected_ranges); break; case 3: DF->Detach(); FindVectorByObjectRawname(DFMgr, selected_ranges); break; case 4: DF->Detach(); FindStrings(DFMgr, selected_ranges); break; case 5: autoSearch(DF,selected_ranges); break; case 6: DF->Detach(); FindVectorByBounds(DFMgr,selected_ranges); break; case 7: DF->Detach(); FindPtrVectorsByObjectAddress(DFMgr,selected_ranges); break; case 8: DF->Detach(); FindVectorByFirstObjectRawname(DFMgr, selected_ranges); break; case 9: DF->Detach(); FindStrBufs(DFMgr, selected_ranges); break; case 10: DF->Detach(); FindData(DFMgr, selected_ranges); break; case 11: DF->Detach(); PtrTrace(DFMgr, selected_ranges); break; case 12: DF->Detach(); DataPtrTrace(DFMgr, selected_ranges); break; default: cout << "not implemented :(" << endl; } #ifndef LINUX_BUILD cout << "Done. Press any key to continue" << endl; cin.ignore(); #endif return 0; }
Maps::Maps() { Core & c = Core::getInstance(); d = new Private; Process *p = d->owner = c.p; d->Inited = d->FeaturesStarted = d->Started = false; DFHack::VersionInfo * mem = c.vinfo; Private::t_offsets &off = d->offsets; d->hasFeatures = d->hasGeology = d->hasVeggies = true; // get the offsets once here OffsetGroup *OG_Maps = mem->getGroup("Maps"); off.world_data = OG_Maps->getAddress("world_data"); { mdata = (map_data *) OG_Maps->getAddress ("map_data"); off.world_size_x = OG_Maps->getOffset ("world_size_x_from_wdata"); off.world_size_y = OG_Maps->getOffset ("world_size_y_from_wdata"); try { OffsetGroup *OG_Geology = OG_Maps->getGroup("geology"); off.world_regions = OG_Geology->getOffset ("ptr2_region_array_from_wdata"); off.world_geoblocks_vector = OG_Geology->getOffset ("geoblock_vector_from_wdata"); off.region_size = OG_Geology->getHexValue ("region_size"); off.region_geo_index_offset = OG_Geology->getOffset ("region_geo_index_off"); off.geolayer_geoblock_offset = OG_Geology->getOffset ("geolayer_geoblock_offset"); off.type_inside_geolayer = OG_Geology->getOffset ("type_inside_geolayer"); } catch(Error::AllMemdef &) { d->hasGeology = false; } OffsetGroup *OG_global_features = OG_Maps->getGroup("features")->getGroup("global"); OffsetGroup *OG_local_features = OG_Maps->getGroup("features")->getGroup("local"); try { off.local_f_start = OG_local_features->getOffset("start_ptr_from_wdata"); off.global_vector = OG_global_features->getOffset("vector_from_wdata"); off.local_material = OG_local_features->getOffset("material"); off.local_submaterial = OG_local_features->getOffset("submaterial"); off.global_funcptr = OG_global_features->getOffset("funcptr"); off.global_material = OG_global_features->getOffset("material"); off.global_submaterial = OG_global_features->getOffset("submaterial"); } catch(Error::AllMemdef &) { d->hasFeatures = false; } } d->OG_vector = mem->getGroup("vector"); // these can (will) fail and will be found when looking at the actual veins later // basically a cache off.vein_ice_vptr = 0; mem->resolveClassnameToVPtr("block_square_event_frozen_liquid", off.vein_ice_vptr); off.vein_mineral_vptr = 0; mem->resolveClassnameToVPtr("block_square_event_mineral",off.vein_mineral_vptr); off.vein_spatter_vptr = 0; mem->resolveClassnameToVPtr("block_square_event_material_spatterst",off.vein_spatter_vptr); off.vein_grass_vptr = 0; mem->resolveClassnameToVPtr("block_square_event_grassst",off.vein_grass_vptr); off.vein_worldconstruction_vptr = 0; mem->resolveClassnameToVPtr("block_square_event_world_constructionst",off.vein_worldconstruction_vptr); d->Inited = true; }
int main (int argc, char *argv[]) { bool print_refs = false; bool print_hex = false; bool print_acc = false; for(int i = 1; i < argc; i++) { char *arg = argv[i]; if (arg[0] != '-') continue; for (; *arg; arg++) { switch (arg[0]) { case 'r': print_refs = true; break; case 'x': print_hex = true; break; case 'a': print_acc = true; break; } } } DFHack::Process * p; 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::Materials * Materials = DF->getMaterials(); Materials->ReadAllMaterials(); DFHack::Gui * Gui = DF->getGui(); DFHack::Items * Items = DF->getItems(); Items->Start(); DFHack::VersionInfo * mem = DF->getMemoryInfo(); p = DF->getProcess(); int32_t x,y,z; Gui->getCursorCoords(x,y,z); std::vector<uint32_t> p_items; Items->readItemVector(p_items); uint32_t size = p_items.size(); // FIXME: tools should never be exposed to DFHack internals! DFHack::OffsetGroup* itemGroup = mem->getGroup("Items"); uint32_t ref_vector = itemGroup->getOffset("item_ref_vector"); for(size_t i = 0; i < size; i++) { DFHack::dfh_item itm; memset(&itm, 0, sizeof(DFHack::dfh_item)); Items->readItem(p_items[i],itm); if (x != -30000 && !(itm.base.x == x && itm.base.y == y && itm.base.z == z && itm.base.flags.on_ground && !itm.base.flags.in_chest && !itm.base.flags.in_inventory && !itm.base.flags.in_building)) continue; printf( "%5d: %08x %6d %08x (%d,%d,%d) #%08x [%d] *%d %s - %s\n", i, itm.origin, itm.id, itm.base.flags.whole, itm.base.x, itm.base.y, itm.base.z, itm.base.vtable, itm.wear_level, itm.quantity, Items->getItemClass(itm).c_str(), Items->getItemDescription(itm, Materials).c_str() ); if (print_hex) hexdump(DF,p_items[i],0x300); if (print_acc) cout << Items->dumpAccessors(itm) << endl; if (print_refs) { DFHack::DfVector<uint32_t> p_refs(p, itm.origin + ref_vector); for (size_t j = 0; j < p_refs.size(); j++) { uint32_t vptr = p->readDWord(p_refs[j]); uint32_t val = p->readDWord(p_refs[j]+4); printf("\t-> %d \t%s\n", int(val), p->readClassName(vptr).c_str()); } } } #ifndef LINUX_BUILD cout << "Done. Press any key to continue" << endl; cin.ignore(); #endif return 0; }