Vehicles - Add Resume/Set functionality to speed control (#8967)

* Add Resume/Set functionality to speed control

* Apply suggestions from code review

Co-authored-by: BrettMayson <brett@mayson.io>

---------

Co-authored-by: BrettMayson <brett@mayson.io>
This commit is contained in:
Dystopian 2023-06-28 17:17:14 +03:00 committed by GitHub
parent 8b94d765aa
commit 22b93e2d03
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 105 additions and 70 deletions

View File

@ -2,3 +2,4 @@ PREP(autoThrottle);
PREP(speedLimiter);
PREP(startEngine);
PREP(setVehicleStartDelay);
PREP(toggleSpeedControl);

View File

@ -3,65 +3,15 @@
if (!hasInterface) exitWith {};
GVAR(isSpeedLimiter) = false;
// Add keybinds
["ACE3 Vehicles", QGVAR(speedLimiter), localize LSTRING(SpeedLimiter),
{
private _connectedUAV = getConnectedUAV ACE_player;
private _uavControl = UAVControl _connectedUAV;
if ((_uavControl select 1) == "DRIVER") then {
if !(_connectedUAV isKindOf "UGV_01_base_F") exitWith {false};
GVAR(isUAV) = true;
[_uavControl select 0, _connectedUAV] call FUNC(speedLimiter);
true
} else {
// Conditions: canInteract
if !([ACE_player, objNull, ["isNotInside"]] call EFUNC(common,canInteractWith)) exitWith {false};
// Conditions: specific
private _vehicle = vehicle ACE_player;
if (
ACE_player != driver _vehicle
|| {-1 == ["Car", "Tank", "Ship"] findIf {_vehicle isKindOf _x}}
) exitWith {false};
GVAR(isUAV) = false;
// Statement
[ACE_player, _vehicle] call FUNC(speedLimiter);
true
};
},
{false},
[DIK_DELETE, [false, false, false]], false] call CBA_fnc_addKeybind;
// Add keybinds
["ACE3 Vehicles", QGVAR(speedLimiter), localize LSTRING(SpeedLimiter), {
false call FUNC(toggleSpeedControl)
}, {false}, [DIK_DELETE, [false, false, false]], false] call CBA_fnc_addKeybind;
["ACE3 Vehicles", QGVAR(cruiseControl), localize LSTRING(CruiseControl), {
private _connectedUAV = getConnectedUAV ACE_player;
private _uavControl = UAVControl _connectedUAV;
if ((_uavControl select 1) == "DRIVER") then {
if !(_connectedUAV isKindOf "UGV_01_base_F") exitWith {false};
GVAR(isUAV) = true;
[_uavControl select 0, _connectedUAV, true] call FUNC(speedLimiter);
true
} else {
// Conditions: canInteract
if !([ACE_player, objNull, ["isNotInside"]] call EFUNC(common,canInteractWith)) exitWith {false};
// Conditions: specific
private _vehicle = vehicle ACE_player;
if (
ACE_player != driver _vehicle
|| {-1 == ["Car", "Tank", "Ship", "Plane"] findIf {_vehicle isKindOf _x}}
) exitWith {false};
GVAR(isUAV) = false;
// Statement
if (_vehicle isKindOf "Plane") then {
[ACE_player, _vehicle] call FUNC(autoThrottle);
} else {
[ACE_player, _vehicle, true] call FUNC(speedLimiter);
};
true
};
},
{false},
[DIK_INSERT, [false, false, false]], false] call CBA_fnc_addKeybind;
true call FUNC(toggleSpeedControl)
}, {false}, [DIK_INSERT, [false, false, false]], false] call CBA_fnc_addKeybind;
["ACE3 Vehicles", QGVAR(scrollUp), localize LSTRING(IncreaseSpeedLimit), {
if (GVAR(isSpeedLimiter)) then {
@ -69,6 +19,9 @@ GVAR(isSpeedLimiter) = false;
GVAR(speedLimit) = 5 max GVAR(speedLimiterStep) * floor (GVAR(speedLimit) / GVAR(speedLimiterStep));
[["%1: %2", LSTRING(SpeedLimit), GVAR(speedLimit)]] call EFUNC(common,displayTextStructured);
true
} else {
!isNil QGVAR(speedLimit)
&& {[GVAR(isCruiseControl), true] call FUNC(toggleSpeedControl)} // RESUME
};
}, {false}, [MOUSE_SCROLL_UP, [false, true, false]], false] call CBA_fnc_addKeybind; // Ctrl + Mouse Wheel Scroll Up
@ -78,5 +31,8 @@ GVAR(isSpeedLimiter) = false;
GVAR(speedLimit) = 5 max GVAR(speedLimiterStep) * ceil (GVAR(speedLimit) / GVAR(speedLimiterStep));
[["%1: %2", LSTRING(SpeedLimit), GVAR(speedLimit)]] call EFUNC(common,displayTextStructured);
true
} else {
!isNil QGVAR(isCruiseControl)
&& {GVAR(isCruiseControl) call FUNC(toggleSpeedControl)} // SET
};
}, {false}, [MOUSE_SCROLL_DOWN, [false, true, false]], false] call CBA_fnc_addKeybind; // Ctrl + Mouse Wheel Scroll Down

View File

@ -6,6 +6,7 @@
* Arguments:
* 0: Driver <OBJECT>
* 1: Vehicle <OBJECT>
* 2: Preserve Speed Limit <BOOL>
*
* Return Value:
* None
@ -20,7 +21,7 @@
#define PID_D 0
#define EPSILON 0.001
params ["_driver", "_vehicle"];
params ["_driver", "_vehicle", ["_preserveSpeedLimit", false]];
if (GVAR(isSpeedLimiter)) exitWith {
[localize LSTRING(Off)] call EFUNC(common,displayTextStructured);
@ -31,9 +32,12 @@ if (GVAR(isSpeedLimiter)) exitWith {
[localize LSTRING(On)] call EFUNC(common,displayTextStructured);
playSound "ACE_Sound_Click";
GVAR(isSpeedLimiter) = true;
GVAR(isCruiseControl) = true; // enables SET/RESUME
// Convert forward speed to KM/H. `speed _vehicle` isnt accurate enough for this controller to work well, so its easier to use M/S. The system assumes it is KM/H so we need the conversion
GVAR(speedLimit) = (((velocityModelSpace _vehicle) select 1) * 3.6) max 5;
if (!_preserveSpeedLimit) then {
// Convert forward speed to KM/H. `speed _vehicle` isnt accurate enough for this controller to work well, so its easier to use M/S. The system assumes it is KM/H so we need the conversion
GVAR(speedLimit) = (((velocityModelSpace _vehicle) select 1) * 3.6) max 5;
};
[{
params ["_args", "_idPFH"];
@ -43,8 +47,15 @@ GVAR(speedLimit) = (((velocityModelSpace _vehicle) select 1) * 3.6) max 5;
// this will take into account game being pausesd
private _deltaTime = CBA_missionTime - _lastTime;
if (_driver != driver _vehicle) then {
GVAR(isSpeedLimiter) = false;
private _role = _driver call EFUNC(common,getUavControlPosition);
if (GVAR(isUAV)) then {
if (_role != "DRIVER") then {
GVAR(isSpeedLimiter) = false;
};
} else {
if (_driver != currentPilot _vehicle || {_role != ""}) then {
GVAR(isSpeedLimiter) = false;
};
};
if (_throttleLogValue == 0) then {
@ -60,6 +71,10 @@ GVAR(speedLimit) = (((velocityModelSpace _vehicle) select 1) * 3.6) max 5;
GVAR(isSpeedLimiter) = false;
};
if (call CBA_fnc_getActiveFeatureCamera != "") then {
GVAR(isSpeedLimiter) = false;
};
if (!GVAR(isSpeedLimiter)) exitWith {
[_idPFH] call CBA_fnc_removePerFrameHandler;
};

View File

@ -7,6 +7,7 @@
* 0: Driver <OBJECT>
* 1: Vehicle <OBJECT>
* 2: Cruise Control <BOOL>
* 3: Preserve Speed Limit <BOOL>
*
* Return Value:
* None
@ -17,7 +18,7 @@
* Public: No
*/
params ["_driver", "_vehicle", ["_cruiseControl", false]];
params ["_driver", "_vehicle", ["_cruiseControl", false], ["_preserveSpeedLimit", false]];
if (GVAR(isSpeedLimiter)) exitWith {
switch ([GVAR(isCruiseControl), _cruiseControl]) do {
@ -26,7 +27,6 @@ if (GVAR(isSpeedLimiter)) exitWith {
playSound "ACE_Sound_Click";
_vehicle setCruiseControl [0, false];
GVAR(isSpeedLimiter) = false;
GVAR(isCruiseControl) = false;
};
case [true, false]: {
[localize LSTRING(On)] call EFUNC(common,displayTextStructured);
@ -59,28 +59,32 @@ playSound "ACE_Sound_Click";
GVAR(isSpeedLimiter) = true;
GVAR(isCruiseControl) = _cruiseControl;
GVAR(speedLimit) = round (speed _vehicle max 5);
if (!_preserveSpeedLimit) then {
GVAR(speedLimit) = round (speed _vehicle max 5);
};
GVAR(speedLimitInit) = true;
[{
params ["_args", "_idPFH"];
_args params ["_driver", "_vehicle"];
private _role = _driver call EFUNC(common,getUavControlPosition);
if (GVAR(isUAV)) then {
private _uavControl = UAVControl _vehicle;
if ((_uavControl select 0) != _driver || _uavControl select 1 != "DRIVER") then {
if (_role == "") then {
GVAR(isSpeedLimiter) = false;
TRACE_1("UAV driver changed, disabling speedlimit",_vehicle);
_vehicle setCruiseControl [0, false];
TRACE_1("UAV controller changed, disabling speedlimit",_vehicle);
};
} else {
if (_driver != driver _vehicle) then {
if (_driver != driver _vehicle || {_role != ""}) then {
GVAR(isSpeedLimiter) = false;
TRACE_3("Vehicle driver changed, disabling speedlimit",_driver,driver _vehicle,_vehicle);
_vehicle setCruiseControl [0, false];
};
};
if (call CBA_fnc_getActiveFeatureCamera != "") then {
GVAR(isSpeedLimiter) = false;
};
if (!GVAR(isSpeedLimiter)) exitWith {
_vehicle setCruiseControl [0, false];
[_idPFH] call CBA_fnc_removePerFrameHandler;

View File

@ -0,0 +1,59 @@
#include "script_component.hpp"
/*
* Author: Dystopian
* Checks if player can toggle speed control and runs proper speed control mode.
* Should run as key handler.
*
* Arguments:
* 0: Cruise Control <BOOL>
* 1: Preserve Speed Limit <BOOL>
*
* Return Value:
* Key handled <BOOL>
*
* Example:
* true call ace_vehicles_fnc_toggleSpeedControl
*
* Public: No
*/
params [["_cruiseControl", false], ["_preserveSpeedLimit", false]];
private _role = ACE_player call EFUNC(common,getUavControlPosition);
private _vehicle = objNull;
private _continue = true;
if (_role != "") then {
GVAR(isUAV) = true;
_vehicle = getConnectedUAV ACE_player;
_continue = (
!visibleMap
&& {_role == "DRIVER" || {!(_vehicle isKindOf "Plane")}}
);
} else {
GVAR(isUAV) = false;
_vehicle = vehicle ACE_player;
_continue = (
ACE_player == currentPilot _vehicle
&& {[ACE_player, objNull, ["isNotInside"]] call EFUNC(common,canInteractWith)}
);
};
if (
!_continue
|| {!(isEngineOn _vehicle)}
|| {!GVAR(isSpeedLimiter) && _cruiseControl && {speed _vehicle < 1}} // don't enable CC when stop or move backward
) exitWith {false};
private _allowedVehicleClasses = ["Car", "Tank", "Ship"];
if (_cruiseControl) then {
_allowedVehicleClasses pushBack "Plane";
};
if (-1 == _allowedVehicleClasses findIf {_vehicle isKindOf _x}) exitWith {false};
if (_vehicle isKindOf "Plane") then {
[ACE_player, _vehicle, _preserveSpeedLimit] call FUNC(autoThrottle);
} else {
[ACE_player, _vehicle, _cruiseControl, _preserveSpeedLimit] call FUNC(speedLimiter);
};
true