From 5c889f7359dd6d64e6438178c306893d01f3c534 Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Thu, 24 Jan 2019 23:18:57 +0300 Subject: [PATCH] Add creature-with-the-same-model soundgen fallback (bug #4813) Creatures will use sounds of the first creature that has the same model in the record store when possible. --- CHANGELOG.md | 1 + apps/openmw/mwclass/creature.cpp | 65 ++++++++++++++++++++++---------- 2 files changed, 46 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d3f4db0fd..a131fe05d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ Bug #4800: Standing collisions are not updated immediately when an object is teleported without a cell change Bug #4803: Stray special characters before begin statement break script compilation Bug #4804: Particle system with the "Has Sizes = false" causes an exception + Bug #4813: Creatures with known file but no "Sound Gen Creature" assigned use default sounds Bug #4820: Spell absorption is broken Bug #4827: NiUVController is handled incorrectly Feature #2229: Improve pathfinding AI diff --git a/apps/openmw/mwclass/creature.cpp b/apps/openmw/mwclass/creature.cpp index c89ea8b7f..962a5bab5 100644 --- a/apps/openmw/mwclass/creature.cpp +++ b/apps/openmw/mwclass/creature.cpp @@ -625,34 +625,59 @@ namespace MWClass std::string Creature::getSoundIdFromSndGen(const MWWorld::Ptr &ptr, const std::string &name) const { - const MWWorld::Store &store = MWBase::Environment::get().getWorld()->getStore().get(); - int type = getSndGenTypeFromName(ptr, name); - if(type >= 0) - { - std::vector sounds; - std::vector fallbacksounds; + if (type < 0) + return std::string(); + + std::vector sounds; + std::vector fallbacksounds; - MWWorld::LiveCellRef* ref = ptr.get(); + MWWorld::LiveCellRef* ref = ptr.get(); - const std::string& ourId = (ref->mBase->mOriginal.empty()) ? ptr.getCellRef().getRefId() : ref->mBase->mOriginal; + const std::string& ourId = (ref->mBase->mOriginal.empty()) ? ptr.getCellRef().getRefId() : ref->mBase->mOriginal; + + const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); + auto sound = store.get().begin(); + while (sound != store.get().end()) + { + if (type == sound->mType && !sound->mCreature.empty() && Misc::StringUtils::ciEqual(ourId, sound->mCreature)) + sounds.push_back(&*sound); + if (type == sound->mType && sound->mCreature.empty()) + fallbacksounds.push_back(&*sound); + ++sound; + } - MWWorld::Store::iterator sound = store.begin(); - while (sound != store.end()) + if (sounds.empty()) + { + const std::string model = getModel(ptr); + if (!model.empty()) { - if (type == sound->mType && !sound->mCreature.empty() && (Misc::StringUtils::ciEqual(ourId, sound->mCreature))) - sounds.push_back(&*sound); - if (type == sound->mType && sound->mCreature.empty()) - fallbacksounds.push_back(&*sound); - ++sound; + for (const ESM::Creature &creature : store.get()) + { + if (creature.mId != ourId && creature.mOriginal != ourId && !creature.mModel.empty() + && Misc::StringUtils::ciEqual(model, "meshes\\" + creature.mModel)) + { + const std::string& fallbackId = !creature.mOriginal.empty() ? creature.mOriginal : creature.mId; + sound = store.get().begin(); + while (sound != store.get().end()) + { + if (type == sound->mType && !sound->mCreature.empty() + && Misc::StringUtils::ciEqual(fallbackId, sound->mCreature)) + sounds.push_back(&*sound); + ++sound; + } + break; + } + } } - if (!sounds.empty()) - return sounds[Misc::Rng::rollDice(sounds.size())]->mSound; - if (!fallbacksounds.empty()) - return fallbacksounds[Misc::Rng::rollDice(fallbacksounds.size())]->mSound; } - return ""; + if (!sounds.empty()) + return sounds[Misc::Rng::rollDice(sounds.size())]->mSound; + if (!fallbacksounds.empty()) + return fallbacksounds[Misc::Rng::rollDice(fallbacksounds.size())]->mSound; + + return std::string(); } MWWorld::Ptr Creature::copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const