ls:: horodisk implemented

This commit is contained in:
Zeno Rogue 2023-09-14 11:41:51 +02:00
parent 0293680ea1
commit 50e5cc2c5a
6 changed files with 107 additions and 29 deletions

View File

@ -758,7 +758,7 @@ EX void killMonster(cell *c, eMonster who, flagtype deathflags IS(0)) {
if(m == moWaterElemental && c->item == itNone)
c->item = itOrbWater;
if(m == moPirate && isOnCIsland(c) && c->item == itNone && (
if(m == moPirate && (isOnCIsland(c) || ls::hv_structure()) && c->item == itNone && (
eubinary ||
(c->master->alt && celldistAlt(c) <= 2-getDistLimit()) ||
isHaunted(c->land)) && !cryst) {

View File

@ -1657,9 +1657,12 @@ EX void start_camelot(cell *c) {
if(alt) {
altmap::radius(alt) = rtr;
altmap::orig_land(alt) = c->land;
horodisk_land[alt] = laCamelot;
}
}
EX map<heptagon*, eLand> horodisk_land;
EX void build_horocycles(cell *c, cell *from) {
bool deepOcean = deep_ocean_at(c, from);
@ -1708,10 +1711,18 @@ EX void build_horocycles(cell *c, cell *from) {
if(c->land == laCaribbean && can_start_horo(c))
create_altmap(c, horo_gen_distance(), hsA);
if(ls::horodisk_structure() && can_start_horo(c)) {
auto m = create_altmap(c, horo_gen_distance(), hsA);
if(m) {
horodisk_land[m] = getNewLand(laCrossroads);
clearing::bpdata[m].root = NULL;
}
}
if(c->land == laCanvas && can_start_horo(c) && ls::any_order())
create_altmap(c, horo_gen_distance(), hsA);
if(c->land == laPalace && can_start_horo(c) && !princess::generating && !shmup::on && multi::players == 1 && !weirdhyperbolic &&
if(c->land == laPalace && can_start_horo(c) && !princess::generating && !shmup::on && multi::players == 1 && !weirdhyperbolic && !ls::hv_structure() &&
(princess::forceMouse ? canReachPlayer(from, moMouse) :
(hrand(2000) < (peace::on ? 100 : 20))) &&
(princess::challenge || kills[moVizier] || peace::on)) {
@ -1966,12 +1977,31 @@ EX void moreBigStuff(cell *c) {
else
c->wall = waSea;
}
if(ls::horodisk_structure()) {
if(have_alt(c) && masterAlt(c) <= 0) {
gen_alt(c);
preventbarriers(c);
}
if(have_alt(c) && celldistAlt(c) <= 0) {
eLand l = horodisk_land[c->master->alt->alt];
setland(c, l);
if(l == laWhirlpool && celldistAlt(c) >= -1) {
setland(c, laOcean);
c->landparam = 30;
}
if(l == laCaribbean) generateTreasureIsland(c);
if(isEquidLand(l)) c->landparam = 1-celldistAlt(c);
}
else
setland(c, laCrossroads);
}
extend_alt(c, laPalace, laPalace, false, PRADIUS1);
extend_alt(c, laCanvas, laCanvas);
if(extend_alt(c, laStorms, laStorms, false)) {
if(extend_alt(c, laStorms, laStorms, false) && !ls::hv_structure()) {
int d = celldistAlt(c);
if(d <= -2) {
c->wall = eubinary ? waCharged : (altmap::which(c->master->alt->alt) & 1) ? waCharged : waGrounded;
@ -1990,10 +2020,12 @@ EX void moreBigStuff(cell *c) {
c->wall = waColumn;
}
else if(extend_alt(c, laTemple, laRlyeh))
else if(extend_alt(c, laTemple, laRlyeh) && !ls::hv_structure())
gen_temple(c);
if(extend_alt(c, laClearing, laOvergrown)) {
if(c->land == laTemple && ls::hv_structure()) gen_temple(c);
if(extend_alt(c, laClearing, laOvergrown) && !ls::hv_structure()) {
if(in_single_horo(c, laClearing)) {
c->land = laClearing, c->wall = waNone;
}
@ -2001,11 +2033,16 @@ EX void moreBigStuff(cell *c) {
c->wall = waSmallTree, c->monst = moNone, c->item = itNone, c->landparam = 1;
}
if(extend_alt(c, laMountain, laJungle) && in_single_horo(c, laMountain)) {
if(c->land == laClearing && ls::hv_structure()) {
if(celldistAlt(c) >= -1)
c->wall = waSmallTree, c->monst = moNone, c->item = itNone, c->landparam = 1;
}
if(extend_alt(c, laMountain, laJungle) && in_single_horo(c, laMountain) && !ls::hv_structure()) {
c->land = laMountain, c->wall = waNone;
}
if(extend_alt(c, laWhirlpool, laOcean) && in_single_horo(c, laWhirlpool))
if(!ls::horodisk_structure() && extend_alt(c, laWhirlpool, laOcean) && in_single_horo(c, laWhirlpool))
c->land = laWhirlpool, c->wall = waSea, c->monst = moNone, c->item = itNone;
}

View File

@ -907,6 +907,8 @@ EX namespace clearing {
c->mondir = 0;
return;
}
if(c->land == laClearing && ls::hv_structure() && celldistAlt(c) >= -1) return;
if(!eubinary && !horo_ok()) return;
// cell *oc = c;
@ -4080,10 +4082,18 @@ EX namespace dungeon {
rdepths[i] = c2 && c3 && c4 && (c2->landflags == 3 || c3->landflags == 3 || c4->landflags == 3);
if(c2) generate_around(c2);
if(c3) generate_around(c3);
c2 = ts::left_parent(c2, coastvalEdge);
c3 = ts::right_parent(c3, coastvalEdge);
if(!c2) { towerError(c); return; }
if(!c3) { towerError(c); return; }
if(ls::horodisk_structure()) {
c2 = ts::left_child(c2, celldistAlt);
c3 = ts::right_child(c3, celldistAlt);
if(!c2 || !c3) return;
}
else {
c2 = ts::left_parent(c2, coastvalEdge);
c3 = ts::right_parent(c3, coastvalEdge);
if(!c2) { towerError(c); return; }
if(!c3) { towerError(c); return; }
}
}
}
@ -4106,10 +4116,17 @@ EX namespace dungeon {
if(c3 && c5 && c5->landflags == 3 && c3->landflags != 3 && c5 == ts::right_of(c3, coastvalEdge))
c->wall = waLadder;
buildEquidistant(c4); buildEquidistant(c5);
if(c2) c2 = ts::left_parent(c2, coastvalEdge);
if(c3) c3 = ts::right_parent(c3, coastvalEdge);
if(c4) c4 = ts::left_parent(c4, coastvalEdge);
if(c5) c5 = ts::right_parent(c5, coastvalEdge);
if(ls::horodisk_structure()) {
c2 = ts::left_child(c2, celldistAlt);
c3 = ts::right_child(c3, celldistAlt);
if(!c2 || !c3) return;
}
else {
if(c2) c2 = ts::left_parent(c2, coastvalEdge);
if(c3) c3 = ts::right_parent(c3, coastvalEdge);
if(c4) c4 = ts::left_parent(c4, coastvalEdge);
if(c5) c5 = ts::right_parent(c5, coastvalEdge);
}
}
}
}
@ -4161,10 +4178,17 @@ EX namespace dungeon {
switchcount++;
generate_around(c2);
generate_around(c3);
c2 = ts::left_parent(c2, coastvalEdge);
c3 = ts::right_parent(c3, coastvalEdge);
if(!c2) { towerError(c); return 0; }
if(!c3) { towerError(c); return 0; }
if(ls::horodisk_structure()) {
c2 = ts::left_child(c2, celldistAlt);
c3 = ts::right_child(c3, celldistAlt);
if(!c2 || !c3) return 0;
}
else {
c2 = ts::left_parent(c2, coastvalEdge);
c3 = ts::right_parent(c3, coastvalEdge);
if(!c2) { towerError(c); return 0; }
if(!c3) { towerError(c); return 0; }
}
}
}
}

View File

@ -276,7 +276,7 @@ EX void place_random_gate_continuous(cell *c) {
}
EX void giantLandSwitch(cell *c, int d, cell *from) {
bool fargen = d == min(BARLEV, 9);
bool fargen = d == min(BARLEV, ls::horodisk_structure() ? 8 : 9);
switch(c->land) {
case laPrairie: // -------------------------------------------------------------
@ -405,7 +405,7 @@ EX void giantLandSwitch(cell *c, int d, cell *from) {
}
else {
if(d == 9) {
if(d == (ls::horodisk_structure() ? 8 : 9)) {
cell *c2 = NONSTDVAR ? c->master->c7 : c;
if(cdist50(c2) == 3 && polarb50(c2))
c->wall = waPalace;
@ -453,7 +453,7 @@ EX void giantLandSwitch(cell *c, int d, cell *from) {
}
// note: Princess Challenge brings back the normal Palace generation
bool lookingForPrincess = !euclid && c->master->alt && !princess::challenge;
bool lookingForPrincess = !euclid && c->master->alt && !princess::challenge && !ls::horodisk_structure();
bool pgate = false;
if(PURE || GOLDBERG) {
@ -551,7 +551,7 @@ EX void giantLandSwitch(cell *c, int d, cell *from) {
}
ONEMPTY {
bool lookingForPrincess0 = !euclid && c->master->alt;
bool lookingForPrincess0 = !euclid && c->master->alt && !ls::horodisk_structure();
bool lookingForPrincess = lookingForPrincess0 && !princess::challenge;
int hardness = lookingForPrincess ? 5 : items[itPalace] + yendor::hardness();
@ -1982,7 +1982,7 @@ EX void giantLandSwitch(cell *c, int d, cell *from) {
for(int i=0; i<c->type; i++) {
cell *c2 = c->move(i);
if(c2 && c2->wall == waRose) nww++;
if(c2 && !ls::any_chaos()) for(int j=0; j<c2->type; j++) {
if(c2 && !ls::any_chaos() && !ls::hv_structure()) for(int j=0; j<c2->type; j++) {
cell *c3 = c2->move(j);
// note: c3->land is required for Android --
// not strictly equivalent since another land there might be not yet generated
@ -2089,6 +2089,12 @@ EX void giantLandSwitch(cell *c, int d, cell *from) {
case laOcean:
if(d >= 8) c->wall = waSea;
if(d == 7 && !safety) {
if(ls::horodisk_structure() && c->master->alt && horodisk_land[c->master->alt->alt] == laWhirlpool) {
if(hrand(100) < 10) c->wall = waBoat;
return;
}
bool placecolumn = false;
if(c->landparam % temple_layer_size() == 0 && c->landparam <= 24) {
int q = 0;
@ -2261,6 +2267,7 @@ EX void giantLandSwitch(cell *c, int d, cell *from) {
case laClearing:
if(d == 7) {
clearing::generate(c);
if(ls::horodisk_structure() && celldistAlt(c) >= -1) c->monst = moNone;
if(pseudohept(c)) {
int d = -celldistAlt(c);
if(hrand_monster(2500) < items[itMutant2] + yendor::hardness() - 10 && !reptilecheat)
@ -2460,6 +2467,7 @@ EX void giantLandSwitch(cell *c, int d, cell *from) {
int freq = 4000;
if(ls::single() && specialland == laCrossroads5 && !racing::on)
freq = 250;
if(ls::hv_structure() && hrand(10000) < 10) { c->monst = moPirate; }
if(hrand_monster(freq) < items[itHyperstone] && !c->monst) {
// only interesting monsters here!
eMonster cm = crossroadsMonster();
@ -2533,7 +2541,7 @@ EX void giantLandSwitch(cell *c, int d, cell *from) {
case laEclectic: {
if(d >= 9) c->wall = waChasm;
if(d >= (ls::hv_structure() ? 8 : 9)) c->wall = waChasm;
if(d == 8) wfc::schedule(c);

View File

@ -532,7 +532,7 @@ EX eLand getNewLand(eLand old) {
// the intermediate lands
if(all_unlocked || gold() >= R30) {
tab[cnt++] = laCrossroads;
tab[cnt++] = geometry ? laMirrorOld : laMirror;
tab[cnt++] = (geometry || ls::hv_structure()) ? laMirrorOld : laMirror;
tab[cnt++] = laOcean;
tab[cnt++] = laLivefjord;
if(all_unlocked || kills[moVizier]) tab[cnt++] = laEmerald;
@ -548,7 +548,7 @@ EX eLand getNewLand(eLand old) {
if(all_unlocked || rlyehComplete()) tab[cnt++] = laRlyeh;
else if(ls::std_chaos() && (old == laWarpCoast || old == laLivefjord || old == laOcean))
tab[cnt++] = laRlyeh;
if((all_unlocked || items[itStatue] >= U5) && ls::std_chaos())
if((all_unlocked || items[itStatue] >= U5) && (ls::std_chaos() || ls::horodisk_structure()))
tab[cnt++] = laTemple;
if(old == laCrossroads || old == laCrossroads2) tab[cnt++] = laOcean;
if(old == laOcean) tab[cnt++] = laCrossroads;
@ -563,6 +563,9 @@ EX eLand getNewLand(eLand old) {
tab[cnt++] = laDual;
tab[cnt++] = laSnakeNest;
}
if(landUnlocked(laMountain)) tab[cnt++] = laMountain;
if(landUnlocked(laClearing)) tab[cnt++] = laClearing;
if(landUnlocked(laTrollheim)) {
if(isTrollLand(old)) LIKELY tab[cnt++] = laTrollheim;
@ -731,6 +734,7 @@ namespace lv {
land_validity_t not_in_shmup = {0, q0, "This land is not available in the shmup mode."};
land_validity_t not_in_multi = {0, q0, "This land is not available in multiplayer."};
land_validity_t single_only = {2, q0 | switch_to_single, "Available in single land mode only." };
land_validity_t not_in_hv = { 0, q0, "Does not work in horodisk/Voronoi mode."};
}
// old Daily Challenges should keep their validity forever
@ -853,6 +857,8 @@ EX land_validity_t& land_validity(eLand l) {
if(l == laBurial && !shmup::on) return not_implemented;
if(l == laMirrorOld && !shmup::on) return not_implemented;
}
if(ls::hv_structure() && among(l, laPrairie, laIvoryTower, laDungeon, laEndorian, laBrownian, laTortoise, laElementalWall)) return not_in_hv;
if(l == laBrownian) {
if(quotient || !hyperbolic || cryst) return dont_work;
@ -935,12 +941,14 @@ EX land_validity_t& land_validity(eLand l) {
if(l == laWhirlwind && hyperbolic_not37)
return pattern_incompatibility;
bool better_mirror = !geometry && STDVAR && !ls::hv_structure();
// available only in non-standard geometries
if(l == laMirrorOld && !geometry && STDVAR)
if(l == laMirrorOld && better_mirror)
return better_version_exists;
// available only in standard geometry
if(l == laMirror && (geometry || NONSTDVAR))
if(l == laMirror && !better_mirror)
return not_implemented;
// Halloween needs bounded world (can be big bounded)

View File

@ -1770,6 +1770,7 @@ auto cgm = addHook(hooks_clearmemory, 40, [] () {
crush_next.clear();
crush_now.clear();
rosemap.clear();
horodisk_land.clear();
for(auto &am: adj_memo) am.clear();
}) +
addHook(hooks_gamedata, 0, [] (gamedata* gd) {