diff --git a/AUTHORS.md b/AUTHORS.md index 9c6a5edbe..17f11730d 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -44,6 +44,7 @@ Programmers crussell187 DanielVukelich darkf + David Cernat (davidcernat) devnexen Dieho Dmitry Shkurskiy (endorph) diff --git a/apps/openmw-mp/Script/Functions/Worldstate.cpp b/apps/openmw-mp/Script/Functions/Worldstate.cpp new file mode 100644 index 000000000..b95b67d14 --- /dev/null +++ b/apps/openmw-mp/Script/Functions/Worldstate.cpp @@ -0,0 +1,50 @@ +#include + +#include +#include +#include + +#include "Worldstate.hpp" + +#include +using namespace std; + +void WorldstateFunctions::SetHour(unsigned short pid, double hour) noexcept +{ + Player *player; + GET_PLAYER(pid, player, ); + + player->hour = hour; + player->month = -1; + player->day = -1; + + mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_GAME_TIME)->setPlayer(player); + mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_GAME_TIME)->Send(false); +} + +void WorldstateFunctions::SetMonth(unsigned short pid, int month) noexcept +{ + Player *player; + GET_PLAYER(pid, player, ); + + player->hour = -1; + player->month = month; + player->day = -1; + + mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_GAME_TIME)->setPlayer(player); + mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_GAME_TIME)->Send(false); + +} + +void WorldstateFunctions::SetDay(unsigned short pid, int day) noexcept +{ + Player *player; + GET_PLAYER(pid, player, ); + + player->hour = -1; + player->month = -1; + player->day = day; + + mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_GAME_TIME)->setPlayer(player); + mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_GAME_TIME)->Send(false); +} diff --git a/apps/openmw-mp/Script/Functions/Worldstate.hpp b/apps/openmw-mp/Script/Functions/Worldstate.hpp new file mode 100644 index 000000000..5a1f6ee8a --- /dev/null +++ b/apps/openmw-mp/Script/Functions/Worldstate.hpp @@ -0,0 +1,44 @@ +#ifndef OPENMW_WORLDSTATEAPI_HPP +#define OPENMW_WORLDSTATEAPI_HPP + +#include "../Types.hpp" + +#define WORLDSTATEAPI \ + {"SetHour", WorldstateFunctions::SetHour},\ + {"SetMonth", WorldstateFunctions::SetMonth},\ + {"SetDay", WorldstateFunctions::SetDay} + +class WorldstateFunctions +{ +public: + + /** + * \brief Set the game hour for a player and send a GameTime packet to that player. + * + * \param pid The player ID. + * \param hour The hour. + * \return void + */ + static void SetHour(unsigned short pid, double hour) noexcept; + + /** + * \brief Set the game month for a player and send a GameTime packet to that player. + * + * \param pid The player ID. + * \param month The month. + * \return void + */ + static void SetMonth(unsigned short pid, int month) noexcept; + + /** + * \brief Set the game day for a player and send a GameTime packet to that player. + * + * \param pid The player ID. + * \param day The day. + * \return void + */ + static void SetDay(unsigned short pid, int day) noexcept; + +}; + +#endif //OPENMW_WORLDSTATEAPI_HPP diff --git a/apps/openmw/mwbase/windowmanager.hpp b/apps/openmw/mwbase/windowmanager.hpp index 6b731fbc4..12f7fbb7a 100644 --- a/apps/openmw/mwbase/windowmanager.hpp +++ b/apps/openmw/mwbase/windowmanager.hpp @@ -423,7 +423,7 @@ namespace MWBase /// Cycle to next or previous weapon virtual void cycleWeapon(bool next) = 0; - virtual void playSound(const std::string& soundId, bool preventOverlapping = false, float volume = 1.f, float pitch = 1.f) = 0; + virtual void playSound(const std::string& soundId, float volume = 1.f, float pitch = 1.f) = 0; // In WindowManager for now since there isn't a VFS singleton virtual std::string correctIconPath(const std::string& path) = 0; diff --git a/apps/openmw/mwgui/bookwindow.cpp b/apps/openmw/mwgui/bookwindow.cpp index cb902cadf..c18548dad 100644 --- a/apps/openmw/mwgui/bookwindow.cpp +++ b/apps/openmw/mwgui/bookwindow.cpp @@ -200,7 +200,7 @@ namespace MWGui { if ((mCurrentPage+1)*2 < mPages.size()) { - MWBase::Environment::get().getWindowManager()->playSound("book page2", true); + MWBase::Environment::get().getWindowManager()->playSound("book page2"); ++mCurrentPage; @@ -211,7 +211,7 @@ namespace MWGui { if (mCurrentPage > 0) { - MWBase::Environment::get().getWindowManager()->playSound("book page", true); + MWBase::Environment::get().getWindowManager()->playSound("book page"); --mCurrentPage; diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index a36634542..6bb454cd6 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -956,6 +956,9 @@ namespace MWGui updateMap(); + if (!mMap->isVisible()) + mMap->onFrame(frameDuration); + mHud->onFrame(frameDuration); mDebugWindow->onFrame(frameDuration); @@ -2043,16 +2046,12 @@ namespace MWGui mInventoryWindow->cycle(next); } - void WindowManager::playSound(const std::string& soundId, bool preventOverlapping, float volume, float pitch) + void WindowManager::playSound(const std::string& soundId, float volume, float pitch) { if (soundId.empty()) return; - MWBase::SoundManager *sndmgr = MWBase::Environment::get().getSoundManager(); - if (preventOverlapping && sndmgr->getSoundPlaying(MWWorld::Ptr(), soundId)) - return; - - sndmgr->playSound(soundId, volume, pitch, MWSound::Type::Sfx, MWSound::PlayMode::NoEnv); + MWBase::Environment::get().getSoundManager()->playSound(soundId, volume, pitch, MWSound::Type::Sfx, MWSound::PlayMode::NoEnv); } void WindowManager::updateSpellWindow() diff --git a/apps/openmw/mwgui/windowmanagerimp.hpp b/apps/openmw/mwgui/windowmanagerimp.hpp index c153438e5..d4862c726 100644 --- a/apps/openmw/mwgui/windowmanagerimp.hpp +++ b/apps/openmw/mwgui/windowmanagerimp.hpp @@ -452,7 +452,7 @@ namespace MWGui /// Cycle to next or previous weapon virtual void cycleWeapon(bool next); - virtual void playSound(const std::string& soundId, bool preventOverlapping = false, float volume = 1.f, float pitch = 1.f); + virtual void playSound(const std::string& soundId, float volume = 1.f, float pitch = 1.f); // In WindowManager for now since there isn't a VFS singleton virtual std::string correctIconPath(const std::string& path); diff --git a/apps/openmw/mwsound/soundmanagerimp.cpp b/apps/openmw/mwsound/soundmanagerimp.cpp index db02bb482..0dd95f773 100644 --- a/apps/openmw/mwsound/soundmanagerimp.cpp +++ b/apps/openmw/mwsound/soundmanagerimp.cpp @@ -20,9 +20,9 @@ #include "../mwmechanics/actorutil.hpp" -#include "sound_output.hpp" #include "sound_buffer.hpp" #include "sound_decoder.hpp" +#include "sound_output.hpp" #include "sound.hpp" #include "openal_output.hpp" @@ -577,6 +577,9 @@ namespace MWSound Sound_Buffer *sfx = loadSound(Misc::StringUtils::lowerCase(soundId)); if(!sfx) return nullptr; + // Only one copy of given sound can be played at time, so stop previous copy + stopSound(sfx, MWWorld::ConstPtr()); + Sound *sound = getSoundRef(); sound->init(volume * sfx->mVolume, volumeFromType(type), pitch, mode|type|Play_2D); if(!mOutput->playSound(sound, sfx->mHandle, offset)) @@ -611,7 +614,7 @@ namespace MWSound return nullptr; // Only one copy of given sound can be played at time on ptr, so stop previous copy - stopSound3D(ptr, soundId); + stopSound(sfx, ptr); bool played; Sound *sound = getSoundRef(); @@ -678,12 +681,11 @@ namespace MWSound mOutput->finishSound(sound); } - void SoundManager::stopSound3D(const MWWorld::ConstPtr &ptr, const std::string& soundId) + void SoundManager::stopSound(Sound_Buffer *sfx, const MWWorld::ConstPtr &ptr) { SoundMap::iterator snditer = mActiveSounds.find(ptr); if(snditer != mActiveSounds.end()) { - Sound_Buffer *sfx = loadSound(Misc::StringUtils::lowerCase(soundId)); for(SoundBufferRefPair &snd : snditer->second) { if(snd.second == sfx) @@ -692,6 +694,22 @@ namespace MWSound } } + void SoundManager::stopSound(const std::string& soundId) + { + Sound_Buffer *sfx = loadSound(Misc::StringUtils::lowerCase(soundId)); + if (!sfx) return; + + stopSound(sfx, MWWorld::ConstPtr()); + } + + void SoundManager::stopSound3D(const MWWorld::ConstPtr &ptr, const std::string& soundId) + { + Sound_Buffer *sfx = loadSound(Misc::StringUtils::lowerCase(soundId)); + if (!sfx) return; + + stopSound(sfx, ptr); + } + void SoundManager::stopSound3D(const MWWorld::ConstPtr &ptr) { SoundMap::iterator snditer = mActiveSounds.find(ptr); @@ -715,6 +733,7 @@ namespace MWSound mOutput->finishSound(sndbuf.first); } } + for(SaySoundMap::value_type &snd : mActiveSaySounds) { if(!snd.first.isEmpty() && snd.first != MWMechanics::getPlayer() && snd.first.getCell() == cell) @@ -722,20 +741,6 @@ namespace MWSound } } - void SoundManager::stopSound(const std::string& soundId) - { - SoundMap::iterator snditer = mActiveSounds.find(MWWorld::ConstPtr()); - if(snditer != mActiveSounds.end()) - { - Sound_Buffer *sfx = loadSound(Misc::StringUtils::lowerCase(soundId)); - for(SoundBufferRefPair &sndbuf : snditer->second) - { - if(sndbuf.second == sfx) - mOutput->finishSound(sndbuf.first); - } - } - } - void SoundManager::fadeOutSound3D(const MWWorld::ConstPtr &ptr, const std::string& soundId, float duration) { diff --git a/apps/openmw/mwsound/soundmanagerimp.hpp b/apps/openmw/mwsound/soundmanagerimp.hpp index e31a0e575..4064a05af 100644 --- a/apps/openmw/mwsound/soundmanagerimp.hpp +++ b/apps/openmw/mwsound/soundmanagerimp.hpp @@ -145,6 +145,9 @@ namespace MWSound DecoderPtr getDecoder(); friend class OpenAL_Output; + void stopSound(Sound_Buffer *sfx, const MWWorld::ConstPtr &ptr); + ///< Stop the given object from playing given sound buffer. + public: SoundManager(const VFS::Manager* vfs, const std::map& fallbackMap, bool useSound); virtual ~SoundManager();