Skip to content

Commit 613d6ce

Browse files
authored
Pause animations while game is paused (#10658)
Pauses all mesh animations while game is paused.
1 parent ea4c8a7 commit 613d6ce

File tree

1 file changed

+40
-0
lines changed

1 file changed

+40
-0
lines changed

src/client/game.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
6868
#include "util/pointedthing.h"
6969
#include "util/quicktune_shortcutter.h"
7070
#include "irrlicht_changes/static_text.h"
71+
#include "irr_ptr.h"
7172
#include "version.h"
7273
#include "script/scripting_client.h"
7374
#include "hud.h"
@@ -647,6 +648,8 @@ struct ClientEventHandler
647648
THE GAME
648649
****************************************************************************/
649650

651+
using PausedNodesList = std::vector<std::pair<irr_ptr<scene::IAnimatedMeshSceneNode>, float>>;
652+
650653
/* This is not intended to be a public class. If a public class becomes
651654
* desirable then it may be better to create another 'wrapper' class that
652655
* hides most of the stuff in this class (nothing in this class is required
@@ -796,6 +799,9 @@ class Game {
796799
void showDeathFormspec();
797800
void showPauseMenu();
798801

802+
void pauseAnimation();
803+
void resumeAnimation();
804+
799805
// ClientEvent handlers
800806
void handleClientEvent_None(ClientEvent *event, CameraOrientation *cam);
801807
void handleClientEvent_PlayerDamage(ClientEvent *event, CameraOrientation *cam);
@@ -873,6 +879,7 @@ class Game {
873879
std::string *error_message;
874880
bool *reconnect_requested;
875881
scene::ISceneNode *skybox;
882+
PausedNodesList paused_animated_nodes;
876883

877884
bool simple_singleplayer_mode;
878885
/* End 'cache' */
@@ -2484,13 +2491,43 @@ inline void Game::step(f32 *dtime)
24842491
if (can_be_and_is_paused) { // This is for a singleplayer server
24852492
*dtime = 0; // No time passes
24862493
} else {
2494+
if (simple_singleplayer_mode && !paused_animated_nodes.empty())
2495+
resumeAnimation();
2496+
24872497
if (server)
24882498
server->step(*dtime);
24892499

24902500
client->step(*dtime);
24912501
}
24922502
}
24932503

2504+
static void pauseNodeAnimation(PausedNodesList &paused, scene::ISceneNode *node) {
2505+
if (!node)
2506+
return;
2507+
for (auto &&child: node->getChildren())
2508+
pauseNodeAnimation(paused, child);
2509+
if (node->getType() != scene::ESNT_ANIMATED_MESH)
2510+
return;
2511+
auto animated_node = static_cast<scene::IAnimatedMeshSceneNode *>(node);
2512+
float speed = animated_node->getAnimationSpeed();
2513+
if (!speed)
2514+
return;
2515+
paused.push_back({grab(animated_node), speed});
2516+
animated_node->setAnimationSpeed(0.0f);
2517+
}
2518+
2519+
void Game::pauseAnimation()
2520+
{
2521+
pauseNodeAnimation(paused_animated_nodes, smgr->getRootSceneNode());
2522+
}
2523+
2524+
void Game::resumeAnimation()
2525+
{
2526+
for (auto &&pair: paused_animated_nodes)
2527+
pair.first->setAnimationSpeed(pair.second);
2528+
paused_animated_nodes.clear();
2529+
}
2530+
24942531
const ClientEventHandler Game::clientEventHandler[CLIENTEVENT_MAX] = {
24952532
{&Game::handleClientEvent_None},
24962533
{&Game::handleClientEvent_PlayerDamage},
@@ -4230,6 +4267,9 @@ void Game::showPauseMenu()
42304267
fs_src, txt_dst, client->getFormspecPrepend(), sound);
42314268
formspec->setFocus("btn_continue");
42324269
formspec->doPause = true;
4270+
4271+
if (simple_singleplayer_mode)
4272+
pauseAnimation();
42334273
}
42344274

42354275
/****************************************************************************/

0 commit comments

Comments
 (0)