BVB Source Codes

CRYENGINE Show PuppetRateOfDeath.cpp Source code

Return Download CRYENGINE: download PuppetRateOfDeath.cpp Source code - Download CRYENGINE Source code - Type:.cpp
  1. // Copyright 2001-2016 Crytek GmbH / Crytek Group. All rights reserved.
  2.  
  3. /*************************************************************************
  4.    -------------------------------------------------------------------------
  5.    $Id$
  6.    $DateTime$
  7.    Description: Rate of Death handling for the Puppet
  8.  
  9.    -------------------------------------------------------------------------
  10.    History:
  11.    - 07:09:2009: Migrated over code from Puppet.cpp (Kevin Kirst)
  12.  
  13. *************************************************************************/
  14.  
  15. #include "StdAfx.h"
  16. #include "Puppet.h"
  17. #include <CryAISystem/IAIRateOfDeathHandler.h>
  18.  
  19. //#pragma optimize("", off)
  20. //#pragma inline_depth(0)
  21.  
  22. //===================================================================
  23. // GetTargetAliveTime
  24. //===================================================================
  25. float CPuppet::GetTargetAliveTime()
  26. {
  27.         float fTargetStayAliveTime = gAIEnv.CVars.RODAliveTime;
  28.  
  29.         const CAIObject* pLiveTarget = GetLiveTarget(m_refAttentionTarget).GetAIObject();
  30.         if (!pLiveTarget)
  31.                 return fTargetStayAliveTime;
  32.  
  33.         const CAIActor* pLiveActor = pLiveTarget->CastToCAIActor();
  34.         if (!pLiveActor)
  35.                 return fTargetStayAliveTime;
  36.  
  37.         CCCPOINT(CPuppet_GetTargetAliveTime);
  38.  
  39.         // Delegate to handle if available
  40.         if (m_pRODHandler)
  41.         {
  42.                 fTargetStayAliveTime = m_pRODHandler->GetTargetAliveTime(this, pLiveTarget, m_targetZone, m_targetDazzlingTime);
  43.         }
  44.         else
  45.         {
  46.                 Vec3 vTargetDir = pLiveTarget->GetPos() - GetPos();
  47.                 const float fTargetDist = vTargetDir.NormalizeSafe();
  48.  
  49.                 // Scale target life time based on target speed.
  50.                 const float fMoveInc = gAIEnv.CVars.RODMoveInc;
  51.                 {
  52.                         float fIncrease = 0.0f;
  53.  
  54.                         const Vec3& vTargetVel = pLiveTarget->GetVelocity();
  55.                         const float fSpeed = vTargetVel.GetLength2D();
  56.  
  57.                         if ((pLiveTarget->GetType() == AIOBJECT_PLAYER) &&
  58.                             (m_fireMode != FIREMODE_MELEE) && (m_fireMode != FIREMODE_MELEE_FORCED))
  59.                         {
  60.                                 // Super speed run or super jump.
  61.                                 if (fSpeed > 12.0f || vTargetVel.z > 7.0f)
  62.                                 {
  63.                                         fIncrease += fMoveInc * 2.0f;
  64.  
  65.                                         // Dazzle the shooter for a moment.
  66.                                         m_targetDazzlingTime = 1.0f;
  67.                                 }
  68.                                 else if (fSpeed > 6.0f)
  69.                                 {
  70.                                         fIncrease += fMoveInc;
  71.                                 }
  72.                         }
  73.                         else if (fSpeed > 6.0f)
  74.                         {
  75.                                 fIncrease *= fMoveInc;
  76.                         }
  77.  
  78.                         fTargetStayAliveTime += fIncrease;
  79.                 }
  80.  
  81.                 // Scale target life time based on target stance.
  82.                 const float fStanceInc = gAIEnv.CVars.RODStanceInc;
  83.                 {
  84.                         float fIncrease = 0.0f;
  85.  
  86.                         const SAIBodyInfo& bi = pLiveActor->GetBodyInfo();
  87.                         if (bi.stance == STANCE_CROUCH && m_targetZone > AIZONE_KILL)
  88.                                 fIncrease += fStanceInc;
  89.                         else if (bi.stance == STANCE_PRONE && m_targetZone >= AIZONE_COMBAT_FAR)
  90.                                 fIncrease += fStanceInc * fStanceInc;
  91.  
  92.                         fTargetStayAliveTime += fIncrease;
  93.                 }
  94.  
  95.                 // Scale target life time based on target vs. shooter orientation.
  96.                 const float fDirectionInc = gAIEnv.CVars.RODDirInc;
  97.                 {
  98.                         float fIncrease = 0.0f;
  99.  
  100.                         const float thr1 = cosf(DEG2RAD(30.0f));
  101.                         const float thr2 = cosf(DEG2RAD(95.0f));
  102.                         float dot = -vTargetDir.Dot(pLiveTarget->GetViewDir());
  103.                         if (dot < thr2)
  104.                                 fIncrease += fDirectionInc * 2.0f;
  105.                         else if (dot < thr1)
  106.                                 fIncrease += fDirectionInc;
  107.  
  108.                         fTargetStayAliveTime += fIncrease;
  109.                 }
  110.  
  111.                 if (!m_allowedToHitTarget)
  112.                 {
  113.                         // If the agent is set not to be allowed to hit the target, let the others shoot first.
  114.                         const float fAmbientFireInc = gAIEnv.CVars.RODAmbientFireInc;
  115.                         fTargetStayAliveTime += fAmbientFireInc;
  116.                 }
  117.                 else if (m_targetZone == AIZONE_KILL)
  118.                 {
  119.                         // Kill much faster when the target is in kill-zone (but not if in a vehicle)
  120.                         const SAIBodyInfo bi = GetBodyInfo();
  121.                         if (!bi.GetLinkedVehicleEntity())
  122.                         {
  123.                                 const float fKillZoneInc = gAIEnv.CVars.RODKillZoneInc;
  124.                                 fTargetStayAliveTime += fKillZoneInc;
  125.                         }
  126.                 }
  127.         }
  128.  
  129.         CCCPOINT(CPuppet_GetTargetAliveTime_A);
  130.         return max(0.0f, fTargetStayAliveTime);
  131. }
  132.  
  133. //===================================================================
  134. // UpdateHealthTracking
  135. //===================================================================
  136. void CPuppet::UpdateHealthTracking()
  137. {
  138.         FUNCTION_PROFILER(GetISystem(), PROFILE_AI);
  139.  
  140.         // Update target health tracking.
  141.         float fTargetHealth = 0.0f;
  142.         float fTargetMaxHealth = 1.0f;
  143.  
  144.         // Convert the current health to normalized range (1.0 == normal max health).
  145.         const CAIObject* pTarget = GetLiveTarget(m_refAttentionTarget).GetAIObject();
  146.         IAIActorProxy* pTargetProxy = (pTarget ? pTarget->GetProxy() : NULL);
  147.         if (pTargetProxy)
  148.         {
  149.                 CCCPOINT(CPuppet_UpdateHealthTracking);
  150.  
  151.                 const float fProxyMaxHealth = pTargetProxy->GetActorMaxHealth();
  152.  
  153.                 const float fCurrHealth = (pTargetProxy->GetActorHealth() + pTargetProxy->GetActorArmor());
  154.                 const float fCurrMaxHealth = (fProxyMaxHealth + pTargetProxy->GetActorMaxArmor());
  155.  
  156.                 fTargetMaxHealth = fCurrMaxHealth / fProxyMaxHealth;
  157.                 fTargetHealth = fCurrHealth / fProxyMaxHealth;
  158.         }
  159.  
  160.         // Calculate the rate of death.
  161.         float fTargetStayAliveTime = GetTargetAliveTime();
  162.  
  163.         // This catches the case when the target turns on and off the armor.
  164.         if (m_targetDamageHealthThr > fTargetMaxHealth)
  165.                 m_targetDamageHealthThr = fTargetMaxHealth;
  166.  
  167.         if (fTargetHealth >= m_targetDamageHealthThr || fTargetStayAliveTime <= FLT_EPSILON)
  168.         {
  169.                 m_targetDamageHealthThr = fTargetHealth;
  170.         }
  171.         else
  172.         {
  173.                 const float fFrametime = GetAISystem()->GetFrameDeltaTime();
  174.                 m_targetDamageHealthThr = max(0.0f, m_targetDamageHealthThr - (1.0f / fTargetStayAliveTime) * m_Parameters.m_fAccuracy * fFrametime);
  175.         }
  176.  
  177.         if (gAIEnv.CVars.DebugDrawDamageControl > 0)
  178.         {
  179.                 if (!m_targetDamageHealthThrHistory)
  180.                         m_targetDamageHealthThrHistory = new CValueHistory<float>(100, 0.1f);
  181.                 m_targetDamageHealthThrHistory->Sample(m_targetDamageHealthThr, GetAISystem()->GetFrameDeltaTime());
  182.  
  183. #ifdef CRYAISYSTEM_DEBUG
  184.                 UpdateHealthHistory();
  185. #endif
  186.         }
  187. }
  188.  
  189. //====================================================================
  190. // GetFiringReactionTime
  191. //====================================================================
  192. float CPuppet::GetFiringReactionTime(const Vec3& targetPos) const
  193. {
  194.         // Apply archetype modifier
  195.         float fReactionTime = gAIEnv.CVars.RODReactionTime * GetParameters().m_PerceptionParams.reactionTime;
  196.  
  197.         const CAIActor* pLiveTarget = GetLiveTarget(m_refAttentionTarget).GetAIObject();
  198.         if (!pLiveTarget)
  199.                 return fReactionTime;
  200.  
  201.         const CAIActor* pLiveActor = pLiveTarget->CastToCAIActor();
  202.         if (!pLiveActor)
  203.                 return fReactionTime;
  204.  
  205.         // Delegate to handle if available
  206.         if (m_pRODHandler)
  207.         {
  208.                 fReactionTime = m_pRODHandler->GetFiringReactionTime(this, pLiveTarget, targetPos);
  209.         }
  210.         else
  211.         {
  212.                 if (IsAffectedByLight())
  213.                 {
  214.                         EAILightLevel iTargetLightLevel = pLiveTarget->GetLightLevel();
  215.                         if (iTargetLightLevel == AILL_MEDIUM)
  216.                         {
  217.                                 fReactionTime += gAIEnv.CVars.RODReactionMediumIllumInc;
  218.                         }
  219.                         else if (iTargetLightLevel == AILL_DARK)
  220.                         {
  221.                                 fReactionTime += gAIEnv.CVars.RODReactionDarkIllumInc;
  222.                         }
  223.                         else if (iTargetLightLevel == AILL_SUPERDARK)
  224.                         {
  225.                                 fReactionTime += gAIEnv.CVars.RODReactionSuperDarkIllumInc;
  226.                         }
  227.                 }
  228.  
  229.                 const float fDistInc = min(1.0f, gAIEnv.CVars.RODReactionDistInc);
  230.                 // Increase reaction time if the target is further away.
  231.                 if (m_targetZone == AIZONE_COMBAT_NEAR)
  232.                         fReactionTime += fDistInc;
  233.                 else if (m_targetZone >= AIZONE_COMBAT_FAR)
  234.                         fReactionTime += fDistInc * 2.0f;
  235.  
  236.                 // Increase the reaction time of the target is leaning.
  237.                 const SAIBodyInfo& bi = pLiveActor->GetBodyInfo();
  238.                 if (fabsf(bi.lean) > 0.01f)
  239.                 {
  240.                         fReactionTime += gAIEnv.CVars.RODReactionLeanInc;
  241.                 }
  242.  
  243.                 Vec3 dirTargetToShooter = GetPos() - pLiveTarget->GetPos();
  244.                 dirTargetToShooter.Normalize();
  245.                 const float fLeaningDot = pLiveTarget->GetViewDir().Dot(dirTargetToShooter);
  246.  
  247.                 const float thr1 = cosf(DEG2RAD(30.0f));
  248.                 const float thr2 = cosf(DEG2RAD(95.0f));
  249.                 if (fLeaningDot < thr1)
  250.                         fReactionTime += gAIEnv.CVars.RODReactionDirInc;
  251.                 else if (fLeaningDot < thr2)
  252.                         fReactionTime += gAIEnv.CVars.RODReactionDirInc * 2.0f;
  253.         }
  254.  
  255.         return fReactionTime;
  256. }
  257.  
  258. //====================================================================
  259. // UpdateFireReactionTimer
  260. //====================================================================
  261. void CPuppet::UpdateFireReactionTimer(const Vec3& vTargetPos)
  262. {
  263.         const float fFrametime = GetAISystem()->GetFrameDeltaTime();
  264.         const float fReactionTime = GetFiringReactionTime(vTargetPos);
  265.  
  266.         // Update the fire reaction timer
  267.         bool bReacting = false;
  268.         if (IsAllowedToHitTarget() && AllowedToFire())
  269.         {
  270.                 if (GetAttentionTargetType() == AITARGET_VISUAL && GetAttentionTargetThreat() == AITHREAT_AGGRESSIVE)
  271.                 {
  272.                         m_firingReactionTime = min(m_firingReactionTime + fFrametime, fReactionTime + 0.001f);
  273.                         bReacting = true;
  274.                 }
  275.         }
  276.  
  277.         if (!bReacting)
  278.         {
  279.                 m_firingReactionTime = max(0.0f, m_firingReactionTime - fFrametime);
  280.         }
  281.  
  282.         m_firingReactionTimePassed = m_firingReactionTime >= fReactionTime;
  283. }
  284.  
  285. //====================================================================
  286. // UpdateTargetZone
  287. //====================================================================
  288. void CPuppet::UpdateTargetZone(CWeakRef<CAIObject> refTarget)
  289. {
  290.         CAIObject* pTarget = refTarget.GetAIObject();
  291.         if (!pTarget)
  292.         {
  293.                 m_targetZone = AIZONE_OUT;
  294.                 return;
  295.         }
  296.  
  297.         // Delegate to handler if available
  298.         if (m_pRODHandler)
  299.         {
  300.                 m_targetZone = m_pRODHandler->GetTargetZone(this, pTarget);
  301.         }
  302.         else
  303.         {
  304.                 const float fKillRange = gAIEnv.CVars.RODKillRangeMod;
  305.                 const float fCombatRange = gAIEnv.CVars.RODCombatRangeMod;
  306.  
  307.                 // Calculate off of attack range
  308.                 const float fDistToTargetSqr = Distance::Point_PointSq(GetPos(), pTarget->GetPos());
  309.                 if (fDistToTargetSqr < sqr(m_Parameters.m_fAttackRange * fKillRange))
  310.                         m_targetZone = AIZONE_KILL;
  311.                 else if (fDistToTargetSqr < sqr(m_Parameters.m_fAttackRange * (fCombatRange + fKillRange) / 2))
  312.                         m_targetZone = AIZONE_COMBAT_NEAR;
  313.                 else if (fDistToTargetSqr < sqr(m_Parameters.m_fAttackRange * fCombatRange))
  314.                         m_targetZone = AIZONE_COMBAT_FAR;
  315.                 else if (fDistToTargetSqr < sqr(m_Parameters.m_fAttackRange))
  316.                         m_targetZone = AIZONE_WARN;
  317.                 else
  318.                         m_targetZone = AIZONE_OUT;
  319.         }
  320. }
  321.  
  322. std::vector<Vec3> CPuppet::s_projectedPoints(16);
  323.  
  324. //====================================================================
  325. // UpdateTargetTracking
  326. //====================================================================
  327. Vec3 CPuppet::UpdateTargetTracking(CWeakRef<CAIObject> refTarget, const Vec3& vTargetPos)
  328. {
  329.         const float fFrametime = GetAISystem()->GetFrameDeltaTime();
  330.         const float fReactionTime = GetFiringReactionTime(vTargetPos);
  331.  
  332.         // Update the fire reaction timer
  333.         UpdateFireReactionTimer(vTargetPos);
  334.  
  335.         const CAIObject* pTarget = refTarget.GetAIObject();
  336.         const CAIActor* pLiveTarget = GetLiveTarget(refTarget).GetAIObject();
  337.         if (!pLiveTarget)
  338.         {
  339.                 ResetTargetTracking();
  340.                 m_targetBiasDirection += (Vec3(0, 0, -1) - m_targetBiasDirection) * fFrametime;
  341.                 return vTargetPos;
  342.         }
  343.  
  344.         CCCPOINT(CPuppet_UpdateTargetTracking);
  345.  
  346.         // Update the current target's zone
  347.         UpdateTargetZone(refTarget);
  348.  
  349.         float fFocusTargetValue = 0.0f;
  350.         fFocusTargetValue += pTarget->GetVelocity().GetLength() / 3.0f;
  351.         fFocusTargetValue += m_targetEscapeLastMiss;
  352.         if (m_targetZone >= AIZONE_WARN)
  353.                 fFocusTargetValue += 1.0f;
  354.         Limit(fFocusTargetValue, 0.0f, 1.0f);
  355.         if (fFocusTargetValue > m_targetFocus)
  356.                 m_targetFocus += (fFocusTargetValue - m_targetFocus) * fFrametime;
  357.         else
  358.                 m_targetFocus += (fFocusTargetValue - m_targetFocus) * 0.4f * fFrametime;
  359.  
  360.         // Calculate a silhouette which is later used to miss the player intentionally.
  361.         // The silhouette is the current target AABB extruded into the movement direction.
  362.         // The silhouette exists on a plane which separates the shooter and the target.
  363.         if (!m_bDryUpdate || !m_targetSilhouette.valid)
  364.         {
  365.                 m_targetSilhouette.valid = true;
  366.  
  367.                 //AIAssert(pLiveTarget->GetProxy());
  368.  
  369.                 // Calculate the current and predicted AABB of the target.
  370.                 const float MISS_PREDICTION_TIME = 0.8f;
  371.  
  372.                 AABB aabbCur, aabbNext;
  373.  
  374.                 IPhysicalEntity* pPhys = 0;
  375.  
  376.                 // Marcio: pLiveTarget will be a different object if it was retrieved by association.
  377.                 if (pLiveTarget)
  378.                 {
  379.                         pPhys = pLiveTarget->GetPhysics(true);
  380.                         if (!pPhys)
  381.                                 pPhys = pLiveTarget->GetProxy() ? pLiveTarget->GetProxy()->GetPhysics(true) : 0;
  382.                 }
  383.                 else
  384.                 {
  385.                         pPhys = pTarget->GetPhysics(true);
  386.                         if (!pPhys)
  387.                                 pPhys = pTarget->GetProxy() ? pTarget->GetProxy()->GetPhysics(true) : 0;
  388.                 }
  389.  
  390.                 if (!pPhys)
  391.                 {
  392.                         AIWarning("CPuppet::UpdateTargetTracking() Target %s does not have physics!", pTarget->GetName());
  393.                         AIAssert(0);
  394.                         ResetTargetTracking();
  395.                         m_targetBiasDirection += (Vec3(0, 0, -1) - m_targetBiasDirection) * fFrametime;
  396.                         return vTargetPos;
  397.                 }
  398.  
  399.                 pe_status_pos statusPos;
  400.                 pPhys->GetStatus(&statusPos);
  401.                 aabbCur.Reset();
  402.                 aabbCur.Add(statusPos.BBox[0] + statusPos.pos);
  403.                 aabbCur.Add(statusPos.BBox[1] + statusPos.pos);
  404.                 aabbNext = aabbCur;
  405.                 aabbCur.min.z -= 0.05f; // This adjustment moves any ground effect slightly in front of the target.
  406.                 aabbNext.min.z -= 0.05f;
  407.  
  408.                 Vec3 vel = pTarget->GetVelocity() * MISS_PREDICTION_TIME;
  409.                 aabbNext.Move(vel);
  410.  
  411.                 // Create a list of points which is used to calculate the silhouette.
  412.                 Vec3 points[16];
  413.                 SetAABBCornerPoints(aabbCur, &points[0]);
  414.                 SetAABBCornerPoints(aabbNext, &points[8]);
  415.  
  416.                 m_targetSilhouette.center = aabbCur.GetCenter() + vel * 0.5f;
  417.  
  418.                 // Project points on a plane between the shooter and the target.
  419.                 Vec3 dir = m_targetSilhouette.center - GetPos();
  420.                 dir.NormalizeSafe();
  421.                 m_targetSilhouette.baseMtx.SetRotationVDir(dir, 0.0f);
  422.  
  423.                 const Vec3& u = m_targetSilhouette.baseMtx.GetColumn0();
  424.                 const Vec3& v = m_targetSilhouette.baseMtx.GetColumn2();
  425.  
  426.                 for (unsigned i = 0; i < 16; ++i)
  427.                 {
  428.                         Vec3 pt = points[i] - m_targetSilhouette.center;
  429.                         s_projectedPoints[i].Set(u.Dot(pt), v.Dot(pt), 0.0f);
  430.                 }
  431.  
  432.                 // The silhouette is the convex hull of all the points in the two AABBs.
  433.                 m_targetSilhouette.points.clear();
  434.                 ConvexHull2D(m_targetSilhouette.points, s_projectedPoints);
  435.         }
  436.  
  437.         // Calculate a direction that is used to calculate the miss points on the silhouette.
  438.         Vec3 desiredTargetBias(0, 0, 0);
  439.  
  440.         // 1) Bend the direction towards the target movement direction.
  441.         if (pTarget)
  442.                 desiredTargetBias += pTarget->GetVelocity().GetNormalizedSafe(Vec3(0, 0, 0));
  443.  
  444.         // 2) Bend the direction towards the point that is visible to the shooter.
  445.         // Note: If the target is visible vTargetPos==m_targetSilhouette.center.
  446.         desiredTargetBias += ((vTargetPos - m_targetSilhouette.center) / 2.0f) * (1 - m_targetEscapeLastMiss);
  447.  
  448.         // 3) Bend the direction towards ground if not trying to adjust the away from obstructed area.
  449.         desiredTargetBias.z -= 0.1f + 0.5f * (1 - m_targetEscapeLastMiss);
  450.  
  451.         // 4) If the current aim is obstructed, try to climb the silhouette to the other side.
  452.         if (m_targetEscapeLastMiss > 0.0f && !m_targetLastMissPoint.IsZero())
  453.         {
  454.                 Vec3 deltaProj = m_targetSilhouette.ProjectVectorOnSilhouette(m_targetBiasDirection);
  455.                 deltaProj.NormalizeSafe();
  456.                 if (!deltaProj.IsZero())
  457.                 {
  458.                         float lastMissAngle = atan2f(deltaProj.y, deltaProj.x);
  459.  
  460.                         const Vec3& u = m_targetSilhouette.baseMtx.GetColumn0();
  461.                         const Vec3& v = m_targetSilhouette.baseMtx.GetColumn2();
  462.  
  463.                         // Choose the climb direction based on the current side
  464.                         float a = u.Dot(m_targetBiasDirection) < 0.0f ? -gf_PI / 2 : gf_PI / 2;
  465.  
  466.                         float x = cosf(lastMissAngle + a);
  467.                         float y = sinf(lastMissAngle + a);
  468.  
  469.                         desiredTargetBias += (u * x + v * y) * m_targetEscapeLastMiss;
  470.                 }
  471.         }
  472.  
  473.         if (desiredTargetBias.NormalizeSafe(ZERO) > 0.0f)
  474.         {
  475.                 m_targetBiasDirection += (desiredTargetBias - m_targetBiasDirection) * 4.0f * fFrametime;
  476.                 m_targetBiasDirection.NormalizeSafe(ZERO);
  477.         }
  478.  
  479.         m_targetPosOnSilhouettePlane = m_targetSilhouette.IntersectSilhouettePlane(GetFirePos(), vTargetPos);
  480.         Vec3 targetPosOnSilhouettePlaneProj = m_targetSilhouette.ProjectVectorOnSilhouette(m_targetPosOnSilhouettePlane - m_targetSilhouette.center);
  481.  
  482.         // Calculate the distance between the target pos and the silhouette.
  483.         if (Overlap::Point_Polygon2D(targetPosOnSilhouettePlaneProj, m_targetSilhouette.points))
  484.         {
  485.                 // Inside the polygon, zero dist.
  486.                 m_targetDistanceToSilhouette = 0.0f;
  487.         }
  488.         else
  489.         {
  490.                 // Distance to the nearest edge.
  491.                 Vec3 pt;
  492.                 m_targetDistanceToSilhouette = Distance::Point_Polygon2D(targetPosOnSilhouettePlaneProj, m_targetSilhouette.points, pt);
  493.         }
  494.  
  495.         return vTargetPos;
  496. }
  497.  
  498. //====================================================================
  499. // CanDamageTarget
  500. //====================================================================
  501. bool CPuppet::CanDamageTarget(IAIObject* target) const
  502. {
  503.         // Never hit when in panic spread fire mode.
  504.         if (m_fireMode == FIREMODE_PANIC_SPREAD)
  505.                 return false;
  506.  
  507.         if (m_Parameters.m_fAccuracy < 0.001f)
  508.                 return false;
  509.  
  510.         CAIObject* fireTargetObject = GetFireTargetObject();
  511.         tAIObjectID fireTargetID = fireTargetObject ? fireTargetObject->GetAIObjectID() : 0;
  512.  
  513.         CAIObject* player = GetAISystem()->GetPlayer();
  514.  
  515.         bool isCurrentFireTarget = !target || (target->GetAIObjectID() == fireTargetID);
  516.         //bool targetIsPlayer = target && player && target->GetAIObjectID() == player->GetAIObjectID();
  517.  
  518.         if (isCurrentFireTarget)
  519.         {
  520.                 // Allow to hit always when requested kill fire mode.
  521.                 if (m_fireMode == FIREMODE_KILL)
  522.                         return true;
  523.  
  524.                 if (m_targetDazzlingTime > 0.0f)
  525.                         return false;
  526.  
  527.                 // HACK: [16:05:08 mieszko]: I'm not sure it's a hack. I just don't think this kind of things should be
  528.                 // decided purely on C++ side (see the way m_firingReactionTimePassed value is determined).
  529.                 if (gAIEnv.configuration.eCompatibilityMode != ECCM_GAME04)
  530.                 {
  531.                         if (/*targetIsPlayer && */
  532.                           (m_fireMode != FIREMODE_VEHICLE) && (m_fireMode != FIREMODE_FORCED) && (m_fireMode != FIREMODE_KILL) && (m_fireMode != FIREMODE_OFF) && !HasFiringReactionTimePassed())
  533.                                 return false;
  534.                 }
  535.         }
  536.  
  537.         CAIObject* targetAIObject = target ? static_cast<CAIObject*>(target) : fireTargetObject;
  538.         const bool isAIObjectTarget = targetAIObject ? (targetAIObject->GetType() == AIOBJECT_TARGET) : false;
  539.         if (isAIObjectTarget)
  540.                 return true;
  541.  
  542.         CWeakRef<CAIObject> refTarget = GetWeakRef(targetAIObject);
  543.         const CAIActor* pLiveTargetActor = GetLiveTarget(refTarget).GetAIObject();
  544.         if (!pLiveTargetActor || !pLiveTargetActor->GetProxy())
  545.                 return true;
  546.  
  547.         // If the target is at low health, allow short time of mercy for it.
  548.         if (pLiveTargetActor->IsLowHealthPauseActive())
  549.                 return false;
  550.  
  551.         CCCPOINT(CPuppet_CanDamageTarget);
  552.  
  553.         float maxHealth = pLiveTargetActor->GetProxy()->GetActorMaxHealth();
  554.         float health = 0.001f + pLiveTargetActor->GetProxy()->GetActorHealth() + pLiveTargetActor->GetProxy()->GetActorArmor();
  555.  
  556.         float thr = m_targetDamageHealthThr * maxHealth;
  557.  
  558.         return (thr > 0.0f) && (health >= thr);
  559. }
  560.  
  561. //====================================================================
  562. // CanDamageTargetWithMelee
  563. //====================================================================
  564. bool CPuppet::CanDamageTargetWithMelee() const
  565. {
  566.         const CAIObject* pLiveTarget = GetLiveTarget(m_refAttentionTarget).GetAIObject();
  567.         if (!pLiveTarget)
  568.                 return true;
  569.  
  570.         // If the target is at low health, allow short time of mercy for it.
  571.         if (const CAIActor* pLiveTargetActor = pLiveTarget->CastToCAIActor())
  572.                 if (pLiveTargetActor->IsLowHealthPauseActive())
  573.                         return false;
  574.  
  575.         return true;
  576. }
  577.  
  578. //====================================================================
  579. // ResetTargetTracking
  580. //====================================================================
  581. void CPuppet::ResetTargetTracking()
  582. {
  583.         m_targetLastMissPoint.zero();
  584.         m_targetEscapeLastMiss = 0.0f;
  585.         m_targetFocus = 0.0f;
  586.         m_lastHitShotsCount = ~0l;
  587.         m_lastMissShotsCount = ~0l;
  588.  
  589.         if (m_targetSilhouette.valid)
  590.                 m_targetSilhouette.Reset();
  591. }
  592.  
  593. //====================================================================
  594. // GetCoverFireTime
  595. //====================================================================
  596. float CPuppet::GetCoverFireTime() const
  597. {
  598.         return m_CurrentWeaponDescriptor.coverFireTime * gAIEnv.CVars.RODCoverFireTimeMod;
  599. }
  600.  
  601. //====================================================================
  602. // GetBurstFireDistanceScale
  603. //====================================================================
  604. float CPuppet::GetBurstFireDistanceScale() const
  605. {
  606.         float fResult = 1.0f;
  607.  
  608.         switch (m_targetZone)
  609.         {
  610.         case AIZONE_KILL:
  611.                 fResult = 1.0f;
  612.                 break;
  613.         case AIZONE_COMBAT_NEAR:
  614.                 fResult = 0.9f;
  615.                 break;
  616.         case AIZONE_COMBAT_FAR:
  617.                 fResult = 0.9f;
  618.                 break;
  619.         case AIZONE_WARN:
  620.                 fResult = 0.4f;
  621.                 break;
  622.         case AIZONE_OUT:
  623.                 fResult = 0.0f;
  624.                 break;
  625.  
  626.         // Ignore or default don't alter the scale
  627.         case AIZONE_IGNORE:
  628.         default:
  629.                 fResult = 1.0f;
  630.                 break;
  631.         }
  632.  
  633.         return fResult;
  634. }
  635.  
  636. //====================================================================
  637. // GetBurstFireDistanceScale
  638. //====================================================================
  639. void CPuppet::HandleBurstFireInit()
  640. {
  641.         // When starting burst in warn zone, force first bullets to miss
  642.         // TODO: not nice to handle it this way!
  643.         if (m_targetZone == AIZONE_WARN)
  644.                 m_targetSeenTime = std::max(0.0f, m_targetSeenTime - (cry_random(1, 3)) / 10.0f);
  645.  
  646.         /* M谩rcio: does not work for Burst fire weapons - does not seem to have any benefits anyways
  647.            IAIActorProxy *pProxy = GetProxy();
  648.            if (pProxy)
  649.             pProxy->GetAndResetShotBulletCount();
  650.          */
  651. }
  652.  
downloadPuppetRateOfDeath.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