PageRenderTime 28ms CodeModel.GetById 7ms RepoModel.GetById 0ms app.codeStats 0ms

/Code/GameSDK/GameDll/Effects/GameEffects/ExplosionGameEffect.cpp

https://gitlab.com/blackbird91/CS188_AI_Game
C++ | 724 lines | 518 code | 99 blank | 107 comment | 83 complexity | 9ebf83004ceddf8826713c33add176a2 MD5 | raw file
  1. /*
  2. * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
  3. * its licensors.
  4. *
  5. * For complete copyright and license terms please see the LICENSE at the root of this
  6. * distribution (the "License"). All use of this software is governed by the License,
  7. * or, if provided, by the license below or the license accompanying this file. Do not
  8. * remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
  9. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. *
  11. */
  12. // Original file Copyright Crytek GMBH or its affiliates, used under license.
  13. // Description : Explosion game effect - handles screen filters like radial blur etc
  14. #include "StdAfx.h"
  15. #include "ExplosionGameEffect.h"
  16. #include "IGameRulesSystem.h"
  17. #include "IMovementController.h"
  18. #include "Player.h"
  19. #include "GameCVars.h"
  20. #include "ScreenEffects.h"
  21. #include "GameRules.h"
  22. #include "GameCodeCoverage/GameCodeCoverageTracker.h"
  23. #include "RecordingSystem.h"
  24. #include "Battlechatter.h"
  25. #include "PersistantStats.h"
  26. #include <IForceFeedbackSystem.h>
  27. #include "ActorManager.h"
  28. REGISTER_EFFECT_DEBUG_DATA(CExplosionGameEffect::DebugOnInputEvent,CExplosionGameEffect::DebugDisplay,Explosion);
  29. REGISTER_DATA_CALLBACKS(CExplosionGameEffect::LoadStaticData,CExplosionGameEffect::ReleaseStaticData,CExplosionGameEffect::ReloadStaticData,ExplosionData);
  30. //--------------------------------------------------------------------------------------------------
  31. // Name: SExplosionGameEffectData
  32. // Desc: Data loaded from xml to control game effect
  33. //--------------------------------------------------------------------------------------------------
  34. struct SExplosionGameEffectData
  35. {
  36. SExplosionGameEffectData()
  37. : isInitialised(false)
  38. , fCloakHighlightStrengthModifier(0.0f)
  39. {
  40. }
  41. float fCloakHighlightStrengthModifier;
  42. bool isInitialised;
  43. };
  44. static SExplosionGameEffectData s_explosionGEData;
  45. CDeferredExplosionEffect::~CDeferredExplosionEffect()
  46. {
  47. for (uint32 i = 0; i < m_queuedRays.size(); ++i)
  48. {
  49. g_pGame->GetRayCaster().Cancel(m_queuedRays[i].rayID);
  50. }
  51. m_queuedRays.clear();
  52. }
  53. void CDeferredExplosionEffect::OnRayCastDataReceived( const QueuedRayID& rayID, const RayCastResult& result )
  54. {
  55. const int queuedRayIdx = FindRequestedRay(rayID);
  56. CRY_ASSERT(queuedRayIdx != -1);
  57. if (queuedRayIdx != -1)
  58. {
  59. const SQueuedRayInfo& info = m_queuedRays[queuedRayIdx];
  60. if ((info.effectType == CDeferredExplosionEffect::eDET_RadialBlur) && (result.hitCount == 0))
  61. {
  62. TriggerRadialBlur( info.explosionPos, info.effectMaxDistance, info.distance);
  63. }
  64. m_queuedRays.removeAt(queuedRayIdx);
  65. }
  66. }
  67. void CDeferredExplosionEffect::RequestRayCast( CDeferredExplosionEffect::EDeferredEffectType effectType, const Vec3 &startPos, const Vec3 &dir, float distance, float effectMaxDistance, int objTypes, int flags, IPhysicalEntity **pSkipEnts, int nSkipEnts )
  68. {
  69. FreeOldestRequestIfNeeded();
  70. SQueuedRayInfo requestedRay;
  71. requestedRay.effectType = effectType;
  72. requestedRay.effectMaxDistance = effectMaxDistance;
  73. requestedRay.distance = distance;
  74. requestedRay.explosionPos = startPos;
  75. requestedRay.request = ++m_requestCounter;
  76. requestedRay.rayID = g_pGame->GetRayCaster().Queue(
  77. RayCastRequest::HighPriority,
  78. RayCastRequest(startPos, dir * distance,
  79. objTypes,
  80. flags,
  81. pSkipEnts,
  82. nSkipEnts),
  83. functor(*this, &CDeferredExplosionEffect::OnRayCastDataReceived));
  84. m_queuedRays.push_back(requestedRay);
  85. }
  86. int CDeferredExplosionEffect::FindRequestedRay( const QueuedRayID& rayID ) const
  87. {
  88. const int queuedCount = m_queuedRays.size();
  89. for (int i = 0; i < queuedCount; ++i)
  90. {
  91. if (m_queuedRays[i].rayID == rayID)
  92. return i;
  93. }
  94. return -1;
  95. }
  96. void CDeferredExplosionEffect::FreeOldestRequestIfNeeded()
  97. {
  98. const int queuedCount = m_queuedRays.size();
  99. if (queuedCount == m_queuedRays.max_size())
  100. {
  101. int oldestIdx = 0;
  102. uint32 oldestRequest = 0xFFFFFFFF;
  103. for (int i = 0; i < queuedCount; ++i)
  104. {
  105. if (m_queuedRays[i].request < oldestRequest)
  106. {
  107. oldestIdx = i;
  108. oldestRequest = m_queuedRays[i].request;
  109. }
  110. }
  111. g_pGame->GetRayCaster().Cancel(m_queuedRays[oldestIdx].rayID);
  112. m_queuedRays.removeAt(oldestIdx);
  113. }
  114. }
  115. void CDeferredExplosionEffect::TriggerRadialBlur( const Vec3& radialBlurCenter, float maxBlurDistance, float distance )
  116. {
  117. CRY_ASSERT(maxBlurDistance > 0.0f);
  118. const float maxBlurDistanceInv = fres(maxBlurDistance);
  119. if(CScreenEffects* pScreenFX = g_pGame->GetScreenEffects())
  120. {
  121. const float blurRadius = (-maxBlurDistanceInv * distance) + 1.0f;
  122. pScreenFX->ProcessExplosionEffect(blurRadius, radialBlurCenter);
  123. }
  124. const float distAmp = 1.0f - (distance * maxBlurDistanceInv);
  125. IForceFeedbackSystem* pForceFeedback = g_pGame->GetIGameFramework()->GetIForceFeedbackSystem();
  126. const ForceFeedbackFxId effectId = pForceFeedback->GetEffectIdByName("explosion");
  127. SForceFeedbackRuntimeParams ffParams(distAmp * 3.0f, 0.0f);
  128. pForceFeedback->PlayForceFeedbackEffect(effectId, ffParams);
  129. }
  130. //--------------------------------------------------------------------------------------------------
  131. // Name: CExplosionGameEffect
  132. // Desc: Constructor
  133. //--------------------------------------------------------------------------------------------------
  134. CExplosionGameEffect::CExplosionGameEffect()
  135. {
  136. m_cutSceneActive = false;
  137. }//-------------------------------------------------------------------------------------------------
  138. //--------------------------------------------------------------------------------------------------
  139. // Name: ~CExplosionGameEffect
  140. // Desc: Destructor
  141. //--------------------------------------------------------------------------------------------------
  142. CExplosionGameEffect::~CExplosionGameEffect()
  143. {
  144. }//-------------------------------------------------------------------------------------------------
  145. //--------------------------------------------------------------------------------------------------
  146. // Name: Initialise
  147. // Desc: Initializes game effect
  148. //--------------------------------------------------------------------------------------------------
  149. void CExplosionGameEffect::Initialise(const SGameEffectParams* gameEffectParams)
  150. {
  151. GameSDKCGameEffect::Initialise(gameEffectParams);
  152. }//-------------------------------------------------------------------------------------------------
  153. //--------------------------------------------------------------------------------------------------
  154. // Name: Release
  155. // Desc: Releases game effect
  156. //--------------------------------------------------------------------------------------------------
  157. void CExplosionGameEffect::Release()
  158. {
  159. GameSDKCGameEffect::Release();
  160. }//-------------------------------------------------------------------------------------------------
  161. //--------------------------------------------------------------------------------------------------
  162. // Name: Update
  163. // Desc: Updates game effect
  164. //--------------------------------------------------------------------------------------------------
  165. void CExplosionGameEffect::Update(float frameTime)
  166. {
  167. GameSDKCGameEffect::Update(frameTime);
  168. }//-------------------------------------------------------------------------------------------------
  169. //--------------------------------------------------------------------------------------------------
  170. // Name: Explode
  171. // Desc: Spawns explosion
  172. //--------------------------------------------------------------------------------------------------
  173. void CExplosionGameEffect::Explode(SExplosionContainer &explosionContainer)
  174. {
  175. if(IsFlagSet(GAME_EFFECT_ACTIVE))
  176. {
  177. SpawnParticleEffect(explosionContainer);
  178. SpawnCharacterEffects(explosionContainer);
  179. if(!m_cutSceneActive)
  180. {
  181. SpawnScreenExplosionEffect(explosionContainer);
  182. QueueMaterialEffect(explosionContainer);
  183. }
  184. }
  185. }//-------------------------------------------------------------------------------------------------
  186. //--------------------------------------------------------------------------------------------------
  187. // Name: SpawnParticleEffect
  188. // Desc: Spawns the explosion's particle effect
  189. //--------------------------------------------------------------------------------------------------
  190. void CExplosionGameEffect::SpawnParticleEffect(const SExplosionContainer &explosionContainer)
  191. {
  192. if(gEnv->IsClient())
  193. {
  194. const ExplosionInfo& explosionInfo = explosionContainer.m_explosionInfo;
  195. if(explosionInfo.pParticleEffect)
  196. {
  197. const bool bIndependent = true;
  198. explosionInfo.pParticleEffect->Spawn( bIndependent, IParticleEffect::ParticleLoc(explosionInfo.pos, explosionInfo.dir, explosionInfo.effect_scale) );
  199. }
  200. }
  201. }//-------------------------------------------------------------------------------------------------
  202. //--------------------------------------------------------------------------------------------------
  203. // Name: SpawnScreenExplosionEffect
  204. // Desc: Spawns screen explosion effect
  205. //--------------------------------------------------------------------------------------------------
  206. void CExplosionGameEffect::SpawnScreenExplosionEffect(const SExplosionContainer &explosionContainer)
  207. {
  208. // Disclaimer: this code was originally from GameRulesClientServer::ProcessClientExplosionScreenFX()
  209. const ExplosionInfo& explosionInfo = explosionContainer.m_explosionInfo;
  210. if(explosionInfo.pressure < 1.0f)
  211. return;
  212. IActor *pClientActor = g_pGame->GetIGameFramework()->GetClientActor();
  213. if(pClientActor != NULL && !pClientActor->IsDead())
  214. {
  215. CPlayer* pPlayer = static_cast<CPlayer*>(pClientActor);
  216. bool hasFlashBangEffect = explosionInfo.blindAmount > 0.0f;
  217. // Flashbang friends and self?...
  218. if(hasFlashBangEffect)
  219. {
  220. bool flashBangSelf = true;
  221. bool flashBangFriends = false;
  222. #ifndef _RELEASE
  223. flashBangSelf = g_pGameCVars->g_flashBangSelf != 0;
  224. flashBangFriends = g_pGameCVars->g_flashBangFriends != 0;
  225. #endif
  226. bool ownFlashBang = pPlayer->GetEntityId() == explosionInfo.shooterId;
  227. if((!flashBangSelf && ownFlashBang) || // FlashBang self?
  228. ((g_pGame->GetGameRules()->GetFriendlyFireRatio()<=0.0f) && (!flashBangFriends) && (!ownFlashBang) && pPlayer->IsFriendlyEntity(explosionInfo.shooterId))) // FlashBang friends?
  229. {
  230. return;
  231. }
  232. }
  233. // Distance
  234. float dist = (pClientActor->GetEntity()->GetWorldPos() - explosionInfo.pos).len();
  235. // Is the explosion in Player's FOV (let's suppose the FOV a bit higher, like 80)
  236. SMovementState state;
  237. if(IMovementController *pMV = pClientActor->GetMovementController())
  238. {
  239. pMV->GetMovementState(state);
  240. }
  241. Vec3 eyeToExplosion = explosionInfo.pos - state.eyePosition;
  242. Vec3 eyeDir = pClientActor->GetLinkedVehicle() ? pPlayer->GetVehicleViewDir() : state.eyeDirection;
  243. eyeToExplosion.Normalize();
  244. float eyeDirectionDP = eyeDir.Dot(eyeToExplosion);
  245. bool inFOV = (eyeDirectionDP > 0.68f);
  246. // All explosions have radial blur (default 30m radius)
  247. const float maxBlurDistance = (explosionInfo.maxblurdistance >0.0f) ? explosionInfo.maxblurdistance : 30.0f;
  248. if((maxBlurDistance > 0.0f) && (g_pGameCVars->g_radialBlur > 0.0f) && (explosionInfo.radius > 0.5f))
  249. {
  250. if (inFOV && (dist < maxBlurDistance))
  251. {
  252. const int intersectionObjTypes = ent_static | ent_terrain;
  253. const unsigned int intersectionFlags = rwi_stop_at_pierceable|rwi_colltype_any;
  254. m_deferredScreenEffects.RequestRayCast(CDeferredExplosionEffect::eDET_RadialBlur,
  255. explosionInfo.pos, -eyeToExplosion, dist, maxBlurDistance, intersectionObjTypes, intersectionFlags, NULL, 0);
  256. }
  257. }
  258. // Flashbang effect
  259. if(hasFlashBangEffect && ((dist < (explosionInfo.radius*g_pGameCVars->g_flashBangNotInFOVRadiusFraction))
  260. || (inFOV && (dist < explosionInfo.radius))))
  261. {
  262. ray_hit hit;
  263. const int intersectionObjTypes = ent_static | ent_terrain;
  264. const unsigned int intersectionFlags = rwi_stop_at_pierceable|rwi_colltype_any;
  265. const int intersectionMaxHits = 1;
  266. int collision = gEnv->pPhysicalWorld->RayWorldIntersection( explosionInfo.pos,
  267. -eyeToExplosion*dist,
  268. intersectionObjTypes,
  269. intersectionFlags,
  270. &hit,
  271. intersectionMaxHits);
  272. // If there was no obstacle between flashbang grenade and player
  273. if(!collision)
  274. {
  275. bool enabled = true;
  276. if(enabled)
  277. {
  278. CCCPOINT (FlashBang_Explode_BlindLocalPlayer);
  279. float timeScale = max(0.0f, 1 - (dist/explosionInfo.radius));
  280. float lookingAt = max(g_pGameCVars->g_flashBangMinFOVMultiplier, (eyeDirectionDP + 1)*0.5f);
  281. float time = explosionInfo.flashbangScale * timeScale *lookingAt; // time is determined by distance to explosion
  282. CRY_ASSERT_MESSAGE(pClientActor->IsPlayer(),"Effect shouldn't be spawned if not a player");
  283. SPlayerStats* pStats = static_cast<SPlayerStats*>(pPlayer->GetActorStats());
  284. NET_BATTLECHATTER(BC_Blinded, pPlayer);
  285. if(pClientActor->GetEntityId() == explosionInfo.shooterId)
  286. {
  287. g_pGame->GetPersistantStats()->IncrementClientStats(EIPS_BlindSelf);
  288. }
  289. else
  290. {
  291. g_pGame->GetGameRules()->SuccessfulFlashBang(explosionInfo, time);
  292. }
  293. pPlayer->StartFlashbangEffects(time, explosionInfo.shooterId);
  294. gEnv->p3DEngine->SetPostEffectParam("Flashbang_Time", time);
  295. gEnv->p3DEngine->SetPostEffectParam("FlashBang_BlindAmount", explosionInfo.blindAmount);
  296. gEnv->p3DEngine->SetPostEffectParam("Flashbang_DifractionAmount", time);
  297. gEnv->p3DEngine->SetPostEffectParam("Flashbang_Active", 1.0f);
  298. CRecordingSystem *pRecordingSystem = g_pGame->GetRecordingSystem();
  299. if (pRecordingSystem)
  300. {
  301. pRecordingSystem->OnPlayerFlashed(time, explosionInfo.blindAmount);
  302. }
  303. }
  304. }
  305. else
  306. {
  307. CCCPOINT (FlashBang_Explode_NearbyButBlockedByGeometry);
  308. }
  309. }
  310. else if(inFOV && (dist < explosionInfo.radius))
  311. {
  312. if(explosionInfo.damage>10.0f || explosionInfo.pressure>100.0f)
  313. {
  314. // Add some angular impulse to the client actor depending on distance, direction...
  315. float dt = (1.0f - dist/explosionInfo.radius);
  316. dt = dt * dt;
  317. float angleZ = gf_PI*0.15f*dt;
  318. float angleX = gf_PI*0.15f*dt;
  319. if (pClientActor)
  320. {
  321. static_cast<CActor*>(pClientActor)->AddAngularImpulse(Ang3(cry_random(-angleX*0.5f,angleX),0.0f,cry_random(-angleZ,angleZ)),0.0f,dt*2.0f);
  322. }
  323. }
  324. }
  325. }
  326. }//-------------------------------------------------------------------------------------------------
  327. //--------------------------------------------------------------------------------------------------
  328. // Name: QueueMaterialEffect
  329. // Desc: Queues material effect and sets off a deferred linetest for later processing
  330. //--------------------------------------------------------------------------------------------------
  331. void CExplosionGameEffect::QueueMaterialEffect(SExplosionContainer &explosionContainer)
  332. {
  333. ExplosionInfo explosionInfo = explosionContainer.m_explosionInfo;
  334. // If an effect was already specified, don't use MFX
  335. if(explosionInfo.pParticleEffect)
  336. return;
  337. const int intersectionObjTypes = ent_all|ent_water;
  338. const unsigned int intersectionFlags = rwi_stop_at_pierceable|rwi_colltype_any;
  339. CRY_ASSERT(explosionContainer.m_mfxInfo.m_rayId == 0);
  340. if(explosionInfo.impact)
  341. {
  342. Vec3 explosionDir = explosionInfo.impact_velocity.normalized();
  343. explosionContainer.m_mfxInfo.m_rayId = g_pGame->GetRayCaster().Queue(
  344. RayCastRequest::HighPriority,
  345. RayCastRequest(explosionInfo.pos-explosionDir*0.1f, explosionDir,
  346. intersectionObjTypes,
  347. intersectionFlags),
  348. functor(explosionContainer.m_mfxInfo, &SDeferredMfxExplosion::OnRayCastDataReceived));
  349. }
  350. else
  351. {
  352. const Vec3 explosionDir(0.0f, 0.0f, -g_pGameCVars->g_explosion_materialFX_raycastLength);
  353. explosionContainer.m_mfxInfo.m_rayId = g_pGame->GetRayCaster().Queue(
  354. RayCastRequest::HighPriority,
  355. RayCastRequest(explosionInfo.pos, explosionDir,
  356. intersectionObjTypes,
  357. intersectionFlags),
  358. functor(explosionContainer.m_mfxInfo, &SDeferredMfxExplosion::OnRayCastDataReceived));
  359. }
  360. explosionContainer.m_mfxInfo.m_state = eDeferredMfxExplosionState_Dispatched;
  361. }
  362. //--------------------------------------------------------------------------------------------------
  363. // Name: SpawnMaterialEffect
  364. // Desc: Spawns material effect
  365. //--------------------------------------------------------------------------------------------------
  366. void CExplosionGameEffect::SpawnMaterialEffect(const SExplosionContainer &explosionContainer)
  367. {
  368. // Disclaimer: this code was originally from GameRulesClientServer::ProcessExplosionMaterialFX()
  369. const ExplosionInfo& explosionInfo = explosionContainer.m_explosionInfo;
  370. // impact stuff here
  371. SMFXRunTimeEffectParams params;
  372. //params.soundSemantic = eSoundSemantic_Explosion;
  373. params.pos = params.decalPos = explosionInfo.pos;
  374. params.trg = 0;
  375. params.trgRenderNode = 0;
  376. params.trgSurfaceId = 0;
  377. if(explosionInfo.impact && (explosionInfo.impact_velocity.len2() > 0.000001f))
  378. {
  379. params.dir[0] = explosionInfo.impact_velocity.normalized();
  380. params.normal = explosionInfo.impact_normal;
  381. }
  382. else
  383. {
  384. const Vec3 gravityDir = Vec3(0.0f, 0.0f, -1.0f);
  385. params.dir[0] = gravityDir;
  386. params.normal = -gravityDir;
  387. }
  388. const SDeferredMfxExplosion& mfxInfo = explosionContainer.m_mfxInfo;
  389. if(mfxInfo.m_state == eDeferredMfxExplosionState_ResultImpact)
  390. {
  391. params.trgSurfaceId = mfxInfo.m_mfxTargetSurfaceId;
  392. if (mfxInfo.m_pMfxTargetPhysEnt.get())
  393. {
  394. if (mfxInfo.m_pMfxTargetPhysEnt->GetiForeignData() == PHYS_FOREIGN_ID_STATIC)
  395. {
  396. params.trgRenderNode = (IRenderNode*)mfxInfo.m_pMfxTargetPhysEnt->GetForeignData(PHYS_FOREIGN_ID_STATIC);
  397. }
  398. }
  399. }
  400. // Create query name
  401. stack_string effectClass = explosionInfo.effect_class;
  402. if(effectClass.empty())
  403. effectClass = "generic";
  404. const float waterLevel = gEnv->p3DEngine->GetWaterLevel(&params.pos);
  405. stack_string query = effectClass + "_explode";
  406. if(waterLevel > explosionInfo.pos.z)
  407. query = query + "_underwater";
  408. // Get material effect id
  409. IMaterialEffects* pMaterialEffects = gEnv->pGame->GetIGameFramework()->GetIMaterialEffects();
  410. TMFXEffectId effectId = pMaterialEffects->GetEffectId(query.c_str(), params.trgSurfaceId);
  411. if(effectId == InvalidEffectId)
  412. {
  413. // Get default surface id
  414. effectId = pMaterialEffects->GetEffectId(query.c_str(), pMaterialEffects->GetDefaultSurfaceIndex());
  415. }
  416. // Execute material effect
  417. if(effectId != InvalidEffectId)
  418. {
  419. pMaterialEffects->ExecuteEffect(effectId, params);
  420. bool hasFlashBangEffect = explosionInfo.blindAmount > 0.0f;
  421. if(hasFlashBangEffect)
  422. {
  423. // Calc screen pos
  424. Vec3 screenspace;
  425. gEnv->pRenderer->ProjectToScreen(explosionInfo.pos.x, explosionInfo.pos.y, explosionInfo.pos.z, &screenspace.x, &screenspace.y, &screenspace.z);
  426. // Pass screen pos to flow graph node
  427. SMFXCustomParamValue paramPosX;
  428. paramPosX.fValue = screenspace.x*0.01f;
  429. pMaterialEffects->SetCustomParameter(effectId,"Intensity",paramPosX); // Use intensity param to pass x pos
  430. SMFXCustomParamValue paramPosY;
  431. paramPosY.fValue = screenspace.y*0.01f;
  432. pMaterialEffects->SetCustomParameter(effectId,"BlendOutTime",paramPosY); // Use blendOutTime param to pass y pos
  433. }
  434. }
  435. }//-------------------------------------------------------------------------------------------------
  436. //--------------------------------------------------------------------------------------------------
  437. // Name: SpawnCharacterEffects
  438. // Desc: Spawns character effects
  439. //--------------------------------------------------------------------------------------------------
  440. void CExplosionGameEffect::SpawnCharacterEffects(const SExplosionContainer &explosionContainer)
  441. {
  442. }//-------------------------------------------------------------------------------------------------
  443. #if DEBUG_GAME_FX_SYSTEM
  444. //--------------------------------------------------------------------------------------------------
  445. // Name: DebugOnInputEvent
  446. // Desc: Called when input events happen in debug builds
  447. //--------------------------------------------------------------------------------------------------
  448. void CExplosionGameEffect::DebugOnInputEvent(int keyId)
  449. {
  450. // Initialise static version of effect
  451. static CExplosionGameEffect explosionGameEffect;
  452. if(!explosionGameEffect.IsFlagSet(GAME_EFFECT_INITIALISED))
  453. {
  454. explosionGameEffect.Initialise();
  455. explosionGameEffect.SetFlag(GAME_EFFECT_DEBUG_EFFECT,true);
  456. explosionGameEffect.SetFlag(GAME_EFFECT_AUTO_RELEASE,true);
  457. explosionGameEffect.SetActive(true);
  458. }
  459. // Get player pos
  460. Vec3 playerDir(0.0f,0.0f,0.0f);
  461. Vec3 playerPos(0.0f,0.0f,0.0f);
  462. EntityId localClientId = gEnv->pGame->GetIGameFramework()->GetClientActorId();
  463. if (localClientId != 0 && g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(localClientId) != 0)
  464. {
  465. IEntity* playerEntity = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(localClientId)->GetEntity();
  466. playerDir = playerEntity->GetForwardDir();
  467. playerPos = playerEntity->GetPos();
  468. }
  469. // Distance from player controlled by keyboard
  470. static float distFromPlayer = 0.0f;
  471. static float distStep = 1.0f;
  472. switch(keyId)
  473. {
  474. case eKI_NP_Multiply:
  475. {
  476. distFromPlayer += distStep;
  477. break;
  478. }
  479. case eKI_NP_Divide:
  480. {
  481. distFromPlayer -= distStep;
  482. break;
  483. }
  484. case eKI_NP_0:
  485. {
  486. distFromPlayer = 0.0f;
  487. break;
  488. }
  489. case eKI_NP_1:
  490. {
  491. // Frag
  492. SExplosionContainer explosionContainer;
  493. ExplosionInfo& explosionInfo = explosionContainer.m_explosionInfo;
  494. explosionInfo.pParticleEffect = gEnv->pParticleManager->FindEffect("Crysis2_weapon_explosives.frag.concrete");
  495. explosionInfo.pos = playerPos + (playerDir * distFromPlayer);
  496. explosionInfo.dir.Set(0.0f,-1.0f,0.0f);
  497. explosionInfo.effect_scale = 1.0f;
  498. explosionInfo.pressure = 1000.0f;
  499. explosionInfo.maxblurdistance = 10.0;
  500. explosionInfo.radius = 15.0;
  501. explosionInfo.blindAmount = 0.0f;
  502. explosionInfo.flashbangScale = 8.0f;
  503. explosionInfo.damage = 5.0f;
  504. explosionInfo.hole_size = 0.0f;
  505. explosionGameEffect.Explode(explosionContainer);
  506. break;
  507. }
  508. case eKI_NP_2:
  509. {
  510. // Flashbang
  511. SExplosionContainer explosionContainer;
  512. ExplosionInfo& explosionInfo = explosionContainer.m_explosionInfo;
  513. explosionInfo.pParticleEffect = gEnv->pParticleManager->FindEffect("Crysis2_weapon_explosives.grenades.flash_explosion");
  514. explosionInfo.pos = playerPos + (playerDir * distFromPlayer);
  515. explosionInfo.dir.Set(0.0f,-1.0f,0.0f);
  516. explosionInfo.effect_scale = 1.0f;
  517. explosionInfo.pressure = 1000.0f;
  518. explosionInfo.maxblurdistance = 10.0;
  519. explosionInfo.radius = 15.0;
  520. explosionInfo.blindAmount = 0.66f;
  521. explosionInfo.flashbangScale = 8.0f;
  522. explosionInfo.damage = 5.0f;
  523. explosionInfo.hole_size = 0.0f;
  524. explosionGameEffect.Explode(explosionContainer);
  525. break;
  526. }
  527. case eKI_NP_3:
  528. {
  529. // L-Tag
  530. SExplosionContainer explosionContainer;
  531. ExplosionInfo& explosionInfo = explosionContainer.m_explosionInfo;
  532. explosionInfo.pParticleEffect = gEnv->pParticleManager->FindEffect("Crysis2_weapon_fx.l-tag.rico_explosion");
  533. explosionInfo.pos = playerPos + (playerDir * distFromPlayer);
  534. explosionInfo.dir.Set(0.0f,-1.0f,0.0f);
  535. explosionInfo.effect_scale = 1.0f;
  536. explosionInfo.pressure = 1000.0f;
  537. explosionInfo.maxblurdistance = 10.0;
  538. explosionInfo.radius = 15.0;
  539. explosionInfo.blindAmount = 0.0f;
  540. explosionInfo.flashbangScale = 8.0f;
  541. explosionInfo.damage = 5.0f;
  542. explosionInfo.hole_size = 0.0f;
  543. explosionGameEffect.Explode(explosionContainer);
  544. break;
  545. }
  546. case GAME_FX_INPUT_ReleaseDebugEffect:
  547. {
  548. explosionGameEffect.Release();
  549. break;
  550. }
  551. }
  552. }//-------------------------------------------------------------------------------------------------
  553. //--------------------------------------------------------------------------------------------------
  554. // Name: DebugDisplay
  555. // Desc: Display when this effect is selected to debug through the game effects system
  556. //--------------------------------------------------------------------------------------------------
  557. void CExplosionGameEffect::DebugDisplay(const Vec2& textStartPos,float textSize,float textYStep)
  558. {
  559. ColorF textCol(1.0f,1.0f,0.0f,1.0f);
  560. Vec2 currentTextPos = textStartPos;
  561. gEnv->pRenderer->Draw2dLabel(currentTextPos.x,currentTextPos.y,textSize,&textCol.r,false,"Reset distance: NumPad 0");
  562. currentTextPos.y += textYStep;
  563. gEnv->pRenderer->Draw2dLabel(currentTextPos.x,currentTextPos.y,textSize,&textCol.r,false,"Add distance: NumPad *");
  564. currentTextPos.y += textYStep;
  565. gEnv->pRenderer->Draw2dLabel(currentTextPos.x,currentTextPos.y,textSize,&textCol.r,false,"Subtract distance: NumPad /");
  566. currentTextPos.y += textYStep;
  567. gEnv->pRenderer->Draw2dLabel(currentTextPos.x,currentTextPos.y,textSize,&textCol.r,false,"Frag: NumPad 1");
  568. currentTextPos.y += textYStep;
  569. gEnv->pRenderer->Draw2dLabel(currentTextPos.x,currentTextPos.y,textSize,&textCol.r,false,"Flashbang: NumPad 2");
  570. currentTextPos.y += textYStep;
  571. gEnv->pRenderer->Draw2dLabel(currentTextPos.x,currentTextPos.y,textSize,&textCol.r,false,"L-tag: NumPad 3");
  572. }//-------------------------------------------------------------------------------------------------
  573. #endif
  574. //--------------------------------------------------------------------------------------------------
  575. // Name: LoadStaticData
  576. // Desc: Loads static data for effect
  577. //--------------------------------------------------------------------------------------------------
  578. void CExplosionGameEffect::LoadStaticData(IItemParamsNode* pRootNode)
  579. {
  580. const IItemParamsNode* pParamNode = pRootNode->GetChild("Explosion");
  581. Vec3 tempData;
  582. if(pParamNode)
  583. {
  584. const IItemParamsNode* pActualParamsNode = pParamNode->GetChild("params");
  585. if(pActualParamsNode)
  586. {
  587. pActualParamsNode->GetAttribute("CloakHighlightStrengthModifier",s_explosionGEData.fCloakHighlightStrengthModifier);
  588. }
  589. s_explosionGEData.isInitialised = true;
  590. }
  591. }
  592. //--------------------------------------------------------------------------------------------------
  593. // Name: ReloadStaticData
  594. // Desc: Reloads static data
  595. //--------------------------------------------------------------------------------------------------
  596. void CExplosionGameEffect::ReloadStaticData(IItemParamsNode* pRootNode)
  597. {
  598. ReleaseStaticData();
  599. LoadStaticData(pRootNode);
  600. #if DEBUG_GAME_FX_SYSTEM
  601. // Data has been reloaded, so re-initialse debug effect with new data
  602. CExplosionGameEffect* pDebugEffect = (CExplosionGameEffect*)GAME_FX_SYSTEM.GetDebugEffect("Explosion");
  603. if(pDebugEffect && pDebugEffect->IsFlagSet(GAME_EFFECT_REGISTERED))
  604. {
  605. pDebugEffect->Initialise();
  606. // Re-activate effect if currently active, so it will register correctly
  607. if(pDebugEffect->IsFlagSet(GAME_EFFECT_ACTIVE))
  608. {
  609. pDebugEffect->SetActive(false);
  610. pDebugEffect->SetActive(true);
  611. }
  612. }
  613. #endif
  614. }
  615. //--------------------------------------------------------------------------------------------------
  616. // Name: ReleaseStaticData
  617. // Desc: Releases static data
  618. //--------------------------------------------------------------------------------------------------
  619. void CExplosionGameEffect::ReleaseStaticData()
  620. {
  621. if(s_explosionGEData.isInitialised)
  622. {
  623. s_explosionGEData.isInitialised = false;
  624. }
  625. }