//----------------------------------------------------------------------------- // // $Logfile:: /Code/DLLs/game/actor_posturecontroller.cpp $ // $Revision:: 8 $ // $Author:: Steven $ // $Date:: 5/04/03 2:02p $ // // Copyright (C) 2002 by Ritual Entertainment, Inc. // All rights reserved. // // This source may not be distributed and/or modified without // expressly written permission by Ritual Entertainment, Inc. // //----------------------------------------------------------------------------- #include "_pch_cpp.h" #include "actor_posturecontroller.hpp" extern Event EV_Actor_SetPostureStateMap; //-------------------------------------------------------------- // Name: PostureController() // Class: PostureController // // Description: Constructor // // Parameters: None // // Returns: None //-------------------------------------------------------------- PostureController::PostureController() { // Should always use other constructor gi.Error( ERR_FATAL, "PostureController::PostureController -- Default Constructor Called" ); } //-------------------------------------------------------------- // Name: PostureController() // Class: PostureController // // Description: Constructor // // Parameters: Actor *actor // // Returns: None //-------------------------------------------------------------- PostureController::PostureController( Actor *actor ) { if ( actor ) act = actor; else gi.Error( ERR_DROP, "PostureController::PostureController -- actor is NULL" ); init(); } //-------------------------------------------------------------- // Name: ~PostureController() // Class: PostureController // // Description: Destructor // // Parameters: None // // Returns: None //-------------------------------------------------------------- PostureController::~PostureController() { act->freeConditionals( _postureConditionals ); } //-------------------------------------------------------------- // Name: DoArchive() // Class: PostureController // // Description: Archives our Actor and Calls our Archive Function // // Parameters: Archiver &arc -- The Archiver Object // Actor *actor -- The pointer to our actor // // Returns: None //-------------------------------------------------------------- void PostureController::DoArchive( Archiver &arc, Actor *actor ) { Archive( arc ); if ( actor ) act = actor; else gi.Error( ERR_FATAL, "PostureController::DoArchive -- actor is NULL" ); } //-------------------------------------------------------------- // Name: Archive() // Class: PostureController // // Description: Archives the class // // Parameters: Archiver &arc // // Returns: None //-------------------------------------------------------------- void PostureController::Archive( Archiver &arc ) { arc.ArchiveString( &_postureStateMap_Name ); arc.ArchiveString( &_currentPostureState_Name ); arc.ArchiveString( &_requestedPostureState_Name ); arc.ArchiveSafePointer ( &_requestor ); if ( !arc.Saving() ) { if ( _postureStateMap_Name.length() ) { Event *event; event = new Event( EV_Actor_SetPostureStateMap ); event->AddString( _postureStateMap_Name ); event->AddInteger( 1 ); act->ProcessEvent ( event ); _currentPostureState = _postureStateMap->FindState( _currentPostureState_Name.c_str() ); _requestedPostureState = _postureStateMap->FindState(_requestedPostureState_Name.c_str() ); } } } //-------------------------------------------------------------- // Name: init() // Class: PostureController // // Description: Initializes the class // // Parameters: None // // Returns: None //-------------------------------------------------------------- void PostureController::init() { _postureStateMap = NULL; _postureStateMap_Name = ""; _currentPostureState = NULL; _currentPostureState_Name = ""; _requestedPostureState = NULL; _requestedPostureState_Name = ""; _requestor = NULL; } //-------------------------------------------------------------- // Name: evaluate() // Class: PostureController // // Description: Evaluation Routine, Called Every Frame // // Parameters: None // // Returns: None //-------------------------------------------------------------- void PostureController::evaluate() { int count; State *laststate = NULL; str currentanim; str stateLegAnim; stateLegAnim = act->animname; count = 0; if ( !_postureStateMap ) return; if ( act->deadflag || !_currentPostureState ) return; do { // Since we could get into an infinite loop here, do a check to make sure we don't. count++; if ( count > 10 ) { gi.WDPrintf( "Possible infinite loop in posture state '%s'\n", _currentPostureState->getName() ); if ( count > 50 ) { gi.Error( ERR_DROP, "Stopping due to possible infinite state loop\n" ); break; } } // Determine the next state to go to laststate = _currentPostureState; _currentPostureState = _currentPostureState->Evaluate( *act, &_postureConditionals ); if ( !_currentPostureState ) return; _currentPostureState_Name = _currentPostureState->getName(); // Change the behavior if the state has changed if ( laststate != _currentPostureState ) { // Initialize some stuff for changing states act->SetActorFlag( ACTOR_FLAG_POSTURE_ANIM_DONE, false ); } if ( _currentPostureState == _requestedPostureState ) { if ( _requestor ) _requestor->ProcessEvent( EV_PostureChanged_Completed ); } // Change the animation if it has changed currentanim = _currentPostureState->getLegAnim( *act, &_postureConditionals ); if ( currentanim.length() && ( stricmp( stateLegAnim , currentanim.c_str() ) != 0 ) ) { act->SetAnim( currentanim, EV_Posture_Anim_Done, legs ); stateLegAnim = currentanim; } } while( laststate != _currentPostureState ); } //-------------------------------------------------------------- // Name: requestPosture() // Class: PostureController // // Description: Request Handler for a specific Posture // // Parameters: PostureStates_t postureState // // Returns: true -- if the posture is viable // false -- if the posture in not viable //-------------------------------------------------------------- bool PostureController::requestPosture( const str &postureState , Listener *requestor ) { if ( !_postureStateMap ) return false; _requestedPostureState = _postureStateMap->FindState( postureState.c_str() ); if ( _requestedPostureState ) { _requestor = requestor; _requestedPostureState_Name = postureState; return true; } return false; } void PostureController::setPostureStateMap( const str &stateMap , bool loading ) { str animName; // Load the new state map _postureStateMap_Name = stateMap; //_postureConditionals.FreeObjectList(); act->freeConditionals( _postureConditionals ); _postureStateMap = GetStatemap( _postureStateMap_Name, ( Condition * )act->Conditions, &_postureConditionals, false ); // Set the first state _currentPostureState_Name = "START"; // Initialize the actors first animation if ( !loading ) setPostureState( _currentPostureState_Name.c_str() ); } void PostureController::setPostureState( const str &postureState ) { if ( !_postureStateMap ) return; if ( act->deadflag ) return; _currentPostureState = _postureStateMap->FindState( postureState.c_str() ); } void PostureController::setPostureState( const str &postureState, const str &requestedState ) { if ( !_postureStateMap ) return; if ( act->deadflag ) return; _currentPostureState = _postureStateMap->FindState( postureState.c_str() ); _requestedPostureState = _postureStateMap->FindState( requestedState.c_str() ); _requestedPostureState_Name = requestedState.c_str(); }