1
0
mirror of https://github.com/zenorogue/hyperrogue.git synced 2024-11-30 15:39:54 +00:00

3D graphics in 2D (first commit)

This commit is contained in:
Zeno Rogue 2019-05-08 18:33:08 +02:00
parent ea768b634b
commit 1c4d86e0e9
27 changed files with 424 additions and 269 deletions

View File

@ -27,7 +27,11 @@ hyperpoint get_center(const vector<hyperpoint>& vh) {
return normalize(h);
}
ld zc(ld z) { return geom3::human_height * (z - 0.5); }
ld zc(ld z) {
if(WDIM == 2 && GDIM == 3)
return geom3::lev_to_factor(geom3::human_height * z);
return geom3::human_height * (z - 0.5);
}
transmatrix zpush(ld z) {
return cpush(2, z);
@ -487,7 +491,6 @@ void make_paw_3d(hpcshape& sh, hpcshape& legsh) {
add_prism_sync(zc(0.1), leg, zc(0.4), leg);
add_cone(zc(0.4), leg, zc(0.45));
add_texture(sh);
shift_last(-geom3::LEG0);
}
void make_abody_3d(hpcshape& sh, ld tail) {
@ -508,6 +511,7 @@ void make_abody_3d(hpcshape& sh, ld tail) {
add_cone(zc(0.4), body8, zc(0.36));
add_cone(zc(0.6), body8, zc(0.64));
add_texture(sh);
if(GDIM == 3 && WDIM == 2) shift_last(-geom3::ABODY);
}
void make_ahead_3d(hpcshape& sh) {
@ -760,33 +764,35 @@ void make_3d_models() {
// make_abody_3d(shWolfBody, 0.01);
// make_ahead_3d(shWolfHead);
// make_ahead_3d(shFamiliarHead);
make_revolution_cut(shWolfBody, 30, 0, 0.01*S);
make_revolution_cut(shWolfHead, 180, geom3::AHEAD - geom3::ABODY);
make_revolution_cut(shFamiliarHead, 30, geom3::AHEAD - geom3::ABODY);
ld g = WDIM == 2 ? geom3::ABODY - zc(0.4) : 0;
make_revolution_cut(shWolfBody, 30, g, 0.01*S);
make_revolution_cut(shWolfHead, 180, geom3::AHEAD - geom3::ABODY +g);
make_revolution_cut(shFamiliarHead, 30, geom3::AHEAD - geom3::ABODY +g);
// make_abody_3d(shDogTorso, 0.01);
make_revolution_cut(shDogTorso, 30);
make_revolution_cut(shDogHead, 180, geom3::AHEAD - geom3::ABODY);
make_revolution_cut(shDogTorso, 30, +g);
make_revolution_cut(shDogHead, 180, geom3::AHEAD - geom3::ABODY +g);
// make_ahead_3d(shDogHead);
// make_abody_3d(shCatBody, 0.05);
// make_ahead_3d(shCatHead);
make_revolution_cut(shCatBody, 30);
make_revolution_cut(shCatHead, 180, geom3::AHEAD - geom3::ABODY);
make_revolution_cut(shCatBody, 30, +g);
make_revolution_cut(shCatHead, 180, geom3::AHEAD - geom3::ABODY +g);
make_paw_3d(shReptileFrontFoot, shReptileFrontLeg);
make_paw_3d(shReptileRearFoot, shReptileRearLeg);
make_abody_3d(shReptileBody, -1);
// make_ahead_3d(shReptileHead);
make_revolution_cut(shReptileHead, 180, geom3::AHEAD - geom3::ABODY);
make_revolution_cut(shReptileHead, 180, geom3::AHEAD - geom3::ABODY+g);
make_paw_3d(shBullFrontHoof, shBullFrontHoof);
make_paw_3d(shBullRearHoof, shBullRearHoof);
// make_abody_3d(shBullBody, 0.05);
// make_ahead_3d(shBullHead);
// make_ahead_3d(shBullHorn);
make_revolution_cut(shBullBody, 180);
make_revolution_cut(shBullHead, 60, geom3::AHEAD - geom3::ABODY);
make_revolution_cut(shBullBody, 180, +g);
make_revolution_cut(shBullHead, 60, geom3::AHEAD - geom3::ABODY +g);
shift_shape(shBullHorn, -(geom3::AHEAD - geom3::ABODY));
// make_revolution_cut(shBullHorn, 180, geom3::AHEAD - geom3::ABODY);
@ -794,7 +800,7 @@ void make_3d_models() {
make_paw_3d(shTrylobiteRearClaw, shTrylobiteRearLeg);
make_abody_3d(shTrylobiteBody, 0);
// make_ahead_3d(shTrylobiteHead);
make_revolution_cut(shTrylobiteHead, 180, geom3::AHEAD - geom3::ABODY);
make_revolution_cut(shTrylobiteHead, 180, geom3::AHEAD - geom3::ABODY +g);
make_revolution_cut(shShark, 180);

View File

@ -359,7 +359,7 @@ void extendBarrier(cell *c) {
}
if(c->barleft == NOWALLSEP) {
if(DIM == 3) extend3D(c);
if(WDIM == 3) extend3D(c);
else extendNowall(c);
return;
}
@ -819,9 +819,9 @@ bool buildBarrierNowall(cell *c, eLand l2, int forced_dir) {
#if MAXMDIM >= 4
// 3D binary tilings create walls using their own methods
if(DIM == 3 && binarytiling) return false;
if(WDIM == 3 && binarytiling) return false;
if(DIM == 3 && hyperbolic) return buildBarrier3D(c, l2, forced_dir);
if(WDIM == 3 && hyperbolic) return buildBarrier3D(c, l2, forced_dir);
#endif
if(c->land == laNone) {

View File

@ -41,7 +41,7 @@ int celldistAltRelative(cell *c) {
if(geometry == gCrystal) return crystal::dist_relative(c);
#endif
#if MAXMDIM >= 4
if(euclid && DIM == 3) return euclid3::dist_relative(c);
if(euclid && WDIM == 3) return euclid3::dist_relative(c);
#endif
if(euwrap) return celldistAlt(c) - roundTableRadius(c);
if(sphere || quotient) {
@ -468,7 +468,7 @@ int coastval(cell *c, eLand base) {
bool checkInTree(cell *c, int maxv) {
if(c->landparam <= 3) return false;
if(!maxv && DIM == 3 && binarytiling) {
if(!maxv && WDIM == 3 && binarytiling) {
forCellEx(c2, c) if(c2->landflags) return true;
}
if(!maxv) return false;
@ -522,7 +522,7 @@ void buildEquidistant(cell *c) {
// if(generatingEquidistant) printf("mcv=0\n");
c->landparam = 1;
}
else if(DIM == 3) {
else if(WDIM == 3) {
forCellCM(c2, c) if(coastval(c2, b) == mcv)
forCellEx(c3, c2) if(coastval(c3, b) < mcv)
forCellCM(c4, c3) {
@ -593,23 +593,23 @@ void buildEquidistant(cell *c) {
int skip = geometry == gHoroRec ? 3 : 2;
if(c->landparam == 1)
c->landflags = (hrand(100) < 20);
else if(DIM == 2 && c->type == 6 && (c->landparam % 2) && c->move(binary::bd_down) && c->move(binary::bd_down)->landflags)
else if(WDIM == 2 && c->type == 6 && (c->landparam % 2) && c->move(binary::bd_down) && c->move(binary::bd_down)->landflags)
c->landflags = 1;
else if(DIM == 2 && c->type == 7 && (c->landparam % 2 == 0)) {
else if(WDIM == 2 && c->type == 7 && (c->landparam % 2 == 0)) {
for(int d: {binary::bd_down_left, binary::bd_down_right})
if(c->move(d) && c->move(d)->landflags)
c->landflags = 1;
}
else if(DIM == 3 && c->landparam % skip != 1 && c->move(S7-1) && c->move(S7-1)->landflags)
else if(WDIM == 3 && c->landparam % skip != 1 && c->move(S7-1) && c->move(S7-1)->landflags)
c->landflags = 1;
else if(DIM == 3 && c->landparam % skip == 1 && c->move(S7-1) && c->move(S7-1)->c.spin(S7-1) == (c->c.spin(S7-1)) && c->move(S7-1)->move(S7-1)->landflags)
else if(WDIM == 3 && c->landparam % skip == 1 && c->move(S7-1) && c->move(S7-1)->c.spin(S7-1) == (c->c.spin(S7-1)) && c->move(S7-1)->move(S7-1)->landflags)
c->landflags = 1;
if(c->landflags) c->wall = (DIM == 3 ? waTrunk3 : waTrunk);
if(c->landflags) c->wall = (WDIM == 3 ? waTrunk3 : waTrunk);
}
else
#endif
#if MAXMDIM >= 4
if(DIM == 3 && hyperbolic) {
if(WDIM == 3 && hyperbolic) {
if(c->landparam == 1)
c->landflags = (hrand(100) < 20);
else if(S7 == 12) {
@ -1201,7 +1201,7 @@ bool deep_ocean_at(cell *c, cell *from) {
bool good_for_wall(cell *c) {
if(archimedean) return true;
if(DIM == 3) return true;
if(WDIM == 3) return true;
return pseudohept(c);
}
@ -1471,7 +1471,7 @@ void buildCamelot(cell *c) {
int masterAlt(cell *c) {
#if MAXMDIM >= 4
if(DIM == 3 && hyperbolic) return reg3::altdist(c->master);
if(WDIM == 3 && hyperbolic) return reg3::altdist(c->master);
#endif
return c->master->alt->distance;
}
@ -1533,7 +1533,7 @@ void moreBigStuff(cell *c) {
else if(geometry == gHoroTris || geometry == gHoroRec) {
if(c->c.spin(S7-1) != 0) c->wall = waColumn;
}
else if(DIM == 3) {
else if(WDIM == 3) {
if(c->master->zebraval != 1) c->wall = waColumn;
}
else if(weirdhyperbolic && !BITRUNCATED) {

View File

@ -97,7 +97,7 @@ namespace binary {
h->cdata = NULL;
h->zebraval = side;
h->emeraldval = 0;
if(DIM == 3 && h->c7) {
if(WDIM == 3 && h->c7) {
if(!parent->emeraldval) parent->emeraldval = currentmap->gamestart()->land;
eLand z = eLand(parent->emeraldval);
int chance = 0;
@ -337,7 +337,7 @@ namespace binary {
if(!do_draw(c, V)) continue;
drawcell(c, V, 0, false);
if(DIM == 2) {
if(WDIM == 2) {
dq::enqueue(h->move(bd_up), V * xpush(-log(2)));
dq::enqueue(h->move(bd_right), V * parabolic(1));
dq::enqueue(h->move(bd_left), V * parabolic(-1));
@ -366,7 +366,7 @@ namespace binary {
transmatrix gm = Id, where = Id;
while(h1 != h2) {
if(h1->distance <= h2->distance) {
if(DIM == 3)
if(WDIM == 3)
where = itmatrix(h2, S7-1) * where, h2 = may_create_step(h2, S7-1);
else {
if(type_of(h2) == 6)
@ -378,7 +378,7 @@ namespace binary {
}
}
else {
if(DIM == 3)
if(WDIM == 3)
gm = gm * tmatrix(h1, S7-1), h1 = may_create_step(h1, S7-1);
else {
if(type_of(h1) == 6)
@ -609,7 +609,7 @@ auto bt_config = addHook(hooks_args, 0, [] () {
#endif
bool pseudohept(cell *c) {
if(DIM == 2)
if(WDIM == 2)
return c->type & c->master->distance & 1;
else if(geometry == gHoroRec)
return c->c.spin(S7-1) == 0 && (c->master->distance & 1) && c->cmove(S7-1)->c.spin(S7-1) == 0;

View File

@ -68,7 +68,7 @@ hrmap_hyperbolic::hrmap_hyperbolic() {
binary::rxcode[1<<16] = &h;
#endif
h.zebraval = 0, h.emeraldval = 0,
h.c7 = newCell(DIM == 3 ? S7 : 6, origin);
h.c7 = newCell(WDIM == 3 ? S7 : 6, origin);
}
#endif
#if CAP_IRR
@ -225,12 +225,12 @@ void initcells() {
else if(archimedean) currentmap = arcm::new_map();
#endif
#if MAXMDIM >= 4
else if(euclid && DIM == 3) currentmap = euclid3::new_map();
else if(euclid && WDIM == 3) currentmap = euclid3::new_map();
#endif
else if(fulltorus) currentmap = new hrmap_torus;
else if(euclid) currentmap = new hrmap_euclidean;
#if MAXMDIM >= 4
else if(DIM == 3 && !binarytiling) currentmap = reg3::new_map();
else if(WDIM == 3 && !binarytiling) currentmap = reg3::new_map();
#endif
else if(sphere) currentmap = new hrmap_spherical;
else if(quotient) currentmap = new quotientspace::hrmap_quotient;
@ -320,7 +320,7 @@ void clearfrom(heptagon *at) {
}
}
int edges = at->degree();
if(binarytiling && DIM == 2) edges = at->c7->type;
if(binarytiling && WDIM == 2) edges = at->c7->type;
for(int i=0; i<edges; i++) if(at->move(i)) {
if(at->move(i)->alt != &deletion_marker)
q.push(at->move(i));
@ -399,13 +399,13 @@ int compdist(int dx[]) {
}
int celldist(cell *c) {
if(fulltorus && DIM == 2)
if(fulltorus && WDIM == 2)
return torusmap()->dists[decodeId(c->master)];
if(euwrap)
return torusconfig::cyldist(decodeId(c->master), 0);
if(masterless)
return eudist(decodeId(c->master));
if(sphere || binarytiling || DIM == 3 || geometry == gCrystal) return celldistance(c, currentmap->gamestart());
if(sphere || binarytiling || WDIM == 3 || geometry == gCrystal) return celldistance(c, currentmap->gamestart());
#if CAP_IRR
if(IRREGULAR) return irr::celldist(c, false);
#endif
@ -443,8 +443,8 @@ int celldistAlt(cell *c) {
return celldist(c) - 3;
}
#if MAXMDIM >= 4
if(euclid && DIM == 3) return euclid3::dist_alt(c);
if(hyperbolic && DIM == 3) return reg3::altdist(c->master);
if(euclid && WDIM == 3) return euclid3::dist_alt(c);
if(hyperbolic && WDIM == 3) return reg3::altdist(c->master);
#endif
if(!c->master->alt) return 0;
#if CAP_IRR
@ -812,7 +812,7 @@ int heptdistance(cell *c1, cell *c2) {
#if CAP_CRYSTAL
if(geometry == gCrystal) return crystal::space_distance(c1, c2);
#endif
if(!hyperbolic || quotient || DIM == 3) return celldistance(c1, c2);
if(!hyperbolic || quotient || WDIM == 3) return celldistance(c1, c2);
else return heptdistance(c1->master, c2->master);
}
@ -872,15 +872,15 @@ int celldistance(cell *c1, cell *c2) {
}
#if CAP_BT && MAXMDIM >= 4
if(binarytiling && DIM == 3)
if(binarytiling && WDIM == 3)
return binary::celldistance3(c1, c2);
#endif
#if MAXMDIM >= 4
if(euclid && DIM == 3)
if(euclid && WDIM == 3)
return euclid3::celldistance(c1, c2);
if(hyperbolic && DIM == 3) return reg3::celldistance(c1, c2);
if(hyperbolic && WDIM == 3) return reg3::celldistance(c1, c2);
#endif
return hyperbolic_celldistance(c1, c2);

View File

@ -1197,7 +1197,7 @@ namespace mirror {
cell *c = cw.at;
#if MAXMDIM >= 4
if(DIM == 3 && !binarytiling) {
if(WDIM == 3 && !binarytiling) {
if(shmup::on) for(int i=0; i<cw.at->type; i++)
createMirror(cw + i + wstep - i, cpid);
return;
@ -1228,7 +1228,7 @@ namespace mirror {
}
#endif
#if MAXMDIM >= 4
if(DIM == 3 && !binarytiling) {
if(WDIM == 3 && !binarytiling) {
if(shmup::on) for(int i=0; i<cw.at->type; i++)
createMirror(cw + i + wstep - i, cpid);
return;
@ -1959,7 +1959,7 @@ namespace heat {
int divby = 10;
if(S7 > 10) divby *= 2;
if(archimedean) divby *= 2;
if(DIM == 3) divby *= 2;
if(WDIM == 3) divby *= 2;
for(int i=0; i<dcs; i++) {
cell *c = allcells[i];
@ -3637,7 +3637,7 @@ namespace dungeon {
c->wall = waLadder;
}
else if(DIM == 3) {
else if(WDIM == 3) {
int cnt = 0;
int below = 0;
manual_celllister cl;
@ -3718,7 +3718,7 @@ namespace dungeon {
bool rdepths[5];
int switchcount = 0;
if(DIM == 3) {
if(WDIM == 3) {
for(int i=0; i<5; i++) rdepths[i] = false;
manual_celllister cl;
@ -3818,8 +3818,8 @@ namespace dungeon {
if(df&1) {
generate_around(c);
int df1 = DIM == 3 ? 0 : dungeonFlags(ts::left_of(c, coastvalEdge));
int df2 = DIM == 3 ? 0 : dungeonFlags(ts::right_of(c, coastvalEdge));
int df1 = WDIM == 3 ? 0 : dungeonFlags(ts::left_of(c, coastvalEdge));
int df2 = WDIM == 3 ? 0 : dungeonFlags(ts::right_of(c, coastvalEdge));
c->wparam = 0;
if(hrand(100) < (c->landparam % 5 == 0 ? 80 : 20)) {
@ -3847,7 +3847,7 @@ namespace dungeon {
if(q) downs[hrand(q)]->wall = waLadder;
*/
cell *c2 =
DIM == 3 ? random_child(c, coastvalEdge) :
WDIM == 3 ? random_child(c, coastvalEdge) :
c->wparam == 1 ? ts::add(c, 1, 2, coastvalEdge) :
c->wparam == 2 ? ts::add(c, -1, -2, coastvalEdge) :
c->wparam == 3 ? ts::add(c, 1, 3, coastvalEdge) :
@ -3902,7 +3902,7 @@ namespace dungeon {
void all(cell *c, int d) {
if(d == 8 && (c->land == laIvoryTower || c->land == laDungeon) && !euclid) {
if(hrand(1000) < 75 && (DIM == 3 || (c->landparam & 1))) {
if(hrand(1000) < 75 && (WDIM == 3 || (c->landparam & 1))) {
c->landflags = 3;
}
else c->landflags = 0;

View File

@ -361,6 +361,8 @@ void initConfig() {
addsaverenum(conformal::basic_model, "basic model");
addsaver(conformal::use_atan, "use_atan");
for(auto& g: sightranges) g = 10;
addsaver(sightranges[gBinary3], "sight-binary3", 3);
addsaver(sightranges[gCubeTiling], "sight-cubes", 7);
addsaver(sightranges[gCell120], "sight-120cell", 2 * M_PI);
@ -619,10 +621,10 @@ void add_cells_drawn(char c = 'C') {
void edit_sightrange() {
if(vid.use_smart_range) {
ld& det = DIM == 2 ? vid.smart_range_detail : vid.smart_range_detail_3;
dialog::editNumber(det, 1, 50, 1, DIM == 2 ? 8 : 30, XLAT("minimum visible cell in pixels"), "");
ld& det = WDIM == 2 ? vid.smart_range_detail : vid.smart_range_detail_3;
dialog::editNumber(det, 1, 50, 1, WDIM == 2 ? 8 : 30, XLAT("minimum visible cell in pixels"), "");
}
else if(DIM == 3) {
else if(WDIM == 3) {
dialog::editNumber(sightranges[geometry], 0, 2 * M_PI, 0.5, M_PI, XLAT("3D sight range"),
XLAT(
"Sight range for 3D geometries is specified in the absolute units. This value also affects the fog effect.\n\n"
@ -646,7 +648,7 @@ void edit_sightrange() {
dialog::extra_options = [] () {
dialog::addBoolItem(XLAT("draw range based on distance"), vid.use_smart_range == 0, 'D');
dialog::add_action([] () { vid.use_smart_range = 0; popScreen(); edit_sightrange(); });
if(DIM == 2 && allowIncreasedSight()) {
if(WDIM == 2 && allowIncreasedSight()) {
dialog::addBoolItem(XLAT("draw based on size in the projection (no generation)"), vid.use_smart_range == 1, 'N');
dialog::add_action([] () { vid.use_smart_range = 1; popScreen(); edit_sightrange(); });
}
@ -654,7 +656,7 @@ void edit_sightrange() {
dialog::addBoolItem(XLAT("draw based on size in the projection (generation)"), vid.use_smart_range == 2, 'G');
dialog::add_action([] () { vid.use_smart_range = 2; popScreen(); edit_sightrange(); });
}
if(vid.use_smart_range == 0 && allowChangeRange() && DIM == 2) {
if(vid.use_smart_range == 0 && allowChangeRange() && WDIM == 2) {
dialog::addSelItem(XLAT("generation range bonus"), its(genrange_bonus), 'O');
dialog::add_action([] () { genrange_bonus = sightrange_bonus; doOvergenerate(); });
dialog::addSelItem(XLAT("game range bonus"), its(gamerange_bonus), 'S');
@ -664,7 +666,7 @@ void edit_sightrange() {
dialog::addItem(XLAT("enable the cheat mode for additional options"), 'X');
dialog::add_action(enable_cheat);
}
if(DIM == 3 && !vid.use_smart_range) {
if(WDIM == 3 && !vid.use_smart_range) {
dialog::addBoolItem_action(XLAT("sloppy range checking"), vid.sloppy_3d, 'S');
}
if(DIM == 3 && !vid.use_smart_range) {
@ -681,8 +683,8 @@ void edit_sightrange() {
void menuitem_sightrange(char c) {
if(vid.use_smart_range)
dialog::addSelItem(XLAT("minimum visible cell in pixels"), fts(DIM == 3 ? vid.smart_range_detail_3 : vid.smart_range_detail), c);
else if(DIM == 3)
dialog::addSelItem(XLAT("minimum visible cell in pixels"), fts(WDIM == 3 ? vid.smart_range_detail_3 : vid.smart_range_detail), c);
else if(WDIM == 3)
dialog::addSelItem(XLAT("3D sight range"), fts(sightranges[geometry]), c);
else
dialog::addSelItem(XLAT("sight range"), its(sightrange_bonus), c);
@ -1189,7 +1191,7 @@ void show3D() {
dialog::addBreak(50);
}
if(DIM == 2) {
if(WDIM == 2) {
dialog::addSelItem(XLAT("Camera level above the plane"), fts3(camera), 'c');
dialog::addSelItem(XLAT("Ground level below the plane"), fts3(depth), 'g');
@ -1270,26 +1272,50 @@ void show3D() {
dialog::addBoolItem_action(XLAT("3D monsters/walls on the surface"), rug::spatial_rug, 'S');
}
#endif
dialog::addBoolItem(XLAT("configure TPP automatically"), pmodel == mdDisk && vid.camera_angle, 'T');
dialog::add_action([] () {
if(pmodel == mdDisk && vid.camera_angle) {
vid.yshift = 0;
vid.camera_angle = 0;
vid.xposition = 0;
vid.yposition = 0;
vid.scale = 1;
vid.fixed_facing = false;
}
else {
vid.yshift = -0.3;
vid.camera_angle = -45;
vid.scale = 18/16. * vid.xres / vid.yres / multi::players;
vid.xposition = 0;
vid.yposition = -0.9;
vid.fixed_facing = true;
vid.fixed_facing_dir = 90;
}
});
if(GDIM == 2) {
dialog::addBoolItem(XLAT("configure TPP automatically"), pmodel == mdDisk && vid.camera_angle, 'T');
dialog::add_action([] () {
if(pmodel == mdDisk && vid.camera_angle) {
vid.yshift = 0;
vid.camera_angle = 0;
vid.xposition = 0;
vid.yposition = 0;
vid.scale = 1;
vid.fixed_facing = false;
}
else {
vid.yshift = -0.3;
vid.camera_angle = -45;
vid.scale = 18/16. * vid.xres / vid.yres / multi::players;
vid.xposition = 0;
vid.yposition = -0.9;
vid.fixed_facing = true;
vid.fixed_facing_dir = 90;
}
});
}
if(WDIM == 2) {
dialog::addBoolItem(XLAT("configure FPP automatically"), DIM == 3, 'F');
dialog::add_action([] {
if(!geom3::always3) {
geom3::always3 = true;
geom3::wall_height = 1.5;
geom3::human_wall_ratio = 0.8;
geom3::camera = 0;
if(pmodel == mdDisk) pmodel = mdPerspective;
need_reset_geometry = true;
}
else {
geom3::always3 = false;
geom3::wall_height = .3;
geom3::human_wall_ratio = .7;
geom3::camera = 1;
if(pmodel == mdPerspective) pmodel = mdDisk;
need_reset_geometry = true;
}
});
}
if(0);
#if CAP_RUG
@ -1327,7 +1353,7 @@ void show3D() {
if(highdetail > middetail) highdetail = middetail;
};
}
else if(uni == 'c' && DIM == 2)
else if(uni == 'c' && WDIM == 2)
tc_camera = ticks,
dialog::editNumber(geom3::camera, 0, 5, .1, 1, XLAT("Camera level above the plane"), ""),
dialog::reaction = delayed_geo_reset,
@ -1344,7 +1370,7 @@ void show3D() {
fts3(atan(1/cosh(camera))*2/degree),
fts3(1/cosh(camera))));
};
else if(uni == 'g' && DIM == 2)
else if(uni == 'g' && WDIM == 2)
tc_depth = ticks,
dialog::editNumber(geom3::depth, 0, 5, .1, 1, XLAT("Ground level below the plane"), ""),
dialog::reaction = delayed_geo_reset,
@ -1366,9 +1392,9 @@ void show3D() {
fts3(depth), fts3(cosh(depth))));
// mention absolute units
};
else if(uni == 'a' && DIM == 2)
else if(uni == 'a' && WDIM == 2)
projectionDialog();
else if(uni == 'w' && DIM == 2) {
else if(uni == 'w' && WDIM == 2) {
dialog::editNumber(geom3::wall_height, 0, 1, .1, .3, XLAT("Height of walls"), "");
dialog::reaction = delayed_geo_reset;
dialog::extra_options = [] () {
@ -1386,13 +1412,13 @@ void show3D() {
});
};
}
else if(uni == 'l' && DIM == 2)
else if(uni == 'l' && WDIM == 2)
dialog::editNumber(geom3::lake_top, 0, 1, .1, .25, XLAT("Level of water surface"), ""),
dialog::reaction = delayed_geo_reset;
else if(uni == 'k' && DIM == 2)
else if(uni == 'k' && WDIM == 2)
dialog::editNumber(geom3::lake_bottom, 0, 1, .1, .9, XLAT("Level of water bottom"), ""),
dialog::reaction = delayed_geo_reset;
else if(uni == 'r' && DIM == 2)
else if(uni == 'r' && WDIM == 2)
dialog::editNumber(geom3::rock_wall_ratio, 0, 1, .1, .9, XLAT("Rock-III to wall ratio"), ""),
dialog::extra_options = [] { dialog::addHelp(XLAT(
"The ratio of Rock III to walls is %1, so Rock III are %2 absolute units high. "
@ -1402,7 +1428,7 @@ void show3D() {
fts3(cosh(depth - wall_height * rock_wall_ratio) / cosh(depth))));
},
dialog::reaction = delayed_geo_reset;
else if(uni == 'h' && DIM == 2)
else if(uni == 'h' && WDIM == 2)
dialog::editNumber(geom3::human_wall_ratio, 0, 1, .1, .7, XLAT("Human to wall ratio"), ""),
dialog::reaction = delayed_geo_reset,
dialog::extra_options = [] { dialog::addHelp(XLAT(
@ -1413,10 +1439,10 @@ void show3D() {
fts3(cosh(depth - wall_height * human_wall_ratio) / cosh(depth)))
);
};
else if(uni == 'h' && DIM == 3)
else if(uni == 'h' && WDIM == 3)
dialog::editNumber(geom3::height_width, 0, 1, .1, .7, XLAT("Height to width"), ""),
dialog::reaction = delayed_geo_reset;
else if(uni == 'c' && DIM == 3)
else if(uni == 'c' && WDIM == 3)
dialog::editNumber(geom3::creature_scale, 0, 1, .1, .7, XLAT("Creature scale"), ""),
dialog::reaction = delayed_geo_reset;
@ -1895,6 +1921,15 @@ int read_config_args() {
PHASEFROM(2);
nomenukey = true;
}
else if(argis("-al3")) {
PHASEFROM(2);
geom3::always3 = true;
geom3::wall_height = 1.5;
geom3::human_wall_ratio = 0.8;
geom3::camera = 0;
if(pmodel == mdDisk) pmodel = mdPerspective;
need_reset_geometry = true;
}
else if(argis("-nohelp")) {
PHASEFROM(2);
nohelp = true;

View File

@ -93,7 +93,9 @@ void remission() {
}
hyperpoint move_destination_vec(int d) {
if(DIM == 2) return spin(-d * M_PI/4) * tC0(pushone());
if(GDIM == 2) return spin(-d * M_PI/4) * tC0(pushone());
else if(WDIM == 2 && pmodel == mdPerspective) return cspin(0, 2, d * M_PI/4) * tC0(pushone());
else if(WDIM == 2) return spin(-d * M_PI/4) * tC0(pushone());
else if(d&1) return cspin(0, 1, d > 4 ? M_PI/2 : -M_PI/2) * tC0(pushone());
else return cspin(0, 2, d * M_PI/4) * tC0(pushone());
}

View File

@ -650,7 +650,7 @@ int read_cheat_args() {
PHASE(3); shift(); test_distances(argi());
}
else if(argis("-M")) {
PHASE(3) cheat(); start_game(); if(DIM == 3) { drawthemap(); bfs(); }
PHASE(3) cheat(); start_game(); if(WDIM == 3) { drawthemap(); bfs(); }
shift(); eMonster m = readMonster(args());
shift(); int q = argi();
printf("m = %s q = %d\n", dnameof(m), q);
@ -716,7 +716,7 @@ int read_cheat_args() {
else if(argis("-smart")) {
PHASEFROM(2); cheat();
vid.use_smart_range = 2;
shift_arg_formula(DIM == 3 ? vid.smart_range_detail_3 : vid.smart_range_detail);
shift_arg_formula(WDIM == 3 ? vid.smart_range_detail_3 : vid.smart_range_detail);
}
else if(argis("-smartn")) {
PHASEFROM(2);

View File

@ -160,7 +160,7 @@ struct fpattern {
matcode[M] = i, matrices.push_back(M);
for(int j=0; j<isize(qcoords); j++)
addas(mmul(M, qcoords[j]), i);
if(DIM == 3) add(mmul(X, M));
if(WDIM == 3) add(mmul(X, M));
add(mmul(R, M));
}
}
@ -221,8 +221,8 @@ struct fpattern {
return 1;
}
rotations = DIM == 2 ? S7 : 4;
local_group = DIM == 2 ? S7 : 24;
rotations = WDIM == 2 ? S7 : 4;
local_group = WDIM == 2 ? S7 : 24;
for(int pw=1; pw<3; pw++) {
if(pw>3) break;
@ -277,10 +277,10 @@ struct fpattern {
sh = sqrts[chx];
P[0][0] = sub(0, ch);
P[0][DIM] = sub(0, sh);
P[0][WDIM] = sub(0, sh);
P[1][1] = Prime-1;
P[DIM][0] = sh;
P[DIM][DIM] = ch;
P[WDIM][0] = sh;
P[WDIM][WDIM] = ch;
matrix Z1 = mmul(P, R);
matrix Z = Z1;
@ -332,7 +332,7 @@ struct fpattern {
DEBB(DF_FIELD, (debugfile, "Number of heptagons: %d\n", N));
if(DIM == 3) return;
if(WDIM == 3) return;
rrf.resize(N); rrf[0] = S7-1;
for(int i=0; i<N; i++)
@ -423,7 +423,7 @@ struct fpattern {
void analyze() {
if(DIM == 3) return;
if(WDIM == 3) return;
DEBB(DF_FIELD, (debugfile, "variation = %d\n", int(variation)));
int N = connections.size();
@ -729,7 +729,7 @@ bool quotient_field_changed;
fpattern& getcurrfp() {
if(geometry == gFieldQuotient && quotient_field_changed)
return current_quotient_field;
if(DIM == 3) {
if(WDIM == 3) {
dynamicval<eGeometry> g(geometry, gSpace435);
static fpattern fp(5);
return fp;

View File

@ -267,10 +267,47 @@ void bshape_regular(floorshape &fsh, int id, int sides, int shift, ld size) {
for(int k=0; k<SIDEPARS; k++) {
fsh.side[k].resize(2);
bshape(fsh.side[k][id], PPR::LAKEWALL);
hpcpush(xspinpush0(M_PI/sides, size));
hpcpush(xspinpush0(+M_PI/sides, size));
hpcpush(xspinpush0(-M_PI/sides, size));
chasmifyPoly(dlow_table[k], dhi_table[k], k);
}
for(int k=0; k<SIDEPARS; k++) {
fsh.levels[k].resize(2);
bshape(fsh.levels[k][id], fsh.prio);
/*
for(int i=fsh.b[id].s; i< fsh.b[id].e; i++)
hpcpush(zshift(hpc[i], dfloor_table[k]));
*/
fsh.levels[k][id].tinf = &fsh.tinf3;
fsh.levels[k][id].texture_offset = 0;
auto at = [&] (hyperpoint h, int a) {
hpcpush(normalize(h));
};
const int STEP = TEXTURE_STEP_3D;
for(int t=0; t<sides; t++)
for(int y=0; y<STEP; y++)
for(int x=0; x<STEP; x++) {
using namespace hyperpoint_vec;
hyperpoint center = zpush(dfloor_table[k]) * C0;
hyperpoint v1 = (xspinpush(t*2 * M_PI / sides + shift * M_PI / S42, size) * center - center) / STEP;
hyperpoint v2 = (xspinpush((t+1)*2 * M_PI / sides + shift * M_PI / S42, size) * center - center) / STEP;
if(x+y < STEP) {
at(center + v1 * x + v2 * y, 0);
at(center + v1 * (x+1) + v2 * y, 1);
at(center + v1 * x + v2 * (y+1), 2);
}
if(x+y <= STEP && x && y) {
at(center + v1 * x + v2 * y, 0);
at(center + v1 * (x-1) + v2 * y, 1);
at(center + v1 * x + v2 * (y-1), 2);
}
}
last->flags |= POLY_TRIANGLES;
}
}
#if CAP_IRR
@ -406,11 +443,35 @@ void generate_floorshapes_for(int id, cell *c, int siid, int sidir) {
hpcpush(iddspin(c, cid) * cornerlist[(cid+1)%cor]);
chasmifyPoly(dlow_table[k], dhi_table[k], k);
}
for(int k=0; k<SIDEPARS; k++) {
sizeto(fsh.levels[k], id);
bshape(fsh.levels[k][id], fsh.prio);
for(int i=fsh.b[id].s; i< fsh.b[id].e; i++)
hpcpush(zshift(hpc[i], dfloor_table[k]));
}
}
for(auto pfsh: all_escher_floorshapes) {
auto& fsh = *pfsh;
if(WDIM == 2 && GDIM == 3) {
ld hexside = shFullFloor.rad0, heptside = shFullFloor.rad1;
int td = ((PURE || euclid) && !(S7&1)) ? S42+S6 : 0;
if(id == 1)
bshape_regular(fsh, 1, S7, td, heptside);
else if(PURE)
bshape_regular(fsh, 0, S7, td, heptside);
else
bshape_regular(fsh, 0, S6, S7, hexside);
continue;
}
sizeto(fsh.b, id);
sizeto(fsh.shadow, id);
@ -477,7 +538,7 @@ void generate_floorshapes_for(int id, cell *c, int siid, int sidir) {
void generate_floorshapes() {
if(DIM == 3) ;
if(WDIM == 3) ;
#if CAP_IRR
else if(IRREGULAR) {
@ -622,7 +683,7 @@ void set_floor(const transmatrix& spin, hpcshape& sh) {
void draw_shapevec(cell *c, const transmatrix& V, const vector<hpcshape> &shv, color_t col, PPR prio = PPR::DEFAULT) {
if(!c) queuepolyat(V, shv[0], col, prio);
else if(DIM == 3) ;
else if(WDIM == 3) ;
#if CAP_GP
else if(GOLDBERG) {
int id = gp::get_plainshape_id(c);
@ -800,8 +861,12 @@ void make_floor_textures() {
dynamicval<eGeometry> g(geometry, gEuclidSquare);
dynamicval<eModel> gm(pmodel, mdDisk);
dynamicval<eVariation> va(variation, eVariation::pure);
dynamicval<bool> a3(geom3::always3, false);
dynamicval<bool> hq(inHighQual, true);
dynamicval<int> hd(darken, 0);
dynamicval<ld> ga(vid.alpha, 1);
dynamicval<ld> gd(geom3::depth, 1);
dynamicval<ld> gc(geom3::camera, 1);
resetGeometry();
dynamicval<videopar> vi(vid, vid);

View File

@ -2670,7 +2670,7 @@ bool cellEdgeUnstable(cell *c, flagtype flags) {
if(isWorm(c2))
return false;
}
if(DIM == 3) {
if(WDIM == 3) {
if(d == 0 && !passable(c2, NULL, P_MONSTER | P_DEADLY)) return false;
if(d == -1 && !passable(c2, NULL, P_MONSTER | P_DEADLY)) forCellEx(c3, c2) if(c3 != c && gravityLevelDiff(c3, c) == 0) return false;
}
@ -3090,7 +3090,7 @@ void bfs() {
int d = c->cpdist;
if(DIM == 2 && d == distlimit) { first7 = qb; break; }
if(WDIM == 2 && d == distlimit) { first7 = qb; break; }
for(int j=0; j<c->type; j++) if(i = (fd+j) % c->type, c->move(i)) {
// printf("i=%d cd=%d\n", i, c->move(i)->cpdist);
@ -3105,7 +3105,7 @@ void bfs() {
c2->wall = waSea;
if(c2 && signed(c2->cpdist) > d+1) {
if(DIM == 3 && !gmatrix.count(c2)) {
if(WDIM == 3 && !gmatrix.count(c2)) {
if(!first7) first7 = qb;
continue;
}
@ -3323,7 +3323,7 @@ bool makeEmpty(cell *c) {
c->wall = waBoat;
else if(c->wall == waFreshGrave && bounded)
;
else if(c->wall == waBarrier && sphere && DIM == 3)
else if(c->wall == waBarrier && sphere && WDIM == 3)
;
else if(isReptile(c->wall))
c->wparam = reptilemax();
@ -4152,7 +4152,7 @@ cell *determinePush(cellwalker who, cell *c2, int subdir, const T& valid, int& p
}
cellwalker push = who;
push += wstep;
if(DIM == 3 && binarytiling) {
if(WDIM == 3 && binarytiling) {
for(int a=0; a<4; a++) {
if(push.spin < 4) push.spin = 8;
else if(push.spin >= 8) push.spin = a;
@ -7363,8 +7363,8 @@ int mine_adjacency_rule = 0;
map<cell*, vector<cell*>> adj_memo;
bool geometry_has_alt_mine_rule() {
if(DIM == 2) return VALENCE > 3;
if(DIM == 3) return !among(geometry, gHoroHex, gCell5, gBitrunc3, gCell8, gECell8, gCell120, gECell120);
if(WDIM == 2) return VALENCE > 3;
if(WDIM == 3) return !among(geometry, gHoroHex, gCell5, gBitrunc3, gCell8, gECell8, gCell120, gECell120);
return true;
}
@ -7372,7 +7372,7 @@ vector<cell*> adj_minefield_cells(cell *c) {
vector<cell*> res;
if(mine_adjacency_rule == 0 || !geometry_has_alt_mine_rule())
forCellCM(c2, c) res.push_back(c2);
else if(DIM == 2) {
else if(WDIM == 2) {
cellwalker cw(c, 0);
cw += wstep;
cw++;

View File

@ -497,7 +497,7 @@ void showEuclideanMenu() {
else if(sphere && nonorientable) euler = 1;
else if(sphere) euler = 2;
else if(!bounded) euler = -2;
else if(DIM == 3) euler = 0;
else if(WDIM == 3) euler = 0;
else switch(geometry) {
case gFieldQuotient:
worldsize = isize(currentmap->allcells());
@ -605,7 +605,7 @@ void showEuclideanMenu() {
dialog::add_action_push([] { ge_select_tiling(quotientlist); });
#if MAXMDIM >= 4
dialog::addSelItem(XLAT("dimension"), its(DIM), 'd');
dialog::addSelItem(XLAT("dimension"), its(WDIM), 'd');
dialog::add_action_push([] { ge_select_tiling(list3d); });
#endif
@ -632,7 +632,7 @@ void showEuclideanMenu() {
};
});
}
else if(DIM == 3) dialog::addBreak(100);
else if(WDIM == 3) dialog::addBreak(100);
else {
dialog::addSelItem(XLAT("variations"), gp::operation_name(), 'v');
dialog::add_action([] {
@ -653,7 +653,7 @@ void showEuclideanMenu() {
if(euwrap || geometry == gFieldQuotient || geometry == gCrystal || archimedean || (euclid && DIM == 3)) {
if(euwrap || geometry == gFieldQuotient || geometry == gCrystal || archimedean || (euclid && WDIM == 3)) {
dialog::addItem(XLAT("advanced parameters"), '4');
dialog::add_action([] {
if(0);
@ -666,7 +666,7 @@ void showEuclideanMenu() {
pushScreen(crystal::show);
#endif
#if MAXMDIM == 4
else if(euclid && DIM == 3)
else if(euclid && WDIM == 3)
euclid3::prepare_torus3(),
pushScreen(euclid3::show_torus3);
#endif
@ -704,7 +704,7 @@ void showEuclideanMenu() {
}
if(specialland == laMinefield && geometry_has_alt_mine_rule()) {
dialog::addSelItem(XLAT("mine adjacency rule"), XLAT(mine_adjacency_rule ? "vertex" : DIM == 3 ? "face" : "edge"), 'M');
dialog::addSelItem(XLAT("mine adjacency rule"), XLAT(mine_adjacency_rule ? "vertex" : WDIM == 3 ? "face" : "edge"), 'M');
dialog::add_action([] {
stop_game();
mine_adjacency_rule = !mine_adjacency_rule;
@ -716,7 +716,7 @@ void showEuclideanMenu() {
if(specialland == laCanvas) dialog::lastItem().value = patterns::whichCanvas;
dialog::add_action_push(patterns::showPrePattern);
validity_info();
if(DIM == 3) {
if(WDIM == 3) {
dialog::addItem(XLAT("3D configuration"), '9');
dialog::add_action_push(show3D);
}
@ -744,11 +744,11 @@ void showEuclideanMenu() {
dialog::addTitle(XLAT("info about: %1", fgname), 0xFFFFFF, 150);
if(DIM == 2) dialog::addSelItem(XLAT("faces per vertex"), spf, 0);
if(WDIM == 2) dialog::addSelItem(XLAT("faces per vertex"), spf, 0);
dialog::addSelItem(XLAT("size of the world"),
#if CAP_BT
binarytiling ? fts4(8 * M_PI * sqrt(2) * log(2) / pow(vid.binary_width, DIM-1)) + " exp(∞)" :
binarytiling ? fts4(8 * M_PI * sqrt(2) * log(2) / pow(vid.binary_width, WDIM-1)) + " exp(∞)" :
#endif
#if CAP_ARCM
archimedean ? arcm::current.world_size() :
@ -757,23 +757,23 @@ void showEuclideanMenu() {
#if CAP_CRYSTAL
geometry == gCrystal ? "∞^" + its(ts/2) :
#endif
DIM == 3 && bounded ? its(isize(currentmap->allcells())) :
DIM == 3 && euclid ? "" :
WDIM == 3 && bounded ? its(isize(currentmap->allcells())) :
WDIM == 3 && euclid ? "" :
worldsize < 0 ? (nom%denom ? its(nom)+"/"+its(denom) : its(-worldsize)) + " exp(∞)":
(euwrap && !fulltorus) ? "" :
worldsize == 0 ? "∞²" :
its(worldsize),
'3');
if(DIM == 2) dialog::add_action([] {
if(WDIM == 2) dialog::add_action([] {
if(!viewdists) { enable_viewdists(); pushScreen(viewdist_configure_dialog); }
else if(viewdists) viewdists = false;
});
if(bounded) {
if(DIM == 3) euler = 0;
if(WDIM == 3) euler = 0;
dialog::addSelItem(XLAT("Euler characteristics"), its(euler), 0);
if(DIM == 3) ;
if(WDIM == 3) ;
else if(nonorientable)
dialog::addSelItem(XLAT("demigenus"), its(2-euler), 0);
else

View File

@ -93,7 +93,7 @@ void precalc() {
goto finish;
}
if((sphere || hyperbolic) && DIM == 3 && !binarytiling) {
if((sphere || hyperbolic) && WDIM == 3 && !binarytiling) {
rhexf = hexf = 0.378077;
crossf = hcrossf = 0.620672;
tessf = 1.090550;
@ -165,16 +165,16 @@ void precalc() {
if(geometry == gHoroRec) hexvdist = rhexf = .5, tessf = .5, scalefactor = .5, crossf = hcrossf7/2;
#endif
#if CAP_BT && MAXMDIM >= 4
if(binarytiling && DIM == 3) binary::build_tmatrix();
if(binarytiling && WDIM == 3) binary::build_tmatrix();
#endif
scalefactor = crossf / hcrossf7;
orbsize = crossf;
if(DIM == 3) scalefactor *= geom3::creature_scale;
if(WDIM == 3) scalefactor *= geom3::creature_scale;
zhexf = BITRUNCATED ? hexf : crossf* .55;
if(DIM == 3) zhexf *= geom3::creature_scale;
if(WDIM == 3) zhexf *= geom3::creature_scale;
floorrad0 = hexvdist* 0.92;
floorrad1 = rhexf * 0.94;
@ -199,6 +199,7 @@ transmatrix xspinpush(ld dir, ld dist) {
namespace geom3 {
bool always3 = false;
int tc_alpha=3, tc_depth=1, tc_camera=2;
ld depth = 1; // world below the plane
@ -246,7 +247,8 @@ namespace geom3 {
}
ld lev_to_factor(ld lev) {
if(DIM == 3) return lev;
if(WDIM == 3) return lev;
if(GDIM == 3) return lev - depth;
return projection_to_factor(lev_to_projection(lev));
}
ld factor_to_lev(ld fac) {
@ -260,7 +262,7 @@ namespace geom3 {
return cosh(depth - lev);
}
ld INFDEEP, BOTTOM, HELLSPIKE, LAKE, WALL,
ld INFDEEP, BOTTOM, HELLSPIKE, LAKE, WALL, FLOOR, STUFF,
SLEV[4], FLATEYE,
LEG0, LEG1, LEG, LEG3, GROIN, GROIN1, GHOST,
BODY, BODY1, BODY2, BODY3,
@ -281,7 +283,8 @@ namespace geom3 {
// tanh(depth) / tanh(camera) == vid.alpha
invalid = "";
if(tc_alpha < tc_depth && tc_alpha < tc_camera)
if(GDIM == 3) ;
else if(tc_alpha < tc_depth && tc_alpha < tc_camera)
vid.alpha = tan_auto(depth) / tan_auto(camera);
else if(tc_depth < tc_alpha && tc_depth < tc_camera) {
ld v = vid.alpha * tan_auto(camera);
@ -301,6 +304,7 @@ namespace geom3 {
BOTTOM = .8;
HELLSPIKE = .85;
LAKE = .9;
FLOOR = 1;
WALL = 1.25;
SLEV[0] = 1;
SLEV[1] = 1.08;
@ -332,12 +336,13 @@ namespace geom3 {
INFDEEP = (euclid || sphere) ? 0.01 : lev_to_projection(0) * tanh(camera);
ld wh = actual_wall_height();
WALL = lev_to_factor(wh);
FLOOR = lev_to_factor(0);
human_height = human_wall_ratio * wh;
if(DIM == 3) human_height = scalefactor * height_width / 2;
if(WDIM == 3) human_height = scalefactor * height_width / 2;
ld reduce = (WDIM == 3 ? human_height / 2 : 0);
ld reduce = (DIM == 3 ? human_height / 2 : 0);
LEG0 = lev_to_factor(human_height * .0 - reduce);
LEG1 = lev_to_factor(human_height * .1 - reduce);
LEG = lev_to_factor(human_height * .2 - reduce);
@ -358,6 +363,8 @@ namespace geom3 {
reduce = (DIM == 3 ? human_height * .3 : 0);
STUFF = lev_to_factor(human_height * .2);
ABODY = lev_to_factor(human_height * .4 - reduce);
ALEG0 = lev_to_factor(human_height * .0 - reduce);
ALEG = lev_to_factor(human_height * .2 - reduce);

View File

@ -8,14 +8,14 @@ namespace hr {
transmatrix &ggmatrix(cell *c);
void fixelliptic(transmatrix& at) {
if(elliptic && at[DIM][DIM] < 0) {
if(elliptic && at[GDIM][GDIM] < 0) {
for(int i=0; i<MDIM; i++) for(int j=0; j<MDIM; j++)
at[i][j] = -at[i][j];
}
}
void fixelliptic(hyperpoint& h) {
if(elliptic && h[DIM] < 0)
if(elliptic && h[GDIM] < 0)
for(int i=0; i<MDIM; i++) h[i] = -h[i];
}
@ -46,7 +46,7 @@ transmatrix master_relative(cell *c, bool get_inverse) {
return (get_inverse?invhexmove:hexmove)[d];
return Id;
}
else if(DIM == 3 || euclid)
else if(WDIM == 3 || euclid)
return Id;
else
return pispin * Id;
@ -163,10 +163,10 @@ transmatrix hrmap_standard::relative_matrix(cell *c2, cell *c1, const hyperpoint
transmatrix &ggmatrix(cell *c) {
transmatrix& t = gmatrix[c];
if(t[DIM][DIM] == 0) {
if(t[GDIM][GDIM] == 0) {
if(euwrap && centerover.at)
t = calc_relative_matrix(c, centerover.at, C0);
else if(euclid && DIM == 2) {
else if(euclid && WDIM == 2) {
if(!centerover.at) centerover = cwt;
t = View * eumove(cell_to_vec(c) - cellwalker_to_vec(centerover));
}
@ -246,7 +246,7 @@ struct horo_distance {
template<class T, class U>
void virtualRebase(cell*& base, T& at, bool tohex, const U& check) {
if((euclid || sphere) && DIM == 2) {
if((euclid || sphere) && WDIM == 2) {
again:
if(euwrap) for(int i=0; i<6; i++) {
// fix cylinder and square grid
@ -283,7 +283,7 @@ void virtualRebase(cell*& base, T& at, bool tohex, const U& check) {
transmatrix bestV;
if(DIM == 2 && !binarytiling) for(int d=0; d<S7; d++) {
if(WDIM == 2 && !binarytiling) for(int d=0; d<S7; d++) {
heptspin hs(h, d, false);
heptspin hs2 = hs + wstep;
transmatrix V2 = spin(-hs2.spin*2*M_PI/S7) * invheptmove[d];
@ -315,7 +315,7 @@ void virtualRebase(cell*& base, T& at, bool tohex, const U& check) {
at = bestV * at;
}
else at = master_relative(base, true) * at;
if(binarytiling || (tohex && (GOLDBERG || IRREGULAR)) || DIM == 3) {
if(binarytiling || (tohex && (GOLDBERG || IRREGULAR)) || WDIM == 3) {
while(true) {
newbase = NULL;
forCellCM(c2, base) {
@ -345,8 +345,8 @@ void virtualRebase(cell*& base, transmatrix& at, bool tohex) {
void virtualRebase(cell*& base, hyperpoint& h, bool tohex) {
// we perform fixing in check, so that it works with larger range
virtualRebase(base, h, tohex, [] (const hyperpoint& h) {
if(hyperbolic && DIM == 2) return hpxy(h[0], h[1]);
if(hyperbolic && DIM == 3) return hpxy3(h[0], h[1], h[2]);
if(hyperbolic && GDIM == 2) return hpxy(h[0], h[1]);
if(hyperbolic && GDIM == 3) return hpxy3(h[0], h[1], h[2]);
return h;
});
}
@ -356,7 +356,7 @@ void virtualRebaseSimple(heptagon*& base, transmatrix& at) {
while(true) {
double currz = at[DIM][DIM];
double currz = at[GDIM][GDIM];
heptagon *h = base;
@ -368,7 +368,7 @@ void virtualRebaseSimple(heptagon*& base, transmatrix& at) {
heptspin hs(h, d, false);
heptspin hs2 = hs + wstep;
transmatrix V2 = spin(-hs2.spin*2*M_PI/S7) * invheptmove[d] * at;
double newz = V2[DIM][DIM];
double newz = V2[GDIM][GDIM];
if(newz < currz) {
currz = newz;
bestV = V2;
@ -439,7 +439,7 @@ hyperpoint get_corner_position(cell *c, int cid, ld cf) {
#endif
#if CAP_BT
if(binarytiling) {
if(DIM == 3) {
if(WDIM == 3) {
println(hlog, "get_corner_position called");
return C0;
}
@ -528,7 +528,7 @@ hyperpoint nearcorner(cell *c, int i) {
#endif
#if CAP_BT
if(binarytiling) {
if(DIM == 3) {
if(WDIM == 3) {
println(hlog, "nearcorner called");
return Hypc;
}

View File

@ -315,12 +315,12 @@ double hexshiftat(cell *c) {
}
transmatrix ddspin(cell *c, int d, ld bonus) {
if(DIM == 3 && d < c->type) return rspintox(tC0(calc_relative_matrix(c->move(d), c, C0))) * cspin(2, 0, bonus);
if(WDIM == 3 && d < c->type) return rspintox(tC0(calc_relative_matrix(c->move(d), c, C0))) * cspin(2, 0, bonus);
return spin(displayspin(c, d) + bonus - hexshiftat(c));
}
transmatrix iddspin(cell *c, int d, ld bonus) {
if(DIM == 3 && d < c->type) return cspin(0, 2, bonus) * spintox(tC0(calc_relative_matrix(c->move(d), c, C0)));
if(WDIM == 3 && d < c->type) return cspin(0, 2, bonus) * spintox(tC0(calc_relative_matrix(c->move(d), c, C0)));
return spin(hexshiftat(c) - displayspin(c, d) + bonus);
}
@ -336,7 +336,7 @@ void drawPlayerEffects(const transmatrix& V, cell *c, bool onplayer) {
if(onplayer && (items[itOrbSword] || items[itOrbSword2])) {
using namespace sword;
if(shmup::on && DIM == 2) {
if(shmup::on && WDIM == 2) {
#if CAP_SHAPES
if(items[itOrbSword])
queuepoly(V*spin(shmup::pc[multi::cpid]->swordangle), (peace::on ? shMagicShovel : shMagicSword), darkena(iinf[itOrbSword].color, 0, 0xC0 + 0x30 * sintick(200)));
@ -346,7 +346,7 @@ void drawPlayerEffects(const transmatrix& V, cell *c, bool onplayer) {
#endif
}
else if(shmup::on && DIM == 3) {
else if(shmup::on && WDIM == 3) {
#if CAP_SHAPES
if(items[itOrbSword])
queuepoly(V*shmup::swordmatrix[multi::cpid] * cspin(2, 0, M_PI/2) * cspin(1,2, ticks / 150.), (peace::on ? shMagicShovel : shMagicSword), darkena(iinf[itOrbSword].color, 0, 0xC0 + 0x30 * sintick(200)));
@ -517,7 +517,7 @@ void animallegs(const transmatrix& V, eMonster mo, color_t col, double footphase
hpcshape **x = sh[mo == moRagingBull ? 5 : mo == moBug0 ? 3 : mo == moMetalBeast ? 4 : mo == moRunDog ? 0 : mo == moReptile ? 2 : 1];
const transmatrix VL = (DIM == 2 ? V : mmscale(V, geom3::ALEG0));
const transmatrix VL = (GDIM == 3 ? V : mmscale(V, geom3::ALEG0));
if(x[0]) queuepolyat(VL * xpush(rightfoot), *x[0], col, PPR::MONSTER_FOOT);
if(x[0]) queuepolyat(VL * Mirror * xpush(leftfoot), *x[0], col, PPR::MONSTER_FOOT);
@ -738,6 +738,7 @@ bool drawItemType(eItem it, cell *c, const transmatrix& V, color_t icol, int pti
#endif
transmatrix Vit = V;
if(GDIM == 3 && WDIM == 2) Vit = mscale(V, geom3::STUFF);
if(DIM == 3 && c) Vit = face_the_player(Vit);
// V * cspin(0, 2, ptick(618, 0));
@ -1149,7 +1150,7 @@ bool drawMonsterType(eMonster m, cell *where, const transmatrix& V1, color_t col
char xch = minf[m].glyph;
transmatrix V = V1;
if(DIM == 3 && (classflag(m) & CF_FACE_UP)) V = V1 * cspin(0, 2, M_PI/2);
if(WDIM == 3 && (classflag(m) & CF_FACE_UP)) V = V1 * cspin(0, 2, M_PI/2);
// if(DIM == 3) V = V * cspin(0, 2, M_PI/2);
@ -2467,7 +2468,7 @@ bool drawMonster(const transmatrix& Vparam, int ct, cell *c, color_t col) {
// other monsters face the player
if(!nospins) {
if(DIM == 2) {
if(WDIM == 2) {
hyperpoint V0 = inverse(cwtV) * tC0(Vs);
hyperpoint V1 = spintox(V0) * V0;
@ -2479,7 +2480,7 @@ bool drawMonster(const transmatrix& Vparam, int ct, cell *c, color_t col) {
// cwtV * rgpushxto0(inverse(cwtV) * tC0(Vs));
}
if(c->monst == moHunterChanging)
Vs = Vs * cspin(DIM-2, DIM-1, M_PI);
Vs = Vs * cspin(WDIM-2, WDIM-1, M_PI);
}
if(c->monst == moShadow)
@ -3650,7 +3651,7 @@ void escherSidewall(cell *c, int sidepar, const transmatrix& V, color_t col) {
bool placeSidewall(cell *c, int i, int sidepar, const transmatrix& V, color_t col) {
if(!qfi.fshape || !qfi.fshape->is_plain || !validsidepar[sidepar] || qfi.usershape >= 0) {
if(!qfi.fshape || !qfi.fshape->is_plain || !validsidepar[sidepar] || qfi.usershape >= 0) if(GDIM == 2) {
escherSidewall(c, sidepar, V, col);
return true;
}
@ -3867,6 +3868,18 @@ int getSnakelevColor(cell *c, int i, int last, int fd, color_t wcol) {
#if CAP_SHAPES
void draw_wall(cell *c, const transmatrix& V, color_t wcol, color_t& zcol, int ct6, int fd) {
if(DIM == 3 && WDIM == 2) {
color_t wcol0 = wcol;
color_t wcol2 = gradient(0, wcol0, 0, .8, 1);
if(!qfi.fshape) qfi.fshape = &shFullFloor;
draw_shapevec(c, V, qfi.fshape->levels[SIDE_WALL], darkena(wcol, 0, 0xFF), PPR::WALL);
forCellIdEx(c2, i, c)
if(!highwall(c2))
placeSidewall(c, i, SIDE_WALL, V, darkena(wcol2, fd, 255));
return;
}
zcol = wcol;
color_t wcol0 = wcol;
int starcol = wcol;
@ -4183,7 +4196,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
viewBuggyCells(c,V);
#endif
if(conformal::on || inHighQual || DIM == 3 || sightrange_bonus > gamerange_bonus) checkTide(c);
if(conformal::on || inHighQual || WDIM == 3 || sightrange_bonus > gamerange_bonus) checkTide(c);
// save the player's view center
if(isPlayerOn(c) && !shmup::on) {
@ -4877,7 +4890,10 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
if(chasmg == 2) ;
else if(chasmg && wmspatial && detaillevel == 0) {
draw_qfi(c, (*Vdp), darkena(fcol, fd, 0x80), PPR::LAKELEV);
if(WDIM == 2 && GDIM == 3 && qfi.fshape)
draw_shapevec(c, V, qfi.fshape->levels[SIDE_LAKE], darkena3(fcol, fd, 0x80), PPR::LAKELEV);
else
draw_qfi(c, (*Vdp), darkena(fcol, fd, 0x80), PPR::LAKELEV);
}
else if(chasmg && wmspatial) {
@ -4892,14 +4908,23 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
else if(qfi.fshape == &shCaveFloor)
set_floor(shCaveSeabed);
draw_qfi(c, mscale(V, geom3::BOTTOM), col, PPR::LAKEBOTTOM);
if(WDIM == 2 && GDIM == 3 && qfi.fshape)
draw_shapevec(c, V, qfi.fshape->levels[SIDE_LTOB], col, PPR::LAKEBOTTOM);
else
draw_qfi(c, mscale(V, geom3::BOTTOM), col, PPR::LAKEBOTTOM);
int fd0 = fd ? fd-1 : 0;
draw_qfi(c, (*Vdp), darkena(fcol, fd0, 0x80), PPR::LAKELEV);
if(WDIM == 2 && GDIM == 3 && qfi.fshape)
draw_shapevec(c, V, qfi.fshape->levels[SIDE_LAKE], darkena3(fcol, fd0, 0x80), PPR::TRANSPARENT);
else
draw_qfi(c, (*Vdp), darkena(fcol, fd0, 0x80), PPR::LAKELEV);
}
else {
if(patterns::whichShape == '^') poly_outline = darkena(fcol, fd, flooralpha);
draw_qfi(c, V, darkena(fcol, fd, flooralpha));
if(WDIM == 2 && GDIM == 3 && qfi.fshape)
draw_shapevec(c, V, qfi.fshape->levels[0], darkena(fcol, fd, 255), PPR::FLOOR);
else
draw_qfi(c, V, darkena(fcol, fd, flooralpha));
}
// walls
@ -4962,7 +4987,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
char xch = winf[c->wall].glyph;
#if MAXMDIM >= 4
if(DIM == 3) {
if(WDIM == 3) {
color_t dummy;
if(isWall3(c, wcol)) {
color_t wcol2 = wcol;
@ -5317,7 +5342,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
#if CAP_SHAPES
int sha = shallow(c);
if(wmspatial && sha && DIM == 2) {
if(wmspatial && sha && WDIM == 2) {
color_t col = (highwall(c) || c->wall == waTower) ? wcol : fcol;
if(!chasmg) {
@ -5534,7 +5559,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
if(0);
#if MAXMDIM == 4
else if(DIM == 3) {
else if(WDIM == 3) {
for(int t=0; t<c->type; t++) {
if(!c->move(t)) continue;
if(binarytiling && !among(t, 5, 6, 8)) continue;
@ -5545,7 +5570,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
}
#endif
#if CAP_BT
else if(binarytiling && DIM == 2) {
else if(binarytiling && WDIM == 2) {
ld yx = log(2) / 2;
ld yy = yx;
ld xx = 1 / sqrt(2)/2;
@ -5674,7 +5699,7 @@ struct flashdata {
flashdata(int _t, int _s, cell *_w, color_t col, int sped) {
t=_t; size=_s; where=_w; color = col;
angle = rand() % 1000; spd = sped;
if(DIM == 3) angle2 = acos((rand() % 1000 - 499.5) / 500);
if(WDIM == 3) angle2 = acos((rand() % 1000 - 499.5) / 500);
}
};
@ -5723,7 +5748,7 @@ void fallingMonsterAnimation(cell *c, eMonster m, int id) {
void queuecircleat(cell *c, double rad, color_t col) {
if(!c) return;
if(!gmatrix.count(c)) return;
if(DIM == 3) {
if(WDIM == 3) {
dynamicval<color_t> p(poly_outline, col);
for(int i=0; i<c->type; i++) {
queuepolyat(gmatrix[c], shWireframe3D[i], 0, PPR::SUPERLINE);
@ -5828,17 +5853,17 @@ void drawMarkers() {
#endif
#if CAP_QUEUE
if(lmouseover && vid.drawmousecircle && ok && DEFAULTCONTROL && MOBON && DIM == 2) {
if(lmouseover && vid.drawmousecircle && ok && DEFAULTCONTROL && MOBON && WDIM == 2) {
queuecircleat(lmouseover, .8, darkena(lmouseover->cpdist > 1 ? 0x00FFFF : 0xFF0000, 0, 0xFF));
}
if(global_pushto && vid.drawmousecircle && ok && DEFAULTCONTROL && MOBON && DIM == 2) {
if(global_pushto && vid.drawmousecircle && ok && DEFAULTCONTROL && MOBON && WDIM == 2) {
queuecircleat(global_pushto, .6, darkena(0xFFD500, 0, 0xFF));
}
#endif
#if CAP_SDLJOY && CAP_QUEUE
if(joydir.d >= 0 && DIM == 2)
if(joydir.d >= 0 && WDIM == 2)
queuecircleat(cwt.at->modmove(joydir.d+cwt.spin), .78 - .02 * sintick(199),
darkena(0x00FF00, 0, 0xFF));
#endif
@ -5850,7 +5875,7 @@ void drawMarkers() {
#endif
#if CAP_QUEUE
if(centerover.at && !playermoved && m && !anims::any_animation() && DIM == 2)
if(centerover.at && !playermoved && m && !anims::any_animation() && WDIM == 2)
queuecircleat(centerover.at, .70 - .06 * sintick(200),
darkena(int(175 + 25 * sintick(200)), 0, 0xFF));
@ -5963,7 +5988,7 @@ void drawFlashes() {
poly_outline = OUTLINE_DEFAULT;
ld t = f.spd * tim * scalefactor / 50000.;
transmatrix T =
DIM == 2 ? V * spin(f.angle) * xpush(t) :
WDIM == 2 ? V * spin(f.angle) * xpush(t) :
V * cspin(0, 1, f.angle) * cspin(0, 2, f.angle2) * cpush(2, t);
queuepoly(T, shParticle[f.size], partcol);
#endif
@ -6015,7 +6040,7 @@ bool allowIncreasedSight() {
if(randomPatternsMode) return true;
if(racing::on) return true;
if(quotient || !hyperbolic || archimedean) return true;
if(DIM == 3) return true;
if(WDIM == 3) return true;
return false;
}
@ -6027,7 +6052,7 @@ bool allowChangeRange() {
if(racing::on) return true;
if(sightrange_bonus >= 0) return true;
if(archimedean) return true;
if(DIM == 3) return true;
if(WDIM == 3) return true;
return false;
}
@ -6055,11 +6080,11 @@ ld wall_radar(cell *c, transmatrix T) {
void make_actual_view() {
sphereflip = Id;
if(DIM == 3 && !shmup::on && vid.yshift) {
if(WDIM == 3 && !shmup::on && vid.yshift) {
actual_view_transform = cpush(2, wall_radar(viewctr.at->c7, inverse(View)));
return;
}
if(DIM == 3) { actual_view_transform = Id; return; }
if(WDIM == 3) { actual_view_transform = Id; return; }
if(sphereflipped()) sphereflip[DIM][DIM] = -1;
actual_view_transform = ypush(vid.yshift) * sphereflip;
}

View File

@ -738,7 +738,7 @@ void describeMouseover() {
out = XLAT1(linf[c->land].name);
help = bygen([c] () { gotoHelpFor(c->land); });
if(DIM == 3 && isGravityLand(c->land)) out += " [" + its(gravityLevel(c)) + "]";
if(WDIM == 3 && isGravityLand(c->land)) out += " [" + its(gravityLevel(c)) + "]";
if(isIcyLand(c))
out += " (" + fts(heat::celsius(c)) + " °C)";

View File

@ -352,6 +352,7 @@ void draw_radar(bool cornermode) {
dynamicval<eGeometry> g(geometry, gEuclid);
dynamicval<eModel> pm(pmodel, mdUnchanged);
dynamicval<bool> ga(geom3::always3, false);
initquickqueue();
int rad = vid.radarsize;

24
hyper.h
View File

@ -196,14 +196,18 @@ typedef complex<ld> cld;
#define DEBSM(x)
#if MAXMDIM == 3
#define DIM 2
#define WDIM 2
#else
#define DIM ((geometry >= gBinary3) ? 3 : 2)
#define WDIM ((geometry >= gBinary3) ? 3 : 2)
#endif
#define GDIM (geom3::always3 ? 3 : WDIM)
#define DIM GDIM
#define MDIM (DIM+1)
extern array<ld, gGUARD> sightranges;
namespace geom3 { extern bool always3; }
struct hyperpoint : array<ld, MAXMDIM> {
hyperpoint() {}
@ -516,7 +520,7 @@ template<class T> struct walker {
}
walker<T>& operator += (rev_t) {
int d = at->degree();
if(DIM == 3 && binarytiling) {
if(WDIM == 3 && binarytiling) {
if(spin < 4) spin = 8;
else if(spin >= 8) spin = 0;
else spin ^= 1;
@ -1568,7 +1572,7 @@ bool bearsCamelot(eLand l);
extern bool safety;
#define SAGEMELT .1
#define TEMPLE_EACH (among(geometry, gHoroRec, gHoroHex) ? 3 : (DIM == 3 && binarytiling) ? 2 : geometry == gSpace435 ? 4 : (DIM == 3 && hyperbolic) ? 3 : 6)
#define TEMPLE_EACH (among(geometry, gHoroRec, gHoroHex) ? 3 : (WDIM == 3 && binarytiling) ? 2 : geometry == gSpace435 ? 4 : (WDIM == 3 && hyperbolic) ? 3 : 6)
#define PT(x, y) ((tactic::on || quotient == 2 || daily::on) ? (y) : inv::on ? min(2*(y),x) : (x))
#define ROCKSNAKELENGTH 50
#define WORMLENGTH 15
@ -4228,11 +4232,11 @@ extern vector<blizzardcell*> bcells;
void set_blizzard_frame(cell *c, int frameid);
#define SIDE_SLEV 0
#define SIDE_WALL 3
#define SIDE_LAKE 4
#define SIDE_LTOB 5
#define SIDE_BTOI 6
#define SIDE_WTS3 7
#define SIDE_WTS3 3
#define SIDE_WALL 4
#define SIDE_LAKE 5
#define SIDE_LTOB 6
#define SIDE_BTOI 7
#define SIDEPARS 8
#if CAP_SHAPES
@ -4242,7 +4246,7 @@ struct floorshape {
int pstrength; // pattern strength in 3D
int fstrength; // frame strength in 3D
PPR prio;
vector<hpcshape> b, shadow, side[SIDEPARS], gpside[SIDEPARS][MAX_EDGE];
vector<hpcshape> b, shadow, side[SIDEPARS], gpside[SIDEPARS][MAX_EDGE], levels[SIDEPARS];
basic_textureinfo tinf3;
floorshape() { prio = PPR::FLOOR; pstrength = fstrength = 10; }
};

View File

@ -38,7 +38,7 @@ ld inverse_tanh(ld x) { return log((1+x)/(1-x)) / 2; } */
ld squar(ld x) { return x*x; }
int sig(int z) { return (sphere || z<DIM)?1:-1; }
int sig(int z) { return (sphere || z<GDIM)?1:-1; }
int curvature() {
switch(cgclass) {
@ -157,7 +157,7 @@ const hyperpoint C03 = hyperpoint(0,0,0,1);
const hyperpoint Cx12 = hyperpoint(1,0,1.41421356237,0);
const hyperpoint Cx13 = hyperpoint(1,0,0,1.41421356237);
#define Cx1 (DIM==2?Cx12:Cx13)
#define Cx1 (GDIM==2?Cx12:Cx13)
// this function returns approximate square of distance between two points
// (in the spherical analogy, this would be the distance in the 3D space,
@ -191,9 +191,9 @@ ld hypot_d(int d, const hyperpoint& h) {
}
ld zlevel(const hyperpoint &h) {
if(euclid) return h[DIM];
if(euclid) return h[GDIM];
else if(sphere) return sqrt(intval(h, Hypc));
else return (h[DIM] < 0 ? -1 : 1) * sqrt(-intval(h, Hypc));
else return (h[GDIM] < 0 ? -1 : 1) * sqrt(-intval(h, Hypc));
}
ld hypot_auto(ld x, ld y) {
@ -252,7 +252,7 @@ transmatrix cspin(int a, int b, ld alpha) {
transmatrix spin(ld alpha) { return cspin(0, 1, alpha); }
transmatrix random_spin() {
if(DIM == 2) return spin(randd() * 2 * M_PI);
if(GDIM == 2) return spin(randd() * 2 * M_PI);
else {
ld alpha2 = acos(randd() * 2 - 1);
ld alpha = randd() * 2 * M_PI;
@ -263,22 +263,22 @@ transmatrix random_spin() {
transmatrix eupush(ld x, ld y) {
transmatrix T = Id;
T[0][DIM] = x;
T[1][DIM] = y;
T[0][GDIM] = x;
T[1][GDIM] = y;
return T;
}
transmatrix eupush3(ld x, ld y, ld z) {
transmatrix T = Id;
T[0][DIM] = x;
T[1][DIM] = y;
if(DIM == 3) T[2][DIM] = z;
T[0][GDIM] = x;
T[1][GDIM] = y;
if(GDIM == 3) T[2][GDIM] = z;
return T;
}
transmatrix eupush(hyperpoint h) {
transmatrix T = Id;
for(int i=0; i<DIM; i++) T[i][DIM] = h[i];
for(int i=0; i<GDIM; i++) T[i][GDIM] = h[i];
return T;
}
@ -300,9 +300,9 @@ transmatrix euaffine(hyperpoint h) {
transmatrix cpush(int cid, ld alpha) {
transmatrix T = Id;
T[DIM][DIM] = T[cid][cid] = cos_auto(alpha);
T[cid][DIM] = sin_auto(alpha);
T[DIM][cid] = -curvature() * sin_auto(alpha);
T[GDIM][GDIM] = T[cid][cid] = cos_auto(alpha);
T[cid][GDIM] = sin_auto(alpha);
T[GDIM][cid] = -curvature() * sin_auto(alpha);
return T;
}
@ -311,14 +311,14 @@ transmatrix xpush(ld alpha) { return cpush(0, alpha); }
inline hyperpoint cpush0(int c, ld x) {
hyperpoint h = Hypc;
h[DIM] = cos_auto(x);
h[GDIM] = cos_auto(x);
h[c] = sin_auto(x);
return h;
}
inline hyperpoint xspinpush0(ld alpha, ld x) {
hyperpoint h = Hypc;
h[DIM] = cos_auto(x);
h[GDIM] = cos_auto(x);
h[0] = sin_auto(x) * cos(alpha);
h[1] = sin_auto(x) * -sin(alpha);
return h;
@ -400,7 +400,7 @@ transmatrix rspintoc(const hyperpoint& H, int t, int f) {
// rotate the hyperbolic plane around C0 such that H[1] == 0 and H[0] >= 0
transmatrix spintox(const hyperpoint& H) {
if(DIM == 2) return spintoc(H, 0, 1);
if(GDIM == 2) return spintoc(H, 0, 1);
transmatrix T1 = spintoc(H, 0, 1);
return spintoc(T1*H, 0, 2) * T1;
}
@ -421,7 +421,7 @@ transmatrix build_matrix(hyperpoint h1, hyperpoint h2, hyperpoint h3) {
// reverse of spintox(H)
transmatrix rspintox(const hyperpoint& H) {
if(DIM == 2) return rspintoc(H, 0, 1);
if(GDIM == 2) return rspintoc(H, 0, 1);
transmatrix T1 = spintoc(H, 0, 1);
return rspintoc(H, 0, 1) * rspintoc(T1*H, 0, 2);
}
@ -429,16 +429,16 @@ transmatrix rspintox(const hyperpoint& H) {
// for H such that H[1] == 0, this matrix pushes H to C0
transmatrix pushxto0(const hyperpoint& H) {
transmatrix T = Id;
T[0][0] = +H[DIM]; T[0][DIM] = -H[0];
T[DIM][0] = curvature() * H[0]; T[DIM][DIM] = +H[DIM];
T[0][0] = +H[GDIM]; T[0][GDIM] = -H[0];
T[GDIM][0] = curvature() * H[0]; T[GDIM][GDIM] = +H[GDIM];
return T;
}
// reverse of pushxto0(H)
transmatrix rpushxto0(const hyperpoint& H) {
transmatrix T = Id;
T[0][0] = +H[DIM]; T[0][DIM] = H[0];
T[DIM][0] = -curvature() * H[0]; T[DIM][DIM] = +H[DIM];
T[0][0] = +H[GDIM]; T[0][GDIM] = H[0];
T[GDIM][0] = -curvature() * H[0]; T[GDIM][GDIM] = +H[GDIM];
return T;
}
@ -448,16 +448,16 @@ transmatrix ggpushxto0(const hyperpoint& H, ld co) {
return eupush(co * H);
}
transmatrix res = Id;
if(sqhypot_d(DIM, H) < 1e-12) return res;
ld fac = (H[DIM]-1) / sqhypot_d(DIM, H);
for(int i=0; i<DIM; i++)
for(int j=0; j<DIM; j++)
if(sqhypot_d(GDIM, H) < 1e-12) return res;
ld fac = (H[GDIM]-1) / sqhypot_d(GDIM, H);
for(int i=0; i<GDIM; i++)
for(int j=0; j<GDIM; j++)
res[i][j] += H[i] * H[j] * fac;
for(int d=0; d<DIM; d++)
res[d][DIM] = co * H[d],
res[DIM][d] = -curvature() * co * H[d];
res[DIM][DIM] = H[DIM];
for(int d=0; d<GDIM; d++)
res[d][GDIM] = co * H[d],
res[GDIM][d] = -curvature() * co * H[d];
res[GDIM][GDIM] = H[GDIM];
return res;
}
@ -476,16 +476,16 @@ transmatrix rgpushxto0(const hyperpoint& H) {
void fixmatrix(transmatrix& T) {
if(euclid) {
for(int x=0; x<DIM; x++) for(int y=0; y<=x; y++) {
for(int x=0; x<GDIM; x++) for(int y=0; y<=x; y++) {
ld dp = 0;
for(int z=0; z<DIM; z++) dp += T[z][x] * T[z][y];
for(int z=0; z<GDIM; z++) dp += T[z][x] * T[z][y];
if(y == x) dp = 1 - sqrt(1/dp);
for(int z=0; z<DIM; z++) T[z][x] -= dp * T[z][y];
for(int z=0; z<GDIM; z++) T[z][x] -= dp * T[z][y];
}
for(int x=0; x<DIM; x++) T[DIM][x] = 0;
T[DIM][DIM] = 1;
for(int x=0; x<GDIM; x++) T[GDIM][x] = 0;
T[GDIM][GDIM] = 1;
}
else for(int x=0; x<MDIM; x++) for(int y=0; y<=x; y++) {
ld dp = 0;
@ -500,7 +500,7 @@ void fixmatrix(transmatrix& T) {
// show the matrix on screen
ld det(const transmatrix& T) {
if(DIM == 2) {
if(GDIM == 2) {
ld det = 0;
for(int i=0; i<3; i++)
det += T[0][i] * T[1][(i+1)%3] * T[2][(i+2)%3];
@ -512,14 +512,14 @@ ld det(const transmatrix& T) {
ld det = 1;
transmatrix M = T;
for(int a=0; a<MDIM; a++) {
for(int b=a; b<=DIM; b++)
for(int b=a; b<=GDIM; b++)
if(M[b][a]) {
if(b != a)
for(int c=a; c<MDIM; c++) tie(M[b][c], M[a][c]) = make_pair(-M[a][c], M[b][c]);
break;
}
if(!M[a][a]) return 0;
for(int b=a+1; b<=DIM; b++) {
for(int b=a+1; b<=GDIM; b++) {
ld co = -M[b][a] / M[a][a];
for(int c=a; c<MDIM; c++) M[b][c] += M[a][c] * co;
}
@ -534,7 +534,7 @@ void inverse_error(const transmatrix& T) {
}
transmatrix inverse(const transmatrix& T) {
if(DIM == 2) {
if(GDIM == 2) {
ld d = det(T);
transmatrix T2;
if(d == 0) {
@ -565,7 +565,7 @@ transmatrix inverse(const transmatrix& T) {
swap(T1[b][c], T1[a][c]), swap(T2[b][c], T2[a][c]);
if(!T1[a][a]) { inverse_error(T); return Id; }
for(int b=a+1; b<=DIM; b++) {
for(int b=a+1; b<=GDIM; b++) {
ld co = -T1[b][a] / T1[a][a];
for(int c=0; c<MDIM; c++) T1[b][c] += T1[a][c] * co, T2[b][c] += T2[a][c] * co;
}
@ -587,13 +587,13 @@ transmatrix inverse(const transmatrix& T) {
ld hdist0(const hyperpoint& mh) {
switch(cgclass) {
case gcHyperbolic:
if(mh[DIM] < 1) return 0;
return acosh(mh[DIM]);
if(mh[GDIM] < 1) return 0;
return acosh(mh[GDIM]);
case gcEuclid: {
return hypot_d(DIM, mh);
return hypot_d(GDIM, mh);
}
case gcSphere: {
ld res = mh[DIM] >= 1 ? 0 : mh[DIM] <= -1 ? M_PI : acos(mh[DIM]);
ld res = mh[GDIM] >= 1 ? 0 : mh[GDIM] <= -1 ? M_PI : acos(mh[GDIM]);
if(elliptic && res > M_PI/2) res = M_PI-res;
return res;
}
@ -634,7 +634,7 @@ ld hdist(const hyperpoint& h1, const hyperpoint& h2) {
}
hyperpoint mscale(const hyperpoint& t, double fac) {
if(DIM == 3) return cpush(2, fac) * t;
if(GDIM == 3) return cpush(2, fac) * t;
hyperpoint res;
for(int i=0; i<MDIM; i++)
res[i] = t[i] * fac;
@ -642,7 +642,7 @@ hyperpoint mscale(const hyperpoint& t, double fac) {
}
transmatrix mscale(const transmatrix& t, double fac) {
if(DIM == 3) return t * cpush(2, fac);
if(GDIM == 3) return t * cpush(2, fac);
transmatrix res;
for(int i=0; i<MDIM; i++) for(int j=0; j<MDIM; j++)
res[i][j] = t[i][j] * fac;
@ -651,24 +651,24 @@ transmatrix mscale(const transmatrix& t, double fac) {
transmatrix xyscale(const transmatrix& t, double fac) {
transmatrix res;
for(int i=0; i<MDIM; i++) for(int j=0; j<DIM; j++)
for(int i=0; i<MDIM; i++) for(int j=0; j<GDIM; j++)
res[i][j] = t[i][j] * fac;
return res;
}
transmatrix xyzscale(const transmatrix& t, double fac, double facz) {
transmatrix res;
for(int i=0; i<MDIM; i++) for(int j=0; j<DIM; j++)
for(int i=0; i<MDIM; i++) for(int j=0; j<GDIM; j++)
res[i][j] = t[i][j] * fac;
for(int i=0; i<MDIM; i++)
res[i][DIM] = t[i][DIM] * facz;
res[i][GDIM] = t[i][GDIM] * facz;
return res;
}
// double downspin_zivory;
transmatrix mzscale(const transmatrix& t, double fac) {
if(DIM == 3) return t * cpush(2, fac);
if(GDIM == 3) return t * cpush(2, fac);
// take only the spin
transmatrix tcentered = gpushxto0(tC0(t)) * t;
// tcentered = tcentered * spin(downspin_zivory);

View File

@ -761,7 +761,7 @@ ld master_to_c7_angle() {
}
transmatrix actualV(const heptspin& hs, const transmatrix& V) {
if(DIM == 3) return V;
if(WDIM == 3) return V;
#if CAP_IRR
if(IRREGULAR)
return V * spin(M_PI + 2 * M_PI / S7 * (hs.spin + irr::periodmap[hs.at].base.spin));
@ -1168,7 +1168,7 @@ void optimizeview() {
if(0) ;
#if CAP_BT || CAP_ARCM || MAXMDIM == 4
else if(binarytiling || archimedean || DIM == 3) {
else if(binarytiling || archimedean || WDIM == 3) {
turn = -1, best = hdist0(tC0(View));
for(int i=0; i<viewctr.at->c7->type; i++) {
int i1 = i * DUALMUL;
@ -1666,7 +1666,7 @@ bool do_draw(cell *c) {
ld extra_generation_distance = 99;
bool do_draw(cell *c, const transmatrix& T) {
if(DIM == 3) {
if(WDIM == 3) {
if(cells_drawn > vid.cells_drawn_limit) return false;
if(vid.use_smart_range) {
if(cells_drawn >= 50 && !in_smart_range(T)) return false;

View File

@ -669,7 +669,7 @@ land_validity_t& land_validity(eLand l) {
return specially_designed;
}
if(DIM == 3) {
if(WDIM == 3) {
if(l == laWarpCoast) return ugly_version;
if(l == laWineyard && hyperbolic && !binarytiling && S7 == 6) return lv::pattern_special;
if(l == laEmerald && hyperbolic && !binarytiling && S7 == 12) return lv::pattern_special;
@ -1059,7 +1059,7 @@ land_validity_t& land_validity(eLand l) {
if(l == laDual && !geometry && !GOLDBERG)
return hyperbolic_37 ? not_in_full_game3 : not_in_full_game;
if(l == laSnakeNest && DIM == 2) {
if(l == laSnakeNest && WDIM == 2) {
if(geosupport_threecolor() < 2)
return needs_threecolor;
else return specially_designed;

View File

@ -265,7 +265,7 @@ bool haveOrbPower() {
cell *c = dcal[i];
if(itemclass(c->item) == IC_ORB) return true;
}
else if(sphere_narcm && DIM == 2) for(int i=0; i<spherecells(); i++) {
else if(sphere_narcm && WDIM == 2) for(int i=0; i<spherecells(); i++) {
cell *c = getDodecahedron(i)->c7;
if(itemclass(c->item) == IC_ORB) return true;
forCellEx(c2, c) if(itemclass(c2->item) == IC_ORB) return true;
@ -474,7 +474,7 @@ void wandering() {
}
if(!peace::on && c->land == laKraken && ((sphere && !hrand(15)) || wchance(items[itKraken], 240)) && !kraken_pseudohept(c)) {
bool b = sphere || canReachPlayer(c, moKrakenH);
if(sphere_narcm && DIM == 2 && (haveKraken() || !items[itOrbFish])) {
if(sphere_narcm && WDIM == 2 && (haveKraken() || !items[itOrbFish])) {
c->monst = moViking; c->wall = waBoat; c->item = itOrbFish;
playSeenSound(c);
continue;

View File

@ -369,7 +369,7 @@ int fieldval_uniq(cell *c) {
}
else if(binarytiling || archimedean) return 0;
else if(&currfp == &fp_invalid) return 0;
else if(DIM == 3) return c->master->fieldval;
else if(WDIM == 3) return c->master->fieldval;
else if(ctof(c) || NONSTDVAR) return c->master->fieldval/S7;
else {
int z = 0;
@ -450,7 +450,7 @@ int getHemisphere(heptagon *h, int which) {
int getHemisphere(cell *c, int which) {
if(euwrap) return 0;
if(DIM == 3) {
if(WDIM == 3) {
hyperpoint p = tC0(calc_relative_matrix(c, currentmap->gamestart(), C0));
return int(p[which] * 6 + 10.5) - 10;
}
@ -766,7 +766,7 @@ namespace patterns {
}
void val_all(cell *c, patterninfo &si, int sub, int pat) {
if(IRREGULAR || archimedean || binarytiling || DIM == 3) si.symmetries = 1;
if(IRREGULAR || archimedean || binarytiling || WDIM == 3) si.symmetries = 1;
else if(a46) val46(c, si, sub, pat);
else if(a38) val38(c, si, sub, pat);
else if(sphere && S3 == 3) valSibling(c, si, sub, pat);
@ -1296,7 +1296,7 @@ bool pseudohept(cell *c) {
if(binarytiling) return binary::pseudohept(c);
#endif
#if MAXMDIM == 4
if(DIM == 3) {
if(WDIM == 3) {
if(geometry == gField435) return false;
else if(euclid) return euclid3::pseudohept(c);
else return reg3::pseudohept(c);

View File

@ -131,14 +131,16 @@ void hpcpush(hyperpoint h) {
bool validsidepar[SIDEPARS];
hyperpoint zshift(hyperpoint x, ld z) {
if(DIM == 3 && WDIM == 2)
return rgpushxto0(x) * cpush(2, z) * C0;
else return mscale(x, z);
}
void chasmifyPoly(double fac, double fac2, int k) {
for(int i=isize(hpc)-1; i >= last->s; i--) {
hyperpoint H;
for(int j=0; j<3; j++) {
H[j] = hpc[i][j] * fac;
hpc[i][j] *= fac2;
}
hpc.push_back(H);
hpc.push_back(zshift(hpc[i], fac));
hpc[i] = zshift(hpc[i], fac2);
}
hpc.push_back(hpc[last->s]);
last->flags |= POLY_ISSIDE;
@ -1535,7 +1537,7 @@ void drawqueue() {
for(PPR p: {PPR::REDWALLs, PPR::REDWALLs2, PPR::REDWALLs3, PPR::WALL3s,
PPR::LAKEWALL, PPR::INLAKEWALL, PPR::BELOWBOTTOM})
sort(&ptds[qp0[int(p)]], &ptds[qp[int(p)]],
if(DIM == 2) sort(&ptds[qp0[int(p)]], &ptds[qp[int(p)]],
[] (const unique_ptr<drawqueueitem>& p1, const unique_ptr<drawqueueitem>& p2) {
auto ap1 = (dqi_poly&) *p1;
auto ap2 = (dqi_poly&) *p2;
@ -1993,14 +1995,21 @@ template<class... T> ld grot(bool geometry, ld factor, T... t) {
else return grot(t...);
}
ld dlow_table[SIDEPARS], dhi_table[SIDEPARS];
ld dlow_table[SIDEPARS], dhi_table[SIDEPARS], dfloor_table[SIDEPARS];
#define SHADMUL (S3==4 ? 1.05 : 1.3)
void make_sidewalls() {
for(int i=0; i<=3; i++)
dfloor_table[i] = geom3::SLEV[i];
dfloor_table[SIDE_WALL] = geom3::WALL;
dfloor_table[SIDE_LAKE] = geom3::LAKE;
dfloor_table[SIDE_LTOB] = geom3::BOTTOM;
dfloor_table[SIDE_BTOI] = geom3::INFDEEP;
// sidewall parameters for the 3D mode
for(int k=0; k<SIDEPARS; k++) {
double dlow=1, dhi=1;
double dlow=geom3::FLOOR, dhi=geom3::FLOOR;
if(k==SIDE_WALL) dhi = geom3::WALL;
else if(k==SIDE_LAKE) dlow = geom3::LAKE;
else if(k==SIDE_LTOB) dlow = geom3::BOTTOM, dhi = geom3::LAKE;
@ -2010,7 +2019,7 @@ void make_sidewalls() {
dlow_table[k] = dlow;
dhi_table[k] = dhi;
validsidepar[k] = (dlow > 0 && dhi > 0) || (dlow < 0 && dhi < 0);
validsidepar[k] = (dlow > 0 && dhi > 0) || (dlow < 0 && dhi < 0) || GDIM == 3;
bshape(shSemiFloorSide[k], PPR::LAKEWALL);
for(int t=0; t<=3; t+=3) hpcpush(ddi(S7 + (3+t)*S14, floorrad0) * C0);
@ -2444,6 +2453,7 @@ vector<hyperpoint> make5(hyperpoint a, hyperpoint b, hyperpoint c) {
}
void create_wall3d() {
if(WDIM == 2) return;
using namespace hyperpoint_vec;
shWall3D.resize(S7);
shPlainWall3D.resize(S7);
@ -2698,7 +2708,7 @@ void buildpolys() {
#endif
DEBB(DF_INIT, (debugfile,"buildpolys\n"));
if(DIM == 3) {
if(WDIM == 3) {
if(sphere) SD3 = 3, SD7 = 5;
else SD3 = SD7 = 4;
}

View File

@ -1207,7 +1207,7 @@ void set_geometry(eGeometry target) {
if(DUAL && geometry != gArchimedean)
variation = ginf[geometry].default_variation;
#if CAP_BT
if(geometry == gBinaryTiling || DIM == 3) variation = eVariation::pure;
if(geometry == gBinaryTiling || WDIM == 3) variation = eVariation::pure;
#endif
if(DIM == 3 && old_DIM == 2 && pmodel == mdDisk) pmodel = mdPerspective;
if(DIM == 2 && pmodel == mdPerspective) pmodel = mdDisk;

View File

@ -272,7 +272,7 @@ namespace yendor {
}
}
else if(DIM == 3) {
else if(WDIM == 3) {
int d = celldistance(nyi.path[0], ycw.at);
vector<cell*> next;
forCellCM(c, ycw.at) if(celldistance(nyi.path[0], c) > d) next.push_back(c);