#include "actionmanager.hpp" #include #include #include #include "../mwbase/environment.hpp" #include "../mwbase/inputmanager.hpp" #include "../mwbase/luamanager.hpp" #include "../mwbase/mechanicsmanager.hpp" #include "../mwbase/statemanager.hpp" #include "../mwbase/windowmanager.hpp" #include "../mwbase/world.hpp" #include "../mwworld/class.hpp" #include "../mwworld/globals.hpp" #include "../mwworld/player.hpp" #include "../mwmechanics/actorutil.hpp" #include "../mwmechanics/npcstats.hpp" #include "actions.hpp" #include "bindingsmanager.hpp" namespace MWInput { ActionManager::ActionManager(BindingsManager* bindingsManager, osg::ref_ptr viewer, osg::ref_ptr screenCaptureHandler) : mBindingsManager(bindingsManager) , mViewer(std::move(viewer)) , mScreenCaptureHandler(std::move(screenCaptureHandler)) , mTimeIdle(0.f) { } void ActionManager::update(float dt) { if (mBindingsManager->actionIsActive(A_MoveForward) || mBindingsManager->actionIsActive(A_MoveBackward) || mBindingsManager->actionIsActive(A_MoveLeft) || mBindingsManager->actionIsActive(A_MoveRight) || mBindingsManager->actionIsActive(A_Jump) || mBindingsManager->actionIsActive(A_Sneak) || mBindingsManager->actionIsActive(A_TogglePOV) || mBindingsManager->actionIsActive(A_ZoomIn) || mBindingsManager->actionIsActive(A_ZoomOut)) { resetIdleTime(); } else mTimeIdle += dt; } void ActionManager::resetIdleTime() { mTimeIdle = 0.f; } void ActionManager::executeAction(int action) { MWBase::Environment::get().getLuaManager()->inputEvent({ MWBase::LuaManager::InputEvent::Action, action }); const auto inputManager = MWBase::Environment::get().getInputManager(); const auto windowManager = MWBase::Environment::get().getWindowManager(); // trigger action activated switch (action) { case A_GameMenu: toggleMainMenu(); break; case A_Screenshot: screenshot(); break; case A_Console: toggleConsole(); break; case A_Activate: inputManager->resetIdleTime(); activate(); break; case A_MoveLeft: case A_MoveRight: case A_MoveForward: case A_MoveBackward: handleGuiArrowKey(action); break; case A_Rest: rest(); break; case A_QuickKey1: quickKey(1); break; case A_QuickKey2: quickKey(2); break; case A_QuickKey3: quickKey(3); break; case A_QuickKey4: quickKey(4); break; case A_QuickKey5: quickKey(5); break; case A_QuickKey6: quickKey(6); break; case A_QuickKey7: quickKey(7); break; case A_QuickKey8: quickKey(8); break; case A_QuickKey9: quickKey(9); break; case A_QuickKey10: quickKey(10); break; case A_ToggleHUD: windowManager->setHudVisibility(!windowManager->isHudVisible()); break; case A_ToggleDebug: windowManager->toggleDebugWindow(); break; case A_TogglePostProcessorHUD: windowManager->togglePostProcessorHud(); break; case A_QuickSave: quickSave(); break; case A_QuickLoad: quickLoad(); break; case A_CycleSpellLeft: if (checkAllowedToUseItems() && windowManager->isAllowed(MWGui::GW_Magic)) MWBase::Environment::get().getWindowManager()->cycleSpell(false); break; case A_CycleSpellRight: if (checkAllowedToUseItems() && windowManager->isAllowed(MWGui::GW_Magic)) MWBase::Environment::get().getWindowManager()->cycleSpell(true); break; case A_CycleWeaponLeft: if (checkAllowedToUseItems() && windowManager->isAllowed(MWGui::GW_Inventory)) MWBase::Environment::get().getWindowManager()->cycleWeapon(false); break; case A_CycleWeaponRight: if (checkAllowedToUseItems() && windowManager->isAllowed(MWGui::GW_Inventory)) MWBase::Environment::get().getWindowManager()->cycleWeapon(true); break; case A_Inventory: case A_Journal: case A_QuickKeysMenu: // Handled in Lua break; } } bool ActionManager::checkAllowedToUseItems() const { MWWorld::Ptr player = MWMechanics::getPlayer(); if (player.getClass().getNpcStats(player).isWerewolf()) { // Cannot use items or spells while in werewolf form MWBase::Environment::get().getWindowManager()->messageBox("#{sWerewolfRefusal}"); return false; } return true; } void ActionManager::screenshot() { mScreenCaptureHandler->setFramesToCapture(1); mScreenCaptureHandler->captureNextFrame(*mViewer); } void ActionManager::toggleMainMenu() { if (MyGUI::InputManager::getInstance().isModalAny()) { MWBase::Environment::get().getWindowManager()->exitCurrentModal(); return; } if (MWBase::Environment::get().getWindowManager()->isConsoleMode()) { MWBase::Environment::get().getWindowManager()->toggleConsole(); return; } if (MWBase::Environment::get().getWindowManager()->isPostProcessorHudVisible()) { MWBase::Environment::get().getWindowManager()->togglePostProcessorHud(); return; } if (!MWBase::Environment::get().getWindowManager()->isGuiMode()) // No open GUIs, open up the MainMenu { MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_MainMenu); } else // Close current GUI { MWBase::Environment::get().getWindowManager()->exitCurrentGuiMode(); } } void ActionManager::quickLoad() { if (!MyGUI::InputManager::getInstance().isModalAny()) MWBase::Environment::get().getStateManager()->quickLoad(); } void ActionManager::quickSave() { if (!MyGUI::InputManager::getInstance().isModalAny()) MWBase::Environment::get().getStateManager()->quickSave(); } void ActionManager::rest() { if (!MWBase::Environment::get().getInputManager()->getControlSwitch("playercontrols")) return; if (!MWBase::Environment::get().getWindowManager()->getRestEnabled() || MWBase::Environment::get().getWindowManager()->isGuiMode()) return; MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_Rest); // Open rest GUI } void ActionManager::toggleConsole() { if (MyGUI::InputManager::getInstance().isModalAny()) return; MWBase::Environment::get().getWindowManager()->toggleConsole(); } void ActionManager::quickKey(int index) { if (!MWBase::Environment::get().getInputManager()->getControlSwitch("playercontrols") || !MWBase::Environment::get().getInputManager()->getControlSwitch("playerfighting") || !MWBase::Environment::get().getInputManager()->getControlSwitch("playermagic")) return; if (!checkAllowedToUseItems()) return; if (MWBase::Environment::get().getWorld()->getGlobalFloat(MWWorld::Globals::sCharGenState) != -1) return; if (!MWBase::Environment::get().getWindowManager()->isGuiMode()) MWBase::Environment::get().getWindowManager()->activateQuickKey(index); } void ActionManager::activate() { if (MWBase::Environment::get().getWindowManager()->isGuiMode()) { bool joystickUsed = MWBase::Environment::get().getInputManager()->joystickLastUsed(); if (!SDL_IsTextInputActive() && !mBindingsManager->isLeftOrRightButton(A_Activate, joystickUsed)) MWBase::Environment::get().getWindowManager()->injectKeyPress(MyGUI::KeyCode::Return, 0, false); } else if (MWBase::Environment::get().getInputManager()->getControlSwitch("playercontrols")) { MWWorld::Player& player = MWBase::Environment::get().getWorld()->getPlayer(); player.activate(); } } bool ActionManager::isSneaking() const { const MWBase::Environment& env = MWBase::Environment::get(); return env.getMechanicsManager()->isSneaking(env.getWorld()->getPlayer().getPlayer()); } void ActionManager::handleGuiArrowKey(int action) { bool joystickUsed = MWBase::Environment::get().getInputManager()->joystickLastUsed(); // This is currently keyboard-specific code // TODO: see if GUI controls can be refactored into a single function if (joystickUsed) return; if (SDL_IsTextInputActive()) return; if (mBindingsManager->isLeftOrRightButton(action, joystickUsed)) return; MyGUI::KeyCode key; switch (action) { case A_MoveLeft: key = MyGUI::KeyCode::ArrowLeft; break; case A_MoveRight: key = MyGUI::KeyCode::ArrowRight; break; case A_MoveForward: key = MyGUI::KeyCode::ArrowUp; break; case A_MoveBackward: default: key = MyGUI::KeyCode::ArrowDown; break; } MWBase::Environment::get().getWindowManager()->injectKeyPress(key, 0, false); } }