@ -1,4 +1,24 @@
// Plugin tiletypes
//
// This plugin allows fine editing of individual game tiles (expect for
// changing material subtypes).
//
// Commands:
// tiletypes - runs the interractive interpreter
// tiletypes-command - run the given command
// (intended to be mapped to a hotkey or used from dfhack-run)
// tiletypes-here - runs the execute method with the last settings from
// tiletypes(-command), including brush!
// (intended to be mapped to a hotkey)
// tiletypes-here-point - runs the execute method with the last settings from
// tiletypes(-command), except with a point brush!
// (intended to be mapped to a hotkey)
// Options (everything but tiletypes-command):
// ?, help - print some help
//
// Options (tiletypes-command):
// (anything) - run the given command
# include <iostream>
# include <vector>
# include <map>
@ -25,39 +45,120 @@ using namespace MapExtras;
using namespace DFHack ;
using namespace df : : enums ;
//zilpin: These two functions were giving me compile errors in VS2008, so I cheated with the C style loop below, just to get it to build.
//Original code is commented out.
void tolower ( std : : string & str )
{
//The C++ way...
//std::transform(str.begin(), str.end(), str.begin(), std::bind2nd(std::ptr_fun(&std::tolower<char> ), std::locale("")));
CommandHistory tiletypes_hist ;
//The C way...
for ( char * c = ( char * ) str . c_str ( ) ; * c ; + + c )
command_result df_tiletypes ( color_ostream & out , vector < string > & parameters ) ;
command_result df_tiletypes_command ( color_ostream & out , vector < string > & parameters ) ;
command_result df_tiletypes_here ( color_ostream & out , vector < string > & parameters ) ;
command_result df_tiletypes_here_point ( color_ostream & out , vector < string > & parameters ) ;
DFHACK_PLUGIN ( " tiletypes " ) ;
DFhackCExport command_result plugin_init ( color_ostream & out , std : : vector < PluginCommand > & commands )
{
* c = tolower ( * c ) ;
tiletypes_hist . load ( " tiletypes.history " ) ;
commands . push_back ( PluginCommand ( " tiletypes " , " Paint map tiles freely, similar to liquids. " , df_tiletypes , true ) ) ;
commands . push_back ( PluginCommand ( " tiletypes-command " , " Run the given commands (seperated by ' ; '; an empty command is the same as run). " , df_tiletypes_command ) ) ;
commands . push_back ( PluginCommand ( " tiletypes-here " , " Use the last settings from tiletypes, including brush, at cursor location. " , df_tiletypes_here ) ) ;
commands . push_back ( PluginCommand ( " tiletypes-here-point " , " Use the last settings from tiletypes, not including brush, at cursor location. " , df_tiletypes_here_point ) ) ;
return CR_OK ;
}
DFhackCExport command_result plugin_shutdown ( color_ostream & out )
{
tiletypes_hist . save ( " tiletypes.history " ) ;
return CR_OK ;
}
void toupper ( std : : string & str )
void help( color_ostream & out , std : : vector < std : : string > & commands , int start , int end )
{
//std::transform(str.begin(), str.end(), str.begin(), std::bind2nd(std::ptr_fun(&std::toupper<char>), std::locale("")));
for( char * c = ( char * ) str . c_str ( ) ; * c ; + + c )
std : : string option = commands . size ( ) > start ? commands [ start ] : " " ;
if ( option . empty ( ) )
{
* c = toupper ( * c ) ;
out < < " Commands: " < < std : : endl
< < " quit / q : quit " < < std : : endl
< < " filter / f [options] : change filter options " < < std : : endl
< < " paint / p [options] : change paint options " < < std : : endl
< < " point / p : set point brush " < < std : : endl
< < " range / r [w] [h] [z] : set range brush " < < std : : endl
< < " block : set block brush " < < std : : endl
< < " column : set column brush " < < std : : endl
< < " run / (empty) : paint! " < < std : : endl
< < std : : endl
< < " Filter/paint options: " < < std : : endl
< < " Shape / sh / s: set tile shape information " < < std : : endl
< < " Material / mat / m: set tile material information " < < std : : endl
< < " Special / sp: set special tile information " < < std : : endl
< < " Variant / var / v: set variant tile information " < < std : : endl
< < " All / a: set the four above at the same time (no ANY support) " < < std : : endl
< < " Designated / d: set designated flag " < < std : : endl
< < " Hidden / h: set hidden flag " < < std : : endl
< < " Light / l: set light flag " < < std : : endl
< < " Subterranean / st: set subterranean flag " < < std : : endl
< < " Skyview / sv: set skyview flag " < < std : : endl
< < " See help [option] for more information " < < std : : endl ;
}
else if ( option = = " shape " | | option = = " s " | | option = = " sh " )
{
out < < " Available shapes: " < < std : : endl
< < " ANY " < < std : : endl ;
FOR_ENUM_ITEMS ( tiletype_shape , i )
{
out < < " " < < ENUM_KEY_STR ( tiletype_shape , i ) < < std : : endl ;
}
}
int toint ( const std : : string & str , int failValue = 0 )
else if ( option = = " material " | | option = = " mat " | | option = = " m " )
{
std : : istringstream ss ( str ) ;
int valInt ;
ss > > valInt ;
if ( ss . fail ( ) )
out < < " Available materials: " < < std : : endl
< < " ANY " < < std : : endl ;
FOR_ENUM_ITEMS ( tiletype_material , i )
{
return failValue ;
out < < " " < < ENUM_KEY_STR ( tiletype_material , i ) < < std : : endl ;
}
}
else if ( option = = " special " | | option = = " sp " )
{
out < < " Available specials: " < < std : : endl
< < " ANY " < < std : : endl ;
FOR_ENUM_ITEMS ( tiletype_special , i )
{
out < < " " < < ENUM_KEY_STR ( tiletype_special , i ) < < std : : endl ;
}
}
else if ( option = = " variant " | | option = = " var " | | option = = " v " )
{
out < < " Available variants: " < < std : : endl
< < " ANY " < < std : : endl ;
FOR_ENUM_ITEMS ( tiletype_variant , i )
{
out < < " " < < ENUM_KEY_STR ( tiletype_variant , i ) < < std : : endl ;
}
}
else if ( option = = " designated " | | option = = " d " )
{
out < < " Available designated flags: " < < std : : endl
< < " ANY, 0, 1 " < < std : : endl ;
}
else if ( option = = " hidden " | | option = = " h " )
{
out < < " Available hidden flags: " < < std : : endl
< < " ANY, 0, 1 " < < std : : endl ;
}
else if ( option = = " light " | | option = = " l " )
{
out < < " Available light flags: " < < std : : endl
< < " ANY, 0, 1 " < < std : : endl ;
}
else if ( option = = " subterranean " | | option = = " st " )
{
out < < " Available subterranean flags: " < < std : : endl
< < " ANY, 0, 1 " < < std : : endl ;
}
else if ( option = = " skyview " | | option = = " sv " )
{
out < < " Available skyview flags: " < < std : : endl
< < " ANY, 0, 1 " < < std : : endl ;
}
return valInt ;
}
struct TileType
@ -217,12 +318,116 @@ std::ostream &operator<<(std::ostream &stream, const TileType &paint)
return stream ;
}
bool processTileType ( TileType & paint , const std : : string & option , const std : : string & value )
static TileType filter , paint ;
static Brush * brush = new RectangleBrush ( 1 , 1 ) ;
void printState ( color_ostream & out )
{
out < < " Filter: " < < filter < < std : : endl
< < " Paint: " < < paint < < std : : endl
< < " Brush: " < < brush - > str ( ) < < std : : endl ;
}
//zilpin: These two functions were giving me compile errors in VS2008, so I cheated with the C style loop below, just to get it to build.
//Original code is commented out.
void tolower ( std : : string & str )
{
//The C++ way...
//std::transform(str.begin(), str.end(), str.begin(), std::bind2nd(std::ptr_fun(&std::tolower<char> ), std::locale("")));
//The C way...
for ( char * c = ( char * ) str . c_str ( ) ; * c ; + + c )
{
* c = tolower ( * c ) ;
}
}
void toupper ( std : : string & str )
{
//std::transform(str.begin(), str.end(), str.begin(), std::bind2nd(std::ptr_fun(&std::toupper<char>), std::locale("")));
for ( char * c = ( char * ) str . c_str ( ) ; * c ; + + c )
{
* c = toupper ( * c ) ;
}
}
int toint ( const std : : string & str , int failValue = 0 )
{
std : : istringstream ss ( str ) ;
int valInt ;
ss > > valInt ;
if ( ss . fail ( ) )
{
return failValue ;
}
return valInt ;
}
bool tryShape ( std : : string value , TileType & paint )
{
FOR_ENUM_ITEMS ( tiletype_shape , i )
{
if ( value = = ENUM_KEY_STR ( tiletype_shape , i ) )
{
paint . shape = i ;
return true ;
}
}
return false ;
}
bool tryMaterial ( std : : string value , TileType & paint )
{
FOR_ENUM_ITEMS ( tiletype_material , i )
{
if ( value = = ENUM_KEY_STR ( tiletype_material , i ) )
{
paint . material = i ;
return true ;
}
}
return false ;
}
bool trySpecial ( std : : string value , TileType & paint )
{
FOR_ENUM_ITEMS ( tiletype_special , i )
{
if ( value = = ENUM_KEY_STR ( tiletype_special , i ) )
{
paint . special = i ;
return true ;
}
}
return false ;
}
bool tryVariant ( std : : string value , TileType & paint )
{
FOR_ENUM_ITEMS ( tiletype_variant , i )
{
if ( value = = ENUM_KEY_STR ( tiletype_variant , i ) )
{
paint . variant = i ;
return true ;
}
}
return false ;
}
bool processTileType ( color_ostream & out , TileType & paint , std : : vector < std : : string > & params , int start , int end )
{
if ( params . size ( ) < start + 2 )
{
std : : string val = value ;
toupper ( val ) ;
return false ;
}
int loc = start ;
std : : string option = params [ loc + + ] ;
std : : string value = params [ loc + + ] ;
toupper ( value ) ;
int valInt ;
if ( val = = " ANY " )
if ( val ue = = " ANY " )
{
valInt = - 1 ;
}
@ -241,19 +446,9 @@ bool processTileType(TileType &paint, const std::string &option, const std::stri
}
else
{
FOR_ENUM_ITEMS ( tiletype_shape , i )
{
if ( val = = ENUM_KEY_STR ( tiletype_shape , i ) )
{
paint . shape = i ;
found = true ;
break ;
}
}
if ( ! found )
if ( ! tryShape ( value , paint ) )
{
std: : c out < < " Unknown tile shape: " < < value < < std : : endl ;
out < < " Unknown tile shape: " < < value < < std : : endl ;
}
}
}
@ -266,19 +461,9 @@ bool processTileType(TileType &paint, const std::string &option, const std::stri
}
else
{
FOR_ENUM_ITEMS ( tiletype_material , i )
{
if ( val = = ENUM_KEY_STR ( tiletype_material , i ) )
{
paint . material = i ;
found = true ;
break ;
}
}
if ( ! found )
if ( ! tryMaterial ( value , paint ) )
{
std: : c out < < " Unknown tile material: " < < value < < std : : endl ;
out < < " Unknown tile material: " < < value < < std : : endl ;
}
}
}
@ -291,19 +476,9 @@ bool processTileType(TileType &paint, const std::string &option, const std::stri
}
else
{
FOR_ENUM_ITEMS ( tiletype_special , i )
{
if ( val = = ENUM_KEY_STR ( tiletype_special , i ) )
{
paint . special = i ;
found = true ;
break ;
}
}
if ( ! found )
if ( ! trySpecial ( value , paint ) )
{
std: : c out < < " Unknown tile special: " < < value < < std : : endl ;
out < < " Unknown tile special: " < < value < < std : : endl ;
}
}
}
@ -316,19 +491,9 @@ bool processTileType(TileType &paint, const std::string &option, const std::stri
}
else
{
FOR_ENUM_ITEMS ( tiletype_variant , i )
{
if ( val = = ENUM_KEY_STR ( tiletype_variant , i ) )
{
paint . variant = i ;
found = true ;
break ;
}
}
if ( ! found )
if ( ! tryVariant ( value , paint ) )
{
std: : c out < < " Unknown tile variant: " < < value < < std : : endl ;
out < < " Unknown tile variant: " < < value < < std : : endl ;
}
}
}
@ -341,7 +506,7 @@ bool processTileType(TileType &paint, const std::string &option, const std::stri
}
else
{
std: : c out < < " Unknown designation flag: " < < value < < std : : endl ;
out < < " Unknown designation flag: " < < value < < std : : endl ;
}
}
else if ( option = = " hidden " | | option = = " h " )
@ -353,7 +518,7 @@ bool processTileType(TileType &paint, const std::string &option, const std::stri
}
else
{
std: : c out < < " Unknown hidden flag: " < < value < < std : : endl ;
out < < " Unknown hidden flag: " < < value < < std : : endl ;
}
}
else if ( option = = " light " | | option = = " l " )
@ -365,7 +530,7 @@ bool processTileType(TileType &paint, const std::string &option, const std::stri
}
else
{
std: : c out < < " Unknown light flag: " < < value < < std : : endl ;
out < < " Unknown light flag: " < < value < < std : : endl ;
}
}
else if ( option = = " subterranean " | | option = = " st " )
@ -377,7 +542,7 @@ bool processTileType(TileType &paint, const std::string &option, const std::stri
}
else
{
std: : c out < < " Unknown subterranean flag: " < < value < < std : : endl ;
out < < " Unknown subterranean flag: " < < value < < std : : endl ;
}
}
else if ( option = = " skyview " | | option = = " sv " )
@ -389,264 +554,64 @@ bool processTileType(TileType &paint, const std::string &option, const std::stri
}
else
{
std : : cout < < " Unknown skyview flag: " < < value < < std : : endl ;
out < < " Unknown skyview flag: " < < value < < std : : endl ;
}
}
else if ( option = = " all " | | option = = " a " )
{
for ( ; loc < end ; loc + + )
{
std : : string param = params [ loc ] ;
toupper ( param ) ;
if ( ! ( tryShape ( param , paint ) | | tryMaterial ( param , paint ) | |
trySpecial ( param , paint ) | | tryVariant ( param , paint ) ) )
{
out < < " Unknown description: ' " < < param < < " ' " < < std : : endl ;
break ;
}
}
found = true ;
}
else
{
std : : cout < < " Unknown option: ' " < < option < < " ' " < < std : : endl ;
out < < " Unknown option: ' " < < option < < " ' " < < std : : endl ;
}
return found ;
}
void help ( std : : ostream & out , const std : : string & option )
command_result executePaintJob ( color_ostream & out )
{
if ( option . empty ( ) )
if ( paint . empty ( ) )
{
out < < " Commands: " < < std : : endl
< < " quit / q : quit " < < std : : endl
< < " filter / f [options] : change filter options " < < std : : endl
< < " paint / p [options] : change paint options " < < std : : endl
< < " point / p : set point brush " < < std : : endl
< < " range / r : set range brush " < < std : : endl
< < " block : set block brush " < < std : : endl
< < " column : set column brush " < < std : : endl
< < std : : endl
< < " Filter/paint options: " < < std : : endl
< < " Shape / sh / s: set tile shape information " < < std : : endl
< < " Material / mat / m: set tile material information " < < std : : endl
< < " Special / sp: set special tile information " < < std : : endl
< < " Variant / var / v: set variant tile information " < < std : : endl
< < " Designated / d: set designated flag " < < std : : endl
< < " Hidden / h: set hidden flag " < < std : : endl
< < " Light / l: set light flag " < < std : : endl
< < " Subterranean / st: set subterranean flag " < < std : : endl
< < " Skyview / sv: set skyview flag " < < std : : endl
< < " See help [option] for more information " < < std : : endl ;
}
else if ( option = = " shape " | | option = = " s " | | option = = " sh " )
{
out < < " Available shapes: " < < std : : endl
< < " ANY " < < std : : endl ;
FOR_ENUM_ITEMS ( tiletype_shape , i )
{
out < < " " < < ENUM_KEY_STR ( tiletype_shape , i ) < < std : : endl ;
}
}
else if ( option = = " material " | | option = = " mat " | | option = = " m " )
{
out < < " Available materials: " < < std : : endl
< < " ANY " < < std : : endl ;
FOR_ENUM_ITEMS ( tiletype_material , i )
{
out < < " " < < ENUM_KEY_STR ( tiletype_material , i ) < < std : : endl ;
}
}
else if ( option = = " special " | | option = = " sp " )
{
out < < " Available specials: " < < std : : endl
< < " ANY " < < std : : endl ;
FOR_ENUM_ITEMS ( tiletype_special , i )
{
out < < " " < < ENUM_KEY_STR ( tiletype_special , i ) < < std : : endl ;
}
}
else if ( option = = " variant " | | option = = " var " | | option = = " v " )
{
out < < " Available variants: " < < std : : endl
< < " ANY " < < std : : endl ;
FOR_ENUM_ITEMS ( tiletype_variant , i )
{
out < < " " < < ENUM_KEY_STR ( tiletype_variant , i ) < < std : : endl ;
}
}
else if ( option = = " designated " | | option = = " d " )
{
out < < " Available designated flags: " < < std : : endl
< < " ANY, 0, 1 " < < std : : endl ;
}
else if ( option = = " hidden " | | option = = " h " )
{
out < < " Available hidden flags: " < < std : : endl
< < " ANY, 0, 1 " < < std : : endl ;
}
else if ( option = = " light " | | option = = " l " )
{
out < < " Available light flags: " < < std : : endl
< < " ANY, 0, 1 " < < std : : endl ;
}
else if ( option = = " subterranean " | | option = = " st " )
{
out < < " Available subterranean flags: " < < std : : endl
< < " ANY, 0, 1 " < < std : : endl ;
}
else if ( option = = " skyview " | | option = = " sv " )
{
out < < " Available skyview flags: " < < std : : endl
< < " ANY, 0, 1 " < < std : : endl ;
}
}
CommandHistory tiletypes_hist ;
command_result df_tiletypes ( color_ostream & out , vector < string > & parameters ) ;
DFHACK_PLUGIN ( " tiletypes " ) ;
DFhackCExport command_result plugin_init ( color_ostream & out , std : : vector < PluginCommand > & commands )
{
tiletypes_hist . load ( " tiletypes.history " ) ;
commands . push_back ( PluginCommand ( " tiletypes " , " Paint map tiles freely, similar to liquids. " , df_tiletypes , true ) ) ;
return CR_OK ;
}
DFhackCExport command_result plugin_shutdown ( color_ostream & out )
{
tiletypes_hist . save ( " tiletypes.history " ) ;
out . printerr ( " Set the paint first. \n " ) ;
return CR_OK ;
}
command_result df_tiletypes ( color_ostream & out , vector < string > & parameters )
{
CoreSuspender suspend ;
uint32_t x_max = 0 , y_max = 0 , z_max = 0 ;
int32_t x = 0 , y = 0 , z = 0 ;
for ( size_t i = 0 ; i < parameters . size ( ) ; i + + )
{
if ( parameters [ i ] = = " help " | | parameters [ i ] = = " ? " )
{
out . print ( " This tool allows painting tiles types with a brush, using an optional filter. \n "
" The tool is interactive, similarly to the liquids tool. \n "
" Further help is available inside. \n "
) ;
return CR_OK ;
}
}
if ( ! out . is_console ( ) )
return CR_FAILURE ;
Console & con = static_cast < Console & > ( out ) ;
TileType filter , paint ;
Brush * brush = new RectangleBrush ( 1 , 1 ) ;
bool end = false ;
std : : string brushname = " point " ;
int width = 1 , height = 1 , z_levels = 1 ;
con < < " Welcome to the tiletype tool. \n Type 'help' or '?' for a list of available commands, 'q' to quit. \n Press return after a command to confirm. " < < std : : endl ;
con . printerr ( " THIS TOOL CAN BE DANGEROUS. YOU'VE BEEN WARNED. \n " ) ;
while ( ! end )
{
con < < " Filter: " < < filter < < std : : endl
< < " Paint: " < < paint < < std : : endl
< < " Brush: " < < brushname < < std : : endl ;
std : : string input = " " ;
std : : string command = " " ;
std : : string option = " " ;
std : : string value = " " ;
con . lineedit ( " tiletypes> " , input , tiletypes_hist ) ;
tiletypes_hist . add ( input ) ;
std : : istringstream ss ( input ) ;
ss > > command > > option > > value ;
tolower ( command ) ;
tolower ( option ) ;
if ( command = = " help " | | command = = " ? " )
{
help ( con , option ) ;
}
else if ( command = = " quit " | | command = = " q " )
{
end = true ;
}
else if ( command = = " filter " | | command = = " f " )
{
processTileType ( filter , option , value ) ;
}
else if ( command = = " paint " | | ( command = = " p " & & ! option . empty ( ) ) )
{
processTileType ( paint , option , value ) ;
}
else if ( command = = " point " | | command = = " p " )
{
delete brush ;
brushname = " point " ;
brush = new RectangleBrush ( 1 , 1 ) ;
}
else if ( command = = " range " | | command = = " r " )
{
std : : stringstream ss ;
CommandHistory hist ;
ss < < " Set range width < " < < width < < " > " ;
con . lineedit ( ss . str ( ) , command , hist ) ;
width = command = = " " ? width : toint ( command ) ;
if ( width < 1 ) width = 1 ;
ss . str ( " " ) ;
ss < < " Set range height < " < < height < < " > " ;
con . lineedit ( ss . str ( ) , command , hist ) ;
height = command = = " " ? height : toint ( command ) ;
if ( height < 1 ) height = 1 ;
ss . str ( " " ) ;
ss < < " Set range z-levels < " < < z_levels < < " > " ;
con . lineedit ( ss . str ( ) , command , hist ) ;
z_levels = command = = " " ? z_levels : toint ( command ) ;
if ( z_levels < 1 ) z_levels = 1 ;
delete brush ;
if ( width = = 1 & & height = = 1 & & z_levels = = 1 )
{
brushname = " point " ;
}
else
{
brushname = " range " ;
}
brush = new RectangleBrush ( width , height , z_levels , 0 , 0 , 0 ) ;
}
else if ( command = = " block " )
{
delete brush ;
brushname = " block " ;
brush = new BlockBrush ( ) ;
}
else if ( command = = " column " )
{
delete brush ;
brushname = " column " ;
brush = new ColumnBrush ( ) ;
}
else if ( command . empty ( ) )
{
if ( paint . empty ( ) )
{
con . printerr ( " Set the paint first. \n " ) ;
continue ;
}
CoreSuspender suspend ;
if ( ! Maps : : IsValid ( ) )
{
con . printerr ( " Map is not available! \n " ) ;
out . printerr ( " Map is not available! \n " ) ;
return CR_FAILURE ;
}
Maps : : getSize ( x_max , y_max , z_max ) ;
if ( ! Gui : : getCursorCoords ( x , y , z ) )
{
con . printerr ( " Can't get cursor coords! Make sure you have a cursor active in DF. \n " ) ;
out . printerr ( " Can't get cursor coords! Make sure you have a cursor active in DF. \n " ) ;
return CR_FAILURE ;
}
con . print ( " Cursor coords: (%d, %d, %d) \n " , x , y , z ) ;
out . print ( " Cursor coords: (%d, %d, %d) \n " , x , y , z ) ;
DFHack : : DFCoord cursor ( x , y , z ) ;
MapExtras : : MapCache map ;
coord_vec all_tiles = brush - > points ( map , cursor ) ;
con . print ( " working... \n " ) ;
out . print ( " working... \n " ) ;
for ( coord_vec : : iterator iter = all_tiles . begin ( ) ; iter ! = all_tiles . end ( ) ; + + iter )
{
@ -660,7 +625,7 @@ command_result df_tiletypes (color_ostream &out, vector <string> & parameters)
| | ( filter . dig > - 1 & & ( filter . dig ! = 0 ) ! = ( des . bits . dig ! = tile_dig_designation : : No ) )
)
{
continue ;
return CR_OK ;
}
df : : tiletype_shape shape = paint . shape ;
@ -706,13 +671,15 @@ command_result df_tiletypes (color_ostream &out, vector <string> & parameters)
*/
// Remove direction from directionless tiles
DFHack : : TileDirection direction = tileDirection ( source ) ;
if ( ! ( material = = tiletype_material : : RIVER | | shape = = tiletype_shape : : BROOK_BED | | shape = = tiletype_shape : : WALL & & ( material = = tiletype_material : : CONSTRUCTION | | special = = tiletype_special : : SMOOTH ) ) ) {
if ( ! ( material = = tiletype_material : : RIVER | | shape = = tiletype_shape : : BROOK_BED | | shape = = tiletype_shape : : WALL & & ( material = = tiletype_material : : CONSTRUCTION | | special = = tiletype_special : : SMOOTH ) ) )
{
direction . whole = 0 ;
}
df : : tiletype type = DFHack : : findTileType ( shape , material , variant , special , direction ) ;
// hack for empty space
if ( shape = = tiletype_shape : : EMPTY & & material = = tiletype_material : : AIR & & variant = = tiletype_variant : : VAR_1 & & special = = tiletype_special : : NORMAL & & direction . whole = = 0 ) {
if ( shape = = tiletype_shape : : EMPTY & & material = = tiletype_material : : AIR & & variant = = tiletype_variant : : VAR_1 & & special = = tiletype_special : : NORMAL & & direction . whole = = 0 )
{
type = tiletype : : OpenSpace ;
}
// make sure it's not invalid
@ -756,13 +723,217 @@ command_result df_tiletypes (color_ostream &out, vector <string> & parameters)
if ( map . WriteAll ( ) )
{
con . print ( " OK \n " ) ;
out . print ( " OK \n " ) ;
}
else
{
con . printerr ( " Something failed horribly! RUN! \n " ) ;
out . printerr ( " Something failed horribly! RUN! \n " ) ;
return CR_FAILURE ;
}
}
command_result processCommand ( color_ostream & out , std : : vector < std : : string > & commands , int start , int end , bool & endLoop , bool hasConsole = false )
{
if ( commands . size ( ) = = start )
{
return executePaintJob ( out ) ;
}
std : : ostringstream ss_o ;
int loc = start ;
std : : string command = commands [ loc + + ] ;
tolower ( command ) ;
if ( command = = " help " | | command = = " ? " )
{
help ( out , commands , loc , end ) ;
}
else if ( command = = " quit " | | command = = " q " )
{
endLoop = true ;
}
else if ( command = = " filter " | | command = = " f " )
{
processTileType ( out , filter , commands , loc , end ) ;
}
else if ( command = = " paint " | | ( command = = " p " & & commands . size ( ) > 1 ) )
{
processTileType ( out , paint , commands , loc , end ) ;
}
else if ( command = = " point " | | command = = " p " )
{
delete brush ;
brush = new RectangleBrush ( 1 , 1 ) ;
}
else if ( command = = " range " | | command = = " r " )
{
int width = 0 , height = 0 , z_levels = 0 ;
if ( commands . size ( ) > loc + 1 )
{
width = toint ( commands [ loc + + ] ) ;
height = toint ( commands [ loc + + ] ) ;
if ( commands . size ( ) > loc ) {
z_levels = toint ( commands [ loc + + ] ) ;
}
}
if ( width < 1 | | height < 1 ) {
if ( hasConsole ) {
Console & con = static_cast < Console & > ( out ) ;
CommandHistory hist ;
ss_o < < " Set range width < " < < width < < " > " ;
con . lineedit ( ss_o . str ( ) , command , hist ) ;
width = command = = " " ? width : toint ( command ) ;
ss_o . str ( " " ) ;
ss_o < < " Set range height < " < < height < < " > " ;
con . lineedit ( ss_o . str ( ) , command , hist ) ;
height = command = = " " ? height : toint ( command ) ;
ss_o . str ( " " ) ;
ss_o < < " Set range z-levels < " < < z_levels < < " > " ;
con . lineedit ( ss_o . str ( ) , command , hist ) ;
z_levels = command = = " " ? z_levels : toint ( command ) ;
} else {
return CR_WRONG_USAGE ;
}
}
if ( width < 1 ) width = 1 ;
if ( height < 1 ) height = 1 ;
if ( z_levels < 1 ) z_levels = 1 ;
delete brush ;
brush = new RectangleBrush ( width , height , z_levels , 0 , 0 , 0 ) ;
}
else if ( command = = " block " )
{
delete brush ;
brush = new BlockBrush ( ) ;
}
else if ( command = = " column " )
{
delete brush ;
brush = new ColumnBrush ( ) ;
}
else if ( command = = " run " | | command . empty ( ) )
{
executePaintJob ( out ) ;
}
return CR_OK ;
}
command_result df_tiletypes ( color_ostream & out_ , vector < string > & parameters )
{
for ( size_t i = 0 ; i < parameters . size ( ) ; i + + )
{
if ( parameters [ i ] = = " help " | | parameters [ i ] = = " ? " )
{
out_ . print ( " This tool allows painting tiles types with a brush, using an optional filter. \n "
" The tool is interactive, similarly to the liquids tool. \n "
" Further help is available inside. \n "
) ;
return CR_OK ;
}
}
if ( ! out_ . is_console ( ) )
return CR_FAILURE ;
Console & out = static_cast < Console & > ( out_ ) ;
std : : vector < std : : string > commands ;
bool end = false ;
out < < " Welcome to the tiletype tool. \n Type 'help' or '?' for a list of available commands, 'q' to quit. \n Press return after a command to confirm. " < < std : : endl ;
out . printerr ( " THIS TOOL CAN BE DANGEROUS. YOU'VE BEEN WARNED. \n " ) ;
while ( ! end )
{
printState ( out ) ;
std : : string input = " " ;
if ( out . lineedit ( " tiletypes> " , input , tiletypes_hist ) = = - 1 )
return CR_FAILURE ;
commands . clear ( ) ;
Core : : cheap_tokenise ( input , commands ) ;
command_result ret = processCommand ( out , commands , 0 , commands . size ( ) , end , true ) ;
if ( ret ! = CR_OK )
{
return ret ;
}
}
return CR_OK ;
}
command_result df_tiletypes_command ( color_ostream & out , vector < string > & parameters )
{
bool dummy ;
int start = 0 , end = 0 ;
parameters . push_back ( " ; " ) ;
for ( size_t i = 0 ; i < parameters . size ( ) ; i + + )
{
if ( parameters [ i ] = = " ; " ) {
command_result rv = processCommand ( out , parameters , start , end , dummy ) ;
if ( rv ! = CR_OK ) {
return rv ;
}
end + + ;
start = end ;
} else {
end + + ;
}
}
return CR_OK ;
}
command_result df_tiletypes_here ( color_ostream & out , vector < string > & parameters )
{
for ( size_t i = 0 ; i < parameters . size ( ) ; i + + )
{
if ( parameters [ i ] = = " help " | | parameters [ i ] = = " ? " )
{
out < < " This command is supposed to be mapped to a hotkey. " < < endl ;
out < < " It will use the current/last parameters set in tiletypes (including brush settings!). " < < endl ;
return CR_OK ;
}
}
out . print ( " Run tiletypes-here with these parameters: " ) ;
printState ( out ) ;
return executePaintJob ( out ) ;
}
command_result df_tiletypes_here_point ( color_ostream & out , vector < string > & parameters )
{
for ( size_t i = 0 ; i < parameters . size ( ) ; i + + )
{
if ( parameters [ i ] = = " help " | | parameters [ i ] = = " ? " )
{
out < < " This command is supposed to be mapped to a hotkey. " < < endl ;
out < < " It will use the current/last parameters set in tiletypes (except with a point brush). " < < endl ;
return CR_OK ;
}
}
Brush * old = brush ;
brush = new RectangleBrush ( 1 , 1 ) ;
out . print ( " Run tiletypes-here with these parameters: " ) ;
printState ( out ) ;
command_result rv = executePaintJob ( out ) ;
delete brush ;
brush = old ;
return rv ;
}