diff --git a/CHANGELOG.md b/CHANGELOG.md index 7fd1e4d26..fa84ec10a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -104,6 +104,7 @@ Bug #4999: Drop instruction behaves differently from vanilla Bug #5001: Possible data race in the Animation::setAlpha() Bug #5004: Werewolves shield their eyes during storm + Bug #5012: "Take all" on owned container generates a messagebox per item Bug #5018: Spell tooltips don't support purely negative magnitudes Bug #5025: Data race in the ICO::setMaximumNumOfObjectsToCompilePerFrame() Bug #5028: Offered price caps are not trading-specific diff --git a/apps/openmw/mwbase/soundmanager.hpp b/apps/openmw/mwbase/soundmanager.hpp index bad80d6bd..a6d0d1223 100644 --- a/apps/openmw/mwbase/soundmanager.hpp +++ b/apps/openmw/mwbase/soundmanager.hpp @@ -100,9 +100,12 @@ namespace MWBase ///< Say some text, without an actor ref /// \param filename name of a sound file in "Sound/" in the data directory. - virtual bool sayDone(const MWWorld::ConstPtr &reference=MWWorld::ConstPtr()) const = 0; + virtual bool sayActive(const MWWorld::ConstPtr &reference=MWWorld::ConstPtr()) const = 0; ///< Is actor not speaking? + virtual bool sayDone(const MWWorld::ConstPtr &reference=MWWorld::ConstPtr()) const = 0; + ///< For scripting backward compatibility + virtual void stopSay(const MWWorld::ConstPtr &reference=MWWorld::ConstPtr()) = 0; ///< Stop an actor speaking diff --git a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp index c075d3cac..21bc067d7 100644 --- a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp +++ b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp @@ -540,7 +540,7 @@ namespace MWDialogue void DialogueManager::say(const MWWorld::Ptr &actor, const std::string &topic) { MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager(); - if(!sndMgr->sayDone(actor)) + if(sndMgr->sayActive(actor)) { // Actor is already saying something. return; diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 4a17dea7b..02bedee86 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -175,6 +175,7 @@ namespace MWGui , mHudEnabled(true) , mCursorVisible(true) , mCursorActive(false) + , mPlayerBounty(-1) , mPlayerName() , mPlayerRaceId() , mPlayerAttributes() @@ -1025,6 +1026,18 @@ namespace MWGui if (!gameRunning) return; + // We should display message about crime only once per frame, even if there are several crimes. + // Otherwise we will get message spam when stealing several items via Take All button. + const MWWorld::Ptr player = MWMechanics::getPlayer(); + int currentBounty = player.getClass().getNpcStats(player).getBounty(); + if (currentBounty != mPlayerBounty) + { + if (mPlayerBounty >= 0 && currentBounty > mPlayerBounty) + messageBox("#{sCrimeMessage}"); + + mPlayerBounty = currentBounty; + } + mDragAndDrop->onFrame(); mHud->onFrame(frameDuration); @@ -1773,6 +1786,8 @@ namespace MWGui void WindowManager::clear() { + mPlayerBounty = -1; + for (WindowBase* window : mWindows) window->clear(); diff --git a/apps/openmw/mwgui/windowmanagerimp.hpp b/apps/openmw/mwgui/windowmanagerimp.hpp index e7fc8109d..0b4307ec4 100644 --- a/apps/openmw/mwgui/windowmanagerimp.hpp +++ b/apps/openmw/mwgui/windowmanagerimp.hpp @@ -462,6 +462,8 @@ namespace MWGui bool mCursorVisible; bool mCursorActive; + int mPlayerBounty; + void setCursorVisible(bool visible); /// \todo get rid of this stuff. Move it to the respective UI element classes, if needed. diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index ff59ba4b9..8cab2f00b 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -372,7 +372,7 @@ namespace MWMechanics void Actors::playIdleDialogue(const MWWorld::Ptr& actor) { - if (!actor.getClass().isActor() || actor == getPlayer() || !MWBase::Environment::get().getSoundManager()->sayDone(actor)) + if (!actor.getClass().isActor() || actor == getPlayer() || MWBase::Environment::get().getSoundManager()->sayActive(actor)) return; const CreatureStats &stats = actor.getClass().getCreatureStats(actor); diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index c39487493..7547f086b 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -1452,7 +1452,6 @@ namespace MWMechanics if (reported) { - MWBase::Environment::get().getWindowManager()->messageBox("#{sCrimeMessage}"); player.getClass().getNpcStats(player).setBounty(player.getClass().getNpcStats(player).getBounty() + arg); @@ -1923,7 +1922,6 @@ namespace MWMechanics { npcStats.setBounty(npcStats.getBounty()+ gmst.find("iWereWolfBounty")->mValue.getInteger()); - windowManager->messageBox("#{sCrimeMessage}"); } } } diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index 09c2c8e1c..d56ac9bd0 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -184,7 +184,7 @@ void HeadAnimationTime::update(float dt) if (!mEnabled) return; - if (MWBase::Environment::get().getSoundManager()->sayDone(mReference)) + if (!MWBase::Environment::get().getSoundManager()->sayActive(mReference)) { mBlinkTimer += dt; diff --git a/apps/openmw/mwsound/soundmanagerimp.cpp b/apps/openmw/mwsound/soundmanagerimp.cpp index aa1686f7c..cef791c85 100644 --- a/apps/openmw/mwsound/soundmanagerimp.cpp +++ b/apps/openmw/mwsound/soundmanagerimp.cpp @@ -566,6 +566,27 @@ namespace MWSound return true; } + bool SoundManager::sayActive(const MWWorld::ConstPtr &ptr) const + { + SaySoundMap::const_iterator snditer = mSaySoundsQueue.find(ptr); + if(snditer != mSaySoundsQueue.end()) + { + if(mOutput->isStreamPlaying(snditer->second)) + return true; + return false; + } + + snditer = mActiveSaySounds.find(ptr); + if(snditer != mActiveSaySounds.end()) + { + if(mOutput->isStreamPlaying(snditer->second)) + return true; + return false; + } + + return false; + } + void SoundManager::stopSay(const MWWorld::ConstPtr &ptr) { SaySoundMap::iterator snditer = mSaySoundsQueue.find(ptr); diff --git a/apps/openmw/mwsound/soundmanagerimp.hpp b/apps/openmw/mwsound/soundmanagerimp.hpp index d0b98ffe4..786e3a5a7 100644 --- a/apps/openmw/mwsound/soundmanagerimp.hpp +++ b/apps/openmw/mwsound/soundmanagerimp.hpp @@ -179,9 +179,12 @@ namespace MWSound ///< Say some text, without an actor ref /// \param filename name of a sound file in "Sound/" in the data directory. - virtual bool sayDone(const MWWorld::ConstPtr &reference=MWWorld::ConstPtr()) const; + virtual bool sayActive(const MWWorld::ConstPtr &reference=MWWorld::ConstPtr()) const; ///< Is actor not speaking? + virtual bool sayDone(const MWWorld::ConstPtr &reference=MWWorld::ConstPtr()) const; + ///< For scripting backward compatibility + virtual void stopSay(const MWWorld::ConstPtr &reference=MWWorld::ConstPtr()); ///< Stop an actor speaking