Jump to content
Sign in to follow this  
X14Halo

Volumetric clouds in ARMA 3?

Recommended Posts

So, I'm working through this, and got some of it working. I've gotten to the point where players can choose initial weather and it shows up on all initial players machines and on the server. Additionally, I've got it set to change every hour or so, but it's messy and the new commands are tough to work with.

Couple of things I've figured out.

1) setOvercast does not create clouds. All it does is 'darken' the amount of sun that appears to be reaching the ground.

2) simulSetHumidity actually creates the clouds and the rain, but appears to rely on it being overcast enough (not sure of the minimum level) for rain to occur.

3) setOvercast appears to need the 'skipTime -24' / 'skipTime 24' trick to set the Overcast level correctly at mission start, setHumidity does not.

4) You need both setOvercast and simulSetHumidity to be high for it to actually rain.

Examples:

- Overcast 0, Humidity 0 will be bright and sunny on the ground and have no clouds in the sky.

- Overcast 1, Humidity 0 will appear very dark on the ground and the sky will be hazy, but there won't be a cloud in the sky.

- Overcast 0, Humidity 1 will appear very sunny on the ground, but the sky will be loaded with clouds.

- Overcast 1, Humidity 1 will appear dark on the ground, the sky will be loaded with clouds, and it will start to rain after about 10 seconds.

Here's what I have so far:

/*  randomWeather.sqf v 0.1
By Meatball

Script Requirements:

1) Place script as "randomWeather.sqf" in root mission folder.

2) Have a simple call in init.sqf that will run on server and all clients.  
execVM "randomWeather.sqf";

3) Have the following listed as a selectable parameter in description.ext

// paramsArray[0]
      class initialWeather {
         title = "Initial Weather";
         values[] = {0,1,2,3,4,5,6};
         texts[] = {"Clear","Overcast","Light Rain","Heavy Rain","Light Fog","Heavy Fog","Random"};
         default = 0;
      }; 

*/

// JIP Check
if (!isServer && isNull player) then {isJIP=1;} else {isJIP=0;};

if(isServer) then {
// Set initial Weather from Parameter options chosen by players.
initialWeather = (paramsArray select 0);
switch (initialWeather) do{
case 0: {initialCloud = 0;initialRain = 0;initialFog = 0;};								// Clear
case 1: {initialCloud = .65;initialRain = .50;initialFog = 0;};							// Overcast
case 2: {initialCloud = .80;initialRain = .80;initialFog = .05;};						// Light Rain
case 3: {initialCloud = 1;initialRain = 1;initialFog = .05;};							// Heavy Rain
case 4: {initialCloud = .75;initialRain = .10;initialFog = .30;};						// Light Fog
case 5: {initialCloud = .85;initialRain = .20;initialFog = .50;};						// Heavy Fog
case 6: {initialCloud = random(1);initialRain = random(1);initialFog = random(.25);};	// Random
};

// Create a random weather forecasts based off current conditions and make sure they stay within proper limits (Rain/Clouds: 0-1, Fog: 0 - .5)
_randCloud = round ((random(1)-0.5)*(10^2))/(10^2);
_randRain = round ((random(1)-0.5)*(10^2))/(10^2);
_randFog = round ((random(0.5)-0.25)*(10^2))/(10^2);
_randCloud2 = round ((random(1)-0.5)*(10^2))/(10^2);
_randRain2 = round ((random(1)-0.5)*(10^2))/(10^2);
_randFog2 = round ((random(0.5)-0.25)*(10^2))/(10^2);

// Create random overcast/cloud level forecasts	
forecastCloud = initialCloud + _randCloud;
if (forecastCloud > 1) then {forecastCloud = forecastCloud - (2*_randCloud)};
if (forecastCloud < 0) then {forecastCloud = forecastCloud + (abs(2*_randCloud))};

forecastCloud2 = forecastCloud + _randCloud2;
if (forecastCloud2 > 1) then {forecastCloud2 = forecastCloud2 - (2*_randCloud2)};
if (forecastCloud2 < 0) then {forecastCloud2 = forecastCloud2 + (abs(2*_randCloud2))};

// Create random rain/humidity level forecasts	
forecastRain = initialRain + _randRain;
if (forecastRain > 1) then {forecastRain = forecastRain - (2*_randRain)};
if (forecastRain < 0) then {forecastRain = forecastRain + (abs(2*_randRain))};

forecastRain2 = forecastRain + _randRain2;
if (forecastRain2 > 1) then {forecastRain2 = forecastRain2 - (2*_randRain2)};
if (forecastRain2 < 0) then {forecastRain2 = forecastRain2 + (abs(2*_randRain2))};

// Create random fog level forecasts	
forecastFog = initialFog + _randFog;
if (forecastFog > 0.6) then {forecastFog = forecastFog - (2*_randFog)};
if (forecastFog < 0) then {forecastFog = forecastFog + (abs(2*_randFog))};

forecastFog2 = forecastFog + _randFog2;
if (forecastFog2 > 0.6) then {forecastFog2 = forecastFog2 - (2*_randFog2)};
if (forecastFog2 < 0) then {forecastFog2 = forecastFog2 + (abs(2*_randFog2))};

// Broadcast Initial Weather settings
publicVariable "initialCloud";
publicVariable "initialRain";
publicVariable "initialFog";
// Broadcast 60 Minute Forecast
publicVariable "forecastCloud";
publicVariable "forecastRain";
publicVariable "forecastFog";
// Broadcast 120 Minute Forecast
publicVariable "forecastCloud2";
publicVariable "forecastRain2";
publicVariable "forecastFog2";
};

// Wait until initial and forecast weather settings are setup.
waitUntil {!isnil "forecastFog2"};

// Debug Hint
// hint format ["IC: %1 | IR: %2 | IF: %3 | FC: %4 | FR: %5 | FF: %6 | FC2: %7 | FR2: %8 | FF2: %9",initialCloud,initialRain,initialFog,forecastCloud,forecastRain,forecastFog,forecastCloud2,forecastRain2,forecastFog2];

// Set up initial Weather for Server/non JIP Players, but keep on same date. (Skiptime commands required for immediate cloud/humidity level changes)
if (isServer or isJIP == 0) then {
skipTime -24;
86400 setOvercast initialCloud;
86400 setFog initialFog;
simulSetHumidity initialRain;
skipTime 24;

// Set up 60 minute Forecast weather after short delay.
sleep 60;
3600 setOvercast forecastCloud;
3600 setFog forecastFog;
sleep 3600;
simulSetHumidity forecastRain;
// Set up 120 minute Forecast weather after short delay.
sleep 60;
3600 setOvercast forecastCloud2;
3600 setFog forecastFog2;
sleep 3600;
simulSetHumidity forecastRain2;
// Set up 180 minute Forecast weather after short delay.	
sleep 60;
3600 setOvercast initialCloud;
3600 setFog initialFog;
sleep 3600;
simulSetHumidity initialRain;
};

// Set up weather for JIP players
if (isJIP == 1) then {
sleep 60;
// Set up 60 minute Forecast weather after short delay.
(3660 - serverTime) setOvercast forecastCloud;
(3660 - serverTime) setFog forecastFog;
sleep (3660	- serverTime);
simulSetHumidity forecastRain;
// Set up 120 minute Forecast weather after short delay.	
sleep 60;
(7320 - serverTime) setOvercast forecastCloud2;
(7320 - serverTime) setFog forecastFog2;
sleep (7320 - serverTime);
simulSetHumidity forecastRain2;
// Set up 180 minute Forecast weather after short delay.
sleep 60;
(10980 - serverTime) setOvercast initialCloud;
(10980 - serverTime) setFog initialFog;
sleep (10980 - serverTime);
simulSetHumidity initialRain;	
};

This script is butt ugly and I'm sure the code could be written a lot more efficiently/cleaner. I'm just learning and any input is appreciated. The script does allow the players to select the starting mission weather and correctly sets that up for all players at mission start. It also appears to correctly 'adjust' the weather at the 60 minute intervals I've set on the server and the originally connected player clients. I have run into two issues so far though.

1) setSimulHumidity appears to work almost immediately when called. So while overCast, Fog and Wind can slowly be transitioned over a set period of time, Humidity needs to be set to fire at the end of the transition period, and honestly, it looks a bit goofy with the clouds/rain just stopping all of a sudden whereas the other weather aspects have a smooth transition over time.

2) Almost positive that the JIP code does not work correctly, and I've yet to be able to test it.

---------- Post added at 19:51 ---------- Previous post was at 19:37 ----------

Quick update, to test it out, I created two dummy radio triggers on a map with 0 overcast set as a default. Radio Alpha I set to run "0 setOvercast 1;" and radio Bravo I set to run repeatedly "hint format["Current OC Level: %1",overcast];"

I started the mission, ran the bravo radio and it came back with 0 overcast. Ran Alpha and then I saw the overcast level slowly increasing from 0 upwards. After 1 minute it had gone from 0 to 0.0167569.

Which means, you need almost exactly an hour for the engine to go from Overcast 0 to Overcast 1, even if you have it set to delay of 0.

On the flip side, set two radio triggers up (that both can both run repeatedly) with "simulSetHumidity 0;" and "simulSetHumidity 1;" as the action and you can watch the clouds pop in and pop out immediately on the trigger.

Edited by Meatball

Share this post


Link to post
Share on other sites

Ooo... sweet. Much appreciated Meatball. I'll definitely put it on our servers this evening and have a go at it. I'm not 100% but from a quick look I think it'll probably work as intended, as is. I normally check JIP players against a nil value like so:

if (!isNil "jip") exitWith {other foo};

But yeah, either way, will test it out. :D

Share this post


Link to post
Share on other sites

Sounds good, let me know how it goes.

JIP is a problem for sure. I _think_ they should get the correct/current weather from the server when they connect. The problem is how to keep them in synch with the random changes. So, say they connect 45 minutes in, they'll problem get all the same weather everyone else is seeing at that time, but in 15 minutes when everyone else changes, I don't know if they'll get that correctly.

Right now the script sets original weather, and then the first random weather to kick in at 60 minutes, 2nd to kick in at 120 minutes and then it goes back to the original weather at 180 minutes. It won't change after that point, which is fine in my mission because it shouldn't last much more than 3-4 hours, but in other missions that may be in an issue. I'm sure there's a better way to do that so it would continuously loop through random changes, and I might try to figure that out.

I bet some of the skilled scripters out there are looking at mine and going, "What the heck is this guy thinking, he's doing it all wrong!" :)

Edited by Meatball

Share this post


Link to post
Share on other sites

Set up a really simple weather test mission if anyone wants to mess with it. Use the radio to setRain, setOvercast and simulSetHumidity as well as advance the skipTime by 1 minute blocks.

https://dl.dropboxusercontent.com/u/64136645/Testweather.Stratis.pbo.zip

setOvercast seems to be the key to weather as you can set humidity to 1 or rain to 1 and nothing will happen until overcast reaches a certain point. Be nice if someone from BIS actually posted up the 'rules' of the weather functions so we could work up some scripts :)

Share this post


Link to post
Share on other sites
Are you sure they are local? They take time to work so you need to fast forward time to see instant results.

Hi ProGamer,

Feel free to try it yourself. A quick simple test is to put two playable units in a map (say called UNIT1 & UNIT2), and in the init.sqf file, add the commands "0 setOvercast 1; simulsethumidity 1; setDate [(date select 0),(date select 1),(date select 2),(date select 3) + 1,(date select 4)]" to execute only for one of them (IF player== UNIT1). Grab a buddy, jump on a dedicated server and see what happens.

As far I can see, setting time & weather, advancing time, etc... yes. The commands that change weather via scripting after mission start appear to only show the effect locally where those commands are executed. However, i do not work for BIS, i don't have access to any of their documentation on the matter and i haven't tested for the past two nights dev updates but this is my conclusion based on the observations, I'll let you decide for yourself.

Share this post


Link to post
Share on other sites

Updated my script and cleaned a few things up/added some more comments to help clarify things. Still no idea if JIP weather will work the way I have it set.

/*  randomWeather.sqf v 0.2
By Meatball

Script Requirements:

1) Put this code/script in a file named "randomWeather.sqf" in root mission folder.

2) Create a call in init.sqf that will run on the server and all clients.
execVM "randomWeather.sqf";

3) Have the following code in the "class Params" section of your description.ext to create weather as a selectable parameter for the players.  

// paramsArray[0]
      class initialWeather {
         title = "Initial Weather";
         values[] = {0,1,2,3,4,5,6};
         texts[] = {"Clear","Overcast","Light Rain","Heavy Rain","Light Fog","Heavy Fog","Random"};
         default = 0;
      }; 

*/

// JIP Check
if (!isServer && isNull player) then {isJIP=1;} else {isJIP=0;};

// Set initial Weather from Parameter options chosen by players.
if(isServer) then {

// Make sure the # in the select below matches what # your initialWeather class is in the description.ext
initialWeather = (paramsArray select 5);  
switch (initialWeather) do{
case 0: {initialOvercast = 0;initialHumidity = 0;initialFog = 0;};								// Clear
case 1: {initialOvercast = .65;initialHumidity = .50;initialFog = 0;};							// Overcast
case 2: {initialOvercast = .80;initialHumidity = .80;initialFog = .05;};						// Light Rain
case 3: {initialOvercast = 1;initialHumidity = 1;initialFog = .05;};							// Heavy Rain
case 4: {initialOvercast = .75;initialHumidity = .10;initialFog = .30;};						// Light Fog
case 5: {initialOvercast = .85;initialHumidity = .20;initialFog = .50;};						// Heavy Fog
case 6: {initialOvercast = random(1);initialHumidity = random(1);initialFog = random(.25);};	// Random
};

// Create two random weather forecasts based off current conditions and keep values within proper limits (Overcast/Humidity: 0 - 1, Fog: 0 - 0.5)
_randOvercast = round ((random(1)-0.5)*(10^2))/(10^2);
_randHumidity = round ((random(1)-0.5)*(10^2))/(10^2);
_randFog = round ((random(0.5)-0.25)*(10^2))/(10^2);
_randOvercast2 = round ((random(1)-0.5)*(10^2))/(10^2);
_randHumidity2 = round ((random(1)-0.5)*(10^2))/(10^2);
_randFog2 = round ((random(0.5)-0.25)*(10^2))/(10^2);

// Create two random overcast level forecasts and keep between 0 and 1
forecastOvercast = initialOvercast + _randOvercast;
if (forecastOvercast > 1) then {forecastOvercast = forecastOvercast - (2*_randOvercast)};
if (forecastOvercast < 0) then {forecastOvercast = forecastOvercast + (abs(2*_randOvercast))};

forecastOvercast2 = forecastOvercast + _randOvercast2;
if (forecastOvercast2 > 1) then {forecastOvercast2 = forecastOvercast2 - (2*_randOvercast2)};
if (forecastOvercast2 < 0) then {forecastOvercast2 = forecastOvercast2 + (abs(2*_randOvercast2))};

// Create two random humidity level forecasts and keep between 0 and 1
forecastHumidity = initialHumidity + _randHumidity;
if (forecastHumidity > 1) then {forecastHumidity = forecastHumidity - (2*_randHumidity)};
if (forecastHumidity < 0) then {forecastHumidity = forecastHumidity + (abs(2*_randHumidity))};

forecastHumidity2 = forecastHumidity + _randHumidity2;
if (forecastHumidity2 > 1) then {forecastHumidity2 = forecastHumidity2 - (2*_randHumidity2)};
if (forecastHumidity2 < 0) then {forecastHumidity2 = forecastHumidity2 + (abs(2*_randHumidity2))};

// Create two random fog level forecasts and keep between 0 and 0.6
forecastFog = initialFog + _randFog;
if (forecastFog > 0.6) then {forecastFog = forecastFog - (2*_randFog)};
if (forecastFog < 0) then {forecastFog = forecastFog + (abs(2*_randFog))};

forecastFog2 = forecastFog + _randFog2;
if (forecastFog2 > 0.6) then {forecastFog2 = forecastFog2 - (2*_randFog2)};
if (forecastFog2 < 0) then {forecastFog2 = forecastFog2 + (abs(2*_randFog2))};

// Broadcast Initial Weather settings from Parameters Selection
publicVariable "initialOvercast";
publicVariable "initialHumidity";
publicVariable "initialFog";
// Broadcast 60 Minute Random Forecast
publicVariable "forecastOvercast";
publicVariable "forecastHumidity";
publicVariable "forecastFog";
// Broadcast 120 Minute Random Forecast
publicVariable "forecastOvercast2";
publicVariable "forecastHumidity2";
publicVariable "forecastFog2";
};

// Wait until initial and forecast weather forecasts are set up.
waitUntil {!isnil "forecastFog2"};

// Debug Hint
// hint format ["IO: %1 | IH: %2 | IF: %3 | FO: %4 | FH: %5 | FF: %6 | FO2: %7 | FH2: %8 | FF2: %9",initialOvercast,initialHumidity,initialFog,forecastOvercast,forecastHumidity,forecastFog,forecastOvercast2,forecastHumidity2,forecastFog2];

// Set up initial Weather for the server and non-JIP Players, but keep on same date. (Skiptime commands are required for immediate humidity level changes)
if (isServer or isJIP == 0) then {
skipTime -24;
86400 setOvercast initialOvercast;
86400 setFog initialFog;
simulSetHumidity initialHumidity;
skipTime 24;

// Set up 60 minute forecast weather after short delay.
sleep 60;
3600 setOvercast forecastOvercast;
3600 setFog forecastFog;
sleep 3600;
simulSetHumidity forecastHumidity;
// Set up 120 minute forecast weather after short delay.
sleep 60;
3600 setOvercast forecastOvercast2;
3600 setFog forecastFog2;
sleep 3600;
simulSetHumidity forecastHumidity2;
// Set up 180 minute forecast weather after short delay.	
sleep 60;
3600 setOvercast initialOvercast;
3600 setFog initialFog;
sleep 3600;
simulSetHumidity initialHumidity;
};

// Set up weather for JIP players (Work in Progress, not sure it works)
if (isJIP == 1) then {
// If server has been running less than 60 minutes, Set up 60 minute forecast weather.
if ((3660 - serverTime) > 0) then {
(3660 - serverTime) setOvercast forecastOvercast;
(3660 - serverTime) setFog forecastFog;
sleep (3660	- serverTime);
simulSetHumidity forecastHumidity;
};
// If server has been running less than 120 minutes, Set up 120 minute forecast weather.	
if ((7320 - serverTime) > 0) then {
(7320 - serverTime) setOvercast forecastOvercast2;
(7320 - serverTime) setFog forecastFog2;
sleep (7320 - serverTime);
simulSetHumidity forecastHumidity2;
};
// If server has been running less than 180 minutes, Set up 180 minute forecast weather.
if ((10980 - serverTime) > 0) then {
(10980 - serverTime) setOvercast initialOvercast;
(10980 - serverTime) setFog initialFog;
sleep (10980 - serverTime);
simulSetHumidity initialHumidity;
};
};

Share this post


Link to post
Share on other sites

Looks good Meatball, will keep an eye out for progress.

So is the Dynamic Weather mod not keeping JIP in sync?

Share this post


Link to post
Share on other sites

I don't think the Dynamic Weather mod works at all in A3 with the new humidity/cloud setup. I haven't been able to get it to work, but maybe someone else has. And if they have, please share, I'd love to just use that. :)

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
Sign in to follow this  

×