Jump to content
Sign in to follow this  
wyattwic

[Code blurb] Wyatt's timekeeper.sqf for A3

Recommended Posts

Hello everyone,

Just today I decided to do a nitty gritty update to my old timekeeper.sqf from ArmA2. I have upgraded a few features and changed things around for A3.

Features

- Fast time via SetDate (Weather is not effected, easier on clients apparently. Only the sun, moon and stars observe the change in time.)

- Reduced light cycles (Choose to cut the day or night in half)

How to install

1. Run on all clients and server via execvm. No variables should be passed via execvm.

2. Set the following global variables via starting parameters or via script.

Shorttime - [0, Disabled],[1, Daytime will be cut in half],[2, Nighttime will be cut in half]

fasttime - [For every minute, skip X minutes - 0 will Disable]

starttime - [Hour of the day you would like to start. This will not change day, month, year or minute set via the editor.]

rundebug - [True will provide your debug log with plenty of information. False will do nothing, nil will flood your RPT]

Here is my code -

//[AWG] Wyatt's time management script
/*    Disambiguation:
       This script is made to manage a few key game play features.
           - Game starting time
           - Fast time (We will use setdate to avoid clouds skipping around)

       Start time:  I want to keep this option simple.   I will give them the options of 
       sunrise, noon, sunset, midnight.

       Fast time: I know there has to be over a dozen different published ways to forward
       through time.  This script uses the more complex setdate wich in contrast to skiptime, advances players through time 
       without the lower clouds jumping around.   Forecast and clouds stay the same.

   Important notes and operation methodology:
       This script must be started via the global init file as it must be ran on the
       server as well as the client.
       Clients will check with the server every 10 minutes to make sure that the client
       time is correct and to avoid dsync.
*/
private ["_date","_tm","_ct","_min","_hour","_day","_month","_year"];//Set game time in accordance to parameters.  JIP ready! XD
if (isDedicated && isServer) then {
   PublicServerTime = date; 
   PublicServerTime set [3,starttime];
   publicvariable "PublicServerTime"; 
   setdate PublicServerTime;
   if (rundebug) then {diag_log text format["timekeeper.sqf - Server - Initial time sync has been pushed to clients as hour %1.",PublicServerTime select 3];};
   };


if (!isDedicated && !isServer) then {
   waituntil {!isnil "PublicServerTime"};
   setdate PublicServerTime;
   if (rundebug) then {diag_log text format["timekeeper.sqf - Client - Initial time sync completed with server - %1", PublicServerTime];};
   };
_ct = 0;                /*loop counter.  Used for counting the minutes since last server sync.*/
//Fast time and skiptime below
if (fasttime == 0) then {  /*Parameters requested no fast time.   24 hours in real life, 24 hours in game.  This if statement is here for good coding practices and debug log purposes.*/

 if (rundebug) then {diag_log text format["timekeeper.sqf - Fasttime parameter returned %1.  Fast time will not run.",fasttime];};
  			if (shorttime == 0) then {
			if (rundebug) then {diag_log text format["timekeeper.sqf - Shorttime parameter returned %1.  Short days and nights will not run.",shorttime];};
		};

		if (shorttime == 1) then {
			if (rundebug) then {diag_log text format["timekeeper.sqf - Shorttime parameter returned %1.  Daytime will be cut in half.",shorttime];};
			while {true} do {
           sleep 60;                 /*Sleep one minute*/
           _date = date;            /*Get the date/time*/

           _min = _date select 4;    /*Turn the date array into something we can easily manipulate.*/
           _hour = _date select 3;
           _day = _date select 2;
           _month = _date select 1;
           _year = _date select 0;


			if (_hour >= 5 && _hour < 19)   then {
			if (rundebug) then {diag_log text format["timekeeper.sqf - Shorttime parameter returned %1 and it is %2 hour.  Daytime will be cut in half.",shorttime,_hour];};
			_min = _min + 1; //daytime - If the sun is up and I am enabled, fast time is doubled during this period.




           //The following are setdate syntax checks.
           if (_min > 59) then {_min = _min - 60; _hour = _hour + 1;/*If minutes added go out of date range, modify hours as needed.*/
               if (_hour > 23) then {_hour = _hour - 24; _day = _day + 1;/*If hours go out of date range, modify days as needed.*/
                   if (_day > 31) then {_day = _day - 30;_month = _month + 1;/*If days go out of date range, modify months as needed.*/
                       if (_month > 12) then {_month = _month - 12; _year = _year + 1;/*If months go out of range, modify year as needed.*/
           };    };    };    };   /*If statement, inside if statement, etc.   Thought process is, if we don't have to fix minutes, we don't have to fix hours and so on.*/

           setdate [_year,_month,_day,_hour,_min]; /*Use setdate to set the manipulated date.*/

		};
           /*everything from this point on is to prevent clients from dsyncing too much.*/
           _ct=_ct+1; /*This is the master sync control counter.  Adds 1 every cycle.*/
           if (_ct >= 10) then {  
               if (isDedicated && isServer) then {PublicServerTime = date; publicvariable "PublicServerTime"; if (rundebug) then {diag_log text format["timekeeper.sqf - Server - Time sync has been pushed to clients."];};};
               sleep (random 15);
               if (!isDedicated && !isServer) then {setdate PublicServerTime; if (rundebug) then {diag_log text format["timekeeper.sqf - Client - Time sync completed with server"];};};
               _ct = 0;
           };
       };/////////////////////////////////////////////////



		};
		if (shorttime == 2) then {
			if (rundebug) then {diag_log text format["timekeeper.sqf - Shorttime parameter returned %1.  Night time will be cut in half.",shorttime];};
		while {true} do {
           sleep 60;                 /*Sleep one minute*/
           _date = date;            /*Get the date/time*/

           _min = _date select 4;    /*Turn the date array into something we can easily manipulate.*/
           _hour = _date select 3;
           _day = _date select 2;
           _month = _date select 1;
           _year = _date select 0;



			if !(_hour >= 5 && _hour < 19) then {
			if (rundebug) then {diag_log text format["timekeeper.sqf - Shorttime parameter returned %1 and it is %2 hour.  Nighttime will be cut in half.",shorttime,_hour];};
			_min = _min + 1; //nighttime - If the sun is down and I am enabled, fast time is doubled during this period.




           //The following are setdate syntax checks.
           if (_min > 59) then {_min = _min - 60; _hour = _hour + 1;/*If minutes added go out of date range, modify hours as needed.*/
               if (_hour > 23) then {_hour = _hour - 24; _day = _day + 1;/*If hours go out of date range, modify days as needed.*/
                   if (_day > 31) then {_day = _day - 30;_month = _month + 1;/*If days go out of date range, modify months as needed.*/
                       if (_month > 12) then {_month = _month - 12; _year = _year + 1;/*If months go out of range, modify year as needed.*/
           };    };    };    };   /*If statement, inside if statement, etc.   Thought process is, if we don't have to fix minutes, we don't have to fix hours and so on.*/

           setdate [_year,_month,_day,_hour,_min]; /*Use setdate to set the manipulated date.*/
       };
           /*everything from this point on is to prevent clients from dsyncing too much.*/
           _ct=_ct+1; /*This is the master sync control counter.  Adds 1 every cycle.*/
           if (_ct >= 10) then {  
               if (isDedicated && isServer) then {PublicServerTime = date; publicvariable "PublicServerTime"; if (rundebug) then {diag_log text format["timekeeper.sqf - Server - Time sync has been pushed to clients."];};};
               sleep (random 15);
               if (!isDedicated && !isServer) then {setdate PublicServerTime; if (rundebug) then {diag_log text format["timekeeper.sqf - Client - Time sync completed with server"];};};
               _ct = 0;
           };
       };

		};


  } else {
   if (rundebug) then {diag_log text format["timekeeper.sqf - Fast time is running with a modifier of 1 to %1.",fasttime];};
   _tm = fasttime;    /*Set time multiplier into local variable.*/
       while {true} do {
           sleep 60;                 /*Sleep one minute*/
           _date = date;            /*Get the date/time*/

           _min = _date select 4;    /*Turn the date array into something we can easily manipulate.*/
           _hour = _date select 3;
           _day = _date select 2;
           _month = _date select 1;
           _year = _date select 0;

		_min = _min + _tm;

		/*This section enables the half day/night setting*/
		if (shorttime == 0) then {
			if (rundebug) then {diag_log text format["timekeeper.sqf - Shorttime parameter returned %1.  Short days and nights will not run.",shorttime];};
		};
		if (shorttime == 1) then { 
			if (rundebug) then {diag_log text format["timekeeper.sqf - Shorttime parameter returned %1 and it is %2 hour.  Daytime will be cut in half.",shorttime,_hour];};
			if (_hour >= 5 && _hour < 19)   then {_min = _min + _tm}; //daytime - If the sun is up and I am enabled, fast time is doubled during this period.
			};
		if (shorttime == 2) then { 
			if (rundebug) then {diag_log text format["timekeeper.sqf - Shorttime parameter returned %1 and it is %2 hour.  Nighttime will be cut in half.",shorttime,_hour];};
			if !(_hour >= 5 && _hour < 19) then {_min = _min + _tm}; //nighttime - If the sun is down and I am enabled, fast time is doubled during this period.
			};



           //The following are setdate syntax checks.
           if (_min > 59) then {_min = _min - 60; _hour = _hour + 1;/*If minutes added go out of date range, modify hours as needed.*/
               if (_hour > 23) then {_hour = _hour - 24; _day = _day + 1;/*If hours go out of date range, modify days as needed.*/
                   if (_day > 31) then {_day = _day - 30;_month = _month + 1;/*If days go out of date range, modify months as needed.*/
                       if (_month > 12) then {_month = _month - 12; _year = _year + 1;/*If months go out of range, modify year as needed.*/
           };    };    };    };   /*If statement, inside if statement, etc.   Thought process is, if we don't have to fix minutes, we don't have to fix hours and so on.*/

           setdate [_year,_month,_day,_hour,_min]; /*Use setdate to set the manipulated date.*/

           /*everything from this point on is to prevent clients from dsyncing too much.*/
           _ct=_ct+1; /*This is the master sync control counter.  Adds 1 every cycle.*/
           if (_ct >= 10) then {  
               if (isDedicated && isServer) then {PublicServerTime = date; publicvariable "PublicServerTime"; if (rundebug) then {diag_log text format["timekeeper.sqf - Server - Time sync has been pushed to clients."];};};
               sleep (random 15);
               if (!isDedicated && !isServer) then {setdate PublicServerTime; if (rundebug) then {diag_log text format["timekeeper.sqf - Client - Time sync completed with server"];};};
               _ct = 0;
           };
       };
   };  

Its not perfect, so feel free to let me know if you spot anything.

EDIT: Fixed many variable errors, other noob mistakes.

Changelog

6/14/14 - Fixed Variable errors

6/15/14 - Fixed mathematical errors - Currently the short days/nights do not work.

Edited by Wyattwic

Share this post


Link to post
Share on other sites

shouldn't it be isDedicated or IsServer? isdedicated should already cover it being the server. not sure though. i will try this in my next coop. always interested in fast time scripts. thx for sharing.

Share this post


Link to post
Share on other sites

I made a good number of mistakes in that, will be editing it soon.

Its a code blurb, this is right off the top of my head with limited bug testing so far.

I am going to be using it in my next mission release.

I did (isDedicated && isServer) for safety and paranoia sakes. If I remember correctly, I did that because at one point in time I was under the impression that isdedicated was true for headless clients.

EDIT: If a moderator could move this to the scripting section, I may have posted in the wrong area.

Share this post


Link to post
Share on other sites

oh i thought that you were trying to make it work for local host and dedi at the same time. no worries though. wasn'T trying to put you on the spot. just trying to be constructive :)

do you have a server you test this on? i would love to see this in action using some extremer values. anyways- keep up the good work. it's much appreciated.

Share this post


Link to post
Share on other sites

I do have a server that I test it on. Although I seem to have a few minor glitches in the half day/night settings right now.

The previous A2 variant still works well, but my reamp for A3 didnt go as smooth.

Share this post


Link to post
Share on other sites

Script updated. Currently working out the bugs involving reduced day/night cycles.

Edit, this script currently is functioning in regards to accelerating time.

---------- Post added at 17:18 ---------- Previous post was at 15:23 ----------

This version has not been tested yet, but should sync players and server time more accurately. In the previous versions there was a 1 in 10 chance that the player would jump backwards 10 minutes and be brought back to the correct time on the next sync.

This version utilizes a EH to update the moment it receives an update to the server time.

//[AWG] Wyatt's time management script
/*    Disambiguation:
       This script is made to manage a few key game play features.
           - Game starting time
           - Fast time (We will use setdate to avoid clouds skipping around)

       Start time:  I want to keep this option simple.   I will give them the options of 
       sunrise, noon, sunset, midnight.

       Fast time: I know there has to be over a dozen different published ways to forward
       through time.  This script uses the more complex setdate wich in contrast to skiptime, advances players through time 
       without the lower clouds jumping around.   Forecast and clouds stay the same.

   Important notes and operation methodology:
       This script must be started via the global init file as it must be ran on the
       server as well as the client.
       Clients will check with the server every 10 minutes to make sure that the client
       time is correct and to avoid dsync.
*/
private ["_date","_tm","_ct","_min","_hour","_day","_month","_year"];//Set game time in accordance to parameters.  JIP ready! XD
if (isDedicated && isServer) then {
   PublicServerTime = date; 
   PublicServerTime set [3,starttime];
   publicvariable "PublicServerTime"; 
   setdate PublicServerTime;
   if (rundebug) then {diag_log text format["timekeeper.sqf - Server - Initial time sync has been pushed to clients as hour %1.",PublicServerTime select 3];};
   };


if (!isDedicated && !isServer) then {
   waituntil {!isnil "PublicServerTime"};
   setdate PublicServerTime;
"PublicServerTime" addPublicVariableEventHandler {
setdate PublicServerTime; if (rundebug) then {diag_log text format["timekeeper.sqf - Client - Time sync completed with server"];};
};
  if (rundebug) then {diag_log text format["timekeeper.sqf - Client - Initial time sync completed with server - %1", PublicServerTime];};
   };



_ct = 0;                /*loop counter.  Used for counting the minutes since last server sync.*/
//Fast time and skiptime below
if (fasttime == 0) then {  /*Parameters requested no fast time.   24 hours in real life, 24 hours in game.  This if statement is here for good coding practices and debug log purposes.*/

 if (rundebug) then {diag_log text format["timekeeper.sqf - Fasttime parameter returned %1.  Fast time will not run.",fasttime];};
  			if (shorttime == 0) then {
			if (rundebug) then {diag_log text format["timekeeper.sqf - Shorttime parameter returned %1.  Short days and nights will not run.",shorttime];};
		};

		if (shorttime == 1) then {
			if (rundebug) then {diag_log text format["timekeeper.sqf - Shorttime parameter returned %1.  Daytime will be cut in half.",shorttime];};
			while {true} do {
           sleep 60;                 /*Sleep one minute*/
           _date = date;            /*Get the date/time*/

           _min = _date select 4;    /*Turn the date array into something we can easily manipulate.*/
           _hour = _date select 3;
           _day = _date select 2;
           _month = _date select 1;
           _year = _date select 0;


			if (_hour >= 5 && _hour < 19)   then {
			if (rundebug) then {diag_log text format["timekeeper.sqf - Shorttime parameter returned %1 and it is %2 hour.  Daytime will be cut in half.",shorttime,_hour];};
			_min = _min + 1; //daytime - If the sun is up and I am enabled, fast time is doubled during this period.




           //The following are setdate syntax checks.
           if (_min > 59) then {_min = _min - 60; _hour = _hour + 1;/*If minutes added go out of date range, modify hours as needed.*/
               if (_hour > 23) then {_hour = _hour - 24; _day = _day + 1;/*If hours go out of date range, modify days as needed.*/
                   if (_day > 31) then {_day = _day - 30;_month = _month + 1;/*If days go out of date range, modify months as needed.*/
                       if (_month > 12) then {_month = _month - 12; _year = _year + 1;/*If months go out of range, modify year as needed.*/
           };    };    };    };   /*If statement, inside if statement, etc.   Thought process is, if we don't have to fix minutes, we don't have to fix hours and so on.*/

           setdate [_year,_month,_day,_hour,_min]; /*Use setdate to set the manipulated date.*/

		};
           /*everything from this point on is to prevent clients from dsyncing too much.*/
           _ct=_ct+1; /*This is the master sync control counter.  Adds 1 every cycle.*/
           if (_ct >= 10) then {  
               if (isDedicated && isServer) then {PublicServerTime = date; publicvariable "PublicServerTime"; if (rundebug) then {diag_log text format["timekeeper.sqf - Server - Time sync has been pushed to clients."];};};
               _ct = 0;
           };
       };/////////////////////////////////////////////////



		};
		if (shorttime == 2) then {
			if (rundebug) then {diag_log text format["timekeeper.sqf - Shorttime parameter returned %1.  Night time will be cut in half.",shorttime];};
		while {true} do {
           sleep 60;                 /*Sleep one minute*/
           _date = date;            /*Get the date/time*/

           _min = _date select 4;    /*Turn the date array into something we can easily manipulate.*/
           _hour = _date select 3;
           _day = _date select 2;
           _month = _date select 1;
           _year = _date select 0;



			if !(_hour >= 5 && _hour < 19) then {
			if (rundebug) then {diag_log text format["timekeeper.sqf - Shorttime parameter returned %1 and it is %2 hour.  Nighttime will be cut in half.",shorttime,_hour];};
			_min = _min + 1; //nighttime - If the sun is down and I am enabled, fast time is doubled during this period.




           //The following are setdate syntax checks.
           if (_min > 59) then {_min = _min - 60; _hour = _hour + 1;/*If minutes added go out of date range, modify hours as needed.*/
               if (_hour > 23) then {_hour = _hour - 24; _day = _day + 1;/*If hours go out of date range, modify days as needed.*/
                   if (_day > 31) then {_day = _day - 30;_month = _month + 1;/*If days go out of date range, modify months as needed.*/
                       if (_month > 12) then {_month = _month - 12; _year = _year + 1;/*If months go out of range, modify year as needed.*/
           };    };    };    };   /*If statement, inside if statement, etc.   Thought process is, if we don't have to fix minutes, we don't have to fix hours and so on.*/

           setdate [_year,_month,_day,_hour,_min]; /*Use setdate to set the manipulated date.*/
       };
           /*everything from this point on is to prevent clients from dsyncing too much.*/
           _ct=_ct+1; /*This is the master sync control counter.  Adds 1 every cycle.*/
           if (_ct >= 10) then {  
               if (isDedicated && isServer) then {PublicServerTime = date; publicvariable "PublicServerTime"; if (rundebug) then {diag_log text format["timekeeper.sqf - Server - Time sync has been pushed to clients."];};};
               _ct = 0;
           };
       };

		};


  } else {
   if (rundebug) then {diag_log text format["timekeeper.sqf - Fast time is running with a modifier of 1 to %1.",fasttime];};
   _tm = fasttime;    /*Set time multiplier into local variable.*/
       while {true} do {
           sleep 60;                 /*Sleep one minute*/
           _date = date;            /*Get the date/time*/

           _min = _date select 4;    /*Turn the date array into something we can easily manipulate.*/
           _hour = _date select 3;
           _day = _date select 2;
           _month = _date select 1;
           _year = _date select 0;

		_min = _min + _tm;

		/*This section enables the half day/night setting*/
		if (shorttime == 0) then {
			if (rundebug) then {diag_log text format["timekeeper.sqf - Shorttime parameter returned %1.  Short days and nights will not run.",shorttime];};
		};
		if (shorttime == 1) then { 
			if (rundebug) then {diag_log text format["timekeeper.sqf - Shorttime parameter returned %1 and it is %2 hour.  Daytime will be cut in half.",shorttime,_hour];};
			if (_hour >= 5 && _hour < 19)   then {_min = _min + _tm}; //daytime - If the sun is up and I am enabled, fast time is doubled during this period.
			};
		if (shorttime == 2) then { 
			if (rundebug) then {diag_log text format["timekeeper.sqf - Shorttime parameter returned %1 and it is %2 hour.  Nighttime will be cut in half.",shorttime,_hour];};
			if !(_hour >= 5 && _hour < 19) then {_min = _min + _tm}; //nighttime - If the sun is down and I am enabled, fast time is doubled during this period.
			};



           //The following are setdate syntax checks.
           if (_min > 59) then {_min = _min - 60; _hour = _hour + 1;/*If minutes added go out of date range, modify hours as needed.*/
               if (_hour > 23) then {_hour = _hour - 24; _day = _day + 1;/*If hours go out of date range, modify days as needed.*/
                   if (_day > 31) then {_day = _day - 30;_month = _month + 1;/*If days go out of date range, modify months as needed.*/
                       if (_month > 12) then {_month = _month - 12; _year = _year + 1;/*If months go out of range, modify year as needed.*/
           };    };    };    };   /*If statement, inside if statement, etc.   Thought process is, if we don't have to fix minutes, we don't have to fix hours and so on.*/

           setdate [_year,_month,_day,_hour,_min]; /*Use setdate to set the manipulated date.*/

           /*everything from this point on is to prevent clients from dsyncing too much.*/
           _ct=_ct+1; /*This is the master sync control counter.  Adds 1 every cycle.*/
           if (_ct >= 10) then {  
               if (isDedicated && isServer) then {PublicServerTime = date; publicvariable "PublicServerTime"; if (rundebug) then {diag_log text format["timekeeper.sqf - Server - Time sync has been pushed to clients."];};};
               _ct = 0;
           };
       };
   };  

Share this post


Link to post
Share on other sites

Ha, I was thinking about doing something similar, but maybe it can be done with your script. My ideas were, it could have 4 arguments: begin daytime, begin nighttime, daytime multiplier, nighttime multiplier.

I.e., if nighttime is 5 hours and multiplier is 0.2, the nighttime would last 1 hour. Maybe even multipliers > 1 would be handy... Another idea was, even more day cycles could be done with individual multipliers.

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  

×