2011-07-13 21:44:37 -06:00
//
# include <iostream>
# include <vector>
# include <map>
# include <cstdlib>
# include <limits>
using namespace std ;
# include <conio.h>
# include <DFHack.h>
2011-12-31 04:48:42 -07:00
# include <DFTileTypes.h>
2011-07-13 21:44:37 -06:00
//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. \n Type '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: \n Choose a mode (default is walls), then enter 'd' to being drawing. \n Move the cursor in DF wherever you want to draw. \n Press any key to pause drawing. " < < endl ;
break ;
case ' p ' :
//Classes
printf ( " \n Tile Type Classes: \n " ) ;
for ( int i = 0 ; i < DFHack : : tileshape_count ; + + i )
{
printf ( " %4i ; %s \n " , i , DFHack : : TileShapeString [ i ] , 0 ) ;
}
//Materials
printf ( " \n Tile Type Materials: \n " ) ;
for ( int i = 0 ; i < DFHack : : tilematerial_count ; + + i )
{
printf ( " %4i ; %s \n " , i , DFHack : : TileMaterialString [ i ] , 0 ) ;
}
//fall through...
case 10 :
case 13 :
case 0 :
//Print current cursor & brush settings.
cout < < " \n Current Brush: \n " ;
cout < < " tile = " ;
if ( BrushClass < 0 ) cout < < " (not drawing) " ; else cout < < DFHack : : TileShapeString [ BrushClass ] ; cout < < endl ;
cout < < " mat = " ;
if ( BrushMat < 0 ) cout < < " (not drawing) " ; else cout < < DFHack : : TileMaterialString [ BrushMat ] ; cout < < endl ;
cout < < " type = " ;
if ( BrushType < 0 ) {
cout < < " (not drawing) " ;
} else {
printtiletype ( BrushType ) ;
}
break ;
case ' P ' :
cout < < " \n All Valid Tile Types: \n " ;
for ( int i = 0 ; i < TILE_TYPE_ARRAY_LENGTH ; + + i )
{
if ( DFHack : : tileTypeTable [ i ] . name )
printtiletype ( i ) ;
}
case ' w ' :
BrushType = - 1 ;
BrushClass = DFHack : : WALL ;
cout < < " Tile brush shape set to Wall. " < < endl ;
break ;
case ' f ' :
BrushType = - 1 ;
BrushClass = DFHack : : FLOOR ;
cout < < " Tile brush shape set to Floor. " < < endl ;
break ;
case ' h ' :
BrushType = - 1 ;
BrushClass = ( DFHack : : TileShape ) atol ( command . c_str ( ) + 1 ) ;
cout < < " Tile brush shape set to " < < BrushClass < < endl ;
break ;
case ' M ' :
BrushClass = DFHack : : tileshape_invalid ;
cout < < " Tile brush will not draw tile shape. " < < endl ;
break ;
case ' r ' :
BrushType = - 1 ;
BrushMat = DFHack : : STONE ;
cout < < " Tile brush material set to Rock. " < < endl ;
break ;
case ' l ' :
BrushType = - 1 ;
BrushMat = DFHack : : SOIL ;
cout < < " Tile brush material set to Soil. " < < endl ;
break ;
case ' v ' :
BrushType = - 1 ;
BrushMat = DFHack : : VEIN ;
cout < < " Tile brush material set to Vein. " < < endl ;
break ;
case ' m ' :
BrushType = - 1 ;
BrushMat = ( DFHack : : TileMaterial ) atol ( command . c_str ( ) + 1 ) ;
cout < < " Tile brush material set to " < < BrushMat < < endl ;
break ;
case ' H ' :
BrushMat = DFHack : : tilematerial_invalid ;
cout < < " Tile brush will not draw material. " < < endl ;
break ;
case ' O ' :
BrushType = - 1 ;
BrushClass = DFHack : : EMPTY ;
BrushMat = DFHack : : AIR ;
cout < < " Tile brush will draw Open Space. " < < endl ;
break ;
case ' t ' :
BrushClass = DFHack : : tileshape_invalid ;
BrushMat = DFHack : : tilematerial_invalid ;
BrushType = atol ( command . c_str ( ) + 1 ) ;
cout < < " Tile brush type set to: " < < endl ;
printtiletype ( BrushType ) ;
break ;
case ' q ' :
end = true ;
cout < < " Bye! " < < endl ;
break ;
case ' d ' :
{
count = 0 ;
cout < < " Beginning to draw at cursor. " < < endl < < " Press any key to stop drawing. " < < endl ;
//DF->Suspend();
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 < BrushType ) {
//Explicit tile type set. Trust the user.
newT = BrushType ;
} else if ( 0 = = BrushMat & & 0 = = BrushClass ) {
//Special case, Empty Air.
newT = 32 ;
} else if ( BrushMat > = 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 ;
}