mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-09-17 00:22:24 -04:00
Merge branch 'reststates' into 'master'
Inform the player about both resting hindrances (#8408) Closes #8408 See merge request OpenMW/openmw!4598
This commit is contained in:
commit
9013ed16f0
@ -406,17 +406,16 @@ namespace MWBase
|
|||||||
|
|
||||||
virtual void enableActorCollision(const MWWorld::Ptr& actor, bool enable) = 0;
|
virtual void enableActorCollision(const MWWorld::Ptr& actor, bool enable) = 0;
|
||||||
|
|
||||||
enum RestPermitted
|
enum RestFlags
|
||||||
{
|
{
|
||||||
Rest_Allowed = 0,
|
Rest_PlayerIsUnderwater = 1,
|
||||||
Rest_OnlyWaiting = 1,
|
|
||||||
Rest_PlayerIsInAir = 2,
|
Rest_PlayerIsInAir = 2,
|
||||||
Rest_PlayerIsUnderwater = 3,
|
Rest_EnemiesAreNearby = 4,
|
||||||
Rest_EnemiesAreNearby = 4
|
Rest_CanSleep = 8,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// check if the player is allowed to rest
|
/// check if the player is allowed to rest
|
||||||
virtual RestPermitted canRest() const = 0;
|
virtual int canRest() const = 0;
|
||||||
|
|
||||||
/// \todo Probably shouldn't be here
|
/// \todo Probably shouldn't be here
|
||||||
virtual MWRender::Animation* getAnimation(const MWWorld::Ptr& ptr) = 0;
|
virtual MWRender::Animation* getAnimation(const MWWorld::Ptr& ptr) = 0;
|
||||||
|
@ -84,15 +84,29 @@ namespace MWGui
|
|||||||
|
|
||||||
void WaitDialog::setPtr(const MWWorld::Ptr& ptr)
|
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
|
if (!solidGround)
|
||||||
MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage1}");
|
MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage1}");
|
||||||
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Rest);
|
|
||||||
|
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())
|
if (mUntilHealedButton->getVisible())
|
||||||
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mUntilHealedButton);
|
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mUntilHealedButton);
|
||||||
else
|
else
|
||||||
@ -138,20 +152,6 @@ namespace MWGui
|
|||||||
MWBase::Environment::get().getWindowManager()->popGuiMode();
|
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);
|
onHourSliderChangedPosition(mHourSlider, 0);
|
||||||
mHourSlider->setScrollPosition(0);
|
mHourSlider->setScrollPosition(0);
|
||||||
|
|
||||||
|
@ -2333,34 +2333,35 @@ namespace MWWorld
|
|||||||
Log(Debug::Warning) << "Player agent bounds are not supported by navigator: " << agentBounds;
|
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();
|
CellStore* currentCell = mWorldScene->getCurrentCell();
|
||||||
|
|
||||||
Ptr player = mPlayer->getPlayer();
|
Ptr player = mPlayer->getPlayer();
|
||||||
RefData& refdata = player.getRefData();
|
|
||||||
osg::Vec3f playerPos(refdata.getPosition().asVec3());
|
|
||||||
|
|
||||||
const MWPhysics::Actor* actor = mPhysics->getActor(player);
|
const MWPhysics::Actor* actor = mPhysics->getActor(player);
|
||||||
if (!actor)
|
if (!actor)
|
||||||
throw std::runtime_error("can't find player");
|
throw std::runtime_error("can't find player");
|
||||||
|
|
||||||
if (mPlayer->enemiesNearby())
|
const osg::Vec3f playerPos(player.getRefData().getPosition().asVec3());
|
||||||
return Rest_EnemiesAreNearby;
|
|
||||||
|
|
||||||
if (isUnderwater(currentCell, playerPos) || isWalkingOnWater(player))
|
if (isUnderwater(currentCell, playerPos) || isWalkingOnWater(player))
|
||||||
return Rest_PlayerIsUnderwater;
|
result |= Rest_PlayerIsUnderwater;
|
||||||
|
|
||||||
float fallHeight = player.getClass().getCreatureStats(player).getFallHeight();
|
float fallHeight = player.getClass().getCreatureStats(player).getFallHeight();
|
||||||
float epsilon = 1e-4;
|
float epsilon = 1e-4;
|
||||||
if ((actor->getCollisionMode() && (!mPhysics->isOnSolidGround(player) || fallHeight >= epsilon))
|
if ((actor->getCollisionMode() && (!mPhysics->isOnSolidGround(player) || fallHeight >= epsilon))
|
||||||
|| isFlying(player))
|
|| isFlying(player))
|
||||||
return Rest_PlayerIsInAir;
|
result |= Rest_PlayerIsInAir;
|
||||||
|
|
||||||
if (currentCell->getCell()->noSleep() || player.getClass().getNpcStats(player).isWerewolf())
|
if (mPlayer->enemiesNearby())
|
||||||
return Rest_OnlyWaiting;
|
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)
|
MWRender::Animation* World::getAnimation(const MWWorld::Ptr& ptr)
|
||||||
|
@ -505,7 +505,7 @@ namespace MWWorld
|
|||||||
|
|
||||||
void enableActorCollision(const MWWorld::Ptr& actor, bool enable) override;
|
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
|
///< check if the player is allowed to rest
|
||||||
|
|
||||||
void rest(double hours) override;
|
void rest(double hours) override;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user