mirror of
				https://github.com/zenorogue/hyperrogue.git
				synced 2025-10-30 21:42:59 +00:00 
			
		
		
		
	expansion, ctrl+E cheat, fix with distance calculation
This commit is contained in:
		
							
								
								
									
										755
									
								
								cell.cpp
									
									
									
									
									
								
							
							
						
						
									
										755
									
								
								cell.cpp
									
									
									
									
									
								
							| @@ -1,9 +1,10 @@ | ||||
|                      | ||||
| // Hyperbolic Rogue -- cells | ||||
| // Copyright (C) 2011-2016 Zeno Rogue, see 'hyper.cpp' for details | ||||
|  | ||||
| // cells the game is played on | ||||
|  | ||||
| #define DEBMEM(x) // { x fflush(stdout); } | ||||
|                      | ||||
| int fix6(int a) { return (a+96)% 6; } | ||||
| int fix7(int a) { return (a+420)%S7; } | ||||
|  | ||||
| @@ -61,8 +62,260 @@ typedef unsigned short eucoord; | ||||
|  | ||||
| #include <map> | ||||
|  | ||||
| struct cdata { | ||||
|   int val[4]; | ||||
|   int bits; | ||||
|   }; | ||||
|  | ||||
| // list all cells in distance at most maxdist, or until when maxcount cells are reached | ||||
|  | ||||
| struct celllister { | ||||
|   vector<cell*> lst; | ||||
|   vector<int> tmps; | ||||
|   vector<int> dists; | ||||
|    | ||||
|   bool listed(cell *c) { | ||||
|     return c->aitmp >= 0 && c->aitmp < size(lst) && lst[c->aitmp] == c; | ||||
|     } | ||||
|    | ||||
|   void add(cell *c, int d) { | ||||
|     if(listed(c)) return; | ||||
|     c->aitmp = size(lst); | ||||
|     tmps.push_back(c->aitmp); | ||||
|     lst.push_back(c); | ||||
|     dists.push_back(d); | ||||
|     } | ||||
|    | ||||
|   int getdist(cell *c) { return dists[c->aitmp]; } | ||||
|    | ||||
|   ~celllister() { | ||||
|     for(int i=0; i<size(lst); i++) lst[i]->aitmp = tmps[i]; | ||||
|     } | ||||
|    | ||||
|   celllister(cell *orig, int maxdist, int maxcount, cell *breakon) { | ||||
|     lst.clear(); | ||||
|     tmps.clear(); | ||||
|     dists.clear(); | ||||
|     add(orig, 0); | ||||
|     cell *last = orig; | ||||
|     for(int i=0; i<size(lst); i++) { | ||||
|       cell *c = lst[i]; | ||||
|       if(maxdist) forCellCM(c2, c) { | ||||
|         add(c2, dists[i]+1); | ||||
|         if(c2 == breakon) return; | ||||
|         } | ||||
|       if(c == last) { | ||||
|         if(size(lst) >= maxcount || dists[i]+1 == maxdist) break; | ||||
|         last = lst[size(lst)-1]; | ||||
|         maxdist--; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   }; | ||||
|  | ||||
| // -- hrmap --- | ||||
|  | ||||
| #include <typeinfo> | ||||
|  | ||||
| struct hrmap { | ||||
|   virtual heptagon *getOrigin() { return NULL; } | ||||
|   virtual cell *gamestart() { return getOrigin()->c7; } | ||||
|   virtual ~hrmap() { printf("removing %s\n", typeid(this).name()); }; | ||||
|   virtual vector<cell*>& allcells() { return dcal; } | ||||
|   virtual void verify() { } | ||||
|   }; | ||||
|  | ||||
| hrmap *currentmap; | ||||
| vector<hrmap*> allmaps; | ||||
|  | ||||
| // --- auxiliary hyperbolic map for horocycles --- | ||||
| struct hrmap_alternate : hrmap { | ||||
|   heptagon *origin; | ||||
|   hrmap_alternate(heptagon *o) { origin = o; } | ||||
|   ~hrmap_alternate() { clearfrom(origin); } | ||||
|   }; | ||||
|  | ||||
| // --- hyperbolic geometry --- | ||||
|  | ||||
| struct hrmap_hyperbolic : hrmap { | ||||
|   heptagon *origin; | ||||
|   hrmap_hyperbolic() { | ||||
|     origin = new heptagon; | ||||
|     heptagon& h = *origin; | ||||
|     h.s = hsOrigin; | ||||
|     h.emeraldval = 98; | ||||
|     h.zebraval = 40; | ||||
|     h.fiftyval = 0; | ||||
|     h.fieldval = 0; | ||||
|     h.rval0 = h.rval1 = 0; | ||||
|     h.cdata = NULL; | ||||
|     for(int i=0; i<7; i++) h.move[i] = NULL; | ||||
|     h.spintable = 0; | ||||
|     h.alt = NULL; | ||||
|     h.distance = 0; | ||||
|     h.c7 = newCell(7, origin); | ||||
|     } | ||||
|   heptagon *getOrigin() { return origin; } | ||||
|   ~hrmap_hyperbolic() { | ||||
|     DEBMEM ( verifycells(origin); ) | ||||
|     clearfrom(origin); | ||||
|     } | ||||
|   void verify() { verifycells(origin); } | ||||
|   }; | ||||
|  | ||||
| // --- spherical geometry --- | ||||
|  | ||||
| int spherecells() { | ||||
|   if(S7 == 5) return (elliptic?6:12); | ||||
|   if(S7 == 4) return (elliptic?3:6); | ||||
|   if(S7 == 3) return 4; | ||||
|   if(S7 == 2) return (elliptic?1:2); | ||||
|   if(S7 == 1) return 1; | ||||
|   return 12; | ||||
|   } | ||||
|    | ||||
| struct hrmap_spherical : hrmap { | ||||
|   heptagon *dodecahedron[12]; | ||||
|  | ||||
|   hrmap_spherical() { | ||||
|     for(int i=0; i<spherecells(); i++) { | ||||
|       heptagon& h = *(dodecahedron[i] = new heptagon); | ||||
|       h.s = hsOrigin; | ||||
|       h.emeraldval = i; | ||||
|       h.zebraval = i; | ||||
|       h.fiftyval = i; | ||||
|       h.rval0 = h.rval1 = 0; | ||||
|       h.alt = NULL; | ||||
|       h.cdata = NULL; | ||||
|       h.spintable = 0; | ||||
|       for(int i=0; i<S7; i++) h.move[i] = NULL; | ||||
|       h.c7 = newCell(S7, &h); | ||||
|       } | ||||
|    for(int i=0; i<S7; i++) { | ||||
|       dodecahedron[0]->move[i] = dodecahedron[i+1]; | ||||
|       dodecahedron[0]->setspin(i, 0); | ||||
|       dodecahedron[i+1]->move[0] = dodecahedron[0]; | ||||
|       dodecahedron[i+1]->setspin(0, i); | ||||
|        | ||||
|       dodecahedron[i+1]->move[1] = dodecahedron[(i+S7-1)%S7+1]; | ||||
|       dodecahedron[i+1]->setspin(1, S7-1); | ||||
|       dodecahedron[i+1]->move[S7-1] = dodecahedron[(i+1)%S7+1]; | ||||
|       dodecahedron[i+1]->setspin(S7-1, 1); | ||||
|        | ||||
|       if(S7 == 5 && elliptic) { | ||||
|         dodecahedron[i+1]->move[2] = dodecahedron[(i+2)%S7+1]; | ||||
|         dodecahedron[i+1]->setspin(2, 3 + 8); | ||||
|         dodecahedron[i+1]->move[3] = dodecahedron[(i+3)%S7+1]; | ||||
|         dodecahedron[i+1]->setspin(3, 2 + 8); | ||||
|         } | ||||
|  | ||||
|       else if(S7 == 5) { | ||||
|         dodecahedron[6]->move[i] = dodecahedron[7+i]; | ||||
|         dodecahedron[6]->setspin(i, 0); | ||||
|         dodecahedron[7+i]->move[0] = dodecahedron[6]; | ||||
|         dodecahedron[7+i]->setspin(0, i); | ||||
|    | ||||
|         dodecahedron[i+7]->move[1] = dodecahedron[(i+4)%5+7]; | ||||
|         dodecahedron[i+7]->setspin(1, 4); | ||||
|         dodecahedron[i+7]->move[4] = dodecahedron[(i+1)%5+7]; | ||||
|         dodecahedron[i+7]->setspin(4, 1); | ||||
|          | ||||
|         dodecahedron[i+1]->move[2] = dodecahedron[7+(10-i)%5]; | ||||
|         dodecahedron[i+1]->setspin(2, 2); | ||||
|         dodecahedron[7+(10-i)%5]->move[2] = dodecahedron[1+i]; | ||||
|         dodecahedron[7+(10-i)%5]->setspin(2, 2); | ||||
|    | ||||
|         dodecahedron[i+1]->move[3] = dodecahedron[7+(9-i)%5]; | ||||
|         dodecahedron[i+1]->setspin(3, 3); | ||||
|         dodecahedron[7+(9-i)%5]->move[3] = dodecahedron[i+1]; | ||||
|         dodecahedron[7+(9-i)%5]->setspin(3, 3); | ||||
|         } | ||||
|       if(S7 == 4) { | ||||
|         dodecahedron[5]->move[3-i] = dodecahedron[i+1]; | ||||
|         dodecahedron[5]->setspin(3-i, 2); | ||||
|         dodecahedron[i+1]->move[2] = dodecahedron[5]; | ||||
|         dodecahedron[i+1]->setspin(2, 3-i); | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|  | ||||
|   heptagon *getOrigin() { return dodecahedron[0]; } | ||||
|  | ||||
|    ~hrmap_spherical() { | ||||
|     for(int i=0; i<spherecells(); i++) clearHexes(dodecahedron[i]); | ||||
|     for(int i=0; i<spherecells(); i++) delete dodecahedron[i]; | ||||
|     }     | ||||
|  | ||||
|   void verify() { | ||||
|     for(int i=0; i<spherecells(); i++) for(int k=0; k<S7; k++) { | ||||
|       heptspin hs; | ||||
|       hs.h = dodecahedron[i]; | ||||
|       hs.spin = k; | ||||
|       hs = hsstep(hs, 0); | ||||
|       hs = hsspin(hs, S7-1); | ||||
|       hs = hsstep(hs, 0); | ||||
|       hs = hsspin(hs, S7-1); | ||||
|       hs = hsstep(hs, 0); | ||||
|       hs = hsspin(hs, S7-1); | ||||
|       if(hs.h != dodecahedron[i]) printf("error %d,%d\n", i, k); | ||||
|       } | ||||
|     for(int i=0; i<spherecells(); i++) verifycells(dodecahedron[i]); | ||||
|     } | ||||
|   }; | ||||
|  | ||||
| heptagon *getDodecahedron(int i) { | ||||
|   hrmap_spherical *s = dynamic_cast<hrmap_spherical*> (currentmap); | ||||
|   if(!s) return NULL; | ||||
|   return s->dodecahedron[i]; | ||||
|   } | ||||
|  | ||||
| // --- euclidean geometry --- | ||||
|  | ||||
| cell*& euclideanAtCreate(eucoord x, eucoord y); | ||||
|  | ||||
| struct hrmap_euclidean : hrmap { | ||||
|  | ||||
|   cell *gamestart() { | ||||
|     return euclideanAtCreate(0,0); | ||||
|     } | ||||
|  | ||||
|   struct euclideanSlab { | ||||
|     cell* a[256][256]; | ||||
|     euclideanSlab() { | ||||
|       for(int y=0; y<256; y++) for(int x=0; x<256; x++) | ||||
|         a[y][x] = NULL; | ||||
|       } | ||||
|     ~euclideanSlab() { | ||||
|       for(int y=0; y<256; y++) for(int x=0; x<256; x++) | ||||
|         if(a[y][x]) delete a[y][x]; | ||||
|       } | ||||
|     }; | ||||
|    | ||||
|   euclideanSlab* euclidean[256][256]; | ||||
|    | ||||
|   hrmap_euclidean() { | ||||
|     for(int y=0; y<256; y++) for(int x=0; x<256; x++) | ||||
|       euclidean[y][x] = NULL; | ||||
|     } | ||||
|    | ||||
|   cell*& at(eucoord x, eucoord y) { | ||||
|     euclideanSlab*& slab = euclidean[y>>8][x>>8]; | ||||
|     if(!slab) slab = new hrmap_euclidean::euclideanSlab; | ||||
|     return slab->a[y&255][x&255]; | ||||
|     } | ||||
|    | ||||
|   map<heptagon*, struct cdata> eucdata; | ||||
|  | ||||
|   ~hrmap_euclidean() { | ||||
|     for(int y=0; y<256; y++) for(int x=0; x<256; x++) | ||||
|       if(euclidean[y][x]) {  | ||||
|         delete euclidean[y][x]; | ||||
|         euclidean[y][x] = NULL; | ||||
|         } | ||||
|     eucdata.clear(); | ||||
|     } | ||||
|   }; | ||||
|  | ||||
| union heptacoder { | ||||
|   heptagon *h; | ||||
|   struct { eucoord x; eucoord y; } c; | ||||
| @@ -79,6 +332,145 @@ heptagon* encodeMaster(eucoord x, eucoord y) { | ||||
|   return u.h; | ||||
|   } | ||||
|  | ||||
| // --- quotient geometry --- | ||||
|  | ||||
| namespace quotientspace { | ||||
|   struct code { | ||||
|     int c[8]; | ||||
|     }; | ||||
|    | ||||
|   bool operator == (const code& c1, const code &c2) { | ||||
|     for(int i=0; i<8; i++) if(c1.c[i] != c2.c[i]) return false; | ||||
|     return true; | ||||
|     } | ||||
|  | ||||
|   bool operator < (const code& c1, const code &c2) { | ||||
|     for(int i=0; i<8; i++) if(c1.c[i] != c2.c[i]) return c1.c[i] < c2.c[i]; | ||||
|     return false; | ||||
|     }   | ||||
|  | ||||
|   int cod(heptagon *h) { | ||||
|     return zebra40(h->c7); | ||||
|     } | ||||
|    | ||||
|   code get(heptspin hs) { | ||||
|     code res; | ||||
|     res.c[0] = cod(hs.h); | ||||
|     for(int i=1; i<8; i++) { | ||||
|       res.c[i] = cod(hsstep(hs, 0).h); | ||||
|       hs = hsspin(hs, 1); | ||||
|       } | ||||
|     return res; | ||||
|     } | ||||
|    | ||||
|   int rvadd = 0, rvdir = 1; | ||||
|    | ||||
|   int rv(int x) { return (rvadd+x*rvdir) % 7; } | ||||
|    | ||||
| struct hrmap_quotient : hrmap { | ||||
|  | ||||
|   hrmap_hyperbolic base; | ||||
|    | ||||
|   vector<cell*> celllist; | ||||
|    | ||||
|   cell *origin; | ||||
|    | ||||
|   map<quotientspace::code, int> reachable; | ||||
|   vector<heptspin> bfsq; | ||||
|    | ||||
|   vector<int> connections; | ||||
|    | ||||
|   void add(const heptspin& hs) { | ||||
|     code g = get(hs); | ||||
|     if(!reachable.count(g)) { | ||||
|       reachable[g] = bfsq.size(); | ||||
|       bfsq.push_back(hs); | ||||
|       add(hsspin(hs, 1)); | ||||
|       } | ||||
|     } | ||||
|  | ||||
|   vector<heptagon*> allh; | ||||
|    | ||||
|   hrmap_quotient() { | ||||
|    | ||||
|     if(quotient == 2) { | ||||
|       connections = fp43.connections; | ||||
|       } | ||||
|     else { | ||||
|       heptspin hs; hs.h = base.origin; hs.spin = 0; | ||||
|       reachable.clear(); | ||||
|       bfsq.clear(); | ||||
|       connections.clear(); | ||||
|       add(hs); | ||||
|  | ||||
|       for(int i=0; i<(int)bfsq.size(); i++) { | ||||
|         hs = hsstep(bfsq[i], 0); | ||||
|         add(hs); | ||||
|         connections.push_back(reachable[get(hs)]); | ||||
|         } | ||||
|  | ||||
|       } | ||||
|      | ||||
|     int TOT = connections.size() / 7; | ||||
|     printf("heptagons = %d\n", TOT); | ||||
|     printf("all cells = %d\n", TOT*10/3); | ||||
|     if(!TOT) exit(1); | ||||
|     allh.resize(TOT); | ||||
|     for(int i=0; i<TOT; i++) allh[i] = new heptagon; | ||||
|     // heptagon *oldorigin = origin; | ||||
|     allh[0]->alt = base.origin; | ||||
|    | ||||
|     for(int i=0; i<TOT; i++) { | ||||
|       heptagon *h = allh[i]; | ||||
|       if(i) { | ||||
|         h->alt = NULL; | ||||
|         } | ||||
|       if(true) { | ||||
|         h->s = hsOrigin; | ||||
|         h->emeraldval = 0; | ||||
|         h->zebraval = 0; | ||||
|         h->fiftyval = 0; | ||||
|         h->fieldval = 7*i; | ||||
|         h->rval0 = h->rval1 = 0; h->cdata = NULL; | ||||
|         h->distance = 0; | ||||
|         h->c7 = newCell(7, h); | ||||
|         } | ||||
|       for(int j=0; j<7; j++) { | ||||
|         h->move[rv(j)] = allh[connections[i*7+j]/7]; | ||||
|         h->setspin(rv(j), rv(connections[i*7+j]%7)); | ||||
|         } | ||||
|       } | ||||
|    | ||||
|     for(int i=0; i<TOT; i++) { | ||||
|       generateAlts(allh[i]); | ||||
|       allh[i]->emeraldval = allh[i]->alt->emeraldval; | ||||
|       allh[i]->zebraval = allh[i]->alt->zebraval; | ||||
|       allh[i]->fiftyval = allh[i]->alt->fiftyval; | ||||
|       allh[i]->distance = allh[i]->alt->distance; | ||||
|       /* for(int j=0; j<7; j++) | ||||
|         allh[i]->move[j]->alt = createStep(allh[i]->alt, j); */ | ||||
|       }     | ||||
|      | ||||
|     celllister cl(gamestart(), 100, 100000000, NULL); | ||||
|     celllist = cl.lst; | ||||
|     } | ||||
|  | ||||
|   heptagon *getOrigin() { return allh[0]; } | ||||
|  | ||||
|   ~hrmap_quotient() { | ||||
|     for(int i=0; i<size(allh); i++) { | ||||
|       clearHexes(allh[i]); | ||||
|       delete allh[i]; | ||||
|       } | ||||
|     } | ||||
|    | ||||
|   vector<cell*>& allcells() { return celllist; } | ||||
|   }; | ||||
|  | ||||
|   }; | ||||
|  | ||||
| // --- general --- | ||||
|  | ||||
| // very similar to createMove in heptagon.cpp | ||||
| cell *createMov(cell *c, int d) { | ||||
|  | ||||
| @@ -193,32 +585,17 @@ void eumerge(cell* c1, cell *c2, int s1, int s2) { | ||||
|   c2->mov[s2] = c1; tsetspin(c2->spintable, s2, s1); | ||||
|   }        | ||||
|  | ||||
| struct euclideanSlab { | ||||
|   cell* a[256][256]; | ||||
|   euclideanSlab() { | ||||
|     for(int y=0; y<256; y++) for(int x=0; x<256; x++) | ||||
|       a[y][x] = NULL; | ||||
|     } | ||||
|   ~euclideanSlab() { | ||||
|     for(int y=0; y<256; y++) for(int x=0; x<256; x++) | ||||
|       if(a[y][x]) delete a[y][x]; | ||||
|     } | ||||
|   }; | ||||
|  | ||||
| euclideanSlab* euclidean[256][256]; | ||||
|  | ||||
| //  map<pair<eucoord, eucoord>, cell*> euclidean; | ||||
|  | ||||
| cell*& euclideanAt(eucoord x, eucoord y) { | ||||
|   euclideanSlab*& slab(euclidean[y>>8][x>>8]); | ||||
|   if(!slab) slab = new euclideanSlab; | ||||
|   return slab->a[y&255][x&255]; | ||||
|   hrmap_euclidean* euc = dynamic_cast<hrmap_euclidean*> (currentmap); | ||||
|   return euc->at(x, y); | ||||
|   } | ||||
|  | ||||
| cell*& euclideanAtCreate(eucoord x, eucoord y) { | ||||
|   cell*& c ( euclideanAt(x,y) ); | ||||
|   cell*& c = euclideanAt(x,y); | ||||
|   if(!c) { | ||||
|     c = newCell(6, &origin); | ||||
|     c = newCell(6, NULL); | ||||
|     c->master = encodeMaster(x,y); | ||||
|     euclideanAt(x,y) = c; | ||||
|     eumerge(c, euclideanAt(x+1,y), 0, 3); | ||||
| @@ -231,104 +608,20 @@ cell*& euclideanAtCreate(eucoord x, eucoord y) { | ||||
|   return c; | ||||
|   } | ||||
|  | ||||
| int spherecells() { | ||||
|   if(S7 == 5) return (elliptic?6:12); | ||||
|   if(S7 == 4) return (elliptic?3:6); | ||||
|   if(S7 == 3) return 4; | ||||
|   if(S7 == 2) return (elliptic?1:2); | ||||
|   if(S7 == 1) return 1; | ||||
|   return 12; | ||||
|   } | ||||
|  | ||||
| // initializer (also inits origin from heptagon.cpp) | ||||
| void initcells() { | ||||
|   DEBB(DF_INIT, (debugfile,"initcells\n")); | ||||
|    | ||||
|   if(sphere) { | ||||
|     for(int i=0; i<spherecells(); i++) { | ||||
|       heptagon& h = dodecahedron[i]; | ||||
|       h.s = hsOrigin; | ||||
|       h.emeraldval = i; | ||||
|       h.zebraval = i; | ||||
|       h.fiftyval = i; | ||||
|       h.rval0 = h.rval1 = 0; | ||||
|       h.alt = NULL; | ||||
|       h.cdata = NULL; | ||||
|       h.spintable = 0; | ||||
|       for(int i=0; i<S7; i++) h.move[i] = NULL; | ||||
|       h.c7 = newCell(S7, &h); | ||||
|       } | ||||
|    for(int i=0; i<S7; i++) { | ||||
|       dodecahedron[0].move[i] = &dodecahedron[i+1]; | ||||
|       dodecahedron[0].setspin(i, 0); | ||||
|       dodecahedron[i+1].move[0] = &dodecahedron[0]; | ||||
|       dodecahedron[i+1].setspin(0, i); | ||||
|   if(euclid) currentmap = new hrmap_euclidean; | ||||
|   else if(sphere) currentmap = new hrmap_spherical; | ||||
|   else if(quotient) currentmap = new quotientspace::hrmap_quotient; | ||||
|   else currentmap = new hrmap_hyperbolic; | ||||
|    | ||||
|       dodecahedron[i+1].move[1] = &dodecahedron[(i+S7-1)%S7+1]; | ||||
|       dodecahedron[i+1].setspin(1, S7-1); | ||||
|       dodecahedron[i+1].move[S7-1] = &dodecahedron[(i+1)%S7+1]; | ||||
|       dodecahedron[i+1].setspin(S7-1, 1); | ||||
|   allmaps.push_back(currentmap); | ||||
|    | ||||
|       if(S7 == 5 && elliptic) { | ||||
|         dodecahedron[i+1].move[2] = &dodecahedron[(i+2)%S7+1]; | ||||
|         dodecahedron[i+1].setspin(2, 3 + 8); | ||||
|         dodecahedron[i+1].move[3] = &dodecahedron[(i+3)%S7+1]; | ||||
|         dodecahedron[i+1].setspin(3, 2 + 8); | ||||
|   // origin->emeraldval =  | ||||
|   } | ||||
|  | ||||
|       else if(S7 == 5) { | ||||
|         dodecahedron[6].move[i] = &dodecahedron[7+i]; | ||||
|         dodecahedron[6].setspin(i, 0); | ||||
|         dodecahedron[7+i].move[0] = &dodecahedron[6]; | ||||
|         dodecahedron[7+i].setspin(0, i); | ||||
|    | ||||
|         dodecahedron[i+7].move[1] = &dodecahedron[(i+4)%5+7]; | ||||
|         dodecahedron[i+7].setspin(1, 4); | ||||
|         dodecahedron[i+7].move[4] = &dodecahedron[(i+1)%5+7]; | ||||
|         dodecahedron[i+7].setspin(4, 1); | ||||
|          | ||||
|         dodecahedron[i+1].move[2] = &dodecahedron[7+(10-i)%5]; | ||||
|         dodecahedron[i+1].setspin(2, 2); | ||||
|         dodecahedron[7+(10-i)%5].move[2] = &dodecahedron[1+i]; | ||||
|         dodecahedron[7+(10-i)%5].setspin(2, 2); | ||||
|    | ||||
|         dodecahedron[i+1].move[3] = &dodecahedron[7+(9-i)%5]; | ||||
|         dodecahedron[i+1].setspin(3, 3); | ||||
|         dodecahedron[7+(9-i)%5].move[3] = &dodecahedron[i+1]; | ||||
|         dodecahedron[7+(9-i)%5].setspin(3, 3); | ||||
|         } | ||||
|       if(S7 == 4) { | ||||
|         dodecahedron[5].move[3-i] = &dodecahedron[i+1]; | ||||
|         dodecahedron[5].setspin(3-i, 2); | ||||
|         dodecahedron[i+1].move[2] = &dodecahedron[5]; | ||||
|         dodecahedron[i+1].setspin(2, 3-i); | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   else { | ||||
|     origin.s = hsOrigin; | ||||
|     origin.emeraldval = 98; | ||||
|     origin.zebraval = 40; | ||||
|     origin.fiftyval = 0; | ||||
|     origin.fieldval = 0; | ||||
|     origin.rval0 = origin.rval1 = 0; | ||||
|     origin.cdata = NULL; | ||||
|     for(int i=0; i<7; i++) origin.move[i] = NULL; | ||||
|     origin.spintable = 0; | ||||
|     origin.alt = NULL; | ||||
|     origin.distance = 0; | ||||
|     if(euclid) | ||||
|       origin.c7 = euclideanAtCreate(0,0); | ||||
|     else | ||||
|       origin.c7 = newCell(7, &origin); | ||||
|     } | ||||
|  | ||||
|   if(quotient) quotientspace::build(); | ||||
|   // origin.emeraldval =  | ||||
|   } | ||||
|  | ||||
| #define DEBMEM(x) // { x fflush(stdout); } | ||||
|  | ||||
| void clearcell(cell *c) { | ||||
|   if(!c) return; | ||||
|   DEBMEM ( printf("c%d %p\n", c->type, c); ) | ||||
| @@ -380,7 +673,7 @@ void clearfrom(heptagon *at) { | ||||
|       at->move[i] = NULL; | ||||
|       } | ||||
|     clearHexes(at); | ||||
|     if(at != &origin) delete at; | ||||
|     delete at; | ||||
|     } | ||||
| //printf("maxq = %d\n", maxq); | ||||
|   } | ||||
| @@ -400,10 +693,11 @@ void verifycell(cell *c) { | ||||
|   } | ||||
|  | ||||
| void verifycells(heptagon *at) { | ||||
|   for(int i=0; i<7; i++) if(at->move[i] && at->move[i]->move[at->spin(i)] && at->move[i]->move[at->spin(i)] != at) { | ||||
|   for(int i=0; i<S7; i++) if(at->move[i] && at->move[i]->move[at->spin(i)] && at->move[i]->move[at->spin(i)] != at) { | ||||
|     printf("hexmix error %p [%d s=%d] %p %p\n", at, i, at->spin(i), at->move[i], at->move[i]->move[at->spin(i)]); | ||||
|     } | ||||
|   if(!sphere && !quotient) for(int i=0; i<7; i++) if(at->move[i] && at->spin(i) == 0 && at->move[i] != &origin) | ||||
|   if(!sphere && !quotient)  | ||||
|     for(int i=0; i<7; i++) if(at->move[i] && at->spin(i) == 0 && at->s != hsOrigin) | ||||
|       verifycells(at->move[i]); | ||||
|   verifycell(at->c7); | ||||
|   } | ||||
| @@ -807,12 +1101,6 @@ map<heptagon*, int> spins; | ||||
| #define RVAL_MASK 0x10000000 | ||||
| #define DATA_MASK 0x20000000 | ||||
|  | ||||
| struct cdata { | ||||
|   int val[4]; | ||||
|   int bits; | ||||
|   }; | ||||
|  | ||||
| map<heptagon*, struct cdata> eucdata; | ||||
| cdata orig_cdata; | ||||
|  | ||||
| void affect(cdata& d, short rv, signed char signum) { | ||||
| @@ -835,9 +1123,9 @@ void setHeptagonRval(heptagon *h) { | ||||
| cdata *getHeptagonCdata(heptagon *h) { | ||||
|   if(h->cdata) return h->cdata; | ||||
|  | ||||
|   if(sphere || quotient) h = &origin; | ||||
|   if(sphere || quotient) h = currentmap->gamestart()->master; | ||||
|  | ||||
|   if(h == &origin) { | ||||
|   if(h == currentmap->gamestart()->master) { | ||||
|     return h->cdata = new cdata(orig_cdata); | ||||
|     } | ||||
|    | ||||
| @@ -907,14 +1195,15 @@ cdata *getHeptagonCdata(heptagon *h) { | ||||
|  | ||||
| cdata *getEuclidCdata(heptagon *h) { | ||||
|   eucoord x, y; | ||||
|   if(eucdata.count(h)) return &(eucdata[h]); | ||||
|   hrmap_euclidean* euc = dynamic_cast<hrmap_euclidean*> (currentmap); | ||||
|   if(euc->eucdata.count(h)) return &(euc->eucdata[h]); | ||||
|   decodeMaster(h, x, y); | ||||
|  | ||||
|   if(x == 0 && y == 0) { | ||||
|     cdata xx; | ||||
|     for(int i=0; i<4; i++) xx.val[i] = 0; | ||||
|     xx.bits = 0; | ||||
|     return &(eucdata[h] = xx); | ||||
|     return &(euc->eucdata[h] = xx); | ||||
|     } | ||||
|   int ord = 1, bid = 0; | ||||
|   while(!((x|y)&ord)) ord <<= 1, bid++; | ||||
| @@ -946,7 +1235,7 @@ cdata *getEuclidCdata(heptagon *h) { | ||||
|       if(gbit) xx.bits |= (1<<b); | ||||
|       } | ||||
|      | ||||
|     return &(eucdata[h] = xx); | ||||
|     return &(euc->eucdata[h] = xx); | ||||
|     } | ||||
|    | ||||
|   // impossible! | ||||
| @@ -981,52 +1270,6 @@ eLand getCLand(cell *c) { | ||||
|   return land_scape[b & 31]; | ||||
|   } | ||||
|  | ||||
| // list all cells in distance at most maxdist, or until when maxcount cells are reached | ||||
|  | ||||
| struct celllister { | ||||
|   vector<cell*> lst; | ||||
|   vector<int> tmps; | ||||
|   vector<int> dists; | ||||
|    | ||||
|   bool listed(cell *c) { | ||||
|     return c->aitmp >= 0 && c->aitmp < size(lst) && lst[c->aitmp] == c; | ||||
|     } | ||||
|    | ||||
|   void add(cell *c, int d) { | ||||
|     if(listed(c)) return; | ||||
|     c->aitmp = size(lst); | ||||
|     tmps.push_back(c->aitmp); | ||||
|     lst.push_back(c); | ||||
|     dists.push_back(d); | ||||
|     } | ||||
|    | ||||
|   int getdist(cell *c) { return dists[c->aitmp]; } | ||||
|    | ||||
|   ~celllister() { | ||||
|     for(int i=0; i<size(lst); i++) lst[i]->aitmp = tmps[i]; | ||||
|     } | ||||
|    | ||||
|   celllister(cell *orig, int maxdist, int maxcount, cell *breakon) { | ||||
|     lst.clear(); | ||||
|     tmps.clear(); | ||||
|     dists.clear(); | ||||
|     add(orig, 0); | ||||
|     cell *last = orig; | ||||
|     for(int i=0; i<size(lst); i++) { | ||||
|       cell *c = lst[i]; | ||||
|       if(maxdist) forCellCM(c2, c) { | ||||
|         add(c2, dists[i]+1); | ||||
|         if(c2 == breakon) return; | ||||
|         } | ||||
|       if(c == last) { | ||||
|         if(size(lst) >= maxcount || dists[i]+1 == maxdist) break; | ||||
|         last = lst[size(lst)-1]; | ||||
|         maxdist--; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   }; | ||||
|  | ||||
| cell *heptatdir(cell *c, int d) { | ||||
|   if(d&1) { | ||||
|     cell *c2 = createMov(c, d); | ||||
| @@ -1098,6 +1341,9 @@ int celldistance(cell *c1, cell *c2) { | ||||
|     forCellEx(c, cl2) if(isNeighbor(c, cr1)) return d+2; | ||||
|     forCellEx(c, cl1) if(isNeighbor(c, cr2)) return d+2; | ||||
|  | ||||
|     forCellEx(ca, cl2) forCellEx(cb, cr1) if(isNeighbor(ca, cb)) return d+3; | ||||
|     forCellEx(ca, cl1) forCellEx(cb, cr2) if(isNeighbor(ca, cb)) return d+3; | ||||
|  | ||||
|     int d1 = celldist(cl1), d2 = celldist(cl2); | ||||
|      | ||||
|     if(d1 >= d2) { | ||||
| @@ -1117,28 +1363,9 @@ int celldistance(cell *c1, cell *c2) { | ||||
|     } | ||||
|   } | ||||
|  | ||||
| void clearHyperbolicMemory() { | ||||
|   DEBMEM ( verifycells(&origin); ) | ||||
|   clearfrom(&origin); | ||||
|   for(int i=0; i<size(allAlts); i++) clearfrom(allAlts[i]); | ||||
|   allAlts.clear(); | ||||
|   } | ||||
|  | ||||
| void clearCellMemory() { | ||||
|   // EUCLIDEAN | ||||
|   if(sphere) { | ||||
|     for(int i=0; i<spherecells(); i++) clearHexes(&dodecahedron[i]); | ||||
|     } | ||||
|   else if(quotient) quotientspace::clear(); | ||||
|   else if(euclid) { | ||||
|     for(int y=0; y<256; y++) for(int x=0; x<256; x++) | ||||
|       if(euclidean[y][x]) {  | ||||
|         delete euclidean[y][x]; | ||||
|         euclidean[y][x] = NULL; | ||||
|         } | ||||
|     eucdata.clear(); | ||||
|     } | ||||
|   else clearHyperbolicMemory(); | ||||
|   for(int i=0; i<size(allmaps); i++) delete allmaps[i]; | ||||
|   allmaps.clear(); | ||||
|   } | ||||
|  | ||||
| void clearMemory() { | ||||
| @@ -1153,22 +1380,6 @@ void clearMemory() { | ||||
|   DEBMEM ( printf("ok\n"); ) | ||||
|   } | ||||
|  | ||||
| void verifyDodecahedron() { | ||||
|   for(int i=0; i<spherecells(); i++) for(int k=0; k<S7; k++) { | ||||
|     heptspin hs; | ||||
|     hs.h = &dodecahedron[i]; | ||||
|     hs.spin = k; | ||||
|     hs = hsstep(hs, 0); | ||||
|     hs = hsspin(hs, S7-1); | ||||
|     hs = hsstep(hs, 0); | ||||
|     hs = hsspin(hs, S7-1); | ||||
|     hs = hsstep(hs, 0); | ||||
|     hs = hsspin(hs, S7-1); | ||||
|     if(hs.h != &dodecahedron[i]) printf("error %d,%d\n", i, k); | ||||
|     } | ||||
|   for(int i=0; i<spherecells(); i++) verifycells(&dodecahedron[i]); | ||||
|   } | ||||
|  | ||||
| int getHemisphere(cell *c, int which) { | ||||
|   if(c->type != 6) { | ||||
|     int id = c->master->fiftyval; | ||||
| @@ -1187,133 +1398,3 @@ int getHemisphere(cell *c, int which) { | ||||
|     } | ||||
|   } | ||||
|  | ||||
| namespace quotientspace { | ||||
|  | ||||
|   vector<cell*> allcells; | ||||
|    | ||||
|   struct code { | ||||
|     int c[8]; | ||||
|     }; | ||||
|    | ||||
|   bool operator == (const code& c1, const code &c2) { | ||||
|     for(int i=0; i<8; i++) if(c1.c[i] != c2.c[i]) return false; | ||||
|     return true; | ||||
|     } | ||||
|  | ||||
|   bool operator < (const code& c1, const code &c2) { | ||||
|     for(int i=0; i<8; i++) if(c1.c[i] != c2.c[i]) return c1.c[i] < c2.c[i]; | ||||
|     return false; | ||||
|     } | ||||
|    | ||||
|   map<code, int> reachable; | ||||
|   vector<heptspin> bfsq; | ||||
|    | ||||
|   int cod(heptagon *h) { | ||||
|     return zebra40(h->c7); | ||||
|     } | ||||
|    | ||||
|   code get(heptspin hs) { | ||||
|     code res; | ||||
|     res.c[0] = cod(hs.h); | ||||
|     for(int i=1; i<8; i++) { | ||||
|       res.c[i] = cod(hsstep(hs, 0).h); | ||||
|       hs = hsspin(hs, 1); | ||||
|       } | ||||
|     return res; | ||||
|     } | ||||
|    | ||||
|   vector<int> connections; | ||||
|    | ||||
|   int rvadd = 0, rvdir = 1; | ||||
|    | ||||
|   int rv(int x) { return (rvadd+x*rvdir) % 7; } // if(x) return 7-x; else return x; } | ||||
|    | ||||
|   void add(const heptspin& hs) { | ||||
|     code g = get(hs); | ||||
|     if(!reachable.count(g)) { | ||||
|       reachable[g] = bfsq.size(); | ||||
|       bfsq.push_back(hs); | ||||
|       add(hsspin(hs, 1)); | ||||
|       } | ||||
|     } | ||||
|  | ||||
|   vector<heptagon*> allh; | ||||
|    | ||||
|   void clear() { | ||||
|     clearfrom(origin.alt); | ||||
|     for(int i=0; i<size(allh); i++) { | ||||
|       clearHexes(allh[i]); | ||||
|       if(i) delete allh[i]; | ||||
|       } | ||||
|     allh.clear(); | ||||
|     allcells.clear(); | ||||
|     } | ||||
|    | ||||
|   void build() { | ||||
|    | ||||
|     if(quotient == 2) { | ||||
|       connections = fp43.connections; | ||||
|       } | ||||
|     else { | ||||
|       heptspin hs; hs.h = &origin; hs.spin = 0; | ||||
|       reachable.clear(); | ||||
|       bfsq.clear(); | ||||
|       connections.clear(); | ||||
|       add(hs); | ||||
|  | ||||
|       for(int i=0; i<(int)bfsq.size(); i++) { | ||||
|         hs = hsstep(bfsq[i], 0); | ||||
|         add(hs); | ||||
|         connections.push_back(reachable[get(hs)]); | ||||
|         } | ||||
|  | ||||
|       } | ||||
|      | ||||
|     clearHyperbolicMemory(); | ||||
|     origin.c7 = newCell(7, &origin); | ||||
|  | ||||
|     int TOT = connections.size() / 7; | ||||
|     printf("heptagons = %d\n", TOT); | ||||
|     printf("all cells = %d\n", TOT*10/3); | ||||
|     if(!TOT) exit(1); | ||||
|     allh.resize(TOT); | ||||
|     for(int i=0; i<TOT; i++) allh[i] = i==0 ? &origin : new heptagon; | ||||
|     origin.alt = new heptagon; | ||||
|     *origin.alt = origin; | ||||
|     for(int i=0; i<7; i++) origin.alt->move[i] = NULL; | ||||
|     origin.alt->c7 = newCell(7, origin.alt); | ||||
|    | ||||
|     for(int i=0; i<TOT; i++) { | ||||
|       heptagon *h = allh[i]; | ||||
|       if(i) { | ||||
|         h->alt = NULL; | ||||
|         h->s = hsOrigin; | ||||
|         h->emeraldval = 0; | ||||
|         h->zebraval = 0; | ||||
|         h->fiftyval = 0; | ||||
|         h->fieldval = 7*i; | ||||
|         h->rval0 = h->rval1 = 0; h->cdata = NULL; | ||||
|         h->distance = 0; | ||||
|         h->c7 = newCell(7, h); | ||||
|         } | ||||
|       for(int j=0; j<7; j++) { | ||||
|         h->move[rv(j)] = allh[connections[i*7+j]/7]; | ||||
|         h->setspin(rv(j), rv(connections[i*7+j]%7)); | ||||
|         } | ||||
|       } | ||||
|    | ||||
|     for(int i=0; i<TOT; i++) { | ||||
|       generateAlts(allh[i]); | ||||
|       allh[i]->emeraldval = allh[i]->alt->emeraldval; | ||||
|       allh[i]->zebraval = allh[i]->alt->zebraval; | ||||
|       allh[i]->fiftyval = allh[i]->alt->fiftyval; | ||||
|       allh[i]->distance = allh[i]->alt->distance; | ||||
|       /* for(int j=0; j<7; j++) | ||||
|         allh[i]->move[j]->alt = createStep(allh[i]->alt, j); */ | ||||
|       }     | ||||
|      | ||||
|     celllister cl(origin.c7, 100, 100000000, NULL); | ||||
|     allcells = cl.lst; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   | ||||
| @@ -1600,7 +1600,7 @@ namespace heat { | ||||
|     vinefires.clear(); | ||||
|     rosefires.clear(); | ||||
|          | ||||
|     vector<cell*>& allcells = quotient ? quotientspace::allcells : dcal; | ||||
|     vector<cell*>& allcells = currentmap->allcells(); | ||||
|  | ||||
|     int dcs = size(allcells); | ||||
|      | ||||
| @@ -1760,7 +1760,7 @@ namespace heat { | ||||
|     } | ||||
|    | ||||
|   void dryforest() { | ||||
|     vector<cell*>& allcells = quotient ? quotientspace::allcells : dcal; | ||||
|     vector<cell*>& allcells = currentmap->allcells(); | ||||
|     int dcs = size(allcells); | ||||
|     for(int i=0; i<dcs; i++) { | ||||
|       cell *c = allcells[i]; | ||||
| @@ -1789,7 +1789,7 @@ bool gardener = false; | ||||
| bool lifebrought = false; // was Life brought to the Dead Caves? | ||||
|  | ||||
| void livecaves() { | ||||
|   vector<cell*>& allcells = quotient ? quotientspace::allcells : dcal; | ||||
|   vector<cell*>& allcells = currentmap->allcells(); | ||||
|   int dcs = size(allcells); | ||||
|    | ||||
|   vector<cell*> bringlife; | ||||
| @@ -2708,7 +2708,7 @@ namespace ca { | ||||
|    | ||||
|   void simulate() { | ||||
|     if(cwt.c->land != laCA) return; | ||||
|     vector<cell*>& allcells = quotient ? quotientspace::allcells : dcal; | ||||
|     vector<cell*>& allcells = currentmap->allcells(); | ||||
|     int dcs = size(allcells); | ||||
|     bool willlive[dcs]; | ||||
|     for(int i=0; i<dcs; i++) { | ||||
|   | ||||
| @@ -276,7 +276,7 @@ namespace conformal { | ||||
|       m->at = Id; | ||||
|       m->base = c; | ||||
|       v.push_back(m); | ||||
|       if(c == origin.c7) break; | ||||
|       if(c == currentmap->gamestart()) break; | ||||
|       for(int i=0; i<c->type; i++) | ||||
|         if(celldist(c->mov[i]) < celldist(c)) { | ||||
|           c = c->mov[i]; | ||||
| @@ -586,12 +586,18 @@ namespace conformal { | ||||
|         setvideomode(); | ||||
|         } */ | ||||
|       } | ||||
|     else if(sym == 'x' && pmodel == mdPolygonal)  | ||||
|     else if(sym == 'x' && pmodel == mdPolygonal) { | ||||
|       dialog::editNumber(polygonal::SI, 3, 10, 1, 4, XLAT("polygon sides"), ""); | ||||
|     else if(sym == 'y' && pmodel == mdPolygonal)  | ||||
|       dialog::sidedialog = true; | ||||
|       } | ||||
|     else if(sym == 'y' && pmodel == mdPolygonal) { | ||||
|       dialog::editNumber(polygonal::STAR, -1, 1, .1, 0, XLAT("star factor"), ""); | ||||
|     else if(sym == 'n' && pmodel == mdPolygonal)  | ||||
|       dialog::sidedialog = true; | ||||
|       } | ||||
|     else if(sym == 'n' && pmodel == mdPolygonal) { | ||||
|       dialog::editNumber(polygonal::deg, 2, MSI-1, 1, 2, XLAT("degree of the approximation"), ""); | ||||
|       dialog::sidedialog = true; | ||||
|       } | ||||
|     else if(sym == 'x' && pmodel == mdPolynomial)  { | ||||
|       polygonal::maxcoef = max(polygonal::maxcoef, polygonal::coefid); | ||||
|       int ci = polygonal::coefid + 1; | ||||
|   | ||||
							
								
								
									
										44
									
								
								dialogs.cpp
									
									
									
									
									
								
							
							
						
						
									
										44
									
								
								dialogs.cpp
									
									
									
									
									
								
							| @@ -167,13 +167,20 @@ namespace dialog { | ||||
|     addBreak(brk); | ||||
|     } | ||||
|  | ||||
|   int dcenter, dwidth; | ||||
|  | ||||
|   bool sidedialog; | ||||
|  | ||||
|   int displayLong(string str, int siz, int y, bool measure) { | ||||
|  | ||||
|     int last = 0; | ||||
|     int lastspace = 0; | ||||
|      | ||||
|     int xs = vid.xres * 618/1000; | ||||
|     int xo = vid.xres * 186/1000; | ||||
|     int xs, xo; | ||||
|     if(sidescreen) | ||||
|       xs = dwidth - vid.fsize, xo = vid.xres + vid.fsize; | ||||
|     else | ||||
|       xs = vid.xres * 618/1000, xo = vid.xres * 186/1000; | ||||
|      | ||||
|     for(int i=0; i<=size(str); i++) { | ||||
|       int ls = 0; | ||||
| @@ -223,9 +230,9 @@ namespace dialog { | ||||
|      | ||||
|     int fwidth = innerwidth + leftwidth + rightwidth; | ||||
|     dialogwidth = max(dialogwidth, fwidth); | ||||
|     itemx  = (vid.xres - fwidth) / 2 + leftwidth; | ||||
|     keyx   = (vid.xres - fwidth) / 2 + leftwidth - dfsize/2; | ||||
|     valuex = (vid.xres - fwidth) / 2 + leftwidth + innerwidth + dfsize/2; | ||||
|     itemx  = dcenter - fwidth / 2 + leftwidth; | ||||
|     keyx   = dcenter - fwidth / 2 + leftwidth - dfsize/2; | ||||
|     valuex = dcenter - fwidth / 2 + leftwidth + innerwidth + dfsize/2; | ||||
|     } | ||||
|  | ||||
|   void display() { | ||||
| @@ -238,7 +245,16 @@ namespace dialog { | ||||
|     dfsize *= 3; | ||||
|     #endif | ||||
|     dfspace = dfsize * 5/4; | ||||
|      | ||||
|     dcenter = vid.xres/2; | ||||
|     dwidth = vid.xres; | ||||
|     measure(); | ||||
|      | ||||
|     if(sidescreen) { | ||||
|       dwidth = vid.xres - vid.yres; | ||||
|       dcenter = (vid.xres + dwidth) / 2; | ||||
|       } | ||||
|      | ||||
|     while(tothei > vid.yres - 5 * vid.fsize) { | ||||
|       int adfsize = int(dfsize * sqrt((vid.yres - 5. * vid.fsize) / tothei)); | ||||
|       if(adfsize < dfsize-1) dfsize = adfsize + 1; | ||||
| @@ -246,7 +262,7 @@ namespace dialog { | ||||
|       dfspace = dfsize * 5/4; | ||||
|       measure(); | ||||
|       } | ||||
|     while(dialogwidth > vid.xres) { | ||||
|     while(dialogwidth > dwidth) { | ||||
|       int adfsize = int(dfsize * sqrt(vid.xres * 1. / dialogwidth)); | ||||
|       if(adfsize < dfsize-1) dfsize = adfsize + 1; | ||||
|       else dfsize--; // keep dfspace | ||||
| @@ -267,7 +283,7 @@ namespace dialog { | ||||
|       tothei += dfspace * I.scale / 100; | ||||
|       int mid = (top + tothei) / 2; | ||||
|       if(I.type == diTitle || I.type == diInfo) { | ||||
|         displayfr(vid.xres/2, mid, 2, dfsize * I.scale/100, I.body, I.color, 8); | ||||
|         displayfr(dcenter, mid, 2, dfsize * I.scale/100, I.body, I.color, 8); | ||||
|         } | ||||
|       else if(I.type == diItem) { | ||||
|         bool xthis = (mousey >= top && mousey < tothei); | ||||
| @@ -291,9 +307,15 @@ namespace dialog { | ||||
|         }       | ||||
|       else if(I.type == diSlider) { | ||||
|         bool xthis = (mousey >= top && mousey < tothei); | ||||
|         displayfr(vid.xres*1/4, mid, 2, dfsize * I.scale/100, "(", I.color, 16); | ||||
|         displayfr(vid.xres*1/4 + double(vid.xres/2 * I.param), mid, 2, dfsize * I.scale/100, "#", I.color, 8); | ||||
|         displayfr(vid.xres*3/4, mid, 2, dfsize * I.scale/100, ")", I.color, 0); | ||||
|         int sl, sr; | ||||
|         if(sidescreen) | ||||
|           sl = vid.yres + vid.fsize*2, sr = vid.xres - vid.fsize*2; | ||||
|         else | ||||
|           sl = vid.xres/4, sr = vid.xres*3/4; | ||||
|         int sw = sr-sl; | ||||
|         displayfr(sl, mid, 2, dfsize * I.scale/100, "(", I.color, 16); | ||||
|         displayfr(sl + double(sw * I.param), mid, 2, dfsize * I.scale/100, "#", I.color, 8); | ||||
|         displayfr(sr, mid, 2, dfsize * I.scale/100, ")", I.color, 0); | ||||
|         if(xthis) getcstat = I.key, inslider = true; | ||||
|         } | ||||
|       } | ||||
| @@ -480,11 +502,13 @@ namespace dialog { | ||||
|     ne.scale = ne.inverse_scale = identity; | ||||
|     ne.intval = NULL; | ||||
|     ne.positive = false; | ||||
|     sidedialog = false; | ||||
|     } | ||||
|  | ||||
|   void editNumber(int& x, int vmin, int vmax, int step, int dft, string title, string help) { | ||||
|     editNumber(ne.intbuf, vmin, vmax, step, dft, title, help); | ||||
|     ne.intbuf = x; ne.intval = &x; ne.s = its(x); | ||||
|     sidedialog = true; | ||||
|     } | ||||
|    | ||||
|   string disp(ld x) { if(ne.intval) return its((int) (x+.5)); else return fts(x); } | ||||
|   | ||||
							
								
								
									
										6
									
								
								game.cpp
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								game.cpp
									
									
									
									
									
								
							| @@ -348,9 +348,9 @@ bool pseudohept(cell *c) { | ||||
|   if(purehepta) { | ||||
|     if(sphere)  | ||||
|       return  | ||||
|         c->master == &dodecahedron[3] || | ||||
|         c->master == &dodecahedron[5] || | ||||
|         c->master == &dodecahedron[6]; | ||||
|         c->master == getDodecahedron(3) || | ||||
|         c->master == getDodecahedron(5) || | ||||
|         c->master == getDodecahedron(6); | ||||
|     int z = zebra40(c); | ||||
|     return z == 5 || z == 8 || z == 15; | ||||
|     } | ||||
|   | ||||
							
								
								
									
										92
									
								
								graph.cpp
									
									
									
									
									
								
							
							
						
						
									
										92
									
								
								graph.cpp
									
									
									
									
									
								
							| @@ -2821,7 +2821,12 @@ bool bugsNearby(cell *c, int dist = 2) { | ||||
|  | ||||
| int minecolors[8] = { | ||||
|   0xFFFFFF, 0xF0, 0xF060, 0xF00000,  | ||||
|   0x60, 0x600000, 0x00C0C0, 0 | ||||
|   0x60, 0x600000, 0x00C0C0, 0x000000 | ||||
|   }; | ||||
|  | ||||
| int distcolors[8] = { | ||||
|   0xFFFFFF, 0xF0, 0xF060, 0xF00000,  | ||||
|   0xA0A000, 0xA000A0, 0x00A0A0, 0xFFD500 | ||||
|   }; | ||||
|  | ||||
| const char* minetexts[8] = { | ||||
| @@ -3012,6 +3017,8 @@ transmatrix pushone() { return euclid ? eupush(1, 0) : xpush(sphere?.5 : 1); } | ||||
|  | ||||
| void drawMovementArrows(cell *c, transmatrix V) { | ||||
|  | ||||
|   if(viewdists) return; | ||||
|  | ||||
|   for(int d=0; d<8; d++) { | ||||
|    | ||||
|     movedir md = vectodir(spin(-d * M_PI/4) * tC0(pushone())); | ||||
| @@ -3725,7 +3732,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { | ||||
|   ivoryz = isGravityLand(c->land); | ||||
|  | ||||
|   transmatrix& gm = gmatrix[c]; | ||||
|   bool orig = (gm[2][2] == 0 || fabs(gm[2][2]-1) >= fabs(V[2][2]-1)) - 1e-8; | ||||
|   bool orig = (gm[2][2] == 0 || fabs(gm[2][2]-1) >= fabs(V[2][2]-1) - 1e-8); | ||||
|  | ||||
|   if(sphere && vid.alpha > 1) { | ||||
|      long double d = V[2][2]; | ||||
| @@ -3859,6 +3866,19 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { | ||||
|     int wcol, fcol, asciicol; | ||||
|      | ||||
|     setcolors(c, wcol, fcol); | ||||
|  | ||||
|     if(viewdists) { | ||||
|       int cd = celldistance(c, cwt.c); | ||||
|       string label = its(cd); | ||||
|       // string label = its(fieldpattern::getriverdistleft(c)) + its(fieldpattern::getriverdistright(c)); | ||||
|       int dc = distcolors[cd&7]; | ||||
|       wcol = gradient(wcol, dc, 0, .4, 1); | ||||
|       fcol = gradient(fcol, dc, 0, .4, 1); | ||||
|       /* queuepolyat(V, shFloor[ct6], darkena(gradient(0, distcolors[cd&7], 0, .25, 1), fd, 0xC0), | ||||
|         PPR_TEXT); */ | ||||
|       queuestr(V, (cd > 9 ? .6 : 1) * .2, label, 0xFF000000 + distcolors[cd&7], 1); | ||||
|       } | ||||
|  | ||||
|     asciicol = wcol; | ||||
|      | ||||
|     if(c->land == laNone && c->wall == waNone)  | ||||
| @@ -4316,12 +4336,6 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { | ||||
|  | ||||
| #ifndef NOEDIT | ||||
|  | ||||
|       if(viewdists) { | ||||
|         string label = its(celldistance(c, cwt.c)); | ||||
|         // string label = its(fieldpattern::getriverdistleft(c)) + its(fieldpattern::getriverdistright(c)); | ||||
|         queuestr(V, .5, label, 0xFFFFFFFF); | ||||
|         } | ||||
|  | ||||
|       if(cmode == emMapEditor && mapeditor::displaycodes) { | ||||
|  | ||||
|         int labeli = mapeditor::displaycodes == 1 ? mapeditor::realpattern(c) : mapeditor::subpattern(c); | ||||
| @@ -5860,6 +5874,8 @@ void describeMouseover() { | ||||
|  | ||||
|       out += " LP:" + itsh(c->landparam)+"/"+its(turncount); | ||||
|  | ||||
|       out += " CD:" + its(celldist(c)); | ||||
|        | ||||
|       out += " D:" + its(c->mpdist); | ||||
|        | ||||
|       char zz[64]; sprintf(zz, " P%p", c); out += zz; | ||||
| @@ -6375,6 +6391,8 @@ void centerpc(ld aspd) { | ||||
|  | ||||
| void drawmovestar(double dx, double dy) { | ||||
|  | ||||
|   if(viewdists) return; | ||||
|  | ||||
|   DEBB(DF_GRAPH, (debugfile,"draw movestar\n")); | ||||
|   if(!playerfound) return; | ||||
|    | ||||
| @@ -6574,6 +6592,8 @@ void checkpanjoy(double t) { | ||||
|  | ||||
| int realradius; | ||||
|  | ||||
| bool sidescreen; | ||||
|  | ||||
| void calcparam() { | ||||
|   DEBB(DF_GRAPH, (debugfile,"calc param\n")); | ||||
|   vid.xcenter = vid.xres / 2; | ||||
| @@ -6585,10 +6605,18 @@ void calcparam() { | ||||
|    | ||||
|   realradius = min(realradius, vid.radius); | ||||
|    | ||||
|   sidescreen = false; | ||||
|    | ||||
|   if(vid.xres < vid.yres) { | ||||
|     vid.radius = int(vid.scale * vid.xcenter) - (ISIOS ? 10 : 2); | ||||
|     vid.ycenter = vid.yres - realradius - vid.fsize - (ISIOS ? 10 : 0); | ||||
|     } | ||||
|   else { | ||||
|     if(vid.xres >= vid.yres * 4/3 && dialog::sidedialog && cmode == emNumber)  | ||||
|       sidescreen = true; | ||||
|     if(viewdists && cmode == emNormal && vid.xres >= vid.yres * 4/3) sidescreen = true; | ||||
|     if(sidescreen) vid.xcenter = vid.yres/2; | ||||
|     } | ||||
|  | ||||
|   ld eye = vid.eye; if(pmodel || rug::rugged) eye = 0; | ||||
|   vid.beta = 1 + vid.alpha + eye; | ||||
| @@ -7069,6 +7097,42 @@ void drawStats() { | ||||
| #ifdef ROGUEVIZ | ||||
|   if(rogueviz::on) return; | ||||
| #endif | ||||
|   if(viewdists && sidescreen) { | ||||
|     dialog::init(""); | ||||
|     int qty[64]; | ||||
|     vector<cell*>& ac = currentmap->allcells(); | ||||
|     for(int i=0; i<64; i++) qty[i] = 0; | ||||
|     for(int i=0; i<size(ac); i++) { | ||||
|       int d = celldistance(ac[i], cwt.c); | ||||
|       if(d >= 0 && d < 64) qty[d]++; | ||||
|       } | ||||
|     if(geometry == gNormal) | ||||
|       for(int i=purehepta?6:8; i<=15; i++)  | ||||
|         qty[i] =  | ||||
|           purehepta ? | ||||
|             3*qty[i-1] - qty[i-2] | ||||
|           : qty[i-1] + qty[i-2] + qty[i-3] - qty[i-4]; | ||||
|     if(geometry == gEuclid) | ||||
|       for(int i=8; i<=15; i++) qty[i] = 6*i; | ||||
|     for(int i=0; i<64; i++) if(qty[i]) | ||||
|       dialog::addInfo(its(qty[i]), distcolors[i&7]); | ||||
|     if(geometry == gNormal && !purehepta) { | ||||
|       dialog::addBreak(200); | ||||
|       dialog::addInfo("a(d+4) = a(d+3) + a(d+2) + a(d+1) - a(d)", 0xFFFFFF); | ||||
|       dialog::addInfo("a(d) ~ 1.72208^d", 0xFFFFFF); | ||||
|       } | ||||
|     if(geometry == gNormal && purehepta) { | ||||
|       dialog::addBreak(200); | ||||
|       dialog::addInfo("a(d+2) = 3a(d+1) - a(d+2)", 0xFFFFFF); | ||||
|       dialog::addInfo("a(d) ~ 2.61803^d", 0xFFFFFF); | ||||
|       } | ||||
|     if(geometry == gEuclid) { | ||||
|       dialog::addBreak(300); | ||||
|       dialog::addInfo("a(n) = 6n", 0xFFFFFF); | ||||
|       } | ||||
|     dialog::display(); | ||||
|     } | ||||
|   if(sidescreen) return; | ||||
|   instat = false; | ||||
|   bool portrait = vid.xres < vid.yres; | ||||
|   int colspace = portrait ? (vid.yres - vid.xres - vid.fsize*3) : (vid.xres - vid.yres - 16) / 2; | ||||
| @@ -7402,7 +7466,8 @@ void drawscreen() { | ||||
|   if(cmode != emNormal && cmode != emDraw && cmode != emCustomizeChar) darken = 2; | ||||
|   if(cmode == emQuit && !canmove) darken = 0; | ||||
|   if(cmode == emOverview) darken = 16; | ||||
|   if(cmode == emNumber && dialog::lastmode == em3D) darken = 0; | ||||
|    | ||||
|   if(sidescreen) darken = 0; | ||||
|  | ||||
| #ifndef NOEDIT | ||||
|   if(cmode == emMapEditor && !mapeditor::subscreen && !mapeditor::choosefile) darken = 0; | ||||
| @@ -7581,18 +7646,21 @@ void setvideomode() { | ||||
|  | ||||
| void restartGraph() { | ||||
|   DEBB(DF_INIT, (debugfile,"restartGraph\n")); | ||||
|    | ||||
|   View = Id; | ||||
|   webdisplay = 0; | ||||
|   if(currentmap) { | ||||
|     if(euclid) { | ||||
|       centerover = euclideanAtCreate(0,0); | ||||
|       } | ||||
|     else { | ||||
|     viewctr.h = &origin; | ||||
|       viewctr.h = currentmap->getOrigin(); | ||||
|       viewctr.spin = 0; | ||||
|       viewctr.mirrored = false; | ||||
|       } | ||||
|   View = Id; | ||||
|   webdisplay = 0; | ||||
|     if(sphere) View = spin(-M_PI/2); | ||||
|     } | ||||
|   } | ||||
|  | ||||
| void resetview() { | ||||
|   DEBB(DF_GRAPH, (debugfile,"reset view\n")); | ||||
|   | ||||
| @@ -95,11 +95,6 @@ hstate transition(hstate s, int dir) { | ||||
|   return hsError; | ||||
|   } | ||||
|  | ||||
| heptagon dodecahedron[12]; | ||||
| #define origin (dodecahedron[0]) | ||||
|  | ||||
| vector<heptagon*> allAlts; | ||||
|  | ||||
| // create h->move[d] if not created yet | ||||
| heptagon *createStep(heptagon *h, int d); | ||||
|  | ||||
| @@ -118,7 +113,7 @@ heptagon *buildHeptagon(heptagon *parent, int d, hstate s, int pard = 0) { | ||||
|     h->zebraval = zebra_heptagon(parent->zebraval, d); | ||||
|     h->fieldval = fp43.connections[fieldpattern::btspin(parent->fieldval, d)]; | ||||
|     h->rval0 = h->rval1 = 0; h->cdata = NULL; | ||||
|     if(parent == &origin || parent == origin.alt) | ||||
|     if(parent->s == hsOrigin) | ||||
|       h->fiftyval = fiftytable[0][d]; | ||||
|     else | ||||
|       h->fiftyval = nextfiftyval(parent->fiftyval, parent->move[0]->fiftyval, d); | ||||
| @@ -211,7 +206,7 @@ heptspin hsspin(const heptspin &hs, int val) { | ||||
|  | ||||
| // display the coordinates of the heptagon | ||||
| void backtrace(heptagon *pos) { | ||||
|   if(pos == &origin) return; | ||||
|   if(pos->s == hsOrigin) return; | ||||
|   backtrace(pos->move[0]); | ||||
|   printf(" %d", pos->spin(0)); | ||||
|   } | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <manifest xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|       package="com.roguetemple.hyperroid" | ||||
|       android:versionCode="9403" android:versionName="9.4c" | ||||
|       android:versionCode="9404" android:versionName="9.4d" | ||||
|       android:installLocation="auto"> | ||||
| <!--    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />         --> | ||||
| <!--    <uses-sdk android:minSdkVersion="9" android:targetSdkVersion="9" /> --> | ||||
|   | ||||
							
								
								
									
										6
									
								
								init.cpp
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								init.cpp
									
									
									
									
									
								
							| @@ -1,6 +1,6 @@ | ||||
| #define VER "9.4d" | ||||
| #define VERNUM 9404 | ||||
| #define VERNUM_HEX 0x9404 | ||||
| #define VER "9.4e" | ||||
| #define VERNUM 9405 | ||||
| #define VERNUM_HEX 0x9405 | ||||
|  | ||||
| #define GEN_M 0 | ||||
| #define GEN_F 1 | ||||
|   | ||||
| @@ -4895,7 +4895,7 @@ void setdist(cell *c, int d, cell *from) { | ||||
|           c->monst = moMonkey; | ||||
|         else if(hrand(80000) < 5 + items[itRuby] + hard) | ||||
|           c->monst = moEagle; | ||||
|         else if(ishept(c) && c != origin.c7 && hrand(4000) < 300 + items[itRuby] && !c->monst) { | ||||
|         else if(ishept(c) && c != currentmap->gamestart() && hrand(4000) < 300 + items[itRuby] && !c->monst) { | ||||
|           int hardchance = items[itRuby] + hard; | ||||
|           if(hardchance > 25) hardchance = 25; | ||||
|           bool hardivy = hrand(100) < hardchance; | ||||
| @@ -5224,7 +5224,7 @@ bool haveOrbPower() { | ||||
|     if(itemclass(c->item) == IC_ORB) return true; | ||||
|     } | ||||
|   else if(sphere) for(int i=0; i<spherecells(); i++) { | ||||
|     cell *c = dodecahedron[i].c7; | ||||
|     cell *c = getDodecahedron(i)->c7; | ||||
|     if(itemclass(c->item) == IC_ORB) return true; | ||||
|     forCellEx(c2, c) if(itemclass(c2->item) == IC_ORB) return true; | ||||
|     } | ||||
| @@ -5233,7 +5233,7 @@ bool haveOrbPower() { | ||||
|  | ||||
| bool haveKraken() { | ||||
|   for(int i=0; i<spherecells(); i++) { | ||||
|     cell *c = dodecahedron[i].c7; | ||||
|     cell *c = getDodecahedron(i)->c7; | ||||
|     if(c->monst == moKrakenH || c->monst == moKrakenT) return true; | ||||
|     } | ||||
|   return false; | ||||
| @@ -5617,7 +5617,7 @@ heptagon *createAlternateMap(cell *c, int rad, hstate firststate, int special) { | ||||
|     } | ||||
|    | ||||
|   heptagon *alt = new heptagon; | ||||
|   allAlts.push_back(alt); | ||||
|   allmaps.push_back(new hrmap_alternate(alt)); | ||||
| //printf("new alt {%p}\n", alt); | ||||
|   alt->s = firststate; | ||||
|   alt->emeraldval = 0; | ||||
|   | ||||
| @@ -155,7 +155,7 @@ namespace mapstream { | ||||
|       int rspin; | ||||
|        | ||||
|       if(size(cellbyid) == 0) { | ||||
|         c = origin.c7; | ||||
|         c = currentmap->gamestart(); | ||||
|         rspin = 0; | ||||
|         } | ||||
|       else { | ||||
| @@ -202,7 +202,7 @@ namespace mapstream { | ||||
|     int32_t whereami = loadInt(); | ||||
|     if(whereami >= 0 && whereami < size(cellbyid)) | ||||
|       cwt.c = cellbyid[whereami]; | ||||
|     else cwt.c = origin.c7; | ||||
|     else cwt.c = currentmap->gamestart(); | ||||
|  | ||||
|     for(int i=0; i<size(cellbyid); i++) { | ||||
|       cell *c = cellbyid[i]; | ||||
|   | ||||
							
								
								
									
										17
									
								
								menus.cpp
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								menus.cpp
									
									
									
									
									
								
							| @@ -374,6 +374,7 @@ void projectionDialog() { | ||||
| //  "to the eye. " | ||||
|     "See also the conformal mode (in the special modes menu) " | ||||
|     "for more models.")); | ||||
|   dialog::sidedialog = true; | ||||
|   } | ||||
|  | ||||
| void handleVisual1(int sym, int uni) { | ||||
| @@ -392,6 +393,7 @@ void handleVisual1(int sym, int uni) { | ||||
|     dialog::editNumber(vid.scale, .001, 1000, .1, 1, XLAT("scale factor"),  | ||||
|       XLAT("Scale the displayed model.")); | ||||
|     dialog::scaleLog(); | ||||
|     dialog::sidedialog = true; | ||||
|     } | ||||
|    | ||||
|   if(xuni == 'a') dialog::editNumber(vid.sspeed, -5, 5, 1, 0,  | ||||
| @@ -671,6 +673,8 @@ void handle3D(int sym, int uni) { | ||||
|     pmodel = (pmodel == mdHyperboloid ? mdDisk : mdHyperboloid); | ||||
|  | ||||
|   else if(uni) cmode = emVisual2; | ||||
|    | ||||
|   if(cmode == emNumber) dialog::sidedialog = true; | ||||
|   } | ||||
|  | ||||
| void showVisual2() { | ||||
| @@ -777,11 +781,13 @@ void handleVisual2(int sym, int uni) { | ||||
|   if(xuni == 'f')  | ||||
|     dialog::editNumber(vid.framelimit, 5, 300, 10, 300, XLAT("framerate limit"), ""); | ||||
|    | ||||
|   if(xuni == 'a')  | ||||
|   if(xuni == 'a') { | ||||
|     dialog::editNumber(sightrange, 4, cheater ? 10 : 7, 1, 7, XLAT("sight range"),  | ||||
|       XLAT("Roughly 42% cells are on the edge of your sight range. Reducing " | ||||
|       "the sight range makes HyperRogue work faster, but also makes " | ||||
|       "the game effectively harder.")); | ||||
|     dialog::sidedialog = true; | ||||
|     } | ||||
|  | ||||
|   if(xuni == 'r') revcontrol = !revcontrol; | ||||
|   if(xuni == 'd') vid.drawmousecircle = !vid.drawmousecircle; | ||||
| @@ -791,10 +797,12 @@ void handleVisual2(int sym, int uni) { | ||||
|     dialog::editNumber(fontscale, 0, 400, 10, 100, XLAT("font scale"), ""); | ||||
| #endif | ||||
|  | ||||
|   if(xuni == 'e')  | ||||
|   if(xuni == 'e') { | ||||
|     dialog::editNumber(vid.eye, -10, 10, 0.01, 0, XLAT("distance between eyes"), | ||||
|       XLAT("Watch the Minkowski hyperboloid or the hypersian rug mode with the " | ||||
|       "red/cyan 3D glasses.")); | ||||
|     dialog::sidedialog = true; | ||||
|     } | ||||
|  | ||||
| #ifdef STEAM | ||||
|   if(xuni == 'l') vid.steamscore = vid.steamscore^1; | ||||
| @@ -843,6 +851,7 @@ void showChangeMode() { | ||||
|   dialog::addBoolItem(XLAT("paper model creator"), (false), 'n'); | ||||
| #endif | ||||
|   dialog::addBoolItem(XLAT("conformal/history mode"), (conformal::on), 'a'); | ||||
|   dialog::addBoolItem(XLAT("expansion"), viewdists, 'x'); | ||||
|    | ||||
|   dialog::addBreak(50); | ||||
|    | ||||
| @@ -886,6 +895,10 @@ void handleChangeMode(int sym, int uni) { | ||||
|   else if(xuni == 'e') { | ||||
|     cmode = emPickEuclidean; | ||||
|   } | ||||
|   else if(xuni == 'x') { | ||||
|     viewdists = !viewdists; | ||||
|     cmode = emNormal; | ||||
|     } | ||||
|   else if(xuni == 't') { | ||||
|     clearMessages(); | ||||
|     cmode = emTactic; | ||||
|   | ||||
| @@ -1962,7 +1962,7 @@ void queuechr(const hyperpoint& h, int size, char chr, int col, int frame = 0) { | ||||
| void queuechr(const transmatrix& V, double size, char chr, int col, int frame = 0) { | ||||
|   int xc, yc, sc; getcoord0(tC0(V), xc, yc, sc); | ||||
|   int xs, ys, ss; getcoord0(V * xpush0(.5), xs, ys, ss); | ||||
|   queuechr(xc, yc, sc, int(sqrt(squar(xc-xs)+squar(yc-ys)) * size), chr, col, frame); | ||||
|   queuechr(xc, yc, sc, int(sqrt(squar(xc-xs)+squar(yc-ys)) * scalef * size), chr, col, frame); | ||||
|   } | ||||
|    | ||||
| void queuestr(const hyperpoint& h, int size, const string& chr, int col, int frame = 0) { | ||||
|   | ||||
| @@ -1399,8 +1399,10 @@ void handleMenu(int sym, int uni) { | ||||
|   else if(uni == 'l') showlabels = !showlabels; | ||||
|   else if(uni == 'x') specialmark = !specialmark; | ||||
|   else if(uni == 'b') backcolor ^= 0xFFFFFF; | ||||
|   else if(uni == 'g')  | ||||
|   else if(uni == 'g') { | ||||
|     dialog::editNumber(ggamma, 0, 5, .01, 0.5, XLAT("gamma value for edges"), ""); | ||||
|     dialog::sidedialog = true; | ||||
|     } | ||||
|   else if(uni) cmode = emNormal; | ||||
|   } | ||||
|  | ||||
|   | ||||
							
								
								
									
										79
									
								
								system.cpp
									
									
									
									
									
								
							
							
						
						
									
										79
									
								
								system.cpp
									
									
									
									
									
								
							| @@ -37,7 +37,7 @@ void initgame() { | ||||
|   if(firstland == laMountain && !tactic::on) firstland = laJungle; | ||||
|   if(isGravityLand(firstland) && !tactic::on) firstland = laCrossroads; | ||||
|    | ||||
|   cwt.c = origin.c7; cwt.spin = 0; cwt.mirrored = false; | ||||
|   cwt.c = currentmap->gamestart(); cwt.spin = 0; cwt.mirrored = false; | ||||
|   cwt.c->land = (euclid || sphere) ? euclidland : firstland; | ||||
|    | ||||
|   chaosAchieved = false; | ||||
| @@ -113,13 +113,12 @@ void initgame() { | ||||
|     setdist(cwt.c, i, NULL); | ||||
|     if(tactic::trailer) safety = false; | ||||
|      | ||||
|     if(sphere) verifyDodecahedron(); | ||||
|     else verifycells(&origin); | ||||
|     currentmap->verify(); | ||||
|     } | ||||
|    | ||||
|   if(quotient && generateAll(firstland)) { | ||||
|     for(int i=0; i<size(quotientspace::allcells); i++) | ||||
|       setdist(quotientspace::allcells[i], 8, NULL); | ||||
|     for(int i=0; i<size(currentmap->allcells()); i++) | ||||
|       setdist(currentmap->allcells()[i], 8, NULL); | ||||
|     } | ||||
|  | ||||
|    | ||||
| @@ -844,8 +843,58 @@ void loadsave() { | ||||
|   } | ||||
| #endif | ||||
|  | ||||
| void restartGame(char switchWhat) { | ||||
| namespace gamestack { | ||||
|  | ||||
|   struct gamedata { | ||||
|     hrmap *hmap; | ||||
|     cellwalker cwt; | ||||
|     heptspin viewctr; | ||||
|     transmatrix View; | ||||
|     eGeometry geometry; | ||||
|     }; | ||||
|  | ||||
|   vector<gamedata> gd; | ||||
|    | ||||
|   bool pushed() { return size(gd); } | ||||
|    | ||||
|   void push() { | ||||
|     if(geometry) { | ||||
|       printf("ERROR: push implemented only in non-hyperbolic geometry\n"); | ||||
|       exit(1); | ||||
|       } | ||||
|     gamedata gdn; | ||||
|     gdn.hmap = currentmap; | ||||
|     gdn.cwt = cwt; | ||||
|     gdn.viewctr = viewctr; | ||||
|     gdn.View = View; | ||||
|     gdn.geometry = geometry; | ||||
|     gd.push_back(gdn); | ||||
|     } | ||||
|      | ||||
|   void pop() { | ||||
|     gamedata& gdn = gd[size(gd)-1]; | ||||
|     currentmap = gdn.hmap; | ||||
|     cwt = gdn.cwt; | ||||
|     viewctr = gdn.viewctr; | ||||
|     View = gdn.View; | ||||
|     geometry = gdn.geometry; | ||||
|     resetGeometry(); | ||||
|     gd.pop_back(); | ||||
|     bfs(); | ||||
|     } | ||||
|    | ||||
|   }; | ||||
|  | ||||
| void restartGame(char switchWhat, bool push) { | ||||
|   DEBB(DF_INIT, (debugfile,"restartGame\n")); | ||||
|    | ||||
|   if(push) | ||||
|     gamestack::push(); | ||||
|   else if(gamestack::pushed()) { | ||||
|     gamestack::pop(); | ||||
|     return; | ||||
|     } | ||||
|   else { | ||||
|     achievement_final(true); | ||||
|   #ifndef NOSAVE | ||||
|     saveStats(); | ||||
| @@ -872,6 +921,7 @@ void restartGame(char switchWhat) { | ||||
|     // items[itGreenStone] = 100; | ||||
|     cellcount = 0; | ||||
|     clearMemory(); | ||||
|     } | ||||
|   if(switchWhat == 'C') { | ||||
|     geometry = gNormal; | ||||
|     yendor::on = tactic::on = princess::challenge = false; | ||||
| @@ -1187,14 +1237,13 @@ bool applyCheat(char u, cell *c = NULL) { | ||||
|     return true; | ||||
|     } | ||||
|   if(u == 'E'-64) { | ||||
|     addMessage(XLAT("You summon many monsters!")); | ||||
|     cheater++; | ||||
|     for(int i=0; i<cwt.c->type; i++) { | ||||
|       cell *c2 = cwt.c->mov[i]; | ||||
|       if(passable(c2, NULL, P_MONSTER)) { | ||||
|         eMonster mo[2] = { moRedTroll, moDarkTroll }; | ||||
|         c2->monst = mo[hrand(2)]; | ||||
|     if(geometry) { | ||||
|       restartGame(0, false); | ||||
|       } | ||||
|     else { | ||||
|       euclidland = cwt.c->land; | ||||
|       printf("target geometry = %d\n", targetgeometry); | ||||
|       restartGame('g', true); | ||||
|       } | ||||
|     return true; | ||||
|     } | ||||
| @@ -1299,6 +1348,10 @@ bool applyCheat(char u, cell *c = NULL) { | ||||
|     return true; | ||||
|     } | ||||
| #ifdef LOCAL | ||||
|   if(u == 'K'-64) { | ||||
|     printf("viewctr = %p.%d\n", viewctr.h, viewctr.spin); | ||||
|     display(View); | ||||
|     } | ||||
|   if(u == 'D'-64) { | ||||
|     cheater = 0; autocheat = 0; | ||||
|     return true; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Zeno Rogue
					Zeno Rogue