From c8e604f40855b1dfc32449cc666dabdd250a0c6b Mon Sep 17 00:00:00 2001 From: Zeno Rogue Date: Sun, 23 Sep 2018 23:55:03 +0200 Subject: [PATCH] reflect view in mirror walls during animation and just scrolling; better translate animation in memory saving mode --- hyper.h | 1 + hypgraph.cpp | 4 ++++ screenshot.cpp | 40 +++++++++++++++++++++++++++++++++++----- shmup.cpp | 40 ++++++++++++++++++++++------------------ 4 files changed, 62 insertions(+), 23 deletions(-) diff --git a/hyper.h b/hyper.h index 7f495ce0..43e53ba8 100644 --- a/hyper.h +++ b/hyper.h @@ -894,6 +894,7 @@ namespace shmup { void virtualRebase(shmup::monster *m, bool tohex); extern monster *pc[MAXPLAYER]; + int reflect(cell*& c2, cell*& mbase, transmatrix& nat); } transmatrix& ggmatrix(cell *c); diff --git a/hypgraph.cpp b/hypgraph.cpp index ff5c2de8..c8b85c79 100644 --- a/hypgraph.cpp +++ b/hypgraph.cpp @@ -798,6 +798,10 @@ void centerpc(ld aspd) { void optimizeview() { + if(centerover.at && inmirror(centerover.at)) { + anims::reflect_view(); + } + DEBB(DF_GRAPH, (debugfile,"optimize view\n")); int turn = 0; ld best = INF; diff --git a/screenshot.cpp b/screenshot.cpp index 235d47e0..492b1223 100644 --- a/screenshot.cpp +++ b/screenshot.cpp @@ -373,8 +373,19 @@ ld circle_radius = acosh(2.), circle_spins = 1; void moved() { optimizeview(); - if(cheater || autocheat) + if(cheater || autocheat) { + if(hyperbolic && memory_saving_mode && cwt.at != centerover.at && !quotient) { + if(isNeighbor(cwt.at, centerover.at)) { + cwt.spin = neighborId(centerover.at, cwt.at); + flipplayer = true; + } + animateMovement(cwt.at, centerover.at, LAYER_SMALL, NODIR); + cwt.at = centerover.at; + save_memory(); + return; + } setdist(masterless ? centerover.at : viewctr.at->c7, 7 - getDistLimit() - genrange_bonus, NULL); + } playermoved = false; } @@ -417,20 +428,38 @@ int paramstate = 0; bool needs_highqual; +void reflect_view() { + if(centerover.at) { + transmatrix T = Id; + cell *mbase = centerover.at; + cell *c = centerover.at; + if(shmup::reflect(c, mbase, T)) + View = inverse(T) * View; + } + } + void apply() { int t = ticks - lastticks; lastticks = ticks; + switch(ma) { case maTranslation: if(conformal::on) { conformal::phase = (isize(conformal::v) - 1) * ticks * 1. / period; conformal::movetophase(); } - else { - if(inmirror(centerover.at) || (hyperbolic && !quotient && - centerover.at->land != cwt.at->land && among(centerover.at->land, laHaunted, laIvoryTower, laDungeon, laEndorian) && centerover.at->landparam >= 10 + else if(centerover.at) { + reflect_view(); + if((hyperbolic && !quotient && + (centerover.at->land != cwt.at->land || memory_saving_mode) && among(centerover.at->land, laHaunted, laIvoryTower, laDungeon, laEndorian) && centerover.at->landparam >= 10 ) ) { - fullcenter(); View = spin(rand() % 1000) * View; + if(memory_saving_mode) { + activateSafety(laIce); + return; + } + else { + fullcenter(); View = spin(rand() % 1000) * View; + } } View = spin(movement_angle * M_PI / 180) * ypush(shift_angle * M_PI / 180) * xpush(cycle_length * t / period) * ypush(-shift_angle * M_PI / 180) * spin(-movement_angle * M_PI / 180) * View; @@ -441,6 +470,7 @@ void apply() { View = spin(2 * M_PI * t / period) * View; break; case maParabolic: + reflect_view(); View = spin(movement_angle * M_PI / 180) * ypush(shift_angle * M_PI / 180) * binary::parabolic(parabolic_length * t / period) * ypush(-shift_angle * M_PI / 180) * spin(-movement_angle * M_PI / 180) * View; moved(); diff --git a/shmup.cpp b/shmup.cpp index 2d94f67d..2e67465d 100644 --- a/shmup.cpp +++ b/shmup.cpp @@ -1430,8 +1430,6 @@ bool noncrashable(monster *m, monster *by) { int bulltime[MAXPLAYER]; -void reflect(cell*& c2, monster *m, transmatrix& nat); - // set to P_MIRRORWALL to allow the PCs to go through mirrors static const int reflectflag = P_MIRRORWALL; @@ -1583,7 +1581,7 @@ void movePlayer(monster *m, int delta) { // spin(span[igo]) * xpush(playergo[cpid]) * spin(-span[igo]); c2 = m->findbase(nat); - if(reflectflag & P_MIRRORWALL) reflect(c2, m, nat); + if(reflectflag & P_MIRRORWALL) reflect(c2, m->base, nat); // don't have several players in one spot // also don't let them run too far from each other! @@ -1866,23 +1864,27 @@ bool reflectmatrix(transmatrix& M, cell *c1, cell *c2, bool onlypos) { return true; } -void reflect(cell*& c2, monster *m, transmatrix& nat) { - if(c2 != m->base && c2->wall == waMirrorWall && inmirror(c2)) { - if(reflectmatrix(nat, m->base, c2, false)) - c2 = m->base; +int reflect(cell*& c2, cell*& mbase, transmatrix& nat) { + int reflections = 0; + if(c2 != mbase && c2->wall == waMirrorWall && inmirror(c2)) { + if(reflectmatrix(nat, mbase, c2, false)) { + c2 = mbase; + reflections++; + } } - if(c2 == m->base && inmirror(c2)) { + if(c2 == mbase && inmirror(c2)) { forCellEx(c3, c2) if(c3->land == laMirrorWall) { - cell *c1 = m->base; - m->base = c3; - reflect(c3, m, nat); - m->base = c1; + cell *c1 = mbase; + mbase = c3; + reflect(c3, mbase, nat); + mbase = c1; c2 = c3; + reflections++; } } - if(c2 == m->base && c2->wall == waMirrorWall && c2->land == laMirrorWall) { + if(c2 == mbase && c2->wall == waMirrorWall && c2->land == laMirrorWall) { int d = mirror::mirrordir(c2); if(d != -1) { for(int k=0; k<7; k++) { @@ -1890,6 +1892,7 @@ void reflect(cell*& c2, monster *m, transmatrix& nat) { cell *cb = createMovR(c2, d+k); if(ca->land == laMirror && inmirror(cb)) { reflectmatrix(nat, ca, cb, true); + reflections++; break; } } @@ -1901,11 +1904,12 @@ void reflect(cell*& c2, monster *m, transmatrix& nat) { if(cb->land != laMirrorWall || cc->land != laMirrorWall) continue; cell *ca = createMovR(c2, k); cell *cd = createMovR(c2, k+3); - reflectmatrix(nat, cc, ca, true); - for(int limit=0; limit<10 && reflectmatrix(nat, cb, cd, true) && reflectmatrix(nat, cc, ca, true); limit++); + if(reflectmatrix(nat, cc, ca, true)) reflections++; + for(int limit=0; limit<10 && reflectmatrix(nat, cb, cd, true) && (reflections++, reflectmatrix(nat, cc, ca, true)); limit++) reflections+=2; } } } + return reflections; } void moveMimic(monster *m) { @@ -1918,7 +1922,7 @@ void moveMimic(monster *m) { nat = nat * spin(playerturn[cpid]) * xpush(playergo[cpid]); cell *c2 = m->findbase(nat); - reflect(c2, m, nat); + reflect(c2, m->base, nat); if(c2 != m->base && !passable(c2, m->base, P_ISPLAYER | P_MIRROR | P_MIRRORWALL)) killMonster(m, moNone); else { @@ -2105,7 +2109,7 @@ void moveBullet(monster *m, int delta) { awakenMimics(m, c2); } - reflect(c2, m, nat); + reflect(c2, m->base, nat); bool godragon = m->type == moFireball && isDragon(c2->monst); @@ -2585,7 +2589,7 @@ void moveMonster(monster *m, int delta) { if(crashintomon) { igo++; goto igo_retry; } cell *c2 = m->findbase(nat); - if(reflectflag & P_MIRRORWALL) reflect(c2, m, nat); + if(reflectflag & P_MIRRORWALL) reflect(c2, m->base, nat); if(m->type == moButterfly && !passable_for(m->type, c2, m->base, P_CHAIN | reflectflag)) { igo++; goto igo_retry;