Add particles for Cast + Hit. Not looking quite right yet.

actorid
scrawl 11 years ago
parent 6f3d737498
commit ffdb91bb21

@ -17,6 +17,8 @@
#include "../mwbase/world.hpp"
#include "../mwbase/soundmanager.hpp"
#include "../mwrender/animation.hpp"
#include "../mwworld/class.hpp"
#include "creaturestats.hpp"
@ -217,7 +219,8 @@ namespace MWMechanics
else
iter->second = params;
// Play sounds
// Play sounds & particles
bool first=true;
for (std::vector<ESM::ENAMstruct>::const_iterator iter (effects.first.mList.begin());
iter!=effects.first.mList.end(); ++iter)
{
@ -228,17 +231,24 @@ namespace MWMechanics
MWBase::Environment::get().getWorld()->getStore().get<ESM::MagicEffect>().find (
iter->mEffectID);
static const std::string schools[] = {
"alteration", "conjuration", "destruction", "illusion", "mysticism", "restoration"
};
// Only the sound of the first effect plays
if (first)
{
static const std::string schools[] = {
"alteration", "conjuration", "destruction", "illusion", "mysticism", "restoration"
};
MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager();
if(!magicEffect->mHitSound.empty())
sndMgr->playSound3D(actor, magicEffect->mHitSound, 1.0f, 1.0f);
else
sndMgr->playSound3D(actor, schools[magicEffect->mData.mSchool]+" hit", 1.0f, 1.0f);
}
MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager();
if(!magicEffect->mHitSound.empty())
sndMgr->playSound3D(actor, magicEffect->mHitSound, 1.0f, 1.0f);
else
sndMgr->playSound3D(actor, schools[magicEffect->mData.mSchool]+" hit", 1.0f, 1.0f);
const ESM::Static* castStatic = MWBase::Environment::get().getWorld()->getStore().get<ESM::Static>().find (magicEffect->mHit);
MWBase::Environment::get().getWorld()->getAnimation(actor)->addEffect("meshes\\" + castStatic->mModel, "");
break;
first = false;
}
mSpellsChanged = true;

@ -512,6 +512,9 @@ bool CharacterController::updateNpcState(bool onground, bool inwater, bool isrun
const ESM::MagicEffect *effect;
effect = store.get<ESM::MagicEffect>().find(effectentry.mEffectID);
const ESM::Static* castStatic = store.get<ESM::Static>().find (effect->mCasting);
mAnimation->addEffect("meshes\\" + castStatic->mModel, "");
switch(effectentry.mRange)
{
case 0: mAttackType = "self"; break;

@ -39,6 +39,15 @@ void Animation::AnimationValue::setValue(Ogre::Real)
{
}
Ogre::Real Animation::EffectAnimationValue::getValue() const
{
return mTime;
}
void Animation::EffectAnimationValue::setValue(Ogre::Real)
{
}
void Animation::destroyObjectList(Ogre::SceneManager *sceneMgr, NifOgre::ObjectList &objects)
{
@ -916,6 +925,25 @@ Ogre::Vector3 Animation::runAnimation(float duration)
mSkelBase->getAllAnimationStates()->_notifyDirty();
}
for (std::vector<NifOgre::ObjectList>::iterator it = mEffects.begin(); it != mEffects.end(); )
{
for(size_t i = 0; i < it->mControllers.size() ;i++)
{
static_cast<EffectAnimationValue*> (it->mControllers[i].getSource().get())->addTime(duration);
it->mControllers[i].update();
}
if (it->mControllers[0].getSource()->getValue() >= it->mMaxControllerLength)
{
destroyObjectList(mInsert->getCreator(), *it);
it = mEffects.erase(it);
}
else
++it;
}
return movement;
}
@ -980,6 +1008,17 @@ void Animation::detachObjectFromBone(Ogre::MovableObject *obj)
mSkelBase->detachObjectFromBone(obj);
}
void Animation::addEffect(const std::string &model, const std::string &bonename)
{
NifOgre::ObjectList list = NifOgre::Loader::createObjects(mInsert, model);
for(size_t i = 0;i < list.mControllers.size();i++)
{
if(list.mControllers[i].getSource().isNull())
list.mControllers[i].setSource(Ogre::SharedPtr<EffectAnimationValue> (new EffectAnimationValue()));
}
mEffects.push_back(list);
}
ObjectAnimation::ObjectAnimation(const MWWorld::Ptr& ptr, const std::string &model)
: Animation(ptr, ptr.getRefData().getBaseNode())

@ -3,6 +3,7 @@
#include <OgreController.h>
#include <OgreVector3.h>
#include <OgreTimer.h>
#include <components/nifogre/ogrenifloader.hpp>
@ -52,6 +53,19 @@ protected:
virtual void setValue(Ogre::Real value);
};
class EffectAnimationValue : public Ogre::ControllerValue<Ogre::Real>
{
private:
float mTime;
public:
EffectAnimationValue() : mTime(0) { }
void addTime(float time) { mTime += time; }
virtual Ogre::Real getValue() const;
virtual void setValue(Ogre::Real value);
};
class NullAnimationValue : public Ogre::ControllerValue<Ogre::Real>
{
@ -95,6 +109,8 @@ protected:
typedef std::map<Ogre::MovableObject*,std::string> ObjectAttachMap;
std::vector<NifOgre::ObjectList> mEffects;
MWWorld::Ptr mPtr;
Camera *mCamera;
@ -114,6 +130,7 @@ protected:
ObjectAttachMap mAttachedObjects;
/* Sets the appropriate animations on the bone groups based on priority.
*/
void resetActiveGroups();
@ -173,6 +190,8 @@ public:
Animation(const MWWorld::Ptr &ptr, Ogre::SceneNode *node);
virtual ~Animation();
void addEffect (const std::string& model, const std::string& bonename = "");
void updatePtr(const MWWorld::Ptr &ptr);
bool hasAnimation(const std::string &anim);

@ -2029,6 +2029,8 @@ namespace MWWorld
MWMechanics::CreatureStats& stats = actor.getClass().getCreatureStats(actor);
stats.setAttackingOrSpell(false);
ESM::EffectList effects;
std::string selectedSpell = stats.getSpells().getSelectedSpell();
std::string sourceName;
if (!selectedSpell.empty())
@ -2094,6 +2096,7 @@ namespace MWWorld
actor.getClass().skillUsageSucceeded(actor, MWMechanics::spellSchoolToSkill(MWMechanics::getSpellSchool(selectedSpell, actor)), 0);
effects = spell->mEffects;
}
InventoryStore& inv = actor.getClass().getInventoryStore(actor);
if (selectedSpell.empty() && inv.getSelectedEnchantItem() != inv.end())
@ -2137,6 +2140,8 @@ namespace MWWorld
}
else
MWBase::Environment::get().getWindowManager()->setSelectedEnchantItem(item); // Set again to show the modified charge
effects = enchantment->mEffects;
}
// Now apply the spell!
@ -2158,7 +2163,6 @@ namespace MWWorld
}
}
// TODO: Launch projectile if there's a Target portion
}
void World::updateAnimParts(const Ptr& actor)

@ -64,8 +64,8 @@ struct MagicEffect
MEDTstruct mData;
std::string mIcon, mParticle; // Textures
std::string mCasting, mHit, mArea; // Statics
std::string mBolt; // Weapon
std::string mCasting, mHit, mArea; // ESM::Static
std::string mBolt; // ESM::Weapon
std::string mCastSound, mBoltSound, mHitSound, mAreaSound; // Sounds
std::string mDescription;

@ -54,6 +54,7 @@ private:
float mFrequency;
float mPhase;
float mStartTime;
public:
float mStopTime;
public:
@ -468,7 +469,10 @@ class NIFObjectLoader
Ogre::ControllerManager::getSingleton().getFrameTimeSource() :
Ogre::ControllerValueRealPtr());
Ogre::ControllerValueRealPtr dstval(OGRE_NEW UVController::Value(material, uv->data.getPtr()));
Ogre::ControllerFunctionRealPtr func(OGRE_NEW UVController::Function(uv, (animflags&Nif::NiNode::AnimFlag_AutoPlay)));
UVController::Function* function = OGRE_NEW UVController::Function(uv, (animflags&Nif::NiNode::AnimFlag_AutoPlay));
objectlist.mMaxControllerLength = std::max(function->mStopTime, objectlist.mMaxControllerLength);
Ogre::ControllerFunctionRealPtr func(function);
objectlist.mControllers.push_back(Ogre::Controller<Ogre::Real>(srcval, dstval, func));
}
@ -481,7 +485,10 @@ class NIFObjectLoader
Ogre::ControllerManager::getSingleton().getFrameTimeSource() :
Ogre::ControllerValueRealPtr());
Ogre::ControllerValueRealPtr dstval(OGRE_NEW GeomMorpherController::Value(subent, geom->data.getPtr()));
Ogre::ControllerFunctionRealPtr func(OGRE_NEW GeomMorpherController::Function(geom, (animflags&Nif::NiNode::AnimFlag_AutoPlay)));
GeomMorpherController::Function* function = OGRE_NEW GeomMorpherController::Function(geom, (animflags&Nif::NiNode::AnimFlag_AutoPlay));
objectlist.mMaxControllerLength = std::max(function->mStopTime, objectlist.mMaxControllerLength);
Ogre::ControllerFunctionRealPtr func(function);
objectlist.mControllers.push_back(Ogre::Controller<Ogre::Real>(srcval, dstval, func));
}
@ -616,7 +623,11 @@ class NIFObjectLoader
Ogre::ControllerManager::getSingleton().getFrameTimeSource() :
Ogre::ControllerValueRealPtr());
Ogre::ControllerValueRealPtr dstval(OGRE_NEW ParticleSystemController::Value(partsys, partctrl));
Ogre::ControllerFunctionRealPtr func(OGRE_NEW ParticleSystemController::Function(partctrl, (partflags&Nif::NiNode::ParticleFlag_AutoPlay)));
ParticleSystemController::Function* function =
OGRE_NEW ParticleSystemController::Function(partctrl, (partflags&Nif::NiNode::ParticleFlag_AutoPlay));
objectlist.mMaxControllerLength = std::max(function->mStopTime, objectlist.mMaxControllerLength);
Ogre::ControllerFunctionRealPtr func(function);
objectlist.mControllers.push_back(Ogre::Controller<Ogre::Real>(srcval, dstval, func));
}
@ -648,7 +659,10 @@ class NIFObjectLoader
Ogre::ControllerManager::getSingleton().getFrameTimeSource() :
Ogre::ControllerValueRealPtr());
Ogre::ControllerValueRealPtr dstval(OGRE_NEW VisController::Value(trgtbone, vis->data.getPtr()));
Ogre::ControllerFunctionRealPtr func(OGRE_NEW VisController::Function(vis, (animflags&Nif::NiNode::AnimFlag_AutoPlay)));
VisController::Function* function = OGRE_NEW VisController::Function(vis, (animflags&Nif::NiNode::AnimFlag_AutoPlay));
objectlist.mMaxControllerLength = std::max(function->mStopTime, objectlist.mMaxControllerLength);
Ogre::ControllerFunctionRealPtr func(function);
objectlist.mControllers.push_back(Ogre::Controller<Ogre::Real>(srcval, dstval, func));
}
@ -663,7 +677,9 @@ class NIFObjectLoader
Ogre::ControllerManager::getSingleton().getFrameTimeSource() :
Ogre::ControllerValueRealPtr());
Ogre::ControllerValueRealPtr dstval(OGRE_NEW KeyframeController::Value(trgtbone, key->data.getPtr()));
Ogre::ControllerFunctionRealPtr func(OGRE_NEW KeyframeController::Function(key, (animflags&Nif::NiNode::AnimFlag_AutoPlay)));
KeyframeController::Function* function = OGRE_NEW KeyframeController::Function(key, (animflags&Nif::NiNode::AnimFlag_AutoPlay));
objectlist.mMaxControllerLength = std::max(function->mStopTime, objectlist.mMaxControllerLength);
Ogre::ControllerFunctionRealPtr func(function);
objectlist.mControllers.push_back(Ogre::Controller<Ogre::Real>(srcval, dstval, func));
}

@ -45,11 +45,14 @@ struct ObjectList {
std::vector<Ogre::ParticleSystem*> mParticles;
std::vector<Ogre::Light*> mLights;
// The maximum length on any of the controllers. For animations with controllers, but no text keys, consider this the animation length.
float mMaxControllerLength;
std::map<int,TextKeyMap> mTextKeys;
std::vector<Ogre::Controller<Ogre::Real> > mControllers;
ObjectList() : mSkelBase(0)
ObjectList() : mSkelBase(0), mMaxControllerLength(0)
{ }
};

Loading…
Cancel
Save