diff --git a/bigstuff.cpp b/bigstuff.cpp index 97ec7d4c..dbec0eb3 100644 --- a/bigstuff.cpp +++ b/bigstuff.cpp @@ -977,7 +977,7 @@ int wallchance(cell *c, bool deepOcean) { bool horo_ok() { // do the horocycles work in the current geometry? // (they work in ALL hyperbolic geometries currently!) - return hyperbolic && !irr::on; + return hyperbolic; } bool gp_wall_test() { @@ -1085,7 +1085,7 @@ void buildBigStuff(cell *c, cell *from) { } if((!chaosmode) && bearsCamelot(c->land) && is_master(c) && - (quickfind(laCamelot) || peace::on || (hrand(I2000) < 200 && ((irr::on && hyperbolic) || horo_ok()) && + (quickfind(laCamelot) || peace::on || (hrand(I2000) < 200 && horo_ok() && items[itEmerald] >= U5 && !tactic::on))) { int rtr = newRoundTableRadius(); heptagon *alt = createAlternateMap(c, rtr+14, hsOrigin); diff --git a/complex.cpp b/complex.cpp index 57c088ff..c681d97a 100644 --- a/complex.cpp +++ b/complex.cpp @@ -821,7 +821,7 @@ namespace clearing { void generate(cell *c) { if(buggyplant) return; if(sphere) return; - if(gp::on) return; + if(gp::on || irr::on) return; if(quotient) return; if(euclid) { diff --git a/hyper.h b/hyper.h index 71b275e1..028c045b 100644 --- a/hyper.h +++ b/hyper.h @@ -522,7 +522,6 @@ bool destroyHalfvine(cell *c, eWall newwall = waNone, int tval = 6); void buildCrossroads2(cell *c); bool isHaunted(eLand l); heptagon *createAlternateMap(cell *c, int rad, hstate firststate, int special=0); -void generateAlts(heptagon *h, int levs = S3-3, bool link_cdata = true); void setdist(cell *c, int d, cell *from); void checkOnYendorPath(); void killThePlayerAt(eMonster m, cell *c, flagtype flags); @@ -3714,4 +3713,6 @@ extern ld hexshift; extern bool noshadow, bright, nohelp, dont_face_pc; extern void switchHardcore(); + +void generateAlts(heptagon *h, int levs = irr::on ? 1 : S3-3, bool link_cdata = true); } diff --git a/irregular.cpp b/irregular.cpp index 2d220ec2..75b509ba 100644 --- a/irregular.cpp +++ b/irregular.cpp @@ -506,7 +506,25 @@ int hdist(heptagon *h1, heptagon *h2) { // - 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 +static const int NODISTANCE = 2000000000; + +map last_on_horocycle; + +void compute_horocycle(heptagon *); + void compute_distances(heptagon *h, bool alts) { + /* if(alts) printf("[%p] compute_distances %p\n", h->alt->alt, h); + printf("neighbors:"); for(int i=0; ialt->alt]) + last_on_horocycle[h->alt->alt] = h; + + if(h->alt->alt->s != hsOrigin) + while(h->alt->distance <= last_on_horocycle[h->alt->alt]->alt->distance) + compute_horocycle(h->alt->alt); + } + auto dm4 = [alts, h] (heptagon *h1) -> unsigned { if(!alts) return h1->dm4; if(alts && !h1->alt) return 100; // error @@ -526,7 +544,7 @@ void compute_distances(heptagon *h, bool alts) { int ct = isize(hi.subcells); auto& cd = hi.celldists[alts]; if(cd.empty() && hx != h) to_clear.push_back(&cd); - cd.resize(ct, 2000000000); + cd.resize(ct, NODISTANCE); if(h == hx && (alts ? h->alt->s == hsOrigin : h->s == hsOrigin)) cd[0] = 0; } @@ -544,14 +562,109 @@ void compute_distances(heptagon *h, bool alts) { } if(!changed) break; } + + /* for(auto hx: hs) { + auto& hi = periodmap[hx]; + auto& cd = hi.celldists[alts]; + // for(int i: cd) if(i == NODISTANCE) printf("distances not computed\n"); + } */ + for(auto x: to_clear) x->clear(); + // for(int i: cd) printf(" %d", i); printf("\n"); } +void erase_alt(heptagon *alt) { + last_on_horocycle.erase(alt); + } + +void compute_horocycle(heptagon *alt) { + heptagon *master = last_on_horocycle[alt]; + // printf("computing horocycle, master distance = %d [M=%p, A=%p]\n", master->alt->distance, master, alt); + + static const int LOOKUP = 16; + set hs[LOOKUP]; + hs[0].insert(master); + set region; + for(int i=0; imove[j]->alt->alt != master->alt->alt) continue; + region.insert(h->move[j]); + if(h->move[j]->alt->distance < h->alt->distance) + hs[i+1].insert(h->move[j]); + } + } + if(hs[i+1].empty()) { printf("error: hs[%d] not found\n", i+1); exit(1); } + } + /* printf("[%p] compute_horocycle "); + for(int i=0; i ", isize(hs[i])); printf("%p\n", isize(hs[LOOKUP-1])); */ + map xdist; + vector xdqueue; + cell *orig = periodmap[*(hs[LOOKUP-1].begin())].subcells[0]; + xdist[orig] = 0; + xdqueue.push_back(orig); + for(int i=0; imaster)) { + xdist[c1] = xdist[xdqueue[i]] + 1; + xdqueue.push_back(c1); + } + } + int delta = NODISTANCE; + for(int i=0; imove[i]; + if(h->alt->alt != master->alt->alt) continue; + heptinfo& hi = periodmap[h]; + if(!isize(hi.celldists[1])) continue; + for(int c=0; calt->distance - xdist[periodmap[master].subcells[0]]; + // printf("delta not found, set to %d\n", delta); + } + // printf("using delta = %d\n", delta); + + for(int i=0; imove[j]]; + hi.celldists[1].resize(isize(hi.subcells)); + for(int c=0; cmaster; auto &hi = periodmap[master]; - if(isize(hi.celldists[alts]) == 0) + /* if(alts && master->alt->alt->s != hsOrigin && isize(hi.celldists[alts]) == 0) { + int doalts = 0; + for(int i=0; imove[i]->alt == master->alt->move[0]) { + doalts = 1; + if(periodmap[master->move[i]].celldists[true].empty()) { + compute_horocycle(master); + doalts = 2; + } + } + if(doalts == 0) { + generateAlts(master); + for(int i=0; imove[i]->alt == master->alt->move[0] && periodmap[master->move[i]].celldists[true].empty()) + compute_horocycle(master); + } + } */ + if(isize(hi.celldists[alts]) == 0) compute_distances(master, alts); return hi.celldists[alts][cells[cellindex[c]].localindex]; } diff --git a/landlock.cpp b/landlock.cpp index 8d01aff4..105c4afb 100644 --- a/landlock.cpp +++ b/landlock.cpp @@ -1162,12 +1162,9 @@ land_validity_t& land_validity(eLand l) { if((isWarped(l) || l == laDual) && irr::on) return dont_work; - if(irr::on && among(l, laStorms, laPrairie, laBlizzard, laVolcano)) + if(irr::on && among(l, laPrairie, laBlizzard, laVolcano, laMirror, laMirrorOld)) return dont_work; - if(irr::on && among(l, laWhirlpool, laCamelot, laCaribbean, laClearing, laTemple, laHive, laMirror, laMirrorOld, laReptile)) - return dont_work; - // equidistant-based lands if(isEquidLand(l)) { // no equidistants supported in chaos mode @@ -1201,7 +1198,7 @@ land_validity_t& land_validity(eLand l) { return not_in_chaos; if(l == laClearing) - if(!(stdeuc || a38 || (a45 && !nonbitrunc) || (a47 && !nonbitrunc)) || gp::on) + if(!(stdeuc || a38 || (a45 && !nonbitrunc) || (a47 && !nonbitrunc)) || gp::on || irr::on) if(!bounded) return not_implemented; @@ -1313,7 +1310,7 @@ land_validity_t& land_validity(eLand l) { if(l == laTrollheim && !stdeuc && !bounded) return some1; - if(l == laReptile && (a38 || a4 || sphere || nonbitrunc || gp::on || (quotient && geometry != gZebraQuotient))) + if(l == laReptile && (a38 || a4 || sphere || nonbitrunc || gp::on || irr::on || (quotient && geometry != gZebraQuotient))) return bad_graphics; if((l == laDragon || l == laReptile) && !stdeuc && !smallbounded && !randomPatternsMode)