diff --git a/celldrawer.cpp b/celldrawer.cpp index f61e71fc..8f753ccf 100644 --- a/celldrawer.cpp +++ b/celldrawer.cpp @@ -2987,7 +2987,9 @@ void celldrawer::draw() { ld footphase; applyAnimation(c, Vthrow, footphase, LAYER_THROW); eItem it = animations[LAYER_THROW][c].thrown_item; - drawItemType(it, c, Vthrow, iinf[it].color, 0, false); + if(it) drawItemType(it, c, Vthrow, iinf[it].color, 0, false); + eMonster mo = animations[LAYER_THROW][c].thrown_monster; + if(mo) drawMonsterType(mo, c, Vthrow, minf[mo].color, 0, minf[mo].color); } #if CAP_TEXTURE diff --git a/complex.cpp b/complex.cpp index c8467bcf..2a4e2d0e 100644 --- a/complex.cpp +++ b/complex.cpp @@ -1472,6 +1472,7 @@ EX namespace mirror { } c->monst = moNone; } + if(!fwd) animateCorrectAttack(movei(cw2+wstep), LAYER_SMALL, moMimic); if(c2->wall == waBigTree) c2->wall = waSmallTree; else if(c2->wall == waSmallTree) diff --git a/graph.cpp b/graph.cpp index 15883a42..36fbf3d9 100644 --- a/graph.cpp +++ b/graph.cpp @@ -1710,6 +1710,11 @@ EX bool drawMonsterType(eMonster m, cell *where, const shiftmatrix& V1, color_t return true; case moBullet: + if(getcs().charid >= 10) { + ShadowV(V, cgi.shKnife); + queuepoly(VBODY, cgi.shMissile, getcs().swordcolor); + return true; + } ShadowV(V, cgi.shKnife); queuepoly(VBODY * spin270(), cgi.shKnife, getcs().swordcolor); return true; @@ -6102,6 +6107,7 @@ struct animation { transmatrix attackat; bool mirrored; eItem thrown_item; /** for thrown items */ + eMonster thrown_monster; /** for thrown monsters */ }; // we need separate animation layers for Orb of Domination and Tentacle+Ghost, @@ -6153,7 +6159,7 @@ EX void animateMovement(const movei& m, int layer) { a.mirrored = !a.mirrored; } -EX void animate_item_throw(cell *from, cell *to, eItem it) { +EX void animate_item_throw(cell *from, cell *to, eItem it, eMonster mo IS(moNone)) { bool steps = false; again: @@ -6169,6 +6175,7 @@ EX void animate_item_throw(cell *from, cell *to, eItem it) { if(steps) { animation& a = animations[LAYER_THROW][to]; a.thrown_item = it; + a.thrown_monster = mo; } } @@ -6188,6 +6195,14 @@ EX void animateAttack(const movei& m, int layer) { animateAttackOrHug(m, layer, 1, 1/3., 0); } +EX void animateCorrectAttack(const movei& m, int layer, eMonster who) { + if(among(who, moPlayer, moMimic, moIllusion, moShadow) && getcs().charid >= 10) { + animate_item_throw(m.s, m.t, itNone, moBullet); + return; + } + 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); } diff --git a/monstermove.cpp b/monstermove.cpp index ac9ba15e..3c0636f1 100644 --- a/monstermove.cpp +++ b/monstermove.cpp @@ -742,7 +742,7 @@ EX cell *moveNormal(cell *c, flagtype mf) { } else if(m2) { attackMonster(c2, AF_NORMAL | AF_MSG, m); - animateAttack(mi, LAYER_SMALL); + animateCorrectAttack(mi, LAYER_SMALL, m); if(m == moFlailer && m2 == moIllusion) attackMonster(c, 0, m2); return c2; @@ -1156,7 +1156,7 @@ EX void groupmove2(const movei& mi, eMonster movtype, flagtype mf) { if(!(mf & MF_NOATTACKS)) for(int j=0; jtype; j++) if(c->move(j) && canAttack(c, c->monst, c->move(j), c->move(j)->monst, af)) { attackMonster(c->move(j), AF_NORMAL | AF_GETPLAYER | AF_MSG, c->monst); - animateAttack(movei(c, j), LAYER_SMALL); + animateCorrectAttack(movei(c, j), LAYER_SMALL, c->monst); onpath_mark(c); // XLATC eagle return; @@ -1738,7 +1738,7 @@ EX void movegolems(flagtype flags) { else if((flags & AF_CRUSH) && !canAttack(c, m, c2, c2->monst, flags ^ AF_CRUSH ^ AF_MUSTKILL)) markOrb(itOrbEmpathy), markOrb(itOrbSlaying); attackMonster(c2, flags | AF_MSG, m); - animateAttack(movei(c, dir), LAYER_SMALL); + animateCorrectAttack(movei(c, dir), LAYER_SMALL, m); spread_plague(c, c2, dir, m); produceGhost(c2, m2, m); sideAttack(c, dir, m, 0); diff --git a/pcmove.cpp b/pcmove.cpp index 6bd17fab..0723dea6 100644 --- a/pcmove.cpp +++ b/pcmove.cpp @@ -503,7 +503,7 @@ bool pcmove::swing() { if(checkonly) return true; if(changes.on) changes.commit(); - animateAttack(mi, LAYER_SMALL); + animateCorrectAttack(mi, LAYER_SMALL, moPlayer); if(survivalist && isHaunted(mi.t->land)) survivalist = false; lastmovetype = lmTree; lastmove = mi.t; @@ -1233,7 +1233,7 @@ bool pcmove::attack() { produceGhost(c2, m, moPlayer); } if(mip.proper()) pushMonster(mip); - animateAttack(mi, LAYER_SMALL); + animateCorrectAttack(mi, LAYER_SMALL, moPlayer); } }