1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-01-30 15:15:31 +00:00

Issue #1887: Equipped items do not emit sounds

Added handling of autoEquip and unequipAll cases.

Signed-off-by: Lukasz Gromanowski <lgromanowski@gmail.com>
This commit is contained in:
Lukasz Gromanowski 2014-10-04 22:27:23 +02:00
parent e566e4abf2
commit bcb38c3eba
4 changed files with 86 additions and 33 deletions

View file

@ -186,7 +186,9 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, Ogre::SceneNode* node, int v
mShowCarriedLeft(true), mShowCarriedLeft(true),
mFirstPersonOffset(0.f, 0.f, 0.f), mFirstPersonOffset(0.f, 0.f, 0.f),
mAlpha(1.f), mAlpha(1.f),
mNpcType(Type_Normal) mNpcType(Type_Normal),
mUnequipping(false),
mFirstEquip(true)
{ {
mNpc = mPtr.get<ESM::NPC>()->mBase; mNpc = mPtr.get<ESM::NPC>()->mBase;
@ -928,31 +930,78 @@ void NpcAnimation::applyAlpha(float alpha, Ogre::Entity *ent, NifOgre::ObjectSce
} }
} }
void NpcAnimation::equipmentChanged (const MWWorld::Ptr& actor, const MWWorld::Ptr& item, InventoryStoreListener::State state) void NpcAnimation::equipmentChanged(const MWWorld::Ptr& actor, const MWWorld::Ptr& item, InventoryStoreListener::State state)
{ {
if (actor.getRefData().getHandle() == "player" && !item.isEmpty()) if (actor.getRefData().getHandle() == "player")
{ {
std::string soundId; std::string soundId;
if (item.getTypeName() == typeid(ESM::Light).name()) MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager();
{
soundId = item.get<ESM::Light>()->mBase->mSound;
}
if (!soundId.empty()) if (state == InventoryStoreListener::EQUIP
|| state == InventoryStoreListener::UNEQUIP)
{ {
MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager(); if (item.getTypeName() == typeid(ESM::Light).name())
if (state == InventoryStoreListener::EQUIPPED)
{ {
sndMgr->playSound3D(mPtr, soundId, 1.0f, 1.0f, MWBase::SoundManager::Play_TypeSfx, soundId = item.get<ESM::Light>()->mBase->mSound;
MWBase::SoundManager::Play_Loop);
} }
else if (state == InventoryStoreListener::UNEQUIPPED)
if (!soundId.empty())
{ {
sndMgr->stopSound3D(mPtr, soundId); if (state == InventoryStoreListener::EQUIP)
{
sndMgr->playSound3D(mPtr, soundId, 1.0f, 1.0f, MWBase::SoundManager::Play_TypeSfx,
MWBase::SoundManager::Play_Loop);
}
else
{
sndMgr->stopSound3D(mPtr, soundId);
}
} }
} }
else if (state == InventoryStoreListener::AUTOEQUIP)
{
const MWWorld::Class &cls = mPtr.getClass();
MWWorld::InventoryStore &inv = cls.getInventoryStore(mPtr);
for (int i = MWWorld::InventoryStore::Slot_Helmet; i < MWWorld::InventoryStore::Slots; ++i)
{
MWWorld::ContainerStoreIterator store = inv.getSlot(i);
if (store != inv.end() && store->getTypeName() == typeid(ESM::Light).name())
{
soundId = store->get<ESM::Light>()->mBase->mSound;
}
if (!soundId.empty())
{
sndMgr->playSound3D(mPtr, soundId, 1.0f, 1.0f, MWBase::SoundManager::Play_TypeSfx,
MWBase::SoundManager::Play_Loop);
}
}
}
}
/**
* AUTOEQUIP is triggered just after setting listener (ie. when game is loaded from savegame),
* but not all things are initialized yet, so we have to check it (mFirstEquip variable)
* and skip one call to updateParts() method.
*
* Also call to updateParts() method will be called only once if inventory.unequipAll()
* was called (mUnequipping == true).
*/
if (state == InventoryStoreListener::UNEQUIPALL_BEGIN)
mUnequipping = true;
else if (state == InventoryStoreListener::UNEQUIPALL_END)
mUnequipping = false;
if (!mUnequipping && !mFirstEquip)
{
updateParts();
}
if (mFirstEquip && state == InventoryStoreListener::AUTOEQUIP)
{
mFirstEquip = false;
} }
} }

View file

@ -51,7 +51,7 @@ public:
class NpcAnimation : public Animation, public WeaponAnimation, public MWWorld::InventoryStoreListener class NpcAnimation : public Animation, public WeaponAnimation, public MWWorld::InventoryStoreListener
{ {
public: public:
virtual void equipmentChanged() { updateParts(); } virtual void equipmentChanged(const MWWorld::Ptr& actor, const MWWorld::Ptr& item, InventoryStoreListener::State state);
virtual void permanentEffectAdded(const ESM::MagicEffect *magicEffect, bool isNew, bool playSound); virtual void permanentEffectAdded(const ESM::MagicEffect *magicEffect, bool isNew, bool playSound);
public: public:
@ -97,6 +97,8 @@ private:
Ogre::SharedPtr<WeaponAnimationTime> mWeaponAnimationTime; Ogre::SharedPtr<WeaponAnimationTime> mWeaponAnimationTime;
float mAlpha; float mAlpha;
bool mUnequipping;
bool mFirstEquip;
void updateNpcBase(); void updateNpcBase();
@ -114,10 +116,6 @@ private:
void applyAlpha(float alpha, Ogre::Entity* ent, NifOgre::ObjectScenePtr scene); void applyAlpha(float alpha, Ogre::Entity* ent, NifOgre::ObjectScenePtr scene);
/**
* Implementation of MWWorld::InventoryStoreListener equipmentChanged method
*/
void equipmentChanged (const MWWorld::Ptr& actor, const MWWorld::Ptr& item, InventoryStoreListener::State state);
public: public:
/** /**
* @param ptr * @param ptr

View file

@ -146,19 +146,18 @@ void MWWorld::InventoryStore::equip (int slot, const ContainerStoreIterator& ite
flagAsModified(); flagAsModified();
fireEquipmentChangedEvent(actor, *iterator, InventoryStoreListener::EQUIPPED); fireEquipmentChangedEvent(actor, *iterator, InventoryStoreListener::EQUIP);
updateMagicEffects(actor); updateMagicEffects(actor);
} }
void MWWorld::InventoryStore::unequipAll(const MWWorld::Ptr& actor) void MWWorld::InventoryStore::unequipAll(const MWWorld::Ptr& actor)
{ {
// Only *one* change event should be fired fireEquipmentChangedEvent(actor, MWWorld::Ptr(), InventoryStoreListener::UNEQUIPALL_BEGIN);
mUpdatesEnabled = false;
for (int slot=0; slot < MWWorld::InventoryStore::Slots; ++slot) for (int slot=0; slot < MWWorld::InventoryStore::Slots; ++slot)
unequipSlot(slot, actor); unequipSlot(slot, actor);
mUpdatesEnabled = true;
fireEquipmentChangedEvent(actor, MWWorld::Ptr(), InventoryStoreListener::ALL_UNEQUIPPED); fireEquipmentChangedEvent(actor, MWWorld::Ptr(), InventoryStoreListener::UNEQUIPALL_END);
updateMagicEffects(actor); updateMagicEffects(actor);
} }
@ -277,17 +276,19 @@ void MWWorld::InventoryStore::autoEquip (const MWWorld::Ptr& actor)
bool changed = false; bool changed = false;
for (std::size_t i=0; i<slots_.size(); ++i) for (std::size_t i=0; i<slots_.size(); ++i)
if (slots_[i]!=mSlots[i]) {
if (slots_[i] != mSlots[i])
{ {
changed = true; changed = true;
break;
} }
}
mUpdatesEnabled = true; mUpdatesEnabled = true;
if (changed) if (changed)
{ {
mSlots.swap (slots_); mSlots.swap (slots_);
fireEquipmentChangedEvent(actor, MWWorld::Ptr(), InventoryStoreListener::AUTOEQUIPPED); fireEquipmentChangedEvent(actor, MWWorld::Ptr(), InventoryStoreListener::AUTOEQUIP);
updateMagicEffects(actor); updateMagicEffects(actor);
flagAsModified(); flagAsModified();
} }
@ -520,7 +521,7 @@ MWWorld::ContainerStoreIterator MWWorld::InventoryStore::unequipSlot(int slot, c
} }
} }
fireEquipmentChangedEvent(actor, *it, InventoryStoreListener::UNEQUIPPED); fireEquipmentChangedEvent(actor, *it, InventoryStoreListener::UNEQUIP);
updateMagicEffects(actor); updateMagicEffects(actor);
return retval; return retval;
@ -545,6 +546,10 @@ void MWWorld::InventoryStore::setListener(InventoryStoreListener *listener, cons
{ {
mListener = listener; mListener = listener;
updateMagicEffects(actor); updateMagicEffects(actor);
if (mListener != NULL)
{
mListener->equipmentChanged(actor, MWWorld::Ptr(), InventoryStoreListener::AUTOEQUIP);
}
} }
void MWWorld::InventoryStore::fireEquipmentChangedEvent(const MWWorld::Ptr& actor, const MWWorld::Ptr& item, InventoryStoreListener::State state) void MWWorld::InventoryStore::fireEquipmentChangedEvent(const MWWorld::Ptr& actor, const MWWorld::Ptr& item, InventoryStoreListener::State state)

View file

@ -22,10 +22,11 @@ namespace MWWorld
public: public:
enum State enum State
{ {
EQUIPPED, EQUIP,
AUTOEQUIPPED, AUTOEQUIP,
UNEQUIPPED, UNEQUIP,
ALL_UNEQUIPPED UNEQUIPALL_BEGIN,
UNEQUIPALL_END
}; };
/** /**