1
0
mirror of https://github.com/zenorogue/hyperrogue.git synced 2025-06-17 13:54:08 +00:00

reworked wmspatial: consistent naming of geometry variables, priorities, and side parameters. Fixed some bugs with shallow water

This commit is contained in:
Zeno Rogue 2025-03-16 23:34:55 +01:00
parent 5320da992d
commit a48dc9a856
15 changed files with 401 additions and 446 deletions

View File

@ -1135,7 +1135,7 @@ void geometry_information::make_3d_models() {
} }
shift_shape(shBoatOuter, FLOOR); shift_shape(shBoatOuter, FLOOR);
shift_shape(shBoatInner, (FLOOR+LAKE)/2); shift_shape(shBoatInner, (FLOOR+WATERLEVEL)/2);
for(int i=0; i<14; i++) for(int i=0; i<14; i++)
shift_shape(shTriheptaSpecial[i], FLOOR); shift_shape(shTriheptaSpecial[i], FLOOR);

View File

@ -4,6 +4,11 @@ namespace hr {
#if HDR #if HDR
int coastvalEdge(cell *c); int coastvalEdge(cell *c);
struct spatial_info {
SIDE top, deep;
int levels;
};
struct celldrawer { struct celldrawer {
cell *c; cell *c;
shiftmatrix V; shiftmatrix V;
@ -14,7 +19,6 @@ struct celldrawer {
color_t asciicol; color_t asciicol;
color_t aura_color; color_t aura_color;
int fd; int fd;
int chasmg;
int ct6; int ct6;
bool error; bool error;
bool onradar; bool onradar;
@ -22,6 +26,7 @@ struct celldrawer {
shiftmatrix Vboat; shiftmatrix Vboat;
shiftmatrix Vd; shiftmatrix Vd;
int sl; int sl;
spatial_info sha;
color_t asciiborder; color_t asciiborder;
color_t asciicol1; color_t asciicol1;
char asciichar1; char asciichar1;
@ -730,18 +735,9 @@ void celldrawer::draw_wall() {
int hdir = 0; int hdir = 0;
for(int i=0; i<c->type; i++) if(c->move(i)->wall == waClosedGate) for(int i=0; i<c->type; i++) if(c->move(i)->wall == waClosedGate)
hdir = i; hdir = i;
queuepolyat(V * ddspin180(c, hdir), cgi.shPalaceGate, darkena(wcol, 0, 0xFF), wmspatial?PPR::WALL3A:PPR::WALL); queuepolyat(V * ddspin180(c, hdir), cgi.shPalaceGate, darkena(wcol, 0, 0xFF), wmspatial?PPR::WALL_DECO:PPR::WALL);
return; return;
} }
color_t wcol0 = wcol_star;
color_t wcol2 = gradient(0, wcol0, 0, .8, 1);
color_t wcol1 = wcol2;
if(geometry == gEuclidSquare) wcol1 = gradient(0, wcol0, 0, .9, 1);
draw_shapevec(c, V, qfi.fshape->levels[SIDE_WALL], darkena(wcol_star, 0, 0xFF), PPR::WALL);
forCellIdEx(c2, i, c)
if(!highwall(c2) || conegraph(c2) || c2->wall == waClosedGate || fake::split())
placeSidewall(c, i, SIDE_WALL, V, darkena((i&1)?wcol1:wcol2, fd, 255));
draw_wallshadow(); draw_wallshadow();
return; return;
} }
@ -752,14 +748,12 @@ void celldrawer::draw_wall() {
if(c->wall == waWarpGate) starcol = 0; if(c->wall == waWarpGate) starcol = 0;
if(c->wall == waVinePlant) starcol = 0x60C000; if(c->wall == waVinePlant) starcol = 0x60C000;
color_t wcol2 = gradient(0, wcol0, 0, .8, 1);
if(c->wall == waClosedGate) { if(c->wall == waClosedGate) {
int hdir = 0; int hdir = 0;
for(int i=0; i<c->type; i++) if(c->move(i) && c->move(i)->wall == waClosedGate) for(int i=0; i<c->type; i++) if(c->move(i) && c->move(i)->wall == waClosedGate)
hdir = i; hdir = i;
shiftmatrix V2 = orthogonal_move_fol(V, wmspatial?cgi.WALL:1) * ddspin180(c, hdir); // to test shiftmatrix V2 = orthogonal_move_fol(V, wmspatial?cgi.WALL:1) * ddspin180(c, hdir); // to test
queuepolyat(V2, cgi.shPalaceGate, darkena(wcol, 0, 0xFF), wmspatial?PPR::WALL3A:PPR::WALL); queuepolyat(V2, cgi.shPalaceGate, darkena(wcol, 0, 0xFF), wmspatial?PPR::WALL_DECO:PPR::WALL);
starcol = 0; starcol = 0;
} }
@ -776,7 +770,7 @@ void celldrawer::draw_wall() {
for(int z=1; z<layers; z++) { for(int z=1; z<layers; z++) {
double zg = zgrad0(0, geom3::actual_wall_height(), z, layers); double zg = zgrad0(0, geom3::actual_wall_height(), z, layers);
draw_qfi(c, xyzscale(V, zg*(layers-z)/layers, zg), draw_qfi(c, xyzscale(V, zg*(layers-z)/layers, zg),
darkena(gradient(0, wcol_star, -layers, z, layers), 0, 0xFF), PPR::WALL3+z-layers+2); darkena(gradient(0, wcol_star, -layers, z, layers), 0, 0xFF), PPR::WALL_SIDE);
} }
floorShadow(c, V, SHADOW_WALL); floorShadow(c, V, SHADOW_WALL);
} }
@ -792,31 +786,10 @@ void celldrawer::draw_wall() {
alpha = 0xC0; alpha = 0xC0;
if(starcol && !(wmescher && c->wall == waPlatform)) if(starcol && !(wmescher && c->wall == waPlatform))
queuepolyat(Vdepth, shThisWall, darkena(starcol, 0, 0xFF), PPR::WALL3A); queuepolyat(Vdepth, shThisWall, darkena(starcol, 0, 0xFF), PPR::WALL_DECO);
draw_qfi(c, Vdepth, darkena(wcol0, fd, alpha), PPR::WALL3); draw_qfi(c, Vdepth, darkena(wcol0, fd, alpha), PPR::WALL_TOP);
floorShadow(c, V, SHADOW_WALL); floorShadow(c, V, SHADOW_WALL);
if(c->wall == waCamelot) {
forCellIdEx(c2, i, c) {
if(placeSidewall(c, i, SIDE_SLEV, V, darkena(wcol2, fd, alpha))) break;
}
forCellIdEx(c2, i, c) {
if(placeSidewall(c, i, SIDE_SLEV+1, V, darkena(wcol2, fd, alpha))) break;
}
forCellIdEx(c2, i, c) {
if(placeSidewall(c, i, SIDE_SLEV+2, V, darkena(wcol2, fd, alpha))) break;
}
forCellIdEx(c2, i, c) {
if(placeSidewall(c, i, SIDE_WTS3, V, darkena(wcol2, fd, alpha))) break;
}
}
else {
forCellIdEx(c2, i, c)
if(!highwall(c2) || conegraph(c2) || neon_mode == eNeon::illustration) {
if(placeSidewall(c, i, SIDE_WALL, V, darkena(wcol2, fd, alpha))) break;
}
}
} }
} }
} }
@ -856,7 +829,7 @@ void celldrawer::draw_boat() {
animations[LAYER_SMALL][c].footphase = 0; animations[LAYER_SMALL][c].footphase = 0;
} }
if(wmspatial && GDIM == 2) if(wmspatial && GDIM == 2)
queuepolyat(orthogonal_move_fol(Vboat, (cgi.LAKE+1)/2), cgi.shBoatOuter, outcol, PPR::BOATLEV2); queuepolyat(orthogonal_move_fol(Vboat, (cgi.WATERLEVEL+cgi.FLOOR)/2), cgi.shBoatOuter, outcol, PPR::BOATLEV2);
if(GDIM == 3) { if(GDIM == 3) {
queuepoly(orthogonal_move(Vboat, -0.004), cgi.shBoatOuter, outcol); queuepoly(orthogonal_move(Vboat, -0.004), cgi.shBoatOuter, outcol);
queuepoly(orthogonal_move(Vboat, -0.008), cgi.shBoatInner, incol); queuepoly(orthogonal_move(Vboat, -0.008), cgi.shBoatInner, incol);
@ -995,8 +968,8 @@ void celldrawer::draw_halfvine() {
set_floor(cgi.shSemiFeatherFloor[0]); set_floor(cgi.shSemiFeatherFloor[0]);
int dk = 1; int dk = 1;
int vcol = winf[waVinePlant].color; int vcol = winf[waVinePlant].color;
draw_qfi(c, orthogonal_move_fol(V2, cgi.WALL), darkena(vcol, dk, 0xFF), PPR::WALL3A); draw_qfi(c, orthogonal_move_fol(V2, cgi.WALL), darkena(vcol, dk, 0xFF), PPR::WALL_DECO);
escherSidewall(c, SIDE_WALL, V2, darkena(gradient(0, vcol, 0, .8, 1), dk, 0xFF)); escherSidewall(c, SIDE::WALL, V2, darkena(gradient(0, vcol, 0, .8, 1), dk, 0xFF));
queuepoly(V2, cgi.shSemiFeatherFloor[1], darkena(fcol, dk, 0xFF)); queuepoly(V2, cgi.shSemiFeatherFloor[1], darkena(fcol, dk, 0xFF));
set_floor(cgi.shFeatherFloor); set_floor(cgi.shFeatherFloor);
} }
@ -1011,25 +984,25 @@ void celldrawer::draw_halfvine() {
shiftmatrix Vdepth = orthogonal_move_fol(V2, cgi.WALL); shiftmatrix Vdepth = orthogonal_move_fol(V2, cgi.WALL);
queuepolyat(GDIM == 2 ? Vdepth : V2, cgi.shSemiFloor[0], darkena(vcol, fd, 0xFF), PPR::WALL3A); queuepolyat(GDIM == 2 ? Vdepth : V2, cgi.shSemiFloor[0], darkena(vcol, fd, 0xFF), PPR::WALL_DECO);
if(!noshadow) { if(!noshadow) {
dynamicval<color_t> p(poly_outline, OUTLINE_TRANS); dynamicval<color_t> p(poly_outline, OUTLINE_TRANS);
queuepolyat(V2 * spin(120._deg), cgi.shSemiFloorShadow, SHADOW_WALL, GDIM == 2 ? PPR::WALLSHADOW : PPR::TRANSPARENT_SHADOW); queuepolyat(V2 * spin(120._deg), cgi.shSemiFloorShadow, SHADOW_WALL, GDIM == 2 ? PPR::WALLSHADOW : PPR::TRANSPARENT_SHADOW);
} }
#if MAXMDIM >= 4 #if MAXMDIM >= 4
if(GDIM == 3 && qfi.fshape) { if(GDIM == 3 && qfi.fshape) {
auto& side = queuepolyat(V2, cgi.shSemiFloorSide[SIDE_WALL], darkena(vcol, fd, 0xFF), PPR::WALL3A-2+away(V2.T)); auto& side = queuepolyat(V2, cgi.shSemiFloorSide[SIDE::WALL], darkena(vcol, fd, 0xFF), PPR::WALL_DECO-2+away(V2.T));
side.tinf = &floor_texture_vertices[shar.id]; side.tinf = &floor_texture_vertices[shar.id];
ensure_vertex_number(*side.tinf, side.cnt); ensure_vertex_number(*side.tinf, side.cnt);
} }
#endif #endif
if(cgi.validsidepar[SIDE_WALL]) forCellIdEx(c2, j, c) { if(cgi.validsidepar[SIDE::WALL]) forCellIdEx(c2, j, c) {
int dis = i-j; int dis = i-j;
dis %= 6; dis %= 6;
if(dis<0) dis += 6; if(dis<0) dis += 6;
if(dis != 1 && dis != 5) continue; if(dis != 1 && dis != 5) continue;
if(placeSidewall(c, j, SIDE_WALL, V, darkena(vcol2, fd, 0xFF))) break; if(placeSidewall(c, j, SIDE::WALL, V, darkena(vcol2, fd, 0xFF))) break;
} }
} }
@ -1076,10 +1049,10 @@ void celldrawer::draw_mirrorwall() {
else if(wmspatial) { else if(wmspatial) {
const int layers = 2 << detaillevel; const int layers = 2 << detaillevel;
for(int z=1; z<layers; z++) for(int z=1; z<layers; z++)
queuepolyat(orthogonal_move_fol(V2, zgrad0(0, geom3::actual_wall_height(), z, layers)), cgi.shHalfMirror[2], 0xC0C0C080, PPR::WALL3+z-layers); queuepolyat(orthogonal_move_fol(V2, zgrad0(0, geom3::actual_wall_height(), z, layers)), cgi.shHalfMirror[2], 0xC0C0C080, PPR::WALL_SIDE);
} }
else else
queuepolyat(V2, cgi.shHalfMirror[2], 0xC0C0C080, PPR::WALL3); queuepolyat(V2, cgi.shHalfMirror[2], 0xC0C0C080, PPR::WALL_TOP);
} }
else { else {
qfi.spin = ddspin180(c, d); qfi.spin = ddspin180(c, d);
@ -1104,10 +1077,10 @@ void celldrawer::draw_mirrorwall() {
else if(wmspatial) { else if(wmspatial) {
const int layers = 2 << detaillevel; const int layers = 2 << detaillevel;
for(int z=1; z<layers; z++) for(int z=1; z<layers; z++)
queuepolyat(orthogonal_move_fol(V2, zgrad0(0, geom3::actual_wall_height(), z, layers)), cgi.shHalfMirror[ct6], 0xC0C0C080, PPR::WALL3+z-layers); queuepolyat(orthogonal_move_fol(V2, zgrad0(0, geom3::actual_wall_height(), z, layers)), cgi.shHalfMirror[ct6], 0xC0C0C080, PPR::WALL_SIDE);
} }
else else
queuepolyat(V2, cgi.shHalfMirror[ct6], 0xC0C0C080, PPR::WALL3); queuepolyat(V2, cgi.shHalfMirror[ct6], 0xC0C0C080, PPR::WALL_TOP);
} }
} }
@ -1143,7 +1116,7 @@ void celldrawer::set_land_floor(const shiftmatrix& Vf) {
case caflDragon: set_floor(cgi.shDragonFloor); break; case caflDragon: set_floor(cgi.shDragonFloor); break;
case caflReptile: set_reptile_floor(V, fcol); break; case caflReptile: set_reptile_floor(V, fcol); break;
case caflHive: case caflHive:
if(c->wall != waFloorB && c->wall != waFloorA && c->wall != waMirror && c->wall != waCloud && !chasmgraph(c)) { if(c->wall != waFloorB && c->wall != waFloorA && c->wall != waMirror && c->wall != waCloud && sha.top == SIDE::FLOOR) {
set_floor(cgi.shFloor); set_floor(cgi.shFloor);
if(GDIM == 2) { if(GDIM == 2) {
draw_floorshape(c, V, cgi.shMFloor, darkena(fcol, fd + 1, 0xFF), PPR::FLOORa); draw_floorshape(c, V, cgi.shMFloor, darkena(fcol, fd + 1, 0xFF), PPR::FLOORa);
@ -1155,7 +1128,7 @@ void celldrawer::set_land_floor(const shiftmatrix& Vf) {
break; break;
case caflSwitch: case caflSwitch:
set_floor(cgi.shSwitchFloor); set_floor(cgi.shSwitchFloor);
if(!chasmgraph(c) && ctof(c) && STDVAR && !arcm::in() && !bt::in() && GDIM == 2) for(int i=0; i<c->type; i++) if(sha.top == SIDE::FLOOR && ctof(c) && STDVAR && !arcm::in() && !bt::in() && GDIM == 2) for(int i=0; i<c->type; i++)
queuepoly(Vf * ddspin(c, i, M_PI/S7) * xpush(cgi.rhexf), cgi.shSwitchDisk, darkena(fcol, fd, 0xFF)); queuepoly(Vf * ddspin(c, i, M_PI/S7) * xpush(cgi.rhexf), cgi.shSwitchDisk, darkena(fcol, fd, 0xFF));
break; break;
case caflTower: set_towerfloor(celldist); break; case caflTower: set_towerfloor(celldist); break;
@ -1329,8 +1302,8 @@ void celldrawer::set_land_floor(const shiftmatrix& Vf) {
shiftmatrix Vbspin = Vf * bspin; shiftmatrix Vbspin = Vf * bspin;
queuepoly(Vbspin, cgi.shMercuryBridge[1], darkena(fcol, fd+1, 0xFF)); queuepoly(Vbspin, cgi.shMercuryBridge[1], darkena(fcol, fd+1, 0xFF));
if(wmspatial) { if(wmspatial) {
queuepolyat(orthogonal_move_fol(Vbspin, cgi.LAKE), cgi.shMercuryBridge[1], darkena(gradient(0, winf[waMercury].color, 0, 0.8,1), 0, 0x80), PPR::LAKELEV); queuepolyat(orthogonal_move_fol(Vbspin, cgi.WATERLEVEL), cgi.shMercuryBridge[1], darkena(gradient(0, winf[waMercury].color, 0, 0.8,1), 0, 0x80), PPR::WATERLEVEL_TOP);
queuepolyat(orthogonal_move_fol(Vbspin, cgi.BOTTOM), cgi.shMercuryBridge[1], darkena(0x202020, 0, 0xFF), PPR::LAKEBOTTOM); queuepolyat(orthogonal_move_fol(Vbspin, cgi.DEEP), cgi.shMercuryBridge[1], darkena(0x202020, 0, 0xFF), PPR::DEEP_TOP);
} }
} }
} }
@ -1458,22 +1431,22 @@ void celldrawer::draw_features() {
case waBigBush: case waBigBush:
if(detaillevel >= 2) if(detaillevel >= 2)
queuepolyat(at_smart_lof(V, zgrad0(0, cgi.slev, 1, 2)), cgi.shHeptaMarker, darkena(wcol, 0, 0xFF), PPR::REDWALL); queuepolyat(at_smart_lof(V, zgrad0(0, cgi.slev, 1, 2)), cgi.shHeptaMarker, darkena(wcol, 0, 0xFF), PPR::RED1_TOP);
if(detaillevel >= 1) if(detaillevel >= 1)
queuepolyat(at_smart_lof(V, cgi.SLEV[1]) * lpispin(), cgi.shWeakBranch, darkena(wcol, 0, 0xFF), PPR::REDWALL+1); queuepolyat(at_smart_lof(V, cgi.RED[1]) * lpispin(), cgi.shWeakBranch, darkena(wcol, 0, 0xFF), PPR::RED1_TOP+1);
if(detaillevel >= 2) if(detaillevel >= 2)
queuepolyat(at_smart_lof(V, zgrad0(0, cgi.slev, 3, 2)), cgi.shHeptaMarker, darkena(wcol, 0, 0xFF), PPR::REDWALL+2); queuepolyat(at_smart_lof(V, zgrad0(0, cgi.slev, 3, 2)), cgi.shHeptaMarker, darkena(wcol, 0, 0xFF), PPR::RED1_TOP+2);
queuepolyat(at_smart_lof(V, cgi.SLEV[2]), cgi.shSolidBranch, darkena(wcol, 0, 0xFF), PPR::REDWALL+3); queuepolyat(at_smart_lof(V, cgi.RED[2]), cgi.shSolidBranch, darkena(wcol, 0, 0xFF), PPR::RED1_TOP+3);
break; break;
case waSmallBush: case waSmallBush:
if(detaillevel >= 2) if(detaillevel >= 2)
queuepolyat(at_smart_lof(V, zgrad0(0, cgi.slev, 1, 2)), cgi.shHeptaMarker, darkena(wcol, 0, 0xFF), PPR::REDWALL); queuepolyat(at_smart_lof(V, zgrad0(0, cgi.slev, 1, 2)), cgi.shHeptaMarker, darkena(wcol, 0, 0xFF), PPR::RED1_TOP);
if(detaillevel >= 1) if(detaillevel >= 1)
queuepolyat(at_smart_lof(V, cgi.SLEV[1]) * lpispin(), cgi.shWeakBranch, darkena(wcol, 0, 0xFF), PPR::REDWALL+1); queuepolyat(at_smart_lof(V, cgi.RED[1]) * lpispin(), cgi.shWeakBranch, darkena(wcol, 0, 0xFF), PPR::RED1_TOP+1);
if(detaillevel >= 2) if(detaillevel >= 2)
queuepolyat(at_smart_lof(V, zgrad0(0, cgi.slev, 3, 2)), cgi.shHeptaMarker, darkena(wcol, 0, 0xFF), PPR::REDWALL+2); queuepolyat(at_smart_lof(V, zgrad0(0, cgi.slev, 3, 2)), cgi.shHeptaMarker, darkena(wcol, 0, 0xFF), PPR::RED1_TOP+2);
queuepolyat(at_smart_lof(V, cgi.SLEV[2]), cgi.shWeakBranch, darkena(wcol, 0, 0xFF), PPR::REDWALL+3); queuepolyat(at_smart_lof(V, cgi.RED[2]), cgi.shWeakBranch, darkena(wcol, 0, 0xFF), PPR::RED1_TOP+3);
break; break;
case waSolidBranch: case waSolidBranch:
@ -1487,7 +1460,7 @@ void celldrawer::draw_features() {
case waLadder: case waLadder:
if(GDIM == 3) { if(GDIM == 3) {
#if MAXMDIM >= 4 #if MAXMDIM >= 4
draw_shapevec(c, V * lzpush(-cgi.human_height/20), cgi.shMFloor.levels[0], 0x804000FF, PPR::FLOOR+1); draw_shapevec(c, V * lzpush(-cgi.human_height/20), cgi.shMFloor.levels[SIDE::FLOOR], 0x804000FF, PPR::FLOOR+1);
#endif #endif
} }
else if(euclid) { else if(euclid) {
@ -1504,12 +1477,8 @@ void celldrawer::draw_features() {
Vboat = V; Vboat = V;
dynamicval<qfloorinfo> qfi2(qfi, qfi); dynamicval<qfloorinfo> qfi2(qfi, qfi);
color_t col = reptilecolor(c); color_t col = reptilecolor(c);
chasmg = 0;
set_reptile_floor(V, col); set_reptile_floor(V, col);
draw_qfi(c, V, col); draw_qfi(c, V, col);
forCellIdEx(c2, i, c) if(chasmgraph(c2))
if(placeSidewall(c, i, SIDE_LAKE, V, darkena(gradient(0, col, 0, .8, 1), fd, 0xFF))) break;
chasmg = 1;
break; break;
} }
@ -1555,8 +1524,8 @@ void celldrawer::draw_features() {
if(wmescher && geosupport_football() == 2 && pseudohept(c) && c->land == laPalace) V2 = V * spin(M_PI / c->type); if(wmescher && geosupport_football() == 2 && pseudohept(c) && c->land == laPalace) V2 = V * spin(M_PI / c->type);
if(GDIM == 3) { if(GDIM == 3) {
#if MAXMDIM >= 4 #if MAXMDIM >= 4
draw_shapevec(c, V2 * lzpush(-cgi.human_height/40), cgi.shMFloor.levels[0], darkena(winf[c->wall].color, 0, 0xFF)); draw_shapevec(c, V2 * lzpush(-cgi.human_height/40), cgi.shMFloor.levels[SIDE::FLOOR], darkena(winf[c->wall].color, 0, 0xFF));
draw_shapevec(c, V2 * lzpush(-cgi.human_height/35), cgi.shMFloor2.levels[0], (!wmblack) ? darkena(fcol, 1, 0xFF) : darkena(0,1,0xFF)); draw_shapevec(c, V2 * lzpush(-cgi.human_height/35), cgi.shMFloor2.levels[SIDE::FLOOR], (!wmblack) ? darkena(fcol, 1, 0xFF) : darkena(0,1,0xFF));
#endif #endif
} }
else { else {
@ -1577,11 +1546,11 @@ void celldrawer::draw_features() {
const int layers = 2 << detaillevel; const int layers = 2 << detaillevel;
for(int z=1; z<=layers; z++) { for(int z=1; z<=layers; z++) {
double zg = zgrad0(0, geom3::actual_wall_height(), z, layers); double zg = zgrad0(0, geom3::actual_wall_height(), z, layers);
queuepolyat(xyzscale(V, zg, zg), cgi.shBarrel, darkena((z&1) ? 0xFF0000 : 0xC00000, 0, 0xFF), PPR(PPR::REDWALLm+z)); queuepolyat(xyzscale(V, zg, zg), cgi.shBarrel, darkena((z&1) ? 0xFF0000 : 0xC00000, 0, 0xFF), PPR(PPR::RED1_SIDE));
} }
} }
else { else {
queuepolyat(V, cgi.shBarrel, darkena(0xC00000, 0, 0xFF), PPR(PPR::REDWALLm)); queuepolyat(V, cgi.shBarrel, darkena(0xC00000, 0, 0xFF), PPR(PPR::RED1_TOP));
} }
} }
break; break;
@ -1626,13 +1595,13 @@ void celldrawer::draw_features() {
int dcol = darkena(col, 0, 0x80); int dcol = darkena(col, 0, 0x80);
shiftmatrix Vdepth = orthogonal_move_fol(Vd, cgi.WALL); shiftmatrix Vdepth = orthogonal_move_fol(Vd, cgi.WALL);
if(GDIM == 3) if(GDIM == 3)
draw_shapevec(c, V, cgi.shMFloor.levels[SIDE_WALL], dcol, PPR::WALL); draw_shapevec(c, V, cgi.shMFloor.levels[SIDE::WALL], dcol, PPR::WALL);
else else
draw_floorshape(c, Vdepth, cgi.shMFloor, dcol, PPR::WALL); // GLASS draw_floorshape(c, Vdepth, cgi.shMFloor, dcol, PPR::WALL); // GLASS
dynamicval<qfloorinfo> dq(qfi, qfi); dynamicval<qfloorinfo> dq(qfi, qfi);
set_floor(cgi.shMFloor); set_floor(cgi.shMFloor);
if(cgi.validsidepar[SIDE_WALL]) forCellIdEx(c2, i, c) if(cgi.validsidepar[SIDE::WALL]) forCellIdEx(c2, i, c)
if(placeSidewall(c, i, SIDE_WALL, Vd, dcol)) break; if(placeSidewall(c, i, SIDE::WALL, Vd, dcol)) break;
} }
break; break;
@ -1656,8 +1625,8 @@ void celldrawer::draw_features() {
if(GDIM == 3) { if(GDIM == 3) {
#if MAXMDIM >= 4 #if MAXMDIM >= 4
draw_shapevec(c, V * lzpush(-cgi.human_height/40), cgi.shMFloor.levels[0], darkena(0xC00000, 0, 0xFF)); draw_shapevec(c, V * lzpush(-cgi.human_height/40), cgi.shMFloor.levels[SIDE::FLOOR], darkena(0xC00000, 0, 0xFF));
draw_shapevec(c, V * lzpush(-cgi.human_height/20), cgi.shMFloor2.levels[0], darkena(0x600000, 0, 0xFF)); draw_shapevec(c, V * lzpush(-cgi.human_height/20), cgi.shMFloor2.levels[SIDE::FLOOR], darkena(0x600000, 0, 0xFF));
#endif #endif
} }
else { else {
@ -1687,7 +1656,7 @@ void celldrawer::draw_features() {
for(int z=1; z<layers; z++) { for(int z=1; z<layers; z++) {
double zg = zgrad0(-vid.lake_top, geom3::actual_wall_height(), z, layers); double zg = zgrad0(-vid.lake_top, geom3::actual_wall_height(), z, layers);
draw_qfi(c, xyzscale(V, zg*(layers-z)/layers, zg), draw_qfi(c, xyzscale(V, zg*(layers-z)/layers, zg),
darkena(gradient(0, wcol, -layers, z, layers), 0, 0xFF), PPR::WALL3+z-layers+2); darkena(gradient(0, wcol, -layers, z, layers), 0, 0xFF), PPR::WALL_SIDE);
} }
} }
else goto wa_default; else goto wa_default;
@ -1711,21 +1680,11 @@ void celldrawer::draw_features() {
default: { default: {
wa_default: wa_default:
if(sl && wmspatial) { if(sl && wmspatial) {
if(GDIM == 3 && qfi.fshape)
draw_shapevec(c, V, qfi.fshape->levels[sl], darkena(wcol, fd, 0xFF), PPR::REDWALL-4+4*sl);
else
draw_qfi(c, Vd, darkena(wcol, fd, 0xFF), PPR::REDWALL-4+4*sl);
floorShadow(c, V, SHADOW_SL * sl); floorShadow(c, V, SHADOW_SL * sl);
for(int s=0; s<sl; s++)
forCellIdEx(c2, i, c) {
int sl_2 = snakelevel(c2);
if(s >= sl_2)
if(placeSidewall(c, i, SIDE_SLEV+s, V, getSnakelevColor(s, sl))) break;
}
} }
else if(highwall(c)) draw_wall(); else if(highwall(c)) draw_wall();
else if(xch == '%') { else if(xch == '%') {
@ -1737,13 +1696,13 @@ void celldrawer::draw_features() {
int dcol = darkena(col, 0, 0xC0); int dcol = darkena(col, 0, 0xC0);
shiftmatrix Vdepth = orthogonal_move_fol(Vd, cgi.WALL); shiftmatrix Vdepth = orthogonal_move_fol(Vd, cgi.WALL);
if(GDIM == 3) if(GDIM == 3)
draw_shapevec(c, V, cgi.shMFloor.levels[SIDE_WALL], dcol, PPR::WALL); draw_shapevec(c, V, cgi.shMFloor.levels[SIDE::WALL], dcol, PPR::WALL);
else else
draw_floorshape(c, Vdepth, cgi.shMFloor, dcol, PPR::WALL); // GLASS draw_floorshape(c, Vdepth, cgi.shMFloor, dcol, PPR::WALL); // GLASS
dynamicval<qfloorinfo> dq(qfi, qfi); dynamicval<qfloorinfo> dq(qfi, qfi);
set_floor(cgi.shMFloor); set_floor(cgi.shMFloor);
if(cgi.validsidepar[SIDE_WALL]) forCellIdEx(c2, i, c) if(cgi.validsidepar[SIDE::WALL]) forCellIdEx(c2, i, c)
if(placeSidewall(c, i, SIDE_WALL, Vd, dcol)) break; if(placeSidewall(c, i, SIDE::WALL, Vd, dcol)) break;
} }
else { else {
queuepoly(V, cgi.shMirror, darkena(wcol, 0, 0xC0)); queuepoly(V, cgi.shMirror, darkena(wcol, 0, 0xC0));
@ -1770,14 +1729,14 @@ void celldrawer::draw_features() {
else if(c->wall == waExplosiveBarrel) { else if(c->wall == waExplosiveBarrel) {
if(GDIM == 3 && qfi.fshape) { if(GDIM == 3 && qfi.fshape) {
draw_shapevec(c, V, qfi.fshape->cone[1], 0xD00000FF, PPR::REDWALL); draw_shapevec(c, V, qfi.fshape->cone[1], 0xD00000FF, PPR::RED1_TOP);
draw_wallshadow(); draw_wallshadow();
break; break;
} }
const int layers = 2 << detaillevel; const int layers = 2 << detaillevel;
for(int z=1; z<=layers; z++) { for(int z=1; z<=layers; z++) {
double zg = zgrad0(0, geom3::actual_wall_height(), z, layers); double zg = zgrad0(0, geom3::actual_wall_height(), z, layers);
queuepolyat(xyzscale(V, zg, zg), cgi.shBarrel, darkena((z&1) ? 0xFF0000 : 0xC00000, 0, 0xFF), PPR(PPR::REDWALLm+z)); queuepolyat(xyzscale(V, zg, zg), cgi.shBarrel, darkena((z&1) ? 0xFF0000 : 0xC00000, 0, 0xFF), PPR(PPR::RED1_SIDE));
} }
} }
@ -1949,13 +1908,13 @@ void celldrawer::draw_features_and_walls_3d() {
else if(winf[c->wall].glyph == '.' || among(c->wall, waFloorA, waFloorB, waChasm, waLadder, waCanopy, waRed1, waRed2, waRed3, waRubble, waDeadfloor2) || isWatery(c) || isSulphuric(c->wall)) ; else if(winf[c->wall].glyph == '.' || among(c->wall, waFloorA, waFloorB, waChasm, waLadder, waCanopy, waRed1, waRed2, waRed3, waRubble, waDeadfloor2) || isWatery(c) || isSulphuric(c->wall)) ;
else if(c->wall == waBigBush || c->wall == waSolidBranch) else if(c->wall == waBigBush || c->wall == waSolidBranch)
queuepolyat(face_the_player(V), cgi.shSolidBranch, darkena(wcol, 0, 0xFF), PPR::REDWALL+3); queuepolyat(face_the_player(V), cgi.shSolidBranch, darkena(wcol, 0, 0xFF), PPR::RED3_TOP);
else if(c->wall == waSmallBush || c->wall == waWeakBranch) else if(c->wall == waSmallBush || c->wall == waWeakBranch)
queuepolyat(face_the_player(V), cgi.shWeakBranch, darkena(wcol, 0, 0xFF), PPR::REDWALL+3); queuepolyat(face_the_player(V), cgi.shWeakBranch, darkena(wcol, 0, 0xFF), PPR::RED2_TOP);
else else
queuepoly(face_the_player(V), chasmgraph(c) ? cgi.shSawRing : cgi.shRing, darkena(wcol, 0, 0xFF)); queuepoly(face_the_player(V), sha.deep < SIDE::SHALLOW ? cgi.shSawRing : cgi.shRing, darkena(wcol, 0, 0xFF));
} }
after_walls: after_walls:
@ -2216,7 +2175,7 @@ EX int default_flooralpha = 255;
void celldrawer::draw_wall_full() { void celldrawer::draw_wall_full() {
shiftmatrix Vf0; shiftmatrix Vf0;
const shiftmatrix& Vf = (chasmg && wmspatial) ? (Vf0=orthogonal_move_fol(V, cgi.BOTTOM)) : V; const shiftmatrix& Vf = (sha.top != SIDE::FLOOR) ? (Vf0=orthogonal_move_fol(V, cgi.dhi_table[sha.top])) : V;
#if CAP_SHAPES #if CAP_SHAPES
int flooralpha = default_flooralpha; int flooralpha = default_flooralpha;
@ -2243,9 +2202,9 @@ void celldrawer::draw_wall_full() {
if(GDIM == 2 && (c->land != laRose || ls::any_chaos())) { if(GDIM == 2 && (c->land != laRose || ls::any_chaos())) {
int rd = rosedist(c); int rd = rosedist(c);
if(rd == 1) if(rd == 1)
draw_floorshape(c, at_smart_lof(V, cgi.SLEV[2]), cgi.shRoseFloor, 0x80406040, PPR::LIZEYE); draw_floorshape(c, at_smart_lof(V, cgi.RED[2]), cgi.shRoseFloor, 0x80406040, PPR::LIZEYE);
if(rd == 2) if(rd == 2)
draw_floorshape(c, at_smart_lof(V, cgi.SLEV[2]), cgi.shRoseFloor, 0x80406080, PPR::LIZEYE); draw_floorshape(c, at_smart_lof(V, cgi.RED[2]), cgi.shRoseFloor, 0x80406080, PPR::LIZEYE);
} }
if(c->wall == waChasm) { if(c->wall == waChasm) {
@ -2259,11 +2218,11 @@ void celldrawer::draw_wall_full() {
} }
if(c->land == laZebra) fd++; if(c->land == laZebra) fd++;
if(c->land == laHalloween && !wmblack) { if(c->land == laHalloween && !wmblack) {
shiftmatrix Vdepth = wmspatial ? orthogonal_move_fol(V, cgi.BOTTOM) : V; shiftmatrix Vdepth = wmspatial ? orthogonal_move_fol(V, cgi.DEEP) : V;
if(GDIM == 3) if(GDIM == 3)
draw_shapevec(c, V, cgi.shFullFloor.levels[SIDE_LAKE], darkena(firecolor(0, 10), 0, 0xDF), PPR::TRANSPARENT_LAKE); draw_shapevec(c, V, cgi.shFullFloor.levels[SIDE::WATERLEVEL], darkena(firecolor(0, 10), 0, 0xDF), PPR::TRANSPARENT_LAKE);
else else
draw_floorshape(c, Vdepth, cgi.shFullFloor, darkena(firecolor(0, 10), 0, 0xDF), PPR::LAKEBOTTOM); draw_floorshape(c, Vdepth, cgi.shFullFloor, darkena(firecolor(0, 10), 0, 0xDF), PPR::DEEP_TOP);
} }
} }
@ -2338,14 +2297,7 @@ void celldrawer::draw_wall_full() {
// actually draw the floor // actually draw the floor
if(chasmg == 2) ; if((sha.top != sha.deep) && wmspatial && detaillevel) {
else if(chasmg && wmspatial && detaillevel == 0) {
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, Vd, darkena(fcol, fd, 0x80), PPR::LAKELEV);
}
else if(chasmg && wmspatial) {
color_t col = c->land == laCocytus ? 0x080808FF : 0x101010FF; color_t col = c->land == laCocytus ? 0x080808FF : 0x101010FF;
@ -2358,27 +2310,32 @@ void celldrawer::draw_wall_full() {
else if(qfi.fshape == &cgi.shCaveFloor) else if(qfi.fshape == &cgi.shCaveFloor)
set_floor(cgi.shCaveSeabed); set_floor(cgi.shCaveSeabed);
int sid = SIDE_LTOB;
if(c->wall == waShallow) sid = SIDE_ASHA;
if(WDIM == 2 && GDIM == 3 && qfi.fshape) if(WDIM == 2 && GDIM == 3 && qfi.fshape)
draw_shapevec(c, V, qfi.fshape->levels[sid], col, PPR::LAKEBOTTOM); draw_shapevec(c, V, qfi.fshape->levels[sha.deep], col, side_to_prio_top[sha.deep]);
else else
draw_qfi(c, orthogonal_move_fol(V, cgi.BOTTOM), col, PPR::LAKEBOTTOM); draw_qfi(c, orthogonal_move_fol(V, cgi.dhi_table[sha.deep]), col, side_to_prio_top[sha.deep]);
int fd0 = fd ? fd-1 : 0; int fd0 = fd ? fd-1 : 0;
if(WDIM == 2 && GDIM == 3 && qfi.fshape) if(WDIM == 2 && GDIM == 3 && qfi.fshape)
draw_shapevec(c, V, qfi.fshape->levels[SIDE_LAKE], darkena3(fcol, fd0, 0x80), PPR::TRANSPARENT_LAKE); draw_shapevec(c, V, qfi.fshape->levels[sha.top], darkena3(fcol, fd0, 0x80), PPR::TRANSPARENT_LAKE);
else else
draw_qfi(c, Vd, darkena(fcol, fd0, 0x80), PPR::LAKELEV); draw_qfi(c, Vd, darkena(fcol, fd0, 0x80), PPR::WATERLEVEL_TOP);
} }
else {
else if(sha.top != SIDE::INFDEEP) {
auto col = fcol;
if(patterns::whichShape == '^') poly_outline = darkena(fcol, fd, flooralpha); if(patterns::whichShape == '^') poly_outline = darkena(fcol, fd, flooralpha);
if(sha.top == SIDE::WALL) col = wcol_star;
else if(sha.top >= SIDE::RED1) col = wcol;
auto sf = sha.top; if(!wmspatial) sf = SIDE::FLOOR;
if(WDIM == 2 && GDIM == 3 && qfi.fshape && !draw_plain_floors) if(WDIM == 2 && GDIM == 3 && qfi.fshape && !draw_plain_floors)
draw_shapevec(c, V, qfi.fshape->levels[0], darkena(fcol, fd, 255), PPR::FLOOR); draw_shapevec(c, V, qfi.fshape->levels[sf], darkena(col, fd, 255), side_to_prio_top[sha.top]);
else { else if(sf == SIDE::FLOOR)
draw_qfi(c, V, darkena3(fcol, fd, flooralpha)); draw_qfi(c, V, darkena3(col, fd, flooralpha), PPR::FLOOR);
} else
draw_qfi(c, orthogonal_move_fol(V, cgi.dhi_table[sf]), darkena3(col, fd, flooralpha), side_to_prio_top[sha.top]);
} }
#if MAXMDIM >= 4 #if MAXMDIM >= 4
@ -2398,7 +2355,7 @@ void celldrawer::draw_wall_full() {
if(rd == 2) rcol = 0x80406080; if(rd == 2) rcol = 0x80406080;
forCellIdEx(c2, i, c) forCellIdEx(c2, i, c)
if(rosedist(c2) < rd) if(rosedist(c2) < rd)
placeSidewall(c, i, SIDE_WALL, V, rcol); placeSidewall(c, i, SIDE::WALL, V, rcol);
for(int i=t; i<isize(ptds); i++) { for(int i=t; i<isize(ptds); i++) {
auto p = ptds[i]->as_poly(); auto p = ptds[i]->as_poly();
if(p) p->prio = PPR::TRANSPARENT_WALL; if(p) p->prio = PPR::TRANSPARENT_WALL;
@ -2472,63 +2429,59 @@ void celldrawer::draw_wall_full() {
if(wmascii && !((c->item && !itemHiddenFromSight(c)) || c->monst || c->cpdist == 0)) error = true; if(wmascii && !((c->item && !itemHiddenFromSight(c)) || c->monst || c->cpdist == 0)) error = true;
asciiborder = bordcolor; asciiborder = bordcolor;
} }
#if CAP_SHAPES #if CAP_SHAPES
int sha = shallow(c); if(wmspatial) {
color_t col = (highwall(c) || c->wall == waTower) ? wcol : fcol;
auto shab = sha.levels;
forCellIdEx(c1, i, c) {
auto fsha1 = get_spatial_info(c1);
auto& sha1 = fsha1.levels;
auto sha0 = shab;
constexpr int w = Flag((int) SIDE::WALL);
constexpr int r = ((Flag((int) SIDE::RED1)) | (Flag((int) SIDE::RED2)) | (Flag((int) SIDE::RED3)));
constexpr int r4 = r | (Flag((int) SIDE::RED4));
if(fake::split()) sha1 ^= (w | r | r4);
if(c->land == laCamelot || ((sha0 & w) && (sha1 & r))) {
sha0 ^= (w | r | r4);
}
auto shad = sha0 &~ sha1; shad = shad & ((1<<28)-1);
while(shad) {
int lev = __builtin_ctz(shad);
shad ^= (1<<lev);
auto col1 = darkena(col, fd, 0xFF);
#define D(v) darkena(gradient(0, col, 0, v * (sphere ? spherity(V.T * currentmap->adj(c,i)) : 1), 1), fd, 0xFF) #define D(v) darkena(gradient(0, col, 0, v * (sphere ? spherity(V.T * currentmap->adj(c,i)) : 1), 1), fd, 0xFF)
if(wmspatial && c->wall == waShallow && WDIM == 2) { if(SIDE(lev) == SIDE::FLOOR) col1 = D(0.8);
color_t col = (highwall(c) || c->wall == waTower) ? wcol : fcol; if(SIDE(lev) == SIDE::WATERLEVEL) col1 = D(0.75);
forCellIdEx(c2, i, c) if(chasmgraph(c2) && c2->wall != waShallow) if(SIDE(lev) == SIDE::SHALLOW) col1 = D(0.7);
if(placeSidewall(c, i, SIDE_BSHA, V, D(.6))) break;
forCellIdEx(c2, i, c) if(chasmgraph(c2) == 2) {
dynamicval<qfloorinfo> qfib(qfi, qfi);
set_floor(cgi.shFullFloor);
placeSidewall(c, i, SIDE_LAKE, V, 0x202030FF);
// placeSidewall(c, i, SIDE_LTOB, V, 0x181820FF);
placeSidewall(c, i, SIDE_BTOI, V, 0x101010FF);
}
}
else if(wmspatial && sha && WDIM == 2) {
color_t col = (highwall(c) || c->wall == waTower) ? wcol : fcol;
if(!chasmg) {
// #define D(v) darkena(col, fd, 0xFF)
if(sha & 1) {
forCellIdEx(c2, i, c) if(chasmgraph(c2))
if(placeSidewall(c, i, SIDE_LAKE, V, D(.8))) break;
}
if(sha & 2) {
forCellIdEx(c2, i, c) {
if(chasmgraph(c2)) {
if(placeSidewall(c, i, c2->wall == waShallow ? SIDE_ASHA : SIDE_LTOB, V, D(.7))) break;
}
}
}
if(sha & 4) {
bool dbot = true;
forCellIdEx(c2, i, c) if(chasmgraph(c2) == 2) {
if(dbot) {
dbot = false;
if(GDIM == 2)
draw_qfi(c, orthogonal_move_fol(V, cgi.BOTTOM), 0x080808FF, PPR::LAKEBOTTOM);
else if(qfi.fshape)
draw_shapevec(c, V, qfi.fshape->levels[SIDE_BTOI], 0x0F0808FF, PPR::LAKEBOTTOM);
}
if(placeSidewall(c, i, SIDE_BTOI, V, D(.6))) break;
}
#undef D #undef D
if(SIDE(lev) == SIDE::DEEP) col1 = 0x101010FF;
if(SIDE(lev) == SIDE::WALL) {
col1 = (geometry == gEuclidSquare && (i&1)) ? gradient(0, wcol_star, 0, .9, 1) : gradient(0, wcol_star, 0, .8, 1);
col1 = darkena(col1, fd, 255);
}
if(lev >= int(SIDE::RED1) && lev <= int(SIDE::RED3) && sl) {
col1 = getSnakelevColor(lev - int(SIDE::RED1), sl);
}
if(placeSidewall(c, i, SIDE(lev), V, col1)) shab &= ~(1<<lev);
}
if(sha.top == SIDE::WATERLEVEL && fsha1.top == SIDE::INFDEEP) {
dynamicval<qfloorinfo> qfib(qfi, qfi);
set_floor(cgi.shFullFloor);
placeSidewall(c, i, SIDE::WATERLEVEL, V, 0x202030FF);
if(sha.deep == SIDE::DEEP) placeSidewall(c, i, SIDE::SHALLOW, V, 0x181820FF);
} }
}
// wall between lake and chasm -- no Escher here
if(chasmg == 1) forCellIdEx(c2, i, c) if(chasmgraph(c2) == 2) {
dynamicval<qfloorinfo> qfib(qfi, qfi);
set_floor(cgi.shFullFloor);
placeSidewall(c, i, SIDE_LAKE, V, 0x202030FF);
placeSidewall(c, i, SIDE_LTOB, V, 0x181820FF);
placeSidewall(c, i, SIDE_BTOI, V, 0x101010FF);
} }
} }
} }
@ -2640,8 +2593,8 @@ void celldrawer::draw_monster_full() {
if(dm) onradar = false; if(dm) onradar = false;
#if CAP_SHAPES #if CAP_SHAPES
if(isize(ptds) != q && !(c == lmouseover_distant && isDie(c->monst))) { if(isize(ptds) != q && !(c == lmouseover_distant && isDie(c->monst))) {
if(WDIM == 2 && GDIM == 3 && abs(cgi.SLEV[sl] - cgi.FLOOR) > 1e-6) if(WDIM == 2 && GDIM == 3 && abs(cgi.RED[sl] - cgi.FLOOR) > 1e-6)
pushdown(c, q, V, cgi.SLEV[sl] - cgi.FLOOR, false, false); pushdown(c, q, V, cgi.RED[sl] - cgi.FLOOR, false, false);
if(GDIM ==2 && abs(geom3::factor_to_lev(zlevel(tC0(Vboat.T)))) > 1e-6) if(GDIM ==2 && abs(geom3::factor_to_lev(zlevel(tC0(Vboat.T)))) > 1e-6)
pushdown(c, q, V, -geom3::factor_to_lev(zlevel(tC0(Vboat.T))), !isMultitile(c->monst), false); pushdown(c, q, V, -geom3::factor_to_lev(zlevel(tC0(Vboat.T))), !isMultitile(c->monst), false);
} }
@ -2650,7 +2603,7 @@ void celldrawer::draw_monster_full() {
void celldrawer::add_map_effects() { void celldrawer::add_map_effects() {
if(chasmg) draw_fallanims(); if(get_spatial_info(c).top < SIDE::FLOOR) draw_fallanims();
if(!shmup::on && sword::at(c)) { if(!shmup::on && sword::at(c)) {
queuepolyat(V, cgi.shDisk, 0xC0404040, PPR::SWORDMARK); queuepolyat(V, cgi.shDisk, 0xC0404040, PPR::SWORDMARK);
@ -2965,23 +2918,21 @@ void celldrawer::draw() {
onradar = true; onradar = true;
#if CAP_SHAPES sha = get_spatial_info(c);
chasmg = chasmgraph(c);
#endif
if(c->wall == waMagma) fd = 0; if(c->wall == waMagma) fd = 0;
poly_outline = OUTLINE_DEFAULT; poly_outline = OUTLINE_DEFAULT;
sl = snakelevel(c); sl = snakelevel(c);
Vd = Vd =
WDIM == 3 ? V: WDIM == 3 ? V:
!wmspatial ? V : !wmspatial ? V :
sl ? orthogonal_move_fol(V, GDIM == 3 ? cgi.SLEV[sl] - cgi.FLOOR : cgi.SLEV[sl]) : sl ? orthogonal_move_fol(V, GDIM == 3 ? cgi.RED[sl] - cgi.FLOOR : cgi.RED[sl]) :
(highwall(c) && GDIM == 2) ? orthogonal_move_fol(V, (1+cgi.WALL)/2) : (highwall(c) && GDIM == 2) ? orthogonal_move_fol(V, (1+cgi.WALL)/2) :
#if CAP_SHAPES #if CAP_SHAPES
(chasmg==1) ? orthogonal_move_fol(V, GDIM == 3 ? cgi.LAKE - cgi.FLOOR : cgi.LAKE) : (sha.top < SIDE::FLOOR) ? orthogonal_move_fol(V, GDIM == 3 ? cgi.WATERLEVEL - cgi.FLOOR : cgi.WATERLEVEL) :
#endif #endif
V; V;
@ -3047,16 +2998,12 @@ void celldrawer::draw() {
for(int z=0; z<sl*4; z++) if(z%4 == 0) for(int z=0; z<sl*4; z++) if(z%4 == 0)
queuestrn(orthogonal_move_fol(V, zgrad0(0, cgi.slev * sl, z, sl*4)), mapfontscale / 100, s1, darkenedby(gradient(bordcolor, asciicol1, -sl, z, sl*4), darken), 1); queuestrn(orthogonal_move_fol(V, zgrad0(0, cgi.slev * sl, z, sl*4)), mapfontscale / 100, s1, darkenedby(gradient(bordcolor, asciicol1, -sl, z, sl*4), darken), 1);
poly_outline = asciiborder << 8; poly_outline = asciiborder << 8;
queuestrn(orthogonal_move_fol(V, cgi.SLEV[sl]), mapfontscale / 100, s, darkenedby(asciicol, darken), 2); queuestrn(orthogonal_move_fol(V, cgi.RED[sl]), mapfontscale / 100, s, darkenedby(asciicol, darken), 2);
} }
// else if(c->wall == waChasm) { else if(sha.top < SIDE::FLOOR) {
// const int layers = 1 << detaillevel;
// queuestr(orthogonal_move_fol(V, BOTTOM), zgrad0(0, -vid.lake_bottom, z, layers)), 1, s, darkenedby(gradient(asciicol, 0, 0, z, layers+1), darken), z==0?2:1);
// }
else if(chasmgraph(c)) {
string s1 = s0+asciichar1; string s1 = s0+asciichar1;
poly_outline = bordcolor << 8; poly_outline = bordcolor << 8;
queuestrn(orthogonal_move_fol(V, cgi.BOTTOM), mapfontscale / 100, s1, darkenedby(gradient(bordcolor, asciicol1, 0, 0.3, 1), darken), 2); queuestrn(orthogonal_move_fol(V, cgi.DEEP), mapfontscale / 100, s1, darkenedby(gradient(bordcolor, asciicol1, 0, 0.3, 1), darken), 2);
poly_outline = asciiborder << 8; poly_outline = asciiborder << 8;
queuestrn(V, mapfontscale / 100, s, darkenedby(asciicol, darken), 2); queuestrn(V, mapfontscale / 100, s, darkenedby(asciicol, darken), 2);
} }
@ -3202,7 +3149,7 @@ void celldrawer::set_reptile_floor(const shiftmatrix& V, color_t col, bool nodet
dynamicval<color_t> p(poly_outline, dynamicval<color_t> p(poly_outline,
doHighlight() && ecol != -1 && ecol != 0 ? OUTLINE_ENEMY : OUTLINE_DEFAULT); doHighlight() && ecol != -1 && ecol != 0 ? OUTLINE_ENEMY : OUTLINE_DEFAULT);
if(!chasmg) { if(sha.top != SIDE::INFDEEP) {
if(wmescher) if(wmescher)
queuepoly(V*D, cgi.shReptile[j][1], dcol); queuepoly(V*D, cgi.shReptile[j][1], dcol);
else else
@ -3246,7 +3193,7 @@ void celldrawer::shmup_gravity_floor() {
void celldrawer::draw_reptile(color_t col) { void celldrawer::draw_reptile(color_t col) {
auto qfib = qfi; auto qfib = qfi;
set_reptile_floor(V, col, chasmg == 2); set_reptile_floor(V, col, sha.top == SIDE::INFDEEP);
draw_qfi(c, V, col); draw_qfi(c, V, col);
qfi = qfib; qfi = qfib;
} }

View File

@ -3020,7 +3020,7 @@ EX void show3D_height_details() {
dialog::addBreak(100); dialog::addBreak(100);
dialog::addHelp(lalign(0, "absolute altitudes:\n\n" dialog::addHelp(lalign(0, "absolute altitudes:\n\n"
"depth ", cgi.INFDEEP, "depth ", cgi.INFDEEP,
" water ", tie(cgi.BOTTOM, cgi.SHALLOW, cgi.LAKE), " water ", tie(cgi.DEEP, cgi.SHALLOW, cgi.WATERLEVEL),
" floor ", cgi.FLOOR, " floor ", cgi.FLOOR,
" eye ", vid.eye, " eye ", vid.eye,
" walls ", tie(cgi.WALL, cgi.HIGH, cgi.HIGH2), " walls ", tie(cgi.WALL, cgi.HIGH, cgi.HIGH2),

View File

@ -2387,9 +2387,12 @@ EX void reverse_priority(PPR p) {
reverse(ptds.begin()+qp0[int(p)], ptds.begin()+qp[int(p)]); reverse(ptds.begin()+qp0[int(p)], ptds.begin()+qp[int(p)]);
} }
constexpr PPR all_side_prios[] = {
PPR::DEEP_SIDE, PPR::SHALLOW_SIDE, PPR::WATERLEVEL_SIDE, PPR::FLOOR_SIDE, PPR::RED1_SIDE, PPR::RED2_SIDE, PPR::RED3_SIDE, PPR::WALL_SIDE
};
EX void reverse_side_priorities() { EX void reverse_side_priorities() {
for(PPR p: {PPR::REDWALLs, PPR::REDWALLs2, PPR::REDWALLs3, PPR::WALL3s, for(PPR p: all_side_prios)
PPR::LAKEWALL, PPR::INLAKEWALL, PPR::BELOWBOTTOM, PPR::BSHALLOW, PPR::ASHALLOW})
reverse_priority(p); reverse_priority(p);
} }
@ -2609,9 +2612,8 @@ EX void drawqueue() {
DEBB(DF_GRAPH, ("sort walls")); DEBB(DF_GRAPH, ("sort walls"));
if(GDIM == 2) if(GDIM == 2)
for(PPR p: {PPR::REDWALLs, PPR::REDWALLs2, PPR::REDWALLs3, PPR::WALL3s, for(PPR p: all_side_prios) {
PPR::LAKEWALL, PPR::INLAKEWALL, PPR::BELOWBOTTOM, PPR::ASHALLOW, PPR::BSHALLOW}) {
int pp = int(p); int pp = int(p);
if(qp0[pp] == qp[pp]) continue; if(qp0[pp] == qp[pp]) continue;
for(int i=qp0[pp]; i<qp[pp]; i++) { for(int i=qp0[pp]; i<qp[pp]; i++) {

View File

@ -345,14 +345,33 @@ EX bool highwall(cell *c) {
return winf[c->wall].glyph == '#' || c->wall == waClosedGate; return winf[c->wall].glyph == '#' || c->wall == waClosedGate;
} }
EX int chasmgraph(cell *c) { EX spatial_info get_spatial_info(cell *c) {
if(c->wall == waChasm || c->wall == waInvisibleFloor) return 2; #define F(x) Flag((int) SIDE::x)
if(isChasmy(c)) return 1; if(cellUnstable(c))
if(isWateryOrBoat(c)) return 1; return spatial_info{SIDE::INFDEEP, SIDE::INFDEEP, 0};
if(c->wall == waShallow) return 1; if(c->wall == waChasm || c->wall == waInvisibleFloor)
if(wmescher && c->wall == waBarrier && c->land == laOceanWall) return 1; return spatial_info{SIDE::INFDEEP, SIDE::INFDEEP, 0};
if(c->wall == waReptileBridge) return 1; if(c->wall == waBarrier && wmescher && c->land == laOceanWall)
return 0; return spatial_info{SIDE::WATERLEVEL, SIDE::DEEP, F(DEEP)};
if(c->wall == waReptile)
return spatial_info{SIDE::FLOOR, SIDE::FLOOR, F(FLOOR) | F(DEEP)};
if(c->wall == waShallow)
return spatial_info{SIDE::WATERLEVEL, SIDE::SHALLOW, F(SHALLOW) | F(DEEP)};
if(isWateryOrBoat(c) || isChasmy(c))
return spatial_info{SIDE::WATERLEVEL, SIDE::DEEP, F(DEEP)};
if(among(c->wall, waReptileBridge, waGargoyleFloor, waGargoyleBridge, waTempFloor, waTempBridge, waPetrifiedBridge, waFrozenLake))
return spatial_info{SIDE::WATERLEVEL, SIDE::DEEP, F(WATERLEVEL) | F(DEEP)};
int slev = snakelevel(c);
if(slev == 1)
return spatial_info{SIDE::RED1, SIDE::RED1, F(RED1) | F(FLOOR) | F(WATERLEVEL) | F(SHALLOW) | F(DEEP)};
if(slev == 2)
return spatial_info{SIDE::RED2, SIDE::RED2, F(RED1) | F(RED2) | F(FLOOR) | F(WATERLEVEL) | F(SHALLOW) | F(DEEP)};
if(slev == 3)
return spatial_info{SIDE::RED3, SIDE::RED3, F(RED1) | F(RED2) | F(RED3) | F(FLOOR) | F(WATERLEVEL) | F(SHALLOW) | F(DEEP)};
if(highwall(c))
return spatial_info{SIDE::WALL, SIDE::WALL, F(WALL) | F(FLOOR) | F(WATERLEVEL) | F(SHALLOW) | F(DEEP)};
return spatial_info{SIDE::FLOOR, SIDE::FLOOR, F(FLOOR) | F(WATERLEVEL) | F(SHALLOW) | F(DEEP)};
#undef F
} }
EX bool conegraph(cell *c) { EX bool conegraph(cell *c) {

View File

@ -319,18 +319,18 @@ void geometry_information::bshape_regular(floorshape &fsh, int id, int sides, ld
hpcpush(hpc[last->s]); hpcpush(hpc[last->s]);
} }
for(int k=0; k<SIDEPARS; k++) { for(auto p: allsides) {
if(isize(fsh.gpside[k]) < c->type) if(isize(fsh.gpside[p]) < c->type)
fsh.gpside[k].resize(c->type); fsh.gpside[p].resize(c->type);
for(int i=0; i<c->type; i++) { for(int i=0; i<c->type; i++) {
sizeto(fsh.gpside[k][i], id); sizeto(fsh.gpside[p][i], id);
bshape(fsh.gpside[k][i][id], PPR::LAKEWALL); bshape(fsh.gpside[p][i][id], PPR::FLOOR_SIDE);
hyperpoint h0 = bt::get_corner_horo_coordinates(c, i) * size; hyperpoint h0 = bt::get_corner_horo_coordinates(c, i) * size;
hyperpoint h1 = bt::get_corner_horo_coordinates(c, i+1) * size; hyperpoint h1 = bt::get_corner_horo_coordinates(c, i+1) * size;
hyperpoint hd = (h1 - h0) / STEP; hyperpoint hd = (h1 - h0) / STEP;
for(int j=0; j<=STEP; j++) for(int j=0; j<=STEP; j++)
hpcpush(iddspin_side(c, i) * bt::get_horopoint(h0 + hd * j)); hpcpush(iddspin_side(c, i) * bt::get_horopoint(h0 + hd * j));
chasmifyPoly(dlow_table[k], dhi_table[k], k); chasmifyPoly(dlow_table[p], dhi_table[p], p);
} }
} }
@ -346,21 +346,21 @@ void geometry_information::bshape_regular(floorshape &fsh, int id, int sides, ld
for(int t=0; t<=sides; t++) for(int t=0; t<=sides; t++)
hpcpush(xspinpush0(t * TAU / sides + shift * S_step, size * SHADMUL)); hpcpush(xspinpush0(t * TAU / sides + shift * S_step, size * SHADMUL));
for(int k=0; k<SIDEPARS; k++) { for(auto p: allsides) {
fsh.side[k].resize(2); fsh.side[p].resize(2);
bshape(fsh.side[k][id], PPR::LAKEWALL); bshape(fsh.side[p][id], PPR::FLOOR_SIDE);
hpcpush(xspinpush0(+M_PI/sides, size)); 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); chasmifyPoly(dlow_table[p], dhi_table[p], p);
if(cgi.emb->is_euc_in_noniso()) { if(cgi.emb->is_euc_in_noniso()) {
fsh.gpside[k].resize(c->type); fsh.gpside[p].resize(c->type);
for(int i=0; i<c->type; i++) { for(int i=0; i<c->type; i++) {
sizeto(fsh.gpside[k][i], id); sizeto(fsh.gpside[p][i], id);
bshape(fsh.gpside[k][i][id], PPR::LAKEWALL); bshape(fsh.gpside[p][i][id], PPR::FLOOR_SIDE);
hpcpush(xspinpush0(M_PI - i * TAU / sides + shift * S_step, size)); hpcpush(xspinpush0(M_PI - i * TAU / sides + shift * S_step, size));
hpcpush(xspinpush0(M_PI - (i + 1) * TAU / sides + shift * S_step, size)); hpcpush(xspinpush0(M_PI - (i + 1) * TAU / sides + shift * S_step, size));
chasmifyPoly(dlow_table[k], dhi_table[k], k); chasmifyPoly(dlow_table[p], dhi_table[p], p);
} }
} }
} }
@ -416,7 +416,7 @@ void geometry_information::generate_floorshapes_for(int id, cell *c, int siid, i
ld hexside = fsh.rad0, heptside = fsh.rad1; ld hexside = fsh.rad0, heptside = fsh.rad1;
for(int k=0; k<SIDEPARS; k++) sizeto(fsh.side[k], id); for(auto p: allsides) sizeto(fsh.side[p], id);
ld td = (PURE && !(S7&1)) ? S42+S6 : 0; ld td = (PURE && !(S7&1)) ? S42+S6 : 0;
if(&fsh == &shBigHepta) td += S6; if(&fsh == &shBigHepta) td += S6;
@ -594,15 +594,15 @@ void geometry_information::generate_floorshapes_for(int id, cell *c, int siid, i
for(int i=0; i<=cor; i++) for(int i=0; i<=cor; i++)
hpcpush(mid_at(hpxy(0,0), cornerlist[i%cor], SHADMUL)); hpcpush(mid_at(hpxy(0,0), cornerlist[i%cor], SHADMUL));
for(int k=0; k<SIDEPARS; k++) { for(auto p: allsides) {
if(isize(fsh.gpside[k]) < cor) if(isize(fsh.gpside[p]) < cor)
fsh.gpside[k].resize(cor); fsh.gpside[p].resize(cor);
for(int cid=0; cid<cor; cid++) { for(int cid=0; cid<cor; cid++) {
sizeto(fsh.gpside[k][cid], id); sizeto(fsh.gpside[p][cid], id);
bshape(fsh.gpside[k][cid][id], fsh.prio); bshape(fsh.gpside[p][cid][id], fsh.prio);
hpcpush(iddspin_side(c, cid) * cornerlist[cid]); hpcpush(iddspin_side(c, cid) * cornerlist[cid]);
hpcpush(iddspin_side(c, cid) * cornerlist[(cid+1)%cor]); hpcpush(iddspin_side(c, cid) * cornerlist[(cid+1)%cor]);
chasmifyPoly(dlow_table[k], dhi_table[k], k); chasmifyPoly(dlow_table[p], dhi_table[p], p);
} }
} }
} }
@ -702,9 +702,9 @@ void geometry_information::generate_floorshapes_for(int id, cell *c, int siid, i
for(int i=fsh.shadow[id].s; i<fsh.shadow[id].e; i++) for(int i=fsh.shadow[id].s; i<fsh.shadow[id].e; i++)
hpc[i] = orthogonal_move(hpc[i], FLOOR - human_height / 100); hpc[i] = orthogonal_move(hpc[i], FLOOR - human_height / 100);
for(int k=0; k<SIDEPARS; k++) { for(auto p: allsides) {
sizeto(fsh.levels[k], id); sizeto(fsh.levels[p], id);
bshape(fsh.levels[k][id], fsh.prio); bshape(fsh.levels[p][id], fsh.prio);
last->flags |= POLY_TRIANGLES; last->flags |= POLY_TRIANGLES;
last->tinf = get_floor_texture_vertices(fsh.id); last->tinf = get_floor_texture_vertices(fsh.id);
last->texture_offset = 0; last->texture_offset = 0;
@ -716,12 +716,12 @@ void geometry_information::generate_floorshapes_for(int id, cell *c, int siid, i
if(vid.pseudohedral == phInscribed) { if(vid.pseudohedral == phInscribed) {
hyperpoint ctr = Hypc; hyperpoint ctr = Hypc;
for(int t=0; t<e-s; t++) for(int t=0; t<e-s; t++)
ctr += kleinize(cgi.emb->orthogonal_move(hpc[s+t], dfloor_table[k])); ctr += kleinize(cgi.emb->orthogonal_move(hpc[s+t], dhi_table[p]));
ctr = normalize(ctr); ctr = normalize(ctr);
for(int t=0; t<e-s; t++) { for(int t=0; t<e-s; t++) {
hyperpoint v1 = kleinize(cgi.emb->orthogonal_move(hpc[s+t], dfloor_table[k])) - ctr; hyperpoint v1 = kleinize(cgi.emb->orthogonal_move(hpc[s+t], dhi_table[p])) - ctr;
hyperpoint v2 = kleinize(cgi.emb->orthogonal_move(hpc[s+t+1], dfloor_table[k])) - ctr; hyperpoint v2 = kleinize(cgi.emb->orthogonal_move(hpc[s+t+1], dhi_table[p])) - ctr;
texture_order([&] (ld x, ld y) { texture_order([&] (ld x, ld y) {
hpcpush(normalize(ctr + v1 * x + v2 * y)); hpcpush(normalize(ctr + v1 * x + v2 * y));
}); });
@ -730,7 +730,7 @@ void geometry_information::generate_floorshapes_for(int id, cell *c, int siid, i
if(vid.pseudohedral == phCircumscribed) { if(vid.pseudohedral == phCircumscribed) {
vector<hyperpoint> hs(c->type); vector<hyperpoint> hs(c->type);
hyperpoint z = Hypc; z[2] = dfloor_table[k]; hyperpoint z = Hypc; z[2] = dhi_table[p];
hyperpoint ctr = cgi.emb->logical_to_actual(z); hyperpoint ctr = cgi.emb->logical_to_actual(z);
for(int t=0; t<c->type; t++) hs[t] = get_circumscribed_corner(c, t, ctr); for(int t=0; t<c->type; t++) hs[t] = get_circumscribed_corner(c, t, ctr);
// for(int t=0; t<c->type; t++) hs[t] = xspinpush0(t * TAU / c->type, 0.2); // kleinize(get_circumscribed_corner(c, t, ctr)); // for(int t=0; t<c->type; t++) hs[t] = xspinpush0(t * TAU / c->type, 0.2); // kleinize(get_circumscribed_corner(c, t, ctr));
@ -754,7 +754,7 @@ void geometry_information::generate_floorshapes_for(int id, cell *c, int siid, i
texture_order([&] (ld x, ld y) { texture_order([&] (ld x, ld y) {
hyperpoint a = v1 * x + v2 * y; hyperpoint a = v1 * x + v2 * y;
a[2] = dfloor_table[k]; a[2] = dhi_table[p];
auto c = cgi.emb->logical_to_actual(a); auto c = cgi.emb->logical_to_actual(a);
cgi.hpcpush(c); cgi.hpcpush(c);
}); });
@ -762,7 +762,7 @@ void geometry_information::generate_floorshapes_for(int id, cell *c, int siid, i
} }
finishshape(); finishshape();
ensure_vertex_number(fsh.levels[k][id]); ensure_vertex_number(fsh.levels[p][id]);
} }
for(int co=0; co<2; co++) { for(int co=0; co<2; co++) {
@ -790,12 +790,12 @@ void geometry_information::generate_floorshapes_for(int id, cell *c, int siid, i
ensure_vertex_number(fsh.cone[co][id]); ensure_vertex_number(fsh.cone[co][id]);
} }
for(int l=0; l<SIDEPARS; l++) { for(auto p: allsides) {
for(auto& li: fsh.side[l]) for(auto& li: fsh.side[p])
bind_floor_texture(li, fsh.id); bind_floor_texture(li, fsh.id);
if(isize(fsh.gpside[l]) < c->type) if(isize(fsh.gpside[p]) < c->type)
fsh.gpside[l].resize(c->type); fsh.gpside[p].resize(c->type);
for(auto& gs: fsh.gpside[l]) { for(auto& gs: fsh.gpside[p]) {
for(auto& li: gs) for(auto& li: gs)
bind_floor_texture(li, fsh.id); bind_floor_texture(li, fsh.id);
} }
@ -805,17 +805,17 @@ void geometry_information::generate_floorshapes_for(int id, cell *c, int siid, i
for(auto pfsh: all_escher_floorshapes) { for(auto pfsh: all_escher_floorshapes) {
auto& fsh = *pfsh; auto& fsh = *pfsh;
for(int l=0; l<SIDEPARS; l++) { for(auto p: allsides) {
fsh.levels[l] = shFullFloor.levels[l]; fsh.levels[p] = shFullFloor.levels[p];
fsh.shadow = shFullFloor.shadow; fsh.shadow = shFullFloor.shadow;
for(auto& li: fsh.levels[l]) bind_floor_texture(li, fsh.id); for(auto& li: fsh.levels[p]) bind_floor_texture(li, fsh.id);
fsh.side[l] = shFullFloor.side[l]; fsh.side[p] = shFullFloor.side[p];
for(auto& li: fsh.side[l]) bind_floor_texture(li, fsh.id); for(auto& li: fsh.side[p]) bind_floor_texture(li, fsh.id);
if(isize(fsh.gpside[l]) < c->type) if(isize(fsh.gpside[p]) < c->type)
fsh.gpside[l].resize(c->type); fsh.gpside[p].resize(c->type);
for(int e=0; e<c->type; e++) { for(int e=0; e<c->type; e++) {
fsh.gpside[l][e] = shFullFloor.gpside[l][e]; fsh.gpside[p][e] = shFullFloor.gpside[p][e];
for(auto& li: fsh.gpside[l][e]) for(auto& li: fsh.gpside[p][e])
bind_floor_texture(li, fsh.id); bind_floor_texture(li, fsh.id);
} }
fsh.cone[0] = shFullFloor.cone[0]; fsh.cone[0] = shFullFloor.cone[0];
@ -1390,7 +1390,7 @@ void draw_shape_for_texture(floorshape* sh) {
curvepoint(eupush(gx-s1, gy-s1) * C0); curvepoint(eupush(gx-s1, gy-s1) * C0);
curvepoint(eupush(gx+s1, gy-s1) * C0); curvepoint(eupush(gx+s1, gy-s1) * C0);
queuecurve(shiftless(Id), 0x000000FF, brightalpha(255 - sh->pstrength * tp.escher_strength, 255), PPR::LAKELEV); queuecurve(shiftless(Id), 0x000000FF, brightalpha(255 - sh->pstrength * tp.escher_strength, 255), PPR::WATERLEVEL_TOP);
} }
vid.linewidth = tp.escher_width; vid.linewidth = tp.escher_width;

View File

@ -38,18 +38,32 @@ struct hpcshape {
hpcshape() { clear(); } hpcshape() { clear(); }
}; };
#define SIDE_SLEV 0 enum class SIDE {
#define SIDE_WTS3 3 INFDEEP, DEEP, SHALLOW, WATERLEVEL, FLOOR, RED1, RED2, RED3, RED4, WALL, HIGH, HIGH2, SKY, GUARD
#define SIDE_WALL 4 };
#define SIDE_LAKE 5
#define SIDE_LTOB 6 constexpr SIDE allsides[] = {
#define SIDE_BTOI 7 SIDE::INFDEEP, SIDE::DEEP, SIDE::SHALLOW, SIDE::WATERLEVEL, SIDE::FLOOR, SIDE::RED1, SIDE::RED2, SIDE::RED3, SIDE::RED4, SIDE::WALL, SIDE::HIGH, SIDE::HIGH2, SIDE::SKY
#define SIDE_SKY 8 };
#define SIDE_HIGH 9
#define SIDE_HIGH2 10 constexpr int SIDEPARS = int(SIDE::GUARD);
#define SIDE_ASHA 11
#define SIDE_BSHA 12 template<class T> struct sidearray : array<T, SIDEPARS> {
#define SIDEPARS 13 T& operator [] (SIDE s) { return array<T, SIDEPARS>::operator[] ((int) s); };
const T& operator [] (SIDE s) const { return array<T, SIDEPARS>::operator[] ((int) s); };
};
constexpr sidearray<PPR> side_to_prio = {
PPR::DEEP_SIDE, PPR::DEEP_SIDE, PPR::SHALLOW_SIDE, PPR::WATERLEVEL_SIDE, PPR::FLOOR_SIDE, PPR::RED1_SIDE, PPR::RED2_SIDE, PPR::RED3_SIDE,
PPR::WALL_SIDE, PPR::WALL_SIDE,
PPR::DEFAULT, PPR::DEFAULT, PPR::DEFAULT
};
constexpr sidearray<PPR> side_to_prio_top = {
PPR::DEEP_TOP, PPR::DEEP_TOP, PPR::SHALLOW_TOP, PPR::WATERLEVEL_TOP, PPR::FLOOR, PPR::RED1_TOP, PPR::RED2_TOP, PPR::RED3_TOP,
PPR::WALL_TOP, PPR::WALL_TOP,
PPR::DEFAULT, PPR::DEFAULT, PPR::DEFAULT
};
/** GOLDBERG_BITS controls the size of tables for Goldberg. see gp::check_limits */ /** GOLDBERG_BITS controls the size of tables for Goldberg. see gp::check_limits */
@ -79,8 +93,9 @@ struct floorshape {
int pstrength; // pattern strength in 3D int pstrength; // pattern strength in 3D
int fstrength; // frame strength in 3D int fstrength; // frame strength in 3D
PPR prio; PPR prio;
vector<hpcshape> b, shadow, side[SIDEPARS], levels[SIDEPARS], cone[2]; vector<hpcshape> b, shadow, cone[2];
vector<vector<hpcshape>> gpside[SIDEPARS]; sidearray<vector<hpcshape>> side, levels;
sidearray<vector<vector<hpcshape>>> gpside;
floorshape() { prio = PPR::FLOOR; pstrength = fstrength = 10; } floorshape() { prio = PPR::FLOOR; pstrength = fstrength = 10; }
}; };
@ -231,20 +246,22 @@ struct geometry_information {
int use_direct; int use_direct;
/** various parameters related to the 3D view */ /** various parameters related to the 3D view */
ld INFDEEP, BOTTOM, HELLSPIKE, LAKE, WALL, FLOOR, STUFF, ld INFDEEP, HELL, DEEP, HELLSPIKE, SHALLOW, WATERLEVEL, FLOOR, RED[4], WALL, HIGH, HIGH2, LOWSKY, SKY, STAR,
SLEV[4], FLATEYE, STUFF, FLATEYE,
LEG0, LEG1, LEG, LEG3, GROIN, GROIN1, GHOST, LEG0, LEG1, LEG, LEG3, GROIN, GROIN1, GHOST,
BODY, BODY1, BODY2, BODY3, BODY, BODY1, BODY2, BODY3,
NECK1, NECK, NECK3, HEAD, HEAD1, HEAD2, HEAD3, NECK1, NECK, NECK3, HEAD, HEAD1, HEAD2, HEAD3,
ALEG0, ALEG, ABODY, AHEAD, BIRD, LOWSKY, SKY, HIGH, HIGH2, ALEG0, ALEG, ABODY, AHEAD, BIRD;
HELL, STAR, SHALLOW;
ld human_height, slev; ld human_height, slev;
ld eyelevel_familiar, eyelevel_human, eyelevel_dog; ld eyelevel_familiar, eyelevel_human, eyelevel_dog;
#if CAP_SHAPES #if CAP_SHAPES
sidearray<hpcshape> shSemiFloorSide;
hpcshape hpcshape
shSemiFloorSide[SIDEPARS],
shBFloor[2], shBFloor[2],
shWave[8][2], shWave[8][2],
shCircleFloor, shCircleFloor,
@ -397,7 +414,7 @@ hpcshape
shDesertFloor, shPowerFloor, shRoseFloor, shSwitchFloor, shDesertFloor, shPowerFloor, shRoseFloor, shSwitchFloor,
shTurtleFloor, shRedRockFloor[3], shDragonFloor; shTurtleFloor, shRedRockFloor[3], shDragonFloor;
ld dlow_table[SIDEPARS], dhi_table[SIDEPARS], dfloor_table[SIDEPARS]; sidearray<ld> dlow_table, dhi_table;
int prehpc; int prehpc;
/** list of points in all shapes */ /** list of points in all shapes */
@ -415,7 +432,7 @@ hpcshape
/** last ideal point of the current shape */ /** last ideal point of the current shape */
hyperpoint last_ideal; hyperpoint last_ideal;
bool validsidepar[SIDEPARS]; sidearray<bool> validsidepar;
vector<glvertex> ourshape; vector<glvertex> ourshape;
#endif #endif
@ -456,7 +473,7 @@ hpcshape
void hpcpush(hyperpoint h); void hpcpush(hyperpoint h);
void hpc_connect_ideal(hyperpoint a, hyperpoint b); void hpc_connect_ideal(hyperpoint a, hyperpoint b);
void hpcsquare(hyperpoint h1, hyperpoint h2, hyperpoint h3, hyperpoint h4); void hpcsquare(hyperpoint h1, hyperpoint h2, hyperpoint h3, hyperpoint h4);
void chasmifyPoly(double fac, double fac2, int k); void chasmifyPoly(double fac, double fac2, SIDE p);
void shift(hpcshape& sh, double dx, double dy, double dz); void shift(hpcshape& sh, double dx, double dy, double dz);
void initPolyForGL(); void initPolyForGL();
void extra_vertices(); void extra_vertices();
@ -1027,15 +1044,17 @@ EX namespace geom3 {
if(invalid != "") { if(invalid != "") {
INFDEEP = .7; INFDEEP = .7;
BOTTOM = .8; DEEP = .8;
HELLSPIKE = .85; HELLSPIKE = .85;
LAKE = .9; SHALLOW = .9;
WATERLEVEL = .95;
FLOOR = 1; FLOOR = 1;
RED[0] = 1;
RED[1] = 1.08;
RED[2] = 1.16;
RED[3] = 1.24;
WALL = 1.25; WALL = 1.25;
SLEV[0] = 1;
SLEV[1] = 1.08;
SLEV[2] = 1.16;
SLEV[3] = 1.24;
FLATEYE = 1.03; FLATEYE = 1.03;
LEG1 = 1.025; LEG1 = 1.025;
LEG = 1.05; LEG = 1.05;
@ -1057,7 +1076,6 @@ EX namespace geom3 {
ABODY = 1.08; ABODY = 1.08;
AHEAD = 1.12; AHEAD = 1.12;
BIRD = 1.20; BIRD = 1.20;
SHALLOW = .95;
STUFF = 1; STUFF = 1;
LOWSKY = SKY = HIGH = HIGH2 = STAR = 1; LOWSKY = SKY = HIGH = HIGH2 = STAR = 1;
} }
@ -1107,11 +1125,11 @@ EX namespace geom3 {
slev = vid.rock_wall_ratio * wh / 3; slev = vid.rock_wall_ratio * wh / 3;
for(int s=0; s<=3; s++) for(int s=0; s<=3; s++)
SLEV[s] = lev_to_factor(vid.rock_wall_ratio * wh * s/3); RED[s] = lev_to_factor(vid.rock_wall_ratio * wh * s/3);
LAKE = lev_to_factor(wh * -vid.lake_top); WATERLEVEL = lev_to_factor(wh * -vid.lake_top);
SHALLOW = lev_to_factor(wh * -vid.lake_shallow); SHALLOW = lev_to_factor(wh * -vid.lake_shallow);
HELLSPIKE = lev_to_factor(wh * -(vid.lake_top+vid.lake_bottom)/2); HELLSPIKE = lev_to_factor(wh * -(vid.lake_top+vid.lake_bottom)/2);
BOTTOM = lev_to_factor(wh * -vid.lake_bottom); DEEP = lev_to_factor(wh * -vid.lake_bottom);
LOWSKY = lev_to_factor(vid.lowsky_height * wh); LOWSKY = lev_to_factor(vid.lowsky_height * wh);
HIGH = lev_to_factor(vid.wall_height2 * wh); HIGH = lev_to_factor(vid.wall_height2 * wh);
HIGH2 = lev_to_factor(vid.wall_height3 * wh); HIGH2 = lev_to_factor(vid.wall_height3 * wh);
@ -1138,9 +1156,9 @@ EX namespace geom3 {
adjust(HIGH2, HIGH, 0.5); adjust(HIGH2, HIGH, 0.5);
adjust(SKY, FLOOR, 1); adjust(SKY, FLOOR, 1);
adjust(STAR, FLOOR, 0.9); adjust(STAR, FLOOR, 0.9);
adjust(LAKE, FLOOR, 0.8); adjust(WATERLEVEL, FLOOR, 0.8);
adjust(SHALLOW, LAKE, 0.9); adjust(SHALLOW, WATERLEVEL, 0.9);
adjust(BOTTOM, SHALLOW, 0.5); adjust(DEEP, SHALLOW, 0.5);
adjust(INFDEEP, FLOOR, 1); adjust(INFDEEP, FLOOR, 1);
} }
} }

120
graph.cpp
View File

@ -1046,13 +1046,13 @@ EX bool drawItemType(eItem it, cell *c, const shiftmatrix& V, color_t icol, int
shiftmatrix V2 = V * spin(pticks * vid.ispeed / 1500.); shiftmatrix V2 = V * spin(pticks * vid.ispeed / 1500.);
/* divisors should be higher than in plate renderer */ /* divisors should be higher than in plate renderer */
qfi.fshape = &cgi.shMFloor2; qfi.fshape = &cgi.shMFloor2;
draw_shapevec(c, V2 * lzpush(-h/30), qfi.fshape->levels[0], 0xFFD500FF, PPR::WALL); draw_shapevec(c, V2 * lzpush(-h/30), qfi.fshape->levels[SIDE::FLOOR], 0xFFD500FF, PPR::WALL);
qfi.fshape = &cgi.shMFloor3; qfi.fshape = &cgi.shMFloor3;
draw_shapevec(c, V2 * lzpush(-h/25), qfi.fshape->levels[0], darkena(icol, 0, 0xFF), PPR::WALL); draw_shapevec(c, V2 * lzpush(-h/25), qfi.fshape->levels[SIDE::FLOOR], darkena(icol, 0, 0xFF), PPR::WALL);
qfi.fshape = &cgi.shMFloor4; qfi.fshape = &cgi.shMFloor4;
draw_shapevec(c, V2 * lzpush(-h/20), qfi.fshape->levels[0], 0xFFD500FF, PPR::WALL); draw_shapevec(c, V2 * lzpush(-h/20), qfi.fshape->levels[SIDE::FLOOR], 0xFFD500FF, PPR::WALL);
} }
else if(WDIM == 3 && c) { else if(WDIM == 3 && c) {
ld h = cgi.human_height; ld h = cgi.human_height;
@ -3881,38 +3881,47 @@ EX bool use_warp_graphics() {
return true; return true;
} }
EX void escherSidewall(cell *c, int sidepar, const shiftmatrix& V, color_t col) { EX void escherSidewall(cell *c, SIDE sidepar, const shiftmatrix& V, color_t col) {
if(sidepar >= SIDE_SLEV && sidepar <= SIDE_SLEV+2) { if(sidepar >= SIDE::RED1 && sidepar <= SIDE::RED3) {
int sl = sidepar - SIDE_SLEV; int sl = int(sidepar) - int(SIDE::RED1);
for(int z=1; z<=4; z++) if(z == 1 || (z == 4 && detaillevel == 2)) for(int z=1; z<=4; z++) if(z == 1 || (z == 4 && detaillevel == 2))
draw_qfi(c, orthogonal_move_fol(V, zgrad0(cgi.slev * sl, cgi.slev * (sl+1), z, 4)), col, PPR::REDWALL-4+z+4*sl); draw_qfi(c, orthogonal_move_fol(V, zgrad0(cgi.slev * sl, cgi.slev * (sl+1), z, 4)), col, PPR::RED1_ESCHER+3*sl);
} }
else if(sidepar == SIDE_WALL) { else if(sidepar == SIDE::WALL) {
const int layers = 2 << detaillevel; const int layers = 2 << detaillevel;
for(int z=1; z<layers; z++) for(int z=1; z<layers; z++)
draw_qfi(c, orthogonal_move_fol(V, zgrad0(0, geom3::actual_wall_height(), z, layers)), col, PPR::WALL3+z-layers); draw_qfi(c, orthogonal_move_fol(V, zgrad0(0, geom3::actual_wall_height(), z, layers)), col, PPR::WALL_ESCHER);
} }
else if(sidepar == SIDE_LAKE) { else if(sidepar == SIDE::FLOOR) {
const int layers = 1 << (detaillevel-1); const int layers = 1 << (detaillevel-1);
if(detaillevel) for(int z=0; z<layers; z++) if(detaillevel) for(int z=0; z<layers; z++)
draw_qfi(c, orthogonal_move_fol(V, zgrad0(-vid.lake_top, 0, z, layers)), col, PPR::FLOOR+z-layers); draw_qfi(c, orthogonal_move_fol(V, zgrad0(-vid.lake_top, 0, z, layers)), col, PPR::FLOOR_ESCHER);
} }
else if(sidepar == SIDE_LTOB) { else if(sidepar == SIDE::WATERLEVEL) {
const int layers = 1 << (detaillevel-1); const int layers = 1 << (detaillevel-1);
if(detaillevel) for(int z=0; z<layers; z++) if(detaillevel) for(int z=0; z<layers; z++)
draw_qfi(c, orthogonal_move_fol(V, zgrad0(-vid.lake_bottom, -vid.lake_top, z, layers)), col, PPR::INLAKEWALL+z-layers); draw_qfi(c, orthogonal_move_fol(V, zgrad0(-vid.lake_shallow, -vid.lake_top, z, layers)), col, PPR::WATERLEVEL_ESCHER);
} }
else if(sidepar == SIDE_BTOI) { else if(sidepar == SIDE::SHALLOW) {
const int layers = 1 << (detaillevel-1);
if(detaillevel) for(int z=0; z<layers; z++)
draw_qfi(c, orthogonal_move_fol(V, zgrad0(-vid.lake_bottom, -vid.lake_shallow, z, layers)), col, PPR::SHALLOW_ESCHER);
}
else if(sidepar == SIDE::DEEP) {
const int layers = 1 << detaillevel; const int layers = 1 << detaillevel;
draw_qfi(c, orthogonal_move_fol(V, cgi.INFDEEP), col, PPR::MINUSINF); draw_qfi(c, orthogonal_move_fol(V, cgi.INFDEEP), col, PPR::MINUSINF);
for(int z=1; z<layers; z++) for(int z=layers-1; z>1; z--)
draw_qfi(c, orthogonal_move_fol(V, zgrad0(-vid.lake_bottom, -vid.lake_top, -z, 1)), col, PPR::LAKEBOTTOM+z-layers); draw_qfi(c, orthogonal_move_fol(V, zgrad0(-vid.lake_bottom, -vid.lake_top, -z, 1)), col, PPR::DEEP_ESCHER);
} }
} }
EX bool placeSidewall(cell *c, int i, int sidepar, const shiftmatrix& V, color_t col) { EX bool use_escher(SIDE sidepar) {
return (!qfi.fshape || !qfi.fshape->is_plain || !cgi.validsidepar[sidepar] || qfi.usershape >= 0) && (GDIM == 2);
}
if(!qfi.fshape || !qfi.fshape->is_plain || !cgi.validsidepar[sidepar] || qfi.usershape >= 0) if(GDIM == 2) { EX bool placeSidewall(cell *c, int i, SIDE sidepar, const shiftmatrix& V, color_t col) {
if(use_escher(sidepar)) {
escherSidewall(c, sidepar, V, col); escherSidewall(c, sidepar, V, col);
return true; return true;
} }
@ -3921,16 +3930,7 @@ EX bool placeSidewall(cell *c, int i, int sidepar, const shiftmatrix& V, color_t
if(qfi.fshape == &cgi.shBigTriangle && pseudohept(c->move(i))) return false; if(qfi.fshape == &cgi.shBigTriangle && pseudohept(c->move(i))) return false;
if(qfi.fshape == &cgi.shTriheptaFloor && !pseudohept(c) && !pseudohept(c->move(i))) return false; if(qfi.fshape == &cgi.shTriheptaFloor && !pseudohept(c) && !pseudohept(c->move(i))) return false;
PPR prio; PPR prio = side_to_prio[sidepar];
/* if(mirr) prio = PPR::GLASS - 2;
else */ if(sidepar == SIDE_WALL) prio = PPR::WALL3 - 2;
else if(sidepar == SIDE_WTS3) prio = PPR::WALL3 - 2;
else if(sidepar == SIDE_LAKE) prio = PPR::LAKEWALL;
else if(sidepar == SIDE_LTOB) prio = PPR::INLAKEWALL;
else if(sidepar == SIDE_BTOI) prio = PPR::BELOWBOTTOM;
else if(sidepar == SIDE_ASHA) prio = PPR::ASHALLOW;
else if(sidepar == SIDE_BSHA) prio = PPR::BSHALLOW;
else prio = PPR::REDWALL-2+4*(sidepar-SIDE_SLEV);
if((col & 255) < 255) prio = PPR::TRANSPARENT_WALL; if((col & 255) < 255) prio = PPR::TRANSPARENT_WALL;
@ -3950,12 +3950,12 @@ EX bool placeSidewall(cell *c, int i, int sidepar, const shiftmatrix& V, color_t
if(currentmap->strict_tree_rules()) { if(currentmap->strict_tree_rules()) {
i = rulegen::get_arb_dir(c, i); i = rulegen::get_arb_dir(c, i);
} }
if(sidepar >= SIDEPARS) { if(int(sidepar) >= SIDEPARS) {
println(hlog, "ERROR: sidepar >= SIDEPARS", make_pair(sidepar, SIDEPARS)); println(hlog, "ERROR: sidepar >= SIDEPARS: ", make_pair(int(sidepar), SIDEPARS));
return false; return false;
} }
if(i >= isize(qfi.fshape->gpside[sidepar])) { if(i >= isize(qfi.fshape->gpside[sidepar])) {
println(hlog, "ERROR: i >= gpside[sidepar]", make_tuple(sidepar, i, isize(qfi.fshape->gpside[sidepar]))); println(hlog, "ERROR: i >= gpside[sidepar]", make_tuple(int(sidepar), i, isize(qfi.fshape->gpside[sidepar])));
return false; return false;
} }
draw_shapevec(c, V2, qfi.fshape->gpside[sidepar][i], col, prio); draw_shapevec(c, V2, qfi.fshape->gpside[sidepar][i], col, prio);
@ -3990,7 +3990,7 @@ EX int gridcolor(cell *c1, cell *c2) {
if(r == 3) return Dark(0xC02020); if(r == 3) return Dark(0xC02020);
if(r == 2) return Dark(0xF02020); if(r == 2) return Dark(0xF02020);
} }
if(chasmgraph(c1) != chasmgraph(c2) && c1->land != laAsteroids && c2->land != laAsteroids) if((get_spatial_info(c1).deep<SIDE::SHALLOW) != (get_spatial_info(c2).deep<SIDE::SHALLOW) && c1->land != laAsteroids && c2->land != laAsteroids)
return Dark(0x808080); return Dark(0x808080);
if(c1->land == laAlchemist && c2->land == laAlchemist && c1->wall != c2->wall && !c1->item && !c2->item) if(c1->land == laAlchemist && c2->land == laAlchemist && c1->wall != c2->wall && !c1->item && !c2->item)
return Dark(0xC020C0); return Dark(0xC020C0);
@ -4050,35 +4050,18 @@ EX void pushdown(cell *c, int& q, const shiftmatrix &V, double down, bool rezoom
if(!repriority) ; if(!repriority) ;
else if(nlev < -vid.lake_bottom-1e-3) { else if(nlev < -vid.lake_bottom-1e-3) {
ptd.prio = PPR::BELOWBOTTOM_FALLANIM; ptd.prio = PPR::DEEP_FALLANIM;
if(c->wall != waChasm) if(c->wall != waChasm)
ptd.color = 0; // disappear! ptd.color = 0; // disappear!
} }
else if(nlev < -vid.lake_top-1e-3) else if(nlev < -vid.lake_top-1e-3)
ptd.prio = PPR::INLAKEWALL_FALLANIM; ptd.prio = PPR::SHALLOW_FALLANIM;
else if(nlev < 0) else if(nlev < 0)
ptd.prio = PPR::LAKEWALL_FALLANIM; ptd.prio = PPR::FLOOR_FALLANIM;
} }
} }
#endif #endif
// 1 : (floor, water); 2 : (water, bottom); 4 : (bottom, inf)
EX int shallow(cell *c) {
if(cellUnstable(c)) return 0;
else if(
c->wall == waReptile) return 1;
else if(c->wall == waReptileBridge ||
c->wall == waGargoyleFloor ||
c->wall == waGargoyleBridge ||
c->wall == waTempFloor ||
c->wall == waTempBridge ||
c->wall == waPetrifiedBridge ||
c->wall == waFrozenLake)
return 5;
return 7;
}
bool allemptynear(cell *c) { bool allemptynear(cell *c) {
if(c->wall) return false; if(c->wall) return false;
forCellEx(c2, c) if(c2->wall) return false; forCellEx(c2, c) if(c2->wall) return false;
@ -4202,10 +4185,10 @@ EX color_t transcolor(cell *c, cell *c2, color_t wcol) {
if(among(c->wall, waCanopy, waSolidBranch, waWeakBranch) && !among(c2->wall, waCanopy, waSolidBranch, waWeakBranch)) return 0x00C00060; if(among(c->wall, waCanopy, waSolidBranch, waWeakBranch) && !among(c2->wall, waCanopy, waSolidBranch, waWeakBranch)) return 0x00C00060;
if(c->wall == waFloorA && c2->wall == waFloorB && !c->item && !c2->item) return darkena3(0xFF00FF, 0, 0x80); if(c->wall == waFloorA && c2->wall == waFloorB && !c->item && !c2->item) return darkena3(0xFF00FF, 0, 0x80);
if(realred(c->wall) || realred(c2->wall)) { if(realred(c->wall) || realred(c2->wall)) {
int l = snakelevel(c) - snakelevel(c2); int l = int(get_spatial_info(c).top) - int(get_spatial_info(c2).top);
if(l > 0) return darkena3(floorcolors[laRedRock], 0, 0x30 * l); if(l > 0) return darkena3(floorcolors[laRedRock], 0, 0x30 * l);
} }
if(among(c->wall, waRubble, waDeadfloor2) && !snakelevel(c2)) return darkena3(winf[c->wall].color, 0, 0x40); if(among(c->wall, waRubble, waDeadfloor2) && !among(get_spatial_info(c2).top, SIDE::RED1, SIDE::RED2, SIDE::RED3)) return darkena3(winf[c->wall].color, 0, 0x40);
if(c->wall == waMagma && c2->wall != waMagma) return darkena3(magma_color(lavatide(c, -1)/4), 0, 0x80); if(c->wall == waMagma && c2->wall != waMagma) return darkena3(magma_color(lavatide(c, -1)/4), 0, 0x80);
if(among(c->wall, waMineUnknown, waMineMine) && !among(c2->wall, waMineMine, waMineUnknown) && mine_opacity > 0 && mine_opacity < 255) if(among(c->wall, waMineUnknown, waMineMine) && !among(c2->wall, waMineMine, waMineUnknown) && mine_opacity > 0 && mine_opacity < 255)
return 0xFFFFFF00 | mine_opacity; return 0xFFFFFF00 | mine_opacity;
@ -4781,7 +4764,7 @@ void celldrawer::draw_fallanims() {
if(t <= maxtime) { if(t <= maxtime) {
erase = false; erase = false;
if(GDIM == 3) if(GDIM == 3)
draw_shapevec(c, V, qfi.fshape->levels[0], darkena(fcol, fd, 0xFF), PPR::WALL); draw_shapevec(c, V, qfi.fshape->levels[SIDE::FLOOR], darkena(fcol, fd, 0xFF), PPR::WALL);
else if(fa.walltype == waNone) { else if(fa.walltype == waNone) {
draw_qfi(c, V, darkena(fcol, fd, 0xFF), PPR::FLOOR); draw_qfi(c, V, darkena(fcol, fd, 0xFF), PPR::FLOOR);
} }
@ -4793,10 +4776,10 @@ void celldrawer::draw_fallanims() {
ddalt.setcolors(); ddalt.setcolors();
int starcol = c->wall == waVinePlant ? 0x60C000 : ddalt.wcol; int starcol = c->wall == waVinePlant ? 0x60C000 : ddalt.wcol;
c->wall = w; c->wparam = p; c->wall = w; c->wparam = p;
draw_qfi(c, orthogonal_move_fol(V, cgi.WALL), darkena(starcol, fd, 0xFF), PPR::WALL3); draw_qfi(c, orthogonal_move_fol(V, cgi.WALL), darkena(starcol, fd, 0xFF), PPR::WALL_TOP);
queuepolyat(orthogonal_move_fol(V, cgi.WALL), cgi.shWall[ct6], darkena(ddalt.wcol, 0, 0xFF), PPR::WALL3A); queuepolyat(orthogonal_move_fol(V, cgi.WALL), cgi.shWall[ct6], darkena(ddalt.wcol, 0, 0xFF), PPR::WALL_DECO);
forCellIdEx(c2, i, c) forCellIdEx(c2, i, c)
if(placeSidewall(c, i, SIDE_WALL, V, darkena(ddalt.wcol, 1, 0xFF))) break; if(placeSidewall(c, i, SIDE::WALL, V, darkena(ddalt.wcol, 1, 0xFF))) break;
} }
pushdown(c, q, V, t*t / 1000000. + t / 1000., true, true); pushdown(c, q, V, t*t / 1000000. + t / 1000., true, true);
} }
@ -4848,14 +4831,17 @@ EX void queuecircleat1(cell *c, const shiftmatrix& V, double rad, color_t col) {
#endif #endif
queuecircle(V, rad, col); queuecircle(V, rad, col);
if(!wmspatial) return; if(!wmspatial) return;
if(highwall(c)) auto si = get_spatial_info(c);
if(si.top == SIDE::WALL)
queuecircle(orthogonal_move_fol(V, cgi.WALL), rad, col); queuecircle(orthogonal_move_fol(V, cgi.WALL), rad, col);
int sl; if(si.top == SIDE::RED1)
if((sl = snakelevel(c))) { queuecircle(orthogonal_move_fol(V, cgi.RED[1]), rad, col);
queuecircle(orthogonal_move_fol(V, cgi.SLEV[sl]), rad, col); if(si.top == SIDE::RED2)
} queuecircle(orthogonal_move_fol(V, cgi.RED[2]), rad, col);
if(chasmgraph(c)) if(si.top == SIDE::RED3)
queuecircle(orthogonal_move_fol(V, cgi.LAKE), rad, col); queuecircle(orthogonal_move_fol(V, cgi.RED[3]), rad, col);
if(si.top <= SIDE::WATERLEVEL)
queuecircle(orthogonal_move_fol(V, cgi.WATERLEVEL), rad, col);
} }
EX void queuecircleat(cell *c, double rad, color_t col) { EX void queuecircleat(cell *c, double rad, color_t col) {

25
hyper.h
View File

@ -687,18 +687,10 @@ static constexpr int MAXPLAYER = 7;
enum class PPR { enum class PPR {
ZERO, EUCLIDEAN_SKY, OUTCIRCLE, MOVESTAR, ZERO, EUCLIDEAN_SKY, OUTCIRCLE, MOVESTAR,
MINUSINF, MINUSINF,
BELOWBOTTOM, DEEP_ESCHER, DEEP_SIDE, DEEP_FALLANIM, DEEP_TOP, HELLSPIKE,
BELOWBOTTOM_FALLANIM, SHALLOW_ESCHER, SHALLOW_SIDE, SHALLOW_FALLANIM, SHALLOW_TOP,
LAKEBOTTOM, HELLSPIKE, WATERLEVEL_ESCHER, WATERLEVEL_SIDE, WATERLEVEL_TOP, BOATLEV, BOATLEV2, BOATLEV3,
INLAKEWALL, FLOOR_ESCHER, FLOOR_SIDE, FLOOR_FALLANIM, FLOOR_TOWER, FLOOR, FLOOR_DRAGON,
INLAKEWALL_FALLANIM,
BSHALLOW, SHALLOW, ASHALLOW,
SUBLAKELEV, LAKELEV, BOATLEV, BOATLEV2, BOATLEV3,
LAKEWALL,
LAKEWALL_FALLANIM,
FLOOR_TOWER,
FLOOR,
FLOOR_DRAGON,
FLOORa, FLOORb, FLOORc, FLOORd, FLOORa, FLOORb, FLOORc, FLOORd,
LIZEYE, LIZEYE,
BFLOOR, BFLOOR,
@ -706,17 +698,16 @@ enum class PPR {
WALLSHADOW, WALLSHADOW,
STRUCT0, STRUCT1, STRUCT2, STRUCT3, STRUCT0, STRUCT1, STRUCT2, STRUCT3,
THORNS, WALL, THORNS, WALL,
REDWALLs, REDWALL, RED1_ESCHER, RED1_SIDE, RED1_TOP,
REDWALLs2, REDWALLt2, RED2_ESCHER, RED2_SIDE, RED2_TOP,
REDWALLs3, REDWALLt3, RED3_ESCHER, RED3_SIDE, RED3_TOP,
HEPTAMARK, HEPTAMARK,
ITEM_BELOW, ITEM_BELOW,
ITEM, ITEMa, ITEMb, ITEM, ITEMa, ITEMb,
BIGSTATUE, BIGSTATUE,
WALL3s, WALL3, WALL3A, WALL_ESCHER, WALL_SIDE, WALL_TOP, WALL_DECO,
// WALL3m, WALL3s, WALL3p, WALL3, WALL3A,
HIDDEN, GIANTSHADOW, HIDDEN, GIANTSHADOW,
TENTACLE0, TENTACLE1, TENTACLE0, TENTACLE1,
ONTENTACLE, ONTENTACLE_EYES, ONTENTACLE_EYES2, ONTENTACLE, ONTENTACLE_EYES, ONTENTACLE_EYES2,

View File

@ -2227,7 +2227,7 @@ EX void adjust_eye(transmatrix& T, cell *c, ld sign) {
if(isWorm(c->monst) && sl < 3) sl++; if(isWorm(c->monst) && sl < 3) sl++;
ld i = cgi.emb->center_z(); ld i = cgi.emb->center_z();
if(sl || vid.eye || i) if(sl || vid.eye || i)
T = T * lzpush(sign * (cgi.SLEV[sl] - cgi.FLOOR - vid.eye + i)); T = T * lzpush(sign * (cgi.RED[sl] - cgi.FLOOR - vid.eye + i));
} }
EX bool shmup_inverted() { EX bool shmup_inverted() {

View File

@ -90,7 +90,7 @@ void geometry_information::hpcpush(hyperpoint h) {
} }
} }
void geometry_information::chasmifyPoly(double fol, double fol2, int k) { void geometry_information::chasmifyPoly(double fol, double fol2, SIDE p) {
if(GDIM == 2) { if(GDIM == 2) {
for(int i=isize(hpc)-1; i >= last->s; i--) { for(int i=isize(hpc)-1; i >= last->s; i--) {
hpc.push_back(orthogonal_move_fol(hpc[i], fol)); hpc.push_back(orthogonal_move_fol(hpc[i], fol));
@ -375,39 +375,31 @@ template<class... T> ld grot(bool geometry, ld factor, T... t) {
#endif #endif
void geometry_information::make_sidewalls() { void geometry_information::make_sidewalls() {
for(int i=0; i<=3; i++)
dfloor_table[i] = SLEV[i];
dfloor_table[SIDE_WALL] = WALL;
dfloor_table[SIDE_LAKE] = LAKE;
dfloor_table[SIDE_LTOB] = BOTTOM;
dfloor_table[SIDE_BTOI] = INFDEEP;
dfloor_table[SIDE_HIGH] = HIGH;
dfloor_table[SIDE_HIGH2] = HIGH2;
dfloor_table[SIDE_SKY ] = SKY;
dfloor_table[SIDE_ASHA] = SHALLOW;
// sidewall parameters for the 3D mode // sidewall parameters for the 3D mode
for(int k=0; k<SIDEPARS; k++) { for(int k=0; k<SIDEPARS; k++) {
double dlow=FLOOR, dhi=FLOOR; double dlow=FLOOR, dhi=FLOOR;
if(k==SIDE_WALL) dhi = WALL; auto p = SIDE(k);
else if(k==SIDE_LAKE) dlow = LAKE; if(p==SIDE::INFDEEP) dlow = INFDEEP, dhi = INFDEEP;
else if(k==SIDE_LTOB) dlow = BOTTOM, dhi = LAKE; else if(p==SIDE::DEEP) dlow = INFDEEP, dhi = DEEP;
else if(k==SIDE_BTOI) dlow = INFDEEP, dhi = BOTTOM; else if(p==SIDE::SHALLOW) dlow = DEEP, dhi = SHALLOW;
else if(k==SIDE_WTS3) dlow = SLEV[3], dhi = WALL; else if(p==SIDE::WATERLEVEL) dlow = SHALLOW, dhi = WATERLEVEL;
else if(k==SIDE_HIGH) dlow = WALL, dhi = HIGH; else if(p==SIDE::FLOOR) dlow = WATERLEVEL, dhi = FLOOR;
else if(k==SIDE_HIGH2) dlow = HIGH, dhi = HIGH2; else if(p==SIDE::RED1) dlow = RED[0], dhi = RED[1];
else if(k==SIDE_SKY) dlow = HIGH2, dhi = SKY; else if(p==SIDE::RED2) dlow = RED[1], dhi = RED[2];
else if(k==SIDE_BSHA) dlow = BOTTOM, dhi = SHALLOW; else if(p==SIDE::RED3) dlow = RED[2], dhi = RED[3];
else if(k==SIDE_ASHA) dlow = SHALLOW, dhi = LAKE; else if(p==SIDE::RED4) dlow = RED[3], dhi = WALL;
else dlow = SLEV[k-SIDE_SLEV], dhi = SLEV[k-SIDE_SLEV+1]; else if(p==SIDE::WALL) dlow = FLOOR, dhi = WALL;
dlow_table[k] = dlow; else if(p==SIDE::HIGH) dlow = WALL, dhi = HIGH;
dhi_table[k] = dhi; else if(p==SIDE::HIGH2) dlow = HIGH, dhi = HIGH2;
else if(p==SIDE::SKY) dlow = HIGH2, dhi = SKY;
dlow_table[p] = dlow;
dhi_table[p] = dhi;
validsidepar[k] = (dlow > 0 && dhi > 0) || (dlow < 0 && dhi < 0) || GDIM == 3; validsidepar[p] = (dlow > 0 && dhi > 0) || (dlow < 0 && dhi < 0) || GDIM == 3;
bshape(shSemiFloorSide[k], PPR::LAKEWALL); bshape(shSemiFloorSide[p], PPR::FLOOR_SIDE);
for(int t=0; t<=3; t+=3) hpcpush(ddi(S7 + (3+t)*S14, floorrad0) * C0); for(int t=0; t<=3; t+=3) hpcpush(ddi(S7 + (3+t)*S14, floorrad0) * C0);
chasmifyPoly(dlow, dhi, k); chasmifyPoly(dlow, dhi, p);
} }
} }
@ -1241,16 +1233,16 @@ void geometry_information::prepare_shapes() {
ld hlenx = hdist(xpush0(hcrossf), spin(TAU/S7) * xpush0(hcrossf)); ld hlenx = hdist(xpush0(hcrossf), spin(TAU/S7) * xpush0(hcrossf));
bshape(shHalfMirror[2], PPR::WALL); bshape(shHalfMirror[2], PPR::WALL);
hpcpush(C0); hpcpush(xpush0(-len6*scalefactor)); chasmifyPoly(FLOOR, WALL, 0); hpcpush(C0); hpcpush(xpush0(-len6*scalefactor)); chasmifyPoly(FLOOR, WALL, SIDE::FLOOR);
bshape(shHalfMirror[1], PPR::WALL); bshape(shHalfMirror[1], PPR::WALL);
if(PURE) { if(PURE) {
hpcpush(xpush0(-hlen7)); hpcpush(xpush0(hcrossf+hlenx/2)); chasmifyPoly(FLOOR, WALL, 0); hpcpush(xpush0(-hlen7)); hpcpush(xpush0(hcrossf+hlenx/2)); chasmifyPoly(FLOOR, WALL, SIDE::FLOOR);
} }
else { else {
hpcpush(xpush0(-len7*scalefactor)); hpcpush(xpush0((hexf+lenx/2)*scalefactor)); chasmifyPoly(FLOOR, WALL, 0); hpcpush(xpush0(-len7*scalefactor)); hpcpush(xpush0((hexf+lenx/2)*scalefactor)); chasmifyPoly(FLOOR, WALL, SIDE::FLOOR);
} }
bshape(shHalfMirror[0], PPR::WALL); bshape(shHalfMirror[0], PPR::WALL);
hpcpush(xpush0(len6)); hpcpush(xpush0(-len6)); chasmifyPoly(FLOOR, WALL, 0); hpcpush(xpush0(len6)); hpcpush(xpush0(-len6)); chasmifyPoly(FLOOR, WALL, SIDE::FLOOR);
} }
bshape(shAsymmetric, PPR::TEXT, scalefactor, 374); bshape(shAsymmetric, PPR::TEXT, scalefactor, 374);

View File

@ -465,7 +465,7 @@ struct lilymodel : public model {
h[0] += 0.67; h[1] -= 0.36; h[0] += 0.67; h[1] -= 0.36;
h[0] *= 5; h[0] *= 5;
h[1] *= 5; h[1] *= 5;
h[2] = lerp(cgi.LAKE, cgi.FLOOR, ilerp(0.018, -0.0496, h[2]) * hmul); h[2] = lerp(cgi.WATERLEVEL, cgi.FLOOR, ilerp(0.018, -0.0496, h[2]) * hmul);
if(GDIM == 3) h = cgi.emb->logical_to_actual(h); if(GDIM == 3) h = cgi.emb->logical_to_actual(h);
else h[2] = 1; else h[2] = 1;
return h; return h;
@ -479,7 +479,7 @@ struct duckmodel : public model {
hyperpoint transform(hyperpoint h) override { hyperpoint transform(hyperpoint h) override {
h = cspin90(1, 2) * h; h = cspin90(1, 2) * h;
h[0] += 3.8; h[1] -= 2; h[0] += 3.8; h[1] -= 2;
h[2] = lerp(cgi.LAKE, cgi.FLOOR, ilerp(0.056, -0.408, h[2]) * hmul * 1.5); h[2] = lerp(cgi.WATERLEVEL, cgi.FLOOR, ilerp(0.056, -0.408, h[2]) * hmul * 1.5);
if(GDIM == 3) h = cgi.emb->logical_to_actual(h); if(GDIM == 3) h = cgi.emb->logical_to_actual(h);
else h[2] = 1; else h[2] = 1;
return h; return h;
@ -1030,16 +1030,16 @@ bool chess_ceiling(celldrawer *cw) {
color_t wcol1 = (gradient(0, domcol, 0, .9, 1) << 8) | 0xFF; color_t wcol1 = (gradient(0, domcol, 0, .9, 1) << 8) | 0xFF;
color_t wcol2 = (gradient(0, domcol, 0, .8, 1) << 8) | 0xFF; color_t wcol2 = (gradient(0, domcol, 0, .8, 1) << 8) | 0xFF;
if(house1.count(cw->c)) forCellIdEx(c2, i, cw->c) if(!house1.count(c2)) { if(house1.count(cw->c)) forCellIdEx(c2, i, cw->c) if(!house1.count(c2)) {
placeSidewall(cw->c, i, SIDE_HIGH, cw->V, (i&1)?wcol1:wcol2); placeSidewall(cw->c, i, SIDE::HIGH, cw->V, (i&1)?wcol1:wcol2);
placeSidewall(cw->c, i, SIDE_HIGH2, cw->V, (i&1)?wcol1:wcol2); placeSidewall(cw->c, i, SIDE::HIGH2, cw->V, (i&1)?wcol1:wcol2);
} }
forCellIdEx(c2, i, cw->c) if(!house2.count(c2)) { forCellIdEx(c2, i, cw->c) if(!house2.count(c2)) {
placeSidewall(cw->c, i, SIDE_HIGH2, cw->V, (i&1)?wcol1:wcol2); placeSidewall(cw->c, i, SIDE::HIGH2, cw->V, (i&1)?wcol1:wcol2);
} }
if(house1.count(cw->c) != house2.count(cw->c)) if(house1.count(cw->c) != house2.count(cw->c))
draw_shapevec(cw->c, cw->V, qfi.fshape->levels[SIDE_HIGH], col, PPR::REDWALL); draw_shapevec(cw->c, cw->V, qfi.fshape->levels[SIDE::HIGH], col, PPR::RED1_TOP);
if(house2.count(cw->c)) if(house2.count(cw->c))
draw_shapevec(cw->c, cw->V, qfi.fshape->levels[SIDE_HIGH2], (domroof << 8) | 0xFF, PPR::REDWALL); draw_shapevec(cw->c, cw->V, qfi.fshape->levels[SIDE::HIGH2], (domroof << 8) | 0xFF, PPR::RED1_TOP);
auto co = euc::full_coords2(cw->c); auto co = euc::full_coords2(cw->c);
int x = gmod(co.first, 20); int x = gmod(co.first, 20);
@ -1047,7 +1047,7 @@ bool chess_ceiling(celldrawer *cw) {
char ch = xmap[y][x]; char ch = xmap[y][x];
if(ch == 'O') { if(ch == 'O') {
placeSidewall(cw->c, 1, SIDE_HIGH, cw->V, 0xC0E0FFC0); placeSidewall(cw->c, 1, SIDE::HIGH, cw->V, 0xC0E0FFC0);
((dqi_poly&)(*ptds.back())).tinf = nullptr; ((dqi_poly&)(*ptds.back())).tinf = nullptr;
} }
} }

View File

@ -190,9 +190,9 @@ bool draw_fifteen(cell *c, const shiftmatrix& V) {
ensure_floorshape_generated(shvid(c), c); ensure_floorshape_generated(shvid(c), c);
for(int i=0; i<c->type; i++) for(int i=0; i<c->type; i++)
if(!fif.count(c->move(i)) || (showing ? fif[c->move(i)].target : fif[c->move(i)].current) == Empty) if(!fif.count(c->move(i)) || (showing ? fif[c->move(i)].target : fif[c->move(i)].current) == Empty)
placeSidewall(c, i, SIDE_SLEV, V, 0xFFFFFFFF); placeSidewall(c, i, SIDE::RED1, V, 0xFFFFFFFF);
auto V1 = orthogonal_move_fol(V, cgi.SLEV[1]); auto V1 = orthogonal_move_fol(V, cgi.RED[1]);
draw_qfi(c, V1, 0xFFFFFFFF, PPR::WALL3A); draw_qfi(c, V1, 0xFFFFFFFF, PPR::WALL_DECO);
write_in_space(V1 * ddspin(c,cdir,0) * (cmir ? MirrorX: Id), 72, 1, dotted(cur), 0xFF, 0, 8); write_in_space(V1 * ddspin(c,cdir,0) * (cmir ? MirrorX: Id), 72, 1, dotted(cur), 0xFF, 0, 8);
return true; return true;
} }

View File

@ -417,20 +417,20 @@ void render_tile(shiftmatrix V, tile& t, cell *c, vector<tile>* origbox, int box
set_floor(cgi.shFullFloor); set_floor(cgi.shFullFloor);
ensure_floorshape_generated(shvid(c), c); ensure_floorshape_generated(shvid(c), c);
for(int i=0; i<c->type; i++) for(int i=0; i<c->type; i++)
if(!board.count(c->move(i))) placeSidewall(c, i, SIDE_SLEV, V, back); if(!board.count(c->move(i))) placeSidewall(c, i, SIDE::RED1, V, back);
V1 = orthogonal_move_fol(V, cgi.SLEV[1]); V1 = orthogonal_move_fol(V, cgi.RED[1]);
if(!gig || !euclid_only()) draw_qfi(c, V1, back, PPR::WALL3A); if(!gig || !euclid_only()) draw_qfi(c, V1, back, PPR::WALL_DECO);
} }
else if(get_gigantic(c) == c) { else if(get_gigantic(c) == c) {
wider w(wide); wider w(wide);
for(int i=0; i<=corners; i++) curvepoint(pt(i, 3)); for(int i=0; i<=corners; i++) curvepoint(pt(i, 3));
queuecurve(V, lines, backd, PPR::WALL3A); queuecurve(V, lines, backd, PPR::WALL_DECO);
} }
if(c && gig) { if(c && gig) {
if(gigants.at(c) != c) return; if(gigants.at(c) != c) return;
if(euclid_only()) if(euclid_only())
draw_qfi(c, V1 * euscalexx(3), back, PPR::WALL3A); draw_qfi(c, V1 * euscalexx(3), back, PPR::WALL_DECO);
} }
const ld nearco = 4; const ld nearco = 4;
@ -441,7 +441,7 @@ void render_tile(shiftmatrix V, tile& t, cell *c, vector<tile>* origbox, int box
a = floor(a) + 1; a = floor(a) + 1;
while(a < b) curvepoint(pt(a++, 3)); while(a < b) curvepoint(pt(a++, 3));
curvepoint(pt(b, 3)); curvepoint(pt(b, 3));
queuecurve(V1, 0, darkena(col, 0, 0xFF), PPR::WALL3A); queuecurve(V1, 0, darkena(col, 0, 0xFF), PPR::WALL_DECO);
}; };
if(has_power(t, sp::polski)) { if(has_power(t, sp::polski)) {
@ -466,14 +466,14 @@ void render_tile(shiftmatrix V, tile& t, cell *c, vector<tile>* origbox, int box
if(has_power(t, sp::english)) { if(has_power(t, sp::english)) {
vid.linewidth *= 3; vid.linewidth *= 3;
for(int i=0; i<corners; i++) queueline(V1 * pt(i/2., 3), V1 * pt((i+corners)/2., 3), darkena(0xFFFFFF, 0, 0xFF), 2, PPR::WALL3A); for(int i=0; i<corners; i++) queueline(V1 * pt(i/2., 3), V1 * pt((i+corners)/2., 3), darkena(0xFFFFFF, 0, 0xFF), 2, PPR::WALL_DECO);
vid.linewidth /= 3; vid.linewidth /= 3;
// for simplicity, and less confusion with the letter, we do not add the red cross on top // for simplicity, and less confusion with the letter, we do not add the red cross on top
} }
if(has_power(t, sp::portugues_br)) { if(has_power(t, sp::portugues_br)) {
for(int i=0; i<=corners; i++) curvepoint(pt(i+.5, 3)); for(int i=0; i<=corners; i++) curvepoint(pt(i+.5, 3));
queuecurve(V1, 0, darkena(0xFEDD00, 0, 0xFF), PPR::WALL3A); queuecurve(V1, 0, darkena(0xFEDD00, 0, 0xFF), PPR::WALL_DECO);
} }
if(has_power(t, sp::bending)) { if(has_power(t, sp::bending)) {
@ -592,8 +592,8 @@ bool draw(cell *c, const shiftmatrix& V) {
queueline(V * pt0(cw, j), V1 * pt0(cw1, j), 0x0000FF80, 5); queueline(V * pt0(cw, j), V1 * pt0(cw1, j), 0x0000FF80, 5);
if(tiles3) { if(tiles3) {
auto high_V = orthogonal_move_fol(V, cgi.SLEV[1]); auto high_V = orthogonal_move_fol(V, cgi.RED[1]);
auto high_V1 = orthogonal_move_fol(V1, cgi.SLEV[1]); auto high_V1 = orthogonal_move_fol(V1, cgi.RED[1]);
queueline(high_V * pt0(cw, 1), high_V1 * pt0(cw1, 1), 0xFF800080, 5); queueline(high_V * pt0(cw, 1), high_V1 * pt0(cw1, 1), 0xFF800080, 5);
queueline(high_V * pt0(cw, j), high_V1 * pt0(cw1, j), 0x0000FF80, 5); queueline(high_V * pt0(cw, j), high_V1 * pt0(cw1, j), 0x0000FF80, 5);
} }

38
sky.cpp
View File

@ -406,7 +406,7 @@ void celldrawer::draw_ceiling() {
if(star_for(fieldpattern::fieldval_uniq(c) ^ 0x5555)) if(star_for(fieldpattern::fieldval_uniq(c) ^ 0x5555))
draw_star(V, cgi.shNightStar, 0xFFFFFFFF, true); draw_star(V, cgi.shNightStar, 0xFFFFFFFF, true);
int sk = get_skybrightness(-1); int sk = get_skybrightness(-1);
auto sky = draw_shapevec(c, V * MirrorZ, cgi.shFullFloor.levels[SIDE_SKY], 0x000000FF + 0x100 * (sk/17), PPR::SKY); auto sky = draw_shapevec(c, V * MirrorZ, cgi.shFullFloor.levels[SIDE::SKY], 0x000000FF + 0x100 * (sk/17), PPR::SKY);
if(sky) sky->tinf = NULL, sky->flags |= POLY_INTENSE; if(sky) sky->tinf = NULL, sky->flags |= POLY_INTENSE;
} }
return; return;
@ -491,13 +491,13 @@ void celldrawer::draw_ceiling() {
add_to_sky(0, 0); add_to_sky(0, 0);
if(camera_over(cgi.WALL)) return; if(camera_over(cgi.WALL)) return;
if(c->land == laMercuryRiver) fcol = linf[laTerracotta].color, fd = 1; if(c->land == laMercuryRiver) fcol = linf[laTerracotta].color, fd = 1;
if(qfi.fshape) draw_shapevec(c, V, qfi.fshape->levels[SIDE_WALL], darkena(fcol, fd, 0xFF), PPR::WALL); if(qfi.fshape) draw_shapevec(c, V, qfi.fshape->levels[SIDE::WALL], darkena(fcol, fd, 0xFF), PPR::WALL);
forCellIdEx(c2, i, c) forCellIdEx(c2, i, c)
if(ceiling_category(c2) != 3) { if(ceiling_category(c2) != 3) {
color_t wcol2 = gradient(0, wcol, 0, .8, 1); color_t wcol2 = gradient(0, wcol, 0, .8, 1);
placeSidewall(c, i, SIDE_HIGH, V, darkena(wcol2, fd, 0xFF)); placeSidewall(c, i, SIDE::HIGH, V, darkena(wcol2, fd, 0xFF));
placeSidewall(c, i, SIDE_HIGH2, V, darkena(wcol2, fd, 0xFF)); placeSidewall(c, i, SIDE::HIGH2, V, darkena(wcol2, fd, 0xFF));
placeSidewall(c, i, SIDE_SKY, V, darkena(wcol2, fd, 0xFF)); placeSidewall(c, i, SIDE::SKY, V, darkena(wcol2, fd, 0xFF));
} }
return; return;
} }
@ -509,17 +509,17 @@ void celldrawer::draw_ceiling() {
color_t wcol2 = 0xFFD500; color_t wcol2 = 0xFFD500;
if(ispal(c)) { if(ispal(c)) {
forCellIdEx(c2, i, c) if(!ispal(c2)) forCellIdEx(c2, i, c) if(!ispal(c2))
placeSidewall(c, i, SIDE_HIGH, V, darkena(wcol2, fd, 0xFF)); placeSidewall(c, i, SIDE::HIGH, V, darkena(wcol2, fd, 0xFF));
} }
else { else {
bool window = false; bool window = false;
forCellIdEx(c2, i, c) if(c2->wall == waPalace && ispal(c->cmodmove(i+1)) && ispal(c->cmodmove(i-1))) window = true; forCellIdEx(c2, i, c) if(c2->wall == waPalace && ispal(c->cmodmove(i+1)) && ispal(c->cmodmove(i-1))) window = true;
if(qfi.fshape && !window) draw_shapevec(c, V, qfi.fshape->levels[SIDE_HIGH], darkena(fcol, fd, 0xFF), PPR::WALL); if(qfi.fshape && !window) draw_shapevec(c, V, qfi.fshape->levels[SIDE::HIGH], darkena(fcol, fd, 0xFF), PPR::WALL);
if(window) if(window)
forCellIdEx(c2, i, c) forCellIdEx(c2, i, c)
placeSidewall(c, i, SIDE_HIGH2, V, darkena(wcol2, fd, 0xFF)); placeSidewall(c, i, SIDE::HIGH2, V, darkena(wcol2, fd, 0xFF));
} }
if(among(c->wall, waClosedGate, waOpenGate) && qfi.fshape) draw_shapevec(c, V, qfi.fshape->levels[SIDE_WALL], 0x202020FF, PPR::WALL); if(among(c->wall, waClosedGate, waOpenGate) && qfi.fshape) draw_shapevec(c, V, qfi.fshape->levels[SIDE::WALL], 0x202020FF, PPR::WALL);
draw_star(V, cgi.shNightStar, 0xFFFFFFFF); draw_star(V, cgi.shNightStar, 0xFFFFFFFF);
break; break;
@ -531,14 +531,14 @@ void celldrawer::draw_ceiling() {
color_t wcol2 = winf[waRuinWall].color; color_t wcol2 = winf[waRuinWall].color;
if(c->landparam == 1) if(c->landparam == 1)
forCellIdEx(c2, i, c) if(c2->landparam != 1) forCellIdEx(c2, i, c) if(c2->landparam != 1)
placeSidewall(c, i, SIDE_HIGH, V, darkena(wcol2, fd, 0xFF)); placeSidewall(c, i, SIDE::HIGH, V, darkena(wcol2, fd, 0xFF));
if(c->landparam != 2) if(c->landparam != 2)
forCellIdEx(c2, i, c) if(c2->landparam == 2) forCellIdEx(c2, i, c) if(c2->landparam == 2)
placeSidewall(c, i, SIDE_HIGH2, V, darkena(wcol2, fd, 0xFF)); placeSidewall(c, i, SIDE::HIGH2, V, darkena(wcol2, fd, 0xFF));
/* if(c->landparam == 0) /* if(c->landparam == 0)
if(qfi.fshape) draw_shapevec(c, V, qfi.fshape->levels[SIDE_HIGH], darkena(wcol2, fd, 0xFF), PPR::WALL); */ if(qfi.fshape) draw_shapevec(c, V, qfi.fshape->levels[SIDE::HIGH], darkena(wcol2, fd, 0xFF), PPR::WALL); */
if(c->landparam == 1) if(c->landparam == 1)
if(qfi.fshape) draw_shapevec(c, V, qfi.fshape->levels[SIDE_WALL], darkena(wcol2, fd, 0xFF), PPR::WALL); if(qfi.fshape) draw_shapevec(c, V, qfi.fshape->levels[SIDE::WALL], darkena(wcol2, fd, 0xFF), PPR::WALL);
break; break;
} }
@ -550,14 +550,14 @@ void celldrawer::draw_ceiling() {
color_t wcol2 = winf[waColumn].color; color_t wcol2 = winf[waColumn].color;
if(c->landparam == 1) if(c->landparam == 1)
forCellIdEx(c2, i, c) if(c2->landparam != 1) forCellIdEx(c2, i, c) if(c2->landparam != 1)
placeSidewall(c, i, SIDE_HIGH, V, darkena(wcol2, fd, 0xFF)); placeSidewall(c, i, SIDE::HIGH, V, darkena(wcol2, fd, 0xFF));
if(c->landparam != 2) if(c->landparam != 2)
forCellIdEx(c2, i, c) if(c2->landparam == 2) forCellIdEx(c2, i, c) if(c2->landparam == 2)
placeSidewall(c, i, SIDE_HIGH2, V, darkena(wcol2, fd, 0xFF)); placeSidewall(c, i, SIDE::HIGH2, V, darkena(wcol2, fd, 0xFF));
if(c->landparam == 0) if(c->landparam == 0)
if(qfi.fshape) draw_shapevec(c, V, qfi.fshape->levels[SIDE_HIGH], darkena(wcol2, fd, 0xFF), PPR::WALL); if(qfi.fshape) draw_shapevec(c, V, qfi.fshape->levels[SIDE::HIGH], darkena(wcol2, fd, 0xFF), PPR::WALL);
if(c->landparam == 1) if(c->landparam == 1)
if(qfi.fshape) draw_shapevec(c, V, qfi.fshape->levels[SIDE_WALL], darkena(wcol2, fd, 0xFF), PPR::WALL); if(qfi.fshape) draw_shapevec(c, V, qfi.fshape->levels[SIDE::WALL], darkena(wcol2, fd, 0xFF), PPR::WALL);
break; break;
} }
@ -567,10 +567,10 @@ void celldrawer::draw_ceiling() {
if(pseudohept(c)) { if(pseudohept(c)) {
forCellIdEx(c2, i, c) forCellIdEx(c2, i, c)
placeSidewall(c, i, SIDE_HIGH, V, darkena(fcol, fd, 0xFF)); placeSidewall(c, i, SIDE::HIGH, V, darkena(fcol, fd, 0xFF));
} }
else if(qfi.fshape) else if(qfi.fshape)
draw_shapevec(c, V, qfi.fshape->levels[SIDE_WALL], darkena(fcol, fd, 0xFF), PPR::WALL); draw_shapevec(c, V, qfi.fshape->levels[SIDE::WALL], darkena(fcol, fd, 0xFF), PPR::WALL);
draw_star(V, cgi.shNightStar, 0xFFFFFFFF); draw_star(V, cgi.shNightStar, 0xFFFFFFFF);
break; break;