From 9c9afceb412535d5b658636c5a8fbdbbe28acb43 Mon Sep 17 00:00:00 2001 From: Zeno Rogue Date: Sat, 26 Dec 2020 18:09:09 +0100 Subject: [PATCH] Princess hug animation --- complex.cpp | 18 +++++++++++++++++- graph.cpp | 30 +++++++++++++++++++++++------- 2 files changed, 40 insertions(+), 8 deletions(-) diff --git a/complex.cpp b/complex.cpp index 72d5a159..83fecc6e 100644 --- a/complex.cpp +++ b/complex.cpp @@ -506,6 +506,7 @@ struct info { int bestnear; // best dist achieved, by the player int value; // number of Rugs at 120 cell *princess; // where is the Princess currently + int together; // in which turn have we been together -- for the hug animation }; #endif @@ -542,6 +543,7 @@ struct info { i->id = isize(infos); i->bestdist = 0; i->bestnear = OUT_OF_PRISON; + i->together = -INF; infos.push_back(i); assign(i); return i->id; @@ -555,6 +557,7 @@ struct info { i->id = isize(infos); i->bestdist = items[itSavedPrincess] ? OUT_OF_PALACE : OUT_OF_PRISON; i->bestnear = 0; + i->together = -INF; infos.push_back(i); assign(i); } @@ -673,7 +676,20 @@ struct info { changes.value_keep(*i); i->princess = ct; setdist(i, dist(ct)); - // printf("newdist = %d (vs %d)\n", newdist, i->bestdist); + + forCellIdEx(cp, j, ct) if(isPlayerOn(cp)) { + bool safe = true; + for(cell *test: {ct, cp}) forCellEx(c1, test) forCellEx(c2, test) + if(isActiveEnemy(c1, moPlayer) || isActiveEnemy(c2, moPlayer)) + safe = false; + if(safe) { + if(turncount > i->together + 20) { + animateHug(movei(ct, j), LAYER_SMALL); + animateHug(movei(ct, j).rev(), LAYER_SMALL); + } + i->together = turncount; + } + } } } diff --git a/graph.cpp b/graph.cpp index 2f488634..677dae8c 100644 --- a/graph.cpp +++ b/graph.cpp @@ -2344,20 +2344,22 @@ EX bool applyAnimation(cell *c, shiftmatrix& V, double& footphase, int layer) { return true; } - if(a.attacking == 1) + if(among(a.attacking, 1, 3)) R = hdist(tC0(a.attackat), tC0(a.wherenow)); else R = hdist0(tC0(a.wherenow)); aspd *= (1+R+(shmup::on?1:0)); + + if(a.attacking == 3 && aspd > R) aspd = R; - if(R < aspd || std::isnan(R) || std::isnan(aspd) || R > 10) { + if((R < aspd || std::isnan(R) || std::isnan(aspd) || R > 10) && a.attacking != 3) { if(a.attacking == 1) { a.attacking = 2; goto again; } animations[layer].erase(c); return false; } else { hyperpoint wnow; - if(a.attacking == 1) + if(a.attacking == 1 || a.attacking == 3) wnow = tC0(z_inverse(a.wherenow) * a.attackat); else wnow = tC0(z_inverse(a.wherenow)); @@ -2382,6 +2384,11 @@ EX bool applyAnimation(cell *c, shiftmatrix& V, double& footphase, int layer) { } fixmatrix(a.wherenow); a.footphase += a.attacking == 2 ? -aspd : aspd; + if(a.attacking == 3 && aspd >= R) { + a.footphase = 0; + hyperpoint h1 = a.wherenow * C0; + a.wherenow = rgpushxto0(h1) * rspintox(h1); + } footphase = a.footphase; V = V * a.wherenow; if(a.mirrored) V = V * Mirror; @@ -5327,7 +5334,7 @@ struct animation { int ltick; double footphase; transmatrix wherenow; - int attacking; + int attacking; /** 0 = no attack animation, 1 = first phase, 2 = second phase, 3 = hugging */ transmatrix attackat; bool mirrored; }; @@ -5380,17 +5387,26 @@ EX void animateMovement(const movei& m, int layer) { a.mirrored = !a.mirrored; } -EX void animateAttack(const movei& m, int layer) { +EX void animateAttackOrHug(const movei& m, int layer, int phase, ld ratio, ld delta) { LATE( animateAttack(m, layer); ) if(vid.mspeed >= 5) return; // no animations! transmatrix T = iadj(m); bool newanim = !animations[layer].count(m.s); animation& a = animations[layer][m.s]; - a.attacking = 1; - a.attackat = rspintox(tC0(iso_inverse(T))) * xpush(hdist0(T*C0) / 3); + a.attacking = phase; + if(phase == 3) println(hlog, "distance = ", hdist0(T * C0)); + a.attackat = rspintox(tC0(iso_inverse(T))) * xpush(hdist0(T*C0) * ratio + delta); if(newanim) a.wherenow = Id, a.ltick = ticks, a.footphase = 0; } +EX void animateAttack(const movei& m, int layer) { + animateAttackOrHug(m, layer, 1, 1/3., 0); + } + +EX void animateHug(const movei& m, int layer) { + animateAttackOrHug(m, layer, 3, 0.5, -0.0713828 * cgi.scalefactor); + } + vector > animstack; EX void indAnimateMovement(const movei& m, int layer) {