diff --git a/source/player/psidle.cpp b/source/player/psidle.cpp index 40e2ff565..29358f8a2 100644 --- a/source/player/psidle.cpp +++ b/source/player/psidle.cpp @@ -58,6 +58,16 @@ Vars ---- */ +CPlayerStateIdle::IdleAnims CPlayerStateIdle::s_idleAnims[]= +{ + // start frame loop frame end frame loop count + { -1, ANIM_PLAYER_ANIM_IDLEGENERIC04, -1, 4 }, + { -1, ANIM_PLAYER_ANIM_IDLEGENERIC04, -1, 10 }, + { -1, ANIM_PLAYER_ANIM_IDLEGENERIC03, -1, 3 }, +}; +int CPlayerStateIdle::s_numIdleAnims=sizeof(CPlayerStateIdle::s_idleAnims)/sizeof(CPlayerStateIdle::IdleAnims); + + /*---------------------------------------------------------------------- Function: Purpose: @@ -66,7 +76,11 @@ ---------------------------------------------------------------------- */ void CPlayerStateIdle::enter(CPlayer *_player) { - setAnimNo(_player,ANIM_PLAYER_ANIM_IDLEGENERIC04); + m_idleTime=0; + m_currentIdleAnim=0; + m_animState=ANIMSTATE_END; + + setNextIdleAnim(_player); } @@ -99,13 +113,99 @@ void CPlayerStateIdle::think(CPlayer *_player) } else if(advanceAnimFrameAndCheckForEndOfAnim(_player)) { - if(getRndRange(100)<95) - setAnimNo(_player,ANIM_PLAYER_ANIM_IDLEGENERIC04); - else - setAnimNo(_player,ANIM_PLAYER_ANIM_IDLEGENERIC03); + setNextIdleAnim(_player); } } +/*---------------------------------------------------------------------- + Function: + Purpose: + Params: + Returns: + ---------------------------------------------------------------------- */ +void CPlayerStateIdle::setNextIdleAnim(CPlayer *_player) +{ + IdleAnims *anims; + int finished=false; + + anims=&s_idleAnims[m_currentIdleAnim]; + switch(m_animState) + { + case ANIMSTATE_START: + m_animState=ANIMSTATE_LOOP; + setAnimNo(_player,anims->m_loopFrame); + break; + case ANIMSTATE_LOOP: + if(--m_loopCount<=0) + { + if(anims->m_endFrame==-1) + { + finished=true; + } + else + { + m_animState=ANIMSTATE_END; + setAnimNo(_player,anims->m_endFrame); + } + } + else + { + setAnimNo(_player,anims->m_loopFrame); + } + break; + case ANIMSTATE_END: + finished=true; + break; + } + + if(finished) + { + int animNo; + if(m_idleTime<5) + { + m_currentIdleAnim=0; // First anim in list is the default idle + } + else + { + if(s_numIdleAnims) + { + // Randomly choose the next anim to run + int lastAnim; + lastAnim=m_currentIdleAnim; + do + { + m_currentIdleAnim=getRndRange(s_numIdleAnims); + }while(m_currentIdleAnim==lastAnim); + } + else + { + m_currentIdleAnim=0; + } + } + + // Start playing the anim + anims=&s_idleAnims[m_currentIdleAnim]; + if(anims->m_startFrame==-1) + { + // No start anim - go straight into loop + animNo=anims->m_loopFrame; + m_animState=ANIMSTATE_LOOP; + } + else + { + // Play start anim for this idle + animNo=anims->m_startFrame; + m_animState=ANIMSTATE_START; + } + m_loopCount=anims->m_loopCount; + setAnimNo(_player,animNo); + + m_idleTime++; + } + +} + + /*=========================================================================== end */ diff --git a/source/player/psidle.h b/source/player/psidle.h index 0233bb2e7..b8b9a8377 100644 --- a/source/player/psidle.h +++ b/source/player/psidle.h @@ -38,6 +38,31 @@ public: void enter(class CPlayer *_player); void think(class CPlayer *_player); +private: + typedef struct + { + int m_startFrame; // Or -1 for none + int m_loopFrame; // Must exist + int m_endFrame; // Or -1 for none + int m_loopCount; // Number of times to run m_loopFrame; + } IdleAnims; + + typedef enum + { + ANIMSTATE_START, + ANIMSTATE_LOOP, + ANIMSTATE_END, + } ANIMSTATE; + + void setNextIdleAnim(class CPlayer *_player); + + int m_idleTime; // Number of idle anims that have been started + int m_currentIdleAnim; + ANIMSTATE m_animState; + int m_loopCount; // Number of times to loop middle section of anim + + static IdleAnims s_idleAnims[]; + static int s_numIdleAnims; };