|
|
@ -30,6 +30,7 @@
|
|
|
|
#include "../mwrender/animation.hpp"
|
|
|
|
#include "../mwrender/animation.hpp"
|
|
|
|
#include "../mwrender/vismask.hpp"
|
|
|
|
#include "../mwrender/vismask.hpp"
|
|
|
|
#include "../mwrender/renderingmanager.hpp"
|
|
|
|
#include "../mwrender/renderingmanager.hpp"
|
|
|
|
|
|
|
|
#include "../mwrender/util.hpp"
|
|
|
|
|
|
|
|
|
|
|
|
#include "../mwsound/sound.hpp"
|
|
|
|
#include "../mwsound/sound.hpp"
|
|
|
|
|
|
|
|
|
|
|
@ -37,7 +38,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
namespace
|
|
|
|
namespace
|
|
|
|
{
|
|
|
|
{
|
|
|
|
ESM::EffectList getMagicBoltData(std::vector<std::string>& projectileIDs, std::vector<std::string>& sounds, float& speed, const ESM::EffectList& effects)
|
|
|
|
ESM::EffectList getMagicBoltData(std::vector<std::string>& projectileIDs, std::vector<std::string>& sounds, float& speed, std::string& texture, const ESM::EffectList& effects)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
int count = 0;
|
|
|
|
int count = 0;
|
|
|
|
speed = 0.0f;
|
|
|
|
speed = 0.0f;
|
|
|
@ -73,6 +74,14 @@ namespace
|
|
|
|
|
|
|
|
|
|
|
|
if (count != 0)
|
|
|
|
if (count != 0)
|
|
|
|
speed /= count;
|
|
|
|
speed /= count;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// the particle texture is only used if there is only one projectile
|
|
|
|
|
|
|
|
if (projectileEffects.mList.size() == 1)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
const ESM::MagicEffect *magicEffect = MWBase::Environment::get().getWorld()->getStore().get<ESM::MagicEffect>().find (
|
|
|
|
|
|
|
|
effects.mList.begin()->mEffectID);
|
|
|
|
|
|
|
|
texture = magicEffect->mParticle;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (projectileEffects.mList.size() > 1) // insert a VFX_Multiple projectile if there are multiple projectile effects
|
|
|
|
if (projectileEffects.mList.size() > 1) // insert a VFX_Multiple projectile if there are multiple projectile effects
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -127,7 +136,7 @@ namespace MWWorld
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void ProjectileManager::createModel(State &state, const std::string &model, const osg::Vec3f& pos, const osg::Quat& orient, bool rotate)
|
|
|
|
void ProjectileManager::createModel(State &state, const std::string &model, const osg::Vec3f& pos, const osg::Quat& orient, bool rotate, std::string texture)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
state.mNode = new osg::PositionAttitudeTransform;
|
|
|
|
state.mNode = new osg::PositionAttitudeTransform;
|
|
|
|
state.mNode->setNodeMask(MWRender::Mask_Effect);
|
|
|
|
state.mNode->setNodeMask(MWRender::Mask_Effect);
|
|
|
@ -144,7 +153,7 @@ namespace MWWorld
|
|
|
|
attachTo = rotateNode;
|
|
|
|
attachTo = rotateNode;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
mResourceSystem->getSceneManager()->getInstance(model, attachTo);
|
|
|
|
osg::ref_ptr<osg::Node> projectile = mResourceSystem->getSceneManager()->getInstance(model, attachTo);
|
|
|
|
|
|
|
|
|
|
|
|
if (state.mIdMagic.size() > 1)
|
|
|
|
if (state.mIdMagic.size() > 1)
|
|
|
|
for (size_t iter = 1; iter != state.mIdMagic.size(); ++iter)
|
|
|
|
for (size_t iter = 1; iter != state.mIdMagic.size(); ++iter)
|
|
|
@ -169,6 +178,8 @@ namespace MWWorld
|
|
|
|
|
|
|
|
|
|
|
|
SceneUtil::AssignControllerSourcesVisitor assignVisitor (state.mEffectAnimationTime);
|
|
|
|
SceneUtil::AssignControllerSourcesVisitor assignVisitor (state.mEffectAnimationTime);
|
|
|
|
state.mNode->accept(assignVisitor);
|
|
|
|
state.mNode->accept(assignVisitor);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
MWRender::overrideFirstRootTexture(texture, mResourceSystem, projectile);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ProjectileManager::update(State& state, float duration)
|
|
|
|
void ProjectileManager::update(State& state, float duration)
|
|
|
@ -207,7 +218,9 @@ namespace MWWorld
|
|
|
|
state.mActorId = -1;
|
|
|
|
state.mActorId = -1;
|
|
|
|
state.mStack = stack;
|
|
|
|
state.mStack = stack;
|
|
|
|
|
|
|
|
|
|
|
|
state.mEffects = getMagicBoltData(state.mIdMagic, state.mSoundIds, state.mSpeed, effects);
|
|
|
|
std::string texture = "";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
state.mEffects = getMagicBoltData(state.mIdMagic, state.mSoundIds, state.mSpeed, texture, effects);
|
|
|
|
|
|
|
|
|
|
|
|
// Non-projectile should have been removed by getMagicBoltData
|
|
|
|
// Non-projectile should have been removed by getMagicBoltData
|
|
|
|
if (state.mEffects.mList.empty())
|
|
|
|
if (state.mEffects.mList.empty())
|
|
|
@ -216,7 +229,7 @@ namespace MWWorld
|
|
|
|
MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), state.mIdMagic.at(0));
|
|
|
|
MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), state.mIdMagic.at(0));
|
|
|
|
MWWorld::Ptr ptr = ref.getPtr();
|
|
|
|
MWWorld::Ptr ptr = ref.getPtr();
|
|
|
|
|
|
|
|
|
|
|
|
createModel(state, ptr.getClass().getModel(ptr), pos, orient, true);
|
|
|
|
createModel(state, ptr.getClass().getModel(ptr), pos, orient, true, texture);
|
|
|
|
|
|
|
|
|
|
|
|
MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager();
|
|
|
|
MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager();
|
|
|
|
for (size_t it = 0; it != state.mSoundIds.size(); it++)
|
|
|
|
for (size_t it = 0; it != state.mSoundIds.size(); it++)
|
|
|
@ -486,7 +499,8 @@ namespace MWWorld
|
|
|
|
state.mSpellId = esm.mSpellId;
|
|
|
|
state.mSpellId = esm.mSpellId;
|
|
|
|
state.mActorId = esm.mActorId;
|
|
|
|
state.mActorId = esm.mActorId;
|
|
|
|
state.mStack = esm.mStack;
|
|
|
|
state.mStack = esm.mStack;
|
|
|
|
state.mEffects = getMagicBoltData(state.mIdMagic, state.mSoundIds, state.mSpeed, esm.mEffects);
|
|
|
|
std::string texture = "";
|
|
|
|
|
|
|
|
state.mEffects = getMagicBoltData(state.mIdMagic, state.mSoundIds, state.mSpeed, texture, esm.mEffects);
|
|
|
|
state.mSpeed = esm.mSpeed; // speed is derived from non-projectile effects as well as
|
|
|
|
state.mSpeed = esm.mSpeed; // speed is derived from non-projectile effects as well as
|
|
|
|
// projectile effects, so we can't calculate it from the save
|
|
|
|
// projectile effects, so we can't calculate it from the save
|
|
|
|
// file's effect list, which is already trimmed of non-projectile
|
|
|
|
// file's effect list, which is already trimmed of non-projectile
|
|
|
@ -504,7 +518,7 @@ namespace MWWorld
|
|
|
|
return true;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
createModel(state, model, osg::Vec3f(esm.mPosition), osg::Quat(esm.mOrientation), true);
|
|
|
|
createModel(state, model, osg::Vec3f(esm.mPosition), osg::Quat(esm.mOrientation), true, texture);
|
|
|
|
|
|
|
|
|
|
|
|
MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager();
|
|
|
|
MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager();
|
|
|
|
|
|
|
|
|
|
|
|