diff --git a/celldrawer.cpp b/celldrawer.cpp index 3e9fb3d0..c85f51bf 100644 --- a/celldrawer.cpp +++ b/celldrawer.cpp @@ -1894,8 +1894,9 @@ void celldrawer::bookkeeping() { else { playerV = V * ddspin(c, cwt.spin, 0); if(cwt.mirrored) playerV = playerV * Mirror; - if((!confusingGeometry() && !fake::split() && !inmirrorcount) || eqmatrix(unshift(V), current_display->which_copy, 1e-2)) - current_display->which_copy = unshift(V); + transmatrix F = back_to_view(V); + if((!confusingGeometry() && !fake::split() && !inmirrorcount) || eqmatrix(F, current_display->which_copy, 1e-2)) + current_display->which_copy = F; if(orig) cwtV = playerV; } } diff --git a/hypgraph.cpp b/hypgraph.cpp index 5f93f8e1..5937aaa7 100644 --- a/hypgraph.cpp +++ b/hypgraph.cpp @@ -1868,8 +1868,29 @@ EX void spinEdge(ld aspd) { rotate_view(spin(downspin)); } -EX void centerpc(ld aspd) { - +/** \brief convert a shiftmatrix to the coordinate system of View + * usually used to set which_copy + */ +EX transmatrix back_to_view(const shiftmatrix& V) { + // ortho_inverse does not work in 2.5D, iso_inverse does not work in Nil. + // just use inverse + return inverse(actual_view_transform) * unshift(V); + } + +EX void fix_whichcopy(cell *c) { + if(!gmatrix.count(cwt.at)) return; + current_display->which_copy = back_to_view(gmatrix[c]); + } + +void fix_whichcopy_if_near() { + if(!gmatrix.count(cwt.at)) return; + transmatrix T = back_to_view(gmatrix[cwt.at]); + if(!eqmatrix(T, current_display->which_copy)) return; + current_display->which_copy = T; + } + +EX void centerpc(ld aspd) { + if(subscreens::split([=] () {centerpc(aspd);})) return; if(dual::split([=] () { centerpc(aspd); })) return; @@ -1928,9 +1949,8 @@ EX void centerpc(ld aspd) { if(sl || vid.eye) T = T * zpush(cgi.SLEV[sl] - cgi.FLOOR + vid.eye); } #endif - // ortho_inverse does not work in 2.5D, iso_inverse does not work in Nil. - // just use inverse - hyperpoint H = inverse(actual_view_transform) * tC0(T); + + hyperpoint H = tC0(T); ld R = (zero_d(GDIM, H) && !prod) ? 0 : hdist0(H); if(R < 1e-9) { // either already centered or direction unknown @@ -1939,16 +1959,14 @@ EX void centerpc(ld aspd) { } */ spinEdge(aspd); fixmatrix(View); - if(gmatrix.count(cwt.at)) - current_display->which_copy = unshift(gmatrix[cwt.at]); + fix_whichcopy(cwt.at); + fixmatrix(current_display->which_copy); } else { aspd *= euclid ? (2+3*R*R) : (1+R+(shmup::on?1:0)); - if(R < aspd && gmatrix.count(cwt.at) && eqmatrix(unshift(gmatrix[cwt.at]), current_display->which_copy)) { - current_display->which_copy = unshift(gmatrix[cwt.at]); - } + if(R < aspd) fix_whichcopy_if_near(); if(R < aspd) shift_view_to(shiftless(H)); diff --git a/orbs.cpp b/orbs.cpp index 36e3193c..32b63e12 100644 --- a/orbs.cpp +++ b/orbs.cpp @@ -623,7 +623,7 @@ EX void teleportTo(cell *dest) { cell *from = cwt.at; movecost(from, dest, 1); playerMoveEffects(movei(cwt.at, dest, TELEPORT)); - current_display->which_copy = unshift(ggmatrix(dest)); + fix_whichcopy(dest); cwt.at = dest; cwt.spin = hrand(dest->type); flipplayer = !!(hrand(2)); drainOrb(itOrbTeleport); @@ -713,7 +713,7 @@ EX bool jumpTo(orbAction a, cell *dest, eItem byWhat, int bonuskill IS(0), eMons changes.commit(); - current_display->which_copy = unshift(ggmatrix(dest)); + fix_whichcopy(dest); countLocalTreasure(); for(int i=9; i>=0; i--) diff --git a/shmup.cpp b/shmup.cpp index 6b4be864..ae1ba4f1 100644 --- a/shmup.cpp +++ b/shmup.cpp @@ -196,7 +196,7 @@ void monster::rebasePat(const shiftmatrix& new_pat, cell *c2) { fix_to_2(at); pat = shiftless(at); if(multi::players == 1 && this == shmup::pc[0]) - current_display->which_copy = unshift(ggmatrix(base)); + current_display->which_copy = back_to_view(ggmatrix(base)); return; } if(quotient || fake::split()) {