mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2024-12-24 17:10:36 +00:00
irr:: horocycles
This commit is contained in:
parent
4de4d3e640
commit
190fa3ea1d
@ -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);
|
||||
|
@ -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) {
|
||||
|
3
hyper.h
3
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);
|
||||
}
|
||||
|
115
irregular.cpp
115
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<heptagon*, heptagon*> 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; i<S7; i++) printf(" %p", createStep(h, i)); printf("\n"); */
|
||||
|
||||
if(alts) {
|
||||
if(!last_on_horocycle[h->alt->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,13 +562,108 @@ 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<heptagon*> hs[LOOKUP];
|
||||
hs[0].insert(master);
|
||||
set<heptagon*> region;
|
||||
for(int i=0; i<LOOKUP-1; i++) {
|
||||
for(auto h: hs[i]) {
|
||||
generateAlts(h);
|
||||
for(int j=0; j<S7; j++) {
|
||||
if(h->move[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<LOOKUP-1; i++) printf("%d -> ", isize(hs[i])); printf("%p\n", isize(hs[LOOKUP-1])); */
|
||||
map<cell*, int> xdist;
|
||||
vector<cell*> xdqueue;
|
||||
cell *orig = periodmap[*(hs[LOOKUP-1].begin())].subcells[0];
|
||||
xdist[orig] = 0;
|
||||
xdqueue.push_back(orig);
|
||||
for(int i=0; i<isize(xdqueue); i++) {
|
||||
forCellCM(c1, xdqueue[i])
|
||||
if(!xdist.count(c1) && region.count(c1->master)) {
|
||||
xdist[c1] = xdist[xdqueue[i]] + 1;
|
||||
xdqueue.push_back(c1);
|
||||
}
|
||||
}
|
||||
int delta = NODISTANCE;
|
||||
for(int i=0; i<S7; i++) {
|
||||
heptagon *h = master->move[i];
|
||||
if(h->alt->alt != master->alt->alt) continue;
|
||||
heptinfo& hi = periodmap[h];
|
||||
if(!isize(hi.celldists[1])) continue;
|
||||
for(int c=0; c<isize(hi.subcells); c++) {
|
||||
if(hi.celldists[1][c] == NODISTANCE) continue;
|
||||
int delta_candidate = hi.celldists[1][c] - xdist[hi.subcells[c]];
|
||||
if(delta != NODISTANCE && delta_candidate != delta) {
|
||||
printf("delta conflict: %d vs %d\n", delta, delta_candidate);
|
||||
delta = max(delta, delta_candidate);
|
||||
}
|
||||
delta = delta_candidate;
|
||||
}
|
||||
}
|
||||
if(delta == NODISTANCE) {
|
||||
delta = master->alt->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; i<LOOKUP/2; i++) {
|
||||
for(auto h: hs[i]) for(int j=-1; j<S7; j++) {
|
||||
heptinfo& hi = periodmap[j == -1 ? h : h->move[j]];
|
||||
hi.celldists[1].resize(isize(hi.subcells));
|
||||
for(int c=0; c<isize(hi.subcells); c++)
|
||||
hi.celldists[1][c] = delta + xdist[hi.subcells[c]];
|
||||
}
|
||||
}
|
||||
|
||||
last_on_horocycle[alt] = *(hs[LOOKUP/2].begin());
|
||||
}
|
||||
|
||||
int celldist(cell *c, bool alts) {
|
||||
heptagon *master = c->master;
|
||||
auto &hi = periodmap[master];
|
||||
/* if(alts && master->alt->alt->s != hsOrigin && isize(hi.celldists[alts]) == 0) {
|
||||
int doalts = 0;
|
||||
for(int i=0; i<S7; i++) if(master->move[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; i<S7; i++) if(master->move[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];
|
||||
|
@ -1162,10 +1162,7 @@ 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))
|
||||
return dont_work;
|
||||
|
||||
if(irr::on && among(l, laWhirlpool, laCamelot, laCaribbean, laClearing, laTemple, laHive, laMirror, laMirrorOld, laReptile))
|
||||
if(irr::on && among(l, laPrairie, laBlizzard, laVolcano, laMirror, laMirrorOld))
|
||||
return dont_work;
|
||||
|
||||
// equidistant-based lands
|
||||
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user