diff --git a/needs_porting/copypaste.cpp b/needs_porting/copypaste.cpp deleted file mode 100644 index 4f584241e..000000000 --- a/needs_porting/copypaste.cpp +++ /dev/null @@ -1,479 +0,0 @@ -// Console version of DF copy paste, proof of concept -// By belal - -#include -#include -#include -#include -#include -#include -#include -#include - -#define DFHACK_WANT_MISCUTILS -#define DFHACK_WANT_TILETYPES -#include -#include "modules/WindowIO.h" - -using namespace DFHack; -//bool waitTillCursorState(DFHack::Context *DF, bool On); -//bool waitTillCursorPositionState(DFHack::Context *DF, int32_t x,int32_t y, int32_t z); - -//change this if you are having problems getting correct results, lower if you would like to go faster -//const int WAIT_AMT = 25; - -void sort(uint32_t &a,uint32_t &b) -{ - if(a > b){ - uint32_t c = b; - b = a; - a = c; - } -} -void sort(int32_t &a,int32_t &b) -{ - if(a > b){ - int16_t c = b; - b = a; - a = c; - } -} -void printVecOfVec(ostream &out, vector > >vec,char sep) -{ - for(size_t k=0;k 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 > >dig(cz2-cz1+1,vector >(cy2-cy1+1,vector(cx2-cx1+1))); - vector > >build(cz2-cz1+1,vector >(cy2-cy1+1,vector(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 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; -} -/* -bool waitTillCursorState(DFHack::Context *DF, bool On) -{ - DFHack::WindowIO * w = DF->getWindowIO(); - DFHack::Position * p = DF->getPosition(); - int32_t x,y,z; - int tryCount = 0; - DF->Suspend(); - bool cursorResult = p->getCursorCoords(x,y,z); - while(tryCount < 50 && On && !cursorResult || !On && cursorResult) - { - DF->Resume(); - w->TypeSpecial(DFHack::WAIT,1,WAIT_AMT); - tryCount++; - DF->Suspend(); - cursorResult = p->getCursorCoords(x,y,z); - } - if(tryCount >= 50) - { - cerr << "Something went wrong, cursor at x: " << x << " y: " << y << " z: " << z << endl; - return false; - } - DF->Resume(); - return true; -} -bool waitTillCursorPositionState(DFHack::Context *DF, int32_t x,int32_t y, int32_t z) -{ - DFHack::WindowIO * w = DF->getWindowIO(); - DFHack::Position * p = DF->getPosition(); - int32_t x2,y2,z2; - int tryCount = 0; - DF->Suspend(); - bool cursorResult = p->getCursorCoords(x2,y2,z2); - while(tryCount < 50 && (x != x2 || y != y2 || z != z2)) - { - DF->Resume(); - w->TypeSpecial(DFHack::WAIT,1,WAIT_AMT); - tryCount++; - DF->Suspend(); - cursorResult = p->getCursorCoords(x2,y2,z2); - } - if(tryCount >= 50) - { - cerr << "Something went wrong, cursor at x: " << x2 << " y: " << y2 << " z: " << z2 << endl; - return false; - } - DF->Resume(); - return true; -}*/ \ No newline at end of file diff --git a/needs_porting/creaturemanager.cpp b/needs_porting/creaturemanager.cpp deleted file mode 100644 index 0d65e9f6e..000000000 --- a/needs_porting/creaturemanager.cpp +++ /dev/null @@ -1,1428 +0,0 @@ -/********************************************* - * Purpose: - * - * - Display creatures - * - Modify skills and labors of creatures - * - Kill creatures - * - Etc. - * - * Version: 0.1.1 - * Date: 2011-04-07 - * Author: raoulxq (based on creaturedump.cpp from peterix) - - * Todo: - * - Option to add/remove single skills - * - Ghosts/Merchants/etc. should be tagged as not own creatures - * - Filter by nickname with -n - * - Filter by first name with -fn - * - Filter by last name with -ln - * - Add pattern matching (or at least matching) to -n/-fn/-ln - * - Set nickname with --setnick (only if -i is given) - * - Show skills/labors only when -ss/-sl/-v is given or a skill/labor is changed - * - Make -1 the default for everything but -i - * - Imply -i if first argument is a number - * - Search for nick/profession if first argument is a string without - (i.e. no switch) - * - Switch --showhappy (show dwarf's experiences which make her un-/happy) - * - Switch --makefriendly - * - Switch --listskills, showing first 3 important skills - - * Done: - * - More space for "Current Job" - * - Attempted to revive creature(s) with --revive, but it doesn't work (flag is there but invisible) - * - Switch -rcs, remove civil skills - * - Switch -rms, remove military skills (who would want that?) - * - Allow comma separated list of IDs for -i - * - '-c all' shows all creatures - * - Rename from skillmodify.cpp to creature.cpp - * - Kill creature(s) with --kill - * - Hide skills with level 0 and 0 experience points - * - Add --showallflags flag to display all flags (default: display a few important ones) - * - Add --showdead flag to also display dead creatures - * - Display more creature flags - * - Show creature type (again) - * - Add switch -1/--summary to only display one line for every creature. Good for an overview. - * - Display current job (has been there all the time, but not shown in Windows due to missing memory offsets) - * - Remove magic numbers - * - Show social skills only when -ss is given - * - Hide hauler labors when +sh is given - * - Add -v for verbose - * - Override forbidden mass-designation with -f - * - Option to add/remove single labors - * - Switches -ras and rl should only be possible with -nn or -i - * - Switch -rh removes hauler jobs - * - Dead creatures should not be displayed - * - Childs should not get labors assigned to - * - Babies should not get labors assigned to - * - Switch -al adds labor number n - * - Switch -rl removes labor number n - * - Switch -ral removes all labors - * - Switch -ll lists all available labors - ********************************************* -*/ - -#include -#include -#include -#include -#include -#include -using namespace std; - -#define DFHACK_WANT_MISCUTILS -#include -#include - -/* Note about magic numbers: - * If you have an idea how to better solve this, tell me. Currently I'd be - * either dependent on Toady One's implementation (#defining numbers) or - * Memory.xml (#defining text). I voted for Toady One's numbers to be more - * stable, but could be wrong. - * - * Ideally there would be a flag "is_military" or "is_social" in Memory.xml. - */ - -/* Social skills */ -#define SKILL_PERSUASION 72 -#define SKILL_NEGOTIATION 73 -#define SKILL_JUDGING_INTENT 74 -#define SKILL_INTIMIDATION 79 -#define SKILL_CONVERSATION 80 -#define SKILL_COMEDY 81 -#define SKILL_FLATTERY 82 -#define SKILL_CONSOLING 83 -#define SKILL_PACIFICATION 84 - -/* Misc skills */ -#define SKILL_WEAPONSMITHING 27 -#define SKILL_ARMORSMITHING 28 -#define SKILL_RECORD_KEEPING 77 -#define SKILL_WAX_WORKING 115 - -/* Some military skills */ -#define SKILL_COORDINATION 95 -#define SKILL_BALANCE 96 -#define SKILL_LEADERSHIP 97 -#define SKILL_TEACHING 98 -#define SKILL_FIGHTING 99 -#define SKILL_ARCHERY 100 -#define SKILL_WRESTLING 101 -#define SKILL_BITING 102 -#define SKILL_STRIKING 103 -#define SKILL_KICKING 104 -#define SKILL_DODGING 105 - -#define LABOR_STONE_HAULING 1 -#define LABOR_WOOD_HAULING 2 -#define LABOR_BURIAL 3 -#define LABOR_FOOD_HAULING 4 -#define LABOR_REFUSE_HAULING 5 -#define LABOR_ITEM_HAULING 6 -#define LABOR_FURNITURE_HAULING 7 -#define LABOR_ANIMAL_HAULING 8 -#define LABOR_CLEANING 9 -#define LABOR_FEED_PATIENTS_PRISONERS 22 -#define LABOR_RECOVERING_WOUNDED 23 - -#define PROFESSION_CHILD 96 -#define PROFESSION_BABY 97 - -#define NOT_SET INT_MIN -#define MAX_MOOD 4 -#define NO_MOOD -1 - -bool quiet=true; -bool verbose = false; -bool showhauler = true; -bool showsocial = false; -bool showfirstlineonly = false; -bool showdead = false; -bool showallflags = false; - -int hauler_labors[] = { - LABOR_STONE_HAULING - ,LABOR_WOOD_HAULING - ,LABOR_BURIAL - ,LABOR_FOOD_HAULING - ,LABOR_REFUSE_HAULING - ,LABOR_ITEM_HAULING - ,LABOR_FURNITURE_HAULING - ,LABOR_ANIMAL_HAULING - ,LABOR_CLEANING - ,LABOR_FEED_PATIENTS_PRISONERS - ,LABOR_RECOVERING_WOUNDED -}; - -int social_skills[] = -{ - SKILL_PERSUASION - ,SKILL_NEGOTIATION - ,SKILL_JUDGING_INTENT - ,SKILL_INTIMIDATION - ,SKILL_CONVERSATION - ,SKILL_COMEDY - ,SKILL_FLATTERY - ,SKILL_CONSOLING - ,SKILL_PACIFICATION -}; - -int military_skills[] = -{ - SKILL_COORDINATION - ,SKILL_BALANCE - ,SKILL_LEADERSHIP - ,SKILL_TEACHING - ,SKILL_FIGHTING - ,SKILL_ARCHERY - ,SKILL_WRESTLING - ,SKILL_BITING - ,SKILL_STRIKING - ,SKILL_KICKING - ,SKILL_DODGING -}; - -void usage(int argc, const char * argv[]) -{ - cout - << "Usage:" << endl - << argv[0] << " [option 1] [option 2] [...]" << endl - << endl - << "Display options:" << endl - << "-q : Suppress \"Press any key to continue\" at program termination" << endl - << "-v : Increase verbosity" << endl - << endl - - << "Choosing which creatures to display and/or modify " - << "(note that all criteria" << endl << "must match, so adding " - << " more narrows things down):" << endl - << "-i id1[,id2,...]: Only show/modify creature with this id" << endl - << "-c creature : Show/modify this creature type instead of dwarves" << endl - << " ('all' to show all creatures)" << endl - << "-nn/--nonicks : Only show/modify creatures with no custom nickname (migrants)" << endl - << "--nicks : Only show/modify creatures with custom nickname" << endl - << "--showdead : Also show/modify dead creatures" << endl - << "--type : Show/modify all creatures of given type" << endl - << " : Can be used multiple times" << endl - << " types:" << endl - << " * dead: all dead creatures" << endl - << " * demon: all demons" << endl - << " * diplomat: all diplomats" << endl - << " * FB: all forgotten beasts" << endl - << " * female: all female creatures" << endl - << " * ghost: all ghosts" << endl - << " * male: all male creatures" << endl - << " * merchants: all merchants (including pack animals)" << endl - << " * neuter: all neuter creatuers" << endl - << " * pregnant: all pregnant creatures" << endl - << " * tame: all tame creatues" << endl - << " * wild: all wild creatures" << endl - - << endl - - << "What information to display:" << endl - << "-saf : Show all flags of a creature" << endl - << "--showallflags : Show all flags of a creature" << endl - << "-ll/--listlabors: List available labors" << endl - << "-ss : Show social skills" << endl - << "+sh : Hide hauler labors" << endl - << "-1/--summary : Only display one line per creature" << endl - - << endl - - << "Options to modify selected creatures:" << endl - << "-al : Add labor to creature" << endl - << "-rl : Remove labor from creature" << endl - << "-ras : Remove all skills from creature (i.e. set them to zero)" << endl - << "-rcs : Remove civil skills from creature (i.e. set them to zero)" << endl - << "-rms : Remove military skills from creature (i.e. set them to zero)" << endl - << "-ral : Remove all labors from creature" << endl - << "-ah : Add hauler labors (stone hauling, etc.) to creature" << endl - << "-rh : Remove hauler labors (stone hauling, etc.) from creature" << endl - // Disabling mood doesn't work as intented - << "--setmood : Set mood to n (-1 = no mood, max=4, buggy!)" << endl - << "--kill : Kill creature(s) (leaves behind corpses)" << endl - << "--erase : Remove creature(s) from game without killing" << endl - << "--tame : Tames animals, recruits intelligent creatures." << endl - << "--slaugher : Mark a creature for slaughter, even sentients" << endl - << "--butcher : Same as --slaugher" << endl - // Doesn't seem to work - //<< "--revive : Attempt to revive creature(s) (remove dead and killed flag)" << endl - // Setting happiness doesn't work really, because hapiness is recalculated - //<< "--sethappiness : Set happiness to n" << endl - << "-f : Force an action" << endl - << endl - << "Examples:" << endl - << endl - << "Show all dwarfs:" << endl - << argv[0] << " -c Dwarf" << endl - << endl - << "Show summary of all creatures (spoiler: includes unknown creatures):" << endl - << argv[0] << " -1 -c all" << endl - << endl - << "Kill that nasty ogre" << endl - << argv[0] << " -i 52 --kill" << endl - << endl - << "Check that the ogre is really dead" << endl - << argv[0] << " -c ogre --showdead" << endl - << endl - << "Remove all skills from dwarfs 15 and 32:" << endl - << argv[0] << " -i 15,32 -ras" << endl - << endl - << "Remove all skills and labors from dwarfs with no custom nickname:" << endl - << argv[0] << " -c DWARF -nn -ras -ral" << endl - << endl - << "Add hauling labors to all dwarfs without nickname (e.g. migrants):" << endl - << argv[0] << " -c DWARF -nn -ah" << endl - << endl - << "Show list of labor ids:" << endl - << argv[0] << " -c DWARF -ll" << endl - << endl - << "Add engraving labor to all dwarfs without nickname (get the labor id from the list above):" << endl - << argv[0] << " -c DWARF -nn -al 13" << endl - << endl - << "Make Urist, Stodir and Ingish miners:" << endl - << argv[0] << " -i 31,42,77 -al 0" << endl - << endl - << "Make all demons friendly:" << endl - << argv[0] << " --type demon --tame" << endl - ; - if (quiet == false) { - cout << "Press any key to continue" << endl; - cin.ignore(); - } -} - -DFHack::Materials * Materials; -DFHack::VersionInfo *mem; -DFHack::Creatures * Creatures = NULL; - -// Note that toCaps() changes the string itself and I'm using it a few times in -// an unsafe way below. Didn't crash yet however. -std::string toCaps(std::string s) -{ - const int length = s.length(); - std::locale loc(""); - bool caps=true; - if (length == 0) { - return s; - } - for(int i=0; i!=length ; ++i) - { - if (caps) - { - s[i] = std::toupper(s[i],loc); - caps = false; - } - else if (s[i] == '_' || s[i] == ' ') - { - s[i] = ' '; - caps = true; - } - else - { - s[i] = std::tolower(s[i],loc); - } - } - return s; -} - -int strtoint(const string &str) -{ - stringstream ss(str); - int result; - return ss >> result ? result : -1; -} - - -// A C++ standard library function should be used instead -bool is_in(int m, int set[], int set_size) -{ - for (int i=0; i v, int comp) -{ - for (size_t i=0; igetTranslation(); - 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 jobid; - stringstream ss; - ss << "(" << creature.current_job.jobId << ")"; - jobid = ss.str(); - - string job="No Job/On Break" + (creature.current_job.jobId == 0 ? "" : jobid); - 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) // Display numeric jobID if unknown job - { - job = jobid; - } - } - - if (showfirstlineonly) - { - printf("%3d", index); - printf(" %-17s", type.c_str()); - printf(" %-24s", name.c_str()); - printf(" %-16s", toCaps(profession).c_str()); - printf(" %-38s", 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"); - printf("Origin: %p\n", creature.origin); - printf("Civ #: %d\n", creature.civ); - } - - 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 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 &) - { - 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 (creature.pregnancy_timer > 0) - cout << "Pregnant: " << creature.pregnancy_timer << " ticks to " - << "birth." << endl; - - if (showallflags) - { - DFHack::t_creaturflags1 f1 = creature.flags1; - DFHack::t_creaturflags2 f2 = creature.flags2; - DFHack::t_creaturflags3 f3 = creature.flags3; - - if(f1.bits.dead){cout << "Flag: dead" << endl; } - if(f1.bits.had_mood){cout<TranslateName(creature.artifact_name,false); - cout << "Artifact: " << artifact_name << endl; - } - } - cout << endl; -} - -class creature_filter -{ -public: - - enum sex_filter - { - SEX_FEMALE = 0, - SEX_MALE = 1, - SEX_ANY = 254, // Our magin number for ignoring sex. - SEX_NEUTER = 255 - }; - - bool dead; - bool demon; - bool diplomat; - bool find_nonicks; - bool find_nicks; - bool forgotten_beast; - bool ghost; - bool merchant; - bool pregnant; - bool tame; - bool wild; - - sex_filter sex; - - string creature_type; - std::vector creature_id; - - #define DEFAULT_CREATURE_STR "Default" - - creature_filter() - { - // By default we only select dwarves, except that if we use the - // --type option we want to default to everyone. So we start out - // with a special string, and if remains unchanged after all - // the options have been processed we turn it to DWARF. - creature_type = DEFAULT_CREATURE_STR; - - dead = false; - demon = false; - diplomat = false; - find_nonicks = false; - find_nicks = false; - forgotten_beast = false; - ghost = false; - merchant = false; - pregnant = false; - sex = SEX_ANY; - tame = false; - wild = false; - } - - // If the creature type is still the default, then change it to allow - // for all creatures. If the creature type has been explicitly set, - // then don't alter it. - void defaultTypeToAll() - { - if (creature_type == DEFAULT_CREATURE_STR) - creature_type = ""; - } - - // If the creature type is still the default, change it to DWARF - void defaultTypeToDwarf() - { - if (creature_type == DEFAULT_CREATURE_STR) - creature_type = "Dwarf"; - } - - void process_type(string type) - { - type = toCaps(type); - - // If we're going by type, then by default all species are - // permitted. - defaultTypeToAll(); - - if (type == "Dead") - { - dead = true; - showdead = true; - } - else if (type == "Demon") - demon = true; - else if (type == "Diplomat") - diplomat = true; - else if (type == "Fb" || type == "Beast") - forgotten_beast = true; - else if (type == "Ghost") - ghost = true; - else if (type == "Merchant") - merchant = true; - else if (type == "Pregnant") - pregnant = true; - else if (type == "Tame") - tame = true; - else if (type == "Wild") - wild = true; - else if (type == "Male") - sex = SEX_MALE; - else if (type == "Female") - sex = SEX_FEMALE; - else if (type == "Neuter") - sex = SEX_NEUTER; - else - { - cerr << "ERROR: Unknown type '" << type << "'" << endl; - } - } - - void doneProcessingOptions() - { - string temp = toCaps(creature_type); - creature_type = temp; - - defaultTypeToDwarf(); - } - - bool creatureMatches(const DFHack::t_creature & creature, - uint32_t creature_idx) - { - // A list of ids overrides everything else. - if (creature_id.size() > 0) - return (find_int(creature_id, creature_idx)); - - // If it's not a list of ids, it has not match all given criteria. - - const DFHack::t_creaturflags1 &f1 = creature.flags1; - const DFHack::t_creaturflags2 &f2 = creature.flags2; - const DFHack::t_creaturflags3 &f3 = creature.flags3; - - if(f1.bits.dead && !showdead) - return false; - - bool hasnick = (creature.name.nickname[0] != '\0'); - if(hasnick && find_nonicks) - return false; - if(!hasnick && find_nicks) - return false; - - string race_name = string(Materials->raceEx[creature.race].rawname); - - if(!creature_type.empty() && creature_type != toCaps(race_name)) - return false; - - if(dead && !f1.bits.dead) - return false; - if(demon && !f2.bits.underworld) - return false; - if(diplomat && !f1.bits.diplomat) - return false; - if(forgotten_beast && !f2.bits.visitor_uninvited) - return false; - if(ghost && !f3.bits.ghostly) - return false; - if(merchant && !f1.bits.merchant) - return false; - if(pregnant && creature.pregnancy_timer == 0) - return false; - if (sex != SEX_ANY && creature.sex != (uint8_t) sex) - return false; - if(tame && !f1.bits.tame) - return false; - - if(wild && !f2.bits.roaming_wilderness_population_source && - !f2.bits.roaming_wilderness_population_source_not_a_map_feature) - { - return false; - } - - return true; - } -}; - -int main (int argc, const char* argv[]) -{ - // let's be more useful when double-clicked on windows -#ifndef LINUX_BUILD - quiet = false; -#endif - creature_filter filter; - - bool remove_skills = false; - bool remove_civil_skills = false; - bool remove_military_skills = false; - bool remove_labors = false; - bool kill_creature = false; - bool erase_creature = false; - bool revive_creature = false; - bool make_hauler = false; - bool remove_hauler = false; - bool add_labor = false; - int add_labor_n = NOT_SET; - bool remove_labor = false; - int remove_labor_n = NOT_SET; - bool set_happiness = false; - int set_happiness_n = NOT_SET; - bool set_mood = false; - int set_mood_n = NOT_SET; - bool list_labors = false; - bool force_massdesignation = false; - bool tame_creature = false; - bool slaughter_creature = false; - - if (argc == 1) { - usage(argc, argv); - return 1; - } - - for(int i = 1; i < argc; i++) - { - string arg_cur = argv[i]; - string arg_next = ""; - int arg_next_int = NOT_SET; - /* Check if argv[i+1] is a number >= 0 */ - if (i < argc-1) { - arg_next = argv[i+1]; - arg_next_int = strtoint(arg_next); - if (arg_next != "0" && arg_next_int == 0) { - arg_next_int = NOT_SET; - } - } - - if(arg_cur == "-q") - { - quiet = true; - } - else if(arg_cur == "+q") - { - quiet = false; - } - else if(arg_cur == "-v") - { - verbose = true; - } - else if(arg_cur == "-1" || arg_cur == "--summary") - { - showfirstlineonly = true; - } - else if(arg_cur == "-ss" || arg_cur == "--showsocial") - { - showsocial = true; - } - else if(arg_cur == "+sh" || arg_cur == "-nosh" || arg_cur == "--noshowhauler") - { - showhauler = false; - } - else if(arg_cur == "--showdead") - { - showdead = true; - } - else if(arg_cur == "--showallflags" || arg_cur == "-saf") - { - showallflags = true; - } - else if(arg_cur == "-ras") - { - remove_skills = true; - } - else if(arg_cur == "-rcs") - { - remove_civil_skills = true; - } - else if(arg_cur == "-rms") - { - remove_military_skills = true; - } - else if(arg_cur == "-f") - { - force_massdesignation = true; - } - // list labors - else if(arg_cur == "-ll" || arg_cur == "--listlabors") - { - list_labors = true; - } - // add single labor - else if(arg_cur == "-al" && i < argc-1) - { - if (arg_next_int == NOT_SET || arg_next_int >= NUM_CREATURE_LABORS) { - usage(argc, argv); - return 1; - } - add_labor = true; - add_labor_n = arg_next_int; - i++; - } - // remove single labor - else if(arg_cur == "-rl" && i < argc-1) - { - if (arg_next_int == NOT_SET || arg_next_int >= NUM_CREATURE_LABORS) { - usage(argc, argv); - return 1; - } - remove_labor = true; - remove_labor_n = arg_next_int; - i++; - } - else if(arg_cur == "--setmood" && i < argc-1) - { - if (arg_next_int < NO_MOOD || arg_next_int > MAX_MOOD) { - usage(argc, argv); - return 1; - } - set_mood = true; - set_mood_n = arg_next_int; - i++; - } - else if(arg_cur == "--sethappiness" && i < argc-1) - { - if (arg_next_int < 1 || arg_next_int >= 2000) { - usage(argc, argv); - return 1; - } - set_happiness = true; - set_happiness_n = arg_next_int; - i++; - } - else if(arg_cur == "--kill") - { - kill_creature = true; - showallflags = true; - showdead = true; - } - else if(arg_cur == "--erase") - { - erase_creature = true; - showallflags = true; - showdead = true; - } - else if(arg_cur == "--revive") - { - revive_creature = true; - showdead = true; - showallflags = true; - } - else if(arg_cur == "-ral") - { - remove_labors = true; - } - else if(arg_cur == "-ah") - { - make_hauler = true; - } - else if(arg_cur == "-rh") - { - remove_hauler = true; - } - else if(arg_cur == "-nn" || arg_cur == "--nonicks") - { - filter.find_nonicks = true; - } - else if(arg_cur == "--nicks") - { - filter.find_nicks = true; - } - else if(arg_cur == "-c" && i < argc-1) - { - filter.creature_type = argv[i+1]; - i++; - } - else if(arg_cur == "-i" && i < argc-1) - { - std::stringstream ss(argv[i+1]); - int num; - while (ss >> num) { - filter.creature_id.push_back(num); - ss.ignore(1); - } - - filter.creature_type = ""; // if -i is given, match all creatures - showdead = true; - i++; - } - else if(arg_cur == "--type" && i < argc-1) - { - filter.process_type(arg_next); - i++; - } - else if (arg_cur == "--tame") - tame_creature = true; - else if (arg_cur == "--slaugher" || arg_cur == "--butcher") - slaughter_creature = true; - else - { - if (arg_cur != "-h") { - cout << "Unknown option '" << arg_cur << "'" << endl; - cout << endl; - } - usage(argc, argv); - return 1; - } - } - - filter.doneProcessingOptions(); - - DFHack::ContextManager DFMgr("Memory.xml"); - DFHack::Context* DF; - try - { - DF = DFMgr.getSingleContext(); - DF->Attach(); - } - catch (exception& e) - { - cerr << e.what() << endl; - if (quiet == false) - { - cin.ignore(); - } - return 1; - } - - Creatures = DF->getCreatures(); - Materials = DF->getMaterials(); - DFHack::Translation * Tran = DF->getTranslation(); - - uint32_t numCreatures; - if(!Creatures->Start(numCreatures)) - { - cerr << "Can't get creatures" << endl; - if (quiet == false) - { - cin.ignore(); - } - return 1; - } - if(!numCreatures) - { - cerr << "No creatures to print" << endl; - if (quiet == false) - { - cin.ignore(); - } - return 1; - } - - mem = DF->getMemoryInfo(); - Materials->ReadInorganicMaterials(); - Materials->ReadOrganicMaterials(); - Materials->ReadWoodMaterials(); - Materials->ReadPlantMaterials(); - Materials->ReadCreatureTypes(); - Materials->ReadCreatureTypesEx(); - Materials->ReadDescriptorColors(); - - if(!Tran->Start()) - { - cerr << "Can't get name tables" << endl; - return 1; - } - - // List all available labors (reproduces contents of Memory.xml) - if (list_labors == true) { - string laborname; - for (int i=0; i < NUM_CREATURE_LABORS; i++) { - try { - laborname = mem->getLabor(i); - cout << "Labor " << int(i) << ": " << laborname << endl; - } - catch (exception&) { - if (verbose) - { - laborname = "Unknown"; - cout << "Labor " << int(i) << ": " << laborname << endl; - } - } - } - } - else - { - if (showfirstlineonly) - { - printf("ID Type Name/nickname Job title Current job Happy%s\n", showdead?" Dead ":""); - printf("--- ----------------- ------------------------ ---------------- -------------------------------------- -----%s\n", showdead?" -----":""); - } - - vector addrs; - for(uint32_t creature_idx = 0; creature_idx < numCreatures; creature_idx++) - { - DFHack::t_creature creature; - Creatures->ReadCreature(creature_idx,creature); - /* Check if we want to display/change this creature or skip it */ - if(filter.creatureMatches(creature, creature_idx)) - { - printCreature(DF,creature,creature_idx); - addrs.push_back(creature.origin); - - bool dochange = ( - remove_skills || remove_civil_skills || remove_military_skills - || remove_labors || add_labor || remove_labor - || make_hauler || remove_hauler - || kill_creature || erase_creature - || revive_creature - || set_happiness - || set_mood - || tame_creature || slaughter_creature - ); - - if (toCaps(filter.creature_type) == "Dwarf" - && (creature.profession == PROFESSION_CHILD || creature.profession == PROFESSION_BABY)) - { - dochange = false; - } - - bool allow_massdesignation = - filter.creature_id.size()==0 || - toCaps(filter.creature_type) != "Dwarf" || - filter.find_nonicks == true || - force_massdesignation; - if (dochange == true && allow_massdesignation == false) - { - cout - << "Not changing creature because none of -c (other than dwarf), -i or -nn was" << endl - << "selected. Add -f (force) to override this safety measure." << endl; - dochange = false; - } - - if (dochange) - { - if(creature.has_default_soul) - { - if (kill_creature && !creature.flags1.bits.dead) - { - DFHack::t_creaturflags1 f1 = creature.flags1; - DFHack::t_creaturflags2 f2 = creature.flags2; - DFHack::t_creaturflags3 f3 = creature.flags3; - - f3.bits.scuttle = true; - - cout << "Writing flags..." << endl; - if (!Creatures->WriteFlags(creature_idx, f1.whole, - f2.whole, f3.whole)) - { - cout << "Error writing creature flags!" << endl; - } - // We want the flags to be shown after our - // modification, but they are not read back - creature.flags1 = f1; - creature.flags2 = f2; - creature.flags3 = f3; - } - - if (erase_creature && !creature.flags1.bits.dead) - { - /* - [quote author=Eldrick Tobin link=topic=58809.msg2178545#msg2178545 date=1302638055] - - After extensive testing that just ate itself -.-; - - Runesmith does not unset the following: - - Active Invader (sets if they are just about the invade, as Currently - Invading removes this one) - - Hidden Ambusher (Just in Case, however it is still set when an Active Invader) - - Hidden in Ambush (Just in Case, however it is still set when an Active Invader, - until discovery) - - Incoming (Sets if something is here yet... wave X of a siege here) - - Invader -Fleeing/Leaving - - Currently Invading - - When it nukes something it basically just sets them to 'dead'. It does not also - set them to 'killed'. Show dead will show everything (short of 'vanished'/'deleted' - I'd suspect) so one CAN go through the intensive process to revive a broken siege. These - particular flags are not visible at the same exact time so multiple passes -even through - a narrow segment- are advised. - - Problem I ran into (last thing before I mention something more DFHack related): - I set the Killed Flag (but not dead), and I got mortally wounded siegers that refused to - just pift in Magma. [color=purple]Likely missing upper torsoes on examination[/color]. - - */ - /* This is from an invading creature's flags: - - ID: 560, Crocodile Cave, Nako, Standard, Job: No Job, Happiness: 100 - Flag: Marauder - Flag: Can Swap - Flag: Active Invader - Flag: Invader Origin - Flag: Coward - Flag: Hidden Ambusher - Flag: Invades - Flag: Ridden - Flag: Calculated Nerves - Flag: Calculated Bodyparts - Flag: Calculated Insulation - Flag: Vision Good - Flag: Breathing Good - - */ - - DFHack::t_creaturflags1 f1 = creature.flags1; - DFHack::t_creaturflags2 f2 = creature.flags2; - - f1.bits.dead = 1; - f2.bits.killed = 1; - f1.bits.active_invader = 0; /*!< 17: Active invader (for organized ones) */ - f1.bits.hidden_ambusher = 0; /*!< 21: Active marauder/invader moving inward? */ - f1.bits.hidden_in_ambush = 0; - f1.bits.invades = 0; /*!< 22: Marauder resident/invader moving in all the way */ - - cout << "Writing flags..." << endl; - if (!Creatures->WriteFlags(creature_idx, f1.whole, f2.whole)) - { - cout << "Error writing creature flags!" << endl; - } - // We want the flags to be shown after our modification, but they are not read back - creature.flags1 = f1; - creature.flags2 = f2; - } - - - if (revive_creature && creature.flags1.bits.dead) - { - DFHack::t_creaturflags1 f1 = creature.flags1; - DFHack::t_creaturflags2 f2 = creature.flags2; - - f1.bits.dead = 0; - f2.bits.killed = 0; - f1.bits.active_invader = 1; /*!< 17: Active invader (for organized ones) */ - f1.bits.hidden_ambusher = 1; /*!< 21: Active marauder/invader moving inward? */ - f1.bits.hidden_in_ambush = 1; - f1.bits.invades = 1; /*!< 22: Marauder resident/invader moving in all the way */ - - cout << "Writing flags..." << endl; - if (!Creatures->WriteFlags(creature_idx, f1.whole, f2.whole)) - { - cout << "Error writing creature flags!" << endl; - } - // We want the flags to be shown after our modification, but they are not read back - creature.flags1 = f1; - creature.flags2 = f2; - } - - if (set_mood) - { - /* Doesn't really work to disable a mood */ - cout << "Setting mood to " << set_mood_n << "..." << endl; - Creatures->WriteMood(creature_idx, set_mood_n); - DFHack::t_creaturflags1 f1 = creature.flags1; - DFHack::t_creaturflags2 f2 = creature.flags2; - f1.bits.has_mood = (set_mood_n == NO_MOOD ? 0 : 1); - if (!Creatures->WriteFlags(creature_idx, f1.whole, f2.whole)) - { - cout << "Error writing creature flags!" << endl; - } - creature.flags1 = f1; - creature.flags2 = f2; - } - - if (set_happiness) - { - cout << "Setting happiness to " << set_happiness_n << "..." << endl; - Creatures->WriteHappiness(creature_idx, set_happiness_n); - } - - if (remove_skills || remove_civil_skills || remove_military_skills) - { - DFHack::t_soul & soul = creature.defaultSoul; - - cout << "Removing skills..." << endl; - - for(unsigned int sk = 0; sk < soul.numSkills;sk++) - { - bool is_military = is_in(soul.skills[sk].id, military_skills, sizeof(military_skills)/sizeof(military_skills[0])); - if (remove_skills - || (remove_civil_skills && !is_military) - || (remove_military_skills && is_military)) - { - soul.skills[sk].rating=0; - soul.skills[sk].experience=0; - } - } - - // Doesn't work anyways, so better leave it alone - //soul.numSkills=0; - if (Creatures->WriteSkills(creature_idx, soul) == true) { - cout << "Success writing skills." << endl; - } else { - cout << "Error writing skills." << endl; - } - } - - if (add_labor || remove_labor || remove_labors || make_hauler || remove_hauler) - { - if (add_labor) { - cout << "Adding labor " << add_labor_n << "..." << endl; - creature.labors[add_labor_n] = 1; - } - - if (remove_labor) { - cout << "Removing labor " << remove_labor_n << "..." << endl; - creature.labors[remove_labor_n] = 0; - } - - if (remove_labors) { - cout << "Removing labors..." << endl; - for(unsigned int lab = 0; lab < NUM_CREATURE_LABORS; lab++) { - creature.labors[lab] = 0; - } - } - - if (remove_hauler) { - for (int labs=0; - labs < sizeof(hauler_labors)/sizeof(hauler_labors[0]); - labs++) - { - creature.labors[hauler_labors[labs]] = 0; - } - } - - if (make_hauler) { - cout << "Setting hauler labors..." << endl; - for (int labs=0; - labs < sizeof(hauler_labors)/sizeof(hauler_labors[0]); - labs++) - { - creature.labors[hauler_labors[labs]] = 1; - } - } - if (Creatures->WriteLabors(creature_idx, creature.labors) == true) { - cout << "Success writing labors." << endl; - } else { - cout << "Error writing labors." << endl; - } - } - - if (tame_creature) - { - bool tame = true; - - DFHack::t_creaturflags1 f1 = creature.flags1; - DFHack::t_creaturflags2 f2 = creature.flags2; - - // Site residents are intelligent, so don't - // tame them. - if (f2.bits.resident) - tame = false; - - f1.bits.diplomat = false; - f1.bits.merchant = false; - f2.bits.resident = false; - f2.bits.underworld = false; - f2.bits.visitor_uninvited = false; - f2.bits.roaming_wilderness_population_source = false; - f2.bits.roaming_wilderness_population_source_not_a_map_feature = false; - - // Creatures which already belong to a civ might - // be intelligent, so don't tame them. - if (creature.civ == -1) - f1.bits.tame = tame; - - if (!Creatures->WriteFlags(creature_idx, - f1.whole, f2.whole)) - { - cout << "Error writing creature flags!" << endl; - } - - int32_t civ = Creatures->GetDwarfCivId(); - if (!Creatures->WriteCiv(creature_idx, civ)) - { - cout << "Error writing creature civ!" << endl; - } - creature.flags1 = f1; - creature.flags2 = f2; - } - - if (slaughter_creature) - { - DFHack::t_creaturflags1 f1 = creature.flags1; - DFHack::t_creaturflags2 f2 = creature.flags2; - - f2.bits.slaughter = true; - - if (!Creatures->WriteFlags(creature_idx, - f1.whole, f2.whole)) - { - cout << "Error writing creature flags!" << endl; - } - creature.flags1 = f1; - creature.flags2 = f2; - } - } - else - { - cout << "Error removing skills: Creature has no default soul." << endl; - } - printCreature(DF,creature,creature_idx); - } /* End remove skills/labors */ - } /* if (print creature) */ - } /* End for(all creatures) */ - } /* End if (we need to walk creatures) */ - - Creatures->Finish(); - DF->Detach(); - if (quiet == false) - { - cout << "Done. Press any key to continue" << endl; - cin.ignore(); - } - return 0; -}