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:
parent
e566e4abf2
commit
bcb38c3eba
4 changed files with 86 additions and 33 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -22,10 +22,11 @@ namespace MWWorld
|
||||||
public:
|
public:
|
||||||
enum State
|
enum State
|
||||||
{
|
{
|
||||||
EQUIPPED,
|
EQUIP,
|
||||||
AUTOEQUIPPED,
|
AUTOEQUIP,
|
||||||
UNEQUIPPED,
|
UNEQUIP,
|
||||||
ALL_UNEQUIPPED
|
UNEQUIPALL_BEGIN,
|
||||||
|
UNEQUIPALL_END
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in a new issue