horocycle refactor/bugfix

This commit is contained in:
Zeno Rogue 2021-04-25 11:30:10 +02:00
parent a99be21653
commit acfacd498f
2 changed files with 181 additions and 161 deletions

View File

@ -346,7 +346,7 @@ EX void beCIsland(cell *c) {
} }
EX void generateTreasureIsland(cell *c) { EX void generateTreasureIsland(cell *c) {
if(!eubinary) currentmap->generateAlts(c->master); gen_alt(c);
if(isOnCIsland(c)) return; if(isOnCIsland(c)) return;
bool src = hrand(100) < 10; bool src = hrand(100) < 10;
@ -359,20 +359,20 @@ EX void generateTreasureIsland(cell *c) {
for(int i=0; i<c->type; i++) { for(int i=0; i<c->type; i++) {
cell *c2 = createMov(c, i); cell *c2 = createMov(c, i);
if(!eubinary) currentmap->generateAlts(c2->master); if(!eubinary) currentmap->generateAlts(c2->master);
if((eubinary || (c->master->alt && c2->master->alt)) && celldistAlt(c2) < celldistAlt(c)) { if(greater_alt(c, c2)) {
ctab.push_back(c2); ctab.push_back(c2);
qlo = i; qhi = i; qlo = i; qhi = i;
while(true && isize(ctab) < c->type) { while(true && isize(ctab) < c->type) {
qlo--; qlo--;
c2 = c->cmodmove(qlo); c2 = c->cmodmove(qlo);
if(!eubinary && !c2->master->alt) break; if(!have_alt(c2)) break;
if(celldistAlt(c2) >= celldistAlt(c)) break; if(celldistAlt(c2) >= celldistAlt(c)) break;
ctab.push_back(c2); ctab.push_back(c2);
} }
while(true && isize(ctab) < c->type) { while(true && isize(ctab) < c->type) {
qhi++; qhi++;
c2 = c->cmodmove(qhi); c2 = c->cmodmove(qhi);
if(!eubinary && !c2->master->alt) break; if(!have_alt(c2)) break;
if(celldistAlt(c2) >= celldistAlt(c)) break; if(celldistAlt(c2) >= celldistAlt(c)) break;
ctab.push_back(c2); ctab.push_back(c2);
} }
@ -392,7 +392,7 @@ EX void generateTreasureIsland(cell *c) {
if(c->wall != waCTree && hrand(100) < 15) if(c->wall != waCTree && hrand(100) < 15)
c->wall = (c->wall == waCIsland ? waCIsland2 : waCIsland); c->wall = (c->wall == waCIsland ? waCIsland2 : waCIsland);
} }
if(src && c2->wall == waCTree && (eubinary||c->master->alt) && celldistAlt(c) <= -10 && geometry != gRhombic3) { if(src && c2->wall == waCTree && have_alt(c) && celldistAlt(c) <= -10 && geometry != gRhombic3) {
bool end = true; bool end = true;
for(cell *cc: ctab) { for(cell *cc: ctab) {
generateTreasureIsland(cc); generateTreasureIsland(cc);
@ -1373,10 +1373,66 @@ EX int wallchance(cell *c, bool deepOcean) {
50; 50;
} }
/** should we generate the horocycles in the current geometry? */ /** \brief should we generate the horocycles in the current geometry? */
EX bool horo_ok() { EX bool horo_ok() {
if(INVERSE) return false; if(INVERSE) return false;
return hyperbolic && !bt::in() && !arcm::in() && !kite::in() && !experimental && !hybri && !arb::in(); return hyperbolic && !bt::in() && !arcm::in() && !kite::in() && !experimental && !hybri && !arb::in() && !quotient;
}
/** \brief should we either generate the horocycles in the current geometry, or have them exist via eubinary? */
EX bool horo_or_eubinary() {
return horo_ok() || eubinary;
}
/** \brief is celldistAlt defined for c? */
EX bool have_alt(cell *c) {
return eubinary || c->master->alt;
}
/** \brief generate alts around c if necessary */
EX void gen_alt(cell *c) {
if(!eubinary) currentmap->generateAlts(c->master);
}
/** \brief generate alts around c and further if necessary */
EX void gen_alt_around(cell *c) {
if(!eubinary) {
currentmap->generateAlts(c->master);
for(int i=0; i<c->master->type; i++)
currentmap->generateAlts(c->master->move(i));
}
}
/** \brief is celldistAlt defined for c and c2, and greater for c? */
EX bool greater_alt(cell *c, cell *c2) {
return have_alt(c) && have_alt(c2) && celldistAlt(c) > celldistAlt(c2);
}
EX int horo_gen_distance() {
return (WDIM == 3 && hyperbolic) ? 1 : 2;
}
EX bool single_horo(eLand horoland) {
return specialland == horoland && ls::single();
}
EX bool in_single_horo(cell *c, eLand horoland) {
return single_horo(horoland) || celldistAlt(c) <= 0;
}
EX bool extend_alt(cell *c, eLand horoland, eLand overland, bool extend_in_single IS(true), int dist IS(horo_gen_distance())) {
if(c->land != horoland && c->land != overland && !(c->land == laBrownian && overland == laOcean)) return false;
if(bt::in() && !single_horo(horoland)) return false;
if(have_alt(c) && ((ls::single() && extend_in_single) || masterAlt(c) <= dist)) {
gen_alt(c);
preventbarriers(c);
return true;
}
return false;
}
EX bool can_start_horo(cell *c) {
return ctof(c) && !have_alt(c) && horo_ok() && !randomPatternsMode && !racing::on && !yendor::on;
} }
EX bool gp_wall_test() { EX bool gp_wall_test() {
@ -1590,42 +1646,33 @@ EX void build_horocycles(cell *c, cell *from) {
// buildbigstuff // buildbigstuff
if(ls::any_order() && bearsCamelot(c->land) && is_master(c) && !bt::in() && if(ls::any_order() && bearsCamelot(c->land) && can_start_horo(c) && !bt::in() &&
#if MAXMDIM >= 4 #if MAXMDIM >= 4
!(hyperbolic && WDIM == 3 && !reg3::in_rule()) && !(hyperbolic && WDIM == 3 && !reg3::in_rule()) &&
#endif #endif
(quickfind(laCamelot) || peace::on || (hrand(I2000) < (c->land == laCrossroads4 ? 800 : 200) && horo_ok() && (quickfind(laCamelot) || peace::on || (hrand(I2000) < (c->land == laCrossroads4 ? 800 : 200) && horo_ok() &&
items[itEmerald] >= U5 && !tactic::on && !racing::on))) items[itEmerald] >= U5)))
start_camelot(c); start_camelot(c);
if(c->land == laRlyeh && ctof(c) && horo_ok() && if(c->land == laRlyeh && can_start_horo(c) && (quickfind(laTemple) || peace::on || (hrand(I2000) < 100 && items[itStatue] >= U5)))
(quickfind(laTemple) || peace::on || (hrand(I2000) < 100 &&
items[itStatue] >= U5 && !randomPatternsMode &&
!tactic::on && !yendor::on && !racing::on)))
createAlternateMap(c, horo_gen_distance(), hsA); createAlternateMap(c, horo_gen_distance(), hsA);
if(c->land == laJungle && ctof(c) && if(c->land == laJungle && can_start_horo(c) && (quickfind(laMountain) || (hrand(I2000) < 100 && landUnlocked(laMountain))))
(quickfind(laMountain) || (hrand(I2000) < 100 && horo_ok() &&
!randomPatternsMode && !tactic::on && !yendor::on && !racing::on && landUnlocked(laMountain))))
createAlternateMap(c, horo_gen_distance(), hsA); createAlternateMap(c, horo_gen_distance(), hsA);
if(c->land == laOvergrown && ctof(c) && horo_ok() && if(c->land == laOvergrown && can_start_horo(c) && (quickfind(laClearing) || (hrand(I2000) < 25 && items[itMutant] >= U5 && isLandIngame(laClearing)))) {
(quickfind(laClearing) || (hrand(I2000) < 25 &&
!randomPatternsMode && items[itMutant] >= U5 &&
isLandIngame(laClearing) &&
!tactic::on && !yendor::on && !racing::on))) {
heptagon *h = createAlternateMap(c, horo_gen_distance(), hsA); heptagon *h = createAlternateMap(c, horo_gen_distance(), hsA);
if(h) clearing::bpdata[h].root = NULL; if(h) clearing::bpdata[h].root = NULL;
} }
if(stdhyperbolic && c->land == laStorms && ctof(c) && hrand(2000) < 1000 && horo_ok() && !randomPatternsMode) { if(stdhyperbolic && c->land == laStorms && can_start_horo(c) && hrand(2000) < 1000) {
heptagon *h = createAlternateMap(c, horo_gen_distance(), hsA); heptagon *h = createAlternateMap(c, horo_gen_distance(), hsA);
if(h) h->alt->emeraldval = hrand(2); if(h) h->alt->emeraldval = hrand(2);
} }
if(c->land == laOcean && ctof(c) && deepOcean && !generatingEquidistant && !peace::on && horo_ok() && if(c->land == laOcean && deepOcean && !generatingEquidistant && !peace::on && can_start_horo(c) &&
(quickfind(laWhirlpool) || ( (quickfind(laWhirlpool) || (
hrand(2000) < (PURE ? 500 : 1000) && !tactic::on && !racing::on && !yendor::on))) hrand(2000) < (PURE ? 500 : 1000))))
createAlternateMap(c, horo_gen_distance(), hsA); createAlternateMap(c, horo_gen_distance(), hsA);
#if CAP_COMPLEX2 #if CAP_COMPLEX2
@ -1633,17 +1680,16 @@ EX void build_horocycles(cell *c, cell *from) {
brownian::init_further(c); brownian::init_further(c);
#endif #endif
if(c->land == laCaribbean && horo_ok() && ctof(c) && !c->master->alt) if(c->land == laCaribbean && can_start_horo(c))
createAlternateMap(c, horo_gen_distance(), hsA); createAlternateMap(c, horo_gen_distance(), hsA);
if(c->land == laCanvas && horo_ok() && ctof(c) && !c->master->alt && ls::any_order()) if(c->land == laCanvas && can_start_horo(c) && ls::any_order())
createAlternateMap(c, horo_gen_distance(), hsA); createAlternateMap(c, horo_gen_distance(), hsA);
if(c->land == laPalace && ctof(c) && !princess::generating && !shmup::on && multi::players == 1 && horo_ok() && !weirdhyperbolic && if(c->land == laPalace && can_start_horo(c) && !princess::generating && !shmup::on && multi::players == 1 && !weirdhyperbolic &&
(princess::forceMouse ? canReachPlayer(from, moMouse) : (princess::forceMouse ? canReachPlayer(from, moMouse) :
(hrand(2000) < (peace::on ? 100 : 20))) && (hrand(2000) < (peace::on ? 100 : 20))) &&
!c->master->alt && (princess::challenge || kills[moVizier] || peace::on)) {
(princess::challenge || kills[moVizier] || peace::on) && !tactic::on && !yendor::on && !racing::on) {
createAlternateMap(c, PRADIUS0, hsOrigin, waPalace); createAlternateMap(c, PRADIUS0, hsOrigin, waPalace);
celllister cl(c, 5, 1000000, NULL); celllister cl(c, 5, 1000000, NULL);
for(cell *c: cl.lst) if(c->master->alt) currentmap->generateAlts(c->master); for(cell *c: cl.lst) if(c->master->alt) currentmap->generateAlts(c->master);
@ -1691,7 +1737,7 @@ EX void buildCamelotWall(cell *c) {
if(WDIM == 3 && hyperbolic) return; if(WDIM == 3 && hyperbolic) return;
for(int i=0; i<c->type; i++) { for(int i=0; i<c->type; i++) {
cell *c2 = createMov(c, i); cell *c2 = createMov(c, i);
if(c2->wall == waNone && (eubinary || (c2->master->alt && c->master->alt)) && celldistAlt(c2) > celldistAlt(c) && c2->monst == moNone) if(c2->wall == waNone && greater_alt(c2, c) && c2->monst == moNone)
c2->wall = waCamelotMoat; c2->wall = waCamelotMoat;
} }
} }
@ -1715,7 +1761,7 @@ EX eMonster camelot_monster() {
EX void buildCamelot(cell *c) { EX void buildCamelot(cell *c) {
int d = celldistAltRelative(c); int d = celldistAltRelative(c);
if(ls::single() || (d <= 14 && roundTableRadius(c) > 20)) { if(ls::single() || (d <= 14 && roundTableRadius(c) > 20)) {
if(!eubinary) currentmap->generateAlts(c->master); gen_alt(c);
preventbarriers(c); preventbarriers(c);
if(d == 10) { if(d == 10) {
if(weirdhyperbolic ? hrand(100) < 50 : pseudohept(c)) buildCamelotWall(c); if(weirdhyperbolic ? hrand(100) < 50 : pseudohept(c)) buildCamelotWall(c);
@ -1782,6 +1828,7 @@ EX int masterAlt(cell *c) {
#if MAXMDIM >= 4 #if MAXMDIM >= 4
if(WDIM == 3 && hyperbolic && !reg3::in_rule()) return reg3::altdist(c->master); if(WDIM == 3 && hyperbolic && !reg3::in_rule()) return reg3::altdist(c->master);
#endif #endif
if(eubinary) return celldistAlt(c);
return c->master->alt->distance; return c->master->alt->distance;
} }
@ -1796,43 +1843,106 @@ EX int temple_layer_size() {
return 6; return 6;
} }
EX int horo_gen_distance() { /** generate the (non-chaotic) Temple of Cthulhu */
return (WDIM == 3 && hyperbolic) ? 1 : 2; EX void gen_temple(cell *c) {
int d = celldistAlt(c);
if(d <= 0) {
c->land = laTemple, c->wall = waNone, c->monst = moNone, c->item = itNone;
}
if(d % temple_layer_size()==0) {
c->landparam = 0;
if(geometry == gSpace534) {
int i = 0;
forCellCM(c2, c) if(greater_alt(c, c2)) i++;
if(i > 1) c->wall = waColumn;
}
else if(geometry == gSpace535) {
c->wall = (c->master->fieldval % 5) ? waRubble : waColumn;
}
else if(geometry == gSpace435) {
c->wall = waRubble;
if(c->master->fieldval == 0) c->wall = waColumn;
forCellCM(c1, c) if(c1->master->fieldval == 0) c->wall = waColumn;
}
else if(sol) {
if(c->master->emeraldval % 3 || c->master->zebraval % 3)
c->wall = waColumn;
}
else if(nih) {
if(c->master->emeraldval % 2)
c->wall = waColumn;
}
#if CAP_BT
else if(geometry == gHoroTris || geometry == gHoroRec) {
if(c->c.spin(bt::updir()) != 0) c->wall = waColumn;
}
else if(geometry == gKiteDart3) {
if(kite::getshape(c->master) == kite::pKite) c->wall = waColumn;
}
#endif
else if(in_s2xe()) {
auto d = hybrid::get_where(c);
if(!PIU(pseudohept(d.first))) c->wall = waColumn;
}
else if(hybri) {
auto d = hybrid::get_where(c);
if(d.first->wall == waColumn || (d.second&1)) c->wall = waColumn;
}
else if(WDIM == 3) {
c->wall = hrand(100) < 10 ? waColumn : waRubble;
}
else if(S3 >= OINF) { }
else if(weirdhyperbolic && !BITRUNCATED) {
if(hrand(100) < 50) c->wall = waColumn;
}
else if(pseudohept(c))
c->wall = waColumn;
else {
gen_alt_around(c);
int q = 0;
for(int t=0; t<c->type; t++) {
createMov(c, t);
if(have_alt(c->move(t)) && celldistAlt(c->move(t)) % temple_layer_size() == 0 && !ishept(c->move(t))) q++;
}
if(q == 2) c->wall = waColumn;
}
c->landparam = 1;
}
else c->landparam = 2;
} }
EX void moreBigStuff(cell *c) { EX void moreBigStuff(cell *c) {
if((bearsCamelot(c->land) && !euclid && !quotient && !nil) || c->land == laCamelot) if((bearsCamelot(c->land) && !euclid && !quotient && !nil) || c->land == laCamelot)
if(eubinary || bt::in() || c->master->alt) if(!(bt::in() && specialland != laCamelot)) if(have_alt(c)) if(!(bt::in() && specialland != laCamelot))
buildCamelot(c); buildCamelot(c);
if(quotient) return; if(quotient) return;
if(c->land == laPalace && !eubinary && c->master->alt) { extend_alt(c, laCaribbean, laCaribbean, false);
int d = celldistAlt(c); if(c->land == laCaribbean) {
if(d <= PRADIUS1) currentmap->generateAlts(c->master); if(have_alt(c) && celldistAlt(c) <= 0)
generateTreasureIsland(c);
else
c->wall = waSea;
} }
extend_alt(c, laPalace, laPalace, false, PRADIUS1);
if(c->land == laCanvas && !eubinary && c->master->alt && !quotient && (ls::single() || celldistAlt(c) <= 0)) extend_alt(c, laCanvas, laCanvas);
currentmap->generateAlts(c->master);
if(c->land == laStorms) if(extend_alt(c, laStorms, laStorms, false)) {
if(!eubinary && !quotient && !sphere) { int d = celldistAlt(c);
if(c->master->alt && masterAlt(c) <= horo_gen_distance()) { if(d <= -2) {
currentmap->generateAlts(c->master); c->wall = eubinary ? waCharged : (c->master->alt->alt->emeraldval & 1) ? waCharged : waGrounded;
preventbarriers(c); c->item = itNone;
int d = celldistAlt(c); c->monst = moNone;
if(d <= -2) { }
c->wall = (c->master->alt->alt->emeraldval & 1) ? waCharged : waGrounded; else if(d <= -1)
c->item = itNone; c->wall = (hrand(100) < 20) ? waSandstone : waNone;
c->monst = moNone; else if(d <= 0)
} c->wall = waNone;
else if(d <= -1) }
c->wall = (hrand(100) < 20) ? waSandstone : waNone;
else if(d <= 0)
c->wall = waNone;
}
}
if(ls::any_chaos() && c->land == laTemple) { if(ls::any_chaos() && c->land == laTemple) {
for(int i=0; i<c->type; i++) for(int i=0; i<c->type; i++)
@ -1840,114 +1950,23 @@ EX void moreBigStuff(cell *c) {
c->wall = waColumn; c->wall = waColumn;
} }
else if((c->land == laRlyeh && !euclid) || c->land == laTemple) if(!(bt::in() && specialland != laTemple && c->land == laRlyeh)) { else if(extend_alt(c, laTemple, laRlyeh))
if(eubinary || in_s2xe() || (c->master->alt && (ls::single() || masterAlt(c) <= horo_gen_distance()))) { gen_temple(c);
if(!eubinary && !ls::any_chaos()) currentmap->generateAlts(c->master);
preventbarriers(c); if(extend_alt(c, laClearing, laOvergrown)) {
int d = celldistAlt(c); if(in_single_horo(c, laClearing)) {
if(d <= 0) { c->land = laClearing, c->wall = waNone;
c->land = laTemple, c->wall = waNone, c->monst = moNone, c->item = itNone;
}
if(d % temple_layer_size()==0) {
c->landparam = 0;
if(geometry == gSpace534) {
int i = 0;
forCellCM(c2, c) if(celldistAlt(c2) < celldistAlt(c)) i++;
if(i > 1) c->wall = waColumn;
}
else if(geometry == gSpace535) {
c->wall = (c->master->fieldval % 5) ? waRubble : waColumn;
}
else if(geometry == gSpace435) {
c->wall = waRubble;
if(c->master->fieldval == 0) c->wall = waColumn;
forCellCM(c1, c) if(c1->master->fieldval == 0) c->wall = waColumn;
}
else if(sol) {
if(c->master->emeraldval % 3 || c->master->zebraval % 3)
c->wall = waColumn;
}
else if(nih) {
if(c->master->emeraldval % 2)
c->wall = waColumn;
}
#if CAP_BT
else if(geometry == gHoroTris || geometry == gHoroRec) {
if(c->c.spin(bt::updir()) != 0) c->wall = waColumn;
}
else if(geometry == gKiteDart3) {
if(kite::getshape(c->master) == kite::pKite) c->wall = waColumn;
}
#endif
else if(in_s2xe()) {
auto d = hybrid::get_where(c);
if(!PIU(pseudohept(d.first))) c->wall = waColumn;
}
else if(hybri) {
auto d = hybrid::get_where(c);
if(d.first->wall == waColumn || (d.second&1)) c->wall = waColumn;
}
else if(WDIM == 3) {
c->wall = hrand(100) < 10 ? waColumn : waRubble;
}
else if(S3 >= OINF) { }
else if(weirdhyperbolic && !BITRUNCATED) {
if(hrand(100) < 50) c->wall = waColumn;
}
else if(pseudohept(c))
c->wall = waColumn;
else {
if(!eubinary) for(int i=0; i<S7; i++) currentmap->generateAlts(c->master->move(i));
int q = 0;
for(int t=0; t<c->type; t++) {
createMov(c, t);
if(celldistAlt(c->move(t)) % temple_layer_size() == 0 && !ishept(c->move(t))) q++;
}
if(q == 2) c->wall = waColumn;
}
c->landparam = 1;
}
else c->landparam = 2;
} }
else if(celldistAlt(c) == 1)
c->wall = waSmallTree, c->monst = moNone, c->item = itNone, c->landparam = 1;
} }
if((c->land == laOvergrown && !euclid) || c->land == laClearing) if(!(bt::in() && specialland != laClearing)) { if(extend_alt(c, laMountain, laJungle) && in_single_horo(c, laMountain)) {
if(eubinary || (c->master->alt && (ls::single() || masterAlt(c) <= horo_gen_distance()))) { c->land = laMountain, c->wall = waNone;
if(!eubinary) currentmap->generateAlts(c->master);
preventbarriers(c);
int d = celldistAlt(c);
if(d <= 0) {
c->land = laClearing, c->wall = waNone; // , c->monst = moNone, c->item = itNone;
}
else if(d == 1 && !ls::single() && !eubinary)
c->wall = waSmallTree, c->monst = moNone, c->item = itNone, c->landparam = 1;
}
} }
if((c->land == laJungle && !euclid) || c->land == laMountain) if(!(bt::in() && specialland != laMountain)) { if(extend_alt(c, laWhirlpool, laOcean) && in_single_horo(c, laWhirlpool))
if(eubinary || (c->master->alt && (ls::single() || masterAlt(c) <= horo_gen_distance()))) { c->land = laWhirlpool, c->wall = waSea, c->monst = moNone, c->item = itNone;
if(!eubinary) currentmap->generateAlts(c->master);
preventbarriers(c);
int d = celldistAlt(c);
if(d <= 0 || (specialland == laMountain && ls::single())) {
c->land = laMountain, c->wall = waNone; // , c->monst = moNone, c->item = itNone;
}
}
}
if(among(c->land, laOcean, laWhirlpool, laBrownian)) if(!(bt::in() && specialland != laWhirlpool)) {
bool fullwhirlpool = false;
if(ls::single() && specialland == laWhirlpool)
fullwhirlpool = true;
if(eubinary || (c->master->alt && (fullwhirlpool || masterAlt(c) <= 2))) {
if(!eubinary) currentmap->generateAlts(c->master);
preventbarriers(c);
int dd = celldistAlt(c);
if(dd <= 0 || fullwhirlpool) {
c->land = laWhirlpool, c->wall = waSea, c->monst = moNone, c->item = itNone;
}
}
}
} }
EX void generate_mines() { EX void generate_mines() {

View File

@ -219,7 +219,8 @@ EX void initgame() {
if(firstland == laWhirlpool) cwt.at->move(0)->wall = waSea; if(firstland == laWhirlpool) cwt.at->move(0)->wall = waSea;
setdist(cwt.at->move(0), BARLEV-1, cwt.at); setdist(cwt.at->move(0), BARLEV-1, cwt.at);
if(!sphere && !eubinary && !quotient) {
if(horo_ok()) {
if(specialland == laCamelot) if(specialland == laCamelot)
start_camelot(cwt.at); start_camelot(cwt.at);
else { else {