From 13b7c5b5196ae4e57cec6a587982714b25f3c1a1 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Thu, 16 Apr 2020 16:36:32 +0400 Subject: [PATCH] Rework actions update --- apps/openmw/mwinput/actionmanager.cpp | 154 ++++++++++++++++++++++ apps/openmw/mwinput/actionmanager.hpp | 17 +++ apps/openmw/mwinput/controllermanager.cpp | 10 +- apps/openmw/mwinput/controllermanager.hpp | 2 +- apps/openmw/mwinput/inputmanagerimp.cpp | 108 ++------------- apps/openmw/mwinput/inputmanagerimp.hpp | 10 -- apps/openmw/mwinput/keyboardmanager.cpp | 63 +-------- apps/openmw/mwinput/keyboardmanager.hpp | 2 +- apps/openmw/mwinput/mousemanager.cpp | 8 +- apps/openmw/mwinput/mousemanager.hpp | 2 +- apps/openmw/mwinput/sensormanager.cpp | 13 +- apps/openmw/mwinput/sensormanager.hpp | 2 +- 12 files changed, 200 insertions(+), 191 deletions(-) diff --git a/apps/openmw/mwinput/actionmanager.cpp b/apps/openmw/mwinput/actionmanager.cpp index 22c7d96a6..2240e7556 100644 --- a/apps/openmw/mwinput/actionmanager.cpp +++ b/apps/openmw/mwinput/actionmanager.cpp @@ -40,9 +40,163 @@ namespace MWInput , mScreenCaptureOperation(screenCaptureOperation) , mAlwaysRunActive(Settings::Manager::getBool("always run", "Input")) , mSneaking(false) + , mAttemptJump(false) + , mOverencumberedMessageDelay(0.f) + , mPreviewPOVDelay(0.f) + , mTimeIdle(0.f) { } + void ActionManager::update(float dt, bool triedToMove) + { + // Disable movement in Gui mode + if (MWBase::Environment::get().getWindowManager()->isGuiMode() + || MWBase::Environment::get().getStateManager()->getState() != MWBase::StateManager::State_Running) + { + mAttemptJump = false; + return; + } + + // Configure player movement according to keyboard input. Actual movement will + // be done in the physics system. + if (MWBase::Environment::get().getInputManager()->getControlSwitch("playercontrols")) + { + bool alwaysRunAllowed = false; + + MWWorld::Player& player = MWBase::Environment::get().getWorld()->getPlayer(); + + if (actionIsActive(A_MoveLeft) != actionIsActive(A_MoveRight)) + { + alwaysRunAllowed = true; + triedToMove = true; + player.setLeftRight (actionIsActive(A_MoveRight) ? 1 : -1); + } + + if (actionIsActive(A_MoveForward) != actionIsActive(A_MoveBackward)) + { + alwaysRunAllowed = true; + triedToMove = true; + player.setAutoMove (false); + player.setForwardBackward (actionIsActive(A_MoveForward) ? 1 : -1); + } + + if (player.getAutoMove()) + { + alwaysRunAllowed = true; + triedToMove = true; + player.setForwardBackward (1); + } + + if (mAttemptJump && MWBase::Environment::get().getInputManager()->getControlSwitch("playerjumping")) + { + player.setUpDown(1); + triedToMove = true; + mOverencumberedMessageDelay = 0.f; + } + + // if player tried to start moving, but can't (due to being overencumbered), display a notification. + if (triedToMove) + { + MWWorld::Ptr playerPtr = MWBase::Environment::get().getWorld ()->getPlayerPtr(); + mOverencumberedMessageDelay -= dt; + if (playerPtr.getClass().getEncumbrance(playerPtr) > playerPtr.getClass().getCapacity(playerPtr)) + { + player.setAutoMove (false); + if (mOverencumberedMessageDelay <= 0) + { + MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage59}"); + mOverencumberedMessageDelay = 1.0; + } + } + } + + if (MWBase::Environment::get().getInputManager()->getControlSwitch("playerviewswitch")) + { + if (actionIsActive(A_TogglePOV)) + { + if (mPreviewPOVDelay <= 0.5 && + (mPreviewPOVDelay += dt) > 0.5) + { + mPreviewPOVDelay = 1.f; + MWBase::Environment::get().getWorld()->togglePreviewMode(true); + } + } + else + { + //disable preview mode + MWBase::Environment::get().getWorld()->togglePreviewMode(false); + if (mPreviewPOVDelay > 0.f && mPreviewPOVDelay <= 0.5) + { + MWBase::Environment::get().getWorld()->togglePOV(); + } + mPreviewPOVDelay = 0.f; + } + } + + if (triedToMove) + MWBase::Environment::get().getInputManager()->resetIdleTime(); + + static const bool isToggleSneak = Settings::Manager::getBool("toggle sneak", "Input"); + if (!isToggleSneak) + { + if(!MWBase::Environment::get().getInputManager()->joystickLastUsed()) + player.setSneak(actionIsActive(A_Sneak)); + } + + float xAxis = mInputBinder->getChannel(A_MoveLeftRight)->getValue(); + float yAxis = mInputBinder->getChannel(A_MoveForwardBackward)->getValue(); + bool isRunning = xAxis > .75 || xAxis < .25 || yAxis > .75 || yAxis < .25; + if ((mAlwaysRunActive && alwaysRunAllowed) || isRunning) + player.setRunState(!actionIsActive(A_Run)); + else + player.setRunState(actionIsActive(A_Run)); + } + + if (actionIsActive(A_MoveForward) || + actionIsActive(A_MoveBackward) || + actionIsActive(A_MoveLeft) || + actionIsActive(A_MoveRight) || + actionIsActive(A_Jump) || + actionIsActive(A_Sneak) || + actionIsActive(A_TogglePOV) || + actionIsActive(A_ZoomIn) || + actionIsActive(A_ZoomOut)) + { + resetIdleTime(); + } + else + { + updateIdleTime(dt); + } + + mAttemptJump = false; + } + + void ActionManager::resetIdleTime() + { + if (mTimeIdle < 0) + MWBase::Environment::get().getWorld()->toggleVanityMode(false); + mTimeIdle = 0.f; + } + + void ActionManager::updateIdleTime(float dt) + { + static const float vanityDelay = MWBase::Environment::get().getWorld()->getStore().get() + .find("fVanityDelay")->mValue.getFloat(); + if (mTimeIdle >= 0.f) + mTimeIdle += dt; + if (mTimeIdle > vanityDelay) + { + MWBase::Environment::get().getWorld()->toggleVanityMode(true); + mTimeIdle = -1.f; + } + } + + bool ActionManager::actionIsActive(int id) + { + return (mInputBinder->getChannel(id)->getValue ()==1.0); + } + void ActionManager::executeAction(int action) { // trigger action activated diff --git a/apps/openmw/mwinput/actionmanager.hpp b/apps/openmw/mwinput/actionmanager.hpp index 7c1fe3f70..399cb318c 100644 --- a/apps/openmw/mwinput/actionmanager.hpp +++ b/apps/openmw/mwinput/actionmanager.hpp @@ -28,6 +28,8 @@ namespace MWInput void clear(); + void update(float dt, bool triedToMove); + void executeAction(int action); bool checkAllowedToUseItems() const; @@ -50,12 +52,22 @@ namespace MWInput void quickKey (int index); void showQuickKeysMenu(); + void resetIdleTime(); + bool isAlwaysRunActive() const { return mAlwaysRunActive; }; bool isSneaking() const { return mSneaking; }; + void setAttemptJump(bool enabled) { mAttemptJump = enabled; } + + float getPreviewDelay() const { return mPreviewPOVDelay; }; + private: void handleGuiArrowKey(int action); + bool actionIsActive(int id); + + void updateIdleTime(float dt); + ICS::InputControlSystem* mInputBinder; osg::ref_ptr mViewer; osg::ref_ptr mScreenCaptureHandler; @@ -63,6 +75,11 @@ namespace MWInput bool mAlwaysRunActive; bool mSneaking; + bool mAttemptJump; + + float mOverencumberedMessageDelay; + float mPreviewPOVDelay; + float mTimeIdle; }; } #endif diff --git a/apps/openmw/mwinput/controllermanager.cpp b/apps/openmw/mwinput/controllermanager.cpp index 209800bd6..697d3ab91 100644 --- a/apps/openmw/mwinput/controllermanager.cpp +++ b/apps/openmw/mwinput/controllermanager.cpp @@ -94,10 +94,10 @@ namespace MWInput return (mInputBinder->getChannel (id)->getValue ()==1.0); } - bool ControllerManager::update(float dt, bool disableControls, bool gamepadPreviewMode) + bool ControllerManager::update(float dt, bool disableControls) { mControlsDisabled = disableControls; - mGamepadPreviewMode = gamepadPreviewMode; + mGamepadPreviewMode = mActionManager->getPreviewDelay() == 1.f; if (mGuiCursorEnabled && !(mJoystickLastUsed && !mGamepadGuiCursorEnabled)) { @@ -153,10 +153,10 @@ namespace MWInput } if (triedToMove) + { mJoystickLastUsed = true; - - if (triedToMove) MWBase::Environment::get().getInputManager()->resetIdleTime(); + } static const bool isToggleSneak = Settings::Manager::getBool("toggle sneak", "Input"); if (!isToggleSneak) @@ -208,7 +208,7 @@ namespace MWInput return triedToMove; } - void ControllerManager::buttonPressed(int deviceID, const SDL_ControllerButtonEvent &arg ) + void ControllerManager::buttonPressed(int deviceID, const SDL_ControllerButtonEvent &arg) { if (!mJoystickEnabled || mInputBinder->detectingBindingState()) return; diff --git a/apps/openmw/mwinput/controllermanager.hpp b/apps/openmw/mwinput/controllermanager.hpp index 77b68be54..1ab6ea76d 100644 --- a/apps/openmw/mwinput/controllermanager.hpp +++ b/apps/openmw/mwinput/controllermanager.hpp @@ -31,7 +31,7 @@ namespace MWInput void clear(); - bool update(float dt, bool disableControls, bool gamepadPreviewMode); + bool update(float dt, bool disableControls); virtual void buttonPressed(int deviceID, const SDL_ControllerButtonEvent &arg); virtual void buttonReleased(int deviceID, const SDL_ControllerButtonEvent &arg); diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index d176ba480..815283ba8 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -46,17 +46,12 @@ namespace MWInput osgViewer::ScreenCaptureHandler::CaptureOperation *screenCaptureOperation, const std::string& userFile, bool userFileExists, const std::string& userControllerBindingsFile, const std::string& controllerBindingsFile, bool grab) - : mWindow(window) - , mWindowVisible(true) + : mWindowVisible(true) , mUserFile(userFile) , mDragDrop(false) - , mGrabCursor (Settings::Manager::getBool("grab cursor", "Input")) - , mPreviewPOVDelay(0.f) - , mTimeIdle(0.f) + , mGrabCursor(Settings::Manager::getBool("grab cursor", "Input")) , mGuiCursorEnabled(true) , mDetectingKeyboard(false) - , mOverencumberedMessageDelay(0.f) - , mAttemptJump(false) , mFakeDeviceID(1) { mInputWrapper = new SDLUtil::InputWrapper(window, viewer, grab); @@ -204,7 +199,7 @@ namespace MWInput action = A_CycleSpellLeft; else - mAttemptJump = (currentValue == 1.0 && previousValue == 0.0); + mActionManager->setAttemptJump(currentValue == 1.0 && previousValue == 0.0); } } @@ -252,82 +247,11 @@ namespace MWInput updateCursorMode(); - bool controllerMove = mControllerManager->update(dt, disableControls, mPreviewPOVDelay == 1.f); - bool keyboardMove = mKeyboardManager->update(dt, disableControls); - - if (mMouseManager->update(dt, disableControls)) - resetIdleTime(); - - if (mSensorManager->update(dt, mGuiCursorEnabled, mControlSwitch["playerlooking"])) - resetIdleTime(); - - // Disable movement in Gui mode - if (!(MWBase::Environment::get().getWindowManager()->isGuiMode() - || MWBase::Environment::get().getStateManager()->getState() != MWBase::StateManager::State_Running)) - { - if (mControlSwitch["playercontrols"]) - { - MWWorld::Player& player = MWBase::Environment::get().getWorld()->getPlayer(); - - bool attemptToJump = false; - if (mAttemptJump && mControlSwitch["playerjumping"]) - { - player.setUpDown(1); - attemptToJump = true; - mOverencumberedMessageDelay = 0.f; - } - - // if player tried to start moving, but can't (due to being overencumbered), display a notification. - if (controllerMove || keyboardMove || attemptToJump) - { - MWWorld::Ptr playerPtr = MWBase::Environment::get().getWorld ()->getPlayerPtr(); - mOverencumberedMessageDelay -= dt; - if (playerPtr.getClass().getEncumbrance(playerPtr) > playerPtr.getClass().getCapacity(playerPtr)) - { - player.setAutoMove (false); - if (mOverencumberedMessageDelay <= 0) - { - MWBase::Environment::get().getWindowManager ()->messageBox("#{sNotifyMessage59}"); - mOverencumberedMessageDelay = 1.0; - } - } - } - - if (mControlSwitch["playerviewswitch"]) { - - if (actionIsActive(A_TogglePOV)) { - if (mPreviewPOVDelay <= 0.5 && - (mPreviewPOVDelay += dt) > 0.5) - { - mPreviewPOVDelay = 1.f; - MWBase::Environment::get().getWorld()->togglePreviewMode(true); - } - } else { - //disable preview mode - MWBase::Environment::get().getWorld()->togglePreviewMode(false); - if (mPreviewPOVDelay > 0.f && mPreviewPOVDelay <= 0.5) { - MWBase::Environment::get().getWorld()->togglePOV(); - } - mPreviewPOVDelay = 0.f; - } - } - } - if (actionIsActive(A_MoveForward) || - actionIsActive(A_MoveBackward) || - actionIsActive(A_MoveLeft) || - actionIsActive(A_MoveRight) || - actionIsActive(A_Jump) || - actionIsActive(A_Sneak) || - actionIsActive(A_TogglePOV) || - actionIsActive(A_ZoomIn) || - actionIsActive(A_ZoomOut) ) - { - resetIdleTime(); - } else { - updateIdleTime(dt); - } - } - mAttemptJump = false; // Can only jump on first frame input is on + bool controllerMove = mControllerManager->update(dt, disableControls); + mKeyboardManager->update(dt, disableControls); + mMouseManager->update(dt, disableControls); + mSensorManager->update(dt, mGuiCursorEnabled); + mActionManager->update(dt, controllerMove); } void InputManager::setDragDrop(bool dragDrop) @@ -453,21 +377,7 @@ namespace MWInput void InputManager::resetIdleTime() { - if (mTimeIdle < 0) - MWBase::Environment::get().getWorld()->toggleVanityMode(false); - mTimeIdle = 0.f; - } - - void InputManager::updateIdleTime(float dt) - { - static const float vanityDelay = MWBase::Environment::get().getWorld()->getStore().get() - .find("fVanityDelay")->mValue.getFloat(); - if (mTimeIdle >= 0.f) - mTimeIdle += dt; - if (mTimeIdle > vanityDelay) { - MWBase::Environment::get().getWorld()->toggleVanityMode(true); - mTimeIdle = -1.f; - } + mActionManager->resetIdleTime(); } bool InputManager::actionIsActive (int id) diff --git a/apps/openmw/mwinput/inputmanagerimp.hpp b/apps/openmw/mwinput/inputmanagerimp.hpp index ff0c43a82..fc01fecab 100644 --- a/apps/openmw/mwinput/inputmanagerimp.hpp +++ b/apps/openmw/mwinput/inputmanagerimp.hpp @@ -146,7 +146,6 @@ namespace MWInput virtual void resetIdleTime(); private: - SDL_Window* mWindow; bool mWindowVisible; ICS::InputControlSystem* mInputBinder; @@ -160,17 +159,10 @@ namespace MWInput bool mGrabCursor; - float mPreviewPOVDelay; - float mTimeIdle; - bool mGuiCursorEnabled; bool mDetectingKeyboard; - float mOverencumberedMessageDelay; - - bool mAttemptJump; - std::map mControlSwitch; ActionManager* mActionManager; @@ -181,8 +173,6 @@ namespace MWInput void convertMousePosForMyGUI(int& x, int& y); - void updateIdleTime(float dt); - void handleGuiArrowKey(int action); void updateCursorMode(); diff --git a/apps/openmw/mwinput/keyboardmanager.cpp b/apps/openmw/mwinput/keyboardmanager.cpp index f56246716..d043f8137 100644 --- a/apps/openmw/mwinput/keyboardmanager.cpp +++ b/apps/openmw/mwinput/keyboardmanager.cpp @@ -27,70 +27,9 @@ namespace MWInput { } - bool KeyboardManager::update(float dt, bool disableControls) + void KeyboardManager::update(float dt, bool disableControls) { mControlsDisabled = disableControls; - - // Disable movement in Gui mode - if (MWBase::Environment::get().getWindowManager()->isGuiMode() - || MWBase::Environment::get().getStateManager()->getState() != MWBase::StateManager::State_Running) - { - return false; - } - - // Configure player movement according to keyboard input. Actual movement will - // be done in the physics system. - if (!MWBase::Environment::get().getInputManager()->getControlSwitch("playercontrols")) - { - return false; - } - - bool triedToMove = false; - bool alwaysRunAllowed = false; - - MWWorld::Player& player = MWBase::Environment::get().getWorld()->getPlayer(); - - if (actionIsActive(A_MoveLeft) != actionIsActive(A_MoveRight)) - { - alwaysRunAllowed = true; - triedToMove = true; - player.setLeftRight (actionIsActive(A_MoveRight) ? 1 : -1); - } - - if (actionIsActive(A_MoveForward) != actionIsActive(A_MoveBackward)) - { - alwaysRunAllowed = true; - triedToMove = true; - player.setAutoMove (false); - player.setForwardBackward (actionIsActive(A_MoveForward) ? 1 : -1); - } - - if (player.getAutoMove()) - { - alwaysRunAllowed = true; - triedToMove = true; - player.setForwardBackward (1); - } - - if (triedToMove) - MWBase::Environment::get().getInputManager()->resetIdleTime(); - - static const bool isToggleSneak = Settings::Manager::getBool("toggle sneak", "Input"); - if (!isToggleSneak) - { - if(!MWBase::Environment::get().getInputManager()->joystickLastUsed()) - player.setSneak(actionIsActive(A_Sneak)); - } - - float xAxis = mInputBinder->getChannel(A_MoveLeftRight)->getValue(); - float yAxis = mInputBinder->getChannel(A_MoveForwardBackward)->getValue(); - bool isRunning = xAxis > .75 || xAxis < .25 || yAxis > .75 || yAxis < .25; - if ((mActionManager->isAlwaysRunActive() && alwaysRunAllowed) || isRunning) - player.setRunState(!actionIsActive(A_Run)); - else - player.setRunState(actionIsActive(A_Run)); - - return triedToMove; } bool KeyboardManager::actionIsActive (int id) diff --git a/apps/openmw/mwinput/keyboardmanager.hpp b/apps/openmw/mwinput/keyboardmanager.hpp index 590241bc7..55b91bac4 100644 --- a/apps/openmw/mwinput/keyboardmanager.hpp +++ b/apps/openmw/mwinput/keyboardmanager.hpp @@ -25,7 +25,7 @@ namespace MWInput virtual ~KeyboardManager() = default; - bool update(float dt, bool disableControls); + void update(float dt, bool disableControls); virtual void textInput(const SDL_TextInputEvent &arg); virtual void keyPressed(const SDL_KeyboardEvent &arg); diff --git a/apps/openmw/mwinput/mousemanager.cpp b/apps/openmw/mwinput/mousemanager.cpp index b34124773..3fbfc7813 100644 --- a/apps/openmw/mwinput/mousemanager.cpp +++ b/apps/openmw/mwinput/mousemanager.cpp @@ -173,17 +173,17 @@ namespace MWInput mInputBinder->mousePressed (arg, id); } - bool MouseManager::update(float dt, bool disableControls) + void MouseManager::update(float dt, bool disableControls) { mControlsDisabled = disableControls; if (!mMouseLookEnabled) - return false; + return; float xAxis = mInputBinder->getChannel(A_LookLeftRight)->getValue()*2.0f-1.0f; float yAxis = mInputBinder->getChannel(A_LookUpDown)->getValue()*2.0f-1.0f; if (xAxis == 0 && yAxis == 0) - return false; + return; float rot[3]; rot[0] = yAxis * (dt * 100.0f) * 10.0f * mCameraSensitivity * (1.0f/256.f) * (mInvertY ? -1 : 1) * mCameraYMultiplier; @@ -198,7 +198,7 @@ namespace MWInput player.pitch(rot[0]); } - return true; + MWBase::Environment::get().getInputManager()->resetIdleTime(); } bool MouseManager::injectMouseButtonPress(Uint8 button) diff --git a/apps/openmw/mwinput/mousemanager.hpp b/apps/openmw/mwinput/mousemanager.hpp index f4517da47..6e59a639b 100644 --- a/apps/openmw/mwinput/mousemanager.hpp +++ b/apps/openmw/mwinput/mousemanager.hpp @@ -30,7 +30,7 @@ namespace MWInput void clear(); - bool update(float dt, bool disableControls); + void update(float dt, bool disableControls); virtual void mouseMoved(const SDLUtil::MouseMotionEvent &arg); virtual void mousePressed(const SDL_MouseButtonEvent &arg, Uint8 id); diff --git a/apps/openmw/mwinput/sensormanager.cpp b/apps/openmw/mwinput/sensormanager.cpp index 55a0882f5..27879d214 100644 --- a/apps/openmw/mwinput/sensormanager.cpp +++ b/apps/openmw/mwinput/sensormanager.cpp @@ -3,6 +3,7 @@ #include #include "../mwbase/environment.hpp" +#include "../mwbase/inputmanager.hpp" #include "../mwbase/world.hpp" #include "../mwworld/player.hpp" @@ -234,10 +235,10 @@ namespace MWInput } } - bool SensorManager::update(float dt, bool isCursorEnabled, bool isTurningEnabled) + void SensorManager::update(float dt, bool isCursorEnabled) { if (mGyroXSpeed == 0.f && mGyroYSpeed == 0.f) - return false; + return; if (mGyroUpdateTimer > 0.5f) { @@ -246,7 +247,7 @@ namespace MWInput // Reset current rotation speed and wait for update. clear(); mGyroUpdateTimer = 0.f; - return false; + return; } mGyroUpdateTimer += dt; @@ -259,16 +260,14 @@ namespace MWInput rot[2] = mGyroXSpeed * dt * mGyroHSensitivity * 4 * (mInvertX ? -1 : 1); // Only actually turn player when we're not in vanity mode - if(!MWBase::Environment::get().getWorld()->vanityRotateCamera(rot) && isTurningEnabled) + if(!MWBase::Environment::get().getWorld()->vanityRotateCamera(rot) && MWBase::Environment::get().getInputManager()->getControlSwitch("playerlooking")) { MWWorld::Player& player = MWBase::Environment::get().getWorld()->getPlayer(); player.yaw(rot[2]); player.pitch(rot[0]); } - return true; + MWBase::Environment::get().getInputManager()->resetIdleTime(); } - - return false; } } diff --git a/apps/openmw/mwinput/sensormanager.hpp b/apps/openmw/mwinput/sensormanager.hpp index 51225e381..283a53c1f 100644 --- a/apps/openmw/mwinput/sensormanager.hpp +++ b/apps/openmw/mwinput/sensormanager.hpp @@ -29,7 +29,7 @@ namespace MWInput void clear(); - bool update(float dt, bool isCursorEnabled, bool isTurningEnabled); + void update(float dt, bool isCursorEnabled); virtual void sensorUpdated(const SDL_SensorEvent &arg); virtual void displayOrientationChanged();