From de24b01a699692092e1e3ec7cef4ecc89273c4b4 Mon Sep 17 00:00:00 2001 From: zilpin Date: Wed, 13 Jul 2011 23:44:37 -0400 Subject: [PATCH] -fix pillar tile types to be TILE_SMOOTH instead of TILE_NORMAL. -Added working (though clumsy) draw tile tool. -Began lumberjack and veinswap tools. --- library/DFTileTypes.cpp | 83 ++++++++- tools/playground/CMakeLists.txt | 17 ++ tools/playground/drawtile.cpp | 315 ++++++++++++++++++++++++++++++++ tools/playground/lumberjack.cpp | 5 + tools/playground/veinswap.cpp | 5 + 5 files changed, 417 insertions(+), 8 deletions(-) create mode 100644 tools/playground/drawtile.cpp create mode 100644 tools/playground/lumberjack.cpp create mode 100644 tools/playground/veinswap.cpp diff --git a/library/DFTileTypes.cpp b/library/DFTileTypes.cpp index 954636fb5..d0ad8e5f7 100644 --- a/library/DFTileTypes.cpp +++ b/library/DFTileTypes.cpp @@ -3,6 +3,8 @@ #include "dfhack/DFTileTypes.h" #include "dfhack/DFExport.h" +#include + namespace DFHack { const TileRow tileTypeTable[TILE_TYPE_ARRAY_LENGTH] = @@ -104,10 +106,10 @@ namespace DFHack {"stone pillar",PILLAR, STONE, VAR_1}, //80 - {"obsidian pillar",PILLAR, OBSIDIAN, VAR_1}, - {"featstone? pillar",PILLAR, FEATSTONE, VAR_1}, - {"vein pillar",PILLAR, VEIN, VAR_1}, - {"ice pillar",PILLAR, ICE, VAR_1}, + {"obsidian pillar",PILLAR, OBSIDIAN, VAR_1,TILE_SMOOTH}, + {"featstone? pillar",PILLAR, FEATSTONE, VAR_1,TILE_SMOOTH}, + {"vein pillar",PILLAR, VEIN, VAR_1,TILE_SMOOTH}, + {"ice pillar",PILLAR, ICE, VAR_1,TILE_SMOOTH}, {0 ,EMPTY, AIR, VAR_1}, {0 ,EMPTY, AIR, VAR_1}, {0 ,EMPTY, AIR, VAR_1}, @@ -658,15 +660,45 @@ namespace DFHack int32_t findSimilarTileType( const int32_t sourceTileType, const TileShape tshape ) { - int32_t tt, match=0; + int32_t match=0; int value=0, matchv=0; const TileRow *source = &tileTypeTable[sourceTileType]; + //Shortcut. + //If the current tile is already a shape match, leave. + if( tshape == source->shape ) return sourceTileType; + + + //Cheap pseudo-entropy, by using address of the variable on the stack. + //No need for real random numbers. + static int entropy; + entropy += (int)( (void *)(&match) ); + entropy ^= ((entropy & 0xFF000000)>>24) ^ ((entropy & 0x00FF0000)>>16); + + #ifdef assert assert( sourceTileType >=0 && sourceTileType < TILE_TYPE_ARRAY_LENGTH ); #endif - for(tt=0;ttspecial || CONSTRUCTED==source->material) ){ + switch( source->material ){ + case CONSTRUCTED: match=495; break; + case ICE: match= 83; break; + case VEIN: match= 82; break; + case FEATSTONE: match= 81; break; + case OBSIDIAN: match= 80; break; + case STONE: match= 79; break; + } + //Prevent the loop. + matchv=value=(8|4|1); + } + + + //Run through until perfect match found or hit end. + for(int32_t tt=0;ttspecial != tileTypeTable[tt].special ) continue; - value=0; + //Special case for constructions. + //Never turn a construction into a non-contruction. + if( CONSTRUCTED == source->material && CONSTRUCTED != tileTypeTable[tt].material ) continue; + + value=0; //Material is high-value match if( tileTypeTable[tt].material == source->material ) value|=8; //Direction is medium value match @@ -684,7 +720,7 @@ namespace DFHack //Variant is low-value match if( tileTypeTable[tt].variant == source->variant ) value|=1; - //Check value against last match + //Check value against last match. if( value>matchv ) { match=tt; @@ -692,6 +728,37 @@ namespace DFHack } } } + + //Post-processing for floors. + //Give raw floors variation. + //Variant matters, but does not matter for source. + //Error on the side of caution. + if( FLOOR==tshape && CONSTRUCTED!=source->material && !source->special ) + { + //Trying to make a floor type with variants, so randomize the variant. + //Very picky, only handle known safe tile types. + //Some floors have 4 variants, some have 3, so the order of these matters. + switch( match ){ + case 261: match=352+(3&entropy); break; //furrowed soil got chosen by accident. + case 336: //STONE + case 340: //OBSIDIAN + case 344: //featstone + case 349: //grass + case 352: //soil + case 356: //wet soil + case 387: //dry grass + case 394: //dead grass + case 398: //grass B + case 441: //vein + match += 3&entropy; + break; + case 242: //ASHES + case 258: //ICE + match += (1&entropy) + (2&entropy); + break; + } + } + if( match ) return match; return sourceTileType; } diff --git a/tools/playground/CMakeLists.txt b/tools/playground/CMakeLists.txt index dba69d21c..47b16b01b 100644 --- a/tools/playground/CMakeLists.txt +++ b/tools/playground/CMakeLists.txt @@ -70,6 +70,23 @@ DFHACK_TOOL(dfprinttiletypes printtiletypes.cpp) # Will have many options in the future. DFHACK_TOOL(dfhellhole hellhole.cpp) +# drawtile +# Author: zilpin +# Arbitrary tile drawing at the cursor. +# Does not fix tiles above/below for consistency (e.g. ramps). +DFHACK_TOOL(dfdrawtile drawtile.cpp) + +# veinswap +# Author: zilpin +# Randomly swap a percentage of the specified vein material with another material. +# Or, set the material of a vein under the cursor. +DFHACK_TOOL(dfveinswap veinswap.cpp) + +# lumberjack +# Author: zilpin +# Designate all trees of the given type which can be reached from the cursor. +DFHACK_TOOL(dflumberjack lumberjack.cpp) + # dfcreaturemanager # Author: raoulxq # - Display creatures (overview & detail) diff --git a/tools/playground/drawtile.cpp b/tools/playground/drawtile.cpp new file mode 100644 index 000000000..8610d7f0c --- /dev/null +++ b/tools/playground/drawtile.cpp @@ -0,0 +1,315 @@ +// + +#include +#include +#include +#include +#include +using namespace std; + +#include + + +#include +#include + +//Avoid including Windows.h because it causes name clashes +extern "C" __declspec(dllimport) void __stdcall Sleep(unsigned long milliseconds); + +//Trim +#define WHITESPACE " \t\r\n" +inline string trimr(const string & s, const string & t = WHITESPACE) +{ + string d (s); + string::size_type i (d.find_last_not_of (t)); + if (i == string::npos) + return ""; + else + return d.erase (d.find_last_not_of (t) + 1) ; +} +inline string triml(const string & s, const string & t = WHITESPACE) +{ + string d (s); + return d.erase (0, s.find_first_not_of (t)) ; +} +inline string trim(const string & s, const string & t = WHITESPACE) +{ + string d (s); + return triml(trimr(d, t), t); +} + +void printtiletype( int i ){ + printf("%s\n%4i ; %-13s ; %-11s ; %c ; %-12s ; %s\n", + ( DFHack::tileTypeTable[i].name ? DFHack::tileTypeTable[i].name : "[invalid tile]" ), + i, + ( DFHack::tileTypeTable[i].name ? DFHack::TileShapeString[ DFHack::tileTypeTable[i].shape ] : "" ), + ( DFHack::tileTypeTable[i].name ? DFHack::TileMaterialString[ DFHack::tileTypeTable[i].material ] : "" ), + ( DFHack::tileTypeTable[i].variant ? '0'+ DFHack::tileTypeTable[i].variant : ' ' ), + ( DFHack::tileTypeTable[i].special ? DFHack::TileSpecialString[ DFHack::tileTypeTable[i].special ] : "" ), + ( DFHack::tileTypeTable[i].direction.whole ? DFHack::tileTypeTable[i].direction.getStr() : "" ), + 0 + ); +} + + +int main (void) +{ + int32_t x,y,z,tx,ty; + //DFHack::designations40d designations; + DFHack::tiletypes40d tiles; + //DFHack::t_temperatures temp1,temp2; + uint32_t x_max,y_max,z_max; + int32_t oldT, newT; + int count, dirty; + + //Brush defaults + DFHack::TileShape BrushClass = DFHack::WALL; + DFHack::TileMaterial BrushMat = DFHack::tilematerial_invalid; + int BrushType = -1; + + DFHack::ContextManager DFMgr("Memory.xml"); + DFHack::Context *DF; + DFHack::Maps * Maps; + DFHack::Gui * Gui; + try + { + DF=DFMgr.getSingleContext(); + DF->Attach(); + Maps = DF->getMaps(); + Maps->Start(); + Maps->getSize(x_max,y_max,z_max); + Gui = DF->getGui(); + } + catch (exception& e) + { + cerr << e.what() << endl; + #ifndef LINUX_BUILD + cin.ignore(); + #endif + return 1; + } + bool end = false; + cout << "Welcome to the Tile Drawing tool.\nType 'help' or ? for a list of available commands, 'q' to quit" << endl; + string mode = "wall"; + 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! + switch(ch) + { + case '?': + cout << "Modes:" << endl + << "O - draw Open Space" << endl + << "M - draw material only (shape unchanged)" << endl + << "m number - use Material value entered" << endl + << "r - use Rock/stone material" << endl + << "l - use Soil material" << endl + << "v - use Vein material" << endl + << "H - draw tile shape only (material unchanged)" << endl + << "h number - draw Tile Shape value entered" << endl + << "w - draw Wall tiles" << endl + << "f - draw Floor tiles" << endl + << "t number - draw exact tile type entered" << endl + << "Commands:" << endl + << "p - print tile shapes and materials, and current brush" << endl + << "P - print all tile types" << endl + << "q - quit" << endl + << "help OR ? - print this list of commands" << endl + << "d - being drawing" << endl + << endl + << "Usage:\nChoose a mode (default is walls), then enter 'd' to being drawing.\nMove the cursor in DF wherever you want to draw.\nPress any key to pause drawing." << endl; + break; + case 'p': + //Classes + printf("\nTile Type Classes:\n"); + for(int i=0;iSuspend(); + kbhit(); //throw away, just to be sure. + for(;;) + { + if(!Maps->Start()) + { + cout << "Can't see any DF map loaded." << endl; + break; + } + if(!Gui->getCursorCoords(x,y,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=x%16; ty=y%16; + + if(!Maps->isValidBlock(x/16,y/16,z)) + { + cout << "Invalid block." << endl; + break; + } + + //Read the tiles. + dirty=0; + Maps->ReadTileTypes((x/16),(y/16),z, &tiles); + oldT = tiles[tx][ty]; + + newT = -1; + if( 0=0 && BrushClass>=0 && ( BrushClass != DFHack::tileTypeTable[oldT].shape || BrushMat != DFHack::tileTypeTable[oldT].material) ){ + //Set tile material and class + newT = DFHack::findTileType(BrushClass,BrushMat, DFHack::tileTypeTable[oldT].variant , DFHack::tileTypeTable[oldT].special , DFHack::tileTypeTable[oldT].direction ); + if(newT<0) newT = DFHack::findTileType(BrushClass,BrushMat, DFHack::tilevariant_invalid, DFHack::tileTypeTable[oldT].special , DFHack::tileTypeTable[oldT].direction ); + if(newT<0) newT = DFHack::findTileType(BrushClass,BrushMat, DFHack::tilevariant_invalid , DFHack::tileTypeTable[oldT].special , (uint32_t)0 ); + }else if( BrushMat<0 && BrushClass>=0 && BrushClass != DFHack::tileTypeTable[oldT].shape ){ + //Set current tile class only, as accurately as can be expected + newT = DFHack::findSimilarTileType(oldT,BrushClass); + }else if( BrushClass<0 && BrushMat>=0 && BrushMat != DFHack::tileTypeTable[oldT].material ){ + //Set current tile material only + newT = DFHack::findTileType(DFHack::tileTypeTable[oldT].shape,BrushMat, DFHack::tileTypeTable[oldT].variant , DFHack::tileTypeTable[oldT].special , DFHack::tileTypeTable[oldT].direction ); + if(newT<0) newT = DFHack::findTileType(DFHack::tileTypeTable[oldT].shape,BrushMat, DFHack::tilevariant_invalid , DFHack::tileTypeTable[oldT].special , DFHack::tileTypeTable[oldT].direction ); + if(newT<0) newT = DFHack::findTileType(DFHack::tileTypeTable[oldT].shape,BrushMat, DFHack::tilevariant_invalid , DFHack::tileTypeTable[oldT].special , (uint32_t)0 ); + } + //If no change, skip it (couldn't find a good tile type, or already what we want) + if ( newT > 0 && oldT != newT ){ + //Set new tile type + tiles[tx][ty] = newT; + dirty=-1; + } + //If anything was changed, write it all. + if (dirty) + { + //Maps->WriteDesignations(x/16,y/16,z/16, &designations); + Maps->WriteTileTypes(x/16,y/16,z, &tiles); + printf("(%4d,%4d,%4d)",x,y,z); + ++count; + } + + Maps->Finish(); + + Sleep(10); + if( kbhit() ) break; + } + cin.clear(); + cout << endl << count << " tiles were drawn." << endl << "Drawing halted. Entering command mode." << endl; + } + continue; + break; + default: + cout << "Unknown command: " << command << endl; + } + + } + DF->Detach(); + #ifndef LINUX_BUILD + cout << "Done. Press any key to continue" << endl; + cin.ignore(); + #endif + return 0; +} diff --git a/tools/playground/lumberjack.cpp b/tools/playground/lumberjack.cpp new file mode 100644 index 000000000..85cd34d07 --- /dev/null +++ b/tools/playground/lumberjack.cpp @@ -0,0 +1,5 @@ + +int main (int numargs, const char ** args) +{ + return 0; +} diff --git a/tools/playground/veinswap.cpp b/tools/playground/veinswap.cpp new file mode 100644 index 000000000..85cd34d07 --- /dev/null +++ b/tools/playground/veinswap.cpp @@ -0,0 +1,5 @@ + +int main (int numargs, const char ** args) +{ + return 0; +}