Jump to content
ZaellixA

Time management function [Sharing]

Recommended Posts

Hey all, just came up with an idea of a function and implemented it. I kinda liked the idea and thought it would be nice to share it here :).

 

So, the function takes as arguments the desired duration of the ArmA day in real-life hours, the day-to-night ratio (how many times the day is bigger than the night) and the (ArmA) date. It returns the needed multipliers (for the desired day and night duration in respect to the total duration of the day) as well as the sunrise and sunset times for that specific day (this is somewhat redundant since you could get them from BIS_fnc_sunriseSunsetTime, but since this function is used inside my function I thought it would be nice to return them).

 

A simple use example would be

// The function will be called myTag_fnc_timeVals for this example but you can name it whatever you want

// Set variables (most probably you will get them from somewhere such as a mission parameter with "BIS_fnc_getParamValue"
private _dayDur = 0.3; // Duration of ArmA day in real-life hours (half an hour in real life corresponds to one full ArmA day)
private _dnFac = 1.5; // Day lasts 1.5 times the duration of the night

// Get day multiplier, night multiplier, sunrise (ArmA) time and sunset (ArmA) time for the current (ArmA) day given by command "date"
_timeVals = [_dayDur, _dnFac, date] call myTag_fnc_timeVals;

// Handle the time in a "continuous" manner
while{true} do {
	// Check time of day
	if(daytime > (_timeVals select 3) || {daytime < (_timeVals select 2)}) then {
		setTimeMultiplier (_timeVals select 1); // Use night multiplier
	} else {
		setTimeMultiplier (_timeVals select 0); // Use day multiplier
	};
                                                              
	// Sleep (a lot...)
	sleep 120;
};

Below is the implementation of the function. I would like to apologise in advance though, for the cluttering with posting all the code here. I thought it could be a convenience for anyone who would like to use it. The function can also be found in this GitLab repository. In the code posted here, I have skipped parameter checks which you can implement yourself or copy the code from the provided link.

 

NOTE: Due to the fact that the function will force the day and the night to have the given relation (given by the fraction), and due to the fact that possibly the "natural" day has different duration than the "natural" night, setting the ratio to 1 does not mean that the time multipliers will be 1. If you want to return to "normal" time use directly setTimeMultiplier command.

 

Finally, please feel free to suggest (or implement yourself and share back) any improvements, or changes :).

 

/* ----------------------------------------------------------------------------------------------------
 * Inputs
 * ----------
 * dayDur [Number] (Optional): Duration of the whole day in real hours (defaults to 24)
 * dnFac [Number] (Optional): The day-to-night ratio (defaults to 1)
 * dayOfYear [date] (Optional): The day of the year for which the multipliers will be
 *                              calculated (defaults to the current ArmA date)
 * ----------------------------------------------------------------------------------------------------
 * Output
 * ----------
 * data [Array]: - _this select 0 [Number]: Day multiplier
 *               - _this select 1 [Number]: Night multiplier
 *               - _this select 2 [Number]: Sunrise time
 *               - _this select 3 [Number]: Sunset time
 *
 * ----------------------------------------------------------------------------------------------------
 */

// Get input variables
params[["_dayDur", 24, [24]], // Total duration of day
       ["_dnFac", 1, [1]], // Day-to-Night factor
       ["_dayOfYear", date, [date]]]; // Asked date

// Declare some variables
private _riseSet = _dayOfYear call BIS_fnc_sunriseSunsetTime; // Get the sunrise and sunset times of the day
private _durs = [nil, nil];

// Calculate day and night duration (in real life hours)
_durs set[0, (_riseSet select 1) - (_riseSet select 0)]; // Calculate day duration
_durs set[1, 24 - (_durs select 0)]; // Calculate night duration

// Calculate multipliers
/* Solve simultaneously:
 *
 * dayDur * dayMul + nightDur * nightMul = 24 (1)
 * (dayDur * dayMul)/(nightDur * nightMul) = dayNightFrac (2)
 *
 * The result is:
 *
 * dayMul = 24/(nightDur * (1 + dayNightFrac))
 * nightMul = (nightDur * dayNightFrac * dayMul)/dayDur
 */
private _dMul = 24/((_durs select 1) * (1 + _dnFac)); // Calculate the day multiplier
private _nMul = ((_durs select 1) * _dnFac * _dMul)/(_durs select 0); // Calculate the night multiplier

// Multiply with "global multiplier"
_dMul = _dMul * 24/_dayDur; // Final day multiplier
_nMul = _nMul * 24/_dayDur; // Final night multiplier

// Return and exit
[_dMul, _nMul, _riseSet select 0, _riseSet select 1]

Hope this will be useful to someone.

 

Take care, have fun and ArmA a lot :).

 

EDIT: Corrected the code. A "total multiplier" was missing and day and night multipliers needed corrections. Now works correctly (I hope)...

 

EDIT: A couple of bug fixes... Sorry ;(

Edited by ZaellixA
Corrected code
  • Like 3
  • Thanks 2

Share this post


Link to post
Share on other sites

Hi

thanks for this script. I have been thinking of writing my own time script similar to this so this really helps to know how that is done. I often write my own scripts because I like to code... I hope you understand :)

 

Btw. I think in the example should use setTimeMultiplier and not timeMultiplier

 

  • Like 1

Share this post


Link to post
Share on other sites
1 minute ago, gc8 said:

Hi

thanks for this script. I have been thinking of writing my own time script similar to this so this really helps to know how that is done. I often write my own scripts because I like to code... I hope you understand :)

 

Btw. I think in the example should use setTimeMultiplier and not timeMultiplier

 

Yep, that's correct... I didn't copy-paste the script and, as always....... I did a couple of mistakes :D... Thanks I'll correct it right away.

Share this post


Link to post
Share on other sites

Hey all, just posting one more way to "handle time". Also posting the first method to handle time just a wee bit refined.

 

The first method sets the full day duration and doesn't mess with the day and night durations.

/* ----------------------------------------------------------------------------------------------------
 * Inputs
 * ----------
 * dayDur [Number] (Optional): Duration of the whole day in real hours (defaults to 24)
 * liteDur [Number] (Optional): The daylight duration (defaults to 12)
 * dayOfYear [Date] (Optional): The day of the year for which the multipliers will be
 *                              calculated (defaults to the current ArmA date)
 * ----------------------------------------------------------------------------------------------------
 * Output
 * ----------
 * data [Array]: - _this select 0 [Number]: Day multiplier
 *               - _this select 1 [Number]: Night multiplier
 *               - _this select 2 [Number]: Sunrise time
 *               - _this select 3 [Number]: Sunset time
 *
 * ----------------------------------------------------------------------------------------------------
 */

// Get input variables
params[["_dayDur", 24, [24]], // Total duration of day
       ["_liteDur", 12, [12]], // Daylight duration
       ["_dayOfYear", date, [date]]]; // Asked date

// Declare some variables
private _riseSet = _dayOfYear call BIS_fnc_sunriseSunsetTime; // Get the sunrise and sunset times of the day
private _durs = [nil, nil]; // Day and night durations

// Calculate day and night duration (in real life hours)
_durs set[0, (_riseSet select 1) - (_riseSet select 0)]; // Calculate day duration
_durs set[1, 24 - (_durs select 0)]; // Calculate night duration

// Check method and calculate
private _dMul = 1; // Initialise day multiplier
private _nMul = 1; // Initialise night multiplier

if(_val >= _dayDur) then {
  _dMul = 0.1; // Set minimum day multiplier
  _nMul = 120; // Set maximum night multiplier
} else {
  _dMul = (_durs select 0)/_val; // Get the day multiplier
  _nMul = (_durs select 1)/(_dayDur - _val); // Get the night multiplier
};

// Multiply with "global multiplier"
_dMul = _dMul * 24/_dayDur; // Final day multiplier
_nMul = _dMul * 24/_dayDur; // Final night multiplier

// Return and exit
[_dMul, _nMul, _riseSet select 0, _riseSet select 1]

This second method is actually the one that was initially posted here but a bit refined.

/* ----------------------------------------------------------------------------------------------------
 * Inputs
 * ----------
 * dayDur [Number] (Optional): Duration of the whole day in real hours (defaults to 24)
 * dnFrac [Number] (Optional): The day-to-night ratio (fractional method) (defaults to 1)
 * dayOfYear [Date] (Optional): The day of the year for which the multipliers will be
 *                              calculated (defaults to the current ArmA date)
 * ----------------------------------------------------------------------------------------------------
 * Output
 * ----------
 * data [Array]: - _this select 0 [Number]: Day multiplier
 *               - _this select 1 [Number]: Night multiplier
 *               - _this select 2 [Number]: Sunrise time
 *               - _this select 3 [Number]: Sunset time
 *
 * ----------------------------------------------------------------------------------------------------
 */

// Get input variables
params[["_dayDur", 24, [24]], // Total duration of day
       ["_dnFrac", 1, [1]], // Day-to-Night factor
       ["_dayOfYear", date, [date]]]; // Asked date

// Declare some variables
private _riseSet = _dayOfYear call BIS_fnc_sunriseSunsetTime; // Get the sunrise and sunset times of the day
private _durs = [nil, nil]; // Day and night durations

// Calculate day and night duration (in real life hours)
_durs set[0, (_riseSet select 1) - (_riseSet select 0)]; // Calculate day duration
_durs set[1, 24 - (_durs select 0)]; // Calculate night duration

// Initialise multipliers
private _dMul = 1; // Initialise day multiplier
private _nMul = 1; // Initialise night multiplier

/* Solve simultaneously:
 *
 * dayDur * dayMul + nightDur * nightMul = 24 (1)
 * (dayDur * dayMul)/(nightDur * nightMul) = dayNightFrac (2)
 *
 * The result is:
 *
 * dayMul = 24/(nightDur * (1 + dayNightFrac))
 * nightMul = (nightDur * dayNightFrac * dayMul)/dayDur
 */
_dMul = 24/((_durs select 1) * (1 + _dnFrac)); // Calculate the day multiplier
_nMul = ((_durs select 1) * _dnFrac * _dMul)/(_durs select 0); // Calculate the night multiplier

// Multiply with "global multiplier"
_dMul = _dMul * 24/_dayDur; // Final day multiplier
_nMul = _dMul * 24/_dayDur; // Final night multiplier

// Return and exit
[_dMul, _nMul, _riseSet select 0, _riseSet select 1]

Hope they are helpful somehow...

 

Enjoy!

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

×