Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

565 lines
18 KiB

  1. //========= Copyright � 1996-2007, Valve Corporation, All rights reserved. ====
  2. //
  3. // An entity that allows level designer control over the fog parameters.
  4. //
  5. //=============================================================================
  6. #include "cbase.h"
  7. #include "fogcontroller.h"
  8. #include "entityinput.h"
  9. #include "entityoutput.h"
  10. #include "eventqueue.h"
  11. #include "player.h"
  12. #include "world.h"
  13. #include "ndebugoverlay.h"
  14. #include "triggers.h"
  15. // memdbgon must be the last include file in a .cpp file!!!
  16. #include "tier0/memdbgon.h"
  17. CFogSystem s_FogSystem( "FogSystem" );
  18. //-----------------------------------------------------------------------------
  19. // Purpose:
  20. //-----------------------------------------------------------------------------
  21. CFogSystem *FogSystem( void )
  22. {
  23. return &s_FogSystem;
  24. }
  25. LINK_ENTITY_TO_CLASS( env_fog_controller, CFogController );
  26. BEGIN_DATADESC( CFogController )
  27. DEFINE_INPUTFUNC( FIELD_FLOAT, "SetStartDist", InputSetStartDist ),
  28. DEFINE_INPUTFUNC( FIELD_FLOAT, "SetEndDist", InputSetEndDist ),
  29. DEFINE_INPUTFUNC( FIELD_FLOAT, "SetMaxDensity", InputSetMaxDensity ),
  30. DEFINE_INPUTFUNC( FIELD_VOID, "TurnOn", InputTurnOn ),
  31. DEFINE_INPUTFUNC( FIELD_VOID, "TurnOff", InputTurnOff ),
  32. DEFINE_INPUTFUNC( FIELD_COLOR32, "SetColor", InputSetColor ),
  33. DEFINE_INPUTFUNC( FIELD_COLOR32, "SetColorSecondary", InputSetColorSecondary ),
  34. DEFINE_INPUTFUNC( FIELD_INTEGER, "SetFarZ", InputSetFarZ ),
  35. DEFINE_INPUTFUNC( FIELD_STRING, "SetAngles", InputSetAngles ),
  36. DEFINE_INPUTFUNC( FIELD_STRING, "SetZoomFogScale", InputSetZoomFogScale ),
  37. DEFINE_INPUTFUNC( FIELD_COLOR32, "SetColorLerpTo", InputSetColorLerpTo ),
  38. DEFINE_INPUTFUNC( FIELD_COLOR32, "SetColorSecondaryLerpTo", InputSetColorSecondaryLerpTo ),
  39. DEFINE_INPUTFUNC( FIELD_FLOAT, "SetStartDistLerpTo", InputSetStartDistLerpTo ),
  40. DEFINE_INPUTFUNC( FIELD_FLOAT, "SetEndDistLerpTo", InputSetEndDistLerpTo ),
  41. DEFINE_INPUTFUNC( FIELD_FLOAT, "SetMaxDensityLerpTo", InputSetMaxDensityLerpTo ),
  42. DEFINE_INPUTFUNC( FIELD_VOID, "StartFogTransition", InputStartFogTransition ),
  43. // Quiet classcheck
  44. //DEFINE_EMBEDDED( m_fog ),
  45. DEFINE_KEYFIELD( m_bUseAngles, FIELD_BOOLEAN, "use_angles" ),
  46. DEFINE_KEYFIELD( m_fog.colorPrimary, FIELD_COLOR32, "fogcolor" ),
  47. DEFINE_KEYFIELD( m_fog.colorSecondary, FIELD_COLOR32, "fogcolor2" ),
  48. DEFINE_KEYFIELD( m_fog.dirPrimary, FIELD_VECTOR, "fogdir" ),
  49. DEFINE_KEYFIELD( m_fog.enable, FIELD_BOOLEAN, "fogenable" ),
  50. DEFINE_KEYFIELD( m_fog.blend, FIELD_BOOLEAN, "fogblend" ),
  51. DEFINE_KEYFIELD( m_fog.start, FIELD_FLOAT, "fogstart" ),
  52. DEFINE_KEYFIELD( m_fog.end, FIELD_FLOAT, "fogend" ),
  53. DEFINE_KEYFIELD( m_fog.maxdensity, FIELD_FLOAT, "fogmaxdensity" ),
  54. DEFINE_KEYFIELD( m_fog.farz, FIELD_FLOAT, "farz" ),
  55. DEFINE_KEYFIELD( m_fog.duration, FIELD_FLOAT, "foglerptime" ),
  56. DEFINE_KEYFIELD( m_fog.HDRColorScale, FIELD_FLOAT, "HDRColorScale" ),
  57. DEFINE_KEYFIELD( m_fog.ZoomFogScale, FIELD_FLOAT, "ZoomFogScale" ),
  58. DEFINE_THINKFUNC( SetLerpValues ),
  59. DEFINE_FIELD( m_iChangedVariables, FIELD_INTEGER ),
  60. DEFINE_FIELD( m_fog.lerptime, FIELD_TIME ),
  61. DEFINE_FIELD( m_fog.colorPrimaryLerpTo, FIELD_COLOR32 ),
  62. DEFINE_FIELD( m_fog.colorSecondaryLerpTo, FIELD_COLOR32 ),
  63. DEFINE_FIELD( m_fog.startLerpTo, FIELD_FLOAT ),
  64. DEFINE_FIELD( m_fog.endLerpTo, FIELD_FLOAT ),
  65. DEFINE_FIELD( m_fog.maxdensityLerpTo, FIELD_FLOAT ),
  66. END_DATADESC()
  67. IMPLEMENT_SERVERCLASS_ST_NOBASE( CFogController, DT_FogController )
  68. // fog data
  69. SendPropInt( SENDINFO_STRUCTELEM( fogparams_t, m_fog, enable ), 1, SPROP_UNSIGNED ),
  70. SendPropInt( SENDINFO_STRUCTELEM( fogparams_t, m_fog, blend ), 1, SPROP_UNSIGNED ),
  71. SendPropVector( SENDINFO_STRUCTELEM(fogparams_t, m_fog, dirPrimary), -1, SPROP_COORD),
  72. SendPropInt( SENDINFO_STRUCTELEM( fogparams_t, m_fog, colorPrimary ), 32, SPROP_UNSIGNED, SendProxy_Color32ToInt32 ),
  73. SendPropInt( SENDINFO_STRUCTELEM( fogparams_t, m_fog, colorSecondary ), 32, SPROP_UNSIGNED, SendProxy_Color32ToInt32 ),
  74. SendPropFloat( SENDINFO_STRUCTELEM( fogparams_t, m_fog, start ), 0, SPROP_NOSCALE ),
  75. SendPropFloat( SENDINFO_STRUCTELEM( fogparams_t, m_fog, end ), 0, SPROP_NOSCALE ),
  76. SendPropFloat( SENDINFO_STRUCTELEM( fogparams_t, m_fog, maxdensity ), 0, SPROP_NOSCALE ),
  77. SendPropFloat( SENDINFO_STRUCTELEM( fogparams_t, m_fog, farz ), 0, SPROP_NOSCALE ),
  78. SendPropInt( SENDINFO_STRUCTELEM( fogparams_t, m_fog, colorPrimaryLerpTo ), 32, SPROP_UNSIGNED, SendProxy_Color32ToInt32 ),
  79. SendPropInt( SENDINFO_STRUCTELEM( fogparams_t, m_fog, colorSecondaryLerpTo ), 32, SPROP_UNSIGNED, SendProxy_Color32ToInt32 ),
  80. SendPropFloat( SENDINFO_STRUCTELEM( fogparams_t, m_fog, startLerpTo ), 0, SPROP_NOSCALE ),
  81. SendPropFloat( SENDINFO_STRUCTELEM( fogparams_t, m_fog, endLerpTo ), 0, SPROP_NOSCALE ),
  82. SendPropFloat( SENDINFO_STRUCTELEM( fogparams_t, m_fog, maxdensityLerpTo ), 0, SPROP_NOSCALE ),
  83. SendPropFloat( SENDINFO_STRUCTELEM( fogparams_t, m_fog, lerptime ), 0, SPROP_NOSCALE ),
  84. SendPropFloat( SENDINFO_STRUCTELEM( fogparams_t, m_fog, duration ), 0, SPROP_NOSCALE ),
  85. SendPropFloat( SENDINFO_STRUCTELEM( fogparams_t, m_fog, HDRColorScale ), 0, SPROP_NOSCALE ),
  86. SendPropFloat( SENDINFO_STRUCTELEM( fogparams_t, m_fog, ZoomFogScale ), 0, SPROP_NOSCALE ),
  87. END_SEND_TABLE()
  88. CFogController::CFogController()
  89. {
  90. // Make sure that old maps without fog fields don't get wacked out fog values.
  91. m_fog.enable = false;
  92. m_fog.maxdensity = 1.0f;
  93. m_fog.HDRColorScale = 1.0f;
  94. }
  95. CFogController::~CFogController()
  96. {
  97. }
  98. void CFogController::Spawn( void )
  99. {
  100. BaseClass::Spawn();
  101. m_fog.colorPrimaryLerpTo = m_fog.colorPrimary;
  102. m_fog.colorSecondaryLerpTo = m_fog.colorSecondary;
  103. }
  104. //-----------------------------------------------------------------------------
  105. // Activate!
  106. //-----------------------------------------------------------------------------
  107. void CFogController::Activate( )
  108. {
  109. BaseClass::Activate();
  110. if ( m_bUseAngles )
  111. {
  112. AngleVectors( GetAbsAngles(), &m_fog.dirPrimary.GetForModify() );
  113. m_fog.dirPrimary.GetForModify() *= -1.0f;
  114. }
  115. }
  116. //-----------------------------------------------------------------------------
  117. // Purpose:
  118. //-----------------------------------------------------------------------------
  119. int CFogController::UpdateTransmitState()
  120. {
  121. return SetTransmitState( FL_EDICT_ALWAYS );
  122. }
  123. //------------------------------------------------------------------------------
  124. // Purpose: Input handler for setting the fog start distance.
  125. //------------------------------------------------------------------------------
  126. void CFogController::InputSetStartDist(inputdata_t &inputdata)
  127. {
  128. // Get the world entity.
  129. m_fog.start = inputdata.value.Float();
  130. }
  131. //------------------------------------------------------------------------------
  132. // Purpose: Input handler for setting the fog end distance.
  133. //------------------------------------------------------------------------------
  134. void CFogController::InputSetEndDist(inputdata_t &inputdata)
  135. {
  136. // Get the world entity.
  137. m_fog.end = inputdata.value.Float();
  138. }
  139. //------------------------------------------------------------------------------
  140. // Input handler for setting the maximum density of the fog. This lets us bring
  141. // the start distance in without the scene fogging too much.
  142. //------------------------------------------------------------------------------
  143. void CFogController::InputSetMaxDensity( inputdata_t &inputdata )
  144. {
  145. m_fog.maxdensity = inputdata.value.Float();
  146. }
  147. //------------------------------------------------------------------------------
  148. // Purpose: Input handler for turning on the fog.
  149. //------------------------------------------------------------------------------
  150. void CFogController::InputTurnOn(inputdata_t &inputdata)
  151. {
  152. // Get the world entity.
  153. m_fog.enable = true;
  154. }
  155. //------------------------------------------------------------------------------
  156. // Purpose: Input handler for turning off the fog.
  157. //------------------------------------------------------------------------------
  158. void CFogController::InputTurnOff(inputdata_t &inputdata)
  159. {
  160. // Get the world entity.
  161. m_fog.enable = false;
  162. }
  163. //------------------------------------------------------------------------------
  164. // Purpose: Input handler for setting the primary fog color.
  165. //------------------------------------------------------------------------------
  166. void CFogController::InputSetColor(inputdata_t &inputdata)
  167. {
  168. // Get the world entity.
  169. m_fog.colorPrimary = inputdata.value.Color32();
  170. }
  171. //------------------------------------------------------------------------------
  172. // Purpose: Input handler for setting the secondary fog color.
  173. //------------------------------------------------------------------------------
  174. void CFogController::InputSetColorSecondary(inputdata_t &inputdata)
  175. {
  176. // Get the world entity.
  177. m_fog.colorSecondary = inputdata.value.Color32();
  178. }
  179. void CFogController::InputSetFarZ(inputdata_t &inputdata)
  180. {
  181. m_fog.farz = inputdata.value.Int();
  182. }
  183. void CFogController::InputSetZoomFogScale( inputdata_t &inputdata )
  184. {
  185. m_fog.ZoomFogScale = inputdata.value.Float();
  186. }
  187. //------------------------------------------------------------------------------
  188. // Purpose: Sets the angles to use for the secondary fog direction.
  189. //------------------------------------------------------------------------------
  190. void CFogController::InputSetAngles( inputdata_t &inputdata )
  191. {
  192. const char *pAngles = inputdata.value.String();
  193. QAngle angles;
  194. UTIL_StringToVector( angles.Base(), pAngles );
  195. Vector vTemp;
  196. AngleVectors( angles, &vTemp );
  197. SetAbsAngles( angles );
  198. AngleVectors( GetAbsAngles(), &m_fog.dirPrimary.GetForModify() );
  199. m_fog.dirPrimary.GetForModify() *= -1.0f;
  200. }
  201. //-----------------------------------------------------------------------------
  202. // Purpose: Draw any debug text overlays
  203. // Output : Current text offset from the top
  204. //-----------------------------------------------------------------------------
  205. int CFogController::DrawDebugTextOverlays(void)
  206. {
  207. int text_offset = BaseClass::DrawDebugTextOverlays();
  208. if (m_debugOverlays & OVERLAY_TEXT_BIT)
  209. {
  210. char tempstr[512];
  211. Q_snprintf(tempstr,sizeof(tempstr),"State: %s",(m_fog.enable)?"On":"Off");
  212. EntityText(text_offset,tempstr,0);
  213. text_offset++;
  214. Q_snprintf(tempstr,sizeof(tempstr),"Start: %3.0f",m_fog.start.Get() );
  215. EntityText(text_offset,tempstr,0);
  216. text_offset++;
  217. Q_snprintf(tempstr,sizeof(tempstr),"End : %3.0f",m_fog.end.Get() );
  218. EntityText(text_offset,tempstr,0);
  219. text_offset++;
  220. color32 color = m_fog.colorPrimary;
  221. Q_snprintf(tempstr,sizeof(tempstr),"1) Red : %i",color.r);
  222. EntityText(text_offset,tempstr,0);
  223. text_offset++;
  224. Q_snprintf(tempstr,sizeof(tempstr),"1) Green: %i",color.g);
  225. EntityText(text_offset,tempstr,0);
  226. text_offset++;
  227. Q_snprintf(tempstr,sizeof(tempstr),"1) Blue : %i",color.b);
  228. EntityText(text_offset,tempstr,0);
  229. text_offset++;
  230. color = m_fog.colorSecondary;
  231. Q_snprintf(tempstr,sizeof(tempstr),"2) Red : %i",color.r);
  232. EntityText(text_offset,tempstr,0);
  233. text_offset++;
  234. Q_snprintf(tempstr,sizeof(tempstr),"2) Green: %i",color.g);
  235. EntityText(text_offset,tempstr,0);
  236. text_offset++;
  237. Q_snprintf(tempstr,sizeof(tempstr),"2) Blue : %i",color.b);
  238. EntityText(text_offset,tempstr,0);
  239. text_offset++;
  240. Q_snprintf(tempstr,sizeof(tempstr),"HDR Color Scale: %0.3f",m_fog.HDRColorScale.Get() );
  241. EntityText(text_offset,tempstr,0);
  242. text_offset++;
  243. }
  244. return text_offset;
  245. }
  246. #define FOG_CONTROLLER_COLORPRIMARY_LERP (1 << 0)
  247. #define FOG_CONTROLLER_COLORSECONDARY_LERP (1 << 1)
  248. #define FOG_CONTROLLER_START_LERP (1 << 2)
  249. #define FOG_CONTROLLER_END_LERP (1 << 3)
  250. #define FOG_CONTROLLER_MAXDENSITY_LERP (1 << 4)
  251. void CFogController::InputSetColorLerpTo(inputdata_t &data)
  252. {
  253. m_iChangedVariables |= FOG_CONTROLLER_COLORPRIMARY_LERP;
  254. m_fog.colorPrimaryLerpTo = data.value.Color32();
  255. }
  256. void CFogController::InputSetColorSecondaryLerpTo(inputdata_t &data)
  257. {
  258. m_iChangedVariables |= FOG_CONTROLLER_COLORSECONDARY_LERP;
  259. m_fog.colorSecondaryLerpTo = data.value.Color32();
  260. }
  261. void CFogController::InputSetStartDistLerpTo(inputdata_t &data)
  262. {
  263. m_iChangedVariables |= FOG_CONTROLLER_START_LERP;
  264. m_fog.startLerpTo = data.value.Float();
  265. }
  266. void CFogController::InputSetEndDistLerpTo(inputdata_t &data)
  267. {
  268. m_iChangedVariables |= FOG_CONTROLLER_END_LERP;
  269. m_fog.endLerpTo = data.value.Float();
  270. }
  271. void CFogController::InputSetMaxDensityLerpTo(inputdata_t &data)
  272. {
  273. m_iChangedVariables |= FOG_CONTROLLER_MAXDENSITY_LERP;
  274. m_fog.maxdensityLerpTo = data.value.Float();
  275. }
  276. void CFogController::InputStartFogTransition(inputdata_t &data)
  277. {
  278. SetThink( &CFogController::SetLerpValues );
  279. m_fog.lerptime = gpGlobals->curtime + m_fog.duration + 0.1;
  280. SetNextThink( gpGlobals->curtime + m_fog.duration );
  281. }
  282. void CFogController::SetLerpValues( void )
  283. {
  284. if ( m_iChangedVariables & FOG_CONTROLLER_COLORPRIMARY_LERP )
  285. {
  286. m_fog.colorPrimary = m_fog.colorPrimaryLerpTo;
  287. }
  288. if ( m_iChangedVariables & FOG_CONTROLLER_COLORSECONDARY_LERP )
  289. {
  290. m_fog.colorSecondary = m_fog.colorSecondaryLerpTo;
  291. }
  292. if ( m_iChangedVariables & FOG_CONTROLLER_START_LERP )
  293. {
  294. m_fog.start = m_fog.startLerpTo;
  295. }
  296. if ( m_iChangedVariables & FOG_CONTROLLER_END_LERP )
  297. {
  298. m_fog.end = m_fog.endLerpTo;
  299. }
  300. if ( m_iChangedVariables & FOG_CONTROLLER_MAXDENSITY_LERP )
  301. {
  302. m_fog.maxdensity = m_fog.maxdensityLerpTo;
  303. }
  304. m_iChangedVariables = 0;
  305. m_fog.lerptime = gpGlobals->curtime;
  306. }
  307. //-----------------------------------------------------------------------------
  308. // Purpose: Clear out the fog controller.
  309. //-----------------------------------------------------------------------------
  310. void CFogSystem::LevelInitPreEntity( void )
  311. {
  312. m_hMasterController = NULL;
  313. ListenForGameEvent( "round_start" );
  314. }
  315. //-----------------------------------------------------------------------------
  316. // Purpose: Find the master controller. If no controller is
  317. // set as Master, use the first controller found.
  318. //-----------------------------------------------------------------------------
  319. void CFogSystem::InitMasterController( void )
  320. {
  321. CFogController *pFogController = NULL;
  322. do
  323. {
  324. pFogController = static_cast<CFogController*>( gEntList.FindEntityByClassname( pFogController, "env_fog_controller" ) );
  325. if ( pFogController )
  326. {
  327. if ( m_hMasterController.Get() == NULL )
  328. {
  329. m_hMasterController = pFogController;
  330. }
  331. else
  332. {
  333. if ( pFogController->IsMaster() )
  334. {
  335. m_hMasterController = pFogController;
  336. }
  337. }
  338. }
  339. } while ( pFogController );
  340. }
  341. void CFogSystem::SetMasterController( CFogController *pFogController )
  342. {
  343. m_hMasterController = pFogController;
  344. }
  345. //-----------------------------------------------------------------------------
  346. // Purpose: On a multiplayer map restart, re-find the master controller.
  347. //-----------------------------------------------------------------------------
  348. void CFogSystem::FireGameEvent( IGameEvent *pEvent )
  349. {
  350. InitMasterController();
  351. }
  352. //-----------------------------------------------------------------------------
  353. // Purpose: On level load find the master fog controller. If no controller is
  354. // set as Master, use the first fog controller found.
  355. //-----------------------------------------------------------------------------
  356. void CFogSystem::LevelInitPostEntity( void )
  357. {
  358. InitMasterController();
  359. // HACK: Singleplayer games don't get a call to CBasePlayer::Spawn on level transitions.
  360. // CBasePlayer::Activate is called before this is called so that's too soon to set up the fog controller.
  361. // We don't have a hook similar to Activate that happens after LevelInitPostEntity
  362. // is called, or we could just do this in the player itself.
  363. if ( gpGlobals->maxClients == 1 )
  364. {
  365. CBasePlayer *pPlayer = UTIL_GetLocalPlayer();
  366. if ( pPlayer && ( pPlayer->m_PlayerFog.m_hCtrl.Get() == NULL ) )
  367. {
  368. pPlayer->InitFogController();
  369. }
  370. }
  371. }
  372. //--------------------------------------------------------------------------------------------------------
  373. class CFogTrigger : public CBaseTrigger
  374. {
  375. public:
  376. DECLARE_CLASS( CFogTrigger, CBaseTrigger );
  377. DECLARE_DATADESC();
  378. virtual void Spawn( void );
  379. virtual void StartTouch( CBaseEntity *other );
  380. virtual void EndTouch( CBaseEntity *other );
  381. fogparams_t *GetFog( void )
  382. {
  383. return &m_fog;
  384. }
  385. private:
  386. fogparams_t m_fog;
  387. };
  388. LINK_ENTITY_TO_CLASS( trigger_fog, CFogTrigger );
  389. BEGIN_DATADESC( CFogTrigger )
  390. DEFINE_KEYFIELD( m_fog.colorPrimary, FIELD_COLOR32, "fogcolor" ),
  391. DEFINE_KEYFIELD( m_fog.colorSecondary, FIELD_COLOR32, "fogcolor2" ),
  392. DEFINE_KEYFIELD( m_fog.dirPrimary, FIELD_VECTOR, "fogdir" ),
  393. DEFINE_KEYFIELD( m_fog.enable, FIELD_BOOLEAN, "fogenable" ),
  394. DEFINE_KEYFIELD( m_fog.blend, FIELD_BOOLEAN, "fogblend" ),
  395. DEFINE_KEYFIELD( m_fog.start, FIELD_FLOAT, "fogstart" ),
  396. DEFINE_KEYFIELD( m_fog.end, FIELD_FLOAT, "fogend" ),
  397. DEFINE_KEYFIELD( m_fog.farz, FIELD_FLOAT, "farz" ),
  398. END_DATADESC()
  399. //--------------------------------------------------------------------------------------------------------
  400. void CFogTrigger::Spawn( void )
  401. {
  402. AddSpawnFlags( SF_TRIGGER_ALLOW_ALL );
  403. BaseClass::Spawn();
  404. InitTrigger();
  405. }
  406. //--------------------------------------------------------------------------------------------------------
  407. void CFogTrigger::StartTouch( CBaseEntity *other )
  408. {
  409. if ( !PassesTriggerFilters( other ) )
  410. return;
  411. BaseClass::StartTouch( other );
  412. CBaseCombatCharacter *character = other->MyCombatCharacterPointer();
  413. if ( !character )
  414. return;
  415. character->OnFogTriggerStartTouch( this );
  416. }
  417. //--------------------------------------------------------------------------------------------------------
  418. void CFogTrigger::EndTouch( CBaseEntity *other )
  419. {
  420. if ( !PassesTriggerFilters( other ) )
  421. return;
  422. BaseClass::EndTouch( other );
  423. CBaseCombatCharacter *character = other->MyCombatCharacterPointer();
  424. if ( !character )
  425. return;
  426. character->OnFogTriggerEndTouch( this );
  427. }
  428. //--------------------------------------------------------------------------------------------------------
  429. bool GetWorldFogParams( CBaseCombatCharacter *character, fogparams_t &fog )
  430. {
  431. fogparams_t *targetFog = NULL;
  432. if ( character && character->GetFogTrigger() )
  433. {
  434. CFogTrigger *trigger = dynamic_cast< CFogTrigger * >(character->GetFogTrigger());
  435. if ( trigger )
  436. {
  437. targetFog = trigger->GetFog();
  438. }
  439. }
  440. if ( !targetFog && FogSystem()->GetMasterFogController() )
  441. {
  442. targetFog = &(FogSystem()->GetMasterFogController()->m_fog);
  443. }
  444. if ( targetFog )
  445. {
  446. if ( *targetFog != fog )
  447. {
  448. fog = *targetFog;
  449. return true;
  450. }
  451. }
  452. else
  453. {
  454. if ( fog.farz != -1 || fog.enable != false )
  455. {
  456. // No fog controller in this level. Use default fog parameters.
  457. fog.farz = -1;
  458. fog.enable = false;
  459. return true;
  460. }
  461. }
  462. return false;
  463. }