diff options
author | Thorbjørn Lindeijer <bjorn@lindeijer.nl> | 2024-10-04 18:24:47 +0200 |
---|---|---|
committer | Thorbjørn Lindeijer <bjorn@lindeijer.nl> | 2024-10-08 21:03:44 +0200 |
commit | d9a6aa323b00e23e7c858e1feeacfd3ee26bc298 (patch) | |
tree | c5fb35d658cdfd7c376a2ae2cf8f2523406aaeeb /src | |
parent | 573df67919ec5f65a6b2ad51ed8aed31c9cfe4a6 (diff) | |
download | mana-d9a6aa323b00e23e7c858e1feeacfd3ee26bc298.tar.gz mana-d9a6aa323b00e23e7c858e1feeacfd3ee26bc298.tar.bz2 mana-d9a6aa323b00e23e7c858e1feeacfd3ee26bc298.tar.xz mana-d9a6aa323b00e23e7c858e1feeacfd3ee26bc298.zip |
Smoother keyboard movement
This change addresses the slight stutter and broken animation playback
when walking with the keyboard.
Once the end of the path has been reached but a movement key is still
held, the LocalPlayer now immediately calculates a new path rather than
waiting on the next logic update.
Diffstat (limited to 'src')
-rw-r--r-- | src/being.cpp | 8 | ||||
-rw-r--r-- | src/being.h | 11 | ||||
-rw-r--r-- | src/localplayer.cpp | 30 | ||||
-rw-r--r-- | src/localplayer.h | 16 |
4 files changed, 39 insertions, 26 deletions
diff --git a/src/being.cpp b/src/being.cpp index c23a650d..1ab13250 100644 --- a/src/being.cpp +++ b/src/being.cpp @@ -828,8 +828,13 @@ void Being::updateMovement() // Also, if the destination is reached, try to get the next // path point, if existing. if (!mPath.empty()) + { mPath.pop_front(); + if (mPath.empty()) + pathFinished(); + } + // Set dt to the time left after performing this move. dt -= dt * (distanceToDest / distanceToMove); } @@ -870,6 +875,9 @@ void Being::updateMovement() // If the current path node has been reached, // remove it and go to the next one. mPath.pop_front(); + + if (mPath.empty()) + pathFinished(); } else { diff --git a/src/being.h b/src/being.h index 8f596810..6636af7b 100644 --- a/src/being.h +++ b/src/being.h @@ -175,7 +175,7 @@ class Being : public ActorSprite, public EventListener * @param damage the amount of damage dealt (0 means miss) * @param attackId the attack id */ - virtual void handleAttack(Being *victim, int damage, int attackId = 1); + void handleAttack(Being *victim, int damage, int attackId = 1); const ItemInfo *getEquippedWeapon() const { return mEquippedWeapon; } @@ -380,7 +380,7 @@ class Being : public ActorSprite, public EventListener /** * Returns the being's pixel radius used to detect collisions. */ - virtual int getCollisionRadius() const; + int getCollisionRadius() const; /** * Shoots a missile particle from this being, to target being @@ -403,7 +403,7 @@ class Being : public ActorSprite, public EventListener /** * Sets the gender of this being. */ - virtual void setGender(Gender gender); + void setGender(Gender gender); Gender getGender() const { return mGender; } @@ -477,6 +477,11 @@ class Being : public ActorSprite, public EventListener */ int getSpeechTextYPosition() const; + /** + * Called when the being has reached the end of its path. + */ + virtual void pathFinished() {} + const BeingInfo *mInfo; Timer mActionTimer; /**< Time spent in current action. TODO: Remove use of it */ diff --git a/src/localplayer.cpp b/src/localplayer.cpp index 5075c44c..40849379 100644 --- a/src/localplayer.cpp +++ b/src/localplayer.cpp @@ -700,23 +700,33 @@ void LocalPlayer::setWalkingDir(int dir) // Don't compute a new path before the last one set by keyboard is finished. // This permits to avoid movement glitches and server spamming. - const Vector &pos = getPosition(); - const Vector &dest = getDestination(); - if (!isPathSetByMouse() && (pos.x != dest.x || pos.y != dest.y)) - return; + if (!isPathSetByMouse()) + { + const Vector &pos = getPosition(); + const Vector &dest = getDestination(); + + if (pos.x != dest.x || pos.y != dest.y) + { + mWalkingDir = dir; + return; + } + } // If the player is pressing a key, and its different from what he has // been pressing, stop (do not send this stop to the server) and // start in the new direction - if (dir && (dir != getWalkingDir())) + if (dir && dir != mWalkingDir) + { local_player->stopWalking(false); - - // Else, he is not pressing a key, - // and the current path hasn't been sent by mouse, - // then let the path die (1/2 tile after that.) - // This permit to avoid desyncs with other clients. + } + // Else, he is not pressing a key, and the current path hasn't been sent by + // mouse, then let the path die (1/2 tile after that.) This permit to avoid + // desyncs with other clients. else if (!dir) + { + mWalkingDir = 0; return; + } cancelGoToTarget(); diff --git a/src/localplayer.h b/src/localplayer.h index 43453498..34021cbd 100644 --- a/src/localplayer.h +++ b/src/localplayer.h @@ -100,18 +100,6 @@ class LocalPlayer final : public Being void stopAttack(); /** - * Overridden to do nothing. The attacks of the local player are - * displayed as soon as the player attacks, not when the server says - * the player does. - * - * @param victim the victim being - * @param damage the amount of damage dealt (0 means miss) - * @param type the attack type - */ - //virtual void handleAttack(Being *victim, int damage, AttackType type) {} - virtual void handleAttack() {} - - /** * Returns the current target of the player. Returns 0 if no being is * currently targeted. */ @@ -209,7 +197,7 @@ class LocalPlayer final : public Being /** * set the next path tile when walking and using the keyboard. */ - virtual void nextTile(unsigned char dir); + void nextTile(unsigned char dir); /** * Compute the next pathnode location when walking using keyboard. @@ -217,6 +205,8 @@ class LocalPlayer final : public Being */ Position getNextWalkPosition(unsigned char dir); + void pathFinished() override { nextTile(mWalkingDir); } + int mAttackRange = -1; Timer mLastTargetTimer; /**< Timer for last targeting action. */ |