geometry flags part 1

This commit is contained in:
? 2019-02-17 18:28:20 +01:00 committed by Zeno Rogue
parent 183b267d64
commit b25730d5c9
32 changed files with 609 additions and 115 deletions

View File

@ -231,10 +231,12 @@ void achievement_collection(eItem it, int prevgold, int newgold) {
if(q == 1) achievement_gain("GRAIL2");
if(PURE && geometry == gNormal)
achievement_gain("GRAILH", rg::special_geometry);
#if CAP_CRYSTAL
if(PURE && geometry == gCrystal && ginf[gCrystal].sides == 8 && ginf[gCrystal].vertex == 4 && !crystal::used_compass_inside)
achievement_gain("GRAIL4D", rg::special_geometry);
if(BITRUNCATED && geometry == gCrystal && ginf[gCrystal].sides == 8 && ginf[gCrystal].vertex == 3 && !crystal::used_compass_inside)
achievement_gain("GRAIL4D2", rg::special_geometry);
#endif
if(q == 3) achievement_gain("GRAIL3");
if(q == 8) achievement_gain("GRAIL4");
}

View File

@ -6,6 +6,7 @@ namespace hr {
namespace arcm {
#if CAP_ARCM
#define SDEBUG(x) if(debug_geometry) { x; fflush(stdout); }
static const int sfPH = 1;
@ -1213,6 +1214,7 @@ int valence() {
return total / isize(current.faces);
}
#endif
}
}

View File

@ -36,7 +36,9 @@ int roundTableRadius(cell *c) {
}
int celldistAltRelative(cell *c) {
#if CAP_CRYSTAL
if(geometry == gCrystal) return crystal::dist_relative(c);
#endif
if(euwrap) return celldistAlt(c) - roundTableRadius(c);
if(sphere || quotient) {
return celldist(c) - 3;
@ -995,8 +997,12 @@ bool horo_ok() {
}
bool gp_wall_test() {
#if CAP_GP
if(GOLDBERG) return hrand(gp::dist_3()) == 0;
#endif
#if CAP_IRR
if(IRREGULAR) return hrand(irr::cellcount * 3) < isize(irr::cells_of_heptagon);
#endif
return true;
}

View File

@ -2,7 +2,7 @@
namespace hr {
namespace binary {
#if CAP_BT
enum bindir {
bd_right = 0,
bd_up_right = 1,
@ -215,6 +215,6 @@ auto bt_config = addHook(hooks_args, 0, [] () {
return 1;
});
#endif
#endif
}
}

View File

@ -63,7 +63,9 @@ hrmap_hyperbolic::hrmap_hyperbolic() {
h.alt = NULL;
h.distance = 0;
mvar = variation;
if(binarytiling) {
if(0);
#if CAP_BT
else if(binarytiling) {
#if DEBUG_BINARY_TILING
binary::xcode.clear();
binary::rxcode.clear();
@ -73,8 +75,11 @@ hrmap_hyperbolic::hrmap_hyperbolic() {
h.zebraval = 0,
h.c7 = newCell(6, origin);
}
#endif
#if CAP_IRR
else if(IRREGULAR)
irr::link_start(origin);
#endif
else
h.c7 = newCell(S7, origin);
}
@ -205,12 +210,14 @@ struct hrmap_spherical : hrmap {
}
}
#if CAP_IRR
if(IRREGULAR) {
irr::link_start(dodecahedron[0]);
for(int i=0; i<spherecells(); i++)
for(int j=0; j<S7; j++)
irr::may_link_next(dodecahedron[i], j);
}
#endif
}
heptagon *getOrigin() { return dodecahedron[0]; }
@ -1052,12 +1059,14 @@ struct hrmap_quotient : hrmap {
allh[i]->move[j]->alt = createStep(allh[i]->alt, j); */
}
#if CAP_IRR
if(IRREGULAR) {
irr::link_start(allh[0]);
for(int i=0; i<TOT; i++)
for(int j=0; j<S7; j++)
irr::may_link_next(allh[i], j);
}
#endif
celllister cl(gamestart(), 100, 100000000, NULL);
celllist = cl.lst;
@ -1097,9 +1106,12 @@ cell *createMov(cell *c, int d) {
}
if(c->move(d)) return c->move(d);
#if CAP_IRR
else if(IRREGULAR) {
irr::link_cell(c, d);
}
#endif
#if CAP_GP
else if(GOLDBERG) {
gp::extend_map(c, d);
if(!c->move(d)) {
@ -1107,6 +1119,8 @@ cell *createMov(cell *c, int d) {
exit(1);
}
}
#endif
#if CAP_ARCM
else if(archimedean && PURE) {
if(arcm::id_of(c->master) < arcm::current.N * 2) {
heptspin hs = heptspin(c->master, d) + wstep + 2 + wstep + 1;
@ -1125,6 +1139,7 @@ cell *createMov(cell *c, int d) {
c->c.connect(d,c,d,false);
}
}
#endif
else if(archimedean || PURE) {
heptagon *h2 = createStep(c->master, d);
c->c.connect(d, h2->c7,c->master->c.spin(d),false);
@ -1212,8 +1227,12 @@ void initcells() {
hrmap* res = callhandlers((hrmap*)nullptr, hooks_newmap);
if(res) currentmap = res;
#if CAP_CRYSTAL
else if(geometry == gCrystal) currentmap = crystal::new_map();
#endif
#if CAP_ARCM
else if(archimedean) currentmap = arcm::new_map();
#endif
else if(fulltorus) currentmap = new hrmap_torus;
else if(euclid) currentmap = new hrmap_euclidean;
else if(sphere) currentmap = new hrmap_spherical;
@ -1262,7 +1281,10 @@ void clearHexes(heptagon *at) {
delete at->cdata;
at->cdata = NULL;
}
if(IRREGULAR) irr::clear_links(at);
if(0);
#if CAP_IRR
else if(IRREGULAR) irr::clear_links(at);
#endif
else if(at->c7) subcell(at->c7, clearcell);
}
@ -1381,9 +1403,13 @@ int celldist(cell *c) {
if(masterless)
return eudist(decodeId(c->master));
if(sphere || binarytiling || geometry == gCrystal) return celldistance(c, currentmap->gamestart());
#if CAP_IRR
if(IRREGULAR) return irr::celldist(c, false);
#endif
if(archimedean || ctof(c)) return c->master->distance;
#if CAP_GP
if(GOLDBERG) return gp::compute_dist(c, celldist);
#endif
int dx[MAX_S3];
for(int u=0; u<S3; u++)
dx[u] = createMov(c, u+u)->master->distance;
@ -1403,16 +1429,24 @@ int celldistAlt(cell *c) {
tie(x,y) = vec_to_pair(decodeId(c->master));
return euclidAlt(x, y);
}
#if CAP_BT
if(binarytiling) return c->master->distance + (specialland == laCamelot && !tactic::on? 30 : 0);
#endif
#if CAP_CRYSTAL
if(geometry == gCrystal)
return crystal::dist_alt(c);
#endif
if(sphere || quotient) {
return celldist(c) - 3;
}
if(!c->master->alt) return 0;
#if CAP_IRR
if(IRREGULAR) return irr::celldist(c, true);
#endif
if(ctof(c)) return c->master->alt->distance;
#if CAP_GP
if(GOLDBERG) return gp::compute_dist(c, celldistAlt);
#endif
int dx[MAX_S3]; dx[0] = 0;
for(int u=0; u<S3; u++) if(createMov(c, u+u)->master->alt == NULL)
return ALTDIST_UNKNOWN;
@ -1755,7 +1789,9 @@ cell *heptatdir(cell *c, int d) {
int heptdistance(heptagon *h1, heptagon *h2) {
// very rough distance
int d = 0;
#if CAP_CRYSTAL
if(geometry == gCrystal) return crystal::space_distance(h1->c7, h2->c7);
#endif
while(true) {
if(h1 == h2) return d;
for(int i=0; i<S7; i++) if(h1->move(i) == h2) return d + 1;
@ -1766,7 +1802,9 @@ int heptdistance(heptagon *h1, heptagon *h2) {
}
int heptdistance(cell *c1, cell *c2) {
#if CAP_CRYSTAL
if(geometry == gCrystal) return crystal::space_distance(c1, c2);
#endif
if(!hyperbolic || quotient) return celldistance(c1, c2);
else return heptdistance(c1->master, c2->master);
}
@ -1802,7 +1840,9 @@ int celldistance(cell *c1, cell *c2) {
return 64;
}
#if CAP_CRYSTAL
if(geometry == gCrystal) return crystal::precise_distance(c1, c2);
#endif
if(masterless || archimedean || quotient) {
@ -1826,7 +1866,9 @@ int celldistance(cell *c1, cell *c2) {
}
vector<cell*> build_shortest_path(cell *c1, cell *c2) {
#if CAP_CRYSTAL
if(geometry == gCrystal) return crystal::build_shortest_path(c1, c2);
#endif
vector<cell*> p;
if(euclid) {
using namespace hyperpoint_vec;

View File

@ -1061,6 +1061,7 @@ namespace whirlpool {
namespace mirror {
bool build(cell *c) {
#if CAP_GP
if(GOLDBERG) {
if(c == c->master->c7) {
c->wall = ((gp::param.second == 0 || gp::param.first == gp::param.second) && hrand(2)) ? waMirror : waCloud;
@ -1068,10 +1069,13 @@ namespace mirror {
}
return false;
}
#endif
#if CAP_ARCM
if(archimedean) {
c->wall = hrand(2) ? waMirror : waCloud;
return true;
}
#endif
if(binarytiling || IRREGULAR) {
// mirrors not supported
if(is_mirrorland(c)) {
@ -1142,6 +1146,7 @@ namespace mirror {
}
}
#if CAP_ARCM
// we go by heptagons in Archimedean,
bool equal(heptspin h1, heptspin h2, int lev) {
if(h1.at->degree() != h2.at->degree()) return false;
@ -1177,23 +1182,28 @@ namespace mirror {
if(create_archimedean_rec(hsx, cpid, hs, 3)) return;
if(create_archimedean_rec(hsx, cpid, hs, 4)) return;
}
#endif
void createMirrors(cellwalker cw, int cpid) {
#if CAP_ARCM
if(archimedean) {
create_archimedean(cw, cpid, true);
return;
}
#endif
cw.mirrored = !cw.mirrored;
cell *c = cw.at;
#if CAP_GP
if(GOLDBERG) {
for(int i=0; i<cw.at->type; i++) {
createMirror(cw + cth + i + wstep + i - (gp::param.first == gp::param.second ? 1 : 0) + cth, cpid);
}
return;
}
#endif
for(int i=0; i<cw.at->type; i++) {
auto cws = cw + wstep;
if(cws.at->type == c->type)
@ -1203,10 +1213,13 @@ namespace mirror {
}
void createMirages(cellwalker cw, int cpid) {
#if CAP_ARCM
if(archimedean) {
create_archimedean(cw, cpid, false);
return;
}
#endif
#if CAP_GP
if(GOLDBERG && !(S7 & 1)) {
for(int i=0; i<cw.at->type; i++) {
createMirror(cw + cth + i + wstep + 1 + wstep + 1 + (S7/2) - i + 1 + cth, cpid);
@ -1219,6 +1232,7 @@ namespace mirror {
}
return;
}
#endif
if(PURE && !(S7 & 1)) {
for(int i=0; i<cw.at->type; i++)
createMirror(cw + i + wstep + 1 + wstep + 1 + (S7/2) - i, cpid);

View File

@ -293,18 +293,22 @@ void initConfig() {
addsaver(vid.stretch, "stretch", 1);
addsaver(vid.binary_width, "binary-tiling-width", 1);
#if CAP_GP
addsaver(gp::param.first, "goldberg-x", gp::param.first);
addsaver(gp::param.second, "goldberg-y", gp::param.second);
#endif
addsaver(nohud, "no-hud", false);
addsaver(nofps, "no-fps", false);
#if CAP_IRR
addsaver(irr::density, "irregular-density", 2);
addsaver(irr::cellcount, "irregular-cellcount", 150);
addsaver(irr::quality, "irregular-quality", .2);
addsaver(irr::place_attempts, "irregular-place", 10);
addsaver(irr::rearrange_max_attempts, "irregular-rearrange-max", 50);
addsaver(irr::rearrange_less, "irregular-rearrangeless", 10);
#endif
addsaver(vid.linequality, "line quality", 0);
@ -319,8 +323,10 @@ void initConfig() {
addsaver(anims::circle_radius, "animation circle radius");
addsaver(anims::circle_spins, "animation circle spins");
#if CAP_CRYSTAL
addsaver(crystal::compass_probability, "compass-probability");
addsaver(crystal::view_coordinates, "crystal-coordinates");
#endif
#if CAP_SHOT
addsaver(shot::shotx, "shotx");
@ -1610,10 +1616,12 @@ void show_color_dialog() {
dialog::add_action([] () { pushScreen([] () { edit_color_table(distcolors); });});
}
#if CAP_CRYSTAL
if(geometry == gCrystal && cheater) {
dialog::addItem(XLAT("crystal coordinate colors"), 'C');
dialog::add_action([] () { crystal::view_coordinates = true; pushScreen([] () { edit_color_table(crystal::coordcolors); });});
}
#endif
dialog::addInfo(XLAT("colors of some game objects can be edited by clicking them."));
@ -1962,7 +1970,9 @@ unordered_map<string, ld&> params = {
{"sang", conformal::spiral_angle},
{"spiralx", conformal::spiral_x},
{"spiraly", conformal::spiral_y},
#if CAP_CRYSTAL
{"cprob", crystal::compass_probability},
#endif
#if CAP_SHOT
{"gamma", shot::gamma},
{"fade", shot::fade},

View File

@ -5,7 +5,7 @@
namespace hr {
namespace crystal {
#if CAP_CRYSTAL
// Crystal can be bitruncated either by changing variation to bitruncated.
// In case of the 4D Crystal, the standard HyperRogue bitruncation becomes
// confused by having both the original and new vertices of degree 8.
@ -1258,7 +1258,7 @@ void may_place_compass(cell *c) {
if(hrandf() < compass_probability)
c->item = itCompass;
}
#endif
}
}

View File

@ -391,8 +391,10 @@ struct debugScreen {
dialog::addSelItem("pathdist", its(what->pathdist), 0);
dialog::addSelItem("celldistAlt", eubinary ? its(celldistAlt(what)) : "--", 0);
dialog::addSelItem("temporary", its(what->listindex), 0);
#if CAP_GP
if(GOLDBERG)
dialog::addSelItem("whirl", sprint(gp::get_local_info(what).relative), 0);
#endif
#if CAP_RACING
if(racing::on) racing::add_debug(what);
#endif
@ -404,8 +406,10 @@ struct debugScreen {
"wall parameter");
});
dialog::addSelItem("item", dnameof(what->item), 0);
#if CAP_ARCM
if(archimedean)
dialog::addSelItem("ID", its(arcm::id_of(what->master)), 0);
#endif
dialog::addBreak(50);
dialog::addSelItem("monster", dnameof2(what->monst, what->mondir), 'm');
dialog::add_action([what] () {

View File

@ -816,6 +816,7 @@ int expansion_readArgs() {
printf(", valid from %d to %d\n", expansion.valid_from, expansion.tested_to);
}
}
#if CAP_GP
else if(argis("-csolve_tab")) {
for(eGeometry geo: {gNormal, gOctagon, g45, g46, g47}) {
set_geometry(geo);
@ -836,6 +837,7 @@ int expansion_readArgs() {
}
}
}
#endif
else if(argis("-expansion")) {
cheat(); viewdists = true;
@ -862,12 +864,21 @@ expansion_analyzer expansion;
int sibling_limit = 0;
void set_sibling_limit() {
if(IRREGULAR) sibling_limit = 3;
if(0) ;
#if CAP_IRR
else if(IRREGULAR) sibling_limit = 3;
#endif
#if CAP_BT
else if(binarytiling) sibling_limit = 3;
#endif
#if CAP_GP
else {
auto p = gp::univ_param();
sibling_limit = 2 * p.first + p.second;
}
#else
else sibling_limit = PURE ? 2 : 3;
#endif
}
int celldist0(cell *c) {

View File

@ -196,6 +196,7 @@ void bshape2(hpcshape& sh, PPR prio, int shapeid, matrixlist& m) {
hpcpush(hpc[last->s]);
}
#if CAP_BT
void horopoint(ld y, ld x) {
hpcpush(get_horopoint(y, x));
}
@ -213,12 +214,14 @@ void horoline(ld y, ld x1, ld x2, cell &fc, int c) {
for(int a=0; a<=16; a++)
horopoint(y, x1 + (x2-x1) * a / 16., fc, c);
}
#endif
void bshape_regular(floorshape &fsh, int id, int sides, int shift, ld size) {
fsh.b.resize(2);
fsh.shadow.resize(2);
#if CAP_BT
if(binarytiling) {
bshape(fsh.b[id], fsh.prio);
@ -251,6 +254,7 @@ void bshape_regular(floorshape &fsh, int id, int sides, int shift, ld size) {
return;
}
#endif
bshape(fsh.b[id], fsh.prio);
for(int t=0; t<=sides; t++)
@ -269,7 +273,9 @@ void bshape_regular(floorshape &fsh, int id, int sides, int shift, ld size) {
}
}
#if CAP_IRR
namespace irr { void generate_floorshapes(); }
#endif
template<class T> void sizeto(T& t, int n) {
if(isize(t) <= n) t.resize(n+1);
@ -471,7 +477,9 @@ void generate_floorshapes_for(int id, cell *c, int siid, int sidir) {
void generate_floorshapes() {
if(IRREGULAR) {
if(0);
#if CAP_IRR
else if(IRREGULAR) {
printf("generating irregular floorshapes...\n");
cell model;
@ -489,9 +497,11 @@ void generate_floorshapes() {
printf("done\n");
}
#endif
else if(GOLDBERG) { /* will be generated on the fly */ }
#if CAP_ARCM
else if(archimedean) {
heptagon master;
cell model;
@ -511,6 +521,7 @@ void generate_floorshapes() {
generate_floorshapes_for(i, &model, 0, 0);
}
}
#endif
else {
cell model;
@ -519,6 +530,7 @@ void generate_floorshapes() {
}
}
#if CAP_GP
namespace gp {
int pshid[3][8][32][32][8];
int nextid;
@ -575,6 +587,7 @@ namespace gp {
return id;
}
}
#endif
qfloorinfo qfi;
@ -611,10 +624,13 @@ void set_floor(const transmatrix& spin, hpcshape& sh) {
void draw_shapevec(cell *c, const transmatrix& V, const vector<hpcshape> &shv, color_t col, PPR prio = PPR::DEFAULT) {
if(!c) queuepolyat(V, shv[0], col, prio);
#if CAP_GP
else if(GOLDBERG) {
int id = gp::get_plainshape_id(c);
queuepolyat(V, shv[id], col, prio);
}
#endif
#if CAP_IRR
else if(IRREGULAR) {
int id = irr::cellindex[c];
if(id < 0 || id >= isize(shv)) {
@ -622,9 +638,12 @@ void draw_shapevec(cell *c, const transmatrix& V, const vector<hpcshape> &shv, c
}
queuepolyat(V, shv[id], col, prio);
}
#endif
#if CAP_ARCM
else if(archimedean) {
queuepolyat(V, shv[arcm::id_of(c->master)], col, prio);
}
#endif
else if((euclid || GOLDBERG) && ishex1(c))
queuepolyat(V * pispin, shv[0], col, prio);
else if(!(S7&1) && PURE) {
@ -697,5 +716,5 @@ auto floor_hook =
else return 1;
});
#endif
#endif
}

View File

@ -7264,12 +7264,14 @@ void knightFlavorMessage(cell *c2) {
else if(msgid == 2 && !tooeasy) {
addMessage(XLAT("\"The Holy Grail is in the center of the Round Table.\""));
}
#if CAP_CRYSTAL
else if(msgid == 3 && geometry == gCrystal) {
if(crystal::pure())
addMessage(XLAT("\"Each piece of the Round Table is exactly %1 steps away from the Holy Grail.\"", its(roundTableRadius(c2))));
else
addMessage(XLAT("\"According to Merlin, the Round Table is a perfect Euclidean sphere in %1 dimensions.\"", its(ginf[gCrystal].sides/2)));
}
#endif
else if(msgid == 3 && !peace::on && in_full_game()) {
addMessage(XLAT("\"I enjoy watching the hyperbug battles.\""));
}
@ -7287,8 +7289,11 @@ void knightFlavorMessage(cell *c2) {
}
else if(msgid == 8 && sizes_known() && !tactic::on) {
string s = "";
if(geometry == gCrystal)
if(0) ;
#if CAP_CRYSTAL
else if(geometry == gCrystal)
s = crystal::get_table_boundary();
#endif
else if(!quotient)
s = expansion.get_descendants(rad).get_str(100);
if(s == "") { msgid++; goto retry; }
@ -7296,8 +7301,11 @@ void knightFlavorMessage(cell *c2) {
}
else if(msgid == 9 && sizes_known() && !tactic::on) {
string s = "";
if(geometry == gCrystal)
if(0);
#if CAP_CRYSTAL
else if(geometry == gCrystal)
s = crystal::get_table_volume();
#endif
else if(!quotient)
s = expansion.get_descendants(rad-1, expansion.diskid).get_str(100);
if(s == "") { msgid++; goto retry; }

View File

@ -390,14 +390,21 @@ void ge_select_tiling(const vector<eGeometry>& lst) {
for(eGeometry i: lst) {
bool on = geometry == i;
dynamicval<eGeometry> cg(geometry, eGeometry(i));
if(archimedean && !CAP_ARCM) continue;
if(geometry == gCrystal && !CAP_CRYSTAL) continue;
dialog::addBoolItem(XLAT(ginf[i].menu_displayed_name), on, letter++);
dialog::lastItem().value += validclasses[land_validity(specialland).quality_level];
dialog::add_action([i] {
eGeometry targetgeometry = eGeometry(i);
if(targetgeometry == gCrystal)
if(0) ;
#if CAP_CRYSTAL
else if(targetgeometry == gCrystal)
pushScreen(crystal::show);
#endif
#if CAP_ARCM
else if(targetgeometry == gArchimedean)
pushScreen(arcm::show);
#endif
else dialog::do_if_confirmed([targetgeometry] () {
set_geometry(targetgeometry);
start_game();
@ -449,11 +456,13 @@ void showEuclideanMenu() {
int nom = (BITRUNCATED ? tv+ts : tv) * 4;
int denom = (2*ts + 2*tv - ts * tv);
#if CAP_GP
if(GOLDBERG && S3)
nom = 2 * (2*tv + ts * (gp::area-1));
if(GOLDBERG && S3 == 4)
nom = 2 * (2*tv + 2 * ts * (gp::area-1));
#endif
int worldsize;
@ -520,7 +529,9 @@ void showEuclideanMenu() {
worldsize = -worldsize;
string spf = its(ts);
if(archimedean) {
if(0) ;
#if CAP_ARCM
else if(archimedean) {
spf = "";
for(int i: arcm::current.faces) {
if(spf != "") spf += ",";
@ -529,14 +540,20 @@ void showEuclideanMenu() {
if(BITRUNCATED) spf = "[" + spf + "]," + its(arcm::current.N * 2) + "," + its(arcm::current.N * 2);
if(DUAL) spf = its(arcm::current.N) + "^[" + spf + "]";
}
#endif
#if CAP_BT
else if(binarytiling)
spf = "6,[6,7],7";
#endif
else if(BITRUNCATED && !euclid6)
spf = spf + "," + its(S6) + "," + its(S6);
#if CAP_IRR
else if(IRREGULAR && irr::bitruncations_performed)
spf = "[4..8],6,6";
else if(IRREGULAR)
spf = "[4..8]^3";
#endif
#if CAP_GP
else if(GOLDBERG && S3 == 4 && gp::param == gp::loc(1, 1))
spf = spf + ",4," + spf + ",4";
else if(GOLDBERG && S3 == 4 && gp::param == gp::loc(2, 0))
@ -545,6 +562,7 @@ void showEuclideanMenu() {
spf = "[" + spf + ",4],4,4,4";
else if(GOLDBERG && S3 == 3)
spf = "[" + spf + ",6],6,6";
#endif
else {
string spf0 = spf;
for(int z=1; z<S3; z++) spf = spf + "," + spf0;
@ -559,12 +577,14 @@ void showEuclideanMenu() {
dialog::add_action([] { pushScreen([] { ge_select_tiling(quotientlist); }); });
#if CAP_IRR
if(hyperbolic && IRREGULAR) {
nom = isize(irr::cells);
// both Klein Quartic and Bolza2 are double the Zebra quotiennt
denom = -2;
if(!quotient) worldsize = nom / denom;
}
#endif
if(ts == 6 && tv == 3)
dialog::addSelItem(XLAT("variations"), XLAT("does not matter"), 'v');
@ -584,13 +604,17 @@ void showEuclideanMenu() {
dialog::addSelItem(XLAT("variations"), gp::operation_name(), 'v');
dialog::add_action([] {
if(euclid6) ;
#if CAP_ARCM
else if(archimedean) arcm::next_variation();
else if(euclid4) dialog::do_if_confirmed([] {
#endif
else if(euclid4 || !CAP_GP) dialog::do_if_confirmed([] {
set_variation(PURE ? eVariation::bitruncated : eVariation::pure);
start_game();
});
#if CAP_GP
else // if(S3 == 3)
gp::configure();
#endif
});
}
@ -599,10 +623,15 @@ void showEuclideanMenu() {
if(euwrap || geometry == gFieldQuotient) {
dialog::addItem(XLAT("advanced parameters"), '4');
dialog::add_action([] {
if(archimedean)
if(0);
#if CAP_ARCM
else if(archimedean)
pushScreen(arcm::show);
#endif
#if CAP_CRYSTAL
else if(geometry == gCrystal)
pushScreen(crystal::show);
#endif
else if(euwrap)
prepare_torusconfig(),
pushScreen(showTorusConfig);
@ -644,10 +673,16 @@ void showEuclideanMenu() {
dialog::addSelItem(XLAT("faces per vertex"), spf, 0);
dialog::addSelItem(XLAT("size of the world"),
#if CAP_BT
binarytiling ? fts4(8 * M_PI * sqrt(2) * log(2) / vid.binary_width) + " exp(∞)" :
#endif
#if CAP_ARCM
archimedean ? arcm::current.world_size() :
(archimedean && sphere) ? its(isize(currentmap->allcells())) :
#endif
#if CAP_CRYSTAL
geometry == gCrystal ? "∞^" + its(ts/2) :
#endif
worldsize < 0 ? (nom%denom ? its(nom)+"/"+its(denom) : its(-worldsize)) + " exp(∞)":
(euwrap && !fulltorus) ? "" :
worldsize == 0 ? "∞²" :
@ -752,12 +787,14 @@ int read_geom_args() {
shift();
set_geometry((eGeometry) argi());
}
#if CAP_GP
else if(argis("-gp")) {
PHASEFROM(2);
shift(); gp::param.first = argi();
shift(); gp::param.second = argi();
set_variation(eVariation::goldberg);
}
#endif
else if(argis("-fi")) {
fieldpattern::info();
exit(0);

View File

@ -160,14 +160,20 @@ void precalc() {
base_distlimit = ginf[geometry].distlimit[!BITRUNCATED];
#if CAP_GP
gp::compute_geometry();
#endif
#if CAP_IRR
irr::compute_geometry();
#endif
#if CAP_ARCM
if(archimedean) {
arcm::current.compute_geometry();
crossf = hcrossf7 * arcm::current.scale();
hexvdist = arcm::current.scale() * .5;
rhexf = arcm::current.scale() * .5;
}
#endif
if(binarytiling) hexvdist = rhexf = 1, tessf = 1, scalefactor = 1, crossf = hcrossf7;
scalefactor = crossf / hcrossf7;
@ -264,8 +270,10 @@ namespace geom3 {
string invalid;
ld actual_wall_height() {
#if CAP_GP
if(GOLDBERG && gp_autoscale_heights)
return wall_height * min<ld>(4 / hypot2(gp::next), 1);
#endif
return wall_height;
}

View File

@ -20,11 +20,15 @@ void fixelliptic(hyperpoint& h) {
}
transmatrix master_relative(cell *c, bool get_inverse) {
if(IRREGULAR) {
if(0) ;
#if CAP_IRR
else if(IRREGULAR) {
int id = irr::cellindex[c];
ld alpha = 2 * M_PI / S7 * irr::periodmap[c->master].base.spin;
return get_inverse ? irr::cells[id].rpusher * spin(-alpha-master_to_c7_angle()): spin(alpha + master_to_c7_angle()) * irr::cells[id].pusher;
}
#endif
#if CAP_GP
else if(GOLDBERG) {
if(c == c->master->c7) {
return spin((get_inverse?-1:1) * master_to_c7_angle());
@ -36,6 +40,7 @@ transmatrix master_relative(cell *c, bool get_inverse) {
return T;
}
}
#endif
else if(BITRUNCATED && !euclid) {
for(int d=0; d<S7; d++) if(c->master->c7->move(d) == c)
return (get_inverse?invhexmove:hexmove)[d];
@ -51,20 +56,26 @@ transmatrix calc_relative_matrix(cell *c2, cell *c1, int direction_hint) {
// target, source, direction from source to target
#if CAP_GP
namespace gp { extern gp::local_info draw_li; }
#endif
transmatrix calc_relative_matrix(cell *c2, cell *c1, const hyperpoint& point_hint) {
if(sphere_narcm) {
if(!gmatrix0.count(c2) || !gmatrix0.count(c1)) {
printf("building gmatrix0 (size=%d)\n", isize(gmatrix0));
#if CAP_GP
auto bak = gp::draw_li;
#endif
swap(gmatrix, gmatrix0);
just_gmatrix = true;
drawStandard();
just_gmatrix = false;
swap(gmatrix, gmatrix0);
#if CAP_GP
gp::draw_li = bak;
#endif
}
if(gmatrix0.count(c2) && gmatrix0.count(c1)) {
transmatrix T = inverse(gmatrix0[c1]) * gmatrix0[c2];
@ -78,8 +89,12 @@ transmatrix calc_relative_matrix(cell *c2, cell *c1, const hyperpoint& point_hin
}
}
#if CAP_BT
if(binarytiling) return binary::relative_matrix(c2->master, c1->master);
#endif
#if CAP_ARCM
if(archimedean) return arcm::relative_matrix(c2->master, c1->master);
#endif
if(euwrap) {
transmatrix t = Id;
@ -157,6 +172,7 @@ transmatrix calc_relative_matrix(cell *c2, cell *c1, const hyperpoint& point_hin
where = heptmove[sp] * spin(2*M_PI*bestd/S7) * where;
h2 = h2->move(bestd);
}
#if CAP_CRYSTAL
else if(geometry == gCrystal) {
for(int d3=0; d3<S7; d3++) {
auto h3 = h2->cmove(d3);
@ -172,6 +188,7 @@ transmatrix calc_relative_matrix(cell *c2, cell *c1, const hyperpoint& point_hin
bestv.pop_back();
if(bestv.empty()) hbdist.erase(hbdist.begin());
}
#endif
else if(h1->distance < h2->distance) {
int sp = h2->c.spin(0);
h2 = h2->move(0);
@ -215,10 +232,13 @@ transmatrix calc_relative_matrix_help(cell *c, heptagon *h1) {
transmatrix gm = Id;
heptagon *h2 = c->master;
transmatrix where = Id;
if(GOLDBERG && c != c->master->c7) {
if(0);
#if CAP_GP
else if(GOLDBERG && c != c->master->c7) {
auto li = gp::get_local_info(c);
where = gp::Tf[li.last_dir][li.relative.first&31][li.relative.second&31][fix6(li.total_dir)];
}
#endif
else if(BITRUNCATED) for(int d=0; d<S7; d++) if(h2->c7->move(d) == c)
where = hexmove[d];
// always add to last!
@ -415,16 +435,23 @@ hyperpoint randomPointIn(int t) {
}
}
#if CAP_BT
hyperpoint get_horopoint(ld y, ld x) {
return xpush(-y) * binary::parabolic(x) * C0;
}
#endif
hyperpoint get_corner_position(cell *c, int cid, ld cf) {
#if CAP_GP
if(GOLDBERG) return gp::get_corner_position(c, cid, cf);
#endif
#if CAP_IRR
if(IRREGULAR) {
auto& vs = irr::cells[irr::cellindex[c]];
return mid_at_actual(vs.vertices[cid], 3/cf);
}
#endif
#if CAP_BT
if(binarytiling) {
ld yx = log(2) / 2;
ld yy = yx;
@ -439,6 +466,8 @@ hyperpoint get_corner_position(cell *c, int cid, ld cf) {
vertices[6] = get_horopoint(-yy, 0);
return mid_at_actual(vertices[cid], 3/cf);
}
#endif
#if CAP_ARCM
if(archimedean) {
auto &ac = arcm::current;
if(PURE) {
@ -458,6 +487,7 @@ hyperpoint get_corner_position(cell *c, int cid, ld cf) {
return xspinpush0(-t0.first, t0.second * 3 / cf * (ac.real_faces == 0 ? 0.999 : 1));
}
}
#endif
if(PURE) {
return ddspin(c,cid,M_PI/S7) * xpush0(hcrossf * 3 / cf);
}
@ -478,11 +508,14 @@ hyperpoint nearcorner(cell *c, int i) {
if(elliptic && cwm[2][2] < 0) cwm = centralsym * cwm;
return cwm * C0;
}
#if CAP_IRR
if(IRREGULAR) {
auto& vs = irr::cells[irr::cellindex[c]];
hyperpoint nc = vs.jpoints[vs.neid[i]];
return mid_at(C0, nc, .94);
}
#endif
#if CAP_ARCM
if(archimedean) {
if(PURE) {
auto &ac = arcm::current;
@ -502,6 +535,8 @@ hyperpoint nearcorner(cell *c, int i) {
return xspinpush0(-t.first, t.second);
}
}
#endif
#if CAP_BT
if(binarytiling) {
ld yx = log(2) / 2;
ld yy = yx;
@ -519,11 +554,13 @@ hyperpoint nearcorner(cell *c, int i) {
neis[5] = get_horopoint(-yy*2, 0);
return neis[i];
}
#endif
double d = cellgfxdist(c, i);
return ddspin(c, i) * xpush0(d);
}
hyperpoint farcorner(cell *c, int i, int which) {
#if CAP_GP
if(GOLDBERG) {
cellwalker cw(c, i);
int hint = cw.spin;
@ -537,6 +574,8 @@ hyperpoint farcorner(cell *c, int i, int which) {
if(which == 1)
return cwm * get_corner_position(li1, (cw-1).spin);
}
#endif
#if CAP_IRR
if(IRREGULAR) {
auto& vs = irr::cells[irr::cellindex[c]];
int neid = vs.neid[i];
@ -548,8 +587,12 @@ hyperpoint farcorner(cell *c, int i, int which) {
if(which == 0) return rel * vs2.vertices[(spin+2)%cor2];
if(which == 1) return rel * vs2.vertices[(spin+cor2-1)%cor2];
}
#endif
#if CAP_BT
if(binarytiling)
return nearcorner(c, (i+which) % c->type); // lazy
#endif
#if CAP_ARCM
if(archimedean) {
if(PURE) {
auto &ac = arcm::current;
@ -574,6 +617,7 @@ hyperpoint farcorner(cell *c, int i, int which) {
return spin(-t1.first) * xpush(t1.second) * spin(M_PI + t2.first) * get_corner_position(&cx, which ? -mul : 2*mul);
}
}
#endif
return cellrelmatrix(c, i) * get_corner_position(c->move(i), (cellwalker(c, i) + wstep + (which?-1:2)).spin);
}
@ -586,8 +630,12 @@ hyperpoint midcorner(cell *c, int i, ld v) {
hyperpoint get_warp_corner(cell *c, int cid) {
// midcorner(c, cid, .5) but sometimes easier versions exist
#if CAP_GP
if(GOLDBERG) return gp::get_corner_position(c, cid, 2);
#endif
#if CAP_IRR || CAP_ARCM
if(IRREGULAR || archimedean) return midcorner(c, cid, .5);
#endif
return ddspin(c,cid,M_PI/S7) * xpush0(tessf/2);
}

View File

@ -1,14 +1,4 @@
namespace hr { namespace gp {
loc param(1, 0);
hyperpoint next;
ld alpha;
int area;
int length(loc p) {
return eudist(p.first, p.second);
}
loc operator+(loc e1, loc e2) {
return make_pair(e1.first+e2.first, e1.second+e2.second);
}
@ -26,13 +16,6 @@ namespace hr { namespace gp {
return loc(e1.first*i, e1.second*i);
}
struct goldberg_mapping_t {
cellwalker cw;
signed char rdir;
signed char mindir;
loc start;
};
loc eudir(int d) {
if(S3 == 3) {
d %= 6; if (d < 0) d += 6;
@ -55,6 +38,24 @@ namespace hr { namespace gp {
}
}
#if CAP_GP
loc param(1, 0);
hyperpoint next;
ld alpha;
int area;
int length(loc p) {
return eudist(p.first, p.second);
}
struct goldberg_mapping_t {
cellwalker cw;
signed char rdir;
signed char mindir;
loc start;
};
int fixg6(int x) { return (x + MODFIXER) % SG6; }
#define WHD(x) // x
@ -609,31 +610,6 @@ namespace hr { namespace gp {
return v;
}
string operation_name() {
if(IRREGULAR)
return XLAT("irregular");
else if(DUAL)
return XLAT("dual");
else if(PURE)
return XLAT("pure");
else if(BITRUNCATED)
return XLAT("bitruncated");
else if(param == loc(1, 0))
return XLAT("pure");
else if(param == loc(1, 1) && S3 == 3)
return XLAT("bitruncated");
else if(param == loc(1, 1) && S3 == 4)
return XLAT("rectified");
else if(param == loc(2, 0))
return S3 == 3 ? XLAT("chamfered") : XLAT("expanded");
else if(param == loc(3, 0) && S3 == 3)
return XLAT("2x bitruncated");
else {
auto p = human_representation(param);
return "GP(" + its(p.first) + "," + its(p.second) + ")";
}
}
void whirl_set(loc xy) {
xy = internal_representation(xy);
if(xy.second && xy.second != xy.first && nonorientable) {
@ -860,20 +836,6 @@ namespace hr { namespace gp {
return corners * loctoh_ort(li.relative);
}
array<heptagon*, 3> get_masters(cell *c) {
if(GOLDBERG) {
auto li = get_local_info(c);
be_in_triangle(li);
auto cm = c->master;
int i = li.last_dir;
return make_array(cm, createStep(cm, i), createStep(cm, fix7(i+1)));
}
else if(IRREGULAR)
return irr::get_masters(c);
else
return make_array(c->move(0)->master, c->move(2)->master, c->move(4)->master);
}
int compute_dist(cell *c, int master_function(cell*)) {
auto li = get_local_info(c);
be_in_triangle(li);
@ -908,5 +870,61 @@ namespace hr { namespace gp {
int dist_1() {
return dist_3() - dist_2();
}
#else
int dist_1() { return 1; }
int dist_2() { return BITRUNCATED ? 2 : 1; }
int dist_3() { return BITRUNCATED ? 3 : 2; }
#endif
array<heptagon*, 3> get_masters(cell *c) {
if(0);
#if CAP_GP
else if(GOLDBERG) {
auto li = get_local_info(c);
be_in_triangle(li);
auto cm = c->master;
int i = li.last_dir;
return make_array(cm, createStep(cm, i), createStep(cm, fix7(i+1)));
}
#endif
#if CAP_IRR
else if(IRREGULAR)
return irr::get_masters(c);
#endif
else
return make_array(c->move(0)->master, c->move(2)->master, c->move(4)->master);
}
string operation_name() {
if(0);
#if CAP_IRR
else if(IRREGULAR)
return XLAT("irregular");
#endif
else if(DUAL)
return XLAT("dual");
else if(PURE)
return XLAT("pure");
else if(BITRUNCATED)
return XLAT("bitruncated");
#if CAP_GP
else if(param == loc(1, 0))
return XLAT("pure");
else if(param == loc(1, 1) && S3 == 3)
return XLAT("bitruncated");
else if(param == loc(1, 1) && S3 == 4)
return XLAT("rectified");
else if(param == loc(2, 0))
return S3 == 3 ? XLAT("chamfered") : XLAT("expanded");
else if(param == loc(3, 0) && S3 == 3)
return XLAT("2x bitruncated");
else {
auto p = human_representation(param);
return "GP(" + its(p.first) + "," + its(p.second) + ")";
}
#else
else return "UNSUPPORTED";
#endif
}
}}

View File

@ -180,7 +180,9 @@ void drawSpeed(const transmatrix& V) {
}
int ctof(cell *c) {
#if CAP_IRR
if(IRREGULAR) return irr::ctof(c);
#endif
if(PURE) return 1;
// if(euclid) return 0;
if(!c) return 1;
@ -257,7 +259,9 @@ void drawLightning(const transmatrix& V) {
}
ld displayspin(cell *c, int d) {
if(archimedean) {
if(0);
#if CAP_ARCM
else if(archimedean) {
if(PURE) {
auto& t1 = arcm::current.get_triangle(c->master, d-1);
return -(t1.first + M_PI / c->type);
@ -271,6 +275,8 @@ ld displayspin(cell *c, int d) {
return -t1.first;
}
}
#endif
#if CAP_IRR
else if(IRREGULAR) {
auto id = irr::cellindex[c];
auto& vs = irr::cells[id];
@ -278,11 +284,14 @@ ld displayspin(cell *c, int d) {
auto& p = vs.jpoints[vs.neid[d]];
return -atan2(p[1], p[0]);
}
#endif
#if CAP_BT
else if(binarytiling) {
if(d == NODIR) return 0;
if(d == c->type-1) d++;
return -(d+2)*M_PI/4;
}
#endif
else if(masterless)
return - d * 2 * M_PI / c->type;
else
@ -675,12 +684,15 @@ bool drawItemType(eItem it, cell *c, const transmatrix& V, int icol, int pticks,
else if(it == itCompass) {
transmatrix V2;
#if CAP_CRYSTAL
if(geometry == gCrystal) {
if(crystal::compass_probability <= 0) return true;
if(cwt.at->land == laCamelot && celldistAltRelative(cwt.at) < 0) crystal::used_compass_inside = true;
V2 = V * spin(crystal::compass_angle() + M_PI);
}
else {
else
#endif
if(1) {
cell *c1 = c ? findcompass(c) : NULL;
if(c1) {
transmatrix P = ggmatrix(c1);
@ -3277,14 +3289,22 @@ bool noAdjacentChasms(cell *c) {
// does the current geometry allow nice duals
bool has_nice_dual() {
#if CAP_IRR
if(IRREGULAR) return irr::bitruncations_performed > 0;
#endif
#if CAP_ARCM
if(archimedean) return geosupport_football() >= 2;
#endif
if(binarytiling) return false;
if(BITRUNCATED) return true;
if(a4) return false;
if((S7 & 1) == 0) return true;
if(PURE) return false;
#if CAP_GP
return (gp::param.first + gp::param.second * 2) % 3 == 0;
#else
return false;
#endif
}
// does the current geometry allow nice duals
@ -3381,8 +3401,10 @@ bool placeSidewall(cell *c, int i, int sidepar, const transmatrix& V, color_t co
transmatrix V2 = V * ddspin(c, i);
if(binarytiling || archimedean || NONSTDVAR) {
#if CAP_ARCM
if(archimedean && !PURE)
i = (i + arcm::parent_index_of(c->master)/DUALMUL + MODFIXER) % c->type;
#endif
draw_shapevec(c, V2, qfi.fshape->gpside[sidepar][i], col, prio);
return false;
}
@ -5029,7 +5051,9 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
int prec = sphere ? 3 : 1;
prec += vid.linequality;
if(binarytiling) {
if(0);
#if CAP_BT
else if(binarytiling) {
ld yx = log(2) / 2;
ld yy = yx;
ld xx = 1 / sqrt(2)/2;
@ -5044,6 +5068,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
horizontal(yy, xx, -xx, 8, binary::bd_up);
horizontal(yy, -xx, -2*xx, 4, binary::bd_up_left);
}
#endif
else if(isWarped(c) && has_nice_dual()) {
if(pseudohept(c)) for(int t=0; t<c->type; t++)
queueline(V * get_warp_corner(c, t%c->type),
@ -5058,18 +5083,23 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
gridcolor(c, c->move(t)), prec);
}
}
#endif
if(!euclid) {
bool usethis = false;
double spd = 1;
int side = 0;
if(binarytiling && conformal::do_rotate >= 2) {
if(0);
#if CAP_BT
else if(binarytiling && conformal::do_rotate >= 2) {
if(!straightDownSeek || c->master->distance < straightDownSeek->master->distance) {
usethis = true;
spd = 1;
}
}
#endif
else if(isGravityLand(cwt.at->land) && cwt.at->land != laMountain) {
if(cwt.at->land == laDungeon) side = 2;
@ -5560,10 +5590,14 @@ void drawthemap() {
profile_start(1);
if(masterless)
drawEuclidean();
#if CAP_BT
else if(binarytiling)
binary::draw();
#endif
#if CAP_ARCM
else if(archimedean)
arcm::draw();
#endif
else
drawStandard();
drawWormSegments();

View File

@ -243,9 +243,11 @@ string generateHelpForItem(eItem it) {
string help = helptitle(XLATN(iinf[it].name), iinf[it].color);
#if CAP_CRYSTAL
if(it == itCompass && geometry == gCrystal)
help += crystal::compass_help();
else
#endif
help += XLAT(iinf[it].help);
if(it == itSavedPrincess || it == itOrbLove) if(!inv::on)
@ -721,6 +723,7 @@ string generateHelpForLand(eLand l) {
);
}
#if CAP_CRYSTAL
if(l == laCamelot && geometry == gCrystal) {
if(!crystal::used_compass_inside) s += XLAT("\nSpecial conduct (still valid)\n");
else s += XLAT("\nSpecial conduct failed:\n");
@ -731,7 +734,7 @@ string generateHelpForLand(eLand l) {
s += XLAT("Crystal Camelot is an octahedron in 'pure' 3D crystal geometry (and a similar polytope in other pure crystals), "
"and an Euclidean ball in bitruncated/Goldberg crystals.");
}
#endif
auto lv = land_validity(l);
if(lv.flags & lv::display_in_help)
@ -816,6 +819,7 @@ void describeMouseover() {
out += " (" + turnstring(t) + XLAT(" to submerge") + ")";
}
}
#if CAP_FIELD
else if(c->land == laVolcano) {
int id = lavatide(c, -1)/4;
if(id < 96/4)
@ -830,6 +834,7 @@ void describeMouseover() {
if(c == cwt.at) windtotal = 0;
out += " [" + its(windtotal) + "]";
}
#endif
if(c->land == laTortoise && tortoise::seek()) out += " " + tortoise::measure(getBits(c));

View File

@ -74,15 +74,19 @@ heptagon *buildHeptagon(heptagon *parent, int d, hstate s, int pard = 0, int fix
heptagon *h = buildHeptagon1(tailored_alloc<heptagon> (S7), parent, d, s, pard, fixdistance);
if(binarytiling || archimedean) return h;
if(parent->c7) {
#if CAP_IRR
if(IRREGULAR)
irr::link_next(parent, d);
else
#endif
h->c7 = newCell(S7, h);
h->rval0 = h->rval1 = 0;
h->emeraldval = emerald_heptagon(parent->emeraldval, d);
h->zebraval = zebra_heptagon(parent->zebraval, d);
#if CAP_FIELD
if(&currfp != &fieldpattern::fp_invalid)
h->fieldval = currfp.connections[fieldpattern::btspin(parent->fieldval, d)];
#endif
if(a38)
h->fiftyval = fifty_38(parent->fiftyval, d);
else if(parent->s == hsOrigin)
@ -125,6 +129,7 @@ heptagon *buildHeptagon(heptagon *parent, int d, hstate s, int pard = 0, int fix
);
}
else if(parent->s == hsOrigin) h->distance = parent->distance + gp::dist_2();
#if CAP_GP
else if(S3 == 4 && GOLDBERG && h->c.spin(0) == S7-2 && h->move(0)->c.spin(0) >= S7-2 && h->move(0)->move(0)->s != hsOrigin) {
heptspin hs(h, 0);
hs += wstep;
@ -148,26 +153,28 @@ heptagon *buildHeptagon(heptagon *parent, int d, hstate s, int pard = 0, int fix
else if(S3 == 4 && GOLDBERG && h->c.spin(0) >= 2 && h->c.spin(0) <= S7-2) {
h->distance = parent->distance + gp::dist_2();
}
#endif
else if(h->c.spin(0) == S7-2) {
if(!GOLDBERG)
h->distance = parent->distance + gp::dist_1();
else {
#if CAP_GP
if(GOLDBERG) {
int d0 = parent->distance;
int d1 = createStep(parent, S7-1)->distance;
int dm = createStep(parent, 0)->distance;
h->distance = gp::solve_triangle(dm, d0, d1, gp::operator* (gp::param, gp::loc(1,1)));
}
} else
#endif
h->distance = parent->distance + gp::dist_1();
}
else if(h->c.spin(0) == S7-3 && h->move(0)->s == hsB) {
if(!GOLDBERG) {
h->distance = createStep(h->move(0), (h->c.spin(0)+2)%S7)->distance + gp::dist_3();
}
else {
#if CAP_GP
if(GOLDBERG) {
int d0 = parent->distance;
int d1 = createStep(parent, S7-2)->distance;
int dm = createStep(parent, S7-1)->distance;
h->distance = gp::solve_triangle(dm, d0, d1, gp::operator* (gp::param, gp::loc(1,1)));
}
} else
#endif
h->distance = createStep(h->move(0), (h->c.spin(0)+2)%S7)->distance + gp::dist_3();
}
else if(h->c.spin(0) == S7-1 && S3 == 4 && GOLDBERG) {
h->distance = parent->distance + gp::dist_1();
@ -212,14 +219,20 @@ heptagon *createStep(heptagon *h, int d) {
d = h->c.fix(d);
if(!h->move(d))
callhooks(hooks_createStep, h, d);
#if CAP_CRYSTAL
if(!h->move(d) && geometry == gCrystal)
crystal::create_step(h, d);
#endif
#if CAP_BT
if(!h->move(d) && binarytiling)
return binary::createStep(h, d);
#endif
#if CAP_ARCM
if(!h->move(d) && archimedean) {
arcm::create_adjacent(h, d);
return h->move(d);
}
#endif
if(!h->move(0) && h->s != hsOrigin && !binarytiling && (geometry != gCrystal)) {
// cheating:
int pard=0;

41
hyper.h
View File

@ -156,7 +156,11 @@ void addMessage(string s, char spamtype = 0);
#define STDVAR (PURE || BITRUNCATED)
#define NONSTDVAR (!STDVAR)
#if CAP_ARCM
#define VALENCE (BITRUNCATED ? 3 : archimedean ? arcm::valence() : S3)
#else
#define VALENCE (BITRUNCATED ? 3 : S3)
#endif
#define NUMWITCH 7
@ -575,7 +579,12 @@ struct cell : gcell {
namespace arcm { int degree(heptagon *h); int valence(); }
int heptagon::degree() { if(archimedean) return arcm::degree(this); else return S7; }
int heptagon::degree() {
#if CAP_ARCM
if(archimedean) return arcm::degree(this); else
#endif
return S7;
}
typedef walker<heptagon> heptspin;
typedef walker<cell> cellwalker;
@ -2974,6 +2983,7 @@ struct hrmap_hyperbolic : hrmap {
};
namespace irr {
#if CAP_IRR
extern ld density;
extern ld quality;
extern int cellcount;
@ -2994,6 +3004,7 @@ namespace irr {
unsigned char density_code();
int celldist(cell *c, bool alts);
extern int bitruncations_requested, bitruncations_performed;
#endif
}
extern hrmap *currentmap;
@ -3549,22 +3560,23 @@ string XLAT(string x, stringpar p1, stringpar p2, stringpar p3, stringpar p4, st
namespace gp {
typedef pair<int, int> loc;
loc operator+(loc e1, loc e2);
loc operator-(loc e1, loc e2);
loc operator*(loc e1, loc e2);
extern loc eudir(int dir);
#if CAP_GP
void compute_geometry();
void extend_map(cell *c, int d);
extern loc param;
extern loc eudir(int dir);
extern int area;
extern string operation_name();
extern int pseudohept_val(cell *);
extern int last_dir(cell *c);
extern void configure();
extern ld alpha;
extern transmatrix Tf[MAX_EDGE][32][32][6];
loc operator+(loc e1, loc e2);
loc operator-(loc e1, loc e2);
loc operator*(loc e1, loc e2);
struct local_info {
int last_dir;
loc relative;
@ -3579,13 +3591,14 @@ namespace gp {
int compute_dist(cell *c, int master_function(cell*));
int dist_1(), dist_2(), dist_3();
int solve_triangle(int dmain, int d0, int d1, loc at);
array<heptagon*, 3> get_masters(cell *c);
hyperpoint get_master_coordinates(cell *c);
loc univ_param();
#endif
int dist_1(), dist_2(), dist_3();
array<heptagon*, 3> get_masters(cell *c);
extern string operation_name();
}
int get_sightrange();
@ -3927,7 +3940,9 @@ eOrbLandRelation getOLR(eItem it, eLand l);
struct plainshape;
void clear_plainshape(plainshape& gsh);
#if CAP_GP
void build_plainshape(plainshape& gsh, gp::local_info& li);
#endif
namespace gp {
void clear_plainshapes();
@ -4127,14 +4142,17 @@ bool saved_tortoise_on(cell *c);
#define PRING(i) for(double i=0; i<=S84+1e-6; i+= pow(.5, vid.linequality))
#define REVPRING(i) for(double i=S84; i>=-1e-6; i-=pow(.5, vid.linequality))
#if CAP_BT
void horopoint(ld y, ld x);
namespace binary {
heptagon *createStep(heptagon *parent, int d);
transmatrix parabolic(ld u);
}
#endif
namespace arcm {
#if CAP_ARCM
struct archimedean_tiling {
@ -4208,9 +4226,11 @@ namespace arcm {
void draw();
void create_adjacent(heptagon*, int);
int fix(heptagon *h, int spin);
#endif
}
namespace crystal {
#if CAP_CRYSTAL
static const int MAXDIM = 7;
typedef array<int, MAXDIM> coord;
static const coord c0 = {};
@ -4248,6 +4268,7 @@ namespace crystal {
void may_place_compass(cell *c);
void centerrug(ld aspd);
vector<cell*> build_shortest_path(cell *c1, cell *c2);
#endif
}
hyperpoint get_warp_corner(cell *c, int cid);

View File

@ -693,20 +693,35 @@ bool confusingGeometry() {
}
ld master_to_c7_angle() {
return (!BITRUNCATED && !binarytiling && !archimedean) ? M_PI + gp::alpha : 0;
#if CAP_GP
auto alpha = gp::alpha;
#else
auto alpha = 0;
#endif
return (!BITRUNCATED && !binarytiling && !archimedean) ? M_PI + alpha : 0;
}
transmatrix actualV(const heptspin& hs, const transmatrix& V) {
#if CAP_IRR
if(IRREGULAR)
return V * spin(M_PI + 2 * M_PI / S7 * (hs.spin + irr::periodmap[hs.at].base.spin));
#endif
#if CAP_ARCM
if(archimedean) return V * spin(-arcm::current.triangles[arcm::id_of(hs.at)][hs.spin].first);
#endif
#if CAP_BT
if(binarytiling) return V;
#endif
return (hs.spin || !BITRUNCATED) ? V * spin(hs.spin*2*M_PI/S7 + master_to_c7_angle()) : V;
}
transmatrix applyspin(const heptspin& hs, const transmatrix& V) {
#if CAP_BT
if(binarytiling) return V;
#endif
#if CAP_ARCM
if(archimedean) return V * spin(arcm::current.triangles[arcm::id_of(hs.at)][hs.spin].first);
#endif
return hs.spin ? V * spin(hs.spin*2*M_PI/S7) : V;
}
@ -748,6 +763,7 @@ bool in_smart_range(const transmatrix& T) {
y + 2 * max(y1, y2) > current_display->ytop;
}
#if CAP_GP
namespace gp {
/*
@ -807,6 +823,7 @@ void drawrec(cell *c, const transmatrix& V) {
return res;
}
}
#endif
vector<tuple<heptspin, hstate, transmatrix, ld> > drawn_cells;
@ -831,10 +848,15 @@ void drawStandard() {
bool draw = false;
if(GOLDBERG) {
if(0) ;
#if CAP_GP
else if(GOLDBERG) {
draw = gp::drawrec(c, actualV(hs, V1));
}
#endif
#if CAP_IRR
else if(IRREGULAR) {
auto& hi = irr::periodmap[hs.at];
transmatrix V0 = actualV(hs, V1);
@ -847,6 +869,7 @@ void drawStandard() {
drawcell(hi.subcells[i], V0 * irr::cells[vc[i]].pusher, 0, false);
}
}
#endif
else {
if(do_draw(c, V1)) {
@ -1000,8 +1023,10 @@ void spinEdge(ld aspd) {
void centerpc(ld aspd) {
#if CAP_CRYSTAL
if(geometry == gCrystal)
crystal::centerrug(aspd);
#endif
#if CAP_RACING
if(racing::on && !racing::standard_centering) {
@ -1069,12 +1094,21 @@ void optimizeview() {
transmatrix TB = Id;
if(binarytiling || archimedean) {
if(0) ;
#if CAP_BT || CAP_ARCM
else if(binarytiling || archimedean) {
turn = -1, best = View[2][2];
for(int i=0; i<viewctr.at->c7->type; i++) {
int i1 = i * DUALMUL;
heptagon *h2 = createStep(viewctr.at, i1);
transmatrix T = (binarytiling) ? binary::relative_matrix(h2, viewctr.at) : arcm::relative_matrix(h2, viewctr.at);
transmatrix T;
#if CAP_BT
if(binarytiling) T = binary::relative_matrix(h2, viewctr.at);
#endif
#if CAP_ARCM
if(archimedean) T = arcm::relative_matrix(h2, viewctr.at);
#endif
hyperpoint H = View * tC0(T);
ld quality = euclid ? hdist0(H) : H[2];
if(quality < best) best = quality, turn = i1, TB = T;
@ -1085,6 +1119,7 @@ void optimizeview() {
viewctr.at = createStep(viewctr.at, turn);
}
}
#endif
else {

View File

@ -1,5 +1,6 @@
namespace hr { namespace irr {
#if CAP_IRR
ld density = 2;
ld quality = .2;
int place_attempts = 10;
@ -1064,6 +1065,7 @@ auto hook =
addHook(hooks_drawcell, 100, draw_cell_schematics) +
addHook(shmup::hooks_turn, 100, step);
#endif
}}
/*

View File

@ -495,8 +495,10 @@ void giantLandSwitch(cell *c, int d, cell *from) {
else
v = 6;
}
#if CAP_ARCM
else if(archimedean && arcm::current.have_line)
v = arcm::linespattern(c) ? 24 : 16;
#endif
else if(fulltorus || hyperbolic_not37 || quotient || archimedean) {
v = hrand(100) < 25 ? 24 : 16;
}
@ -557,16 +559,20 @@ void giantLandSwitch(cell *c, int d, cell *from) {
case laZebra:
if(d==8) {
if(fulltorus) ;
#if CAP_ARCM
else if(archimedean && arcm::current.have_line)
c->wall = arcm::linespattern(c) ? waTrapdoor : waNone;
c->wall = arcm::linespattern(c) ? waTrapdoor : waNone;
#endif
else if(euclid && !archimedean) {
int x,y;
tie(x,y) = cell_to_pair(c);
if(y&1) c->wall = waTrapdoor;
else c->wall = waNone;
}
#if CAP_ARCM
else
if(archimedean) c->wall = hrand(2) ? waTrapdoor : waNone;
#endif
else
c->wall = (randomPatternsMode ? RANDPAT : (zebra40(c)&2)) ? waTrapdoor : waNone;
}
@ -581,8 +587,10 @@ void giantLandSwitch(cell *c, int d, cell *from) {
case laWineyard:
if(d==8) {
if(fulltorus) ;
#if CAP_ARCM
else if(archimedean && arcm::current.have_line)
c->wall = arcm::linespattern(c) ? waVinePlant : waNone;
#endif
else if(euclid && !archimedean) {
int x,y;
tie(x,y) = cell_to_pair(c);
@ -2431,7 +2439,10 @@ void setdist(cell *c, int d, cell *from) {
#else
if(true) {
#endif
if(geometry == gCrystal) crystal::set_land(c);
if(0);
#if CAP_CRYSTAL
else if(geometry == gCrystal) crystal::set_land(c);
#endif
else if(sphere || fulltorus) setLandSphere(c);
else if(euclid) setLandEuclid(c);
else if(quotient) { setland(c, specialland); setLandQuotient(c); }
@ -2504,8 +2515,10 @@ void setdist(cell *c, int d, cell *from) {
placeCrossroadOrbs(c);
else
placeLocalOrbs(c);
#if CAP_CRYSTAL
if(geometry == gCrystal && c->land != laMinefield)
crystal::may_place_compass(c);
#endif
}
if(PURE && c->wall == waMirrorWall && c->land == laMirror)

View File

@ -1161,16 +1161,20 @@ land_validity_t& land_validity(eLand l) {
/* laCamelot, laCaribbean -> they are OK but not recommended */
}
#if CAP_ARCM
if(archimedean) {
if(among(l, laPower, laZebra, laWineyard) && arcm::current.have_line) return lv::pattern_defined;
// horocycles not implemented
if(isCyclic(l)) return not_implemented;
}
#endif
#if CAP_CRYSTAL
if(geometry == gCrystal) {
if(l == laCamelot) return interesting;
if(isCrossroads(l)) return full_game;
}
#endif
// Random Pattern allowed only in some specific lands
if(randomPatternsMode && !isRandland(l))
@ -1253,11 +1257,13 @@ land_validity_t& land_validity(eLand l) {
if(isWarped(l) && a4 && GOLDBERG)
return dont_work;
#if CAP_IRR
if((isWarped(l) || l == laDual) && IRREGULAR && !irr::bitruncations_performed)
return dont_work;
if(IRREGULAR && among(l, laPrairie, laMirror, laMirrorOld))
return dont_work;
#endif
if(archimedean && l == laPrairie) return dont_work;

View File

@ -261,7 +261,9 @@ namespace mapstream {
if(geometry == gCrystal && vernum >= 10504) {
int sides;
f.read(sides);
#if CAP_CRYSTAL
crystal::set_crystal(sides);
#endif
if(sides == 8) {
int vertices;
eVariation v = variation;

View File

@ -6,7 +6,9 @@ namespace hr {
int gp_threecolor() {
if(!GOLDBERG) return 0;
#if CAP_GP
if(S3 == 3 && (gp::param.first - gp::param.second) % 3 == 0) return 2;
#endif
return 1;
}
@ -38,21 +40,27 @@ bool ishept(cell *c) {
bool ishex1(cell *c) {
// EUCLIDEAN
if(euclid) return eupattern(c) == 1;
#if CAP_GP
else if(GOLDBERG) return c->master->c7 != c && !pseudohept(c->move(0));
#endif
else return c->type != S6;
}
bool ishex2(cell *c) {
// EUCLIDEAN
if(euclid) return eupattern(c) == 1;
#if CAP_GP
else if(GOLDBERG) return c->master->c7 != c && gp::pseudohept_val(c) == 1;
#endif
else return c->type != S6;
}
int chessvalue(cell *c) {
#if CAP_ARCM
if(archimedean)
return arcm::chessvalue(c);
else
#endif
return celldist(c) & 1;
}
@ -342,8 +350,12 @@ pair<int, bool> fieldval(cell *c) {
int fieldval_uniq(cell *c) {
if(sphere) {
if(archimedean) return c->master->fiftyval;
#if CAP_IRR
else if(IRREGULAR) return irr::cellindex[c];
#endif
#if CAP_GP
else if(GOLDBERG) return (get_code(gp::get_local_info(c)) << 8) | (c->master->fieldval / S7);
#endif
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;
}
@ -467,7 +479,9 @@ int getHemisphere(cell *c, int which) {
return getHemisphere(c->master, which);
else {
int score = 0;
if(GOLDBERG) {
if(0) ;
#if CAP_GP
else if(GOLDBERG) {
auto li = gp::get_local_info(c);
gp::be_in_triangle(li);
auto corner = gp::corners * gp::loctoh_ort(li.relative);
@ -481,12 +495,15 @@ int getHemisphere(cell *c, int which) {
if(score == 0 && error < -.001) score--;
return score;
}
#endif
#if CAP_IRR
else if(IRREGULAR) {
auto m = irr::get_masters(c);
for(int i=0; i<3; i++)
score += getHemisphere(m[i], which);
return score / 3;
}
#endif
else {
for(int i=0; i<6; i+=2)
score += getHemisphere(c->move(i), which) * (c->c.mirror(i) ? -1 : 1);
@ -649,22 +666,27 @@ namespace patterns {
}
else {
int sp = c->c.spin(0);
#if CAP_GP
if(GOLDBERG) {
sp = gp::last_dir(c);
sp ^= int(ishex2(c));
}
#endif
if(geometry == gBolza2 && (!GOLDBERG || gp_threecolor() == 2)) {
patterninfo si0;
patterninfo si1;
#if CAP_GP
if(GOLDBERG) {
auto li = gp::get_local_info(c);
val38(c->master->c7, si0, 0, PAT_COLORING);
val38(c->master->move(li.last_dir)->c7, si1, 0, PAT_COLORING);
}
else {
else
#endif
{
val38(c->move(0), si0, 0, PAT_COLORING);
val38(c->move(2), si1, 0, PAT_COLORING);
}
}
if((si0.id+1) % 3 == (si1.id) % 3)
si.id = 8;
else
@ -672,7 +694,9 @@ namespace patterns {
}
else
si.id = 8 * ((c->master->fiftyval & 1) ^ (sp & 1));
#if CAP_GP
if(GOLDBERG && pseudohept(c)) si.id = 4;
#endif
bool dock = false;
for(int i=0; i<c->type; i+=2) {
int fiv = createMov(c, i)->master->fiftyval;
@ -685,6 +709,7 @@ namespace patterns {
if(symRotation) si.symmetries = 2;
si.id += 8;
si.id %= 12;
#if CAP_GP
if(GOLDBERG && pat == PAT_COLORING)
for(int i=0; i<c->type; i++) {
cell *c2 = createMov(c, i);
@ -700,6 +725,7 @@ namespace patterns {
// printf("%p %2d : %d %d\n", c, si.id, i, id2);
if((id2+4) % 12 == si.id) si.dir = i;
}
#endif
applyAlt(si, sub, pat);
if(dock && (sub & SPF_DOCKS)) si.id += 16;
}
@ -877,14 +903,21 @@ namespace patterns {
patterninfo getpatterninfo(cell *c, ePattern pat, int sub) {
if(!(sub & SPF_NO_SUBCODES)) {
auto si = getpatterninfo(c, pat, sub | SPF_NO_SUBCODES);
if(IRREGULAR)
if(1) ;
#if CAP_IRR
else if(IRREGULAR)
si.id += irr::cellindex[c] << 8;
#endif
#if CAP_ARCM
else if(archimedean)
si.id += (arcm::id_of(c->master) << 8) + (arcm::parent_index_of(c->master) << 16);
#endif
#if CAP_GP
else if(GOLDBERG) {
if(c == c->master->c7) si.id += (fixdir(si.dir, c) << 8);
else si.id += (get_code(gp::get_local_info(c)) << 16) | (fixdir(si.dir, c) << 8);
}
#endif
return si;
}
bool symRotation = sub & SPF_ROT;
@ -908,6 +941,7 @@ namespace patterns {
return si;
}
#if CAP_ARCM
if(archimedean && pat == 0) {
if(sub & SPF_FOOTBALL) {
val_threecolors(c, si, sub);
@ -923,6 +957,7 @@ namespace patterns {
si.reflect = true;
return si;
}
#endif
if(pat == PAT_ZEBRA && stdhyperbolic) {
@ -1078,16 +1113,20 @@ namespace patterns {
bool geosupport_chessboard() {
return
#if CAP_ARCM
(archimedean && PURE) ? arcm::current.support_chessboard() :
(archimedean && DUAL) ? arcm::current.support_threecolor_bitruncated() :
#endif
(VALENCE % 2 == 0);
}
int geosupport_threecolor() {
if(IRREGULAR) return 0;
#if CAP_ARCM
if(archimedean && PURE) return arcm::current.support_threecolor();
if(archimedean && BITRUNCATED) return arcm::current.support_threecolor_bitruncated();
if(archimedean && DUAL) return 0; // it sometimes does support threecolor, but it can be obtained in other ways then
#endif
if(BITRUNCATED && S3 == 3) {
if(S7 % 2) return 1;
return 2;
@ -1102,13 +1141,17 @@ int geosupport_threecolor() {
int geosupport_football() {
// always works in bitrunc geometries
if(BITRUNCATED) return 2;
#if CAP_ARCM
if(archimedean && DUAL) return false;
// it sometimes does support football, but it can be obtained in other ways then
if(archimedean /* PURE */) return arcm::current.support_football();
#endif
#if CAP_IRR
if(IRREGULAR) return irr::bitruncations_performed ? 2 : 1;
#endif
// always works in patterns supporting three-color
int tc = max(geosupport_threecolor(), gp_threecolor());
@ -1122,13 +1165,16 @@ int geosupport_football() {
}
int pattern_threecolor(cell *c) {
#if CAP_ARCM
if(archimedean) {
if(PURE)
return arcm::threecolor(c);
else /* if(BITRUNCATED) */
return c->master->rval1;
}
#endif
if(IRREGULAR || binarytiling) return !pseudohept(c);
#if CAP_GP
if(S3 == 3 && !(S7&1) && gp_threecolor() == 1 && c->master->c7 != c) {
auto li = gp::get_local_info(c);
int rel = (li.relative.first - li.relative.second + MODFIXER) % 3;
@ -1140,12 +1186,14 @@ int pattern_threecolor(cell *c) {
else
return pattern_threecolor(createStep(c->master, fix7(li.last_dir+1))->c7);
}
#endif
if(a38) {
// if(GOLDBERG && gp_threecolor() == 2 && gp::pseudohept_val(c) == 0) return 0;
patterns::patterninfo si;
patterns::val38(c, si, !BITRUNCATED ? 0 : patterns::SPF_ROT, patterns::PAT_COLORING);
return si.id >> 2;
}
#if CAP_GP
if(a4 && GOLDBERG) {
patterns::patterninfo si;
auto li = gp::get_local_info(c);
@ -1162,6 +1210,7 @@ int pattern_threecolor(cell *c) {
if(li.relative.second & 1) i ^= i2;
return i;
}
#endif
if(a46 && BITRUNCATED) {
patterns::patterninfo si;
patterns::val46(c, si, 0, patterns::PAT_COLORING);
@ -1174,6 +1223,7 @@ int pattern_threecolor(cell *c) {
}
if(S7 == 4 && S3 == 3) {
int codesN[6] = {0,1,2,1,2,0};
#if CAP_GP
if(gp_threecolor() == 2) {
auto li = gp::get_local_info(c);
int sp = (MODFIXER + li.relative.first + 2 * li.relative.second) % 3;
@ -1185,6 +1235,7 @@ int pattern_threecolor(cell *c) {
}
return sp;
}
#endif
if(PURE)
return codesN[c->master->fiftyval];
if(ctof(c))
@ -1218,8 +1269,10 @@ int pattern_threecolor(cell *c) {
}
if(S7 == 3 && PURE)
return c->master->fiftyval;
#if CAP_GP
if(gp_threecolor() && (S7&1))
return gp::pseudohept_val(c) > 0;
#endif
return !ishept(c);
}
@ -1227,29 +1280,42 @@ int pattern_threecolor(cell *c) {
// in the 'pure heptagonal' tiling, returns true for a set of cells
// which roughly corresponds to the heptagons in the normal tiling
bool pseudohept(cell *c) {
#if CAP_IRR
if(IRREGULAR) return irr::pseudohept(c);
#endif
if(binarytiling) return c->type & c->master->distance & 1;
#if CAP_ARCM
if(archimedean) return arcm::pseudohept(c);
#endif
#if CAP_GP
if(GOLDBERG && gp_threecolor() == 2)
return gp::pseudohept_val(c) == 0;
if(GOLDBERG && gp_threecolor() == 1 && (S7&1) && (S3 == 3))
return gp::pseudohept_val(c) == 0;
#endif
return pattern_threecolor(c) == 0;
}
// while Krakens movement is usually restricted to non-pseudohept cells,
// there is one special case when this does not work (because non-pseudohept cells have varying degrees)
bool kraken_pseudohept(cell *c) {
if(!euclid && S3 == 4 && GOLDBERG && (gp::param.first % 2 || gp::param.second % 2 || S7 % 2))
if(0);
#if CAP_GP
else if(!euclid && S3 == 4 && GOLDBERG && (gp::param.first % 2 || gp::param.second % 2 || S7 % 2))
return ishept(c);
#endif
#if CAP_IRR
else if(IRREGULAR)
return c->type != 6;
#endif
#if CAP_ARCM
else if(archimedean && PURE)
return c->type != isize(arcm::current.triangles[0]);
else if(archimedean && BITRUNCATED)
return pseudohept(c);
else if(archimedean && DUAL)
return false;
#endif
else if(!euclid && S3 == 3 && !(S7&1) && gp_threecolor() == 1)
return ishept(c);
else
@ -1327,12 +1393,14 @@ namespace patterns {
exp_parser ep;
ep.extra_params["p"] = p;
switch(geometry) {
#if CAP_CRYSTAL
case gCrystal: {
crystal::ldcoord co = crystal::get_ldcoord(c);
for(int i=0; i<crystal::MAXDIM; i++)
ep.extra_params["x"+its(i)] = co[i];
break;
}
#endif
default: {
hyperpoint h = calc_relative_matrix(c, currentmap->gamestart(), C0) * C0;
@ -1355,8 +1423,14 @@ namespace patterns {
int generateCanvas(cell *c) {
switch(whichCanvas) {
#if CAP_CRYSTAL
case 'K':
return crystal::colorize(c);
#endif
case 'A':
#if CAP_ARCM
if(archimedean) return colortables['A'][arcm::current.tilegroup[arcm::id_of(c->master)]];
#endif
case 'B':
return colortables['B'][c->type & 15];
case 'C': {
@ -1375,8 +1449,6 @@ namespace patterns {
int z = currfp.getdist(fieldval(c), make_pair(0,false));
return 255 * (currfp.maxdist+1-z) / currfp.maxdist;
}
case 'K':
return crystal::colorize(c);
case 'N': {
if(!hyperbolic) return canvasback;
using namespace fieldpattern;
@ -1686,8 +1758,10 @@ namespace patterns {
if(euclid && among(whichPattern, PAT_COLORING, PAT_TYPES) && !archimedean)
dialog::addBoolItem(XLAT("extra symmetries"), subpattern_flags & SPF_EXTRASYM, '=');
#if CAP_ARCM
if(archimedean && arcm::current.have_symmetry && whichPattern == PAT_TYPES)
dialog::addBoolItem(XLAT("extra symmetries"), subpattern_flags & SPF_EXTRASYM, '=');
#endif
if(whichPattern == PAT_SINGLETYPE) {
dialog::addBoolItem(XLAT("odd/even"), subpattern_flags & SPF_TWOCOL, '5');
@ -1954,8 +2028,10 @@ namespace patterns {
start_game();
if(not_restarted) REMAP_TEXTURE;
}
#if CAP_GP
else if(uni == 'G' && (have_goldberg || have_variations))
gp::configure();
#endif
else if(doexiton(sym, uni))
popScreen();
};

View File

@ -1620,7 +1620,9 @@ transmatrix ddi(int a, ld x) { return xspinpush(a * M_PI / S42, x); }
void drawTentacle(hpcshape &h, ld rad, ld var, ld divby) {
double tlength = max(crossf, hexhexdist);
#if CAP_ARCM
if(archimedean) tlength = arcm::current.scale();
#endif
int max = int(20 * pow(2, vid.linequality));
for(ld i=0; i<=max; i++)
hpcpush(ddi(S21, rad + var * sin(i * M_PI/divby)) * ddi(0, tlength * i/max) * C0);
@ -1858,7 +1860,9 @@ void buildpolys() {
symmetriesAt.clear();
allshapes.clear();
geom3::compute();
#if CAP_GP
gp::clear_plainshapes();
#endif
DEBB(DF_INIT, (debugfile,"buildpolys\n"));
// printf("crossf = %f euclid = %d sphere = %d\n", float(crossf), euclid, sphere);
@ -1957,7 +1961,10 @@ void buildpolys() {
for(int t=0; t<=6; t++) hpcpush(ddi(S7 + t*S14, floorrad0*7/8) * C0);
}
if(binarytiling) {
if(0);
#if CAP_BT
else if(binarytiling) {
for(int i=0; i<2; i++) {
bshape(shWall[i], PPR::WALL);
horopoint(log(2)/8, .1);
@ -1965,6 +1972,7 @@ void buildpolys() {
horopoint(-log(2)/8, 0);
}
}
#endif
else {
bshape(shWall[0], PPR::WALL);
@ -2212,8 +2220,11 @@ void buildpolys() {
// hand-drawn shapes
if(archimedean)
if(0);
#if CAP_ARCM
else if(archimedean)
shFullFloor.configure(arcm::current.scale()/2, arcm::current.scale()/2);
#endif
else
shFullFloor.configure(hexvdist, rhexf);
shFloor.configure(floorrad0, floorrad1);

View File

@ -603,12 +603,14 @@ void apply() {
case maRotation:
View = spin(2 * M_PI * t / period) * View;
break;
#if CAP_BT
case maParabolic:
reflect_view();
View = spin(movement_angle * M_PI / 180) * ypush(shift_angle * M_PI / 180) * binary::parabolic(parabolic_length * t / period) * ypush(-shift_angle * M_PI / 180) *
spin(-movement_angle * M_PI / 180) * View;
moved();
break;
#endif
case maCircle: {
if(masterless) centerover = rotation_center_c;
else viewctr = rotation_center_h;

View File

@ -3475,11 +3475,15 @@ void destroyBoats(cell *c) {
}
transmatrix master_relative(cell *c, bool get_inverse) {
if(IRREGULAR) {
if(0);
#if CAP_IRR
else if(IRREGULAR) {
int id = irr::cellindex[c];
ld alpha = 2 * M_PI / S7 * irr::periodmap[c->master].base.spin;
return get_inverse ? irr::cells[id].rpusher * spin(-alpha-master_to_c7_angle()): spin(alpha + master_to_c7_angle()) * irr::cells[id].pusher;
}
#endif
#if CAP_GP
else if(GOLDBERG) {
if(c == c->master->c7) {
return spin((get_inverse?-1:1) * master_to_c7_angle());
@ -3491,6 +3495,7 @@ transmatrix master_relative(cell *c, bool get_inverse) {
return T;
}
}
#endif
else if(BITRUNCATED && !euclid) {
for(int d=0; d<S7; d++) if(c->master->c7->move(d) == c)
return (get_inverse?invhexmove:hexmove)[d];

View File

@ -443,3 +443,27 @@ union SDL_Event;
#endif
#endif
#ifndef CAP_GEOMETRY
#define CAP_GEOMETRY (!(ISMINI))
#endif
#ifndef CAP_IRR
#define CAP_IRR CAP_GEOMETRY
#endif
#ifndef CAP_GP
#define CAP_GP CAP_GEOMETRY
#endif
#ifndef CAP_ARCM
#define CAP_ARCM CAP_GEOMETRY
#endif
#ifndef CAP_CRYSTAL
#define CAP_CRYSTAL CAP_GEOMETRY
#endif
#ifndef CAP_BT
#define CAP_BT CAP_GEOMETRY
#endif

View File

@ -288,7 +288,9 @@ void initgame() {
}
truelotus = 0;
survivalist = true;
#if CAP_CRYSTAL
crystal::used_compass_inside = false;
#endif
got_survivalist = false;
#if CAP_INV
if(inv::on) inv::init();
@ -1177,7 +1179,10 @@ void set_geometry(eGeometry target) {
if(bounded) racing::on = false;
#endif
if(euclid6) variation = eVariation::bitruncated;
#if CAP_IRR
if(IRREGULAR) variation = eVariation::bitruncated;
#endif
#if CAP_GP
if(GOLDBERG && gp::param == gp::loc(1,1) && S3 == 3) {
variation = eVariation::bitruncated;
}
@ -1185,9 +1190,12 @@ void set_geometry(eGeometry target) {
if(gp::param.second && gp::param.second != gp::param.first)
gp::param.second = 0;
}
#endif
if(DUAL && geometry != gArchimedean)
variation = ginf[geometry].default_variation;
#if CAP_BT
if(geometry == gBinaryTiling) variation = eVariation::pure;
#endif
need_reset_geometry = true;
}

View File

@ -1024,18 +1024,22 @@ int modecode() {
// daily/Yendor/Tactics/standard are saved separately, but are using the same codes (Daily uses no code)
// randompattern never records its scores
// no specifics of the advanced configuration of torus/fieldquotient currently recorded
#if CAP_GP
if(GOLDBERG) {
mct += (1 << 19);
auto loc = gp::human_representation(gp::param);
mct += loc.first << 21; // 4 bits
mct += loc.second << 25; // 4 bits
}
#endif
#if CAP_IRR
if(IRREGULAR) {
mct += (1 << 20);
mct += irr::density_code() << 21; // 8 bits
}
#endif
if(DUAL) {
mct += (1 << 19);
@ -1065,17 +1069,21 @@ int modecode() {
mct += ll(fgeomextras[current_extra].current_prime_id) << 37;
}
#if CAP_CRYSTAL
if(geometry == gCrystal) {
mct += ll(ginf[geometry].sides) << 29;
mct += ll(ginf[geometry].vertex) << 37;
}
#endif
#if CAP_ARCM
if(geometry == gArchimedean) {
unsigned res = 7;
for(char c: arcm::current.symbol) res = res * 157 + c;
mct += ll(res) << 29;
if(PURE) mct ^= (1<<29);
}
#endif
return mct;
}