Add vanilla-compatible range limiting for playloopsound (Fixes #244, Fixes #1342)

moveref
scrawl 10 years ago
parent f6960debcb
commit 855fe33c59

@ -42,15 +42,21 @@ namespace MWBase
Play_NoTrack = 1<<2, /* (3D only) Play the sound at the given object's position
* but do not keep it updated (the sound will not move with
* the object and will not stop when the object is deleted. */
Play_LoopNoEnv = Play_Loop | Play_NoEnv
Play_RemoveAtDistance = 1<<3, /* (3D only) If the listener gets further than 2000 units away
from the sound source, the sound is removed.
This is weird stuff but apparently how vanilla works for sounds
played by the PlayLoopSound family of script functions. Perhaps we
can make this cut off a more subtle fade later, but have to
be careful to not change the overall volume of areas by too much. */
Play_LoopNoEnv = Play_Loop | Play_NoEnv,
Play_LoopRemoveAtDistance = Play_Loop | Play_RemoveAtDistance
};
enum PlayType {
Play_TypeSfx = 1<<3, /* Normal SFX sound */
Play_TypeVoice = 1<<4, /* Voice sound */
Play_TypeFoot = 1<<5, /* Footstep sound */
Play_TypeMusic = 1<<6, /* Music track */
Play_TypeMovie = 1<<7, /* Movie audio track */
Play_TypeSfx = 1<<4, /* Normal SFX sound */
Play_TypeVoice = 1<<5, /* Voice sound */
Play_TypeFoot = 1<<6, /* Footstep sound */
Play_TypeMusic = 1<<7, /* Music track */
Play_TypeMovie = 1<<8, /* Movie audio track */
Play_TypeMask = Play_TypeSfx|Play_TypeVoice|Play_TypeFoot|Play_TypeMusic|Play_TypeMovie
};

@ -121,8 +121,8 @@ namespace MWScript
MWBase::Environment::get().getSoundManager()->playSound3D(ptr, sound, 1.0, 1.0,
MWBase::SoundManager::Play_TypeSfx,
mLoop ? MWBase::SoundManager::Play_Loop :
MWBase::SoundManager::Play_Normal);
mLoop ? MWBase::SoundManager::Play_LoopRemoveAtDistance
: MWBase::SoundManager::Play_Normal);
}
};
@ -150,8 +150,8 @@ namespace MWScript
MWBase::Environment::get().getSoundManager()->playSound3D(ptr, sound, volume, pitch,
MWBase::SoundManager::Play_TypeSfx,
mLoop ? MWBase::SoundManager::Play_Loop :
MWBase::SoundManager::Play_Normal);
mLoop ? MWBase::SoundManager::Play_LoopRemoveAtDistance
: MWBase::SoundManager::Play_Normal);
}
};

@ -628,7 +628,9 @@ void OpenAL_Sound3D::update()
{
ALfloat gain = mVolume*mBaseVolume;
ALfloat pitch = mPitch;
if(!(mFlags&MWBase::SoundManager::Play_NoEnv) && mOutput.mLastEnvironment == Env_Underwater)
if(mPos.squaredDistance(mOutput.mPos) > mMaxDistance*mMaxDistance)
gain = 0.0f;
else if(!(mFlags&MWBase::SoundManager::Play_NoEnv) && mOutput.mLastEnvironment == Env_Underwater)
{
gain *= 0.9f;
pitch *= 0.7f;
@ -694,7 +696,7 @@ void OpenAL_Output::init(const std::string &devname)
fail(std::string("Failed to setup context: ")+alcGetString(mDevice, alcGetError(mDevice)));
}
alDistanceModel(AL_INVERSE_DISTANCE);
alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED);
throwALerror();
ALCint maxmono=0, maxstereo=0;

@ -385,6 +385,11 @@ namespace MWSound
const ESM::Position &pos = ptr.getRefData().getPosition();
const Ogre::Vector3 objpos(pos.pos);
if ((mode & Play_RemoveAtDistance) && mListenerPos.squaredDistance(objpos) > 2000*2000)
{
return MWBase::SoundPtr();
}
sound = mOutput->playSound3D(file, objpos, volume, basevol, pitch, min, max, mode|type, offset);
if((mode&Play_NoTrack))
mActiveSounds[sound] = std::make_pair(MWWorld::Ptr(), soundId);
@ -650,6 +655,13 @@ namespace MWSound
const ESM::Position &pos = ptr.getRefData().getPosition();
const Ogre::Vector3 objpos(pos.pos);
snditer->first->setPosition(objpos);
if ((snditer->first->mFlags & Play_RemoveAtDistance)
&& mListenerPos.squaredDistance(Ogre::Vector3(ptr.getRefData().getPosition().pos)) > 2000*2000)
{
mActiveSounds.erase(snditer++);
continue;
}
}
//update fade out
if(snditer->first->mFadeOutTime>0)

Loading…
Cancel
Save