void CDialogSession::PrecacheSounds() { REINST("can this be removed?"); //if (CDialogSystem::sPrecacheSounds == 0) // return; //ISoundSystem* pSoundSys = gEnv->pAudioSystem; //const int numLines = m_pScript->GetNumLines(); //for (int i=0; i<numLines; ++i) //{ // const CDialogScript::SScriptLine* pLine = m_pScript->GetLine(i); // if (pLine->m_sound.empty()) // continue; // const char* fullSoundPath = CDialogActorContext::GetSoundKey(pLine->m_sound); // bool ok = (pSoundSys->Precache(fullSoundPath, CDialogActorContext::SOUND_FLAGS, FLAG_SOUND_PRECACHE_DIALOG_DEFAULT) != ePrecacheResult_Error); // if (ok/* && (pSoundBuffer->Loaded() || pSoundBuffer->Loading() */) // ISoundBuffer is not exposed from SoundSystem // { // // TODO: do something, maybe store for unprecaching? // DiaLOG::Log(DiaLOG::eAlways, "[DIALOG] CDialogSession::PrecacheSounds: %s [Script=%s] Sound '%s' precached", // GetDebugName(), m_pScript->GetID().c_str(), fullSoundPath); // } // else // { // GameWarning("[DIALOG] CDialogSession::PrecacheSounds: %s [Script=%s] Cannot precache sound '%s'", // GetDebugName(), m_pScript->GetID().c_str(), fullSoundPath); // } //} }
//--------------------------------------------------------------------- void CVehicleWeapon::AudioCache( bool enable, bool isThirdPerson ) { REINST("needs verification!"); //IEntity* pEntity = GetEntity(); //if(pEntity) //{ // CryFixedStringT<32> soundCache; // IEntityClass *pClass = pEntity->GetClass(); // const EAudioCacheType cacheType = isThirdPerson ? eACT_3p : eACT_fp; // const bool cacheTypeChanging = cacheType != m_audioCacheType; // //uncache previously cached (if calling disable or changing cacheType) // if(m_audioCacheType != eACT_None && (!enable || cacheTypeChanging)) // { // GetCacheName(pClass, m_audioCacheType == eACT_3p, soundCache); // gEnv->pSoundSystem->RemoveCachedAudioFile(soundCache.c_str(), false); // m_audioCacheType = eACT_None; // } // //enable and changed type so cache // if(enable && cacheTypeChanging) // { // m_audioCacheType = cacheType; // GetCacheName(pClass, isThirdPerson, soundCache); // gEnv->pSoundSystem->CacheAudioFile(soundCache.c_str(), eAFCT_GAME_HINT); // } //} //else //{ // GameWarning("Unable to audio cache for vehicle weapon as entity doesn't exist"); //} }
static void PlaySound(const char* name) { REINST("needs verification!"); /*_smart_ptr<ISound> pSound = gEnv->pSoundSystem->CreateSound(name,0); if (pSound) pSound->Play();*/ }
//------------------------------------------------------------------------ void CVehicleSeatActionAnimation::Update(float frameTime) { if (!m_userId || !m_pVehicleAnim) return; if (m_action != 0.f) { float currTime = m_pVehicleAnim->GetAnimTime(true); float newTime = currTime + m_action * m_speed * frameTime; Limit(newTime, 0.f, 1.f); if (newTime != currTime) { m_pVehicleAnim->SetTime(newTime); // starting if (m_prevAction == 0.f /*&& m_pSound.get()*/) { REINST("starting something"); /*m_pIEntityAudioProxy->PlaySound(m_pSound); m_pIEntityAudioProxy->SetStaticSound(m_pSound->GetId(), true);*/ } } //float color[] = {1,1,1,1}; //gEnv->pRenderer->Draw2dLabel(200,250,1.5,color,false,"action: %.2f, time: %.2f, new: %.2f", m_action, currTime, newTime); } else { // stopping if (m_prevAction != 0.f) { REINST("stopping something"); /*if (m_pSound.get()) m_pIEntityAudioProxy->StopSound(m_pSound->GetId()); if (m_pStopSound.get()) { m_pIEntityAudioProxy->PlaySound(m_pStopSound); m_pIEntityAudioProxy->SetStaticSound(m_pStopSound->GetId(), true); }*/ } } m_prevAction = m_action; }
void CLipSync_TransitionQueue::Release() { IEntity* pEntity = GetEntity(); if (IEntityAudioProxy* pSoundProxy = static_cast<IEntityAudioProxy*>(pEntity->GetProxy(ENTITY_PROXY_AUDIO))) { REINST(add SetLipSyncProvider to interface) //pSoundProxy->SetLipSyncProvider(ILipSyncProviderPtr()); } delete this; }
void CPlayerStateSwim::UpdateSoundListener( CPlayer &player ) { REINST("needs verification!"); /*const float eyeDepth = player.m_playerStateSwim_WaterTestProxy.GetRelativeWaterLevel(); const CCamera& camera = gEnv->pSystem->GetViewCamera(); IAudioListener* const pListener = gEnv->pSoundSystem->GetListener(gEnv->pSoundSystem->GetClosestActiveListener(camera.GetPosition())); if (pListener) pListener->SetUnderwater(eyeDepth);*/ // TODO: Make sure listener interface expects zero at surface and negative under water. }
void STrailParams::PreCacheLevelResources(CItemParticleEffectCache& particleCache) { particleCache.CacheParticle(effect); particleCache.CacheParticle(effect_fp); REINST("needs verification!"); /*if (!sound.empty()) { gEnv->pSoundSystem->Precache(sound.c_str(), 0, FLAG_SOUND_PRECACHE_EVENT_DEFAULT); }*/ }
void CLocalPlayerComponent::RemoveClientSoundmood(CPlayer::EClientSoundmoods soundmood) { REINST("needs verification!"); //if(soundmood > CPlayer::ESoundmood_Invalid && soundmood < CPlayer::ESoundmood_Last) //{ // //Stop any looping sound that might have been playing // m_soundmoods[soundmood].m_enter.Stop(); // //intentionally play ( so it runs execute commands that include RemoveSoundMood ) // m_soundmoods[soundmood].m_exit.Play(); //} }
//------------------------------------------------------------------------ void CGameRulesKingOfTheHillObjective::ClearEntityAudio( SHoldEntityDetails *pDetails ) { REINST("needs verification!"); /*IEntity *pEntity = gEnv->pEntitySystem->GetEntity(pDetails->m_id); if(pEntity) { IEntityAudioProxy *pIEntityAudioProxy = (IEntityAudioProxy*) pEntity->GetProxy(ENTITY_PROXY_AUDIO); if(pIEntityAudioProxy) { pIEntityAudioProxy->StopAllSounds(); } }*/ }
void CEntityAudioProxy::OnMove() { Matrix34 tm = m_pEntity->GetWorldTM(); if (tm.IsValid()) { SATLWorldPosition const oPosition(tm, ZERO); std::for_each(m_mapAuxAudioProxies.begin(), m_mapAuxAudioProxies.end(), SRepositionAudioProxy(oPosition)); if ((m_pEntity->GetFlagsExtended() & ENTITY_FLAG_EXTENDED_AUDIO_LISTENER) != 0) { SAudioRequest oRequest; oRequest.nFlags = eARF_PRIORITY_NORMAL; oRequest.pOwner = this; SAudioListenerRequestData<eALRT_SET_POSITION> oRequestData(oPosition); oRequest.pData = &oRequestData; gEnv->pAudioSystem->PushRequest(oRequest); // As this is an audio listener add its entity to the AreaManager for raising audio relevant events. gEnv->pEntitySystem->GetAreaManager()->MarkEntityForUpdate(m_pEntity->GetId()); } } REINST("voice attachement lookup needs to be done by code creating entityaudioproxy for voice line on character"); //if (m_nAttachmentIndex != -1) //{ // if (ICharacterInstance* const pCharacter = m_pEntity->GetCharacter(0)) // { // if (m_nAttachmentIndex != -1) // { // if (IAttachmentManager const* const pAttachmentManager = pCharacter->GetIAttachmentManager()) // { // if (IAttachment const* const pAttachment = pAttachmentManager->GetInterfaceByIndex(m_nAttachmentIndex)) // { // tm = Matrix34(pAttachment->GetAttWorldAbsolute()); // } // } // } // else if (m_nBoneHead != -1) // { // // re-query SkeletonPose to prevent crash on removed Character // if (ISkeletonPose* const pSkeletonPose = pCharacter->GetISkeletonPose()) // { // tm = tm * Matrix34(pSkeletonPose->GetAbsJointByID(m_nBoneHead)); // } // } // } //} }
//------------------------------------------------------------------------ void CVehicleSeatActionAnimation::StopUsing() { if (m_pVehicleAnim) { m_pVehicleAnim->StopAnimation(); if (m_manualUpdate) m_pVehicle->SetObjectUpdate(this, IVehicle::eVOU_NoUpdate); REINST("event needed?"); /*if (m_pSound.get()) m_pIEntityAudioProxy->StopSound(m_pSound->GetId());*/ } m_userId = 0; m_action = m_prevAction = 0.f; }
void CUIManager::InitSound() { REINST("UI listener"); if (m_soundListener == INVALID_ENTITYID) { //m_soundListener = gEnv->pSoundSystem->CreateListener(); } if (m_soundListener != INVALID_ENTITYID) { /*IAudioListener* const pListener = gEnv->pSoundSystem->GetListener(m_soundListener); if (pListener) { pListener->SetRecordLevel(1.0f); pListener->SetActive(true); }*/ } }
//------------------------------------------------------------------------ void CScriptbind_GameAudio::Reset() { TSignalPlayersSearchMap::iterator iter = m_signalPlayersSearchMap.begin(); while (iter!=m_signalPlayersSearchMap.end()) { const SKey& key = iter->first; int ind = iter->second; CAudioSignalPlayer& signalPlayer = m_signalPlayers[ind]; //signalPlayer.Stop( key.m_entityId ); REINST("needs verification!"); ++iter; } stl::free_container(m_signalPlayers); m_signalPlayersSearchMap.clear(); }
void CPlayerPlugin_CurrentlyTargetting::Leave() { m_currentTarget = 0; m_currentTargetTime = 0.0f; if(m_bTargetingLocalPlayer) { SHUDEvent event (eHUDEvent_LocalPlayerTargeted); event.AddData(false); CHUDEventDispatcher::CallEvent(event); REINST("needs verification!"); /*EntityId clientId = g_pGame->GetClientActorId(); if(clientId && m_targetedSignal.IsPlaying(clientId)) { m_targetedSignal.Stop(clientId); }*/ } CPlayerPlugin::Leave(); }
//------------------------------------------------------------------------ bool CVehicleSeatActionAnimation::Init(IVehicle* pVehicle, IVehicleSeat* pSeat, const CVehicleParams &table) { m_pVehicle = pVehicle; CVehicleParams animTable = table.findChild("Animation"); if (!animTable) return false; if (animTable.haveAttr("vehicleAnimation")) m_pVehicleAnim = m_pVehicle->GetAnimation(animTable.getAttr("vehicleAnimation")); string control = animTable.getAttr("control"); if (!control.empty()) { if (control == "roll") { m_control[0] = eVAI_RollLeft; m_control[1] = eVAI_RollRight; } } animTable.getAttr("manualUpdate", m_manualUpdate); animTable.getAttr("speed", m_speed); REINST("start/stop event?"); /*m_pIEntityAudioProxy = (IEntityAudioProxy*)m_pVehicle->GetEntity()->GetProxy(ENTITY_PROXY_AUDIO); if (m_pIEntityAudioProxy) { if (animTable.haveAttr("sound")) m_pSound = gEnv->pAudioSystem->CreateSound(animTable.getAttr("sound"), FLAG_SOUND_DEFAULT_3D); if (animTable.haveAttr("stopSound")) m_pStopSound = gEnv->pAudioSystem->CreateSound(animTable.getAttr("stopSound"), FLAG_SOUND_DEFAULT_3D); }*/ return true; }
void CEntityAudioProxy::Reload(IEntity* pEntity, SEntitySpawnParams& params) { m_pEntity = static_cast<CEntity*>(pEntity); m_bHide = m_pEntity->IsHidden(); m_fFadeDistance = 0.0f; m_fEnvironmentFadeDistance = 0.0f; m_nBoneHead = -1; m_nAttachmentIndex = -1; m_nAudioEnvironmentID = INVALID_AUDIO_ENVIRONMENT_ID; std::for_each(m_mapAuxAudioProxies.begin(), m_mapAuxAudioProxies.end(), SResetAudioProxy()); #if defined(INCLUDE_ENTITYSYSTEM_PRODUCTION_CODE) std::for_each(m_mapAuxAudioProxies.begin(), m_mapAuxAudioProxies.end(), SInitializeAudioProxy(m_pEntity->GetName())); #else std::for_each(m_mapAuxAudioProxies.begin(), m_mapAuxAudioProxies.end(), SInitializeAudioProxy(NULL)); #endif // INCLUDE_ENTITYSYSTEM_PRODUCTION_CODE SetObstructionCalcType(eAOOCT_IGNORE); OnMove(); REINST("needs voice attachement placement"); //PrecacheHeadBone(); }
void CActorStateSwim::UpdateSoundListener(CActorControllerComponent& actorControllerComponent) { REINST("needs verification! check SDK version of the code later on...ILH"); }
////////////////////////////////////////////////////////////////////////// //clear everything out before loading a checkpoint void CCheckpointSystem::ResetEngine() { //let game do initial resetting if (m_pGameHandler) { m_pGameHandler->OnPreResetEngine(); } //turn off physics gEnv->pSystem->SetThreadState(ESubsys_Physics, false); //reset engine similar to editor when leaving game mode //broken geometry and dynamics CCryAction::GetCryAction()->FlushBreakableObjects(); DeleteDynamicEntities(); CCryAction::GetCryAction()->ResetBrokenGameObjects(); //this should just reset the velocity of all moving things, but instead vehicle doors fall off ... //CXP : add this back in after CXP, Anton has to fix it //gEnv->pPhysicalWorld->ResetDynamicEntities(); //particle and post process effects gEnv->p3DEngine->ResetPostEffects(); gEnv->p3DEngine->ResetParticlesAndDecals(); REINST("notify the audio system?"); //AI System if (gEnv->pAISystem) { gEnv->pAISystem->Reset(IAISystem::RESET_EXIT_GAME); gEnv->pAISystem->Reset(IAISystem::RESET_ENTER_GAME); } //flow system //reset trackview gEnv->pMovieSystem->Reset(true, true); //entity system SEntityEvent event; event.event = ENTITY_EVENT_RESET; event.nParam[0] = 0; gEnv->pEntitySystem->SendEventToAll( event ); //Vehicle System IVehicleSystem *pVehicleSystem = CCryAction::GetCryAction()->GetIVehicleSystem(); IVehicleIteratorPtr pVehIt = pVehicleSystem->CreateVehicleIterator(); while(IVehicle *pVehicle = pVehIt->Next()) { pVehicle->Reset(true); } //make sure the scripts are clean gEnv->pScriptSystem->ForceGarbageCollection(); //turn on physics again gEnv->pSystem->SetThreadState(ESubsys_Physics, true); //let game do final resetting if (m_pGameHandler) { m_pGameHandler->OnPostResetEngine(); } }
//------------------------------------------------------------------------ void CVehicleSeatActionRotateTurret::UpdateRotationSound(EVehicleTurretRotationType type, float speed, float deltaTime) { // update rotation sound, if available if (m_rotations[type].m_turnSoundId == InvalidSoundEventId) return; if (!m_pVehicle->IsPlayerDriving() && !m_pVehicle->IsPlayerPassenger()) return; const static float minSpeed = 0.0002f; const static float soundDamageRatio = 0.2f; speed *= GetDamageSpeedMul(m_rotations[type].m_pPart); bool bDamage = m_rotations[type].m_pPart->m_damageRatio > soundDamageRatio && m_pVehicle->IsPlayerPassenger(); if (speed != m_rotations[type].m_relSpeed) { if ((fabsf(speed) < 1e-4) && (fabsf(m_rotations[type].m_relSpeed) < 1e-4)) { m_rotations[type].m_relSpeed = 0.0f; } else { Interpolate(m_rotations[type].m_relSpeed, speed, 8.0f, deltaTime); } float speedParam = (speed != 0.0f) ? min(1.0f, m_rotations[type].m_relSpeed / speed) : 0.0f; m_pVehicle->SetSoundParam(m_rotations[type].m_turnSoundId, "speed", speedParam, true); if (bDamage) { m_pVehicle->SetSoundParam(m_rotations[type].m_damageSoundId, "speed", speedParam, true); } if (fabsf(m_rotations[type].m_relSpeed) < minSpeed) { m_pVehicle->StopSound(m_rotations[type].m_turnSoundId); m_pVehicle->StopSound(m_rotations[type].m_damageSoundId); } } float inout = 1.f; if (m_pVehicle->IsPlayerPassenger()) { if (IVehicleSeat* pSeat = m_pVehicle->GetSeatForPassenger(CCryAction::GetCryAction()->GetClientActor()->GetEntityId())) { if (IVehicleView* pView = pSeat->GetCurrentView()) { if (!pView->IsThirdPerson()) inout = pSeat->GetSoundParams().inout; } } } REINST("update params"); /*if (ISound* pSound = m_pVehicle->GetSound(m_rotations[type].m_turnSoundId, false)) pSound->SetParam("in_out", inout, false); if (bDamage) { if (ISound* pSound = m_pVehicle->GetSound(m_rotations[type].m_damageSoundId, false)) { pSound->SetParam("in_out", inout, false); pSound->SetParam("damage", min(1.f, m_rotations[type].m_pPart->m_damageRatio), false); } } */ }
bool CDialogActorContext::Update(float dt) { if (IsAborted()) return true; // FIXME: this should never happen, as we should get a notification before. // temp leave in for tracking down a bug [AlexL: 23/11/2006] IEntity* pEntity = gEnv->pEntitySystem->GetEntity(m_entityID); if (pEntity == 0) { m_pIActor = 0; GameWarning("[DIALOG] CDialogActorContext::Update: %s Actor=%d (EntityId=%d) no longer existent.", m_pSession->GetDebugName(), m_actorID, m_entityID); AbortContext(true, CDialogSession::eAR_EntityDestroyed); return true; } CDialogSession::AlertnessInterruptMode alertnessInterruptMode = m_pSession->GetAlertnessInterruptMode(); if(alertnessInterruptMode != CDialogSession::None) { if(IAIObject* aiObject = pEntity->GetAI()) { if(IAIActorProxy* aiActorProxy = aiObject->GetProxy()) { if(aiActorProxy->GetAlertnessState() >= alertnessInterruptMode) { AbortContext(true, CDialogSession::eAR_AIAborted); return true; } } } } float now = m_pSession->GetCurTime(); if (!CheckActorFlags(CDialogSession::eDACF_NoActorDeadAbort) && m_pIActor && m_pIActor->IsDead()) { if (!IsAborted()) { DiaLOG::Log(DiaLOG::eAlways, "[DIALOG] CDialogActorContext::Update: %s Actor=%d (EntityId=%d) has died. Aborting.", m_pSession->GetDebugName(), m_actorID, m_entityID); AbortContext(true, CDialogSession::eAR_ActorDead); return true; } } if (m_bIsLocalPlayer) { // when the local player is involved in the conversation do some special checks if (DoLocalPlayerChecks(dt) == false) { DiaLOG::Log(DiaLOG::eAlways, "[DIALOG] CDialogActorContext::Update: %s Abort from LocalPlayer.", m_pSession->GetDebugName()); AbortContext(true, m_bIsAwareInRange == false ? CDialogSession::eAR_PlayerOutOfRange : CDialogSession::eAR_PlayerOutOfView); return true; } } if (m_bAbortFromAI) { m_bAbortFromAI = false; if (!IsAborted()) { DiaLOG::Log(DiaLOG::eAlways, "[DIALOG] CDialogActorContext::Update: %s Abort from AI.", m_pSession->GetDebugName()); AbortContext(true, CDialogSession::eAR_AIAborted); return true; } } if (SessionAllowsLookAt()) { DoStickyLookAt(); } int loop = 0; do { // DiaLOG::Log("[DIALOG] DiaLOG::eAlways"CDialogActorContext::Update: %s now=%f actorId=%d loop=%d", m_pSession->GetDebugName(), now, m_actorID, loop); bool bAdvance = false; switch (m_phase) { case eDAC_Idle: break; case eDAC_NewLine: { m_bHasScheduled = false; m_lookAtTimeOut = LOOKAT_TIMEOUT; m_animTimeOut = ANIM_TIMEOUT; m_soundTimeOut = SOUND_TIMEOUT; // wait one second until sound is timed out m_bAnimScheduled = false; m_bAnimStarted = false; m_bSoundScheduled = false; m_bSoundStarted = false; m_soundLength = 0.0f; if (m_pCurLine->m_flagResetLookAt) { m_stickyLookAtActorID = CDialogScript::NO_ACTOR_ID; m_lookAtActorID = CDialogScript::NO_ACTOR_ID; } // check if look-at sticky is set else if (m_pCurLine->m_lookatActor != CDialogScript::NO_ACTOR_ID) { if (m_pCurLine->m_flagLookAtSticky == false) { m_lookAtActorID = m_pCurLine->m_lookatActor; m_stickyLookAtActorID = CDialogScript::NO_ACTOR_ID; } else { m_stickyLookAtActorID = m_pCurLine->m_lookatActor; m_lookAtActorID = CDialogScript::NO_ACTOR_ID; } } bAdvance = true; // handle the first sticky look-at here if (SessionAllowsLookAt()) { DoStickyLookAt(); } } break; case eDAC_LookAt: { bool bWaitForLookAtFinish = true; bAdvance = true; if (SessionAllowsLookAt() == false) { break; } // Question: maybe do this although EP is requested if (bWaitForLookAtFinish && m_lookAtActorID != CDialogScript::NO_ACTOR_ID && m_pCurLine->m_flagAGEP == false) { IEntity* pActorEntity = m_pSession->GetActorEntity(m_actorID); IEntity* pLookAtEntity = m_pSession->GetActorEntity(m_lookAtActorID); if (pActorEntity != 0) { m_lookAtTimeOut -= dt; bool bTargetReached; //bool bSuccess = DoLookAt(pActorEntity, pLookAtEntity, bTargetReached); DoLookAt(pActorEntity, pLookAtEntity, bTargetReached); //DiaLOG::Log(DiaLOG::eDebugA, "[DIALOG] CDialogActorContext::Update: %s now=%f actorID=%d phase=eDAC_LookAt %d", // m_pSession->GetDebugName(), now, m_actorID, bTargetReached); if (/* bSuccess == false || */ bTargetReached || m_lookAtTimeOut<=0.0f) { DiaLOG::Log(DiaLOG::eAlways, "[DIALOG] CDialogActorContext::Update: %s now=%f actorID=%d phase=eDAC_LookAt %s", m_pSession->GetDebugName(), now, m_actorID, bTargetReached ? "Target Reached" : "Timed Out"); m_lookAtActorID = CDialogScript::NO_ACTOR_ID; } else bAdvance = false; } } } break; case eDAC_Anim: { bAdvance = true; if (SessionAllowsLookAt() && m_lookAtActorID != CDialogScript::NO_ACTOR_ID) // maybe: don't do this when EP is requested [&& m_pCurLine->m_flagAGEP == false] { IEntity* pActorEntity = m_pSession->GetActorEntity(m_actorID); IEntity* pLookAtEntity = m_pSession->GetActorEntity(m_lookAtActorID); if (pActorEntity != 0) { m_lookAtTimeOut -= dt; bool bTargetReached; //bool bSuccess = DoLookAt(pActorEntity, pLookAtEntity, bTargetReached); DoLookAt(pActorEntity, pLookAtEntity, bTargetReached); if (/* bSuccess == false || */ bTargetReached || m_lookAtTimeOut<=0.0f) { DiaLOG::Log(DiaLOG::eAlways, "[DIALOG] CDialogActorContext::Update: %s now=%f actorID=%d phase=eDAC_Anim %s", m_pSession->GetDebugName(), now, m_actorID, bTargetReached ? "Target Reached" : "Timed Out"); m_lookAtActorID = CDialogScript::NO_ACTOR_ID; } else bAdvance = false; } } const bool bHasAnim = !m_pCurLine->m_anim.empty(); if (SessionAllowsAnim() && bHasAnim) { bAdvance = false; if (!m_bAnimScheduled) { m_bSoundStopsAnim = false; // whenever there is a new animation, no need for the still playing sound // to stop the animation m_bAnimStarted = false; m_bAnimScheduled = true; // schedule animation IEntity* pActorEntity = m_pSession->GetActorEntity(m_actorID); if (pActorEntity) DoAnimAction(pActorEntity, m_pCurLine->m_anim, m_pCurLine->m_flagAGSignal, m_pCurLine->m_flagAGEP); else bAdvance = true; } else { // we scheduled it already // wait until it starts or timeout m_animTimeOut-=dt; bAdvance = m_animTimeOut <= 0.0f || m_bAnimStarted; if (bAdvance) { DiaLOG::Log(DiaLOG::eAlways, "[DIALOG] CDialogActorContext::Update: %s Now=%f actorID=%d phase=eDAC_Anim %s", m_pSession->GetDebugName(), now, m_actorID, m_bAnimStarted ? "Anim Started" : "Anim Timed Out"); } } } } break; case eDAC_ScheduleSoundPlay: { bAdvance = true; const bool bHasSound = !m_pCurLine->m_sound.empty(); if (bHasSound) { if (m_bSoundScheduled == false) { IEntity* pActorEntity = m_pSession->GetActorEntity(m_actorID); if (pActorEntity == 0) break; IEntityAudioProxy* pActorAudioProxy = m_pSession->GetEntityAudioProxy(pActorEntity); if (pActorAudioProxy == 0) break; REINST("play voice line"); // start a new sound //int sFlags = CDialogActorContext::SOUND_FLAGS; //if (CDialogSystem::sLoadSoundSynchronously != 0) // sFlags |= FLAG_SOUND_LOAD_SYNCHRONOUSLY; // //// if it's the local player make the sound relative to the entity //if (m_bIsLocalPlayer) // sFlags |= FLAG_SOUND_RELATIVE; //const char* soundKey = GetSoundKey(m_pCurLine->m_sound); //ISound* pSound = 0; //pSound = gEnv->pAudioSystem->CreateSound(soundKey, sFlags); //DiaLOG::Log(DiaLOG::eDebugA, "[DIALOG] CDialogActorContex::Update: %s Now=%f actorID=%d phase=eDAC_ScheduleSoundPlay: Starting '%s' [key=%s]", // m_pSession->GetDebugName(), now, m_actorID, m_pCurLine->m_sound.c_str(), soundKey); //if (!pSound) //{ // GameWarning("[DIALOG] CDialogActorContext::Update: %s ActorID=%d: Cannot play sound '%s'", // m_pSession->GetDebugName(), m_actorID, m_pCurLine->m_sound.c_str()); //} //if (pSound) //{ // if (m_bSoundStopsAnim) // { // m_bSoundStopsAnim = false; // if (m_pAGState != 0) // { // ResetAGState(); // DiaLOG::Log(DiaLOG::eDebugA, "[DIALOG] CDialogActorContext::Update: %s Now=%f actorID=%d phase=eDAC_ScheduleSoundPlay: Stopping old animation", // m_pSession->GetDebugName(), now, m_actorID); // } // } // StopSound(); // apparently, if we dont explicitely stop the sound, in rare cases it never stops. Im pretty sure that is an engine/fmod bug. // // stopping it this way may lead to some subtitles staying for an extra couple seconds on screen (this comes from another engine bug/problem related to an extra fade out time added to cover the dummy NAX soudns) // m_soundID = pSound->GetId(); // m_bSoundStarted = false; // m_bSoundScheduled = true; // // tell the animation whether to stop on sound stop // m_bSoundStopsAnim = m_pCurLine->m_flagSoundStopsAnim; // DiaLOG::Log(DiaLOG::eDebugA, "[DIALOG] CDialogActorContext::Update: %s Now=%f actorID=%d phase=eDAC_ScheduleSoundPlay: Reg as listener on 0x%p '%s'", // m_pSession->GetDebugName(), now, m_actorID, pSound, pSound->GetName()); // pSound->SetSemantic(eSoundSemantic_Dialog); // pSound->AddEventListener(this, "DialogActor"); // event listener will set m_soundLength // // sound proxy uses head pos on dialog sounds // const bool bResult = pActorAudioProxy->PlaySound(pSound, Vec3(ZERO), FORWARD_DIRECTION, 1.0f); // if (bResult) // { // // Fetch some localization info for the sound // ILocalizationManager* pLocMgr = gEnv->pSystem->GetLocalizationManager(); // if (pLocMgr && CDialogSystem::sWarnOnMissingLoc != 0) // { // SLocalizedInfoGame GameInfo; // const bool bFound = pLocMgr->GetLocalizedInfoByKey(soundKey, GameInfo); // if (!bFound) // { // GameWarning("[DIALOG] CDialogActorContext::Update: '%s' DialogScript '%s': Localized info for '%s' not found!", // m_pSession->GetDebugName(), m_pSession->GetScript()->GetID().c_str(), m_pCurLine->m_sound.c_str()); // } // } // bAdvance = false; // don't advance // } // else // { // GameWarning("[DIALOG] CDialogActorContext::Update: %s ActorID=%d: Cannot play sound '%s' [AudioProxy ignored playback]", // m_pSession->GetDebugName(), m_actorID, m_pCurLine->m_sound.c_str()); // pSound->Stop(ESoundStopMode_AtOnce); // m_soundID = INVALID_SOUNDID; // pSound->RemoveEventListener(this); // pSound = NULL; // } //} //else //{ // GameWarning("[DIALOG] CDialogActorContext::Update: %s ActorID=%d: Cannot play sound '%s' [AudioProxy returns invalid sound]", // m_pSession->GetDebugName(), m_actorID, m_pCurLine->m_sound.c_str()); //} } else { // sound has been scheduled // wait for sound start or timeout m_soundTimeOut-=dt; const bool bTimedOut = m_soundTimeOut <= 0.0f; bAdvance = bTimedOut || m_bSoundStarted; if (bAdvance) { if (bTimedOut) StopSound(true); // unregister from sound as listener and free resource DiaLOG::Log(DiaLOG::eAlways, "[DIALOG] CDialogActorContext::Update: %s Now=%f actorID=%d phase=eDAC_ScheduleSoundPlay %s", m_pSession->GetDebugName(), now, m_actorID, m_bSoundStarted ? "Sound Started" : "Sound Timed Out"); } } } } break; case eDAC_SoundFacial: { bAdvance = true; const bool bHasSound = !m_pCurLine->m_sound.empty(); const bool bHasFacial = !m_pCurLine->m_facial.empty() || m_pCurLine->m_flagResetFacial; if (bHasFacial) { IEntity* pActorEntity = m_pSession->GetActorEntity(m_actorID); if (pActorEntity) DoFacialExpression(pActorEntity, m_pCurLine->m_facial, m_pCurLine->m_facialWeight, m_pCurLine->m_facialFadeTime); } float delay = m_pCurLine->m_delay; if (bHasSound && m_bSoundStarted) { if (m_soundLength < 0.0f) { m_soundLength = Random(2.0f,6.0f); DiaLOG::Log(DiaLOG::eAlways, "[DIALOG] CDialogActorContext::Update: %s Now=%f actorID=%d phase=eDAC_SoundFacial Faking SoundTime to %f", m_pSession->GetDebugName(), now, m_actorID, m_soundLength); } DiaLOG::Log(DiaLOG::eAlways, "[DIALOG] CDialogActorContext::Update: %s Now=%f actorID=%d phase=eDAC_SoundFacial Delay=%f SoundTime=%f", m_pSession->GetDebugName(), now , m_actorID, delay, m_soundLength); delay += m_soundLength; } // schedule END if (delay < 0.0f) delay = 0.0f; m_pSession->ScheduleNextLine(delay+0.05f); // ~1 frame at 20 fps. we now stop the current line sound before going for next line. Sometimes, this stop call is right before the // sound has actually stopped in engine side. When that happens, the engine is adding ~2 seconds extra to the sound duration (because fade problems related to NAX header) // and that looks bad if subtitles are enabled. So we add this small delay here to try to minimize that situation. // this is part of the workaround for some dialogs apparently never finishing in the engine side (rare). m_bHasScheduled = true; } break; case eDAC_EndLine: bAdvance = true; if (m_bHasScheduled == false) { m_bHasScheduled = true; m_pSession->ScheduleNextLine(m_pCurLine->m_delay); } break; } if (bAdvance) { AdvancePhase(); dt = 0.0f; ++loop; assert (loop <= eDAC_EndLine+1); if (loop > eDAC_EndLine+1) { DiaLOG::Log(DiaLOG::eAlways, "[DIALOG] CDialogActorContext::Update: %s Actor=%d InternalLoopCount=%d. Final Exit!", m_pSession->GetDebugName(), m_actorID, loop); } } else break; } while (true); return true; }