void ProjectileManager::launchMagicBolt(const std::string &model, const std::string &sound, const std::string &spellId, float speed, bool stack, const ESM::EffectList &effects, const Ptr &caster, const std::string &sourceName, const Ogre::Vector3& fallbackDirection) { float height = 0; if (OEngine::Physic::PhysicActor* actor = mPhysEngine.getCharacter(caster.getRefData().getHandle())) height = actor->getHalfExtents().z * 2 * 0.75; // Spawn at 0.75 * ActorHeight Ogre::Vector3 pos(caster.getRefData().getPosition().pos); pos.z += height; if (MWBase::Environment::get().getWorld()->isUnderwater(caster.getCell(), pos)) // Underwater casting not possible return; Ogre::Quaternion orient; if (caster.getClass().isActor()) orient = Ogre::Quaternion(Ogre::Radian(caster.getRefData().getPosition().rot[2]), Ogre::Vector3::NEGATIVE_UNIT_Z) * Ogre::Quaternion(Ogre::Radian(caster.getRefData().getPosition().rot[0]), Ogre::Vector3::NEGATIVE_UNIT_X); else orient = Ogre::Vector3::UNIT_Y.getRotationTo(fallbackDirection); MagicBoltState state; state.mSourceName = sourceName; state.mId = model; state.mSpellId = spellId; state.mCasterHandle = caster.getRefData().getHandle(); if (caster.getClass().isActor()) state.mActorId = caster.getClass().getCreatureStats(caster).getActorId(); else state.mActorId = -1; state.mSpeed = speed; state.mStack = stack; state.mSoundId = sound; // Only interested in "on target" effects for (std::vector<ESM::ENAMstruct>::const_iterator iter (effects.mList.begin()); iter!=effects.mList.end(); ++iter) { if (iter->mRange == ESM::RT_Target) state.mEffects.mList.push_back(*iter); } MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), model); MWWorld::Ptr ptr = ref.getPtr(); state.mNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(pos, orient); createModel(state, ptr.getClass().getModel(ptr)); MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager(); state.mSound = sndMgr->playManualSound3D(pos, sound, 1.0f, 1.0f, MWBase::SoundManager::Play_TypeSfx, MWBase::SoundManager::Play_Loop); mMagicBolts.push_back(state); }
bool ProjectileManager::readRecord(ESM::ESMReader &reader, int32_t type) { if (type == ESM::REC_PROJ) { ESM::ProjectileState esm; esm.load(reader); ProjectileState state; state.mActorId = esm.mActorId; state.mBowId = esm.mBowId; state.mVelocity = esm.mVelocity; state.mId = esm.mId; std::string model; try { MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), esm.mId); MWWorld::Ptr ptr = ref.getPtr(); model = ptr.getClass().getModel(ptr); } catch(...) { return true; } state.mNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(esm.mPosition, esm.mOrientation); createModel(state, model); mProjectiles.push_back(state); return true; } else if (type == ESM::REC_MPRJ) { ESM::MagicBoltState esm; esm.load(reader); MagicBoltState state; state.mSourceName = esm.mSourceName; state.mId = esm.mId; state.mSpellId = esm.mSpellId; state.mActorId = esm.mActorId; state.mSpeed = esm.mSpeed; state.mStack = esm.mStack; state.mEffects = esm.mEffects; std::string model; try { MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), esm.mId); MWWorld::Ptr ptr = ref.getPtr(); model = ptr.getClass().getModel(ptr); } catch(...) { return true; } state.mNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(esm.mPosition, esm.mOrientation); createModel(state, model); MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager(); state.mSound = sndMgr->playManualSound3D(esm.mPosition, esm.mSound, 1.0f, 1.0f, MWBase::SoundManager::Play_TypeSfx, MWBase::SoundManager::Play_Loop); state.mSoundId = esm.mSound; mMagicBolts.push_back(state); return true; } return false; }