diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index 20a27e5bc3..f268ed0e52 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -406,17 +406,16 @@ namespace MWBase virtual void enableActorCollision(const MWWorld::Ptr& actor, bool enable) = 0; - enum RestPermitted + enum RestFlags { - Rest_Allowed = 0, - Rest_OnlyWaiting = 1, + Rest_PlayerIsUnderwater = 1, Rest_PlayerIsInAir = 2, - Rest_PlayerIsUnderwater = 3, - Rest_EnemiesAreNearby = 4 + Rest_EnemiesAreNearby = 4, + Rest_CanSleep = 8, }; /// check if the player is allowed to rest - virtual RestPermitted canRest() const = 0; + virtual int canRest() const = 0; /// \todo Probably shouldn't be here virtual MWRender::Animation* getAnimation(const MWWorld::Ptr& ptr) = 0; diff --git a/apps/openmw/mwgui/waitdialog.cpp b/apps/openmw/mwgui/waitdialog.cpp index 568f05abc3..222a34e53b 100644 --- a/apps/openmw/mwgui/waitdialog.cpp +++ b/apps/openmw/mwgui/waitdialog.cpp @@ -84,15 +84,29 @@ namespace MWGui void WaitDialog::setPtr(const MWWorld::Ptr& ptr) { - setCanRest(!ptr.isEmpty() || MWBase::Environment::get().getWorld()->canRest() == MWBase::World::Rest_Allowed); + const int restFlags = MWBase::Environment::get().getWorld()->canRest(); - if (ptr.isEmpty() && MWBase::Environment::get().getWorld()->canRest() == MWBase::World::Rest_PlayerIsInAir) + const bool underwater = (restFlags & MWBase::World::Rest_PlayerIsUnderwater) != 0; + // Resting in air is allowed if you're using a bed + const bool inAir = ptr.isEmpty() && (restFlags & MWBase::World::Rest_PlayerIsInAir) != 0; + const bool enemiesNearby = (restFlags & MWBase::World::Rest_EnemiesAreNearby) != 0; + const bool solidGround = !underwater && !inAir; + + if (!solidGround || enemiesNearby) { - // Resting in air is not allowed unless you're using a bed - MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage1}"); - MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Rest); + if (!solidGround) + MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage1}"); + + if (enemiesNearby) + MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage2}"); + + MWBase::Environment::get().getWindowManager()->popGuiMode(); + return; } + const bool canSleep = !ptr.isEmpty() || (restFlags & MWBase::World::Rest_CanSleep) != 0; + setCanRest(canSleep); + if (mUntilHealedButton->getVisible()) MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mUntilHealedButton); else @@ -138,20 +152,6 @@ namespace MWGui MWBase::Environment::get().getWindowManager()->popGuiMode(); } - MWBase::World::RestPermitted canRest = MWBase::Environment::get().getWorld()->canRest(); - - if (canRest == MWBase::World::Rest_EnemiesAreNearby) - { - MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage2}"); - MWBase::Environment::get().getWindowManager()->popGuiMode(); - } - else if (canRest == MWBase::World::Rest_PlayerIsUnderwater) - { - // resting underwater not allowed - MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage1}"); - MWBase::Environment::get().getWindowManager()->popGuiMode(); - } - onHourSliderChangedPosition(mHourSlider, 0); mHourSlider->setScrollPosition(0); diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index c642d14b16..f608b8c781 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -2333,34 +2333,35 @@ namespace MWWorld Log(Debug::Warning) << "Player agent bounds are not supported by navigator: " << agentBounds; } - World::RestPermitted World::canRest() const + int World::canRest() const { + int result = 0; + CellStore* currentCell = mWorldScene->getCurrentCell(); Ptr player = mPlayer->getPlayer(); - RefData& refdata = player.getRefData(); - osg::Vec3f playerPos(refdata.getPosition().asVec3()); const MWPhysics::Actor* actor = mPhysics->getActor(player); if (!actor) throw std::runtime_error("can't find player"); - if (mPlayer->enemiesNearby()) - return Rest_EnemiesAreNearby; - + const osg::Vec3f playerPos(player.getRefData().getPosition().asVec3()); if (isUnderwater(currentCell, playerPos) || isWalkingOnWater(player)) - return Rest_PlayerIsUnderwater; + result |= Rest_PlayerIsUnderwater; float fallHeight = player.getClass().getCreatureStats(player).getFallHeight(); float epsilon = 1e-4; if ((actor->getCollisionMode() && (!mPhysics->isOnSolidGround(player) || fallHeight >= epsilon)) || isFlying(player)) - return Rest_PlayerIsInAir; + result |= Rest_PlayerIsInAir; - if (currentCell->getCell()->noSleep() || player.getClass().getNpcStats(player).isWerewolf()) - return Rest_OnlyWaiting; + if (mPlayer->enemiesNearby()) + result |= Rest_EnemiesAreNearby; - return Rest_Allowed; + if (!currentCell->getCell()->noSleep() && !player.getClass().getNpcStats(player).isWerewolf()) + result |= Rest_CanSleep; + + return result; } MWRender::Animation* World::getAnimation(const MWWorld::Ptr& ptr) diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 983682a98f..b1286d5532 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -505,7 +505,7 @@ namespace MWWorld void enableActorCollision(const MWWorld::Ptr& actor, bool enable) override; - RestPermitted canRest() const override; + int canRest() const override; ///< check if the player is allowed to rest void rest(double hours) override;