diff --git a/addons/attach/functions/fnc_getChildrenActions.sqf b/addons/attach/functions/fnc_getChildrenActions.sqf index 050eec4021..c156006931 100644 --- a/addons/attach/functions/fnc_getChildrenActions.sqf +++ b/addons/attach/functions/fnc_getChildrenActions.sqf @@ -43,6 +43,6 @@ private _magazines = magazines _player; private _action = [_x, _displayName, _picture, {[{_this call FUNC(attach)}, _this] call CBA_fnc_execNextFrame}, {true}, {}, _x] call EFUNC(interact_menu,createAction); _actions pushBack [_action, [], _target]; }; -} forEach ([_player, false] call CBA_fnc_uniqueUnitItems); +} forEach (_player call EFUNC(common,uniqueItems)); _actions diff --git a/addons/captives/functions/fnc_canApplyHandcuffs.sqf b/addons/captives/functions/fnc_canApplyHandcuffs.sqf index 231970255b..c1e3128feb 100644 --- a/addons/captives/functions/fnc_canApplyHandcuffs.sqf +++ b/addons/captives/functions/fnc_canApplyHandcuffs.sqf @@ -20,7 +20,7 @@ params ["_unit", "_target"]; //Check sides, Player has cableTie, target is alive and not already handcuffed (GVAR(allowHandcuffOwnSide) || {(side _unit) != (side _target)}) && -{"ACE_CableTie" in (items _unit)} && +{"ACE_CableTie" in (_unit call EFUNC(common,uniqueItems))} && {alive _target} && {!(_target getVariable [QGVAR(isHandcuffed), false])} && { diff --git a/addons/common/XEH_PREP.hpp b/addons/common/XEH_PREP.hpp index 526c498cd9..c070623893 100644 --- a/addons/common/XEH_PREP.hpp +++ b/addons/common/XEH_PREP.hpp @@ -178,6 +178,7 @@ PREP(toHex); PREP(toNumber); PREP(unhideUnit); PREP(uniqueElements); +PREP(uniqueItems); PREP(unloadPerson); PREP(unloadPersonLocal); PREP(unmuteUnit); diff --git a/addons/common/XEH_postInit.sqf b/addons/common/XEH_postInit.sqf index 4299213e44..ce6126cba7 100644 --- a/addons/common/XEH_postInit.sqf +++ b/addons/common/XEH_postInit.sqf @@ -261,6 +261,11 @@ TRACE_1("adding unit playerEH to set ace_player",isNull cba_events_oldUnit); ACE_player = (_this select 0); }, true] call CBA_fnc_addPlayerEventHandler; +// Clear uniqueItems cache on loadout change +["loadout", { + GVAR(uniqueItemsCache) = nil; +}] call CBA_fnc_addPlayerEventHandler; + GVAR(OldIsCamera) = false; [{ diff --git a/addons/common/functions/fnc_hasItem.sqf b/addons/common/functions/fnc_hasItem.sqf index 9d5d79b1a5..04d3dd0902 100644 --- a/addons/common/functions/fnc_hasItem.sqf +++ b/addons/common/functions/fnc_hasItem.sqf @@ -18,4 +18,4 @@ params [["_unit", objNull, [objNull]], ["_item", "", [""]]]; -_item in items _unit +_item in (_unit call EFUNC(common,uniqueItems)) diff --git a/addons/common/functions/fnc_uniqueItems.sqf b/addons/common/functions/fnc_uniqueItems.sqf new file mode 100644 index 0000000000..b5e16ab6ed --- /dev/null +++ b/addons/common/functions/fnc_uniqueItems.sqf @@ -0,0 +1,39 @@ +/* + * Author: mharis001 + * Returns list of unique items in a unit's inventory. + * Items are cached if unit is ACE_player. + * + * Arguments: + * 0: Unit + * + * Return Value: + * Items + * + * Example: + * [_player] call ace_common_fnc_uniqueItems + * + * Public: No + */ +#include "script_component.hpp" + +params ["_unit"]; + +private _fnc_getItems = { + private _items = (getItemCargo uniformContainer _unit) select 0; + _items append ((getItemCargo vestContainer _unit) select 0); + _items append ((getItemCargo backpackContainer _unit) select 0); + + _items arrayIntersect _items +}; + +// Use cached items list if unit is ACE_player +if (_unit isEqualTo ACE_player) then { + private _items = GVAR(uniqueItemsCache); + if (isNil "_items") then { + _items = call _fnc_getItems; + GVAR(uniqueItemsCache) = _items; + }; + +_items +} else { + call _fnc_getItems; +}; diff --git a/addons/common/functions/fnc_useItem.sqf b/addons/common/functions/fnc_useItem.sqf index 3accecc429..44be64587c 100644 --- a/addons/common/functions/fnc_useItem.sqf +++ b/addons/common/functions/fnc_useItem.sqf @@ -22,7 +22,7 @@ private _return = false; if !(_vehicleUsage) then { if (_item != "") then { - if (_item in items _unit) then { + if (_item in (_unit call EFUNC(common,uniqueItems))) then { _unit removeItem _item; _return = true; } else { diff --git a/addons/dogtags/CfgVehicles.hpp b/addons/dogtags/CfgVehicles.hpp index af8cfb1442..cc56410699 100644 --- a/addons/dogtags/CfgVehicles.hpp +++ b/addons/dogtags/CfgVehicles.hpp @@ -36,7 +36,7 @@ class CfgVehicles { condition = "true"; statement = ""; exceptions[] = {"isNotSwimming", "isNotInside", "isNotSitting"}; - insertChildren = QUOTE(_this call DFUNC(addDogtagActions)); + insertChildren = QUOTE(_player call DFUNC(addDogtagActions)); }; }; }; diff --git a/addons/dogtags/functions/fnc_addDogtagActions.sqf b/addons/dogtags/functions/fnc_addDogtagActions.sqf index 988f909775..65ebfe5034 100644 --- a/addons/dogtags/functions/fnc_addDogtagActions.sqf +++ b/addons/dogtags/functions/fnc_addDogtagActions.sqf @@ -1,42 +1,33 @@ /* - * Author: SzwedzikPL - * Creates one action per dogtag. + * Author: SzwedzikPL, mharis001 + * Returns children actions for checking dogtags in player's inventory. * * Arguments: - * 0: Target - * 1: Player + * 0: Player * * Return Value: - * Children actions + * Actions * * Example: - * _childrenActions = [unit, player] call ace_dogtags_fnc_addDogtagActions + * [_player] call ace_dogtags_fnc_addDogtagActions * * Public: No */ #include "script_component.hpp" -params ["_target", "_player"]; +params ["_player"]; -//Get all dogtags and their ids -private _unitDogtags = []; -private _unitDogtagIDs = []; -{ - private _id = getNumber (configFile >> "CfgWeapons" >> _x >> QGVAR(tagID)); - if (_id > 0) then { - _unitDogtags pushBack _x; - _unitDogtagIDs pushBack _id; - }; -} forEach items _player; - -//Create action children for all dogtags +private _cfgWeapons = configFile >> "CfgWeapons"; private _actions = []; -{ - private _displayName = getText (configFile >> "CfgWeapons" >> _x >> "displayName"); - private _picture = getText (configFile >> "CfgWeapons" >> _x >> "picture"); - private _action = [_x, _displayName, _picture, {_this call FUNC(checkDogtagItem)}, {true}, {}, _x] call EFUNC(interact_menu,createAction); - _actions pushBack [_action, [], _player]; -} forEach _unitDogtags; +{ + private _config = _cfgWeapons >> _x; + if (getNumber (_config >> QGVAR(tagID)) > 0) then { + private _displayName = getText (_config >> "displayName"); + private _picture = getText (_config >> "picture"); + private _action = [_x, _displayName, _picture, {_this call FUNC(checkDogtagItem)}, {true}, {}, _x] call EFUNC(interact_menu,createAction); + _actions pushBack [_action, [], _player]; + }; +} forEach (_player call EFUNC(common,uniqueItems)); _actions diff --git a/addons/explosives/functions/fnc_canDefuse.sqf b/addons/explosives/functions/fnc_canDefuse.sqf index be114bf072..98f84278db 100644 --- a/addons/explosives/functions/fnc_canDefuse.sqf +++ b/addons/explosives/functions/fnc_canDefuse.sqf @@ -24,7 +24,7 @@ if (isNull _explosive) exitWith { deleteVehicle _target; false }; -if (vehicle _unit != _unit || {!("ACE_DefusalKit" in (items _unit))}) exitWith {false}; +if (vehicle _unit != _unit || {!("ACE_DefusalKit" in (_unit call EFUNC(common,uniqueItems)))}) exitWith {false}; if (GVAR(RequireSpecialist) && {!([_unit] call EFUNC(Common,isEOD))}) exitWith {false}; diff --git a/addons/explosives/functions/fnc_getDetonators.sqf b/addons/explosives/functions/fnc_getDetonators.sqf index d8c095e6f0..279613cf1e 100644 --- a/addons/explosives/functions/fnc_getDetonators.sqf +++ b/addons/explosives/functions/fnc_getDetonators.sqf @@ -1,25 +1,22 @@ /* - * Author: Garth 'L-H' de Wet - * Returns all the detonators of the unit + * Author: Garth 'L-H' de Wet, mharis001 + * Returns all detonators the given unit has. * * Arguments: * 0: Unit * * Return Value: - * Configs of all detonators + * Config names of detonators * * Example: - * _detonators = [player] call ACE_Explosives_fnc_getDetonators; + * [_player] call ace_explosives_fnc_getDetonators * * Public: Yes */ #include "script_component.hpp" -// IGNORE_PRIVATE_WARNING(_detonators); params ["_unit"]; -TRACE_1("params",_unit); +TRACE_1("Getting detonators",_unit); -private _result = (items _unit) select {getNumber (ConfigFile >> "CfgWeapons" >> _x >> QGVAR(Detonator)) == 1}; -_result = _result arrayIntersect _result; - -_result +private _cfgWeapons = configFile >> "CfgWeapons"; +(_unit call EFUNC(common,uniqueItems)) select {getNumber (_cfgWeapons >> _x >> QGVAR(Detonator)) == 1}; diff --git a/addons/explosives/functions/fnc_onIncapacitated.sqf b/addons/explosives/functions/fnc_onIncapacitated.sqf index b134cdb45e..2ae23629d5 100644 --- a/addons/explosives/functions/fnc_onIncapacitated.sqf +++ b/addons/explosives/functions/fnc_onIncapacitated.sqf @@ -25,7 +25,7 @@ if (_unit == ace_player) then { }; // Exit if no item -if (({_x == "ACE_DeadManSwitch"} count (items _unit)) == 0) exitWith {}; +if !("ACE_DeadManSwitch" in (_unit call EFUNC(common,uniqueItems))) exitWith {}; private _range = getNumber (configFile >> "CfgWeapons" >> "ACE_DeadManSwitch" >> QGVAR(range)); private _deadman = [_unit, "DeadManSwitch"] call FUNC(getPlacedExplosives); diff --git a/addons/logistics_uavbattery/functions/fnc_canRefuelUAV.sqf b/addons/logistics_uavbattery/functions/fnc_canRefuelUAV.sqf index 451753a9e2..7d000fdfaa 100644 --- a/addons/logistics_uavbattery/functions/fnc_canRefuelUAV.sqf +++ b/addons/logistics_uavbattery/functions/fnc_canRefuelUAV.sqf @@ -18,4 +18,4 @@ params ["_caller", "_target"]; -("ACE_UAVBattery" in (items _caller)) && {(fuel _target) < 1} && {(speed _target) < 1} && {!(isEngineOn _target)} && {(_target distance _caller) <= 4} +("ACE_UAVBattery" in (_caller call EFUNC(common,uniqueItems))) && {(fuel _target) < 1} && {(speed _target) < 1} && {!(isEngineOn _target)} && {(_target distance _caller) <= 4} diff --git a/addons/map/functions/fnc_getUnitFlashlights.sqf b/addons/map/functions/fnc_getUnitFlashlights.sqf index 86eeed006d..9987d59b1d 100644 --- a/addons/map/functions/fnc_getUnitFlashlights.sqf +++ b/addons/map/functions/fnc_getUnitFlashlights.sqf @@ -24,6 +24,6 @@ private _flashlights = []; if (isText (configFile >> "CfgWeapons" >> _x >> "ItemInfo" >> "FlashLight" >> "ACE_Flashlight_Colour")) then { _flashlights pushBackUnique _x; }; -} forEach (items _unit); +} forEach (_unit call EFUNC(common,uniqueItems)); _flashlights diff --git a/addons/maptools/functions/fnc_canUseMapTools.sqf b/addons/maptools/functions/fnc_canUseMapTools.sqf index bc3c7fbb8a..8b87855d79 100644 --- a/addons/maptools/functions/fnc_canUseMapTools.sqf +++ b/addons/maptools/functions/fnc_canUseMapTools.sqf @@ -24,6 +24,6 @@ visibleMap && } forEach (assignedItems ACE_player); false } && -{"ACE_MapTools" in (items ACE_player)} && +{"ACE_MapTools" in (ACE_player call EFUNC(common,uniqueItems))} && {!GVAR(mapTool_isDragging)} && {!GVAR(mapTool_isRotating)} diff --git a/addons/maptools/functions/fnc_handleMouseMove.sqf b/addons/maptools/functions/fnc_handleMouseMove.sqf index a7c48cfed4..8ff8fd1dc1 100644 --- a/addons/maptools/functions/fnc_handleMouseMove.sqf +++ b/addons/maptools/functions/fnc_handleMouseMove.sqf @@ -21,7 +21,7 @@ params ["_control", "_mousePosX", "_mousePosY"]; TRACE_3("params",_control,_mousePosX,_mousePosY); // If have no map tools, then exit -if (((isNull ACE_player) || {!("ACE_MapTools" in items ACE_player)})) exitWith { +if (((isNull ACE_player) || {!("ACE_MapTools" in (ACE_player call EFUNC(common,uniqueItems)))})) exitWith { false }; diff --git a/addons/maptools/functions/fnc_updateMapToolMarkers.sqf b/addons/maptools/functions/fnc_updateMapToolMarkers.sqf index 026a4037d1..98d47ce385 100644 --- a/addons/maptools/functions/fnc_updateMapToolMarkers.sqf +++ b/addons/maptools/functions/fnc_updateMapToolMarkers.sqf @@ -17,7 +17,7 @@ params ["_theMap"]; -if ((GVAR(mapTool_Shown) == 0) || {!("ACE_MapTools" in items ACE_player)}) exitWith {}; +if ((GVAR(mapTool_Shown) == 0) || {!("ACE_MapTools" in (ACE_player call EFUNC(common,uniqueItems)))}) exitWith {}; private _rotatingTexture = ""; private _textureWidth = 0; diff --git a/addons/microdagr/XEH_clientInit.sqf b/addons/microdagr/XEH_clientInit.sqf index d82721e697..7a8d775a05 100644 --- a/addons/microdagr/XEH_clientInit.sqf +++ b/addons/microdagr/XEH_clientInit.sqf @@ -5,7 +5,7 @@ if (!hasInterface) exitWith {}; //Add deviceKey entry: private _conditonCode = { - ("ACE_microDAGR" in (items ACE_player)) + "ACE_microDAGR" in (ACE_player call EFUNC(common,uniqueItems)) }; private _toggleCode = { if !([ACE_player, objNull, ["notOnMap", "isNotInside", "isNotSitting"]] call EFUNC(common,canInteractWith)) exitWith {}; diff --git a/addons/microdagr/functions/fnc_canShow.sqf b/addons/microdagr/functions/fnc_canShow.sqf index cb652b9214..17cd48cbed 100644 --- a/addons/microdagr/functions/fnc_canShow.sqf +++ b/addons/microdagr/functions/fnc_canShow.sqf @@ -22,12 +22,12 @@ _returnValue = switch (_showType) do { case (DISPLAY_MODE_CLOSED): { true }; //Can always close case (DISPLAY_MODE_HIDDEN): { true }; //Can always hide case (DISPLAY_MODE_DIALOG): { - ("ACE_microDAGR" in (items ACE_player)) && {[ACE_player, objNull, ["notOnMap", "isNotInside", "isNotSitting"]] call EFUNC(common,canInteractWith)} + ("ACE_microDAGR" in (ACE_player call EFUNC(common,uniqueItems))) && {[ACE_player, objNull, ["notOnMap", "isNotInside", "isNotSitting"]] call EFUNC(common,canInteractWith)} }; case (DISPLAY_MODE_DISPLAY): { //Can't have minimap up while zoomed in on foot, but allow drivers to use while in "Gunner" to handle non-3d vehicles like most tanks ((cameraView != "GUNNER") || {(vehicle ACE_player != ACE_player) && {driver vehicle ACE_player == ACE_player}}) && - {"ACE_microDAGR" in (items ACE_player)} && + {"ACE_microDAGR" in (ACE_player call EFUNC(common,uniqueItems))} && {[ACE_player, objNull, ["notOnMap", "isNotInside", "isNotSitting"]] call EFUNC(common,canInteractWith)} }; default { false }; diff --git a/addons/microdagr/functions/fnc_openDisplay.sqf b/addons/microdagr/functions/fnc_openDisplay.sqf index 0f407138f5..3f7594d3a7 100644 --- a/addons/microdagr/functions/fnc_openDisplay.sqf +++ b/addons/microdagr/functions/fnc_openDisplay.sqf @@ -73,7 +73,7 @@ if ((_oldShowMode == DISPLAY_MODE_CLOSED) && {GVAR(currentShowMode) != DISPLAY_M [{ params ["_args", "_idPFH"]; _args params ["_player"]; - if ((isNull ACE_player) || {!alive ACE_player} || {ACE_player != _player} || {!("ACE_microDAGR" in (items ACE_player))} || {GVAR(currentShowMode) == DISPLAY_MODE_CLOSED}) then { + if ((isNull ACE_player) || {!alive ACE_player} || {ACE_player != _player} || {!("ACE_microDAGR" in (ACE_player call EFUNC(common,uniqueItems)))} || {GVAR(currentShowMode) == DISPLAY_MODE_CLOSED}) then { //Close Display if still open: if (GVAR(currentShowMode) != DISPLAY_MODE_CLOSED) then { [DISPLAY_MODE_CLOSED] call FUNC(openDisplay); diff --git a/addons/mk6mortar/functions/fnc_rangeTableCanUse.sqf b/addons/mk6mortar/functions/fnc_rangeTableCanUse.sqf index b98ee543f5..6799798802 100644 --- a/addons/mk6mortar/functions/fnc_rangeTableCanUse.sqf +++ b/addons/mk6mortar/functions/fnc_rangeTableCanUse.sqf @@ -18,4 +18,4 @@ params ["_vehicle", "_player"]; -"ACE_RangeTable_82mm" in (items _player); +"ACE_RangeTable_82mm" in (_player call EFUNC(common,uniqueItems)); diff --git a/addons/sandbag/functions/fnc_canDeploy.sqf b/addons/sandbag/functions/fnc_canDeploy.sqf index 426dde56f2..d22fef72ee 100644 --- a/addons/sandbag/functions/fnc_canDeploy.sqf +++ b/addons/sandbag/functions/fnc_canDeploy.sqf @@ -17,6 +17,6 @@ params ["_unit"]; -if !("ACE_Sandbag_empty" in items _unit) exitWith {false}; +if !("ACE_Sandbag_empty" in (_unit call EFUNC(common,uniqueItems))) exitWith {false}; _unit call EFUNC(common,canDig) diff --git a/addons/sandbag/functions/fnc_handlePlayerInventoryChanged.sqf b/addons/sandbag/functions/fnc_handlePlayerInventoryChanged.sqf index 50d2fdede0..c83c4158c7 100644 --- a/addons/sandbag/functions/fnc_handlePlayerInventoryChanged.sqf +++ b/addons/sandbag/functions/fnc_handlePlayerInventoryChanged.sqf @@ -19,7 +19,7 @@ params ["_unit"]; if (_unit getVariable [QGVAR(isDeploying), false]) then { - if !("ACE_Sandbag_empty" in items _unit) then { + if !("ACE_Sandbag_empty" in (_unit call EFUNC(common,uniqueItems))) then { [_unit] call FUNC(deployCancel); }; }; diff --git a/addons/trenches/functions/fnc_canContinueDiggingTrench.sqf b/addons/trenches/functions/fnc_canContinueDiggingTrench.sqf index 2e1942d6b8..782c434dfd 100644 --- a/addons/trenches/functions/fnc_canContinueDiggingTrench.sqf +++ b/addons/trenches/functions/fnc_canContinueDiggingTrench.sqf @@ -18,7 +18,7 @@ params ["_trench", "_unit"]; -if !("ACE_EntrenchingTool" in items _unit) exitWith {false}; +if !("ACE_EntrenchingTool" in (_unit call EFUNC(common,uniqueItems))) exitWith {false}; if ((_trench getVariable [QGVAR(progress), 0]) >= 1) exitWith {false}; // Prevent removing/digging trench by more than one person diff --git a/addons/trenches/functions/fnc_canDigTrench.sqf b/addons/trenches/functions/fnc_canDigTrench.sqf index a99c5c6b60..0749cbf574 100644 --- a/addons/trenches/functions/fnc_canDigTrench.sqf +++ b/addons/trenches/functions/fnc_canDigTrench.sqf @@ -17,6 +17,6 @@ params ["_unit"]; -if !("ACE_EntrenchingTool" in items _unit) exitWith {false}; +if !("ACE_EntrenchingTool" in (_unit call EFUNC(common,uniqueItems))) exitWith {false}; _unit call EFUNC(common,canDig) diff --git a/addons/trenches/functions/fnc_canRemoveTrench.sqf b/addons/trenches/functions/fnc_canRemoveTrench.sqf index 4e33857637..73cf04f547 100644 --- a/addons/trenches/functions/fnc_canRemoveTrench.sqf +++ b/addons/trenches/functions/fnc_canRemoveTrench.sqf @@ -18,7 +18,7 @@ params ["_trench", "_unit"]; -if !("ACE_EntrenchingTool" in items _unit) exitWith {false}; +if !("ACE_EntrenchingTool" in (_unit call EFUNC(common,uniqueItems))) exitWith {false}; // Prevent removing/digging trench by more than one person if (_trench getVariable [QGVAR(digging), false]) exitWith {false}; diff --git a/addons/trenches/functions/fnc_handlePlayerInventoryChanged.sqf b/addons/trenches/functions/fnc_handlePlayerInventoryChanged.sqf index 11bdef6072..fa3b935074 100644 --- a/addons/trenches/functions/fnc_handlePlayerInventoryChanged.sqf +++ b/addons/trenches/functions/fnc_handlePlayerInventoryChanged.sqf @@ -19,7 +19,7 @@ params ["_unit"]; if (_unit getVariable [QGVAR(isPlacing), false]) then { - if !("ACE_EntrenchingTool" in items _unit) then { + if !("ACE_EntrenchingTool" in (_unit call EFUNC(common,uniqueItems))) then { [_unit] call FUNC(placeCancel); }; }; diff --git a/addons/vehiclelock/functions/fnc_hasKeyForVehicle.sqf b/addons/vehiclelock/functions/fnc_hasKeyForVehicle.sqf index bc566794fe..081cdfd899 100644 --- a/addons/vehiclelock/functions/fnc_hasKeyForVehicle.sqf +++ b/addons/vehiclelock/functions/fnc_hasKeyForVehicle.sqf @@ -25,11 +25,12 @@ if (isNull _veh) exitWith {ERROR("null vehicle"); false}; private _returnValue = false; //Master can open anything "no matter what" -if ("ACE_key_master" in (items _unit)) then {_returnValue = true}; +private _items = _unit call EFUNC(common,uniqueItems); +if ("ACE_key_master" in _items) then {_returnValue = true}; //Check side key private _sideKeyName = [_veh] call FUNC(getVehicleSideKey); -if (_sideKeyName in (items _unit)) then {_returnValue = true}; +if (_sideKeyName in _items) then {_returnValue = true}; //Check custom keys private _customKeys = _veh getVariable [QGVAR(customKeys), []]; diff --git a/addons/vehiclelock/functions/fnc_lockpick.sqf b/addons/vehiclelock/functions/fnc_lockpick.sqf index a08289454a..50e47a2e66 100644 --- a/addons/vehiclelock/functions/fnc_lockpick.sqf +++ b/addons/vehiclelock/functions/fnc_lockpick.sqf @@ -30,7 +30,7 @@ if (isNull _veh) exitWith {ERROR("null vehicle"); false}; if ((locked _veh) == 0) exitWith {false}; //need lockpick item -if (!("ACE_key_lockpick" in (items _unit))) exitWith {false}; +if !("ACE_key_lockpick" in (_unit call EFUNC(common,uniqueItems))) exitWith {false}; private _vehLockpickStrenth = _veh getVariable[QGVAR(lockpickStrength), GVAR(DefaultLockpickStrength)]; if (!(_vehLockpickStrenth isEqualType 0)) exitWith {ERROR("ACE_vehicleLock_LockpickStrength invalid"); false};