lots of work on the new geometries

This commit is contained in:
Zeno Rogue 2017-10-29 01:57:34 +02:00
parent ac37df87a5
commit 016ade10c6
21 changed files with 876 additions and 443 deletions

View File

@ -84,6 +84,7 @@ bool wrongMode(char flags) {
if(flags == 'x') return false;
if(purehepta != (flags == '7')) return true;
if(euclid != (flags == 'e')) return true;
if(flags == 'E' && S7 < 5) return false;
if(sphere != (flags == 'E')) return true;
if((quotient == 1) != (flags == 'q')) return true;
if((quotient == 2) != (flags == 'Q')) return true;

View File

@ -87,35 +87,35 @@ bool grailWasFound(cell *c) {
return c->master->alt->alt->emeraldval & GRAIL_FOUND;
}
void generateAlts(heptagon *h) {
void generateAlts(heptagon *h, int levs) {
if(!h->alt) return;
preventbarriers(h->c7);
for(int i=0; i<7; i++) preventbarriers(h->c7->mov[i]);
for(int i=0; i<7; i++)
for(int i=0; i<S7; i++) preventbarriers(h->c7->mov[i]);
for(int i=0; i<S7; i++)
createStep(h->alt, i)->alt = h->alt->alt;
int relspin = -4; // for horocycles it must go the other way
if(quotient) relspin = 0;
else {
for(int j=0; j<7; j++) for(int i=0; i<7; i++) {
for(int j=0; j<S7; j++) for(int i=0; i<S7; i++) {
createStep(h, i);
if(h->move[i]->alt == h->alt->move[j]) {
relspin = (i-j+7) % 7;
relspin = (i-j+S7) % S7;
break;
}
}
if(relspin == -4 && quotient != 2) {
if(h->alt != h->alt->alt) {
printf("relspin {%p:%p}\n", h->alt, h->alt->alt);
{for(int i=0; i<7; i++) printf("%p ", h->alt->move[i]);} printf(" ALT\n");
{for(int i=0; i<7; i++) printf("%p ", h->move[i]);} printf(" REAL\n");
{for(int i=0; i<7; i++) printf("%p ", h->move[i]->alt);} printf(" REAL ALT\n");
{for(int i=0; i<S7; i++) printf("%p ", h->alt->move[i]);} printf(" ALT\n");
{for(int i=0; i<S7; i++) printf("%p ", h->move[i]);} printf(" REAL\n");
{for(int i=0; i<S7; i++) printf("%p ", h->move[i]->alt);} printf(" REAL ALT\n");
}
relspin = 3;
} }
// h[relspin] matches alt[0]
//printf("{%d~%d}\n", h->distance, h->alt->distance);
for(int i=0; i<7; i++) {
int ir = (7+i-relspin)%7;
for(int i=0; i<S7; i++) {
int ir = (S7+i-relspin)%S7;
heptagon *hm = h->alt->move[ir];
heptagon *ho = createStep(h, i);
// printf("[%p:%d ~ %p:%d] %p ~ %p\n",
@ -129,6 +129,7 @@ void generateAlts(heptagon *h) {
continue;
}
ho->alt = hm;
if(levs) generateAlts(ho, levs-1);
}
}
@ -141,10 +142,16 @@ heptagon *createAlternateMap(cell *c, int rad, hstate firststate, int special) {
}
if(gdir < 0) return NULL;
// non-crossing in weird hyperbolic
if(weirdhyperbolic) {
if(c->bardir == NOBARRIERS) return NULL;
forCellEx(c1, c) if(c1->bardir == NOBARRIERS) return NULL;
}
// check for non-crossing
int bd = 2;
cellwalker bb(c, bd);
if(!(checkBarriersFront(bb) && checkBarriersBack(bb))) {
if(!weirdhyperbolic && !(checkBarriersFront(bb) && checkBarriersBack(bb))) {
return NULL;
}
@ -153,10 +160,7 @@ heptagon *createAlternateMap(cell *c, int rad, hstate firststate, int special) {
cell *cx[rad+1];
for(int i=0; i<rad; i++) {
cx[i] = bf.c;
if(bf.c->type == 6)
cwspin(bf, 3);
else
cwspin(bf, 3 + hrand(2));
cwrev(bf);
cwstep(bf);
}
cx[rad] = bf.c;
@ -420,6 +424,7 @@ bool checkInTree(cell *c, int maxv) {
void buildEquidistant(cell *c) {
if(!c) return;
if(c->landparam) return;
if(geometry) return;
eLand b = c->land;
if(chaosmode && !inmirror(b)) return;
if(!b) {
@ -497,9 +502,9 @@ void buildEquidistant(cell *c) {
}
if(c->land == laEndorian) {
if(c->landparam == 1 && c->type == 7) {
for(int i=0; i<7; i++) {
int i1 = (i+1) % 7;
if(c->landparam == 1 && ctof(c)) {
for(int i=0; i<S7; i++) {
int i1 = (i+1) % S7;
if(c->mov[i] && c->mov[i]->land != laEndorian && c->mov[i]->land != laNone)
if(c->mov[i1] && c->mov[i1]->land != laEndorian && c->mov[i1]->land != laNone) {
c->landflags = 2;
@ -507,12 +512,12 @@ void buildEquidistant(cell *c) {
}
}
}
else if(c->landparam == 1 && c->type == 6) {
for(int i=0; i<6; i++) {
int i1 = (i+1) % 6;
int i2 = (i+2) % 6;
int i4 = (i+4) % 6;
int i5 = (i+5) % 6;
else if(c->landparam == 1 && !ctof(c)) {
for(int i=0; i<S6; i++) {
int i1 = (i+1) % S6;
int i2 = (i+2) % S6;
int i4 = (i+4) % S6;
int i5 = (i+5) % S6;
if(c->mov[i] && c->mov[i]->land == laBarrier && c->mov[i]->type == 7)
if(c->mov[i1] && c->mov[i1]->land != laBarrier)
if(c->mov[i2] && c->mov[i2]->land != laBarrier)
@ -600,7 +605,7 @@ cell *chosenDown(cell *c, int which, int bonus, cellfunction* cf) {
if(c->mov[i]->mpdist > BARLEV && cf == coastvalEdge) setdist(c->mov[i], BARLEV, c);
if((*cf)(c->mov[i]) == d) {
int i2 = (i+which+42)%c->type;
int i2 = (i+which+S42)%c->type;
createMov(c, i2);
if((*cf)(c->mov[i2]) == d)
return createMovR(c, i2+bonus);
@ -834,6 +839,7 @@ void setLandEuclid(cell *c) {
bool quickfind(eLand l) {
if(l == cheatdest) return true;
if(l == specialland && weirdhyperbolic) return true;
#if CAP_TOUR
if(tour::on && tour::quickfind(l)) return true;
#endif
@ -845,27 +851,30 @@ bool quickfind(eLand l) {
#define I10000 (INVLUCK?3000:10000)
void buildBigStuff(cell *c, cell *from) {
if(sphere || quotient || AT8) return;
if(sphere || quotient) return;
bool deepOcean = false;
if(c->land == laOcean) {
if(!from) deepOcean = true;
else for(int i=0; i<from->type; i++) {
cell *c2 = from->mov[i];
if(c2 && c2->land == laOcean && c2->landparam > 30) {
deepOcean = true;
}
if(c2) forCellEx(c3, c2) if(c3 && c3->land == laOcean && c3->landparam > 30)
deepOcean = true;
}
}
if(c->land == laGraveyard) {
if(!from) deepOcean = true;
else for(int i=0; i<from->type; i++) {
cell *c2 = from->mov[i];
if(c2 && c2->landparam > HAUNTED_RADIUS+5)
deepOcean = true;
if(!weirdhyperbolic) {
if(c->land == laOcean) {
if(!from) deepOcean = true;
else for(int i=0; i<from->type; i++) {
cell *c2 = from->mov[i];
if(c2 && c2->land == laOcean && c2->landparam > 30) {
deepOcean = true;
}
if(c2) forCellEx(c3, c2) if(c3 && c3->land == laOcean && c3->landparam > 30)
deepOcean = true;
}
}
if(c->land == laGraveyard) {
if(!from) deepOcean = true;
else for(int i=0; i<from->type; i++) {
cell *c2 = from->mov[i];
if(c2 && c2->landparam > HAUNTED_RADIUS+5)
deepOcean = true;
}
}
}
@ -873,7 +882,9 @@ void buildBigStuff(cell *c, cell *from) {
// buildgreatwalls
if(chaosmode) {
if(weirdhyperbolic) ; // barriers not implemented yet in weird hyperbolic
else if(chaosmode) {
if(c->type == 7 && hrand(10000) < 9000 && c->land && !inmirror(c) && buildBarrierNowall(c, getNewLand(c->land)))
{}
else if(c->type == 7 && c->land == laMirror && hrand(10000) < 2000) {
@ -950,7 +961,7 @@ void buildBigStuff(cell *c, cell *from) {
buildBarrier4(c, bd, 0, getNewLand(c->land), c->land); */
}
if((!chaosmode) && bearsCamelot(c->land) && c->type == 7 &&
if((!chaosmode) && bearsCamelot(c->land) && ctof(c) &&
(quickfind(laCamelot) || peace::on || (hrand(I2000) < 200 &&
items[itEmerald] >= U5 && !tactic::on))) {
int rtr = newRoundTableRadius();
@ -965,18 +976,18 @@ void buildBigStuff(cell *c, cell *from) {
// buildbigstuff
if(c->land == laRlyeh && c->type == 7 &&
if(c->land == laRlyeh && ctof(c) &&
(quickfind(laTemple) || peace::on || (hrand(I2000) < 100 &&
items[itStatue] >= U5 && !randomPatternsMode &&
!tactic::on && !yendor::on)))
createAlternateMap(c, 2, hsA);
if(c->land == laJungle && c->type == 7 &&
if(c->land == laJungle && ctof(c) &&
(quickfind(laMountain) || (hrand(I2000) < 100 &&
!randomPatternsMode && !tactic::on && !yendor::on && landUnlocked(laMountain))))
createAlternateMap(c, 2, hsA);
if(c->land == laOvergrown && c->type == 7 &&
if(c->land == laOvergrown && ctof(c) &&
(quickfind(laClearing) || (hrand(I2000) < 25 &&
!randomPatternsMode && items[itMutant] >= U5 &&
!tactic::on && !yendor::on))) {
@ -984,20 +995,20 @@ void buildBigStuff(cell *c, cell *from) {
if(h) clearing::bpdata[h].root = NULL;
}
if(c->land == laStorms && c->type == 7 && hrand(2000) < 1000 && !randomPatternsMode) {
if(c->land == laStorms && ctof(c) && hrand(2000) < 1000 && !randomPatternsMode) {
heptagon *h = createAlternateMap(c, 2, hsA);
if(h) h->alt->emeraldval = hrand(2);
}
if(c->land == laOcean && c->type == 7 && deepOcean && !generatingEquidistant && !peace::on &&
if(c->land == laOcean && ctof(c) && deepOcean && !generatingEquidistant && !peace::on &&
(quickfind(laWhirlpool) || (
hrand(2000) < (purehepta ? 500 : 1000) && !tactic::on && !yendor::on)))
createAlternateMap(c, 2, hsA);
if(c->land == laCaribbean && c->type == 7)
if(c->land == laCaribbean && ctof(c))
createAlternateMap(c, 2, hsA);
if(c->land == laPalace && c->type == 7 && !princess::generating && !shmup::on && multi::players == 1 &&
if(c->land == laPalace && ctof(c) && !princess::generating && !shmup::on && multi::players == 1 &&
(princess::forceMouse ? (from && from->pathdist != INF) :
(hrand(2000) < (peace::on ? 100 : 20))) &&
!c->master->alt &&
@ -1016,8 +1027,9 @@ bool openplains(cell *c) {
forCellEx(c2, c) if(c2->land != laHunting) return false;
return true;
}
if(purehepta) {
celllister cl(c, 5, 1000000, NULL);
int dlimit = getDistLimit();
if(dlimit < 7) {
celllister cl(c, dlimit, 1000000, NULL);
int bad = 0;
for(cell *c: cl.lst) {
while(c->mpdist > 8) setdist(c, c->mpdist-1, NULL);
@ -1026,7 +1038,7 @@ bool openplains(cell *c) {
return true;
}
else {
celllister cl(c, purehepta ? 5 : 7, 1000000, NULL);
celllister cl(c, dlimit, 1000000, NULL);
for(cell *c: cl.lst) {
while(c->mpdist > 8) setdist(c, c->mpdist-1, NULL);
if(c->land != laHunting) return false;
@ -1085,9 +1097,9 @@ void moreBigStuff(cell *c) {
if(d == 10) {
if(pseudohept(c)) buildCamelotWall(c);
else {
if(!euclid) for(int i=0; i<7; i++) generateAlts(c->master->move[i]);
if(!euclid) for(int i=0; i<S7; i++) generateAlts(c->master->move[i]);
int q = 0;
for(int t=0; t<6; t++) {
for(int t=0; t<S6; t++) {
createMov(c, t);
if(celldistAltRelative(c->mov[t]) == 10 && !pseudohept(c->mov[t])) q++;
}
@ -1101,7 +1113,7 @@ void moreBigStuff(cell *c) {
if(cr == 9) ;
else {
buildCamelotWall(c2);
if(c2->type == 6)
if(!ctof(c2))
c2->wall = waTower, c2->wparam = 1;
}
}
@ -1120,7 +1132,7 @@ void moreBigStuff(cell *c) {
// roughly as many knights as table cells
if(hrand(purehepta ? 2618 : 1720) < 1000)
c->monst = moKnight;
if(!euclid) for(int i=0; i<7; i++) generateAlts(c->master->move[i]);
if(!euclid) for(int i=0; i<S7; i++) generateAlts(c->master->move[i]);
for(int i=0; i<c->type; i++)
if(c->mov[i] && celldistAltRelative(c->mov[i]) < d)
c->mondir = (i+3) % 6;
@ -1155,7 +1167,7 @@ void moreBigStuff(cell *c) {
if(pseudohept(c))
c->wall = waColumn;
else {
if(!euclid) for(int i=0; i<7; i++) generateAlts(c->master->move[i]);
if(!euclid) for(int i=0; i<S7; i++) generateAlts(c->master->move[i]);
int q = 0;
for(int t=0; t<6; t++) {
createMov(c, t);

View File

@ -653,37 +653,12 @@ cell *createMov(cell *c, int d) {
verifycell(n);
}
/*
else if(d == S6-1) {
int di = fixrot(c->spin(0)+1);
cell *c2 = createMov(c->mov[0], di);
bool mirr = c->mov[0]->mirror(di);
merge(c, S6-1, c2, fix6(c->mov[0]->spn(di) + (mirr?-1:1)), mirr);
// c->mov[5] = c->mov[0]->mov[fixrot(c->spn[0]+1)];
// c->spn[5] = fix6(c->mov[0]->spn[fixrot(c->spn[0]+1)] + 1);
}
else if(d == 1) {
int di = fixrot(c->spn(0)-1);
cell *c2 = createMov(c->mov[0], di);
bool mirr = c->mov[0]->mirror(di);
merge(c, 1, c2, fix6(c->mov[0]->spn(di) - (mirr?-1:1)), mirr);
// c->mov[1] = c->mov[0]->mov[fixrot(c->spn[0]-1)];
// c->spn[1] = fix6(c->mov[0]->spn[fixrot(c->spn[0]-1)] - 1);
}
else if(d == 3 || d == 5) { */
else {
bool mirr = c->mirror(d-1);
int di = fixrot(c->spn(d-1)-(mirr?-1:1));
cell *c2 = createMov(c->mov[d-1], di);
bool nmirr = mirr ^ c->mov[d-1]->mirror(di);
merge(c, d, c2, fix6(c->mov[d-1]->spn(di) - (nmirr?-1:1)), nmirr);
// c->mov[3] = c->mov[2]->mov[fixrot(c->spn[2]-1)];
// c->spn[3] = fix6(c->mov[2]->spn[fixrot(c->spn[2]-1)] - 1);
}
return c->mov[d];
}
@ -740,7 +715,7 @@ void initcells() {
allmaps.push_back(currentmap);
if(!AT8 && !AT456) windmap::create();
if(S7 <= 7 && S6 <= 6) windmap::create();
// origin->emeraldval =
}
@ -849,7 +824,7 @@ bool ishex1(cell *c) {
int emeraldval(cell *c) {
if(euclid) return eupattern(c);
if(sphere) return 0;
if(sphere || weirdhyperbolic) return 0;
if(c->type == 7)
return c->master->emeraldval >> 3;
else {
@ -868,13 +843,19 @@ int eudist(short sx, short sy) {
return max(max(z0,z1), z2);
}
int compdist(int dx[3]) {
int mi = min(min(dx[0], dx[1]), dx[2]);
if(dx[0] > mi+2 || dx[1] > mi+2 || dx[2] > mi+2)
return -1; // { printf("cycle error!\n"); exit(1); }
if(dx[0] == mi+2 || dx[1] == mi+2 || dx[2] == mi+2)
return mi+1;
if((dx[0] == mi+1) + (dx[1] == mi+1) + (dx[2] == mi+1) >= 2)
int compdist(int dx[]) {
int mi = dx[0];
for(int u=0; u<S3; u++) mi = min(mi, dx[u]);
for(int u=0; u<S3; u++)
if(dx[u] > mi+2)
return -1; // { printf("cycle error!\n"); exit(1); }
for(int u=0; u<S3; u++)
if(dx[u] == mi+2)
return mi+1;
int cnt = 0;
for(int u=0; u<S3; u++)
if(dx[u] == mi) cnt++;
if(cnt < 2)
return mi+1;
return mi;
}
@ -888,9 +869,9 @@ int celldist(cell *c) {
return eudist(x, y);
}
if(sphere) return celldistance(c, currentmap->gamestart());
if(c->type != 6) return c->master->distance;
int dx[3];
for(int u=0; u<3; u++)
if(ctof(c)) return c->master->distance;
int dx[MAX_S3];
for(int u=0; u<S3; u++)
dx[u] = createMov(c, u+u)->master->distance;
return compdist(dx);
}
@ -911,16 +892,18 @@ int celldistAlt(cell *c) {
return euclidAlt(x, y);
}
if(!c->master->alt) return 0;
if(c->type != 6) return c->master->alt->distance;
int dx[3];
for(int u=0; u<3; u++) if(createMov(c, u+u)->master->alt == NULL)
if(ctof(c)) return c->master->alt->distance;
int dx[MAX_S3];
for(int u=0; u<S3; u++) if(createMov(c, u+u)->master->alt == NULL)
return ALTDIST_UNKNOWN;
for(int u=0; u<3; u++)
for(int u=0; u<S3; u++)
dx[u] = createMov(c, u+u)->master->alt->distance;
int mi = min(min(dx[0], dx[1]), dx[2]);
if(dx[0] > mi+2 || dx[1] > mi+2 || dx[2] > mi+2)
// return compdist(dx); -> not OK because of boundary conditions
int mi = dx[0];
for(int i=1; i<S3; i++) mi = min(mi, dx[i]);
for(int i=0; i<S3; i++) if(dx[i] > mi+2)
return ALTDIST_BOUNDARY; // { printf("cycle error!\n"); exit(1); }
if(dx[0] == mi+2 || dx[1] == mi+2 || dx[2] == mi+2)
for(int i=0; i<S3; i++) if(dx[i] == mi+2)
return mi+1;
return mi;
}
@ -959,7 +942,7 @@ int eufifty(cell *c) {
int fiftyval(cell *c) {
if(euclid) return eufifty(c) * 32;
if(sphere) return 0;
if(sphere || S7>7 || S6>6) return 0;
if(c->type == 7)
return c->master->fiftyval;
else {
@ -971,7 +954,7 @@ int fiftyval(cell *c) {
}
int cdist50(cell *c) {
if(sphere) return 0;
if(sphere || S7>7 || S6>6) return 0;
if(euclid) {
if(c->land == laWildWest)
return "0123333332112332223322233211233333322"[eufifty(c)] - '0';
@ -998,7 +981,7 @@ int land50(cell *c) {
int polara50(cell *c) {
if(c->type != 6) return polara50(fiftyval(c));
else if(sphere || euclid) return 0;
else if(sphere || euclid || S7>7 || S6>6) return 0;
else {
if(cdist50(createMov(c,0)) < 3) return polara50(createMov(c,0));
if(cdist50(createMov(c,2)) < 3) return polara50(createMov(c,2));
@ -1010,7 +993,7 @@ int polara50(cell *c) {
int polarb50(cell *c) {
if(euclid) return true;
if(c->type != 6) return polarb50(fiftyval(c));
else if(sphere || euclid) return true;
else if(sphere || euclid || S7>7 || S6>6) return true;
else {
if(cdist50(createMov(c,0)) < 3) return polarb50(createMov(c,0));
if(cdist50(createMov(c,2)) < 3) return polarb50(createMov(c,2));
@ -1063,7 +1046,7 @@ int fiftyval049(cell *c) {
int zebra40(cell *c) {
if(c->type != 6) return (c->master->zebraval/10);
else if(sphere) return 0;
else if(sphere || S7>7 || S6>6) return 0;
else if(euclid) return eupattern(c);
else {
int ii[3], z;
@ -1087,7 +1070,7 @@ int zebra40(cell *c) {
int zebra3(cell *c) {
if(c->type != 6) return (c->master->zebraval/10)/4;
else if(sphere) return 0;
else if(sphere || S7>7 || S6>6) return 0;
else {
int ii[3];
ii[0] = (c->mov[0]->master->zebraval/10)/4;
@ -1426,7 +1409,7 @@ pair<int, bool> fieldval(cell *c) {
int fieldval_uniq(cell *c) {
if(sphere) {
if(c->type == 5) return c->master->fieldval;
if(ctof(c)) return c->master->fieldval;
else return createMov(c, 0)->master->fieldval + 256 * createMov(c,2)->master->fieldval + (1<<16) * createMov(c,4)->master->fieldval;
}
else if(torus) {
@ -1440,7 +1423,7 @@ int fieldval_uniq(cell *c) {
if(i<0) i += torusconfig::qty;
return i;
}
if(c->type != 6) return c->master->fieldval/7;
if(ctof(c)) return c->master->fieldval/7;
else {
int z = 0;
for(int u=0; u<6; u+=2)

View File

@ -1866,13 +1866,14 @@ eLand land_sph[LAND_SPH] = {
laWildWest, laPalace, laBull, laPrairie, laCA
};
#define LAND_OCT 23
#define LAND_OCT 25
eLand land_oct[LAND_OCT] = {
laDesert, laIce, laCaves, laJungle, laAlchemist,
laIce, laDesert, laCaves, laJungle, laAlchemist,
laGraveyard, laRlyeh, laHell, laCocytus, laMotion,
laDryForest, laDeadCaves, laRedRock, laMinefield, laLivefjord,
laStorms, laOvergrown, laRose, laKraken, laBurial,
laTrollheim, laBull, laHunting
laTrollheim, laBull, laHunting,
laCaribbean, laCamelot
};

View File

@ -3101,6 +3101,7 @@ namespace windmap {
}
int at(cell *c) {
if(weirdhyperbolic) return ((size_t)c) % 255;
return windmap::windcodes[windmap::getId(c)];
}

View File

@ -56,7 +56,8 @@ movedir vectodir(const hyperpoint& P) {
ld dirdist[MAX_EDGE];
for(int i=0; i<cwt.c->type; i++) {
dirdist[i] = intval(Centered * xspinpush0(-i * 2 * M_PI /cwt.c->type, .5), P);
dirdist[i] = intval(Centered * ddspin(cwt.c, i, 0) * xpush(-.5) * C0, P);
//xspinpush0(-i * 2 * M_PI /cwt.c->type, .5), P);
}
movedir res;
@ -266,6 +267,29 @@ void handlePanning(int sym, int uni) {
sym = 1;
}
}
#ifdef SCALETUNER
double tunev = .1;
bool handleTune(int sym, int uni) {
if(uni == 'q') { tunev *= .5; return true; }
else if(uni == 'e') { tunev *= 2; return true; }
else if(uni == 'w') bscale7 += tunev*shiftmul;
else if(uni == 's') bscale7 -= tunev*shiftmul;
else if(uni == 'a') brot7 -= tunev*shiftmul;
else if(uni == 'd') brot7 += tunev*shiftmul;
else if(uni == 'i') bscale6 += tunev*shiftmul;
else if(uni == 'k') bscale6 -= tunev*shiftmul;
else if(uni == 'j') brot6 -= tunev*shiftmul;
else if(uni == 'l') brot6 += tunev*shiftmul;
else if(uni == 'z')
bscale7 = bscale6 = 1, brot7 = brot6 = 0;
else return false;
printf("s7 %lf r7 %lf s6 %lf r6 %lf\n", bscale7, brot7, bscale6, brot6);
resetGeometry();
return true;
}
#endif
void handleKeyNormal(int sym, int uni) {
@ -275,6 +299,10 @@ void handleKeyNormal(int sym, int uni) {
}
if(DEFAULTNOR(sym)) handlePanning(sym, uni);
#ifdef SCALETUNER
if(handleTune(sym, uni)) return;
#endif
if(!(uni >= 'A' && uni <= 'Z') && DEFAULTCONTROL) {
if(sym == 'l' || sym == 'd' || sym == SDLK_KP6) movepckeydir(0);

View File

@ -332,6 +332,7 @@ void debugScreen() {
dialog::addSelItem("item", dnameof(mouseover->item), 0);
dialog::addBreak(50);
dialog::addSelItem("cpdist", its(mouseover->cpdist), 0);
dialog::addSelItem("celldist", its(celldist(mouseover)), 0);
dialog::addSelItem("pathdist", its(mouseover->pathdist), 0);
dialog::addSelItem("temporary", its(mouseover->aitmp), 0);
dialog::addBreak(50);

View File

@ -367,6 +367,8 @@ bool pseudohept(cell *c) {
c->master == getDodecahedron(3) ||
c->master == getDodecahedron(5) ||
c->master == getDodecahedron(6);
if(S3 > 3)
return c->master->distance & 1;
int z = zebra40(c);
return z == 5 || z == 8 || z == 15;
}
@ -2019,7 +2021,7 @@ void killMonster(cell *c, eMonster who, flagtype deathflags) {
if(m == moPirate && isOnCIsland(c) && c->item == itNone && (
euclid ||
(c->master->alt && celldistAlt(c) <= (purehepta ? -3 : -5)) ||
(c->master->alt && celldistAlt(c) <= 2-getDistLimit()) ||
isHaunted(c->land))) {
bool toomany = false;
for(int i=0; i<c->type; i++) {
@ -2570,7 +2572,7 @@ void buildRosemap() {
}
int getDistLimit() { return purehepta?(AT8?4:5):(AT8?6:7); }
int getDistLimit() { return ginf[geometry].distlimit[purehepta]; }
bool nogoSlow(cell *to, cell *from) {
if(cellEdgeUnstable(to) && gravityLevel(to) >= gravityLevel(from)) return true;
@ -6158,7 +6160,7 @@ int ambushSize(cell *c, eItem what) {
}
void ambush(cell *c, eItem what) {
int maxdist = purehepta ? 5 : 7;
int maxdist = getDistLimit();
celllister cl(c, maxdist, 1000000, NULL);
cell *c0 = c;
int d = 0;

View File

@ -14,7 +14,7 @@ ld tessf, crossf, hexf, hcrossf, hexhexdist;
#define ALPHA (M_PI*2/S7)
hyperpoint Crad[6*MAX_EDGE];
hyperpoint Crad[MAX_S84];
transmatrix heptmove[MAX_EDGE], hexmove[MAX_EDGE];
transmatrix invheptmove[MAX_EDGE], invhexmove[MAX_EDGE];
@ -56,7 +56,7 @@ void precalc() {
goto finish;
}
fmin = AT456 ? 0 : 1, fmax = 2;
fmin = 0, fmax = 3;
for(int p=0; p<100; p++) {
ld f = (fmin+fmax) / 2;
@ -101,15 +101,12 @@ void precalc() {
}
hexf = fmin;
if(AT8 && !purehepta)
if(!euclid && !purehepta && !(S7&1))
hexshift = ALPHA/2 + ALPHA * ((S7-1)/2) + M_PI;
if(AT46 && !purehepta)
hexshift = ALPHA/2 + ALPHA * ((S7-1)/2) + M_PI;
finish:
printf("hexf = " LDF" hcross = " LDF" tessf = " LDF"\n", hexf, hcrossf, tessf);
printf("S7=%d S6=%d hexf = " LDF" hcross = " LDF" tessf = " LDF" hexshift = " LDF "\n", S7, S6, hexf, hcrossf, tessf, hexshift);
for(int i=0; i<S42; i++)
Crad[i] = spin(2*M_PI*i/S42) * xpush(.4) * C0;

171
graph.cpp
View File

@ -220,16 +220,28 @@ int displaydir(cell *c, int d) {
if(euclid)
return - d * S84 / c->type;
else
return (ctof(c) ? -hexshift:0) + S42 - d * S84 / c->type;
return S42 - d * S84 / c->type;
}
double hexshiftat(cell *c) {
if(ctof(c) && S7==6 && S3 == 4 && !purehepta) return hexshift + 2*M_PI/S7;
if(ctof(c) && (S7==8 || S7 == 4) && S3 == 3 && !purehepta) return hexshift + 2*M_PI/S7;
if(hexshift && ctof(c)) return hexshift;
return 0;
}
transmatrix ddspin(cell *c, int d, int bonus) {
int hdir = displaydir(c, d) + bonus;
double ha = hexshiftat(c);
if(ha) return spin(-ha) * getspinmatrix(hdir);
return getspinmatrix(hdir);
}
transmatrix iddspin(cell *c, int d, int bonus = 0) {
int hdir = displaydir(c, d) + bonus;
double ha = hexshiftat(c);
if(ha) return spin(ha) * getspinmatrix(-hdir);
return getspinmatrix(-hdir);
}
@ -257,7 +269,7 @@ void drawPlayerEffects(const transmatrix& V, cell *c, bool onplayer) {
int& ang = angle[multi::cpid];
ang %= S42;
transmatrix Vnow = gmatrix[c] * rgpushxto0(inverse(gmatrix[c]) * tC0(V));
transmatrix Vnow = gmatrix[c] * rgpushxto0(inverse(gmatrix[c]) * tC0(V)) * spin(-hexshiftat(c));
if(!euclid) for(int a=0; a<S42; a++) {
int dda = S42 + (-1-2*a);
@ -1867,7 +1879,8 @@ bool drawMonster(const transmatrix& Vparam, int ct, cell *c, int col) {
Vb = Vb * pispin;
}
else Vb = Vb * ddspin(c, c->mondir, S42);
if(c->type != 6) Vb = Vb * xpush(hexhexdist - hcrossf);
if(weirdhyperbolic || sphere) Vb = Vb * xpush(-(hexhexdist - hcrossf7));
if(ctof(c) && !euclid) Vb = Vb * xpush(hexhexdist - hcrossf);
return drawMonsterTypeDH(m, c, Vb, col, darkhistory, footphase);
}
@ -2242,8 +2255,6 @@ void drawReptileFloor(const transmatrix& V, cell *c, int col, bool usefloor) {
}
}
#define ECT (euclid?2:ct6)
void drawEmeraldFloor(const transmatrix& V, cell *c, int col) {
int j = -1;
@ -2256,11 +2267,13 @@ void drawEmeraldFloor(const transmatrix& V, cell *c, int col) {
else if(i == 28) j = 4;
else if(i == 36) j = 5;
}
int ct6 = ctof(c);
if(j >= 0)
qfloor(c, V, applyPatterndir(c, 'f'), shEmeraldFloor[j], col);
else
qfloor(c, V, shCaveFloor[euclid?2:ctof(c)], col);
qfloor(c, V, CAVEFLOOR, col);
}
double fanframe;
@ -2776,7 +2789,7 @@ void setcolors(cell *c, int& wcol, int &fcol) {
if(c->wall == waGlass && !wmspatial) fcol = wcol;
if(c->wall == waRoundTable) fcol = wcol;
if(c->wall == waRoundTable) fcol = wcol;
}
bool noAdjacentChasms(cell *c) {
@ -3046,6 +3059,13 @@ bool allemptynear(cell *c) {
static const int trapcol[4] = {0x904040, 0xA02020, 0xD00000, 0x303030};
static const int terracol[8] = {0xD000, 0xE25050, 0xD0D0D0, 0x606060, 0x303030, 0x181818, 0x0080, 0x8080};
void qfloor_eswap(cell *c, const transmatrix& V, const hpcshape& sh, int col) {
if(euclid && ishex1(c))
qfloor(c, V * pispin, sh, col);
else
qfloor(c, V, sh, col);
};
// how much to darken
int getfd(cell *c) {
@ -3576,7 +3596,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
else if(wmplain) {
if(wmspatial && highwall(c)) ;
else qfloor(c, Vf, shFloor[ct6], darkena(fcol, fd, 0xFF));
else qfloor(c, Vf, PLAINFLOOR, darkena(fcol, fd, 0xFF));
}
else if(randomPatternsMode && c->land != laBarrier && !isWarped(c->land)) {
@ -3590,21 +3610,21 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
else if(k == RPV_CYCLE && k7 < 4) drawTowerFloor(Vf, c, dfcol, celldist);
else switch(j) {
case 0: qfloor(c, Vf, shCloudFloor[ct6], dfcol); break;
case 1: qfloor(c, Vf, shFeatherFloor[ECT], dfcol); break;
case 2: qfloor(c, Vf, shStarFloor[ct6], dfcol); break;
case 3: qfloor(c, Vf, shTriFloor[ct6], dfcol); break;
case 4: qfloor(c, Vf, shSStarFloor[ct6], dfcol); break;
case 5: qfloor(c, Vf, shOverFloor[ECT], dfcol); break;
case 6: qfloor(c, Vf, shFeatherFloor[ECT], dfcol); break;
case 7: qfloor(c, Vf, shDemonFloor[ct6], dfcol); break;
case 8: qfloor(c, Vf, shCrossFloor[ct6], dfcol); break;
case 9: qfloor(c, Vf, shMFloor[ct6], dfcol); break;
case 10: qfloor(c, Vf, shCaveFloor[ECT], dfcol); break;
case 11: qfloor(c, Vf, shPowerFloor[ct6], dfcol); break;
case 12: qfloor(c, Vf, shDesertFloor[ct6], dfcol); break;
case 13: qfloor(c, Vf, purehepta ? shChargedFloor[3] : shChargedFloor[ct6], dfcol); break;
case 14: qfloor(c, Vf, ct6?shFloor[1]:shChargedFloor[2], dfcol); break;
case 0: qfloor(c, Vf, CLOUDFLOOR, dfcol); break;
case 1: qfloor(c, Vf, FEATHERFLOOR, dfcol); break;
case 2: qfloor(c, Vf, STARFLOOR, dfcol); break;
case 3: qfloor_eswap(c, Vf, TRIFLOOR, dfcol); break;
case 4: qfloor_eswap(c, Vf, SSTARFLOOR, dfcol); break;
case 5: qfloor(c, Vf, OVERFLOOR, dfcol); break;
case 6: qfloor(c, Vf, FEATHERFLOOR, dfcol); break;
case 7: qfloor_eswap(c, Vf, DEMONFLOOR, dfcol); break;
case 8: qfloor_eswap(c, Vf, CROSSFLOOR, dfcol); break;
case 9: qfloor(c, Vf, MFLOOR1, dfcol); break;
case 10: qfloor(c, Vf, CAVEFLOOR, dfcol); break;
case 11: qfloor_eswap(c, Vf, POWERFLOOR, dfcol); break;
case 12: qfloor_eswap(c, Vf, DESERTFLOOR, dfcol); break;
case 13: qfloor_eswap(c, Vf, CHARGEDFLOOR, dfcol); break;
case 14: qfloor_eswap(c, Vf, CHARGEDFLOOR, dfcol); break;
}
}
@ -3616,20 +3636,20 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
prairie::isleft(c) ? river::towerleft : river::towerright); */
else if(c->land == laPrairie)
qfloor(c, Vf, shCloudFloor[ct6], darkena(fcol, fd, 0xFF));
qfloor(c, Vf, CLOUDFLOOR, darkena(fcol, fd, 0xFF));
else if(c->land == laWineyard) {
qfloor(c, Vf, shFeatherFloor[euclid?2:ct6], darkena(fcol, fd, 0xFF));
qfloor(c, Vf, FEATHERFLOOR, darkena(fcol, fd, 0xFF));
}
else if(c->land == laZebra)
drawZebraFloor(Vf, c, darkena(fcol, fd, 0xFF));
else if(c->wall == waTrunk)
qfloor(c, Vf, shFloor[ct6], darkena(fcol, fd, 0xFF));
qfloor(c, Vf, PLAINFLOOR, darkena(fcol, fd, 0xFF));
else if(c->wall == waCanopy || c->wall == waSolidBranch || c->wall == waWeakBranch)
qfloor(c, Vf, shFeatherFloor[ct6], darkena(fcol, fd, 0xFF));
qfloor(c, Vf, FEATHERFLOOR, darkena(fcol, fd, 0xFF));
else if(c->land == laMountain)
drawTowerFloor(Vf, c, darkena(fcol, fd, 0xFF),
@ -3642,136 +3662,125 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
drawEmeraldFloor(Vf, c, darkena(fcol, fd, 0xFF));
else if(c->land == laRlyeh)
qfloor(c, Vf, (eoh ? shFloor: shTriFloor)[ct6], darkena(fcol, fd, 0xFF));
qfloor_eswap(c, Vf, TRIFLOOR, darkena(fcol, fd, 0xFF));
// qfloor(c, Vf, shTriFloor[ct6], darkena(fcol, fd, 0xFF));
else if(c->land == laTemple)
// qfloor(c, Vf, (eoh ? shFloor: shTriFloor)[ct6], darkena(fcol, fd, 0xFF));
qfloor(c, Vf, shTriFloor[ct6], darkena(fcol, fd, 0xFF));
/* else if(c->land == laAlchemist)
qfloor(c, Vf, shCloudFloor[ct6], darkena(fcol, fd, 0xFF)); */
qfloor_eswap(c, Vf, TRIFLOOR, darkena(fcol, fd, 0xFF));
else if(c->land == laAlchemist)
qfloor(c, Vf, shCloudFloor[ct6], darkena(fcol, fd, 0xFF));
qfloor(c, Vf, CLOUDFLOOR, darkena(fcol, fd, 0xFF));
else if(c->land == laVolcano && !eoh)
qfloor(c, Vf, shLavaFloor[ct6], darkena(fcol, fd, 0xFF));
else if(c->land == laVolcano)
qfloor(c, Vf, LAVAFLOOR, darkena(fcol, fd, 0xFF));
else if(c->land == laRose)
qfloor(c, Vf, shRoseFloor[purehepta ? 2 : ct6], darkena(fcol, fd, 0xFF));
qfloor_eswap(c, Vf, ROSEFLOOR, darkena(fcol, fd, 0xFF));
else if(c->land == laTortoise)
qfloor(c, Vf, shTurtleFloor[purehepta ? 2 : ct6], darkena(fcol, fd, 0xFF));
qfloor_eswap(c, Vf, TURTLEFLOOR, darkena(fcol, fd, 0xFF));
else if(c->land == laDragon && !purehepta) {
/* if(!wmspatial || noAdjacentChasms(c)) */
qfloor(c, Vf, shDragonFloor[euclid?2:ct6], darkena(fcol, fd, 0xFF));
qfloor(c, Vf, DRAGONFLOOR, darkena(fcol, fd, 0xFF));
/* if(wmspatial)
qfloor(c, Vf, shFloor[euclid?2:ct6], darkena(fcol, fd, 0xFF)); */
}
else if((isElemental(c->land) || c->land == laElementalWall) && !eoh)
qfloor(c, Vf, shNewFloor[ct6], darkena(fcol, fd, 0xFF));
else if(isElemental(c->land) || c->land == laElementalWall)
qfloor_eswap(c, Vf, NEWFLOOR, darkena(fcol, fd, 0xFF));
else if(c->land == laBurial)
qfloor(c, Vf, shBarrowFloor[euclid?0:purehepta?2:ct6], darkena(fcol, fd, 0xFF));
qfloor(c, Vf, BARROWFLOOR, darkena(fcol, fd, 0xFF));
else if(c->land == laTrollheim && !eoh)
qfloor(c, Vf, shTrollFloor[ct6], darkena(fcol, fd, 0xFF));
qfloor_eswap(c, Vf, TROLLFLOOR, darkena(fcol, fd, 0xFF));
else if(c->land == laTrollheim)
qfloor(c, Vf, shCaveFloor[euclid?2:1], darkena(fcol, fd, 0xFF));
qfloor(c, Vf, CAVEFLOOR, darkena(fcol, fd, 0xFF));
else if(c->land == laJungle)
qfloor(c, Vf, shFeatherFloor[euclid?2:ct6], darkena(fcol, fd, 0xFF));
qfloor(c, Vf, FEATHERFLOOR, darkena(fcol, fd, 0xFF));
else if(c->land == laMountain)
qfloor(c, Vf, shFeatherFloor[euclid?2:ct6], darkena(fcol, fd, 0xFF));
qfloor(c, Vf, FEATHERFLOOR, darkena(fcol, fd, 0xFF));
else if(c->land == laGraveyard)
qfloor(c, Vf, (eoh ? shFloor : shCrossFloor)[ct6], darkena(fcol, fd, 0xFF));
qfloor_eswap(c, Vf, CROSSFLOOR, darkena(fcol, fd, 0xFF));
else if(c->land == laDeadCaves) {
qfloor(c, Vf, shCaveFloor[euclid?2:ct6], darkena(fcol, fd, 0xFF));
qfloor(c, Vf, CAVEFLOOR, darkena(fcol, fd, 0xFF));
}
else if(c->land == laMotion)
qfloor(c, Vf, shMFloor[ct6], darkena(fcol, fd, 0xFF));
qfloor(c, Vf, MFLOOR1, darkena(fcol, fd, 0xFF));
else if(c->land == laWhirlwind)
qfloor(c, Vf, (eoh ? shCloudFloor : shNewFloor)[ct6], darkena(fcol, fd, 0xFF));
qfloor_eswap(c, Vf, NEWFLOOR, darkena(fcol, fd, 0xFF));
else if(c->land == laHell)
qfloor(c, Vf, (euclid ? shStarFloor : shDemonFloor)[ct6], darkena(fcol, fd, 0xFF));
qfloor_eswap(c, Vf, DEMONFLOOR, darkena(fcol, fd, 0xFF));
else if(c->land == laIce || c->land == laBlizzard)
qfloor(c, Vf, shStarFloor[ct6], darkena(fcol, fd, 0xFF));
qfloor(c, Vf, STARFLOOR, darkena(fcol, fd, 0xFF));
else if(c->land == laCocytus)
qfloor(c, Vf, (eoh ? shCloudFloor : shDesertFloor)[ct6], darkena(fcol, fd, 0xFF));
qfloor_eswap(c, Vf, DESERTFLOOR, darkena(fcol, fd, 0xFF));
else if(c->land == laStorms) {
if(euclid)
qfloor(c, ishex1(c) ? V*pispin : Vf,
ishept(c) ? shFloor[0] : shChargedFloor[2], darkena(fcol, fd, 0xFF));
else
qfloor(c, Vf, (purehepta ? shChargedFloor[3] : ct6 ? shFloor[1] : shChargedFloor[2]), darkena(fcol, fd, 0xFF));
}
else if(c->land == laStorms)
qfloor_eswap(c, Vf, CHARGEDFLOOR, darkena(fcol, fd, 0xFF));
else if(c->land == laWildWest)
qfloor(c, Vf, (eoh ? shCloudFloor : shSStarFloor)[ct6], darkena(fcol, fd, 0xFF));
qfloor_eswap(c, Vf, SSTARFLOOR, darkena(fcol, fd, 0xFF));
else if(c->land == laPower)
qfloor(c, Vf, (eoh ? shStarFloor : shPowerFloor)[ct6], darkena(fcol, fd, 0xFF));
qfloor_eswap(c, Vf, POWERFLOOR, darkena(fcol, fd, 0xFF));
else if(c->land == laHive && c->wall != waFloorB && c->wall != waFloorA && c->wall != waMirror && c->wall != waCloud) {
qfloor(c, Vf, shFloor[ct6], darkena(fcol, 1, 0xFF));
qfloor(c, Vf, PLAINFLOOR, darkena(fcol, 1, 0xFF));
if(c->wall != waMirror && c->wall != waCloud)
qfloor(c, Vf, shMFloor[ct6], darkena(fcol, 2, 0xFF));
qfloor(c, Vf, MFLOOR1, darkena(fcol, 2, 0xFF));
if(c->wall != waMirror && c->wall != waCloud)
qfloor(c, Vf, shMFloor2[ct6], darkena(fcol, fcol==wcol ? 1 : 2, 0xFF));
qfloor(c, Vf, MFLOOR2, darkena(fcol, fcol==wcol ? 1 : 2, 0xFF));
}
else if(c->land == laCaves)
qfloor(c, Vf, shCaveFloor[ECT], darkena(fcol, fd, 0xFF));
qfloor(c, Vf, CAVEFLOOR, darkena(fcol, fd, 0xFF));
else if(c->land == laDesert)
qfloor(c, Vf, (eoh ? shCloudFloor : shDesertFloor)[ct6], darkena(fcol, fd, 0xFF));
qfloor_eswap(c, Vf, DESERTFLOOR, darkena(fcol, fd, 0xFF));
else if(c->land == laOvergrown || c->land == laClearing || isHaunted(c->land))
qfloor(c, Vf, shOverFloor[ECT], darkena(fcol, fd, 0xFF));
else if(c->land == laRose)
qfloor(c, Vf, shOverFloor[ECT], darkena(fcol, fd, 0xFF));
qfloor(c, Vf, OVERFLOOR, darkena(fcol, fd, 0xFF));
else if(c->land == laBull)
qfloor(c, Vf, (eoh ? shFloor : shButterflyFloor)[ct6], darkena(fcol, fd, 0xFF));
qfloor_eswap(c, Vf, BUTTERFLYFLOOR, darkena(fcol, fd, 0xFF));
else if(c->land == laDryForest)
qfloor(c, Vf, (eoh ? shStarFloor : shDesertFloor)[ct6], darkena(fcol, fd, 0xFF));
qfloor_eswap(c, Vf, DESERTFLOOR, darkena(fcol, fd, 0xFF));
// else if(c->land == laOcean && c->landparam > 25)
// qfloor(c, Vf, shWave[wavephase][ct6], darkena(fcol, fd, 0xFF));
else if((c->land == laCaribbean || c->land == laOcean || c->land == laOceanWall || c->land == laWhirlpool))
qfloor(c, Vf, shCloudFloor[ct6], darkena(fcol, fd, 0xFF));
qfloor(c, Vf, CLOUDFLOOR, darkena(fcol, fd, 0xFF));
else if(c->land == laKraken)
qfloor(c, Vf, shFullFloor[ct6], darkena(fcol, fd, 0xFF));
qfloor(c, Vf, FULLFLOOR, darkena(fcol, fd, 0xFF));
else if(c->land == laLivefjord)
qfloor(c, Vf, shCaveFloor[ECT], darkena(fcol, fd, 0xFF));
qfloor(c, Vf, CAVEFLOOR, darkena(fcol, fd, 0xFF));
else if(c->land == laRedRock)
qfloor(c, Vf, eoh ? shFloor[ct6] : shDesertFloor[ct6], darkena(fcol, fd, 0xFF));
qfloor_eswap(c, Vf, DESERTFLOOR, darkena(fcol, fd, 0xFF));
else if(c->land == laPalace || c->land == laTerracotta)
qfloor(c, Vf, (eoh?shFloor:shPalaceFloor)[ct6], darkena(fcol, fd, 0xFF));
qfloor_eswap(c, Vf, PALACEFLOOR, darkena(fcol, fd, 0xFF));
else if(c->land == laMercuryRiver) {
if(eoh)
qfloor(c, Vf, shFloor[ct6], darkena(fcol, fd, 0xFF));
qfloor(c, Vf, PLAINFLOOR, darkena(fcol, fd, 0xFF));
else {
int bridgedir = -1;
if(c->type == 6) {
@ -3781,7 +3790,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
bridgedir = i;
}
if(bridgedir == -1)
qfloor(c, Vf, (eoh?shFloor:shPalaceFloor)[ct6], darkena(fcol, fd, 0xFF));
qfloor_eswap(c, Vf, PALACEFLOOR, darkena(fcol, fd, 0xFF));
else {
transmatrix bspin = ddspin(c, bridgedir);
qfloor(c, Vf, bspin, shMercuryBridge[0], darkena(fcol, fd, 0xFF));
@ -3799,7 +3808,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
}
else {
qfloor(c, Vf, shFloor[ct6], darkena(fcol, fd, 0xFF));
qfloor(c, Vf, PLAINFLOOR, darkena(fcol, fd, 0xFF));
}
// walls
@ -4849,6 +4858,8 @@ void drawthemap() {
conformal::on ? sr + 2:
(!playermoved) ? sr+1 : sr + 4;
if(S3>3) maxreclevel+=2;
drawrec(viewctr,
maxreclevel,
hsOrigin, ypush(vid.yshift) * sphereflip * View);

View File

@ -774,6 +774,14 @@ void describeMouseover() {
if(isWarped(c))
help += s0 + "\n\n" + warpdesc;
}
if(c && c->master->alt) {
char buf[100];
sprintf(buf, " [alt=%p]", c->master->alt->alt);
out += " ALT " + its(celldistAlt(c));
out += buf;
}
#if CAP_ROGUEVIZ
rogueviz::describe(c);

View File

@ -88,7 +88,7 @@ hstate transition(hstate s, int dir) {
if(s == hsB0 && dir == S7-2) return hsC;
return hsError;
}
else if(AT456) {
else if(S6 == 8) {
if(s == hsOrigin) return hsA;
if(s == hsA && (dir >= 2 && dir < S7-1)) return hsA;
if(s == hsA && (dir == S7-1)) return hsB;
@ -99,9 +99,8 @@ hstate transition(hstate s, int dir) {
if(s == hsOrigin) return hsA;
if(s == hsA && dir >= 3 && dir <= S7-3) return hsA;
if(s == hsA && dir == S7-2) return hsB;
if(s == hsB && dir >= 3 && dir <= S7-4) return hsA;
if(s == hsB && dir == S7-3) return hsB;
if(s == hsB && dir == 3) return hsA;
if(s == hsB && AT8 && dir == 4) return hsA;
}
return hsError;
}
@ -120,8 +119,10 @@ struct indenter {
template<class... T> auto iprintf(T... t) { for(int i=0; i<indent; i++) putchar(' '); return printf(t...); }
*/
#define COMPUTE -1000000
// create a new heptagon
heptagon *buildHeptagon(heptagon *parent, int d, hstate s, int pard = 0) {
heptagon *buildHeptagon(heptagon *parent, int d, hstate s, int pard = 0, int fixdistance = COMPUTE) {
heptagon *h = new heptagon;
h->alt = NULL;
h->s = s;
@ -132,7 +133,7 @@ heptagon *buildHeptagon(heptagon *parent, int d, hstate s, int pard = 0) {
if(parent->c7) {
h->c7 = newCell(S7, h);
h->rval0 = h->rval1 = 0; h->cdata = NULL;
if(!AT8 && !AT456) {
if(!weirdhyperbolic) {
h->emeraldval = emerald_heptagon(parent->emeraldval, d);
h->zebraval = zebra_heptagon(parent->zebraval, d);
h->fieldval = fp43.connections[fieldpattern::btspin(parent->fieldval, d)];
@ -151,16 +152,51 @@ heptagon *buildHeptagon(heptagon *parent, int d, hstate s, int pard = 0) {
//generateEmeraldval(h);
if(pard == 0) {
h->dm4 = parent->dm4+1;
if(purehepta) h->distance = parent->distance + 1;
else if(parent->s == hsOrigin) h->distance = 2;
else if(h->spin(0) == 5)
if(fixdistance != COMPUTE) h->distance = fixdistance;
else if(purehepta) h->distance = parent->distance + 1;
else if(parent->s == hsOrigin) h->distance = parent->distance + 2;
else if(S3 == 4) {
h->distance = parent->distance + 2;
if(h->spin(0) == 2 || (h->spin(0) == 3 && S7 <= 5))
h->distance = min<short>(h->distance, createStep(h->move[0], 0)->distance + 3);
if(h->spin(0) == 2 && h->move[0]) {
int d = h->spin(0);
int d1 = (d+S7-1)%S7;
heptagon* h1 = createStep(h->move[0], d1);
if(h1->distance <= h->move[0]->distance)
h->distance = h->move[0]->distance+1;
}
if((h->s == hsB && h->move[0]->s == hsB) || h->move[0]->s == hsA) {
int d = h->spin(0);
heptagon* h1 = createStep(h->move[0], (d+1)%S7);
if(h1->distance <= h->move[0]->distance)
h->distance = h->move[0]->distance+1;
}
if(h->spin(0) == S7-1)
h->distance = min(
h->move[0]->move[0]->distance + 2,
createStep(h, S7-1)->distance + 1
);
}
else if(h->spin(0) == S7-2)
h->distance = parent->distance + 1;
else if(h->spin(0) == 4 && h->move[0]->s == hsB)
h->distance = createStep(h->move[0], (h->spin(0)+2)%7)->distance + 3;
else if(h->spin(0) == S7-3 && h->move[0]->s == hsB)
h->distance = createStep(h->move[0], (h->spin(0)+2)%S7)->distance + 3;
else h->distance = parent->distance + 2;
}
else {
h->distance = parent->distance - (purehepta?1:2);
if(S3 == 4 && S7 == 5) {
if(h->s == hsOrigin) {
printf("had to cheat!\n");
h->distance = parent->distance - 2;
}
else {
h->distance = parent->distance - 1;
buildHeptagon(h, 2, hsA, 0, h->distance + 2);
buildHeptagon(h, 4, hsB, 0, h->distance);
}
}
h->dm4 = parent->dm4-1;
}
return h;
@ -173,6 +209,12 @@ void connectHeptagons(heptagon *h1, int d1, heptagon *h2, int d2) {
h2->setspin(d2, d1);
}
int recsteps;
void breakpoint() {
// printf("Breakpoint!\n");
}
void addSpin(heptagon *h, int d, heptagon *from, int rot, int spin) {
rot = fixrot(rot);
createStep(from, rot);
@ -198,8 +240,13 @@ struct heptspin {
heptspin() { mirrored = false; }
};
int lrecsteps;
heptspin hsstep(const heptspin &hs, int spin) {
recsteps++;
if(recsteps % 5 == 0 && recsteps > lrecsteps) lrecsteps = recsteps, breakpoint();
createStep(hs.h, hs.spin);
recsteps--;
heptspin res;
res.h = hs.h->move[hs.spin];
res.mirrored = hs.mirrored ^ hs.h->mirror(hs.spin);
@ -218,13 +265,21 @@ heptspin hsspin(const heptspin &hs, int val) {
heptagon *createStep(heptagon *h, int d) {
d = fixrot(d);
if(!h->move[0] && h->s != hsOrigin) {
buildHeptagon(h, 0, hsA, 3 + hrand(2));
// cheating:
int pard;
if(S3 == 3)
pard = 3 + hrand(2);
else if(S3 == 4 && S7 == 5)
pard = 3; // to do: randomize
else if(S3 == 4)
pard = 3;
buildHeptagon(h, 0, h->distance < -1000 ? hsOrigin : hsA, pard);
}
if(h->move[d]) return h->move[d];
if(h->s == hsOrigin) {
buildHeptagon(h, d, hsA);
}
else if(AT456) {
else if(S3 == 4) {
if(d == 1) {
heptspin hs;
hs.h = h;

11
hyper.h
View File

@ -87,7 +87,7 @@ bool destroyHalfvine(cell *c, eWall newwall = waNone, int tval = 6);
void buildCrossroads2(cell *c);
bool isHaunted(eLand l);
heptagon *createAlternateMap(cell *c, int rad, hstate firststate, int special=0);
void generateAlts(heptagon *h);
void generateAlts(heptagon *h, int levs = S3-3);
void setdist(cell *c, int d, cell *from);
void checkOnYendorPath();
void killThePlayerAt(eMonster m, cell *c, flagtype flags);
@ -536,7 +536,7 @@ extern bool safety;
#define INF 9999
#define INFD 20
#define PINFD 125
#define BARLEV ((ISANDROID||ISIOS||ISFAKEMOBILE||purehepta)?9:10)
#define BARLEV ((ISANDROID||ISIOS||ISFAKEMOBILE||getDistLimit()<7)?9:10)
#define BUGLEV 15
// #define BARLEV 9
@ -1489,8 +1489,6 @@ namespace leader { void showMenu(); void handleKey(int sym, int uni); }
bool needConfirmation();
extern const char* geometrynames_short[gGUARD];
namespace mirror {
cellwalker reflect(const cellwalker& cw);
}
@ -1604,3 +1602,8 @@ transmatrix cellrelmatrix(cell *c, int i);
void terracottaAround(cell *c);
double cellgfxdist(cell *c, int i);
int ctof(cell *c);
void modalDebug(cell *c);
int getDistLimit();

View File

@ -1,17 +1,53 @@
// Hyperbolic Rogue
// Copyright (C) 2011-2012 Zeno Rogue, see 'hyper.cpp' for details
enum eGeometry {gNormal, gEuclid, gSphere, gElliptic, gQuotient, gQuotient2, gTorus, gOctagon, g45, g46, gGUARD};
eGeometry geometry, targetgeometry = gEuclid;
#define euclid (geometry == gEuclid || geometry == gTorus)
#define sphere (geometry == gSphere || geometry == gElliptic)
#define elliptic (geometry == gElliptic)
#define quotient (geometry == gQuotient ? 1 : geometry == gQuotient2 ? 2 : 0)
#define torus (geometry == gTorus)
#define doall (quotient || torus)
enum eGeometry {gNormal, gEuclid, gSphere, gElliptic, gQuotient, gQuotient2, gTorus, gOctagon, g45, g46, g47, gSmallSphere, gTinySphere, gGUARD};
struct geometryinfo {
const char* name;
const char* shortname;
int sides;
int vertex;
int quotientstyle;
int cclass; // 0-hyperbolic, 1-Euclidean, 2-spherical
int distlimit[2]; // truncated, non-truncated
};
static const int qZEBRA = 1;
static const int qFIELD = 2;
static const int qELLIP = 4;
static const int qTORUS = 8;
// note: dnext assumes that x&7 equals 7
static const int SEE_ALL = 15;
static const int FORBIDDEN = -1;
geometryinfo ginf[gGUARD] = {
{"hyperbolic", "hyper", 7, 3, 0, 0, {7, 5}},
{"Euclidean", "euclid", 6, 3, 0, 1, {7, FORBIDDEN}},
{"spherical", "sphere", 5, 3, 0, 2, {SEE_ALL, SEE_ALL}},
{"elliptic", "elliptic", 5, 3, qELLIP, 2, {SEE_ALL, SEE_ALL}},
{"Zebra quotient", "Zebra", 7, 3, qZEBRA, 0, {7, 5}},
{"field quotient", "field", 7, 3, qFIELD, 0, {7, 5}},
{"torus", "torus", 6, 3, qTORUS, 1, {7, FORBIDDEN}},
{"octagons", "oct", 8, 3, 0, 0, {6, 4}},
{"four pentagons", "4x5", 5, 4, 0, 0, {6, 4}},
{"four hexagons", "4x6", 6, 4, 0, 0, {5, 3}},
{"four heptagons", "4x7", 7, 4, 0, 0, {4, 3}},
{"small sphere", "3x4", 4, 3, 0, 2, {SEE_ALL, SEE_ALL}},
{"tiny sphere", "3x3", 3, 3, 0, 2, {SEE_ALL, SEE_ALL}},
};
eGeometry geometry, targetgeometry = gEuclid;
extern bool targettrunc;
#define euclid (ginf[geometry].cclass == 1)
#define sphere (ginf[geometry].cclass == 2)
#define elliptic (ginf[geometry].quotientstyle & 4)
#define quotient (ginf[geometry].quotientstyle & 3)
#define torus (ginf[geometry].quotientstyle & 8)
#define doall (ginf[geometry].quotientstyle)
#define smallbounded (sphere || quotient == 1 || torus)
// for the pure heptagonal grid
bool purehepta = false;

View File

@ -325,22 +325,19 @@ const char *musicfile = "";
const char *loadlevel = NULL;
#endif
#define AT8 (geometry == gOctagon ? 1 : 0)
#define AT45 (geometry == g45 ? 1 : 0)
#define AT46 (geometry == g46 ? 1 : 0)
#define AT456 (AT45 | AT46)
#define AT4568 (AT45 | AT46 | AT8)
#define S7 (sphere?5:AT45?5:AT46?6:AT8?8:euclid?6:7)
#define S6 (AT456 ? 8 : 6)
#define S7 ginf[geometry].sides
#define S3 ginf[geometry].vertex
#define weirdhyperbolic (S7 > 7 || S3 > 3)
#define S6 (S3*2)
#define S42 (S7*S6)
#define S12 (S6*2)
#define S14 (S7*2)
#define S21 (S7*3)
#define S21 (S7*S3)
#define S28 (S7*4)
#define S36 (S6*6)
#define S84 (S7*S6*2)
#define MAX_EDGE 8
#define MAX_S3 4
#define MAX_S84 240
#include "util.cpp"

View File

@ -108,6 +108,25 @@ void giantLandSwitch(cell *c, int d, cell *from) {
break;
case laPalace: // -------------------------------------------------------------
if(weirdhyperbolic) {
if(d == 9) {
int i = hrand(100);
if(i < 10)
c->wall = waPalace;
else if(i < 15)
c->wall = waClosePlate;
else if(i < 20)
c->wall = waOpenPlate;
else if(i < 25)
c->wall = waTrapdoor;
else if(i < 30)
c->wall = waClosedGate;
else if(i < 35)
c->wall = waOpenGate;
}
break;
}
if(d == 9) {
if(cdist50(c) == 3 && polarb50(c) == 1)
@ -1951,18 +1970,31 @@ void repairLandgen(cell *c) {
}
int dnext(int d) {
if(!purehepta && !AT8)
//0,1,2,3,4,5,6,7
return d+1;
else if(!purehepta && AT8)
//0,1,2,3,4,5,7
return d+(d==5?2:1);
else if(purehepta && AT8)
//0,1,3,5,7
return d+(d>=1 && d<7?2:1);
else
// 0,1,2,3,5,7
return d+(d>=3 && d<7?2:1);
switch(getDistLimit()&7) {
case 0:
case 1:
// 0,7
return d+(d<7?7:1);
case 2:
// 0,1,7
return d+(d>=1 && d<7?6:1);
case 3:
// 0,1,4,7
return d+(d>=1 && d<7?3:1);
case 4:
//0,1,3,5,7
return d+(d>=1 && d<7?2:1);
case 5:
// 0,1,2,3,5,7
return d+(d>=3 && d<7?2:1);
case 6:
// 0,1,2,3,4,5,7
return d+(d==5?2:1);
case 7:
//0,1,2,3,4,5,6,7
return d+1;
}
return d+1;
}
void setdist(cell *c, int d, cell *from) {

View File

@ -2196,12 +2196,12 @@ lessalphaif(col, behindsphere(V), behindsphere(gmatrix[c2]))
}
case patTree:
if(c->type != 6 && !euclid)
if(ctof(c) && !euclid)
queueline(tC0(V), V*ddi0(purehepta?S42:0, tessf), col1, 2);
break;
case patAltTree:
if(c->type != 6 && !euclid && c->master->alt) {
if(ctof(c) && !euclid && c->master->alt) {
for(int i=0; i<S7; i++)
if(c->master->move[i] && c->master->move[i]->alt == c->master->alt->move[0])
queueline(tC0(V), V*xspinpush0((purehepta?M_PI:0) -2*M_PI*i/S7, tessf), col, 2);

208
menus.cpp
View File

@ -425,7 +425,7 @@ void showChangeMode() {
dialog::addBoolItem(XLAT("Tutorial"), tour::on, 'T');
#endif
dialog::addBoolItem(XLAT("Euclidean/elliptic mode"), (euclid || sphere), 'e');
dialog::addBoolItem(XLAT("experiment with geometry"), (euclid || sphere), 'e');
dialog::addBoolItem(XLAT(SHMUPTITLE), (shmup::on || multi::players > 1), 's');
if(!shmup::on) dialog::addSelItem(XLAT("hardcore mode"),
hardcore && !pureHardcore() ? XLAT("PARTIAL") : ONOFF(hardcore), 'h');
@ -480,8 +480,10 @@ void showChangeMode() {
}
}
else if(xuni == 'e')
else if(xuni == 'e') {
targettrunc = purehepta;
pushScreen(showEuclideanMenu);
}
else if(xuni == 't') {
clearMessages();
pushScreen(tactic::showMenu);
@ -555,25 +557,164 @@ void showChangeMode() {
int eupage = 0;
int euperpage = 21;
#define LAND_SPHEUC ((AT4568) ? LAND_OCT : (targetgeometry > 1) ? LAND_SPH : LAND_EUC)
#define land_spheuc ((AT4568) ? land_oct : (targetgeometry > 1) ? land_sph : land_euc)
// test all the floor patterns!
const char* geometrynames[gGUARD] = {
"hyperbolic", "Euclidean", "spherical", "elliptic",
"Zebra quotient", "field quotient", "torus", "octagons",
"four pentagons", "four hexagons"
};
#ifdef SCALETUNER
#define LAND_SPHEUC 26
const char* geometrynames_short[gGUARD] = {
"hyper", "Euclid", "sphere", "elliptic",
"Zebra", "field", "torus", "oct", "4,5", "4,6"
};
eLand land_spheuc[LAND_SPHEUC] = {
laDesert,
laBull,
laPalace,
laWildWest,
laPower,
laStorms,
laHell,
laWhirlwind,
laGraveyard,
laTrollheim,
laBurial,
laVolcano,
laRlyeh,
laTortoise,
laRose,
laCrossroads,
laCaves,
laOvergrown,
laAlchemist,
laJungle,
laMotion,
laIce,
laDragon,
laKraken,
laWarpCoast,
laCaribbean
};
#else
#define LAND_SPHEUC ((weirdhyperbolic) ? LAND_OCT : (targetgeometry > 1) ? LAND_SPH : LAND_EUC)
#define land_spheuc ((weirdhyperbolic) ? land_oct : (targetgeometry > 1) ? land_sph : land_euc)
#endif
const char *curvenames[8] = {
"0", "1", "2", "extremely hyperbolic", "strongly hyperbolic", "strongly hyperbolic", "moderately hyperbolic", "weakly hyperbolic"
};
void useHyperrogueGeometry() {
targetgeometry = geometry;
restartGame('g');
if(targettrunc != purehepta) restartGame('7');
}
string euchelp =
"If you want to know how much the gameplay is affected by the "
"hyperbolic geometry in HyperRogue, this mode is for you!\n\n"
"You can try many different geometries here. We start by gluing "
"n-gons in such a way that k of them meet in every vertex. "
"Depending on n and k, this either folds into a sphere, unfolds into a plane, "
"or requires a hyperbolic space. The result may be then 'truncated' by "
"replacing each vertex by a 2k-gon. Furthermore, you can play "
"with quotient geometries. For example, the elliptic geometry is "
"obtained from the sphere by making the antipodes be the same point, "
"so you return to the same spot (but as a mirror image) after going there. "
"Halloween is a land specially designed for the 'sphere' geometry; "
"several more tilings can be played on by playing Graveyard or Warped Coast "
"in a truncated tiling. "
"Have fun experimenting! Not all graphics and lands are implemented in "
"all geometries, but lots of them are.";
void showPickGeometry() {
int ts = ginf[targetgeometry].sides;
int tv = ginf[targetgeometry].vertex;
int tq = ginf[targetgeometry].quotientstyle;
int nom = (targettrunc ? tv : tv+ts) * ((tq & qELLIP) ? 2 : 4);
int denom = (2*ts + 2*tv - ts * tv);
gamescreen(4);
dialog::init(XLAT("select the geometry"));
for(int i=0; i<gGUARD; i++)
dialog::addBoolItem(XLAT(ginf[i].name), targetgeometry == i, 'a'+i);
dialog::addBreak(50);
if(ts == 6 && tv == 3)
dialog::addSelItem("truncated", "does not matter", 't');
else
dialog::addBoolItem("truncated", !targettrunc, 't');
dialog::addBreak(50);
int worldsize = denom ? nom/denom : 0;
if(tq & qTORUS) worldsize = torusconfig::qty;
if(tq & qZEBRA) worldsize = targettrunc ? 12 : 40;
if(tq & qFIELD) {
worldsize = size(fp43.matrices) / ts;
if(!targettrunc) worldsize = (10*worldsize) / 3;
}
dialog::addSelItem("sides per face", its(ts), 0);
dialog::addSelItem("faces per vertex", its(tv), 0);
string qstring = "none";
if(tq & qZEBRA) qstring = "zebra";
else if(tq & qFIELD) qstring = "field";
else if(tq & qELLIP) qstring = "torus";
else if(tq & qTORUS) qstring = "torus";
dialog::addSelItem("quotient space", qstring, 0);
dialog::addSelItem("size of the world",
XLAT(
worldsize == 0 ? "infinite" :
worldsize > 0 ? "finite (%1)" :
"exponentially infinite (%1)", its(worldsize)),
0);
switch(ginf[targetgeometry].cclass) {
case 0:
dialog::addSelItem("curvature", curvenames[ginf[targetgeometry].distlimit[targettrunc]], 0);
break;
case 1:
dialog::addSelItem("curvature", "flat", 0);
break;
case 2:
dialog::addSelItem("curvature", "spherical", 0);
break;
}
dialog::addItem(XLAT("help"), SDLK_F1);
dialog::addItem(XLAT("done"), '0');
dialog::display();
keyhandler = [] (int sym, int uni) {
dialog::handleNavigation(sym, uni);
if(uni >= 'a' && uni < 'a'+gGUARD)
targetgeometry = eGeometry(uni - 'a');
else if(uni == 't')
targettrunc = !targettrunc;
else if(uni == '2' || sym == SDLK_F1) gotoHelp(euchelp);
else if(doexiton(sym, uni)) {
popScreen();
if(targetgeometry == gEuclid) targettrunc = false;
if(targetgeometry == gNormal) popScreen(), useHyperrogueGeometry();
}
};
}
bool targettrunc;
void showEuclideanMenu() {
gamescreen(4);
int s = vid.fsize;
vid.fsize = vid.fsize * 4/5;
dialog::init(XLAT("Euclidean/elliptic mode"));
dialog::init(XLAT("experiment with geometry"));
if(cheater) for(int i=0; i<landtypes; i++) landvisited[i] = true;
for(int i=0; i<landtypes; i++)
if(hiitemsMax(treasureType(eLand(i))) >= 25) landvisited[i] = true;
@ -583,11 +724,17 @@ void showEuclideanMenu() {
landvisited[laPrincessQuest] = cheater || princess::everSaved;
landvisited[laWildWest] = true;
landvisited[laHalloween] = true;
landvisited[laWarpCoast] = true;
landvisited[laGraveyard] = true;
landvisited[laCA] = true;
// for(int i=2; i<lt; i++) landvisited[i] = true;
string truncatenames[2] = {" (t)", " (n)"};
dialog::addSelItem(XLAT("geometry"), XLAT(geometrynames[targetgeometry]), '5');
dialog::addSelItem(XLAT("geometry"), XLAT(ginf[targetgeometry].name) + truncatenames[targettrunc], '5');
dialog::addBreak(50);
eLand current = (geometry == targetgeometry) ? specialland : laNone;
for(int i=0; i<euperpage; i++) {
if(euperpage * eupage + i >= LAND_SPHEUC) { dialog::addBreak(100); break; }
@ -596,7 +743,7 @@ void showEuclideanMenu() {
char ch;
if(i < 26) ch = 'a' + i;
else ch = 'A' + (i-26);
dialog::addItem(XLAT1(linf[l].name), ch);
dialog::addBoolItem(XLAT1(linf[l].name), l == current, ch);
}
else dialog::addBreak(100);
}
@ -622,13 +769,10 @@ void showEuclideanMenu() {
if(lid >= 0) lid += euperpage * eupage;
if(uni == '0') {
targetgeometry = geometry;
restartGame('g');
}
if(uni == '0')
useHyperrogueGeometry();
else if(uni == '5') {
targetgeometry = eGeometry(1+targetgeometry);
if(targetgeometry == gGUARD) targetgeometry = gEuclid;
pushScreen(showPickGeometry);
}
else if(uni == '-' || uni == PSEUDOKEY_WHEELUP || uni == PSEUDOKEY_WHEELDOWN) {
eupage++;
@ -641,23 +785,15 @@ void showEuclideanMenu() {
restartGame('g');
else
restartGame(tactic::on ? 't' : 0);
// switch the truncated if necessary
if(targettrunc != purehepta)
restartGame('7');
// disable PTM if chosen a land from the Euclidean menu
if(tactic::on) restartGame('t');
}
else specialland = laIce;
}
else if(uni == '2' || sym == SDLK_F1) gotoHelp(
"If you want to know how much the gameplay is affected by the "
"hyperbolic geometry in HyperRogue, this mode is for you!\n\n"
"You can play an Euclidean version of each of the lands in "
"HyperRogue. Lands which include horocycles (Temple, Caribbean, "
"Whirlpool), infinite trees (Zebra, Emerald), or networks of "
"ultraparallel lines (Crossroads, Vineyard, Palace) cannot be "
"faithfully represented in Euclidean, so yo get more "
"or less simplified versions of them. Choose Crossroads to play a game "
"where many different lands appear."
);
else if(uni == '2' || sym == SDLK_F1) gotoHelp(euchelp);
else if(doexiton(sym, uni)) popScreen();
};
}
@ -805,8 +941,10 @@ void setAppropriateOverview() {
pushScreen(yendor::showMenu);
else if(peace::on)
pushScreen(peace::showMenu);
else if(geometry != gNormal)
else if(geometry != gNormal) {
targettrunc = purehepta;
pushScreen(showEuclideanMenu);
}
else {
mapeditor::infix = "";
pushScreen(showOverview);

View File

@ -630,13 +630,13 @@ void drawqueue() {
hpcshape
shFloorSide[SIDEPARS][2], shSemiFloorSide[SIDEPARS], shTriheptaSide[SIDEPARS][2], shMFloorSide[SIDEPARS][2],
shFullFloor[2],
shSeabed[2], shCloudSeabed[2], shCaveSeabed[2],
shSeabed[2], shCloudSeabed[3], shCaveSeabed[2],
shWave[8][2],
shFloor[2], shBFloor[2], shMFloor2[2], shMFloor3[2], shMFloor4[2],
shCircleFloor,
shFloorShadow[2], shTriheptaFloorShadow[2], shTriheptaEucShadow[3],
shWall[2], shMineMark[2], shFan,
shStarFloor[2], shCloudFloor[2], shTriFloor[2], shZebra[5],
shStarFloor[3], shCloudFloor[3], shTriFloor[2], shZebra[5],
shButterflyFloor[2], shLavaFloor[2],
shTower[11],
shTurtleFloor[3], shDragonFloor[3], shRoseFloor[3],
@ -748,10 +748,11 @@ struct usershape {
usershape *usershapes[USERSHAPEGROUPS][USERSHAPEIDS];
void drawTentacle(hpcshape &h, ld rad, ld var, ld divby) {
double tlength = max(crossf, hexhexdist);
for(int i=0; i<=20; i++)
hpcpush(ddi(S21, rad + var * sin(i * M_PI/divby)) * ddi(0, crossf * i/20.) * C0);
hpcpush(ddi(S21, rad + var * sin(i * M_PI/divby)) * ddi(0, tlength * i/20.) * C0);
for(int i=20; i>=0; i--)
hpcpush(ddi(S21*3, rad - var * sin(i * M_PI/divby)) * ddi(0, crossf * i/20.) * C0);
hpcpush(ddi(S21*3, rad - var * sin(i * M_PI/divby)) * ddi(0, tlength * i/20.) * C0);
}
hyperpoint hpxd(ld d, ld x, ld y, ld z) {
@ -781,16 +782,14 @@ void bshape(hpcshape& sh, int p) {
first = true;
}
hyperpoint spfix(int rots, hyperpoint h) {
if(!sphere) return h;
if(rots != 7) return h;
double d = atan2(h[0], h[1]);
return spin(M_PI + M_PI * 4/35 * d) * h;
}
vector<array<int, 3>> symmetriesAt;
void bshape(hpcshape& sh, int p, double shzoom, int shapeid, double bonus8 = 0) {
#ifdef SCALETUNER
static const
#endif
double bscale7 = 1, brot7 = 0, bscale6 = 1, brot6 = 0;
void bshape(hpcshape& sh, int p, double shzoom, int shapeid, double bonus = 0) {
bshape(sh, p);
int whereis = 0;
while(polydata[whereis] != NEWSHAPE || polydata[whereis+1] != shapeid) whereis++;
@ -805,20 +804,44 @@ void bshape(hpcshape& sh, int p, double shzoom, int shapeid, double bonus8 = 0)
double shzoomy = shzoom;
if(shzoom == WOLF) shzoomx = 1.5 * (purehepta ? crossf / hcrossf : 1), shzoomy = 1.6 * (purehepta ? crossf / hcrossf : 1);
int rots2 = rots;
double bonus = 0;
if(rots == 7) {
rots2 = S7;
if((S7&1) == 0)
bonus = bonus8;
if(rots2 != 7) bonus += M_PI;
shzoomx *= bscale7;
shzoomy *= bscale7;
bonus += brot7;
}
if(rots == 3) {
rots2 = S3;
shzoomx *= bscale6;
shzoomy *= bscale6;
if(S6 == 8) bonus += .4;
bonus += brot6;
}
if(rots == 6) {
rots2 = S6;
shzoomx *= bscale6;
shzoomy *= bscale6;
if(S6 == 8) bonus += .4;
bonus += brot6;
}
double bonusf = /* sphere ? M_PI*4/35 : */ (rots-rots2+.0) / rots2;
auto ipoint = [&] (int i, int mul) {
hyperpoint h = hpxy(polydata[whereis+2*i] * shzoomx, polydata[whereis+2*i+1] * shzoomy * mul);
if(rots == rots2 && !bonus) return h;
double d = atan2(h[0], h[1]);
return spin(bonus + bonusf * d) * h;
};
for(int r=0; r<rots2; r++) {
for(int i=0; i<qty; i++)
hpcpush(spin(bonus+2*M_PI*r/rots2) * spfix(rots, hpxy(polydata[whereis+2*i] * shzoomx, polydata[whereis+2*i+1] * shzoomy)));
hpcpush(spin(2*M_PI*r/rots2) * ipoint(i, 1));
if(sym == 2)
for(int i=qty-1; i>=0; i--)
hpcpush(spin(bonus+2*M_PI*r/rots2) * spfix(rots, hpxy(polydata[whereis+2*i] * shzoomx, -polydata[whereis+2*i+1] * shzoomy)));
hpcpush(spin(2*M_PI*r/rots2) * ipoint(i, -1));
}
hpcpush(spin(bonus) * spfix(rots, hpxy(polydata[whereis] * shzoomx, polydata[whereis+1] * shzoomy)));
hpcpush(ipoint(0, 1));
}
void copyshape(hpcshape& sh, hpcshape& orig, int p) {
@ -889,8 +912,8 @@ void buildpolys() {
double spzoom7 = sphere ? .8 : 1;
double spzoomd7 = (purehepta && sphere) ? 1 : spzoom7;
double fac80 = AT45 ? 1.4 : AT46 ? 1.2 : .8;
double fac94 = euclid ? .8 : AT456 ? (purehepta ? 1.1 : .9) : .94;
double fac80 = geometry == g45 ? 1.4 : geometry == g46 ? 1.2 : .8;
double fac94 = euclid ? .8 : (S6==4) ? (purehepta ? 1.1 : .9) : .94;
auto MF = [] (double f, int i) { return (f*i)/8; };
@ -901,39 +924,79 @@ void buildpolys() {
double p = -.006;
int td = ((purehepta || euclid) && !(S7&1)) ? S42+S6 : 0;
bool a4 = S6 == 8;
#define SCA4(x) (a4?x:1)
#define ROT4(x) (a4?x:0)
#define SCA46(x) (a4 && S7 == 6?x:1)
#define SCA47(x) (a4 && S7 == 7?x:1)
#define SCA467(x) (a4 && S7 >= 6?x:1)
#define ROT46(x) (a4 && S7 == 6?x:0)
#define ROT47(x) (a4 && S7 == 7?x:0)
#define ROT467(x) (a4 && S7 >= 6?x:0)
#define ROTS4(x) (sphere && S7 == 4?x:0)
#define SCAP4(x) (a4&&purehepta?x:1)
double trihepta0 = scalef*spzoom6*(.2776+p) * SCA4(1.3) * SCA46(.975) * SCA47(.85) * bscale6 * (S7==8?.9:1);
double trihepta1 = (sphere ? .54 : scalef*spzoom6*(.5273-2*p) * SCA4(.8) * SCA46(1.075)) * (sphere&&S7==4?1.3:1) * bscale7;
if(sphere&&S7==3) trihepta0 *= 1.3, trihepta1 *= 1.6;
int tshift0 = (a4?S14:0);
int tshift1 = td + (!(S7&1)) ? S6:0; // +S6+(a4&(S7&1)?S6:0);
bshape(shTriheptaFloor[0], PPR_FLOOR);
for(int t=0; t<=3; t++) hpcpush(ddi(t*S28, scalef*spzoom6*(.2776+p)) * C0);
for(int t=0; t<=S3; t++) hpcpush(ddi(t*S28 + tshift0, trihepta0) * C0);
bshape(shTriheptaFloor[1], PPR_FLOOR);
for(int t=0; t<=S7; t++) hpcpush(ddi(t*12, sphere ? .54 : scalef*spzoom6*(.5273-2*p)) * C0);
for(int t=0; t<=S7; t++) hpcpush(ddi(t*S12 + tshift1, trihepta1) * C0);
bshape(shTriheptaFloorShadow[0], PPR_FLOOR);
for(int t=0; t<=3; t++) hpcpush(ddi(t*S28, scalef*spzoom6*.2776*SHADMUL) * C0);
for(int t=0; t<=S3; t++) hpcpush(ddi(t*S28 + tshift0, trihepta0*SHADMUL) * C0);
bshape(shTriheptaFloorShadow[1], PPR_FLOOR);
for(int t=0; t<=S7; t++) hpcpush(ddi(t*12, sphere ? .54 : scalef*spzoom6*.5273*SHADMUL) * C0);
for(int t=0; t<=S7; t++) hpcpush(ddi(t*S12 + tshift1, trihepta1*SHADMUL) * C0);
{double x = sphere?.401:euclid?.3 : .328;
bshape(shFullFloor[0], PPR_FLOOR);
for(int t=0; t<=6; t++) hpcpush(ddi(S7 + t*S14, x) * C0);
if(a4) x = hcrossf * .7;
if(a4 && S7 == 6) x *= .9125;
if(a4 && S7 == 7) x *= .85;
if(sphere&&S7==4) x*= 1.7;
if(sphere&&S7==3) x*= 2.55;
x *= bscale6;
for(int t=0; t<=S6; t++) hpcpush(ddi(S7 + t*S14, x) * C0);
x = purehepta ? 0.62 : sphere ? .345 : 0.38;
x = purehepta ? 0.62 : sphere ? .345 : euclid ? .3 : 0.38;
if(a4) x = purehepta ? hcrossf: hexf;
if(sphere&&S7==4) x*= 1.3;
if(sphere&&S7==3) x*= 1.5;
x *= bscale7;
bshape(shFullFloor[1], PPR_FLOOR);
for(int t=0; t<=S7; t++) hpcpush(ddi(t*12, x) * C0);
for(int t=0; t<=S7; t++) hpcpush(ddi(t*S12+td, x) * C0);
}
int td = ((purehepta || euclid) && !(S7&1)) ? S42+S6 : 0;
bool strict = false;
if(a4 && purehepta) fac94 *= 1.1;
double floorrad0 = shexf*fac80*spzoom;
double floorrad1 = strict ? hcrossf : euclid ? shexf*fac80*spzoom : shexf*fac94;
bshape(shFloor[0], PPR_FLOOR);
for(int t=0; t<=S6; t++) hpcpush(ddi(S7 + t*S14, shexf*fac80*spzoom) * C0);
for(int t=0; t<=S6; t++) hpcpush(ddi(S7 + t*S14, floorrad0) * C0);
bshape(shCircleFloor, PPR_FLOOR);
for(int t=0; t<=84; t+=2) hpcpush(ddi(t, shexf*.7*spzoom) * C0);
bshape(shFloor[1], PPR_FLOOR);
for(int t=0; t<=S7; t++) hpcpush(ddi(t*S12 + td, strict ? hcrossf : euclid ? shexf*fac80*spzoom : shexf*fac94) * C0);
for(int t=0; t<=S7; t++) hpcpush(ddi(t*S12 + td, floorrad1) * C0);
for(int i=0; i<3; i++) for(int j=0; j<3; j++) shadowmulmatrix[i][j] =
i==2&&j==2 ? 1:
@ -941,10 +1004,10 @@ void buildpolys() {
0;
bshape(shFloorShadow[0], PPR_FLOOR);
for(int t=0; t<=6; t++) hpcpush(ddi(S7 + t*S14, shexf*fac80*spzoom*SHADMUL) * C0);
for(int t=0; t<=6; t++) hpcpush(ddi(S7 + t*S14, floorrad0*SHADMUL) * C0);
bshape(shFloorShadow[1], PPR_FLOOR);
for(int t=0; t<=S7; t++) hpcpush(ddi(t*12, shexf*fac94*SHADMUL) * C0);
for(int t=0; t<=S7; t++) hpcpush(ddi(t*12, floorrad1*SHADMUL) * C0);
// sidewalls for the 3D mode
for(int k=0; k<SIDEPARS; k++) {
@ -959,31 +1022,31 @@ void buildpolys() {
validsidepar[k] = (dlow > 0 && dhi > 0) || (dlow < 0 && dhi < 0);
bshape(shFloorSide[k][0], PPR_LAKEWALL);
for(int t=0; t<=1; t++) hpcpush(ddi(t*S14-S7, shexf*fac80*spzoom) * C0);
for(int t=0; t<=1; t++) hpcpush(ddi(t*S14-S7, floorrad0) * C0);
chasmifyPoly(dlow, dhi, k);
bshape(shFloorSide[k][1], PPR_LAKEWALL);
for(int t=0; t<=1; t++) hpcpush(ddi(t*12-6, shexf*fac94) * C0);
for(int t=0; t<=1; t++) hpcpush(ddi(t*S12-S6, floorrad1) * C0);
chasmifyPoly(dlow, dhi, k);
bshape(shSemiFloorSide[k], PPR_LAKEWALL);
for(int t=0; t<=3; t+=3) hpcpush(ddi(S7 + (3+t)*S14, shexf*fac80*spzoom) * C0);
for(int t=0; t<=3; t+=3) hpcpush(ddi(S7 + (3+t)*S14, floorrad0) * C0);
chasmifyPoly(dlow, dhi, k);
bshape(shTriheptaSide[k][0], PPR_LAKEWALL);
for(int t=0; t<=1; t++) hpcpush(ddi(t*S28-S14, scalef*spzoom6*.2776) * C0);
for(int t=0; t<=1; t++) hpcpush(ddi(t*S28-S14, trihepta0) * C0);
chasmifyPoly(dlow, dhi, k);
bshape(shTriheptaSide[k][1], PPR_LAKEWALL);
for(int t=0; t<=1; t++) hpcpush(ddi(t*12-6, sphere ?.54 : scalef*spzoom6*.5273) * C0);
for(int t=0; t<=1; t++) hpcpush(ddi(t*S12-S6, trihepta1) * C0);
chasmifyPoly(dlow, dhi, k);
bshape(shMFloorSide[k][0], PPR_LAKEWALL);
for(int t=0; t<=1; t++) hpcpush(ddi(t*S14-S7, shexf*MF(fac80,7)*spzoom) * C0);
for(int t=0; t<=1; t++) hpcpush(ddi(t*S14-S7, MF(floorrad0,7)) * C0);
chasmifyPoly(dlow, dhi, k);
bshape(shMFloorSide[k][1], PPR_LAKEWALL);
for(int t=0; t<=1; t++) hpcpush(ddi(t*12-6, shexf*MF(fac94,7)) * C0);
for(int t=0; t<=1; t++) hpcpush(ddi(t*S12-S6, MF(floorrad1,7)) * C0);
chasmifyPoly(dlow, dhi, k);
}
@ -993,28 +1056,28 @@ void buildpolys() {
}
bshape(shMFloor[0], PPR_FLOORa);
for(int t=0; t<=6; t++) hpcpush(ddi(S7 + t*S14, shexf*MF(fac80,7)*spzoom) * C0);
for(int t=0; t<=S6; t++) hpcpush(ddi(S7 + t*S14, shexf*MF(fac80,7)*spzoom) * C0);
bshape(shMFloor[1], PPR_FLOORa);
for(int t=0; t<=S7; t++) hpcpush(ddi(t*12, shexf*MF(fac94,7)) * C0);
for(int t=0; t<=S7; t++) hpcpush(ddi(td + t*S12, shexf*MF(fac94,7)) * C0);
bshape(shMFloor2[0], PPR_FLOORb);
for(int t=0; t<=6; t++) hpcpush(ddi(S7 + t*S14, shexf*MF(fac80,6)*spzoom) * C0);
for(int t=0; t<=S6; t++) hpcpush(ddi(S7 + t*S14, shexf*MF(fac80,6)*spzoom) * C0);
bshape(shMFloor2[1], PPR_FLOORb);
for(int t=0; t<=S7; t++) hpcpush(ddi(t*12, shexf*MF(fac94,6)) * C0);
for(int t=0; t<=S7; t++) hpcpush(ddi(td + t*S12, shexf*MF(fac94,6)) * C0);
bshape(shMFloor3[0], PPR_FLOORc);
for(int t=0; t<=6; t++) hpcpush(ddi(S7 + t*S14, shexf*MF(fac80,5)*spzoom) * C0);
for(int t=0; t<=S6; t++) hpcpush(ddi(S7 + t*S14, shexf*MF(fac80,5)*spzoom) * C0);
bshape(shMFloor3[1], PPR_FLOORc);
for(int t=0; t<=S7; t++) hpcpush(ddi(t*12, shexf*MF(fac94,5)) * C0);
for(int t=0; t<=S7; t++) hpcpush(ddi(td + t*S12, shexf*MF(fac94,5)) * C0);
bshape(shMFloor4[0], PPR_FLOORd);
for(int t=0; t<=6; t++) hpcpush(ddi(S7 + t*S14, shexf*MF(fac80,4)*spzoom) * C0);
for(int t=0; t<=S6; t++) hpcpush(ddi(S7 + t*S14, shexf*MF(fac80,4)*spzoom) * C0);
bshape(shMFloor4[1], PPR_FLOORd);
for(int t=0; t<=S7; t++) hpcpush(ddi(t*12, shexf*MF(fac94,4)) * C0);
for(int t=0; t<=S7; t++) hpcpush(ddi(td + t*S12, shexf*MF(fac94,4)) * C0);
bshape(shBigCarpet1, PPR_GFLOORa);
//for(int t=0; t<=7; t++) hpcpush(ddi(t*12, -shexf*3.5) * C0);
@ -1029,16 +1092,16 @@ void buildpolys() {
for(int t=0; t<=S7; t++) hpcpush(ddi(t*12*3, -shexf*1.7) * C0);
bshape(shBFloor[0], PPR_BFLOOR);
for(int t=0; t<=6; t++) hpcpush(ddi(S7 + t*S14, shexf*.1) * C0);
for(int t=0; t<=S6; t++) hpcpush(ddi(S7 + t*S14, shexf*.1) * C0);
bshape(shBFloor[1], PPR_BFLOOR);
for(int t=0; t<=S7; t++) hpcpush(ddi(t*12, shexf*.1) * C0);
for(int t=0; t<=S7; t++) hpcpush(ddi(t*S12, shexf*.1) * C0);
bshape(shMineMark[0], PPR_MINEMARK);
for(int t=0; t<=6; t++) hpcpush(ddi(S7 + t*S14, shexf*.1) * C0);
for(int t=0; t<=S6; t++) hpcpush(ddi(S7 + t*S14, shexf*.1) * C0);
bshape(shMineMark[1], PPR_MINEMARK);
for(int t=0; t<=S7; t++) hpcpush(ddi(t*12, shexf*.1) * C0);
for(int t=0; t<=S7; t++) hpcpush(ddi(t*S12, shexf*.1) * C0);
for(int d=0; d<2; d++) {
bshape(shSemiBFloor[d], PPR_BFLOOR);
@ -1120,30 +1183,35 @@ void buildpolys() {
for(int t=0; t<=4; t++) {
hpcpush(ddi(t*S28, shexf*.5) * C0);
}
double disksize = crossf;
if(purehepta && S7 == 8) disksize *= 2;
else if(S7 == 8) disksize *= 1.5;
else if(purehepta && S6 == 8) disksize *= 1.5;
bshape(shDisk, PPR_ITEM);
for(int i=0; i<=S84; i+=3)
hpcpush(ddi(i, crossf * .2) * C0);
hpcpush(ddi(i, disksize * .2) * C0);
bshape(shDiskT, PPR_ITEM);
for(int i=0; i<=S84; i+=S28)
hpcpush(ddi(i, crossf * .2) * C0);
hpcpush(ddi(i, disksize * .2) * C0);
bshape(shDiskS, PPR_ITEM);
for(int i=0; i<=S84; i+=S21) {
hpcpush(ddi(i, crossf * .2) * C0);
hpcpush(ddi(i+S21/3, crossf * .1) * C0);
hpcpush(ddi(i+S21-S21/3, crossf * .1) * C0);
hpcpush(ddi(i, disksize * .2) * C0);
hpcpush(ddi(i+S21/3, disksize * .1) * C0);
hpcpush(ddi(i+S21-S21/3, disksize * .1) * C0);
}
bshape(shDiskM, PPR_ITEM);
for(int i=0; i<=S84; i+=3) {
hpcpush(ddi(i, crossf * .1) * C0);
hpcpush(ddi(i, disksize * .1) * C0);
}
bshape(shDiskSq, PPR_ITEM);
for(int i=0; i<=S84; i+=21) {
hpcpush(ddi(i, crossf * .15) * C0);
hpcpush(ddi(i, disksize * .15) * C0);
}
bshape(shEgg, PPR_ITEM);
@ -1152,55 +1220,55 @@ void buildpolys() {
bshape(shRing, PPR_ITEM);
for(int i=0; i<=S84; i+=3)
hpcpush(ddi(i, crossf * .25) * C0);
hpcpush(ddi(i, disksize * .25) * C0);
for(int i=S84; i>=0; i--)
hpcpush(ddi(i, crossf * .30) * C0);
hpcpush(ddi(0, crossf * .25) * C0);
hpcpush(ddi(i, disksize * .30) * C0);
hpcpush(ddi(0, disksize * .25) * C0);
bshape(shSpikedRing, PPR_ITEM);
for(int i=0; i<=S84; i+=3)
hpcpush(ddi(i, crossf * .25) * C0);
hpcpush(ddi(i, disksize * .25) * C0);
for(int i=S84; i>=0; i--)
hpcpush(ddi(i, crossf * (i&1?.35:.30)) * C0);
hpcpush(ddi(0, crossf * .25) * C0);
hpcpush(ddi(i, disksize * (i&1?.35:.30)) * C0);
hpcpush(ddi(0, disksize * .25) * C0);
bshape(shTargetRing, PPR_ITEM);
for(int i=0; i<=S84; i+=3)
hpcpush(ddi(i, crossf * .25) * C0);
hpcpush(ddi(i, disksize * .25) * C0);
for(int i=S84; i>=0; i--)
hpcpush(ddi(i, crossf * (i >= S42-6 && i <= S42+6 ?.36:.30)) * C0);
hpcpush(ddi(0, crossf * .25) * C0);
hpcpush(ddi(i, disksize * (i >= S42-6 && i <= S42+6 ?.36:.30)) * C0);
hpcpush(ddi(0, disksize * .25) * C0);
bshape(shSpearRing, PPR_ITEM);
for(int i=0; i<=S84; i+=3)
hpcpush(ddi(i, crossf * .25) * C0);
hpcpush(ddi(i, disksize * .25) * C0);
for(int i=S84; i>=0; i--) {
int d = i - S42;
if(d<0) d = -d;
d = 8 - 2 * d;
if(d<0) d = 0;
hpcpush(ddi(i, crossf * (.3 + .04 * d)) * C0);
hpcpush(ddi(i, disksize * (.3 + .04 * d)) * C0);
}
hpcpush(ddi(0, crossf * .25) * C0);
hpcpush(ddi(0, disksize * .25) * C0);
/* three nice spikes
bshape(shLoveRing, PPR_ITEM);
for(int i=0; i<=S84; i+=3)
hpcpush(ddi(i, crossf * .25) * C0);
hpcpush(ddi(i, disksize * .25) * C0);
for(int i=S84; i>=0; i--) {
int j = i*3 % S84;
int d = j - S42;
if(d<0) d = -d;
d = 8 - 2 * d;
if(d<0) d = 0;
hpcpush(ddi(i, crossf * (.3 + .02 * d)) * C0);
hpcpush(ddi(i, disksize * (.3 + .02 * d)) * C0);
}
hpcpush(ddi(0, crossf * .25) * C0);
hpcpush(ddi(0, disksize * .25) * C0);
*/
bshape(shLoveRing, PPR_ITEM);
for(int i=0; i<=S84; i+=3)
hpcpush(ddi(i, crossf * .25) * C0);
hpcpush(ddi(i, disksize * .25) * C0);
for(int i=S84; i>=0; i--) {
int j = i*3 % S84;
double d = j - S42;
@ -1209,37 +1277,37 @@ void buildpolys() {
d = 8 - 2 * d;
if(d<0) d = 0;
if(d >= 6) d -= (d-6)/3;
hpcpush(ddi(i, crossf * (.27 + .02 * d)) * C0);
hpcpush(ddi(i, disksize * (.27 + .02 * d)) * C0);
}
hpcpush(ddi(0, crossf * .25) * C0);
hpcpush(ddi(0, disksize * .25) * C0);
bshape(shSawRing, PPR_ITEM);
for(int i=0; i<=S84; i+=3)
hpcpush(ddi(i, crossf * .25) * C0);
hpcpush(ddi(i, disksize * .25) * C0);
for(int i=S84; i>=0; i--)
hpcpush(ddi(i, crossf * (.3 + (i&3) * .02)) * C0);
hpcpush(ddi(0, crossf * .25) * C0);
hpcpush(ddi(i, disksize * (.3 + (i&3) * .02)) * C0);
hpcpush(ddi(0, disksize * .25) * C0);
bshape(shGearRing, PPR_ITEM);
for(int i=0; i<=S84; i+=3)
hpcpush(ddi(i, crossf * .25) * C0);
hpcpush(ddi(i, disksize * .25) * C0);
for(int i=S84; i>=0; i--)
hpcpush(ddi(i, crossf * ((i%6<3)?.3:.36)) * C0);
hpcpush(ddi(0, crossf * .25) * C0);
hpcpush(ddi(i, disksize * ((i%6<3)?.3:.36)) * C0);
hpcpush(ddi(0, disksize * .25) * C0);
bshape(shPeaceRing, PPR_ITEM);
for(int i=0; i<=S84; i+=3)
hpcpush(ddi(i, crossf * .25) * C0);
hpcpush(ddi(i, disksize * .25) * C0);
for(int i=S84; i>=0; i--)
hpcpush(ddi(i, crossf * (i%28 < 7?.36 : .3)) * C0);
hpcpush(ddi(0, crossf * .25) * C0);
hpcpush(ddi(i, disksize * (i%28 < 7?.36 : .3)) * C0);
hpcpush(ddi(0, disksize * .25) * C0);
bshape(shHeptaRing, PPR_ITEM);
for(int i=0; i<=S84; i+=3)
hpcpush(ddi(i, crossf * .25) * C0);
hpcpush(ddi(i, disksize * .25) * C0);
for(int i=S84; i>=0; i--)
hpcpush(ddi(i, crossf * (i%12 < 3?.4 : .27)) * C0);
hpcpush(ddi(0, crossf * .25) * C0);
hpcpush(ddi(i, disksize * (i%12 < 3?.4 : .27)) * C0);
hpcpush(ddi(0, disksize * .25) * C0);
bshape(shCompass1, PPR_ITEM);
for(int i=0; i<=S84; i+=3)
@ -1274,25 +1342,25 @@ void buildpolys() {
hpcpush(ddi(i, crossf * (0.7 + .2 * sin(i * M_PI * 2 / S84 * 9))) * C0);
bshape(shHeptaMarker, PPR_HEPTAMARK);
for(int t=0; t<=S7; t++) hpcpush(ddi(t*12, shexf*.2) * C0);
for(int t=0; t<=S7; t++) hpcpush(ddi(t*S12, shexf*.2) * C0);
bshape(shSnowball, PPR_ITEM);
for(int t=0; t<=S7*4; t++) hpcpush(ddi(t*3, shexf*.1) * C0);
for(int t=0; t<=S7*4; t++) hpcpush(ddi(t*S3, shexf*.1) * C0);
bshape(shBigHepta, PPR_FLOOR);
for(int t=0; t<=S7; t++) hpcpush(ddi(t*12, -shexf*1.5) * C0);
for(int t=0; t<=S7; t++) hpcpush(ddi(t*S12, -shexf*1.5) * C0);
bshape(shBigHex, PPR_FLOOR);
for(int t=0; t<=6; t++) hpcpush(ddi(t*S14, -shexf*1.3) * C0);
for(int t=0; t<=S6; t++) hpcpush(ddi(t*S14, -shexf*1.3) * C0);
bshape(shBigTriangle, PPR_FLOOR);
for(int t=0; t<=3; t++) hpcpush(ddi(t*S28, -shexf*1.5) * C0);
for(int t=0; t<=S3; t++) hpcpush(ddi(t*S28, -shexf*1.5) * C0);
bshape(shBigHexTriangleRev, PPR_FLOOR);
for(int t=0; t<=3; t++) hpcpush(ddi(t*S28, -shexf*1.3) * C0);
for(int t=0; t<=S3; t++) hpcpush(ddi(t*S28, -shexf*1.3) * C0);
bshape(shBigHexTriangle, PPR_FLOOR);
for(int t=0; t<=3; t++) hpcpush(ddi(S14+t*S28, -shexf*1.3) * C0);
for(int t=0; t<=S3; t++) hpcpush(ddi(S14+t*S28, -shexf*1.3) * C0);
bshape(shRose, PPR_ITEM);
for(int t=0; t<S84; t++)
@ -1310,47 +1378,69 @@ void buildpolys() {
}
// hand-drawn shapes
// floors:
bshape(shStarFloor[0], PPR_FLOOR, scalef2*spzoom6, 1);
if(euclid)
bshape(shStarFloor[1], PPR_FLOOR, scalef2*spzoom6, 1);
else
bshape(shStarFloor[1], PPR_FLOOR, scalef2*spzoomd7, 2, .9);
bshape(shCloudFloor[0], PPR_FLOOR, scalef2*spzoom6, 3);
bshape(shCloudFloor[1], PPR_FLOOR, scalef2*spzoomd7, 4, .17);
bshape(shCrossFloor[0], PPR_FLOOR, scalef*spzoom6, 5);
bshape(shCrossFloor[1], PPR_FLOOR, scalef*spzoomd7, 6);
bshape(shChargedFloor[0], PPR_FLOOR, scalef*spzoom6, 8);
if(S7 == 8) spzoom6 *= .9;
if(a4 && !purehepta) spzoom6 *= 1.9, spzoom7 *= .9, spzoomd7 *= .9;
if(a4 && !purehepta && S7 == 6) spzoom6 *= .9;
if(a4 && !purehepta && S7 == 7) spzoom6 *= .85;
double espzoom6 = spzoom6, espzoomd7 = spzoomd7;
if(euclid) espzoom6 *= 1.5, espzoomd7 *= 1.2;
double octroll = S7 == 8 ? .2 : (S7 == 6 && a4) ? -.2 : (S7 == 7 && a4) ? .1 : 0;
double ffscale6 = SCA4(.675);
double ffspin6 = ROT4(.125);
double ffspin7 = ROT4(-.45);
double ffscale2 = SCA4(.7);
double ffspin2 = ROT4(M_PI/4);
// floors:
bshape(shStarFloor[0], PPR_FLOOR, scalef2*spzoom6*ffscale2, 1, ffspin2);
bshape(shStarFloor[1], PPR_FLOOR, scalef2*spzoomd7*ffscale2*SCAP4(1.5), 2, octroll);
bshape(shStarFloor[2], PPR_FLOOR, scalef2*spzoom6, 1);
bshape(shCloudFloor[0], PPR_FLOOR, scalef2*spzoom6*(sphere?.9:1)*ffscale2, 3, ffspin2);
bshape(shCloudFloor[1], PPR_FLOOR, scalef2*spzoomd7*ffscale2*SCAP4(1.5), 4, octroll);
bshape(shCloudFloor[2], PPR_FLOOR, scalef2*spzoom6*.9, 3);
bshape(shCrossFloor[0], PPR_FLOOR, scalef*espzoom6*(sphere?.9:1)*ffscale2, 5, ffspin2);
bshape(shCrossFloor[1], PPR_FLOOR, scalef*espzoomd7*(sphere?.9:1)*ffscale2 * SCA47(1.3), 6, octroll);
bshape(shChargedFloor[0], PPR_FLOOR, scalef*espzoom6*(sphere?.9:1)*ffscale2, 7, ffspin2);
bshape(shChargedFloor[1], PPR_FLOOR, scalef*spzoomd7, 9);
bshape(shChargedFloor[2], PPR_FLOOR, scalef*spzoom6, 7);
bshape(shChargedFloor[3], 12, spzoomd7 * (sphere&&purehepta?.9:1), 10); // purehepta variant
bshape(shSStarFloor[0], PPR_FLOOR, scalef*spzoom6, 11);
bshape(shSStarFloor[1], PPR_FLOOR, scalef*spzoomd7, 12);
bshape(shChargedFloor[2], PPR_FLOOR, scalef*espzoom6, 7);
bshape(shChargedFloor[3], 12, spzoomd7 * (sphere&&purehepta?.9:1) * SCA4(1.2), 10); // purehepta variant
bshape(shSStarFloor[0], PPR_FLOOR, scalef*spzoom6*(euclid?1.4:sphere?.8:1)*ffscale2, 11, ROT4(.775));
bshape(shSStarFloor[1], PPR_FLOOR, scalef*spzoomd7*(euclid?1.2:1)*SCA4(.85), 12, octroll);
bshape(shOverFloor[0], PPR_FLOOR, scalef*spzoom, 13);
if(purehepta) bshape(shOverFloor[1], PPR_FLOOR, sphere ? .83 : 1, 14);
if(purehepta) bshape(shOverFloor[1], PPR_FLOOR, sphere ? .83 : 1, 14, octroll);
else bshape(shOverFloor[1], PPR_FLOOR, scalef*spzoom7, 15);
bshape(shOverFloor[2], PPR_FLOOR, 1*spzoom7, 16);
bshape(shTriFloor[0], PPR_FLOOR, scalef*spzoom6, 17);
bshape(shTriFloor[1], PPR_FLOOR, scalef*spzoomd7, 18);
bshape(shFeatherFloor[0], PPR_FLOOR, scalef*spzoom6, 19);
if(purehepta) bshape(shFeatherFloor[1], PPR_FLOOR, sphere ? .83 : 1, 20);
else bshape(shFeatherFloor[1], PPR_FLOOR, scalef*spzoom7, 21);
bshape(shTriFloor[0], PPR_FLOOR, scalef*espzoom6*(sphere?.9:1)*ffscale2*SCA4(0.9), 17, ffspin2 + ROT47(.1));
bshape(shTriFloor[1], PPR_FLOOR, scalef*espzoomd7*ffscale2*SCA4(1.2)*SCA47(1.5), 18, octroll + ROT4(.25) - ROT47(.1) + ROTS4(.7));
bshape(shFeatherFloor[0], PPR_FLOOR, scalef*spzoom6*ffscale2, 19, ffspin2);
if(purehepta) bshape(shFeatherFloor[1], PPR_FLOOR, sphere ? .83 : SCAP4(1.1), 20);
else bshape(shFeatherFloor[1], PPR_FLOOR, scalef*spzoom7*(sphere?1.1:1)*ffscale2*(a4?1.1:1), 21, sphere?1.3:0);
bshape(shFeatherFloor[2], PPR_FLOOR, 1, 22); // Euclidean variant
bshape(shBarrowFloor[0], PPR_FLOOR, spzoom6, 23);
bshape(shBarrowFloor[1], PPR_FLOOR, (sphere&&purehepta?.9:1) * spzoomd7, 24);
bshape(shBarrowFloor[0], PPR_FLOOR, spzoom6 * (S7==8?1.4:1) * SCA467(1.7) * SCA46(.8), 23);
bshape(shBarrowFloor[1], PPR_FLOOR, (sphere&&purehepta?.9:1) * spzoomd7 * (S7==8?1.5:1) * SCA4(1.15) * SCA467(1.9) * SCA46(.8), 24, octroll - ROT47(.1));
bshape(shBarrowFloor[2], PPR_FLOOR, sphere?.9:1, 25);
bshape(shNewFloor[0], PPR_FLOOR, scalef*spzoom6, 26);
bshape(shNewFloor[1], PPR_FLOOR, scalef*spzoomd7, 27);
bshape(shTrollFloor[0], PPR_FLOOR, 1*spzoom6, 28);
bshape(shTrollFloor[1], PPR_FLOOR, 1*spzoomd7, 29);
bshape(shNewFloor[0], PPR_FLOOR, scalef*espzoom6 * ffscale2, 26, ffspin2);
bshape(shNewFloor[1], PPR_FLOOR, scalef*espzoomd7 * ffscale2, 27, octroll);
bshape(shButterflyFloor[0], PPR_FLOOR, scalef*spzoom6, 325);
bshape(shButterflyFloor[1], PPR_FLOOR, scalef*spzoomd7, 326);
bshape(shTrollFloor[0], PPR_FLOOR, 1*spzoom6*(S7==8?1.4:1)*SCA467(1.6) * SCA46(.8), 28);
bshape(shTrollFloor[1], PPR_FLOOR, 1*spzoomd7*(S7==8?1.6:1)*SCA467(2.4) * SCA46(.8), 29, octroll);
bshape(shLavaFloor[0], PPR_FLOOR, scalef*spzoom6, 359);
bshape(shLavaFloor[1], PPR_FLOOR, scalef*spzoomd7, 360);
bshape(shButterflyFloor[0], PPR_FLOOR, scalef*espzoom6*(sphere?.9:1)*ffscale2, 325, ffspin2);
bshape(shButterflyFloor[1], PPR_FLOOR, scalef*espzoomd7*ffscale2, 326, sphere?.7:0);
bshape(shLavaFloor[0], PPR_FLOOR, scalef*espzoom6 * ffscale2, 359, ffspin2);
bshape(shLavaFloor[1], PPR_FLOOR, scalef*espzoomd7 * ffscale2 * SCA467(1.4), 360, octroll);
bshape(shHalfFloor[0], PPR_FLOOR, scalef*spzoom6, 329);
bshape(shHalfFloor[1], PPR_FLOOR, scalef*spzoom6, 327);
@ -1361,8 +1451,9 @@ void buildpolys() {
bshape(shSeabed[0], PPR_FLOOR, scalef*spzoom6, 334);
bshape(shSeabed[1], PPR_FLOOR, scalef*spzoom6, 335);
bshape(shCloudSeabed[0], PPR_FLOOR, scalef*spzoom6, 336);
bshape(shCloudSeabed[1], PPR_FLOOR, scalef*spzoom6, 337);
bshape(shCloudSeabed[0], PPR_FLOOR, scalef*spzoom6 * SCA46(.8) * SCA47(.75), 336);
bshape(shCloudSeabed[1], PPR_FLOOR, scalef*spzoom6 * SCA46(.5) * SCA47(.6), 337, ROT46(-.2));
bshape(shCloudSeabed[2], PPR_FLOOR, scalef*espzoom6*0.825, 337);
bshape(shCaveSeabed[0], PPR_FLOOR, scalef*spzoom6, 338);
bshape(shCaveSeabed[1], PPR_FLOOR, scalef*spzoom6, 339);
@ -1388,41 +1479,41 @@ void buildpolys() {
bshape(shTriheptaFloor2[0], PPR_FLOOR, scalef, 40);
bshape(shTriheptaFloor2[1], PPR_FLOOR, scalef, 41);
bshape(shSemiFloorShadow, PPR_FLOOR, scalef, 263);
bshape(shTriheptaEuc[0], PPR_FLOOR, scalef, 42);
bshape(shTriheptaEuc[1], PPR_FLOOR, scalef, 43);
bshape(shTriheptaEuc[2], PPR_FLOOR, scalef, 44);
bshape(shTriheptaEuc[0], PPR_FLOOR, scalef * 1.5, 42);
bshape(shTriheptaEuc[1], PPR_FLOOR, scalef * 1.5, 43);
bshape(shTriheptaEuc[2], PPR_FLOOR, scalef * 1.5, 44);
bshape(shTriheptaEucShadow[0], PPR_FLOOR, scalef*SHADMUL, 42);
bshape(shTriheptaEucShadow[1], PPR_FLOOR, scalef*SHADMUL, 43);
bshape(shTriheptaEucShadow[2], PPR_FLOOR, scalef*SHADMUL, 44);
bshape(shPalaceFloor[0], PPR_FLOOR, scalef*spzoom6, 45);
bshape(shPalaceFloor[1], PPR_FLOOR, scalef*spzoomd7, 46);
bshape(shPalaceFloor[0], PPR_FLOOR, scalef*espzoom6*ffscale2, 45, ROT4(.775));
bshape(shPalaceFloor[1], PPR_FLOOR, scalef*espzoomd7*(euclid?1.1:1)*SCA4(.85), 46, (euclid ? M_PI/2-.4 : S7==8 ? -.6 : 0) + ROT46(-.3));
bshape(shMercuryBridge[0], PPR_FLOOR, scalef*spzoom6, 365);
bshape(shMercuryBridge[1], PPR_FLOOR, scalef*spzoomd7, 366);
bshape(shWindArrow, PPR_HEPTAMARK, scalef, 367);
bshape(shPalaceGate, PPR_STRUCT1, scalef, 47);
bshape(shSemiFeatherFloor[0], PPR_FLOOR, scalef*spzoom6, 48);
bshape(shSemiFeatherFloor[1], PPR_FLOOR, scalef*spzoom6, 49);
bshape(shDemonFloor[1], PPR_FLOOR, scalef*spzoomd7, 50);
bshape(shDemonFloor[0], PPR_FLOOR, scalef*spzoom6, 51);
bshape(shCaveFloor[0], PPR_FLOOR, scalef*spzoom6, 52);
bshape(shCaveFloor[1], PPR_FLOOR, scalef*spzoomd7, 53);
bshape(shDemonFloor[1], PPR_FLOOR, scalef*espzoomd7*(sphere?.9:1) * ffscale2 * SCAP4(1.6), 50, (sphere?M_PI:S7==8?.2:0));
bshape(shDemonFloor[0], PPR_FLOOR, scalef*espzoom6*(sphere?.9:1) * ffscale2, 51, ffspin2);
bshape(shCaveFloor[0], PPR_FLOOR, scalef*spzoom6 * ffscale2, 52, ffspin2);
bshape(shCaveFloor[1], PPR_FLOOR, scalef*spzoomd7 * ffscale2 * (sphere?.9:1) * SCAP4(1.6), 53, octroll);
bshape(shCaveFloor[2], PPR_FLOOR, 1, 54); // Euclidean variant
bshape(shDesertFloor[0], PPR_FLOOR, scalef*spzoom6, 55);
bshape(shDesertFloor[1], PPR_FLOOR, scalef*spzoomd7, 56, 2.7);
bshape(shDesertFloor[0], PPR_FLOOR, scalef*espzoom6*ffscale6, 55, ffspin6);
bshape(shDesertFloor[1], PPR_FLOOR, scalef*espzoomd7*(sphere?.9:1), 56, octroll+ffspin7);
for(int i=1; i<=3; i++) for(int j=0; j<2; j++)
zoomShape(shDesertFloor[j], shRedRockFloor[i-1][j], 1 - .1 * i, PPR_FLOORa+i);
bshape(shPowerFloor[0], PPR_FLOOR_DRAGON, scalef*spzoom6, 57);
bshape(shPowerFloor[1], PPR_FLOOR_DRAGON, scalef*spzoomd7, 58);
bshape(shPowerFloor[0], PPR_FLOOR_DRAGON, scalef*espzoom6*(sphere?.8:1)*ffscale2, 57, ffspin2);
bshape(shPowerFloor[1], PPR_FLOOR_DRAGON, scalef*espzoomd7*ffscale2, 58, euclid?M_PI/2:octroll);
bshape(shRoseFloor[2], PPR_FLOOR, 1, 173); // purehepta
bshape(shRoseFloor[0], PPR_FLOOR, 1, 174);
bshape(shRoseFloor[1], PPR_FLOOR, scalef, 175);
bshape(shTurtleFloor[0], PPR_FLOOR, 1, 176);
bshape(shTurtleFloor[1], PPR_FLOOR, scalef, 177);
bshape(shRoseFloor[1], PPR_FLOOR, scalef * SCAP4(.85), 175, (purehepta && a4 ? M_PI/8 : 0));
bshape(shTurtleFloor[0], PPR_FLOOR, (sphere?.9*1.3: a4 ? 1.6 : S7==8 ? 1.3 : 1) * SCA46(1.4) * SCA47(1.4), 176);
bshape(shTurtleFloor[1], PPR_FLOOR, scalef * (euclid?1.2:a4?.9:1) * SCA47(1.3), 177, (euclid ? M_PI/2 : octroll) - ROT47(.1));
bshape(shTurtleFloor[2], PPR_FLOOR, sphere && purehepta ? .9 : 1, 178); // purehepta
bshape(shDragonFloor[0], PPR_FLOOR_DRAGON, 1, 181);
bshape(shDragonFloor[1], PPR_FLOOR_DRAGON, scalef, 182);
bshape(shDragonFloor[0], PPR_FLOOR_DRAGON, (S7==8?1.3:1) * SCA4(1.6), 181, ffspin2);
bshape(shDragonFloor[1], PPR_FLOOR_DRAGON, (sphere ? .9:1) * (S7==8?1.1:1) * SCA4(.9) * scalef, 182, octroll);
bshape(shDragonFloor[2], PPR_FLOOR, 1, 183);
bshape(shZebra[0], PPR_FLOOR, scalef, 162);
bshape(shZebra[1], PPR_FLOOR, scalef, 163);
@ -1849,6 +1940,7 @@ bool isSpecial(const hpcshape &h) {
}
const hpcshape& getSeabed(const hpcshape& c) {
if(&c == &shCloudFloor[2]) return shCloudSeabed[2];
if(purehepta || euclid || sphere) return c;
if(&c == &shFloor[0]) return shFullFloor[0];
if(&c == &shFloor[1]) return shFullFloor[1];
@ -2902,3 +2994,38 @@ NEWSHAPE, 367, 1, 2, -0.096569,0.019944, 0.040859,0.019906, 0.037742,0.058710, 0
NEWSHAPE
};
/* floors */
// need eswap
#define DESERTFLOOR (purehepta ? shCloudFloor : shDesertFloor)[ct6]
#define BUTTERFLYFLOOR (purehepta ? shFloor : shButterflyFloor)[ct6]
#define PALACEFLOOR (purehepta?shFloor:shPalaceFloor)[ct6]
#define SSTARFLOOR (purehepta ? shCloudFloor : shSStarFloor)[ct6] // untested
#define POWERFLOOR (purehepta ? shStarFloor : shPowerFloor)[ct6] // untested
#define CHARGEDFLOOR (purehepta ? shChargedFloor[3] : ct6 ? shFloor[1] : shChargedFloor[0]) // scale!
#define DEMONFLOOR shDemonFloor[ct6] // untested
#define NEWFLOOR (purehepta ? shCloudFloor : shNewFloor)[ct6] // untested
#define CROSSFLOOR (purehepta ? shFloor : shCrossFloor)[ct6] // untested
#define TROLLFLOOR shTrollFloor[ct6] // tested?
#define BARROWFLOOR shBarrowFloor[euclid?0:purehepta?2:ct6]
#define LAVAFLOOR (purehepta ? shFloor : shLavaFloor)[ct6]
#define TRIFLOOR ((purehepta ? shFloor : shTriFloor)[ct6])
#define TURTLEFLOOR shTurtleFloor[ct6]
#define ROSEFLOOR shRoseFloor[ct6]
#define ECT (euclid?2:ct6)
// no eswap
#define PLAINFLOOR shFloor[ct6]
#define FULLFLOOR shFullFloor[ct6]
#define CAVEFLOOR shCaveFloor[ECT]
#define OVERFLOOR shOverFloor[ECT]
#define CLOUDFLOOR shCloudFloor[ECT]
#define FEATHERFLOOR shFeatherFloor[ECT]
#define MFLOOR1 shMFloor[ct6]
#define MFLOOR2 shMFloor2[ct6]
#define STARFLOOR shStarFloor[ECT]
#define DRAGONFLOOR shDragonFloor[ECT]
// fix Warp
// fix Kraken

View File

@ -59,7 +59,7 @@ string modedesc(score *S) {
eGeometry g = (eGeometry) S->box[116];
if(S->box[238]) g = gSphere;
if(S->box[239]) g = gElliptic;
string s = geometrynames_short[g];
string s = ginf[g].shortname;
if(g != gNormal) s += " " + csub(XLATT1((eLand) S->box[120]), 3);
if(S->box[186]) s += "/7";
if(S->box[196]) s += "/C";

View File

@ -103,7 +103,7 @@ void initgame() {
if(isGravityLand(firstland) && !tactic::on) firstland = laCrossroads;
cwt.c = currentmap->gamestart(); cwt.spin = 0; cwt.mirrored = false;
cwt.c->land = (euclid || sphere || AT4568) ? specialland : firstland;
cwt.c->land = geometry ? specialland : firstland;
chaosAchieved = false;