mirror of
				https://github.com/zenorogue/hyperrogue.git
				synced 2025-11-04 07:43:02 +00:00 
			
		
		
		
	Refactoring: moved all the remaining pattern code from mapeditor to pattern2
This commit is contained in:
		@@ -72,8 +72,8 @@ int arg::readCommon() {
 | 
				
			|||||||
  else if(argis("-canvas")) {
 | 
					  else if(argis("-canvas")) {
 | 
				
			||||||
    firstland = specialland = laCanvas;
 | 
					    firstland = specialland = laCanvas;
 | 
				
			||||||
    shift();
 | 
					    shift();
 | 
				
			||||||
    if(args()[1] == 0) mapeditor::whichCanvas = args()[0];
 | 
					    if(args()[1] == 0) patterns::whichCanvas = args()[0];
 | 
				
			||||||
    else mapeditor::canvasback = strtol(args(), NULL, 16);
 | 
					    else patterns::canvasback = strtol(args(), NULL, 16);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  else if(argis("-noplayer")) 
 | 
					  else if(argis("-noplayer")) 
 | 
				
			||||||
    mapeditor::drawplayer = !mapeditor::drawplayer;
 | 
					    mapeditor::drawplayer = !mapeditor::drawplayer;
 | 
				
			||||||
@@ -81,7 +81,7 @@ int arg::readCommon() {
 | 
				
			|||||||
    PHASE(3);
 | 
					    PHASE(3);
 | 
				
			||||||
    shift();
 | 
					    shift();
 | 
				
			||||||
    char *c = args();
 | 
					    char *c = args();
 | 
				
			||||||
    using namespace mapeditor;
 | 
					    using namespace patterns;
 | 
				
			||||||
    sym01 = sym02 = sym03 = symRotation = false;
 | 
					    sym01 = sym02 = sym03 = symRotation = false;
 | 
				
			||||||
    while(*c) { 
 | 
					    while(*c) { 
 | 
				
			||||||
      if(*c == '1') sym01 = true; 
 | 
					      if(*c == '1') sym01 = true; 
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,8 +15,6 @@ ld tessf, crossf, hexf, hcrossf, hexhexdist, hexvdist, hepvdist, rhexf;
 | 
				
			|||||||
// hepvdist: distance between heptagon vertex and hexagon center (either hcrossf or something else)
 | 
					// hepvdist: distance between heptagon vertex and hexagon center (either hcrossf or something else)
 | 
				
			||||||
// rhexf: distance from heptagon center to heptagon vertex (either hexf or hcrossf)
 | 
					// rhexf: distance from heptagon center to heptagon vertex (either hexf or hcrossf)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define ALPHA (M_PI*2/S7)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
hyperpoint Crad[MAX_S84];
 | 
					hyperpoint Crad[MAX_S84];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
transmatrix heptmove[MAX_EDGE], hexmove[MAX_EDGE];
 | 
					transmatrix heptmove[MAX_EDGE], hexmove[MAX_EDGE];
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										30
									
								
								graph.cpp
									
									
									
									
									
								
							
							
						
						
									
										30
									
								
								graph.cpp
									
									
									
									
									
								
							@@ -2187,17 +2187,17 @@ int countMinesAround(cell *c) {
 | 
				
			|||||||
  return mines;
 | 
					  return mines;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
transmatrix applyPatterndir(cell *c, char patt = mapeditor::whichPattern) {
 | 
					transmatrix applyPatterndir(cell *c, char patt = patterns::whichPattern) {
 | 
				
			||||||
  transmatrix V = ddspin(c, mapeditor::patterndir(c, patt), S42);
 | 
					  transmatrix V = ddspin(c, patterns::patterndir(c, patt), S42);
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  if(mapeditor::reflectPatternAt(c, patt)) 
 | 
					  if(patterns::reflectPatternAt(c, patt)) 
 | 
				
			||||||
    return V * Mirror;
 | 
					    return V * Mirror;
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  return V;
 | 
					  return V;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
transmatrix applyDowndir(cell *c, cellfunction *cf) {
 | 
					transmatrix applyDowndir(cell *c, cellfunction *cf) {
 | 
				
			||||||
  return ddspin(c, mapeditor::downdir(c, cf), S42);
 | 
					  return ddspin(c, patterns::downdir(c, cf), S42);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void drawTowerFloor(const transmatrix& V, cell *c, int col, cellfunction *cf = coastvalEdge) {
 | 
					void drawTowerFloor(const transmatrix& V, cell *c, int col, cellfunction *cf = coastvalEdge) {
 | 
				
			||||||
@@ -2883,7 +2883,7 @@ void plainfloor(cell *c, bool warp, const transmatrix &V, int col, int prio) {
 | 
				
			|||||||
        queuepolyat(V, shTriheptaFloor[ctof(c)], col, prio);
 | 
					        queuepolyat(V, shTriheptaFloor[ctof(c)], col, prio);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    else 
 | 
					    else 
 | 
				
			||||||
      queuepolyat(V * applyPatterndir(c), shTriheptaFloor[sphere ? ctof(c) : mapeditor::nopattern(c)], col, prio);
 | 
					      queuepolyat(V * applyPatterndir(c), shTriheptaFloor[sphere ? ctof(c) : patterns::nopattern(c)], col, prio);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  else if(c->land == laDual && !nontruncated) {
 | 
					  else if(c->land == laDual && !nontruncated) {
 | 
				
			||||||
    if(euclid && ishex1(c))
 | 
					    if(euclid && ishex1(c))
 | 
				
			||||||
@@ -2907,7 +2907,7 @@ void qplainfloor(cell *c, bool warp, const transmatrix &V, int col) {
 | 
				
			|||||||
        qfloor(c, V, applyPatterndir(c), shTriheptaFloor[ctof(c)], col);
 | 
					        qfloor(c, V, applyPatterndir(c), shTriheptaFloor[ctof(c)], col);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    else 
 | 
					    else 
 | 
				
			||||||
      qfloor(c, V, applyPatterndir(c), shTriheptaFloor[sphere ? ctof(c) : mapeditor::nopattern(c)], col);
 | 
					      qfloor(c, V, applyPatterndir(c), shTriheptaFloor[sphere ? ctof(c) : patterns::nopattern(c)], col);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  else if(c->land == laDual && !nontruncated)
 | 
					  else if(c->land == laDual && !nontruncated)
 | 
				
			||||||
    qfloor_eswap(c, V, shBigTriangle, col);
 | 
					    qfloor_eswap(c, V, shBigTriangle, col);
 | 
				
			||||||
@@ -3518,21 +3518,21 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
              
 | 
					              
 | 
				
			||||||
#if CAP_EDIT
 | 
					#if CAP_EDIT
 | 
				
			||||||
      if(mapeditor::drawUserShape(Vpdir, mapeditor::cellShapeGroup(), mapeditor::realpattern(c),
 | 
					      if(mapeditor::drawUserShape(Vpdir, mapeditor::cellShapeGroup(), patterns::realpattern(c),
 | 
				
			||||||
        darkena(fcol, fd, (cmode & sm::DRAW) ? 0xC0 : 0xFF), c));
 | 
					        darkena(fcol, fd, (cmode & sm::DRAW) ? 0xC0 : 0xFF), c));
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
      else if(mapeditor::whichShape == '7') {
 | 
					      else if(patterns::whichShape == '7') {
 | 
				
			||||||
        if(ishept(c))
 | 
					        if(ishept(c))
 | 
				
			||||||
          qfloor(c, Vf, wmblack ? shBFloor[ct6] : 
 | 
					          qfloor(c, Vf, wmblack ? shBFloor[ct6] : 
 | 
				
			||||||
            euclid ? shBigHex :
 | 
					            euclid ? shBigHex :
 | 
				
			||||||
            shBigHepta, darkena(fcol, fd, 0xFF));
 | 
					            shBigHepta, darkena(fcol, fd, 0xFF));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
      else if(mapeditor::whichShape == '8') {
 | 
					      else if(patterns::whichShape == '8') {
 | 
				
			||||||
        qfloor_eswap(c, Vf, shTriheptaFloor[ctof(c)], darkena(fcol, fd, 0xFF));
 | 
					        qfloor_eswap(c, Vf, shTriheptaFloor[ctof(c)], darkena(fcol, fd, 0xFF));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
      else if(mapeditor::whichShape == '6') {
 | 
					      else if(patterns::whichShape == '6') {
 | 
				
			||||||
        if(!ishept(c))
 | 
					        if(!ishept(c))
 | 
				
			||||||
          qfloor(c, Vf, 
 | 
					          qfloor(c, Vf, 
 | 
				
			||||||
            wmblack ? shBFloor[ct6] : 
 | 
					            wmblack ? shBFloor[ct6] : 
 | 
				
			||||||
@@ -3675,7 +3675,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      else if(isWarped(c) && !nontruncated && !shmup::on) {
 | 
					      else if(isWarped(c) && !nontruncated && !shmup::on) {
 | 
				
			||||||
        int np = mapeditor::nopattern(c);
 | 
					        int np = patterns::nopattern(c);
 | 
				
			||||||
        if(c->landparam == 1337) np = 0; // for the achievement screenshot
 | 
					        if(c->landparam == 1337) np = 0; // for the achievement screenshot
 | 
				
			||||||
        if(np < 13)
 | 
					        if(np < 13)
 | 
				
			||||||
          qfloor(c, Vf, applyPatterndir(c), shTriheptaFloor[np], darkena(fcol, fd, 0xFF));
 | 
					          qfloor(c, Vf, applyPatterndir(c), shTriheptaFloor[np], darkena(fcol, fd, 0xFF));
 | 
				
			||||||
@@ -3903,9 +3903,9 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#if CAP_EDIT
 | 
					#if CAP_EDIT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if(mapeditor::displaycodes) {
 | 
					      if(patterns::displaycodes) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        int labeli = mapeditor::displaycodes == 1 ? mapeditor::realpattern(c) : mapeditor::subpattern(c);
 | 
					        int labeli = patterns::displaycodes == 1 ? patterns::realpattern(c) : patterns::subpattern(c);
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        string label = its(labeli);
 | 
					        string label = its(labeli);
 | 
				
			||||||
        queuestr(V, .5, label, 0xFF000000 + forecolor);
 | 
					        queuestr(V, .5, label, 0xFF000000 + forecolor);
 | 
				
			||||||
@@ -4582,7 +4582,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
 | 
				
			|||||||
#if CAP_EDIT
 | 
					#if CAP_EDIT
 | 
				
			||||||
    if((cmode & sm::MAP) && lmouseover && darken == 0 &&
 | 
					    if((cmode & sm::MAP) && lmouseover && darken == 0 &&
 | 
				
			||||||
      !mouseout() && 
 | 
					      !mouseout() && 
 | 
				
			||||||
      (mapeditor::whichPattern ? mapeditor::subpattern(c) == mapeditor::subpattern(lmouseover) : c == lmouseover)) {
 | 
					      (patterns::whichPattern ? patterns::subpattern(c) == patterns::subpattern(lmouseover) : c == lmouseover)) {
 | 
				
			||||||
      queuecircle(V, .78, 0x00FFFFFF);
 | 
					      queuecircle(V, .78, 0x00FFFFFF);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -5157,7 +5157,7 @@ void drawfullmap() {
 | 
				
			|||||||
  if(pmodel == mdPolygonal || pmodel == mdPolynomial) 
 | 
					  if(pmodel == mdPolygonal || pmodel == mdPolynomial) 
 | 
				
			||||||
    polygonal::drawBoundary(darkena(0xFF, 0, 0xFF));
 | 
					    polygonal::drawBoundary(darkena(0xFF, 0, 0xFF));
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  /* if(vid.wallmode < 2 && !euclid && !mapeditor::whichShape) {
 | 
					  /* if(vid.wallmode < 2 && !euclid && !patterns::whichShape) {
 | 
				
			||||||
    int ls = size(lines);
 | 
					    int ls = size(lines);
 | 
				
			||||||
    if(ISMOBILE) ls /= 10;
 | 
					    if(ISMOBILE) ls /= 10;
 | 
				
			||||||
    for(int t=0; t<ls; t++) queueline(View * lines[t].P1, View * lines[t].P2, lines[t].col >> (darken+1));
 | 
					    for(int t=0; t<ls; t++) queueline(View * lines[t].P1, View * lines[t].P2, lines[t].col >> (darken+1));
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										29
									
								
								hyper.h
									
									
									
									
									
								
							
							
						
						
									
										29
									
								
								hyper.h
									
									
									
									
									
								
							@@ -652,19 +652,28 @@ extern string mouseovers;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
extern struct SDL_Surface *s;
 | 
					extern struct SDL_Surface *s;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace mapeditor { 
 | 
					namespace patterns {
 | 
				
			||||||
  extern bool drawplayer; 
 | 
					  extern char whichShape;
 | 
				
			||||||
  extern char whichPattern, whichShape;
 | 
					  extern char whichPattern;
 | 
				
			||||||
  extern char whichCanvas;
 | 
					 | 
				
			||||||
  extern bool symRotation, sym01, sym02, sym03;
 | 
					  extern bool symRotation, sym01, sym02, sym03;
 | 
				
			||||||
  extern int displaycodes;
 | 
					  extern char whichCanvas;
 | 
				
			||||||
  int generateCanvas(cell *c);
 | 
					 | 
				
			||||||
  void applyModelcell(cell *c);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  extern int displaycodes;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  int generateCanvas(cell *c);
 | 
				
			||||||
  int realpattern(cell *c, char w = whichPattern);
 | 
					  int realpattern(cell *c, char w = whichPattern);
 | 
				
			||||||
  int patterndir(cell *c, char w = whichPattern);
 | 
					  int patterndir(cell *c, char w = whichPattern);
 | 
				
			||||||
  bool reflectPatternAt(cell *c, char p = whichPattern);
 | 
					  bool reflectPatternAt(cell *c, char p = whichPattern);
 | 
				
			||||||
  int subpattern(cell *c, char w = whichPattern);
 | 
					  int subpattern(cell *c, char w = whichPattern);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace mapeditor { 
 | 
				
			||||||
 | 
					#if CAP_EDIT
 | 
				
			||||||
 | 
					  extern map<int, cell*> modelcell;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  extern bool drawplayer; 
 | 
				
			||||||
 | 
					  void applyModelcell(cell *c);
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  extern cell *drawcell;
 | 
					  extern cell *drawcell;
 | 
				
			||||||
  void initdraw(cell *c); 
 | 
					  void initdraw(cell *c); 
 | 
				
			||||||
@@ -2311,3 +2320,9 @@ extern const unsigned int nestcolors[8];
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
extern bool texture_on;
 | 
					extern bool texture_on;
 | 
				
			||||||
void showTextureMenu();
 | 
					void showTextureMenu();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void queueline(const hyperpoint& H1, const hyperpoint& H2, int col, int prf = 0, int prio = PPR_LINE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					hyperpoint ddi0(ld dir, ld dist);
 | 
				
			||||||
 | 
					extern ld tessf, crossf, hexf, hcrossf, hexhexdist, hexvdist, hepvdist, rhexf;
 | 
				
			||||||
 | 
					unsigned char& part(int& col, int i);
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										1
									
								
								init.cpp
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								init.cpp
									
									
									
									
									
								
							@@ -345,6 +345,7 @@ using namespace std;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void addMessage(string s, char spamtype = 0);
 | 
					void addMessage(string s, char spamtype = 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define ALPHA (M_PI*2/S7)
 | 
				
			||||||
#define S7 ginf[geometry].sides
 | 
					#define S7 ginf[geometry].sides
 | 
				
			||||||
#define S3 ginf[geometry].vertex
 | 
					#define S3 ginf[geometry].vertex
 | 
				
			||||||
#define weirdhyperbolic (S7 > 7 || S3 > 3)
 | 
					#define weirdhyperbolic (S7 > 7 || S3 > 3)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2161,7 +2161,7 @@ void setdist(cell *c, int d, cell *from) {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  if(d == BARLEV && c->land == laCanvas)  {
 | 
					  if(d == BARLEV && c->land == laCanvas)  {
 | 
				
			||||||
    c->landparam = mapeditor::generateCanvas(c);
 | 
					    c->landparam = patterns::generateCanvas(c);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if(d >= BARLEV-1 && c->land == laPrairie)
 | 
					  if(d >= BARLEV-1 && c->land == laPrairie)
 | 
				
			||||||
@@ -2225,7 +2225,7 @@ void setdist(cell *c, int d, cell *from) {
 | 
				
			|||||||
  if(d == 7) playSeenSound(c);
 | 
					  if(d == 7) playSeenSound(c);
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
#if CAP_EDIT
 | 
					#if CAP_EDIT
 | 
				
			||||||
  if(d >= 7 && mapeditor::whichPattern)
 | 
					  if(d >= 7 && patterns::whichPattern)
 | 
				
			||||||
    mapeditor::applyModelcell(c);
 | 
					    mapeditor::applyModelcell(c);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										754
									
								
								mapeditor.cpp
									
									
									
									
									
								
							
							
						
						
									
										754
									
								
								mapeditor.cpp
									
									
									
									
									
								
							@@ -12,8 +12,6 @@
 | 
				
			|||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace mapeditor {
 | 
					namespace mapeditor {
 | 
				
			||||||
  int subcanvas;
 | 
					 | 
				
			||||||
  int displaycodes;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  struct editwhat {
 | 
					  struct editwhat {
 | 
				
			||||||
    double dist;
 | 
					    double dist;
 | 
				
			||||||
@@ -30,9 +28,8 @@ namespace mapeditor {
 | 
				
			|||||||
  bool handleKeyFile(int sym, int uni);
 | 
					  bool handleKeyFile(int sym, int uni);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void applyModelcell(cell *c) {
 | 
					  void applyModelcell(cell *c) {
 | 
				
			||||||
    if(mapeditor::whichPattern == 'H') return;
 | 
					    if(patterns::whichPattern == 'H') return;
 | 
				
			||||||
    if(mapeditor::whichPattern == 'H') return;
 | 
					    int i = patterns::realpattern(c);
 | 
				
			||||||
    int i = realpattern(c);
 | 
					 | 
				
			||||||
    cell *c2 = modelcell[i];
 | 
					    cell *c2 = modelcell[i];
 | 
				
			||||||
    if(c2) {
 | 
					    if(c2) {
 | 
				
			||||||
      c->wall = c2->wall;
 | 
					      c->wall = c2->wall;
 | 
				
			||||||
@@ -45,7 +42,7 @@ namespace mapeditor {
 | 
				
			|||||||
      c->stuntime = c2->stuntime;
 | 
					      c->stuntime = c2->stuntime;
 | 
				
			||||||
      c->hitpoints = c2->hitpoints;
 | 
					      c->hitpoints = c2->hitpoints;
 | 
				
			||||||
      if(c2->mondir != NODIR)
 | 
					      if(c2->mondir != NODIR)
 | 
				
			||||||
        c->mondir = (c2->mondir - patterndir(c2) + patterndir(c) + MODFIXER) % c->type;
 | 
					        c->mondir = (c2->mondir - patterns::patterndir(c2) + patterns::patterndir(c) + MODFIXER) % c->type;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
@@ -87,7 +84,7 @@ namespace mapstream {
 | 
				
			|||||||
    f = fopen(fname, "wb");
 | 
					    f = fopen(fname, "wb");
 | 
				
			||||||
    if(!f) return false;
 | 
					    if(!f) return false;
 | 
				
			||||||
    int32_t i = VERNUM; save(i);
 | 
					    int32_t i = VERNUM; save(i);
 | 
				
			||||||
    save(mapeditor::whichPattern);
 | 
					    save(patterns::whichPattern);
 | 
				
			||||||
    save(geometry);
 | 
					    save(geometry);
 | 
				
			||||||
    save(nontruncated);
 | 
					    save(nontruncated);
 | 
				
			||||||
    if(geometry == gTorus) {
 | 
					    if(geometry == gTorus) {
 | 
				
			||||||
@@ -170,7 +167,7 @@ namespace mapstream {
 | 
				
			|||||||
    if(!f) return false;
 | 
					    if(!f) return false;
 | 
				
			||||||
    clearMemory();
 | 
					    clearMemory();
 | 
				
			||||||
    int vernum = loadInt();
 | 
					    int vernum = loadInt();
 | 
				
			||||||
    if(vernum >= 7400) load(mapeditor::whichPattern);
 | 
					    if(vernum >= 7400) load(patterns::whichPattern);
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    if(vernum >= 10203) {
 | 
					    if(vernum >= 10203) {
 | 
				
			||||||
      load(geometry);
 | 
					      load(geometry);
 | 
				
			||||||
@@ -241,8 +238,8 @@ namespace mapstream {
 | 
				
			|||||||
      c->stuntime = loadChar();
 | 
					      c->stuntime = loadChar();
 | 
				
			||||||
      c->hitpoints = loadChar();
 | 
					      c->hitpoints = loadChar();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if(mapeditor::whichPattern)
 | 
					      if(patterns::whichPattern)
 | 
				
			||||||
        mapeditor::modelcell[mapeditor::realpattern(c)] = c;
 | 
					        mapeditor::modelcell[patterns::realpattern(c)] = c;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    int32_t whereami = loadInt();
 | 
					    int32_t whereami = loadInt();
 | 
				
			||||||
@@ -311,57 +308,7 @@ namespace mapstream {
 | 
				
			|||||||
namespace mapeditor {
 | 
					namespace mapeditor {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  bool drawplayer = true;
 | 
					  bool drawplayer = true;
 | 
				
			||||||
  char whichPattern = 0;
 | 
					 | 
				
			||||||
  char whichShape = 0;
 | 
					 | 
				
			||||||
  char whichCanvas = 0;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  bool symRotation, sym01, sym02, sym03;
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
  int subpattern(int i, char w) {  
 | 
					 | 
				
			||||||
    if(euclid) {
 | 
					 | 
				
			||||||
      if(w == 'p') 
 | 
					 | 
				
			||||||
        return i;
 | 
					 | 
				
			||||||
      if(w == 'z' || w == 'f')
 | 
					 | 
				
			||||||
        return (symRotation && (i<3)) ? 0 : i;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    if(a38 && w == 'p') {
 | 
					 | 
				
			||||||
      if(sym01 && i == 5) i = 4;
 | 
					 | 
				
			||||||
      if(symRotation && i < 4) i = 0;
 | 
					 | 
				
			||||||
      return i;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    if(w == 'z' || w == 'f' || w == 'p') {
 | 
					 | 
				
			||||||
      if((sym01?1:0)+(sym02?1:0)+(sym03?1:0) >= 2) i &= ~3;
 | 
					 | 
				
			||||||
      if(sym01 && (i&1)) i ^= 1;
 | 
					 | 
				
			||||||
      if(sym02 && (i&2)) i ^= 2;
 | 
					 | 
				
			||||||
      if(sym03 && (i&2)) i ^= 3;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    if(w == 'z' && symRotation) {
 | 
					 | 
				
			||||||
      if(a4 && !a46) {
 | 
					 | 
				
			||||||
        if(i >= 4 && i < 7) i -= 4;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      else {
 | 
					 | 
				
			||||||
        if(i >= 8 && i < 12) i -= 4;
 | 
					 | 
				
			||||||
        if(i >= 12 && i < 16) i -= 8;
 | 
					 | 
				
			||||||
        if(i >= 20 && i < 24) i -= 4;
 | 
					 | 
				
			||||||
        if(i >= 24 && i < 28) i -= 8;
 | 
					 | 
				
			||||||
        if(i >= 32 && i < 36) i -= 4;
 | 
					 | 
				
			||||||
        if(i >= 36 && i < 40) i -= 8;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    if(w == 'p' && stdhyperbolic && symRotation && i >= 3)
 | 
					 | 
				
			||||||
      i -= ((i/4-1) % 7) * 4;
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
    return i;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  int subpattern(cell *c, char w) {
 | 
					 | 
				
			||||||
    return subpattern(realpattern(c, w), w);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
  string infix;
 | 
					  string infix;
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  bool hasInfix(const string &s) {
 | 
					  bool hasInfix(const string &s) {
 | 
				
			||||||
@@ -598,205 +545,6 @@ namespace mapeditor {
 | 
				
			|||||||
    v.push_back(make_pair(s, i));
 | 
					    v.push_back(make_pair(s, i));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  void showPrePattern() {
 | 
					 | 
				
			||||||
    dialog::init("predesigned patterns");
 | 
					 | 
				
			||||||
    dialog::addItem(XLAT("Gameboard"), 'g');
 | 
					 | 
				
			||||||
    dialog::addItem(XLAT("random colors"), 'r');
 | 
					 | 
				
			||||||
    dialog::addItem(XLAT("rainbow landscape"), 'l');
 | 
					 | 
				
			||||||
    dialog::addItem(XLAT("dark rainbow landscape"), 'd');
 | 
					 | 
				
			||||||
    dialog::addItem(XLAT("football"), 'F');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    dialog::addItem(XLAT("nice coloring"), 'T');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    dialog::addSelItem(XLAT("emerald pattern"), "emerald", 'e');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    dialog::addSelItem(XLAT("four elements"), "palace", 'b');
 | 
					 | 
				
			||||||
    dialog::addSelItem(XLAT("eight domains"), "palace", 'a');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    dialog::addSelItem(XLAT("zebra pattern"), "zebra", 'z');
 | 
					 | 
				
			||||||
    dialog::addSelItem(XLAT("four triangles"), "zebra", 't');
 | 
					 | 
				
			||||||
    dialog::addSelItem(XLAT("three stripes"), "zebra", 'x');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    dialog::addSelItem(XLAT("random black-and-white"), "current", 'w');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    dialog::addSelItem(XLAT("field pattern C"), "field", 'C');
 | 
					 | 
				
			||||||
    dialog::addSelItem(XLAT("field pattern D"), "field", 'D');
 | 
					 | 
				
			||||||
    dialog::addSelItem(XLAT("field pattern N"), "field", 'N');
 | 
					 | 
				
			||||||
    dialog::addSelItem(XLAT("field pattern S"), "field", 'S');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    dialog::display();
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    keyhandler = [] (int sym, int uni) {
 | 
					 | 
				
			||||||
      dialog::handleNavigation(sym, uni);
 | 
					 | 
				
			||||||
      if((uni >= 'a' && uni <= 'z') || (uni >= 'A' && uni <= 'Z')) {
 | 
					 | 
				
			||||||
        whichCanvas = uni;
 | 
					 | 
				
			||||||
        subcanvas = rand();
 | 
					 | 
				
			||||||
        firstland = specialland = laCanvas; 
 | 
					 | 
				
			||||||
        randomPatternsMode = false;
 | 
					 | 
				
			||||||
        restartGame();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      else if(doexiton(sym, uni)) popScreen();
 | 
					 | 
				
			||||||
      };    
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
  void showPattern() {
 | 
					 | 
				
			||||||
    cmode = sm::SIDE | sm::MAYDARK;
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
    dynamicval<int> dc(displaycodes, displaycodes ? displaycodes : 2);
 | 
					 | 
				
			||||||
    gamescreen(0);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    dialog::init();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if(a46) {
 | 
					 | 
				
			||||||
      dialog::addBoolItem(XLAT("two colors"), (whichPattern == 'f'), 'f');
 | 
					 | 
				
			||||||
      dialog::addBoolItem(XLAT("two colors rotated"), (whichPattern == 'z'), 'z');
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    else if(a4) {
 | 
					 | 
				
			||||||
      dialog::addBoolItem(XLAT("Zebra Pattern"), (whichPattern == 'z'), 'z');
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    else if(a38) {
 | 
					 | 
				
			||||||
      dialog::addBoolItem(XLAT("Zebra Pattern"), (whichPattern == 'z'), 'z');
 | 
					 | 
				
			||||||
      dialog::addBoolItem(XLAT("broken Emerald Pattern"), (whichPattern == 'f'), 'f');
 | 
					 | 
				
			||||||
      dialog::addBoolItem(XLAT("rotated pattern"), (whichPattern == 'p'), 'p');
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    else if(euclid) {
 | 
					 | 
				
			||||||
      dialog::addBoolItem(XLAT("three colors"), (whichPattern == 'f'), 'f');
 | 
					 | 
				
			||||||
      dialog::addBoolItem(XLAT("Palace Pattern"), (whichPattern == 'p'), 'p');
 | 
					 | 
				
			||||||
      dialog::addBoolItem(XLAT("three colors rotated"), (whichPattern == 'z'), 'z');
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    else if(sphere) {
 | 
					 | 
				
			||||||
      dialog::addBoolItem(XLAT("siblings"), (whichPattern == 'p'), 'p');
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    else {
 | 
					 | 
				
			||||||
      if(!stdhyperbolic) 
 | 
					 | 
				
			||||||
        dialog::addInfo("patterns do not work correctly in this geometry!");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      dialog::addBoolItem(XLAT("Emerald Pattern"), (whichPattern == 'f'), 'f');
 | 
					 | 
				
			||||||
      dialog::addBoolItem(XLAT("Palace Pattern"), (whichPattern == 'p'), 'p');
 | 
					 | 
				
			||||||
      dialog::addBoolItem(XLAT("Zebra Pattern"), (whichPattern == 'z'), 'z');
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    if(euclid)
 | 
					 | 
				
			||||||
      dialog::addBoolItem(XLAT("torus pattern"), (whichPattern == 'F'), 'F');
 | 
					 | 
				
			||||||
    else if(sphere)
 | 
					 | 
				
			||||||
      dialog::addBoolItem(XLAT("single cells"), (whichPattern == 'F'), 'F');
 | 
					 | 
				
			||||||
    else
 | 
					 | 
				
			||||||
      dialog::addBoolItem(XLAT("field pattern"), (whichPattern == 'F'), 'F');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if(whichPattern == 'f' && stdhyperbolic) symRotation = true;
 | 
					 | 
				
			||||||
    if(whichPattern == 'F') ;
 | 
					 | 
				
			||||||
    else if(!euclid) {
 | 
					 | 
				
			||||||
      dialog::addBoolItem(XLAT("rotational symmetry"), (symRotation), '0');
 | 
					 | 
				
			||||||
      dialog::addBoolItem(XLAT("symmetry 0-1"), (sym01), '1');
 | 
					 | 
				
			||||||
      dialog::addBoolItem(XLAT("symmetry 0-2"), (sym02), '2');
 | 
					 | 
				
			||||||
      dialog::addBoolItem(XLAT("symmetry 0-3"), (sym03), '3');
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    else
 | 
					 | 
				
			||||||
      dialog::addBoolItem(XLAT("edit all three colors"), (symRotation), '0');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    dialog::addBoolItem(XLAT("display pattern codes (full)"), (displaycodes == 1), 'd');
 | 
					 | 
				
			||||||
    dialog::addBoolItem(XLAT("display pattern codes (simplified)"), (displaycodes == 2), 's');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    dialog::addBoolItem(XLAT("display only hexagons"), (whichShape == '6'), '6');
 | 
					 | 
				
			||||||
    dialog::addBoolItem(XLAT("display only heptagons"), (whichShape == '7'), '7');
 | 
					 | 
				
			||||||
    dialog::addBoolItem(XLAT("display the triheptagonal grid"), (whichShape == '8'), '8');
 | 
					 | 
				
			||||||
    if(cheater || autocheat) dialog::addItem(XLAT("line patterns"), 'l');
 | 
					 | 
				
			||||||
    else dialog::addInfo("enable the cheat mode to use line patterns");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if(!needConfirmation()) dialog::addItem(XLAT("predesigned patterns"), 'r');
 | 
					 | 
				
			||||||
    else dialog::addInfo("start a new game to use predesigned patterns");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    dialog::display();
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    keyhandler = [] (int sym, int uni) {
 | 
					 | 
				
			||||||
      dialog::handleNavigation(sym, uni);
 | 
					 | 
				
			||||||
      if(uni == 'f' || uni == 'p' || uni == 'z' || uni == 'H' || uni == 'F') {
 | 
					 | 
				
			||||||
        if(whichPattern == uni) whichPattern = 0;
 | 
					 | 
				
			||||||
        else whichPattern = uni;
 | 
					 | 
				
			||||||
        modelcell.clear();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      
 | 
					 | 
				
			||||||
      else if(uni == '0') symRotation = !symRotation;
 | 
					 | 
				
			||||||
      else if(uni == '1') sym01 = !sym01;
 | 
					 | 
				
			||||||
      else if(uni == '2') sym02 = !sym02;
 | 
					 | 
				
			||||||
      else if(uni == '3') sym03 = !sym03;
 | 
					 | 
				
			||||||
      else if(uni == '6' || uni == '7' || uni == '8') {
 | 
					 | 
				
			||||||
        if(whichShape == uni) whichShape = 0;
 | 
					 | 
				
			||||||
        else whichShape = uni;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      else if(uni == '3') sym03 = !sym03;
 | 
					 | 
				
			||||||
      else if(uni == 'd') displaycodes = displaycodes == 1 ? 0 : 1;
 | 
					 | 
				
			||||||
      else if(uni == 's') displaycodes = displaycodes == 2 ? 0 : 2;
 | 
					 | 
				
			||||||
      
 | 
					 | 
				
			||||||
      else if(uni == 'l' && (cheater || autocheat))
 | 
					 | 
				
			||||||
        pushScreen(linepatterns::showMenu);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      else if(uni == 'r' && !needConfirmation()) pushScreen(showPrePattern);
 | 
					 | 
				
			||||||
      
 | 
					 | 
				
			||||||
      else if(doexiton(sym, uni)) popScreen();
 | 
					 | 
				
			||||||
      };
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
  void showList() {
 | 
					 | 
				
			||||||
    v.clear();
 | 
					 | 
				
			||||||
    if(painttype == 4) painttype = 0;
 | 
					 | 
				
			||||||
    switch(painttype) {
 | 
					 | 
				
			||||||
      case 0: 
 | 
					 | 
				
			||||||
        for(int i=0; i<motypes; i++) {
 | 
					 | 
				
			||||||
          eMonster m = eMonster(i);
 | 
					 | 
				
			||||||
          if(
 | 
					 | 
				
			||||||
            m == moTongue || m == moPlayer || m == moFireball || m == moBullet ||
 | 
					 | 
				
			||||||
            m == moFlailBullet || m == moShadow || m == moAirball ||
 | 
					 | 
				
			||||||
            m == moWolfMoved || m == moGolemMoved ||
 | 
					 | 
				
			||||||
            m == moTameBomberbirdMoved || m == moKnightMoved ||
 | 
					 | 
				
			||||||
            m == moDeadBug || m == moLightningBolt || m == moDeadBird ||
 | 
					 | 
				
			||||||
            m == moMouseMoved || m == moPrincessMoved || m == moPrincessArmedMoved) ;
 | 
					 | 
				
			||||||
          else if(m == moDragonHead) vpush(i, "Dragon Head");
 | 
					 | 
				
			||||||
          else vpush(i, minf[i].name);
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        break;
 | 
					 | 
				
			||||||
      case 1:
 | 
					 | 
				
			||||||
        for(int i=0; i<ittypes; i++) vpush(i, iinf[i].name);
 | 
					 | 
				
			||||||
        break;
 | 
					 | 
				
			||||||
      case 2:
 | 
					 | 
				
			||||||
        for(int i=0; i<landtypes; i++) vpush(i, linf[i].name);
 | 
					 | 
				
			||||||
        break;
 | 
					 | 
				
			||||||
      case 3:
 | 
					 | 
				
			||||||
        for(int i=0; i<walltypes; i++) if(i != waChasmD) vpush(i, winf[i].name);
 | 
					 | 
				
			||||||
        break;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    // sort(v.begin(), v.end());
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    if(infix != "") mouseovers = infix;
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    int q = v.size();
 | 
					 | 
				
			||||||
    int percolumn = vid.yres / (vid.fsize+5) - 4;
 | 
					 | 
				
			||||||
    int columns = 1 + (q-1) / percolumn;
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    for(int i=0; i<q; i++) {
 | 
					 | 
				
			||||||
      int x = 16 + (vid.xres * (i/percolumn)) / columns;
 | 
					 | 
				
			||||||
      int y = (vid.fsize+5) * (i % percolumn) + vid.fsize*2;
 | 
					 | 
				
			||||||
      
 | 
					 | 
				
			||||||
      int actkey = 1000 + i;
 | 
					 | 
				
			||||||
      string vv = v[i].first;
 | 
					 | 
				
			||||||
      if(i < 9) { vv += ": "; vv += ('1' + i); }
 | 
					 | 
				
			||||||
      
 | 
					 | 
				
			||||||
      displayButton(x, y, vv, actkey, 0);
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    keyhandler = [] (int sym, int uni) {
 | 
					 | 
				
			||||||
      if(uni >= '1' && uni <= '9') uni = 1000 + uni - '1';
 | 
					 | 
				
			||||||
      if(sym == SDLK_RETURN || sym == SDLK_KP_ENTER || sym == '-' || sym == SDLK_KP_MINUS) uni = 1000;
 | 
					 | 
				
			||||||
      for(int z=0; z<size(v); z++) if(1000 + z == uni) {
 | 
					 | 
				
			||||||
        paintwhat = v[z].second;
 | 
					 | 
				
			||||||
        paintwhat_str = v[z].first;
 | 
					 | 
				
			||||||
        mousepressed = false;
 | 
					 | 
				
			||||||
        popScreen();
 | 
					 | 
				
			||||||
        return;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      if(editInfix(uni)) ;
 | 
					 | 
				
			||||||
      else if(doexiton(sym, uni)) popScreen();
 | 
					 | 
				
			||||||
      };    
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
  void showMapEditor() {
 | 
					  void showMapEditor() {
 | 
				
			||||||
    cmode = sm::MAP;
 | 
					    cmode = sm::MAP;
 | 
				
			||||||
    gamescreen(0);
 | 
					    gamescreen(0);
 | 
				
			||||||
@@ -833,6 +581,7 @@ namespace mapeditor {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  int cellShapeGroup() {
 | 
					  int cellShapeGroup() {
 | 
				
			||||||
 | 
					    using namespace patterns;
 | 
				
			||||||
    if(whichPattern == 'f') return 4;
 | 
					    if(whichPattern == 'f') return 4;
 | 
				
			||||||
    if(whichPattern == 'p') return 5;
 | 
					    if(whichPattern == 'p') return 5;
 | 
				
			||||||
    if(whichPattern == 'z') return 6;
 | 
					    if(whichPattern == 'z') return 6;
 | 
				
			||||||
@@ -851,13 +600,13 @@ namespace mapeditor {
 | 
				
			|||||||
    if(drawcell == cwt.c) return vid.cs.charid;
 | 
					    if(drawcell == cwt.c) return vid.cs.charid;
 | 
				
			||||||
    if(drawcell->monst) return drawcell->monst;
 | 
					    if(drawcell->monst) return drawcell->monst;
 | 
				
			||||||
    if(drawcell->item) return drawcell->item;
 | 
					    if(drawcell->item) return drawcell->item;
 | 
				
			||||||
    return subpattern(drawcell);
 | 
					    return patterns::subpattern(drawcell);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  bool editingShape(int group, int id) {
 | 
					  bool editingShape(int group, int id) {
 | 
				
			||||||
    if(group != mapeditor::drawcellShapeGroup()) return false;
 | 
					    if(group != mapeditor::drawcellShapeGroup()) return false;
 | 
				
			||||||
    if(group < 3) return id == drawcellShapeID();
 | 
					    if(group < 3) return id == drawcellShapeID();
 | 
				
			||||||
    return subpattern(id, whichPattern) == subpattern(drawcell);
 | 
					    return patterns::subpattern(id, patterns::whichPattern) == patterns::subpattern(drawcell);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void editCell(const pair<cellwalker, cellwalker>& where) {
 | 
					  void editCell(const pair<cellwalker, cellwalker>& where) {
 | 
				
			||||||
@@ -982,7 +731,7 @@ namespace mapeditor {
 | 
				
			|||||||
  
 | 
					  
 | 
				
			||||||
  void allInPattern(cellwalker where) {
 | 
					  void allInPattern(cellwalker where) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if(!whichPattern) {
 | 
					    if(!patterns::whichPattern) {
 | 
				
			||||||
      editAt(where);
 | 
					      editAt(where);
 | 
				
			||||||
      return;
 | 
					      return;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
@@ -1004,13 +753,13 @@ namespace mapeditor {
 | 
				
			|||||||
    
 | 
					    
 | 
				
			||||||
    int cdir = where.spin;
 | 
					    int cdir = where.spin;
 | 
				
			||||||
    if(cdir >= 0) 
 | 
					    if(cdir >= 0) 
 | 
				
			||||||
      cdir = cdir - patterndir(where.c);
 | 
					      cdir = cdir - patterns::patterndir(where.c);
 | 
				
			||||||
    int sp = subpattern(where.c);
 | 
					    int sp = patterns::subpattern(where.c);
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    for(cell* c2: v)
 | 
					    for(cell* c2: v)
 | 
				
			||||||
      if(subpattern(c2) == sp) {
 | 
					      if(patterns::subpattern(c2) == sp) {
 | 
				
			||||||
        editAt(cellwalker(c2, cdir>=0 ? fixdir(cdir + patterndir(c2), c2) : -1));
 | 
					        editAt(cellwalker(c2, cdir>=0 ? fixdir(cdir + patterns::patterndir(c2), c2) : -1));
 | 
				
			||||||
        modelcell[realpattern(c2)] = c2;
 | 
					        modelcell[patterns::realpattern(c2)] = c2;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
@@ -1063,6 +812,67 @@ namespace mapeditor {
 | 
				
			|||||||
    return cellwalker(mouseover, d);
 | 
					    return cellwalker(mouseover, d);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
 | 
					  void showList() {
 | 
				
			||||||
 | 
					    v.clear();
 | 
				
			||||||
 | 
					    if(painttype == 4) painttype = 0;
 | 
				
			||||||
 | 
					    switch(painttype) {
 | 
				
			||||||
 | 
					      case 0: 
 | 
				
			||||||
 | 
					        for(int i=0; i<motypes; i++) {
 | 
				
			||||||
 | 
					          eMonster m = eMonster(i);
 | 
				
			||||||
 | 
					          if(
 | 
				
			||||||
 | 
					            m == moTongue || m == moPlayer || m == moFireball || m == moBullet ||
 | 
				
			||||||
 | 
					            m == moFlailBullet || m == moShadow || m == moAirball ||
 | 
				
			||||||
 | 
					            m == moWolfMoved || m == moGolemMoved ||
 | 
				
			||||||
 | 
					            m == moTameBomberbirdMoved || m == moKnightMoved ||
 | 
				
			||||||
 | 
					            m == moDeadBug || m == moLightningBolt || m == moDeadBird ||
 | 
				
			||||||
 | 
					            m == moMouseMoved || m == moPrincessMoved || m == moPrincessArmedMoved) ;
 | 
				
			||||||
 | 
					          else if(m == moDragonHead) vpush(i, "Dragon Head");
 | 
				
			||||||
 | 
					          else vpush(i, minf[i].name);
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      case 1:
 | 
				
			||||||
 | 
					        for(int i=0; i<ittypes; i++) vpush(i, iinf[i].name);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      case 2:
 | 
				
			||||||
 | 
					        for(int i=0; i<landtypes; i++) vpush(i, linf[i].name);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      case 3:
 | 
				
			||||||
 | 
					        for(int i=0; i<walltypes; i++) if(i != waChasmD) vpush(i, winf[i].name);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    // sort(v.begin(), v.end());
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if(infix != "") mouseovers = infix;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    int q = v.size();
 | 
				
			||||||
 | 
					    int percolumn = vid.yres / (vid.fsize+5) - 4;
 | 
				
			||||||
 | 
					    int columns = 1 + (q-1) / percolumn;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    for(int i=0; i<q; i++) {
 | 
				
			||||||
 | 
					      int x = 16 + (vid.xres * (i/percolumn)) / columns;
 | 
				
			||||||
 | 
					      int y = (vid.fsize+5) * (i % percolumn) + vid.fsize*2;
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					      int actkey = 1000 + i;
 | 
				
			||||||
 | 
					      string vv = v[i].first;
 | 
				
			||||||
 | 
					      if(i < 9) { vv += ": "; vv += ('1' + i); }
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					      displayButton(x, y, vv, actkey, 0);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    keyhandler = [] (int sym, int uni) {
 | 
				
			||||||
 | 
					      if(uni >= '1' && uni <= '9') uni = 1000 + uni - '1';
 | 
				
			||||||
 | 
					      if(sym == SDLK_RETURN || sym == SDLK_KP_ENTER || sym == '-' || sym == SDLK_KP_MINUS) uni = 1000;
 | 
				
			||||||
 | 
					      for(int z=0; z<size(v); z++) if(1000 + z == uni) {
 | 
				
			||||||
 | 
					        paintwhat = v[z].second;
 | 
				
			||||||
 | 
					        paintwhat_str = v[z].first;
 | 
				
			||||||
 | 
					        mousepressed = false;
 | 
				
			||||||
 | 
					        popScreen();
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      if(editInfix(uni)) ;
 | 
				
			||||||
 | 
					      else if(doexiton(sym, uni)) popScreen();
 | 
				
			||||||
 | 
					      };    
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
  void handleKeyMap(int sym, int uni) {
 | 
					  void handleKeyMap(int sym, int uni) {
 | 
				
			||||||
    handlePanning(sym, uni);
 | 
					    handlePanning(sym, uni);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1081,7 +891,7 @@ namespace mapeditor {
 | 
				
			|||||||
    else if(uni == 'i') pushScreen(showList), painttype = 1, infix = "";
 | 
					    else if(uni == 'i') pushScreen(showList), painttype = 1, infix = "";
 | 
				
			||||||
    else if(uni == 'l') pushScreen(showList), painttype = 2, infix = "";
 | 
					    else if(uni == 'l') pushScreen(showList), painttype = 2, infix = "";
 | 
				
			||||||
    else if(uni == 'w') pushScreen(showList), painttype = 3, infix = "";
 | 
					    else if(uni == 'w') pushScreen(showList), painttype = 3, infix = "";
 | 
				
			||||||
    else if(uni == 'r') pushScreen(showPattern);
 | 
					    else if(uni == 'r') pushScreen(patterns::showPattern);
 | 
				
			||||||
    else if(uni == 't' && mouseover) {
 | 
					    else if(uni == 't' && mouseover) {
 | 
				
			||||||
      playermoved = true;
 | 
					      playermoved = true;
 | 
				
			||||||
      cwt = mouseover_cw(true);
 | 
					      cwt = mouseover_cw(true);
 | 
				
			||||||
@@ -1242,7 +1052,7 @@ namespace mapeditor {
 | 
				
			|||||||
      
 | 
					      
 | 
				
			||||||
      default:
 | 
					      default:
 | 
				
			||||||
        line1 = XLAT("floor/pattern");
 | 
					        line1 = XLAT("floor/pattern");
 | 
				
			||||||
        line2 = "#" + its(subpattern(drawcell));
 | 
					        line2 = "#" + its(patterns::subpattern(drawcell));
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
@@ -1602,7 +1412,7 @@ namespace mapeditor {
 | 
				
			|||||||
    if(uni == 'b') autochoose = !autochoose;
 | 
					    if(uni == 'b') autochoose = !autochoose;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    if(uni == 'r') {
 | 
					    if(uni == 'r') {
 | 
				
			||||||
      pushScreen(showPattern);
 | 
					      pushScreen(patterns::showPattern);
 | 
				
			||||||
      if(drawplayer) 
 | 
					      if(drawplayer) 
 | 
				
			||||||
        addMessage(XLAT("Hint: use F7 to edit floor under the player"));
 | 
					        addMessage(XLAT("Hint: use F7 to edit floor under the player"));
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
@@ -1690,142 +1500,12 @@ namespace mapeditor {
 | 
				
			|||||||
      mapeditor::paintwhat_str = "clear monster";
 | 
					      mapeditor::paintwhat_str = "clear monster";
 | 
				
			||||||
    mapeditor::copysource.c = NULL;
 | 
					    mapeditor::copysource.c = NULL;
 | 
				
			||||||
    mapeditor::undo.clear();
 | 
					    mapeditor::undo.clear();
 | 
				
			||||||
    if(!cheater) mapeditor::displaycodes = 0;
 | 
					    if(!cheater) patterns::displaycodes = 0;
 | 
				
			||||||
    if(!cheater) mapeditor::whichShape = 0;
 | 
					    if(!cheater) patterns::whichShape = 0;
 | 
				
			||||||
    modelcell.clear();
 | 
					    modelcell.clear();
 | 
				
			||||||
    });  
 | 
					    });  
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  int canvasback = linf[laCanvas].color >> 2;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  int generateCanvas(cell *c) {
 | 
					 | 
				
			||||||
    if(whichCanvas == 'C' && !torus) {
 | 
					 | 
				
			||||||
      using namespace fieldpattern;
 | 
					 | 
				
			||||||
      int z = currfp.getdist(fieldval(c), make_pair(0,false));
 | 
					 | 
				
			||||||
      if(z < currfp.circrad) return 0x00C000;
 | 
					 | 
				
			||||||
      int z2 = currfp.getdist(fieldval(c), make_pair(currfp.otherpole,false));
 | 
					 | 
				
			||||||
      if(z2 < currfp.disthep[currfp.otherpole] - currfp.circrad)
 | 
					 | 
				
			||||||
        return 0x3000;
 | 
					 | 
				
			||||||
      return 0x6000;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    if(whichCanvas == 'D' && !torus) {
 | 
					 | 
				
			||||||
      using namespace fieldpattern;
 | 
					 | 
				
			||||||
      int z = currfp.getdist(fieldval(c), make_pair(0,false));
 | 
					 | 
				
			||||||
      return 255 * (currfp.maxdist+1-z) / currfp.maxdist;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    if(whichCanvas == 'N' && !torus) {
 | 
					 | 
				
			||||||
      using namespace fieldpattern;
 | 
					 | 
				
			||||||
      int z = currfp.getdist(fieldval(c), make_pair(0,false));
 | 
					 | 
				
			||||||
      int z2 = currfp.getdist(fieldval(c), make_pair(currfp.otherpole,false));
 | 
					 | 
				
			||||||
      if(z < z2) return 0x00C000;
 | 
					 | 
				
			||||||
      if(z > z2) return 0xC00000;
 | 
					 | 
				
			||||||
      return 0xCCCC00;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    if(whichCanvas == 'S' && !torus) {
 | 
					 | 
				
			||||||
      return 0x3F1F0F * fieldpattern::subval(c).second + 0x000080;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    if(whichCanvas == 'g')
 | 
					 | 
				
			||||||
      return canvasback;
 | 
					 | 
				
			||||||
    if(whichCanvas == 'r')
 | 
					 | 
				
			||||||
      return hrand(0xFFFFFF + 1);
 | 
					 | 
				
			||||||
    if(whichCanvas == 'e') {
 | 
					 | 
				
			||||||
      static unsigned int fcol[4] = { 0x404040, 0x800000, 0x008000, 0x000080 };
 | 
					 | 
				
			||||||
      int fv = emeraldval(c);
 | 
					 | 
				
			||||||
      return fcol[fv&3];
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    if(whichCanvas == 'a') {
 | 
					 | 
				
			||||||
      static unsigned int fcol8[8] = { 
 | 
					 | 
				
			||||||
        0x800000,
 | 
					 | 
				
			||||||
        0x503000,
 | 
					 | 
				
			||||||
        0x206000,
 | 
					 | 
				
			||||||
        0x007010,
 | 
					 | 
				
			||||||
        0x004040,
 | 
					 | 
				
			||||||
        0x001070,
 | 
					 | 
				
			||||||
        0x200060,
 | 
					 | 
				
			||||||
        0x500030
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
      if(c->wall == waNone) {
 | 
					 | 
				
			||||||
        int col = fcol8[land50(c)];
 | 
					 | 
				
			||||||
        if(polara50(c)) col += 0x181818;
 | 
					 | 
				
			||||||
        return col;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    if(whichCanvas == 'b') {
 | 
					 | 
				
			||||||
      static unsigned int fcol[4] = { 0x404040, 0x800000, 0x008000, 0x000080 };
 | 
					 | 
				
			||||||
      return fcol[polara50(c) + 2 * polarb50(c)];
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    if(whichCanvas == 'z') {
 | 
					 | 
				
			||||||
      static unsigned int fcol[4] = { 0xC0C0C0, 0xE0E0E0, 0x404040, 0x606060 };
 | 
					 | 
				
			||||||
      int fv = zebra40(c);
 | 
					 | 
				
			||||||
      return fcol[fv&3];
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    if(whichCanvas == 't') {
 | 
					 | 
				
			||||||
      static unsigned int fcol[4] = { 0x804040, 0x408040, 0x404080, 0x808040 };
 | 
					 | 
				
			||||||
      int fv = zebra40(c);
 | 
					 | 
				
			||||||
      if(fv/4 == 4 || fv/4 == 6 || fv/4 == 5 || fv/4 == 10) fv ^= 2;
 | 
					 | 
				
			||||||
      return fcol[fv&3];
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    if(whichCanvas == 'x') {
 | 
					 | 
				
			||||||
      static unsigned int fcol[4] = { 0xC0C0C0, 0x800000, 0x008000, 0x000080 };
 | 
					 | 
				
			||||||
      return fcol[zebra3(c)];
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    if(whichCanvas == 'w') {
 | 
					 | 
				
			||||||
      static unsigned int fcol[2] = { 0x303030, 0xC0C0C0 };
 | 
					 | 
				
			||||||
      return fcol[randpattern(c, subcanvas) ? 1 : 0];
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    if(whichCanvas == 'l') {
 | 
					 | 
				
			||||||
      int col[4];
 | 
					 | 
				
			||||||
      bool err = false;
 | 
					 | 
				
			||||||
      for(int j=0; j<4; j++) {
 | 
					 | 
				
			||||||
        col[j] = getCdata(c, j);
 | 
					 | 
				
			||||||
        col[j] *= 3;
 | 
					 | 
				
			||||||
        col[j] %= 240;
 | 
					 | 
				
			||||||
        if(col[j] > 120) col[j] = 240 - col[j];
 | 
					 | 
				
			||||||
        if(col[j] < -120) col[j] = -240 - col[j];
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      return (0x808080 + col[0] + (col[1] << 8) + (col[2] << 16)) >> (err?2:0);
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    if(whichCanvas == 'd') {
 | 
					 | 
				
			||||||
      int col[4];
 | 
					 | 
				
			||||||
      bool err = false;
 | 
					 | 
				
			||||||
      for(int j=0; j<4; j++) {
 | 
					 | 
				
			||||||
        col[j] = getCdata(c, j);
 | 
					 | 
				
			||||||
        col[j] *= 6;
 | 
					 | 
				
			||||||
        col[j] %= 240;
 | 
					 | 
				
			||||||
        if(col[j] > 120) col[j] = 240 - col[j];
 | 
					 | 
				
			||||||
        if(col[j] < -120) col[j] = -240 - col[j];
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      col[0] /= 8;
 | 
					 | 
				
			||||||
      col[1] /= 8;
 | 
					 | 
				
			||||||
      col[2] /= 8;
 | 
					 | 
				
			||||||
      return (0x101010 + col[0] + (col[1] << 8) + (col[2] << 16)) >> (err?2:0);
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    if(whichCanvas == 'h') {
 | 
					 | 
				
			||||||
      int col[4];
 | 
					 | 
				
			||||||
      bool err = false;
 | 
					 | 
				
			||||||
      for(int j=0; j<4; j++) {
 | 
					 | 
				
			||||||
        col[j] = getCdata(c, j);
 | 
					 | 
				
			||||||
        col[j] *= 6;
 | 
					 | 
				
			||||||
        col[j] %= 240;
 | 
					 | 
				
			||||||
        if(col[j] > 120) col[j] = 240 - col[j];
 | 
					 | 
				
			||||||
        if(col[j] < -120) col[j] = -240 - col[j];
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      col[0] /= 4;
 | 
					 | 
				
			||||||
      col[1] /= 4;
 | 
					 | 
				
			||||||
      col[2] /= 4;
 | 
					 | 
				
			||||||
      return (0x202020 + col[0] + (col[1] << 8) + (col[2] << 16)) >> (err?2:0);
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    if(whichCanvas == 'F') {
 | 
					 | 
				
			||||||
      return pseudohept(c) ? 0x202020 : 0xC0C0C0;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    if(whichCanvas == 'T') {
 | 
					 | 
				
			||||||
      int fv = pattern_threecolor(c);
 | 
					 | 
				
			||||||
      return nestcolors[fv&7];
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    return canvasback;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  void initdraw(cell *c) {
 | 
					  void initdraw(cell *c) {
 | 
				
			||||||
    mapeditor::drawcell = c;
 | 
					    mapeditor::drawcell = c;
 | 
				
			||||||
    ew.c = c;
 | 
					    ew.c = c;
 | 
				
			||||||
@@ -1958,273 +1638,3 @@ namespace mapeditor {
 | 
				
			|||||||
  
 | 
					  
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace linepatterns {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  int lessalpha(int col, int m) {
 | 
					 | 
				
			||||||
    part(col, 0) /= m;
 | 
					 | 
				
			||||||
    return col;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
  int lessalphaif(int col, bool b) {
 | 
					 | 
				
			||||||
    return b?lessalpha(col, 4):col;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
  int lessalphaif(int col, bool b1, bool b2) {
 | 
					 | 
				
			||||||
    if(b1) col = lessalpha(col, 2);
 | 
					 | 
				
			||||||
    if(b2) col = lessalpha(col, 2);
 | 
					 | 
				
			||||||
    return col;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
  struct {
 | 
					 | 
				
			||||||
    int id;
 | 
					 | 
				
			||||||
    const char *lpname;
 | 
					 | 
				
			||||||
    unsigned int color;
 | 
					 | 
				
			||||||
    } patterns[] = {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    {patTriNet, "triangle grid: not rings", 0xFFFFFF00},
 | 
					 | 
				
			||||||
    {patTriRings, "triangle grid: rings", 0xFFFFFF00},
 | 
					 | 
				
			||||||
    {patHepta, "heptagonal grid", 0x0000C000},
 | 
					 | 
				
			||||||
    {patRhomb, "rhombic tesselation", 0x0000C000},
 | 
					 | 
				
			||||||
    {patTrihepta, "triheptagonal tesselation", 0x0000C000},
 | 
					 | 
				
			||||||
    {patNormal, "normal tesselation", 0x0000C000},
 | 
					 | 
				
			||||||
    {patBigTriangles, "big triangular grid", 0x00606000},
 | 
					 | 
				
			||||||
    {patBigRings, "big triangles: rings", 0x0000C000},
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    {patTree, "underlying tree", 0x00d0d000},
 | 
					 | 
				
			||||||
    {patAltTree, "circle/horocycle tree", 0xd000d000},
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    {patZebraTriangles, "zebra triangles", 0x40FF4000},
 | 
					 | 
				
			||||||
    {patZebraLines, "zebra lines", 0xFF000000},
 | 
					 | 
				
			||||||
    {patVine, "vineyard pattern", 0x8438A400},
 | 
					 | 
				
			||||||
    {patPalacelike, "firewall lines", 0xFF400000},
 | 
					 | 
				
			||||||
    {patPalace, "firewall lines: Palace", 0xFFD50000},
 | 
					 | 
				
			||||||
    {patPower, "firewall lines: Power", 0xFFFF0000},
 | 
					 | 
				
			||||||
    {0, NULL, 0}
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  void clearAll() {
 | 
					 | 
				
			||||||
    for(int k=0; patterns[k].lpname; k++) patterns[k].color &= ~255;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  bool any() {
 | 
					 | 
				
			||||||
    for(int k=0; patterns[k].lpname; k++) if(patterns[k].color & 255) return true;
 | 
					 | 
				
			||||||
    return false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  void setColor(ePattern id, int col) {
 | 
					 | 
				
			||||||
    for(int k=0; patterns[k].lpname; k++)
 | 
					 | 
				
			||||||
      if(patterns[k].id == id) patterns[k].color = col;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
  void switchAlpha(ePattern id, int col) {
 | 
					 | 
				
			||||||
    for(int k=0; patterns[k].lpname; k++)
 | 
					 | 
				
			||||||
      if(patterns[k].id == id) patterns[k].color ^= col;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  void drawPattern(int id, int col, cell *c, const transmatrix& V) {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    switch(id) {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      case patZebraTriangles:
 | 
					 | 
				
			||||||
        if(zebra40(c) / 4 == 10) {
 | 
					 | 
				
			||||||
          bool all = true;
 | 
					 | 
				
			||||||
          hyperpoint tri[3];
 | 
					 | 
				
			||||||
          for(int i=0; i<3; i++) {
 | 
					 | 
				
			||||||
            cell *c2 = createMov(c, i*2);
 | 
					 | 
				
			||||||
            if(!gmatrix.count(c2)) all = false;
 | 
					 | 
				
			||||||
            else tri[i] = tC0(gmatrix[c2]);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
          
 | 
					 | 
				
			||||||
          if(all) for(int i=0; i<3; i++)
 | 
					 | 
				
			||||||
            queueline(tri[i], tri[(i+1)%3], col, 3);
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        break;
 | 
					 | 
				
			||||||
      
 | 
					 | 
				
			||||||
      case patZebraLines:
 | 
					 | 
				
			||||||
        if(!pseudohept(c)) for(int i=0; i<c->type; i+=2) {
 | 
					 | 
				
			||||||
          cell *c2 = createMov(c, i);
 | 
					 | 
				
			||||||
          int fv1 = zebra40(c);
 | 
					 | 
				
			||||||
          if(fv1/4 == 4 || fv1/4 == 6 || fv1/4 == 5 || fv1/4 == 10) fv1 ^= 2;
 | 
					 | 
				
			||||||
          int fv2 = zebra40(c2);
 | 
					 | 
				
			||||||
          if(fv2/4 == 4 || fv2/4 == 6 || fv2/4 == 5 || fv2/4 == 10) fv2 ^= 2;
 | 
					 | 
				
			||||||
          if((fv1&1) == (fv2&1)) continue;
 | 
					 | 
				
			||||||
          
 | 
					 | 
				
			||||||
          double x = sphere?.3651:euclid?.2611:.2849;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
          queueline(V * ddspin(c,i,-S14) * xpush0(x), 
 | 
					 | 
				
			||||||
            V * ddspin(c,i,+S14) * xpush0(x), 
 | 
					 | 
				
			||||||
            col, 1);
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        break;
 | 
					 | 
				
			||||||
      
 | 
					 | 
				
			||||||
      case patNormal: {
 | 
					 | 
				
			||||||
        double x = sphere?.401:euclid?.3 : .328;
 | 
					 | 
				
			||||||
        if(euclid || !pseudohept(c)) for(int t=0; t<c->type; t++) 
 | 
					 | 
				
			||||||
          if(euclid ? c->mov[t]<c : (((t^1)&1) || c->mov[t] < c))
 | 
					 | 
				
			||||||
            queueline(V * ddspin(c,t,-S7) * xpush0(x), 
 | 
					 | 
				
			||||||
                V * ddspin(c,t,+S7) * xpush0(x), 
 | 
					 | 
				
			||||||
                col, 1);
 | 
					 | 
				
			||||||
        break;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      
 | 
					 | 
				
			||||||
      case patTrihepta:
 | 
					 | 
				
			||||||
        if(!pseudohept(c)) for(int i=0; i<6; i++) {
 | 
					 | 
				
			||||||
          cell *c2 = c->mov[i];
 | 
					 | 
				
			||||||
          if(!c2 || !pseudohept(c2)) continue;
 | 
					 | 
				
			||||||
          double x = sphere?.3651:euclid?.2611:.2849;
 | 
					 | 
				
			||||||
          queueline(V * ddspin(c,i,-S14) * xpush0(x), 
 | 
					 | 
				
			||||||
            V * ddspin(c,i,+S14) * xpush0(x), 
 | 
					 | 
				
			||||||
            col, 1);
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        break;
 | 
					 | 
				
			||||||
      
 | 
					 | 
				
			||||||
      case patTriNet:
 | 
					 | 
				
			||||||
        forCellEx(c2, c) if(c2 > c) if(gmatrix.count(c2)) if(celldist(c) != celldist(c2)) {
 | 
					 | 
				
			||||||
          queueline(tC0(V), gmatrix[c2]*C0, 
 | 
					 | 
				
			||||||
            darkena(backcolor ^ 0xFFFFFF, 0, col),
 | 
					 | 
				
			||||||
            2);
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      case patTriRings:
 | 
					 | 
				
			||||||
        forCellEx(c2, c) if(c2 > c) if(gmatrix.count(c2) && celldist(c) == celldist(c2)) 
 | 
					 | 
				
			||||||
          queueline(tC0(V), gmatrix[c2]*C0, 
 | 
					 | 
				
			||||||
            darkena(backcolor ^ 0xFFFFFF, 0, col),
 | 
					 | 
				
			||||||
            2);
 | 
					 | 
				
			||||||
        break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      case patHepta:
 | 
					 | 
				
			||||||
        forCellEx(c2, c) if(c2 > c) if(gmatrix.count(c2) && pseudohept(c) == pseudohept(c2)) 
 | 
					 | 
				
			||||||
          queueline(tC0(V), gmatrix[c2]*C0, 
 | 
					 | 
				
			||||||
            darkena(backcolor ^ 0xFFFFFF, 0, col),
 | 
					 | 
				
			||||||
            2);
 | 
					 | 
				
			||||||
        break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      case patRhomb:
 | 
					 | 
				
			||||||
        forCellEx(c2, c) if(c2 > c) if(gmatrix.count(c2) && pseudohept(c) != pseudohept(c2)) 
 | 
					 | 
				
			||||||
          queueline(tC0(V), gmatrix[c2]*C0, 
 | 
					 | 
				
			||||||
            darkena(backcolor ^ 0xFFFFFF, 0, col),
 | 
					 | 
				
			||||||
            2);
 | 
					 | 
				
			||||||
        break;
 | 
					 | 
				
			||||||
      
 | 
					 | 
				
			||||||
      case patPalace: {
 | 
					 | 
				
			||||||
        int a = polarb50(c);
 | 
					 | 
				
			||||||
        if(pseudohept(c)) for(int i=0; i<7; i++) {
 | 
					 | 
				
			||||||
            cell *c1 = createMov(c, (i+3) % 7);
 | 
					 | 
				
			||||||
            cell *c2 = createMov(c, (i+4) % 7);
 | 
					 | 
				
			||||||
            if(polarb50(c1) != a && polarb50(c2) != a)
 | 
					 | 
				
			||||||
                queueline(V * ddspin(c,i,84*5/14) * xpush0(tessf/2),
 | 
					 | 
				
			||||||
                          V * ddspin(c,i,84*9/14) * xpush0(tessf/2),
 | 
					 | 
				
			||||||
                                    col, 1);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        break;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      
 | 
					 | 
				
			||||||
      case patPalacelike:
 | 
					 | 
				
			||||||
        if(pseudohept(c)) for(int i=0; i<7; i++) 
 | 
					 | 
				
			||||||
          queueline(V * ddspin(c,i,84*5/14) * xpush0(tessf/2),
 | 
					 | 
				
			||||||
                    V * ddspin(c,i,84*9/14) * xpush0(tessf/2),
 | 
					 | 
				
			||||||
                              col, 1);
 | 
					 | 
				
			||||||
        break;
 | 
					 | 
				
			||||||
      
 | 
					 | 
				
			||||||
      case patBigTriangles: {
 | 
					 | 
				
			||||||
        if(pseudohept(c) && !euclid) for(int i=0; i<S7; i++) 
 | 
					 | 
				
			||||||
          if(c->master->move[i] < c->master) {
 | 
					 | 
				
			||||||
            queueline(tC0(V), V*xspinpush0((nontruncated?M_PI:0) -2*M_PI*i/S7, tessf), col, 2);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        break;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
      case patBigRings: {
 | 
					 | 
				
			||||||
        if(pseudohept(c) && !euclid) for(int i=0; i<S7; i++) 
 | 
					 | 
				
			||||||
          if(c->master->move[i] && c->master->move[i] < c->master && c->master->move[i]->dm4 == c->master->dm4)
 | 
					 | 
				
			||||||
            queueline(tC0(V), V*xspinpush0((nontruncated?M_PI:0) -2*M_PI*i/S7, tessf), col, 2);
 | 
					 | 
				
			||||||
        break;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
      case patTree:
 | 
					 | 
				
			||||||
        if(ctof(c) && !euclid) 
 | 
					 | 
				
			||||||
          queueline(tC0(V), V*ddi0(nontruncated?S42:0, tessf), col, 2);
 | 
					 | 
				
			||||||
        break;
 | 
					 | 
				
			||||||
      
 | 
					 | 
				
			||||||
      case patAltTree:
 | 
					 | 
				
			||||||
        if(ctof(c) && !euclid && c->master->alt) {
 | 
					 | 
				
			||||||
          for(int i=0; i<S7; i++)
 | 
					 | 
				
			||||||
            if(c->master->move[i] && c->master->move[i]->alt == c->master->alt->move[0])
 | 
					 | 
				
			||||||
              queueline(tC0(V), V*xspinpush0((nontruncated?M_PI:0) -2*M_PI*i/S7, tessf), col, 2);
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        break;
 | 
					 | 
				
			||||||
      
 | 
					 | 
				
			||||||
      case patVine: {
 | 
					 | 
				
			||||||
        int p = emeraldval(c);
 | 
					 | 
				
			||||||
        double hdist = hdist0(heptmove[0] * heptmove[2] * C0);
 | 
					 | 
				
			||||||
        if(pseudohept(c) && (p/4 == 10 || p/4 == 8))
 | 
					 | 
				
			||||||
        for(int i=0; i<S7; i++) if(c->mov[i] && emeraldval(c->mov[i]) == p-4) {
 | 
					 | 
				
			||||||
          queueline(tC0(V), V*tC0(heptmove[i]), col, 2);
 | 
					 | 
				
			||||||
          queueline(tC0(V), V*tC0(spin(-i * ALPHA) * xpush(-hdist/2)), col, 2);
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        break;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      
 | 
					 | 
				
			||||||
      case patPower: {
 | 
					 | 
				
			||||||
        int a = emeraldval(c);
 | 
					 | 
				
			||||||
        if(pseudohept(c) && a/4 == 8) for(int i=0; i<7; i++) {
 | 
					 | 
				
			||||||
            heptagon *h1 = c->master->move[(i+1)%7];
 | 
					 | 
				
			||||||
            heptagon *h2 = c->master->move[(i+6)%7];
 | 
					 | 
				
			||||||
            if(!h1 || !h2) continue;
 | 
					 | 
				
			||||||
            if(emeraldval(h1->c7)/4 == 8 && emeraldval(h2->c7)/4 == 8)
 | 
					 | 
				
			||||||
                queueline(V * ddspin(c,i,84*5/14) * xpush0(tessf/2),
 | 
					 | 
				
			||||||
                          V * ddspin(c,i,84*9/14) * xpush0(tessf/2),
 | 
					 | 
				
			||||||
                                    col, 1);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        break;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }  
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  void drawAll() {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if(any()) for(map<cell*, transmatrix>::iterator it = gmatrix.begin(); it != gmatrix.end(); it++) {
 | 
					 | 
				
			||||||
      cell *c = it->first;
 | 
					 | 
				
			||||||
      transmatrix& V = it->second;
 | 
					 | 
				
			||||||
      
 | 
					 | 
				
			||||||
      for(int k=0; patterns[k].lpname; k++) {
 | 
					 | 
				
			||||||
        int col = patterns[k].color;
 | 
					 | 
				
			||||||
        if(!(col & 255)) continue;
 | 
					 | 
				
			||||||
        int id = patterns[k].id;
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        drawPattern(id, col, c, V);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
  int numpat = 0;
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
  void showMenu() {
 | 
					 | 
				
			||||||
    cmode = sm::SIDE | sm::MAYDARK;
 | 
					 | 
				
			||||||
    gamescreen(0);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    dialog::init(XLAT("line patterns"));
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    for(numpat=0; patterns[numpat].lpname; numpat++)
 | 
					 | 
				
			||||||
      dialog::addColorItem(XLAT(patterns[numpat].lpname), patterns[numpat].color, 'a'+numpat);
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
    dialog::addBreak(50);
 | 
					 | 
				
			||||||
    dialog::addItem(XLAT("exit menu"), 'v');
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    dialog::addBreak(50);
 | 
					 | 
				
			||||||
    dialog::addInfo("change the alpha parameter to show the lines");
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
    dialog::display();
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    keyhandler = [] (int sym, int uni) {
 | 
					 | 
				
			||||||
      dialog::handleNavigation(sym, uni);
 | 
					 | 
				
			||||||
      if(uni >= 'a' && uni < 'a' + numpat) {
 | 
					 | 
				
			||||||
        dialog::openColorDialog(patterns[uni - 'a'].color, NULL);
 | 
					 | 
				
			||||||
        dialog::dialogflags |= sm::MAYDARK | sm::SIDE;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      else if(doexiton(sym,uni)) popScreen();
 | 
					 | 
				
			||||||
      }; 
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
  };
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										596
									
								
								pattern2.cpp
									
									
									
									
									
								
							
							
						
						
									
										596
									
								
								pattern2.cpp
									
									
									
									
									
								
							@@ -397,7 +397,7 @@ sphereinfo valsphere(cell *c) {
 | 
				
			|||||||
  return si;
 | 
					  return si;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace mapeditor {
 | 
					namespace patterns {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  int nopattern(cell *c) {
 | 
					  int nopattern(cell *c) {
 | 
				
			||||||
    if(isWarped(c) && !euclid) {
 | 
					    if(isWarped(c) && !euclid) {
 | 
				
			||||||
@@ -618,6 +618,55 @@ namespace mapeditor {
 | 
				
			|||||||
        return 0;
 | 
					        return 0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
 | 
					  char whichPattern = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  bool symRotation, sym01, sym02, sym03;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  int subpattern(int i, char w) {  
 | 
				
			||||||
 | 
					    if(euclid) {
 | 
				
			||||||
 | 
					      if(w == 'p') 
 | 
				
			||||||
 | 
					        return i;
 | 
				
			||||||
 | 
					      if(w == 'z' || w == 'f')
 | 
				
			||||||
 | 
					        return (symRotation && (i<3)) ? 0 : i;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if(a38 && w == 'p') {
 | 
				
			||||||
 | 
					      if(sym01 && i == 5) i = 4;
 | 
				
			||||||
 | 
					      if(symRotation && i < 4) i = 0;
 | 
				
			||||||
 | 
					      return i;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if(w == 'z' || w == 'f' || w == 'p') {
 | 
				
			||||||
 | 
					      if((sym01?1:0)+(sym02?1:0)+(sym03?1:0) >= 2) i &= ~3;
 | 
				
			||||||
 | 
					      if(sym01 && (i&1)) i ^= 1;
 | 
				
			||||||
 | 
					      if(sym02 && (i&2)) i ^= 2;
 | 
				
			||||||
 | 
					      if(sym03 && (i&2)) i ^= 3;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if(w == 'z' && symRotation) {
 | 
				
			||||||
 | 
					      if(a4 && !a46) {
 | 
				
			||||||
 | 
					        if(i >= 4 && i < 7) i -= 4;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      else {
 | 
				
			||||||
 | 
					        if(i >= 8 && i < 12) i -= 4;
 | 
				
			||||||
 | 
					        if(i >= 12 && i < 16) i -= 8;
 | 
				
			||||||
 | 
					        if(i >= 20 && i < 24) i -= 4;
 | 
				
			||||||
 | 
					        if(i >= 24 && i < 28) i -= 8;
 | 
				
			||||||
 | 
					        if(i >= 32 && i < 36) i -= 4;
 | 
				
			||||||
 | 
					        if(i >= 36 && i < 40) i -= 8;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if(w == 'p' && stdhyperbolic && symRotation && i >= 3)
 | 
				
			||||||
 | 
					      i -= ((i/4-1) % 7) * 4;
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					    return i;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  int subpattern(cell *c, char w) {
 | 
				
			||||||
 | 
					    return subpattern(realpattern(c, w), w);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int geosupport_threecolor() {
 | 
					int geosupport_threecolor() {
 | 
				
			||||||
@@ -687,3 +736,548 @@ bool pseudohept(cell *c) {
 | 
				
			|||||||
  return pattern_threecolor(c) == 0;
 | 
					  return pattern_threecolor(c) == 0;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace patterns {
 | 
				
			||||||
 | 
					  int canvasback = linf[laCanvas].color >> 2;
 | 
				
			||||||
 | 
					  int subcanvas;
 | 
				
			||||||
 | 
					  int displaycodes;
 | 
				
			||||||
 | 
					  char whichShape = 0;
 | 
				
			||||||
 | 
					  char whichCanvas = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  int generateCanvas(cell *c) {
 | 
				
			||||||
 | 
					    if(whichCanvas == 'C' && !torus) {
 | 
				
			||||||
 | 
					      using namespace fieldpattern;
 | 
				
			||||||
 | 
					      int z = currfp.getdist(fieldval(c), make_pair(0,false));
 | 
				
			||||||
 | 
					      if(z < currfp.circrad) return 0x00C000;
 | 
				
			||||||
 | 
					      int z2 = currfp.getdist(fieldval(c), make_pair(currfp.otherpole,false));
 | 
				
			||||||
 | 
					      if(z2 < currfp.disthep[currfp.otherpole] - currfp.circrad)
 | 
				
			||||||
 | 
					        return 0x3000;
 | 
				
			||||||
 | 
					      return 0x6000;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    if(whichCanvas == 'D' && !torus) {
 | 
				
			||||||
 | 
					      using namespace fieldpattern;
 | 
				
			||||||
 | 
					      int z = currfp.getdist(fieldval(c), make_pair(0,false));
 | 
				
			||||||
 | 
					      return 255 * (currfp.maxdist+1-z) / currfp.maxdist;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    if(whichCanvas == 'N' && !torus) {
 | 
				
			||||||
 | 
					      using namespace fieldpattern;
 | 
				
			||||||
 | 
					      int z = currfp.getdist(fieldval(c), make_pair(0,false));
 | 
				
			||||||
 | 
					      int z2 = currfp.getdist(fieldval(c), make_pair(currfp.otherpole,false));
 | 
				
			||||||
 | 
					      if(z < z2) return 0x00C000;
 | 
				
			||||||
 | 
					      if(z > z2) return 0xC00000;
 | 
				
			||||||
 | 
					      return 0xCCCC00;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    if(whichCanvas == 'S' && !torus) {
 | 
				
			||||||
 | 
					      return 0x3F1F0F * fieldpattern::subval(c).second + 0x000080;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    if(whichCanvas == 'g')
 | 
				
			||||||
 | 
					      return canvasback;
 | 
				
			||||||
 | 
					    if(whichCanvas == 'r')
 | 
				
			||||||
 | 
					      return hrand(0xFFFFFF + 1);
 | 
				
			||||||
 | 
					    if(whichCanvas == 'e') {
 | 
				
			||||||
 | 
					      static unsigned int fcol[4] = { 0x404040, 0x800000, 0x008000, 0x000080 };
 | 
				
			||||||
 | 
					      int fv = emeraldval(c);
 | 
				
			||||||
 | 
					      return fcol[fv&3];
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    if(whichCanvas == 'a') {
 | 
				
			||||||
 | 
					      static unsigned int fcol8[8] = { 
 | 
				
			||||||
 | 
					        0x800000,
 | 
				
			||||||
 | 
					        0x503000,
 | 
				
			||||||
 | 
					        0x206000,
 | 
				
			||||||
 | 
					        0x007010,
 | 
				
			||||||
 | 
					        0x004040,
 | 
				
			||||||
 | 
					        0x001070,
 | 
				
			||||||
 | 
					        0x200060,
 | 
				
			||||||
 | 
					        0x500030
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					      if(c->wall == waNone) {
 | 
				
			||||||
 | 
					        int col = fcol8[land50(c)];
 | 
				
			||||||
 | 
					        if(polara50(c)) col += 0x181818;
 | 
				
			||||||
 | 
					        return col;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    if(whichCanvas == 'b') {
 | 
				
			||||||
 | 
					      static unsigned int fcol[4] = { 0x404040, 0x800000, 0x008000, 0x000080 };
 | 
				
			||||||
 | 
					      return fcol[polara50(c) + 2 * polarb50(c)];
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    if(whichCanvas == 'z') {
 | 
				
			||||||
 | 
					      static unsigned int fcol[4] = { 0xC0C0C0, 0xE0E0E0, 0x404040, 0x606060 };
 | 
				
			||||||
 | 
					      int fv = zebra40(c);
 | 
				
			||||||
 | 
					      return fcol[fv&3];
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    if(whichCanvas == 't') {
 | 
				
			||||||
 | 
					      static unsigned int fcol[4] = { 0x804040, 0x408040, 0x404080, 0x808040 };
 | 
				
			||||||
 | 
					      int fv = zebra40(c);
 | 
				
			||||||
 | 
					      if(fv/4 == 4 || fv/4 == 6 || fv/4 == 5 || fv/4 == 10) fv ^= 2;
 | 
				
			||||||
 | 
					      return fcol[fv&3];
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    if(whichCanvas == 'x') {
 | 
				
			||||||
 | 
					      static unsigned int fcol[4] = { 0xC0C0C0, 0x800000, 0x008000, 0x000080 };
 | 
				
			||||||
 | 
					      return fcol[zebra3(c)];
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    if(whichCanvas == 'w') {
 | 
				
			||||||
 | 
					      static unsigned int fcol[2] = { 0x303030, 0xC0C0C0 };
 | 
				
			||||||
 | 
					      return fcol[randpattern(c, subcanvas) ? 1 : 0];
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    if(whichCanvas == 'l') {
 | 
				
			||||||
 | 
					      int col[4];
 | 
				
			||||||
 | 
					      bool err = false;
 | 
				
			||||||
 | 
					      for(int j=0; j<4; j++) {
 | 
				
			||||||
 | 
					        col[j] = getCdata(c, j);
 | 
				
			||||||
 | 
					        col[j] *= 3;
 | 
				
			||||||
 | 
					        col[j] %= 240;
 | 
				
			||||||
 | 
					        if(col[j] > 120) col[j] = 240 - col[j];
 | 
				
			||||||
 | 
					        if(col[j] < -120) col[j] = -240 - col[j];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      return (0x808080 + col[0] + (col[1] << 8) + (col[2] << 16)) >> (err?2:0);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    if(whichCanvas == 'd') {
 | 
				
			||||||
 | 
					      int col[4];
 | 
				
			||||||
 | 
					      bool err = false;
 | 
				
			||||||
 | 
					      for(int j=0; j<4; j++) {
 | 
				
			||||||
 | 
					        col[j] = getCdata(c, j);
 | 
				
			||||||
 | 
					        col[j] *= 6;
 | 
				
			||||||
 | 
					        col[j] %= 240;
 | 
				
			||||||
 | 
					        if(col[j] > 120) col[j] = 240 - col[j];
 | 
				
			||||||
 | 
					        if(col[j] < -120) col[j] = -240 - col[j];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      col[0] /= 8;
 | 
				
			||||||
 | 
					      col[1] /= 8;
 | 
				
			||||||
 | 
					      col[2] /= 8;
 | 
				
			||||||
 | 
					      return (0x101010 + col[0] + (col[1] << 8) + (col[2] << 16)) >> (err?2:0);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    if(whichCanvas == 'h') {
 | 
				
			||||||
 | 
					      int col[4];
 | 
				
			||||||
 | 
					      bool err = false;
 | 
				
			||||||
 | 
					      for(int j=0; j<4; j++) {
 | 
				
			||||||
 | 
					        col[j] = getCdata(c, j);
 | 
				
			||||||
 | 
					        col[j] *= 6;
 | 
				
			||||||
 | 
					        col[j] %= 240;
 | 
				
			||||||
 | 
					        if(col[j] > 120) col[j] = 240 - col[j];
 | 
				
			||||||
 | 
					        if(col[j] < -120) col[j] = -240 - col[j];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      col[0] /= 4;
 | 
				
			||||||
 | 
					      col[1] /= 4;
 | 
				
			||||||
 | 
					      col[2] /= 4;
 | 
				
			||||||
 | 
					      return (0x202020 + col[0] + (col[1] << 8) + (col[2] << 16)) >> (err?2:0);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    if(whichCanvas == 'F') {
 | 
				
			||||||
 | 
					      return pseudohept(c) ? 0x202020 : 0xC0C0C0;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    if(whichCanvas == 'T') {
 | 
				
			||||||
 | 
					      int fv = pattern_threecolor(c);
 | 
				
			||||||
 | 
					      return nestcolors[fv&7];
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    return canvasback;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void showPrePattern() {
 | 
				
			||||||
 | 
					    dialog::init("predesigned patterns");
 | 
				
			||||||
 | 
					    dialog::addItem(XLAT("Gameboard"), 'g');
 | 
				
			||||||
 | 
					    dialog::addItem(XLAT("random colors"), 'r');
 | 
				
			||||||
 | 
					    dialog::addItem(XLAT("rainbow landscape"), 'l');
 | 
				
			||||||
 | 
					    dialog::addItem(XLAT("dark rainbow landscape"), 'd');
 | 
				
			||||||
 | 
					    dialog::addItem(XLAT("football"), 'F');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    dialog::addItem(XLAT("nice coloring"), 'T');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    dialog::addSelItem(XLAT("emerald pattern"), "emerald", 'e');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    dialog::addSelItem(XLAT("four elements"), "palace", 'b');
 | 
				
			||||||
 | 
					    dialog::addSelItem(XLAT("eight domains"), "palace", 'a');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    dialog::addSelItem(XLAT("zebra pattern"), "zebra", 'z');
 | 
				
			||||||
 | 
					    dialog::addSelItem(XLAT("four triangles"), "zebra", 't');
 | 
				
			||||||
 | 
					    dialog::addSelItem(XLAT("three stripes"), "zebra", 'x');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    dialog::addSelItem(XLAT("random black-and-white"), "current", 'w');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    dialog::addSelItem(XLAT("field pattern C"), "field", 'C');
 | 
				
			||||||
 | 
					    dialog::addSelItem(XLAT("field pattern D"), "field", 'D');
 | 
				
			||||||
 | 
					    dialog::addSelItem(XLAT("field pattern N"), "field", 'N');
 | 
				
			||||||
 | 
					    dialog::addSelItem(XLAT("field pattern S"), "field", 'S');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    dialog::display();
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    keyhandler = [] (int sym, int uni) {
 | 
				
			||||||
 | 
					      dialog::handleNavigation(sym, uni);
 | 
				
			||||||
 | 
					      if((uni >= 'a' && uni <= 'z') || (uni >= 'A' && uni <= 'Z')) {
 | 
				
			||||||
 | 
					        whichCanvas = uni;
 | 
				
			||||||
 | 
					        subcanvas = rand();
 | 
				
			||||||
 | 
					        firstland = specialland = laCanvas; 
 | 
				
			||||||
 | 
					        randomPatternsMode = false;
 | 
				
			||||||
 | 
					        restartGame();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      else if(doexiton(sym, uni)) popScreen();
 | 
				
			||||||
 | 
					      };    
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  void showPattern() {
 | 
				
			||||||
 | 
					    cmode = sm::SIDE | sm::MAYDARK;
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					    dynamicval<int> dc(displaycodes, displaycodes ? displaycodes : 2);
 | 
				
			||||||
 | 
					    gamescreen(0);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    dialog::init();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(a46) {
 | 
				
			||||||
 | 
					      dialog::addBoolItem(XLAT("two colors"), (whichPattern == 'f'), 'f');
 | 
				
			||||||
 | 
					      dialog::addBoolItem(XLAT("two colors rotated"), (whichPattern == 'z'), 'z');
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    else if(a4) {
 | 
				
			||||||
 | 
					      dialog::addBoolItem(XLAT("Zebra Pattern"), (whichPattern == 'z'), 'z');
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    else if(a38) {
 | 
				
			||||||
 | 
					      dialog::addBoolItem(XLAT("Zebra Pattern"), (whichPattern == 'z'), 'z');
 | 
				
			||||||
 | 
					      dialog::addBoolItem(XLAT("broken Emerald Pattern"), (whichPattern == 'f'), 'f');
 | 
				
			||||||
 | 
					      dialog::addBoolItem(XLAT("rotated pattern"), (whichPattern == 'p'), 'p');
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    else if(euclid) {
 | 
				
			||||||
 | 
					      dialog::addBoolItem(XLAT("three colors"), (whichPattern == 'f'), 'f');
 | 
				
			||||||
 | 
					      dialog::addBoolItem(XLAT("Palace Pattern"), (whichPattern == 'p'), 'p');
 | 
				
			||||||
 | 
					      dialog::addBoolItem(XLAT("three colors rotated"), (whichPattern == 'z'), 'z');
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    else if(sphere) {
 | 
				
			||||||
 | 
					      dialog::addBoolItem(XLAT("siblings"), (whichPattern == 'p'), 'p');
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    else {
 | 
				
			||||||
 | 
					      if(!stdhyperbolic) 
 | 
				
			||||||
 | 
					        dialog::addInfo("patterns do not work correctly in this geometry!");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      dialog::addBoolItem(XLAT("Emerald Pattern"), (whichPattern == 'f'), 'f');
 | 
				
			||||||
 | 
					      dialog::addBoolItem(XLAT("Palace Pattern"), (whichPattern == 'p'), 'p');
 | 
				
			||||||
 | 
					      dialog::addBoolItem(XLAT("Zebra Pattern"), (whichPattern == 'z'), 'z');
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    if(euclid)
 | 
				
			||||||
 | 
					      dialog::addBoolItem(XLAT("torus pattern"), (whichPattern == 'F'), 'F');
 | 
				
			||||||
 | 
					    else if(sphere)
 | 
				
			||||||
 | 
					      dialog::addBoolItem(XLAT("single cells"), (whichPattern == 'F'), 'F');
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      dialog::addBoolItem(XLAT("field pattern"), (whichPattern == 'F'), 'F');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(whichPattern == 'f' && stdhyperbolic) symRotation = true;
 | 
				
			||||||
 | 
					    if(whichPattern == 'F') ;
 | 
				
			||||||
 | 
					    else if(!euclid) {
 | 
				
			||||||
 | 
					      dialog::addBoolItem(XLAT("rotational symmetry"), (symRotation), '0');
 | 
				
			||||||
 | 
					      dialog::addBoolItem(XLAT("symmetry 0-1"), (sym01), '1');
 | 
				
			||||||
 | 
					      dialog::addBoolItem(XLAT("symmetry 0-2"), (sym02), '2');
 | 
				
			||||||
 | 
					      dialog::addBoolItem(XLAT("symmetry 0-3"), (sym03), '3');
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      dialog::addBoolItem(XLAT("edit all three colors"), (symRotation), '0');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    dialog::addBoolItem(XLAT("display pattern codes (full)"), (displaycodes == 1), 'd');
 | 
				
			||||||
 | 
					    dialog::addBoolItem(XLAT("display pattern codes (simplified)"), (displaycodes == 2), 's');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    dialog::addBoolItem(XLAT("display only hexagons"), (whichShape == '6'), '6');
 | 
				
			||||||
 | 
					    dialog::addBoolItem(XLAT("display only heptagons"), (whichShape == '7'), '7');
 | 
				
			||||||
 | 
					    dialog::addBoolItem(XLAT("display the triheptagonal grid"), (whichShape == '8'), '8');
 | 
				
			||||||
 | 
					    if(cheater || autocheat) dialog::addItem(XLAT("line patterns"), 'l');
 | 
				
			||||||
 | 
					    else dialog::addInfo("enable the cheat mode to use line patterns");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(!needConfirmation()) dialog::addItem(XLAT("predesigned patterns"), 'r');
 | 
				
			||||||
 | 
					    else dialog::addInfo("start a new game to use predesigned patterns");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    dialog::display();
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    keyhandler = [] (int sym, int uni) {
 | 
				
			||||||
 | 
					      dialog::handleNavigation(sym, uni);
 | 
				
			||||||
 | 
					      if(uni == 'f' || uni == 'p' || uni == 'z' || uni == 'H' || uni == 'F') {
 | 
				
			||||||
 | 
					        if(whichPattern == uni) whichPattern = 0;
 | 
				
			||||||
 | 
					        else whichPattern = uni;
 | 
				
			||||||
 | 
					        mapeditor::modelcell.clear();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					      else if(uni == '0') symRotation = !symRotation;
 | 
				
			||||||
 | 
					      else if(uni == '1') sym01 = !sym01;
 | 
				
			||||||
 | 
					      else if(uni == '2') sym02 = !sym02;
 | 
				
			||||||
 | 
					      else if(uni == '3') sym03 = !sym03;
 | 
				
			||||||
 | 
					      else if(uni == '6' || uni == '7' || uni == '8') {
 | 
				
			||||||
 | 
					        if(whichShape == uni) whichShape = 0;
 | 
				
			||||||
 | 
					        else whichShape = uni;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      else if(uni == '3') sym03 = !sym03;
 | 
				
			||||||
 | 
					      else if(uni == 'd') displaycodes = displaycodes == 1 ? 0 : 1;
 | 
				
			||||||
 | 
					      else if(uni == 's') displaycodes = displaycodes == 2 ? 0 : 2;
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					      else if(uni == 'l' && (cheater || autocheat))
 | 
				
			||||||
 | 
					        pushScreen(linepatterns::showMenu);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      else if(uni == 'r' && !needConfirmation()) pushScreen(showPrePattern);
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					      else if(doexiton(sym, uni)) popScreen();
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace linepatterns {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  int lessalpha(int col, int m) {
 | 
				
			||||||
 | 
					    part(col, 0) /= m;
 | 
				
			||||||
 | 
					    return col;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  int lessalphaif(int col, bool b) {
 | 
				
			||||||
 | 
					    return b?lessalpha(col, 4):col;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					  int lessalphaif(int col, bool b1, bool b2) {
 | 
				
			||||||
 | 
					    if(b1) col = lessalpha(col, 2);
 | 
				
			||||||
 | 
					    if(b2) col = lessalpha(col, 2);
 | 
				
			||||||
 | 
					    return col;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					  struct {
 | 
				
			||||||
 | 
					    int id;
 | 
				
			||||||
 | 
					    const char *lpname;
 | 
				
			||||||
 | 
					    unsigned int color;
 | 
				
			||||||
 | 
					    } patterns[] = {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    {patTriNet, "triangle grid: not rings", 0xFFFFFF00},
 | 
				
			||||||
 | 
					    {patTriRings, "triangle grid: rings", 0xFFFFFF00},
 | 
				
			||||||
 | 
					    {patHepta, "heptagonal grid", 0x0000C000},
 | 
				
			||||||
 | 
					    {patRhomb, "rhombic tesselation", 0x0000C000},
 | 
				
			||||||
 | 
					    {patTrihepta, "triheptagonal tesselation", 0x0000C000},
 | 
				
			||||||
 | 
					    {patNormal, "normal tesselation", 0x0000C000},
 | 
				
			||||||
 | 
					    {patBigTriangles, "big triangular grid", 0x00606000},
 | 
				
			||||||
 | 
					    {patBigRings, "big triangles: rings", 0x0000C000},
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    {patTree, "underlying tree", 0x00d0d000},
 | 
				
			||||||
 | 
					    {patAltTree, "circle/horocycle tree", 0xd000d000},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    {patZebraTriangles, "zebra triangles", 0x40FF4000},
 | 
				
			||||||
 | 
					    {patZebraLines, "zebra lines", 0xFF000000},
 | 
				
			||||||
 | 
					    {patVine, "vineyard pattern", 0x8438A400},
 | 
				
			||||||
 | 
					    {patPalacelike, "firewall lines", 0xFF400000},
 | 
				
			||||||
 | 
					    {patPalace, "firewall lines: Palace", 0xFFD50000},
 | 
				
			||||||
 | 
					    {patPower, "firewall lines: Power", 0xFFFF0000},
 | 
				
			||||||
 | 
					    {0, NULL, 0}
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void clearAll() {
 | 
				
			||||||
 | 
					    for(int k=0; patterns[k].lpname; k++) patterns[k].color &= ~255;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  bool any() {
 | 
				
			||||||
 | 
					    for(int k=0; patterns[k].lpname; k++) if(patterns[k].color & 255) return true;
 | 
				
			||||||
 | 
					    return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void setColor(ePattern id, int col) {
 | 
				
			||||||
 | 
					    for(int k=0; patterns[k].lpname; k++)
 | 
				
			||||||
 | 
					      if(patterns[k].id == id) patterns[k].color = col;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  void switchAlpha(ePattern id, int col) {
 | 
				
			||||||
 | 
					    for(int k=0; patterns[k].lpname; k++)
 | 
				
			||||||
 | 
					      if(patterns[k].id == id) patterns[k].color ^= col;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void drawPattern(int id, int col, cell *c, const transmatrix& V) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    switch(id) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      case patZebraTriangles:
 | 
				
			||||||
 | 
					        if(zebra40(c) / 4 == 10) {
 | 
				
			||||||
 | 
					          bool all = true;
 | 
				
			||||||
 | 
					          hyperpoint tri[3];
 | 
				
			||||||
 | 
					          for(int i=0; i<3; i++) {
 | 
				
			||||||
 | 
					            cell *c2 = createMov(c, i*2);
 | 
				
			||||||
 | 
					            if(!gmatrix.count(c2)) all = false;
 | 
				
			||||||
 | 
					            else tri[i] = tC0(gmatrix[c2]);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          
 | 
				
			||||||
 | 
					          if(all) for(int i=0; i<3; i++)
 | 
				
			||||||
 | 
					            queueline(tri[i], tri[(i+1)%3], col, 3);
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					      case patZebraLines:
 | 
				
			||||||
 | 
					        if(!pseudohept(c)) for(int i=0; i<c->type; i+=2) {
 | 
				
			||||||
 | 
					          cell *c2 = createMov(c, i);
 | 
				
			||||||
 | 
					          int fv1 = zebra40(c);
 | 
				
			||||||
 | 
					          if(fv1/4 == 4 || fv1/4 == 6 || fv1/4 == 5 || fv1/4 == 10) fv1 ^= 2;
 | 
				
			||||||
 | 
					          int fv2 = zebra40(c2);
 | 
				
			||||||
 | 
					          if(fv2/4 == 4 || fv2/4 == 6 || fv2/4 == 5 || fv2/4 == 10) fv2 ^= 2;
 | 
				
			||||||
 | 
					          if((fv1&1) == (fv2&1)) continue;
 | 
				
			||||||
 | 
					          
 | 
				
			||||||
 | 
					          double x = sphere?.3651:euclid?.2611:.2849;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          queueline(V * ddspin(c,i,-S14) * xpush0(x), 
 | 
				
			||||||
 | 
					            V * ddspin(c,i,+S14) * xpush0(x), 
 | 
				
			||||||
 | 
					            col, 1);
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					      case patNormal: {
 | 
				
			||||||
 | 
					        double x = sphere?.401:euclid?.3 : .328;
 | 
				
			||||||
 | 
					        if(euclid || !pseudohept(c)) for(int t=0; t<c->type; t++) 
 | 
				
			||||||
 | 
					          if(euclid ? c->mov[t]<c : (((t^1)&1) || c->mov[t] < c))
 | 
				
			||||||
 | 
					            queueline(V * ddspin(c,t,-S7) * xpush0(x), 
 | 
				
			||||||
 | 
					                V * ddspin(c,t,+S7) * xpush0(x), 
 | 
				
			||||||
 | 
					                col, 1);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					      case patTrihepta:
 | 
				
			||||||
 | 
					        if(!pseudohept(c)) for(int i=0; i<6; i++) {
 | 
				
			||||||
 | 
					          cell *c2 = c->mov[i];
 | 
				
			||||||
 | 
					          if(!c2 || !pseudohept(c2)) continue;
 | 
				
			||||||
 | 
					          double x = sphere?.3651:euclid?.2611:.2849;
 | 
				
			||||||
 | 
					          queueline(V * ddspin(c,i,-S14) * xpush0(x), 
 | 
				
			||||||
 | 
					            V * ddspin(c,i,+S14) * xpush0(x), 
 | 
				
			||||||
 | 
					            col, 1);
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					      case patTriNet:
 | 
				
			||||||
 | 
					        forCellEx(c2, c) if(c2 > c) if(gmatrix.count(c2)) if(celldist(c) != celldist(c2)) {
 | 
				
			||||||
 | 
					          queueline(tC0(V), gmatrix[c2]*C0, 
 | 
				
			||||||
 | 
					            darkena(backcolor ^ 0xFFFFFF, 0, col),
 | 
				
			||||||
 | 
					            2);
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      case patTriRings:
 | 
				
			||||||
 | 
					        forCellEx(c2, c) if(c2 > c) if(gmatrix.count(c2) && celldist(c) == celldist(c2)) 
 | 
				
			||||||
 | 
					          queueline(tC0(V), gmatrix[c2]*C0, 
 | 
				
			||||||
 | 
					            darkena(backcolor ^ 0xFFFFFF, 0, col),
 | 
				
			||||||
 | 
					            2);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      case patHepta:
 | 
				
			||||||
 | 
					        forCellEx(c2, c) if(c2 > c) if(gmatrix.count(c2) && pseudohept(c) == pseudohept(c2)) 
 | 
				
			||||||
 | 
					          queueline(tC0(V), gmatrix[c2]*C0, 
 | 
				
			||||||
 | 
					            darkena(backcolor ^ 0xFFFFFF, 0, col),
 | 
				
			||||||
 | 
					            2);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      case patRhomb:
 | 
				
			||||||
 | 
					        forCellEx(c2, c) if(c2 > c) if(gmatrix.count(c2) && pseudohept(c) != pseudohept(c2)) 
 | 
				
			||||||
 | 
					          queueline(tC0(V), gmatrix[c2]*C0, 
 | 
				
			||||||
 | 
					            darkena(backcolor ^ 0xFFFFFF, 0, col),
 | 
				
			||||||
 | 
					            2);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					      case patPalace: {
 | 
				
			||||||
 | 
					        int a = polarb50(c);
 | 
				
			||||||
 | 
					        if(pseudohept(c)) for(int i=0; i<7; i++) {
 | 
				
			||||||
 | 
					            cell *c1 = createMov(c, (i+3) % 7);
 | 
				
			||||||
 | 
					            cell *c2 = createMov(c, (i+4) % 7);
 | 
				
			||||||
 | 
					            if(polarb50(c1) != a && polarb50(c2) != a)
 | 
				
			||||||
 | 
					                queueline(V * ddspin(c,i,84*5/14) * xpush0(tessf/2),
 | 
				
			||||||
 | 
					                          V * ddspin(c,i,84*9/14) * xpush0(tessf/2),
 | 
				
			||||||
 | 
					                                    col, 1);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					      case patPalacelike:
 | 
				
			||||||
 | 
					        if(pseudohept(c)) for(int i=0; i<7; i++) 
 | 
				
			||||||
 | 
					          queueline(V * ddspin(c,i,84*5/14) * xpush0(tessf/2),
 | 
				
			||||||
 | 
					                    V * ddspin(c,i,84*9/14) * xpush0(tessf/2),
 | 
				
			||||||
 | 
					                              col, 1);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					      case patBigTriangles: {
 | 
				
			||||||
 | 
					        if(pseudohept(c) && !euclid) for(int i=0; i<S7; i++) 
 | 
				
			||||||
 | 
					          if(c->master->move[i] < c->master) {
 | 
				
			||||||
 | 
					            queueline(tC0(V), V*xspinpush0((nontruncated?M_PI:0) -2*M_PI*i/S7, tessf), col, 2);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					      case patBigRings: {
 | 
				
			||||||
 | 
					        if(pseudohept(c) && !euclid) for(int i=0; i<S7; i++) 
 | 
				
			||||||
 | 
					          if(c->master->move[i] && c->master->move[i] < c->master && c->master->move[i]->dm4 == c->master->dm4)
 | 
				
			||||||
 | 
					            queueline(tC0(V), V*xspinpush0((nontruncated?M_PI:0) -2*M_PI*i/S7, tessf), col, 2);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					      case patTree:
 | 
				
			||||||
 | 
					        if(ctof(c) && !euclid) 
 | 
				
			||||||
 | 
					          queueline(tC0(V), V*ddi0(nontruncated?S42:0, tessf), col, 2);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					      case patAltTree:
 | 
				
			||||||
 | 
					        if(ctof(c) && !euclid && c->master->alt) {
 | 
				
			||||||
 | 
					          for(int i=0; i<S7; i++)
 | 
				
			||||||
 | 
					            if(c->master->move[i] && c->master->move[i]->alt == c->master->alt->move[0])
 | 
				
			||||||
 | 
					              queueline(tC0(V), V*xspinpush0((nontruncated?M_PI:0) -2*M_PI*i/S7, tessf), col, 2);
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					      case patVine: {
 | 
				
			||||||
 | 
					        int p = emeraldval(c);
 | 
				
			||||||
 | 
					        double hdist = hdist0(heptmove[0] * heptmove[2] * C0);
 | 
				
			||||||
 | 
					        if(pseudohept(c) && (p/4 == 10 || p/4 == 8))
 | 
				
			||||||
 | 
					        for(int i=0; i<S7; i++) if(c->mov[i] && emeraldval(c->mov[i]) == p-4) {
 | 
				
			||||||
 | 
					          queueline(tC0(V), V*tC0(heptmove[i]), col, 2);
 | 
				
			||||||
 | 
					          queueline(tC0(V), V*tC0(spin(-i * ALPHA) * xpush(-hdist/2)), col, 2);
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					      case patPower: {
 | 
				
			||||||
 | 
					        int a = emeraldval(c);
 | 
				
			||||||
 | 
					        if(pseudohept(c) && a/4 == 8) for(int i=0; i<7; i++) {
 | 
				
			||||||
 | 
					            heptagon *h1 = c->master->move[(i+1)%7];
 | 
				
			||||||
 | 
					            heptagon *h2 = c->master->move[(i+6)%7];
 | 
				
			||||||
 | 
					            if(!h1 || !h2) continue;
 | 
				
			||||||
 | 
					            if(emeraldval(h1->c7)/4 == 8 && emeraldval(h2->c7)/4 == 8)
 | 
				
			||||||
 | 
					                queueline(V * ddspin(c,i,84*5/14) * xpush0(tessf/2),
 | 
				
			||||||
 | 
					                          V * ddspin(c,i,84*9/14) * xpush0(tessf/2),
 | 
				
			||||||
 | 
					                                    col, 1);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void drawAll() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(any()) for(map<cell*, transmatrix>::iterator it = gmatrix.begin(); it != gmatrix.end(); it++) {
 | 
				
			||||||
 | 
					      cell *c = it->first;
 | 
				
			||||||
 | 
					      transmatrix& V = it->second;
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					      for(int k=0; patterns[k].lpname; k++) {
 | 
				
			||||||
 | 
					        int col = patterns[k].color;
 | 
				
			||||||
 | 
					        if(!(col & 255)) continue;
 | 
				
			||||||
 | 
					        int id = patterns[k].id;
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        drawPattern(id, col, c, V);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  int numpat = 0;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  void showMenu() {
 | 
				
			||||||
 | 
					    cmode = sm::SIDE | sm::MAYDARK;
 | 
				
			||||||
 | 
					    gamescreen(0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    dialog::init(XLAT("line patterns"));
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    for(numpat=0; patterns[numpat].lpname; numpat++)
 | 
				
			||||||
 | 
					      dialog::addColorItem(XLAT(patterns[numpat].lpname), patterns[numpat].color, 'a'+numpat);
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					    dialog::addBreak(50);
 | 
				
			||||||
 | 
					    dialog::addItem(XLAT("exit menu"), 'v');
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    dialog::addBreak(50);
 | 
				
			||||||
 | 
					    dialog::addInfo("change the alpha parameter to show the lines");
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					    dialog::display();
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    keyhandler = [] (int sym, int uni) {
 | 
				
			||||||
 | 
					      dialog::handleNavigation(sym, uni);
 | 
				
			||||||
 | 
					      if(uni >= 'a' && uni < 'a' + numpat) {
 | 
				
			||||||
 | 
					        dialog::openColorDialog(patterns[uni - 'a'].color, NULL);
 | 
				
			||||||
 | 
					        dialog::dialogflags |= sm::MAYDARK | sm::SIDE;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      else if(doexiton(sym,uni)) popScreen();
 | 
				
			||||||
 | 
					      }; 
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2315,7 +2315,7 @@ void queuecurve(int linecol, int fillcol, int prio) {
 | 
				
			|||||||
  curvestart = size(curvedata);
 | 
					  curvestart = size(curvedata);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void queueline(const hyperpoint& H1, const hyperpoint& H2, int col, int prf = 0, int prio = PPR_LINE) {
 | 
					void queueline(const hyperpoint& H1, const hyperpoint& H2, int col, int prf, int prio) {
 | 
				
			||||||
  polytodraw& ptd = nextptd();
 | 
					  polytodraw& ptd = nextptd();
 | 
				
			||||||
  ptd.kind = pkLine;
 | 
					  ptd.kind = pkLine;
 | 
				
			||||||
  ptd.u.line.H1 = H1;
 | 
					  ptd.u.line.H1 = H1;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1380,7 +1380,7 @@ void rvvideo(const char *fname) {
 | 
				
			|||||||
    pngformat = 2;
 | 
					    pngformat = 2;
 | 
				
			||||||
    sightrange = 12;
 | 
					    sightrange = 12;
 | 
				
			||||||
    overgenerate = true;
 | 
					    overgenerate = true;
 | 
				
			||||||
    dronemode = true; vid.camera_angle = -45; rog3 = true; mapeditor::whichShape = '8';
 | 
					    dronemode = true; vid.camera_angle = -45; rog3 = true; patterns::whichShape = '8';
 | 
				
			||||||
    vid.aurastr = 512;
 | 
					    vid.aurastr = 512;
 | 
				
			||||||
    long long reached = 763ll;
 | 
					    long long reached = 763ll;
 | 
				
			||||||
    while(reached < (1ll<<60)) {
 | 
					    while(reached < (1ll<<60)) {
 | 
				
			||||||
@@ -1666,7 +1666,7 @@ int readArgs() {
 | 
				
			|||||||
    shift(); collatz::cshift = argf();
 | 
					    shift(); collatz::cshift = argf();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  else if(argis("-rvwarp")) {
 | 
					  else if(argis("-rvwarp")) {
 | 
				
			||||||
    mapeditor::whichShape = '8';
 | 
					    patterns::whichShape = '8';
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  else if(argis("-lq")) {
 | 
					  else if(argis("-lq")) {
 | 
				
			||||||
    shift(); linequality = argf();
 | 
					    shift(); linequality = argf();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -241,8 +241,7 @@ void initgame() {
 | 
				
			|||||||
  if(!safety) {
 | 
					  if(!safety) {
 | 
				
			||||||
    usedSafety = false;
 | 
					    usedSafety = false;
 | 
				
			||||||
    timerstart = time(NULL); turncount = 0; rosewave = 0; rosephase = 0;
 | 
					    timerstart = time(NULL); turncount = 0; rosewave = 0; rosephase = 0;
 | 
				
			||||||
    if(!quotient) mapeditor::whichPattern = 0;
 | 
					    patterns::whichShape = 0;
 | 
				
			||||||
    mapeditor::whichShape = 0;
 | 
					 | 
				
			||||||
    noiseuntil = 0;
 | 
					    noiseuntil = 0;
 | 
				
			||||||
    sagephase = 0; hardcoreAt = 0;
 | 
					    sagephase = 0; hardcoreAt = 0;
 | 
				
			||||||
    timerstopped = false;
 | 
					    timerstopped = false;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -118,7 +118,7 @@ void mapTextureTriangle(textureinfo &mi, array<hyperpoint, 3> v) {
 | 
				
			|||||||
map<int, textureinfo> texture_map;
 | 
					map<int, textureinfo> texture_map;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool applyTextureMap(cell *c, const transmatrix &V, int col) {
 | 
					bool applyTextureMap(cell *c, const transmatrix &V, int col) {
 | 
				
			||||||
  using namespace mapeditor;
 | 
					  using namespace patterns;
 | 
				
			||||||
  int t = subpattern(c, whichPattern);
 | 
					  int t = subpattern(c, whichPattern);
 | 
				
			||||||
  try {
 | 
					  try {
 | 
				
			||||||
    auto& mi = texture_map.at(t);
 | 
					    auto& mi = texture_map.at(t);
 | 
				
			||||||
@@ -154,7 +154,7 @@ bool applyTextureMap(cell *c, const transmatrix &V, int col) {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
void perform_mapping() {
 | 
					void perform_mapping() {
 | 
				
			||||||
  using namespace mapeditor;
 | 
					  using namespace patterns;
 | 
				
			||||||
  if(!texture_read) readtexture();
 | 
					  if(!texture_read) readtexture();
 | 
				
			||||||
  texture_map.clear();
 | 
					  texture_map.clear();
 | 
				
			||||||
  glfont_t& f(textures); int tabid = 1;
 | 
					  glfont_t& f(textures); int tabid = 1;
 | 
				
			||||||
@@ -251,7 +251,7 @@ void showTextureMenu() {
 | 
				
			|||||||
  keyhandler = [] (int sym, int uni) {
 | 
					  keyhandler = [] (int sym, int uni) {
 | 
				
			||||||
    dialog::handleNavigation(sym, uni);
 | 
					    dialog::handleNavigation(sym, uni);
 | 
				
			||||||
    if(uni == 'r')
 | 
					    if(uni == 'r')
 | 
				
			||||||
      pushScreen(mapeditor::showPattern);
 | 
					      pushScreen(patterns::showPattern);
 | 
				
			||||||
    else if(uni == 'f') {
 | 
					    else if(uni == 'f') {
 | 
				
			||||||
      mapeditor::cfileptr = &texturename;
 | 
					      mapeditor::cfileptr = &texturename;
 | 
				
			||||||
      mapeditor::filecaption = XLAT("texture to load:");
 | 
					      mapeditor::filecaption = XLAT("texture to load:");
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										14
									
								
								tour.cpp
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								tour.cpp
									
									
									
									
									
								
							@@ -22,14 +22,14 @@ void setCanvas(presmode mode, char canv) {
 | 
				
			|||||||
  static char wc;
 | 
					  static char wc;
 | 
				
			||||||
  static eLand ld;
 | 
					  static eLand ld;
 | 
				
			||||||
  if(mode == pmStart) {
 | 
					  if(mode == pmStart) {
 | 
				
			||||||
    wc = mapeditor::whichCanvas;
 | 
					    wc = patterns::whichCanvas;
 | 
				
			||||||
    mapeditor::whichCanvas = canv;
 | 
					    patterns::whichCanvas = canv;
 | 
				
			||||||
    ld = firstland;
 | 
					    ld = firstland;
 | 
				
			||||||
    firstland = laCanvas;
 | 
					    firstland = laCanvas;
 | 
				
			||||||
    restartGame(0, true); 
 | 
					    restartGame(0, true); 
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  if(mode == pmStop) {
 | 
					  if(mode == pmStop) {
 | 
				
			||||||
    mapeditor::whichCanvas = wc;
 | 
					    patterns::whichCanvas = wc;
 | 
				
			||||||
    firstland = ld;
 | 
					    firstland = ld;
 | 
				
			||||||
    popGame();
 | 
					    popGame();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -595,11 +595,11 @@ slide default_slides[] = {
 | 
				
			|||||||
    [] (presmode mode) {
 | 
					    [] (presmode mode) {
 | 
				
			||||||
      setCanvas(mode, 't');
 | 
					      setCanvas(mode, 't');
 | 
				
			||||||
      if(mode == 1) 
 | 
					      if(mode == 1) 
 | 
				
			||||||
        mapeditor::displaycodes = 2,
 | 
					        patterns::displaycodes = 2,
 | 
				
			||||||
        mapeditor::whichPattern = 'z';
 | 
					        patterns::whichPattern = 'z';
 | 
				
			||||||
      if(mode == 3) 
 | 
					      if(mode == 3) 
 | 
				
			||||||
        mapeditor::displaycodes = 0,
 | 
					        patterns::displaycodes = 0,
 | 
				
			||||||
        mapeditor::whichPattern = 0;
 | 
					        patterns::whichPattern = 0;
 | 
				
			||||||
      SHOWLAND ( l == laCanvas );
 | 
					      SHOWLAND ( l == laCanvas );
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user