//------------------------------------------------------------------------ bool CItem::PlayFragment(IAction* pAction, float speedOverride, float timeOverride, float animWeight, float ffeedbackWeight, bool concentratedFire) { _smart_ptr<IAction> pActionPtr(pAction); CRY_ASSERT(pAction); if(!pAction) { return false; } CWeapon *pWeapon = static_cast<CWeapon*>(GetIWeapon()); if (pWeapon && pWeapon->IsProxyWeapon()) { return false; } bool success = false; float speed = (float)__fsel(-speedOverride, 1.0f, speedOverride); FragmentID fragID = pAction->GetFragmentID(); pAction->SetSubContext(m_subContext); IActionController *pActionController = GetActionController(); if ((fragID != FRAGMENT_ID_INVALID) && pActionController) { float fragmentDuration, transitionDuration; if (pActionController->QueryDuration(*pAction, fragmentDuration, transitionDuration)) { float duration = fragmentDuration+transitionDuration; if ((duration > 0.0f) && (timeOverride > 0.0f)) { speed = (duration / timeOverride); CRY_ASSERT((speed > 0.0f) && (speed < 99999.0f)); } if(duration > 0.f) { m_animationTime[eIGS_Owner] = (uint32) MAX((duration*1000.0f/speed) - 20, 0.0f); } pAction->SetSpeedBias(speed); pAction->SetAnimWeight(animWeight); if(concentratedFire) { pAction->SetParam(CItem::sActionParamCRCs.concentratedFire, 1.f); } if(ffeedbackWeight != 1.f) { pAction->SetParam(CItem::sActionParamCRCs.ffeedbackScale, ffeedbackWeight); } pActionController->Queue(pAction); success = true; } } return success; }
// ---------------------------------------------------------------------------- CExactPositioning::ETriggerState CExactPositioning::StateFinalPreparation_HandleEvent( SStateMachineEvent& event ) { switch( event.type ) { case ESME_Enter: { CRY_ASSERT( m_pExactPositioningTarget->preparing ); CRY_ASSERT( !m_pExactPositioningTarget->activated ); if ( !m_pAnimatedCharacter ) return eTS_Disabled; IActionController* pActionController = m_pAnimatedCharacter->GetActionController(); if ( !pActionController ) return eTS_Disabled; if ( m_pExactPositioningTarget->pAction->GetStatus() != IAction::None ) return eTS_Disabled; m_pAnimAction = m_pExactPositioningTarget->pAction; pActionController->Queue( *m_pAnimAction ); // We've queued the animation, let listeners know if ( m_triggerQueryStart ) { SendQueryComplete( m_triggerQueryStart, true ); m_triggerQueryStart = 0; } break; } case ESME_Update: if ( m_pPendingRequest.get() ) return eTS_Disabled; CRY_ASSERT( m_pAnimAction.get() ); switch( m_pAnimAction->GetStatus() ) { case IAction::Pending: break; case IAction::Installed: return eTS_Running; break; case IAction::Finished: // this means 'about to finish' case IAction::None: return eTS_Completing; break; } break; }; return m_state; }
void CMountedGunController::OnEnter(EntityId mountedGunId) { CRY_ASSERT_MESSAGE(m_pControlledPlayer, "Controlled player not initialized"); ICharacterInstance* pCharacter = m_pControlledPlayer->IsThirdPerson() ? m_pControlledPlayer->GetEntity()->GetCharacter(0) : m_pControlledPlayer->GetShadowCharacter(); if (pCharacter) { CItem* pWeapon = static_cast<CItem*>(g_pGame->GetIGameFramework()->GetIItemSystem()->GetItem(mountedGunId)); assert(pWeapon); IActionController* pActionController = m_pControlledPlayer->GetAnimatedCharacter()->GetActionController(); if (pActionController && m_pMannequinParams) { SAFE_RELEASE(m_pMovementAction); m_pMovementAction = new TPlayerAction(PP_PlayerAction, m_pMannequinParams->fragmentIDs.MotionMounted); m_pMovementAction->AddRef(); pActionController->Queue(m_pMovementAction); } ////////////////////////////////////////////////////////////////////////// // NOTE: This should go through mannequin CRecordingSystem* pRecordingSystem = g_pGame->GetRecordingSystem(); if (pRecordingSystem) { const SParams& pWeaponParams = pWeapon->GetParams(); IAnimationSet* pAnimationSet = pCharacter->GetIAnimationSet(); const int upAnimId = pAnimationSet->GetAnimIDByName(pWeaponParams.mountedTPAimAnims[MountedTPAimAnim::Up].c_str()); const int downAnimId = pAnimationSet->GetAnimIDByName(pWeaponParams.mountedTPAimAnims[MountedTPAimAnim::Down].c_str()); pRecordingSystem->OnMountedGunEnter(m_pControlledPlayer, upAnimId, downAnimId); } ////////////////////////////////////////////////////////////////////////// IAnimatedCharacter* pAnimatedCharacter = m_pControlledPlayer->GetAnimatedCharacter(); CRY_ASSERT(pAnimatedCharacter); pAnimatedCharacter->RequestPhysicalColliderMode(eColliderMode_Disabled, eColliderModeLayer_Game, "CMountedGunController::OnEnter"); pAnimatedCharacter->SetNoMovementOverride(true); if (gEnv->bMultiplayer) pAnimatedCharacter->EnableRigidCollider(0.5f); else if (m_pControlledPlayer->IsPlayer()) pAnimatedCharacter->EnableRigidCollider(1.5f); pAnimatedCharacter->GetGroundAlignmentParams().SetFlag(eGA_AllowWithNoCollision, true); BATTLECHATTER(BC_WatchMyBack, m_pControlledPlayer->GetEntityId()); } }
void CInteractiveObjectRegistry::ApplyInteractionToObject(IEntity *pEntity, const TagID interactionTypeTag, const int interactionIndex) const { if (m_pDatabaseObject && m_pControllerDef) { IMannequin &mannequinSys = gEnv->pGame->GetIGameFramework()->GetMannequinInterface(); SAnimationContext animContext(*m_pControllerDef); IActionController *pActionController = mannequinSys.CreateActionController(pEntity, animContext); int scopeContextID = m_pControllerDef->m_scopeContexts.Find("SlaveObject"); pActionController->SetScopeContext(scopeContextID, *pEntity, pEntity->GetCharacter(0), m_pDatabaseObject); TagState fragTags = TAG_STATE_EMPTY; const CTagDefinition *pTagDef = m_pControllerDef->GetFragmentTagDef(m_interactFragID); if (pTagDef) { pTagDef->Set(fragTags, interactionTypeTag, true); } IAction *pAction = new TAction<SAnimationContext>(0, m_interactFragID, fragTags); pAction->SetOptionIdx(interactionIndex); pActionController->Queue(pAction); // Set the time increments to non-zero to force the ActionController::Update() to drive the animation to the end. // When time increment is zero, animation position will not update. This will be changed to a simpler process by Tom Berry at some point. const uint32 totalScopes = pActionController->GetTotalScopes(); for(uint32 s=0; s<totalScopes; ++s) { pActionController->GetScope(s)->IncrementTime(0.001f); } pActionController->Update(1000.0f); // "false" here leaves the anim on the transition queue in the animation system so it isn't cleared on pActionController->Release(). pActionController->ClearScopeContext(scopeContextID, false); pActionController->Release(); CRecordingSystem* pRecordingSystem = g_pGame->GetRecordingSystem(); if (pRecordingSystem) { pRecordingSystem->OnInteractiveObjectFinishedUse(pEntity->GetId(), interactionTypeTag, interactionIndex); } } }
// ---------------------------------------------------------------------------- bool CMannequinAGState::SetActionOrSignalInput(_smart_ptr<CAnimActionAGAction>& pAction, TKeyValue& currentValue, InputID inputID, EAIActionType actionType, const char* defaultValue, uint32 defaultValueCRC, const char* value, TAnimationGraphQueryID* pQueryID, bool optional) { IActionController* pActionController = GetActionController(); if (!pActionController) return false; // TODO Where to get the priorities from? const int MANNEQUIN_PRIORITY = 2; // currently equal to PP_Action, just above movement, but underneath urgent actions, hit death, etc. TAnimationGraphQueryID queryID = 0; if (pQueryID) queryID = *pQueryID = GenerateQueryID(); const uint32 valueCRC = CCrc32::ComputeLowercase(value); static uint32 idleCRC = CCrc32::ComputeLowercase("idle"); static uint32 noneCRC = CCrc32::ComputeLowercase("none"); const bool isUnsupportedFragmentID = ((valueCRC == idleCRC) || (valueCRC == noneCRC)); const FragmentID fragmentID = isUnsupportedFragmentID ? FRAGMENT_ID_INVALID : pActionController->GetContext().controllerDef.m_fragmentIDs.Find(valueCRC); const bool isDefaultValue = (valueCRC == defaultValueCRC); const bool somethingIsPendingOrInstalled = pAction && pAction->IsPendingOrInstalled(); if (isDefaultValue) { if ( actionType == EAT_Looping ) { StopAnyLoopingExactPositioningAction(); } const bool isPendingOrInstalled = !somethingIsPendingOrInstalled; // the fake action 'idle' isPendingOrInstalled if something else is NOT pending or installed if (isPendingOrInstalled) { // In the old sense: the current requested 'value' did not change, we were already 'idle' SendEvent_Entered(NULL, queryID, true); } else { currentValue = defaultValue; if (pAction) { pAction->Stop(); // this will eventually call Entered(..,false) of the user that was waiting on Entered() pAction = NULL; } // TODO: This is not entirely correct. The Entered() event for the idle action should only // be called when you exactly "go back to idle". But this is not well defined in mannequin, // so I just send it right away... SendEvent_Entered(NULL, queryID, true); SendEvent_ChangedInput(inputID, true); // tell whoever is listening to the input that it changed } return true; } else if (fragmentID != FRAGMENT_ID_INVALID) { const bool isPendingOrInstalled = somethingIsPendingOrInstalled && (pAction->GetValueCRC() == valueCRC); if (isPendingOrInstalled) { // In the old sense: the current requested 'value' did not change // reuse the old queryid, if there is one, otherwise set the new one if (pAction->GetQueryID()) { queryID = pAction->GetQueryID(); if (pQueryID) *pQueryID = queryID; } else { if (queryID) pAction->SetQueryID(queryID); } if (pAction->GetStatus() == IAction::Installed) { // The other system is already playing the same action. // Send the 'entered' event immediately // (afai can see the AG only did this for signals for some reason??) SendEvent_Entered(pAction, pAction->GetQueryID(), true); } } else { currentValue = value; pAction = new CAnimActionAGAction(MANNEQUIN_PRIORITY, fragmentID, *this, actionType, value, valueCRC, queryID); pActionController->Queue(*pAction.get()); SendEvent_ChangedInput(inputID, true); // tell whoever is listening the input that it changed } return true; } else if (!optional) { // 'not optional' means invalid values get translated into the default value // (so we always set a value, hence the setting of values is 'not optional') // Recurse and pass the defaultValue as value: return SetActionOrSignalInput(pAction, currentValue, inputID, actionType, defaultValue, defaultValueCRC, defaultValue, NULL, true); } else { #ifndef _RELEASE if(!isUnsupportedFragmentID) { CryWarning( VALIDATOR_MODULE_GAME, VALIDATOR_WARNING, "CMannequinAGState::SetInput: Unable to find animation '%s'", value); } #endif //#ifndef _RELEASE return false; } }