BVB Source Codes

CRYENGINE Show CAISystemUpdate.cpp Source code

Return Download CRYENGINE: download CAISystemUpdate.cpp Source code - Download CRYENGINE Source code - Type:.cpp
  1. // Copyright 2001-2016 Crytek GmbH / Crytek Group. All rights reserved.
  2.  
  3. /********************************************************************
  4.    -------------------------------------------------------------------------
  5.    File name:   CAISystemUpdate.cpp
  6.    $Id$
  7.    Description: all the update related functionality here
  8.  
  9.    -------------------------------------------------------------------------
  10.    History:
  11.    - 2007                               : Created by Kirill Bulatsev
  12.  
  13.  *********************************************************************/
  14.  
  15. #include "StdAfx.h"
  16.  
  17. #include <stdio.h>
  18.  
  19. #include <limits>
  20. #include <map>
  21. #include <numeric>
  22. #include <algorithm>
  23.  
  24. #include <CryPhysics/IPhysics.h>
  25. #include <CryEntitySystem/IEntitySystem.h>
  26. #include <CryScriptSystem/IScriptSystem.h>
  27. #include <Cry3DEngine/I3DEngine.h>
  28. #include <CrySystem/ILog.h>
  29. #include <CrySystem/File/CryFile.h>
  30. #include <CryMath/Cry_Math.h>
  31. #include <CrySystem/ISystem.h>
  32. #include <CrySystem/ITimer.h>
  33. #include <CrySystem/IConsole.h>
  34. #include <CryNetwork/ISerialize.h>
  35. #include <CryAISystem/IAgent.h>
  36. #include <CryCore/Containers/VectorSet.h>
  37. #include <CryAISystem/AISystemListener.h>
  38.  
  39. #include "CAISystem.h"
  40. #include "CryAISystem.h"
  41. #include "AILog.h"
  42. #include "CTriangulator.h"
  43. #include "Free2DNavRegion.h"
  44. #include "Graph.h"
  45. #include "AStarSolver.h"
  46. #include "Puppet.h"
  47. #include "AIVehicle.h"
  48. #include "GoalOp.h"
  49. #include "AIPlayer.h"
  50. #include "PipeUser.h"
  51. #include "Leader.h"
  52. #include "SmartObjects.h"
  53. #include "AIActions.h"
  54. #include "AICollision.h"
  55. #include "AIRadialOcclusion.h"
  56. #include "GraphNodeManager.h"
  57. #include "CentralInterestManager.h"
  58. #include "CodeCoverageManager.h"
  59. #include "CodeCoverageGUI.h"
  60. #include "StatsManager.h"
  61. #include "TacticalPointSystem/TacticalPointSystem.h"
  62. #include "Communication/CommunicationManager.h"
  63. #include "SelectionTree/SelectionTreeManager.h"
  64. #include "Walkability/WalkabilityCacheManager.h"
  65. #include "Navigation/NavigationSystem/NavigationSystem.h"
  66.  
  67. #include "DebugDrawContext.h"
  68.  
  69. #include "Navigation/MNM/TileGenerator.h"
  70. #include "Navigation/MNM/NavMesh.h"
  71.  
  72. //-----------------------------------------------------------------------------------------------------------
  73. static bool IsPuppetOnScreen(CPuppet* pPuppet)
  74. {
  75.         IEntity* pEntity = pPuppet->GetEntity();
  76.         if (!pEntity)
  77.                 return false;
  78.         IEntityRender* pIEntityRender = pEntity->GetRenderInterface();
  79.         if (!pIEntityRender || !pIEntityRender->GetRenderNode())
  80.                 return false;
  81.         int frameDiff = gEnv->nMainFrameID - pIEntityRender->GetRenderNode()->GetDrawFrame();
  82.         if (frameDiff > 2)
  83.                 return false;
  84.         return true;
  85. }
  86.  
  87. //
  88. //-----------------------------------------------------------------------------------------------------------
  89. EPuppetUpdatePriority CAISystem::CalcPuppetUpdatePriority(CPuppet* pPuppet) const
  90. {
  91.         float fMinDistSq = std::numeric_limits<float>::max();
  92.         bool bOnScreen = false;
  93.         const Vec3 pos = pPuppet->GetPos();
  94.  
  95.         if (gAIEnv.configuration.eCompatibilityMode != ECCM_CRYSIS && gAIEnv.configuration.eCompatibilityMode != ECCM_CRYSIS2)
  96.         {
  97.                 // find closest player distance (better than using the camera pos in coop / dedicated server)
  98.                 //      and check visibility against all players
  99.  
  100.                 AIObjectOwners::const_iterator ai = gAIEnv.pAIObjectManager->m_Objects.find(AIOBJECT_PLAYER);
  101.                 for (; ai != gAIEnv.pAIObjectManager->m_Objects.end() && ai->first == AIOBJECT_PLAYER; ++ai)
  102.                 {
  103.                         CAIPlayer* pPlayer = CastToCAIPlayerSafe(ai->second.GetAIObject());
  104.                         if (pPlayer)
  105.                         {
  106.                                 fMinDistSq = min(fMinDistSq, (pos - pPlayer->GetPos()).GetLengthSquared());
  107.  
  108.                                 if (!bOnScreen)
  109.                                         bOnScreen = (IAIObject::eFOV_Outside != pPlayer->IsPointInFOV(pos, 2.0f));  // double range for this check, real sight range is used below.
  110.                         }
  111.                 }
  112.         }
  113.         else
  114.         {
  115.                 // previous behavior retained for Crysis compatibility
  116.                 Vec3 camPos = gEnv->pSystem->GetViewCamera().GetPosition();
  117.                 fMinDistSq = Distance::Point_PointSq(camPos, pos);
  118.                 bOnScreen = IsPuppetOnScreen(pPuppet);
  119.         }
  120.  
  121.         // Calculate the update priority of the puppet.
  122.         const float fSightRangeSq = sqr(pPuppet->GetParameters().m_PerceptionParams.sightRange);
  123.         const bool bInSightRange = (fMinDistSq < fSightRangeSq);
  124.         if (bOnScreen)
  125.         {
  126.                 return (bInSightRange ? AIPUP_VERY_HIGH : AIPUP_HIGH);
  127.         }
  128.         else
  129.         {
  130.                 return (bInSightRange ? AIPUP_MED : AIPUP_LOW);
  131.         }
  132. }
  133.  
  134. //
  135. //-----------------------------------------------------------------------------------------------------------
  136. #ifdef CRYAISYSTEM_DEBUG
  137. void CAISystem::UpdateDebugStuff()
  138. {
  139.         #if CRY_PLATFORM_WINDOWS
  140.  
  141.         FUNCTION_PROFILER(gEnv->pSystem, PROFILE_AI);
  142.         // Delete the debug lines if the debug draw is not on.
  143.         if ((gAIEnv.CVars.DebugDraw == 0))
  144.         {
  145.                 m_vecDebugLines.clear();
  146.                 m_vecDebugBoxes.clear();
  147.         }
  148.  
  149.         bool drawCover = (gAIEnv.CVars.DebugDraw != 0) && (gAIEnv.CVars.DebugDrawCover != 0);
  150.  
  151.         const char* debugHideSpotName = gAIEnv.CVars.DebugHideSpotName;
  152.         drawCover &= (debugHideSpotName && debugHideSpotName[0] && strcmp(debugHideSpotName, "0"));
  153.  
  154.         if (drawCover)
  155.         {
  156.                 uint32 anchorTypes[2] =
  157.                 {
  158.                         AIANCHOR_COMBAT_HIDESPOT,
  159.                         AIANCHOR_COMBAT_HIDESPOT_SECONDARY
  160.                 };
  161.  
  162.                 uint32 anchorTypeCount = CRY_ARRAY_COUNT(anchorTypes);
  163.  
  164.                 bool all = !stricmp(debugHideSpotName, "all");
  165.                 if (!all && (m_DebugHideObjects.size() > 1))
  166.                         m_DebugHideObjects.clear();
  167.  
  168.                 const float maxDistanceSq = sqr(75.0f);
  169.                 const CCamera& camera = gEnv->pSystem->GetViewCamera();
  170.  
  171.                 bool found = false;
  172.                 for (uint32 at = 0; at < anchorTypeCount; ++at)
  173.                 {
  174.                         const AIObjectOwners::const_iterator itEnd = gAIEnv.pAIObjectManager->m_Objects.end();
  175.                         for (AIObjectOwners::const_iterator it = gAIEnv.pAIObjectManager->m_Objects.find(anchorTypes[at]); it != itEnd; ++it)
  176.                         {
  177.                                 CAIObject* pObject = it->second.GetAIObject();
  178.                                 if (pObject->GetType() != anchorTypes[at])
  179.                                         break;
  180.  
  181.                                 if (!pObject->IsEnabled())
  182.                                         continue;
  183.  
  184.                                 const GraphNode* pNode = gAIEnv.pGraph->GetNode(pObject->GetNavNodeIndex());
  185.                                 if (!pNode)
  186.                                         continue;
  187.  
  188.                                 if (all)
  189.                                 {
  190.                                         if ((pObject->GetPos() - camera.GetPosition()).GetLengthSquared() > maxDistanceSq)
  191.                                         {
  192.                                                 DebugHideObjectMap::iterator delIt = m_DebugHideObjects.find(pObject->GetAIObjectID());
  193.                                                 if (delIt != m_DebugHideObjects.end())
  194.                                                         m_DebugHideObjects.erase(delIt);
  195.  
  196.                                                 continue;
  197.                                         }
  198.  
  199.                                         // Marcio: Assume max radius for now!
  200.                                         Sphere sphere(pObject->GetPos(), 12.0f);
  201.  
  202.                                         if (!camera.IsSphereVisible_F(sphere))
  203.                                         {
  204.                                                 DebugHideObjectMap::iterator delIt = m_DebugHideObjects.find(pObject->GetAIObjectID());
  205.                                                 if (delIt != m_DebugHideObjects.end())
  206.                                                         m_DebugHideObjects.erase(delIt);
  207.  
  208.                                                 continue;
  209.                                         }
  210.                                 }
  211.                                 else
  212.                                 {
  213.                                         if (stricmp(pObject->GetName(), debugHideSpotName))
  214.                                                 continue;
  215.                                 }
  216.  
  217.                                 SHideSpot hideSpot(SHideSpotInfo::eHST_ANCHOR, pObject->GetPos(), pObject->GetMoveDir());
  218.                                 hideSpot.pNavNode = pNode;
  219.                                 hideSpot.pAnchorObject = pObject;
  220.  
  221.                                 std::pair<DebugHideObjectMap::iterator, bool> result = m_DebugHideObjects.insert(
  222.                                   DebugHideObjectMap::value_type(pObject->GetAIObjectID(), CAIHideObject()));
  223.  
  224.                                 CAIHideObject& hideObject = result.first->second;
  225.                                 hideObject.Set(&hideSpot, pObject->GetPos(), pObject->GetMoveDir());
  226.  
  227.                                 if (!all)
  228.                                 {
  229.                                         found = true;
  230.                                         break;
  231.                                 }
  232.                         }
  233.  
  234.                         if (!all && found)
  235.                                 break;
  236.                 }
  237.  
  238.                 // clean up removed objects
  239.                 {
  240.                         DebugHideObjectMap::iterator it = m_DebugHideObjects.begin();
  241.                         DebugHideObjectMap::iterator itEnd = m_DebugHideObjects.end();
  242.  
  243.                         while (it != itEnd)
  244.                         {
  245.                                 CAIObject* pAIObject = gAIEnv.pObjectContainer->GetAIObject(it->first);
  246.  
  247.                                 bool ok = false;
  248.                                 if (pAIObject && pAIObject->IsEnabled())
  249.                                 {
  250.                                         for (uint32 at = 0; at < anchorTypeCount; ++at)
  251.                                         {
  252.                                                 if (pAIObject->GetType() == anchorTypes[at])
  253.                                                 {
  254.                                                         ok = true;
  255.                                                         break;
  256.                                                 }
  257.                                         }
  258.                                 }
  259.  
  260.                                 DebugHideObjectMap::iterator toErase = it++;
  261.                                 if (!ok)
  262.                                         m_DebugHideObjects.erase(toErase);
  263.                         }
  264.                 }
  265.  
  266.                 // update and draw them
  267.                 DebugHideObjectMap::iterator it = m_DebugHideObjects.begin();
  268.                 DebugHideObjectMap::iterator itEnd = m_DebugHideObjects.end();
  269.  
  270.                 for (; it != itEnd; ++it)
  271.                 {
  272.                         CAIHideObject& debugHideObject = it->second;
  273.  
  274.                         if (debugHideObject.IsValid())
  275.                         {
  276.                                 debugHideObject.HurryUpCoverPathGen();
  277.                                 while (!debugHideObject.IsCoverPathComplete())
  278.                                         debugHideObject.Update(0);
  279.                                 debugHideObject.DebugDraw();
  280.                         }
  281.                 }
  282.         }
  283.         else
  284.                 m_DebugHideObjects.clear();
  285.  
  286.         // Update fake tracers
  287.         if (gAIEnv.CVars.DrawFakeTracers > 0)
  288.         {
  289.                 for (size_t i = 0; i < m_DEBUG_fakeTracers.size(); )
  290.                 {
  291.                         m_DEBUG_fakeTracers[i].t -= m_frameDeltaTime;
  292.                         if (m_DEBUG_fakeTracers[i].t < 0.0f)
  293.                         {
  294.                                 m_DEBUG_fakeTracers[i] = m_DEBUG_fakeTracers.back();
  295.                                 m_DEBUG_fakeTracers.pop_back();
  296.                         }
  297.                         else
  298.                         {
  299.                                 ++i;
  300.                         }
  301.                 }
  302.         }
  303.         else
  304.         {
  305.                 m_DEBUG_fakeTracers.clear();
  306.         }
  307.  
  308.         // Update fake hit effects
  309.         if (gAIEnv.CVars.DrawFakeHitEffects > 0)
  310.         {
  311.                 for (size_t i = 0; i < m_DEBUG_fakeHitEffect.size(); )
  312.                 {
  313.                         m_DEBUG_fakeHitEffect[i].t -= m_frameDeltaTime;
  314.                         if (m_DEBUG_fakeHitEffect[i].t < 0.0f)
  315.                         {
  316.                                 m_DEBUG_fakeHitEffect[i] = m_DEBUG_fakeHitEffect.back();
  317.                                 m_DEBUG_fakeHitEffect.pop_back();
  318.                         }
  319.                         else
  320.                         {
  321.                                 ++i;
  322.                         }
  323.                 }
  324.         }
  325.         else
  326.         {
  327.                 m_DEBUG_fakeHitEffect.clear();
  328.         }
  329.  
  330.         // Update fake damage indicators
  331.         if (gAIEnv.CVars.DrawFakeDamageInd > 0)
  332.         {
  333.                 for (unsigned i = 0; i < m_DEBUG_fakeDamageInd.size(); )
  334.                 {
  335.                         m_DEBUG_fakeDamageInd[i].t -= m_frameDeltaTime;
  336.                         if (m_DEBUG_fakeDamageInd[i].t < 0)
  337.                         {
  338.                                 m_DEBUG_fakeDamageInd[i] = m_DEBUG_fakeDamageInd.back();
  339.                                 m_DEBUG_fakeDamageInd.pop_back();
  340.                         }
  341.                         else
  342.                                 ++i;
  343.                 }
  344.                 m_DEBUG_screenFlash = max(0.0f, m_DEBUG_screenFlash - m_frameDeltaTime);
  345.         }
  346.         else
  347.         {
  348.                 m_DEBUG_fakeDamageInd.clear();
  349.                 m_DEBUG_screenFlash = 0.0f;
  350.         }
  351.  
  352.         if (gAIEnv.CVars.DebugCheckWalkability)
  353.         {
  354.                 CAIObject* startObject = gAIEnv.pAIObjectManager->GetAIObjectByName("CheckWalkabilityTestStart");
  355.                 CAIObject* endObject = gAIEnv.pAIObjectManager->GetAIObjectByName("CheckWalkabilityTestEnd");
  356.  
  357.                 if (startObject && endObject)
  358.                 {
  359.                         bool result = false;
  360.                         const float radius = gAIEnv.CVars.DebugCheckWalkabilityRadius;
  361.  
  362.                         if (gAIEnv.CVars.DebugCheckWalkability == 1)
  363.                         {
  364.                                 // query all entities in this path as well as their bounding boxes from physics
  365.                                 AABB enclosingAABB(AABB::RESET);
  366.  
  367.                                 enclosingAABB.Add(startObject->GetPos());
  368.                                 enclosingAABB.Add(endObject->GetPos());
  369.                                 enclosingAABB.Expand(Vec3(radius));
  370.  
  371.                                 StaticAABBArray aabbs;
  372.                                 StaticPhysEntityArray entities;
  373.  
  374.                                 size_t entityCount = GetPhysicalEntitiesInBox(enclosingAABB.min, enclosingAABB.max, entities, AICE_ALL);
  375.                                 entities.resize(entityCount);
  376.                                 aabbs.resize(entityCount);
  377.  
  378.                                 // get all aabbs
  379.                                 pe_status_pos status;
  380.  
  381.                                 for (size_t i = 0; i < entityCount; ++i)
  382.                                 {
  383.                                         if (entities[i]->GetStatus(&status))
  384.                                         {
  385.                                                 const Vec3 aabbMin = status.BBox[0];
  386.                                                 const Vec3 aabbMax = status.BBox[1];
  387.  
  388.                                                 // some aabbs strangely return all zero from physics, thus use the enclosingAABB for the whole path
  389.                                                 if (aabbMin.IsZero() && aabbMax.IsZero())
  390.                                                         aabbs[i] = enclosingAABB;
  391.                                                 else
  392.                                                         aabbs[i] = AABB(aabbMin + status.pos, aabbMax + status.pos);
  393.                                         }
  394.                                 }
  395.  
  396.                                 result = CheckWalkability(startObject->GetPos(), endObject->GetPos(), radius, entities, aabbs);
  397.                         }
  398.                         else if (gAIEnv.CVars.DebugCheckWalkability == 2)
  399.                                 result = CheckWalkability(startObject->GetPos(), endObject->GetPos(), radius);
  400.  
  401.                         CDebugDrawContext dc;
  402.                         dc->Draw2dLabel(400.0f, 100.0f, 5.0f, result ? Col_Green : Col_Red, true, "%s %s!", "CheckWalkability ", result ? "passed" : "failed");
  403.                 }
  404.         }
  405.  
  406.         if (gAIEnv.CVars.DebugWalkabilityCache)
  407.         {
  408.                 gAIEnv.pWalkabilityCacheManager->Draw();
  409.         }
  410.  
  411.         #endif // #if CRY_PLATFORM_WINDOWS
  412. }
  413. #endif //CRYAISYSTEM_DEBUG
  414.  
  415. //===================================================================
  416. // GetUpdateAllAlways
  417. //===================================================================
  418. bool CAISystem::GetUpdateAllAlways() const
  419. {
  420.         bool updateAllAlways = gAIEnv.CVars.UpdateAllAlways != 0;
  421.         return updateAllAlways;
  422. }
  423.  
  424. struct SSortedPuppetB
  425. {
  426.         SSortedPuppetB(CPuppet* o, float dot, float d) : obj(o), weight(0.f), dot(dot), dist(d) {}
  427.         bool operator<(const SSortedPuppetB& rhs) const { return weight < rhs.weight;  }
  428.  
  429.         float    weight, dot, dist;
  430.         CPuppet* obj;
  431. };
  432.  
  433. //
  434. //-----------------------------------------------------------------------------------------------------------
  435. void CAISystem::UpdateAmbientFire()
  436. {
  437.         FUNCTION_PROFILER(gEnv->pSystem, PROFILE_AI);
  438.  
  439.         if (gAIEnv.CVars.AmbientFireEnable == 0)
  440.                 return;
  441.  
  442.         int64 dt((GetFrameStartTime() - m_lastAmbientFireUpdateTime).GetMilliSecondsAsInt64());
  443.         if (dt < (int)(gAIEnv.CVars.AmbientFireUpdateInterval * 1000.0f))
  444.                 return;
  445.  
  446.         // Marcio: Update ambient fire towards all players.
  447.         for (AIObjectOwners::const_iterator ai = gAIEnv.pAIObjectManager->m_Objects.find(AIOBJECT_ACTOR), end = gAIEnv.pAIObjectManager->m_Objects.end(); ai != end && ai->first == AIOBJECT_ACTOR; ++ai)
  448.         {
  449.                 CAIObject* obj = ai->second.GetAIObject();
  450.                 if (!obj || !obj->IsEnabled())
  451.                         continue;
  452.  
  453.                 CPuppet* pPuppet = obj->CastToCPuppet();
  454.                 if (!pPuppet)
  455.                         continue;
  456.  
  457.                 // By default make every AI in ambient fire, only the ones that are allowed to shoot right are set explicitly.
  458.                 pPuppet->SetAllowedToHitTarget(false);
  459.         }
  460.  
  461.         for (AIObjectOwners::const_iterator ai = gAIEnv.pAIObjectManager->m_Objects.find(AIOBJECT_VEHICLE), end = gAIEnv.pAIObjectManager->m_Objects.end(); ai != end && ai->first == AIOBJECT_VEHICLE; ++ai)
  462.         {
  463.                 CAIVehicle* obj = CastToCAIVehicleSafe(ai->second.GetAIObject());
  464.                 if (!obj || !obj->IsDriverInside())
  465.                         continue;
  466.                 CPuppet* pPuppet = obj->CastToCPuppet();
  467.                 if (!pPuppet)
  468.                         continue;
  469.  
  470.                 // By default make every AI in ambient fire, only the ones that are allowed to shoot right are set explicitly.
  471.                 pPuppet->SetAllowedToHitTarget(false);
  472.         }
  473.  
  474.         AIObjectOwners::const_iterator plit = gAIEnv.pAIObjectManager->m_Objects.find(AIOBJECT_PLAYER);
  475.         for (; plit != gAIEnv.pAIObjectManager->m_Objects.end() && plit->first == AIOBJECT_PLAYER; ++plit)
  476.         {
  477.                 CAIPlayer* pPlayer = CastToCAIPlayerSafe(plit->second.GetAIObject());
  478.                 if (!pPlayer)
  479.                         return;
  480.  
  481.                 m_lastAmbientFireUpdateTime = GetFrameStartTime();
  482.  
  483.                 const Vec3& playerPos = pPlayer->GetPos();
  484.                 const Vec3& playerDir = pPlayer->GetMoveDir();
  485.  
  486.                 typedef std::vector<SSortedPuppetB> TShooters;
  487.                 TShooters shooters;
  488.                 shooters.reserve(32);                     // sizeof(SSortedPuppetB) = 16, 512 / 16 = 32, will go in bucket allocator
  489.  
  490.                 float maxDist = 0.0f;
  491.  
  492.                 // Update
  493.                 for (AIObjectOwners::const_iterator ai = gAIEnv.pAIObjectManager->m_Objects.find(AIOBJECT_ACTOR), end = gAIEnv.pAIObjectManager->m_Objects.end(); ai != end && ai->first == AIOBJECT_ACTOR; ++ai)
  494.                 {
  495.                         CAIObject* obj = ai->second.GetAIObject();
  496.                         if (!obj->IsEnabled())
  497.                                 continue;
  498.                         CPuppet* pPuppet = obj->CastToCPuppet();
  499.                         if (!pPuppet)
  500.                                 continue;
  501.  
  502.                         CAIObject* pTarget = (CAIObject*)pPuppet->GetAttentionTarget();
  503.  
  504.                         if ((pTarget != NULL) && pTarget->IsAgent())
  505.                         {
  506.                                 if (pTarget == pPlayer)
  507.                                 {
  508.                                         Vec3 dirPlayerToPuppet = pPuppet->GetPos() - playerPos;
  509.                                         float dist = dirPlayerToPuppet.NormalizeSafe();
  510.                                         if (dist > 0.01f && dist < pPuppet->GetParameters().m_fAttackRange)
  511.                                         {
  512.                                                 maxDist = max(maxDist, dist);
  513.                                                 float dot = playerDir.Dot(dirPlayerToPuppet);
  514.                                                 shooters.push_back(SSortedPuppetB(pPuppet, dot, dist));
  515.                                         }
  516.                                         continue;
  517.                                 }
  518.                         }
  519.  
  520.                         // Shooting something else than player, allow to hit.
  521.                         pPuppet->SetAllowedToHitTarget(true);
  522.                 }
  523.  
  524.                 // Update
  525.                 for (AIObjectOwners::const_iterator ai = gAIEnv.pAIObjectManager->m_Objects.find(AIOBJECT_VEHICLE), end = gAIEnv.pAIObjectManager->m_Objects.end(); ai != end && ai->first == AIOBJECT_VEHICLE; ++ai)
  526.                 {
  527.                         CAIVehicle* obj = ai->second.GetAIObject()->CastToCAIVehicle();
  528.                         if (!obj->IsDriverInside())
  529.                                 continue;
  530.                         CPuppet* pPuppet = obj->CastToCPuppet();
  531.                         if (!pPuppet)
  532.                                 continue;
  533.  
  534.                         CAIObject* pTarget = (CAIObject*)pPuppet->GetAttentionTarget();
  535.  
  536.                         if ((pTarget != NULL) && pTarget->IsAgent())
  537.                         {
  538.                                 if (pTarget == pPlayer)
  539.                                 {
  540.                                         Vec3 dirPlayerToPuppet = pPuppet->GetPos() - playerPos;
  541.                                         float dist = dirPlayerToPuppet.NormalizeSafe();
  542.  
  543.                                         if ((dist > 0.01f) && (dist < pPuppet->GetParameters().m_fAttackRange) && pPuppet->AllowedToFire())
  544.                                         {
  545.                                                 maxDist = max(maxDist, dist);
  546.  
  547.                                                 float dot = playerDir.Dot(dirPlayerToPuppet);
  548.                                                 shooters.push_back(SSortedPuppetB(pPuppet, dot, dist));
  549.                                         }
  550.  
  551.                                         continue;
  552.                                 }
  553.                         }
  554.                         // Shooting something else than player, allow to hit.
  555.                         pPuppet->SetAllowedToHitTarget(true);
  556.                 }
  557.  
  558.                 if (!shooters.empty() && maxDist > 0.01f)
  559.                 {
  560.                         // Find nearest shooter
  561.                         TShooters::iterator nearestIt = shooters.begin();
  562.                         float nearestWeight = sqr((1.0f - nearestIt->dot) / 2) * (0.3f + 0.7f * nearestIt->dist / maxDist);
  563.                         ;
  564.                         for (TShooters::iterator it = shooters.begin() + 1; it != shooters.end(); ++it)
  565.                         {
  566.                                 float weight = sqr((1.0f - it->dot) / 2) * (0.3f + 0.7f * it->dist / maxDist);
  567.                                 if (weight < nearestWeight)
  568.                                 {
  569.                                         nearestWeight = weight;
  570.                                         nearestIt = it;
  571.                                 }
  572.                         }
  573.  
  574.                         Vec3 dirToNearest = nearestIt->obj->GetPos() - playerPos;
  575.                         dirToNearest.NormalizeSafe();
  576.  
  577.                         for (TShooters::iterator it = shooters.begin(); it != shooters.end(); ++it)
  578.                         {
  579.                                 Vec3 dirPlayerToPuppet = it->obj->GetPos() - playerPos;
  580.                                 float dist = dirPlayerToPuppet.NormalizeSafe();
  581.                                 float dot = dirToNearest.Dot(dirPlayerToPuppet);
  582.                                 it->weight = sqr((1.0f - dot) / 2) * (dist / maxDist);
  583.                         }
  584.  
  585.                         std::sort(shooters.begin(), shooters.end());
  586.  
  587.                         uint32 i = 0;
  588.                         uint32 quota = gAIEnv.CVars.AmbientFireQuota;
  589.  
  590.                         for (TShooters::iterator it = shooters.begin(); it != shooters.end(); ++it)
  591.                         {
  592.                                 it->obj->SetAllowedToHitTarget(true);
  593.                                 if ((++i >= quota) && (it->dist > 7.5f)) // Always allow to hit if in 2.5 meter radius
  594.                                         break;
  595.                         }
  596.                 }
  597.         }
  598. }
  599.  
  600. inline bool PuppetFloatSorter(const std::pair<CPuppet*, float>& lhs, const std::pair<CPuppet*, float>& rhs)
  601. {
  602.         return lhs.second < rhs.second;
  603. }
  604.  
  605. //
  606. //-----------------------------------------------------------------------------------------------------------
  607. void CAISystem::UpdateExpensiveAccessoryQuota()
  608. {
  609.         FUNCTION_PROFILER(gEnv->pSystem, PROFILE_AI);
  610.  
  611.         for (unsigned i = 0; i < m_delayedExpAccessoryUpdates.size(); )
  612.         {
  613.                 SAIDelayedExpAccessoryUpdate& update = m_delayedExpAccessoryUpdates[i];
  614.                 update.timeMs -= (int)(m_frameDeltaTime * 1000.0f);
  615.  
  616.                 if (update.timeMs < 0)
  617.                 {
  618.                         update.pPuppet->SetAllowedToUseExpensiveAccessory(update.state);
  619.                         m_delayedExpAccessoryUpdates[i] = m_delayedExpAccessoryUpdates.back();
  620.                         m_delayedExpAccessoryUpdates.pop_back();
  621.                 }
  622.                 else
  623.                         ++i;
  624.         }
  625.  
  626.         const int UpdateTimeMs = 3000;
  627.         const float fUpdateTimeMs = (float)UpdateTimeMs;
  628.  
  629.         int64 dt((GetFrameStartTime() - m_lastExpensiveAccessoryUpdateTime).GetMilliSecondsAsInt64());
  630.         if (dt < UpdateTimeMs)
  631.                 return;
  632.  
  633.         m_lastExpensiveAccessoryUpdateTime = GetFrameStartTime();
  634.  
  635.         m_delayedExpAccessoryUpdates.clear();
  636.  
  637.         Vec3 interestPos = gEnv->pSystem->GetViewCamera().GetPosition();
  638.  
  639.         std::vector<std::pair<CPuppet*, float>> puppets;
  640.         VectorSet<CPuppet*> stateRemoved;
  641.  
  642.         // Choose the best of each group, then best of the best.
  643.         for (AIGroupMap::iterator it = m_mapAIGroups.begin(), itend = m_mapAIGroups.end(); it != itend; ++it)
  644.         {
  645.                 CAIGroup* pGroup = it->second;
  646.  
  647.                 CPuppet* pBestUnit = 0;
  648.                 float bestVal = FLT_MAX;
  649.  
  650.                 for (TUnitList::iterator itu = pGroup->GetUnits().begin(), ituend = pGroup->GetUnits().end(); itu != ituend; ++itu)
  651.                 {
  652.                         CPuppet* pPuppet = CastToCPuppetSafe(itu->m_refUnit.GetAIObject());
  653.                         if (!pPuppet)
  654.                                 continue;
  655.                         if (!pPuppet->IsEnabled())
  656.                                 continue;
  657.  
  658.                         if (pPuppet->IsAllowedToUseExpensiveAccessory())
  659.                                 stateRemoved.insert(pPuppet);
  660.  
  661.                         const int accessories = pPuppet->GetParameters().m_weaponAccessories;
  662.                         if ((accessories & (AIWEPA_COMBAT_LIGHT | AIWEPA_PATROL_LIGHT)) == 0)
  663.                                 continue;
  664.  
  665.                         if (pPuppet->GetProxy())
  666.                         {
  667.                                 SAIWeaponInfo wi;
  668.                                 pPuppet->GetProxy()->QueryWeaponInfo(wi);
  669.                                 if (!wi.hasLightAccessory)
  670.                                         continue;
  671.                         }
  672.  
  673.                         float val = Distance::Point_Point(interestPos, pPuppet->GetPos());
  674.  
  675.                         if (pPuppet->GetAttentionTargetThreat() == AITHREAT_AGGRESSIVE)
  676.                                 val *= 0.5f;
  677.                         else if (pPuppet->GetAttentionTargetThreat() >= AITHREAT_INTERESTING)
  678.                                 val *= 0.8f;
  679.  
  680.                         if (val < bestVal)
  681.                         {
  682.                                 bestVal = val;
  683.                                 pBestUnit = pPuppet;
  684.                         }
  685.                 }
  686.  
  687.                 if (pBestUnit)
  688.                 {
  689.                         CCCPOINT(UpdateExpensiveAccessoryQuota);
  690.                         puppets.push_back(std::make_pair(pBestUnit, bestVal));
  691.                 }
  692.         }
  693.  
  694.         std::sort(puppets.begin(), puppets.end(), PuppetFloatSorter);
  695.  
  696.         unsigned maxExpensiveAccessories = 3;
  697.         for (unsigned i = 0, ni = puppets.size(); i < ni && i < maxExpensiveAccessories; ++i)
  698.         {
  699.                 stateRemoved.erase(puppets[i].first);
  700.  
  701.                 if (!puppets[i].first->IsAllowedToUseExpensiveAccessory())
  702.                 {
  703.                         //              puppets[i].first->SetAllowedToUseExpensiveAccessory(true);
  704.  
  705.                         int timeMs = (int)(fUpdateTimeMs * 0.5f + cry_random(0.0f, fUpdateTimeMs) * 0.4f);
  706.                         m_delayedExpAccessoryUpdates.push_back(SAIDelayedExpAccessoryUpdate(puppets[i].first, timeMs, true));
  707.                 }
  708.         }
  709.  
  710.         for (unsigned i = 0, ni = stateRemoved.size(); i < ni; ++i)
  711.         {
  712.                 int timeMs = (int)(cry_random(0.0f, fUpdateTimeMs) * 0.4f);
  713.                 m_delayedExpAccessoryUpdates.push_back(SAIDelayedExpAccessoryUpdate(stateRemoved[i], timeMs, false));
  714.         }
  715. }
  716.  
  717. //
  718. //-----------------------------------------------------------------------------------------------------------
  719. void CAISystem::SingleDryUpdate(CAIActor* pAIActor)
  720. {
  721.         FUNCTION_PROFILER(gEnv->pSystem, PROFILE_AI);
  722.         if (pAIActor->IsEnabled())
  723.                 pAIActor->Update(AIUPDATE_DRY);
  724.         else
  725.                 pAIActor->UpdateDisabled(AIUPDATE_DRY);
  726. }
  727.  
  728. //
  729. //-----------------------------------------------------------------------------------------------------------
  730. void CAISystem::UpdateAuxSignalsMap()
  731. {
  732.         FUNCTION_PROFILER(gEnv->pSystem, PROFILE_AI);
  733.  
  734.         if (!m_mapAuxSignalsFired.empty())
  735.         {
  736.                 MapSignalStrings::iterator mss = m_mapAuxSignalsFired.begin();
  737.                 while (mss != m_mapAuxSignalsFired.end())
  738.                 {
  739.                         (mss->second).fTimeout -= m_frameDeltaTime;
  740.                         if ((mss->second).fTimeout < 0)
  741.                         {
  742.                                 MapSignalStrings::iterator mss_to_erase = mss;
  743.                                 ++mss;
  744.                                 m_mapAuxSignalsFired.erase(mss_to_erase);
  745.                         }
  746.                         else
  747.                                 ++mss;
  748.                 }
  749.         }
  750. }
  751.  
downloadCAISystemUpdate.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