2011-05-13 11:37:48 -06:00
//
# include <iostream>
# include <vector>
2011-08-10 20:39:12 -06:00
# include <map>
# include <set>
# include <cstdlib>
# include <sstream>
using std : : vector ;
using std : : string ;
using std : : endl ;
using std : : set ;
2011-12-31 04:48:42 -07:00
# include "Core.h"
2012-01-15 13:54:14 -07:00
# include "Console.h"
# include "Export.h"
# include "PluginManager.h"
# include "modules/Vegetation.h"
# include "modules/Maps.h"
# include "modules/Gui.h"
# include "TileTypes.h"
# include "modules/MapCache.h"
2012-01-19 13:11:52 -07:00
# include "df/tile_dig_designation.h"
2011-08-10 20:39:12 -06:00
using namespace MapExtras ;
using namespace DFHack ;
2012-01-21 17:31:15 -07:00
using namespace df : : enums ;
2011-05-13 11:37:48 -06:00
2011-07-18 14:45:00 -06:00
//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.
2011-05-13 11:37:48 -06:00
void tolower ( std : : string & str )
{
2011-08-10 20:39:12 -06:00
//The C++ way...
2011-07-18 14:45:00 -06:00
//std::transform(str.begin(), str.end(), str.begin(), std::bind2nd(std::ptr_fun(&std::tolower<char> ), std::locale("")));
2011-08-10 20:39:12 -06:00
//The C way...
for ( char * c = ( char * ) str . c_str ( ) ; * c ; + + c )
{
* c = tolower ( * c ) ;
}
2011-05-13 11:37:48 -06:00
}
void toupper ( std : : string & str )
{
2011-07-18 14:45:00 -06:00
//std::transform(str.begin(), str.end(), str.begin(), std::bind2nd(std::ptr_fun(&std::toupper<char>), std::locale("")));
2011-08-10 20:39:12 -06:00
for ( char * c = ( char * ) str . c_str ( ) ; * c ; + + c )
{
* c = toupper ( * c ) ;
}
2011-05-13 11:37:48 -06:00
}
int toint ( const std : : string & str , int failValue = 0 )
{
std : : istringstream ss ( str ) ;
int valInt ;
ss > > valInt ;
if ( ss . fail ( ) )
{
return failValue ;
}
return valInt ;
}
2011-08-10 20:39:12 -06:00
struct TileType
{
2012-02-13 15:56:33 -07:00
df : : tiletype_shape shape ;
df : : tiletype_material material ;
df : : tiletype_special special ;
df : : tiletype_variant variant ;
2011-11-20 00:40:01 -07:00
int dig ;
2011-11-05 04:55:23 -06:00
int hidden ;
int light ;
int subterranean ;
int skyview ;
2011-05-13 11:37:48 -06:00
TileType ( )
{
2012-02-13 15:56:33 -07:00
shape = tiletype_shape : : NONE ;
material = tiletype_material : : NONE ;
special = tiletype_special : : NONE ;
variant = tiletype_variant : : NONE ;
2011-11-20 00:40:01 -07:00
dig = - 1 ;
2011-11-05 04:55:23 -06:00
hidden = - 1 ;
light = - 1 ;
subterranean = - 1 ;
skyview = - 1 ;
2011-05-13 11:37:48 -06:00
}
bool empty ( )
{
2011-11-05 04:55:23 -06:00
return shape = = - 1 & & material = = - 1 & & special = = - 1 & & variant = = - 1
2011-12-29 19:05:53 -07:00
& & hidden = = - 1 & & light = = - 1 & & subterranean = = - 1 & & skyview = = - 1
& & dig = = - 1 ;
2011-05-13 11:37:48 -06:00
}
} ;
std : : ostream & operator < < ( std : : ostream & stream , const TileType & paint )
{
bool used = false ;
bool needSpace = false ;
if ( paint . special > = 0 )
{
2012-02-13 18:17:38 -07:00
stream < < ENUM_KEY_STR ( tiletype_special , paint . special ) ;
2011-05-13 11:37:48 -06:00
used = true ;
needSpace = true ;
}
if ( paint . material > = 0 )
{
if ( needSpace )
{
stream < < " " ;
needSpace = false ;
}
2012-02-13 18:17:38 -07:00
stream < < ENUM_KEY_STR ( tiletype_material , paint . material ) ;
2011-05-13 11:37:48 -06:00
used = true ;
needSpace = true ;
}
if ( paint . shape > = 0 )
{
if ( needSpace )
{
stream < < " " ;
needSpace = false ;
}
2012-02-13 18:17:38 -07:00
stream < < ENUM_KEY_STR ( tiletype_shape , paint . shape ) ;
2011-05-13 11:37:48 -06:00
used = true ;
2011-11-05 04:55:23 -06:00
needSpace = true ;
}
if ( paint . variant > = 0 )
{
if ( needSpace )
{
stream < < " " ;
needSpace = false ;
}
2012-02-13 18:17:38 -07:00
stream < < ENUM_KEY_STR ( tiletype_variant , paint . variant ) ;
2011-11-05 04:55:23 -06:00
used = true ;
needSpace = true ;
}
2011-11-20 00:40:01 -07:00
if ( paint . dig > = 0 )
{
if ( needSpace )
{
stream < < " " ;
needSpace = false ;
}
2011-12-29 19:05:53 -07:00
stream < < ( paint . dig ? " DESIGNATED " : " UNDESIGATNED " ) ;
2011-11-20 00:40:01 -07:00
used = true ;
needSpace = true ;
}
2011-11-05 04:55:23 -06:00
if ( paint . hidden > = 0 )
{
if ( needSpace )
{
stream < < " " ;
needSpace = false ;
}
stream < < ( paint . hidden ? " HIDDEN " : " VISIBLE " ) ;
used = true ;
needSpace = true ;
}
if ( paint . light > = 0 )
{
if ( needSpace )
{
stream < < " " ;
needSpace = false ;
}
stream < < ( paint . light ? " LIGHT " : " DARK " ) ;
used = true ;
needSpace = true ;
}
if ( paint . subterranean > = 0 )
{
if ( needSpace )
{
stream < < " " ;
needSpace = false ;
}
stream < < ( paint . subterranean ? " SUBTERRANEAN " : " ABOVE GROUND " ) ;
used = true ;
needSpace = true ;
}
if ( paint . skyview > = 0 )
{
if ( needSpace )
{
stream < < " " ;
needSpace = false ;
}
stream < < ( paint . skyview ? " OUTSIDE " : " INSIDE " ) ;
used = true ;
needSpace = true ;
2011-05-13 11:37:48 -06:00
}
if ( ! used )
{
stream < < " any " ;
}
return stream ;
}
bool processTileType ( TileType & paint , const std : : string & option , const std : : string & value )
{
std : : string val = value ;
toupper ( val ) ;
int valInt ;
if ( val = = " ANY " )
{
valInt = - 1 ;
}
else
{
valInt = toint ( value , - 2 ) ;
}
bool found = false ;
if ( option = = " shape " | | option = = " sh " | | option = = " s " )
{
2012-02-13 18:17:38 -07:00
if ( tiletype_shape : : is_valid ( ( df : : tiletype_shape ) valInt ) )
2011-05-13 11:37:48 -06:00
{
2012-02-13 18:17:38 -07:00
paint . shape = ( df : : tiletype_shape ) valInt ;
2011-05-13 11:37:48 -06:00
found = true ;
}
else
{
2012-02-13 18:17:38 -07:00
FOR_ENUM_ITEMS ( tiletype_shape , i )
2011-05-13 11:37:48 -06:00
{
2012-02-13 18:17:38 -07:00
if ( val = = ENUM_KEY_STR ( tiletype_shape , i ) )
2011-05-13 11:37:48 -06:00
{
2012-02-13 18:17:38 -07:00
paint . shape = i ;
2011-05-13 11:37:48 -06:00
found = true ;
break ;
}
}
if ( ! found )
{
std : : cout < < " Unknown tile shape: " < < value < < std : : endl ;
}
}
}
else if ( option = = " material " | | option = = " mat " | | option = = " m " )
{
2012-02-13 15:56:33 -07:00
if ( tiletype_material : : is_valid ( ( df : : tiletype_material ) valInt ) )
2011-05-13 11:37:48 -06:00
{
2012-02-13 15:56:33 -07:00
paint . material = ( df : : tiletype_material ) valInt ;
2011-05-13 11:37:48 -06:00
found = true ;
}
else
{
2012-02-13 15:56:33 -07:00
FOR_ENUM_ITEMS ( tiletype_material , i )
2011-05-13 11:37:48 -06:00
{
2012-02-13 18:17:38 -07:00
if ( val = = ENUM_KEY_STR ( tiletype_material , i ) )
2011-05-13 11:37:48 -06:00
{
2012-02-13 15:56:33 -07:00
paint . material = i ;
2011-05-13 11:37:48 -06:00
found = true ;
break ;
}
}
if ( ! found )
{
std : : cout < < " Unknown tile material: " < < value < < std : : endl ;
}
}
}
else if ( option = = " special " | | option = = " sp " )
{
2012-02-13 18:17:38 -07:00
if ( tiletype_special : : is_valid ( ( df : : tiletype_special ) valInt ) )
2011-05-13 11:37:48 -06:00
{
2012-02-13 18:17:38 -07:00
paint . special = ( df : : tiletype_special ) valInt ;
2011-05-13 11:37:48 -06:00
found = true ;
}
else
{
2012-02-13 18:17:38 -07:00
FOR_ENUM_ITEMS ( tiletype_special , i )
2011-05-13 11:37:48 -06:00
{
2012-02-13 18:17:38 -07:00
if ( val = = ENUM_KEY_STR ( tiletype_special , i ) )
2011-05-13 11:37:48 -06:00
{
2012-02-13 18:17:38 -07:00
paint . special = i ;
2011-05-13 11:37:48 -06:00
found = true ;
break ;
}
}
if ( ! found )
{
std : : cout < < " Unknown tile special: " < < value < < std : : endl ;
}
}
}
2011-11-05 04:55:23 -06:00
else if ( option = = " variant " | | option = = " var " | | option = = " v " )
{
2012-02-13 18:17:38 -07:00
if ( tiletype_variant : : is_valid ( ( df : : tiletype_variant ) valInt ) )
2011-11-05 04:55:23 -06:00
{
2012-02-13 18:17:38 -07:00
paint . variant = ( df : : tiletype_variant ) valInt ;
2011-11-05 04:55:23 -06:00
found = true ;
}
else
{
2012-02-13 18:17:38 -07:00
FOR_ENUM_ITEMS ( tiletype_variant , i )
{
if ( val = = ENUM_KEY_STR ( tiletype_variant , i ) )
{
paint . variant = i ;
found = true ;
break ;
}
}
if ( ! found )
{
std : : cout < < " Unknown tile variant: " < < value < < std : : endl ;
}
2011-11-05 04:55:23 -06:00
}
}
2011-12-29 19:05:53 -07:00
else if ( option = = " designated " | | option = = " d " )
2011-11-20 00:40:01 -07:00
{
if ( valInt > = - 1 & & valInt < 2 )
{
paint . dig = valInt ;
found = true ;
}
else
{
2011-12-29 19:05:53 -07:00
std : : cout < < " Unknown designation flag: " < < value < < std : : endl ;
2011-11-20 00:40:01 -07:00
}
}
2011-11-05 04:55:23 -06:00
else if ( option = = " hidden " | | option = = " h " )
{
if ( valInt > = - 1 & & valInt < 2 )
{
paint . hidden = valInt ;
found = true ;
}
else
{
std : : cout < < " Unknown hidden flag: " < < value < < std : : endl ;
}
}
else if ( option = = " light " | | option = = " l " )
{
if ( valInt > = - 1 & & valInt < 2 )
{
paint . light = valInt ;
found = true ;
}
else
{
std : : cout < < " Unknown light flag: " < < value < < std : : endl ;
}
}
else if ( option = = " subterranean " | | option = = " st " )
{
if ( valInt > = - 1 & & valInt < 2 )
{
paint . subterranean = valInt ;
found = true ;
}
else
{
std : : cout < < " Unknown subterranean flag: " < < value < < std : : endl ;
}
}
else if ( option = = " skyview " | | option = = " sv " )
{
if ( valInt > = - 1 & & valInt < 2 )
{
paint . skyview = valInt ;
found = true ;
}
else
{
std : : cout < < " Unknown skyview flag: " < < value < < std : : endl ;
}
}
2011-05-13 11:37:48 -06:00
else
{
std : : cout < < " Unknown option: ' " < < option < < " ' " < < std : : endl ;
}
return found ;
}
2011-08-10 20:39:12 -06:00
void help ( std : : ostream & out , const std : : string & option )
2011-05-13 11:37:48 -06:00
{
if ( option . empty ( ) )
{
2011-08-10 20:39:12 -06:00
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
2011-11-05 04:55:23 -06:00
< < " Special / sp: set special tile information " < < std : : endl
< < " Variant / var / v: set variant tile information " < < std : : endl
2011-12-29 19:05:53 -07:00
< < " Designated / d: set designated flag " < < std : : endl
2011-11-05 04:55:23 -06:00
< < " 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
2011-08-10 20:39:12 -06:00
< < " See help [option] for more information " < < std : : endl ;
2011-05-13 11:37:48 -06:00
}
2011-08-14 17:59:57 -06:00
else if ( option = = " shape " | | option = = " s " | | option = = " sh " )
2011-05-13 11:37:48 -06:00
{
2011-08-10 20:39:12 -06:00
out < < " Available shapes: " < < std : : endl
< < " ANY " < < std : : endl ;
2012-02-13 18:17:38 -07:00
FOR_ENUM_ITEMS ( tiletype_shape , i )
2011-05-13 11:37:48 -06:00
{
2012-02-13 18:17:38 -07:00
out < < " " < < ENUM_KEY_STR ( tiletype_shape , i ) < < std : : endl ;
2011-05-13 11:37:48 -06:00
}
}
2011-08-14 17:59:57 -06:00
else if ( option = = " material " | | option = = " mat " | | option = = " m " )
2011-05-13 11:37:48 -06:00
{
2011-08-10 20:39:12 -06:00
out < < " Available materials: " < < std : : endl
< < " ANY " < < std : : endl ;
2012-02-13 18:17:38 -07:00
FOR_ENUM_ITEMS ( tiletype_material , i )
2011-05-13 11:37:48 -06:00
{
2012-02-13 18:17:38 -07:00
out < < " " < < ENUM_KEY_STR ( tiletype_material , i ) < < std : : endl ;
2011-05-13 11:37:48 -06:00
}
}
2011-11-05 04:55:23 -06:00
else if ( option = = " special " | | option = = " sp " )
2011-05-13 11:37:48 -06:00
{
2011-08-10 20:39:12 -06:00
out < < " Available specials: " < < std : : endl
< < " ANY " < < std : : endl ;
2012-02-13 18:17:38 -07:00
FOR_ENUM_ITEMS ( tiletype_special , i )
2011-05-13 11:37:48 -06:00
{
2012-02-13 18:17:38 -07:00
out < < " " < < ENUM_KEY_STR ( tiletype_special , i ) < < std : : endl ;
2011-05-13 11:37:48 -06:00
}
}
2011-11-05 04:55:23 -06:00
else if ( option = = " variant " | | option = = " var " | | option = = " v " )
{
out < < " Available variants: " < < std : : endl
2012-02-13 18:17:38 -07:00
< < " ANY " < < std : : endl ;
FOR_ENUM_ITEMS ( tiletype_variant , i )
{
out < < " " < < ENUM_KEY_STR ( tiletype_variant , i ) < < std : : endl ;
}
2011-11-05 04:55:23 -06:00
}
2011-12-29 19:05:53 -07:00
else if ( option = = " designated " | | option = = " d " )
2011-11-20 00:40:01 -07:00
{
2011-12-29 19:05:53 -07:00
out < < " Available designated flags: " < < std : : endl
2011-11-20 00:40:01 -07:00
< < " ANY, 0, 1 " < < std : : endl ;
}
2011-11-05 04:55:23 -06:00
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 ;
}
2011-05-13 11:37:48 -06:00
}
typedef std : : vector < DFHack : : DFCoord > coord_vec ;
class Brush
{
public :
virtual ~ Brush ( ) { } ;
virtual coord_vec points ( MapExtras : : MapCache & mc , DFHack : : DFCoord start ) = 0 ;
} ;
/**
* generic 3 D rectangle brush . you can specify the dimensions of
* the rectangle and optionally which tile is its ' center '
*/
class RectangleBrush : public Brush
{
int x_ , y_ , z_ ;
int cx_ , cy_ , cz_ ;
public :
RectangleBrush ( int x , int y , int z = 1 , int centerx = - 1 , int centery = - 1 , int centerz = - 1 )
{
if ( centerx = = - 1 )
{
cx_ = x / 2 ;
}
else
{
cx_ = centerx ;
}
if ( centery = = - 1 )
{
cy_ = y / 2 ;
}
else
{
cy_ = centery ;
}
if ( centerz = = - 1 )
{
cz_ = z / 2 ;
}
else
{
cz_ = centerz ;
}
x_ = x ;
y_ = y ;
z_ = z ;
} ;
coord_vec points ( MapExtras : : MapCache & mc , DFHack : : DFCoord start )
{
coord_vec v ;
DFHack : : DFCoord iterstart ( start . x - cx_ , start . y - cy_ , start . z - cz_ ) ;
DFHack : : DFCoord iter = iterstart ;
for ( int xi = 0 ; xi < x_ ; xi + + )
{
for ( int yi = 0 ; yi < y_ ; yi + + )
{
for ( int zi = 0 ; zi < z_ ; zi + + )
{
if ( mc . testCoord ( iter ) )
v . push_back ( iter ) ;
iter . z + + ;
}
iter . z = iterstart . z ;
iter . y + + ;
}
iter . y = iterstart . y ;
iter . x + + ;
}
return v ;
} ;
~ RectangleBrush ( ) { } ;
} ;
/**
* stupid block brush , legacy . use when you want to apply something to a whole DF map block .
*/
class BlockBrush : public Brush
{
public :
BlockBrush ( ) { } ;
~ BlockBrush ( ) { } ;
coord_vec points ( MapExtras : : MapCache & mc , DFHack : : DFCoord start )
{
coord_vec v ;
DFHack : : DFCoord blockc = start % 16 ;
DFHack : : DFCoord iterc = blockc * 16 ;
if ( ! mc . testCoord ( start ) )
return v ;
for ( int xi = 0 ; xi < 16 ; xi + + )
{
for ( int yi = 0 ; yi < 16 ; yi + + )
{
v . push_back ( iterc ) ;
iterc . y + + ;
}
iterc . x + + ;
}
return v ;
} ;
} ;
/**
* Column from a position through open space tiles
* example : create a column of magma
*/
class ColumnBrush : public Brush
{
public :
ColumnBrush ( ) { } ;
~ ColumnBrush ( ) { } ;
coord_vec points ( MapExtras : : MapCache & mc , DFHack : : DFCoord start )
{
coord_vec v ;
bool juststarted = true ;
while ( mc . testCoord ( start ) )
{
2012-02-13 18:17:38 -07:00
df : : tiletype tt = mc . tiletypeAt ( start ) ;
if ( LowPassable ( tt ) | | juststarted & & HighPassable ( tt ) )
2011-05-13 11:37:48 -06:00
{
v . push_back ( start ) ;
juststarted = false ;
start . z + + ;
}
else break ;
}
return v ;
} ;
} ;
2011-08-13 06:42:09 -06:00
CommandHistory tiletypes_hist ;
2011-08-10 20:39:12 -06:00
DFhackCExport command_result df_tiletypes ( Core * c , vector < string > & parameters ) ;
DFhackCExport const char * plugin_name ( void )
{
return " tiletypes " ;
}
DFhackCExport command_result plugin_init ( Core * c , std : : vector < PluginCommand > & commands )
{
2011-08-13 06:42:09 -06:00
tiletypes_hist . load ( " tiletypes.history " ) ;
2011-08-10 20:39:12 -06:00
commands . clear ( ) ;
commands . push_back ( PluginCommand ( " tiletypes " , " Paint map tiles freely, similar to liquids. " , df_tiletypes , true ) ) ;
return CR_OK ;
}
DFhackCExport command_result plugin_shutdown ( Core * c )
{
2011-08-13 06:42:09 -06:00
tiletypes_hist . save ( " tiletypes.history " ) ;
2011-08-10 20:39:12 -06:00
return CR_OK ;
}
DFhackCExport command_result df_tiletypes ( Core * c , vector < string > & parameters )
2011-05-13 11:37:48 -06:00
{
uint32_t x_max = 0 , y_max = 0 , z_max = 0 ;
int32_t x = 0 , y = 0 , z = 0 ;
2011-08-10 20:39:12 -06:00
DFHack : : Gui * gui ;
2012-01-31 09:55:38 -07:00
for ( size_t i = 0 ; i < parameters . size ( ) ; i + + )
2011-08-14 00:42:21 -06:00
{
if ( parameters [ i ] = = " help " | | parameters [ i ] = = " ? " )
{
c - > con . 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 ;
}
}
2011-05-13 11:37:48 -06:00
TileType filter , paint ;
Brush * brush = new RectangleBrush ( 1 , 1 ) ;
bool end = false ;
std : : string brushname = " point " ;
int width = 1 , height = 1 , z_levels = 1 ;
2011-08-14 00:42:21 -06:00
c - > 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 ;
2011-08-14 17:59:57 -06:00
c - > con . printerr ( " THIS TOOL CAN BE DANGEROUS. YOU'VE BEEN WARNED. \n " ) ;
2011-05-13 11:37:48 -06:00
while ( ! end )
{
2011-08-10 20:39:12 -06:00
c - > con < < " Filter: " < < filter < < std : : endl
< < " Paint: " < < paint < < std : : endl
< < " Brush: " < < brushname < < std : : endl ;
2011-05-13 11:37:48 -06:00
std : : string input = " " ;
std : : string command = " " ;
std : : string option = " " ;
std : : string value = " " ;
2011-08-13 06:42:09 -06:00
c - > con . lineedit ( " tiletypes> " , input , tiletypes_hist ) ;
tiletypes_hist . add ( input ) ;
2011-05-13 11:37:48 -06:00
std : : istringstream ss ( input ) ;
ss > > command > > option > > value ;
tolower ( command ) ;
tolower ( option ) ;
if ( command = = " help " | | command = = " ? " )
{
2011-08-10 20:39:12 -06:00
help ( c - > con , option ) ;
2011-05-13 11:37:48 -06:00
}
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 " )
{
2011-08-10 20:39:12 -06:00
std : : stringstream ss ;
2011-08-13 06:42:09 -06:00
CommandHistory hist ;
2011-08-10 20:39:12 -06:00
ss < < " Set range width < " < < width < < " > " ;
2011-08-13 06:42:09 -06:00
c - > con . lineedit ( ss . str ( ) , command , hist ) ;
2011-05-13 11:37:48 -06:00
width = command = = " " ? width : toint ( command ) ;
if ( width < 1 ) width = 1 ;
2011-08-10 20:39:12 -06:00
ss . str ( " " ) ;
ss < < " Set range height < " < < height < < " > " ;
2011-08-13 06:42:09 -06:00
c - > con . lineedit ( ss . str ( ) , command , hist ) ;
2011-05-13 11:37:48 -06:00
height = command = = " " ? height : toint ( command ) ;
if ( height < 1 ) height = 1 ;
2011-08-10 20:39:12 -06:00
ss . str ( " " ) ;
ss < < " Set range z-levels < " < < z_levels < < " > " ;
2011-08-13 06:42:09 -06:00
c - > con . lineedit ( ss . str ( ) , command , hist ) ;
2011-05-13 11:37:48 -06:00
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 ( ) )
{
2011-08-10 20:39:12 -06:00
c - > con . printerr ( " Set the paint first. \n " ) ;
2011-05-13 11:37:48 -06:00
continue ;
}
2012-01-21 17:31:15 -07:00
CoreSuspender suspend ( c ) ;
2011-08-10 20:39:12 -06:00
gui = c - > getGui ( ) ;
2012-01-19 20:44:17 -07:00
if ( ! Maps : : IsValid ( ) )
2011-05-13 11:37:48 -06:00
{
2012-01-19 20:44:17 -07:00
c - > con . printerr ( " Map is not available! \n " ) ;
2011-08-10 20:39:12 -06:00
return CR_FAILURE ;
2011-05-13 11:37:48 -06:00
}
2012-01-19 20:44:17 -07:00
Maps : : getSize ( x_max , y_max , z_max ) ;
2011-05-13 11:37:48 -06:00
if ( ! ( gui - > Start ( ) & & gui - > getCursorCoords ( x , y , z ) ) )
{
2011-08-10 20:39:12 -06:00
c - > con . printerr ( " Can't get cursor coords! Make sure you have a cursor active in DF. \n " ) ;
return CR_FAILURE ;
2011-05-13 11:37:48 -06:00
}
2011-08-10 20:39:12 -06:00
c - > con . print ( " Cursor coords: (%d, %d, %d) \n " , x , y , z ) ;
2011-05-13 11:37:48 -06:00
DFHack : : DFCoord cursor ( x , y , z ) ;
2012-01-19 20:44:17 -07:00
MapExtras : : MapCache map ;
2011-05-13 11:37:48 -06:00
coord_vec all_tiles = brush - > points ( map , cursor ) ;
2011-08-10 20:39:12 -06:00
c - > con . print ( " working... \n " ) ;
2011-05-13 11:37:48 -06:00
for ( coord_vec : : iterator iter = all_tiles . begin ( ) ; iter ! = all_tiles . end ( ) ; + + iter )
{
2012-02-13 15:56:33 -07:00
const df : : tiletype source = map . tiletypeAt ( * iter ) ;
2012-01-19 13:11:52 -07:00
df : : tile_designation des = map . designationAt ( * iter ) ;
2011-05-13 11:37:48 -06:00
2012-02-13 15:56:33 -07:00
if ( ( filter . shape > - 1 & & filter . shape ! = tileShape ( source ) )
| | ( filter . material > - 1 & & filter . material ! = tileMaterial ( source ) )
| | ( filter . special > - 1 & & filter . special ! = tileSpecial ( source ) )
| | ( filter . variant > - 1 & & filter . variant ! = tileVariant ( source ) )
2012-01-21 17:31:15 -07:00
| | ( filter . dig > - 1 & & ( filter . dig ! = 0 ) ! = ( des . bits . dig ! = tile_dig_designation : : No ) )
2011-11-20 00:40:01 -07:00
)
2011-05-13 11:37:48 -06:00
{
continue ;
}
2012-02-13 15:56:33 -07:00
df : : tiletype_shape shape = paint . shape ;
if ( shape = = tiletype_shape : : NONE )
2011-05-13 11:37:48 -06:00
{
2012-02-13 15:56:33 -07:00
shape = tileShape ( source ) ;
2011-05-13 11:37:48 -06:00
}
2012-02-13 15:56:33 -07:00
df : : tiletype_material material = paint . material ;
if ( material = = tiletype_material : : NONE )
2011-05-13 11:37:48 -06:00
{
2012-02-13 15:56:33 -07:00
material = tileMaterial ( source ) ;
2011-05-13 11:37:48 -06:00
}
2012-02-13 15:56:33 -07:00
df : : tiletype_special special = paint . special ;
if ( special = = tiletype_special : : NONE )
2011-05-13 11:37:48 -06:00
{
2012-02-13 15:56:33 -07:00
special = tileSpecial ( source ) ;
2011-05-13 11:37:48 -06:00
}
2012-02-13 15:56:33 -07:00
df : : tiletype_variant variant = paint . variant ;
2011-11-20 00:40:01 -07:00
/*
* FIXME : variant should be :
* 1. If user variant :
* 2. If user variant \ belongs target variants
* 3. use user variant
* 4. Else
* 5. use variant 0
* 6. If the source variant \ belongs target variants
* 7 use source variant
* 8 ElseIf num target shape / material variants > 1
* 9. pick one randomly
* 10. Else
* 11. use variant 0
*
* The following variant check has been disabled because it ' s severely limiting
* the usefullness of the tool .
*/
/*
2012-02-13 15:56:33 -07:00
if ( variant = = tiletype_variant : : NONE )
2011-11-05 04:55:23 -06:00
{
2012-02-13 15:56:33 -07:00
variant = tileVariant ( source ) ;
2011-11-05 04:55:23 -06:00
}
2011-11-20 00:40:01 -07:00
*/
2011-11-05 04:55:23 -06:00
// Remove direction from directionless tiles
2012-02-13 15:56:33 -07:00
DFHack : : TileDirection direction = tileDirection ( source ) ;
if ( ! ( shape = = tiletype_shape : : RIVER_BED | | shape = = tiletype_shape : : BROOK_BED | | shape = = tiletype_shape : : WALL & & ( material = = tiletype_material : : CONSTRUCTION | | special = = tiletype_special : : SMOOTH ) ) ) {
2011-11-05 04:55:23 -06:00
direction . whole = 0 ;
}
2012-02-13 15:56:33 -07:00
df : : tiletype type = DFHack : : findTileType ( shape , material , variant , special , direction ) ;
2011-11-05 04:55:23 -06:00
// hack for empty space
2012-02-13 15:56:33 -07:00
if ( shape = = tiletype_shape : : EMPTY & & material = = tiletype_material : : AIR & & variant = = tiletype_variant : : VAR_1 & & special = = tiletype_special : : NORMAL & & direction . whole = = 0 ) {
type = tiletype : : OpenSpace ;
2011-11-05 04:55:23 -06:00
}
2011-08-14 17:30:15 -06:00
// make sure it's not invalid
2012-02-13 15:56:33 -07:00
if ( type ! = tiletype : : Void )
2011-08-14 17:30:15 -06:00
map . setTiletypeAt ( * iter , type ) ;
2011-05-13 11:37:48 -06:00
2011-11-05 04:55:23 -06:00
if ( paint . hidden > - 1 )
{
des . bits . hidden = paint . hidden ;
}
if ( paint . light > - 1 )
{
des . bits . light = paint . light ;
}
if ( paint . subterranean > - 1 )
{
des . bits . subterranean = paint . subterranean ;
}
if ( paint . skyview > - 1 )
{
2012-01-19 13:11:52 -07:00
des . bits . outside = paint . skyview ;
2011-11-05 04:55:23 -06:00
}
2011-05-13 11:37:48 -06:00
// Remove liquid from walls, etc
2011-11-05 04:55:23 -06:00
if ( type ! = - 1 & & ! DFHack : : FlowPassable ( type ) )
2011-05-13 11:37:48 -06:00
{
des . bits . flow_size = 0 ;
2011-11-05 04:55:23 -06:00
//des.bits.liquid_type = DFHack::liquid_water;
//des.bits.water_table = 0;
des . bits . flow_forbid = 0 ;
//des.bits.liquid_static = 0;
//des.bits.water_stagnant = 0;
//des.bits.water_salt = 0;
2011-05-13 11:37:48 -06:00
}
2011-11-05 04:55:23 -06:00
map . setDesignationAt ( * iter , des ) ;
2011-05-13 11:37:48 -06:00
}
if ( map . WriteAll ( ) )
{
2011-08-10 20:39:12 -06:00
c - > con . print ( " OK \n " ) ;
2011-05-13 11:37:48 -06:00
}
else
{
2011-08-10 20:39:12 -06:00
c - > con . printerr ( " Something failed horribly! RUN! \n " ) ;
2011-05-13 11:37:48 -06:00
}
}
}
2011-08-10 20:39:12 -06:00
return CR_OK ;
2011-05-13 11:37:48 -06:00
}