diff --git a/addons/common/fnc_waitAndExecute.sqf b/addons/common/fnc_waitAndExecute.sqf index 4a6f029194..e950b90c41 100644 --- a/addons/common/fnc_waitAndExecute.sqf +++ b/addons/common/fnc_waitAndExecute.sqf @@ -4,7 +4,7 @@ Function: CBA_fnc_waitAndExecute Description: Executes a code once in unscheduled environment with a given game time delay. - Note that unlike PFEH, the delay is in CBA_missionTime not diag_tickTime (will be adjusted for time accl). + Note that unlike PFEH, the delay is in CBA_missionTimeTriple not diag_tickTime (will be adjusted for time accl). Parameters: _function - The function you wish to execute. @@ -28,5 +28,12 @@ Author: params [["_function", {}, [{}]], ["_args", []], ["_delay", 0, [0]]]; -GVAR(waitAndExecArray) pushBack [CBA_missionTime + _delay, _function, _args]; +_delay = [ + floor((_delay % 1e9)/1e6), + floor((_delay % 1e6)/1e3), + _delay % 1e3 +]; +private _timeOfExec = CBA_missionTimeTriple vectorAdd _delay; + +GVAR(waitAndExecArray) pushBack (_timeOfExec + [_function, _args]); GVAR(waitAndExecArrayIsSorted) = false; diff --git a/addons/common/fnc_waitUntilAndExecute.sqf b/addons/common/fnc_waitUntilAndExecute.sqf index 05b74af619..a0dda525a5 100644 --- a/addons/common/fnc_waitUntilAndExecute.sqf +++ b/addons/common/fnc_waitUntilAndExecute.sqf @@ -49,7 +49,8 @@ if (_timeout < 0) then { GVAR(waitUntilAndExecArray) pushBack [{ params ["_condition", "_statement", "_args", "_timeout", "_timeoutCode", "_startTime"]; - if (CBA_missionTime - _startTime > _timeout) exitWith { + private _timeDiff = CBA_missionTimeTriple vectorDiff _startTime; + if (_timeDiff vectorDotProduct [1e6 , 1e3, 1] > _timeout) exitWith { _args call _timeoutCode; true }; @@ -58,7 +59,7 @@ if (_timeout < 0) then { true }; false - }, {}, [_condition, _statement, _args, _timeout, _timeoutCode, CBA_missionTime]]; + }, {}, [_condition, _statement, _args, _timeout, _timeoutCode, CBA_missionTimeTriple]]; }; nil diff --git a/addons/common/init_perFrameHandler.sqf b/addons/common/init_perFrameHandler.sqf index 795211f423..246a933951 100644 --- a/addons/common/init_perFrameHandler.sqf +++ b/addons/common/init_perFrameHandler.sqf @@ -46,9 +46,11 @@ GVAR(waitUntilAndExecArray) = []; }; private _delete = false; { - if (_x select 0 > CBA_missionTime) exitWith {}; + private _timeDiff = [_x select [0, 3], CBA_missionTimeTriple]; + _timeDiff sort true; + if (_timeDiff#0 isEqualTo CBA_missionTimeTriple) exitWith {}; - (_x select 2) call (_x select 1); + (_x select 4) call (_x select 3); // Mark the element for deletion so it's not executed ever again GVAR(waitAndExecArray) set [_forEachIndex, objNull]; @@ -97,10 +99,10 @@ addMissionEventHandler ["Loaded", { GVAR(lastTickTime) = _tickTime; }]; -CBA_missionTime = 0; +CBA_missionTimeTriple = [0, 0, 0]; // [999,999,999.99] = 999999999.99 GVAR(lastTime) = time; -// increase CBA_missionTime variable every frame +// increase CBA_missionTimeTriple variable every frame if (isMultiplayer) then { // multiplayer - no accTime in MP if (isServer) then { @@ -108,7 +110,15 @@ if (isMultiplayer) then { [QFUNC(missionTimePFH), { SCRIPT(missionTimePFH_server); if (time != GVAR(lastTime)) then { - CBA_missionTime = CBA_missionTime + (_tickTime - GVAR(lastTickTime)); + CBA_missionTimeTriple = CBA_missionTimeTriple vectorAdd [0, 0, _tickTime - GVAR(lastTickTime)]; + if (selectMax CBA_missionTimeTriple > 1e3) then { + private _limitReach = CBA_missionTimeTriple findIf {_x > 1e3}; + private _diff = [0, 0, 0]; + _diff set [_limitReach, -1e3]; + _diff set [_limitReach - 1, 1]; + CBA_missionTimeTriple = CBA_missionTimeTriple vectorAdd _diff; + }; + CBA_missionTime = CBA_missionTimeTriple vectorDotProduct [1e6 , 1e3, 1]; GVAR(lastTime) = time; // used to detect paused game }; @@ -116,23 +126,31 @@ if (isMultiplayer) then { }] call CBA_fnc_compileFinal; addMissionEventHandler ["PlayerConnected", { - (_this select 4) publicVariableClient "CBA_missionTime"; + (_this select 4) publicVariableClient "CBA_missionTimeTriple"; }]; } else { - CBA_missionTime = -1; + CBA_missionTimeTriple = []; // multiplayer client 0 spawn { isNil { private _fnc_init = { - CBA_missionTime = _this select 1; + CBA_missionTimeTriple = _this select 1; GVAR(lastTickTime) = diag_tickTime; // prevent time skip on clients [QFUNC(missionTimePFH), { SCRIPT(missionTimePFH_client); if (time != GVAR(lastTime)) then { - CBA_missionTime = CBA_missionTime + (_tickTime - GVAR(lastTickTime)); + CBA_missionTimeTriple = CBA_missionTimeTriple vectorAdd [0, 0, _tickTime - GVAR(lastTickTime)]; + if (selectMax CBA_missionTimeTriple > 1e3) then { + private _limitReach = CBA_missionTimeTriple findIf {_x > 1e3}; + private _diff = [0, 0, 0]; + _diff set [_limitReach, -1e3]; + _diff set [_limitReach - 1, 1]; + CBA_missionTimeTriple = CBA_missionTimeTriple vectorAdd _diff; + }; + CBA_missionTime = CBA_missionTimeTriple vectorDotProduct [1e6 , 1e3, 1]; GVAR(lastTime) = time; // used to detect paused game }; @@ -141,11 +159,11 @@ if (isMultiplayer) then { }; - "CBA_missionTime" addPublicVariableEventHandler _fnc_init; + "CBA_missionTimeTriple" addPublicVariableEventHandler _fnc_init; - if (CBA_missionTime != -1) then { - WARNING_1("CBA_missionTime packet arrived prematurely. Installing update handler manually. Transferred value was %1.",CBA_missionTime); - [nil, CBA_missionTime] call _fnc_init; + if !(CBA_missionTimeTriple isEqualTo []) then { + WARNING_1("CBA_missionTimeTriple packet arrived prematurely. Installing update handler manually. Transferred value was %1.",CBA_missionTimeTriple); + [nil, CBA_missionTimeTriple] call _fnc_init; }; }; }; @@ -155,7 +173,15 @@ if (isMultiplayer) then { [QFUNC(missionTimePFH), { SCRIPT(missionTimePFH_sp); if (time != GVAR(lastTime)) then { - CBA_missionTime = CBA_missionTime + (_tickTime - GVAR(lastTickTime)) * accTime; + CBA_missionTimeTriple = CBA_missionTimeTriple vectorAdd [0, 0, (_tickTime - GVAR(lastTickTime)) * accTime]; + if (selectMax CBA_missionTimeTriple > 1e3) then { + private _limitReach = CBA_missionTimeTriple findIf {_x > 1e3}; + private _diff = [0, 0, 0]; + _diff set [_limitReach, -1e3]; + _diff set [_limitReach - 1, 1]; + CBA_missionTimeTriple = CBA_missionTimeTriple vectorAdd _diff; + }; + CBA_missionTime = CBA_missionTimeTriple vectorDotProduct [1e6 , 1e3, 1]; GVAR(lastTime) = time; // used to detect paused game }; diff --git a/addons/diagnostic/fnc_debug.sqf b/addons/diagnostic/fnc_debug.sqf index bf169397a2..54bbe6ea31 100644 --- a/addons/diagnostic/fnc_debug.sqf +++ b/addons/diagnostic/fnc_debug.sqf @@ -75,7 +75,7 @@ _message set [0, format [ "(%3) %1 - %2", _title, _message select 0, - [CBA_missionTime, "H:MM:SS"] call CBA_fnc_formatElapsedTime + [CBA_missionTimeTriple vectorDotProduct [1e6 , 1e3, 1], "H:MM:SS"] call CBA_fnc_formatElapsedTime ]]; _message = _message call _fnc_splitLines; diff --git a/addons/events/fnc_weaponEvents.sqf b/addons/events/fnc_weaponEvents.sqf index a1ddd167de..147f9361bc 100644 --- a/addons/events/fnc_weaponEvents.sqf +++ b/addons/events/fnc_weaponEvents.sqf @@ -110,13 +110,14 @@ if (!_isEmpty || _onEmpty) then { _this set [10, true]; }; - _this set [8, CBA_missionTime]; + _this set [8, CBA_missionTimeTriple]; _unit setWeaponReloadingTime [_unit, _muzzle, 1]; false }; // keep waiting until time over - if (CBA_missionTime < _time + _delay) exitWith {false}; + private _timeDiff = CBA_missionTimeTriple vectorDiff _time; + if (_timeDiff vectorDotProduct [1e6 , 1e3, 1] < _delay) exitWith {false}; if (local _unit) then { _unit playAction _handAction; @@ -185,7 +186,7 @@ if (!_isEmpty || _onEmpty) then { }, {}, [ _unit, _weapon, _muzzle, _optic, _handAction, _sound, call _fnc_soundSource, - _expectedMagazineCount, CBA_missionTime, _delay, + _expectedMagazineCount, CBA_missionTimeTriple, _delay, _triggerReleased, _config ]] call CBA_fnc_waitUntilAndExecute; }; diff --git a/addons/music/fnc_getMusicPlaying.sqf b/addons/music/fnc_getMusicPlaying.sqf index 60e5b32ca0..d3c5732d41 100644 --- a/addons/music/fnc_getMusicPlaying.sqf +++ b/addons/music/fnc_getMusicPlaying.sqf @@ -24,7 +24,8 @@ if (isNil QGVAR(track)) exitWith {["", 0, 0]}; GVAR(track) params ["_class", "_startTime", "_playPos", "_duration"]; -private _trackTime = (CBA_missionTime - _startTime) + _playPos; +private _timeDiff = CBA_missionTimeTriple vectorDiff _startTime; +private _trackTime = (_timeDiff vectorDotProduct [1e6 , 1e3, 1]) + _playPos; private _remainingTime = _duration - _trackTime; if (_remainingTime <= 0) then { diff --git a/addons/music/fnc_playMusic.sqf b/addons/music/fnc_playMusic.sqf index cf7160d0ab..f3be7885f1 100644 --- a/addons/music/fnc_playMusic.sqf +++ b/addons/music/fnc_playMusic.sqf @@ -37,7 +37,7 @@ private _duration = [_className, "duration"] call CBA_fnc_getMusicData; if (!isNil "_duration") then { if (_time < _duration) then { playMusic [_className, _time]; - GVAR(track) = [_className, CBA_missionTime, _time, _duration]; + GVAR(track) = [_className, CBA_missionTimeTriple, _time, _duration]; _return = true; } else { WARNING("Time is greater than song length"); diff --git a/addons/statemachine/fnc_dumpPerformanceCounters.sqf b/addons/statemachine/fnc_dumpPerformanceCounters.sqf index d705f5a6b2..4b1375777b 100644 --- a/addons/statemachine/fnc_dumpPerformanceCounters.sqf +++ b/addons/statemachine/fnc_dumpPerformanceCounters.sqf @@ -27,7 +27,7 @@ if (true) exitWith {WARNING("Requires `STATEMACHINE_PERFORMANCE_COUNTERS` in scr #endif diag_log text format ["CBA State Machine Results:"]; -diag_log text format ["------------------ [Time: %1] -------------------------", CBA_missionTime toFixed 1]; +diag_log text format ["------------------ [Time: %1] -------------------------", (CBA_missionTimeTriple vectorDotProduct [1e6 , 1e3, 1]) toFixed 1]; { // _x is an array of small individual run times from FUNC(clockwork) diff --git a/addons/ui/fnc_progressBar.sqf b/addons/ui/fnc_progressBar.sqf index 074f22c8e8..f91b82fdd4 100644 --- a/addons/ui/fnc_progressBar.sqf +++ b/addons/ui/fnc_progressBar.sqf @@ -78,12 +78,13 @@ _ctrlTitle ctrlSetText _title; // run failure code on previous progress bar if (!isNil QGVAR(ProgressBarParams)) then { GVAR(ProgressBarParams) params ["_arguments", "", "", "_onFailure", "_startTime", "_totalTime"]; - private _elapsedTime = (CBA_missionTime - _startTime) min _totalTime; + private _timeDiff = CBA_missionTimeTriple vectorDiff _startTime; + private _elapsedTime = (_timeDiff vectorDotProduct [1e6 , 1e3, 1]) min _totalTime; [_onFailure, [_arguments, false, _elapsedTime, _totalTime, 3]] call CBA_fnc_execNextFrame; }; -GVAR(ProgressBarParams) = [_arguments, _condition, _onSuccess, _onFailure, CBA_missionTime, _totalTime, _blockMouse, _blockKeys, _allowClose]; +GVAR(ProgressBarParams) = [_arguments, _condition, _onSuccess, _onFailure, CBA_missionTimeTriple, _totalTime, _blockMouse, _blockKeys, _allowClose]; // update bar, check condition, execute success or failure scripts private _ctrlScript = _display displayCtrl IDC_PROGRESSBAR_SCRIPT; @@ -92,7 +93,8 @@ _ctrlScript ctrlAddEventHandler ["Draw", { private _display = ctrlParent _ctrlScript; GVAR(ProgressBarParams) params ["_arguments", "_condition", "_onSuccess", "_onFailure", "_startTime", "_totalTime"]; - private _elapsedTime = (CBA_missionTime - _startTime) min _totalTime; + private _timeDiff = CBA_missionTimeTriple vectorDiff _startTime; + private _elapsedTime = (_timeDiff vectorDotProduct [1e6 , 1e3, 1]) min _totalTime; private _continue = [[_arguments, true, _elapsedTime, _totalTime], _condition] call { // prevent these variables from being overwritten @@ -133,7 +135,8 @@ if (_blockMouse) then { params ["_blockInputDisplay", "_key", "_shift", "_control", "_alt"]; GVAR(ProgressBarParams) params ["_arguments", "", "", "_onFailure", "_startTime", "_totalTime", "_blockMouse", "_blockKeys", "_allowClose"]; - private _elapsedTime = (CBA_missionTime - _startTime) min _totalTime; + private _timeDiff = CBA_missionTimeTriple vectorDiff _startTime; + private _elapsedTime = (_timeDiff vectorDotProduct [1e6 , 1e3, 1]) min _totalTime; if (_key isEqualTo DIK_ESCAPE) then { if (_allowClose) then { diff --git a/addons/xeh/fnc_postInit.sqf b/addons/xeh/fnc_postInit.sqf index 63fbe274c4..f13a05a6e6 100644 --- a/addons/xeh/fnc_postInit.sqf +++ b/addons/xeh/fnc_postInit.sqf @@ -19,9 +19,9 @@ Author: isNil { XEH_LOG("PostInit started. " + PFORMAT_9("MISSIONINIT",missionName,missionVersion,worldName,isMultiplayer,isServer,isDedicated,CBA_isHeadlessClient,hasInterface,didJIP)); - // fix CBA_missionTime being -1 on (non-JIP) clients at mission start. - if (CBA_missionTime == -1) then { - CBA_missionTime = 0; + // fix CBA_missionTimeTriple being -1 on (non-JIP) clients at mission start. + if (CBA_missionTimeTriple isEqualTo []) then { + CBA_missionTimeTriple = [0, 0, 0]; }; // call PostInit events