BVB Source Codes

CRYENGINE Show CommunicationHandler.cpp Source code

Return Download CRYENGINE: download CommunicationHandler.cpp Source code - Download CRYENGINE Source code - Type:.cpp
  1. // Copyright 2001-2016 Crytek GmbH / Crytek Group. All rights reserved.
  2.  
  3. #include "StdAfx.h"
  4. #include "CommunicationHandler.h"
  5. #include "AIProxy.h"
  6.  
  7. namespace ATLUtils
  8. {
  9. void SetSwitchState(const char* switchIdName, const char* switchValue, IEntityAudioComponent* pIEntityAudioComponent)
  10. {
  11.         assert(gEnv && gEnv->pAudioSystem);
  12.         IAudioSystem* pAudioSystem = gEnv->pAudioSystem;
  13.         AudioControlId switchControlId(INVALID_AUDIO_CONTROL_ID);
  14.         pAudioSystem->GetAudioSwitchId(switchIdName, switchControlId);
  15.         if (switchControlId)
  16.         {
  17.                 AudioSwitchStateId switchStateId(INVALID_AUDIO_SWITCH_STATE_ID);
  18.                 pAudioSystem->GetAudioSwitchStateId(switchControlId, switchValue, switchStateId);
  19.                 IF_UNLIKELY (switchStateId == INVALID_AUDIO_SWITCH_STATE_ID)
  20.                 {
  21.                         CryWarning(VALIDATOR_MODULE_AI, VALIDATOR_WARNING, "CommunicationHandler - You are trying to switch the state of the audio switch '%s' to the value '%s'. This switch state doesn't exist.", switchIdName, switchValue);
  22.                 }
  23.                 pIEntityAudioComponent->SetSwitchState(switchControlId, switchStateId);
  24.         }
  25. }
  26. }
  27.  
  28. CommunicationHandler::CommunicationHandler(CAIProxy& proxy, IEntity* entity)
  29.         : m_proxy(proxy)
  30.         , m_entityId(entity->GetId())
  31.         , m_agState(0)
  32.         , m_currentQueryID(0)
  33.         , m_currentPlaying(0)
  34.         , m_signalInputID(0)
  35.         , m_actionInputID(0)
  36. {
  37.         assert(entity);
  38.         Reset();
  39.  
  40.         gEnv->pAudioSystem->AddRequestListener(&CommunicationHandler::TriggerFinishedCallback, this, eAudioRequestType_AudioCallbackManagerRequest, eAudioCallbackManagerRequestType_ReportFinishedTriggerInstance);
  41. }
  42.  
  43. CommunicationHandler::~CommunicationHandler()
  44. {
  45.         gEnv->pAudioSystem->RemoveRequestListener(&CommunicationHandler::TriggerFinishedCallback, this);
  46.  
  47.         if (m_agState)
  48.                 m_agState->RemoveListener(this);
  49. }
  50.  
  51. void CommunicationHandler::Reset()
  52. {
  53.         // Notify sound/voice listeners that the sounds have stopped
  54.         {
  55.                 IEntityAudioComponent* pIEntityAudioComponent;
  56.                 IEntity* pEntity = gEnv->pEntitySystem->GetEntity(m_entityId);
  57.                 if (pEntity)
  58.                 {
  59.                         pIEntityAudioComponent = pEntity->GetOrCreateComponent<IEntityAudioComponent>();
  60.                 }
  61.  
  62.                 PlayingSounds::iterator end = m_playingSounds.end();
  63.  
  64.                 for (PlayingSounds::iterator it(m_playingSounds.begin()); it != end; ++it)
  65.                 {
  66.                         PlayingSound& playingSound(it->second);
  67.  
  68.                         if (playingSound.listener)
  69.                         {
  70.                                 ECommunicationHandlerEvent cancelEvent = (playingSound.type == Sound) ? SoundCancelled : VoiceCancelled;
  71.                                 playingSound.listener->OnCommunicationHandlerEvent(cancelEvent, playingSound.playID, m_entityId);
  72.                         }
  73.  
  74.                         if (pIEntityAudioComponent)
  75.                         {
  76.                                 pIEntityAudioComponent->ExecuteTrigger(playingSound.correspondingStopControlId);
  77.                         }
  78.                 }
  79.  
  80.                 m_playingSounds.clear();
  81.         }
  82.  
  83.         // Notify animation listeners that the animations have stopped
  84.         {
  85.                 PlayingAnimations::iterator end = m_playingAnimations.end();
  86.  
  87.                 for (PlayingAnimations::iterator it(m_playingAnimations.begin()); it != end; ++it)
  88.                 {
  89.                         PlayingAnimation& playingAnim(it->second);
  90.  
  91.                         if (playingAnim.listener)
  92.                         {
  93.                                 ECommunicationHandlerEvent cancelEvent = (playingAnim.method == AnimationMethodAction) ? ActionCancelled : SignalCancelled;
  94.                                 playingAnim.listener->OnCommunicationHandlerEvent(cancelEvent, playingAnim.playID, m_entityId);
  95.                         }
  96.                 }
  97.  
  98.                 m_playingAnimations.clear();
  99.         }
  100.  
  101.         const ICVar* pCvar = gEnv->pConsole->GetCVar("ai_CommunicationForceTestVoicePack");
  102.         const bool useTestVoicePack = pCvar ? pCvar->GetIVal() == 1 : false;
  103.  
  104.         IEntity* pEntity = gEnv->pEntitySystem->GetEntity(m_entityId);
  105.         if (pEntity)
  106.         {
  107.                 IEntityAudioComponent* pIEntityAudioComponent = pEntity->GetOrCreateComponent<IEntityAudioComponent>();
  108.                 if (pIEntityAudioComponent)
  109.                 {
  110.                         const ICommunicationManager::WWiseConfiguration& wiseConfigutation = gEnv->pAISystem->GetCommunicationManager()->GetWiseConfiguration();
  111.  
  112.                         if (!wiseConfigutation.switchNameForCharacterVoice.empty())
  113.                         {
  114.                                 const char* voiceLibraryName = m_proxy.GetVoiceLibraryName(useTestVoicePack);
  115.                                 if (voiceLibraryName && voiceLibraryName[0])
  116.                                 {
  117.                                         ATLUtils::SetSwitchState(wiseConfigutation.switchNameForCharacterVoice.c_str(), voiceLibraryName, pIEntityAudioComponent);
  118.                                 }
  119.                         }
  120.  
  121.                         if (!wiseConfigutation.switchNameForCharacterType.empty())
  122.                         {
  123.                                 if (IAIObject* pAIObject = pEntity->GetAI())
  124.                                 {
  125.                                         if (IAIActorProxy* pAIProxy = pAIObject->GetProxy())
  126.                                         {
  127.                                                 stack_string characterType;
  128.                                                 characterType.Format("%f", pAIProxy->GetFmodCharacterTypeParam());
  129.                                                 if (!characterType.empty())
  130.                                                 {
  131.                                                         ATLUtils::SetSwitchState(wiseConfigutation.switchNameForCharacterType.c_str(), characterType.c_str(), pIEntityAudioComponent);
  132.                                                 }
  133.                                         }
  134.                                 }
  135.                         }
  136.                 }
  137.         }
  138. }
  139.  
  140. bool CommunicationHandler::IsInAGState(const char* name)
  141. {
  142.         if (GetAGState())
  143.         {
  144.                 char inputValue[256] = "";
  145.                 m_agState->GetInput(m_signalInputID, inputValue);
  146.  
  147.                 if (strcmp(inputValue, name) == 0)
  148.                         return true;
  149.  
  150.                 m_agState->GetInput(m_actionInputID, inputValue);
  151.  
  152.                 if (strcmp(inputValue, name) == 0)
  153.                         return true;
  154.  
  155.         }
  156.  
  157.         return false;
  158. }
  159.  
  160. void CommunicationHandler::ResetAnimationState()
  161. {
  162.         if (GetAGState())
  163.         {
  164.                 m_agState->SetInput(m_signalInputID, "none");
  165.                 m_agState->SetInput(m_actionInputID, "idle");
  166.  
  167.                 m_agState->Update();
  168.                 m_agState->ForceTeleportToQueriedState();
  169.         }
  170. }
  171.  
  172. void CommunicationHandler::OnReused(IEntity* entity)
  173. {
  174.         assert(entity);
  175.         m_entityId = entity->GetId();
  176.         Reset();
  177. }
  178.  
  179. SCommunicationSound CommunicationHandler::PlaySound(CommPlayID playID, const char* name, IEventListener* listener)
  180. {
  181.         return PlaySound(playID, name, Sound, listener);
  182. }
  183.  
  184. void CommunicationHandler::StopSound(const SCommunicationSound& soundToStop)
  185. {
  186.         IEntity* pEntity = gEnv->pEntitySystem->GetEntity(m_entityId);
  187.         if (pEntity)
  188.         {
  189.                 IEntityAudioComponent* pIEntityAudioComponent = pEntity->GetOrCreateComponent<IEntityAudioComponent>();
  190.                 if (pIEntityAudioComponent)
  191.                 {
  192.                         if (soundToStop.stopSoundControlId != INVALID_AUDIO_CONTROL_ID)
  193.                         {
  194.                                 pIEntityAudioComponent->ExecuteTrigger(soundToStop.stopSoundControlId);
  195.                         }
  196.                         else
  197.                         {
  198.                                 pIEntityAudioComponent->StopTrigger(soundToStop.playSoundControlId);
  199.                         }
  200.  
  201.                         PlayingSounds::iterator it = m_playingSounds.find(soundToStop.playSoundControlId);
  202.                         if (it != m_playingSounds.end())
  203.                         {
  204.                                 PlayingSound& playingSound = it->second;
  205.                                 if (playingSound.listener)
  206.                                 {
  207.                                         ECommunicationHandlerEvent cancelEvent = (playingSound.type == Sound) ? SoundCancelled : VoiceCancelled;
  208.                                         playingSound.listener->OnCommunicationHandlerEvent(cancelEvent, playingSound.playID, m_entityId);
  209.                                 }
  210.  
  211.                                 m_playingSounds.erase(it);
  212.                         }
  213.                 }
  214.         }
  215. }
  216.  
  217. SCommunicationSound CommunicationHandler::PlayVoice(CommPlayID playID, const char* variationName, IEventListener* listener)
  218. {
  219.         return PlaySound(playID, variationName, Voice, listener);
  220. }
  221.  
  222. void CommunicationHandler::StopVoice(const SCommunicationSound& voiceToStop)
  223. {
  224.         StopSound(voiceToStop);
  225. }
  226.  
  227. void CommunicationHandler::PlayAnimation(CommPlayID playID, const char* name, EAnimationMethod method, IEventListener* listener)
  228. {
  229.         bool ok = false;
  230.  
  231.         if (GetAGState())
  232.         {
  233.                 AnimationGraphInputID inputID = method == AnimationMethodAction ? m_actionInputID : m_signalInputID;
  234.  
  235.                 if (ok = m_agState->SetInput(inputID, name, &m_currentQueryID))
  236.                 {
  237.                         //Force the animation graph to update to the new signal, to provide quicker communication responsiveness
  238.                         m_agState->Update();
  239.                         m_agState->ForceTeleportToQueriedState();
  240.                         std::pair<PlayingAnimations::iterator, bool> iresult = m_playingAnimations.insert(
  241.                           PlayingAnimations::value_type(m_currentQueryID, PlayingAnimation()));
  242.  
  243.                         PlayingAnimation& playingAnimation = iresult.first->second;
  244.                         playingAnimation.listener = listener;
  245.                         playingAnimation.name = name;
  246.                         playingAnimation.method = method;
  247.                         playingAnimation.playing = m_currentPlaying;
  248.                         playingAnimation.playID = playID;
  249.                 }
  250.                 m_currentPlaying = false;
  251.                 m_currentQueryID = 0;
  252.         }
  253.  
  254.         if (!ok && listener)
  255.                 listener->OnCommunicationHandlerEvent(
  256.                   (method == AnimationMethodAction) ? ActionFailed : SignalFailed, playID, m_entityId);
  257. }
  258.  
  259. void CommunicationHandler::StopAnimation(CommPlayID playID, const char* name, EAnimationMethod method)
  260. {
  261.         if (GetAGState())
  262.         {
  263.                 if (method == AnimationMethodSignal)
  264.                 {
  265.                         m_agState->SetInput(m_signalInputID, "none");
  266.                 }
  267.                 else
  268.                 {
  269.                         m_agState->SetInput(m_actionInputID, "idle");
  270.                 }
  271.                 m_agState->Update();
  272.                 m_agState->ForceTeleportToQueriedState();
  273.         }
  274.  
  275.         PlayingAnimations::iterator it = m_playingAnimations.begin();
  276.         PlayingAnimations::iterator end = m_playingAnimations.end();
  277.  
  278.         for (; it != end; )
  279.         {
  280.                 PlayingAnimation& playingAnim = it->second;
  281.  
  282.                 bool animMatch = playID ? playingAnim.playID == playID : strcmp(playingAnim.name, name) == 0;
  283.  
  284.                 if (animMatch)
  285.                 {
  286.                         if (playingAnim.listener)
  287.                         {
  288.                                 ECommunicationHandlerEvent cancelEvent = (playingAnim.method == AnimationMethodSignal) ? SignalCancelled : ActionCancelled;
  289.                                 playingAnim.listener->OnCommunicationHandlerEvent(cancelEvent, playingAnim.playID, m_entityId);
  290.                         }
  291.  
  292.                         m_playingAnimations.erase(it++);
  293.                 }
  294.                 else
  295.                 {
  296.                         ++it;
  297.                 }
  298.         }
  299. }
  300.  
  301. SCommunicationSound CommunicationHandler::PlaySound(CommPlayID playID, const char* name, ESoundType type, IEventListener* listener)
  302. {
  303.         IEntity* pEntity = gEnv->pEntitySystem->GetEntity(m_entityId);
  304.         if (pEntity)
  305.         {
  306.                 IEntityAudioComponent* pIEntityAudioComponent = pEntity->GetOrCreateComponent<IEntityAudioComponent>();
  307.                 if (pIEntityAudioComponent)
  308.                 {
  309.                         const ICommunicationManager::WWiseConfiguration& wiseConfigutation = gEnv->pAISystem->GetCommunicationManager()->GetWiseConfiguration();
  310.  
  311.                         assert(gEnv && gEnv->pAudioSystem);
  312.                         IAudioSystem* pAudioSystem = gEnv->pAudioSystem;
  313.                         AudioControlId playCommunicationControlId(INVALID_AUDIO_CONTROL_ID);
  314.                         AudioControlId stopCommunicationControlId(INVALID_AUDIO_CONTROL_ID);
  315.                         stack_string playTriggerName;
  316.                         playTriggerName.Format("%s%s", wiseConfigutation.prefixForPlayTrigger.c_str(), name);
  317.                         stack_string stopTriggerName;
  318.                         stopTriggerName.Format("%s%s", wiseConfigutation.prefixForStopTrigger.c_str(), name);
  319.  
  320.                         pAudioSystem->GetAudioTriggerId(playTriggerName, playCommunicationControlId);
  321.                         pAudioSystem->GetAudioTriggerId(stopTriggerName, stopCommunicationControlId);
  322.                         if (playCommunicationControlId != INVALID_AUDIO_CONTROL_ID)
  323.                         {
  324.                                 if (listener)
  325.                                 {
  326.                                         std::pair<PlayingSounds::iterator, bool> iresult = m_playingSounds.insert(
  327.                                           PlayingSounds::value_type(playCommunicationControlId, PlayingSound()));
  328.  
  329.                                         PlayingSound& playingSound = iresult.first->second;
  330.                                         playingSound.listener = listener;
  331.                                         playingSound.type = type;
  332.                                         playingSound.playID = playID;
  333.                                 }
  334.  
  335.                                 SAudioCallBackInfo const callbackInfo(this, reinterpret_cast<void*>(static_cast<UINT_PTR>(m_entityId)), this, eAudioRequestFlags_PriorityNormal | eAudioRequestFlags_SyncFinishedCallback);
  336.                                 pIEntityAudioComponent->ExecuteTrigger(playCommunicationControlId, DEFAULT_AUDIO_PROXY_ID, callbackInfo);
  337.  
  338.                                 SCommunicationSound soundInfo;
  339.                                 soundInfo.playSoundControlId = playCommunicationControlId;
  340.                                 soundInfo.stopSoundControlId = stopCommunicationControlId;
  341.                                 return soundInfo;
  342.                         }
  343.                         else
  344.                         {
  345.                                 CryLogAlways("The audio trigger to play communication '%s' is not defined.", name);
  346.                         }
  347.                 }
  348.         }
  349.  
  350.         return SCommunicationSound();
  351. }
  352.  
  353. void CommunicationHandler::TriggerFinishedCallback(SAudioRequestInfo const* const pAudioRequestInfo)
  354. {
  355.         EntityId entityId = static_cast<EntityId>(reinterpret_cast<UINT_PTR>(pAudioRequestInfo->pUserData));
  356.  
  357.         if (IEntity* pEntity = gEnv->pEntitySystem->GetEntity(entityId))
  358.         {
  359.                 if (IAIObject* pAIObject = pEntity->GetAI())
  360.                 {
  361.                         if (IAIActorProxy* pAiProxy = pAIObject->GetProxy())
  362.                         {
  363.                                 if (IAICommunicationHandler* pCommunicationHandler = pAiProxy->GetCommunicationHandler())
  364.                                 {
  365.                                         pCommunicationHandler->OnSoundTriggerFinishedToPlay(pAudioRequestInfo->audioControlId);
  366.                                 }
  367.                         }
  368.                 }
  369.         }
  370. }
  371.  
  372. void CommunicationHandler::OnSoundTriggerFinishedToPlay(const AudioControlId nTriggerID)
  373. {
  374.         PlayingSounds::iterator it = m_playingSounds.find(nTriggerID);
  375.         if (it != m_playingSounds.end())
  376.         {
  377.                 PlayingSound& playing = it->second;
  378.                 if (playing.listener)
  379.                 {
  380.                         ECommunicationHandlerEvent outEvent = (playing.type == Sound) ? SoundFinished : VoiceFinished;
  381.  
  382.                         // Let the CommunicationPlayer know this sound/voice has finished
  383.                         playing.listener->OnCommunicationHandlerEvent(outEvent, playing.playID, m_entityId);
  384.                 }
  385.  
  386.                 m_playingSounds.erase(it);
  387.         }
  388. }
  389.  
  390. IAnimationGraphState* CommunicationHandler::GetAGState()
  391. {
  392.         if (m_agState)
  393.                 return m_agState;
  394.  
  395.         if (IActor* actor = CCryAction::GetCryAction()->GetIActorSystem()->GetActor(m_entityId))
  396.         {
  397.                 if (m_agState = actor->GetAnimationGraphState())
  398.                 {
  399.                         m_agState->AddListener("AICommunicationHandler", this);
  400.                         m_signalInputID = m_agState->GetInputId("Signal");
  401.                         m_actionInputID = m_agState->GetInputId("Action");
  402.                 }
  403.         }
  404.  
  405.         return m_agState;
  406. }
  407.  
  408. void CommunicationHandler::QueryComplete(TAnimationGraphQueryID queryID, bool succeeded)
  409. {
  410.         if (queryID == m_currentQueryID) // this call happened during SetInput
  411.         {
  412.                 m_currentPlaying = true;
  413.                 m_agState->QueryLeaveState(&m_currentQueryID);
  414.  
  415.                 return;
  416.         }
  417.  
  418.         PlayingAnimations::iterator animationIt = m_playingAnimations.find(queryID);
  419.         if (animationIt != m_playingAnimations.end())
  420.         {
  421.                 PlayingAnimation& playingAnimation = animationIt->second;
  422.                 if (!playingAnimation.playing)
  423.                 {
  424.                         ECommunicationHandlerEvent event;
  425.  
  426.                         if (playingAnimation.method == AnimationMethodAction)
  427.                                 event = succeeded ? ActionStarted : ActionFailed;
  428.                         else
  429.                                 event = succeeded ? SignalStarted : SignalFailed;
  430.  
  431.                         if (playingAnimation.listener)
  432.                                 playingAnimation.listener->OnCommunicationHandlerEvent(event, playingAnimation.playID, m_entityId);
  433.  
  434.                         if (succeeded)
  435.                         {
  436.                                 playingAnimation.playing = true;
  437.  
  438.                                 TAnimationGraphQueryID leaveQueryID;
  439.                                 m_agState->QueryLeaveState(&leaveQueryID);
  440.  
  441.                                 m_playingAnimations.insert(PlayingAnimations::value_type(leaveQueryID, playingAnimation));
  442.                         }
  443.                 }
  444.                 else
  445.                 {
  446.                         ECommunicationHandlerEvent event;
  447.  
  448.                         if (playingAnimation.method == AnimationMethodAction)
  449.                                 event = ActionCancelled;
  450.                         else
  451.                                 event = succeeded ? SignalFinished : SignalCancelled;
  452.  
  453.                         if (playingAnimation.listener)
  454.                                 playingAnimation.listener->OnCommunicationHandlerEvent(event, playingAnimation.playID, m_entityId);
  455.                 }
  456.  
  457.                 m_playingAnimations.erase(animationIt);
  458.         }
  459. }
  460.  
  461. void CommunicationHandler::DestroyedState(IAnimationGraphState* agState)
  462. {
  463.         if (agState == m_agState)
  464.                 m_agState = 0;
  465. }
  466.  
  467. bool CommunicationHandler::IsPlayingAnimation() const
  468. {
  469.         return !m_playingAnimations.empty();
  470. }
  471.  
  472. bool CommunicationHandler::IsPlayingSound() const
  473. {
  474.         return true;//!m_playingSounds.empty();
  475. }
  476.  
downloadCommunicationHandler.cpp Source code - Download CRYENGINE Source code
Related Source Codes/Software:
postal - 2017-06-11
reactide - Reactide is the first dedicated IDE for React web ... 2017-06-11
rkt - rkt is a pod-native container engine for Linux. It... 2017-06-11
uWebSockets - Tiny WebSockets https://for... 2017-06-11
realworld - TodoMVC for the RealWorld - Exemplary fullstack Me... 2017-06-11
CRYENGINE - CRYENGINE is a powerful real-time game development... 2017-06-11
goreplay - GoReplay is an open-source tool for capturing and ... 2017-06-10
pyenv - Simple Python version management 2017-06-10
redux-saga - An alternative side effect model for Redux apps ... 2017-06-10
angular-starter - 2017-06-10

 Back to top