|
|
|
@ -10,6 +10,9 @@
|
|
|
|
|
#include <assert.h>
|
|
|
|
|
#include <math.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <limits.h>
|
|
|
|
|
using namespace std;
|
|
|
|
|
|
|
|
|
|
#include <DFHack.h>
|
|
|
|
@ -48,7 +51,8 @@ void waitmsec (int delay)
|
|
|
|
|
//end PITTYPEMACRO
|
|
|
|
|
|
|
|
|
|
#define X(name,desc) name,
|
|
|
|
|
enum e_pitType {
|
|
|
|
|
enum e_pitType
|
|
|
|
|
{
|
|
|
|
|
pitTypeInvalid=-1,
|
|
|
|
|
PITTYPEMACRO
|
|
|
|
|
pitTypeCount,
|
|
|
|
@ -67,20 +71,33 @@ const char * pitTypeDesc[pitTypeCount+1] =
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int getyesno( const char * msg , int default_value ){
|
|
|
|
|
int getyesno( const char * msg , int default_value )
|
|
|
|
|
{
|
|
|
|
|
const int bufferlen=4;
|
|
|
|
|
static char buf[bufferlen];
|
|
|
|
|
memset(buf,0,bufferlen);
|
|
|
|
|
while(-1){
|
|
|
|
|
while (-1)
|
|
|
|
|
{
|
|
|
|
|
if (msg) printf("\n%s (default=%s)\n:" , msg , (default_value?"yes":"no") );
|
|
|
|
|
fflush(stdin);
|
|
|
|
|
fgets(buf,bufferlen,stdin);
|
|
|
|
|
switch(buf[0]){
|
|
|
|
|
case 0: case 0x0d: case 0x0a:
|
|
|
|
|
switch (buf[0])
|
|
|
|
|
{
|
|
|
|
|
case 0:
|
|
|
|
|
case 0x0d:
|
|
|
|
|
case 0x0a:
|
|
|
|
|
return default_value;
|
|
|
|
|
case 'y': case 'Y': case 'T': case 't': case '1':
|
|
|
|
|
case 'y':
|
|
|
|
|
case 'Y':
|
|
|
|
|
case 'T':
|
|
|
|
|
case 't':
|
|
|
|
|
case '1':
|
|
|
|
|
return -1;
|
|
|
|
|
case 'n': case 'N': case 'F': case 'f': case '0':
|
|
|
|
|
case 'n':
|
|
|
|
|
case 'N':
|
|
|
|
|
case 'F':
|
|
|
|
|
case 'f':
|
|
|
|
|
case '0':
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -92,29 +109,50 @@ int getint( const char * msg , int min, int max, int default_value ){
|
|
|
|
|
static char buf[bufferlen];
|
|
|
|
|
int n=0;
|
|
|
|
|
memset(buf,0,bufferlen);
|
|
|
|
|
while(-1){
|
|
|
|
|
while (-1)
|
|
|
|
|
{
|
|
|
|
|
if (msg) printf("\n%s (default=%d)\n:" , msg , default_value);
|
|
|
|
|
fflush(stdin);
|
|
|
|
|
fgets(buf,bufferlen,stdin);
|
|
|
|
|
if( !buf[0] || 0x0a==buf[0] || 0x0d==buf[0] ) return default_value;
|
|
|
|
|
if( sscanf(buf,"%d", &n) ){
|
|
|
|
|
if(n>=min && n<=max ) return n;
|
|
|
|
|
if ( !buf[0] || 0x0a==buf[0] || 0x0d==buf[0] )
|
|
|
|
|
{
|
|
|
|
|
return default_value;
|
|
|
|
|
}
|
|
|
|
|
if ( sscanf(buf,"%d", &n) )
|
|
|
|
|
{
|
|
|
|
|
if (n>=min && n<=max )
|
|
|
|
|
{
|
|
|
|
|
return n;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int getint( const char * msg , int min, int max ){
|
|
|
|
|
int getint( const char * msg , int min, int max )
|
|
|
|
|
{
|
|
|
|
|
const int bufferlen=16;
|
|
|
|
|
static char buf[bufferlen];
|
|
|
|
|
int n=0;
|
|
|
|
|
memset(buf,0,bufferlen);
|
|
|
|
|
while(-1){
|
|
|
|
|
if(msg) printf("\n%s \n:" , msg );
|
|
|
|
|
while (-1)
|
|
|
|
|
{
|
|
|
|
|
if (msg)
|
|
|
|
|
{
|
|
|
|
|
printf("\n%s \n:" , msg );
|
|
|
|
|
}
|
|
|
|
|
fflush(stdin);
|
|
|
|
|
fgets(buf,bufferlen,stdin);
|
|
|
|
|
if( !buf[0] || 0x0a==buf[0] || 0x0d==buf[0] ) continue;
|
|
|
|
|
if( sscanf(buf,"%d", &n) ){
|
|
|
|
|
if(n>=min && n<=max ) return n;
|
|
|
|
|
|
|
|
|
|
if ( !buf[0] || 0x0a==buf[0] || 0x0d==buf[0] )
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if ( sscanf(buf,"%d", &n) )
|
|
|
|
|
{
|
|
|
|
|
if (n>=min && n<=max )
|
|
|
|
|
{
|
|
|
|
|
return n;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -122,10 +160,13 @@ int getint( const char * msg , int min, int max ){
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//Interactive, get pit type from user
|
|
|
|
|
e_pitType selectPitType(){
|
|
|
|
|
while( -1 ){
|
|
|
|
|
e_pitType selectPitType()
|
|
|
|
|
{
|
|
|
|
|
while ( -1 )
|
|
|
|
|
{
|
|
|
|
|
printf("Enter the type of hole to dig:\n" );
|
|
|
|
|
for(int n=0;n<pitTypeCount;++n){
|
|
|
|
|
for (int n=0;n<pitTypeCount;++n)
|
|
|
|
|
{
|
|
|
|
|
printf("%2d) %s\n", n, pitTypeDesc[n] );
|
|
|
|
|
}
|
|
|
|
|
printf(":");
|
|
|
|
@ -134,16 +175,20 @@ e_pitType selectPitType(){
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void drawcircle(const int radius, unsigned char pattern[16][16], unsigned char v ){
|
|
|
|
|
void drawcircle(const int radius, unsigned char pattern[16][16], unsigned char v )
|
|
|
|
|
{
|
|
|
|
|
//Small circles get better randomness if handled manually
|
|
|
|
|
if( 1==radius ){
|
|
|
|
|
if ( 1==radius )
|
|
|
|
|
{
|
|
|
|
|
pattern[7][7]=v;
|
|
|
|
|
if ( (rand()&1) ) pattern[6][7]=v;
|
|
|
|
|
if ( (rand()&1) ) pattern[8][7]=v;
|
|
|
|
|
if ( (rand()&1) ) pattern[7][6]=v;
|
|
|
|
|
if ( (rand()&1) ) pattern[7][8]=v;
|
|
|
|
|
|
|
|
|
|
}else if( 2==radius ){
|
|
|
|
|
}
|
|
|
|
|
else if ( 2==radius )
|
|
|
|
|
{
|
|
|
|
|
pattern[7][7]=v;
|
|
|
|
|
pattern[7][5]=v;
|
|
|
|
|
pattern[7][6]=v;
|
|
|
|
@ -166,12 +211,17 @@ void drawcircle(const int radius, unsigned char pattern[16][16], unsigned char v
|
|
|
|
|
if ( (rand()&1) ) pattern[5][8]=v;
|
|
|
|
|
if ( (rand()&1) ) pattern[8][9]=v;
|
|
|
|
|
if ( (rand()&1) ) pattern[9][8]=v;
|
|
|
|
|
}else{
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
//radius 3 or larger, simple circle calculation.
|
|
|
|
|
int x,y;
|
|
|
|
|
for(y=0-radius; y<=radius; ++y){
|
|
|
|
|
for(x=0-radius; x<=radius; ++x){
|
|
|
|
|
if(x*x+y*y <= radius*radius + (rand()&31-8) ){
|
|
|
|
|
for (y=0-radius; y<=radius; ++y)
|
|
|
|
|
{
|
|
|
|
|
for (x=0-radius; x<=radius; ++x)
|
|
|
|
|
{
|
|
|
|
|
if (x*x+y*y <= radius*radius + (rand()&31-8) )
|
|
|
|
|
{
|
|
|
|
|
pattern[ minmax(0,7+x,15) ][ minmax(0,7+y,15) ]=v;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -190,14 +240,46 @@ void drawcircle(const int radius, unsigned char pattern[16][16], unsigned char v
|
|
|
|
|
int checkneighbors(unsigned char pattern[16][16], int x, int y, unsigned char n , char v )
|
|
|
|
|
{
|
|
|
|
|
int r=0;
|
|
|
|
|
if( x>0 && y>0 && n==pattern[x-1][y-1] ){ ++r; if(v>-1) pattern[x][y]=v; }
|
|
|
|
|
if( x>0 && n==pattern[x-1][y ] ){ ++r; if(v>-1) pattern[x][y]=v; }
|
|
|
|
|
if( y>0 && n==pattern[x ][y-1] ){ ++r; if(v>-1) pattern[x][y]=v; }
|
|
|
|
|
if( x<15 && n==pattern[x+1][y ] ){ ++r; if(v>-1) pattern[x][y]=v; }
|
|
|
|
|
if( x<15 && y>0 && n==pattern[x+1][y-1] ){ ++r; if(v>-1) pattern[x][y]=v; }
|
|
|
|
|
if( x<15 && y<15 && n==pattern[x+1][y+1] ){ ++r; if(v>-1) pattern[x][y]=v; }
|
|
|
|
|
if( y<15 && n==pattern[x ][y+1] ){ ++r; if(v>-1) pattern[x][y]=v; }
|
|
|
|
|
if( x>0 && y<15 && n==pattern[x-1][y+1] ){ ++r; if(v>-1) pattern[x][y]=v; }
|
|
|
|
|
if ( x>0 && y>0 && n==pattern[x-1][y-1] )
|
|
|
|
|
{
|
|
|
|
|
++r;
|
|
|
|
|
if (v>-1) pattern[x][y]=v;
|
|
|
|
|
}
|
|
|
|
|
if ( x>0 && n==pattern[x-1][y ] )
|
|
|
|
|
{
|
|
|
|
|
++r;
|
|
|
|
|
if (v>-1) pattern[x][y]=v;
|
|
|
|
|
}
|
|
|
|
|
if ( y>0 && n==pattern[x ][y-1] )
|
|
|
|
|
{
|
|
|
|
|
++r;
|
|
|
|
|
if (v>-1) pattern[x][y]=v;
|
|
|
|
|
}
|
|
|
|
|
if ( x<15 && n==pattern[x+1][y ] )
|
|
|
|
|
{
|
|
|
|
|
++r;
|
|
|
|
|
if (v>-1) pattern[x][y]=v;
|
|
|
|
|
}
|
|
|
|
|
if ( x<15 && y>0 && n==pattern[x+1][y-1] )
|
|
|
|
|
{
|
|
|
|
|
++r;
|
|
|
|
|
if (v>-1) pattern[x][y]=v;
|
|
|
|
|
}
|
|
|
|
|
if ( x<15 && y<15 && n==pattern[x+1][y+1] )
|
|
|
|
|
{
|
|
|
|
|
++r;
|
|
|
|
|
if (v>-1) pattern[x][y]=v;
|
|
|
|
|
}
|
|
|
|
|
if ( y<15 && n==pattern[x ][y+1] )
|
|
|
|
|
{
|
|
|
|
|
++r;
|
|
|
|
|
if (v>-1) pattern[x][y]=v;
|
|
|
|
|
}
|
|
|
|
|
if ( x>0 && y<15 && n==pattern[x-1][y+1] )
|
|
|
|
|
{
|
|
|
|
|
++r;
|
|
|
|
|
if (v>-1) pattern[x][y]=v;
|
|
|
|
|
}
|
|
|
|
|
return r;
|
|
|
|
|
}
|
|
|
|
|
//convenience
|
|
|
|
@ -212,12 +294,17 @@ void settileat(unsigned char pattern[16][16], const unsigned char needle, const
|
|
|
|
|
int safety=256*256;
|
|
|
|
|
int y,x,i=0;
|
|
|
|
|
//Scan for sequential index
|
|
|
|
|
while( !ok && --safety ){
|
|
|
|
|
for(y=0 ; !ok && y<16 ; ++y ){
|
|
|
|
|
for(x=0 ; !ok && x<16 ; ++x ){
|
|
|
|
|
if( needle==pattern[x][y] ){
|
|
|
|
|
while ( !ok && --safety )
|
|
|
|
|
{
|
|
|
|
|
for (y=0 ; !ok && y<16 ; ++y )
|
|
|
|
|
{
|
|
|
|
|
for (x=0 ; !ok && x<16 ; ++x )
|
|
|
|
|
{
|
|
|
|
|
if ( needle==pattern[x][y] )
|
|
|
|
|
{
|
|
|
|
|
++i;
|
|
|
|
|
if( index==i ){
|
|
|
|
|
if ( index==i )
|
|
|
|
|
{
|
|
|
|
|
//Got it!
|
|
|
|
|
pattern[x][y]=v;
|
|
|
|
|
ok=-1;
|
|
|
|
@ -229,6 +316,7 @@ void settileat(unsigned char pattern[16][16], const unsigned char needle, const
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//FIXME: good candidate for adding to dfhack. Maybe the Maps should have those cached so they can be queried?
|
|
|
|
|
//Is a given feature present at the given tile?
|
|
|
|
|
int isfeature(
|
|
|
|
|
vector<DFHack::t_feature> global_features,
|
|
|
|
@ -251,7 +339,7 @@ int isfeature(
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// FIXME: use block cache, break into manageable bits
|
|
|
|
|
int main (void)
|
|
|
|
|
{
|
|
|
|
|
srand ( (unsigned int)time(NULL) );
|
|
|
|
@ -294,7 +382,8 @@ int main (void)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//Modify default settings based on pit type.
|
|
|
|
|
switch( pittype ){
|
|
|
|
|
switch ( pittype )
|
|
|
|
|
{
|
|
|
|
|
case pitTypeChasm:
|
|
|
|
|
floor=35;
|
|
|
|
|
break;
|
|
|
|
@ -351,8 +440,8 @@ int main (void)
|
|
|
|
|
|
|
|
|
|
int accept = getyesno("Use default settings?",1);
|
|
|
|
|
|
|
|
|
|
while( !accept ){
|
|
|
|
|
|
|
|
|
|
while ( !accept )
|
|
|
|
|
{
|
|
|
|
|
//Pit Depth
|
|
|
|
|
pitdepth = getint( "Enter max depth (0 for bottom of map)", 0, INT_MAX, pitdepth );
|
|
|
|
|
|
|
|
|
@ -409,7 +498,8 @@ int main (void)
|
|
|
|
|
unsigned char pattern[16][16];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for(int regen=1;regen; ){
|
|
|
|
|
for (int regen=1;regen; )
|
|
|
|
|
{
|
|
|
|
|
regen=0;
|
|
|
|
|
|
|
|
|
|
memset(pattern,0,sizeof(pattern));
|
|
|
|
@ -420,25 +510,34 @@ int main (void)
|
|
|
|
|
|
|
|
|
|
//Two concentric irregular circles
|
|
|
|
|
//Outer circle, solid.
|
|
|
|
|
if( wallthickness ){
|
|
|
|
|
if ( wallthickness )
|
|
|
|
|
{
|
|
|
|
|
drawcircle(holeradius+wallthickness, pattern, 2);
|
|
|
|
|
}
|
|
|
|
|
//Inner circle, hole.
|
|
|
|
|
if( holeradius ){
|
|
|
|
|
if ( holeradius )
|
|
|
|
|
{
|
|
|
|
|
drawcircle(holeradius, pattern, 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//Post-process to be certain the wall totally encloses hole.
|
|
|
|
|
if(wallthickness){
|
|
|
|
|
for(y=0;y<16;++y){
|
|
|
|
|
for(x=0;x<16;++x){
|
|
|
|
|
if( 1==pattern[x][y] ){
|
|
|
|
|
if (wallthickness)
|
|
|
|
|
{
|
|
|
|
|
for (y=0;y<16;++y)
|
|
|
|
|
{
|
|
|
|
|
for (x=0;x<16;++x)
|
|
|
|
|
{
|
|
|
|
|
if ( 1==pattern[x][y] )
|
|
|
|
|
{
|
|
|
|
|
//No hole at edges.
|
|
|
|
|
if( x<1 || x>14 || y<1 || y>14 ){
|
|
|
|
|
if ( x<1 || x>14 || y<1 || y>14 )
|
|
|
|
|
{
|
|
|
|
|
pattern[x][y]=2;
|
|
|
|
|
}
|
|
|
|
|
}else if( 0==pattern[x][y] ){
|
|
|
|
|
}
|
|
|
|
|
else if ( 0==pattern[x][y] )
|
|
|
|
|
{
|
|
|
|
|
//check neighbors
|
|
|
|
|
checkneighbors( pattern , x,y, 1, 2);
|
|
|
|
|
}
|
|
|
|
@ -448,15 +547,15 @@ int main (void)
|
|
|
|
|
|
|
|
|
|
//Makes sure that somewhere random gets a vertical pillar of rock which is safe
|
|
|
|
|
//to dig stairs down, to permit access to anywhere within the pit from the top.
|
|
|
|
|
for(n=holepillar; n ; --n){
|
|
|
|
|
for (n=holepillar; n ; --n)
|
|
|
|
|
{
|
|
|
|
|
settileat( pattern , 1 , 3 , rand()&255 );
|
|
|
|
|
}
|
|
|
|
|
for(n=wallpillar; n ; --n){
|
|
|
|
|
for (n=wallpillar; n ; --n)
|
|
|
|
|
{
|
|
|
|
|
settileat( pattern , 2 , 3 , rand()&255 );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//Note:
|
|
|
|
|
//At this point, the pattern holds:
|
|
|
|
|
//0 for all tiles which will be ignored.
|
|
|
|
@ -469,8 +568,10 @@ int main (void)
|
|
|
|
|
const char patternkey[] = ".cW!?567890123";
|
|
|
|
|
|
|
|
|
|
//Print the pattern
|
|
|
|
|
for(y=0;y<16;++y){
|
|
|
|
|
for(x=0;x<16;++x){
|
|
|
|
|
for (y=0;y<16;++y)
|
|
|
|
|
{
|
|
|
|
|
for (x=0;x<16;++x)
|
|
|
|
|
{
|
|
|
|
|
cout << patternkey[ pattern[x][y] ];
|
|
|
|
|
}
|
|
|
|
|
cout << endl;
|
|
|
|
@ -481,7 +582,10 @@ int main (void)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//Post-process settings to fix problems here
|
|
|
|
|
if(pitdepth<1) pitdepth=INT_MAX;
|
|
|
|
|
if (pitdepth<1)
|
|
|
|
|
{
|
|
|
|
|
pitdepth=INT_MAX;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
@ -528,7 +632,8 @@ int main (void)
|
|
|
|
|
int32_t cursorX, cursorY, cursorZ;
|
|
|
|
|
DFHack::Position *Pos = DF->getPosition();
|
|
|
|
|
Pos->getCursorCoords(cursorX,cursorY,cursorZ);
|
|
|
|
|
if(-30000==cursorX){
|
|
|
|
|
if (-30000==cursorX)
|
|
|
|
|
{
|
|
|
|
|
cout << "No cursor position found. Exiting." << endl;
|
|
|
|
|
#ifndef LINUX_BUILD
|
|
|
|
|
cin.ignore();
|
|
|
|
@ -541,7 +646,6 @@ int main (void)
|
|
|
|
|
//Tile coordinates within block
|
|
|
|
|
int32_t tx=cursorX%16, ty=cursorY%16, tz=cursorZ;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
//Access the DF interface to pause the game.
|
|
|
|
|
//Copied from the reveal tool.
|
|
|
|
@ -553,10 +657,11 @@ int main (void)
|
|
|
|
|
DF->Suspend();
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//Verify that every z-level at this location exists.
|
|
|
|
|
for(int32_t Z = 0; Z<= bz ;Z++){
|
|
|
|
|
if( ! Mapz->isValidBlock(bx,by,Z) ){
|
|
|
|
|
for (int32_t Z = 0; Z<= bz ;Z++)
|
|
|
|
|
{
|
|
|
|
|
if ( ! Mapz->isValidBlock(bx,by,Z) )
|
|
|
|
|
{
|
|
|
|
|
cout << "This block does't exist! Exiting." << endl;
|
|
|
|
|
#ifndef LINUX_BUILD
|
|
|
|
|
cin.ignore();
|
|
|
|
@ -567,15 +672,18 @@ int main (void)
|
|
|
|
|
|
|
|
|
|
//Get all the map features.
|
|
|
|
|
vector<DFHack::t_feature> global_features;
|
|
|
|
|
if(!Mapz->ReadGlobalFeatures(global_features)){
|
|
|
|
|
if (!Mapz->ReadGlobalFeatures(global_features))
|
|
|
|
|
{
|
|
|
|
|
cout << "Couldn't load global features! Probably a version problem." << endl;
|
|
|
|
|
#ifndef LINUX_BUILD
|
|
|
|
|
cin.ignore();
|
|
|
|
|
#endif
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::map <DFHack::planecoord, std::vector<DFHack::t_feature *> > local_features;
|
|
|
|
|
if(!Mapz->ReadLocalFeatures(local_features)){
|
|
|
|
|
if (!Mapz->ReadLocalFeatures(local_features))
|
|
|
|
|
{
|
|
|
|
|
cout << "Couldn't load local features! Probably a version problem." << endl;
|
|
|
|
|
#ifndef LINUX_BUILD
|
|
|
|
|
cin.ignore();
|
|
|
|
@ -588,7 +696,8 @@ int main (void)
|
|
|
|
|
Mapz->ReadBlock40d( bx, by, bz , &topblock );
|
|
|
|
|
//Related block info
|
|
|
|
|
planecoord pc;
|
|
|
|
|
pc.dim.x=bx; pc.dim.y=by;
|
|
|
|
|
pc.dim.x=bx;
|
|
|
|
|
pc.dim.y=by;
|
|
|
|
|
mapblock40d block;
|
|
|
|
|
const TileRow * tp;
|
|
|
|
|
t_designation * d;
|
|
|
|
@ -600,18 +709,28 @@ int main (void)
|
|
|
|
|
//Top level, cap.
|
|
|
|
|
//Might make this an option in the future
|
|
|
|
|
//For now, no wall means no cap.
|
|
|
|
|
if(wallthickness){
|
|
|
|
|
if (wallthickness)
|
|
|
|
|
{
|
|
|
|
|
Mapz->ReadBlock40d( bx, by, bz , &block );
|
|
|
|
|
for(uint32_t x=0;x<16;++x){
|
|
|
|
|
for(uint32_t y=0;y<16;++y){
|
|
|
|
|
if( (pattern[x][y]>1) || (roof && pattern[x][y]) ){
|
|
|
|
|
for (uint32_t x=0;x<16;++x)
|
|
|
|
|
{
|
|
|
|
|
for (uint32_t y=0;y<16;++y)
|
|
|
|
|
{
|
|
|
|
|
if ( (pattern[x][y]>1) || (roof && pattern[x][y]) )
|
|
|
|
|
{
|
|
|
|
|
tp = getTileTypeP(block.tiletypes[x][y]);
|
|
|
|
|
d = &block.designation[x][y];
|
|
|
|
|
//Only modify this level if it's 'empty'
|
|
|
|
|
if( EMPTY != tp->c && RAMP_TOP != tp->c && STAIR_DOWN != tp->c && DFHack::TILE_STREAM_TOP != tp->s) continue;
|
|
|
|
|
if ( EMPTY != tp->c && RAMP_TOP != tp->c && STAIR_DOWN != tp->c && DFHack::TILE_STREAM_TOP != tp->s)
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//Need a floor for empty space.
|
|
|
|
|
if(reveal) d->bits.hidden = 0; //topblock.designation[x][y].bits.hidden;
|
|
|
|
|
if (reveal)
|
|
|
|
|
{
|
|
|
|
|
d->bits.hidden = 0; //topblock.designation[x][y].bits.hidden;
|
|
|
|
|
}
|
|
|
|
|
//Always clear the dig designation.
|
|
|
|
|
d->bits.dig = designation_no;
|
|
|
|
|
//unlock fluids, so they fall down the pit.
|
|
|
|
@ -638,7 +757,8 @@ int main (void)
|
|
|
|
|
int32_t z = bz-1;
|
|
|
|
|
int32_t bottom = max(0,bz-pitdepth-1);
|
|
|
|
|
assert( bottom>=0 && bottom<=bz );
|
|
|
|
|
for( ; !done && z>=bottom ; --z){
|
|
|
|
|
for ( ; !done && z>=bottom ; --z)
|
|
|
|
|
{
|
|
|
|
|
int watercount=0;
|
|
|
|
|
int magmacount=0;
|
|
|
|
|
int moltencount=0;
|
|
|
|
@ -653,7 +773,8 @@ int main (void)
|
|
|
|
|
|
|
|
|
|
cout << z << endl;
|
|
|
|
|
assert( Mapz->isValidBlock(bx,by,z) );
|
|
|
|
|
if(!Mapz->ReadBlock40d( bx, by, z , &block )){
|
|
|
|
|
if (!Mapz->ReadBlock40d( bx, by, z , &block ))
|
|
|
|
|
{
|
|
|
|
|
cout << "Bad block! " << bx << "," << by << "," << z << endl;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -668,7 +789,8 @@ int main (void)
|
|
|
|
|
tpat=pattern[x][y];
|
|
|
|
|
|
|
|
|
|
//Tile type material categories
|
|
|
|
|
switch( tp->m ){
|
|
|
|
|
switch ( tp->m )
|
|
|
|
|
{
|
|
|
|
|
case AIR:
|
|
|
|
|
++emptycount;
|
|
|
|
|
break;
|
|
|
|
@ -684,40 +806,52 @@ int main (void)
|
|
|
|
|
//basicly, ignored.
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
if( EMPTY == tp->c || RAMP_TOP == tp->c || STAIR_DOWN == tp->c ){
|
|
|
|
|
if ( EMPTY == tp->c || RAMP_TOP == tp->c || STAIR_DOWN == tp->c )
|
|
|
|
|
{
|
|
|
|
|
++emptycount;
|
|
|
|
|
}else{
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
++rockcount;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//Magma and water
|
|
|
|
|
if( d->bits.flow_size ){
|
|
|
|
|
if(d->bits.liquid_type){
|
|
|
|
|
if ( d->bits.flow_size )
|
|
|
|
|
{
|
|
|
|
|
if (d->bits.liquid_type)
|
|
|
|
|
{
|
|
|
|
|
++magmacount;
|
|
|
|
|
}else{
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
++watercount;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//Check for Features
|
|
|
|
|
if( block.local_feature > -1 || block.global_feature > -1 ){
|
|
|
|
|
if ( block.local_feature > -1 || block.global_feature > -1 )
|
|
|
|
|
{
|
|
|
|
|
//Count tiles which actually are in the feature.
|
|
|
|
|
//It is possible for a block to have a feature, but no tiles to be feature.
|
|
|
|
|
if( d->bits.feature_global || d->bits.feature_local ){
|
|
|
|
|
if ( d->bits.feature_global || d->bits.feature_local )
|
|
|
|
|
{
|
|
|
|
|
//All features
|
|
|
|
|
++featcount;
|
|
|
|
|
|
|
|
|
|
if( d->bits.feature_global && d->bits.feature_local ){
|
|
|
|
|
if ( d->bits.feature_global && d->bits.feature_local )
|
|
|
|
|
{
|
|
|
|
|
cout << "warn:tile is global and local at same time!" << endl;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
n=0;
|
|
|
|
|
if( block.global_feature > -1 && d->bits.feature_global ){
|
|
|
|
|
if ( block.global_feature > -1 && d->bits.feature_global )
|
|
|
|
|
{
|
|
|
|
|
n=global_features[block.global_feature].type;
|
|
|
|
|
switch( n ){
|
|
|
|
|
switch ( n )
|
|
|
|
|
{
|
|
|
|
|
case feature_Other:
|
|
|
|
|
//no count
|
|
|
|
|
break;
|
|
|
|
@ -737,9 +871,11 @@ int main (void)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
n=0;
|
|
|
|
|
if( block.local_feature > -1 && d->bits.feature_local ){
|
|
|
|
|
if ( block.local_feature > -1 && d->bits.feature_local )
|
|
|
|
|
{
|
|
|
|
|
n=local_features[pc][block.local_feature]->type;
|
|
|
|
|
switch( n ){
|
|
|
|
|
switch ( n )
|
|
|
|
|
{
|
|
|
|
|
case feature_Other:
|
|
|
|
|
//no count
|
|
|
|
|
break;
|
|
|
|
@ -765,7 +901,8 @@ int main (void)
|
|
|
|
|
|
|
|
|
|
//If stopping at magma, and no no non-feature stone in this layer, and magma found, then we're either at
|
|
|
|
|
//or below the magma sea / molten rock.
|
|
|
|
|
if( stopatmagma && (moltencount || magmacount) && (!exposemagma || !rockcount) ){
|
|
|
|
|
if ( stopatmagma && (moltencount || magmacount) && (!exposemagma || !rockcount) )
|
|
|
|
|
{
|
|
|
|
|
//If not exposing magma, quit at the first sign of magma.
|
|
|
|
|
//If exposing magma, quite once magma is exposed.
|
|
|
|
|
done=-1;
|
|
|
|
@ -775,19 +912,21 @@ int main (void)
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
//Some checks, based on settings and stats collected
|
|
|
|
|
//First check, are we at illegal depth?
|
|
|
|
|
if( !done && hellcount && stopatmagma ){
|
|
|
|
|
if ( !done && hellcount && stopatmagma )
|
|
|
|
|
{
|
|
|
|
|
//Panic!
|
|
|
|
|
done=-1;
|
|
|
|
|
tpat=0;
|
|
|
|
|
cout << "error: illegal breach of hell!" << endl;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
//Actually process the current z-level.
|
|
|
|
|
//These loops do the work.
|
|
|
|
|
for(int32_t x=0;!done && x<16;++x){
|
|
|
|
|
for(int32_t y=0;!done && y<16;++y){
|
|
|
|
|
for (int32_t x=0;!done && x<16;++x)
|
|
|
|
|
{
|
|
|
|
|
for (int32_t y=0;!done && y<16;++y)
|
|
|
|
|
{
|
|
|
|
|
t=0;
|
|
|
|
|
tp = getTileTypeP(block.tiletypes[x][y]);
|
|
|
|
|
d = &block.designation[x][y];
|
|
|
|
@ -797,20 +936,23 @@ int main (void)
|
|
|
|
|
//It may be added back if aquify is set.
|
|
|
|
|
d->bits.water_table=0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//Change behaviour based on settings and stats from this z-level
|
|
|
|
|
|
|
|
|
|
//In hell?
|
|
|
|
|
if( tpat && tpat!=3 && isfeature(global_features, local_features,block,pc,x,y,feature_Underworld ) ){
|
|
|
|
|
if( exposehell ){
|
|
|
|
|
if ( tpat && tpat!=3 && isfeature(global_features, local_features,block,pc,x,y,feature_Underworld ) )
|
|
|
|
|
{
|
|
|
|
|
if ( exposehell )
|
|
|
|
|
{
|
|
|
|
|
tpat=0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//Expose magma?
|
|
|
|
|
if( tpat && tpat!=3 && exposemagma ){
|
|
|
|
|
if ( tpat && tpat!=3 && exposemagma )
|
|
|
|
|
{
|
|
|
|
|
//Leave certain tiles unchanged.
|
|
|
|
|
switch( tp->m ){
|
|
|
|
|
switch ( tp->m )
|
|
|
|
|
{
|
|
|
|
|
case HFS:
|
|
|
|
|
case FEATSTONE:
|
|
|
|
|
case MAGMA:
|
|
|
|
@ -819,11 +961,13 @@ int main (void)
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
//Adamantine may be left unchanged...
|
|
|
|
|
if( isfeature(global_features, local_features,block,pc,x,y,feature_Adamantine_Tube ) ){
|
|
|
|
|
if ( isfeature(global_features, local_features,block,pc,x,y,feature_Adamantine_Tube ) )
|
|
|
|
|
{
|
|
|
|
|
tpat=0;
|
|
|
|
|
}
|
|
|
|
|
//Leave magma sea unchanged.
|
|
|
|
|
if( d->bits.flow_size && d->bits.liquid_type){
|
|
|
|
|
if ( d->bits.flow_size && d->bits.liquid_type)
|
|
|
|
|
{
|
|
|
|
|
tpat=0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -831,15 +975,18 @@ int main (void)
|
|
|
|
|
|
|
|
|
|
//For all situations...
|
|
|
|
|
//Special modification for walls, always for adamantine.
|
|
|
|
|
if( isfeature(global_features, local_features,block,pc,x,y,feature_Adamantine_Tube ) ){
|
|
|
|
|
if( 2==pattern[x][y] || 3==pattern[x][y] ){
|
|
|
|
|
if ( isfeature(global_features, local_features,block,pc,x,y,feature_Adamantine_Tube ) )
|
|
|
|
|
{
|
|
|
|
|
if ( 2==pattern[x][y] || 3==pattern[x][y] )
|
|
|
|
|
{
|
|
|
|
|
tpat=2;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//Border or space?
|
|
|
|
|
switch(tpat){
|
|
|
|
|
switch (tpat)
|
|
|
|
|
{
|
|
|
|
|
case 0:
|
|
|
|
|
continue;
|
|
|
|
|
break;
|
|
|
|
@ -854,15 +1001,21 @@ int main (void)
|
|
|
|
|
//d->bits.feature_global = d->bits.feature_local = 0;
|
|
|
|
|
|
|
|
|
|
//Water? Magma?
|
|
|
|
|
if(fillmagma || fillwater){
|
|
|
|
|
if (fillmagma || fillwater)
|
|
|
|
|
{
|
|
|
|
|
d->bits.flow_size=7;
|
|
|
|
|
d->bits.liquid_character = liquid_fresh;
|
|
|
|
|
if(fillmagma){
|
|
|
|
|
if (fillmagma)
|
|
|
|
|
{
|
|
|
|
|
d->bits.liquid_type=liquid_magma;
|
|
|
|
|
}else{
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
d->bits.liquid_type=liquid_water;
|
|
|
|
|
}
|
|
|
|
|
}else{
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
//Otherwise, remove all liquids.
|
|
|
|
|
d->bits.flow_size=0;
|
|
|
|
|
d->bits.liquid_character = liquid_fresh;
|
|
|
|
@ -873,7 +1026,8 @@ int main (void)
|
|
|
|
|
case 2:
|
|
|
|
|
//Wall.
|
|
|
|
|
//First guess based on current material
|
|
|
|
|
switch( tp->m ){
|
|
|
|
|
switch ( tp->m )
|
|
|
|
|
{
|
|
|
|
|
case OBSIDIAN:
|
|
|
|
|
t=wmagma;
|
|
|
|
|
break;
|
|
|
|
@ -892,17 +1046,18 @@ int main (void)
|
|
|
|
|
default:
|
|
|
|
|
t=wcave;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//Adamantine (a local feature) trumps veins.
|
|
|
|
|
{
|
|
|
|
|
//Local Feature?
|
|
|
|
|
if( block.local_feature > -1 ){
|
|
|
|
|
switch( n=local_features[pc][block.local_feature]->type ){
|
|
|
|
|
if ( block.local_feature > -1 )
|
|
|
|
|
{
|
|
|
|
|
switch ( n=local_features[pc][block.local_feature]->type )
|
|
|
|
|
{
|
|
|
|
|
case feature_Underworld:
|
|
|
|
|
case feature_Hell_Temple:
|
|
|
|
|
//Only adopt these if there is no global feature present
|
|
|
|
|
if( block.global_feature >-1 ){
|
|
|
|
|
if ( block.global_feature >-1 )
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case feature_Adamantine_Tube:
|
|
|
|
@ -915,8 +1070,10 @@ int main (void)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//Global Feature?
|
|
|
|
|
else if(block.global_feature > -1 && !d->bits.feature_local ){
|
|
|
|
|
switch( n=global_features[block.global_feature].type ){
|
|
|
|
|
else if (block.global_feature > -1 && !d->bits.feature_local )
|
|
|
|
|
{
|
|
|
|
|
switch ( n=global_features[block.global_feature].type )
|
|
|
|
|
{
|
|
|
|
|
case feature_Adamantine_Tube:
|
|
|
|
|
case feature_Underworld:
|
|
|
|
|
case feature_Hell_Temple:
|
|
|
|
@ -935,20 +1092,21 @@ int main (void)
|
|
|
|
|
|
|
|
|
|
//Placing an aquifer?
|
|
|
|
|
//(bugged, these aquifers don't generate water!)
|
|
|
|
|
if( aquify ){
|
|
|
|
|
if ( aquify )
|
|
|
|
|
{
|
|
|
|
|
//Only normal stone types can be aquified
|
|
|
|
|
if( tp->m!=MAGMA && tp->m!=FEATSTONE && tp->m!=HFS ){
|
|
|
|
|
if ( tp->m!=MAGMA && tp->m!=FEATSTONE && tp->m!=HFS )
|
|
|
|
|
{
|
|
|
|
|
//Only place next to the hole.
|
|
|
|
|
//If no hole, place in middle.
|
|
|
|
|
if( checkneighbors(pattern,x,y,1) || (7==x && 7==y) ){
|
|
|
|
|
if ( checkneighbors(pattern,x,y,1) || (7==x && 7==y) )
|
|
|
|
|
{
|
|
|
|
|
d->bits.water_table = 1;
|
|
|
|
|
//t=265; //soil wall
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 3:
|
|
|
|
|
////No obsidian walls on bottom of map!
|
|
|
|
|
//if(z<1 && (d->bits.feature_global || d->bits.feature_local) ) {
|
|
|
|
@ -971,7 +1129,10 @@ int main (void)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//For all tiles.
|
|
|
|
|
if(reveal) d->bits.hidden = 0; //topblock.designation[x][y].bits.hidden;
|
|
|
|
|
if (reveal)
|
|
|
|
|
{
|
|
|
|
|
d->bits.hidden = 0; //topblock.designation[x][y].bits.hidden;
|
|
|
|
|
}
|
|
|
|
|
//Always clear the dig designation.
|
|
|
|
|
d->bits.dig=designation_no;
|
|
|
|
|
//Make it underground, because it is capped
|
|
|
|
@ -1002,30 +1163,38 @@ int main (void)
|
|
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
//The bottom level is special.
|
|
|
|
|
if(-1){
|
|
|
|
|
if(!Mapz->ReadBlock40d( bx, by, z , &block )){
|
|
|
|
|
if (-1)
|
|
|
|
|
{
|
|
|
|
|
if (!Mapz->ReadBlock40d( bx, by, z , &block ))
|
|
|
|
|
{
|
|
|
|
|
cout << "Bad block! " << bx << "," << by << "," << z << endl;
|
|
|
|
|
}
|
|
|
|
|
for(uint32_t x=0;x<16;++x){
|
|
|
|
|
for(uint32_t y=0;y<16;++y){
|
|
|
|
|
for (uint32_t x=0;x<16;++x)
|
|
|
|
|
{
|
|
|
|
|
for (uint32_t y=0;y<16;++y)
|
|
|
|
|
{
|
|
|
|
|
t=floor;
|
|
|
|
|
v=floorvar;
|
|
|
|
|
tp = getTileTypeP(block.tiletypes[x][y]);
|
|
|
|
|
d = &block.designation[x][y];
|
|
|
|
|
|
|
|
|
|
if( exposehell ){
|
|
|
|
|
if ( exposehell )
|
|
|
|
|
{
|
|
|
|
|
//Leave hell tiles unchanged when exposing hell.
|
|
|
|
|
if( isfeature(global_features,local_features,block,pc,x,y,feature_Underworld) ){
|
|
|
|
|
if ( isfeature(global_features,local_features,block,pc,x,y,feature_Underworld) )
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//Does expose magma need anything at this level?
|
|
|
|
|
if( exposemagma && stopatmagma ){
|
|
|
|
|
if ( exposemagma && stopatmagma )
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch(pattern[x][y]){
|
|
|
|
|
switch (pattern[x][y])
|
|
|
|
|
{
|
|
|
|
|
case 0:
|
|
|
|
|
continue;
|
|
|
|
|
break;
|
|
|
|
@ -1050,7 +1219,8 @@ int main (void)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//Tile material check.
|
|
|
|
|
switch( tp->m ){
|
|
|
|
|
switch ( tp->m )
|
|
|
|
|
{
|
|
|
|
|
case OBSIDIAN:
|
|
|
|
|
t=340;
|
|
|
|
|
v=3;
|
|
|
|
@ -1091,7 +1261,6 @@ int main (void)
|
|
|
|
|
|
|
|
|
|
//Set the tile.
|
|
|
|
|
block.tiletypes[x][y] = t + ( v ? rand()&v : 0 );
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//Write the block.
|
|
|
|
@ -1101,7 +1270,6 @@ int main (void)
|
|
|
|
|
Mapz->WriteDirtyBit(bx,by,z,1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
DF->Detach();
|
|
|
|
|
#ifndef LINUX_BUILD
|
|
|
|
|
cout << "Done. Press any key to continue" << endl;
|
|
|
|
|