mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2024-12-24 09:00:34 +00:00
improvements to patterns; codenumbers also display directions
This commit is contained in:
parent
4fa764c175
commit
9933f373d2
4
cell.cpp
4
cell.cpp
@ -524,6 +524,9 @@ void cwrevstep(cellwalker& cw) {
|
||||
|
||||
// very similar to createMove in heptagon.cpp
|
||||
cell *createMov(cell *c, int d) {
|
||||
if(d<0 || d>= c->type) {
|
||||
printf("ERROR createmov\n");
|
||||
}
|
||||
|
||||
if(euclid && !c->mov[d]) {
|
||||
eucoord x, y;
|
||||
@ -641,6 +644,7 @@ void clearcell(cell *c) {
|
||||
DEBMEM ( printf("mov %p [%p] S%d\n", c->mov[t], c->mov[t]->mov[c->spn(t)], c->spn(t)); )
|
||||
if(c->mov[t]->mov[c->spn(t)] != NULL &&
|
||||
c->mov[t]->mov[c->spn(t)] != c) {
|
||||
printf("type = %d %d -> %d\n", c->type, t, c->spn(t));
|
||||
printf("cell error\n");
|
||||
exit(1);
|
||||
}
|
||||
|
@ -82,12 +82,9 @@ int arg::readCommon() {
|
||||
shift();
|
||||
char *c = args();
|
||||
using namespace patterns;
|
||||
sym01 = sym02 = sym03 = symRotation = false;
|
||||
subpattern_flags = 0;
|
||||
while(*c) {
|
||||
if(*c == '1') sym01 = true;
|
||||
else if(*c == '2') sym02 = true;
|
||||
else if(*c == '3') sym03 = true;
|
||||
else if(*c == '0') symRotation = true;
|
||||
if(*c >= '0' && *c <= '9') subpattern_flags ^= (*c - '0');
|
||||
else whichPattern = *c;
|
||||
c++;
|
||||
}
|
||||
|
114
graph.cpp
114
graph.cpp
@ -2187,12 +2187,9 @@ int countMinesAround(cell *c) {
|
||||
return mines;
|
||||
}
|
||||
|
||||
transmatrix applyPatterndir(cell *c, char patt = patterns::whichPattern) {
|
||||
transmatrix V = ddspin(c, patterns::patterndir(c, patt), S42);
|
||||
|
||||
if(patterns::reflectPatternAt(c, patt))
|
||||
return V * Mirror;
|
||||
|
||||
transmatrix applyPatterndir(cell *c, const patterns::patterninfo& si) {
|
||||
transmatrix V = ddspin(c, si.dir, S42);
|
||||
if(si.reflect) return V * Mirror;
|
||||
return V;
|
||||
}
|
||||
|
||||
@ -2238,42 +2235,40 @@ void drawZebraFloor(const transmatrix& V, cell *c, int col) {
|
||||
qfloor(c, V, PLAINFLOOR, col); return;
|
||||
}
|
||||
|
||||
int i = zebra40(c);
|
||||
i &= ~3;
|
||||
auto si = patterns::getpatterninfo(c, 'z', patterns::SPF_SYM0123);
|
||||
|
||||
int j;
|
||||
|
||||
if(nontruncated) j = 4;
|
||||
else if(i >=4 && i < 16) j = 2;
|
||||
else if(i >= 16 && i < 28) j = 1;
|
||||
else if(i >= 28 && i < 40) j = 3;
|
||||
else if(si.id >=4 && si.id < 16) j = 2;
|
||||
else if(si.id >= 16 && si.id < 28) j = 1;
|
||||
else if(si.id >= 28 && si.id < 40) j = 3;
|
||||
else j = 0;
|
||||
|
||||
qfloor(c, V, applyPatterndir(c, 'z'), shZebra[j], col);
|
||||
qfloor(c, V, applyPatterndir(c, si), shZebra[j], col);
|
||||
}
|
||||
|
||||
void qplainfloor(cell *c, bool warp, const transmatrix &V, int col);
|
||||
|
||||
void drawReptileFloor(const transmatrix& V, cell *c, int col, bool usefloor) {
|
||||
|
||||
int i = zebra40(c);
|
||||
i &= ~3;
|
||||
auto si = patterns::getpatterninfo(c, 'z', patterns::SPF_SYM0123);
|
||||
|
||||
int j;
|
||||
|
||||
if(!wmescher) j = 4;
|
||||
else if(nontruncated) j = 0;
|
||||
else if(i < 4) j = 0;
|
||||
else if(i >=4 && i < 16) j = 1;
|
||||
else if(i >= 16 && i < 28) j = 2;
|
||||
else if(i >= 28 && i < 40) j = 3;
|
||||
else if(si.id < 4) j = 0;
|
||||
else if(si.id >=4 && si.id < 16) j = 1;
|
||||
else if(si.id >= 16 && si.id < 28) j = 2;
|
||||
else if(si.id >= 28 && si.id < 40) j = 3;
|
||||
else j = 4;
|
||||
|
||||
transmatrix V2 = V * applyPatterndir(c, 'z');
|
||||
transmatrix D = applyPatterndir(c, si);
|
||||
transmatrix V2 = V * D;
|
||||
|
||||
if(wmescher) {
|
||||
if(usefloor)
|
||||
qfloor(c, V, applyPatterndir(c, 'z'), shReptile[j][0], darkena(col, 0, 0xFF));
|
||||
qfloor(c, V, D, shReptile[j][0], darkena(col, 0, 0xFF));
|
||||
else
|
||||
queuepoly(V2, shReptile[j][0], darkena(col, 0, 0xFF));
|
||||
}
|
||||
@ -2317,23 +2312,25 @@ void drawReptileFloor(const transmatrix& V, cell *c, int col, bool usefloor) {
|
||||
}
|
||||
|
||||
void drawEmeraldFloor(const transmatrix& V, cell *c, int col) {
|
||||
if(!euclid && !nontruncated) {
|
||||
auto si = patterns::getpatterninfo(c, 'f', patterns::SPF_SYM0123);
|
||||
|
||||
int j = -1;
|
||||
|
||||
if(!euclid && !nontruncated) {
|
||||
int i = emeraldval(c) & ~3;
|
||||
if(i == 8) j = 0;
|
||||
else if(i == 12) j = 1;
|
||||
else if(i == 16) j = 2;
|
||||
else if(i == 20) j = 3;
|
||||
else if(i == 28) j = 4;
|
||||
else if(i == 36) j = 5;
|
||||
if(si.id == 8) j = 0;
|
||||
else if(si.id == 12) j = 1;
|
||||
else if(si.id == 16) j = 2;
|
||||
else if(si.id == 20) j = 3;
|
||||
else if(si.id == 28) j = 4;
|
||||
else if(si.id == 36) j = 5;
|
||||
|
||||
if(j >= 0) {
|
||||
qfloor(c, V, applyPatterndir(c, si), shEmeraldFloor[j], col);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int ct6 = ctof(c);
|
||||
|
||||
if(j >= 0)
|
||||
qfloor(c, V, applyPatterndir(c, 'f'), shEmeraldFloor[j], col);
|
||||
else
|
||||
qfloor(c, V, CAVEFLOOR, col);
|
||||
}
|
||||
|
||||
@ -2856,8 +2853,10 @@ void floorShadow(cell *c, const transmatrix& V, int col, bool warp) {
|
||||
else
|
||||
queuepolyat(V, shTriheptaFloorShadow[ctof(c)], col, PPR_WALLSHADOW);
|
||||
}
|
||||
else
|
||||
queuepolyat(V * applyPatterndir(c), shTriheptaFloorShadow[ctof(c)], col, PPR_WALLSHADOW);
|
||||
else {
|
||||
auto si = patterns::getpatterninfo(c, 0, 0);
|
||||
queuepolyat(V * applyPatterndir(c, si), shTriheptaFloorShadow[ctof(c)], col, PPR_WALLSHADOW);
|
||||
}
|
||||
}
|
||||
else if(c->land == laDual && !nontruncated) {
|
||||
if(euclid && ishex1(c))
|
||||
@ -2873,17 +2872,15 @@ void floorShadow(cell *c, const transmatrix& V, int col, bool warp) {
|
||||
void plainfloor(cell *c, bool warp, const transmatrix &V, int col, int prio) {
|
||||
if(warp) {
|
||||
if(euclid) {
|
||||
/* if(ishex1(c))
|
||||
queuepolyat(V * pispin * applyPatterndir(c), shTriheptaFloor[0], col, prio);
|
||||
else
|
||||
queuepolyat(V * applyPatterndir(c), shTriheptaFloor[ctof(c)], col, prio); */
|
||||
if(ishex1(c))
|
||||
queuepolyat(V * pispin, shTriheptaFloor[ctof(c)], col, prio);
|
||||
else
|
||||
queuepolyat(V, shTriheptaFloor[ctof(c)], col, prio);
|
||||
}
|
||||
else
|
||||
queuepolyat(V * applyPatterndir(c), shTriheptaFloor[sphere ? ctof(c) : patterns::nopattern(c)], col, prio);
|
||||
else {
|
||||
auto si = patterns::getpatterninfo(c, 0, 0);
|
||||
queuepolyat(V * applyPatterndir(c, si), shTriheptaFloor[sphere ? ctof(c) : si.id], col, prio);
|
||||
}
|
||||
}
|
||||
else if(c->land == laDual && !nontruncated) {
|
||||
if(euclid && ishex1(c))
|
||||
@ -2900,14 +2897,8 @@ void qfloor_eswap(cell *c, const transmatrix& V, const hpcshape& sh, int col);
|
||||
|
||||
void qplainfloor(cell *c, bool warp, const transmatrix &V, int col) {
|
||||
if(warp) {
|
||||
if(euclid) {
|
||||
if(ishex1(c))
|
||||
qfloor(c, V, applyPatterndir(c) * pispin, shTriheptaFloor[0], col);
|
||||
else
|
||||
qfloor(c, V, applyPatterndir(c), shTriheptaFloor[ctof(c)], col);
|
||||
}
|
||||
else
|
||||
qfloor(c, V, applyPatterndir(c), shTriheptaFloor[sphere ? ctof(c) : patterns::nopattern(c)], col);
|
||||
auto si = patterns::getpatterninfo(c, 0, 0);
|
||||
qfloor(c, V, applyPatterndir(c, si), shTriheptaFloor[si.id], col);
|
||||
}
|
||||
else if(c->land == laDual && !nontruncated)
|
||||
qfloor_eswap(c, V, shBigTriangle, col);
|
||||
@ -3503,7 +3494,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
|
||||
// floor
|
||||
|
||||
#if CAP_EDIT
|
||||
transmatrix Vpdir = V * applyPatterndir(c);
|
||||
auto si = patterns::getpatterninfo0(c);
|
||||
#endif
|
||||
|
||||
bool eoh = euclid || nontruncated;
|
||||
@ -3518,7 +3509,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
|
||||
}
|
||||
|
||||
#if CAP_EDIT
|
||||
if(mapeditor::drawUserShape(Vpdir, mapeditor::cellShapeGroup(), patterns::realpattern(c),
|
||||
if(mapeditor::drawUserShape(V * applyPatterndir(c, si), mapeditor::cellShapeGroup(), si.id,
|
||||
darkena(fcol, fd, (cmode & sm::DRAW) ? 0xC0 : 0xFF), c));
|
||||
|
||||
else if(patterns::whichShape == '7') {
|
||||
@ -3675,10 +3666,9 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
|
||||
}
|
||||
|
||||
else if(isWarped(c) && !nontruncated && !shmup::on) {
|
||||
int np = patterns::nopattern(c);
|
||||
if(c->landparam == 1337) np = 0; // for the achievement screenshot
|
||||
if(np < 13)
|
||||
qfloor(c, Vf, applyPatterndir(c), shTriheptaFloor[np], darkena(fcol, fd, 0xFF));
|
||||
auto si = patterns::getpatterninfo(c, 0, 0);
|
||||
if(si.id < 13)
|
||||
qfloor(c, Vf, applyPatterndir(c, si), shTriheptaFloor[si.id], darkena(fcol, fd, 0xFF));
|
||||
else
|
||||
qfloor(c, Vf, shFloor[ctof(c)], darkena(fcol, fd, 0xFF));
|
||||
}
|
||||
@ -3905,14 +3895,14 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
|
||||
|
||||
if(patterns::displaycodes) {
|
||||
|
||||
int labeli = patterns::displaycodes == 1 ? patterns::realpattern(c) : patterns::subpattern(c);
|
||||
int pf = patterns::displaycodes == 2 ? patterns::subpattern_flags : 0;
|
||||
|
||||
string label = its(labeli);
|
||||
auto si = patterns::getpatterninfo(c, patterns::whichPattern, pf);
|
||||
|
||||
queuepoly(V * applyPatterndir(c,si), shAsymmetric, darkena(0x000000, 0, 0xC0));
|
||||
|
||||
string label = its(si.id);
|
||||
queuestr(V, .5, label, 0xFF000000 + forecolor);
|
||||
|
||||
/* transmatrix V2 = V * applyPatterndir(c);
|
||||
qfloor(c, V2, shNecro, 0x80808080);
|
||||
qfloor(c, V2, shStatue, 0x80808080); */
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -4582,7 +4572,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
|
||||
#if CAP_EDIT
|
||||
if((cmode & sm::MAP) && lmouseover && darken == 0 &&
|
||||
!mouseout() &&
|
||||
(patterns::whichPattern ? patterns::subpattern(c) == patterns::subpattern(lmouseover) : c == lmouseover)) {
|
||||
(patterns::whichPattern ? patterns::getpatterninfo0(c).id == patterns::getpatterninfo0(lmouseover).id : c == lmouseover)) {
|
||||
queuecircle(V, .78, 0x00FFFFFF);
|
||||
}
|
||||
|
||||
|
45
hyper.h
45
hyper.h
@ -654,17 +654,46 @@ extern struct SDL_Surface *s;
|
||||
|
||||
namespace patterns {
|
||||
extern char whichShape;
|
||||
|
||||
extern char whichPattern;
|
||||
extern bool symRotation, sym01, sym02, sym03;
|
||||
|
||||
static const char PAT_WARP = 0;
|
||||
static const char PAT_ZEBRA = 'z';
|
||||
static const char PAT_EMERALD = 'f';
|
||||
static const char PAT_PALACE = 'p';
|
||||
static const char PAT_FIELD = 'F';
|
||||
static const char PAT_DOWN = 'H';
|
||||
static const char PAT_COLORING = 'C';
|
||||
static const char PAT_SIBLING = 'S';
|
||||
|
||||
extern int subpattern_flags;
|
||||
|
||||
static const int SPF_ROT = 1;
|
||||
static const int SPF_SYM01 = 2;
|
||||
static const int SPF_SYM02 = 4;
|
||||
static const int SPF_SYM03 = 8;
|
||||
static const int SPF_CHANGEROT = 16;
|
||||
static const int SPF_TWOCOL = 32;
|
||||
|
||||
static const int SPF_SYM0123 = 14;
|
||||
|
||||
extern char whichCanvas;
|
||||
|
||||
extern int displaycodes;
|
||||
|
||||
int generateCanvas(cell *c);
|
||||
int realpattern(cell *c, char w = whichPattern);
|
||||
int patterndir(cell *c, char w = whichPattern);
|
||||
bool reflectPatternAt(cell *c, char p = whichPattern);
|
||||
int subpattern(cell *c, char w = whichPattern);
|
||||
|
||||
struct patterninfo {
|
||||
int id;
|
||||
int dir;
|
||||
bool reflect;
|
||||
};
|
||||
|
||||
patterninfo getpatterninfo(cell *c, char pat, int sub);
|
||||
|
||||
patterninfo getpatterninfo0(cell *c) {
|
||||
return getpatterninfo(c, whichPattern, subpattern_flags);
|
||||
}
|
||||
}
|
||||
|
||||
namespace mapeditor {
|
||||
@ -1598,8 +1627,8 @@ void pushThumper(cell *th, cell *cto);
|
||||
template<class T> T pick(T x, T y) { return hrand(2) ? x : y; }
|
||||
template<class T> T pick(T x, T y, T z) { switch(hrand(3)) { case 0: return x; case 1: return y; case 2: return z; } return x; }
|
||||
template<class T> T pick(T x, T y, T z, T v) { switch(hrand(4)) { case 0: return x; case 1: return y; case 2: return z; case 3: return v; } return x; }
|
||||
template<class T, class... U> bool among(T x, T y) { return x == y; }
|
||||
template<class T, class... U> bool among(T x, T y, U... u) { return x==y || among(x,u...); }
|
||||
template<class T, class V, class... U> bool among(T x, V y) { return x == y; }
|
||||
template<class T, class V, class... U> bool among(T x, V y, U... u) { return x==y || among(x,u...); }
|
||||
|
||||
eLand getNewSealand(eLand old);
|
||||
bool createOnSea(eLand old);
|
||||
@ -2335,3 +2364,5 @@ void queueline(const hyperpoint& H1, const hyperpoint& H2, int col, int prf = 0,
|
||||
hyperpoint ddi0(ld dir, ld dist);
|
||||
extern ld tessf, crossf, hexf, hcrossf, hexhexdist, hexvdist, hepvdist, rhexf;
|
||||
unsigned char& part(int& col, int i);
|
||||
|
||||
transmatrix applyPatterndir(cell *c, const patterns::patterninfo& si);
|
||||
|
1
init.cpp
1
init.cpp
@ -356,6 +356,7 @@ void addMessage(string s, char spamtype = 0);
|
||||
#define a45 (S3 == 4 && S7 == 5)
|
||||
#define a46 (S3 == 4 && S7 == 6)
|
||||
#define a47 (S3 == 4 && S7 == 7)
|
||||
#define a457 (S3 == 4 && S7 != 6)
|
||||
#define a467 (S3 == 4 && S7 >= 6)
|
||||
#define a38 (S7 == 8)
|
||||
#define sphere4 (sphere && S7 == 4)
|
||||
|
@ -28,8 +28,8 @@ namespace mapeditor {
|
||||
|
||||
void applyModelcell(cell *c) {
|
||||
if(patterns::whichPattern == 'H') return;
|
||||
int i = patterns::realpattern(c);
|
||||
cell *c2 = modelcell[i];
|
||||
auto si = patterns::getpatterninfo0(c);
|
||||
cell *c2 = modelcell[si.id];
|
||||
if(c2) {
|
||||
c->wall = c2->wall;
|
||||
c->land = c2->land;
|
||||
@ -40,8 +40,11 @@ namespace mapeditor {
|
||||
c->mondir = c2->mondir;
|
||||
c->stuntime = c2->stuntime;
|
||||
c->hitpoints = c2->hitpoints;
|
||||
if(c2->mondir != NODIR)
|
||||
c->mondir = (c2->mondir - patterns::patterndir(c2) + patterns::patterndir(c) + MODFIXER) % c->type;
|
||||
if(c2->mondir != NODIR) {
|
||||
auto si2 = patterns::getpatterninfo0(c2);
|
||||
c->mondir = (c2->mondir - si2.dir + si.dir + MODFIXER) % c->type;
|
||||
// todo reflect
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -238,7 +241,7 @@ namespace mapstream {
|
||||
c->hitpoints = loadChar();
|
||||
|
||||
if(patterns::whichPattern)
|
||||
mapeditor::modelcell[patterns::realpattern(c)] = c;
|
||||
mapeditor::modelcell[patterns::getpatterninfo0(c).id] = c;
|
||||
}
|
||||
|
||||
int32_t whereami = loadInt();
|
||||
@ -498,13 +501,15 @@ namespace mapeditor {
|
||||
if(drawcell == cwt.c) return vid.cs.charid;
|
||||
if(drawcell->monst) return drawcell->monst;
|
||||
if(drawcell->item) return drawcell->item;
|
||||
return patterns::subpattern(drawcell);
|
||||
return patterns::getpatterninfo0(drawcell).id;
|
||||
}
|
||||
|
||||
bool editingShape(int group, int id) {
|
||||
if(group != mapeditor::drawcellShapeGroup()) return false;
|
||||
if(group < 3) return id == drawcellShapeID();
|
||||
return patterns::subpattern(id, patterns::whichPattern) == patterns::subpattern(drawcell);
|
||||
// todo fix this
|
||||
return id == drawcellShapeID();
|
||||
// return patterns::getpatterninfo0(id).id == patterns::getpatterninfo0(drawcell).id;
|
||||
}
|
||||
|
||||
void editCell(const pair<cellwalker, cellwalker>& where) {
|
||||
@ -649,15 +654,16 @@ namespace mapeditor {
|
||||
c3->aitmp = sval, v.push_back(c3);
|
||||
}
|
||||
|
||||
auto si = patterns::getpatterninfo0(where.c);
|
||||
int cdir = where.spin;
|
||||
if(cdir >= 0)
|
||||
cdir = cdir - patterns::patterndir(where.c);
|
||||
int sp = patterns::subpattern(where.c);
|
||||
if(cdir >= 0) cdir = cdir - si.dir;
|
||||
|
||||
for(cell* c2: v)
|
||||
if(patterns::subpattern(c2) == sp) {
|
||||
editAt(cellwalker(c2, cdir>=0 ? fixdir(cdir + patterns::patterndir(c2), c2) : -1));
|
||||
modelcell[patterns::realpattern(c2)] = c2;
|
||||
for(cell* c2: v) {
|
||||
auto si2 = patterns::getpatterninfo0(c2);
|
||||
if(si2.id == si.id) {
|
||||
editAt(cellwalker(c2, cdir>=0 ? fixdir(cdir + si2.dir, c2) : -1));
|
||||
modelcell[si2.id] = c2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -903,7 +909,7 @@ namespace mapeditor {
|
||||
|
||||
default:
|
||||
line1 = XLAT("floor/pattern");
|
||||
line2 = "#" + its(patterns::subpattern(drawcell));
|
||||
line2 = "#" + its(patterns::getpatterninfo0(drawcell).id);
|
||||
break;
|
||||
}
|
||||
|
||||
|
591
pattern2.cpp
591
pattern2.cpp
@ -24,14 +24,8 @@ bool ishex1(cell *c) {
|
||||
else return c->type != S6;
|
||||
}
|
||||
|
||||
int val46(cell *c) {
|
||||
return ctof(c) ? c->master->emeraldval :
|
||||
((c->master->emeraldval & 1) ^ ((c->master->emeraldval & 2)>>1) ^ (c->spin(0)&1)) ? 8 : 4;
|
||||
}
|
||||
|
||||
int emeraldval(cell *c) {
|
||||
if(euclid) return eupattern(c);
|
||||
if(a46) return val46(c);
|
||||
if(sphere) return 0;
|
||||
if(ctof(c))
|
||||
return c->master->emeraldval >> 3;
|
||||
@ -68,13 +62,7 @@ int eufifty(cell *c) {
|
||||
}
|
||||
}
|
||||
|
||||
int val38(cell *c) {
|
||||
if(ctof(c)) return (c->master->fiftyval >> 1) & 3;
|
||||
else return 4 ^ (c->master->fiftyval & 1) ^ (c->spin(0) & 1);
|
||||
}
|
||||
|
||||
int fiftyval(cell *c) {
|
||||
if(a38) return val38(c);
|
||||
if(euclid) return eufifty(c) * 32;
|
||||
if(sphere || S7>7 || S6>6) return 0;
|
||||
if(ctof(c))
|
||||
@ -180,10 +168,14 @@ int fiftyval049(cell *c) {
|
||||
|
||||
int dir_truncated457(cell *c) {
|
||||
int wset = 0;
|
||||
for(int i=0; i<4; i++)
|
||||
if(zebra40(createMov(c, i*2))&2) wset |= (1<<i);
|
||||
if(wset == 0) return -8;
|
||||
if(wset == 15) return -10;
|
||||
int has1 = 0;
|
||||
for(int i=0; i<4; i++) {
|
||||
int z = zebra40(createMov(c, i*2));
|
||||
if(z&1) has1 = 1;
|
||||
if(z&2) wset |= (1<<i);
|
||||
}
|
||||
if(wset == 0) return -8-has1;
|
||||
if(wset == 15) return -10-has1;
|
||||
if(wset == 3) return 1;
|
||||
if(wset == 6) return 3;
|
||||
if(wset == 12) return 5;
|
||||
@ -191,14 +183,37 @@ int dir_truncated457(cell *c) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int val46(cell *c);
|
||||
|
||||
int zebra40(cell *c) {
|
||||
if(euclid) return eupattern(c);
|
||||
else if(a46) return val46(c);
|
||||
else if(a46) {
|
||||
int v = val46(c);
|
||||
if(v<4) return v;
|
||||
else return 4+(v-4)/2;
|
||||
}
|
||||
else if(ctof(c)) return (c->master->zebraval/10);
|
||||
else if(a4) {
|
||||
int ws = dir_truncated457(c);
|
||||
if(ws < 0) return -ws;
|
||||
return 16 + (ws/2);
|
||||
int tot = 0;
|
||||
array<int, 4> zebras;
|
||||
for(int i=0; i<4; i++) {
|
||||
zebras[i] = zebra40(createMov(c, i*2));
|
||||
tot += zebras[i];
|
||||
}
|
||||
|
||||
// break cycles
|
||||
int cod = 0;
|
||||
int mo = 0; for(int i=0; i<4; i++) if(zebras[i] < zebras[mo]) mo = i;
|
||||
for(int i=0; i<4; i++) for(int j=1; j<i; j++)
|
||||
if(zebras[(mo+i)&3] < zebras[(mo+j)&3]) cod ^= 4;
|
||||
|
||||
if(tot == 0+2+4+6) return 16+cod;
|
||||
if(tot == 1+3+5+7) return 19+cod;
|
||||
if(tot == 0+1+2+3) return 18+cod;
|
||||
if(tot == 4+5+6+7) return 17+cod;
|
||||
return 24;
|
||||
}
|
||||
else if(sphere) return 0;
|
||||
else if(euclid) return eupattern(c);
|
||||
@ -349,17 +364,13 @@ int getHemisphere(cell *c, int which) {
|
||||
}
|
||||
}
|
||||
|
||||
struct sphereinfo {
|
||||
int id;
|
||||
int dir;
|
||||
bool reflect;
|
||||
};
|
||||
namespace patterns {
|
||||
|
||||
sphereinfo valsphere(cell *c) {
|
||||
sphereinfo si;
|
||||
void valSibling(cell *c, patterninfo& si, int sub) {
|
||||
if(ctof(c)) {
|
||||
int d = c->master->fieldval;
|
||||
si.id = (d < siblings[d]) ? 0 : 1;
|
||||
if(sub & SPF_ROT) si.id = 0;
|
||||
for(int i=0; i<S7; i++) {
|
||||
int di = c->master->move[i]->fieldval;
|
||||
if(di == siblings[d]) si.dir = i;
|
||||
@ -387,32 +398,14 @@ sphereinfo valsphere(cell *c) {
|
||||
else {
|
||||
si.id = 8;
|
||||
si.dir = 0; // whatever
|
||||
sphereinfo si2 = valsphere(c->mov[0]);
|
||||
patterninfo si2;
|
||||
valSibling(c->mov[0], si2, sub);
|
||||
int di = si2.dir - c->spin(0);
|
||||
di %= S7;
|
||||
if(di<0) di += S7;
|
||||
si.reflect = di > S7/2;
|
||||
}
|
||||
}
|
||||
return si;
|
||||
}
|
||||
|
||||
namespace patterns {
|
||||
|
||||
int nopattern(cell *c) {
|
||||
if(isWarped(c) && !euclid) {
|
||||
int u = ishept(c)?1:0;
|
||||
int qhex = 0;
|
||||
for(int v=0; v<c->type; v++) if(c->mov[v] && !isWarped(c->mov[v])) {
|
||||
u += 2;
|
||||
if(!ishept(c->mov[v])) qhex++;
|
||||
}
|
||||
if(u == 8 && qhex == 2) return 12;
|
||||
if(u == 2 && qhex == 1) return 8;
|
||||
if(u == 6 && qhex == 2) return 10;
|
||||
return u;
|
||||
}
|
||||
return ishept(c) ? 1 : ishex1(c) ? 2 : 0; // 0 to 1
|
||||
}
|
||||
|
||||
int downdir(cell *c, cellfunction *cf = coastvalEdge) {
|
||||
@ -421,131 +414,226 @@ namespace patterns {
|
||||
return neighborId(c, c2);
|
||||
}
|
||||
|
||||
int realpattern(cell *c, char code) {
|
||||
switch(code) {
|
||||
case 'z':
|
||||
return zebra40(c); // 4 to 43
|
||||
case 'f':
|
||||
return emeraldval(c); // 44 to 99
|
||||
case 'p': {
|
||||
if(a46) return val46(c);
|
||||
if(a38) return val38(c);
|
||||
if(sphere) return valsphere(c).id;
|
||||
int i = fiftyval049(c);
|
||||
i *= 4;
|
||||
if(polara50(c)) i|=1;
|
||||
if(polarb50(c)) i|=2;
|
||||
return i;
|
||||
}
|
||||
case 'H':
|
||||
return towerval(c);
|
||||
case 'F': {
|
||||
if(euclid)
|
||||
// use the torus ID
|
||||
return fieldpattern::fieldval_uniq(c);
|
||||
else if(nontruncated)
|
||||
// use the actual field codes
|
||||
return fieldpattern::fieldval(c).first;
|
||||
else
|
||||
// use the small numbers from windmap
|
||||
return windmap::getId(c);
|
||||
}
|
||||
}
|
||||
return nopattern(c);
|
||||
void applySym0123(int& i, int sub) {
|
||||
bool sym01 = sub & SPF_SYM01;
|
||||
bool sym02 = sub & SPF_SYM02;
|
||||
bool sym03 = sub & SPF_SYM03;
|
||||
if((sym01?1:0)+(sym02?1:0)+(sym03?1:0) >= 2) i &= ~3;
|
||||
if(sym01 && (i&1)) i ^= 1;
|
||||
if(sym02 && (i&2)) i ^= 2;
|
||||
if(sym03 && (i&2)) i ^= 3;
|
||||
}
|
||||
|
||||
int patterndir46(cell *c, int bits) {
|
||||
void val46(cell *c, patterninfo &si, int sub) {
|
||||
int bits = (sub & SPF_CHANGEROT) ? 1 : 2;
|
||||
if(ctof(c)) {
|
||||
si.id = c->master->emeraldval >> 1;
|
||||
applySym0123(si.id, sub);
|
||||
int b = c->master->emeraldval & bits;
|
||||
return (b&1) ^ (b & 2 ? 1 : 0);
|
||||
si.dir = (b&1) ^ (b & 2 ? 1 : 0);
|
||||
}
|
||||
else {
|
||||
if(sub & SPF_TWOCOL) si.id = 4;
|
||||
else
|
||||
return ((c->mov[0]->master->emeraldval + c->spin(0)) & 1) ? 2 : 0;
|
||||
si.id = ((c->master->emeraldval & 1) ^ ((c->master->emeraldval & 2)>>1) ^ (c->spin(0)&1)) ? 8 : 4;
|
||||
si.dir = ((c->mov[0]->master->emeraldval + c->spin(0)) & 1) ? 2 : 0;
|
||||
if(createMov(c, si.dir)->master->emeraldval & 4)
|
||||
si.dir += 4;
|
||||
}
|
||||
}
|
||||
|
||||
int patterndir38(cell *c) {
|
||||
if(ctof(c)) return c->master->fiftyval | (c->master->fiftyval & 8 ? 0 : 2);
|
||||
return 0;
|
||||
}
|
||||
// if(a46) return patterndir46(c, w == PAT_ZEBRA ? 3 : w == PAT_PALACE ? 2 : 1);
|
||||
|
||||
int patterndir457(cell *c) {
|
||||
if(!ctof(c)) {
|
||||
int d = dir_truncated457(c);
|
||||
if(d >= 0) return d;
|
||||
return 0;
|
||||
void val457(cell *c, patterninfo &si, int sub) {
|
||||
si.id = zebra40(c);
|
||||
applySym0123(si.id, sub);
|
||||
if(sub & SPF_ROT) {
|
||||
if(si.id >= 4 && si.id < 7) si.id -= 4;
|
||||
if(si.id >= 20 && si.id < 23) si.id -= 4;
|
||||
}
|
||||
if(ctof(c)) {
|
||||
for(int i=0; i<c->type; i++)
|
||||
if((zebra40(createStep(c->master, i + S7/2)->c7)&2) == (zebra40(createStep(c->master, i + 1 + S7/2)->c7)&2))
|
||||
return i;
|
||||
return 0;
|
||||
si.dir = i;
|
||||
}
|
||||
|
||||
bool reflectPatternAt(cell *c, char p) {
|
||||
if(p == 'p' && sphere) return valsphere(c).reflect;
|
||||
if(p == 'p' && polarb50(c)) return true;
|
||||
if(p == 0) {
|
||||
int np = nopattern(c);
|
||||
if(np == 4) {
|
||||
int d = patterndir(c);
|
||||
return !isWarped(createMov(c, (d+1)%6));
|
||||
}
|
||||
if(np == 12) {
|
||||
int d = patterndir(c);
|
||||
return !isWarped(createMov(c, (d+1)%6));
|
||||
else {
|
||||
int d = dir_truncated457(c);
|
||||
if(d >= 0) si.dir = d;
|
||||
else si.dir = (zebra40(createMov(c, 0)) & 4) ? 2 : 0;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
void val38(cell *c, patterninfo &si, int sub) {
|
||||
bool symRotation = sub & SPF_ROT;
|
||||
bool sym01 = sub & SPF_TWOCOL;
|
||||
|
||||
if(ctof(c)) {
|
||||
if(!symRotation)
|
||||
si.id = (c->master->fiftyval >> 1) & 3;
|
||||
si.dir = c->master->fiftyval | (c->master->fiftyval & 8 ? 0 : 2);
|
||||
}
|
||||
else {
|
||||
if(sym01)
|
||||
si.id = 4;
|
||||
else
|
||||
si.id = 4 ^ (c->master->fiftyval & 1) ^ (c->spin(0) & 1);
|
||||
}
|
||||
}
|
||||
|
||||
int patterndir(cell *c, char w) {
|
||||
if(w != 'H') {
|
||||
if(a46) return patterndir46(c, w == 'z' ? 3 : w == 'p' ? 2 : 1);
|
||||
if(a4) return patterndir457(c);
|
||||
if(a38) return patterndir38(c);
|
||||
if(sphere) return valsphere(c).dir;
|
||||
void valEuclid(cell *c, patterninfo &si, int sub) {
|
||||
bool symRotation = sub & SPF_ROT;
|
||||
si.id = ishept(c) ? 1 : ishex1(c) ? 2 : 0;
|
||||
if(sub & SPF_CHANGEROT)
|
||||
si.dir = (zebra40(c)*4) % 6;
|
||||
if(symRotation) si.id = 0;
|
||||
}
|
||||
switch(w) {
|
||||
case 'z': {
|
||||
int t = zebra40(c);
|
||||
|
||||
if(euclid) return (t*4) % 6;
|
||||
void val_all(cell *c, patterninfo &si, int sub) {
|
||||
if(a46) val46(c, si, sub);
|
||||
else if(a38) val38(c, si, sub);
|
||||
else if(sphere) valSibling(c, si, sub);
|
||||
else if(euclid) valEuclid(c, si, sub);
|
||||
else if(a4) val457(c, si, sub);
|
||||
}
|
||||
|
||||
int t4 = t>>2, tcdir = 0;
|
||||
void val_warped(cell *c, patterninfo& si) {
|
||||
// use val_all for nicer rotation
|
||||
val_all(c, si, 0);
|
||||
|
||||
if(nontruncated) tcdir = t^1;
|
||||
// get id:
|
||||
if(stdhyperbolic && isWarped(c)) {
|
||||
int u = ishept(c)?1:0;
|
||||
int qhex = 0;
|
||||
for(int v=0; v<c->type; v++) if(c->mov[v] && !isWarped(c->mov[v])) {
|
||||
u += 2;
|
||||
if(!ishept(c->mov[v])) qhex++;
|
||||
}
|
||||
if(u == 8 && qhex == 2) si.id = 12;
|
||||
else if(u == 2 && qhex == 1) si.id = 8;
|
||||
else if(u == 6 && qhex == 2) si.id = 10;
|
||||
si.id = u;
|
||||
|
||||
else if(t4 == 10) tcdir = t-20;
|
||||
else if(t4 >= 4 && t4 < 7) tcdir = 40 + (t&3);
|
||||
else if(t4 >= 1 && t4 < 4) tcdir = t+12;
|
||||
else if(t4 >= 7 && t4 < 10) tcdir = t-24;
|
||||
if(u == 6) {
|
||||
for(int i=1; i<c->type; i+=2) if(!isWarped(createMov(c,i)))
|
||||
si.dir = i;
|
||||
}
|
||||
|
||||
else if(u == 2 || u == 3 || u == 8) {
|
||||
for(int i=0; i<c->type; i++) if(!isWarped(createMov(c,i)))
|
||||
si.dir = i;
|
||||
}
|
||||
|
||||
else if(u == 4 || u == 10) {
|
||||
for(int i=0; i<c->type; i+=2) if(!isWarped(createMov(c,i)))
|
||||
si.dir = i;
|
||||
if(u == 4)
|
||||
si.reflect = !isWarped(createMov(c, (si.dir+1)%6));
|
||||
}
|
||||
|
||||
else if(u == 6) {
|
||||
for(int i=1; i<c->type; i+=2) if(!isWarped(createMov(c,i)))
|
||||
si.dir = i;
|
||||
}
|
||||
|
||||
else if(u == 5) {
|
||||
for(int i=0; i<c->type; i++) if(!isWarped(createMov(c,(i+3)%7)) && !isWarped(createMov(c,(i+4)%7)))
|
||||
si.dir = i;
|
||||
}
|
||||
|
||||
else if(u == 9) {
|
||||
for(int i=0; i<c->type; i++) if(!isWarped(createMov(c,(i+2)%7)) && !isWarped(createMov(c,(i+5)%7)))
|
||||
si.dir = i;
|
||||
}
|
||||
|
||||
else if(u == 11) {
|
||||
for(int i=0; i<c->type; i++) if(isWarped(createMov(c,(i)%7)) && isWarped(createMov(c,(i+1)%7)))
|
||||
si.dir = i;
|
||||
}
|
||||
|
||||
else if(u == 12) {
|
||||
for(int i=0; i<c->type; i+=2) if(isWarped(createMov(c,i))) {
|
||||
si.dir = i;
|
||||
si.reflect = !isWarped(createMov(c, (i+1)%6));
|
||||
}
|
||||
}
|
||||
|
||||
else if(u == 7) {
|
||||
for(int i=0; i<c->type; i++) if(!isWarped(createMov(c,(i+1)%7)) && !isWarped(createMov(c,(i+6)%7)))
|
||||
si.dir = i;
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
si.id = ishept(c) ? 1 : 0;
|
||||
if(euclid) si.dir = ishex1(c) ? 3 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
char whichPattern = 0;
|
||||
|
||||
int subpattern_flags;
|
||||
|
||||
patterninfo getpatterninfo(cell *c, char pat, int sub) {
|
||||
bool symRotation = sub & SPF_ROT;
|
||||
|
||||
patterninfo si;
|
||||
si.dir = 0; si.reflect = false; si.id = ctof(c);
|
||||
|
||||
if(pat == PAT_ZEBRA && stdhyperbolic) {
|
||||
|
||||
si.id = zebra40(c); // 4 to 43
|
||||
int t4 = si.id>>2, tcdir = 0;
|
||||
|
||||
if(nontruncated) tcdir = si.id^1;
|
||||
|
||||
else if(t4 == 10) tcdir = si.id-20;
|
||||
else if(t4 >= 4 && t4 < 7) tcdir = 40 + (si.id&3);
|
||||
else if(t4 >= 1 && t4 < 4) tcdir = si.id+12;
|
||||
else if(t4 >= 7 && t4 < 10) tcdir = si.id-24;
|
||||
|
||||
for(int i=0; i<c->type; i++) if(c->mov[i] && zebra40(c->mov[i]) == tcdir)
|
||||
return i;
|
||||
si.dir = i;
|
||||
|
||||
// printf("fail to fintd %d -> %d\n", t, tcdir);
|
||||
applySym0123(si.id, sub);
|
||||
|
||||
return 0;
|
||||
if(symRotation) {
|
||||
if(si.id >= 8 && si.id < 12) si.id -= 4;
|
||||
if(si.id >= 12 && si.id < 16) si.id -= 8;
|
||||
if(si.id >= 20 && si.id < 24) si.id -= 4;
|
||||
if(si.id >= 24 && si.id < 28) si.id -= 8;
|
||||
if(si.id >= 32 && si.id < 36) si.id -= 4;
|
||||
if(si.id >= 36 && si.id < 40) si.id -= 8;
|
||||
}
|
||||
}
|
||||
|
||||
case 'f': {
|
||||
int t = emeraldval(c);
|
||||
if(euclid) return 0;
|
||||
int tcdir = 0, tbest = (t&3);
|
||||
else if(pat == PAT_EMERALD && (stdhyperbolic || a38)) {
|
||||
si.id = emeraldval(c); // 44 to 99
|
||||
if(!euclid) {
|
||||
int tcdir = 0, tbest = (si.id&3);
|
||||
for(int i=0; i<c->type; i++) {
|
||||
cell *c2 = c->mov[i];
|
||||
if(c2) {
|
||||
int t2 = emeraldval(c2);
|
||||
if((t&3) == (t2&3) && t2 > tbest)
|
||||
if((si.id&3) == (t2&3) && t2 > tbest)
|
||||
tbest = t2, tcdir = i;
|
||||
}
|
||||
}
|
||||
return tcdir;
|
||||
si.dir = tcdir;
|
||||
}
|
||||
applySym0123(si.id, sub);
|
||||
}
|
||||
|
||||
case 'p': {
|
||||
else if(pat == PAT_PALACE && stdhyperbolic) {
|
||||
int i = fiftyval049(c);
|
||||
i *= 4;
|
||||
if(polara50(c)) i|=1;
|
||||
if(polarb50(c)) i|=2;
|
||||
si.id = i;
|
||||
|
||||
int tcdir = -1, tbest = -1;
|
||||
int pa = polara50(c);
|
||||
int pb = polarb50(c);
|
||||
si.reflect = pb;
|
||||
for(int i=0; i<c->type; i++) {
|
||||
cell *c2 = c->mov[i];
|
||||
if(c2 && polara50(c2) == pa && polarb50(c2) == pb) {
|
||||
@ -553,118 +641,51 @@ namespace patterns {
|
||||
if(t2 > tbest) tbest = t2, tcdir = i;
|
||||
}
|
||||
}
|
||||
return tcdir;
|
||||
si.dir = tcdir;
|
||||
applySym0123(si.id, sub);
|
||||
|
||||
if(symRotation && si.id >= 3)
|
||||
si.id -= ((si.id/4-1) % 7) * 4;
|
||||
}
|
||||
|
||||
case 'H':
|
||||
return downdir(c);
|
||||
|
||||
case 0: {
|
||||
if(euclid) return 0;
|
||||
int u = nopattern(c);
|
||||
|
||||
if(u == 6) {
|
||||
for(int i=1; i<c->type; i+=2) if(!isWarped(createMov(c,i)))
|
||||
return i;
|
||||
else if(pat == PAT_PALACE && euclid) {
|
||||
si.id = fiftyval049(c);
|
||||
}
|
||||
|
||||
else if(u == 2 || u == 3 || u == 8) {
|
||||
for(int i=0; i<c->type; i++) if(!isWarped(createMov(c,i)))
|
||||
return i;
|
||||
else if(pat == PAT_DOWN) {
|
||||
si.id = towerval(c);
|
||||
si.dir = downdir(c);
|
||||
}
|
||||
|
||||
else if(u == 4 || u == 10) {
|
||||
for(int i=0; i<c->type; i+=2) if(!isWarped(createMov(c,i)))
|
||||
return i;
|
||||
else if(pat == PAT_FIELD) {
|
||||
if(euclid)
|
||||
// use the torus ID
|
||||
si.id = fieldpattern::fieldval_uniq(c);
|
||||
else if(nontruncated)
|
||||
// use the actual field codes
|
||||
si.id = fieldpattern::fieldval(c).first;
|
||||
else
|
||||
// use the small numbers from windmap
|
||||
si.id = windmap::getId(c);
|
||||
// todo dir
|
||||
}
|
||||
|
||||
else if(u == 6) {
|
||||
for(int i=1; i<c->type; i+=2) if(!isWarped(createMov(c,i)))
|
||||
return i;
|
||||
else if(sphere && pat == PAT_SIBLING) {
|
||||
val_all(c, si, sub);
|
||||
}
|
||||
|
||||
else if(u == 5) {
|
||||
for(int i=0; i<c->type; i++) if(!isWarped(createMov(c,(i+3)%7)) && !isWarped(createMov(c,(i+4)%7)))
|
||||
return i;
|
||||
else if(a457 && pat == PAT_ZEBRA) {
|
||||
val_all(c, si, sub);
|
||||
}
|
||||
|
||||
else if(u == 9) {
|
||||
for(int i=0; i<c->type; i++) if(!isWarped(createMov(c,(i+2)%7)) && !isWarped(createMov(c,(i+5)%7)))
|
||||
return i;
|
||||
else if(pat == PAT_COLORING && (a46 || euclid)) {
|
||||
val_all(c, si, sub);
|
||||
}
|
||||
|
||||
else if(u == 11) {
|
||||
for(int i=0; i<c->type; i++) if(isWarped(createMov(c,(i)%7)) && isWarped(createMov(c,(i+1)%7)))
|
||||
return i;
|
||||
}
|
||||
else
|
||||
val_warped(c, si);
|
||||
|
||||
else if(u == 12) {
|
||||
for(int i=0; i<c->type; i+=2) if(isWarped(createMov(c,i)))
|
||||
return i;
|
||||
}
|
||||
|
||||
else if(u == 7) {
|
||||
for(int i=0; i<c->type; i++) if(!isWarped(createMov(c,(i+1)%7)) && !isWarped(createMov(c,(i+6)%7)))
|
||||
return i;
|
||||
}
|
||||
|
||||
else if(u < 2) return 0;
|
||||
|
||||
#if LOCAL
|
||||
printf("unhandled: u=%d\n", u);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
char whichPattern = 0;
|
||||
|
||||
bool symRotation, sym01, sym02, sym03;
|
||||
|
||||
int subpattern(int i, char w) {
|
||||
if(euclid) {
|
||||
if(w == 'p')
|
||||
return i;
|
||||
if(w == 'z' || w == 'f')
|
||||
return (symRotation && (i<3)) ? 0 : i;
|
||||
}
|
||||
|
||||
if(a38 && w == 'p') {
|
||||
if(sym01 && i == 5) i = 4;
|
||||
if(symRotation && i < 4) i = 0;
|
||||
return i;
|
||||
}
|
||||
|
||||
if(w == 'z' || w == 'f' || w == 'p') {
|
||||
if((sym01?1:0)+(sym02?1:0)+(sym03?1:0) >= 2) i &= ~3;
|
||||
if(sym01 && (i&1)) i ^= 1;
|
||||
if(sym02 && (i&2)) i ^= 2;
|
||||
if(sym03 && (i&2)) i ^= 3;
|
||||
}
|
||||
|
||||
if(w == 'z' && symRotation) {
|
||||
if(a4 && !a46) {
|
||||
if(i >= 4 && i < 7) i -= 4;
|
||||
}
|
||||
else {
|
||||
if(i >= 8 && i < 12) i -= 4;
|
||||
if(i >= 12 && i < 16) i -= 8;
|
||||
if(i >= 20 && i < 24) i -= 4;
|
||||
if(i >= 24 && i < 28) i -= 8;
|
||||
if(i >= 32 && i < 36) i -= 4;
|
||||
if(i >= 36 && i < 40) i -= 8;
|
||||
}
|
||||
}
|
||||
|
||||
if(w == 'p' && stdhyperbolic && symRotation && i >= 3)
|
||||
i -= ((i/4-1) % 7) * 4;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
int subpattern(cell *c, char w) {
|
||||
return subpattern(realpattern(c, w), w);
|
||||
return si;
|
||||
}
|
||||
|
||||
}
|
||||
@ -689,12 +710,16 @@ int geosupport_graveyard() {
|
||||
|
||||
int pattern_threecolor(cell *c) {
|
||||
if(a38) {
|
||||
int i = val38(c);
|
||||
patterns::patterninfo si;
|
||||
patterns::val38(c, si, 0);
|
||||
int i = si.id;
|
||||
if(nontruncated) return i;
|
||||
else return i < 4 ? 0 : (1+(i&1));
|
||||
}
|
||||
if(a46 && !nontruncated) {
|
||||
int i = val46(c);
|
||||
patterns::patterninfo si;
|
||||
patterns::val46(c, si, 0);
|
||||
int i = si.id;
|
||||
return i >> 2;
|
||||
}
|
||||
if(S7 == 4) {
|
||||
@ -861,7 +886,7 @@ namespace patterns {
|
||||
col[2] /= 4;
|
||||
return (0x202020 + col[0] + (col[1] << 8) + (col[2] << 16)) >> (err?2:0);
|
||||
}
|
||||
if(whichCanvas == 'F') {
|
||||
if(whichCanvas == PAT_FIELD) {
|
||||
return pseudohept(c) ? 0x202020 : 0xC0C0C0;
|
||||
}
|
||||
if(whichCanvas == 'T') {
|
||||
@ -920,51 +945,62 @@ namespace patterns {
|
||||
}
|
||||
dialog::init();
|
||||
|
||||
if(a46) {
|
||||
dialog::addBoolItem(XLAT("two colors"), (whichPattern == 'f'), 'f');
|
||||
dialog::addBoolItem(XLAT("two colors rotated"), (whichPattern == 'z'), 'z');
|
||||
}
|
||||
else if(a4) {
|
||||
dialog::addBoolItem(XLAT("Zebra Pattern"), (whichPattern == 'z'), 'z');
|
||||
}
|
||||
else if(a38) {
|
||||
dialog::addBoolItem(XLAT("Zebra Pattern"), (whichPattern == 'z'), 'z');
|
||||
dialog::addBoolItem(XLAT("broken Emerald Pattern"), (whichPattern == 'f'), 'f');
|
||||
dialog::addBoolItem(XLAT("rotated pattern"), (whichPattern == 'p'), 'p');
|
||||
}
|
||||
else if(euclid) {
|
||||
dialog::addBoolItem(XLAT("three colors"), (whichPattern == 'f'), 'f');
|
||||
dialog::addBoolItem(XLAT("Palace Pattern"), (whichPattern == 'p'), 'p');
|
||||
dialog::addBoolItem(XLAT("three colors rotated"), (whichPattern == 'z'), 'z');
|
||||
}
|
||||
else if(sphere) {
|
||||
dialog::addBoolItem(XLAT("siblings"), (whichPattern == 'p'), 'p');
|
||||
}
|
||||
else {
|
||||
if(!stdhyperbolic)
|
||||
dialog::addInfo("patterns do not work correctly in this geometry!");
|
||||
if(stdhyperbolic || a4)
|
||||
dialog::addBoolItem(XLAT("Zebra Pattern"), (whichPattern == PAT_ZEBRA), PAT_ZEBRA);
|
||||
|
||||
if(stdhyperbolic)
|
||||
dialog::addBoolItem(XLAT("Emerald Pattern"), (whichPattern == PAT_EMERALD), PAT_EMERALD);
|
||||
else if(a38)
|
||||
dialog::addBoolItem(XLAT("broken Emerald Pattern"), (whichPattern == PAT_EMERALD), PAT_EMERALD);
|
||||
|
||||
if(stdhyperbolic || euclid)
|
||||
dialog::addBoolItem(XLAT("Palace Pattern"), (whichPattern == PAT_PALACE), PAT_PALACE);
|
||||
|
||||
if(a38 || a46 || euclid)
|
||||
dialog::addBoolItem(XLAT("coloring"), (whichPattern == PAT_COLORING), PAT_COLORING);
|
||||
|
||||
if(sphere)
|
||||
dialog::addBoolItem(XLAT("siblings"), (whichPattern == PAT_SIBLING), PAT_SIBLING);
|
||||
|
||||
dialog::addBoolItem(XLAT("Emerald Pattern"), (whichPattern == 'f'), 'f');
|
||||
dialog::addBoolItem(XLAT("Palace Pattern"), (whichPattern == 'p'), 'p');
|
||||
dialog::addBoolItem(XLAT("Zebra Pattern"), (whichPattern == 'z'), 'z');
|
||||
}
|
||||
if(euclid)
|
||||
dialog::addBoolItem(XLAT("torus pattern"), (whichPattern == 'F'), 'F');
|
||||
dialog::addBoolItem(XLAT("torus pattern"), (whichPattern == PAT_FIELD), PAT_FIELD);
|
||||
else if(sphere)
|
||||
dialog::addBoolItem(XLAT("single cells"), (whichPattern == 'F'), 'F');
|
||||
dialog::addBoolItem(XLAT("single cells"), (whichPattern == PAT_FIELD), PAT_FIELD);
|
||||
else
|
||||
dialog::addBoolItem(XLAT("field pattern"), (whichPattern == 'F'), 'F');
|
||||
dialog::addBoolItem(XLAT("field pattern"), (whichPattern == PAT_FIELD), PAT_FIELD);
|
||||
|
||||
if(whichPattern == 'f' && stdhyperbolic) symRotation = true;
|
||||
if(whichPattern == 'F') ;
|
||||
else if(!euclid) {
|
||||
dialog::addBoolItem(XLAT("rotational symmetry"), (symRotation), '0');
|
||||
dialog::addBoolItem(XLAT("symmetry 0-1"), (sym01), '1');
|
||||
dialog::addBoolItem(XLAT("symmetry 0-2"), (sym02), '2');
|
||||
dialog::addBoolItem(XLAT("symmetry 0-3"), (sym03), '3');
|
||||
if(
|
||||
(whichPattern == PAT_EMERALD && (stdhyperbolic || a38)) ||
|
||||
(whichPattern == PAT_PALACE && stdhyperbolic) ||
|
||||
(whichPattern == PAT_ZEBRA && stdhyperbolic) ||
|
||||
(whichPattern == PAT_SIBLING && sphere) ||
|
||||
(whichPattern == PAT_ZEBRA && a457)) {
|
||||
dialog::addBoolItem(XLAT("rotational symmetry"), subpattern_flags & SPF_ROT, '0');
|
||||
}
|
||||
|
||||
if((euclid && whichPattern == PAT_COLORING) ||
|
||||
(a38 && whichPattern == PAT_COLORING))
|
||||
dialog::addBoolItem(XLAT("edit all three colors"), subpattern_flags & SPF_ROT, '0');
|
||||
|
||||
if(euclid && whichPattern == PAT_COLORING)
|
||||
dialog::addBoolItem(XLAT("rotate the color groups"), subpattern_flags & SPF_CHANGEROT, '4');
|
||||
|
||||
if((a38 && whichPattern == PAT_COLORING && !nontruncated) ||
|
||||
(a46 && whichPattern == PAT_COLORING && !nontruncated)
|
||||
)
|
||||
dialog::addBoolItem(XLAT("edit both truncated colors"), subpattern_flags & SPF_TWOCOL, '5');
|
||||
|
||||
if(
|
||||
(whichPattern == PAT_EMERALD && (stdhyperbolic || a38)) ||
|
||||
(whichPattern == PAT_PALACE && stdhyperbolic) ||
|
||||
(whichPattern == PAT_ZEBRA && stdhyperbolic) ||
|
||||
(whichPattern == PAT_COLORING && a46) ||
|
||||
(whichPattern == PAT_ZEBRA && a457)
|
||||
) {
|
||||
dialog::addBoolItem(XLAT("symmetry 0-1"), subpattern_flags & SPF_SYM01, '1');
|
||||
dialog::addBoolItem(XLAT("symmetry 0-2"), subpattern_flags & SPF_SYM02, '2');
|
||||
dialog::addBoolItem(XLAT("symmetry 0-3"), subpattern_flags & SPF_SYM03, '3');
|
||||
}
|
||||
else
|
||||
dialog::addBoolItem(XLAT("edit all three colors"), (symRotation), '0');
|
||||
|
||||
dialog::addBoolItem(XLAT("display pattern codes (full)"), (displaycodes == 1), 'd');
|
||||
dialog::addBoolItem(XLAT("display pattern codes (simplified)"), (displaycodes == 2), 's');
|
||||
@ -982,21 +1018,19 @@ namespace patterns {
|
||||
|
||||
keyhandler = [] (int sym, int uni) {
|
||||
dialog::handleNavigation(sym, uni);
|
||||
if(uni == 'f' || uni == 'p' || uni == 'z' || uni == 'H' || uni == 'F') {
|
||||
if(among(uni, PAT_EMERALD, PAT_PALACE, PAT_ZEBRA, PAT_DOWN, PAT_FIELD, PAT_COLORING, PAT_SIBLING)) {
|
||||
if(whichPattern == uni) whichPattern = 0;
|
||||
else whichPattern = uni;
|
||||
mapeditor::modelcell.clear();
|
||||
}
|
||||
|
||||
else if(uni == '0') symRotation = !symRotation;
|
||||
else if(uni == '1') sym01 = !sym01;
|
||||
else if(uni == '2') sym02 = !sym02;
|
||||
else if(uni == '3') sym03 = !sym03;
|
||||
else if(uni >= '0' && uni <= '5')
|
||||
subpattern_flags ^= (1 << (uni - '0'));
|
||||
|
||||
else if(uni == '6' || uni == '7' || uni == '8') {
|
||||
if(whichShape == uni) whichShape = 0;
|
||||
else whichShape = uni;
|
||||
}
|
||||
else if(uni == '3') sym03 = !sym03;
|
||||
else if(uni == 'd') displaycodes = displaycodes == 1 ? 0 : 1;
|
||||
else if(uni == 's') displaycodes = displaycodes == 2 ? 0 : 2;
|
||||
|
||||
@ -1281,3 +1315,10 @@ namespace linepatterns {
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
int val46(cell *c) {
|
||||
patterns::patterninfo si;
|
||||
patterns::val46(c, si, 0);
|
||||
return si.id;
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
// rules for the emeraldvalues of heptagons.
|
||||
int emerald_heptagon(int parent, int dir) {
|
||||
|
||||
if(a46) return parent ^ (dir & 1) ^ 2;
|
||||
if(a46) return parent ^ (dir & 1) ^ 2 ^ (((parent^dir) & 1) << 2);
|
||||
|
||||
if(S7 == 8 && dir > 3) dir--;
|
||||
|
||||
|
@ -990,6 +990,8 @@ hpcshape
|
||||
shTerraArmor1, shTerraArmor2, shTerraArmor3, shTerraHead, shTerraFace,
|
||||
shJiangShi, shJiangShiDress, shJiangShiCap1, shJiangShiCap2,
|
||||
|
||||
shAsymmetric,
|
||||
|
||||
shDodeca;
|
||||
|
||||
#define USERLAYERS 32
|
||||
@ -1039,7 +1041,6 @@ hyperpoint turtlevertex(int u, double x, double y, double z) {
|
||||
return hpxd(scale, x, y, z);
|
||||
}
|
||||
|
||||
|
||||
void finishshape() {
|
||||
last->e = qhpc;
|
||||
double area = 0;
|
||||
@ -1793,6 +1794,8 @@ void buildpolys() {
|
||||
bshape(shLeafFloor[0], PPR_FLOOR_DRAGON, 1*spzoom6, 313);
|
||||
bshape(shLeafFloor[1], PPR_FLOOR_DRAGON, 1*spzoomd7, 314);
|
||||
|
||||
bshape(shAsymmetric, PPR_TEXT, scalef, 374);
|
||||
|
||||
bshape(shTriheptaFloor[2], PPR_FLOOR, scalef, 32);
|
||||
bshape(shTriheptaFloor[3], PPR_FLOOR, scalef, 33);
|
||||
bshape(shTriheptaFloor[4], PPR_FLOOR, scalef, 34);
|
||||
@ -3329,6 +3332,8 @@ NEWSHAPE, 371, 1, 1, -0.013726,-0.304365, 0.244972,-0.147728, 0.266167,0.130112,
|
||||
NEWSHAPE, 372, 1, 1, -0.514563,-0.238476, -0.340659,0.172987, -0.100245,0.368967, 0.214334,0.276255, 0.349294,-0.008293, 0.203063,-0.280225, -0.078470,-0.352806,
|
||||
NEWSHAPE, 373, 1, 1, -0.019312,0.304743, -0.289045,0.177117, -0.127176,-0.240665, 0.007400,-0.336712, 0.257684,-0.184398, 0.234654,0.191587,
|
||||
|
||||
NEWSHAPE, 374, 1, 1, -0.229502,-0.051000, 0.320183,0.006447, 0.148302,0.144065, 0.173317,0.054954, -0.253447,0.021298,
|
||||
|
||||
NEWSHAPE
|
||||
};
|
||||
|
||||
|
25
textures.cpp
25
textures.cpp
@ -119,15 +119,10 @@ map<int, textureinfo> texture_map;
|
||||
|
||||
bool applyTextureMap(cell *c, const transmatrix &V, int col) {
|
||||
using namespace patterns;
|
||||
int t = subpattern(c, whichPattern);
|
||||
auto si = getpatterninfo0(c);
|
||||
try {
|
||||
auto& mi = texture_map.at(t);
|
||||
qfi.spin = Id;
|
||||
|
||||
int d = patterndir(c, whichPattern);
|
||||
qfi.spin = qfi.spin * spin(-M_PI * 2 * d / c->type);
|
||||
if(reflectPatternAt(c))
|
||||
qfi.spin = qfi.spin * Mirror;
|
||||
auto& mi = texture_map.at(si.id);
|
||||
qfi.spin = applyPatterndir(c, si);
|
||||
|
||||
int n = mi.vertices.size() / 3;
|
||||
|
||||
@ -160,25 +155,21 @@ void perform_mapping() {
|
||||
glfont_t& f(textures); int tabid = 1;
|
||||
for(auto p: gmatrix) {
|
||||
cell *c = p.first;
|
||||
int t = subpattern(c, whichPattern);
|
||||
auto si = getpatterninfo0(c);
|
||||
bool replace = false;
|
||||
|
||||
if(!texture_map.count(t))
|
||||
if(!texture_map.count(si.id))
|
||||
replace = true;
|
||||
else if(p.second[2][2] < texture_map[t].M[2][2])
|
||||
else if(p.second[2][2] < texture_map[si.id].M[2][2])
|
||||
replace = true;
|
||||
|
||||
if(replace) {
|
||||
auto& mi = texture_map[t];
|
||||
auto& mi = texture_map[si.id];
|
||||
mi.M = p.second;
|
||||
mi.vertices.clear();
|
||||
mi.tvertices.clear();
|
||||
|
||||
int d = patterndir(c, whichPattern);
|
||||
if(d)
|
||||
mi.M = mi.M * spin(-M_PI * 2 * d / c->type);
|
||||
if(reflectPatternAt(c, whichPattern))
|
||||
mi.M = mi.M * Mirror;
|
||||
mi.M = mi.M * applyPatterndir(c, si);
|
||||
|
||||
ld z = ctof(c) ? rhexf : hexvdist;
|
||||
ld base = ctof(c) ? 0 : 0; // -hexshift;
|
||||
|
Loading…
Reference in New Issue
Block a user