1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-03-30 16:20:21 +00:00

Merge remote-tracking branch 'emperorarthur/anim_fail'

This commit is contained in:
Marc Zinnschlag 2015-08-08 10:47:46 +02:00
commit d29862eac3
11 changed files with 66 additions and 24 deletions

View File

@ -160,12 +160,13 @@ namespace MWBase
virtual void forceStateUpdate(const MWWorld::Ptr &ptr) = 0; virtual void forceStateUpdate(const MWWorld::Ptr &ptr) = 0;
///< Forces an object to refresh its animation state. ///< Forces an object to refresh its animation state.
virtual void playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number=1) = 0; virtual bool playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number=1) = 0;
///< Run animation for a MW-reference. Calls to this function for references that are currently not ///< Run animation for a MW-reference. Calls to this function for references that are currently not
/// in the scene should be ignored. /// in the scene should be ignored.
/// ///
/// \param mode 0 normal, 1 immediate start, 2 immediate loop /// \param mode 0 normal, 1 immediate start, 2 immediate loop
/// \param count How many times the animation should be run /// \param count How many times the animation should be run
/// \return Success or error
virtual void skipAnimation(const MWWorld::Ptr& ptr) = 0; virtual void skipAnimation(const MWWorld::Ptr& ptr) = 0;
///< Skip the animation for the given MW-reference for one frame. Calls to this function for ///< Skip the animation for the given MW-reference for one frame. Calls to this function for

View File

@ -1,6 +1,7 @@
#include "actors.hpp" #include "actors.hpp"
#include <typeinfo> #include <typeinfo>
#include <iostream>
#include <osg/PositionAttitudeTransform> #include <osg/PositionAttitudeTransform>
@ -1245,11 +1246,18 @@ namespace MWMechanics
iter->second->getCharacterController()->forceStateUpdate(); iter->second->getCharacterController()->forceStateUpdate();
} }
void Actors::playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number) bool Actors::playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number)
{ {
PtrActorMap::iterator iter = mActors.find(ptr); PtrActorMap::iterator iter = mActors.find(ptr);
if(iter != mActors.end()) if(iter != mActors.end())
iter->second->getCharacterController()->playGroup(groupName, mode, number); {
return iter->second->getCharacterController()->playGroup(groupName, mode, number);
}
else
{
std::cerr<< "Error in Actors::playAnimationGroup: Unable to find " << ptr.getTypeName() << std::endl;
return false;
}
} }
void Actors::skipAnimation(const MWWorld::Ptr& ptr) void Actors::skipAnimation(const MWWorld::Ptr& ptr)
{ {

View File

@ -105,7 +105,7 @@ namespace MWMechanics
void forceStateUpdate(const MWWorld::Ptr &ptr); void forceStateUpdate(const MWWorld::Ptr &ptr);
void playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number); bool playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number);
void skipAnimation(const MWWorld::Ptr& ptr); void skipAnimation(const MWWorld::Ptr& ptr);
bool checkAnimationPlaying(const MWWorld::Ptr& ptr, const std::string& groupName); bool checkAnimationPlaying(const MWWorld::Ptr& ptr, const std::string& groupName);

View File

@ -1,6 +1,7 @@
#include "aiwander.hpp" #include "aiwander.hpp"
#include <cfloat> #include <cfloat>
#include <iostream>
#include <components/misc/rng.hpp> #include <components/misc/rng.hpp>
@ -57,7 +58,6 @@ namespace MWMechanics
bool mTurnActorGivingGreetingToFacePlayer; bool mTurnActorGivingGreetingToFacePlayer;
float mReaction; // update some actions infrequently float mReaction; // update some actions infrequently
AiWander::GreetingState mSaidGreeting; AiWander::GreetingState mSaidGreeting;
int mGreetingTimer; int mGreetingTimer;
@ -67,6 +67,7 @@ namespace MWMechanics
AiWander::WanderState mState; AiWander::WanderState mState;
unsigned short mIdleAnimation; unsigned short mIdleAnimation;
std::vector<unsigned short> mBadIdles; // Idle animations that when called cause errors
PathFinder mPathFinder; PathFinder mPathFinder;
@ -78,7 +79,8 @@ namespace MWMechanics
mGreetingTimer(0), mGreetingTimer(0),
mCell(NULL), mCell(NULL),
mState(AiWander::Wander_ChooseAction), mState(AiWander::Wander_ChooseAction),
mIdleAnimation(0) mIdleAnimation(0),
mBadIdles()
{}; {};
}; };
@ -394,15 +396,23 @@ namespace MWMechanics
if (!idleAnimation && mDistance) if (!idleAnimation && mDistance)
{ {
storage.mState = Wander_MoveNow; storage.mState = Wander_MoveNow;
return;
} }
else if(idleAnimation)
{ {
// Play idle animation and recreate vanilla (broken?) behavior of resetting start time of AIWander: if(std::find(storage.mBadIdles.begin(), storage.mBadIdles.end(), idleAnimation)==storage.mBadIdles.end())
MWWorld::TimeStamp currentTime = MWBase::Environment::get().getWorld()->getTimeStamp(); {
mStartTime = currentTime; if(!playIdle(actor, idleAnimation))
playIdle(actor, idleAnimation); {
storage.mState = Wander_IdleNow; storage.mBadIdles.push_back(idleAnimation);
storage.mState = Wander_ChooseAction;
return;
}
}
} }
// Recreate vanilla (broken?) behavior of resetting start time of AIWander:
mStartTime = MWBase::Environment::get().getWorld()->getTimeStamp();
storage.mState = Wander_IdleNow;
} }
void AiWander::evadeObstacles(const MWWorld::Ptr& actor, AiWanderStorage& storage, float duration) void AiWander::evadeObstacles(const MWWorld::Ptr& actor, AiWanderStorage& storage, float duration)
@ -621,12 +631,17 @@ namespace MWMechanics
actor.getClass().getMovementSettings(actor).mPosition[1] = 0; actor.getClass().getMovementSettings(actor).mPosition[1] = 0;
} }
void AiWander::playIdle(const MWWorld::Ptr& actor, unsigned short idleSelect) bool AiWander::playIdle(const MWWorld::Ptr& actor, unsigned short idleSelect)
{ {
if ((GroupIndex_MinIdle <= idleSelect) && (idleSelect <= GroupIndex_MaxIdle)) if ((GroupIndex_MinIdle <= idleSelect) && (idleSelect <= GroupIndex_MaxIdle))
{ {
const std::string& groupName = sIdleSelectToGroupName[idleSelect - GroupIndex_MinIdle]; const std::string& groupName = sIdleSelectToGroupName[idleSelect - GroupIndex_MinIdle];
MWBase::Environment::get().getMechanicsManager()->playAnimationGroup(actor, groupName, 0, 1); return MWBase::Environment::get().getMechanicsManager()->playAnimationGroup(actor, groupName, 0, 1);
}
else
{
std::cerr<< "Attempted to play out of range idle animation \""<<idleSelect<<"\" for " << actor.getCellRef().getRefId() << std::endl;
return false;
} }
} }

View File

@ -75,7 +75,10 @@ namespace MWMechanics
void init(); void init();
void stopWalking(const MWWorld::Ptr& actor, AiWanderStorage& storage); void stopWalking(const MWWorld::Ptr& actor, AiWanderStorage& storage);
void playIdle(const MWWorld::Ptr& actor, unsigned short idleSelect);
/// Have the given actor play an idle animation
/// @return Success or error
bool playIdle(const MWWorld::Ptr& actor, unsigned short idleSelect);
bool checkIdle(const MWWorld::Ptr& actor, unsigned short idleSelect); bool checkIdle(const MWWorld::Ptr& actor, unsigned short idleSelect);
short unsigned getRandomIdle(); short unsigned getRandomIdle();
void setPathToAnAllowedNode(const MWWorld::Ptr& actor, AiWanderStorage& storage, const ESM::Position& actorPos); void setPathToAnAllowedNode(const MWWorld::Ptr& actor, AiWanderStorage& storage, const ESM::Position& actorPos);

View File

@ -1871,10 +1871,13 @@ void CharacterController::update(float duration)
} }
void CharacterController::playGroup(const std::string &groupname, int mode, int count) bool CharacterController::playGroup(const std::string &groupname, int mode, int count)
{ {
if(!mAnimation || !mAnimation->hasAnimation(groupname)) if(!mAnimation || !mAnimation->hasAnimation(groupname))
{
std::cerr<< "Animation "<<groupname<<" not found for " << mPtr.getCellRef().getRefId() << std::endl; std::cerr<< "Animation "<<groupname<<" not found for " << mPtr.getCellRef().getRefId() << std::endl;
return false;
}
else else
{ {
count = std::max(count, 1); count = std::max(count, 1);
@ -1899,6 +1902,7 @@ void CharacterController::playGroup(const std::string &groupname, int mode, int
mAnimQueue.push_back(std::make_pair(groupname, count-1)); mAnimQueue.push_back(std::make_pair(groupname, count-1));
} }
} }
return true;
} }
void CharacterController::skipAnim() void CharacterController::skipAnim()

View File

@ -226,7 +226,7 @@ public:
void update(float duration); void update(float duration);
void playGroup(const std::string &groupname, int mode, int count); bool playGroup(const std::string &groupname, int mode, int count);
void skipAnim(); void skipAnim();
bool isAnimPlaying(const std::string &groupName); bool isAnimPlaying(const std::string &groupName);

View File

@ -843,12 +843,12 @@ namespace MWMechanics
mActors.forceStateUpdate(ptr); mActors.forceStateUpdate(ptr);
} }
void MechanicsManager::playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number) bool MechanicsManager::playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number)
{ {
if(ptr.getClass().isActor()) if(ptr.getClass().isActor())
mActors.playAnimationGroup(ptr, groupName, mode, number); return mActors.playAnimationGroup(ptr, groupName, mode, number);
else else
mObjects.playAnimationGroup(ptr, groupName, mode, number); return mObjects.playAnimationGroup(ptr, groupName, mode, number);
} }
void MechanicsManager::skipAnimation(const MWWorld::Ptr& ptr) void MechanicsManager::skipAnimation(const MWWorld::Ptr& ptr)
{ {

View File

@ -137,7 +137,9 @@ namespace MWMechanics
virtual void forceStateUpdate(const MWWorld::Ptr &ptr); virtual void forceStateUpdate(const MWWorld::Ptr &ptr);
virtual void playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number); /// Attempt to play an animation group
/// @return Success or error
virtual bool playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number);
virtual void skipAnimation(const MWWorld::Ptr& ptr); virtual void skipAnimation(const MWWorld::Ptr& ptr);
virtual bool checkAnimationPlaying(const MWWorld::Ptr& ptr, const std::string &groupName); virtual bool checkAnimationPlaying(const MWWorld::Ptr& ptr, const std::string &groupName);

View File

@ -1,5 +1,7 @@
#include "objects.hpp" #include "objects.hpp"
#include <iostream>
#include "movement.hpp" #include "movement.hpp"
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
@ -77,11 +79,18 @@ void Objects::update(float duration, bool paused)
} }
} }
void Objects::playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number) bool Objects::playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number)
{ {
PtrControllerMap::iterator iter = mObjects.find(ptr); PtrControllerMap::iterator iter = mObjects.find(ptr);
if(iter != mObjects.end()) if(iter != mObjects.end())
iter->second->playGroup(groupName, mode, number); {
return iter->second->playGroup(groupName, mode, number);
}
else
{
std::cerr<< "Error in Objects::playAnimationGroup: Unable to find " << ptr.getTypeName() << std::endl;
return false;
}
} }
void Objects::skipAnimation(const MWWorld::Ptr& ptr) void Objects::skipAnimation(const MWWorld::Ptr& ptr)
{ {

View File

@ -38,7 +38,7 @@ namespace MWMechanics
void update(float duration, bool paused); void update(float duration, bool paused);
///< Update object animations ///< Update object animations
void playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number); bool playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number);
void skipAnimation(const MWWorld::Ptr& ptr); void skipAnimation(const MWWorld::Ptr& ptr);
void getObjectsInRange (const osg::Vec3f& position, float radius, std::vector<MWWorld::Ptr>& out); void getObjectsInRange (const osg::Vec3f& position, float radius, std::vector<MWWorld::Ptr>& out);