mirror of
				https://github.com/zenorogue/hyperrogue.git
				synced 2025-10-31 14:02:59 +00:00 
			
		
		
		
	big change: more configuration for the torus (and also Klein bottle)
This commit is contained in:
		
							
								
								
									
										95
									
								
								bigstuff.cpp
									
									
									
									
									
								
							
							
						
						
									
										95
									
								
								bigstuff.cpp
									
									
									
									
									
								
							| @@ -732,9 +732,18 @@ void setLandSphere(cell *c) { | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
| eLand euland[65536]; | eLand euland[max_vec]; | ||||||
|  |  | ||||||
| eLand switchable(eLand nearland, eLand farland, eucoord c) { | eLand& get_euland(int c) { | ||||||
|  |   return euland[c & (max_vec-1)]; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | void clear_euland(eLand first) { | ||||||
|  |   for(int i=0; i<max_vec; i++) euland[i] = laNone; | ||||||
|  |   euland[0] = euland[1] = euland[max_vec-1] = first; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | eLand switchable(eLand nearland, eLand farland, int c) { | ||||||
|   if(specialland == laCrossroads4) { |   if(specialland == laCrossroads4) { | ||||||
|     if(hrand(15) == 0) |     if(hrand(15) == 0) | ||||||
|       return getNewLand(nearland); |       return getNewLand(nearland); | ||||||
| @@ -755,37 +764,36 @@ eLand switchable(eLand nearland, eLand farland, eucoord c) { | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
| eLand getEuclidLand(eucoord c) { | eLand getEuclidLand(int c) { | ||||||
|   if(euland[c]) return euland[c]; |   auto& la = get_euland(c); | ||||||
|   if(c == 0 || c == eucoord(-1) || c == 1) |   if(la) return la; | ||||||
|     return euland[c] = specialland; |   if(get_euland(c-2) && !get_euland(c-1)) getEuclidLand(c-1); | ||||||
|   if(euland[eucoord(c-2)] && ! euland[eucoord(c-1)]) getEuclidLand(c-1); |   if(get_euland(c-1)) return  | ||||||
|   if(euland[eucoord(c+2)] && ! euland[eucoord(c+1)]) getEuclidLand(c+1); |     la = switchable(get_euland(c-1), get_euland(c-2), c); | ||||||
|   if(euland[eucoord(c-1)]) return  |   if(get_euland(c+2) && !get_euland(c+1)) getEuclidLand(c+1); | ||||||
|     euland[c] = switchable(euland[c-1], euland[eucoord(c-2)], c); |   if(get_euland(c+1)) return  | ||||||
|   if(euland[eucoord(c+1)]) return  |     la = switchable(get_euland(c+1), get_euland(c+2), c); | ||||||
|     euland[c] = switchable(euland[c+1], euland[eucoord(c+2)], c); |   return la = laCrossroads; | ||||||
|   return euland[c] = laCrossroads; |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
| void setLandEuclid(cell *c) { | void setLandEuclid(cell *c) { | ||||||
|   setland(c, specialland); |   setland(c, specialland); | ||||||
|   if(specialland == laCrossroads) { |   if(specialland == laCrossroads) { | ||||||
|     eucoord x, y; |     int x, y; | ||||||
|     decodeMaster(c->master, x, y); |     tie(x,y) = cell_to_pair(c); | ||||||
|     setland(c, getEuclidLand(y+2*x)); |     setland(c, getEuclidLand(y+2*x)); | ||||||
|     } |     } | ||||||
|   if(specialland == laTerracotta) { |   if(specialland == laTerracotta) { | ||||||
|     eucoord x, y; |     int x, y; | ||||||
|     decodeMaster(c->master, x, y); |     tie(x,y) = cell_to_pair(c); | ||||||
|     if((y+2*x) % 16 == 1) { |     if(((y+2*x) & 15) == 1) { | ||||||
|       setland(c, laMercuryRiver); |       setland(c, laMercuryRiver); | ||||||
|       c->wall = waMercury; |       c->wall = waMercury; | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   if(specialland == laCrossroads4) { |   if(specialland == laCrossroads4) { | ||||||
|     eucoord x, y; |     int x, y; | ||||||
|     decodeMaster(c->master, x, y); |     tie(x,y) = cell_to_pair(c); | ||||||
|     c->land = getEuclidLand(y); |     c->land = getEuclidLand(y); | ||||||
|     } |     } | ||||||
|   if(specialland == laWhirlpool) { |   if(specialland == laWhirlpool) { | ||||||
| @@ -794,30 +802,29 @@ void setLandEuclid(cell *c) { | |||||||
|     } |     } | ||||||
|   if(specialland == laPrincessQuest) setland(c, laPalace); |   if(specialland == laPrincessQuest) setland(c, laPalace); | ||||||
|   if(specialland == laOcean) { |   if(specialland == laOcean) { | ||||||
|     eucoord x, y; |     int x, y; | ||||||
|     decodeMaster(c->master, x, y); |     tie(x,y) = cell_to_pair(c); | ||||||
|     int y0 = y; if(y>50000) y0 -= 65536; y0 += 10; |     y += 10; | ||||||
|     if(y0 == 0)  |     if(y == 0)  | ||||||
|       { setland(c, laBarrier); if(ishept(c)) c->land = laRlyeh; } |       { setland(c, laBarrier); if(ishept(c)) c->land = laRlyeh; } | ||||||
|     else if(y0<0) setland(c, laRlyeh); |     else if(y<0) setland(c, laRlyeh); | ||||||
|     else c->landparam = y0; |     else c->landparam = y; | ||||||
|     } |     } | ||||||
|   if(specialland == laIvoryTower || specialland == laDungeon) { |   if(specialland == laIvoryTower || specialland == laDungeon) { | ||||||
|     eucoord x, y; |     int x, y; | ||||||
|     decodeMaster(c->master, x, y); |     tie(x,y) = cell_to_pair(c); y -= 5; | ||||||
|     int y0 = y; if(y>50000) y0 -= 65536; y0 = -y0; y0 -= 5; |     if(y == 0)  | ||||||
|     if(y0 == 0)  |  | ||||||
|       {setland(c, laBarrier); if(ishept(c)) setland(c, laAlchemist); } |       {setland(c, laBarrier); if(ishept(c)) setland(c, laAlchemist); } | ||||||
|     else if(y0<0) setland(c, laAlchemist); |     else if(y<0) setland(c, laAlchemist); | ||||||
|     else { |     else { | ||||||
|       c->landparam = y0; |       c->landparam = y; | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   if(specialland == laElementalWall) { |   if(specialland == laElementalWall) { | ||||||
|     eucoord x, y; |     int x, y; | ||||||
|     decodeMaster(c->master, x, y); |     tie(x,y) = cell_to_pair(c); | ||||||
|     int y0 = y; if(y>32768) y0 -= 65536; |     int x0 = x + (y>>1); | ||||||
|     int x0 = x +y/2; |     int y0 = y; | ||||||
|      |      | ||||||
|     int id = 0; |     int id = 0; | ||||||
|     if(y0&16) id += 2; |     if(y0&16) id += 2; | ||||||
| @@ -843,10 +850,10 @@ void setLandEuclid(cell *c) { | |||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   if(specialland == laCrossroads3) { |   if(specialland == laCrossroads3) { | ||||||
|     eucoord x, y; |     int x, y; | ||||||
|     decodeMaster(c->master, x, y); |     tie(x,y) = cell_to_pair(c); | ||||||
|     int y0 = y; if(y>32768) y0 -= 65536; |     int y0 = y;  | ||||||
|     int x0 = x +y/2; |     int x0 = x + y/2; | ||||||
|      |      | ||||||
|     x0 += 24; y0 += 8; |     x0 += 24; y0 += 8; | ||||||
|      |      | ||||||
| @@ -862,11 +869,11 @@ void setLandEuclid(cell *c) { | |||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   if(specialland == laWarpCoast) { |   if(specialland == laWarpCoast) { | ||||||
|     eucoord x, y; |     int x, y; | ||||||
|     decodeMaster(c->master, x, y); |     tie(x,y) = cell_to_pair(c); | ||||||
|      |      | ||||||
|     int zz = a4 ? short(x) : 2*short(x)+short(y) + 10; |     int zz = a4 ? x : 2*x+y + 10; | ||||||
|     zz %= 30; if(zz<0) zz += 30; |     zz = gmod(zz, 30); | ||||||
|     if(zz >= 15) |     if(zz >= 15) | ||||||
|       setland(c, laWarpSea); |       setland(c, laWarpSea); | ||||||
|     else |     else | ||||||
|   | |||||||
							
								
								
									
										357
									
								
								cell.cpp
									
									
									
									
									
								
							
							
						
						
									
										357
									
								
								cell.cpp
									
									
									
									
									
								
							| @@ -192,7 +192,20 @@ heptagon *getDodecahedron(int i) { | |||||||
|  |  | ||||||
| // --- euclidean geometry --- | // --- euclidean geometry --- | ||||||
|  |  | ||||||
| cell*& euclideanAtCreate(eucoord x, eucoord y); | cell*& euclideanAtCreate(int vec); | ||||||
|  |  | ||||||
|  | static const int max_vec = (1<<15); | ||||||
|  |  | ||||||
|  | int pair_to_vec(int x, int y) { | ||||||
|  |   return x + (y << 15); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | pair<int, int> vec_to_pair(int vec) { | ||||||
|  |   int x = vec & ((1<<15)-1); | ||||||
|  |   int y = (vec >> 15); | ||||||
|  |   if(x >= (1<<14)) x -= (1<<15), y++; | ||||||
|  |   return {x, y}; | ||||||
|  |   } | ||||||
|  |  | ||||||
| namespace torusconfig { | namespace torusconfig { | ||||||
|   // the configuration of the torus topology. |   // the configuration of the torus topology. | ||||||
| @@ -208,14 +221,176 @@ namespace torusconfig { | |||||||
|   int def_qty = 127*3, dx = 1, def_dy = -11*2; |   int def_qty = 127*3, dx = 1, def_dy = -11*2; | ||||||
|   int qty = def_qty, dy = def_dy; |   int qty = def_qty, dy = def_dy; | ||||||
|    |    | ||||||
|  |   int sdx = 12, sdy = 12; | ||||||
|  |  | ||||||
|   // new values to change |   // new values to change | ||||||
|   int newqty, newdy; |   int newqty, newdy, newsdx, newsdy; | ||||||
|   int torus_cx, torus_cy; |   int torus_cx, torus_cy; | ||||||
|  |    | ||||||
|  |   enum eTorusMode {  | ||||||
|  |     tmSingleHex,  | ||||||
|  |     tmSingle,  | ||||||
|  |     tmSlantedHex,  | ||||||
|  |     tmStraight,  | ||||||
|  |     tmStraightHex, | ||||||
|  |     tmKlein, | ||||||
|  |     tmKleinHex | ||||||
|  |     }; | ||||||
|  |    | ||||||
|  |   static const flagtype TF_SINGLE = 1; | ||||||
|  |   static const flagtype TF_SIMPLE = 2; | ||||||
|  |   static const flagtype TF_WEIRD  = 4; | ||||||
|  |  | ||||||
|  |   static const flagtype TF_HEX    = 16; | ||||||
|  |   static const flagtype TF_SQUARE = 32; | ||||||
|  |  | ||||||
|  |   static const flagtype TF_KLEIN = 256; | ||||||
|  |    | ||||||
|  |   struct torusmode_info { | ||||||
|  |     string name; | ||||||
|  |     flagtype flags; | ||||||
|  |     }; | ||||||
|  |    | ||||||
|  |   vector<torusmode_info> tmodes = { | ||||||
|  |     {"single row (hex)", TF_SINGLE | TF_HEX}, | ||||||
|  |     {"single row (squares)", TF_SINGLE | TF_SQUARE}, | ||||||
|  |     {"parallelogram (hex)", TF_SIMPLE | TF_HEX}, | ||||||
|  |     {"rectangle (squares)", TF_SIMPLE | TF_SQUARE}, | ||||||
|  |     {"rectangle (hex)", TF_WEIRD | TF_HEX}, | ||||||
|  |     {"Klein bottle (squares)", TF_SIMPLE | TF_KLEIN | TF_SQUARE}, | ||||||
|  |     {"Klein bottle (hex)", TF_WEIRD | TF_KLEIN | TF_HEX}, | ||||||
|  |     };     | ||||||
|  |    | ||||||
|  |   eTorusMode torus_mode, newmode; | ||||||
|  |   flagtype tmflags() { return tmodes[torus_mode].flags; } | ||||||
|  |    | ||||||
|  |   int getqty() { | ||||||
|  |     if(tmflags() & TF_SINGLE) | ||||||
|  |       return qty; | ||||||
|  |     else | ||||||
|  |       return sdx * sdy; | ||||||
|  |     } | ||||||
|  |    | ||||||
|  |   int getvec(int x, int y) { | ||||||
|  |     if(tmflags() & TF_SINGLE) | ||||||
|  |       return x * dx + y * dy; | ||||||
|  |     else if(tmflags() & TF_SIMPLE) | ||||||
|  |       return pair_to_vec(x, y); | ||||||
|  |     else | ||||||
|  |       return pair_to_vec(-y - 2 * x, 3 * y); | ||||||
|  |     } | ||||||
|  |    | ||||||
|  |   int id_to_vec(int id, bool mirrored = false) { | ||||||
|  |     if(tmflags() & TF_SINGLE) | ||||||
|  |       return id; | ||||||
|  |     else { | ||||||
|  |       int dx = id % sdx; | ||||||
|  |       int dy = id / sdx; | ||||||
|  |       if(mirrored)  | ||||||
|  |         dy = -dy, dx += sdx; | ||||||
|  |       if(tmflags() & TF_SIMPLE) | ||||||
|  |         return pair_to_vec(dx, dy); | ||||||
|  |       else | ||||||
|  |         return pair_to_vec(- 2 * dx - (dy & 1), 3 * dy); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |    | ||||||
|  |   pair<int, bool> vec_to_id_mirror(int vec) { | ||||||
|  |     if(tmflags() & TF_SINGLE) { | ||||||
|  |       return {gmod(vec, qty), false}; | ||||||
|  |       } | ||||||
|  |     else { | ||||||
|  |       int x, y; | ||||||
|  |       tie(x,y) = vec_to_pair(vec); | ||||||
|  |       bool mirror = false; | ||||||
|  |       if(tmflags() & TF_KLEIN) { | ||||||
|  |         if(tmflags() & TF_WEIRD) { | ||||||
|  |           x = gmod(x, 4 * sdx); | ||||||
|  |           mirror = x > 0 && x <= 2 * sdx; | ||||||
|  |           } | ||||||
|  |         else { | ||||||
|  |           x = gmod(x, 2 * sdx); | ||||||
|  |           mirror = x >= sdx; | ||||||
|  |           } | ||||||
|  |         if(mirror) y = -y; | ||||||
|  |         } | ||||||
|  |       if(tmflags() & TF_WEIRD) { | ||||||
|  |         y /= 3; x = (x + (y&1)) / -2; | ||||||
|  |         } | ||||||
|  |       x = gmod(x, sdx), y = gmod(y, sdy); | ||||||
|  |       return {y * sdx + x, mirror}; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   int vec_to_id(int vec) { | ||||||
|  |     return vec_to_id_mirror(vec).first; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   void torus_test() { | ||||||
|  |     printf("Testing torus vec_to_pair/pair_to_vec...\n"); | ||||||
|  |     for(int x=-10; x<=10; x++) | ||||||
|  |     for(int y=-10; y<=10; y++) { | ||||||
|  |       auto p = vec_to_pair(pair_to_vec(x, y)); | ||||||
|  |       if(p.first != x || p.second != y) | ||||||
|  |         printf("Failed for (%d,%d) -> [%d] -> (%d,%d)\n", x, y, pair_to_vec(x,y), p.first, p.second); | ||||||
|  |       } | ||||||
|  |     printf("Testing id_to_vec / vec_to_id...\n"); | ||||||
|  |     for(int i=0; i < getqty(); i++)  | ||||||
|  |     for(int m=0; m< (torus_mode == tmKlein ? 2 : 1); m++) | ||||||
|  |       if(vec_to_id_mirror(id_to_vec(i, m)) != pair<int,bool> (i,m)) | ||||||
|  |         printf("Failed for id %d.%d [%d] (%d.%d)\n", i, m, id_to_vec(i,m), vec_to_id(id_to_vec(i,m)), vec_to_id_mirror(id_to_vec(i,m)).second); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   int tester = addHook(hooks_tests, 0, torus_test); | ||||||
|  |    | ||||||
|  |   void activate() { | ||||||
|  |     if(tmflags() & TF_HEX) | ||||||
|  |       ginf[gTorus].vertex = 3, ginf[gTorus].sides = 6; | ||||||
|  |     else | ||||||
|  |       ginf[gTorus].vertex = 4, ginf[gTorus].sides = 4; | ||||||
|  |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
| int decodeId(heptagon* h); | int decodeId(heptagon* h); | ||||||
| heptagon* encodeId(int id); | heptagon* encodeId(int id); | ||||||
|  |  | ||||||
|  | int euclid_getvec(int dx, int dy) { | ||||||
|  |   if(torus) return torusconfig::getvec(dx, dy); | ||||||
|  |   else return pair_to_vec(dx, dy); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | template<class T> void build_euclidean_moves(cell *c, int vec, const T& builder) { | ||||||
|  |   int x, y; | ||||||
|  |   tie(x,y) = vec_to_pair(vec); | ||||||
|  |   c->type = a4 ? (nontruncated || ((x^y^1) & 1) ? 4 : 8) : 6; | ||||||
|  |  | ||||||
|  |   if(c->type == 4) { | ||||||
|  |     int m = nontruncated ? 1 : 2; | ||||||
|  |     builder(euclid_getvec(+1,+0), 0, 2 * m);         | ||||||
|  |     builder(euclid_getvec(+0,+1), 1, 3 * m); | ||||||
|  |     builder(euclid_getvec(-1,+0), 2, 0 * m); | ||||||
|  |     builder(euclid_getvec(+0,-1), 3, 1 * m); | ||||||
|  |     } | ||||||
|  |   else if(c->type == 8) { | ||||||
|  |     builder(euclid_getvec(+1,+0), 0, 2); | ||||||
|  |     builder(euclid_getvec(+1,+1), 1, 5); | ||||||
|  |     builder(euclid_getvec(+0,+1), 2, 3); | ||||||
|  |     builder(euclid_getvec(-1,+1), 3, 7); | ||||||
|  |     builder(euclid_getvec(-1,+0), 4, 0); | ||||||
|  |     builder(euclid_getvec(-1,-1), 5, 1); | ||||||
|  |     builder(euclid_getvec(+0,-1), 6, 1); | ||||||
|  |     builder(euclid_getvec(+1,-1), 7, 3); | ||||||
|  |     } | ||||||
|  |   else /* 6 */ { | ||||||
|  |     builder(euclid_getvec(+1,+0), 0, 3); | ||||||
|  |     builder(euclid_getvec(+0,+1), 1, 4); | ||||||
|  |     builder(euclid_getvec(-1,+1), 2, 5); | ||||||
|  |     builder(euclid_getvec(-1,+0), 3, 0); | ||||||
|  |     builder(euclid_getvec(+0,-1), 4, 1); | ||||||
|  |     builder(euclid_getvec(+1,-1), 5, 2); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
| struct hrmap_torus : hrmap { | struct hrmap_torus : hrmap { | ||||||
|  |  | ||||||
|   vector<cell*> all; |   vector<cell*> all; | ||||||
| @@ -229,25 +404,27 @@ struct hrmap_torus : hrmap { | |||||||
|  |  | ||||||
|   hrmap_torus() { |   hrmap_torus() { | ||||||
|     using namespace torusconfig; |     using namespace torusconfig; | ||||||
|     all.resize(qty); |     int q = getqty(); | ||||||
|     for(int i=0; i<qty; i++) { |     all.resize(q); | ||||||
|       all[i] = newCell(6, NULL); |     for(int i=0; i<q; i++) { | ||||||
|       all[i]->master = encodeId(i); |       all[i] = newCell(8, encodeId(i)); | ||||||
|       } |       } | ||||||
|     dx %= qty; |     for(int i=0; i<q; i++) { | ||||||
|     dy %= qty; |       int iv = id_to_vec(i); | ||||||
|     for(int i=0; i<qty; i++) { |       build_euclidean_moves(all[i], iv, [&] (int delta, int d, int d2) { | ||||||
|       all[i]->mov[0] = all[(i+dx+2*qty)%qty]; |         auto im = vec_to_id_mirror(iv + delta); | ||||||
|       all[i]->mov[1] = all[(i+dy+2*qty)%qty]; |         all[i]->mov[d] = all[im.first]; | ||||||
|       all[i]->mov[2] = all[(i+dy-dx+2*qty)%qty]; |         tsetspin(all[i]->spintable, d, im.second); | ||||||
|       all[i]->mov[3] = all[(i-dx+2*qty)%qty]; |         }); | ||||||
|       all[i]->mov[4] = all[(i-dy+2*qty)%qty]; |       } | ||||||
|       all[i]->mov[5] = all[(i-dy+dx+2*qty)%qty]; |     for(cell *c: all) for(int d=0; d<c->type; d++) { | ||||||
|       for(int j=0; j<6; j++) |       cell *c2 = c->mov[d]; | ||||||
|         tsetspin(all[i]->spintable, j, (j+3) % 6); |       for(int d2=0; d2<c2->type; d2++)  | ||||||
|  |         if(c2->mov[d2] == c) | ||||||
|  |           tsetspin(c->spintable, d, d2 + (8 * c->spin(d))); | ||||||
|       } |       } | ||||||
|     celllister cl(gamestart(), 100, 100000000, NULL); |     celllister cl(gamestart(), 100, 100000000, NULL); | ||||||
|     dists.resize(qty); |     dists.resize(q); | ||||||
|     for(int i=0; i<size(cl.lst); i++) |     for(int i=0; i<size(cl.lst); i++) | ||||||
|       dists[decodeId(cl.lst[i]->master)] = cl.dists[i]; |       dists[decodeId(cl.lst[i]->master)] = cl.dists[i]; | ||||||
|     } |     } | ||||||
| @@ -257,27 +434,20 @@ struct hrmap_torus : hrmap { | |||||||
|     } |     } | ||||||
|   }; |   }; | ||||||
|  |  | ||||||
| int toridMod(int id) { |  | ||||||
|   using namespace torusconfig; |  | ||||||
|   id %= qty; if(id < 0) id += qty; |  | ||||||
|   return id; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
| hrmap_torus *torusmap() { | hrmap_torus *torusmap() { | ||||||
|   return dynamic_cast<hrmap_torus*> (currentmap); |   return dynamic_cast<hrmap_torus*> (currentmap); | ||||||
|   } |   } | ||||||
|  |  | ||||||
| cell *getTorusId(int id) { | /* cell *getTorusId(int id) { | ||||||
|   hrmap_torus *cur = torusmap(); |   hrmap_torus *cur = torusmap(); | ||||||
|   if(!cur) return NULL; |   if(!cur) return NULL; | ||||||
|   return cur->all[toridMod(id)]; |   return cur->all[id]; | ||||||
|   } |   } */ | ||||||
|  |  | ||||||
|  |  | ||||||
| struct hrmap_euclidean : hrmap { | struct hrmap_euclidean : hrmap { | ||||||
|  |  | ||||||
|   cell *gamestart() { |   cell *gamestart() { | ||||||
|     return euclideanAtCreate(0,0); |     return euclideanAtCreate(0); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   struct euclideanSlab { |   struct euclideanSlab { | ||||||
| @@ -299,8 +469,10 @@ struct hrmap_euclidean : hrmap { | |||||||
|       euclidean[y][x] = NULL; |       euclidean[y][x] = NULL; | ||||||
|     } |     } | ||||||
|    |    | ||||||
|   cell*& at(eucoord x, eucoord y) { |   cell*& at(int vec) { | ||||||
|     euclideanSlab*& slab = euclidean[y>>8][x>>8]; |     auto p = vec_to_pair(vec); | ||||||
|  |     int x = p.first, y = p.second; | ||||||
|  |     euclideanSlab*& slab = euclidean[(y>>8)&255][(x>>8)&255]; | ||||||
|     if(!slab) slab = new hrmap_euclidean::euclideanSlab; |     if(!slab) slab = new hrmap_euclidean::euclideanSlab; | ||||||
|     return slab->a[y&255][x&255]; |     return slab->a[y&255][x&255]; | ||||||
|     } |     } | ||||||
| @@ -317,30 +489,43 @@ struct hrmap_euclidean : hrmap { | |||||||
|     } |     } | ||||||
|   }; |   }; | ||||||
|  |  | ||||||
|  | cellwalker vec_to_cellwalker(int vec) { | ||||||
|  |   if(!torus)  | ||||||
|  |     return cellwalker(euclideanAtCreate(vec), 0, false); | ||||||
|  |   else { | ||||||
|  |     hrmap_torus *cur = torusmap(); | ||||||
|  |     if(!cur) return cellwalker(NULL, 0); | ||||||
|  |     auto p = torusconfig::vec_to_id_mirror(vec); | ||||||
|  |     return cellwalker(cur->all[p.first], 0, p.second); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | int cellwalker_to_vec(cellwalker cw) { | ||||||
|  |   int id = decodeId(cw.c->master); | ||||||
|  |   if(!torus) return id; | ||||||
|  |   return torusconfig::id_to_vec(id, cw.mirrored); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | int cell_to_vec(cell *c) { | ||||||
|  |   int id = decodeId(c->master); | ||||||
|  |   if(!torus) return id; | ||||||
|  |   return torusconfig::id_to_vec(id, false); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | auto cell_to_pair(cell *c) { | ||||||
|  |   return vec_to_pair(cell_to_vec(c)); | ||||||
|  |   } | ||||||
|  |  | ||||||
| union heptacoder { | union heptacoder { | ||||||
|   heptagon *h; |   heptagon *h; | ||||||
|   struct { eucoord x; eucoord y; } c; |  | ||||||
|   int id; |   int id; | ||||||
|   }; |   }; | ||||||
|  |  | ||||||
| void decodeMaster(heptagon *h, eucoord& x, eucoord& y) { |  | ||||||
|   if(torus) { printf("decodeMaster on torus\n"); exit(1); } |  | ||||||
|   heptacoder u; |  | ||||||
|   u.h = h; x = u.c.x; y = u.c.y; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
| int decodeId(heptagon* h) { | int decodeId(heptagon* h) { | ||||||
|   heptacoder u; |   heptacoder u; | ||||||
|   u.h = h; return u.id; |   u.h = h; return u.id; | ||||||
|   } |   } | ||||||
|  |  | ||||||
| heptagon* encodeMaster(eucoord x, eucoord y) { |  | ||||||
|   if(torus) { printf("encodeMaster on torus\n"); exit(1); } |  | ||||||
|   heptacoder u; |  | ||||||
|   u.c.x = x; u.c.y = y; |  | ||||||
|   return u.h; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
| heptagon* encodeId(int id) { | heptagon* encodeId(int id) { | ||||||
|   heptacoder u; |   heptacoder u; | ||||||
|   u.id = id; |   u.id = id; | ||||||
| @@ -528,11 +713,10 @@ cell *createMov(cell *c, int d) { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|   if(euclid && !c->mov[d]) { |   if(euclid && !c->mov[d]) { | ||||||
|     eucoord x, y; |     int id = decodeId(c->master); | ||||||
|     decodeMaster(c->master, x, y); |  | ||||||
|     for(int dx=-1; dx<=1; dx++) |     for(int dx=-1; dx<=1; dx++) | ||||||
|     for(int dy=-1; dy<=1; dy++) |     for(int dy=-1; dy<=1; dy++) | ||||||
|       euclideanAtCreate(x+dx, y+dy); |       euclideanAtCreate(id + pair_to_vec(dx, dy)); | ||||||
|     if(!c->mov[d]) { printf("fail!\n"); } |     if(!c->mov[d]) { printf("fail!\n"); } | ||||||
|     } |     } | ||||||
|    |    | ||||||
| @@ -597,43 +781,18 @@ void eumerge(cell* c1, cell *c2, int s1, int s2) { | |||||||
|  |  | ||||||
| //  map<pair<eucoord, eucoord>, cell*> euclidean; | //  map<pair<eucoord, eucoord>, cell*> euclidean; | ||||||
|  |  | ||||||
| cell*& euclideanAt(eucoord x, eucoord y) { | cell*& euclideanAt(int vec) { | ||||||
|   if(torus) { printf("euclideanAt called\n"); exit(1); } |   if(torus) { printf("euclideanAt called\n"); exit(1); } | ||||||
|   hrmap_euclidean* euc = dynamic_cast<hrmap_euclidean*> (currentmap); |   hrmap_euclidean* euc = dynamic_cast<hrmap_euclidean*> (currentmap); | ||||||
|   return euc->at(x, y); |   return euc->at(vec); | ||||||
|   } |   } | ||||||
|  |  | ||||||
| cell*& euclideanAtCreate(eucoord x, eucoord y) { | cell*& euclideanAtCreate(int vec) { | ||||||
|   cell*& c = euclideanAt(x,y); |   cell*& c = euclideanAt(vec); | ||||||
|   if(!c) { |   if(!c) { | ||||||
|     c = newCell(a4 ? (nontruncated || ((x^y^1) & 1) ? 4 : 8) : 6, NULL); |     c = newCell(8, encodeId(vec)); | ||||||
|     c->master = encodeMaster(x,y); |     euclideanAt(vec) = c; | ||||||
|     euclideanAt(x,y) = c; |     build_euclidean_moves(c, vec, [c,vec] (int delta, int d, int d2) { eumerge(c, euclideanAt(vec + delta), d, d2); }); | ||||||
|     if(c->type == 4) { |  | ||||||
|       int m = nontruncated ? 1 : 2; |  | ||||||
|       eumerge(c, euclideanAt(x+1,y), 0, 2 * m);         |  | ||||||
|       eumerge(c, euclideanAt(x,y+1), 1, 3 * m); |  | ||||||
|       eumerge(c, euclideanAt(x-1,y), 2, 0 * m); |  | ||||||
|       eumerge(c, euclideanAt(x,y-1), 3, 1 * m); |  | ||||||
|       } |  | ||||||
|     else if(c->type == 8) { |  | ||||||
|       eumerge(c, euclideanAt(x+1,y), 0, 2); |  | ||||||
|       eumerge(c, euclideanAt(x+1,y+1), 1, 5); |  | ||||||
|       eumerge(c, euclideanAt(x,y+1), 2, 3); |  | ||||||
|       eumerge(c, euclideanAt(x-1,y+1), 3, 7); |  | ||||||
|       eumerge(c, euclideanAt(x-1,y), 4, 0); |  | ||||||
|       eumerge(c, euclideanAt(x-1,y-1), 5, 1); |  | ||||||
|       eumerge(c, euclideanAt(x,y-1), 6, 1); |  | ||||||
|       eumerge(c, euclideanAt(x+1,y-1), 7, 3); |  | ||||||
|       } |  | ||||||
|     else /* 6 */ { |  | ||||||
|       eumerge(c, euclideanAt(x+1,y), 0, 3); |  | ||||||
|       eumerge(c, euclideanAt(x,y+1), 1, 4); |  | ||||||
|       eumerge(c, euclideanAt(x-1,y+1), 2, 5); |  | ||||||
|       eumerge(c, euclideanAt(x-1,y), 3, 0); |  | ||||||
|       eumerge(c, euclideanAt(x,y-1), 4, 1); |  | ||||||
|       eumerge(c, euclideanAt(x+1,y-1), 5, 2); |  | ||||||
|       } |  | ||||||
|     } |     } | ||||||
|   return c; |   return c; | ||||||
|   } |   } | ||||||
| @@ -735,7 +894,7 @@ void verifycells(heptagon *at) { | |||||||
|   verifycell(at->c7); |   verifycell(at->c7); | ||||||
|   } |   } | ||||||
|  |  | ||||||
| int eudist(short sx, short sy) { | int eudist(int sx, int sy) { | ||||||
|   int z0 = abs(sx); |   int z0 = abs(sx); | ||||||
|   int z1 = abs(sy); |   int z1 = abs(sy); | ||||||
|   if(a4) return z0 + z1; |   if(a4) return z0 + z1; | ||||||
| @@ -743,6 +902,11 @@ int eudist(short sx, short sy) { | |||||||
|   return max(max(z0,z1), z2); |   return max(max(z0,z1), z2); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  | int eudist(int vec) { | ||||||
|  |   auto p = vec_to_pair(vec); | ||||||
|  |   return eudist(p.first, p.second); | ||||||
|  |   } | ||||||
|  |  | ||||||
| int compdist(int dx[]) { | int compdist(int dx[]) { | ||||||
|   int mi = dx[0]; |   int mi = dx[0]; | ||||||
|   for(int u=0; u<S3; u++) mi = min(mi, dx[u]); |   for(int u=0; u<S3; u++) mi = min(mi, dx[u]); | ||||||
| @@ -764,9 +928,7 @@ int celldist(cell *c) { | |||||||
|   if(euclid) { |   if(euclid) { | ||||||
|     if(torus)  |     if(torus)  | ||||||
|       return torusmap()->dists[decodeId(c->master)]; |       return torusmap()->dists[decodeId(c->master)]; | ||||||
|     eucoord x, y; |     return eudist(decodeId(c->master)); | ||||||
|     decodeMaster(c->master, x, y); |  | ||||||
|     return eudist(x, y); |  | ||||||
|     } |     } | ||||||
|   if(sphere) return celldistance(c, currentmap->gamestart()); |   if(sphere) return celldistance(c, currentmap->gamestart()); | ||||||
|   if(ctof(c)) return c->master->distance; |   if(ctof(c)) return c->master->distance; | ||||||
| @@ -787,8 +949,8 @@ int euclidAlt(short x, short y); | |||||||
| int celldistAlt(cell *c) { | int celldistAlt(cell *c) { | ||||||
|   if(euclid) { |   if(euclid) { | ||||||
|     if(torus) return celldist(c); |     if(torus) return celldist(c); | ||||||
|     eucoord x, y; |     int x, y; | ||||||
|     decodeMaster(c->master, x, y); |     tie(x,y) = vec_to_pair(decodeId(c->master)); | ||||||
|     return euclidAlt(x, y); |     return euclidAlt(x, y); | ||||||
|     } |     } | ||||||
|   if(sphere || quotient) { |   if(sphere || quotient) { | ||||||
| @@ -1046,11 +1208,11 @@ cdata *getEuclidCdata(heptagon *h) { | |||||||
|     return &xx; |     return &xx; | ||||||
|     } |     } | ||||||
|      |      | ||||||
|   eucoord x, y; |   int x, y; | ||||||
|   hrmap_euclidean* euc = dynamic_cast<hrmap_euclidean*> (currentmap); |   hrmap_euclidean* euc = dynamic_cast<hrmap_euclidean*> (currentmap); | ||||||
|   if(euc->eucdata.count(h)) return &(euc->eucdata[h]); |   if(euc->eucdata.count(h)) return &(euc->eucdata[h]); | ||||||
|    |    | ||||||
|   decodeMaster(h, x, y); |   tie(x,y) = vec_to_pair(decodeId(h)); | ||||||
|  |  | ||||||
|   if(x == 0 && y == 0) { |   if(x == 0 && y == 0) { | ||||||
|     cdata xx; |     cdata xx; | ||||||
| @@ -1062,14 +1224,14 @@ cdata *getEuclidCdata(heptagon *h) { | |||||||
|   while(!((x|y)&ord)) ord <<= 1, bid++; |   while(!((x|y)&ord)) ord <<= 1, bid++; | ||||||
|    |    | ||||||
|   for(int k=0; k<3; k++) { |   for(int k=0; k<3; k++) { | ||||||
|     eucoord x1 = x + (k<2 ? ord : 0); |     int x1 = x + (k<2 ? ord : 0); | ||||||
|     eucoord y1 = y - (k>0 ? ord : 0); |     int y1 = y - (k>0 ? ord : 0); | ||||||
|     if((x1&ord) || (y1&ord)) continue; |     if((x1&ord) || (y1&ord)) continue; | ||||||
|     eucoord x2 = x - (k<2 ? ord : 0); |     int x2 = x - (k<2 ? ord : 0); | ||||||
|     eucoord y2 = y + (k>0 ? ord : 0); |     int y2 = y + (k>0 ? ord : 0); | ||||||
|  |  | ||||||
|     cdata *d1 = getEuclidCdata(encodeMaster(x1,y1)); |     cdata *d1 = getEuclidCdata(encodeId(pair_to_vec(x1,y1))); | ||||||
|     cdata *d2 = getEuclidCdata(encodeMaster(x2,y2)); |     cdata *d2 = getEuclidCdata(encodeId(pair_to_vec(x2,y2))); | ||||||
|     cdata xx; |     cdata xx; | ||||||
|     double disp = pow(2, bid/2.) * 6; |     double disp = pow(2, bid/2.) * 6; | ||||||
|      |      | ||||||
| @@ -1134,11 +1296,8 @@ int celldistance(cell *c1, cell *c2) { | |||||||
|    |    | ||||||
|   if(euclid) { |   if(euclid) { | ||||||
|     if(torus)  |     if(torus)  | ||||||
|       return torusmap()->dists[toridMod(decodeId(c1->master)-decodeId(c2->master))]; |       return torusmap()->dists[torusconfig::vec_to_id(decodeId(c1->master)-decodeId(c2->master))]; | ||||||
|     eucoord x1, y1, x2, y2; |     return eudist(decodeId(c1->master) - decodeId(c2->master)); | ||||||
|     decodeMaster(c1->master, x1, y1); |  | ||||||
|     decodeMaster(c2->master, x2, y2); |  | ||||||
|     return eudist(x1-x2, y1-y2); |  | ||||||
|     } |     } | ||||||
|    |    | ||||||
|   if(sphere || quotient == 1) { |   if(sphere || quotient == 1) { | ||||||
|   | |||||||
| @@ -1613,7 +1613,7 @@ geometryinfo ginf[gGUARD] = { | |||||||
|   {"elliptic",            "elliptic", 5, 3, qELLIP, gcSphere,     {{SEE_ALL, SEE_ALL}}}, |   {"elliptic",            "elliptic", 5, 3, qELLIP, gcSphere,     {{SEE_ALL, SEE_ALL}}}, | ||||||
|   {"Zebra quotient",      "Zebra",    7, 3, qZEBRA, gcHyperbolic, {{7, 5}}}, |   {"Zebra quotient",      "Zebra",    7, 3, qZEBRA, gcHyperbolic, {{7, 5}}}, | ||||||
|   {"field quotient",      "field",    7, 3, qFIELD, gcHyperbolic, {{7, 5}}}, |   {"field quotient",      "field",    7, 3, qFIELD, gcHyperbolic, {{7, 5}}}, | ||||||
|   {"torus",               "torus",    6, 3, qTORUS, gcEuclid,     {{7, FORBIDDEN}}}, |   {"torus/Klein bottle",  "torus",    6, 3, qTORUS, gcEuclid,     {{7, FORBIDDEN}}}, | ||||||
|   {"octagons",            "oct",      8, 3, 0,      gcHyperbolic, {{6, 4}}}, |   {"octagons",            "oct",      8, 3, 0,      gcHyperbolic, {{6, 4}}}, | ||||||
|   {"four pentagons",      "4x5",      5, 4, 0,      gcHyperbolic, {{6, 4}}}, |   {"four pentagons",      "4x5",      5, 4, 0,      gcHyperbolic, {{6, 4}}}, | ||||||
|   {"four hexagons",       "4x6",      6, 4, 0,      gcHyperbolic, {{5, 3}}}, |   {"four hexagons",       "4x6",      6, 4, 0,      gcHyperbolic, {{5, 3}}}, | ||||||
|   | |||||||
| @@ -228,13 +228,27 @@ else if(args()[0] == '-' && args()[1] == x && args()[2] == '0') { showstartmenu | |||||||
|     autocheat = true; |     autocheat = true; | ||||||
|     currfp.init(p);  |     currfp.init(p);  | ||||||
|     } |     } | ||||||
|  |   else if(argis("-test"))  | ||||||
|  |     callhooks(hooks_tests); | ||||||
|   else if(argis("-tpar")) {  |   else if(argis("-tpar")) {  | ||||||
|  |     torusconfig::torus_mode = torusconfig::tmSingle; | ||||||
|     shift(); sscanf(args(), "%d,%d,%d",  |     shift(); sscanf(args(), "%d,%d,%d",  | ||||||
|       &torusconfig::qty,  |       &torusconfig::qty,  | ||||||
|       &torusconfig::dx, |       &torusconfig::dx, | ||||||
|       &torusconfig::dy |       &torusconfig::dy | ||||||
|       ); |       ); | ||||||
|     } |     } | ||||||
|  |   else if(argis("-tparx")) { | ||||||
|  |     shift(); sscanf(args(), "%d,%d,%d",  | ||||||
|  |       (int*) &torusconfig::torus_mode, | ||||||
|  |       &torusconfig::sdx, | ||||||
|  |       &torusconfig::sdy | ||||||
|  |       ); | ||||||
|  |     if(torusconfig::torus_mode == torusconfig::tmSingle) | ||||||
|  |       torusconfig::qty = torusconfig::sdx, | ||||||
|  |       torusconfig::dy = torusconfig::sdy; | ||||||
|  |     torusconfig::activate(); | ||||||
|  |     } | ||||||
|   else if(argis("-cs")) { |   else if(argis("-cs")) { | ||||||
|     shift();  |     shift();  | ||||||
|     fieldpattern::matrix M = currfp.strtomatrix(args()); |     fieldpattern::matrix M = currfp.strtomatrix(args()); | ||||||
| @@ -345,6 +359,14 @@ else if(args()[0] == '-' && args()[1] == x && args()[2] == '0') { showstartmenu | |||||||
|     PHASEFROM(2); |     PHASEFROM(2); | ||||||
|     shift(); whatever = argf(); resetGeometry(); |     shift(); whatever = argf(); resetGeometry(); | ||||||
|     } |     } | ||||||
|  |   else if(argis("-wei")) {     | ||||||
|  |     PHASEFROM(2); | ||||||
|  |     shift(); whateveri = argf(); resetGeometry(); | ||||||
|  |     } | ||||||
|  |   else if(argis("-wei2")) { | ||||||
|  |     PHASEFROM(2); | ||||||
|  |     shift(); whateveri2 = argf(); resetGeometry(); | ||||||
|  |     } | ||||||
|   else if(argis("-rch")) {     |   else if(argis("-rch")) {     | ||||||
|     PHASEFROM(2); |     PHASEFROM(2); | ||||||
|     reptilecheat = true; autocheat = true; firstland = laReptile; |     reptilecheat = true; autocheat = true; firstland = laReptile; | ||||||
|   | |||||||
							
								
								
									
										17
									
								
								complex.cpp
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								complex.cpp
									
									
									
									
									
								
							| @@ -12,8 +12,8 @@ namespace whirlwind { | |||||||
|   int fzebra3(cell *c) { |   int fzebra3(cell *c) { | ||||||
|     if(euclid) { |     if(euclid) { | ||||||
|       if(torus) return 0; |       if(torus) return 0; | ||||||
|       eucoord x, y; |       int x, y; | ||||||
|       decodeMaster(c->master, x, y); |       tie(x,y) = cell_to_pair(c); | ||||||
|       return 1+((((signed short)(y)+int(50000))/3)%3); |       return 1+((((signed short)(y)+int(50000))/3)%3); | ||||||
|       } |       } | ||||||
|     if(S7 == 5) return getHemisphere(c, 0) > 0 ? 1 : 2; |     if(S7 == 5) return getHemisphere(c, 0) > 0 ? 1 : 2; | ||||||
| @@ -809,8 +809,9 @@ namespace clearing { | |||||||
|       if(pseudohept(c)) return; |       if(pseudohept(c)) return; | ||||||
|       c->monst = moMutant; |       c->monst = moMutant; | ||||||
|        |        | ||||||
|       eucoord x, y; |       int x, y; | ||||||
|       decodeMaster(c->master, x, y); |       tie(x,y) = cell_to_pair(c); | ||||||
|  |  | ||||||
|       int xco = x * 2 + y + 1; |       int xco = x * 2 + y + 1; | ||||||
|       c->stuntime = (8-xco/2) & 15; |       c->stuntime = (8-xco/2) & 15; | ||||||
|       // 2, 4, 5, 7 |       // 2, 4, 5, 7 | ||||||
| @@ -2701,8 +2702,8 @@ namespace prairie { | |||||||
|       c->LHU.fi.rval = 0; |       c->LHU.fi.rval = 0; | ||||||
|       } |       } | ||||||
|     else if(euclid) { |     else if(euclid) { | ||||||
|       eucoord x, y; |       int x, y; | ||||||
|       decodeMaster(c->master, x, y); |       tie(x,y) = cell_to_pair(c); | ||||||
|       c->LHU.fi.rval = (y&15); |       c->LHU.fi.rval = (y&15); | ||||||
|       } |       } | ||||||
|     else if(sphere) { |     else if(sphere) { | ||||||
| @@ -3391,8 +3392,8 @@ namespace dungeon { | |||||||
|      |      | ||||||
|     if(euclid) { |     if(euclid) { | ||||||
|       if(torus) return; |       if(torus) return; | ||||||
|       eucoord x, y; |       int x, y; | ||||||
|       decodeMaster(c->master, x, y); |       tie(x, y) = cell_to_pair(c); | ||||||
|       string tab[] = { |       string tab[] = { | ||||||
|         ".####...", |         ".####...", | ||||||
|         "L...L...", |         "L...L...", | ||||||
|   | |||||||
| @@ -30,7 +30,8 @@ movedir joydir; | |||||||
| movedir mousedest; | movedir mousedest; | ||||||
| ld shiftmul = 1; | ld shiftmul = 1; | ||||||
|  |  | ||||||
| cell *mouseover, *mouseover2, *lmouseover, *centerover; | cell *mouseover, *mouseover2, *lmouseover; | ||||||
|  | cellwalker centerover; | ||||||
| ld modist, modist2, centdist; | ld modist, modist2, centdist; | ||||||
|  |  | ||||||
| int lastt; | int lastt; | ||||||
| @@ -340,7 +341,7 @@ void handleKeyNormal(int sym, int uni) { | |||||||
|       // vid.yshift = 1 - vid.yshift; |       // vid.yshift = 1 - vid.yshift; | ||||||
|       // vid.drawmousecircle = true; |       // vid.drawmousecircle = true; | ||||||
|       } |       } | ||||||
|     if(sym == 'm' && canmove && (centerover == cwt.c ? mouseover : centerover)) |     if(sym == 'm' && canmove && (centerover == cwt ? mouseover : centerover.c)) | ||||||
|       performMarkCommand(mouseover); |       performMarkCommand(mouseover); | ||||||
|     } |     } | ||||||
|    |    | ||||||
| @@ -351,9 +352,9 @@ void handleKeyNormal(int sym, int uni) { | |||||||
|     if(sym == 't' && uni != 'T' && uni != 'T'-64 && canmove) { |     if(sym == 't' && uni != 'T' && uni != 'T'-64 && canmove) { | ||||||
|       if(playermoved && items[itStrongWind]) {  |       if(playermoved && items[itStrongWind]) {  | ||||||
|         cell *c = whirlwind::jumpDestination(cwt.c); |         cell *c = whirlwind::jumpDestination(cwt.c); | ||||||
|         if(c) centerover = c; |         if(c) centerover.c = c; | ||||||
|         } |         } | ||||||
|       targetRangedOrb(centerover, roKeyboard); |       targetRangedOrb(centerover.c, roKeyboard); | ||||||
|       sym = 0; uni = 0; |       sym = 0; uni = 0; | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   | |||||||
							
								
								
									
										3
									
								
								game.cpp
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								game.cpp
									
									
									
									
									
								
							| @@ -5795,8 +5795,7 @@ void activateSafety(eLand l) { | |||||||
|   firstland = l; |   firstland = l; | ||||||
|   safetyland = l; |   safetyland = l; | ||||||
|   safetyseed = time(NULL); |   safetyseed = time(NULL); | ||||||
|   for(int i=0; i<65536; i++) euland[i] = laNone; |   clear_euland(firstland); | ||||||
|   euland[0] = euland[1] = firstland; |  | ||||||
|   safety = true; avengers = 0; |   safety = true; avengers = 0; | ||||||
|   clearMemory(); |   clearMemory(); | ||||||
|   initcells(); |   initcells(); | ||||||
|   | |||||||
							
								
								
									
										107
									
								
								geom-exp.cpp
									
									
									
									
									
								
							
							
						
						
									
										107
									
								
								geom-exp.cpp
									
									
									
									
									
								
							| @@ -84,20 +84,76 @@ void showQuotientConfig() { | |||||||
|   dialog::display(); |   dialog::display(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  | bool torus_chamfer; | ||||||
|  |  | ||||||
| void showTorusConfig() { | void showTorusConfig() { | ||||||
|   cmode = sm::SIDE | sm::TORUSCONFIG; |   cmode = sm::SIDE | sm::TORUSCONFIG; | ||||||
|   gamescreen(2); |   gamescreen(2); | ||||||
|    |    | ||||||
|   dialog::init(XLAT("advanced configuration")); |   dialog::init(XLAT("advanced configuration")); | ||||||
|    |    | ||||||
|   dialog::addSelItem(XLAT("number of cells (n)"), its(torusconfig::newqty), 'n'); |   auto& mode = torusconfig::tmodes[torusconfig::newmode]; | ||||||
|   dialog::addSelItem(XLAT("cell bottom-right from 0 (d)"), its(torusconfig::newdy), 'd'); |  | ||||||
|    |    | ||||||
|   if(torusconfig::newqty % 3) |   dialog::addSelItem(XLAT("mode"), XLAT(mode.name), 'm'); | ||||||
|     dialog::addInfo("best if n is divisible by 3", 0x808080); |  | ||||||
|    |    | ||||||
|   if((torusconfig::newdy + 999999) % 3 != 2) |   bool single = (mode.flags & torusconfig::TF_SINGLE); | ||||||
|     dialog::addInfo("best if d+1 is divisible by 3", 0x808080); |   bool square = (mode.flags & torusconfig::TF_SQUARE); | ||||||
|  |   bool simple = (mode.flags & torusconfig::TF_SIMPLE); | ||||||
|  |    | ||||||
|  |   if(single) { | ||||||
|  |     dialog::addSelItem(XLAT("number of cells (n)"), its(torusconfig::newqty), 'n'); | ||||||
|  |     if(torusconfig::TF_HEX) | ||||||
|  |       dialog::addSelItem(XLAT("cell bottom-right from 0 (d)"), its(torusconfig::newdy), 'd'); | ||||||
|  |     else | ||||||
|  |       dialog::addSelItem(XLAT("cell below 0 (d)"), its(torusconfig::newdy), 'd'); | ||||||
|  |     } | ||||||
|  |   else { | ||||||
|  |     if(torusconfig::newsdx < 1) torusconfig::newsdx = 1; | ||||||
|  |     if(torusconfig::newsdy < 1) torusconfig::newsdy = 1; | ||||||
|  |     dialog::addSelItem(XLAT("width (x)"), its(torusconfig::newsdx), 'x'); | ||||||
|  |     dialog::addSelItem(XLAT("height (y)"), its(torusconfig::newsdy), 'y'); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   if(square) dialog::addBoolItem(XLAT("chamfering"), !torus_chamfer, 't'); | ||||||
|  |   else dialog::addInfo("", 100); | ||||||
|  |    | ||||||
|  |   int valid = 2; | ||||||
|  |  | ||||||
|  |   if(single) {   | ||||||
|  |     if(square) { | ||||||
|  |       dialog::addInfo("this mode has bad patterns", 0x808080), valid = 1; | ||||||
|  |       if(!torus_chamfer && valid == 1) | ||||||
|  |         dialog::addInfo("incompatible with chamfering", 0x808080), valid = 0; | ||||||
|  |       } | ||||||
|  |     else { | ||||||
|  |       if(torusconfig::newqty % 3) | ||||||
|  |         dialog::addInfo(XLAT("best if %1 is divisible by %2", "n", "3"), 0x808080), valid = 1; | ||||||
|  |       if((torusconfig::newdy + 999999) % 3 != 2) | ||||||
|  |         dialog::addInfo(XLAT("best if %1 is divisible by %2", "d+1", "3"), 0x808080), valid = 1; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   else { | ||||||
|  |     if(square) { | ||||||
|  |       if(torusconfig::newsdx & 1) | ||||||
|  |         dialog::addInfo(XLAT("best if %1 is divisible by %2", "x", "2"), 0x808080), valid = 1; | ||||||
|  |       if(torusconfig::newsdy & 1) | ||||||
|  |         dialog::addInfo(XLAT("best if %1 is divisible by %2", "y", "2"), 0x808080), valid = 1; | ||||||
|  |       if(!torus_chamfer && valid == 1) | ||||||
|  |         dialog::addInfo("incompatible with chamfering", 0x808080), valid = 0; | ||||||
|  |       } | ||||||
|  |     else if(simple) { | ||||||
|  |       if(torusconfig::newsdx & 1) | ||||||
|  |         dialog::addInfo(XLAT("best if %1 is divisible by %2", "x", "3"), 0x808080), valid = 1; | ||||||
|  |       if(torusconfig::newsdy & 1) | ||||||
|  |         dialog::addInfo(XLAT("best if %1 is divisible by %2", "y", "3"), 0x808080), valid = 1; | ||||||
|  |       } | ||||||
|  |     else { | ||||||
|  |       if(torusconfig::newsdx & 1) | ||||||
|  |         dialog::addInfo(XLAT("best if %1 is divisible by %2", "x", "3"), 0x808080), valid = 1; | ||||||
|  |       if(torusconfig::newsdy & 1) | ||||||
|  |         dialog::addInfo(XLAT("best if %1 is divisible by %2", "y", "2"), 0x808080), valid = 0; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|    |    | ||||||
|   dialog::addSelItem(XLAT("scale factor"), fts(vid.scale), 'z'); |   dialog::addSelItem(XLAT("scale factor"), fts(vid.scale), 'z'); | ||||||
|  |  | ||||||
| @@ -108,22 +164,39 @@ void showTorusConfig() { | |||||||
|   dialog::addItem("activate", 'a'); |   dialog::addItem("activate", 'a'); | ||||||
|   dialog::addItem("default", 'c'); |   dialog::addItem("default", 'c'); | ||||||
|  |  | ||||||
|   keyhandler = [] (int sym, int uni) { |   keyhandler = [=] (int sym, int uni) { | ||||||
|     if(uni == 'n') |     if(uni == 'm') { | ||||||
|  |       int i = torusconfig::newmode + 1; | ||||||
|  |       if(i >= size(torusconfig::tmodes)) i = 0; | ||||||
|  |       torusconfig::newmode = torusconfig::eTorusMode(i); | ||||||
|  |       } | ||||||
|  |     else if(uni == 'n' && single) | ||||||
|       dialog::editNumber(torusconfig::newqty, 0, 1000, 3, torusconfig::def_qty, XLAT("number of cells (n)"), ""); |       dialog::editNumber(torusconfig::newqty, 0, 1000, 3, torusconfig::def_qty, XLAT("number of cells (n)"), ""); | ||||||
|     else if(uni == 'd') |     else if(uni == 'd' && single) | ||||||
|       dialog::editNumber(torusconfig::newdy, -1000, 1000, 3, -torusconfig::def_dy, XLAT("cell bottom-right from 0 (d)"), ""); |       dialog::editNumber(torusconfig::newdy, -1000, 1000, 3, -torusconfig::def_dy, XLAT("cell below 0 (d)"), ""); | ||||||
|     else if((uni == 'a' || uni == '\n') && torusconfig::newqty >= 3 && abs(torusconfig::newdy) < torusconfig::newqty ) { |     else if(uni == 'x' && !single) | ||||||
|       targetgeometry = gEuclid; restartGame('g'); |       dialog::editNumber(torusconfig::newsdx, 0, 1000, square ? 2 : 3, 12, XLAT("width (x)"), ""); | ||||||
|  |     else if(uni == 'y' && !single) | ||||||
|  |       dialog::editNumber(torusconfig::newsdy, 0, 1000, square ? 2 : simple ? 3 : 2, 12, XLAT("height (y)"), ""); | ||||||
|  |     else if(uni == 't') | ||||||
|  |       torus_chamfer = !torus_chamfer; | ||||||
|  |     else if((uni == 'a' || uni == '\n') && torusconfig::newqty >= 3 && valid) { | ||||||
|  |       targetgeometry = gNormal; restartGame('g', false, true); | ||||||
|  |       torusconfig::torus_mode = torusconfig::newmode; | ||||||
|       torusconfig::qty = torusconfig::newqty; |       torusconfig::qty = torusconfig::newqty; | ||||||
|       torusconfig::dy = torusconfig::newdy; |       torusconfig::dy = torusconfig::newdy; | ||||||
|       targetgeometry = gTorus; restartGame('g'); |       torusconfig::sdx = torusconfig::newsdx; | ||||||
|  |       torusconfig::sdy = torusconfig::newsdy; | ||||||
|  |       torusconfig::activate(); | ||||||
|  |       if((square && torus_chamfer) != nontruncated) restartGame('7', false, true); | ||||||
|  |       targetgeometry = gTorus; restartGame('g', false, true); | ||||||
|       } |       } | ||||||
|     else if(uni == 'c') { |     else if(uni == 'c') { | ||||||
|       targetgeometry = gEuclid; restartGame('g'); |       targetgeometry = gEuclid; restartGame('g', false, true); | ||||||
|  |       torusconfig::torus_mode = torusconfig::tmSingle; | ||||||
|       torusconfig::qty = torusconfig::def_qty; |       torusconfig::qty = torusconfig::def_qty; | ||||||
|       torusconfig::dy = torusconfig::def_dy; |       torusconfig::dy = torusconfig::def_dy; | ||||||
|       targetgeometry = gTorus; restartGame('g'); |       targetgeometry = gTorus; restartGame('g', false, true); | ||||||
|       } |       } | ||||||
|     else if(uni == 'z') editScale(); |     else if(uni == 'z') editScale(); | ||||||
| #if CAP_RUG | #if CAP_RUG | ||||||
| @@ -263,6 +336,10 @@ void showEuclideanMenu() { | |||||||
|         if(torus)  |         if(torus)  | ||||||
|           torusconfig::newdy = torusconfig::dy, |           torusconfig::newdy = torusconfig::dy, | ||||||
|           torusconfig::newqty = torusconfig::qty, |           torusconfig::newqty = torusconfig::qty, | ||||||
|  |           torusconfig::newsdx = torusconfig::sdx, | ||||||
|  |           torusconfig::newsdy = torusconfig::sdy, | ||||||
|  |           torusconfig::newmode = torusconfig::torus_mode, | ||||||
|  |           torus_chamfer = nontruncated, | ||||||
|           pushScreen(showTorusConfig); |           pushScreen(showTorusConfig); | ||||||
|         if(quotient==2) pushScreen(showQuotientConfig); |         if(quotient==2) pushScreen(showQuotientConfig); | ||||||
|         } |         } | ||||||
|   | |||||||
							
								
								
									
										33
									
								
								graph.cpp
									
									
									
									
									
								
							
							
						
						
									
										33
									
								
								graph.cpp
									
									
									
									
									
								
							| @@ -3284,12 +3284,12 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { | |||||||
|       mouseover2 = c; |       mouseover2 = c; | ||||||
|       } |       } | ||||||
|  |  | ||||||
|     if(!torus) { |     if(!euclid) { | ||||||
|       double dfc = euclid ? intval(VC0, C0) : VC0[2]; |       double dfc = euclid ? intval(VC0, C0) : VC0[2]; | ||||||
|      |      | ||||||
|       if(dfc < centdist) { |       if(dfc < centdist) { | ||||||
|         centdist = dfc; |         centdist = dfc; | ||||||
|         centerover = c; |         centerover = cellwalker(c, spinv, mirrored); | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|      |      | ||||||
| @@ -3380,10 +3380,19 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { | |||||||
|      |      | ||||||
|     if(cmode & sm::TORUSCONFIG) { |     if(cmode & sm::TORUSCONFIG) { | ||||||
|       using namespace torusconfig; |       using namespace torusconfig; | ||||||
|       int cd = torus_cx * dx + torus_cy * newdy; |       string label; | ||||||
|       cd %= newqty; if(cd<0) cd += newqty; |       bool small; | ||||||
|       string label = its(cd); |       if(tmflags() & TF_SINGLE) { | ||||||
|       queuestr(V, cd ? .2 : .6, label, cd == 0 ? 0xFFFF0040 : 0xFFFFFFD0, 1); |         int cd = torus_cx * dx + torus_cy * newdy; | ||||||
|  |         cd %= newqty; if(cd<0) cd += newqty; | ||||||
|  |         label = its(cd); | ||||||
|  |         small = cd; | ||||||
|  |         } | ||||||
|  |       else { | ||||||
|  |         small = true; | ||||||
|  |         label = its(torus_cx) + "," + its(torus_cy); | ||||||
|  |         } | ||||||
|  |       queuestr(V, small ? .2 : .6, label, small ? 0xFFFFFFD0 : 0xFFFF0040, 1); | ||||||
|       } |       } | ||||||
|  |  | ||||||
|     asciicol = wcol; |     asciicol = wcol; | ||||||
| @@ -4744,8 +4753,8 @@ void drawMarkers() { | |||||||
| #if CAP_MODEL | #if CAP_MODEL | ||||||
|     m = netgen::mode == 0; |     m = netgen::mode == 0; | ||||||
| #endif | #endif | ||||||
|     if(centerover && !playermoved && m && !conformal::on) |     if(centerover.c && !playermoved && m && !conformal::on) | ||||||
|       queuecircleat(centerover, .70 - .06 * sin(ticks/200.0),  |       queuecircleat(centerover.c, .70 - .06 * sin(ticks/200.0),  | ||||||
|         darkena(int(175 + 25 * sin(ticks / 200.0)), 0, 0xFF)); |         darkena(int(175 + 25 * sin(ticks / 200.0)), 0, 0xFF)); | ||||||
|  |  | ||||||
|     if(multi::players > 1 || multi::alwaysuse) for(int i=0; i<numplayers(); i++) { |     if(multi::players > 1 || multi::alwaysuse) for(int i=0; i<numplayers(); i++) { | ||||||
| @@ -4925,7 +4934,7 @@ void drawthemap() { | |||||||
|   modist2 = 1e20; mouseover2 = NULL;  |   modist2 = 1e20; mouseover2 = NULL;  | ||||||
|  |  | ||||||
|   centdist = 1e20;  |   centdist = 1e20;  | ||||||
|   if(!torus) centerover = NULL;  |   if(!euclid) centerover.c = NULL;  | ||||||
|  |  | ||||||
|   for(int i=0; i<multi::players; i++) { |   for(int i=0; i<multi::players; i++) { | ||||||
|     multi::ccdist[i] = 1e20; multi::ccat[i] = NULL; |     multi::ccdist[i] = 1e20; multi::ccat[i] = NULL; | ||||||
| @@ -5406,7 +5415,7 @@ void restartGraph() { | |||||||
|   linepatterns::clearAll(); |   linepatterns::clearAll(); | ||||||
|   if(currentmap) { |   if(currentmap) { | ||||||
|     if(euclid) { |     if(euclid) { | ||||||
|       centerover = torus ? getTorusId(0) : euclideanAtCreate(0,0); |       centerover = vec_to_cellwalker(0); | ||||||
|       } |       } | ||||||
|     else { |     else { | ||||||
|       viewctr.h = currentmap->getOrigin(); |       viewctr.h = currentmap->getOrigin(); | ||||||
| @@ -5419,7 +5428,7 @@ void restartGraph() { | |||||||
|  |  | ||||||
| auto graphcm = addHook(clearmemory, 0, [] () { | auto graphcm = addHook(clearmemory, 0, [] () { | ||||||
|   DEBB(DF_INIT, (debugfile,"clear graph memory\n")); |   DEBB(DF_INIT, (debugfile,"clear graph memory\n")); | ||||||
|   mouseover = centerover = lmouseover = NULL;   |   mouseover = centerover.c = lmouseover = NULL;   | ||||||
|   for(int i=0; i<ANIMLAYERS; i++) animations[i].clear(); |   for(int i=0; i<ANIMLAYERS; i++) animations[i].clear(); | ||||||
|   gmatrix.clear(); gmatrix0.clear(); |   gmatrix.clear(); gmatrix0.clear(); | ||||||
|   flashes.clear(); |   flashes.clear(); | ||||||
| @@ -5505,7 +5514,7 @@ void drawBug(const cellwalker& cw, int col) { | |||||||
|   } |   } | ||||||
|  |  | ||||||
| cell *viewcenter() { | cell *viewcenter() { | ||||||
|   if(euclid) return centerover; |   if(euclid) return centerover.c; | ||||||
|   else return viewctr.h->c7; |   else return viewctr.h->c7; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										12
									
								
								help.cpp
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								help.cpp
									
									
									
									
									
								
							| @@ -650,7 +650,7 @@ int windtotal; | |||||||
| void describeMouseover() { | void describeMouseover() { | ||||||
|   DEBB(DF_GRAPH, (debugfile,"describeMouseover\n")); |   DEBB(DF_GRAPH, (debugfile,"describeMouseover\n")); | ||||||
|  |  | ||||||
|   cell *c = mousing ? mouseover : playermoved ? NULL : centerover; |   cell *c = mousing ? mouseover : playermoved ? NULL : centerover.c; | ||||||
|   string& out = mouseovers; |   string& out = mouseovers; | ||||||
|   if(!c || instat || getcstat != '-') { } |   if(!c || instat || getcstat != '-') { } | ||||||
|   else if(c->wall != waInvisibleFloor) { |   else if(c->wall != waInvisibleFloor) { | ||||||
| @@ -701,12 +701,10 @@ void describeMouseover() { | |||||||
|       out += " " + describeRPM(c->land); |       out += " " + describeRPM(c->land); | ||||||
|        |        | ||||||
|     if(euclid && cheater) { |     if(euclid && cheater) { | ||||||
|       if(torus) { |       out += " ("+its(cell_to_vec(c))+")"; | ||||||
|         out += " ("+its(decodeId(c->master))+")"; |       if(!torus || torusconfig::torus_mode != torusconfig::tmSingle) { | ||||||
|         } |         int x, y; | ||||||
|       else { |         tie(x,y) = cell_to_pair(c); | ||||||
|         eucoord x, y; |  | ||||||
|         decodeMaster(c->master, x, y); |  | ||||||
|         out += " ("+its(short(x))+","+its(short(y))+")"; |         out += " ("+its(short(x))+","+its(short(y))+")"; | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|   | |||||||
							
								
								
									
										13
									
								
								hyper.h
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								hyper.h
									
									
									
									
									
								
							| @@ -541,7 +541,7 @@ void drawCircle(int x, int y, int size, int color); | |||||||
| void fixcolor(int& col); | void fixcolor(int& col); | ||||||
| int displaydir(cell *c, int d); | int displaydir(cell *c, int d); | ||||||
| hyperpoint gethyper(ld x, ld y); | hyperpoint gethyper(ld x, ld y); | ||||||
| void resetview(); extern heptspin viewctr; extern cell *centerover; | void resetview(); extern heptspin viewctr; extern cellwalker centerover; | ||||||
| void drawthemap(); | void drawthemap(); | ||||||
| void drawfullmap(); | void drawfullmap(); | ||||||
| bool displaystr(int x, int y, int shift, int size, const char *str, int color, int align); | bool displaystr(int x, int y, int shift, int size, const char *str, int color, int align); | ||||||
| @@ -829,7 +829,6 @@ bool isElemental(eLand l); | |||||||
| int coastval(cell *c, eLand base); | int coastval(cell *c, eLand base); | ||||||
| int getHauntedDepth(cell *c); | int getHauntedDepth(cell *c); | ||||||
| eLand randomElementalLand(); | eLand randomElementalLand(); | ||||||
| extern eLand euland[65536]; |  | ||||||
| bool notDippingForExtra(eItem i, eItem x); | bool notDippingForExtra(eItem i, eItem x); | ||||||
| void placePrizeOrb(cell *c); | void placePrizeOrb(cell *c); | ||||||
| void wandering(); | void wandering(); | ||||||
| @@ -1388,6 +1387,7 @@ void movecost(cell* from, cell *to); | |||||||
| void checkmove(); | void checkmove(); | ||||||
|  |  | ||||||
| transmatrix eumove(ld x, ld y); | transmatrix eumove(ld x, ld y); | ||||||
|  | transmatrix eumove(int vec); | ||||||
| transmatrix eumovedir(int d); | transmatrix eumovedir(int d); | ||||||
|  |  | ||||||
| int reptilemax(); | int reptilemax(); | ||||||
| @@ -1690,7 +1690,7 @@ template<class T, class U> int addHook(hookset<T>*& m, int prio, const U& hook) | |||||||
|   return 0; |   return 0; | ||||||
|   } |   } | ||||||
|  |  | ||||||
| extern purehookset hooks_frame, hooks_stats, clearmemory, hooks_config; | extern purehookset hooks_frame, hooks_stats, clearmemory, hooks_config, hooks_tests; | ||||||
|  |  | ||||||
| template<class T, class... U> void callhooks(hookset<T> *h, U... args) { | template<class T, class... U> void callhooks(hookset<T> *h, U... args) { | ||||||
|   if(h) for(auto& p: *h) p.second(args...); |   if(h) for(auto& p: *h) p.second(args...); | ||||||
| @@ -2252,9 +2252,6 @@ struct celllister { | |||||||
|    |    | ||||||
|   }; |   }; | ||||||
|  |  | ||||||
| typedef unsigned short eucoord; |  | ||||||
| void decodeMaster(heptagon *h, eucoord& x, eucoord& y); |  | ||||||
|  |  | ||||||
| hrmap *newAltMap(heptagon *o); | hrmap *newAltMap(heptagon *o); | ||||||
|  |  | ||||||
| #define currfp fieldpattern::getcurrfp() | #define currfp fieldpattern::getcurrfp() | ||||||
| @@ -2423,3 +2420,7 @@ transmatrix cview(); | |||||||
|  |  | ||||||
| extern string truncatenames[2]; | extern string truncatenames[2]; | ||||||
| extern bool need_mouseh; | extern bool need_mouseh; | ||||||
|  |  | ||||||
|  | extern int whateveri, whateveri2; | ||||||
|  |  | ||||||
|  | void clear_euland(eLand first); | ||||||
|   | |||||||
							
								
								
									
										45
									
								
								hypgraph.cpp
									
									
									
									
									
								
							
							
						
						
									
										45
									
								
								hypgraph.cpp
									
									
									
									
									
								
							| @@ -395,6 +395,12 @@ transmatrix eumove(ld x, ld y) { | |||||||
|   return Mat; |   return Mat; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  | transmatrix eumove(int vec) { | ||||||
|  |   int x, y; | ||||||
|  |   tie(x,y) = vec_to_pair(vec); | ||||||
|  |   return eumove(x, y); | ||||||
|  |   } | ||||||
|  |  | ||||||
| transmatrix eumovedir(int d) { | transmatrix eumovedir(int d) { | ||||||
|   if(a4) { |   if(a4) { | ||||||
|     d = d & 3; |     d = d & 3; | ||||||
| @@ -426,16 +432,10 @@ ld matrixnorm(const transmatrix& Mat) { | |||||||
| void drawEuclidean() { | void drawEuclidean() { | ||||||
|   DEBB(DF_GRAPH, (debugfile,"drawEuclidean\n")); |   DEBB(DF_GRAPH, (debugfile,"drawEuclidean\n")); | ||||||
|   sphereflip = Id; |   sphereflip = Id; | ||||||
|   eucoord px=0, py=0; |   if(!centerover.c) centerover = cwt; | ||||||
|   if(!centerover) centerover = cwt.c; |  | ||||||
|   // printf("centerover = %p player = %p [%d,%d]-[%d,%d]\n", lcenterover, cwt.c, |   // printf("centerover = %p player = %p [%d,%d]-[%d,%d]\n", lcenterover, cwt.c, | ||||||
|   //   mindx, mindy, maxdx, maxdy); |   //   mindx, mindy, maxdx, maxdy); | ||||||
|   int pid; |   int pvec = cellwalker_to_vec(centerover); | ||||||
|   const bool b = torus; |  | ||||||
|   if(b) |  | ||||||
|     pid = decodeId(centerover->master); |  | ||||||
|   else |  | ||||||
|     decodeMaster(centerover->master, px, py); |  | ||||||
|      |      | ||||||
|   int minsx = mindx-1, maxsx=maxdx+1, minsy=mindy-1, maxsy=maxdy+1; |   int minsx = mindx-1, maxsx=maxdx+1, minsy=mindy-1, maxsy=maxdy+1; | ||||||
|   mindx=maxdx=mindy=maxdy=0; |   mindx=maxdx=mindy=maxdy=0; | ||||||
| @@ -451,25 +451,16 @@ void drawEuclidean() { | |||||||
|     torusconfig::torus_cx = dx; |     torusconfig::torus_cx = dx; | ||||||
|     torusconfig::torus_cy = dy; |     torusconfig::torus_cy = dy; | ||||||
|     reclevel = eudist(dx, dy); |     reclevel = eudist(dx, dy); | ||||||
|     cell *c; |     cellwalker cw = vec_to_cellwalker(pvec + euclid_getvec(dx, dy)); | ||||||
|     transmatrix Mat; |     transmatrix Mat = eumove(dx,dy); | ||||||
|     if(b) { |      | ||||||
|       reclevel = eudist(dx, dy); |     if(!cw.c) continue; | ||||||
|       c = getTorusId(pid+torusconfig::dx*dx+torusconfig::dy*dy); |  | ||||||
|       Mat = eumove(dx,dy); |  | ||||||
|       } |  | ||||||
|     else { |  | ||||||
|       eucoord x = dx+px; |  | ||||||
|       eucoord y = dy+py; |  | ||||||
|       c = euclideanAt(x,y); |  | ||||||
|       Mat = eumove(x, y); |  | ||||||
|       } |  | ||||||
|     if(!c) continue; |  | ||||||
|     Mat = View0 * Mat; |     Mat = View0 * Mat; | ||||||
|      |      | ||||||
|     if(torus) { |     if(true) { | ||||||
|       ld locald = matrixnorm(Mat); |       ld locald = matrixnorm(Mat); | ||||||
|       if(locald < centerd) centerd = locald, centerover = c, View = View0 * eumove(dx, dy); |       if(locald < centerd) centerd = locald, centerover = cw, View = View0 * eumove(dx, dy); | ||||||
|       } |       } | ||||||
|      |      | ||||||
|     // Mat[0][0] = -1; |     // Mat[0][0] = -1; | ||||||
| @@ -488,8 +479,8 @@ void drawEuclidean() { | |||||||
|       if(dy > maxdy) maxdy = dy; |       if(dy > maxdy) maxdy = dy; | ||||||
|       } |       } | ||||||
|     if(cx >= -cellrad && cy >= -cellrad && cx < vid.xres+cellrad && cy < vid.yres+cellrad) |     if(cx >= -cellrad && cy >= -cellrad && cx < vid.xres+cellrad && cy < vid.yres+cellrad) | ||||||
|       if(dodrawcell(c)) { |       if(dodrawcell(cw.c)) { | ||||||
|         drawcell(c, Mat, 0, false); |         drawcell(cw.c, cw.mirrored ? Mat * Mirror : Mat, cw.spin, cw.mirrored); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| @@ -596,7 +587,7 @@ void resetview() { | |||||||
|   if(!euclid)  |   if(!euclid)  | ||||||
|     viewctr.h = cwt.c->master, |     viewctr.h = cwt.c->master, | ||||||
|     viewctr.spin = cwt.spin; |     viewctr.spin = cwt.spin; | ||||||
|   else centerover = cwt.c; |   else centerover = cwt; | ||||||
|   // SDL_LockSurface(s); |   // SDL_LockSurface(s); | ||||||
|   // SDL_UnlockSurface(s); |   // SDL_UnlockSurface(s); | ||||||
|   } |   } | ||||||
|   | |||||||
							
								
								
									
										31
									
								
								landgen.cpp
									
									
									
									
									
								
							
							
						
						
									
										31
									
								
								landgen.cpp
									
									
									
									
									
								
							| @@ -324,8 +324,8 @@ void giantLandSwitch(cell *c, int d, cell *from) { | |||||||
|           c->wall = waCavefloor; |           c->wall = waCavefloor; | ||||||
|           } |           } | ||||||
|         else if(euclid) { |         else if(euclid) { | ||||||
|           eucoord x, y; |           int x, y; | ||||||
|           decodeMaster(c->master, x, y); |           tie(x,y) = cell_to_pair(c); | ||||||
|           if(((y-2)&7) < 4) c->wall = waCavewall; |           if(((y-2)&7) < 4) c->wall = waCavewall; | ||||||
|           else c->wall = waCavefloor; |           else c->wall = waCavefloor; | ||||||
|           } |           } | ||||||
| @@ -407,10 +407,9 @@ void giantLandSwitch(cell *c, int d, cell *from) { | |||||||
|           v = hrand(100) < 25 ? 24 : 16; |           v = hrand(100) < 25 ? 24 : 16; | ||||||
|           } |           } | ||||||
|         else if(euclid) { |         else if(euclid) { | ||||||
|           eucoord x, y; |           int x, y; | ||||||
|           decodeMaster(c->master, x, y); |           tie(x,y) = cell_to_pair(c); | ||||||
|           int y0 = ((short)y) % 6; |           int y0 = gmod(y, 6); | ||||||
|           if(y0<0) y0+=6; |  | ||||||
|           if(y0 == 3 || y0 == 4) v=24; else v=0; |           if(y0 == 3 || y0 == 4) v=24; else v=0; | ||||||
|           } |           } | ||||||
|         else v = emeraldval(c); |         else v = emeraldval(c); | ||||||
| @@ -466,8 +465,8 @@ void giantLandSwitch(cell *c, int d, cell *from) { | |||||||
|       if(d==8) { |       if(d==8) { | ||||||
|         if(torus) ; |         if(torus) ; | ||||||
|         else if(euclid) { |         else if(euclid) { | ||||||
|           eucoord x, y; |           int x,y; | ||||||
|           decodeMaster(c->master, x, y); |           tie(x,y) = cell_to_pair(c); | ||||||
|           if(y&1) c->wall = waTrapdoor; |           if(y&1) c->wall = waTrapdoor; | ||||||
|           else c->wall = waNone; |           else c->wall = waNone; | ||||||
|           } |           } | ||||||
| @@ -486,9 +485,9 @@ void giantLandSwitch(cell *c, int d, cell *from) { | |||||||
|       if(d==8) { |       if(d==8) { | ||||||
|         if(torus) ; |         if(torus) ; | ||||||
|         else if(euclid) { |         else if(euclid) { | ||||||
|           eucoord x, y; |           int x,y; | ||||||
|           decodeMaster(c->master, x, y); |           tie(x,y) = cell_to_pair(c); | ||||||
|           int dy = ((short)y)%3; if(dy<0) dy += 3; |           int dy = gmod(y, 3); | ||||||
|           if(dy == 1) c->wall = waVinePlant; |           if(dy == 1) c->wall = waVinePlant; | ||||||
|           } |           } | ||||||
|         else { |         else { | ||||||
| @@ -1033,9 +1032,9 @@ void giantLandSwitch(cell *c, int d, cell *from) { | |||||||
|           if(pid == torusconfig::qty*2/3) c->wall = waGrounded; |           if(pid == torusconfig::qty*2/3) c->wall = waGrounded; | ||||||
|           } |           } | ||||||
|         else if(euclid) { |         else if(euclid) { | ||||||
|           eucoord x, y; |           int x,y; | ||||||
|           decodeMaster(c->master, x, y); |           tie(x,y) = cell_to_pair(c); | ||||||
|           if(short(x+1)%3 == 0 && short(y)%3 == 0) { |           if((x+1)%3 == 0 && y%3 == 0) { | ||||||
|             if(hrand(100) < 50) |             if(hrand(100) < 50) | ||||||
|               c->wall = hrand(2) ? waCharged : waGrounded; |               c->wall = hrand(2) ? waCharged : waGrounded; | ||||||
|             } |             } | ||||||
| @@ -1043,8 +1042,8 @@ void giantLandSwitch(cell *c, int d, cell *from) { | |||||||
|             bool sand = false; |             bool sand = false; | ||||||
|             for(int i=0; i<c->type; i++) { |             for(int i=0; i<c->type; i++) { | ||||||
|               createMov(c, i); |               createMov(c, i); | ||||||
|               decodeMaster(c->mov[i]->master, x, y); |               tie(x,y) = cell_to_pair(c->mov[i]); | ||||||
|               if(short(x+1)%3 == 0 && short(y)%3 == 0) sand = true; |               if((x+1)%3 == 0 && (y)%3 == 0) sand = true; | ||||||
|               } |               } | ||||||
|             if(sand && hrand(100) < 20) |             if(sand && hrand(100) < 20) | ||||||
|               c->wall = waSandstone; |               c->wall = waSandstone; | ||||||
|   | |||||||
| @@ -102,7 +102,7 @@ namespace mapstream { | |||||||
|         save(fgeomextras[current_extra].current_prime_id); |         save(fgeomextras[current_extra].current_prime_id); | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|     addToQueue(bounded ? currentmap->gamestart() : cwt.c->master->c7); |     addToQueue((bounded || euclid) ? currentmap->gamestart() : cwt.c->master->c7); | ||||||
|     for(int i=0; i<size(cellbyid); i++) { |     for(int i=0; i<size(cellbyid); i++) { | ||||||
|       cell *c = cellbyid[i]; |       cell *c = cellbyid[i]; | ||||||
|       if(i) { |       if(i) { | ||||||
|   | |||||||
| @@ -674,7 +674,7 @@ namespace netgen { | |||||||
|           } |           } | ||||||
|         if(!created) { |         if(!created) { | ||||||
|           View = Id; |           View = Id; | ||||||
|           if(centerover) viewctr.h = centerover->master; |           if(centerover.c) viewctr.h = centerover.c->master; | ||||||
|           else viewctr.h = cwt.c->master; |           else viewctr.h = cwt.c->master; | ||||||
|           playermoved = false; |           playermoved = false; | ||||||
|           dataFromHR(); |           dataFromHR(); | ||||||
| @@ -690,7 +690,7 @@ namespace netgen { | |||||||
|         } |         } | ||||||
|       if(uni == 's') { |       if(uni == 's') { | ||||||
|         View = Id; |         View = Id; | ||||||
|         if(centerover) viewctr.h = centerover->master; |         if(centerover.c) viewctr.h = centerover.c->master; | ||||||
|         else viewctr.h = cwt.c->master; |         else viewctr.h = cwt.c->master; | ||||||
|         playermoved = false; |         playermoved = false; | ||||||
|         } |         } | ||||||
|   | |||||||
							
								
								
									
										41
									
								
								pattern2.cpp
									
									
									
									
									
								
							
							
						
						
									
										41
									
								
								pattern2.cpp
									
									
									
									
									
								
							| @@ -3,25 +3,21 @@ | |||||||
| // Copyright (C) 2011-2017 Zeno Rogue, see 'hyper.cpp' for details | // Copyright (C) 2011-2017 Zeno Rogue, see 'hyper.cpp' for details | ||||||
|  |  | ||||||
| int eupattern(cell *c) { | int eupattern(cell *c) { | ||||||
|  |   int v = cell_to_vec(c); | ||||||
|   if(a4) { |   if(a4) { | ||||||
|     if(torus) return (decodeId(c->master)*2) % 3; |     int x, y; | ||||||
|     eucoord x, y; |     tie(x,y) = vec_to_pair(v); | ||||||
|     decodeMaster(c->master, x, y); |  | ||||||
|     return ((x&1) + 2*(y&1)) % 3; |     return ((x&1) + 2*(y&1)) % 3; | ||||||
|     } |     } | ||||||
|   if(torus) return (decodeId(c->master)*2) % 3; |   else { | ||||||
|   eucoord x, y; |     return gmod(v*2, 3); | ||||||
|   decodeMaster(c->master, x, y); |     } | ||||||
|   short z = (short(y+2*x))%3; |  | ||||||
|   z %= 3; |  | ||||||
|   if(z<0) z += 3; |  | ||||||
|   return z; |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
| int eupattern4(cell *c) { | int eupattern4(cell *c) { | ||||||
|   if(torus) return 0; |   int v = cell_to_vec(c); | ||||||
|   eucoord x, y; |   int x, y; | ||||||
|   decodeMaster(c->master, x, y); |   tie(x,y) = vec_to_pair(v); | ||||||
|   return (x&1) + ((y&1)) * 2; |   return (x&1) + ((y&1)) * 2; | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -58,14 +54,14 @@ unsigned bitmajority(unsigned a, unsigned b, unsigned c) { | |||||||
|   } |   } | ||||||
|  |  | ||||||
| int eufifty(cell *c) { | int eufifty(cell *c) { | ||||||
|   eucoord x, y; |  | ||||||
|   if(torus) { |   if(torus) { | ||||||
|     if(c->land == laWildWest) return decodeId(c->master) % 37; |     if(c->land == laWildWest) return cell_to_vec(c) % 37; | ||||||
|     else return decodeId(c->master) % 27; |     else return cell_to_vec(c) % 27; | ||||||
|     } |     } | ||||||
|   decodeMaster(c->master, x, y); |   int x, y; | ||||||
|   int ix = short(x) + 99999 + short(y); |   tie(x,y) = cell_to_pair(c); | ||||||
|   int iy = short(y) + 99999; |   int ix = x + 99999 + y; | ||||||
|  |   int iy = y + 99999; | ||||||
|   if(c->land == laWildWest)  |   if(c->land == laWildWest)  | ||||||
|     return (ix + iy * 26 + 28) % 37; |     return (ix + iy * 26 + 28) % 37; | ||||||
|   else { |   else { | ||||||
| @@ -314,12 +310,7 @@ int fieldval_uniq(cell *c) { | |||||||
|     return decodeId(c->master); |     return decodeId(c->master); | ||||||
|     } |     } | ||||||
|   else if(euclid) { |   else if(euclid) { | ||||||
|     eucoord x, y; |     return torusconfig::vec_to_id(cell_to_vec(c)); | ||||||
|     decodeMaster(c->master, x, y); |  | ||||||
|     int i = (short int)(x) * torusconfig::dx + (short int)(y) * torusconfig::dy; |  | ||||||
|     i %= torusconfig::qty; |  | ||||||
|     if(i<0) i += torusconfig::qty; |  | ||||||
|     return i; |  | ||||||
|     } |     } | ||||||
|   if(ctof(c)) return c->master->fieldval/S7; |   if(ctof(c)) return c->master->fieldval/S7; | ||||||
|   else { |   else { | ||||||
|   | |||||||
							
								
								
									
										12
									
								
								rug.cpp
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								rug.cpp
									
									
									
									
									
								
							| @@ -664,10 +664,10 @@ void preset(rugpoint *m) { | |||||||
|       double c2 = b->edges[k2].len/blen; |       double c2 = b->edges[k2].len/blen; | ||||||
|        |        | ||||||
|       double cz = (c1*c1-c2*c2+1) / 2; |       double cz = (c1*c1-c2*c2+1) / 2; | ||||||
|       double ch = sqrt(c2*c2 - cz*cz); |       double ch = sqrt(c2*c2 - cz*cz + 1e-10); | ||||||
|  |  | ||||||
|       double az = (a1*a1-a2*a2+1) / 2; |       double az = (a1*a1-a2*a2+1) / 2; | ||||||
|       double ah = sqrt(a2*a2 - az*az); |       double ah = sqrt(a2*a2 - az*az + 1e-10); | ||||||
|        |        | ||||||
|       // c->h = a->h + (b->h-a->h) * cz + ch * ort |       // c->h = a->h + (b->h-a->h) * cz + ch * ort | ||||||
|       hyperpoint ort = (c->flat - a->flat - cz * (b->flat-a->flat)) / ch; |       hyperpoint ort = (c->flat - a->flat - cz * (b->flat-a->flat)) / ch; | ||||||
| @@ -675,14 +675,17 @@ void preset(rugpoint *m) { | |||||||
|       // m->h = a->h + (b->h-a->h) * az - ah * ort |       // m->h = a->h + (b->h-a->h) * az - ah * ort | ||||||
|       hyperpoint res = a->flat + (b->flat-a->flat) * az - ah * ort; |       hyperpoint res = a->flat + (b->flat-a->flat) * az - ah * ort; | ||||||
|        |        | ||||||
|       for(int i=0; i<3; i++) h[i] += res[i]; |       h += res; | ||||||
|        |        | ||||||
|       preset_points.emplace_back(hypot(blen * (ah+ch), blen * (az-cz)), c); |       preset_points.emplace_back(hypot(blen * (ah+ch), blen * (az-cz)), c); | ||||||
|       q++; |       q++; | ||||||
|  |        | ||||||
|  |       printf("A %lf %lf %lf %lf C %lf %lf %lf %lf\n", a1, a2, az, ah, c1, c2, cz, ch); | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|      |      | ||||||
|   if(q>0) for(int i=0; i<3; i++) m->flat[i] = h[i]/q; |   if(q>0) m->flat = h/q; | ||||||
|  |   printf("preset (%d) -> %s\n", q, display(m->flat)); | ||||||
|   } |   } | ||||||
|  |  | ||||||
| ld sse(hyperpoint h) { | ld sse(hyperpoint h) { | ||||||
| @@ -1164,6 +1167,7 @@ void actDraw() { | |||||||
|   Uint8 *keystate = SDL_GetKeyState(NULL); |   Uint8 *keystate = SDL_GetKeyState(NULL); | ||||||
|   int qm = 0; |   int qm = 0; | ||||||
|   double alpha = (ticks - lastticks) / 1000.0; |   double alpha = (ticks - lastticks) / 1000.0; | ||||||
|  |   alpha /= 2.5; | ||||||
|   lastticks = ticks; |   lastticks = ticks; | ||||||
|  |  | ||||||
|   transmatrix t = Id; |   transmatrix t = Id; | ||||||
|   | |||||||
							
								
								
									
										12
									
								
								shmup.cpp
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								shmup.cpp
									
									
									
									
									
								
							| @@ -3328,19 +3328,11 @@ transmatrix &ggmatrix(cell *c) { | |||||||
|   if(t[2][2] == 0) { |   if(t[2][2] == 0) { | ||||||
|     if(torus) { |     if(torus) { | ||||||
|       forCellIdEx(c2, i, c) |       forCellIdEx(c2, i, c) | ||||||
|         if(celldistance(c2, centerover) < celldistance(c, centerover)) |         if(celldistance(c2, centerover.c) < celldistance(c, centerover.c)) | ||||||
|           t = ggmatrix(c2) * eumovedir(3+i); |           t = ggmatrix(c2) * eumovedir(3+i); | ||||||
|       } |       } | ||||||
|     else if(euclid) { |     else if(euclid) { | ||||||
|       eucoord xh, yh, xc, yc; |       t = gmatrix[centerover.c] * eumove(cell_to_vec(c) - cellwalker_to_vec(centerover)); | ||||||
|       decodeMaster(c->master, xh, yh); |  | ||||||
|       decodeMaster(centerover->master, xc, yc); |  | ||||||
|       short xd(xh-xc), yd(yh-yc); |  | ||||||
|       t = gmatrix[centerover] * eumove(xd, yd); |  | ||||||
|       /* printf("H[%d,%d] C[%d,%d] ", int(xh),int(yh), int(xc),int(yc)); |  | ||||||
|       printf("%d,%d t = \n", xd, yd); display(t); |  | ||||||
|       printf("gmatrix0 = \n"); |  | ||||||
|       display(gmatrix0[c]); */ |  | ||||||
|       } |       } | ||||||
|     else |     else | ||||||
|       t = actualV(viewctr, cview()) * calc_relative_matrix(c, viewctr.h); |       t = actualV(viewctr, cview()) * calc_relative_matrix(c, viewctr.h); | ||||||
|   | |||||||
| @@ -151,10 +151,10 @@ void initgame() { | |||||||
|    |    | ||||||
|   yendor::init(2); |   yendor::init(2); | ||||||
|    |    | ||||||
|   for(int i=0; i<65536; i++) euland[i] = laNone; |   clear_euland(specialland); | ||||||
|  |  | ||||||
|   if(euclid && specialland == laPrincessQuest) { |   if(euclid && specialland == laPrincessQuest) { | ||||||
|     cell *c = euclideanAtCreate(EPX, EPY); |     cell *c = euclideanAtCreate(pair_to_vec(EPX, EPY)); | ||||||
|     princess::generating = true; |     princess::generating = true; | ||||||
|     c->land = laPalace; |     c->land = laPalace; | ||||||
|     for(int j=BARLEV; j>=0; j--) setdist(c, j, NULL); |     for(int j=BARLEV; j>=0; j--) setdist(c, j, NULL); | ||||||
|   | |||||||
| @@ -641,7 +641,7 @@ void init_textureconfig() { | |||||||
|   addsaver(patterns::whichPattern, "pattern", 0); |   addsaver(patterns::whichPattern, "pattern", 0); | ||||||
|   addsaver(patterns::subpattern_flags, "pattern flags", 0); |   addsaver(patterns::subpattern_flags, "pattern flags", 0); | ||||||
|  |  | ||||||
|   cell *ctr = euclid ? centerover : viewctr.h->c7; |   cell *ctr = euclid ? centerover.c : viewctr.h->c7; | ||||||
|   si_save = patterns::getpatterninfo0(ctr); |   si_save = patterns::getpatterninfo0(ctr); | ||||||
|    |    | ||||||
|   addsaver(si_save.id, "center type", 1); |   addsaver(si_save.id, "center type", 1); | ||||||
|   | |||||||
							
								
								
									
										8
									
								
								util.cpp
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								util.cpp
									
									
									
									
									
								
							| @@ -55,6 +55,11 @@ int gcd(int i, int j) { | |||||||
|   return i ? gcd(j%i, i) : j; |   return i ? gcd(j%i, i) : j; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  | int gmod(int i, int j) { | ||||||
|  |   i %= j; if(i<0) i += j; | ||||||
|  |   return i; | ||||||
|  |   } | ||||||
|  |  | ||||||
| // debug utilities | // debug utilities | ||||||
|  |  | ||||||
| extern FILE *debugfile; | extern FILE *debugfile; | ||||||
| @@ -116,3 +121,6 @@ void profile_info() { | |||||||
| #define profile_info() | #define profile_info() | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | int whateveri, whateveri2; | ||||||
|  |  | ||||||
|  | purehookset hooks_tests; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Zeno Rogue
					Zeno Rogue