From 4eb13800cdbd17071ce57da1aa76893dc9bc3c16 Mon Sep 17 00:00:00 2001 From: zilpin Date: Mon, 18 Jul 2011 15:55:41 -0400 Subject: [PATCH] -WriteVein(), and some convenience functions for the vein bitmaps. --- library/include/dfhack/modules/Maps.h | 26 ++- library/modules/Maps.cpp | 20 +++ tools/playground/veinswap.cpp | 226 +++++++++++++++++++++++++- 3 files changed, 270 insertions(+), 2 deletions(-) diff --git a/library/include/dfhack/modules/Maps.h b/library/include/dfhack/modules/Maps.h index 0e6f3c2e7..b46a40b8c 100644 --- a/library/include/dfhack/modules/Maps.h +++ b/library/include/dfhack/modules/Maps.h @@ -120,6 +120,7 @@ namespace DFHack uint32_t origin; }; + /** * mineral vein object - bitmap with a material type * \ingroup grp_maps @@ -135,6 +136,26 @@ namespace DFHack uint32_t flags; /// this is NOT part of the DF vein, but an address of the vein as seen by DFhack. uint32_t address_of; + + + //zilpin: Functions to more conveniently check the assignment flags of the vein. + //Coordinates are given in tile within the block. + //Important to make these inline. + inline int getassignment( DFCoord xy ){ + return getassignment(xy.x,xy.y); + } + inline int getassignment( int x, int y ){ + return (assignment[y] & (1 << x)); + } + inline void setassignment( DFCoord xy, int bit ){ + return setassignment(xy.x,xy.y, bit); + } + inline void setassignment( int x, int y, int bit ){ + if(bit) + assignment[y] |= (1 << x); + else + assignment[y] &= 0xFFFF ^ (1 << x); + } }; /** @@ -652,7 +673,10 @@ namespace DFHack std::vector* grass = 0, std::vector* constructions = 0 ); - /// read all plants in this block + /// write a single vein back to the address it was retreived from + bool Maps::WriteVein(t_vein *vein); + + /// read all plants in this block bool ReadVegetation(uint32_t x, uint32_t y, uint32_t z, std::vector* plants); private: struct Private; diff --git a/library/modules/Maps.cpp b/library/modules/Maps.cpp index 76e9f5e6c..28fec081d 100644 --- a/library/modules/Maps.cpp +++ b/library/modules/Maps.cpp @@ -1043,6 +1043,26 @@ bool Maps::ReadVeins(uint32_t x, uint32_t y, uint32_t z, vector * veins, return true; } +/* +Write the vein retreived using ReadVeins back to the address it was taken from. +*/ +bool Maps::WriteVein(t_vein *vein) +{ + if(!vein) return false; + Process* p = d->owner; + + //Write each part individually. + p->writeDWord(vein->address_of + 4 , vein->type ); + p->write( vein->address_of + 8 , 32 , (uint8_t *)vein->assignment ); + p->writeDWord(vein->address_of + 40 , vein->flags ); + + return true; +} + +#include + + + /* __int16 __userpurge GetGeologicalRegion(__int16 block_X, int X, __int16 block_Y, int block_addr, int Y) { diff --git a/tools/playground/veinswap.cpp b/tools/playground/veinswap.cpp index 85cd34d07..47b83bb82 100644 --- a/tools/playground/veinswap.cpp +++ b/tools/playground/veinswap.cpp @@ -1,5 +1,229 @@ +#include +#include +#include +#include +#include +#include +using namespace std; -int main (int numargs, const char ** args) +#include + +#include +#include +#include + + +//Globals +DFHack::Context *DF; +DFHack::Maps *maps; +DFHack::Gui *gui; +DFHack::Materials *mats; + + + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +int main (void) { + int32_t + cx,cy,z, //cursor coords + tx,ty, //tile coords within block + bx,by; //block coords + //DFHack::designations40d designations; + //DFHack::tiletypes40d tiles; + //DFHack::t_temperatures temp1,temp2; + uint32_t x_max,y_max,z_max; + + DFHack::ContextManager DFMgr("Memory.xml"); + try + { + + DF=DFMgr.getSingleContext(); + DF->Attach(); + maps = DF->getMaps(); + maps->Start(); + maps->getSize(x_max,y_max,z_max); + gui = DF->getGui(); + mats = DF->getMaterials(); + mats->ReadAllMaterials(); + if(!mats->ReadInorganicMaterials()) + { + printf("Error: Could not load materials!\n"); + #ifndef LINUX_BUILD + cin.ignore(); + #endif + return 1; + } + } + catch (exception& e) + { + cerr << e.what() << endl; + #ifndef LINUX_BUILD + cin.ignore(); + #endif + return 1; + } + + + + bool end = false; + cout << "Welcome to the Vein Swap tool.\nType 'help' or ? for a list of available commands, 'q' to quit" << endl; + string mode = ""; + string command = ""; + + while(!end) + { + DF->Resume(); + + cout << endl << ":"; + getline(cin, command); + int ch = command[0]; + if(command.length()<=0) ch=0; + if( ((int)command.find("help")) >=0 ) ch='?'; //under windows, find was casting unsigned! + + //Process user command. + switch(ch) + { + case 'h': + case '?': + cout << "" << endl + << "Commands:" << endl + << "p - print vein at cursor" << endl + << "m - print all inorganic material types" << endl + << "r MatTo - replace the vein at cursor with MatTo" << endl + << "R Percent MatFrom MatTo - replace Percent of MatFrom veins with MatTo veins" << endl + << "help OR ? - print this list of commands" << endl + << "q - quit" << endl + << endl + << "Usage:\n\t" << endl; + break; + case 'p': + case 10: + case 13: + case 0: + { + //Print current cursor + mats->ReadAllMaterials(); + + if(!maps->Start()) + { + cout << "Can't see any DF map loaded." << endl; + break; + } + if(!gui->getCursorCoords(cx,cy,z)) + { + cout << "Can't get cursor coords! Make sure you have a cursor active in DF." << endl; + break; + } + //cout << "cursor coords: " << x << "/" << y << "/" << z << endl; + tx=cx%16; ty=cy%16; + bx=cx/16; by=cy/16; + DFHack::DFCoord xyz(cx,cy,z); + + printf("Cursor[%d,%d,%d] Block(%d,%d) Tile(%d,%d)\n", cx,cy,z, bx,by, tx,ty ); + + if(!maps->isValidBlock(bx,by,z)) + { + cout << "Invalid block." << endl; + break; + } + + vector veinVector; + int found=0; + maps->ReadVeins(bx,by,z,&veinVector); + printf("Veins in block (%d):\n",veinVector.size()); + for(unsigned long i=0;iinorganic[veinVector[i].type].id + ); + } + printf("Cursor is%s in vein.\n", (found?"":" not") ); + + maps->Finish(); + DF->Resume(); + } + break; + case 'v': + break; + case 'm': + break; + case 'R': + break; + case 'q': + end = true; + cout << "Bye!" << endl; + break; + case 'r': + DF->Suspend(); + do{ + //Process parameters + long matto = atol( command.c_str()+1 ); + if( matto < 0 || matto >= (long)mats->inorganic.size() ){ + cout << "Invalid material: " << matto << endl; + break; + } + + if(!maps->Start()) + { + cout << "Can't see any DF map loaded." << endl; + break; + } + if(!gui->getCursorCoords(cx,cy,z)) + { + cout << "Can't get cursor coords! Make sure you have a cursor active in DF." << endl; + break; + } + tx=cx%16; ty=cy%16; + bx=cx/16; by=cy/16; + printf("Cursor[%d,%d,%d] Block(%d,%d) Tile(%d,%d)\n", cx,cy,z, bx,by, tx,ty ); + + if(!maps->isValidBlock(bx,by,z)) + { + cout << "Invalid block." << endl; + break; + } + + //MapExtras::MapCache MC(maps); + //MapExtras::Block B(maps,DFHack::DFCoord(bx,by,z)); + + vector veinVector; + int v=-1; //the vector pointed to by the cursor + + mats->ReadAllMaterials(); + + maps->ReadVeins(bx,by,z,&veinVector); + for(unsigned long i=0 ; v<0 && iinorganic[veinVector[v].type].id, matto, mats->inorganic[matto].id ); +printf("%X\n",veinVector[v].vtable); + vector veinTable; + + veinVector[v].type = matto; + maps->WriteVein( &veinVector[v] ); + + + maps->Finish(); + + cout << endl << "Finished." << endl; + }while(0); + DF->Resume(); + break; + default: + cout << "Unknown command: " << command << endl; + }//end switch + + }//end while + + DF->Detach(); + //#ifndef LINUX_BUILD + //cout << "Done. Press any key to continue" << endl; + //cin.ignore(); + //#endif return 0; }