1
0
mirror of https://github.com/zenorogue/hyperrogue.git synced 2024-12-24 01:00:25 +00:00

3d:: in Euclidean, lands are generated just like in Crystal

This commit is contained in:
Zeno Rogue 2019-04-12 00:17:50 +02:00
parent c1373e64f7
commit 7c59f572ca
5 changed files with 115 additions and 64 deletions

View File

@ -39,6 +39,7 @@ int celldistAltRelative(cell *c) {
#if CAP_CRYSTAL
if(geometry == gCrystal) return crystal::dist_relative(c);
#endif
if(euclid && DIM == 3) return euclid3::dist_relative(c);
if(euwrap) return celldistAlt(c) - roundTableRadius(c);
if(sphere || quotient) {
return celldist(c) - 3;
@ -857,6 +858,8 @@ void setLandSphere(cell *c) {
}
eLand euland[max_vec];
map<int, eLand> euland3;
map<int, eLand> euland3_hash;
eLand& get_euland(int c) {
return euland[c & (max_vec-1)];
@ -865,6 +868,8 @@ eLand& get_euland(int c) {
void clear_euland(eLand first) {
for(int i=0; i<max_vec; i++) euland[i] = laNone;
euland[0] = euland[1] = euland[max_vec-1] = first;
euland3.clear();
euland3[0] = laCrossroads;
}
eLand switchable(eLand nearland, eLand farland, int c) {
@ -1029,6 +1034,69 @@ void setLandEuclid(cell *c) {
}
}
eLand get_euland3(int x) {
if(euland3.count(x)) return euland3[x];
if(x > 0) return euland3[x] = getNewLand(euland3[x-1]);
if(x < 0) return euland3[x] = getNewLand(euland3[x+1]);
return euland3[x] = laCrossroads;
}
void set_euland3(cell *c, int co10, int co11, int alt, int hash) {
if(chaosmode) {
setland(c, get_euland3(gdiv(co10, 60)));
}
else if(specialland == laCrossroads) {
eLand l1 = get_euland3(gdiv(co10, 360));
eLand l2 = get_euland3(gdiv(co10+59, 360));
if(l1 != l2 && hrand(100) < 75) setland(c, laBarrier);
else setland(c, l1);
}
else if(specialland == laCrossroads2) {
setland(c, get_euland3(alt/4));
}
else if(specialland == laCrossroads3) {
auto& l = euland3_hash[hash];
if(l == laNone) l = getNewLand(laBarrier);
setland(c, l);
}
else if(specialland == laCrossroads4) {
setland(c, get_euland3(gdiv(co10, 360)));
}
else if(specialland == laElementalWall) {
setland(c, eLand(laEFire + ((co10 / 240)&1?0:2) + ((co11 / 240)&1?0:1)));
}
if(specialland == laCamelot) {
setland(c, laCrossroads);
buildCamelot(c);
}
if(specialland == laTerracotta) {
if(((alt&15) == 8) && hrand(100) < 90)
c->wall = waMercury;
}
if(among(specialland, laOcean, laIvoryTower, laDungeon, laEndorian)) {
if(alt == 0)
c->land = laCrossroads4;
else if(alt > 0)
c->landparam = alt;
else
c->landparam = -alt;
}
if(specialland == laWarpCoast) {
if(gmod(co10, 240) >= 120)
c->land = laWarpSea;
}
}
// the main big stuff function
bool quickfind(eLand l) {

View File

@ -1002,78 +1002,18 @@ void build_rugdata() {
println(hlog, "cut ", cut_level, "r ", crug_rotation);
}
eLand getCLand(int x) {
auto& landmemo = crystal_map()->landmemo;
if(landmemo.count(x)) return landmemo[x];
if(x > 0) return landmemo[x] = getNewLand(landmemo[x-1]);
if(x < 0) return landmemo[x] = getNewLand(landmemo[x+1]);
return landmemo[x] = laCrossroads;
}
void set_land(cell *c) {
setland(c, specialland);
auto m = crystal_map();
auto co = m->get_coord(c);
auto co1 = roundcoord(co * 60);
int cv = co1[0];
if(chaosmode) {
setland(c, getCLand(gdiv(cv, 60)));
}
else if(specialland == laCrossroads) {
eLand l1 = getCLand(gdiv(cv, 360));
eLand l2 = getCLand(gdiv(cv+59, 360));
if(l1 != l2 && hrand(100) < 75) setland(c, laBarrier);
else setland(c, l1);
}
else if(specialland == laCrossroads2) {
setland(c, getCLand(dist_alt(c)/4));
}
else if(specialland == laCrossroads3) {
coord cx = roundcoord(co / 8);
auto& l = m->landmemo4[cx];
if(l == laNone) l = getNewLand(laBarrier);
setland(c, l);
}
else if(specialland == laCrossroads4) {
setland(c, getCLand(gdiv(cv, 360)));
}
coord cx = roundcoord(co / 8);
int hash = 0;
for(int a=0; a<m->cs.dim; a++) hash = 1317 * hash + cx[a];
else if(specialland == laElementalWall) {
setland(c, eLand(laEFire + ((co1[0] / 240)&1?0:2) + ((co1[1] / 240)&1?0:1)));
}
if(specialland == laCamelot) {
setland(c, laCrossroads);
buildCamelot(c);
}
if(specialland == laTerracotta) {
int v = dist_alt(c);
if(((v&15) == 8) && hrand(100) < 90)
c->wall = waMercury;
}
if(among(specialland, laOcean, laIvoryTower, laDungeon, laEndorian)) {
int v = dist_alt(c);
if(v == 0)
c->land = laCrossroads4;
else if(v > 0)
c->landparam = v;
else
c->landparam = -v;
}
if(specialland == laWarpCoast) {
if(gmod(cv, 240) >= 120)
c->land = laWarpSea;
}
set_euland3(c, co1[0], co1[1], dist_alt(c), hash);
}
void set_crystal(int sides) {
@ -1412,6 +1352,9 @@ void transform_crystal_to_euclid () {
for(int i=0; i<S7; i++) c->move(i) = NULL;
}
if(m->camelot_center)
e->camelot_center = e->spacemap[crystal_to_euclid(m->hcoords[m->camelot_center->master])]->c7;
// clean hcoords and heptagon_at so that the map is not deleted when we delete m
m->hcoords.clear();
m->heptagon_at.clear();
@ -1475,6 +1418,9 @@ void transform_euclid_to_crystal () {
for(int i=0; i<S7; i++) c->move(i) = NULL;
}
if(e->camelot_center)
m->camelot_center = m->heptagon_at[euclid3_to_crystal(e->ispacemap[e->camelot_center->master])]->c7;
e->spacemap.clear();
e->ispacemap.clear();
delete e;

View File

@ -552,12 +552,14 @@ namespace euclid3 {
vector<transmatrix> tmatrix;
map<coord, heptagon*> spacemap;
map<heptagon*, coord> ispacemap;
cell *camelot_center;
hrmap_euclid3() {
shifttable = get_shifttable();
tmatrix.resize(S7);
for(int i=0; i<S7; i++) tmatrix[i] = Id;
for(int i=0; i<S7; i++) for(int j=0; j<3; j++)
tmatrix[i][j][DIM] = getcoord(shifttable[i])[j];
camelot_center = NULL;
}
heptagon *getOrigin() {
@ -666,6 +668,7 @@ namespace euclid3 {
}
int dist_alt(cell *c) {
if(specialland == laCamelot) return dist_relative(c) + roundTableRadius(c);
coord co = cubemap()->ispacemap[c->master];
auto v = getcoord(co);
if(S7 == 6) return v[2];
@ -713,6 +716,34 @@ namespace euclid3 {
}
}
void set_land(cell *c) {
setland(c, specialland);
auto m = cubemap();
auto co = getcoord(m->ispacemap[c->master]);
int dv = 1;
if(geometry != gCubeTiling) dv = 2;
int hash = 0;
for(int a=0; a<3; a++) hash = 1317 * hash + co[a] / 4;
set_euland3(c, co[0]*120, co[1]*120, (co[1]+co[2]) / dv, hash);
}
int dist_relative(cell *c) {
auto m = cubemap();
auto& cc = m->camelot_center;
int r = roundTableRadius(NULL);
cell *start = m->gamestart();
if(!cc) {
cc = start;
while(euclid3::celldistance(cc, start) < r + 5)
cc = cc->cmove(hrand(cc->type));
}
return euclid3::celldistance(cc, c) - r;
}
}
#endif

View File

@ -4362,6 +4362,7 @@ namespace binary {
namespace euclid3 {
hrmap* new_map();
void draw();
int dist_relative(cell *c);
}
namespace reg3 {
@ -5003,5 +5004,7 @@ namespace subscreens {
const int TEXTURE_STEP_3D=8;
void set_euland3(cell *c, int co0, int co1, int alt, int hash);
}

View File

@ -2500,6 +2500,9 @@ void setdist(cell *c, int d, cell *from) {
#if CAP_CRYSTAL
else if(geometry == gCrystal) crystal::set_land(c);
#endif
#if MAXMDIM == 4
else if(euclid && DIM == 3) euclid3::set_land(c);
#endif
else if(sphere || fulltorus) setLandSphere(c);
else if(euclid) setLandEuclid(c);
else if(quotient) { setland(c, specialland); setLandQuotient(c); }