BVB Source Codes

CRYENGINE Show VehicleComponent.cpp Source code

Return Download CRYENGINE: download VehicleComponent.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: Implements a standard class for a vehicle component
  8.  
  9.    -------------------------------------------------------------------------
  10.    History:
  11.    - 12:10:2005: Created by Mathieu Pinard
  12.  
  13. *************************************************************************/
  14. #include "StdAfx.h"
  15.  
  16. #include "GameObjects/GameObject.h"
  17. #include "IActorSystem.h"
  18. #include "IVehicleSystem.h"
  19. #include "IViewSystem.h"
  20. #include "CryAction.h"
  21. #include "IGameObject.h"
  22. #include <CryAISystem/IAgent.h>
  23.  
  24. #include "Vehicle.h"
  25. #include "VehicleComponent.h"
  26. #include "VehicleDamageBehaviorDetachPart.h"
  27. #include "VehiclePartAnimatedJoint.h"
  28.  
  29. #include <CryRenderer/IRenderer.h>
  30. #include <CryRenderer/IRenderAuxGeom.h>
  31. #include "IGameRulesSystem.h"
  32.  
  33. DEFINE_SHARED_PARAMS_TYPE_INFO(CVehicleComponent::SSharedParams)
  34.  
  35. #if ENABLE_VEHICLE_DEBUG
  36. namespace
  37. {
  38. ILINE bool DebugDamage() { return VehicleCVars().v_debugdraw == eVDB_Damage; }
  39. }
  40. #endif
  41.  
  42. //------------------------------------------------------------------------
  43. // Suppressed uninitMemberVar warnings due to use of BEGIN_SHARED_PARAMS macro
  44. // cppcheck-suppress uninitMemberVar
  45. CVehicleComponent::CVehicleComponent()
  46.         : m_pVehicle(nullptr)
  47.         , m_damage(0.0f)
  48.         , m_proportionOfVehicleHealth(0.f)
  49.         , m_lastHitLocalPos(ZERO)
  50.         , m_lastHitRadius(0.f)
  51.         , m_lastHitType(0)
  52. {
  53.         m_bounds.Reset();
  54. }
  55.  
  56. //------------------------------------------------------------------------
  57. CVehicleComponent::~CVehicleComponent()
  58. {
  59.         for (TVehicleDamageBehaviorVector::iterator ite = m_damageBehaviors.begin(); ite != m_damageBehaviors.end(); ++ite)
  60.                 ite->second->Release();
  61. }
  62.  
  63. //------------------------------------------------------------------------
  64. bool CVehicleComponent::Init(IVehicle* pVehicle, const CVehicleParams& paramsTable)
  65. {
  66.         // Store pointer to vehicle.
  67.  
  68.         m_pVehicle = static_cast<CVehicle*>(pVehicle);
  69.  
  70.         // Get name.
  71.  
  72.         string name = paramsTable.getAttr("name");
  73.  
  74.         if (name.empty())
  75.         {
  76.                 return false;
  77.         }
  78.  
  79.         // Construct vehicle component name.
  80.  
  81.         string vehicleComponentName = m_pVehicle->GetEntity()->GetClass()->GetName();
  82.  
  83.         const char* pModification = m_pVehicle->GetModification();
  84.  
  85.         if (pModification != 0 && strlen(pModification))
  86.         {
  87.                 vehicleComponentName.append("::");
  88.  
  89.                 vehicleComponentName.append(pModification);
  90.         }
  91.  
  92.         vehicleComponentName.append("::Comp::");
  93.  
  94.         vehicleComponentName.append(name);
  95.  
  96.         // Get shared parameters.
  97.  
  98.         m_pSharedParams = GetSharedParams(vehicleComponentName, paramsTable);
  99.  
  100.         CRY_ASSERT(m_pSharedParams != 0);
  101.  
  102.         if (!m_pSharedParams)
  103.         {
  104.                 return false;
  105.         }
  106.  
  107.         m_bounds = m_pSharedParams->bounds;
  108.         m_lastHitType = 0;
  109.  
  110.         Vec3 position;
  111.         Vec3 size;
  112.         if (paramsTable.getAttr("position", position) && paramsTable.getAttr("size", size))
  113.         {
  114.                 bool hasOldBoundInfo = !m_bounds.IsReset();
  115.                 if (hasOldBoundInfo)
  116.                 {
  117.                         GameWarning("Component %s for vehicle %s has maxBound and/or minBound together with position and size properties. Using position and size.", m_pSharedParams->name.c_str(), m_pVehicle->GetEntity()->GetName());
  118.                 }
  119.                 Vec3 halfSize = size * 0.5f;
  120.                 m_bounds.min = position - halfSize;
  121.                 m_bounds.max = position + halfSize;
  122.         }
  123.  
  124.         if (m_bounds.IsReset())
  125.         {
  126.                 m_bounds.min.zero();
  127.                 m_bounds.max.zero();
  128.         }
  129.         else if (!(m_bounds.min.x <= m_bounds.max.x && m_bounds.min.y <= m_bounds.max.y && m_bounds.min.z <= m_bounds.max.z))
  130.         {
  131.                 GameWarning("Invalid bounding box read for %s, component %s", m_pVehicle->GetEntity()->GetName(), m_pSharedParams->name.c_str());
  132.                 m_bounds.min.zero();
  133.                 m_bounds.max.zero();
  134.         }
  135.  
  136.         m_damage = 0.0f;
  137.  
  138.         if (CVehicleParams damageBehaviorsTable = paramsTable.findChild("DamageBehaviors"))
  139.         {
  140.                 int i = 0;
  141.                 int c = damageBehaviorsTable.getChildCount();
  142.                 m_damageBehaviors.reserve(c);
  143.  
  144.                 for (; i < c; i++)
  145.                 {
  146.                         if (CVehicleParams damageBehaviorTable = damageBehaviorsTable.getChild(i))
  147.                         {
  148.                                 SDamageBehaviorParams behaviorParams;
  149.  
  150.                                 if (!damageBehaviorTable.getAttr("damageRatioMin", behaviorParams.damageRatioMin))
  151.                                 {
  152.                                         behaviorParams.damageRatioMin = 1.0f;
  153.                                 }
  154.  
  155.                                 if (!damageBehaviorTable.getAttr("damageRatioMax", behaviorParams.damageRatioMax))
  156.                                 {
  157.                                         behaviorParams.damageRatioMax = 0.0f;
  158.                                 }
  159.  
  160.                                 if (!damageBehaviorTable.getAttr("ignoreVehicleDestruction", behaviorParams.ignoreOnVehicleDestroyed))
  161.                                 {
  162.                                         behaviorParams.ignoreOnVehicleDestroyed = false;
  163.                                 }
  164.  
  165.                                 if (damageBehaviorTable.haveAttr("class"))
  166.                                 {
  167.                                         IVehicleSystem* pVehicleSystem = CCryAction::GetCryAction()->GetIVehicleSystem();
  168.  
  169.                                         const char* szClass = damageBehaviorTable.getAttr("class");
  170.                                         IVehicleDamageBehavior* pDamageBehavior = (szClass && szClass[0] ? pVehicleSystem->CreateVehicleDamageBehavior(szClass) : NULL);
  171.                                         if (pDamageBehavior)
  172.                                         {
  173.                                                 if (pDamageBehavior->Init(pVehicle, damageBehaviorTable))
  174.                                                         m_damageBehaviors.push_back(TVehicleDamageBehaviorPair(behaviorParams, pDamageBehavior));
  175.                                                 else
  176.                                                         pDamageBehavior->Release();
  177.                                         }
  178.                                 }
  179.                         }
  180.                 }
  181.         }
  182.  
  183.         m_lastHitLocalPos.zero();
  184.         m_lastHitRadius = 0.0f;
  185.  
  186.         return true;
  187. }
  188.  
  189. //------------------------------------------------------------------------
  190. void CVehicleComponent::Reset()
  191. {
  192.         m_damage = 0.0f;
  193.  
  194.         for (TVehicleDamageBehaviorVector::iterator ite = m_damageBehaviors.begin(); ite != m_damageBehaviors.end(); ++ite)
  195.         {
  196.                 IVehicleDamageBehavior* pVehicleDamageBehavior = ite->second;
  197.                 pVehicleDamageBehavior->Reset();
  198.         }
  199.  
  200.         m_lastHitLocalPos.zero();
  201.         m_lastHitRadius = 0.0f;
  202.         m_lastHitType = 0;
  203.  
  204.         m_proportionOfVehicleHealth = 0.0f;
  205. }
  206.  
  207. //------------------------------------------------------------------------
  208. unsigned int CVehicleComponent::GetPartCount() const
  209. {
  210.         return m_parts.size();
  211. }
  212.  
  213. //------------------------------------------------------------------------
  214. IVehiclePart* CVehicleComponent::GetPart(unsigned int index) const
  215. {
  216.         if (index < m_parts.size())
  217.         {
  218.                 return m_parts[index];
  219.         }
  220.  
  221.         return NULL;
  222. }
  223.  
  224. //------------------------------------------------------------------------
  225. const AABB& CVehicleComponent::GetBounds()
  226. {
  227.         if (m_pSharedParams->useBoundsFromParts)
  228.         {
  229.                 m_bounds.Reset();
  230.  
  231.                 for (TVehiclePartVector::iterator ite = m_parts.begin(), end = m_parts.end(); ite != end; ++ite)
  232.                 {
  233.                         IVehiclePart* pPart = *ite;
  234.                         m_bounds.Add(pPart->GetLocalBounds());
  235.                 }
  236.  
  237.                 if (!m_bounds.IsReset())
  238.                 {
  239.                         // add a tolerance - bbox checks may fail, depending on part geometry
  240.                         Vec3 delta(0.05f, 0.05f, 0.05f);
  241.                         m_bounds.max += delta;
  242.                         m_bounds.min -= delta;
  243.                 }
  244.         }
  245.         else if (m_bounds.IsEmpty())
  246.         {
  247.                 m_pVehicle->GetEntity()->GetLocalBounds(m_bounds);
  248.         }
  249.  
  250.         return m_bounds;
  251. }
  252.  
  253. //------------------------------------------------------------------------
  254. void CVehicleComponent::OnHit(const HitInfo& hitInfo, const TVehicleComponentVector* pAffectedComponents)
  255. {
  256.         if (m_pSharedParams->damageMax <= 0.0f)
  257.                 return;
  258.  
  259. #if ENABLE_VEHICLE_DEBUG
  260.         if (DebugDamage())
  261.                 CryLog("=== Hit Component <%s>, base damage %.1f ===", GetComponentName(), hitInfo.damage);
  262. #endif
  263.  
  264.         Vec3 localPos = m_pVehicle->GetEntity()->GetWorldTM().GetInverted() * hitInfo.pos;
  265.  
  266.         // direct impact?
  267.         bool impact = !hitInfo.explosion || hitInfo.targetId == m_pVehicle->GetEntityId();
  268.  
  269.         HitInfo hitInfoLocal = hitInfo;
  270.         hitInfoLocal.pos = localPos;
  271.         float processedDamage = ProcessDamage(hitInfoLocal, impact, pAffectedComponents);
  272.  
  273. #if ENABLE_VEHICLE_DEBUG
  274.         if (DebugDamage())
  275.                 CryLog("final damage: %.1f", processedDamage);
  276. #endif
  277.  
  278.         if (abs(processedDamage) < 0.001f)
  279.                 return;
  280.  
  281.         // repairing
  282.         if (processedDamage <= 0.0f && (m_pVehicle->IsDestroyed() || m_damage == 0.f))
  283.                 return;
  284.  
  285.         // Repairing: special check here for vehicle damage caused by being submerged in water - otherwise the player
  286.         //      can continually repair the vehicle while it is taking damage in water (gaining lots of PP in MP).
  287.         const SVehicleStatus& status = m_pVehicle->GetStatus();
  288.         const SVehicleDamageParams& damageParams = m_pVehicle->GetDamageParams();
  289.         if (processedDamage <= 0.0f && status.submergedRatio > damageParams.submergedRatioMax)
  290.         {
  291.                 return;
  292.         }
  293.  
  294.         if (m_pSharedParams->isOnlyDamageableByPlayer && processedDamage > 0.f)
  295.         {
  296.                 if (IActor* pActor = CCryAction::GetCryAction()->GetIActorSystem()->GetActor(hitInfo.shooterId))
  297.                 {
  298.                         if (!pActor->IsPlayer())
  299.                                 return;
  300.                 }
  301.         }
  302.  
  303.         m_lastHitLocalPos = localPos;
  304.         m_lastHitRadius = max(0.1f, min(3.0f, hitInfo.radius));
  305.  
  306.         m_lastHitType = hitInfo.type;
  307.  
  308.         float currentDamageRatio = m_damage / m_pSharedParams->damageMax;
  309.         int currentDamageLevel = int(min(currentDamageRatio, 1.0f) / 0.25f);
  310.  
  311.         m_damage = max(0.0f, m_damage + processedDamage);
  312.  
  313.         float newDamageRatio = m_damage / m_pSharedParams->damageMax;
  314.         int newDamageLevel = int(min(newDamageRatio, 1.0f) / 0.25f);
  315.  
  316.         if (gEnv->bServer)
  317.                 CHANGED_NETWORK_STATE(m_pVehicle, CVehicle::ASPECT_COMPONENT_DAMAGE);
  318.  
  319.         if (m_pSharedParams->useDamageLevels && currentDamageLevel == newDamageLevel)
  320.                 return;
  321.  
  322. #if ENABLE_VEHICLE_DEBUG
  323.         if (VehicleCVars().v_debugdraw)
  324.                 CryLog("%s - damaged <%s> with %.1f damages (total: %.1f)", m_pVehicle->GetEntity()->GetName(), m_pSharedParams->name.c_str(), processedDamage, m_damage);
  325. #endif
  326.  
  327.         BroadcastDamage(processedDamage, hitInfo.shooterId);
  328. }
  329.  
  330. //------------------------------------------------------------------------
  331. void CVehicleComponent::OnVehicleDestroyed()
  332. {
  333.         for (TVehicleDamageBehaviorVector::iterator ite = m_damageBehaviors.begin(); ite != m_damageBehaviors.end(); ++ite)
  334.         {
  335.                 const SDamageBehaviorParams& behaviorParams = ite->first;
  336.                 if (!behaviorParams.ignoreOnVehicleDestroyed)
  337.                 {
  338.                         IVehicleDamageBehavior* pVehicleDamageBehavior = ite->second;
  339.  
  340.                         SVehicleDamageBehaviorEventParams eventParams;
  341.                         eventParams.componentDamageRatio = 1.0f;
  342.                         eventParams.localPos.zero();
  343.                         eventParams.hitValue = 1.0f;
  344.                         eventParams.radius = 0.0f;
  345.                         eventParams.shooterId = 0;
  346.                         eventParams.pVehicleComponent = this;
  347.  
  348.                         pVehicleDamageBehavior->OnDamageEvent(eVDBE_VehicleDestroyed, eventParams);
  349.                 }
  350.         }
  351. }
  352.  
  353. //------------------------------------------------------------------------
  354. void CVehicleComponent::Update(float deltaTime)
  355. {
  356.         //FUNCTION_PROFILER( GetISystem(), PROFILE_ACTION );
  357. }
  358.  
  359. #if ENABLE_VEHICLE_DEBUG
  360. //------------------------------------------------------------------------
  361. void CVehicleComponent::DebugDraw()
  362. {
  363.         if (VehicleCVars().v_draw_components == 1)
  364.         {
  365.                 IRenderAuxGeom* pRenderAux = gEnv->pRenderer->GetIRenderAuxGeom();
  366.  
  367.                 const Matrix34& worldTM = m_pVehicle->GetEntity()->GetWorldTM();
  368.                 const AABB& localBounds = GetBounds();
  369.  
  370.                 static float drawColor[4] = { 1, 1, 1, 1 };
  371.  
  372.                 char pMessage[256];
  373.                 cry_sprintf(pMessage, "%s - %5.2f (%3.2f)", m_pSharedParams->name.c_str(), m_damage, m_damage / max(1.f, m_pSharedParams->damageMax));
  374.  
  375.                 IRenderAuxText::DrawLabelEx(worldTM * localBounds.GetCenter(), 1.2f, drawColor, true, true, pMessage);
  376.  
  377.                 pRenderAux->DrawAABB(localBounds, worldTM, false, RGBA8(255, 0, 0, 255), eBBD_Faceted);
  378.  
  379.                 //Add semi-transparent rendering for the bounding boxes
  380.                 pRenderAux->SetRenderFlags(e_Def3DPublicRenderflags | e_AlphaBlended);
  381.                 pRenderAux->DrawAABB(localBounds, worldTM, true, RGBA8(255, 0, 0, 32), eBBD_Faceted);
  382.         }
  383. }
  384. #endif
  385.  
  386. //------------------------------------------------------------------------
  387. void CVehicleComponent::BroadcastDamage(float damage, EntityId shooterId)
  388. {
  389.         float currentDamageRatio = (m_damage - damage) / m_pSharedParams->damageMax;
  390.         float newDamageRatio = m_damage / m_pSharedParams->damageMax;
  391.         int currentDamageLevel = int(min(currentDamageRatio, 1.0f) / 0.25f);
  392.         int newDamageLevel = int(min(newDamageRatio, 1.0f) / 0.25f);
  393.  
  394.         if (m_pSharedParams->useDamageLevels && currentDamageLevel == newDamageLevel)
  395.                 return;
  396.  
  397.         for (TVehicleDamageBehaviorVector::iterator ite = m_damageBehaviors.begin(), end = m_damageBehaviors.end(); ite != end; ++ite)
  398.         {
  399.                 const SDamageBehaviorParams& behaviorParams = ite->first;
  400.                 IVehicleDamageBehavior* pVehicleDamageBehavior = ite->second;
  401.  
  402.                 if (newDamageRatio >= behaviorParams.damageRatioMin || damage < 0.f)
  403.                 {
  404.                         bool hasPassedSecondCheck = true;
  405.                         if (damage > 0.f && behaviorParams.damageRatioMax > 0.0f && newDamageRatio >= behaviorParams.damageRatioMax)
  406.                         {
  407.                                 if (currentDamageRatio < behaviorParams.damageRatioMax)
  408.                                 {
  409.                                         SVehicleDamageBehaviorEventParams behaviorEventParams;
  410.                                         pVehicleDamageBehavior->OnDamageEvent(eVDBE_MaxRatioExceeded, behaviorEventParams);
  411.                                 }
  412.                                 hasPassedSecondCheck = false;
  413.                         }
  414.  
  415.                         if (hasPassedSecondCheck)
  416.                         {
  417.                                 EVehicleDamageBehaviorEvent behaviorEvent = damage > 0.f ? eVDBE_Hit : eVDBE_Repair;
  418.  
  419.                                 SVehicleDamageBehaviorEventParams behaviorEventParams;
  420.                                 behaviorEventParams.componentDamageRatio = newDamageRatio;
  421.                                 behaviorEventParams.localPos = m_lastHitLocalPos;
  422.                                 behaviorEventParams.hitValue = damage;
  423.                                 behaviorEventParams.hitType = m_lastHitType;
  424.                                 behaviorEventParams.radius = m_lastHitRadius;
  425.                                 behaviorEventParams.randomness = 0.0f;
  426.                                 behaviorEventParams.shooterId = shooterId;
  427.                                 behaviorEventParams.pVehicleComponent = this;
  428.  
  429.                                 pVehicleDamageBehavior->OnDamageEvent(behaviorEvent, behaviorEventParams);
  430.                         }
  431.                 }
  432.         }
  433.  
  434.         // always adhere to damage levels here
  435.         if (currentDamageLevel == newDamageLevel)
  436.                 return;
  437.  
  438.         // component damaged, so we notify all the parts related to the component
  439.         IVehiclePart::SVehiclePartEvent partEvent;
  440.         partEvent.type = damage > 0.f ? IVehiclePart::eVPE_Damaged : IVehiclePart::eVPE_Repair;
  441.         partEvent.fparam = newDamageRatio;
  442.         partEvent.pData = this;
  443.  
  444.         for (TVehiclePartVector::iterator ite = m_parts.begin(); ite != m_parts.end(); ++ite)
  445.         {
  446.                 IVehiclePart* pPart = *ite;
  447.                 pPart->OnEvent(partEvent);
  448.         }
  449. }
  450.  
  451. //------------------------------------------------------------------------
  452. void CVehicleComponent::Serialize(TSerialize ser, EEntityAspects aspects)
  453. {
  454.         if (ser.GetSerializationTarget() != eST_Network)
  455.         {
  456.                 ser.Value("damage", m_damage);
  457.  
  458.                 if (ser.IsReading())
  459.                 {
  460.                         float damageRatio = 1.0f;
  461.                         if (m_pSharedParams->damageMax > 0.0f)
  462.                                 damageRatio = m_damage / m_pSharedParams->damageMax;
  463.                         int damageLevel = int(min(damageRatio, 1.0f) / 0.25f);
  464.                 }
  465.  
  466.                 for (TVehicleDamageBehaviorVector::iterator ite = m_damageBehaviors.begin(); ite != m_damageBehaviors.end(); ++ite)
  467.                 {
  468.                         IVehicleDamageBehavior* pVehicleDamageBehavior = ite->second;
  469.  
  470.                         ser.BeginGroup("damageBehavior");
  471.                         pVehicleDamageBehavior->Serialize(ser, aspects);
  472.                         ser.EndGroup();
  473.                 }
  474.         }
  475.         // network
  476.         else
  477.         {
  478.                 if (aspects & CVehicle::ASPECT_COMPONENT_DAMAGE)
  479.                 {
  480.                         NET_PROFILE_SCOPE("VehicleDamage", ser.IsReading());
  481.  
  482.                         float olddamage = m_damage;
  483.                         ser.Value("damage", m_damage, 'vdmg');
  484.                         ser.Value("hitType", m_lastHitType, 'hTyp');
  485.                         ser.Value("lastHitPos", m_lastHitLocalPos, 'vHPs');
  486.                         ser.Value("lastHitRadius", m_lastHitRadius, 'vHRd');
  487.  
  488.                         if (ser.IsReading() && abs(m_damage - olddamage) > 0.001f)
  489.                         {
  490.                                 BroadcastDamage(m_damage - olddamage, 0);
  491.                         }
  492.                 }
  493.         }
  494. }
  495.  
  496. //------------------------------------------------------------------------
  497. float CVehicleComponent::GetDamageRatio() const
  498. {
  499.         return (m_pSharedParams->damageMax > 0.f) ? min(1.f, m_damage / m_pSharedParams->damageMax) : 0.f;
  500. }
  501.  
  502. //------------------------------------------------------------------------
  503. void CVehicleComponent::SetDamageRatio(float ratio)
  504. {
  505.         if (m_pSharedParams->damageMax > 0.f)
  506.                 m_damage = m_pSharedParams->damageMax * min(1.0f, max(0.0f, ratio));
  507. }
  508.  
  509. //------------------------------------------------------------------------
  510. float CVehicleComponent::GetMaxDamage() const
  511. {
  512.         return m_pSharedParams->damageMax;
  513. }
  514.  
  515. //------------------------------------------------------------------------
  516. void CVehicleComponent::AddPart(IVehiclePart* pPart)
  517. {
  518.         m_parts.push_back(pPart);
  519. }
  520.  
  521. //------------------------------------------------------------------------
  522. float CVehicleComponent::ProcessDamage(const HitInfo& hitInfo, bool impact, const TVehicleComponentVector* pAffectedComponents)
  523. {
  524.         // determine hit ratio/splash damage
  525.  
  526.         bool splash = false;
  527.  
  528.         float damage = hitInfo.damage;
  529.  
  530.         if (hitInfo.type == CVehicle::s_repairHitTypeId)
  531.         {
  532.                 damage = -damage;
  533.         }
  534.  
  535.         if (hitInfo.explosion && hitInfo.radius > 0.0f)
  536.         {
  537.                 const AABB& localBounds = GetBounds();
  538.                 bool inside = localBounds.IsContainPoint(hitInfo.pos);
  539.                 if (!(impact && inside))
  540.                 {
  541.                         // no direct hit, apply splash damage
  542.                         splash = true;
  543.  
  544.                         // todo: more accurate ratio calculation
  545.                         float distanceSq = (hitInfo.pos - localBounds.GetCenter()).GetLengthSquared();
  546.                         float hitRatio = max(0.f, 1.f - distanceSq / sqr(hitInfo.radius));
  547.  
  548.                         damage *= hitRatio;
  549.  
  550. #if ENABLE_VEHICLE_DEBUG
  551.                         if (DebugDamage())
  552.                                 CryLog("splash damage, ratio: %.2f", hitRatio);
  553. #endif
  554.                 }
  555.         }
  556.  
  557.         if (IsHull() && pAffectedComponents && impact)
  558.         {
  559.                 // check if the hit hit one or more other components. if so, get the hull affection from these.
  560.                 float affection = 0.f;
  561.                 int affected = 0;
  562.  
  563.                 for (TVehicleComponentVector::const_iterator it = pAffectedComponents->begin(), end = pAffectedComponents->end(); it != end; ++it)
  564.                 {
  565.                         CVehicleComponent* pComponent = *it;
  566.                         if (pComponent == this)
  567.                                 continue;
  568.  
  569.                         if (hitInfo.radius > 0.f)
  570.                         {
  571.                                 const AABB& compBounds = pComponent->GetBounds();
  572.                                 if (!compBounds.IsContainPoint(hitInfo.pos))
  573.                                         continue;
  574.                         }
  575.  
  576.                         affection += (*it)->m_pSharedParams->hullAffection;
  577.                         ++affected;
  578.  
  579. #if ENABLE_VEHICLE_DEBUG
  580.                         if (DebugDamage())
  581.                                 CryLog("component <%s> affecting hull, affection %.2f", (*it)->GetComponentName(), (*it)->m_pSharedParams->hullAffection);
  582. #endif
  583.                 }
  584.  
  585.                 affection = (affected == 0) ? 1.f : affection / affected;
  586.                 damage *= affection;
  587.  
  588. #if ENABLE_VEHICLE_DEBUG
  589.                 if (DebugDamage())
  590.                         CryLog("total affection: %.2f", affection);
  591. #endif
  592.         }
  593.  
  594.         CVehicleDamages::TDamageMultipliers::const_iterator ite = m_pSharedParams->damageMultipliersByProjectile.find(hitInfo.projectileClassId), end = m_pSharedParams->damageMultipliersByProjectile.end();
  595.  
  596. #if ENABLE_VEHICLE_DEBUG
  597.         const char* pDisplayDamageType = NULL;
  598. #endif
  599.         if (ite == end)
  600.         {
  601.                 ite = m_pSharedParams->damageMultipliersByHitType.find(hitInfo.type), end = m_pSharedParams->damageMultipliersByHitType.end();
  602.  
  603.                 if (ite == end)
  604.                 {
  605. #if ENABLE_VEHICLE_DEBUG
  606.                         pDisplayDamageType = "default";
  607. #endif
  608.                         // 0 is the 'default' damage multiplier, check for it if we didn't find the specified one
  609.                         ite = m_pSharedParams->damageMultipliersByHitType.find((int)CVehicleDamages::DEFAULT_HIT_TYPE);
  610.                 }
  611.                 else
  612.                 {
  613. #if ENABLE_VEHICLE_DEBUG
  614.                         pDisplayDamageType = CCryAction::GetCryAction()->GetIGameRulesSystem()->GetCurrentGameRules()->GetHitType(hitInfo.type);
  615. #endif
  616.                 }
  617.         }
  618.         else
  619.         {
  620. #if ENABLE_VEHICLE_DEBUG
  621.                 char str[256];
  622.                 if (gEnv->pGameFramework->GetNetworkSafeClassName(str, sizeof(str), hitInfo.projectileClassId))
  623.                 {
  624.                         pDisplayDamageType = str;
  625.                 }
  626.                 else
  627.                 {
  628.                         pDisplayDamageType = "Unknown_Projectile_Type";
  629.                 }
  630. #endif
  631.         }
  632.  
  633.         if (ite != end)
  634.         {
  635.                 const CVehicleDamages::SDamageMultiplier& mult = ite->second;
  636.                 damage *= mult.mult;
  637.                 damage *= splash ? mult.splash : 1.f;
  638.  
  639. #if ENABLE_VEHICLE_DEBUG
  640.                 if (DebugDamage())
  641.                 {
  642.                         CryLog("mults for %s: %.2f, splash %.2f", pDisplayDamageType, mult.mult, mult.splash);
  643.                 }
  644. #endif
  645.         }
  646.         else
  647.                 m_pVehicle->ProcessHit(damage, hitInfo, splash);
  648.  
  649.         // major components don't get repaired at the normal rate, the repair amount is determined
  650.         //      by how important the component is (what proportion of the vehicle's health it is)
  651.         if (hitInfo.type == CVehicle::s_repairHitTypeId && damage < 0.0f && m_pSharedParams->isMajorComponent && m_proportionOfVehicleHealth > 0.0f)
  652.         {
  653.                 damage *= m_proportionOfVehicleHealth;
  654.         }
  655.  
  656.         return damage;
  657. }
  658.  
  659. void CVehicleComponent::SetProportionOfVehicleHealth(float proportion)
  660. {
  661.         m_proportionOfVehicleHealth = clamp_tpl(proportion, 0.0f, 1.0f);
  662. }
  663.  
  664. void CVehicleComponent::GetMemoryUsage(ICrySizer* s) const
  665. {
  666.         s->AddObject(this, sizeof(*this));
  667.         s->AddObject(m_damageBehaviors);
  668.         s->AddObject(m_parts);
  669. }
  670.  
  671. //------------------------------------------------------------------------
  672. CVehicleComponent::SSharedParamsConstPtr CVehicleComponent::GetSharedParams(const string& vehicleComponentName, const CVehicleParams& paramsTable) const
  673. {
  674.         ISharedParamsManager* pSharedParamsManager = CCryAction::GetCryAction()->GetISharedParamsManager();
  675.  
  676.         CRY_ASSERT(pSharedParamsManager);
  677.  
  678.         SSharedParamsConstPtr pSharedParams = CastSharedParamsPtr<SSharedParams>(pSharedParamsManager->Get(vehicleComponentName));
  679.  
  680.         if (!pSharedParams)
  681.         {
  682.                 SSharedParams sharedParams;
  683.  
  684.                 sharedParams.name = paramsTable.getAttr("name");
  685.  
  686.                 sharedParams.bounds.Reset();
  687.                 {
  688.                         Vec3 bound;
  689.  
  690.                         if (paramsTable.getAttr("minBound", bound))
  691.                         {
  692.                                 sharedParams.bounds.Add(bound);
  693.                         }
  694.  
  695.                         if (paramsTable.getAttr("maxBound", bound))
  696.                         {
  697.                                 sharedParams.bounds.Add(bound);
  698.                         }
  699.                 }
  700.  
  701.                 if (!paramsTable.getAttr("damageMax", sharedParams.damageMax))
  702.                 {
  703.                         sharedParams.damageMax = 0.0f;
  704.                 }
  705.  
  706.                 if (!paramsTable.getAttr("hullAffection", sharedParams.hullAffection))
  707.                 {
  708.                         sharedParams.hullAffection = 1.0f;
  709.                 }
  710.  
  711.                 sharedParams.isHull = sharedParams.name == "hull" || sharedParams.name == "Hull";
  712.  
  713.                 if (!paramsTable.getAttr("major", sharedParams.isMajorComponent))
  714.                 {
  715.                         sharedParams.isMajorComponent = true;
  716.                 }
  717.  
  718.                 if (!paramsTable.getAttr("isOnlyDamageableByPlayer", sharedParams.isOnlyDamageableByPlayer))
  719.                 {
  720.                         sharedParams.isOnlyDamageableByPlayer = false;
  721.                 }
  722.  
  723.                 if (!paramsTable.getAttr("useBoundsFromParts", sharedParams.useBoundsFromParts))
  724.                 {
  725.                         sharedParams.useBoundsFromParts = false;
  726.                 }
  727.  
  728.                 if (!paramsTable.getAttr("useDamageLevels", sharedParams.useDamageLevels))
  729.                 {
  730.                         sharedParams.useDamageLevels = true;
  731.                 }
  732.  
  733.                 assert(m_pVehicle->GetEntity());
  734.                 CVehicleDamages::ParseDamageMultipliers(sharedParams.damageMultipliersByHitType, sharedParams.damageMultipliersByProjectile, paramsTable, *m_pVehicle->GetEntity());
  735.  
  736.                 pSharedParams = CastSharedParamsPtr<SSharedParams>(pSharedParamsManager->Register(vehicleComponentName, sharedParams));
  737.  
  738.                 CRY_ASSERT(pSharedParams != 0);
  739.         }
  740.  
  741.         return pSharedParams;
  742. }
  743.  
downloadVehicleComponent.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