tracking the specific copy of the player in confusing geometries

This commit is contained in:
Zeno Rogue 2019-11-23 19:05:24 +01:00
parent edcf160a28
commit 982f01e6e5
7 changed files with 44 additions and 6 deletions

View File

@ -47,6 +47,8 @@ struct display_data {
void set_mask(int ed);
void set_all(int ed);
/** Which copy of the player cell? */
transmatrix which_copy;
};
#define View (::hr::current_display->view_matrix)

View File

@ -1713,6 +1713,8 @@ void celldrawer::bookkeeping() {
else {
playerV = V * ddspin(c, cwt.spin, 0);
if(cwt.mirrored) playerV = playerV * Mirror;
if(!confusingGeometry() || eqmatrix(V, current_display->which_copy, 1e-2))
current_display->which_copy = V;
if(orig) cwtV = playerV;
}
}

View File

@ -6660,6 +6660,7 @@ EX bool activateRecall() {
// local_perspective = recallDisplay.local_perspective;
gmatrix = recallDisplay.cellmatrices;
gmatrix0 = recallDisplay.old_cellmatrices;
current_display->which_copy = recallDisplay.which_copy;
makeEmpty(cwt.at);
forCellEx(c2, cwt.at)
@ -8628,6 +8629,7 @@ EX bool movepcto(int d, int subdir IS(1), bool checkonly IS(false)) {
}
else
animateMovement(mi, LAYER_SMALL);
current_display->which_copy = current_display->which_copy * adj(mi);
mirror::act(origd, mirror::SPINMULTI | mirror::ATTACK | mirror::GO);

View File

@ -3919,6 +3919,8 @@ EX void drawMarkers() {
if(!(cmode & sm::NORMAL)) return;
queuepolyat(current_display->which_copy, cgi.shAsymmetric, 0xC0C0C0FF, PPR::SUPERLINE);
callhooks(hooks_markers);
#if CAP_SHAPES
viewmat();

View File

@ -1378,11 +1378,22 @@ EX void centerpc(ld aspd) {
if(ors::mode == 2 && vid.sspeed < 5) return;
if(vid.sspeed >= 4.99) aspd = 1000;
DEBBI(DF_GRAPH, ("center pc"));
auto& W = current_display->which_copy;
ors::unrotate(W); ors::unrotate(View); ors::unrotate(cwtV);
/* what should we center? */
transmatrix T;
if(multi::players > 1)
T = cwtV; /* do not even try */
else {
T = W;
if(shmup::on)
T = T * shmup::pc[0]->at;
}
ors::unrotate(cwtV); ors::unrotate(View);
if(invalid_matrix(cwtV)) return;
if(invalid_matrix(T)) return;
transmatrix T = cwtV;
#if MAXMDIM >= 4
if(GDIM == 3 && WDIM == 2) {
geom3::do_auto_eye();
@ -1412,10 +1423,11 @@ EX void centerpc(ld aspd) {
shift_view_towards(H, aspd);
fixmatrix(View);
fixmatrix(current_display->which_copy);
spinEdge(aspd);
}
ors::rerotate(cwtV); ors::rerotate(View);
ors::rerotate(W); ors::rerotate(cwtV); ors::rerotate(View);
}
EX void optimizeview() {
@ -1477,6 +1489,7 @@ EX void resetview() {
View = Id;
}
cwtV = View;
current_display->which_copy = View;
// SDL_LockSurface(s);
// SDL_UnlockSurface(s);
}
@ -2066,6 +2079,7 @@ EX transmatrix& get_view_orientation() {
EX void rotate_view(transmatrix T) {
transmatrix& which = get_view_orientation();
which = T * which;
if(&which == &View) current_display->which_copy = T * current_display->which_copy;
}
/** shift the view according to the given tangent vector */
@ -2086,17 +2100,24 @@ EX transmatrix get_shift_view_of(const hyperpoint H, const transmatrix V) {
/** shift the view according to the given tangent vector */
EX void shift_view(hyperpoint H) {
current_display->which_copy = get_shift_view_of(H, current_display->which_copy);
View = get_shift_view_of(H, View);
}
void multiply_view(transmatrix T) {
View = T * View;
auto& wc = current_display->which_copy;
wc = T * wc;
}
EX void shift_view_to(hyperpoint H) {
if(!nonisotropic) View = gpushxto0(H) * View;
if(!nonisotropic) multiply_view(gpushxto0(H));
else shift_view(-inverse_exp(H, iTable, false));
}
EX void shift_view_towards(hyperpoint H, ld l) {
if(!nonisotropic && !prod)
View = rspintox(H) * xpush(-l) * spintox(H) * View;
multiply_view(rspintox(H) * xpush(-l) * spintox(H));
else if(nonisotropic && !nisot::geodesic_movement)
shift_view(tangent_length(H-C0, -l));
else {

View File

@ -558,6 +558,7 @@ void teleportTo(cell *dest) {
cell *from = cwt.at;
movecost(from, dest, 1);
playerMoveEffects(cwt.at, dest);
current_display->which_copy = ggmatrix(dest);
cwt.at = dest; cwt.spin = hrand(dest->type); flipplayer = !!(hrand(2));
drainOrb(itOrbTeleport);
@ -602,6 +603,7 @@ EX void jumpTo(cell *dest, eItem byWhat, int bonuskill IS(0), eMonster dashmon I
cell *c1 = cwt.at;
animateMovement(match(cwt.at, dest), LAYER_SMALL);
current_display->which_copy = ggmatrix(dest);
cwt.at = dest;
forCellIdEx(c2, i, dest) if(c2->cpdist < dest->cpdist) {
cwt.spin = i;

View File

@ -172,10 +172,13 @@ void monster::rebasePat(const transmatrix& new_pat, cell *c2) {
virtualRebase(this);
fix_to_2(at);
pat = at;
if(multi::players == 1 && this == shmup::pc[0])
current_display->which_copy = ggmatrix(base);
return;
}
if(quotient) {
at = inverse(gmatrix[base]) * new_pat;
transmatrix old_at = at;
virtualRebase(this);
fix_to_2(at);
if(base != c2) {
@ -183,8 +186,12 @@ void monster::rebasePat(const transmatrix& new_pat, cell *c2) {
base = c2;
at = inverse(T) * at;
}
if(multi::players == 1 && this == shmup::pc[0] && !eqmatrix(old_at, at))
current_display->which_copy = current_display->which_copy * old_at * inverse(at);
return;
}
if(multi::players == 1 && this == shmup::pc[0])
current_display->which_copy = current_display->which_copy * inverse(gmatrix[base]) * gmatrix[c2];
pat = new_pat;
// if(c2 != base) printf("rebase %p -> %p\n", base, c2);
base = c2;