mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2025-01-11 09:50:34 +00:00
expansion, ctrl+E cheat, fix with distance calculation
This commit is contained in:
parent
0d7d2cf825
commit
645a64e8c9
757
cell.cpp
757
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);
|
||||
|
||||
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);
|
||||
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+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);
|
||||
allmaps.push_back(currentmap);
|
||||
|
||||
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 =
|
||||
// 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,11 +693,12 @@ 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)
|
||||
verifycells(at->move[i]);
|
||||
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;
|
||||
|
46
dialogs.cpp
46
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;
|
||||
@ -196,7 +203,7 @@ namespace dialog {
|
||||
y += siz/2;
|
||||
return y;
|
||||
}
|
||||
|
||||
|
||||
int tothei, dialogwidth, dfsize, dfspace, leftwidth, rightwidth, innerwidth, itemx, keyx, valuex;
|
||||
|
||||
string highlight_text;
|
||||
@ -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;
|
||||
}
|
||||
|
108
graph.cpp
108
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];
|
||||
@ -3735,7 +3742,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
|
||||
if(sphere && vid.alpha <= 1) {
|
||||
if(V[2][2] < -.8) return;
|
||||
}
|
||||
|
||||
|
||||
if(orig) gm = V;
|
||||
|
||||
ld dist0 = hdist0(tC0(V)) - 1e-6;
|
||||
@ -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);
|
||||
@ -4353,7 +4367,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
|
||||
queuestr(V, .6, buf, col);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
if(realred(c->wall) && !wmspatial) {
|
||||
int s = snakelevel(c);
|
||||
if(s >= 1)
|
||||
@ -5859,6 +5873,8 @@ void describeMouseover() {
|
||||
if(webdisplay & 8) {
|
||||
|
||||
out += " LP:" + itsh(c->landparam)+"/"+its(turncount);
|
||||
|
||||
out += " CD:" + its(celldist(c));
|
||||
|
||||
out += " D:" + its(c->mpdist);
|
||||
|
||||
@ -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,17 +7646,20 @@ void setvideomode() {
|
||||
|
||||
void restartGraph() {
|
||||
DEBB(DF_INIT, (debugfile,"restartGraph\n"));
|
||||
if(euclid) {
|
||||
centerover = euclideanAtCreate(0,0);
|
||||
}
|
||||
else {
|
||||
viewctr.h = &origin;
|
||||
viewctr.spin = 0;
|
||||
viewctr.mirrored = false;
|
||||
}
|
||||
|
||||
View = Id;
|
||||
webdisplay = 0;
|
||||
if(sphere) View = spin(-M_PI/2);
|
||||
if(currentmap) {
|
||||
if(euclid) {
|
||||
centerover = euclideanAtCreate(0,0);
|
||||
}
|
||||
else {
|
||||
viewctr.h = currentmap->getOrigin();
|
||||
viewctr.spin = 0;
|
||||
viewctr.mirrored = false;
|
||||
}
|
||||
if(sphere) View = spin(-M_PI/2);
|
||||
}
|
||||
}
|
||||
|
||||
void resetview() {
|
||||
|
@ -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;
|
||||
|
@ -1961,8 +1961,8 @@ 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);
|
||||
int xs, ys, ss; getcoord0(V * xpush0(.5), xs, ys, ss);
|
||||
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;
|
||||
}
|
||||
|
||||
|
133
system.cpp
133
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,34 +843,85 @@ 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"));
|
||||
achievement_final(true);
|
||||
#ifndef NOSAVE
|
||||
saveStats();
|
||||
#endif
|
||||
for(int i=0; i<ittypes; i++) items[i] = 0;
|
||||
lastkills = 0; for(int i=0; i<motypes; i++) kills[i] = 0;
|
||||
for(int i=0; i<10; i++) explore[i] = 0;
|
||||
for(int i=0; i<10; i++) for(int l=0; l<landtypes; l++)
|
||||
exploreland[i][l] = 0;
|
||||
|
||||
for(int i=0; i<numplayers(); i++)
|
||||
if(multi::playerActive(i))
|
||||
multi::deaths[i]++;
|
||||
|
||||
#ifndef NOSAVE
|
||||
anticheat::tampered = false;
|
||||
#endif
|
||||
achievementsReceived.clear();
|
||||
princess::saved = false;
|
||||
princess::reviveAt = 0;
|
||||
princess::forceVizier = false;
|
||||
princess::forceMouse = false;
|
||||
knighted = 0;
|
||||
// items[itGreenStone] = 100;
|
||||
cellcount = 0;
|
||||
clearMemory();
|
||||
|
||||
if(push)
|
||||
gamestack::push();
|
||||
else if(gamestack::pushed()) {
|
||||
gamestack::pop();
|
||||
return;
|
||||
}
|
||||
else {
|
||||
achievement_final(true);
|
||||
#ifndef NOSAVE
|
||||
saveStats();
|
||||
#endif
|
||||
for(int i=0; i<ittypes; i++) items[i] = 0;
|
||||
lastkills = 0; for(int i=0; i<motypes; i++) kills[i] = 0;
|
||||
for(int i=0; i<10; i++) explore[i] = 0;
|
||||
for(int i=0; i<10; i++) for(int l=0; l<landtypes; l++)
|
||||
exploreland[i][l] = 0;
|
||||
|
||||
for(int i=0; i<numplayers(); i++)
|
||||
if(multi::playerActive(i))
|
||||
multi::deaths[i]++;
|
||||
|
||||
#ifndef NOSAVE
|
||||
anticheat::tampered = false;
|
||||
#endif
|
||||
achievementsReceived.clear();
|
||||
princess::saved = false;
|
||||
princess::reviveAt = 0;
|
||||
princess::forceVizier = false;
|
||||
princess::forceMouse = false;
|
||||
knighted = 0;
|
||||
// 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;
|
||||
|
Loading…
Reference in New Issue
Block a user