Advertisement
Guest User

DynamicWeatherEffects.sqf

a guest
Jan 19th, 2017
107
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 23.97 KB | None | 0 0
  1. /* DynamicWeatherEffects.sqf version 1.01 by Engima of Ostgota Ops
  2.  * Description:
  3.  *   Script that generates dynamic (random) weather. Works in single player, multiplayer (hosted and dedicated), and is JIP compatible.
  4.  * Arguments:
  5.  *   [_initialFog]: Optional. Fog when mission starts. Must be between 0 and 1 where 0 = no fog, 1 = maximum fog. -1 = random fog.
  6.  *   [_initialOvercast]: Optional. Overcast when mission starts. Must be between 0 and 1 where 0 = no overcast, 1 = maximum overcast. -1 = random overcast.
  7.  *   [_initialRain]: Optional. Rain when mission starts. Must be between 0 and 1 where 0 = no rain, 1 = maximum rain. -1 = random rain. (Overcast must be greater than or equal to 0.75).
  8.  *   [_initialWind]: Optional. Wind when mission starts. Must be an array of form [x, z], where x is one wind strength vector and z is the other. x and z must be greater than or equal to 0. [-1, -1] = random wind.
  9.  *   [_debug]: Optional. true if debug text is to be shown, otherwise false.
  10.  */
  11.  
  12. params [["_initialFog",-1,[0]], ["_initialOvercast",-1,[0]], ["_initialRain",-1,[0]], ["_initialWind",[],[[]]], ["_debug",false,[false]]];
  13.  
  14. private ["_minWeatherChangeTimeMin", "_maxWeatherChangeTimeMin", "_minTimeBetweenWeatherChangesMin", "_maxTimeBetweenWeatherChangesMin", "_rainIntervalRainProbability", "_windChangeProbability"];
  15. private ["_minimumFog", "_maximumFog", "_minimumOvercast", "_maximumOvercast", "_minimumRain", "_maximumRain", "_minimumWind", "_maximumWind", "_minRainIntervalTimeMin", "_maxRainIntervalTimeMin", "_forceRainToStopAfterOneRainInterval", "_maxWind"];
  16. private ["_minimumFogDecay", "_maximumFogDecay", "_minimumFogBase", "_maximumFogBase"];
  17.  
  18. #define SLEEP_REALTIME(SECS) if (hasInterface) then { sleep SECS } else { uiSleep SECS }
  19.  
  20. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  21. // The following variables can be changed to tweak weather behaviour
  22.  
  23. // Minimum time in minutes for the weather (fog and overcast) to change. Must be greater than or equal to 1 and less than or equal to
  24. // _maxWeatherChangeTimeMin. When weather changes, it is fog OR overcast that changes, not both at the same time. (Suggested value: 10).
  25. _minWeatherChangeTimeMin = 10;
  26.  
  27. // Maximum time in minutes for the weather (fog and overcast) to change. Must be greater than or equal to _minWeatherChangeTimeMin.
  28. // (Suggested value: 20).
  29. _maxWeatherChangeTimeMin = 20;
  30.  
  31. // Minimum time in minutes that weather (fog and overcast) stays constant between weather changes. Must be less than or equal to 0 and
  32. // greater than or equal to _minWeatherChangeTimeMin. (Suggested value: 5).
  33. _minTimeBetweenWeatherChangesMin = 5;
  34.  
  35. // Maximum time in minutes that weather (fog and overcast) stays unchanged between weather changes. Must be greater than or equal to
  36. // _minWeatherChangeTimeMin. (Suggested value: 10).
  37. _maxTimeBetweenWeatherChangesMin = 10;
  38.  
  39. // Fog intensity never falls below this value. Must be between 0 and 1 and less than or equal to _maximumFog
  40. // (0 = no fog, 1 = pea soup). (Suggested value: 0).
  41. _minimumFog = 0;
  42.  
  43. // Fog intensity never exceeds this value. Must be between 0 and 1 and greater than or equal to _minimumFog
  44. // (0 = no fog, 1 = pea soup). (Suggested value: 0.2).
  45. _maximumFog = 0.05;
  46.  
  47. // New ArmA3 facilities added by Bewilderbeest - not currently taken into account due to engine syncing bugs and weird behavior
  48. _minimumFogDecay = 0;
  49. _maximumFogDecay = 0;
  50. _minimumFogBase = 0;
  51. _maximumFogBase = 0;
  52.  
  53. // Overcast intensity never falls below this value. Must be between 0 and 1 and less than or equal to _maximumOvercast
  54. // (0 = no overcast, 1 = maximum overcast). (Suggested value: 0).
  55. _minimumOvercast = 0.955;
  56.  
  57. // Overcast intensity never exceeds this value. Must be between 0 and 1 and greater than or equal to _minimumOvercast
  58. // (0 = no overcast, 1 = maximum overcast). (Suggested value: 1).
  59. _maximumOvercast = 0.988;
  60.  
  61. // When raining, rain intensity never falls below this value. Must be between 0 and 1 and less than or equal to _maximumRain
  62. // (0 = no rain, 1 = maximum rain intensity). (Suggested value: 0.1);
  63. _minimumRain = 0.1;
  64.  
  65. // When raining, rain intensity never exceeds this value. Must be between 0 and 1 and greater than or equal to _minimumRain
  66. // (0 = no rain, 1 = maximum rain intensity). (Suggested value: 1);
  67. _maximumRain = 0.3;
  68.  
  69. // Wind vector strength never falls below this value. Must be greater or equal to 0 and less than or equal to _maximumWind.
  70. // (Suggested value: 0);
  71. _minimumWind = 6;
  72.  
  73. // Wind vector strength never exceeds this value. Must be greater or equal to 0 and greater than or equal to _minimumWind.
  74. // (Suggested value: 5).
  75. _maximumWind = 13;
  76.  
  77. // Probability in percent for wind to change when weather changes. If set to 0 then wind will never change. If set to 100 then rain will
  78. // change every time the weather (fog or overcast) start to change. (Suggested value: 25);
  79. _windChangeProbability = 15;
  80.  
  81. // A "rain interval" is defined as "a time interval during which it may rain in any intensity (or it may not rain at all)". When overcast
  82. // goes above 0.75, a chain of rain intervals (defined below) is started. It cycles on until overcast falls below 0.75. At overcast
  83. // below 0.75 rain intervals never execute (thus it cannot rain).
  84.  
  85. // Probability in percent (0-100) for rain to start at every rain interval. Set this to 0 if you don't want rain at all. Set this to 100
  86. // if you want it to rain constantly when overcast is greater than 0.75. In short: if you think that it generally rains to often then
  87. // lower this value and vice versa. (Suggested value: 50).
  88. _rainIntervalRainProbability = 5; // overcast syncing fubar, do not enable rain
  89.  
  90. // Minimum time in minutes for rain intervals. Must be greater or equal to 0 and less than or equal to _maxRainIntervalTimeMin.
  91. // (Suggested value: 0).
  92. _minRainIntervalTimeMin = 0;
  93.  
  94. // Maximum time in minutes for rain intervals. Must be greater than or equal to _minRainIntervalTimeMin. (Suggested value:
  95. // (_maxWeatherChangeTimeMin + _maxTimeBetweenWeatherChangesMin) / 2).
  96. _maxRainIntervalTimeMin = (_maxWeatherChangeTimeMin + _maxTimeBetweenWeatherChangesMin) / 2;
  97.  
  98. // If set to true, then the rain is forced to stop after one rain interval during which it has rained (use this for example if you only want
  99. // small occational cloudbursts ). If set to false, then the rain may stop, but it may also just change intensity for an
  100. // immedeate new rain interval. (Suggested value: false).
  101. _forceRainToStopAfterOneRainInterval = false;
  102.  
  103.  
  104. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  105. // Don't touch anything beneath this line
  106.  
  107. drn_DynamicWeather_minFog = _minimumFog;
  108. drn_DynamicWeather_maxFog = _maximumFog;
  109. drn_DynamicWeather_DebugTextEventArgs = []; // Empty
  110.  
  111. "drn_DynamicWeather_DebugTextEventArgs" addPublicVariableEventHandler {
  112.     drn_DynamicWeather_DebugTextEventArgs call drn_fnc_DynamicWeather_ShowDebugTextLocal;
  113. };
  114.  
  115. /*
  116.  * Summary: Shows debug text on local client.
  117.  * Arguments:
  118.  *   _text: Debug text.
  119.  */
  120. drn_fnc_DynamicWeather_ShowDebugTextLocal = {
  121.     private ["_minutes", "_seconds"];
  122.  
  123.     if (!isNull player) then {
  124.         player sideChat (_this select 0);
  125.     };
  126.  
  127.     _minutes = floor (diag_tickTime / 60);
  128.     _seconds = floor (diag_tickTime - (_minutes * 60));
  129.     diag_log ((str _minutes + ":" + str _seconds) + " Debug: " + (_this select 0));
  130. };
  131.  
  132. /*
  133.  * Summary: Shows debug text on all clients.
  134.  * Arguments:
  135.  *   _text: Debug text.
  136.  */
  137. drn_fnc_DynamicWeather_ShowDebugTextAllClients = {
  138.     drn_DynamicWeather_DebugTextEventArgs = _this;
  139.     publicVariable "drn_DynamicWeather_DebugTextEventArgs";
  140.     drn_DynamicWeather_DebugTextEventArgs call drn_fnc_DynamicWeather_ShowDebugTextLocal;
  141. };
  142.  
  143. if (_debug) then {
  144.     ["Starting script WeatherEffects.sqf..."] call drn_fnc_DynamicWeather_ShowDebugTextLocal;
  145. };
  146.  
  147. drn_DynamicWeatherEventArgs = []; // [current overcast, current fog, current rain, current weather change ("OVERCAST", "FOG" or ""), target weather value, time until weather completion (in seconds), current wind x, current wind z]
  148. drn_AskServerDynamicWeatherEventArgs = [];
  149.  
  150. drn_fnc_overcastOdds = { ((9/8) * (_this ^ (5/2))) min 1 }; // https://www.desmos.com/calculator/sp7zsxckhn
  151. drn_fnc_fogOdds =
  152. {
  153.     params ["_currFog", "_maxFog"];
  154.  
  155.     if (_maxFog <= 0) exitWith {0};
  156.  
  157.     private _fogVal = _currFog / _maxFog;
  158.     _fogVal call drn_fnc_overcastOdds
  159. };
  160.  
  161. drn_fnc_DynamicWeather_SetWeatherLocal = {
  162.     params ["_currentOvercast", "_currentFog", "_currentRain", "_currentWeatherChange", "_targetWeatherValue", "_timeUntilCompletion", "_currentWindX", "_currentWindY"];
  163.  
  164.     _currentRain = drn_var_DynamicWeather_Rain;
  165.  
  166.     if (_currentFog isEqualType []) then {
  167.         _currentFog = _currentFog select 0;
  168.     };
  169.  
  170.     /*if (typeName _currentFog == "ARRAY") then {
  171.         _currentFog set [0, (_currentFog select 0) max (_currentRain / 4)];
  172.     }
  173.     else {*/
  174.         _currentFog = (drn_DynamicWeather_minFog max _currentFog min drn_DynamicWeather_maxFog) max (_currentRain / 4);
  175.     //};
  176.  
  177.     // Set current weather values
  178.     if (_currentWeatherChange != "OVERCAST") then { 0 setOvercast _currentOvercast };
  179.     0 setFog [_currentFog, 0.0, 0]; // do not change fog decay/base otherwise the fog level will vary unpredictably
  180.     //drn_var_DynamicWeather_Rain = _currentRain;
  181.     setWind [_currentWindX, _currentWindY, true];
  182.  
  183.     if (isNil "drn_JIPWeatherSynced") then
  184.     {
  185.         forceWeatherChange;
  186.         simulWeatherSync;
  187.         drn_JIPWeatherSynced = true;
  188.     };
  189.  
  190.     // Set forecast
  191.     if (_currentWeatherChange == "OVERCAST") then {
  192.         _timeUntilCompletion setOvercast (_targetWeatherValue call drn_fnc_overcastOdds);
  193.         //5 setFog [_currentRain / 4, 0.0, 0]; // do not change fog decay/base otherwise the fog level will vary unpredictably // Quick hack to ensure fog goes away regularly
  194.     };
  195.     if (_currentWeatherChange == "FOG") then {
  196.         if (typeName _targetWeatherValue == "ARRAY") then {
  197.             _targetWeatherValue = _targetWeatherValue select 0;
  198.         };
  199.         (3600 * timeMultiplier * abs (overcast - _currentOvercast)) setOvercast _currentOvercast;
  200.         _timeUntilCompletion setFog [_targetWeatherValue max (_currentRain / 4), 0.0, 0]; // do not change fog decay/base otherwise the fog level will vary unpredictably
  201.     };
  202. };
  203.  
  204. if (!isServer) then {
  205.     "drn_DynamicWeatherEventArgs" addPublicVariableEventHandler {
  206.         drn_DynamicWeatherEventArgs spawn drn_fnc_DynamicWeather_SetWeatherLocal;
  207.     };
  208.  
  209.     waitUntil {!isNil "drn_var_DynamicWeather_ServerInitialized"};
  210.  
  211.     drn_AskServerDynamicWeatherEventArgs = []; //[clientOwner];
  212.     publicVariable "drn_AskServerDynamicWeatherEventArgs";
  213. };
  214.  
  215. if (isServer) then {
  216.     drn_fnc_DynamicWeather_SetWeatherAllClients = {
  217.         params [["_owner",0,[0]]];
  218.         private ["_timeUntilCompletion", "_currentWeatherChange"];
  219.  
  220.         _timeUntilCompletion = (drn_DynamicWeather_WeatherChangeCompletedTime - drn_DynamicWeather_WeatherChangeStartedTime) * timeMultiplier;
  221.         if (_timeUntilCompletion > 0) then {
  222.             _currentWeatherChange = drn_DynamicWeather_CurrentWeatherChange;
  223.         }
  224.         else {
  225.             _currentWeatherChange = "";
  226.         };
  227.  
  228.         drn_DynamicWeatherEventArgs = [overcast, fog, drn_var_DynamicWeather_Rain, _currentWeatherChange, drn_DynamicWeather_WeatherTargetValue, _timeUntilCompletion, drn_DynamicWeather_WindX, drn_DynamicWeather_WindY];
  229.  
  230.         if (_owner > 0) then
  231.         {
  232.             _owner publicVariableClient "drn_DynamicWeatherEventArgs";
  233.         }
  234.         else
  235.         {
  236.             publicVariable "drn_DynamicWeatherEventArgs";
  237.         };
  238.  
  239.         drn_DynamicWeatherEventArgs spawn drn_fnc_DynamicWeather_SetWeatherLocal;
  240.     };
  241.  
  242.     drn_DynamicWeather_CurrentWeatherChange = "";
  243.     drn_DynamicWeather_WeatherTargetValue = 0;
  244.     drn_DynamicWeather_WeatherChangeStartedTime = diag_tickTime;
  245.     drn_DynamicWeather_WeatherChangeCompletedTime = diag_tickTime;
  246.     drn_DynamicWeather_WindX = _initialWind param [0, nil, [0]];
  247.     drn_DynamicWeather_WindY = _initialWind param [1, nil, [0]];
  248.  
  249.     "drn_AskServerDynamicWeatherEventArgs" addPublicVariableEventHandler {
  250.         (_this select 1) spawn drn_fnc_DynamicWeather_SetWeatherAllClients;
  251.     };
  252.  
  253.     if (_initialFog == -1) then {
  254.         _initialFog = _minimumFog + random (_maximumFog - _minimumFog);
  255.         _initialFog = ([_initialFog, _maximumFog] call drn_fnc_fogOdds) * _maximumFog;
  256.     }
  257.     else {
  258.         _initialFog = _minimumFog max _initialFog min _maximumFog;
  259.     };
  260.  
  261.     //0 setFog [_initialFog max (rain / 4), 0.0, 0]; // do not change fog decay/base otherwise the fog level will vary unpredictably
  262.  
  263.     if (_initialOvercast == -1) then {
  264.         _initialOvercast = _minimumOvercast + random (_maximumOvercast - _minimumOvercast);
  265.         _initialOvercast = _initialOvercast call drn_fnc_overcastOdds;
  266.     }
  267.     else {
  268.         _initialOvercast = _minimumOvercast max _initialOvercast min _maximumOvercast;
  269.     };
  270.  
  271.     0 setOvercast _initialOvercast;
  272.  
  273.     private _keepRain = false;
  274.  
  275.     if (_initialOvercast >= 0.75) then {
  276.         if (_initialRain == -1 || _rainIntervalRainProbability <= 0) then {
  277.             _initialRain = 0; //_minimumRain + random (_minimumRain - _minimumRain); // drn_DynamicWeather_RainThread will override the value anyway, so we keep it at 0
  278.         }
  279.         else {
  280.             _initialRain = _minimumRain max _initialRain min _maximumRain;
  281.             _keepRain = true; // force drn_DynamicWeather_RainThread to wait one cycle after mission start
  282.         };
  283.     }
  284.     else {
  285.         _initialRain = 0;
  286.     };
  287.  
  288.     drn_var_DynamicWeather_Rain = _initialRain;
  289.     0 setRain _initialRain;
  290.     0 setFog [_initialFog max (_initialRain / 4), 0.0, 0]; // do not change fog decay/base otherwise the fog level will vary unpredictably
  291.  
  292.  
  293.     if (isNil "drn_DynamicWeather_WindX") then {
  294.         drn_DynamicWeather_WindX = (_minimumWind + random (_maximumWind - _minimumWind)) * (1 - 2 * round random 1);
  295.     } else {
  296.         drn_DynamicWeather_WindX = -_maximumWind max drn_DynamicWeather_WindX min _maximumWind;
  297.     };
  298.  
  299.     if (isNil "drn_DynamicWeather_WindY") then {
  300.         drn_DynamicWeather_WindY = (_minimumWind + random (_maximumWind - _minimumWind)) * (1 - 2 * round random 1);
  301.     } else {
  302.         drn_DynamicWeather_WindY = -_maximumWind max drn_DynamicWeather_WindY min _maximumWind;
  303.     };
  304.  
  305.     setWind [drn_DynamicWeather_WindX, drn_DynamicWeather_WindY, true];
  306.  
  307.     forceWeatherChange;
  308.  
  309.     sleep 0.05;
  310.  
  311.     publicVariable "drn_var_DynamicWeather_Rain";
  312.     drn_var_DynamicWeather_ServerInitialized = true;
  313.     publicVariable "drn_var_DynamicWeather_ServerInitialized";
  314.  
  315.     // Start weather thread
  316.     if (!isNil "drn_DynamicWeather_WeatherThread") then { terminate drn_DynamicWeather_WeatherThread };
  317.     drn_DynamicWeather_WeatherThread = [_minWeatherChangeTimeMin, _maxWeatherChangeTimeMin, _minTimeBetweenWeatherChangesMin, _maxTimeBetweenWeatherChangesMin, _minimumFog, _maximumFog, _minimumFogDecay, _maximumFogDecay, _minimumFogBase, _maximumFogBase, _minimumOvercast, _maximumOvercast, _minimumWind, _maximumWind, _windChangeProbability, _debug] spawn
  318.     {
  319.         params ["_minWeatherChangeTimeMin", "_maxWeatherChangeTimeMin", "_minTimeBetweenWeatherChangesMin", "_maxTimeBetweenWeatherChangesMin", "_minimumFog", "_maximumFog", "_minimumFogDecay", "_maximumFogDecay", "_minimumFogBase", "_maximumFogBase", "_minimumOvercast", "_maximumOvercast", "_minimumWind", "_maximumWind", "_windChangeProbability", "_debug"];
  320.         private ["_weatherType", "_fogLevel", "_overcastLevel", "_oldFogLevel", "_oldOvercastLevel", "_weatherChangeTimeSek", "_fogValue", "_fogBase", "_fogDecay"];
  321.  
  322.         // Set initial fog level
  323.         _fogLevel = 2;
  324.         _overcastLevel = 2;
  325.  
  326.         while {true} do {
  327.             // Sleep a while until next weather change
  328.             sleep floor (_minTimeBetweenWeatherChangesMin * 60 + random ((_maxTimeBetweenWeatherChangesMin - _minTimeBetweenWeatherChangesMin) * 60));
  329.  
  330.             if (_minimumFog == _maximumFog && _minimumOvercast != _maximumOvercast) then {
  331.                 _weatherType = "OVERCAST";
  332.             };
  333.             if (_minimumFog != _maximumFog && _minimumOvercast == _maximumOvercast) then {
  334.                 _weatherType = "FOG";
  335.             };
  336.             if (_minimumFog != _maximumFog && _minimumOvercast != _maximumOvercast) then {
  337.  
  338.                 // Select type of weather to change
  339.                 _weatherType = ["OVERCAST","FOG"] call BIS_fnc_selectRandom;
  340.             };
  341.  
  342.             // DEBUG
  343.             //_weatherType = "OVERCAST";
  344.  
  345.             if (_weatherType == "FOG") then {
  346.  
  347.                 drn_DynamicWeather_CurrentWeatherChange = "FOG";
  348.  
  349.                 // Select a new fog level
  350.                 _oldFogLevel = _fogLevel;
  351.                 _fogLevel = ([0,1,2,3] - [_oldFogLevel]) call BIS_fnc_selectRandom;
  352.  
  353.                 _fogValue = switch (_fogLevel) do
  354.                 {
  355.                     case 1: { _minimumFog + (_maximumFog - _minimumFog) * (0.05 + random 0.2) };
  356.                     case 2: { _minimumFog + (_maximumFog - _minimumFog) * (0.25 + random 0.3) };
  357.                     case 3: { _minimumFog + (_maximumFog - _minimumFog) * (0.55 + random 0.45) };
  358.                     default { _minimumFog + (_maximumFog - _minimumFog) * random 0.05 };
  359.                 };
  360.  
  361.                 _fogValue = ([_fogValue, _maximumFog] call drn_fnc_fogOdds) * _maximumFog;
  362.  
  363.                 _fogDecay = _minimumFogDecay + (_maximumFogDecay - _minimumFogDecay) * random 1;
  364.                 _fogBase = _minimumFogBase + (_maximumFogBase - _minimumFogBase) * random 1;
  365.  
  366.                 drn_DynamicWeather_WeatherTargetValue = [_fogValue, 0.0, 0]; //_fogDecay, _fogBase];
  367.  
  368.                 drn_DynamicWeather_WeatherChangeStartedTime = diag_tickTime;
  369.                 _weatherChangeTimeSek = _minWeatherChangeTimeMin * 60 + random ((_maxWeatherChangeTimeMin - _minWeatherChangeTimeMin) * 60);
  370.                 drn_DynamicWeather_WeatherChangeCompletedTime = diag_tickTime + _weatherChangeTimeSek;
  371.  
  372.                 if (_debug) then {
  373.                     ["Weather forecast: Fog " + str drn_DynamicWeather_WeatherTargetValue + " in " + str round (_weatherChangeTimeSek / 60) + " minutes."] call drn_fnc_DynamicWeather_ShowDebugTextAllClients;
  374.                 };
  375.             };
  376.  
  377.             if (_weatherType == "OVERCAST") then {
  378.  
  379.                 drn_DynamicWeather_CurrentWeatherChange = "OVERCAST";
  380.  
  381.                 // Select a new overcast level
  382.                 _oldOvercastLevel = _overcastLevel;
  383.                 //_overcastLevel = floor ((random 100) / 25);
  384.                 _overcastLevel = 3;
  385.  
  386.                 if (_overcastLevel == _oldOvercastLevel) then {
  387.                     _overcastLevel = ([0,1,2,3] - [_oldOvercastLevel]) call BIS_fnc_selectRandom;
  388.                 };
  389.  
  390.                 drn_DynamicWeather_WeatherTargetValue = switch (_overcastLevel) do
  391.                 {
  392.                     case 1: { _minimumOvercast + (_maximumOvercast - _minimumOvercast) * (0.05 + random 0.3) };
  393.                     case 2: { _minimumOvercast + (_maximumOvercast - _minimumOvercast) * (0.35 + random 0.35) };
  394.                     case 3: { _minimumOvercast + (_maximumOvercast - _minimumOvercast) * (0.7 + random 0.3) };
  395.                     default { _minimumOvercast + (_maximumOvercast - _minimumOvercast) * random 0.05 };
  396.                 };
  397.  
  398.                 // DEBUG
  399.                 /*
  400.                 if (overcast > 0.8) then {
  401.                     drn_DynamicWeather_WeatherTargetValue = 0.5;
  402.                 }
  403.                 else {
  404.                     drn_DynamicWeather_WeatherTargetValue = 0.85;
  405.                 };
  406.                 */
  407.  
  408.                 drn_DynamicWeather_WeatherChangeStartedTime = diag_tickTime;
  409.                 _weatherChangeTimeSek = _minWeatherChangeTimeMin * 60 + random ((_maxWeatherChangeTimeMin - _minWeatherChangeTimeMin) * 60);
  410.                 drn_DynamicWeather_WeatherChangeCompletedTime = diag_tickTime + _weatherChangeTimeSek;
  411.  
  412.                 if (_debug) then {
  413.                     ["Weather forecast: Overcast " + str drn_DynamicWeather_WeatherTargetValue + " in " + str round (_weatherChangeTimeSek / 60) + " minutes."] call drn_fnc_DynamicWeather_ShowDebugTextAllClients;
  414.                 };
  415.             };
  416.  
  417.             // On average every one fourth of weather changes, change wind too
  418.             if (random 100 < _windChangeProbability) then
  419.             {
  420.                 drn_DynamicWeather_WindX = (_minimumWind + random (_maximumWind - _minimumWind)) * (1 - 2 * round random 1);
  421.                 drn_DynamicWeather_WindY = (_minimumWind + random (_maximumWind - _minimumWind)) * (1 - 2 * round random 1);
  422.  
  423.                 if (_debug) then {
  424.                     ["Wind changes: [" + str drn_DynamicWeather_WindX + ", " + str drn_DynamicWeather_WindY + "]."] call drn_fnc_DynamicWeather_ShowDebugTextAllClients;
  425.                 };
  426.             };
  427.  
  428.             [] call drn_fnc_DynamicWeather_SetWeatherAllClients;
  429.  
  430.             SLEEP_REALTIME(_weatherChangeTimeSek);
  431.         };
  432.     };
  433.  
  434.     // Start rain thread
  435.     if (_rainIntervalRainProbability > 0) then {
  436.         if (!isNil "drn_DynamicWeather_RainThread") then { terminate drn_DynamicWeather_RainThread };
  437.         drn_DynamicWeather_RainThread = [_minimumRain, _maximumRain, _forceRainToStopAfterOneRainInterval, _minRainIntervalTimeMin, _maxRainIntervalTimeMin, _rainIntervalRainProbability, _keepRain, _debug] spawn
  438.         {
  439.             params ["_minimumRain", "_maximumRain", "_forceRainToStopAfterOneRainInterval", "_minRainIntervalTimeMin", "_maxRainIntervalTimeMin", "_rainIntervalRainProbability", "_keepRain", "_debug"];
  440.             private ["_nextRainEventTime", "_forceStop", "_rainTimeSec"];
  441.  
  442.             if (rain > 0) then {
  443.                 drn_var_DynamicWeather_Rain = rain;
  444.                 publicVariable "drn_var_DynamicWeather_Rain";
  445.             };
  446.  
  447.             _nextRainEventTime = diag_tickTime;
  448.             _forceStop = false;
  449.  
  450.             if (_keepRain) then
  451.             {
  452.                 _rainTimeSec = _minRainIntervalTimeMin * 60 + random ((_maxRainIntervalTimeMin - _minRainIntervalTimeMin) * 60);
  453.                 _nextRainEventTime = _nextRainEventTime + _rainTimeSec;
  454.             };
  455.  
  456.             while {true} do {
  457.  
  458.                 if (overcast >= 0.75) then {
  459.  
  460.                     if (diag_tickTime >= _nextRainEventTime) then {
  461.  
  462.                         // At every rain event time, start or stop rain with 50% probability
  463.                         if (random 100 < _rainIntervalRainProbability && !_forceStop) then {
  464.                             drn_var_DynamicWeather_rain = _minimumRain + random (_maximumRain - _minimumRain);
  465.                             publicVariable "drn_var_DynamicWeather_rain";
  466.  
  467.                             _forceStop = _forceRainToStopAfterOneRainInterval;
  468.                         }
  469.                         else {
  470.                             drn_var_DynamicWeather_rain = 0;
  471.                             publicVariable "drn_var_DynamicWeather_rain";
  472.  
  473.                             _forceStop = false;
  474.                         };
  475.  
  476.                         // Pick a time for next rain change
  477.                         _rainTimeSec = _minRainIntervalTimeMin * 60 + random ((_maxRainIntervalTimeMin - _minRainIntervalTimeMin) * 60);
  478.                         _nextRainEventTime = diag_tickTime + _rainTimeSec;
  479.  
  480.                         if (_debug) then {
  481.                             ["Rain set to " + str drn_var_DynamicWeather_rain + " for " + str (_rainTimeSec / 60) + " minutes"] call drn_fnc_DynamicWeather_ShowDebugTextAllClients;
  482.                         };
  483.                     };
  484.                 }
  485.                 else {
  486.                     if (drn_var_DynamicWeather_rain != 0) then {
  487.                         drn_var_DynamicWeather_rain = 0;
  488.                         publicVariable "drn_var_DynamicWeather_rain";
  489.  
  490.                         if (_debug) then {
  491.                             ["Rain stops due to low overcast."] call drn_fnc_DynamicWeather_ShowDebugTextAllClients;
  492.                         };
  493.                     };
  494.  
  495.                     _nextRainEventTime = diag_tickTime;
  496.                     _forceStop = false;
  497.                 };
  498.  
  499.                 if (_debug) then {
  500.                     sleep 1;
  501.                 }
  502.                 else {
  503.                     SLEEP_REALTIME(20);
  504.                 };
  505.             };
  506.         };
  507.     };
  508. };
  509.  
  510. // is actually rain thread (#2)
  511. if (!isNil "drn_DynamicWeather_FogThread") then { terminate drn_DynamicWeather_FogThread };
  512. drn_DynamicWeather_FogThread = [_rainIntervalRainProbability, _debug] spawn
  513. {
  514.     params ["_rainIntervalRainProbability", "_debug"];
  515.     private ["_rain", "_rainPerSecond"];
  516.  
  517.     if (_debug) then {
  518.         _rainPerSecond = 0.2;
  519.     }
  520.     else {
  521.         _rainPerSecond = 0.03;
  522.     };
  523.  
  524.     if (_rainIntervalRainProbability > 0) then {
  525.         _rain = 0 max drn_var_DynamicWeather_Rain min 1;
  526.     }
  527.     else {
  528.         _rain = 0;
  529.     };
  530.  
  531.     //0 setRain _rain;
  532.     //0 setFog [fog max (_rain / 4), 0.0, 0]; // do not change fog decay/base otherwise the fog level will vary unpredictably
  533.     sleep 0.1;
  534.  
  535.     while {true} do {
  536.         /*if (_rainIntervalRainProbability > 0) then {
  537.             if (_rain < drn_var_DynamicWeather_Rain) then {
  538.                 _rain = _rain + _rainPerSecond;
  539.                 if (_rain > 1) then { _rain = 1; };
  540.             };
  541.             if (_rain > drn_var_DynamicWeather_Rain) then {
  542.                 _rain = _rain - _rainPerSecond;
  543.                 if (_rain < 0) then { _rain = 0; };
  544.             };
  545.         }
  546.         else {
  547.             _rain = 0;
  548.         };*/
  549.  
  550.         _rain = drn_var_DynamicWeather_Rain;
  551.  
  552.         if (round (rain * 100) != round (_rain * 100) || round (fog * 100) < round ((rain / 4) * 100)) then
  553.         {
  554.             if (overcast >= 0.75) then
  555.             {
  556.                 10 setRain _rain;
  557.  
  558.                 if (fog < _rain / 4) then
  559.                 {
  560.                     10 setFog [_rain / 4, 0.0, 0]; // do not change fog decay/base otherwise the fog level will vary unpredictably
  561.                 };
  562.             }
  563.             else
  564.             {
  565.                 if (rain > 0) then
  566.                 {
  567.                     10 setRain 0;
  568.                     drn_var_DynamicWeather_Rain = 0;
  569.                     drn_DynamicWeatherEventArgs call drn_fnc_DynamicWeather_SetWeatherLocal;
  570.                 };
  571.             };
  572.         };
  573.  
  574.         /*_tempFog = fog max (_rain / 4);
  575.         if (_tempFog > fog + 0.001 || _tempFog < fog - 0.001) then
  576.         {
  577.             (10 * timeMultiplier) setFog [_tempFog, 0.0, 0]; // do not change fog decay/base otherwise the fog level will vary unpredictably
  578.         };*/
  579.  
  580.         SLEEP_REALTIME(10);
  581.     };
  582. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement