Jump to content
Sign in to follow this  
csk222

Change Weather on Dedicated Server

Recommended Posts

I am hoping someone can help me or guide me in the right direction with changing the weather on a dedicated server. I get the following to work in the editor and when I host on my PC, but not on the dedicated server.

---

Example:

 teg_fnc_rain = {
private ["_text","_1","_msg"];
_text = "<t size='1'>" + "Rain" + "<br />" + "<t size='1.5'>" + "Mission Weather Change" + "</t>" + "<br />" + "<img size='4' image='images\a3_bombadge2.paa'/>" + "</t>";
_1 =[_text,0.01,0.01,10,-1,0,90]spawn bis_fnc_dynamicText;

cuttext ["","black out"];
1 fadesound 0;
sleep 1; 

skipTime -24;
0 setOvercast 1;
0 setRain 1;
0 setFog 1;
skipTime 24;
sleep 1;
simulWeatherSync;

2 fadesound 1;
sleep 2;
cuttext ["","black in"];
};

---

This is a working script we use to change the time of day on the dedicated server. I would like to use something similar to this but with weather changes.

teg_fnc_morningMsg = {
		private ["_text","_1","_msg"];			
		_text = "<t size='1'>" + "Morning" + "<br />" + "<t size='1.5'>" + "Mission Time Change" + "</t>" + "<br />" + "<img size='4' image='images\a3_bombadge2.paa'/>" + "</t>";
		_1 =[_text,0.01,0.01,10,-1,0,90]spawn bis_fnc_dynamicText;

		_date = date;
		_date set [3,05]; //--- new hour (18)
		_date set [4,05]; //--- new minute (35)

		cuttext ["","black out"];
		1 fadesound 0;
		sleep 1;

		_showtime = [
			date,  //--- Start time
			_date,   //--- End time
			95     //--- Counter speed
		] call bis_fnc_showTime;

		[[[_date], { setDate (_this select 0) }], "BIS_fnc_spawn"] call BIS_fnc_MP;;
		2 fadesound 1;
		sleep 2;

		_showtime cuttext ["","black in"];
		cuttext ["","black in"];
};

Edited by csk222

Share this post


Link to post
Share on other sites

I'm pretty bad with multiplayer scripting, but, why not just log in as admin and set your commands on the debug console?

Share this post


Link to post
Share on other sites

I've never done it that way but I'll give it a try. I would prefer to have a script to do it. I'm basically looking for a script and or the lines of code needed to make "0 setRain 1;" work in a dedicated server. I can try to figure out the rest, I want the effect to be instant. We use an in game GUI Tablet that allows us to select settings. Thanks for your suggestion.

Share this post


Link to post
Share on other sites
I'm pretty bad with multiplayer scripting

^Keep this in mind when I give you this code.

I think the best way to do this would be using a Public Variable Event Handler since both setRain and setOvercast are local commands.

rainBool = false;

"rainBool" addPublicVariableEventHandler
{
[] spawn { //spawn a new thread to make sure sleep commands are executed even if a non-scheduled evironment

	_rainBool = _this select 1;
	if (_rainBool == true) then
	{
		10 setOvercast 1;
		//it can only rain if overcast is 0.7 or higher
		sleep 11; //make 1 second longer to make sure the cloud coverage is enough to allow rain
		10 setRain 1;
	} else //since rainBool is type Boolean, only other option is false
	{
		10 setRain 0;
		sleep 11; //turns off rain first. I did this to prevent unknown happenings (like rain auto-turning off because no clouds)
		10 setOvercast 0;
	};
};
};

Now, in case you've never used a publicVariableEventHandler before, you will need to publicVariable the variable, which broadcasts it over the network to all players, like this

rainBool is currently false
(some stuff happens, certain conditions are met, and youve written code that decided it should start raining now)

rainBool = true;
publicVariable "rainBool";

publicVariable goes to all computers (including server) and their "rainBool" event handler goes into action. Being that rainBool is true, clouds cover the sky and rain begins to fall.

When I tried using publicVariable, it didn't work. But I think I explained how it works right.

Edited by DreadedEntity

Share this post


Link to post
Share on other sites

If you're pretty bad that's a whole lot better than me. I'm willing to try any method as long as it achieves the weather change.

Where do I place those codes? in an sqf? init?

Share this post


Link to post
Share on other sites

Rain and clouds have a local effect so that code will need to be run on every client in a mission. Put it in your init.sqf

Share this post


Link to post
Share on other sites

I don't know if I did everything right (I think I did), but nothing worked. Thanks for your suggestion.

---

This works properly for mission time change on the dedicated server. Is there nothing similar to the following that will work for weather? Maybe this can be tweaked to work with weather?

teg_fnc_morningMsg = {
private ["_text","_1","_msg"]; 
_text = "<t size='1'>" + "Morning" + "<br />" + "<t size='1.5'>" + "Mission Time Change" + "</t>" + "<br />" + "<img size='4' image='images\a3_bombadge2.paa'/>" + "</t>";
_1 =[_text,0.01,0.01,10,-1,0,90]spawn bis_fnc_dynamicText;

_date = date;
_date set [3,05]; //--- new hour (18)
_date set [4,05]; //--- new minute (35)

cuttext ["","black out"];
1 fadesound 0;
sleep 1;

_showtime = [
date, //--- Start time
_date, //--- End time
95 //--- Counter speed
] call bis_fnc_showTime;

[[[_date], { setDate (_this select 0) }], "BIS_fnc_spawn"] call BIS_fnc_MP;;
2 fadesound 1;
sleep 2;

_showtime cuttext ["","black in"];
cuttext ["","black in"];
}; 

From my understanding the above is a function.? It is called from our in game GUI like this

 	class btnD1: mop_RscButton
{
	idc = 1671;

	action = "closeDialog 0;[[],'teg_fnc_morningMsg',true,true] call BIS_fnc_MP;";
	text = "Dawn (5AM)"; //--- ToDo: Localize;
	x = 0.1945;
	y = 0.0900;
	w = 0.190;
	h = 0.045;
	tooltip = "Change to Morning"; //--- ToDo: Localize;
};

There has to be a way to do the same thing for weather (or at least I hope there is).

Edited by csk222

Share this post


Link to post
Share on other sites

Sorry, I'm really just too inexperienced with multiplayer scripting. We'll just have to wait for someone more experienced to come along and help us out. I'm interested in the answer now, too.

Share this post


Link to post
Share on other sites

Hopefully someone will come along and make this happen. Even if it doesn't get done the way I "picture" above, any solution would be acceptable. Maybe even individual .sqf files for each weather setting (Rain [High], Rain [Low], Cloudy No Rain, Fog [High], Fog [Low], Clear. Anything that works on a dedicated server - Anything.

Share this post


Link to post
Share on other sites

 teg_fnc_rain = { 
private ["_text","_1","_msg"]; 
_text = "<t size='1'>" + "Rain" + "<br />" + "<t size='1.5'>" + "Mission Weather Change" + "</t>" + "<br />" + "<img size='4' image='images\a3_bombadge2.paa'/>" + "</t>"; 
_1 =[_text,0.01,0.01,10,-1,0,90]spawn bis_fnc_dynamicText; 

cuttext ["","black out"]; 
1 fadesound 0; 
sleep 1;  

skipTime -24; 
0 setOvercast 1; 
0 setRain 1; 
0 setFog 1; 
skipTime 24; 
sleep 1; 
simulWeatherSync; 

2 fadesound 1; 
sleep 2; 
cuttext ["","black in"]; 
};  

As I stated above, I get this to work on NON DEDICATED SERVERS. I'm basically looking for a function that will allow instant weather change; Or any weather change for that matter...

Here's video I made as an example:

Share this post


Link to post
Share on other sites

I see you're broadcasting a message function on button press with bis_fnc_mp. Why not execute the weather function on all clients aswell?

[ [ Arguments ], "teg_fnc_rain", true, true ] call BIS_fnc_MP;

Share this post


Link to post
Share on other sites
I see you're broadcasting a message function on button press with bis_fnc_mp. Why not execute the weather function on all clients aswell?

[ [ Arguments ], "teg_fnc_rain", true, true ] call BIS_fnc_MP;

^^this will be the way to go about it^^ The only possible problem with the above is that BIS_fnc_MP doesn't propagate a function declared like: <funcname> = {code} unless you specifically tell it to.

I will be interested to see if it works. If it doesn't, try setting up the function in the description.ext or (if you aren't sure how) call fnc mp like: [[[],teg_fnc_rain],"spawn",TRUE,false] call bis_fnc_mp;

But, be aware that this will propagate the function code over the network, not just the name. (if you change the last FALSE to TRUE then any player that joins will also have the weather set to rain.)

Edited by TKTom

Share this post


Link to post
Share on other sites

Can you explain a bit further or give examples.

This is how the teg_fnc_rain is already being called:

	idc = 1680;

	action = "closeDialog 0;[[],'teg_fnc_rain',true,true] call BIS_fnc_MP;";
	text = "Rain"; //--- ToDo: Localize;
	x = 0.1945;
	y = 0.2700;
	w = 0.190;
	h = 0.045;
	tooltip = "Change Weather to Rain"; //--- ToDo: Localize;
};

Which looks like what you're telling me to do. What should/would the "Arguments" be? Or simply put, what do I do?

Share this post


Link to post
Share on other sites

The arguments are the parameters being passed into your function (teg_fnc_rain), or at least I think so, or at least that's how I understand the wiki page on BIS_fnc_MP.

Share this post


Link to post
Share on other sites

I'll try to explain this as best as I can and what & where I think the solution may be found. I just don't know how to "construct" the proper wording/coding to make it happen.

---

This is what calls the TIME CHANGE function (Button Press).

	class btnD1: mop_RscButton
{
	idc = 1671;

	action = "closeDialog 0;[[],'teg_fnc_morningMsg',true,true] call BIS_fnc_MP;";
	text = "Dawn (5AM)"; //--- ToDo: Localize;
	x = 0.1945;
	y = 0.0900;
	w = 0.190;
	h = 0.045;
	tooltip = "Change to Morning"; //--- ToDo: Localize;
};

---

This is the TIME CHANGE function.

teg_fnc_morningMsg = 
{
	private ["_text","_1","_msg"];			

	_text = "<t size='1'>" + "Morning" + "<br />" + "<t size='1.5'>" + "Mission Time Change" +
	"</t>" + "<br />" + "<img size='4' image='images\a3_bombadge2.paa'/>" + "</t>";

	_1 =[_text,0.01,0.01,10,-1,0,90]spawn bis_fnc_dynamicText;

	_date = date;
	_date set [3,05]; //--- new hour (18)
	_date set [4,05]; //--- new minute (35)

	cuttext ["","black out"];
	1 fadesound 0;
	sleep 1;

	[[[_date], { setDate (_this select 0) }], "BIS_fnc_spawn"] call BIS_fnc_MP;;

	2 fadesound 1;
	sleep 2;
	cuttext ["","black in"];
};

---

This is what calls the WEATHER CHANGE function (Button Press).

	class btnD10: mop_RscButton
{
	idc = 1680;

	action = "closeDialog 0;[[],'teg_fnc_rain',true,true] call BIS_fnc_MP;";
	text = "Rain"; //--- ToDo: Localize;
	x = 0.1945;
	y = 0.2700;
	w = 0.190;
	h = 0.045;
	tooltip = "Change Weather to Rain"; //--- ToDo: Localize;
};

---

This is the WEATHER CHANGE function.

teg_fnc_rain =
{
	private ["_text","_1","_msg"];
	_text = "<t size='1'>" + "Rain" + "<br />" + "<t size='1.5'>" + "Mission Weather Change" +
	"</t>" + "<br />" + "<img size='4' image='images\a3_bombadge2.paa'/>" + "</t>";

	_1 =[_text,0.01,0.01,10,-1,0,90]spawn bis_fnc_dynamicText;

	cuttext ["","black out"];
	1 fadesound 0;
	sleep 1;	

	skipTime -24;
	0 setOvercast 1;
	0 setRain 1;
	0 setFog 1;
	skipTime 24;
	sleep 1;
	simulWeatherSync;

	2 fadesound 1;
	sleep 2;
	cuttext ["","black in"];
};

---

Hybrid of the two aforementioned functions.

teg_fnc_rain = 
{
	private ["_text","_1","_msg"];			

	_text = "<t size='1'>" + "Rain" + "<br />" + "<t size='1.5'>" + "Mission Weather Change" +
	"</t>" + "<br />" + "<img size='4' image='images\a3_bombadge2.paa'/>" + "</t>";

	_1 =[_text,0.01,0.01,10,-1,0,90]spawn bis_fnc_dynamicText;

// Everything above works properly //

// ?? The following section is where the proper coding is needed ?? //		

	//_date = date;
	//_date set [3,05]; //--- new hour (18)

	skipTime -24; // This is needed somewhere in here//

	_overcast = overcast;
	_overcastset set []; // ????????????????? HELP!

	_rain = rain;
	_rain set []; // ????????????????? HELP!

	_fog = fog;
	_fog set []; // ????????????????? HELP!

	skipTime 24; // This is needed somewhere in here//

	simulWeatherSync; // This is needed somewhere in here//

// These next 3 lines work properly//

	cuttext ["","black out"];
	1 fadesound 0;
	sleep 1;

// The next line is probably the critical line that brings everything together//

	//[[[_date], { setDate (_this select 0) }], "BIS_fnc_spawn"] call BIS_fnc_MP;;
	[[[_???], { set??? (_this select 0) }], "BIS_fnc_spawn"] call BIS_fnc_MP;; // ????????????????? HELP!

// Everything below this works properly //

	2 fadesound 1;
	sleep 2;
	cuttext ["","black in"];
};

---

Resources/Links:

https://community.bistudio.com/wiki/setOvercast

https://community.bistudio.com/wiki/overcast

https://community.bistudio.com/wiki/setRain

https://community.bistudio.com/wiki/rain

https://community.bistudio.com/wiki/setFog

https://community.bistudio.com/wiki/fog

https://community.bistudio.com/wiki/simulWeatherSync

https://community.bistudio.com/wiki/BIS_fnc_spawn

https://community.bistudio.com/wiki/BIS_fnc_MP

---

I have also been looking through "weather" scripts to see what they look like.

Real Weather Scipt

private ["_lastrain", "_rain", "_fog", "_mintime", "_maxtime", "_overcast", "_realtime", "_random", "_skiptime", "_startingdate", "_startingweather", "_timeforecast", "_timeratio", "_timesync", "_wind"];

// Real time vs fast time
// true: Real time is more realistic weather conditions change slowly (ideal for persistent game)
// false: fast time give more different weather conditions (ideal for non persistent game) 
_realtime = false;

// Random time before new forecast
// true: forecast happens bewteen mintime and maxtime
// false: forecast happens at mintime
_random = false;

// Min time seconds (real time) before a new weather forecast
_mintime = 600;

// Max time seconds (real time) before a new weather forecast
_maxtime = 1200;

// If Fastime is on
// Ratio 1 real time second for x game time seconds
// Default: 1 real second = 3.6 second in game
_timeratio = 3.6;

// send sync data across the network each xxx seconds
// 60 seconds by default is a good value
// shortest time do not improve weather sync
_timesync = 60;

// Mission starting date is 25/09/2013 at 12:00
_startingdate = [2013, 09, 25, 12, 00];

// Mission starting weather "CLEAR|CLOUDY|RAIN";
_startingweather = "CLEAR";

/////////////////////////////////////////////////////////////////
// Do not edit below
/////////////////////////////////////////////////////////////////

if(_mintime > _maxtime) exitwith {hint format["Real weather: Max time: %1 can no be higher than Min time: %2", _maxtime, _mintime];};
_timeforecast = _mintime;

// we check the skiptime for 10 seconds
_skiptime = _timeratio * 0.000278 * 10;

setdate _startingdate;
switch(toUpper(_startingweather)) do {
	case "CLEAR": {
		wcweather = [0, 0, 0, [random 3, random 3, true], date];
	};

	case "CLOUDY": {
		wcweather = [0, 0, 0.6, [random 3, random 3, true], date];
	};

	case "RAIN": {
		wcweather = [1, 0, 1, [random 3, random 3, true], date];
	};

	default {
		// clear
		wcweather = [0, 0, 0, [random 3, random 3, true], date];
		diag_log "Real weather: wrong starting weather";
	};
};

// add handler
if (local player) then {
	wcweatherstart = true;
	"wcweather" addPublicVariableEventHandler {
		// first JIP synchronization
		if(wcweatherstart) then {
			wcweatherstart = false;
			skipTime -24;
			86400 setRain (wcweather select 0);
			86400 setfog (wcweather select 1);
			86400 setOvercast (wcweather select 2);
			skipTime 24;
			simulweatherSync;
			setwind (wcweather select 3);
			setdate (wcweather select 4);
		}else{
			wcweather = _this select 1;
			60 setRain (wcweather select 0);
			60 setfog (wcweather select 1);
			60 setOvercast (wcweather select 2);
			setwind (wcweather select 3);
			setdate (wcweather select 4);
		};
	};
};

// accelerate time 
if!(_realtime) then {
	[_skiptime] spawn {
		private["_skiptime"];
		_skiptime = _this select 0;

		while {true} do {
			skiptime _skiptime;
			sleep 10;
		};
	};
};

// SERVER SIDE SCRIPT
if (!isServer) exitWith{};

// apply weather
skipTime -24;
86400 setRain (wcweather select 0);
86400 setfog (wcweather select 1);
86400 setOvercast (wcweather select 2);
skipTime 24;
simulweatherSync;
setwind (wcweather select 3);
setdate (wcweather select 4);

// sync server & client weather & time
[_timesync] spawn {
	private["_timesync"];
	_timesync = _this select 0;

	while { true } do {
		wcweather set [4, date];
		publicvariable "wcweather";
		sleep _timesync;
	};
};

_lastrain = 0;
_rain = 0;
_overcast = 0;

while {true} do {
	_overcast = random 1;
	if(_overcast > 0.68) then {
		_rain = random 1;
	} else {
		_rain = 0;
	};
	if((date select 3 > 2) and (date select 3 <6)) then {
		_fog = 0.4 + (random 0.6);
	} else {
		if((_lastrain > 0.6) and (_rain < 0.2)) then {
			_fog = random 0.3;
		} else {
			_fog = 0;
		};
	};
	if(random 1 > 0.95) then {
		_wind = [random 7, random 7, true];
	} else {
		_wind = [random 3, random 3, true];
	};
	_lastrain = _rain;

	wcweather = [_rain, _fog, _overcast, _wind, date];
	60 setRain (wcweather select 0);
	60 setfog (wcweather select 1);
	60 setOvercast (wcweather select 2);
	setwind (wcweather select 3);
	if(_random) then {
		_timeforecast = _mintime + (random (_maxtime - _mintime));
	};
	sleep _timeforecast;
};

Random Weather Script

// ============
// Begin Script
// ============

// Debug Messages.  This is set to 1 for the demo mission, but you should set this to 0 for regular missions. | 0 = Debug Messages Off, 1 = Debug Messages On
rw2Debug = 0;

// If you are using settings in your description.ext to allow parameter settings for initial weather, you must update the # below to match which parameter you are using.  Remember, the ordering starts with 0 and goes up from there.
rw2Param = 0;

// Setup Weather Types Array [Weather Name, Possible Weather Forecasts, Weather Settings] - Suggested that they are left as is.

weatherTemplates = [
       ["Clear",[0,1,5],[0.30,0,0,1,1]],
       ["Overcast",[0,1,2],[0.50,0,0,2,2]],
       ["Light Rain",[1,2,3,5],[0.60,0.3,0.05,3,3]],
       ["Medium Rain",[2,3,4],[0.70,0.5,0.05,4,4]],
       ["Rainstorm",[3],[0.80,0.9,0.1,5,5]],
       ["Light Fog",[0,2,5,6],[0.4,0,[0.2,0.01,10],0,0]],
       ["Medium Fog",[5,6,7],[0.4,0,[0.4,0.005,20],0,0]],
       ["Dense Fog",[6],[0.5,0,[0.4,0.0025,30],0,0]]
];

// DO NOT EDIT BELOW THIS LINE //

// Setup Initial Weather Function
mb_fnc_InitialWeather = {
private["_weatherInitialArray","_weatherInitialSettings","_weatherInitialOvercast","_weatherInitialRainSnow","_weatherInitialFog","_weatherInitialWindEW","_weatherInitialWindNS"];

waitUntil {!isNil "rw2_Current_Weather"};
_weatherInitialArray = weatherTemplates select rw2_Current_Weather;
   weatherCurrentName = _weatherInitialArray select 0;
   _weatherInitialSettings = _weatherInitialArray select 2;

   _weatherInitialOvercast = _weatherInitialSettings select 0;
   _weatherInitialRainSnow = _weatherInitialSettings select 1;
   _weatherInitialFog = _weatherInitialSettings select 2;
   _weatherInitialWindEW = _weatherInitialSettings select 3;
   _weatherInitialWindNS = _weatherInitialSettings select 4;	

	skipTime -24;
       86400 setOvercast _weatherInitialOvercast;
       0 setRain _weatherInitialRainSnow;
       86400 setFog _weatherInitialFog;
       setWind [_weatherInitialWindEW,_weatherInitialWindNS,true];
	skipTime 24;
	sleep 1;
    simulWeatherSync;

	if (rw2Debug == 1) then {hint format ["Debug Initialized Weather - %1\nOvercast: %2\nRain/Snow: %3\nFog: %4\nWind EW|NS: %5|%6",weatherCurrentName,_weatherInitialOvercast,_weatherInitialRainSnow,_weatherInitialFog,_weatherInitialWindEW,_weatherInitialWindNS];};
};

// Setup Update Weather Function
mb_fnc_UpdateWeather = {
private ["_weatherCurrentArray","_weatherNextArray","_weatherNextSettings","_weatherNextOvercast","_weatherNextRainSnow","_weatherNextFog","_weatherNextWindEW","_weatherNextWindNS"];

_weatherCurrentArray = weatherTemplates select rw2_Current_Weather;
weatherCurrentName = _weatherCurrentArray select 0;
_weatherNextArray = weatherTemplates select rw2_Next_Weather;
weatherNextName = _weatherNextArray select 0;
_weatherNextSettings = _weatherNextArray select 2;

_weatherNextOvercast = _weatherNextSettings select 0;
_weatherNextRainSnow = _weatherNextSettings select 1;
_weatherNextFog = _weatherNextSettings select 2;
_weatherNextWindEW = _weatherNextSettings select 3;
_weatherNextWindNS = _weatherNextSettings select 4;	

if (overcast < _weatherNextOvercast) then {0 setOvercast 1;} else {0 setOvercast 0;};
   1200 setRain _weatherNextRainSnow;
   1200 setFog _weatherNextFog;
   setWind [_weatherNextWindEW,_weatherNextWindNS,true];

if (rw2Debug == 1) then {hint format ["Debug Updating Weather - %1\nOvercast: %2\nRain/Snow: %3\nFog: %4\nWind EW/NS: %5|%6",weatherNextName,_weatherNextOvercast,_weatherNextRainSnow,_weatherNextFog,_weatherNextWindEW,_weatherNextWindNS];};
};

if (isServer) then {
private ["_weatherUpdateArray","_weatherUpdateForecasts"];
// Check if there is no ParamsArray, and pick random if so, otherwise pick from paramsArray.
     if(isNil('paramsArray')) then {
       rw2_Current_Weather = floor(random(count(weatherTemplates)));
	} else {
       initialWeatherParam = (paramsArray select rw2Param);
	switch (initialWeatherParam) do{
		case 0: {rw2_Current_Weather = 0;};    										// Clear
           case 1: {rw2_Current_Weather = 1;};    										// Overcast
           case 2: {rw2_Current_Weather = 2 + (floor (random 3));};  					// Rain
           case 3: {rw2_Current_Weather = 5 + (floor (random 3));};  				 	// Fog
           case 4: {rw2_Current_Weather = floor(random(count(weatherTemplates)));};	// Random
       };
};
// Send out Initial Weather Variable
publicVariable "rw2_Current_Weather";
[] spawn mb_fnc_InitialWeather;
  // Start recurring weather loop.
   while {true} do {
	// Pick weather template from possible forecasts for next weather update
	sleep 10;
	_weatherUpdateArray = weatherTemplates select rw2_Current_Weather;
	_weatherUpdateForecasts = _weatherUpdateArray select 1;
	rw2_Next_Weather = _weatherUpdateForecasts select floor(random(count(_weatherUpdateForecasts)));
	publicVariable "rw2_Next_Weather";
	sleep 1190;
       [[],"mb_fnc_UpdateWeather",true] spawn Bis_fnc_MP;
	rw2_Current_Weather = rw2_Next_Weather;
	publicVariable "rw2_Current_Weather";
};
};

// Run Initial Weather Function for all.
[] spawn mb_fnc_InitialWeather;

---

Please excuse the length of the post. Thank you in advance for any help, answers, or guidance you may provide.

Share this post


Link to post
Share on other sites

Well, what is this:

_rain = rain; 
_rain set []; //<<Particularly the "set" command

Because according to the wiki page on the "set" command:

Changes the element at the given (zero-based) index of the array.

If the element does not exist, resize index+1 is called to create it.

array set [index, value]

And the "rain" command and all the others (overcast, etc.), all return numbers, not arrays, unless I'm mistaken.

Using the BIS_fnc_MP, as it now supports scripting commands as of the last public update you should be able to do something like this (example is an instant change in weather):

[[0, 1], "setOvercast", true, true, false] call BIS_fnc_MP;//equivalent to: 0 setOvercast 1;
[[0, 1], "setRain", true, true, false] call BIS_fnc_MP;//equal to: 0 setRain 1;

//Please forgive me if these are incorrect, as I haven't used BIS_fnc_MP with scripting commands before

And can you explain why you need each of the commands that you said they "have to be somewhere"?

And you say the below is the critical line, as in the line that executes this function (teg_fnc_rain?), if so what are you trying to do here?:

// The next line is probably the critical line that brings everything together// 

       //[[[_date], { setDate (_this select 0) }], "BIS_fnc_spawn"] call BIS_fnc_MP;; 
       [[[_???], { set??? (_this select 0) }], "BIS_fnc_spawn"] call BIS_fnc_MP;; // ????????????????? HELP!

And to just execute your function (teg_fnc_rain) with BIS_fnc_MP as a whole on each client and JIP:

[[], "teg_fnc_rain", true, true, false] call BIS_fnc_MP;

Edited by JShock

Share this post


Link to post
Share on other sites

Plain and simple, I don't know how to script the weather changes. Nothing HAS to be ANYWHERE. I am open to any alternatives. What I attempted to do was to modify what worked for TIME CHANGE to suit WEATHER CHANGE. It worked out great, but not on the dedicated server.

I tried what you suggested

[[0, 1], "setOvercast", true, true, false] call BIS_fnc_MP;//equivalent to: 0 setOvercast 1;
[[0, 1], "setRain", true, true, false] call BIS_fnc_MP;//equal to: 0 setRain 1;

- but it didn't work.

"[bIS_fnc_MPexec] Scripting command 'setRain' is not allowed to be remotely executed"

Share this post


Link to post
Share on other sites

I did a bit closer reading on BIS_fnc_MP, try changing the first true in each of those statements to nil:

[[0,1], "teg_fnc_rain", nil, true, false] call BIS_fnc_MP;

If that doesn't work I'm not sure how to fix your issue.

Edited by JShock

Share this post


Link to post
Share on other sites

I just tried it with

[[0,1], "teg_fnc_rain", nil, true, false] call BIS_fnc_MP;

- but it didn't work.

"[bIS_fnc_MPexec] Scripting command 'setRain' is not allowed to be remotely executed"

Thanks for all of the suggestions & responses, I appreciate them very much.

--- Well I guess some days it just simply doesn't rain, and that's all I have to say about that. Where's the wizard behind the curtain when you need one?

Share this post


Link to post
Share on other sites
Hee. Bet it's something simple :p

No kidding....is persistence a remote execution? If so that's why it's throwing that error out, I guess try setting that to false, and leave the other as nil, or maybe set the target as side WEST (just for testing purposes):

[[], "teg_fnc_rain", WEST, false, false] call BIS_fnc_MP;

Share this post


Link to post
Share on other sites

Thanks for the replies in the "Random Weather Script" thread.

I tried the following:

action = "closeDialog 0;[] spawn teg_fnc_rain;";

Instead of:

action = "closeDialog 0;[[],'teg_fnc_rain',true,true] call BIS_fnc_MP;"; 

And it made a little bit of progress;

The weather did change while playing on the dedicated server but only for the person who is pressing the button (calling the function). Each player did successfully change the weather on THEIR machine while playing on the dedicated server.

---

The next question is: In the random weather script this is how it is set up.

execVM "randomWeather2.sqf";

in our init.sqf it looks like this:

[] spawn compile PP "bPad\mop\mission_time.sqf";

Note: The weather change functions are in the same .sqf as the time change functions. Should I make the weather change functions in their own .sqf file?

So it looks something like this - "execVM "mission_weather.sqf";

Will that do anything?

Share this post


Link to post
Share on other sites

It has been a while since I last tried to make this work; Are there any new solutions or ways to make this happen?

Here's a Recap:

"I am hoping someone can help me or guide me in the right direction with changing the weather on a dedicated server. I get the following to work in the editor and when I host on my PC, but not on the dedicated server."

"I get this to work on NON DEDICATED SERVERS. I'm basically looking for a function that will allow instant weather change; Or any weather change for that matter.."

"Plain and simple, I don't know how to script the weather changes. I am open to any alternatives. What I attempted to do was to modify what worked for TIME CHANGE to suit WEATHER CHANGE. It worked out great, but not on the dedicated server."

---

This is what calls the TIME CHANGE function (Button Press).

	class btnD1: mop_RscButton
{
	idc = 1671;

	action = "closeDialog 0;[[],'teg_fnc_morningMsg',true,true] call BIS_fnc_MP;";
	text = "Dawn (5AM)"; //--- ToDo: Localize;
	x = 0.1945;
	y = 0.0900;
	w = 0.190;
	h = 0.045;
	tooltip = "Change to Morning"; //--- ToDo: Localize;
};

---

This is the TIME CHANGE function.

teg_fnc_morningMsg = 
{
	private ["_text","_1","_msg"];			

	_text = "<t size='1'>" + "Morning" + "<br />" + "<t size='1.5'>" + "Mission Time Change" +
	"</t>" + "<br />" + "<img size='4' image='images\a3_bombadge2.paa'/>" + "</t>";

	_1 =[_text,0.01,0.01,10,-1,0,90]spawn bis_fnc_dynamicText;

	_date = date;
	_date set [3,05]; //--- new hour (18)
	_date set [4,05]; //--- new minute (35)

	cuttext ["","black out"];
	1 fadesound 0;
	sleep 1;

	[[[_date], { setDate (_this select 0) }], "BIS_fnc_spawn"] call BIS_fnc_MP;;

	2 fadesound 1;
	sleep 2;
	cuttext ["","black in"];
};

---

This is what calls the WEATHER CHANGE function (Button Press).

	class btnD10: mop_RscButton
{
	idc = 1680;

	action = "closeDialog 0;[[],'teg_fnc_rain',true,true] call BIS_fnc_MP;";
	text = "Rain"; //--- ToDo: Localize;
	x = 0.1945;
	y = 0.2700;
	w = 0.190;
	h = 0.045;
	tooltip = "Change Weather to Rain"; //--- ToDo: Localize;
};

---

This is the WEATHER CHANGE function.

teg_fnc_rain =
{
	private ["_text","_1","_msg"];
	_text = "<t size='1'>" + "Rain" + "<br />" + "<t size='1.5'>" + "Mission Weather Change" +
	"</t>" + "<br />" + "<img size='4' image='images\a3_bombadge2.paa'/>" + "</t>";

	_1 =[_text,0.01,0.01,10,-1,0,90]spawn bis_fnc_dynamicText;

	cuttext ["","black out"];
	1 fadesound 0;
	sleep 1;	

	skipTime -24;
	0 setOvercast 1;
	0 setRain 1;
	0 setFog 1;
	skipTime 24;
	sleep 1;
	simulWeatherSync;

	2 fadesound 1;
	sleep 2;
	cuttext ["","black in"];
};

---

Resources/Links:

https://community.bistudio.com/wiki/setOvercast

https://community.bistudio.com/wiki/overcast

https://community.bistudio.com/wiki/setRain

https://community.bistudio.com/wiki/rain

https://community.bistudio.com/wiki/setFog

https://community.bistudio.com/wiki/fog

https://community.bistudio.com/wiki/simulWeatherSync

https://community.bistudio.com/wiki/BIS_fnc_spawn

https://community.bistudio.com/wiki/BIS_fnc_MP

---

Please excuse the length of the post. Thank you in advance for any help, answers, or guidance you may provide.

Share this post


Link to post
Share on other sites

Had a little spare time, use this as a guide.

Basically, the way it works:

1. Weather is managed on the server.

2. Weather periodically updates.

3. When weather updates, the new values are made available to the players.

4. If the player is in the session, they will receive the updated values immediately.

5. If the player is not in the session, they will receive the current values at the time they connect, and their weather will update to those values and they will also begin to receive regular updates as per usual.

It includes a way to force either the next random weather update, or a custom weather setting.

I didn't bother to write rain and fog logic, so it only includes basic overcast logic. Feel free to replace the variable logic.

The main thing is that you can see how it is set periodically, then sent over the network, then received/used by the client.

I also included some logging functions so you can monitor the activity in your RPT log during development to ensure its all working.

Code to execute on server machine:


//-- execute on server, from 'initServer.sqf' in mission directory (where mission.sqm and description.ext are. if you don't have an 'initServer.sqf', make one)

diag_log '***** DEBUG ***** Server ***** Initializing Weather *****';

private [
'_weatherUpdateInterval_fixed','_weatherUpdateInterval_random','_overcast','_rain','_fog','_currentWeather',
'_currentOvercast','_currentRain','_currentFog'
];

//===== weather values at mission start

_overcast = 0.3;                0 setOvercast _overcast;                 // set this value manually here
_rain = 0;                          0 setRain _rain;                               // set this value manually here       
_fog = [0,0,0];                   0 setFog _fog;                                 // set this value manually here
forceWeatherChange;                                                              // the lazy way to change weather, but its mission start so no one is looking :)

QS_enableWeather = TRUE;                                             // set false to prevent weather updates, more instruction below
QS_weather = [FALSE,_overcast,_rain,_fog,0];	publicVariable 'QS_weather';
QS_forceWeatherUpdate = FALSE;				      // set true to force a weather update
QS_weatherForced = [FALSE,0,0,[0,0,0],0];			// a forced weather setting
_weatherUpdateInterval_fixed = 30;			               // change to 300 after dev, fixed minimum delay between weather updates, in seconds
_weatherUpdateInterval_random = 180;		               // change to 1800 after dev, random time between 0 and this value, to add to fixed time.
_weatherUpdateInterval = time + _weatherUpdateInterval_fixed + (random _weatherUpdateInterval_random);          // we add them together + current time, to give us a time in the future for the next update

//client will report their weather activity to server
'QS_logClient' addPublicVariableEventHandler {
_text = _this select 1;
if (!((typeName _text) isEqualTo 'STRING')) then {
	diag_log str _text;
} else {
	diag_log _text;
};
};

//=== starting weather cycle

diag_log '***** DEBUG ***** Server ***** Weather Initialized, starting cycle *****';

while {TRUE} do {
        // if weather is enabled, we check the time or if a forced update has been requested
if (QS_enableWeather) then {
	if ((time > _weatherUpdateInterval) || (QS_forceWeatherUpdate)) then {
		if (QS_forceWeatherUpdate) then {
                               // if there is a forced update, we reset the forcing variable to allow it to occur again
			QS_forceWeatherUpdate = FALSE;
		};
                       // a variable to determine if custom forcing should occur, if TRUE. or, if FALSE then its just a forced random update.
		if ((QS_weatherForced select 0)) then {
                                 // the custom variable is TRUE, therefore we update weather to a custom setting rather than a random setting.

			diag_log '***** DEBUG ***** Server ***** Forcing weather *****';

			// force weather values and broadcast them

			QS_weather = QS_weatherForced; publicVariable 'QS_weather';

			// set new values on server
			0 setOvercast (QS_weather select 1);
			0 setRain (QS_weather select 2);
			0 setFog (QS_weather select 3);

			QS_weatherForced set [0,FALSE];		// values broadcasted, terminate forcing to allow continuation of random updates.

		} else {

                               // custom forcing not used, therefore we use the logic to determine our next weather
			diag_log '***** DEBUG ***** Server ***** Setting new weather *****';

                               // our current values
			_currentOvercast = QS_weather select 1;
			_currentRain = QS_weather select 2;
			_currentFog = QS_weather select 3;

			//===== set overcast values

                                // we create new values from our current values, using some logic

                               // we set a new random overcast value which is near our current value, + or - a little.
			_overcast = _currentOvercast + (0.2 - (random 0.4));
			if (_overcast >= 0.8) then {
                                       // if the projected sky is really overcast, we reduce the overcast
				_overcast = _overcast - (random 0.2);
			};
			if (_overcast <= 0.2) then {
                                        // if the projected sky is really clear, we add some more clouds
				_overcast = _overcast + (random 0.2);
			};
			0 setOvercast _overcast;		// set overcast on server machine
			QS_weather set [1,_overcast];   // we prepare this new value for our clients

			//===== set rain values

			_rain = QS_weather select 2;

			/* adjust rain here */

			QS_weather set [2,_rain];

			//===== set fog values

			_fog = QS_weather select 3;

			/* adjust fog here */

			//===== set wind values, etc


			//===== Broadcast new weather values to clients

			QS_weather set [0,TRUE];publicVariable 'QS_weather';

			diag_log format ['***** DEBUG ***** Server ***** New weather: %1 *****',QS_weather];

		};

		//===== Time until next weather update

		_weatherUpdateInterval = time + _weatherUpdateInterval_fixed + (random _weatherUpdateInterval_random);
		diag_log format ['***** DEBUG ***** Server ***** Time until next weather update: %1s *****',round (_weatherUpdateInterval - time)];
	};
};
sleep 5;
};

Code to execute on client machine:

//===== On Client (goes in 'initPlayerLocal.sqf')

// if the weather is running on the server
if (!isNil 'QS_weather') then {
        // when client connects his weather will update
0 setOvercast (QS_weather select 1);
0 setRain (QS_weather select 2);
0 setFog (QS_weather select 3);

        // we send data back from client to server for development logging
QS_logClient = format ['***** DEBUG ***** Client (%1) %2 ***** Setting Weather ***** %3 *****',getPlayerUID player,name player,QS_weather]; publicVariableServer 'QS_logClient';

       // after client connects, he will be ready to receive updates from the server
'QS_weather' addPublicVariableEventHandler {
               // the variable will look something like this: QS_weather = [TRUE,0.3,0,[0,0,0],0];    this is an example of what the clients machine reads.
	_array = _this select 1;         // QS_weather = _array
	_update = _array select 0;    // QS_weather = [_update,...etc....];
	_overcast = _array select 1;  // QS_weather = [TRUE,_overcast,...etc....];
	_rain = _array select 2;         // QS_weather = [...,...,_rain,...];
	_fog = _array select 3;         // QS_weather = [...,...,...,[0,0,0]];     remember fog is a 3-element array
	if (_update) then {
		0 setOvercast _overcast;
		0 setRain _rain;
		0 setFog _fog;
	};
               // we send back data from client to server
	QS_logClient = format ['***** DEBUG ***** Client (%1) %2 ***** Setting Weather ***** %3 *****',getPlayerUID player,name player,QS_weather]; publicVariableServer 'QS_logClient';
};
};	

How to force change manually (from client). This could go in an addAction, debug console, or whatever client execution method you prefer.

QS_weatherForced = [TRUE,overcast number,rain number,fog array];  //set new weather variables
QS_forceWeatherUpdate = TRUE; // allow server to read and execute the new variables

//example (execute on client machine)

QS_weatherForced = [TRUE,0.7,0.25,[0.3,0.1,0.1]]; publicVariableServer 'QS_weatherForced';
QS_forceWeatherUpdate = TRUE; publicVariableServer 'QS_forceWeatherUpdate';

To disable weather updates and keep the current weather:

// from server
QS_enableWeather = FALSE;
// from client
QS_enableWeather = FALSE; publicVariableServer 'QS_enableWeather';

To re-enable, just set the FALSE to TRUE

If any questions or unclear, happy to help.

Edited by MDCCLXXVI
Added more comments for readability
  • Like 1

Share this post


Link to post
Share on other sites

Hello. I'm back messing with this weather change and was able to make progress. 

 

Thank you fn_Quiksilver for that lengthy post, but I tinkered and tried and tried and tinkered but was never able to wrap my head around any of it.

 

I re-tried all the methods recommended one by one and finally got a hit with this:

 

On 10/19/2014 at 10:41 PM, jshock said:

Using the BIS_fnc_MP, as it now supports scripting commands as of the last public update you should be able to do something like this (example is an instant change in weather):


[[0, 1], "setOvercast", true, true, false] call BIS_fnc_MP;//equivalent to: 0 setOvercast 1;
[[0, 1], "setRain", true, true, false] call BIS_fnc_MP;//equal to: 0 setRain 1;
 

 

How the function is called:

	class btnD44: mop_RscButton
	{
		idc = 44;
		action = "closeDialog 0;[[],'teg_fnc_hirain',true,true] call BIS_fnc_MP;";
		text = "High Rain"; //--- ToDo: Localize;
		tooltip = ""; //--- ToDo: Localize;
		x = 0.7;
		y = 0.55;
		w = 0.19;
		h = 0.05;
	};

 

The Function To Make It Rain:

	teg_fnc_hirain = {
			private ["_text","_1","_msg"];
			_text = "<t size='1'>" + "High Rain" + "<br />" + "<t size='1.5'>" + "Mission Weather Change" + "</t>" + "<br />" + "<img size='4' image='images\bomsf_thor.paa'/>" + "</t>";
			_1 =[_text,0.01,0.01,10,-1,0,90]spawn bis_fnc_dynamicText;

			cuttext ["","black out"];
			1 fadesound 0;
			sleep 1;	

			skipTime -24;
			[[0, 1], "setOvercast", true, true, false] call BIS_fnc_MP;
			[[0, 1], "setRain", true, true, false] call BIS_fnc_MP;
			[[0, 1], "setLightnings", true, true, false] call BIS_fnc_MP;			
			skipTime 24;
			sleep 1;
			forceWeatherChange;
		
			2 fadesound 1;
			sleep 2;
			cuttext ["","black in"];
	};

 

The Function To Clear The Rain:

	teg_fnc_clear = {
			private ["_text","_1","_msg"];
			_text = "<t size='1'>" + "Clear" + "<br />" + "<t size='1.5'>" + "Mission Weather Change" + "</t>" + "<br />" + "<img size='4' image='images\bomsf_thor.paa'/>" + "</t>";
			_1 =[_text,0.01,0.01,10,-1,0,90]spawn bis_fnc_dynamicText;

			cuttext ["","black out"];
			1 fadesound 0;
			sleep 1;	

			skipTime -24;
			[[0, 0], "setOvercast", true, true, false] call BIS_fnc_MP;
			[[0, 0], "setRain", true, true, false] call BIS_fnc_MP;
			[[0, 0], "setLightnings", true, true, false] call BIS_fnc_MP;	
			skipTime 24;
			sleep 1;
			forceWeatherChange;
		
			2 fadesound 1;
			sleep 2;
			cuttext ["","black in"];
	};

I'm not certain that this is correct but it seems to work: [[0, 0], "setLightnings", true, true, false] call BIS_fnc_MP;

I'm also not certain which to use: forceWeatherChange or simulWeatherSync or both

 

My questions:

Is the above way I'm using the code/functions correct? Can it be better?

What is the proper way to do fog? [[0, [1, 1, 1]], "setFog", true, true, false] call BIS_fnc_MP;    ??

What are some good settings for Overcast (No Rain)? I'd like Clear (0 clouds - Blue Sky), Low Clouds (Some Clouds), High Clouds (Very Cloudy but No Rain)

What are some good settings for Rain? I'd like Low Rain (Slight Drizzle), Medium Rain (Nice Shower), High Rain (Pouring - Max Thunderstorm)

What are some good settings for Fog? I'd like Low, Medium, High (These can be whatever)

Finally I'd want to make sure I'm able to clear/reset all settings back to 0 with the Clear (teg_fnc_clear) function above

 

Thank you for your time. I appreciate all of your input.

 

------

 

These are some of the values in the random weather script, how do I determine what number is what?

weatherTemplates = [
       ["Clear",[0,1,5],[0.30,0,0,1,1]],
       ["Overcast",[0,1,2],[0.50,0,0,2,2]],
       ["Light Rain",[1,2,3,5],[0.60,0.3,0.05,3,3]],
       ["Medium Rain",[2,3,4],[0.70,0.5,0.05,4,4]],
       ["Rainstorm",[3],[0.80,0.9,0.1,5,5]],
       ["Light Fog",[0,2,5,6],[0.4,0,[0.2,0.01,10],0,0]],
       ["Medium Fog",[5,6,7],[0.4,0,[0.4,0.005,20],0,0]],
       ["Dense Fog",[6],[0.5,0,[0.4,0.0025,30],0,0]]
];

  

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  

×