@@ -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+
24942531const 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