Will I add these codes, does it work?
Code: Select all
CFlowNode_AIAnim::~CFlowNode_AIAnim()
{
OnCancel();
}
void CFlowNode_AIAnim::OnCancelPortActivated( IPipeUser* pPipeUser, SActivationInfo* pActInfo )
{
if ( m_iMethod == 2 ) // is method == Action?
{
pPipeUser->RemoveSubPipe( m_GoalPipeId, true );
OnCancel(); // only to reuse unregistering code
}
else
pPipeUser->CancelSubPipe( m_GoalPipeId );
}
void CFlowNode_AIAnim::OnCancel()
{
if ( m_pAGState )
{
m_pAGState->RemoveListener( this );
switch ( m_iMethod )
{
case 0:
if ( !m_bStarted )
m_pAGState->ClearForcedStates();
break;
case 1:
if ( !m_bStarted )
m_pAGState->SetInput( "Signal", "none" );
m_pAGState->Hurry();
break;
case 2:
m_pAGState->SetInput( "Action", "idle" );
break;
}
m_pAGState = NULL;
m_queryID = 0;
m_bStarted = false;
}
}
void CFlowNode_AIAnim::DestroyedState(IAnimationGraphState*)
{
m_pAGState = NULL;
m_queryID = 0;
m_bStarted = false;
}
void CFlowNode_AIAnim::OnEntityEvent( IEntity* pEntity, SEntityEvent& event )
{
TBase::OnEntityEvent( pEntity, event );
if ( event.event == ENTITY_EVENT_POST_SERIALIZE )
{
if ( IActor* pActor = gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(m_EntityId) )
{
m_pAGState = pActor->GetAnimationGraphState();
if ( m_pAGState != NULL )
{
m_pAGState->AddListener( "aianim", this );
if ( !m_bStarted )
{
IAnimationGraphState::InputID inputID = (IAnimationGraphState::InputID) -1;
switch ( m_iMethod )
{
case 1: // use "signal"
inputID = m_pAGState->GetInputId( "Signal" );
break;
case 2: // use "action"
inputID = m_pAGState->GetInputId( "Action" );
break;
}
if ( inputID != (IAnimationGraphState::InputID) -1 )
{
char inputValue[256];
m_pAGState->GetInput( inputID, inputValue );
m_pAGState->SetInput( inputID, inputValue, &m_queryID );
}
}
else
{
if ( m_iMethod <= 1 )
m_pAGState->QueryLeaveState( &m_queryID );
else
m_pAGState->QueryChangeInput( "Action", &m_queryID );
}
}
}
}
}
void CFlowNode_AIAnim::Serialize( SActivationInfo* pActInfo, TSerialize ser )
{
TBase::Serialize( pActInfo, ser );
ser.Value( "m_bStarted", m_bStarted );
ser.Value( "m_iMethod", m_iMethod );
if ( ser.IsReading() && m_pAGState != NULL )
{
m_pAGState->RemoveListener( this );
m_pAGState = NULL;
}
}
//
//-------------------------------------------------------------------------------------------------------------
void CFlowNode_AIAnim::GetConfiguration( SFlowNodeConfig &config )
{
static const SInputPortConfig in_config[] = {
InputPortConfig_Void( "sink", _HELP("for synchronization only"), _HELP("Sync") ),
InputPortConfig_Void( "cancel", _HELP("cancels execution (or stops the action)") ),
InputPortConfig<string>( "animstateEx_name", _HELP("name of animation to be played") ),
InputPortConfig<int>( "signal", 1, _HELP("which method to use"), _HELP("Method"), _UICONFIG("enum_int:Signal=1,Action=2") ),
//InputPortConfig<int>( "count", 1, _HELP("OBSOLETE PORT!!! Don't use it! Will be removed soon...") ),
{0}
};
static const SOutputPortConfig out_config[] = {
OutputPortConfig<EntityId>( "done", _HELP("action done") ),
OutputPortConfig<EntityId>( "succeed", _HELP("action done successfully") ),
OutputPortConfig<EntityId>( "fail", _HELP("action failed") ),
OutputPortConfig<EntityId>( "start", _HELP("activated on animation start") ),
{0}
};
config.sDescription = _HELP( "Plays animation" );
config.pInputPorts = in_config;
config.pOutputPorts = out_config;
config.nFlags |= EFLN_TARGET_ENTITY;
config.SetCategory(EFLN_APPROVED);
}
DEF_CLONE(CFlowNode_AIAnim)
//
//-------------------------------------------------------------------------------------------------------------
void CFlowNode_AIAnim::DoProcessEvent( EFlowEvent event, SActivationInfo* pActInfo )
{
IActor* pActor = gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor( m_EntityId );
if ( pActor )
{
m_pAGState = pActor->GetAnimationGraphState();
if (!m_pAGState)
return;
m_pAGState->AddListener( "aianim", this );
m_iMethod = GetPortInt( pActInfo, 3 );
switch ( m_iMethod )
{
case 0: // forced state
m_pAGState->PushForcedState( GetPortString( pActInfo, 2 ), &m_queryID );
break;
case 1: // use "signal"
m_pAGState->SetInput( "Signal", GetPortString( pActInfo, 2 ), &m_queryID );
break;
case 2: // use "action"
m_pAGState->SetInput( "Action", GetPortString( pActInfo, 2 ), &m_queryID );
break;
}
}
else
{
CRY_ASSERT(0);
}
if (!m_bStarted)
Execute( pActInfo, "ACT_ANIM" );
}
//
//-------------------------------------------------------------------------------------------------------------
void CFlowNode_AIAnim::QueryComplete( TAnimationGraphQueryID queryID, bool succeeded )
{
IEntity* pEntity = gEnv->pEntitySystem->GetEntity( m_EntityId );
if ( !pEntity )
return;
if ( queryID != m_queryID )
return;
IAIObject* pAI = pEntity->GetAI();
if ( succeeded || m_bStarted && m_iMethod == 2 )
{
if ( !m_bStarted )
{
m_bStarted = true;
// if "signal" wait to leave current state
// if "action" wait for input value change
if ( m_iMethod <= 1 )
m_pAGState->QueryLeaveState( &m_queryID );
else
m_pAGState->QueryChangeInput( "Action", &m_queryID );
// activate "Start" output port
SFlowAddress start( m_nodeID, 3, true );
m_pGraph->ActivatePort( start, m_EntityId );
}
else
{
if ( pAI )
{
IPipeUser* pPipeUser = pAI->CastToIPipeUser();
if (pPipeUser)
pPipeUser->RemoveSubPipe( m_GoalPipeId, true );
}
if ( m_pAGState )
{
m_pAGState->RemoveListener( this );
m_pAGState = NULL;
m_queryID = 0;
m_bStarted = false;
}
}
}
else if ( pAI )
{
IPipeUser* pPipeUser = pAI->CastToIPipeUser();
if (pPipeUser)
pPipeUser->CancelSubPipe( m_GoalPipeId );
}
}