@ -444,64 +444,58 @@ void Animation::updatePosition(float oldtime, float newtime, Ogre::Vector3 &posi
bool Animation : : reset ( AnimState & state , const NifOgre : : TextKeyMap & keys , const std : : string & groupname , const std : : string & start , const std : : string & stop , float startpoint )
{
std : : string tag = groupname + " : " + start ;
NifOgre : : TextKeyMap : : const_iterator startkey ( keys . begin ( ) ) ;
while ( startkey ! = keys . end ( ) & & startkey - > second ! = tag )
const NifOgre : : TextKeyMap : : const_iterator groupstart = findGroupStart ( keys , groupname ) ;
std : : string starttag = groupname + " : " + start ;
NifOgre : : TextKeyMap : : const_iterator startkey ( groupstart ) ;
while ( startkey ! = keys . end ( ) & & startkey - > second ! = starttag )
startkey + + ;
if ( startkey = = keys . end ( ) & & start = = " loop start " )
{
tag = groupname + " : start " ;
startkey = keys. begin ( ) ;
while ( startkey ! = keys . end ( ) & & startkey - > second ! = tag)
start tag = groupname + " : start " ;
startkey = groupstart ;
while ( startkey ! = keys . end ( ) & & startkey - > second ! = start tag)
startkey + + ;
}
if ( startkey = = keys . end ( ) )
return false ;
tag = groupname + " : " + stop ;
NifOgre : : TextKeyMap : : const_iterator stopkey ( startkey ) ;
while ( stopkey ! = keys . end ( ) & & stopkey - > second ! = tag)
const std: : string stop tag = groupname + " : " + stop ;
NifOgre : : TextKeyMap : : const_iterator stopkey ( group start) ;
while ( stopkey ! = keys . end ( ) & & stopkey - > second ! = stop tag)
stopkey + + ;
if ( stopkey = = keys . end ( ) )
return false ;
if ( startkey = = stopkey )
if ( startkey - > first > stopkey - > first )
return false ;
state . mStartKey = startkey ;
state . mLoopStartKey = startkey ;
state . mStopKey = stopkey ;
state . mNextKey = startkey ;
state . mTime = state . mStartKey - > first + ( ( state . mStopKey - > first - state . mStartKey - > first ) * startpoint ) ;
state . mStartTime = startkey - > first ;
state . mLoopStartTime = startkey - > first ;
state . mLoopStopTime = stopkey - > first ;
state . mStopTime = stopkey - > first ;
tag = groupname + " : loop start " ;
while( state . mNextKey - > first < = state . mTime & & state . mNextKey ! = state . mStopKey )
state . mTime = state . mStartTime + ( ( state . mStopTime - state . mStartTime ) * startpoint ) ;
if( state . mTime > state . mStartTime )
{
if ( state . mNextKey - > second = = tag )
state . mLoopStartKey = state . mNextKey ;
state . mNextKey + + ;
const std : : string loopstarttag = groupname + " : loop start " ;
const std : : string loopstoptag = groupname + " : loop stop " ;
NifOgre : : TextKeyMap : : const_iterator key ( groupstart ) ;
while ( key - > first < = state . mTime & & key ! = stopkey )
{
if ( key - > second = = loopstarttag )
state . mLoopStartTime = key - > first ;
else if ( key - > second = = loopstoptag )
state . mLoopStopTime = key - > first ;
key + + ;
}
}
return true ;
}
bool Animation : : doLoop ( AnimState & state )
{
if ( state . mLoopCount = = 0 )
return false ;
state . mLoopCount - - ;
state . mTime = state . mLoopStartKey - > first ;
state . mNextKey = state . mLoopStartKey ;
state . mNextKey + + ;
state . mPlaying = true ;
return true ;
}
bool Animation : : handleTextKey ( AnimState & state , const std : : string & groupname , const NifOgre : : TextKeyMap : : const_iterator & key )
void Animation : : handleTextKey ( AnimState & state , const std : : string & groupname , const NifOgre : : TextKeyMap : : const_iterator & key )
{
float time = key - > first ;
const std : : string & evt = key - > second ;
@ -510,7 +504,7 @@ bool Animation::handleTextKey(AnimState &state, const std::string &groupname, co
{
MWBase : : SoundManager * sndMgr = MWBase : : Environment : : get ( ) . getSoundManager ( ) ;
sndMgr - > playSound3D ( mPtr , evt . substr ( 7 ) , 1.0f , 1.0f ) ;
return true ;
return ;
}
if ( evt . compare ( 0 , 10 , " soundgen: " ) = = 0 )
{
@ -523,28 +517,22 @@ bool Animation::handleTextKey(AnimState &state, const std::string &groupname, co
type = MWBase : : SoundManager : : Play_TypeFoot ;
sndMgr - > playSound3D ( mPtr , sound , 1.0f , 1.0f , type ) ;
}
return true ;
return ;
}
if ( evt . compare ( 0 , groupname . size ( ) , groupname ) ! = 0 | |
evt . compare ( groupname . size ( ) , 2 , " : " ) ! = 0 )
{
// Not ours, skip it
return true ;
return ;
}
size_t off = groupname . size ( ) + 2 ;
size_t len = evt . size ( ) - off ;
if ( evt . compare ( off , len , " start " ) = = 0 | | evt . compare ( off , len , " loop start " ) = = 0 )
state . mLoopStartKey = key ;
else if ( evt . compare ( off , len , " loop stop " ) = = 0 | | evt . compare ( off , len , " stop " ) = = 0 )
{
if ( doLoop ( state ) )
{
if ( state . mTime > = time )
return false ;
}
}
if ( evt . compare ( off , len , " loop start " ) = = 0 )
state . mLoopStartTime = key - > first ;
else if ( evt . compare ( off , len , " loop stop " ) = = 0 )
state . mLoopStopTime = key - > first ;
else if ( evt . compare ( off , len , " equip attach " ) = = 0 )
showWeapons ( true ) ;
else if ( evt . compare ( off , len , " unequip detach " ) = = 0 )
@ -557,8 +545,6 @@ bool Animation::handleTextKey(AnimState &state, const std::string &groupname, co
MWWorld : : Class : : get ( mPtr ) . attack ( mPtr , MWMechanics : : CreatureStats : : AT_Thrust ) ;
else if ( evt . compare ( off , len , " hit " ) = = 0 )
MWWorld : : Class : : get ( mPtr ) . attack ( mPtr , - 1 ) ;
return true ;
}
@ -596,8 +582,9 @@ void Animation::play(const std::string &groupname, int priority, int groups, boo
AnimSourceList : : reverse_iterator iter ( mAnimSources . rbegin ( ) ) ;
for ( ; iter ! = mAnimSources . rend ( ) ; iter + + )
{
const NifOgre : : TextKeyMap & textkeys = ( * iter ) - > mTextKeys ;
AnimState state ;
if ( reset ( state , ( * iter ) - > mTextK eys, groupname , start , stop , startpoint ) )
if ( reset ( state , textk eys, groupname , start , stop , startpoint ) )
{
state . mSource = * iter ;
state . mSpeedMult = speedmult ;
@ -608,6 +595,13 @@ void Animation::play(const std::string &groupname, int priority, int groups, boo
state . mAutoDisable = autodisable ;
mStates [ groupname ] = state ;
NifOgre : : TextKeyMap : : const_iterator textkey ( textkeys . lower_bound ( state . mTime ) ) ;
while ( textkey ! = textkeys . end ( ) & & textkey - > first < = state . mTime )
{
handleTextKey ( state , groupname , textkey ) ;
textkey + + ;
}
break ;
}
}
@ -668,29 +662,25 @@ void Animation::resetActiveGroups()
}
bool Animation : : getInfo ( const std : : string & groupname , float * complete , float * speedmult , std : : string * start , std : : string * stop ) const
bool Animation : : getInfo ( const std : : string & groupname , float * complete , float * speedmult ) const
{
AnimStateMap : : const_iterator iter = mStates . find ( groupname ) ;
if ( iter = = mStates . end ( ) )
{
if ( complete ) * complete = 0.0f ;
if ( speedmult ) * speedmult = 0.0f ;
if ( start ) * start = " " ;
if ( stop ) * stop = " " ;
return false ;
}
if ( complete )
{
if ( iter - > second . mStop Key- > first > iter - > second . mStartKey - > first )
* complete = ( iter - > second . mTime - iter - > second . mStart Key- > first ) /
( iter - > second . mStop Key- > first - iter - > second . mStartKey - > first ) ;
if ( iter - > second . mStop Time > iter - > second . mStartTime )
* complete = ( iter - > second . mTime - iter - > second . mStart Time ) /
( iter - > second . mStop Time - iter - > second . mStartTime ) ;
else
* complete = ( iter - > second . mPlaying ? 0.0f : 1.0f ) ;
}
if ( speedmult ) * speedmult = iter - > second . mSpeedMult ;
if ( start ) * start = iter - > second . mStartKey - > second . substr ( groupname . size ( ) + 2 ) ;
if ( stop ) * stop = iter - > second . mStopKey - > second . substr ( groupname . size ( ) + 2 ) ;
return true ;
}
@ -712,27 +702,52 @@ Ogre::Vector3 Animation::runAnimation(float duration)
while ( stateiter ! = mStates . end ( ) )
{
AnimState & state = stateiter - > second ;
const NifOgre : : TextKeyMap & textkeys = state . mSource - > mTextKeys ;
NifOgre : : TextKeyMap : : const_iterator textkey ( textkeys . upper_bound ( state . mTime ) ) ;
float timepassed = duration * state . mSpeedMult ;
while ( state . mPlaying )
{
float targetTime = state . mTime + timepassed ;
if ( state. mNextK ey- > first > targetTime )
if ( textkey = = textkeys . end ( ) | | textk ey- > first > targetTime )
{
if ( mNonAccumCtrl & & stateiter - > first = = mAnimationValuePtr [ 0 ] - > getAnimName ( ) )
updatePosition ( state . mTime , targetTime , movement ) ;
state . mTime = targetTime ;
break ;
state . mTime = std : : min ( targetTime , state . mStopTime ) ;
}
else
{
if ( mNonAccumCtrl & & stateiter - > first = = mAnimationValuePtr [ 0 ] - > getAnimName ( ) )
updatePosition ( state . mTime , textkey - > first , movement ) ;
state . mTime = textkey - > first ;
}
NifOgre : : TextKeyMap : : const_iterator key ( state . mNextKey + + ) ;
if ( mNonAccumCtrl & & stateiter - > first = = mAnimationValuePtr [ 0 ] - > getAnimName ( ) )
updatePosition ( state . mTime , key - > first , movement ) ;
state . mTime = key - > first ;
state . mPlaying = ( key ! = state . mStopKey ) ;
state . mPlaying = ( state . mTime < state . mStopTime ) ;
timepassed = targetTime - state . mTime ;
if ( ! handleTextKey ( state , stateiter - > first , key ) )
while ( textkey ! = textkeys . end ( ) & & textkey - > first < = state . mTime )
{
handleTextKey ( state , stateiter - > first , textkey ) ;
textkey + + ;
}
if ( state . mTime > = state . mLoopStopTime & & state . mLoopCount > 0 )
{
state . mLoopCount - - ;
state . mTime = state . mLoopStartTime ;
state . mPlaying = true ;
if ( state . mTime > = state . mLoopStopTime )
break ;
textkey = textkeys . lower_bound ( state . mTime ) ;
while ( textkey ! = textkeys . end ( ) & & textkey - > first < = state . mTime )
{
handleTextKey ( state , stateiter - > first , textkey ) ;
textkey + + ;
}
}
if ( timepassed < = 0.0f )
break ;
}