BVB Source Codes

CRYENGINE Show AIBubblesSystemImpl.cpp Source code

Return Download CRYENGINE: download AIBubblesSystemImpl.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 "AIBubblesSystemImpl.h"
  5. #include "../DebugDrawContext.h"
  6.  
  7. bool AIQueueBubbleMessage(const char* messageName, const EntityId entityID,
  8.                           const char* message, uint32 flags, float duration /*= 0*/, SAIBubbleRequest::ERequestType requestType /* = eRT_ErrorMessage */)
  9. {
  10. #ifdef CRYAISYSTEM_DEBUG
  11.         if (IAIBubblesSystem* pAIBubblesSystem = gAIEnv.pBubblesSystem)
  12.         {
  13.                 SAIBubbleRequest request(entityID, message, flags, duration, requestType);
  14.                 pAIBubblesSystem->QueueMessage(messageName, request);
  15.                 return true;
  16.         }
  17. #endif
  18.         return false;
  19. }
  20.  
  21. #ifdef CRYAISYSTEM_DEBUG
  22.  
  23. void CAIBubblesSystem::Init()
  24. {
  25.         SetNameFilter(gAIEnv.CVars.BubblesSystemNameFilter);
  26. }
  27.  
  28. void CAIBubblesSystem::Reset()
  29. {
  30.         stl::free_container(m_entityRequestsMap);
  31. }
  32.  
  33. static uint32 ComputeMessageNameId(const char* szMessageName)
  34. {
  35.         return CCrc32::ComputeLowercase(szMessageName);
  36. }
  37.  
  38. SBubbleRequestId CAIBubblesSystem::QueueMessage(const char* messageName, const SAIBubbleRequest& request)
  39. {
  40.         const TBubbleRequestOptionFlags requestFlags = request.GetFlags();
  41.         const EntityId entityID = request.GetEntityID();
  42.         const IEntity* pEntity = gEnv->pEntitySystem->GetEntity(entityID);
  43.         if (!pEntity)
  44.         {
  45.                 LogMessage("The AIBubblesSystem received a message for a non existing entity."
  46.                            " The message will be discarded.", requestFlags);
  47.                 return SBubbleRequestId::Invalid();
  48.         }
  49.  
  50.         RequestsList& requestsList = m_entityRequestsMap[request.GetEntityID()];
  51.         const uint32 messageNameId = ComputeMessageNameId(messageName);
  52.         RequestsList::iterator requestContainerIt = std::find_if(requestsList.begin(), requestsList.end(), SRequestByMessageNameFinder(messageNameId));
  53.  
  54.         if (request.GetRequestType() == SAIBubbleRequest::eRT_PrototypeDialog && requestContainerIt != requestsList.end())
  55.         {
  56.                 requestsList.erase(requestContainerIt);
  57.                 requestContainerIt = requestsList.end();
  58.         }
  59.  
  60.         if (requestContainerIt == requestsList.end())
  61.         {
  62.                 const SBubbleRequestId requestId = ++m_requestIdCounter;
  63.  
  64.                 if (request.GetRequestType() == SAIBubbleRequest::eRT_PrototypeDialog)
  65.                         requestsList.push_back(SAIBubbleRequestContainer(requestId, messageNameId, request));
  66.                 else
  67.                         requestsList.push_front(SAIBubbleRequestContainer(requestId, messageNameId, request));
  68.  
  69.                 // Log the message and if it's needed show the blocking popup
  70.                 stack_string sTmp;
  71.                 stack_string sMessage;
  72.                 request.GetMessage(sTmp);
  73.                 sMessage.Format("%s - Message: %s", pEntity->GetName(), sTmp.c_str());
  74.  
  75.                 LogMessage(sMessage.c_str(), requestFlags);
  76.  
  77.                 PopupBlockingAlert(sMessage.c_str(), requestFlags);
  78.  
  79.                 return requestId;
  80.         }
  81.  
  82.         return SBubbleRequestId::Invalid();
  83. }
  84.  
  85. bool CAIBubblesSystem::CancelMessageBubble(const EntityId entityId, const SBubbleRequestId& bubbleRequestId)
  86. {
  87.         auto iter = m_entityRequestsMap.find(entityId);
  88.         if (iter != m_entityRequestsMap.end())
  89.         {
  90.                 RequestsList& requestsList = iter->second;
  91.                 RequestsList::iterator requestContainerIt = std::find_if(requestsList.begin(), requestsList.end(), SRequestByRequestIdFinder(bubbleRequestId));
  92.                 if (requestContainerIt != requestsList.end())
  93.                 {
  94.                         requestsList.erase(requestContainerIt);
  95.                         return true;
  96.                 }
  97.         }
  98.         return false;
  99. }
  100.  
  101. class CAIBubblesSystem::CBubbleRender
  102. {
  103. public:
  104.         explicit CBubbleRender(CDebugDrawContext& drawContext, EntityId entityId)
  105.                 : m_drawContext(drawContext)
  106.                 , m_entityId(entityId)
  107.                 , m_bubbleOnscreenPos(ZERO)
  108.                 , m_currentTextSize(1.0f)
  109.                 , m_bInitialized(false)
  110.                 , m_bOnScreen(false)
  111.         {}
  112.  
  113.         bool Prepare()
  114.         {
  115.                 if (m_entityId == INVALID_ENTITYID)
  116.                 {
  117.                         return false;
  118.                 }
  119.  
  120.                 if (!m_bInitialized)
  121.                 {
  122.                         const IEntity* pEntity = gEnv->pEntitySystem->GetEntity(m_entityId);
  123.                         if (!pEntity)
  124.                         {
  125.                                 m_entityId = INVALID_ENTITYID;
  126.                                 return false;
  127.                         }
  128.  
  129.                         m_bInitialized = true;
  130.  
  131.                         Vec3 entityPos = pEntity->GetWorldPos();
  132.                         AABB aabb;
  133.                         pEntity->GetLocalBounds(aabb);
  134.                         entityPos.z = entityPos.z + aabb.max.z + 0.2f;
  135.  
  136.                         float x, y, z;
  137.  
  138.                         if (m_drawContext->ProjectToScreen(entityPos.x, entityPos.y, entityPos.z, &x, &y, &z))
  139.                         {
  140.                                 if ((z >= 0.0f) && (z <= 1.0f))
  141.                                 {
  142.                                         m_bOnScreen = true;
  143.  
  144.                                         x *= m_drawContext->GetWidth() * 0.01f;
  145.                                         y *= m_drawContext->GetHeight() * 0.01f;
  146.  
  147.                                         m_bubbleOnscreenPos = Vec3(x, y, z);
  148.  
  149.                                         const float distance = gEnv->pSystem->GetViewCamera().GetPosition().GetDistance(entityPos);
  150.                                         m_currentTextSize = gAIEnv.CVars.BubblesSystemFontSize / distance;
  151.                                 }
  152.                         }
  153.                 }
  154.  
  155.                 return true;
  156.         }
  157.  
  158.         bool IsOnScreen() const
  159.         {
  160.                 return m_bOnScreen;
  161.         }
  162.  
  163.         void DrawBubble(const char* const message, const size_t numberOfLines, const EBubbleRequestOption flags)
  164.         {
  165.                 const float lineHeight = 11.5f * m_currentTextSize;
  166.                 const float messageHeight = lineHeight * (numberOfLines - 1);
  167.                 const float messageShift = messageHeight + lineHeight;
  168.                 const Vec3 drawingPosition = m_bubbleOnscreenPos + Vec3(0.0f, messageHeight, 0.0f);
  169.  
  170.                 const bool bFramed = (flags & eBNS_BalloonNoFrame) == 0;
  171.                 bool bUseDepthTest;
  172.                 if (flags & eBNS_BalloonOverrideDepthTestCVar)
  173.                 {
  174.                         bUseDepthTest = (flags & eBNS_BalloonUseDepthTest) != 0;
  175.                 }
  176.                 else
  177.                 {
  178.                         bUseDepthTest = ((gAIEnv.CVars.BubblesSystemUseDepthTest) != 0);
  179.                 }
  180.  
  181.                 DrawBubbleMessage(message, drawingPosition, bFramed, bUseDepthTest);
  182.  
  183.                 m_bubbleOnscreenPos = m_bubbleOnscreenPos + Vec3(0.0f, -messageShift, 0.0f);
  184.         }
  185. private:
  186.  
  187.         void DrawBubbleMessage(const char* const szMessage, const Vec3& drawingPosition, const bool bFramed, const bool bDepthTest)
  188.         {
  189.                 SDrawTextInfo ti;
  190.                 ti.scale = Vec2(m_currentTextSize);
  191.                 ti.flags = eDrawText_IgnoreOverscan | eDrawText_2D | eDrawText_800x600 | eDrawText_FixedSize | eDrawText_Center
  192.                            | (bDepthTest ? eDrawText_DepthTest : 0)
  193.                            | (bFramed ? eDrawText_Framed : 0);
  194.                 ti.color[0] = 0.0f;
  195.                 ti.color[1] = 0.0f;
  196.                 ti.color[2] = 0.0f;
  197.                 ti.color[3] = 1.0f;
  198.  
  199.                 m_drawContext->DrawLabel(drawingPosition, ti, szMessage);
  200.         }
  201.  
  202. private:
  203.         CDebugDrawContext& m_drawContext;
  204.         EntityId           m_entityId;
  205.         Vec3               m_bubbleOnscreenPos;
  206.         float              m_currentTextSize;
  207.         bool               m_bInitialized;
  208.         bool               m_bOnScreen;
  209. };
  210.  
  211. void CAIBubblesSystem::Update()
  212. {
  213.         if (!m_entityRequestsMap.empty())
  214.         {
  215.                 CDebugDrawContext debugDrawContext;
  216.                 const CTimeValue currentTimestamp = gEnv->pTimer->GetFrameStartTime();
  217.                 EntityRequestsMap::iterator it = m_entityRequestsMap.begin();
  218.                 EntityRequestsMap::iterator end = m_entityRequestsMap.end();
  219.                 for (; it != end; ++it)
  220.                 {
  221.                         RequestsList& requestsList = it->second;
  222.                         if (!requestsList.empty())
  223.                         {
  224.                                 const EntityId entityId = it->first;
  225.                                 CBubbleRender bubbleRender(debugDrawContext, entityId);
  226.  
  227.                                 auto reqIt = requestsList.begin();
  228.                                 auto reqItEnd = requestsList.end();
  229.  
  230.                                 while (reqIt != reqItEnd)
  231.                                 {
  232.                                         SAIBubbleRequestContainer& requestContainer = *reqIt;
  233.                                         bool result = DisplaySpeechBubble(requestContainer, bubbleRender);
  234.                                         if (requestContainer.IsOld(currentTimestamp) || !result)
  235.                                         {
  236.                                                 reqIt = requestsList.erase(reqIt);
  237.                                         }
  238.                                         else
  239.                                         {
  240.                                                 ++reqIt;
  241.                                         }
  242.                                 }
  243.                         }
  244.                 }
  245.         }
  246. }
  247.  
  248. bool CAIBubblesSystem::DisplaySpeechBubble(SAIBubbleRequestContainer& requestContainer, CBubbleRender& bubbleRender) const
  249. {
  250.         /* This function returns false if the entity connected to the message stop
  251.            to exist. In this case the corresponding message will be removed from the queue */
  252.  
  253.         const SAIBubbleRequest& request = requestContainer.GetRequest();
  254.  
  255.         if (ShouldSuppressMessageVisibility(request.GetRequestType()))
  256.         {
  257.                 // We only want to suppress the visibility of the message
  258.                 // but we don't want to remove it from the queue
  259.                 return true;
  260.         }
  261.  
  262.         if (ShouldFilterOutMessage(requestContainer.GetMessageNameId()))
  263.         {
  264.                 return true;
  265.         }
  266.  
  267.         const TBubbleRequestOptionFlags requestFlags = request.GetFlags();
  268.  
  269.         if (requestFlags & eBNS_Balloon && gAIEnv.CVars.BubblesSystemAlertnessFilter & eBNS_Balloon)
  270.         {
  271.                 if (!bubbleRender.Prepare())
  272.                 {
  273.                         return false;
  274.                 }
  275.  
  276.                 if (bubbleRender.IsOnScreen())
  277.                 {
  278.                         stack_string sFormattedMessage;
  279.                         const size_t numberOfLines = request.GetFormattedMessage(sFormattedMessage);
  280.  
  281.                         bubbleRender.DrawBubble(sFormattedMessage.c_str(), numberOfLines, (EBubbleRequestOption)requestFlags);
  282.                 }
  283.         }
  284.  
  285.         return true;
  286. }
  287.  
  288. void CAIBubblesSystem::LogMessage(const char* const message, const TBubbleRequestOptionFlags flags) const
  289. {
  290.         if (gAIEnv.CVars.BubblesSystemAlertnessFilter & eBNS_Log)
  291.         {
  292.                 if (flags & eBNS_LogWarning)
  293.                 {
  294.                         AIWarning("%s", message);
  295.                 }
  296.                 else if (flags & eBNS_Log)
  297.                 {
  298.                         gEnv->pLog->Log("%s", message);
  299.                 }
  300.         }
  301. }
  302.  
  303. void CAIBubblesSystem::PopupBlockingAlert(const char* const message, const TBubbleRequestOptionFlags flags) const
  304. {
  305.         if (ShouldSuppressMessageVisibility())
  306.         {
  307.                 return;
  308.         }
  309.  
  310.         if (flags & eBNS_BlockingPopup && gAIEnv.CVars.BubblesSystemAlertnessFilter & eBNS_BlockingPopup)
  311.         {
  312.                 CryMessageBox(message, "AIBubbleSystemMessageBox");
  313.         }
  314. }
  315.  
  316. bool CAIBubblesSystem::ShouldSuppressMessageVisibility(const SAIBubbleRequest::ERequestType requestType) const
  317. {
  318.         if (gAIEnv.CVars.EnableBubblesSystem != 1)
  319.         {
  320.                 return true;
  321.         }
  322.  
  323.         switch (requestType)
  324.         {
  325.         case SAIBubbleRequest::eRT_ErrorMessage:
  326.                 return gAIEnv.CVars.DebugDraw < 1;
  327.         case SAIBubbleRequest::eRT_PrototypeDialog:
  328.                 return gAIEnv.CVars.BubblesSystemAllowPrototypeDialogBubbles != 1;
  329.         default:
  330.                 assert(0);
  331.                 return gAIEnv.CVars.DebugDraw > 0;
  332.         }
  333. }
  334.  
  335. bool CAIBubblesSystem::ShouldFilterOutMessage(const uint32 messsageNameUniqueId) const
  336. {
  337.         if (m_messageNameFilterSet.empty())
  338.         {
  339.                 return false;
  340.         }
  341.         return m_messageNameFilterSet.find(messsageNameUniqueId) == m_messageNameFilterSet.cend();
  342. }
  343.  
  344. void CAIBubblesSystem::SetNameFilter(const char* szMessageNameFilter)
  345. {
  346.         m_messageNameFilterSet.clear();
  347.         if (!szMessageNameFilter || !szMessageNameFilter[0])
  348.         {
  349.                 return;
  350.         }
  351.  
  352.         stack_string messageNameFilter = szMessageNameFilter;
  353.         const size_t length = messageNameFilter.length();
  354.         int pos = 0;
  355.         do
  356.         {
  357.                 stack_string token = messageNameFilter.Tokenize(" ", pos);
  358.                 m_messageNameFilterSet.insert(ComputeMessageNameId(token.c_str()));
  359.         }
  360.         while (pos < length);
  361. }
  362.  
  363. #endif // CRYAISYSTEM_DEBUG
  364.  
downloadAIBubblesSystemImpl.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