Handle soundgen animation keys

This commit is contained in:
Chris Robinson 2013-07-17 23:58:21 -07:00
parent d6324d71bf
commit 9ea6b22a83
7 changed files with 115 additions and 2 deletions

View file

@ -291,6 +291,33 @@ namespace MWClass
return ref->mBase->mPersistent;
}
std::string Creature::getSoundIdFromSndGen(const MWWorld::Ptr &ptr, const std::string &name) const
{
const MWWorld::Store<ESM::SoundGenerator> &store = MWBase::Environment::get().getWorld()->getStore().get<ESM::SoundGenerator>();
int type = getSndGenTypeFromName(ptr, name);
if(type >= 0)
{
std::vector<const ESM::SoundGenerator*> sounds;
sounds.reserve(8);
std::string ptrid = Creature::getId(ptr);
MWWorld::Store<ESM::SoundGenerator>::iterator sound = store.begin();
while(sound != store.end())
{
if(type == sound->mType && sound->mCreature.size() > 0 &&
Misc::StringUtils::ciEqual(ptrid.substr(0, sound->mCreature.size()),
sound->mCreature))
sounds.push_back(&*sound);
sound++;
}
if(sounds.size() > 0)
return sounds[(int)(rand()/(RAND_MAX+1.0)*sounds.size())]->mSound;
}
return "";
}
MWWorld::Ptr
Creature::copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const
{
@ -300,6 +327,38 @@ namespace MWClass
return MWWorld::Ptr(&cell.mCreatures.insert(*ref), &cell);
}
int Creature::getSndGenTypeFromName(const MWWorld::Ptr &ptr, const std::string &name)
{
if(name == "left")
{
MWBase::World *world = MWBase::Environment::get().getWorld();
Ogre::Vector3 pos(ptr.getRefData().getPosition().pos);
if(world->isUnderwater(ptr.getCell(), pos))
return 2;
if(world->isOnGround(ptr))
return 0;
return -1;
}
if(name == "right")
{
MWBase::World *world = MWBase::Environment::get().getWorld();
Ogre::Vector3 pos(ptr.getRefData().getPosition().pos);
if(world->isUnderwater(ptr.getCell(), pos))
return 3;
if(world->isOnGround(ptr))
return 1;
return -1;
}
if(name == "moan")
return 4;
if(name == "roar")
return 5;
if(name == "scream")
return 6;
throw std::runtime_error(std::string("Unexpected soundgen type: ")+name);
}
const ESM::GameSetting* Creature::fMinWalkSpeedCreature;
const ESM::GameSetting* Creature::fMaxWalkSpeedCreature;
}

View file

@ -12,6 +12,8 @@ namespace MWClass
virtual MWWorld::Ptr
copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const;
static int getSndGenTypeFromName(const MWWorld::Ptr &ptr, const std::string &name);
static const ESM::GameSetting *fMinWalkSpeedCreature;
static const ESM::GameSetting *fMaxWalkSpeedCreature;
@ -69,6 +71,8 @@ namespace MWClass
virtual bool isPersistent (const MWWorld::Ptr& ptr) const;
virtual std::string getSoundIdFromSndGen(const MWWorld::Ptr &ptr, const std::string &name) const;
virtual MWMechanics::Movement& getMovementSettings (const MWWorld::Ptr& ptr) const;
///< Return desired movement.

View file

@ -663,6 +663,42 @@ namespace MWClass
return 0;
}
std::string Npc::getSoundIdFromSndGen(const MWWorld::Ptr &ptr, const std::string &name) const
{
if(name == "left")
{
MWBase::World *world = MWBase::Environment::get().getWorld();
Ogre::Vector3 pos(ptr.getRefData().getPosition().pos);
if(world->isUnderwater(ptr.getCell(), pos))
return "FootWaterLeft";
if(world->isOnGround(ptr))
return "FootBareLeft";
return "";
}
if(name == "right")
{
MWBase::World *world = MWBase::Environment::get().getWorld();
Ogre::Vector3 pos(ptr.getRefData().getPosition().pos);
if(world->isUnderwater(ptr.getCell(), pos))
return "FootWaterRight";
if(world->isOnGround(ptr))
return "FootBareRight";
return "";
}
// TODO: I have no idea what these are supposed to do for NPCs since they use
// voiced dialog for various conditions like health loss and combat taunts. Maybe
// only for biped creatures?
if(name == "moan")
return "";
if(name == "roar")
return "";
if(name == "scream")
return "";
throw std::runtime_error(std::string("Unexpected soundgen type: ")+name);
}
MWWorld::Ptr
Npc::copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const
{

View file

@ -132,6 +132,8 @@ namespace MWClass
virtual bool isPersistent (const MWWorld::Ptr& ptr) const;
virtual std::string getSoundIdFromSndGen(const MWWorld::Ptr &ptr, const std::string &name) const;
static void registerSelf();
virtual std::string getModel(const MWWorld::Ptr &ptr) const;

View file

@ -14,6 +14,7 @@
#include "../mwbase/world.hpp"
#include "../mwmechanics/character.hpp"
#include "../mwworld/class.hpp"
namespace MWRender
{
@ -511,8 +512,12 @@ bool Animation::handleTextKey(AnimState &state, const std::string &groupname, co
}
if(evt.compare(0, 10, "soundgen: ") == 0)
{
// FIXME: Lookup the SoundGen (SNDG) for the specified sound that corresponds
// to this actor type
std::string sound = MWWorld::Class::get(mPtr).getSoundIdFromSndGen(mPtr, evt.substr(10));
if(!sound.empty())
{
MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager();
sndMgr->playSound3D(mPtr, sound, 1.0f, 1.0f);
}
return true;
}

View file

@ -240,6 +240,10 @@ namespace MWWorld
throw std::runtime_error ("class does not have an down sound");
}
std::string Class::getSoundIdFromSndGen(const Ptr &ptr, const std::string &type) const
{
throw std::runtime_error("class does not support soundgen look up");
}
std::string Class::getInventoryIcon (const MWWorld::Ptr& ptr) const
{

View file

@ -221,6 +221,9 @@ namespace MWWorld
///< Return the down sound ID of \a ptr or throw an exception, if class does not support ID retrieval
/// (default implementation: throw an exception)
virtual std::string getSoundIdFromSndGen(const Ptr &ptr, const std::string &type) const;
///< Returns the sound ID for \a ptr of the given soundgen \a type.
virtual float getArmorRating (const MWWorld::Ptr& ptr) const;
///< @return combined armor rating of this actor