From f1a18027f24cc246d19a0d2a2da666f59a47db70 Mon Sep 17 00:00:00 2001 From: Allofich Date: Wed, 31 Aug 2016 19:03:28 +0900 Subject: [PATCH] Shoot projectiles of spells with multiple effects --- apps/openmw/mwmechanics/spellcasting.cpp | 111 ++++++++++------------- apps/openmw/mwmechanics/spellcasting.hpp | 4 + 2 files changed, 50 insertions(+), 65 deletions(-) diff --git a/apps/openmw/mwmechanics/spellcasting.cpp b/apps/openmw/mwmechanics/spellcasting.cpp index 4478c6bd0..df6d2c600 100644 --- a/apps/openmw/mwmechanics/spellcasting.cpp +++ b/apps/openmw/mwmechanics/spellcasting.cpp @@ -27,41 +27,6 @@ #include "npcstats.hpp" #include "actorutil.hpp" -namespace -{ - - /// Get projectile properties (model, sound and speed) for a spell with the given effects - /// If \a model is empty, the spell has no ranged effects and should not spawn a projectile. - void getProjectileInfo (const ESM::EffectList& effects, std::string& model, std::string& sound, float& speed) - { - for (std::vector::const_iterator iter (effects.mList.begin()); - iter!=effects.mList.end(); ++iter) - { - if (iter->mRange != ESM::RT_Target) - continue; - - const ESM::MagicEffect *magicEffect = MWBase::Environment::get().getWorld()->getStore().get().find ( - iter->mEffectID); - - model = magicEffect->mBolt; - if (model.empty()) - model = "VFX_DefaultBolt"; - - static const std::string schools[] = { - "alteration", "conjuration", "destruction", "illusion", "mysticism", "restoration" - }; - if (!magicEffect->mBoltSound.empty()) - sound = magicEffect->mBoltSound; - else - sound = schools[magicEffect->mData.mSchool] + " bolt"; - - speed = magicEffect->mData.mSpeed; - break; - } - } - -} - namespace MWMechanics { @@ -317,6 +282,50 @@ namespace MWMechanics { } + /// Get projectile properties (model, sound and speed) for a spell with the given effects and launch. + /// If \a model is empty, the spell has no ranged effects and should not spawn a projectile. + void CastSpell::getProjectileInfoAndLaunch (const ESM::EffectList& effects) + { + std::string model; + std::string sound; + float speed = 0; + osg::Vec3f fallbackDirection (0,1,0); + for (std::vector::const_iterator iter (effects.mList.begin()); + iter!=effects.mList.end(); ++iter) + { + if (iter->mRange != ESM::RT_Target) + continue; + + const ESM::MagicEffect *magicEffect = MWBase::Environment::get().getWorld()->getStore().get().find ( + iter->mEffectID); + + model = magicEffect->mBolt; + if (model.empty()) + model = "VFX_DefaultBolt"; + + static const std::string schools[] = { + "alteration", "conjuration", "destruction", "illusion", "mysticism", "restoration" + }; + if (!magicEffect->mBoltSound.empty()) + sound = magicEffect->mBoltSound; + else + sound = schools[magicEffect->mData.mSchool] + " bolt"; + + speed = magicEffect->mData.mSpeed; + + // Fall back to a "caster to target" direction if we have no other means of determining it + // (e.g. when cast by a non-actor) + if (!mTarget.isEmpty()) + fallbackDirection = + osg::Vec3f(mTarget.getRefData().getPosition().asVec3())- + osg::Vec3f(mCaster.getRefData().getPosition().asVec3()); + + if (!model.empty()) + MWBase::Environment::get().getWorld()->launchMagicBolt(model, sound, mId, speed, + false, effects, mCaster, mSourceName, fallbackDirection); + } + } + void CastSpell::inflict(const MWWorld::Ptr &target, const MWWorld::Ptr &caster, const ESM::EffectList &effects, ESM::RangeType range, bool reflected, bool exploded) { @@ -785,17 +794,7 @@ namespace MWMechanics } if (launchProjectile) - { - std::string projectileModel; - std::string sound; - float speed = 0; - getProjectileInfo(enchantment->mEffects, projectileModel, sound, speed); - if (!projectileModel.empty()) - MWBase::Environment::get().getWorld()->launchMagicBolt(projectileModel, sound, mId, speed, - false, enchantment->mEffects, mCaster, mSourceName, - // Not needed, enchantments can only be cast by actors - osg::Vec3f(1,0,0)); - } + getProjectileInfoAndLaunch(enchantment->mEffects); else if (!mTarget.isEmpty()) inflict(mTarget, mCaster, enchantment->mEffects, ESM::RT_Target); @@ -876,27 +875,9 @@ namespace MWMechanics inflict(mCaster, mCaster, spell->mEffects, ESM::RT_Self); if (!mTarget.isEmpty()) - { inflict(mTarget, mCaster, spell->mEffects, ESM::RT_Touch); - } - std::string projectileModel; - std::string sound; - float speed = 0; - getProjectileInfo(spell->mEffects, projectileModel, sound, speed); - if (!projectileModel.empty()) - { - osg::Vec3f fallbackDirection (0,1,0); - // Fall back to a "caster to target" direction if we have no other means of determining it - // (e.g. when cast by a non-actor) - if (!mTarget.isEmpty()) - fallbackDirection = - osg::Vec3f(mTarget.getRefData().getPosition().asVec3())- - osg::Vec3f(mCaster.getRefData().getPosition().asVec3()); - - MWBase::Environment::get().getWorld()->launchMagicBolt(projectileModel, sound, mId, speed, - false, spell->mEffects, mCaster, mSourceName, fallbackDirection); - } + getProjectileInfoAndLaunch(spell->mEffects); return true; } diff --git a/apps/openmw/mwmechanics/spellcasting.hpp b/apps/openmw/mwmechanics/spellcasting.hpp index aba263b01..e300b1818 100644 --- a/apps/openmw/mwmechanics/spellcasting.hpp +++ b/apps/openmw/mwmechanics/spellcasting.hpp @@ -94,6 +94,10 @@ namespace MWMechanics void playSpellCastingEffects(const std::string &spellid); + /// Get the models, sounds and speeds for all projectiles + /// in the given effects, and launch them. + void getProjectileInfoAndLaunch (const ESM::EffectList& effects); + /// @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,