diff --git a/bigstuff.cpp b/bigstuff.cpp index 5c0e4052..97ec7d4c 100644 --- a/bigstuff.cpp +++ b/bigstuff.cpp @@ -105,10 +105,8 @@ bool grailWasFound(cell *c) { void generateAlts(heptagon *h, int levs, bool link_cdata) { if(!h->alt) return; - if(!irr::on) { - preventbarriers(h->c7); - for(int i=0; ic7->mov[i]); - } + preventbarriers(h->c7); + for(int i=0; ic7->mov[i]); if(gp::on) for(int i=0; ic7); for(int i=0; ibardir == NOBARRIERS) return NULL; forCellEx(c1, c) if(c1->bardir == NOBARRIERS) return NULL; + if(irr::on) + for(int i=0; imaster, i)->c7->bardir != NODIR) + return NULL; } // check for non-crossing @@ -1082,8 +1084,8 @@ void buildBigStuff(cell *c, cell *from) { buildBarrier4(c, bd, 0, getNewLand(c->land), c->land); */ } - if((!chaosmode) && bearsCamelot(c->land) && ctof(c) && - (quickfind(laCamelot) || peace::on || (hrand(I2000) < 200 && horo_ok() && + if((!chaosmode) && bearsCamelot(c->land) && is_master(c) && + (quickfind(laCamelot) || peace::on || (hrand(I2000) < 200 && ((irr::on && hyperbolic) || horo_ok()) && items[itEmerald] >= U5 && !tactic::on))) { int rtr = newRoundTableRadius(); heptagon *alt = createAlternateMap(c, rtr+14, hsOrigin); diff --git a/cell.cpp b/cell.cpp index 40760c95..f1a46ebd 100644 --- a/cell.cpp +++ b/cell.cpp @@ -1085,9 +1085,9 @@ int celldist(cell *c) { return eudist(decodeId(c->master)); } if(sphere) return celldistance(c, currentmap->gamestart()); + if(irr::on) return irr::celldist(c, false); if(ctof(c)) return c->master->distance; if(gp::on) return gp::compute_dist(c, celldist); - if(irr::on) return c->master->distance; int dx[MAX_S3]; for(int u=0; umaster->distance; @@ -1113,6 +1113,7 @@ int celldistAlt(cell *c) { return celldist(c) - 3; } if(!c->master->alt) return 0; + if(irr::on) return irr::celldist(c, true); if(ctof(c)) return c->master->alt->distance; if(gp::on) return gp::compute_dist(c, celldistAlt); int dx[MAX_S3]; dx[0] = 0; diff --git a/game.cpp b/game.cpp index c853fd06..078b4651 100644 --- a/game.cpp +++ b/game.cpp @@ -6927,7 +6927,7 @@ ld circlesizeD[10000]; int lastsize; bool sizes_known() { - return euclid || (geometry == gNormal && !gp::on); + return euclid || (geometry == gNormal && !gp::on && !irr::on); } void computeSizes() { diff --git a/hyper.h b/hyper.h index c96ece64..71b275e1 100644 --- a/hyper.h +++ b/hyper.h @@ -326,7 +326,7 @@ enum hstate { hsOrigin, hsA, hsB, hsError, hsA0, hsA1, hsB0, hsB1, hsC }; struct heptagon { // automaton state hstate s : 6; - int dm4: 2; + unsigned int dm4: 2; // we are spin[i]-th neighbor of move[i] uint32_t spintable; int spin(int d) { return tspin(spintable, d); } @@ -2587,6 +2587,7 @@ namespace irr { bool supports(eGeometry g); void visual_creator(); unsigned char density_code(); + int celldist(cell *c, bool alts); } extern hrmap *currentmap; diff --git a/irregular.cpp b/irregular.cpp index a5aa6f72..2d220ec2 100644 --- a/irregular.cpp +++ b/irregular.cpp @@ -413,6 +413,7 @@ bool draw_cell_schematics(cell *c, transmatrix V) { struct heptinfo { heptspin base; vector subcells; + vector celldists[2]; }; map periodmap; @@ -492,6 +493,69 @@ void link_cell(cell *c, int d) { tsetspin(c2->spintable, sc.spin[d], d); } +int hdist(heptagon *h1, heptagon *h2) { + if(h1 == h2) return 0; + for(int i=0; imove[i] == h2) return 1; + return 2; + } + +// compute celldist or celldistalt for all the subcells of h. +// We use the following algorithm: +// - assume that everything is computed for all the adjacent heptagons of h which are closer to the origin +// - consider h and its two neighbors which are in the same distance to the origin ('siblings') +// - compute celldists for all the cells in these three heptagons, by bfs, based on the 'parent' heptagons adjacent to h +// - record the computed distances for h, but not for its siblings + +void compute_distances(heptagon *h, bool alts) { + auto dm4 = [alts, h] (heptagon *h1) -> unsigned { + if(!alts) return h1->dm4; + if(alts && !h1->alt) return 100; // error + if(alts && h1->alt->alt != h->alt->alt) return 100; // error + return h1->alt->dm4; + }; + unsigned cdm = dm4(h), pdm = (cdm-1)&3; + vector hs; + hs.push_back(h); + for(int i=0; imove[i]); + + vector*> to_clear; + + for(auto hx: hs) { + auto &hi = periodmap[hx]; + int ct = isize(hi.subcells); + auto& cd = hi.celldists[alts]; + if(cd.empty() && hx != h) to_clear.push_back(&cd); + cd.resize(ct, 2000000000); + if(h == hx && (alts ? h->alt->s == hsOrigin : h->s == hsOrigin)) + cd[0] = 0; + } + while(true) { + bool changed = false; + for(auto hx: hs) { + auto& hi = periodmap[hx]; + auto& cd = hi.celldists[alts]; + for(int i=0; imaster), cdm, pdm) && hdist(h, c2->master) < 2) { + int d = irr::celldist(c2, alts) + 1; + if(d < cd[i]) cd[i] = d, changed = true; + } + } + if(!changed) break; + } + for(auto x: to_clear) x->clear(); + // for(int i: cd) printf(" %d", i); printf("\n"); + } + +int celldist(cell *c, bool alts) { + heptagon *master = c->master; + auto &hi = periodmap[master]; + if(isize(hi.celldists[alts]) == 0) + compute_distances(master, alts); + return hi.celldists[alts][cells[cellindex[c]].localindex]; + } + eGeometry orig_geometry; void start_game_on_created_map() {