mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2024-11-20 03:54:47 +00:00
3d:: Great Walls in H3 geometries
This commit is contained in:
parent
5038686a5b
commit
3f836d1dfe
86
barriers.cpp
86
barriers.cpp
@ -336,6 +336,8 @@ bool isbar4(cell *c) {
|
||||
c->land == laMercuryRiver;
|
||||
}
|
||||
|
||||
void extend3D(cell *c);
|
||||
|
||||
void extendBarrier(cell *c) {
|
||||
limitgen("extend barrier %p\n", c);
|
||||
if(buggyGeneration) return;
|
||||
@ -357,7 +359,8 @@ void extendBarrier(cell *c) {
|
||||
}
|
||||
|
||||
if(c->barleft == NOWALLSEP) {
|
||||
extendNowall(c);
|
||||
if(DIM == 3) extend3D(c);
|
||||
else extendNowall(c);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -731,11 +734,92 @@ void buildCrossroads2(cell *c) {
|
||||
}
|
||||
}
|
||||
|
||||
void extend3D(cell *c) {
|
||||
eLand l1 = c->land;
|
||||
c->barleft = NOWALLSEP_USED;
|
||||
|
||||
cellwalker cw(c, c->bardir);
|
||||
|
||||
if(S3 == 5) {
|
||||
cw += wstep; cw += rev;
|
||||
cw.at->bardir = NOBARRIERS;
|
||||
setland(cw.at, laBarrier);
|
||||
}
|
||||
|
||||
auto cw1 = cw + wstep;
|
||||
setland(cw1.at, c->barright);
|
||||
if(cw1.at->bardir == NODIR) {
|
||||
cw1.at->barleft = NOWALLSEP_USED;
|
||||
cw1.at->barright = l1;
|
||||
cw1.at->bardir = cw1.spin;
|
||||
}
|
||||
|
||||
for(int j=0; j<S7; j++) if(reg3::dirs_adjacent[cw.spin][j]) {
|
||||
cellwalker bb2 = reg3::strafe(cw, j);
|
||||
if(S3 == 5) { bb2 += rev; bb2 += wstep; }
|
||||
|
||||
if(bb2.at->bardir == NODIR) {
|
||||
bb2.at->bardir = bb2.spin;
|
||||
bb2.at->barleft = NOWALLSEP;
|
||||
bb2.at->barright = c->barright;
|
||||
bb2.at->land = l1;
|
||||
// bb2.at->item = itGold;
|
||||
extendBarrier(bb2.at);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool built = false;
|
||||
|
||||
bool buildBarrier3D(cell *c, eLand l2, int forced_dir) {
|
||||
if(forced_dir == NODIR) {
|
||||
for(int t=0; t<S7; t++) if((!c->move(t) || c->move(t)->mpdist > c->mpdist) && buildBarrier3D(c, l2, t)) return true;
|
||||
return false;
|
||||
}
|
||||
cellwalker cw(c, forced_dir);
|
||||
if(S3 == 5) { cw += wstep; cw += rev; }
|
||||
set<cell*> listed_cells = { cw.at };
|
||||
vector<cellwalker> to_test { cw };
|
||||
for(int i=0; i<isize(to_test); i++) {
|
||||
auto bb = to_test[i];
|
||||
if(bb.at->mpdist < BARLEV) return false;
|
||||
if(bb.cpeek()->mpdist < BARLEV) return false;
|
||||
if(bb.cpeek()->bardir != NODIR) return false;
|
||||
if(S3 == 5 && (bb+rev).cpeek()->mpdist < BARLEV) return false;
|
||||
if(S3 == 5 && (bb+rev).cpeek()->bardir != NODIR) return false;
|
||||
if(bb.at->bardir != NODIR) return false;
|
||||
for(int j=0; j<S7; j++) {
|
||||
if(S3 == 5 && i <= 5) bb.at->cmove(j);
|
||||
if(reg3::dirs_adjacent[bb.spin][j] && bb.at->move(j)) {
|
||||
cellwalker bb2 = reg3::strafe(bb, j);
|
||||
if(listed_cells.count(bb2.at)) continue;
|
||||
listed_cells.insert(bb2.at);
|
||||
to_test.push_back(bb2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(int i=0; i<isize(to_test); i++) {
|
||||
auto bb = to_test[i];
|
||||
if(S3 == 5) { bb.at->bardir = NOBARRIERS; setland(bb.at, laBarrier); bb += rev; bb += wstep; }
|
||||
bb.at->land = c->land;
|
||||
bb.at->bardir = bb.spin;
|
||||
bb.at->barleft = NOWALLSEP;
|
||||
bb.at->barright = l2;
|
||||
extendBarrier(bb.at);
|
||||
}
|
||||
|
||||
built = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool buildBarrierNowall(cell *c, eLand l2, int forced_dir) {
|
||||
|
||||
// 3D binary tilings create walls using their own methods
|
||||
if(DIM == 3 && binarytiling) return false;
|
||||
|
||||
if(DIM == 3 && hyperbolic) return buildBarrier3D(c, l2, forced_dir);
|
||||
|
||||
if(c->land == laNone) {
|
||||
printf("barrier nowall! [%p]\n", c);
|
||||
raiseBuggyGeneration(c, "barrier nowall!");
|
||||
|
@ -2414,7 +2414,7 @@ void repairLandgen(cell *c) {
|
||||
}
|
||||
|
||||
if(passable(c, NULL, 0)) {
|
||||
if(c->land == laBarrier) c->wall = waBarrier;
|
||||
if(c->land == laBarrier && DIM != 3) c->wall = waBarrier;
|
||||
if(c->land == laOceanWall)
|
||||
c->wall = c->type == 7 ? waBarrier : waSea;
|
||||
}
|
||||
@ -2467,10 +2467,9 @@ void setdist(cell *c, int d, cell *from) {
|
||||
if(cseek->master->emeraldval) setland(c, eLand(cseek->master->emeraldval));
|
||||
}
|
||||
|
||||
if(!c->land && from && from->land != laElementalWall && from->land != laHauntedWall && from->land != laOceanWall &&
|
||||
from->land != laBarrier && !quotient) {
|
||||
if(!hasbardir(c)) setland(c, from->land);
|
||||
}
|
||||
if(!c->land && from && (DIM == 3 || among(from->land, laBarrier, laElementalWall, laHauntedWall, laOceanWall)) && !quotient) {
|
||||
if(!hasbardir(c)) setland(c, from->land);
|
||||
}
|
||||
if(c->land == laTemple && !tactic::on && !chaosmode) setland(c, laRlyeh);
|
||||
if(c->land == laMountain && !tactic::on && !chaosmode) setland(c, laJungle);
|
||||
if(c->land == laClearing && !tactic::on) setland(c, laOvergrown);
|
||||
|
29
reg3.cpp
29
reg3.cpp
@ -34,6 +34,9 @@ namespace reg3 {
|
||||
|
||||
transmatrix spins[12], adjmoves[12];
|
||||
|
||||
ld adjcheck, strafedist;
|
||||
bool dirs_adjacent[16][16];
|
||||
|
||||
template<class T> ld binsearch(ld dmin, ld dmax, const T& f) {
|
||||
for(int i=0; i<200; i++) {
|
||||
ld d = (dmin + dmax) / 2;
|
||||
@ -154,7 +157,18 @@ namespace reg3 {
|
||||
println(hlog, "center of ", a, " is ", tC0(adjmoves[a]));
|
||||
|
||||
println(hlog, "doublemove = ", tC0(adjmoves[0] * adjmoves[0]));
|
||||
// exit(1);
|
||||
|
||||
adjcheck = hdist(tC0(adjmoves[0]), tC0(adjmoves[1])) * 1.0001;
|
||||
|
||||
int numedges = 0;
|
||||
for(int a=0; a<S7; a++) for(int b=0; b<S7; b++) {
|
||||
dirs_adjacent[a][b] = a != b && hdist(tC0(adjmoves[a]), tC0(adjmoves[b])) < adjcheck;
|
||||
if(dirs_adjacent[a][b]) numedges++;
|
||||
}
|
||||
println(hlog, "numedges = ", numedges);
|
||||
|
||||
if(loop == 4) strafedist = adjcheck;
|
||||
else strafedist = hdist(adjmoves[0] * C0, adjmoves[1] * C0);
|
||||
}
|
||||
|
||||
void binary_rebase(heptagon *h, const transmatrix& V) {
|
||||
@ -537,6 +551,19 @@ int dist_alt(cell *c) {
|
||||
}
|
||||
#endif
|
||||
|
||||
// Construct a cellwalker in direction j from cw.at, such that its direction is as close
|
||||
// as possible to cw.spin. Assume that j and cw.spin are adjacent
|
||||
|
||||
cellwalker strafe(cellwalker cw, int j) {
|
||||
hyperpoint hfront = tC0(adjmoves[cw.spin]);
|
||||
transmatrix T = currentmap->relative_matrix(cw.at->cmove(j)->master, cw.at->master);
|
||||
for(int i=0; i<S7; i++) if(i != cw.at->c.spin(j))
|
||||
if(hdist(hfront, T * tC0(adjmoves[i])) < strafedist + .01)
|
||||
return cellwalker(cw.at->move(j), i);
|
||||
println(hlog, "incorrect strafe");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user