1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-02-20 01:09:41 +00:00

Implement idlestorm animation (Feature #41)

This commit is contained in:
scrawl 2014-06-24 18:37:38 +02:00
parent 1c157b86f6
commit 693a097b21
9 changed files with 103 additions and 3 deletions

View file

@ -521,6 +521,12 @@ namespace MWBase
const MWWorld::Ptr& caster, const std::string& id, const std::string& sourceName) = 0;
virtual void activate (const MWWorld::Ptr& object, const MWWorld::Ptr& actor) = 0;
/// @see MWWorld::WeatherManager::isInStorm
virtual bool isInStorm() const = 0;
/// @see MWWorld::WeatherManager::getStormDirection
virtual Ogre::Vector3 getStormDirection() const = 0;
};
}

View file

@ -20,6 +20,7 @@
#include "character.hpp"
#include <OgreStringConverter.h>
#include <OgreSceneNode.h>
#include "movement.hpp"
#include "npcstats.hpp"
@ -234,6 +235,8 @@ void CharacterController::refreshCurrentAnims(CharacterState idle, CharacterStat
1.0f, "start", "stop", 0.0f, ~0ul);
}
updateIdleStormState();
if(force && mJumpState != JumpState_None)
{
std::string jump;
@ -550,6 +553,45 @@ void CharacterController::updatePtr(const MWWorld::Ptr &ptr)
mPtr = ptr;
}
void CharacterController::updateIdleStormState()
{
bool inStormDirection = false;
if (MWBase::Environment::get().getWorld()->isInStorm())
{
Ogre::Vector3 stormDirection = MWBase::Environment::get().getWorld()->getStormDirection();
Ogre::Vector3 characterDirection = mPtr.getRefData().getBaseNode()->getOrientation().yAxis();
inStormDirection = stormDirection.angleBetween(characterDirection) < Ogre::Degree(40);
}
if (inStormDirection && mUpperBodyState == UpperCharState_Nothing && mAnimation->hasAnimation("idlestorm"))
{
float complete = 0;
mAnimation->getInfo("idlestorm", &complete);
if (complete == 0)
mAnimation->play("idlestorm", Priority_Torch, MWRender::Animation::Group_RightArm, false,
1.0f, "start", "loop start", 0.0f, 0);
else if (complete == 1)
mAnimation->play("idlestorm", Priority_Torch, MWRender::Animation::Group_RightArm, false,
1.0f, "loop start", "loop stop", 0.0f, ~0ul);
}
else
{
if (mUpperBodyState == UpperCharState_Nothing)
{
if (mAnimation->isPlaying("idlestorm"))
{
if (mAnimation->getCurrentTime("idlestorm") < mAnimation->getTextKeyTime("idlestorm: loop stop"))
{
mAnimation->play("idlestorm", Priority_Torch, MWRender::Animation::Group_RightArm, true,
1.0f, "loop stop", "stop", 0.0f, 0);
}
}
}
else
mAnimation->disable("idlestorm");
}
}
bool CharacterController::updateCreatureState()
{
const MWWorld::Class &cls = mPtr.getClass();

View file

@ -178,6 +178,7 @@ class CharacterController
bool updateWeaponState();
bool updateCreatureState();
void updateIdleStormState();
void updateVisibility();

View file

@ -461,7 +461,7 @@ void SkyManager::setWeather(const MWWorld::WeatherResult& weather)
{
if (!mParticleNode)
{
mParticleNode = mCamera->getParentSceneNode()->createChildSceneNode();
mParticleNode = mCamera->getParentSceneNode()->createChildSceneNode(Ogre::Vector3(0,0,100));
mParticleNode->setInheritOrientation(false);
}

View file

@ -54,7 +54,7 @@ namespace MWWorld
RefData();
/// @param cellRef Used to copy constant data such as position into this class where it can
/// be altered without effecting the original data. This makes it possible
/// be altered without affecting the original data. This makes it possible
/// to reset the position as the orignal data is still held in the CellRef
RefData (const ESM::CellRef& cellRef);

View file

@ -63,6 +63,8 @@ void WeatherManager::setFallbackWeather(Weather& weather,const std::string& name
if (offset != std::string::npos)
weather.mCloudTexture.replace(offset, weather.mCloudTexture.length() - offset, ".dds");
weather.mIsStorm = (name == "ashstorm" || name == "blight");
mWeatherSettings[name] = weather;
}
@ -213,6 +215,8 @@ void WeatherManager::setResult(const String& weatherType)
mResult.mAmbientLoopSoundID = current.mAmbientLoopSoundID;
mResult.mSunColor = current.mSunDiscSunsetColor;
mResult.mIsStorm = current.mIsStorm;
mResult.mParticleEffect = current.mParticleEffect;
mResult.mNight = (mHour < mSunriseTime || mHour > mNightStart - 1);
@ -318,6 +322,7 @@ void WeatherManager::transition(float factor)
mResult.mNight = current.mNight;
mResult.mIsStorm = current.mIsStorm;
mResult.mParticleEffect = current.mParticleEffect;
}
@ -771,3 +776,13 @@ void WeatherManager::switchToNextWeather(bool instantly)
}
}
}
bool WeatherManager::isInStorm() const
{
return mResult.mIsStorm;
}
Ogre::Vector3 WeatherManager::getStormDirection() const
{
return Ogre::Vector3(0,-1,0);
}

View file

@ -57,6 +57,8 @@ namespace MWWorld
bool mNight; // use night skybox
float mNightFade; // fading factor for night skybox
bool mIsStorm;
std::string mAmbientLoopSoundID;
std::string mParticleEffect;
@ -102,7 +104,7 @@ namespace MWWorld
// Duration of weather transition (in days)
float mTransitionDelta;
// No idea what this one is used for?
// Used by scripts to animate signs, etc based on the wind (GetWindSpeed)
float mWindSpeed;
// Cloud animation speed multiplier
@ -121,6 +123,12 @@ namespace MWWorld
// Rain sound effect
std::string mRainLoopSoundID;
// Is this an ash storm / blight storm? This controls two things:
// - The particle node will be oriented so that the particles appear to come from the Red Mountain. (not implemented yet)
// - Characters will animate their hand to protect eyes from the storm when looking in its direction (idlestorm animation)
// Possible effect on movement speed?
bool mIsStorm;
std::string mParticleEffect;
// Note: For Weather Blight, there is a "Disease Chance" (=0.1) setting. But according to MWSFD this feature
@ -156,6 +164,11 @@ namespace MWWorld
float getWindSpeed() const;
/// Are we in an ash or blight storm?
bool isInStorm() const;
Ogre::Vector3 getStormDirection() const;
void advanceTime(double hours)
{
mTimePassed += hours*3600;

View file

@ -1998,6 +1998,22 @@ namespace MWWorld
return 0.f;
}
bool World::isInStorm() const
{
if (isCellExterior() || isCellQuasiExterior())
return mWeatherManager->isInStorm();
else
return false;
}
Ogre::Vector3 World::getStormDirection() const
{
if (isCellExterior() || isCellQuasiExterior())
return mWeatherManager->getStormDirection();
else
return Ogre::Vector3(0,1,0);
}
void World::getContainersOwnedBy (const MWWorld::Ptr& npc, std::vector<MWWorld::Ptr>& out)
{
const Scene::CellStoreCollection& collection = mWorldScene->getActiveCells();
@ -2313,6 +2329,7 @@ namespace MWWorld
{
MWMechanics::CreatureStats& stats = actor.getClass().getCreatureStats(actor);
// TODO: this only works for the player
MWWorld::Ptr target = getFacedObject();
std::string selectedSpell = stats.getSpells().getSelectedSpell();

View file

@ -591,6 +591,12 @@ namespace MWWorld
const MWWorld::Ptr& caster, const std::string& id, const std::string& sourceName);
virtual void activate (const MWWorld::Ptr& object, const MWWorld::Ptr& actor);
/// @see MWWorld::WeatherManager::isInStorm
virtual bool isInStorm() const;
/// @see MWWorld::WeatherManager::getStormDirection
virtual Ogre::Vector3 getStormDirection() const;
};
}