forked from Mirrorlandia_minetest/minetest
Pause animations while game is paused (#10658)
Pauses all mesh animations while game is paused.
This commit is contained in:
parent
cafad6ac03
commit
abb0c99a6c
@ -68,6 +68,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "util/pointedthing.h"
|
#include "util/pointedthing.h"
|
||||||
#include "util/quicktune_shortcutter.h"
|
#include "util/quicktune_shortcutter.h"
|
||||||
#include "irrlicht_changes/static_text.h"
|
#include "irrlicht_changes/static_text.h"
|
||||||
|
#include "irr_ptr.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
#include "script/scripting_client.h"
|
#include "script/scripting_client.h"
|
||||||
#include "hud.h"
|
#include "hud.h"
|
||||||
@ -647,6 +648,8 @@ struct ClientEventHandler
|
|||||||
THE GAME
|
THE GAME
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
using PausedNodesList = std::vector<std::pair<irr_ptr<scene::IAnimatedMeshSceneNode>, float>>;
|
||||||
|
|
||||||
/* This is not intended to be a public class. If a public class becomes
|
/* This is not intended to be a public class. If a public class becomes
|
||||||
* desirable then it may be better to create another 'wrapper' class that
|
* desirable then it may be better to create another 'wrapper' class that
|
||||||
* hides most of the stuff in this class (nothing in this class is required
|
* hides most of the stuff in this class (nothing in this class is required
|
||||||
@ -796,6 +799,9 @@ private:
|
|||||||
void showDeathFormspec();
|
void showDeathFormspec();
|
||||||
void showPauseMenu();
|
void showPauseMenu();
|
||||||
|
|
||||||
|
void pauseAnimation();
|
||||||
|
void resumeAnimation();
|
||||||
|
|
||||||
// ClientEvent handlers
|
// ClientEvent handlers
|
||||||
void handleClientEvent_None(ClientEvent *event, CameraOrientation *cam);
|
void handleClientEvent_None(ClientEvent *event, CameraOrientation *cam);
|
||||||
void handleClientEvent_PlayerDamage(ClientEvent *event, CameraOrientation *cam);
|
void handleClientEvent_PlayerDamage(ClientEvent *event, CameraOrientation *cam);
|
||||||
@ -873,6 +879,7 @@ private:
|
|||||||
std::string *error_message;
|
std::string *error_message;
|
||||||
bool *reconnect_requested;
|
bool *reconnect_requested;
|
||||||
scene::ISceneNode *skybox;
|
scene::ISceneNode *skybox;
|
||||||
|
PausedNodesList paused_animated_nodes;
|
||||||
|
|
||||||
bool simple_singleplayer_mode;
|
bool simple_singleplayer_mode;
|
||||||
/* End 'cache' */
|
/* End 'cache' */
|
||||||
@ -2484,6 +2491,9 @@ inline void Game::step(f32 *dtime)
|
|||||||
if (can_be_and_is_paused) { // This is for a singleplayer server
|
if (can_be_and_is_paused) { // This is for a singleplayer server
|
||||||
*dtime = 0; // No time passes
|
*dtime = 0; // No time passes
|
||||||
} else {
|
} else {
|
||||||
|
if (simple_singleplayer_mode && !paused_animated_nodes.empty())
|
||||||
|
resumeAnimation();
|
||||||
|
|
||||||
if (server)
|
if (server)
|
||||||
server->step(*dtime);
|
server->step(*dtime);
|
||||||
|
|
||||||
@ -2491,6 +2501,33 @@ inline void Game::step(f32 *dtime)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void pauseNodeAnimation(PausedNodesList &paused, scene::ISceneNode *node) {
|
||||||
|
if (!node)
|
||||||
|
return;
|
||||||
|
for (auto &&child: node->getChildren())
|
||||||
|
pauseNodeAnimation(paused, child);
|
||||||
|
if (node->getType() != scene::ESNT_ANIMATED_MESH)
|
||||||
|
return;
|
||||||
|
auto animated_node = static_cast<scene::IAnimatedMeshSceneNode *>(node);
|
||||||
|
float speed = animated_node->getAnimationSpeed();
|
||||||
|
if (!speed)
|
||||||
|
return;
|
||||||
|
paused.push_back({grab(animated_node), speed});
|
||||||
|
animated_node->setAnimationSpeed(0.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Game::pauseAnimation()
|
||||||
|
{
|
||||||
|
pauseNodeAnimation(paused_animated_nodes, smgr->getRootSceneNode());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Game::resumeAnimation()
|
||||||
|
{
|
||||||
|
for (auto &&pair: paused_animated_nodes)
|
||||||
|
pair.first->setAnimationSpeed(pair.second);
|
||||||
|
paused_animated_nodes.clear();
|
||||||
|
}
|
||||||
|
|
||||||
const ClientEventHandler Game::clientEventHandler[CLIENTEVENT_MAX] = {
|
const ClientEventHandler Game::clientEventHandler[CLIENTEVENT_MAX] = {
|
||||||
{&Game::handleClientEvent_None},
|
{&Game::handleClientEvent_None},
|
||||||
{&Game::handleClientEvent_PlayerDamage},
|
{&Game::handleClientEvent_PlayerDamage},
|
||||||
@ -4230,6 +4267,9 @@ void Game::showPauseMenu()
|
|||||||
fs_src, txt_dst, client->getFormspecPrepend(), sound);
|
fs_src, txt_dst, client->getFormspecPrepend(), sound);
|
||||||
formspec->setFocus("btn_continue");
|
formspec->setFocus("btn_continue");
|
||||||
formspec->doPause = true;
|
formspec->doPause = true;
|
||||||
|
|
||||||
|
if (simple_singleplayer_mode)
|
||||||
|
pauseAnimation();
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
|
Loading…
Reference in New Issue
Block a user