@ -1,5 +1,3 @@
// TO BE DEPRECATED SOON.
# include <iostream>
# include <vector>
# include <map>
@ -7,7 +5,128 @@
using namespace std ;
# include <DFHack.h>
# include <dfhack/DFTileTypes.h>
# include <dfhack/extra/MapExtras.h>
# include <set>
using namespace MapExtras ;
typedef vector < DFHack : : DFCoord > coord_vec ;
class Brush
{
public :
virtual ~ Brush ( ) { } ;
virtual coord_vec points ( 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
{
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 ( 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 ( ) { } ;
private :
int x_ , y_ , z_ ;
int cx_ , cy_ , cz_ ;
} ;
/**
* 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 ( 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 ( MapCache & mc , DFHack : : DFCoord start )
{
coord_vec v ;
bool juststarted = true ;
while ( mc . testCoord ( start ) )
{
uint16_t tt = mc . tiletypeAt ( start ) ;
if ( DFHack : : LowPassable ( tt ) | | juststarted & & DFHack : : HighPassable ( tt ) )
{
v . push_back ( start ) ;
juststarted = false ;
start . z + + ;
}
else break ;
}
return v ;
} ;
} ;
int main ( int argc , char * * argv )
{
@ -21,15 +140,18 @@ int main (int argc, char** argv)
}
}
int32_t x , y , z ;
/*
DFHack : : designations40d designations ;
DFHack : : tiletypes40d tiles ;
DFHack : : t_temperatures temp1 , temp2 ;
*/
uint32_t x_max , y_max , z_max ;
DFHack : : ContextManager DFMgr ( " Memory.xml " ) ;
DFHack : : Context * DF ;
DFHack : : Maps * Maps ;
DFHack : : Position * Position ;
Brush * brush = new RectangleBrush ( 1 , 1 ) ;
try
{
DF = DFMgr . getSingleContext ( ) ;
@ -50,12 +172,11 @@ int main (int argc, char** argv)
bool end = false ;
cout < < " Welcome to the liquid spawner. type 'help' for a list of available commands, 'q' to quit. " < < endl ;
string mode = " magma " ;
string brush = " point " ;
string flowmode = " f+ " ;
string setmode = " s. " ;
int amount = 7 ;
int width = 1 ;
int height = 1 ;
int width = 1 , height = 1 , z_levels = 1 ;
while ( ! end )
{
DF - > Resume ( ) ;
@ -68,6 +189,8 @@ int main (int argc, char** argv)
< < " m - switch to magma " < < endl
< < " w - switch to water " < < endl
< < " o - make obsidian wall instead " < < endl
< < " of - make obsidian floors " < < endl
< < " rs - make a river source " < < endl
< < " f - flow bits only " < < endl
< < " Set-Modes: " < < endl
< < " s+ - only add " < < endl
@ -80,8 +203,9 @@ int main (int argc, char** argv)
< < " 0-7 - set liquid amount " < < endl
< < " Brush: " < < endl
< < " point - single tile [p] " < < endl
< < " range - rectangle with cursor at top left [r] " < < endl
< < " block - block with cursor in it " < < endl
< < " range - block with cursor at bottom north-west [r] " < < endl
< < " block - DF map block with cursor in it " < < endl
< < " column - Column up through free space " < < endl
< < " Other: " < < endl
< < " q - quit " < < endl
< < " help - print this list of commands " < < endl
@ -98,17 +222,9 @@ int main (int argc, char** argv)
{
mode = " obsidian " ;
}
else if ( command = = " clmn " )
{
mode = " column " ;
}
else if ( command = = " starruby " )
{
mode = " starruby " ;
}
else if ( command = = " darkhide " )
else if ( command = = " of " )
{
mode = " darkhide " ;
mode = " obsidian_floor " ;
}
else if ( command = = " w " )
{
@ -118,9 +234,14 @@ int main (int argc, char** argv)
{
mode = " flowbits " ;
}
else if ( command = = " rs " )
{
mode = " riversource " ;
}
else if ( command = = " point " | | command = = " p " )
{
brush = " point " ;
delete brush ;
brush = new RectangleBrush ( 1 , 1 ) ;
}
else if ( command = = " range " | | command = = " r " )
{
@ -128,15 +249,28 @@ int main (int argc, char** argv)
getline ( cin , command ) ;
width = command = = " " ? width : atoi ( command . c_str ( ) ) ;
if ( width < 1 ) width = 1 ;
cout < < " :set range height< " < < height < < " ># " ;
getline ( cin , command ) ;
height = command = = " " ? height : atoi ( command . c_str ( ) ) ;
if ( height < 1 ) height = 1 ;
brush = " range " ;
cout < < " :set range z-levels< " < < z_levels < < " ># " ;
getline ( cin , command ) ;
z_levels = command = = " " ? z_levels : atoi ( command . c_str ( ) ) ;
if ( z_levels < 1 ) z_levels = 1 ;
delete brush ;
brush = new RectangleBrush ( width , height , z_levels , 0 , 0 , 0 ) ;
}
else if ( command = = " block " )
{
brush = " block " ;
delete brush ;
brush = new BlockBrush ( ) ;
}
else if ( command = = " column " )
{
delete brush ;
brush = new ColumnBrush ( ) ;
}
else if ( command = = " q " )
{
@ -199,273 +333,134 @@ int main (int argc, char** argv)
break ;
}
cout < < " cursor coords: " < < x < < " / " < < y < < " / " < < z < < endl ;
if ( ! Maps - > isValidBlock ( x / 16 , y / 16 , z ) )
{
cout < < " Not a valid block. " < < endl ;
break ;
}
MapCache mcache ( Maps ) ;
cout < < " getting tiles from brush " < < endl ;
DFHack : : DFCoord cursor ( x , y , z ) ;
coord_vec all_tiles = brush - > points ( mcache , cursor ) ;
cout < < " doing things " < < endl ;
if ( mode = = " obsidian " )
{
Maps - > ReadTileTypes ( ( x / 16 ) , ( y / 16 ) , z , & tiles ) ;
tiles [ x % 16 ] [ y % 16 ] = 331 ;
Maps - > WriteTileTypes ( ( x / 16 ) , ( y / 16 ) , z , & tiles ) ;
}
else if ( mode = = " column " )
{
int zzz = z ;
int16_t tile ;
while ( zzz < z_max )
coord_vec : : iterator iter = all_tiles . begin ( ) ;
while ( iter ! = all_tiles . end ( ) )
{
Maps - > ReadTileTypes ( ( x / 16 ) , ( y / 16 ) , zzz , & tiles ) ;
tile = tiles [ x % 16 ] [ y % 16 ] ;
if ( DFHack : : tileTypeTable [ tile ] . c = = DFHack : : WALL )
break ;
tiles [ x % 16 ] [ y % 16 ] = 331 ;
Maps - > WriteTileTypes ( ( x / 16 ) , ( y / 16 ) , zzz , & tiles ) ;
zzz + + ;
}
mcache . setTiletypeAt ( * iter , 331 ) ;
iter + + ;
}
}
// quick hack, do not use for serious stuff
/*
else if ( mode = = " starruby " )
if ( mode = = " obsidian_floor " )
{
if ( Maps - > isValidBlock ( ( x / 16 ) , ( y / 16 ) , z ) )
coord_vec : : iterator iter = all_tiles . begin ( ) ;
while ( iter ! = all_tiles . end ( ) )
{
Maps - > ReadTileTypes ( ( x / 16 ) , ( y / 16 ) , z , & tiles ) ;
Maps - > ReadDesignations ( ( x / 16 ) , ( y / 16 ) , z , & designations ) ;
Maps - > ReadTemperatures ( ( x / 16 ) , ( y / 16 ) , z , & temp1 , & temp2 ) ;
cout < < " sizeof(designations) = " < < sizeof ( designations ) < < endl ;
cout < < " sizeof(tiletypes) = " < < sizeof ( tiles ) < < endl ;
for ( uint32_t xx = 0 ; xx < 16 ; xx + + ) for ( uint32_t yy = 0 ; yy < 16 ; yy + + )
{
cout < < xx < < " " < < yy < < " : " < < tiles [ xx ] [ yy ] < < endl ;
tiles [ xx ] [ yy ] = 335 ; // 45
DFHack : : naked_designation & des = designations [ xx ] [ yy ] . bits ;
des . feature_local = true ;
des . feature_global = false ;
des . flow_size = 0 ;
des . skyview = 0 ;
des . light = 0 ;
des . subterranean = 1 ;
temp1 [ xx ] [ yy ] = 10015 ;
temp2 [ xx ] [ yy ] = 10015 ;
}
Maps - > WriteTemperatures ( ( x / 16 ) , ( y / 16 ) , z , & temp1 , & temp2 ) ;
Maps - > WriteDesignations ( ( x / 16 ) , ( y / 16 ) , z , & designations ) ;
Maps - > WriteTileTypes ( ( x / 16 ) , ( y / 16 ) , z , & tiles ) ;
Maps - > WriteLocalFeature ( ( x / 16 ) , ( y / 16 ) , z , 36 ) ;
mcache . setTiletypeAt ( * iter , 340 ) ;
iter + + ;
}
}
else if ( mode = = " darkhid e" )
else if ( mode = = " riversource " )
{
int16_t zzz = z ;
while ( zzz > = 0 )
set < Block * > seen_blocks ;
coord_vec : : iterator iter = all_tiles . begin ( ) ;
while ( iter ! = all_tiles . end ( ) )
{
if ( Maps - > isValidBlock ( ( x / 16 ) , ( y / 16 ) , zzz ) )
{
int xx = x % 16 ;
int yy = y % 16 ;
Maps - > ReadDesignations ( ( x / 16 ) , ( y / 16 ) , zzz , & designations ) ;
designations [ xx ] [ yy ] . bits . skyview = 0 ;
designations [ xx ] [ yy ] . bits . light = 0 ;
designations [ xx ] [ yy ] . bits . subterranean = 1 ;
Maps - > WriteDesignations ( ( x / 16 ) , ( y / 16 ) , zzz , & designations ) ;
}
zzz - - ;
mcache . setTiletypeAt ( * iter , 90 ) ;
DFHack : : t_designation a = mcache . designationAt ( * iter ) ;
a . bits . liquid_type = DFHack : : liquid_water ;
a . bits . liquid_static = false ;
a . bits . flow_size = 7 ;
mcache . setDesignationAt ( * iter , a ) ;
Block * b = mcache . BlockAt ( ( * iter ) / 16 ) ;
DFHack : : t_blockflags bf = b - > BlockFlags ( ) ;
bf . bits . liquid_1 = true ;
bf . bits . liquid_2 = true ;
b - > setBlockFlags ( bf ) ;
iter + + ;
}
}
*/
else
else if ( mode = = " magma " | | mode = = " water " | | mode = = " flowbits " )
{
// place the magma
if ( brush ! = " range " )
set < Block * > seen_blocks ;
coord_vec : : iterator iter = all_tiles . begin ( ) ;
while ( iter ! = all_tiles . end ( ) )
{
Maps - > ReadDesignations ( ( x / 16 ) , ( y / 16 ) , z , & designations ) ;
Maps - > ReadTemperatures ( ( x / 16 ) , ( y / 16 ) , z , & temp1 , & temp2 ) ;
if ( brush = = " point " )
DFHack : : DFCoord current = * iter ;
DFHack : : t_designation des = mcache . designationAt ( current ) ;
uint16_t tt = mcache . tiletypeAt ( current ) ;
DFHack : : naked_designation & flow = des . bits ;
if ( mode ! = " flowbits " )
{
if ( mode ! = " flowbits " )
if ( ! DFHack : : FlowPassable ( tt ) )
{
iter + + ;
continue ;
}
// if we are setting the levels to 0 or changing magma into water
if ( amount = = 0 | | des . bits . liquid_type = = DFHack : : liquid_magma & & mode = = " water " )
{
// reset temperature to sane default
mcache . setTemp1At ( current , 10015 ) ;
mcache . setTemp2At ( current , 10015 ) ;
}
if ( setmode = = " s. " )
{
// fix temperatures so we don't produce lethal heat traps
if ( amount = = 0 | | designations [ x % 16 ] [ y % 16 ] . bits . liquid_type = = DFHack : : liquid_magma & & mode = = " water " )
temp1 [ x % 16 ] [ y % 16 ] = temp2 [ x % 16 ] [ y % 16 ] = 10015 ;
DFHack : : naked_designation & flow = designations [ x % 16 ] [ y % 16 ] . bits ;
if ( setmode = = " s. " )
{
flow . flow_size = amount ;
}
else if ( setmode = = " s+ " )
{
if ( flow . flow_size < amount )
flow . flow_size = amount ;
}
else if ( setmode = = " s+ " )
{
if ( flow . flow_size < amount )
flow . flow_size = amount ;
}
else if ( setmode = = " s- " )
{
if ( flow . flow_size > amount )
flow . flow_size = amount ;
}
}
if ( mode = = " magma " )
designations [ x % 16 ] [ y % 16 ] . bits . liquid_type = DFHack : : liquid_magma ;
else if ( mode = = " water " )
designations [ x % 16 ] [ y % 16 ] . bits . liquid_type = DFHack : : liquid_water ;
}
else
{
for ( uint32_t xx = 0 ; xx < 16 ; xx + + ) for ( uint32_t yy = 0 ; yy < 16 ; yy + + )
else if ( setmode = = " s- " )
{
if ( mode ! = " flowbits " )
{
// fix temperatures so we don't produce lethal heat traps
if ( amount = = 0 | | designations [ xx ] [ yy ] . bits . liquid_type = = DFHack : : liquid_magma & & mode = = " water " )
temp1 [ xx % 16 ] [ yy % 16 ] = temp2 [ xx % 16 ] [ yy % 16 ] = 10015 ;
DFHack : : naked_designation & flow = designations [ xx ] [ yy ] . bits ;
if ( setmode = = " s. " )
{
flow . flow_size = amount ;
}
else if ( setmode = = " s+ " )
{
if ( flow . flow_size < amount )
flow . flow_size = amount ;
}
else if ( setmode = = " s- " )
{
if ( flow . flow_size > amount )
flow . flow_size = amount ;
}
}
if ( mode = = " magma " )
designations [ xx ] [ yy ] . bits . liquid_type = DFHack : : liquid_magma ;
else if ( mode = = " water " )
designations [ xx ] [ yy ] . bits . liquid_type = DFHack : : liquid_water ;
if ( flow . flow_size > amount )
flow . flow_size = amount ;
}
if ( mode = = " magma " )
flow . liquid_type = DFHack : : liquid_magma ;
else if ( mode = = " water " )
flow . liquid_type = DFHack : : liquid_water ;
mcache . setDesignationAt ( current , des ) ;
}
Maps - > WriteTemperatures ( ( x / 16 ) , ( y / 16 ) , z , & temp1 , & temp2 ) ;
Maps - > WriteDesignations ( x / 16 , y / 16 , z , & designations ) ;
// make the magma flow :)
DFHack : : t_blockflags bflags ;
Maps - > ReadBlockFlags ( ( x / 16 ) , ( y / 16 ) , z , bflags ) ;
// 0x00000001 = job-designated
// 0x0000000C = run flows? - both bit 3 and 4 required for making magma placed on a glacier flow
seen_blocks . insert ( mcache . BlockAt ( ( * iter ) / 16 ) ) ;
iter + + ;
}
set < Block * > : : iterator biter = seen_blocks . begin ( ) ;
while ( biter ! = seen_blocks . end ( ) )
{
DFHack : : t_blockflags bflags = ( * biter ) - > BlockFlags ( ) ;
if ( flowmode = = " f+ " )
{
bflags . bits . liquid_1 = true ;
bflags . bits . liquid_2 = true ;
( * biter ) - > setBlockFlags ( bflags ) ;
}
else if ( flowmode = = " f- " )
{
bflags . bits . liquid_1 = false ;
bflags . bits . liquid_2 = false ;
( * biter ) - > setBlockFlags ( bflags ) ;
}
else
{
cout < < " flow bit 1 = " < < bflags . bits . liquid_1 < < endl ;
cout < < " flow bit 2 = " < < bflags . bits . liquid_2 < < endl ;
}
Maps- > WriteBlockFlags ( ( x / 16 ) , ( y / 16 ) , z , bflags ) ;
biter + + ;
}
else if ( brush = = " range " )
{
// Crop the range into each block if necessary
int beginxblock = x / 16 ;
int endxblock = ( x + width ) / 16 ;
int beginyblock = y / 16 ;
int endyblock = ( y + height ) / 16 ;
for ( uint32_t bx = beginxblock ; bx < endxblock + 1 ; bx + + ) for ( uint32_t by = beginyblock ; by < endyblock + 1 ; by + + )
{
if ( Maps - > isValidBlock ( bx , by , z ) )
{
Maps - > ReadDesignations ( bx , by , z , & designations ) ;
Maps - > ReadTemperatures ( bx , by , z , & temp1 , & temp2 ) ;
// Take original range and crop it into current block
int nx = x ;
int ny = y ;
int nwidth = width ;
int nheight = height ;
if ( x / 16 < bx ) //Start point is left of block
{
nx = bx * 16 ;
nwidth - = nx - x ;
}
if ( nx / 16 < ( nx + nwidth - 1 ) / 16 ) // End point is right of block
{
nwidth = ( bx * 16 ) + 16 - nx ;
}
if ( y / 16 < by ) //Start point is above block
{
ny = by * 16 ;
nheight - = ny - y ;
}
if ( ny / 16 < ( ny + nheight - 1 ) / 16 ) // End point is below block
{
nheight = ( by * 16 ) + 16 - ny ;
}
cout < < " Block: " < < bx < < " , " < < by < < " : " < < endl ;
cout < < " Start: " < < nx < < " , " < < ny < < " : " < < endl ;
cout < < " Area: " < < nwidth < < " , " < < nheight < < " : " < < endl ;
for ( uint32_t xx = nx ; xx < nx + nwidth ; xx + + ) for ( uint32_t yy = ny ; yy < ny + nheight ; yy + + )
{
if ( mode ! = " flowbits " )
{
// fix temperatures so we don't produce lethal heat traps
if ( amount = = 0 | | designations [ xx % 16 ] [ yy % 16 ] . bits . liquid_type = = DFHack : : liquid_magma & & mode = = " water " )
temp1 [ xx % 16 ] [ yy % 16 ] = temp2 [ xx % 16 ] [ yy % 16 ] = 10015 ;
DFHack : : naked_designation & flow = designations [ xx % 16 ] [ yy % 16 ] . bits ;
if ( setmode = = " s. " )
{
flow . flow_size = amount ;
}
else if ( setmode = = " s+ " )
{
if ( flow . flow_size < amount )
flow . flow_size = amount ;
}
else if ( setmode = = " s- " )
{
if ( flow . flow_size > amount )
flow . flow_size = amount ;
}
}
if ( mode = = " magma " )
designations [ xx % 16 ] [ yy % 16 ] . bits . liquid_type = DFHack : : liquid_magma ;
else if ( mode = = " water " )
designations [ xx % 16 ] [ yy % 16 ] . bits . liquid_type = DFHack : : liquid_water ;
}
Maps - > WriteTemperatures ( bx , by , z , & temp1 , & temp2 ) ;
Maps - > WriteDesignations ( bx , by , z , & designations ) ;
// make the magma flow :)
DFHack : : t_blockflags bflags ;
Maps - > ReadBlockFlags ( bx , by , z , bflags ) ;
// 0x00000001 = job-designated
// 0x0000000C = run flows? - both bit 3 and 4 required for making magma placed on a glacier flow
if ( flowmode = = " f+ " )
{
bflags . bits . liquid_1 = true ;
bflags . bits . liquid_2 = true ;
}
else if ( flowmode = = " f- " )
{
bflags . bits . liquid_1 = false ;
bflags . bits . liquid_2 = false ;
}
else
{
cout < < " flow bit 1 = " < < bflags . bits . liquid_1 < < endl ;
cout < < " flow bit 2 = " < < bflags . bits . liquid_2 < < endl ;
}
Maps - > WriteBlockFlags ( bx , by , z , bflags ) ;
}
}
}
}
cout < < " OK " < < endl ;
if ( mcache . WriteAll ( ) )
cout < < " OK " < < endl ;
else
cout < < " Something failed horribly! RUN! " < < endl ;
Maps - > Finish ( ) ;
} while ( 0 ) ;
}
else
{
cout < < command < < " : unknown command. " < < endl ;
}
}
DF - > Detach ( ) ;
# ifndef LINUX_BUILD