mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-02-21 12:09:41 +00:00
Implement idlestorm animation (Feature #41)
This commit is contained in:
parent
1c157b86f6
commit
693a097b21
9 changed files with 103 additions and 3 deletions
|
@ -521,6 +521,12 @@ namespace MWBase
|
||||||
const MWWorld::Ptr& caster, const std::string& id, const std::string& sourceName) = 0;
|
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;
|
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;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include "character.hpp"
|
#include "character.hpp"
|
||||||
|
|
||||||
#include <OgreStringConverter.h>
|
#include <OgreStringConverter.h>
|
||||||
|
#include <OgreSceneNode.h>
|
||||||
|
|
||||||
#include "movement.hpp"
|
#include "movement.hpp"
|
||||||
#include "npcstats.hpp"
|
#include "npcstats.hpp"
|
||||||
|
@ -234,6 +235,8 @@ void CharacterController::refreshCurrentAnims(CharacterState idle, CharacterStat
|
||||||
1.0f, "start", "stop", 0.0f, ~0ul);
|
1.0f, "start", "stop", 0.0f, ~0ul);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateIdleStormState();
|
||||||
|
|
||||||
if(force && mJumpState != JumpState_None)
|
if(force && mJumpState != JumpState_None)
|
||||||
{
|
{
|
||||||
std::string jump;
|
std::string jump;
|
||||||
|
@ -550,6 +553,45 @@ void CharacterController::updatePtr(const MWWorld::Ptr &ptr)
|
||||||
mPtr = 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()
|
bool CharacterController::updateCreatureState()
|
||||||
{
|
{
|
||||||
const MWWorld::Class &cls = mPtr.getClass();
|
const MWWorld::Class &cls = mPtr.getClass();
|
||||||
|
|
|
@ -178,6 +178,7 @@ class CharacterController
|
||||||
|
|
||||||
bool updateWeaponState();
|
bool updateWeaponState();
|
||||||
bool updateCreatureState();
|
bool updateCreatureState();
|
||||||
|
void updateIdleStormState();
|
||||||
|
|
||||||
void updateVisibility();
|
void updateVisibility();
|
||||||
|
|
||||||
|
|
|
@ -461,7 +461,7 @@ void SkyManager::setWeather(const MWWorld::WeatherResult& weather)
|
||||||
{
|
{
|
||||||
if (!mParticleNode)
|
if (!mParticleNode)
|
||||||
{
|
{
|
||||||
mParticleNode = mCamera->getParentSceneNode()->createChildSceneNode();
|
mParticleNode = mCamera->getParentSceneNode()->createChildSceneNode(Ogre::Vector3(0,0,100));
|
||||||
mParticleNode->setInheritOrientation(false);
|
mParticleNode->setInheritOrientation(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,7 @@ namespace MWWorld
|
||||||
RefData();
|
RefData();
|
||||||
|
|
||||||
/// @param cellRef Used to copy constant data such as position into this class where it can
|
/// @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
|
/// to reset the position as the orignal data is still held in the CellRef
|
||||||
RefData (const ESM::CellRef& cellRef);
|
RefData (const ESM::CellRef& cellRef);
|
||||||
|
|
||||||
|
|
|
@ -63,6 +63,8 @@ void WeatherManager::setFallbackWeather(Weather& weather,const std::string& name
|
||||||
if (offset != std::string::npos)
|
if (offset != std::string::npos)
|
||||||
weather.mCloudTexture.replace(offset, weather.mCloudTexture.length() - offset, ".dds");
|
weather.mCloudTexture.replace(offset, weather.mCloudTexture.length() - offset, ".dds");
|
||||||
|
|
||||||
|
weather.mIsStorm = (name == "ashstorm" || name == "blight");
|
||||||
|
|
||||||
mWeatherSettings[name] = weather;
|
mWeatherSettings[name] = weather;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,6 +215,8 @@ void WeatherManager::setResult(const String& weatherType)
|
||||||
mResult.mAmbientLoopSoundID = current.mAmbientLoopSoundID;
|
mResult.mAmbientLoopSoundID = current.mAmbientLoopSoundID;
|
||||||
mResult.mSunColor = current.mSunDiscSunsetColor;
|
mResult.mSunColor = current.mSunDiscSunsetColor;
|
||||||
|
|
||||||
|
mResult.mIsStorm = current.mIsStorm;
|
||||||
|
|
||||||
mResult.mParticleEffect = current.mParticleEffect;
|
mResult.mParticleEffect = current.mParticleEffect;
|
||||||
|
|
||||||
mResult.mNight = (mHour < mSunriseTime || mHour > mNightStart - 1);
|
mResult.mNight = (mHour < mSunriseTime || mHour > mNightStart - 1);
|
||||||
|
@ -318,6 +322,7 @@ void WeatherManager::transition(float factor)
|
||||||
|
|
||||||
mResult.mNight = current.mNight;
|
mResult.mNight = current.mNight;
|
||||||
|
|
||||||
|
mResult.mIsStorm = current.mIsStorm;
|
||||||
mResult.mParticleEffect = current.mParticleEffect;
|
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);
|
||||||
|
}
|
||||||
|
|
|
@ -57,6 +57,8 @@ namespace MWWorld
|
||||||
bool mNight; // use night skybox
|
bool mNight; // use night skybox
|
||||||
float mNightFade; // fading factor for night skybox
|
float mNightFade; // fading factor for night skybox
|
||||||
|
|
||||||
|
bool mIsStorm;
|
||||||
|
|
||||||
std::string mAmbientLoopSoundID;
|
std::string mAmbientLoopSoundID;
|
||||||
|
|
||||||
std::string mParticleEffect;
|
std::string mParticleEffect;
|
||||||
|
@ -102,7 +104,7 @@ namespace MWWorld
|
||||||
// Duration of weather transition (in days)
|
// Duration of weather transition (in days)
|
||||||
float mTransitionDelta;
|
float mTransitionDelta;
|
||||||
|
|
||||||
// No idea what this one is used for?
|
// Used by scripts to animate signs, etc based on the wind (GetWindSpeed)
|
||||||
float mWindSpeed;
|
float mWindSpeed;
|
||||||
|
|
||||||
// Cloud animation speed multiplier
|
// Cloud animation speed multiplier
|
||||||
|
@ -121,6 +123,12 @@ namespace MWWorld
|
||||||
// Rain sound effect
|
// Rain sound effect
|
||||||
std::string mRainLoopSoundID;
|
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;
|
std::string mParticleEffect;
|
||||||
|
|
||||||
// Note: For Weather Blight, there is a "Disease Chance" (=0.1) setting. But according to MWSFD this feature
|
// 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;
|
float getWindSpeed() const;
|
||||||
|
|
||||||
|
/// Are we in an ash or blight storm?
|
||||||
|
bool isInStorm() const;
|
||||||
|
|
||||||
|
Ogre::Vector3 getStormDirection() const;
|
||||||
|
|
||||||
void advanceTime(double hours)
|
void advanceTime(double hours)
|
||||||
{
|
{
|
||||||
mTimePassed += hours*3600;
|
mTimePassed += hours*3600;
|
||||||
|
|
|
@ -1998,6 +1998,22 @@ namespace MWWorld
|
||||||
return 0.f;
|
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)
|
void World::getContainersOwnedBy (const MWWorld::Ptr& npc, std::vector<MWWorld::Ptr>& out)
|
||||||
{
|
{
|
||||||
const Scene::CellStoreCollection& collection = mWorldScene->getActiveCells();
|
const Scene::CellStoreCollection& collection = mWorldScene->getActiveCells();
|
||||||
|
@ -2313,6 +2329,7 @@ namespace MWWorld
|
||||||
{
|
{
|
||||||
MWMechanics::CreatureStats& stats = actor.getClass().getCreatureStats(actor);
|
MWMechanics::CreatureStats& stats = actor.getClass().getCreatureStats(actor);
|
||||||
|
|
||||||
|
// TODO: this only works for the player
|
||||||
MWWorld::Ptr target = getFacedObject();
|
MWWorld::Ptr target = getFacedObject();
|
||||||
|
|
||||||
std::string selectedSpell = stats.getSpells().getSelectedSpell();
|
std::string selectedSpell = stats.getSpells().getSelectedSpell();
|
||||||
|
|
|
@ -591,6 +591,12 @@ namespace MWWorld
|
||||||
const MWWorld::Ptr& caster, const std::string& id, const std::string& sourceName);
|
const MWWorld::Ptr& caster, const std::string& id, const std::string& sourceName);
|
||||||
|
|
||||||
virtual void activate (const MWWorld::Ptr& object, const MWWorld::Ptr& actor);
|
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;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue