'siblings' patterns on spheres

This commit is contained in:
Zeno Rogue 2017-12-03 18:24:34 +01:00
parent 3c600d7d6b
commit dadbbf244f
2 changed files with 104 additions and 40 deletions

View File

@ -85,6 +85,8 @@ int spherecells() {
if(S7 == 1) return 1; if(S7 == 1) return 1;
return 12; return 12;
} }
vector<int> siblings;
struct hrmap_spherical : hrmap { struct hrmap_spherical : hrmap {
heptagon *dodecahedron[12]; heptagon *dodecahedron[12];
@ -102,10 +104,15 @@ struct hrmap_spherical : hrmap {
h.alt = NULL; h.alt = NULL;
h.cdata = NULL; h.cdata = NULL;
h.spintable = 0; h.spintable = 0;
h.fieldval = i;
for(int i=0; i<S7; i++) h.move[i] = NULL; for(int i=0; i<S7; i++) h.move[i] = NULL;
h.c7 = newCell(S7, &h); h.c7 = newCell(S7, &h);
} }
for(int i=0; i<S7; i++) { if(S7 == 5)
siblings = {1, 0, 10, 4, 3, 8, 9, 11, 5, 6, 2, 7};
else
siblings = {1, 0, 3, 2, 5, 4};
for(int i=0; i<S7; i++) {
dodecahedron[0]->move[i] = dodecahedron[i+1]; dodecahedron[0]->move[i] = dodecahedron[i+1];
dodecahedron[0]->setspin(i, 0); dodecahedron[0]->setspin(i, 0);
dodecahedron[i+1]->move[0] = dodecahedron[0]; dodecahedron[i+1]->move[0] = dodecahedron[0];
@ -1540,3 +1547,51 @@ int getHemisphere(cell *c, int which) {
} }
} }
struct sphereinfo {
int id;
int dir;
bool reflect;
};
sphereinfo valsphere(cell *c) {
sphereinfo si;
if(ctof(c)) {
int d = c->master->fieldval;
si.id = (d < siblings[d]) ? 0 : 1;
for(int i=0; i<S7; i++) {
int di = c->master->move[i]->fieldval;
if(di == siblings[d]) si.dir = i;
}
si.reflect = false;
}
else {
int ids = 0, tids = 0, td = 0;
for(int i=0; i<S3; i++) {
int d = c->mov[i*2]->master->fieldval;
ids |= (1<<d); tids += d;
}
for(int i=0; i<S3; i++) {
int d = c->mov[i*2]->master->fieldval;
if(ids & (1<<siblings[d])) td += d;
}
if(td) {
si.id = 4;
for(int i=0; i<S3; i++) {
int d = c->mov[i*2]->master->fieldval;
if(!(ids & (1<<siblings[d]))) si.dir = 2*i;
}
si.reflect = false;
}
else {
si.id = 8;
si.dir = 0; // whatever
sphereinfo si2 = valsphere(c->mov[0]);
int di = si2.dir - c->spin(0);
di %= S7;
if(di<0) di += S7;
si.reflect = di > S7/2;
}
}
return si;
}

View File

@ -332,6 +332,7 @@ namespace mapeditor {
} }
bool reflectPatternAt(cell *c, char p = whichPattern) { bool reflectPatternAt(cell *c, char p = whichPattern) {
if(p == 'p' && sphere) return valsphere(c).reflect;
if(p == 'p' && polarb50(c)) return true; if(p == 'p' && polarb50(c)) return true;
if(p == 0) { if(p == 0) {
int np = nopattern(c); int np = nopattern(c);
@ -378,13 +379,16 @@ namespace mapeditor {
return i; return i;
return 0; return 0;
} }
int patterndir(cell *c, char w) { 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;
}
switch(w) { switch(w) {
case 'z': { case 'z': {
if(a46) return patterndir46(c, 3);
if(a4) return patterndir457(c);
if(a38) return patterndir38(c);
int t = zebra40(c); int t = zebra40(c);
if(euclid) return (t*4) % 6; if(euclid) return (t*4) % 6;
@ -407,9 +411,6 @@ namespace mapeditor {
} }
case 'f': { case 'f': {
if(a46) return patterndir46(c, 1);
if(a38) return patterndir38(c);
if(a4) return patterndir457(c);
int t = emeraldval(c); int t = emeraldval(c);
if(euclid) return 0; if(euclid) return 0;
int tcdir = 0, tbest = (t&3); int tcdir = 0, tbest = (t&3);
@ -425,9 +426,6 @@ namespace mapeditor {
} }
case 'p': { case 'p': {
if(a46) return patterndir46(c, 2);
if(a4) return patterndir457(c);
if(a38) return patterndir38(c);
int tcdir = -1, tbest = -1; int tcdir = -1, tbest = -1;
int pa = polara50(c); int pa = polara50(c);
int pb = polarb50(c); int pb = polarb50(c);
@ -446,9 +444,6 @@ namespace mapeditor {
case 0: { case 0: {
if(euclid) return 0; if(euclid) return 0;
if(a46) return patterndir46(c, 1);
if(a4) return patterndir457(c);
if(a38) return patterndir38(c);
int u = nopattern(c); int u = nopattern(c);
if(u == 6) { if(u == 6) {
@ -807,6 +802,9 @@ namespace mapeditor {
dialog::addBoolItem(XLAT("Palace Pattern"), (whichPattern == 'p'), 'p'); dialog::addBoolItem(XLAT("Palace Pattern"), (whichPattern == 'p'), 'p');
dialog::addBoolItem(XLAT("three colors rotated"), (whichPattern == 'z'), 'z'); dialog::addBoolItem(XLAT("three colors rotated"), (whichPattern == 'z'), 'z');
} }
else if(sphere) {
dialog::addBoolItem(XLAT("siblings"), (whichPattern == 'p'), 'p');
}
else { else {
if(!stdhyperbolic) if(!stdhyperbolic)
dialog::addInfo("patterns do not work correctly in this geometry!"); dialog::addInfo("patterns do not work correctly in this geometry!");
@ -817,7 +815,9 @@ namespace mapeditor {
} }
if(euclid) if(euclid)
dialog::addBoolItem(XLAT("torus pattern"), (whichPattern == 'F'), 'F'); dialog::addBoolItem(XLAT("torus pattern"), (whichPattern == 'F'), 'F');
else if(!sphere) else if(sphere)
dialog::addBoolItem(XLAT("single cells"), (whichPattern == 'F'), 'F');
else
dialog::addBoolItem(XLAT("field pattern"), (whichPattern == 'F'), 'F'); dialog::addBoolItem(XLAT("field pattern"), (whichPattern == 'F'), 'F');
if(whichPattern == 'f' && stdhyperbolic) symRotation = true; if(whichPattern == 'f' && stdhyperbolic) symRotation = true;
@ -837,9 +837,12 @@ namespace mapeditor {
dialog::addBoolItem(XLAT("display only hexagons"), (whichShape == '6'), '6'); dialog::addBoolItem(XLAT("display only hexagons"), (whichShape == '6'), '6');
dialog::addBoolItem(XLAT("display only heptagons"), (whichShape == '7'), '7'); dialog::addBoolItem(XLAT("display only heptagons"), (whichShape == '7'), '7');
dialog::addBoolItem(XLAT("display the triheptagonal grid"), (whichShape == '8'), '8'); dialog::addBoolItem(XLAT("display the triheptagonal grid"), (whichShape == '8'), '8');
dialog::addItem(XLAT("line patterns"), 'l'); if(cheater || autocheat) dialog::addItem(XLAT("line patterns"), 'l');
else dialog::addInfo("enable the cheat mode to use line patterns");
if(!needConfirmation()) dialog::addItem(XLAT("predesigned patterns"), 'r');
else dialog::addInfo("start a new game to use predesigned patterns");
dialog::addItem(XLAT("predesigned patterns"), 'r');
dialog::display(); dialog::display();
keyhandler = [] (int sym, int uni) { keyhandler = [] (int sym, int uni) {
@ -862,10 +865,10 @@ namespace mapeditor {
else if(uni == 'd') displaycodes = displaycodes == 1 ? 0 : 1; else if(uni == 'd') displaycodes = displaycodes == 1 ? 0 : 1;
else if(uni == 's') displaycodes = displaycodes == 2 ? 0 : 2; else if(uni == 's') displaycodes = displaycodes == 2 ? 0 : 2;
else if(uni == 'l') else if(uni == 'l' && (cheater || autocheat))
pushScreen(linepatterns::showMenu); pushScreen(linepatterns::showMenu);
else if(uni == 'r') pushScreen(showPrePattern); else if(uni == 'r' && !needConfirmation()) pushScreen(showPrePattern);
else if(doexiton(sym, uni)) popScreen(); else if(doexiton(sym, uni)) popScreen();
}; };
@ -955,7 +958,7 @@ namespace mapeditor {
displayButton(8, 8+fs*12, XLAT("f = flip %1", ONOFF(copysource.mirrored)), 'u', 0); displayButton(8, 8+fs*12, XLAT("f = flip %1", ONOFF(copysource.mirrored)), 'u', 0);
displayButton(8, 8+fs*13, XLAT("r = regular"), 'r', 0); displayButton(8, 8+fs*13, XLAT("r = regular"), 'r', 0);
displayButton(8, 8+fs*14, XLAT("p = paint"), 'p', 0); displayButton(8, 8+fs*14, XLAT("p = paint"), 'p', 0);
displayFunctionKeys(); displayFunctionKeys();
keyhandler = handleKeyMap; keyhandler = handleKeyMap;
@ -1011,6 +1014,7 @@ namespace mapeditor {
case 'p': { case 'p': {
if(a46) return subpatternEmerald(val46(c)); if(a46) return subpatternEmerald(val46(c));
if(a38) return val38(c); if(a38) return val38(c);
if(sphere) return subpatternEmerald(valsphere(c).id);
int i = fiftyval049(c); int i = fiftyval049(c);
i *= 4; i *= 4;
if(polara50(c)) i|=1; if(polara50(c)) i|=1;
@ -1020,7 +1024,6 @@ namespace mapeditor {
case 'P': case 'P':
return fiftyval(c); return fiftyval(c);
case 'H': case 'H':
return realpattern(c);
case 'F': case 'F':
return realpattern(c); return realpattern(c);
} }
@ -1036,6 +1039,7 @@ namespace mapeditor {
case 'p': { case 'p': {
if(a46) return val46(c); if(a46) return val46(c);
if(a38) return val38(c); if(a38) return val38(c);
if(sphere) return valsphere(c).id;
int i = fiftyval049(c); int i = fiftyval049(c);
i *= 4; i *= 4;
if(polara50(c)) i|=1; if(polara50(c)) i|=1;
@ -1045,26 +1049,20 @@ namespace mapeditor {
case 'H': case 'H':
return towerval(c); return towerval(c);
case 'F': { case 'F': {
if(euclid) { if(euclid)
using namespace torusconfig; // use the torus ID
eucoord cx, cy; return fieldpattern::fieldval_uniq(c);
decodeMaster(c->master, cx, cy); else if(nontruncated)
int cd = cx * dx + cy * dy; // use the actual field codes
cd %= qty; if(cd<0) cd += qty; return fieldpattern::fieldval(c).first;
return cd; else
} // use the small numbers from windmap
pair<int, bool> p = fieldpattern::fieldval(c); return windmap::getId(c);
return 10*p.first + (p.second?6:7);
} }
} }
return nopattern(c); return nopattern(c);
} }
int realpatternsh(cell *c) {
if(whichPattern == 'F') return nopattern(c);
else return realpattern(c);
}
int cellShapeGroup() { int cellShapeGroup() {
if(whichPattern == 'f') return 4; if(whichPattern == 'f') return 4;
if(whichPattern == 'p') return 5; if(whichPattern == 'p') return 5;
@ -1084,7 +1082,7 @@ namespace mapeditor {
if(drawcell == cwt.c) return vid.cs.charid; if(drawcell == cwt.c) return vid.cs.charid;
if(drawcell->monst) return drawcell->monst; if(drawcell->monst) return drawcell->monst;
if(drawcell->item) return drawcell->item; if(drawcell->item) return drawcell->item;
return subpattern(drawcell) % (USERSHAPEIDS); return subpattern(drawcell);
} }
int subpatternShape(int i) { int subpatternShape(int i) {
@ -1450,6 +1448,7 @@ namespace mapeditor {
cmode = sm::DRAW; cmode = sm::DRAW;
gamescreen(0); gamescreen(0);
drawGrid(); drawGrid();
callhandlers(false, hooks_prestats);
if(!mouseout()) getcstat = '-'; if(!mouseout()) getcstat = '-';
@ -1481,7 +1480,7 @@ namespace mapeditor {
default: default:
line1 = XLAT("floor/pattern"); line1 = XLAT("floor/pattern");
line2 = "#" + its(subpattern(cwt.c)); line2 = "#" + its(subpattern(drawcell));
break; break;
} }
@ -1491,7 +1490,10 @@ namespace mapeditor {
// displayButton(8, 8+fs*9, XLAT("l = lands"), 'l', 0); // displayButton(8, 8+fs*9, XLAT("l = lands"), 'l', 0);
displayfr(8, 8+fs, 2, vid.fsize, line1, 0xC0C0C0, 0); displayfr(8, 8+fs, 2, vid.fsize, line1, 0xC0C0C0, 0);
displayfr(8, 8+fs*2, 2, vid.fsize, line2, 0xC0C0C0, 0); if(sg >= 3)
displayButton(8, 8+fs*2, line2 + XLAT(" (r = complex tesselations)"), 'r', 0);
else
displayfr(8, 8+fs*2, 2, vid.fsize, line2, 0xC0C0C0, 0);
displayButton(8, 8+fs*3, XLAT("l = layers: %1", its(dslayer)), 'l', 0); displayButton(8, 8+fs*3, XLAT("l = layers: %1", its(dslayer)), 'l', 0);
if(us && size(us->d[dslayer].list)) { if(us && size(us->d[dslayer].list)) {
usershapelayer& ds(us->d[dslayer]); usershapelayer& ds(us->d[dslayer]);
@ -1836,7 +1838,12 @@ namespace mapeditor {
if(uni == 'g') coldcenter = ccenter, ccenter = mh; if(uni == 'g') coldcenter = ccenter, ccenter = mh;
if(uni == 'c') ew = ewsearch; if(uni == 'c') ew = ewsearch;
if(uni == 'b') autochoose = !autochoose; if(uni == 'b') autochoose = !autochoose;
if(uni == 'r') {
pushScreen(showPattern);
if(drawplayer)
addMessage(XLAT("Hint: use F7 to edit floor under the player"));
}
if(uni == 'S') { if(uni == 'S') {
for(int i=0; i<USERSHAPEGROUPS; i++) for(int j=0; j<USERSHAPEIDS; j++) { for(int i=0; i<USERSHAPEGROUPS; i++) for(int j=0; j<USERSHAPEIDS; j++) {
@ -2068,6 +2075,8 @@ namespace mapeditor {
return false; return false;
#else #else
id = id % USERSHAPEIDS;
usershape *us = usershapes[group][id]; usershape *us = usershapes[group][id];
if(us) { if(us) {
for(int i=0; i<USERLAYERS; i++) { for(int i=0; i<USERLAYERS; i++) {