diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 07aba2f7d..e65195531 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -44,6 +44,7 @@ #include "creaturestats.hpp" #include "security.hpp" #include "actorutil.hpp" +#include "spellcasting.hpp" namespace { @@ -961,34 +962,6 @@ void CharacterController::updateIdleStormState(bool inwater) } } -void CharacterController::castSpell(const std::string &spellid) -{ - static const std::string schools[] = { - "alteration", "conjuration", "destruction", "illusion", "mysticism", "restoration" - }; - - const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); - const ESM::Spell *spell = store.get().find(spellid); - const ESM::ENAMstruct &effectentry = spell->mEffects.mList.at(0); - - const ESM::MagicEffect *effect; - effect = store.get().find(effectentry.mEffectID); - - const ESM::Static* castStatic; - if (!effect->mCasting.empty()) - castStatic = store.get().find (effect->mCasting); - else - castStatic = store.get().find ("VFX_DefaultCast"); - - mAnimation->addEffect("meshes\\" + castStatic->mModel, effect->mIndex); - - MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager(); - if(!effect->mCastSound.empty()) - sndMgr->playSound3D(mPtr, effect->mCastSound, 1.0f, 1.0f); - else - sndMgr->playSound3D(mPtr, schools[effect->mData.mSchool]+" cast", 1.0f, 1.0f); -} - bool CharacterController::updateCreatureState() { const MWWorld::Class &cls = mPtr.getClass(); @@ -1020,7 +993,8 @@ bool CharacterController::updateCreatureState() const std::string spellid = stats.getSpells().getSelectedSpell(); if (!spellid.empty() && MWBase::Environment::get().getWorld()->startSpellCast(mPtr)) { - castSpell(spellid); + MWMechanics::CastSpell cast(mPtr, NULL); + cast.playSpellCastingEffects(spellid); if (!mAnimation->hasAnimation("spellcast")) MWBase::Environment::get().getWorld()->castSpell(mPtr); // No "release" text key to use, so cast immediately @@ -1248,7 +1222,8 @@ bool CharacterController::updateWeaponState() if(!spellid.empty() && MWBase::Environment::get().getWorld()->startSpellCast(mPtr)) { - castSpell(spellid); + MWMechanics::CastSpell cast(mPtr, NULL); + cast.playSpellCastingEffects(spellid); const ESM::Spell *spell = store.get().find(spellid); const ESM::ENAMstruct &effectentry = spell->mEffects.mList.at(0); diff --git a/apps/openmw/mwmechanics/character.hpp b/apps/openmw/mwmechanics/character.hpp index 190e171b3..d5dc5fe28 100644 --- a/apps/openmw/mwmechanics/character.hpp +++ b/apps/openmw/mwmechanics/character.hpp @@ -214,8 +214,6 @@ class CharacterController : public MWRender::Animation::TextKeyListener void updateHeadTracking(float duration); - void castSpell(const std::string& spellid); - void updateMagicEffects(); void playDeath(float startpoint, CharacterState death); diff --git a/apps/openmw/mwmechanics/spellcasting.cpp b/apps/openmw/mwmechanics/spellcasting.cpp index 52815816e..e5f221a02 100644 --- a/apps/openmw/mwmechanics/spellcasting.cpp +++ b/apps/openmw/mwmechanics/spellcasting.cpp @@ -836,6 +836,10 @@ namespace MWMechanics if (mCaster == getPlayer() && spellIncreasesSkill(spell)) mCaster.getClass().skillUsageSucceeded(mCaster, spellSchoolToSkill(school), 0); + + // A non-actor doesn't have casting animation so it plays its spell casting effects here + if (!mCaster.getClass().isActor()) + playSpellCastingEffects(mId); inflict(mCaster, mCaster, spell->mEffects, ESM::RT_Self); @@ -930,6 +934,38 @@ namespace MWMechanics return true; } + void CastSpell::playSpellCastingEffects(const std::string &spellid){ + + const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); + const ESM::Spell *spell = store.get().find(spellid); + const ESM::ENAMstruct &effectentry = spell->mEffects.mList.at(0); + + const ESM::MagicEffect *effect; + effect = store.get().find(effectentry.mEffectID); + + if (mCaster.getClass().isActor()) // TODO: Non-actors (except for large statics?) should also create a visual casting effect + { + const ESM::Static* castStatic; + if (!effect->mCasting.empty()) + castStatic = store.get().find (effect->mCasting); + else + castStatic = store.get().find ("VFX_DefaultCast"); + + MWBase::Environment::get().getWorld()->getAnimation(mCaster)->addEffect( + "meshes\\" + castStatic->mModel, effect->mIndex); + } + + static const std::string schools[] = { + "alteration", "conjuration", "destruction", "illusion", "mysticism", "restoration" + }; + + MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager(); + if(!effect->mCastSound.empty()) + sndMgr->playSound3D(mCaster, effect->mCastSound, 1.0f, 1.0f); + else + sndMgr->playSound3D(mCaster, schools[effect->mData.mSchool]+" cast", 1.0f, 1.0f); + } + int getEffectiveEnchantmentCastCost(float castCost, const MWWorld::Ptr &actor) { /* diff --git a/apps/openmw/mwmechanics/spellcasting.hpp b/apps/openmw/mwmechanics/spellcasting.hpp index ae20a39d0..aba263b01 100644 --- a/apps/openmw/mwmechanics/spellcasting.hpp +++ b/apps/openmw/mwmechanics/spellcasting.hpp @@ -92,6 +92,8 @@ namespace MWMechanics /// @note Auto detects if spell, ingredient or potion bool cast (const std::string& id); + void playSpellCastingEffects(const std::string &spellid); + /// @note \a target can be any type of object, not just actors. /// @note \a caster can be any type of object, or even an empty object. void inflict (const MWWorld::Ptr& target, const MWWorld::Ptr& caster,