octagonal geometry and 10.0g

This commit is contained in:
Zeno Rogue 2017-10-27 20:07:58 +02:00
parent b9fe2b3ec9
commit 8a44a09de5
17 changed files with 179 additions and 106 deletions

View File

@ -177,7 +177,7 @@ heptagon *createAlternateMap(cell *c, int rad, hstate firststate, int special) {
alt->s = firststate;
alt->emeraldval = 0;
alt->zebraval = 0;
for(int i=0; i<7; i++) alt->move[i] = NULL;
for(int i=0; i<MAX_EDGE; i++) alt->move[i] = NULL;
alt->distance = 0;
alt->c7 = NULL;
alt->alt = alt;
@ -225,7 +225,7 @@ void generateTreasureIsland(cell *c) {
beCIsland(c);
if(c->wall == waCTree) return;
}
cell* ctab[7];
cell* ctab[MAX_EDGE];
int qc = 0, qlo, qhi;
for(int i=0; i<c->type; i++) {
cell *c2 = createMov(c, i);
@ -578,7 +578,7 @@ void buildEquidistant(cell *c) {
}
cell *randomDown(cell *c) {
cell *tab[7];
cell *tab[MAX_EDGE];
int q=0;
for(int i=0; i<c->type; i++)
if(c->mov[i] && coastval(c->mov[i], laIvoryTower) < coastval(c, laIvoryTower))
@ -845,7 +845,7 @@ bool quickfind(eLand l) {
#define I10000 (INVLUCK?3000:10000)
void buildBigStuff(cell *c, cell *from) {
if(sphere || quotient) return;
if(sphere || quotient || AT8) return;
bool deepOcean = false;
if(c->land == laOcean) {

View File

@ -32,7 +32,7 @@ struct cell : gcell {
int mirror(int d) { return tmirror(spintable, d); }
heptagon *master;
cell *mov[7]; // meaning very similar to heptagon::move
cell *mov[MAX_EDGE]; // meaning very similar to heptagon::move
};
int fixdir(int a, cell *c) { a %= c->type; if(a<0) a += c->type; return a; }
@ -46,7 +46,7 @@ cell *newCell(int type, heptagon *master) {
cellcount++;
c->type = type;
c->master = master;
for(int i=0; i<7; i++) c->mov[i] = NULL;
for(int i=0; i<MAX_EDGE; i++) c->mov[i] = NULL;
initcell(c);
return c;
}
@ -152,12 +152,12 @@ struct hrmap_hyperbolic : hrmap {
h.fieldval = 0;
h.rval0 = h.rval1 = 0;
h.cdata = NULL;
for(int i=0; i<7; i++) h.move[i] = NULL;
for(int i=0; i<MAX_EDGE; i++) h.move[i] = NULL;
h.spintable = 0;
h.alt = NULL;
h.distance = 0;
ispurehepta = purehepta;
h.c7 = newCell(7, origin);
h.c7 = newCell(S7, origin);
}
heptagon *getOrigin() { return origin; }
~hrmap_hyperbolic() {
@ -526,7 +526,7 @@ struct hrmap_quotient : hrmap {
h->fieldval = 7*i;
h->rval0 = h->rval1 = 0; h->cdata = NULL;
h->distance = 0;
h->c7 = newCell(7, h);
h->c7 = newCell(S7, h);
}
for(int j=0; j<7; j++) {
h->move[rv(j)] = allh[connections[i*7+j]/7];
@ -591,10 +591,10 @@ cell *createMov(cell *c, int d) {
int a3 = c->type/2;
int a4 = a3+1;
heptspin hs2 = hsstep(hsspin(hs, a3), a3);
heptspin hs2 = hsstep(hsspin(hs, a3), -a4);
merge(hs2.h->c7, hs2.spin, n, 2, hs2.mirrored);
heptspin hs3 = hsstep(hsspin(hs, a4), a4);
heptspin hs3 = hsstep(hsspin(hs, a4), -a3);
merge(hs3.h->c7, hs3.spin, n, 4, hs3.mirrored);
extern void verifycell(cell *c);
@ -634,12 +634,12 @@ cell *createMov(cell *c, int d) {
}
cell *createMovR(cell *c, int d) {
d %= 420; d += 420; d %= c->type;
d %= MODFIXER; d += MODFIXER; d %= c->type;
return createMov(c, d);
}
cell *getMovR(cell *c, int d) {
d %= 420; d += 420; d %= c->type;
d %= MODFIXER; d += MODFIXER; d %= c->type;
return c->mov[d];
}
@ -653,7 +653,7 @@ struct cellwalker {
};
void cwspin(cellwalker& cw, int d) {
cw.spin = (cw.spin+(MIRR(cw)?-d:d) + 420) % cw.c->type;
cw.spin = (cw.spin+(MIRR(cw)?-d:d) + MODFIXER) % cw.c->type;
}
bool cwstepcreates(cellwalker& cw) {
@ -661,11 +661,11 @@ bool cwstepcreates(cellwalker& cw) {
}
cell *cwpeek(cellwalker cw, int dir) {
return createMov(cw.c, (cw.spin+420+dir) % cw.c->type);
return createMov(cw.c, (cw.spin+MODFIXER+dir) % cw.c->type);
}
void cwmirrorat(cellwalker& cw, int d) {
cw.spin = (d+d - cw.spin + 420) % cw.c->type;
cw.spin = (d+d - cw.spin + MODFIXER) % cw.c->type;
cw.mirrored = !cw.mirrored;
}
@ -726,8 +726,8 @@ void initcells() {
else currentmap = new hrmap_hyperbolic;
allmaps.push_back(currentmap);
windmap::create();
if(!AT8) windmap::create();
// origin->emeraldval =
}
@ -806,7 +806,7 @@ void verifycells(heptagon *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->s != hsOrigin)
for(int i=0; i<S7; i++) if(at->move[i] && at->spin(i) == 0 && at->s != hsOrigin)
verifycells(at->move[i]);
verifycell(at->c7);
}
@ -831,7 +831,7 @@ bool ishept(cell *c) {
bool ishex1(cell *c) {
// EUCLIDEAN
if(euclid) return eupattern(c) == 1;
else return c->type == 7;
else return c->type != 6;
}
int emeraldval(cell *c) {
@ -875,7 +875,7 @@ int celldist(cell *c) {
return eudist(x, y);
}
if(sphere) return celldistance(c, currentmap->gamestart());
if(c->type == 7) return c->master->distance;
if(c->type != 6) return c->master->distance;
int dx[3];
for(int u=0; u<3; u++)
dx[u] = createMov(c, u+u)->master->distance;
@ -898,7 +898,7 @@ int celldistAlt(cell *c) {
return euclidAlt(x, y);
}
if(!c->master->alt) return 0;
if(c->type == 7) return c->master->alt->distance;
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)
return ALTDIST_UNKNOWN;
@ -964,7 +964,7 @@ int cdist50(cell *c) {
return "0123333332112332223322233211233333322"[eufifty(c)] - '0';
else return "012333321112322232222321123"[eufifty(c)] - '0';
}
if(c->type == 7) return cdist50(fiftyval(c));
if(c->type != 6) return cdist50(fiftyval(c));
int a0 = cdist50(createMov(c,0));
int a1 = cdist50(createMov(c,2));
int a2 = cdist50(createMov(c,4));
@ -973,7 +973,7 @@ int cdist50(cell *c) {
}
int land50(cell *c) {
if(c->type == 7) return land50(fiftyval(c));
if(c->type != 6) return land50(fiftyval(c));
else if(sphere || euclid) return 0;
else {
if(cdist50(createMov(c,0)) < 3) return land50(createMov(c,0));
@ -984,7 +984,7 @@ int land50(cell *c) {
}
int polara50(cell *c) {
if(c->type == 7) return polara50(fiftyval(c));
if(c->type != 6) return polara50(fiftyval(c));
else if(sphere || euclid) return 0;
else {
if(cdist50(createMov(c,0)) < 3) return polara50(createMov(c,0));
@ -996,7 +996,7 @@ int polara50(cell *c) {
int polarb50(cell *c) {
if(euclid) return true;
if(c->type == 7) return polarb50(fiftyval(c));
if(c->type != 6) return polarb50(fiftyval(c));
else if(sphere || euclid) return true;
else {
if(cdist50(createMov(c,0)) < 3) return polarb50(createMov(c,0));
@ -1011,7 +1011,7 @@ int elhextable[28][3] = {
};
int fiftyval049(cell *c) {
if(c->type == 7 || euclid) return fiftyval(c) / 32;
if(c->type != 6 || euclid) return fiftyval(c) / 32;
else if(sphere) return 0;
else {
int a[3], qa=0;
@ -1049,7 +1049,7 @@ int fiftyval049(cell *c) {
// zebraval
int zebra40(cell *c) {
if(c->type == 7) return (c->master->zebraval/10);
if(c->type != 6) return (c->master->zebraval/10);
else if(sphere) return 0;
else if(euclid) return eupattern(c);
else {
@ -1073,7 +1073,7 @@ int zebra40(cell *c) {
}
int zebra3(cell *c) {
if(c->type == 7) return (c->master->zebraval/10)/4;
if(c->type != 6) return (c->master->zebraval/10)/4;
else if(sphere) return 0;
else {
int ii[3];
@ -1368,7 +1368,7 @@ cdata *getEuclidCdata(heptagon *h) {
int getCdata(cell *c, int j) {
if(euclid) return getEuclidCdata(c->master)->val[j];
else if(c->type == 7) return getHeptagonCdata(c->master)->val[j]*3;
else if(c->type != 6) return getHeptagonCdata(c->master)->val[j]*3;
else {
int jj = 0;
for(int k=0; k<6; k++) if(c->mov[k] && c->mov[k]->type == 7)
@ -1379,7 +1379,7 @@ int getCdata(cell *c, int j) {
int getBits(cell *c) {
if(euclid) return getEuclidCdata(c->master)->bits;
else if(c->type == 7) return getHeptagonCdata(c->master)->bits;
else if(c->type != 6) return getHeptagonCdata(c->master)->bits;
else {
int b0 = getHeptagonCdata(createMov(c, 0)->master)->bits;
int b1 = getHeptagonCdata(createMov(c, 2)->master)->bits;
@ -1427,7 +1427,7 @@ int fieldval_uniq(cell *c) {
if(i<0) i += torusconfig::qty;
return i;
}
if(c->type == 7) return c->master->fieldval/7;
if(c->type != 6) return c->master->fieldval/7;
else {
int z = 0;
for(int u=0; u<6; u+=2)
@ -1440,7 +1440,7 @@ int fieldval_uniq_rand(cell *c, int randval) {
if(sphere || torus || euclid)
// we do not care in these cases
return fieldval_uniq(c);
if(c->type == 7) return fp43.gmul(c->master->fieldval, randval)/7;
if(c->type != 6) return fp43.gmul(c->master->fieldval, randval)/7;
else {
int z = 0;
for(int u=0; u<6; u+=2)

View File

@ -2011,3 +2011,11 @@
2019.10.25 23:17 version 10.1f
- fixed the Halloween in main menu
- fixed Zebra unlocking
2019.10.25 23:17 version 10.1g
- fixed floating-point values sometimes saving incorrectly on Windows
- fixed 's'ave the config also toggling the 's'team leaderboards
- fixed the 'wm' and 'mm' commandline options
- added the Octagonal geometry (work in progress)

View File

@ -1767,12 +1767,13 @@ struct gcell {
unsigned
pathdist : 7, // player distance wrt usual movement
cpdist : 5, mpdist : 5; // current/minimum player distance
cpdist : 8, mpdist : 8; // current/minimum player distance
unsigned mondir : 3, // monster direction, for multi-tile monsters and graphics
unsigned
mondir : 4, // monster direction, for multi-tile monsters and graphics
bardir : 4, // barrier direction
stuntime : 4, // stun time left (for Palace Guards and Skeletons)
hitpoints : 3; // hitpoints left (for Palace Guards, also reused as cpid for mirrors)
hitpoints : 4; // hitpoints left (for Palace Guards, also reused as cpid for mirrors)
unsigned landflags : 8; // extra flags for land
@ -1804,8 +1805,8 @@ struct gcell {
#define fval LHU.fi.fieldval
#define NODIR 7
#define NOBARRIERS 8
#define NODIR 8
#define NOBARRIERS 9
#define LAND_OVER 57
#define LAND_OVERX 59
@ -1865,6 +1866,16 @@ eLand land_sph[LAND_SPH] = {
laWildWest, laPalace, laBull, laPrairie, laCA
};
#define LAND_OCT 23
eLand land_oct[LAND_OCT] = {
laDesert, laIce, laCaves, laJungle, laAlchemist,
laGraveyard, laRlyeh, laHell, laCocytus, laMotion,
laDryForest, laDeadCaves, laRedRock, laMinefield, laLivefjord,
laStorms, laOvergrown, laRose, laKraken, laBurial,
laTrollheim, laBull, laHunting
};
#define LAND_HYP 51
eLand land_hyp[LAND_HYP] = {
laHell, laCocytus, laGraveyard,

View File

@ -52,7 +52,7 @@ namespace whirlwind {
qdirs = 0;
if(d == 0) return;
int qdf = 0, qdt = 0;
int cats[7];
int cats[MAX_EDGE];
for(int i=0; i<c->type; i++)
cats[i] = cat(createMov(c,i));
for(int i=0; i<c->type; i++)
@ -2599,7 +2599,7 @@ namespace kraken {
cell *c = dcal[i];
if(c->monst == moKrakenH && !c->stuntime && !isWateryOrBoat(c)) {
int qdir = 0;
cell *ctab[7];
cell *ctab[MAX_EDGE];
forCellEx(c2, c) if(isWatery(c2)) ctab[qdir++] = c2;
random_shuffle(ctab, ctab+qdir);
while(qdir--) trymove(ctab[qdir]);
@ -3529,7 +3529,7 @@ namespace dungeon {
if(c->wparam) {
/* int q = 0;
cell* downs[7];
cell* downs[MAX_EDGE];
forCellEx(c2, c) {
buildEquidistant(c2);
if(coastvalEdge(c2) > coastvalEdge(c)) downs[q++] = c2;

View File

@ -54,7 +54,7 @@ movedir vectodir(const hyperpoint& P) {
Centered = eupush(-H[0], -H[1]) * Centered;
ld binv = 99;
ld dirdist[7];
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);
}
@ -97,7 +97,7 @@ void calcMousedest() {
cellwalker bcwt = cwt;
ld dists[7];
ld dists[MAX_EDGE];
for(int i=0; i<cwt.c->type; i++)
dists[i] = intval(mouseh, tC0(shmup::ggmatrix(cwt.c->mov[i])));

View File

@ -2570,7 +2570,7 @@ void buildRosemap() {
}
int getDistLimit() { return purehepta?5:7; }
int getDistLimit() { return purehepta?(AT8?4:5):7; }
bool nogoSlow(cell *to, cell *from) {
if(cellEdgeUnstable(to) && gravityLevel(to) >= gravityLevel(from)) return true;
@ -3658,7 +3658,8 @@ template<class T>
cell *determinePush(cellwalker who, cell *c2, int subdir, T valid) {
cellwalker push = who;
cwstep(push);
cwspin(push, 3 * -subdir);
int pd = push.c->type == 8 ? 4 : 3;
cwspin(push, pd * -subdir);
cwstep(push);
if(valid(push.c)) return push.c;
if(c2->type == 7) {
@ -4438,7 +4439,7 @@ void movehex(bool mounted) {
cell *c = hexsnakes[i];
if(c->monst == moHexSnake) {
if(!goodmount(c, mounted)) continue;
int t[7];
int t[MAX_EDGE];
for(int i=0; i<c->type; i++) t[i] = i;
for(int j=1; j<c->type; j++) swap(t[j], t[hrand(j+1)]);
for(int u=0; u<c->type; u++) {
@ -4566,7 +4567,7 @@ void moveghosts() {
if(isGhostMover(c->monst) && c->cpdist >= 1) {
int mdir[7];
int mdir[MAX_EDGE];
for(int j=0; j<c->type; j++)
if(c->mov[j] && canAttack(c, c->monst, c->mov[j], c->mov[j]->monst, AF_GETPLAYER | AF_ONLY_FBUG)) {
@ -4902,7 +4903,7 @@ void movegolems(flagtype flags) {
for(int i=0; i<ittypes; i++) recorduse[i] = orbused[i];
DEBT("stayval");
int bestv = stayvalue(m, c), bq = 0, bdirs[7];
int bestv = stayvalue(m, c), bq = 0, bdirs[MAX_EDGE];
DEBT("moveval");
for(int k=0; k<c->type; k++) if(c->mov[k]) {
@ -5266,7 +5267,7 @@ void moverefresh(bool turn = true) {
c->monst = moReptile;
c->hitpoints = 3;
c->stuntime = 0;
int gooddirs[7], qdirs = 0;
int gooddirs[MAX_EDGE], qdirs = 0;
// in the peace mode, a reptile will
// prefer to walk on the ground, rather than the chasm
for(int i=0; i<c->type; i++) {
@ -5774,7 +5775,7 @@ void activateSafety(eLand l) {
restartGraph();
}
bool legalmoves[8];
bool legalmoves[MAX_EDGE+1];
bool hasSafeOrb(cell *c) {
return
@ -5801,7 +5802,7 @@ void checkmove() {
canmove = false;
items[itWarning]+=2;
if(movepcto(-1, 0, true)) canmove = legalmoves[7] = true;
if(movepcto(-1, 0, true)) canmove = legalmoves[MAX_EDGE] = true;
if(ISMOBILE || !canmove)
for(int i=0; i<cwt.c->type; i++)

View File

@ -13,12 +13,14 @@ ld tessf, crossf, hexf, hcrossf, hexhexdist;
#define ALPHA (M_PI*2/S7)
hyperpoint Crad[42];
hyperpoint Crad[6*MAX_EDGE];
transmatrix heptmove[7], hexmove[7];
transmatrix invheptmove[7], invhexmove[7];
transmatrix heptmove[MAX_EDGE], hexmove[MAX_EDGE];
transmatrix invheptmove[MAX_EDGE], invhexmove[MAX_EDGE];
transmatrix spinmatrix[84];
transmatrix spinmatrix[MAX_EDGE*12];
ld hexshift;
const transmatrix& getspinmatrix(int id) {
while(id>=S84) id -= S84;
@ -30,11 +32,15 @@ const transmatrix& getspinmatrix(int id) {
// hexf = 0.378077 hcrossf = 0.620672 tessf = 1.090550
// hexhexdist = 0.566256
ld hcrossf7 = 0.620672;
// the distance between two hexagon centers
void precalc() {
DEBB(DF_INIT, (debugfile,"precalc\n"));
hexshift = 0;
if(euclid) return;
@ -75,8 +81,13 @@ void precalc() {
Crad[i] = spin(2*M_PI*i/S42) * xpush(.4) * C0;
for(int d=0; d<S7; d++)
heptmove[d] = spin(-d * ALPHA) * xpush(tessf) * spin(M_PI);
hexshift = 0;
if(!AT8 && !purehepta)
hexshift = ALPHA/2 + ALPHA * ((S7-1)/2) + M_PI;
for(int d=0; d<S7; d++)
hexmove[d] = spin(-d * ALPHA) * xpush(-crossf)* spin(M_PI);
hexmove[d] = spin(hexshift-d * ALPHA) * xpush(-crossf)* spin(M_PI);
for(int d=0; d<S7; d++) invheptmove[d] = inverse(heptmove[d]);
for(int d=0; d<S7; d++) invhexmove[d] = inverse(hexmove[d]);

View File

@ -211,7 +211,7 @@ int displaydir(cell *c, int d) {
if(euclid)
return - d * S84 / c->type;
else
return S42 - d * S84 / c->type;
return (c->type != 6 ? -hexshift:0) + S42 - d * S84 / c->type;
}
transmatrix ddspin(cell *c, int d, int bonus) {
@ -500,7 +500,7 @@ bool drawstar(cell *c) {
bool drawItemType(eItem it, cell *c, const transmatrix& V, int icol, int ticks, bool hidden) {
char xch = iinf[it].glyph;
int ct6 = c ? c->type-6 : 1;
int ct6 = c ? c->type != 6 : 1;
hpcshape *xsh =
(it == itPirate || it == itKraken) ? &shPirateX :
(it == itBuggy || it == itBuggy2) ? &shPirateX :
@ -2296,7 +2296,7 @@ void drawMovementArrows(cell *c, transmatrix V) {
poly_outline = OUTLINE_DEFAULT;
queuepoly(fixrot * spin(-d * M_PI/4 + (sphere && vid.alpha>1?M_PI:0))/* * eupush(1,0)*/, shArrow, col);
if(c->type != 6 && (isStunnable(c->monst) || c->wall == waThumperOn)) {
if((c->type & 1) && (isStunnable(c->monst) || c->wall == waThumperOn)) {
transmatrix Centered = rgpushxto0(tC0(cwtV));
int sd = md.subdir;
if(sphere) sd = -sd;
@ -4644,7 +4644,7 @@ void drawMarkers() {
calc();
queuecircle(xmove, yb, rad, 0xFF0000FF);
queuecircle(xmove, yb, rad*SKIPFAC,
legalmoves[7] ? 0xFF0000FF : 0xFF000080
legalmoves[MAX_EDGE] ? 0xFF0000FF : 0xFF000080
);
forCellAll(c2, cwt.c) IG(c2) drawMobileArrow(c2, Gm(c2));
}

View File

@ -9,8 +9,10 @@
// automaton state
enum hstate { hsOrigin, hsA, hsB, hsError, hsA0, hsA1, hsB0, hsB1, hsC };
int fixrot(int a) { return (a+490)% S7; }
int fix42(int a) { return (a+420)% S42; }
#define MODFIXER 23520
int fixrot(int a) { return (a+MODFIXER)% S7; }
int fix42(int a) { return (a+MODFIXER)% S42; }
struct heptagon;
@ -43,7 +45,7 @@ struct heptagon {
void setspin(int d, int sp) { tsetspin(spintable, d, sp); }
// neighbors; move[0] always goes towards origin,
// and then we go clockwise
heptagon* move[7];
heptagon* move[MAX_EDGE];
// distance from the origin
short distance;
// emerald/wineyard generator
@ -88,10 +90,11 @@ hstate transition(hstate s, int dir) {
}
else {
if(s == hsOrigin) return hsA;
if(s == hsA && dir >= 3 && dir <= 4) return hsA;
if(s == hsA && dir == 5) return hsB;
if(s == hsB && dir == 4) return hsB;
if(s == hsA && dir >= 3 && dir <= S7-3) return hsA;
if(s == hsA && dir == S7-2) return hsB;
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;
}
@ -99,25 +102,38 @@ hstate transition(hstate s, int dir) {
// create h->move[d] if not created yet
heptagon *createStep(heptagon *h, int d);
/*
int indent = 0;
struct indenter {
indenter() { indent += 2; }
~indenter() { indent -= 2; }
};
template<class... T> auto iprintf(T... t) { for(int i=0; i<indent; i++) putchar(' '); return printf(t...); }
*/
// create a new heptagon
heptagon *buildHeptagon(heptagon *parent, int d, hstate s, int pard = 0) {
heptagon *h = new heptagon;
h->alt = NULL;
h->s = s;
for(int i=0; i<7; i++) h->move[i] = NULL;
for(int i=0; i<MAX_EDGE; i++) h->move[i] = NULL;
h->spintable = 0;
h->move[pard] = parent; tsetspin(h->spintable, pard, d);
parent->move[d] = h; tsetspin(parent->spintable, d, pard);
if(parent->c7) {
h->c7 = newCell(7, h);
h->emeraldval = emerald_heptagon(parent->emeraldval, d);
h->zebraval = zebra_heptagon(parent->zebraval, d);
h->fieldval = fp43.connections[fieldpattern::btspin(parent->fieldval, d)];
h->c7 = newCell(S7, h);
h->rval0 = h->rval1 = 0; h->cdata = NULL;
if(parent->s == hsOrigin)
h->fiftyval = fiftytable[0][d];
else
h->fiftyval = nextfiftyval(parent->fiftyval, parent->move[0]->fiftyval, d);
if(!AT8) {
h->emeraldval = emerald_heptagon(parent->emeraldval, d);
h->zebraval = zebra_heptagon(parent->zebraval, d);
h->fieldval = fp43.connections[fieldpattern::btspin(parent->fieldval, d)];
if(parent->s == hsOrigin)
h->fiftyval = fiftytable[0][d];
else
h->fiftyval = nextfiftyval(parent->fiftyval, parent->move[0]->fiftyval, d);
}
}
else {
h->c7 = NULL;
@ -167,19 +183,19 @@ heptagon *createStep(heptagon *h, int d) {
else if(d == 1) {
addSpin(h, d, h->move[0], h->spin(0)-1, -1);
}
else if(d == 6) {
else if(d == S7-1) {
addSpin(h, d, h->move[0], h->spin(0)+1, +1);
}
else if(d == 2) {
createStep(h->move[0], h->spin(0)-1);
addSpin(h, d, h->move[0]->modmove(h->spin(0)-1), 5 + h->move[0]->gspin(h->spin(0)-1), -1);
addSpin(h, d, h->move[0]->modmove(h->spin(0)-1), S7-2 + h->move[0]->gspin(h->spin(0)-1), -1);
}
else if(d == 5 && h->s == hsB) {
else if(d == S7-2 && h->s == hsB) {
createStep(h->move[0], h->spin(0)+1);
addSpin(h, d, h->move[0]->modmove(h->spin(0)+1), 2 + h->move[0]->gspin(h->spin(0)+1), +1);
}
else
buildHeptagon(h, d, (d == 5 || (h->s == hsB && d == 4)) ? hsB : hsA);
buildHeptagon(h, d, (d == S7-2 || (h->s == hsB && d == S7-3)) ? hsB : hsA);
return h->move[d];
}

View File

@ -1,7 +1,7 @@
// Hyperbolic Rogue
// Copyright (C) 2011-2012 Zeno Rogue, see 'hyper.cpp' for details
enum eGeometry {gNormal, gEuclid, gSphere, gElliptic, gQuotient, gQuotient2, gTorus, gGUARD};
enum eGeometry {gNormal, gEuclid, gSphere, gElliptic, gQuotient, gQuotient2, gTorus, gOctagon, gGUARD};
eGeometry geometry, targetgeometry = gEuclid;
#define euclid (geometry == gEuclid || geometry == gTorus)
#define sphere (geometry == gSphere || geometry == gElliptic)

View File

@ -1,6 +1,6 @@
#define VER "10.1f"
#define VERNUM 10106
#define VERNUM_HEX 0xA086
#define VER "10.1g"
#define VERNUM 10107
#define VERNUM_HEX 0xA087
#define GEN_M 0
#define GEN_F 1
@ -325,12 +325,15 @@ const char *musicfile = "";
const char *loadlevel = NULL;
#endif
#define S7 (sphere?5:7)
#define AT8 (geometry == gOctagon ? 1 : 0)
#define S7 (sphere?5:AT8?8:7)
#define S42 (S7*6)
#define S14 (S7*2)
#define S21 (S7*3)
#define S28 (S7*4)
#define S84 (S7*12)
#define MAX_EDGE 8
#include "util.cpp"
#include "hyperpoint.cpp"

View File

@ -1950,6 +1950,21 @@ 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);
}
void setdist(cell *c, int d, cell *from) {
if(signed(c->mpdist) <= d) return;
@ -2022,7 +2037,8 @@ void setdist(cell *c, int d, cell *from) {
exploreland[d][c->land]++;
if(d < BARLEV) for(int i=0; i<c->type; i++) {
setdist(createMov(c, i), d+(purehepta && d>=3 && d<7?2:1), c);
setdist(createMov(c, i), dnext(d), c);
if(buggyGeneration) return;
}

View File

@ -555,17 +555,17 @@ void showChangeMode() {
int eupage = 0;
int euperpage = 21;
#define LAND_SPHEUC ((targetgeometry > 1) ? LAND_SPH : LAND_EUC)
#define land_spheuc ((targetgeometry > 1) ? land_sph : land_euc)
#define LAND_SPHEUC ((targetgeometry == gOctagon) ? LAND_OCT : (targetgeometry > 1) ? LAND_SPH : LAND_EUC)
#define land_spheuc ((targetgeometry == gOctagon) ? land_oct : (targetgeometry > 1) ? land_sph : land_euc)
const char* geometrynames[gGUARD] = {
"hyperbolic", "Euclidean", "spherical", "elliptic",
"Zebra quotient", "field quotient", "torus"
"Zebra quotient", "field quotient", "torus", "octagons"
};
const char* geometrynames_short[gGUARD] = {
"hyper", "Euclid", "sphere", "elliptic",
"Zebra", "field", "torus"
"Zebra", "field", "torus", "oct"
};
void showEuclideanMenu() {

View File

@ -50,15 +50,15 @@ namespace netgen {
vec center[MAXCELLS];
double rot[MAXCELLS];
int glued[MAXCELLS];
int nei[MAXCELLS][7];
int nei[MAXCELLS][MAX_EDGE];
// auxiliary data
double raylen[MAXCELLS];
double edgist[MAXCELLS];
char patek[MAXCELLS][7];
char patek[MAXCELLS][MAX_EDGE];
// data generated by HyperRogue
hyperpoint hcenter[MAXCELLS][8];
hyperpoint hcenter[MAXCELLS][9];
// Functions handling the data.
//==============================
@ -72,7 +72,7 @@ namespace netgen {
if(mode == 1)
for(int ii=0; ii<CELLS; ii++) if(dcal[ii] == c) {
hcenter[ii][7] = V * C0;
hcenter[ii][MAX_EDGE] = V * C0;
if(c->type == 7) {
for(int i=0; i<c->type; i++) {

View File

@ -785,7 +785,7 @@ hyperpoint spfix(int rots, hyperpoint h) {
vector<array<int, 3>> symmetriesAt;
void bshape(hpcshape& sh, int p, double shzoom, int shapeid) {
void bshape(hpcshape& sh, int p, double shzoom, int shapeid, double bonus8 = 0) {
bshape(sh, p);
int whereis = 0;
while(polydata[whereis] != NEWSHAPE || polydata[whereis+1] != shapeid) whereis++;
@ -800,15 +800,20 @@ void bshape(hpcshape& sh, int p, double shzoom, int shapeid) {
double shzoomy = shzoom;
if(shzoom == WOLF) shzoomx = 1.5 * (purehepta ? crossf / hcrossf : 1), shzoomy = 1.6 * (purehepta ? crossf / hcrossf : 1);
int rots2 = rots;
if(rots == 7) rots2 = S7;
double bonus = 0;
if(rots == 7) {
rots2 = S7;
if((S7&1) == 0)
bonus = bonus8;
}
for(int r=0; r<rots2; r++) {
for(int i=0; i<qty; i++)
hpcpush(spin(2*M_PI*r/rots2) * spfix(rots, hpxy(polydata[whereis+2*i] * shzoomx, polydata[whereis+2*i+1] * shzoomy)));
hpcpush(spin(bonus+2*M_PI*r/rots2) * spfix(rots, hpxy(polydata[whereis+2*i] * shzoomx, polydata[whereis+2*i+1] * shzoomy)));
if(sym == 2)
for(int i=qty-1; i>=0; i--)
hpcpush(spin(2*M_PI*r/rots2) * spfix(rots, hpxy(polydata[whereis+2*i] * shzoomx, -polydata[whereis+2*i+1] * shzoomy)));
hpcpush(spin(bonus+2*M_PI*r/rots2) * spfix(rots, hpxy(polydata[whereis+2*i] * shzoomx, -polydata[whereis+2*i+1] * shzoomy)));
}
hpcpush(spfix(rots, hpxy(polydata[whereis] * shzoomx, polydata[whereis+1] * shzoomy)));
hpcpush(spin(bonus) * spfix(rots, hpxy(polydata[whereis] * shzoomx, polydata[whereis+1] * shzoomy)));
}
void copyshape(hpcshape& sh, hpcshape& orig, int p) {
@ -870,8 +875,8 @@ void buildpolys() {
}
// scales
scalef = purehepta ? crossf / hcrossf : 1;
double scalef2 = purehepta ? crossf / hcrossf * .88 : 1;
scalef = purehepta ? crossf / hcrossf7 : hcrossf / hcrossf7;
double scalef2 = purehepta ? crossf / hcrossf7 * .88 : hcrossf / hcrossf7;
double spzoom = sphere ? 1.4375 : 1;
@ -907,6 +912,8 @@ void buildpolys() {
for(int t=0; t<=S7; t++) hpcpush(ddi(t*12, x) * C0);
}
int td = (AT8 && purehepta) ? S42+6 : 0;
bshape(shFloor[0], PPR_FLOOR);
for(int t=0; t<=6; t++) hpcpush(ddi(S7 + t*S14, shexf*.8*spzoom) * C0);
@ -914,7 +921,7 @@ void buildpolys() {
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*12, shexf*.94) * C0);
for(int t=0; t<=S7; t++) hpcpush(ddi(t*12 + td, shexf*.94) * C0);
for(int i=0; i<3; i++) for(int j=0; j<3; j++) shadowmulmatrix[i][j] =
i==2&&j==2 ? 1:
@ -1053,7 +1060,7 @@ void buildpolys() {
}
bshape(shWall[1], PPR_WALL);
for(int t=0; t<=S7; t++) hpcpush(ddi(t*36, shexf*.94) * C0);
for(int t=0; t<=S7; t++) hpcpush(ddi(t*36+td, shexf*.94) * C0);
bshape(shCross, PPR_WALL);
for(int i=0; i<=S84; i+=S7)
@ -1280,9 +1287,9 @@ void buildpolys() {
// floors:
bshape(shStarFloor[0], PPR_FLOOR, scalef2*spzoom6, 1);
bshape(shStarFloor[1], PPR_FLOOR, scalef2*spzoomd7, 2);
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);
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);
@ -1374,7 +1381,7 @@ void buildpolys() {
bshape(shCaveFloor[1], PPR_FLOOR, scalef*spzoomd7, 53);
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);
bshape(shDesertFloor[1], PPR_FLOOR, scalef*spzoomd7, 56, 2.7);
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);

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) ? specialland : firstland;
cwt.c->land = (euclid || sphere || AT8) ? specialland : firstland;
chaosAchieved = false;