diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index f257b723ea..d9e19bead8 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -249,6 +249,9 @@ namespace MWBase ///< @return true if it is possible to place on object at specified cursor location virtual void processChangedSettings (const Settings::CategorySettingVector& settings) = 0; + + virtual bool isSwimming(const MWWorld::Ptr &object) = 0; + virtual bool isUnderwater(const ESM::Cell &cell, const Ogre::Vector3 &pos) = 0; }; } diff --git a/apps/openmw/mwinput/inputmanager.cpp b/apps/openmw/mwinput/inputmanager.cpp index 3a8315b71e..6bda77ea8e 100644 --- a/apps/openmw/mwinput/inputmanager.cpp +++ b/apps/openmw/mwinput/inputmanager.cpp @@ -90,6 +90,7 @@ namespace MWInput bool mDragDrop; + std::map mControlSwitch; /* InputImpl Methods */ public: @@ -339,6 +340,14 @@ private: poller.bind(A_Jump, KC_E); poller.bind(A_Crouch, KC_LCONTROL); + + mControlSwitch["playercontrols"] = true; + mControlSwitch["playerfighting"] = true; + mControlSwitch["playerjumping"] = true; + mControlSwitch["playerlooking"] = true; + mControlSwitch["playermagic"] = true; + mControlSwitch["playerviewswitch"] = true; + mControlSwitch["vanitymode"] = true; } void setDragDrop(bool dragDrop) @@ -366,33 +375,35 @@ private: // Configure player movement according to keyboard input. Actual movement will // be done in the physics system. - if (poller.isDown(A_MoveLeft)) - { - player.setAutoMove (false); - player.setLeftRight (1); - } - else if (poller.isDown(A_MoveRight)) - { - player.setAutoMove (false); - player.setLeftRight (-1); - } - else - player.setLeftRight (0); + if (mControlSwitch["playercontrols"]) { + if (poller.isDown(A_MoveLeft)) + { + player.setAutoMove (false); + player.setLeftRight (1); + } + else if (poller.isDown(A_MoveRight)) + { + player.setAutoMove (false); + player.setLeftRight (-1); + } + else + player.setLeftRight (0); - if (poller.isDown(A_MoveForward)) - { - player.setAutoMove (false); - player.setForwardBackward (1); + if (poller.isDown(A_MoveForward)) + { + player.setAutoMove (false); + player.setForwardBackward (1); + } + else if (poller.isDown(A_MoveBackward)) + { + player.setAutoMove (false); + player.setForwardBackward (-1); + } + else + player.setForwardBackward (0); } - else if (poller.isDown(A_MoveBackward)) - { - player.setAutoMove (false); - player.setForwardBackward (-1); - } - else - player.setForwardBackward (0); - if (poller.isDown(A_Jump)) + if (poller.isDown(A_Jump) && mControlSwitch["playerjumping"]) player.setUpDown (1); else if (poller.isDown(A_Crouch)) player.setUpDown (-1); @@ -423,6 +434,24 @@ private: guiEvents->enabled = false; } } + + void toggleControlSwitch(std::string sw, bool value) + { + if (mControlSwitch[sw] == value) { + return; + } + /// \note 7 switches at all, if-else is relevant + if (sw == "playercontrols") { + player.setLeftRight(0); + player.setForwardBackward(0); + player.setAutoMove(false); + } else if (sw == "playerjumping") { + /// \fixme maybe crouching at this time + player.setUpDown(0); + } + mControlSwitch[sw] = value; + } + }; /***CONSTRUCTOR***/ @@ -471,4 +500,9 @@ private: if (changeRes) impl->adjustMouseRegion(Settings::Manager::getInt("resolution x", "Video"), Settings::Manager::getInt("resolution y", "Video")); } + + void MWInputManager::toggleControlSwitch(std::string sw, bool value) + { + impl->toggleControlSwitch(sw, value); + } } diff --git a/apps/openmw/mwinput/inputmanager.hpp b/apps/openmw/mwinput/inputmanager.hpp index 4ef3df1371..2486f82d67 100644 --- a/apps/openmw/mwinput/inputmanager.hpp +++ b/apps/openmw/mwinput/inputmanager.hpp @@ -57,6 +57,8 @@ namespace MWInput void processChangedSettings(const Settings::CategorySettingVector& changed); void setDragDrop(bool dragDrop); + + void toggleControlSwitch(std::string sw, bool value); }; } #endif diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index a4b2e8489c..9eb08d77d7 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -273,11 +273,20 @@ void RenderingManager::update (float duration){ mLocalMap->updatePlayer( mRendering.getCamera()->getRealPosition(), mRendering.getCamera()->getRealOrientation() ); - checkUnderwater(); + if (mWater) { + Ogre::Vector3 cam = mRendering.getCamera()->getRealPosition(); - if (mWater) + MWBase::World *world = MWBase::Environment::get().getWorld(); + + mWater->updateUnderwater( + world->isUnderwater( + *world->getPlayer().getPlayer().getCell()->cell, + Ogre::Vector3(cam.x, -cam.z, cam.y)) + ); mWater->update(duration); + } } + void RenderingManager::waterAdded (MWWorld::Ptr::CellStore *store){ if(store->cell->data.flags & store->cell->HasWater || ((!(store->cell->data.flags & ESM::Cell::Interior)) @@ -457,13 +466,6 @@ void RenderingManager::toggleLight() setAmbientMode(); } -void RenderingManager::checkUnderwater() -{ - if(mWater) - { - mWater->checkUnderwater( mRendering.getCamera()->getRealPosition().y ); - } -} void RenderingManager::playAnimationGroup (const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number) diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index d6a372d102..12cbee9b87 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -91,7 +91,6 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList void scaleObject (const MWWorld::Ptr& ptr, const Ogre::Vector3& scale); void rotateObject (const MWWorld::Ptr& ptr, const::Ogre::Quaternion& orientation); - void checkUnderwater(); void setWaterHeight(const float height); void toggleWater(); diff --git a/apps/openmw/mwrender/water.cpp b/apps/openmw/mwrender/water.cpp index 92fc97b3b0..d5b93b7cbe 100644 --- a/apps/openmw/mwrender/water.cpp +++ b/apps/openmw/mwrender/water.cpp @@ -184,22 +184,16 @@ void Water::toggle() updateVisible(); } -void Water::checkUnderwater(float y) +void +Water::updateUnderwater(bool underwater) { - if (!mActive) - { + if (!mActive) { return; } - - if ((mIsUnderwater && y > mTop) || !mWater->isVisible() || mCamera->getPolygonMode() != Ogre::PM_SOLID) - { - mIsUnderwater = false; - } - - if (!mIsUnderwater && y < mTop && mWater->isVisible() && mCamera->getPolygonMode() == Ogre::PM_SOLID) - { - mIsUnderwater = true; - } + mIsUnderwater = + underwater && + mWater->isVisible() && + mCamera->getPolygonMode() == Ogre::PM_SOLID; updateVisible(); } diff --git a/apps/openmw/mwrender/water.hpp b/apps/openmw/mwrender/water.hpp index d0a5a43522..f56ba7410c 100644 --- a/apps/openmw/mwrender/water.hpp +++ b/apps/openmw/mwrender/water.hpp @@ -101,7 +101,8 @@ namespace MWRender { void processChangedSettings(const Settings::CategorySettingVector& settings); - void checkUnderwater(float y); + /// Updates underwater state accordingly + void updateUnderwater(bool underwater); void changeCell(const ESM::Cell* cell); void setHeight(const float height); diff --git a/apps/openmw/mwscript/controlextensions.cpp b/apps/openmw/mwscript/controlextensions.cpp index 24d8bcf1e6..084698c5b5 100644 --- a/apps/openmw/mwscript/controlextensions.cpp +++ b/apps/openmw/mwscript/controlextensions.cpp @@ -14,6 +14,8 @@ #include "../mwmechanics/npcstats.hpp" +#include "../mwinput/inputmanager.hpp" + #include "interpretercontext.hpp" #include "ref.hpp" @@ -36,6 +38,10 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { + MWBase::Environment::get() + .getInputManager() + ->toggleControlSwitch(mControl, mEnable); + if (mEnable) std::cout << "enable: " << mControl << std::endl; else diff --git a/apps/openmw/mwworld/player.cpp b/apps/openmw/mwworld/player.cpp index 4d508c3e9c..54e5a625fc 100644 --- a/apps/openmw/mwworld/player.cpp +++ b/apps/openmw/mwworld/player.cpp @@ -38,12 +38,6 @@ namespace MWWorld delete mClass; } - void Player::setPos(float x, float y, float z) - { - /// \todo This fcuntion should be removed during the mwrender-refactoring. - MWBase::Environment::get().getWorld()->moveObject (getPlayer(), x, y, z); - } - void Player::setRot(float x, float y, float z) { mRenderer->setRot(x, y, z); diff --git a/apps/openmw/mwworld/player.hpp b/apps/openmw/mwworld/player.hpp index ee7c030a51..d2058dea6c 100644 --- a/apps/openmw/mwworld/player.hpp +++ b/apps/openmw/mwworld/player.hpp @@ -42,9 +42,6 @@ namespace MWWorld ~Player(); - /// Set the player position. Uses Morrowind coordinates. - void setPos(float x, float y, float z); - /// Set where the player is looking at. Uses Morrowind (euler) angles void setRot(float x, float y, float z); diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index 13e5ecb85f..c768fce26d 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -135,23 +135,31 @@ namespace MWWorld } - void Scene::playerCellChange (Ptr::CellStore *cell, const ESM::Position& position, + void + Scene::playerCellChange( + MWWorld::CellStore *cell, + const ESM::Position& pos, bool adjustPlayerPos) { bool hasWater = cell->cell->data.flags & cell->cell->HasWater; mPhysics->setCurrentWater(hasWater, cell->cell->water); - if (adjustPlayerPos) - { - MWBase::Environment::get().getWorld()->getPlayer().setPos (position.pos[0], position.pos[1], position.pos[2]); - MWBase::Environment::get().getWorld()->getPlayer().setRot (position.rot[0], position.rot[1], position.rot[2]); + + MWBase::World *world = MWBase::Environment::get().getWorld(); + MWWorld::Ptr player = world->getPlayer().getPlayer(); + + if (adjustPlayerPos) { + world->moveObject(player, pos.pos[0], pos.pos[1], pos.pos[2]); + MWBase::Environment::get().getWorld()->getPlayer().setRot (pos.rot[0], pos.rot[1], pos.rot[2]); } + world->getPlayer().setCell(cell); - MWBase::Environment::get().getWorld()->getPlayer().setCell (cell); + MWMechanics::MechanicsManager *mechMgr = + MWBase::Environment::get().getMechanicsManager(); - MWBase::Environment::get().getMechanicsManager()->addActor (MWBase::Environment::get().getWorld()->getPlayer().getPlayer()); - MWBase::Environment::get().getMechanicsManager()->watchActor (MWBase::Environment::get().getWorld()->getPlayer().getPlayer()); + mechMgr->addActor(player); + mechMgr->watchActor(player); - MWBase::Environment::get().getWindowManager()->changeCell( mCurrentCell ); + MWBase::Environment::get().getWindowManager()->changeCell(mCurrentCell); } void Scene::changeCell (int X, int Y, const ESM::Position& position, bool adjustPlayerPos) diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index c1d7763ce8..203f5f9150 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1095,4 +1095,26 @@ namespace MWWorld { mRendering->getTriangleBatchCount(triangles, batches); } + + bool + World::isSwimming(const MWWorld::Ptr &object) + { + /// \todo add check ifActor() - only actors can swim + float *fpos = object.getRefData().getPosition().pos; + Ogre::Vector3 pos(fpos[0], fpos[1], fpos[2]); + + /// \fixme should rely on object height + pos.z += 30; + + return isUnderwater(*object.getCell()->cell, pos); + } + + bool + World::isUnderwater(const ESM::Cell &cell, const Ogre::Vector3 &pos) + { + if (cell.data.flags & ESM::Cell::HasWater == 0) { + return false; + } + return pos.z < cell.water; + } } diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index d39871c21d..f80b88be2c 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -270,6 +270,9 @@ namespace MWWorld ///< @return true if it is possible to place on object at specified cursor location virtual void processChangedSettings(const Settings::CategorySettingVector& settings); + + virtual bool isSwimming(const MWWorld::Ptr &object); + virtual bool isUnderwater(const ESM::Cell &cell, const Ogre::Vector3 &pos); }; }