1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-11-29 23:07:48 +02:00

Implement configurable object sounds: ambient, visit and removal

* If there more than one sound for visit or removal random is played
* At moment only the first ambient sound will be used
This commit is contained in:
Arseniy Shestakov
2017-09-13 03:35:58 +03:00
committed by DJWarmonger
parent e9bfbb70c1
commit f15cadc87b
22 changed files with 347 additions and 91 deletions

View File

@@ -82,8 +82,10 @@ void CSoundHandler::onVolumeChange(const JsonNode &volumeNode)
}
CSoundHandler::CSoundHandler():
listener(settings.listen["general"]["sound"])
listener(settings.listen["general"]["sound"]),
ambientConfig(JsonNode(ResourceID("config/ambientSounds.json")))
{
allTilesSource = ambientConfig["allTilesSource"].Bool();
listener(std::bind(&CSoundHandler::onVolumeChange, this, _1));
// Vectors for helper(s)
@@ -112,6 +114,8 @@ CSoundHandler::CSoundHandler():
void CSoundHandler::init()
{
CAudioBase::init();
if(ambientConfig["allocateChannels"].isNumber())
Mix_AllocateChannels(ambientConfig["allocateChannels"].Integer());
if (initialized)
{
@@ -160,6 +164,21 @@ Mix_Chunk *CSoundHandler::GetSoundChunk(std::string &sound, bool cache)
}
}
int CSoundHandler::ambientDistToVolume(int distance) const
{
if(distance >= ambientConfig["distances"].Vector().size())
return 0;
int volume = ambientConfig["distances"].Vector()[distance].Integer();
return volume * ambientConfig["volume"].Integer() * getVolume() / 10000;
}
void CSoundHandler::ambientStopSound(std::string soundId)
{
stopSound(ambientChannels[soundId]);
setChannelVolume(ambientChannels[soundId], 100);
}
// Plays a sound, and return its channel so we can fade it out later
int CSoundHandler::playSound(soundBase::soundID soundID, int repeats)
{
@@ -216,7 +235,13 @@ void CSoundHandler::setVolume(ui32 percent)
CAudioBase::setVolume(percent);
if (initialized)
Mix_Volume(-1, (MIX_MAX_VOLUME * volume)/100);
setChannelVolume(-1, volume);
}
// Sets the sound volume, from 0 (mute) to 100
void CSoundHandler::setChannelVolume(int channel, ui32 percent)
{
Mix_Volume(channel, (MIX_MAX_VOLUME * percent)/100);
}
void CSoundHandler::setCallback(int channel, std::function<void()> function)
@@ -244,6 +269,54 @@ void CSoundHandler::soundFinishedCallback(int channel)
callbacks.erase(iter);
}
int CSoundHandler::ambientGetRange() const
{
return ambientConfig["range"].Integer();
}
bool CSoundHandler::ambientCheckVisitable() const
{
return !allTilesSource;
}
void CSoundHandler::ambientUpdateChannels(std::map<std::string, int> sounds)
{
std::vector<std::string> stoppedSounds;
for(auto & pair : ambientChannels)
{
if(!vstd::contains(sounds, pair.first))
{
ambientStopSound(pair.first);
stoppedSounds.push_back(pair.first);
}
else
{
CCS->soundh->setChannelVolume(pair.second, ambientDistToVolume(sounds[pair.first]));
}
}
for(auto soundId : stoppedSounds)
ambientChannels.erase(soundId);
for(auto & pair : sounds)
{
if(!vstd::contains(ambientChannels, pair.first))
{
int channel = CCS->soundh->playSound(pair.first, -1);
CCS->soundh->setChannelVolume(channel, ambientDistToVolume(pair.second));
CCS->soundh->ambientChannels.insert(std::make_pair(pair.first, channel));
}
}
}
void CSoundHandler::ambientStopAllChannels()
{
for(auto ch : ambientChannels)
{
ambientStopSound(ch.first);
}
ambientChannels.clear();
}
void CMusicHandler::onVolumeChange(const JsonNode &volumeNode)
{
setVolume(volumeNode.Float());