void CAIHumanStateAttackMove::UpdateAnimation() { super::UpdateAnimation(); GetAnimationContext()->SetProp(kAPG_Posture, kAP_Stand); GetAnimationContext()->SetProp(kAPG_WeaponPosition, kAP_Up); switch( m_eAttackMove ) { // Step. case kAP_ShuffleRight: case kAP_ShuffleLeft: GetAnimationContext()->SetProp( kAPG_Evasive, m_eAttackMove ); GetAnimationContext()->Lock(); break; // BackUp. case kAP_BackUp: case kAP_FlankLeft: case kAP_FlankRight: m_pStrategyShoot->UpdateAnimation(); m_pStrategyFollowPath->UpdateAnimation(); break; default: AIASSERT( 0, GetAI()->m_hObject, "CAIHumanStateAttackMove::UpdateAnimation: Unexpected attack move." ); } }
void CAIHumanStateLaunch::UpdateAnimation() { super::UpdateAnimation(); GetAnimationContext()->SetProp( kAPG_Posture, kAP_Stand ); GetAnimationContext()->SetProp( kAPG_WeaponPosition, kAP_Down ); GetAnimationContext()->SetProp( kAPG_Movement, m_eLaunchMovement ); }
void CAIHumanStateAttackProne::UpdateAnimation() { super::UpdateAnimation(); GetAnimationContext()->SetProp(kAPG_Posture, kAP_Prone); GetAnimationContext()->SetProp(kAPG_WeaponPosition, kAP_Up); m_pStrategyShoot->UpdateAnimation(); }
//---------------------------------------------------------------------------- // // ROUTINE: CAIHumanStateResurrecting::GetDeathAni() // // PURPOSE: // //---------------------------------------------------------------------------- /*virtual*/ HMODELANIM CAIHumanStateResurrecting::GetDeathAni(LTBOOL bFront) { if ( !GetAnimationContext() ) return INVALID_MODEL_ANIM; if ( !GetAnimationContext()->IsPropSet(kAPG_Action, kAP_Resurrecting ) ) return INVALID_MODEL_ANIM; return g_pLTServer->GetAnimIndex(GetAI()->GetObject(), "PrUn"); }
//---------------------------------------------------------------------------- // // ROUTINE: CAIHumanStateObstruct::UpdateAnimation() // // PURPOSE: Sets the Props for the given animation // //---------------------------------------------------------------------------- void CAIHumanStateObstruct::UpdateAnimation(void) { super::UpdateAnimation(); GetAnimationContext()->SetProp(kAPG_Posture, kAP_Stand); GetAnimationContext()->SetProp(kAPG_WeaponPosition, kAP_Up); if( IsNodeStillValid() && CanUpdatePath() ) { m_pStrategyFollowPath->UpdateAnimation(); } }
//---------------------------------------------------------------------------- // // ROUTINE: CAIHumanStateCatch::UpdateAnimation() // // PURPOSE: Sets animation flags depending on state, then locks the // animation in place. Here and only here do we handle setting // the props. // //---------------------------------------------------------------------------- void CAIHumanStateCatch::UpdateAnimation(void) { CAIHumanState::UpdateAnimation(); // Set the common flags.. GetAnimationContext()->SetProp( kAPG_Posture, kAP_Stand ); GetAnimationContext()->SetProp( kAPG_WeaponPosition, kAP_Up ); switch( m_eStateStatus ) { case kSStat_TriplePhaseOne: { GetAnimationContext()->SetProp( kAPG_WeaponAction, m_eAnimProp1 ); break; } case kSStat_TriplePhaseTwo: { GetAnimationContext()->SetProp( kAPG_WeaponAction, m_eAnimProp2 ); break; } case kSStat_TriplePhaseThree: { GetAnimationContext()->SetProp( kAPG_WeaponAction, m_eAnimProp3 ); break; } case kSStat_StateComplete: { break; } } // Always lock the animation. Let the caller handle unlocking later // if the animation ends. GetAnimationContext()->Lock(); }
//---------------------------------------------------------------------------- // // ROUTINE: CAIHumanStateCatch::Update() // // PURPOSE: // //---------------------------------------------------------------------------- void CAIHumanStateCatch::Update(void) { CAIHumanState::Update(); // Remember the entry status so we can see if the status changed // over the course of this run. EnumAIStateStatus eEntryStatus = m_eStateStatus; switch( m_eStateStatus ) { case kSStat_Initialized: { HandleSetupCatch(); break; } case kSStat_TriplePhaseOne: { HandleStartCatch(); break; } case kSStat_TriplePhaseTwo: { HandleHoldCatch(); break; } case kSStat_TriplePhaseThree: { HandleDropCatch(); break; } } // If we changed states, force an animation recalculation by locking, // and then clearing the lock if ( m_eStateStatus != eEntryStatus ) { GetAnimationContext()->Lock(); GetAnimationContext()->ClearLock(); } }
//---------------------------------------------------------------------------- // // ROUTINE: CAIHumanStateCatch::HandleDropCatch() // // PURPOSE: // //---------------------------------------------------------------------------- void CAIHumanStateCatch::HandleDropCatch() { // If we are done with the previous animation (locking is off) // then we can enter the next phase if( !GetAnimationContext()->IsLocked() ) { // If we have a target, turn to face it now. if ( GetAI()->HasTarget() ) { GetAI()->FaceTarget(); } m_eStateStatus = kSStat_StateComplete; } }
//---------------------------------------------------------------------------- // // ROUTINE: CAIHumanStateResurrecting::Update() // // PURPOSE: // //---------------------------------------------------------------------------- /*virtual*/ void CAIHumanStateResurrecting::Update() { CAIHumanState::Update(); AIASSERT( m_fResurrectCompleteTime!=-1, GetAI()->m_hObject, "CAIHumanStateResurrecting::Update: m_fResurrectCompleteTime == -1" ); if ( m_bFirstUpdate ) { GetAI()->KillDlgSnd(); // TEMP!! // Replace this with FXEd effects setup! CLIENTDEBRIS cd; cd.rRot = m_pAI->GetRotation(); cd.vPos = m_pAI->GetPosition() + LTVector( 0.0f, 10.0f, 0.0f ); cd.nDebrisId = 43; ::CreatePropDebris( cd.vPos, LTVector(0,1,0), 43 ); } switch ( m_eStateStatus ) { case kSStat_Conscious: break; case kSStat_RegainingConsciousness: { if ( GetAnimationContext()->IsPropSet(kAPG_Posture, kAP_Stand) ) { m_eStateStatus = kSStat_Conscious; GetAI()->SetBlinking(LTTRUE); } } break; case kSStat_Resurrecting: { if ( m_fResurrectCompleteTime < g_pLTServer->GetTime() ) { m_eStateStatus = kSStat_RegainingConsciousness; } } break; } }
//---------------------------------------------------------------------------- // // ROUTINE: CAIHumanStateCatch::HandleStartCatch() // // PURPOSE: // //---------------------------------------------------------------------------- void CAIHumanStateCatch::HandleStartCatch() { // Set up the direction and duration of the Catch if ( m_hObjectToCatch != LTNULL ) { // Reset the facing direction GetAI()->FacePos( m_vIncomingPosition ); } // If we are done with the previous animation (locking is off) // then we can enter the next phase if( !GetAnimationContext()->IsLocked() ) { LTVector vOrigin = GetAI()->GetPosition(); // Set up the direction and duration of the Catch if ( m_hObjectToCatch != LTNULL ) { // If we have a specific object, then orient ourselves to face it g_pLTServer->GetObjectPos( m_hObjectToCatch, &m_vIncomingPosition ); } // Find the length of the fly animation. CAnimationProps Props; Props.Set(kAPG_Posture, kAP_Stand); Props.Set(kAPG_WeaponPosition, kAP_Up); Props.Set(kAPG_Weapon, GetAI()->GetCurrentWeaponProp()); Props.Set(kAPG_WeaponAction, m_eAnimProp2); // Advance to the next phase.. m_eStateStatus = kSStat_TriplePhaseTwo; } // Decide if we ought to abort this phase -- we might not want // to hold the catch for the animations duration if( ShouldDropCatch() ) { // Advance to the last phase.. m_eStateStatus = kSStat_TriplePhaseThree; } }
//---------------------------------------------------------------------------- // // ROUTINE: CAIHumanStrategyShootStream::UpdateAiming() // // PURPOSE: // //---------------------------------------------------------------------------- /*virtual*/ void CAIHumanStrategyShootStream::UpdateAiming(HOBJECT hTarget) { if ( m_flStreamTime < g_pLTServer->GetTime() ) { // Don't calculate new stream time until finished firing animation. if( !GetAnimationContext()->IsLocked() ) { CalculateStreamTime(); } Aim(); } else { // We're done waiting, fire if we're at a reasonable angle if ( m_bIgnoreFOV ) { Fire(); } else { LTVector vTargetPos; g_pLTServer->GetObjectPos(hTarget, &vTargetPos); LTVector vDir = vTargetPos - GetAI()->GetPosition(); vDir.y = 0.0f; vDir.Normalize(); if ( vDir.Dot(GetAI()->GetTorsoForward()) < 0.70f ) { Aim(); } else { Fire(); } } } }
void CAIHumanStateAttackMove::Update() { super::Update(); // Make sure we have a target if ( !GetAI()->HasTarget() ) { m_eStateStatus = kSStat_FailedComplete; return; } HOBJECT hTarget = GetAI()->GetTarget()->GetObject(); HOBJECT hAI = GetAI()->m_hObject; // Head and Torso tracking. if( m_bFirstUpdate ) { GetAI()->SetNodeTrackingTarget( kTrack_AimAt, hTarget, "Head" ); } // Handle update appropriately for the type of move. switch( m_eAttackMove ) { // Step. case kAP_ShuffleRight: case kAP_ShuffleLeft: if( m_bFirstUpdate ) { // Snap AI to face the direction of his torso. GetAI()->FaceDir( GetAI()->GetTorsoForward() ); GetAI()->FaceTargetRotImmediately(); GetAnimationContext()->ClearLock(); } else if( !GetAnimationContext()->IsLocked() ) { m_eStateStatus = kSStat_StateComplete; } // Head and Torso tracking. GetAI()->EnableNodeTracking( kTrack_AimAt, hTarget ); break; // BackUp. case kAP_BackUp: case kAP_FlankLeft: case kAP_FlankRight: if( m_pStrategyFollowPath->IsUnset() ) { if( m_eAttackMove == kAP_BackUp ) { m_pStrategyFollowPath->SetMovement( kAP_BackUp ); } else { m_pStrategyFollowPath->SetMovement( kAP_Run ); } m_bTurnedAround = LTFALSE; if( !m_pStrategyFollowPath->Set( m_vAttackMoveDest, LTFALSE ) ) { m_eStateStatus = kSStat_FailedComplete; } } if( m_pStrategyFollowPath->IsDone() ) { m_eStateStatus = kSStat_StateComplete; } else if( m_pStrategyFollowPath->IsSet() ) { SelectMoveAnim(); m_pStrategyFollowPath->Update(); } if( m_pStrategyShoot->ShouldReload() ) { m_pStrategyShoot->Reload(LTTRUE); } if( m_pStrategyShoot->IsReloading() || m_pStrategyShoot->IsFiring() || GetAI()->GetTarget()->IsVisibleCompletely() ) { m_pStrategyShoot->Update(); } // Head and Torso tracking. GetAI()->EnableNodeTracking( kTrack_AimAt, LTNULL ); break; default: AIASSERT( 0, GetAI()->m_hObject, "CAIHumanStateAttackMove::Update: Unexpected attack move." ); m_eStateStatus = kSStat_FailedComplete; break; } }
void CAIHumanStateAttackProne::Update() { super::Update(); // Make sure we have a target if ( !GetAI()->HasTarget() ) { m_eStateStatus = kSStat_FailedComplete; return; } HOBJECT hTarget = GetAI()->GetTarget()->GetObject(); HOBJECT hAI = GetAI()->m_hObject; // Ensure that node tracking is disabled. m_pAIHuman->DisableNodeTracking(); // Find the direction to the target. LTVector vTargetDir = m_pAI->GetTarget()->GetVisiblePosition() - m_pAI->GetPosition(); vTargetDir.Normalize(); // Snap AI to face the direction of his torso. if( m_bFirstUpdate ) { GetAI()->FaceDir( vTargetDir ); GetAI()->FaceTargetRotImmediately(); GetAnimationContext()->ClearLock(); return; } // Do no processing while transitioning into prone position. LTFLOAT fCurTime = g_pLTServer->GetTime(); if( GetAnimationContext()->IsTransitioning() ) { m_fStayProneTime = fCurTime + 3.f; return; } LTFLOAT fDot = GetAI()->GetForwardVector().Dot( vTargetDir ); // Be sure to stay down at least 3 seconds. if( m_fStayProneTime < fCurTime ) { // Bail if the target is outside of fov. if( fDot < c_fFOV60 ) { m_eStateStatus = kSStat_StateComplete; return; } // Bail if target is within half of the minimum prone distance. if( m_fHalfMinDistSqr > GetAI()->GetTarget()->GetVisiblePosition().DistSqr( GetAI()->GetPosition() ) ) { m_eStateStatus = kSStat_StateComplete; return; } } // Reload. if( m_pStrategyShoot->ShouldReload() ) { m_pStrategyShoot->Reload(LTTRUE); return; } // Shoot if we are in the middle of shooting or reloading. if( m_pStrategyShoot->IsReloading() || m_pStrategyShoot->IsFiring() ) { m_pStrategyShoot->Update(); m_fLastFiredTime = fCurTime; return; } // Shoot if target is visible, and within a small fov. if( ( GetAI()->GetTarget()->IsVisibleCompletely() ) && ( fDot > c_fFOV45 ) ) { m_pStrategyShoot->Update(); m_fLastFiredTime = fCurTime; } // Bail if haven't shot in 3 seconds. else if( ( m_fLastFiredTime + 3.f < fCurTime ) && ( m_fStayProneTime < fCurTime ) ) { m_eStateStatus = kSStat_StateComplete; return; } }
// ----------------------------------------------------------------------- // // // ROUTINE: CAIHumanStrategyShoot::UpdateAnimation // // PURPOSE: Handles any pending AnimationContext specializations. // Extends the base class and makes the following assumptions: // 1) Animations are being locked by the base class. // // ----------------------------------------------------------------------- // LTBOOL CAIHumanStrategyShootStream::UpdateAnimation() { if( !CAIHumanStrategyShoot::UpdateAnimation() ) { return LTFALSE; } switch ( m_eFireState ) { case eFireStateStart: { // If we are in the fire state, and if our animation is not locked, // then make sure it is cleared fully. Rely on the base class to // handle the initial locking. if( GetAI()->GetCurrentWeapon() == GetAI()->GetPrimaryWeapon() ) { GetAnimationContext()->SetProp(kAPG_WeaponAction, kAP_FireStreamStart); } else { GetAnimationContext()->SetProp(kAPG_WeaponAction, kAP_FireSecondaryStreamStart); } GetAnimationContext()->Lock(); } break; case eFireStateFiring: { // Streaming attacks are NEVER garenteed to play all the way through -- we want // tighter control over them than the animation will give us. BUT we want to also // have the ability to kick out when the animation ends UNLESS the animation is // looping. if( GetAI()->GetCurrentWeapon() == GetAI()->GetPrimaryWeapon() ) { GetAnimationContext()->SetProp(kAPG_WeaponAction, kAP_FireStream); } else { GetAnimationContext()->SetProp(kAPG_WeaponAction, kAP_FireSecondaryStream); } GetAnimationContext()->Lock(); } break; case eFireStateEnding: { if( GetAI()->GetCurrentWeapon() == GetAI()->GetPrimaryWeapon() ) { GetAnimationContext()->SetProp(kAPG_WeaponAction, kAP_FireStreamEnd); } else { GetAnimationContext()->SetProp(kAPG_WeaponAction, kAP_FireSecondaryStreamEnd); } GetAnimationContext()->Lock(); } break; case eFireStateInvalid: { // we are not in one of the basic firing states, so don't do anything special ; } break; default: { AIASSERT( 0, GetAI()->GetHOBJECT(), "CAIHumanStrategyShootStream::UpdateAnimation: Unexpected m_eFireState" ); } break; } return LTTRUE; }