From 726bf8d407c969213595363f5d45119727dbf04a Mon Sep 17 00:00:00 2001 From: PabstMirror Date: Sun, 15 Mar 2015 11:27:21 -0500 Subject: [PATCH 01/14] Headers, Formating, Fixes, Lock Inventory Option --- addons/vehiclelock/CfgEventHandlers.hpp | 12 ++ addons/vehiclelock/CfgMagazines.hpp | 15 +- addons/vehiclelock/CfgVehicles.hpp | 191 +++++++++--------- addons/vehiclelock/CfgWeapons.hpp | 76 +++---- addons/vehiclelock/XEH_postInit.sqf | 5 + addons/vehiclelock/XEH_preInit.sqf | 5 +- addons/vehiclelock/config.cpp | 4 + .../functions/fnc_addKeyForVehicle.sqf | 67 +++--- .../functions/fnc_getVehicleSideKey.sqf | 40 ++-- .../functions/fnc_hasKeyForVehicle.sqf | 44 ++-- addons/vehiclelock/functions/fnc_lockpick.sqf | 105 +++++----- .../vehiclelock/functions/fnc_moduleInit.sqf | 80 ++++---- .../vehiclelock/functions/fnc_moduleSync.sqf | 79 ++++---- .../functions/fnc_onOpenInventory.sqf | 40 ++++ .../functions/fnc_serverSetupCustomKeyEH.sqf | 36 ++-- .../functions/fnc_setVehicleLockEH.sqf | 42 ++-- 16 files changed, 433 insertions(+), 408 deletions(-) create mode 100644 addons/vehiclelock/XEH_postInit.sqf create mode 100644 addons/vehiclelock/functions/fnc_onOpenInventory.sqf diff --git a/addons/vehiclelock/CfgEventHandlers.hpp b/addons/vehiclelock/CfgEventHandlers.hpp index b928bc2de6..cf704d000c 100644 --- a/addons/vehiclelock/CfgEventHandlers.hpp +++ b/addons/vehiclelock/CfgEventHandlers.hpp @@ -3,3 +3,15 @@ class Extended_PreInit_EventHandlers { init = QUOTE(call COMPILE_FILE(XEH_preInit)); }; }; +class Extended_PostInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_FILE(XEH_postInit)); + }; +}; +class Extended_InventoryOpened_EventHandlers { + class CAManBase { + class ADDON { + clientInventoryOpened = QUOTE(_this call FUNC(onOpenInventory);); + }; + }; +}; diff --git a/addons/vehiclelock/CfgMagazines.hpp b/addons/vehiclelock/CfgMagazines.hpp index 198c617509..100df8065b 100644 --- a/addons/vehiclelock/CfgMagazines.hpp +++ b/addons/vehiclelock/CfgMagazines.hpp @@ -1,9 +1,10 @@ class CfgMagazines { - class CA_Magazine; - class ACE_key_customKeyMagazine: CA_Magazine { - picture = QUOTE(PATHTOF(ui\keyBlack.paa)); - displayName = "ACE Vehicle Key"; //!!!CANNONT be localized!!!, because it is used as part of the magazineDetail string - descriptionShort = "$STR_ACE_Vehicle_Item_Custom_Description"; - count = 1; - }; + class CA_Magazine; + class ACE_key_customKeyMagazine: CA_Magazine { + picture = QUOTE(PATHTOF(ui\keyBlack.paa)); + displayName = "ACE Vehicle Key"; //!!!CANNOT be localized!!!: because it is used as part of the magazineDetail string + descriptionShort = "$STR_ACE_Vehicle_Item_Custom_Description"; + count = 1; + mass = 0; + }; }; diff --git a/addons/vehiclelock/CfgVehicles.hpp b/addons/vehiclelock/CfgVehicles.hpp index 5be796c126..1a7da461ca 100644 --- a/addons/vehiclelock/CfgVehicles.hpp +++ b/addons/vehiclelock/CfgVehicles.hpp @@ -1,102 +1,107 @@ #define MACRO_LOCK_ACTIONS \ - class ACE_MainActions { \ - class ACE_unlockVehicle { \ - displayName = "$STR_ACE_Vehicle_Action_UnLock"; \ - distance = 4; \ - condition = QUOTE(([ARR_2(_player, _target)] call FUNC(hasKeyForVehicle)) && {(locked _target) in [ARR_2(2,3)]}); \ - statement = QUOTE([ARR_3('SetVehicleLock', [_target], [ARR_2(_target,false)])] call EFUNC(common,targetEvent)); \ - showDisabled = 0; \ - priority = 0.3; \ - icon = QUOTE(PATHTOF(ui\key_menuIcon_ca.paa)); \ - }; \ - class ACE_lockVehicle { \ - displayName = "$STR_ACE_Vehicle_Action_Lock"; \ - distance = 4; \ - condition = QUOTE(([ARR_2(_player, _target)] call FUNC(hasKeyForVehicle)) && {(locked _target) in [ARR_2(0,1)]}); \ - statement = QUOTE([ARR_3('SetVehicleLock', [_target], [ARR_2(_target,true)])] call EFUNC(common,targetEvent)); \ - showDisabled = 0; \ - priority = 0.2; \ - icon = QUOTE(PATHTOF(ui\key_menuIcon_ca.paa)); \ - }; \ - class ACE_lockpickVehicle { \ - displayName = "$STR_ACE_Vehicle_Action_Lockpick"; \ - distance = 4; \ - condition = QUOTE([ARR_3(_player, _target, 'canLockpick')] call FUNC(lockpick)); \ - statement = QUOTE([ARR_3(_player, _target, 'startLockpick')] call FUNC(lockpick)); \ - showDisabled = 0; \ - priority = 0.1; \ - }; \ - }; + class ACE_MainActions { \ + class ACE_unlockVehicle { \ + displayName = "$STR_ACE_Vehicle_Action_UnLock"; \ + distance = 4; \ + condition = QUOTE(([ARR_2(_player, _target)] call FUNC(hasKeyForVehicle)) && {(locked _target) in [ARR_2(2,3)]}); \ + statement = QUOTE([ARR_3('VehicleLock_SetVehicleLock', [_target], [ARR_2(_target,false)])] call EFUNC(common,targetEvent)); \ + showDisabled = 0; \ + priority = 0.3; \ + icon = QUOTE(PATHTOF(ui\key_menuIcon_ca.paa)); \ + }; \ + class ACE_lockVehicle { \ + displayName = "$STR_ACE_Vehicle_Action_Lock"; \ + distance = 4; \ + condition = QUOTE(([ARR_2(_player, _target)] call FUNC(hasKeyForVehicle)) && {(locked _target) in [ARR_2(0,1)]}); \ + statement = QUOTE([ARR_3('VehicleLock_SetVehicleLock', [_target], [ARR_2(_target,true)])] call EFUNC(common,targetEvent)); \ + showDisabled = 0; \ + priority = 0.2; \ + icon = QUOTE(PATHTOF(ui\key_menuIcon_ca.paa)); \ + }; \ + class ACE_lockpickVehicle { \ + displayName = "$STR_ACE_Vehicle_Action_Lockpick"; \ + distance = 4; \ + condition = QUOTE([ARR_3(_player, _target, 'canLockpick')] call FUNC(lockpick)); \ + statement = QUOTE([ARR_3(_player, _target, 'startLockpick')] call FUNC(lockpick)); \ + showDisabled = 0; \ + priority = 0.1; \ + }; \ + }; class CfgVehicles { - class LandVehicle; - class Car: LandVehicle { - class ACE_Actions { - MACRO_LOCK_ACTIONS - }; - }; - class Tank: LandVehicle { - class ACE_Actions { - MACRO_LOCK_ACTIONS - }; - }; - class Air; - class Helicopter: Air { - class ACE_Actions { - MACRO_LOCK_ACTIONS - }; - }; - - class Logic; - class Module_F: Logic { - class ArgumentsBaseUnits {}; - class ModuleDescription {}; - }; - class ACE_VehicleLock_ModuleSetup: Module_F { - author = "$STR_ACE_Common_ACETeam"; - category = "ACE"; - displayName = "Vehicle Lock Setup"; - function = "ACE_VehicleLock_fnc_moduleInit"; - scope = 2; - isGlobal = 1; - icon = QUOTE(PATHTOF(ui\IconLock_ca.paa)); - functionPriority = 0; - class Arguments { - class SetLockState { - displayName = "Set Lock State"; // Argument label - description = "Set lock state for all vehicles on map at start"; // Tooltip description - typeName = "NUMBER"; // Value type, can be "NUMBER", "STRING" or "BOOL" - class values { - class None {name = "As Is"; value = 0; default = 1;}; - class Side {name = "Locked"; value = 1;}; - class Unique {name = "Unlocked"; value = 2;}; + class LandVehicle; + class Car: LandVehicle { + class ACE_Actions { + MACRO_LOCK_ACTIONS }; - }; - class LockpickStrength { - displayName = "Global Lockpick Strength"; - description = "Global Time to lockpick (in seconds). Default: 10"; - typeName = "NUMBER"; // Value type, can be "NUMBER", "STRING" or "BOOL" - defaultValue = "10"; // Default text filled in the input box - }; }; - class ModuleDescription: ModuleDescription { - description = "Settings for lockpick strength and initial vehicle lock state. Removes ambiguous lock states.
Source: vehiclelock.pbo"; + class Tank: LandVehicle { + class ACE_Actions { + MACRO_LOCK_ACTIONS + }; + }; + class Air; + class Helicopter: Air { + class ACE_Actions { + MACRO_LOCK_ACTIONS + }; }; - }; - class ACE_VehicleLock_ModuleSyncedAssign: Module_F { - author = "$STR_ACE_Common_ACETeam"; - category = "ACE"; - displayName = "Vehicle Key Assign"; - function = "ACE_VehicleLock_fnc_moduleSync"; - scope = 2; - isGlobal = 1; - icon = QUOTE(PATHTOF(ui\IconLock_ca.paa)); - functionPriority = 0; - class Arguments {}; - class ModuleDescription: ModuleDescription { - description = "Sync with vehicles and players. Will handout custom keys to players for every synced vehicle. Only valid for objects present at mission start.
Source: vehiclelock.pbo"; - sync[] = {"AnyPlayer", "AnyVehicle"}; + class Logic; + class Module_F: Logic { + class ModuleDescription {}; + }; + class ACE_VehicleLock_ModuleSetup: Module_F { + author = "$STR_ACE_Common_ACETeam"; + category = "ACE"; + displayName = "Vehicle Lock Setup"; + function = QUOTE(DFUNC(moduleInit)); + scope = 2; + isGlobal = 0; + icon = QUOTE(PATHTOF(ui\IconLock_ca.paa)); + functionPriority = 0; + class Arguments { + class LockVehicleInventory { + displayName = "Lock Vehicle Inventory"; + description = "Locks the inventory of locked vehicles"; + typeName = "BOOL"; + defaultValue = 0; + }; + class SetLockState { + displayName = "Set Lock State"; // Argument label + description = "Set lock state for all vehicles on map at start"; // Tooltip description + typeName = "NUMBER"; // Value type, can be "NUMBER", "STRING" or "BOOL" + class values { + class None {name = "As Is"; value = 0; default = 1;}; + class Side {name = "Locked"; value = 1;}; + class Unique {name = "Unlocked"; value = 2;}; + }; + }; + class DefaultLockpickStrength { + displayName = "Default Lockpick Strength"; + description = "Default Time to lockpick (in seconds). Default: 10"; + typeName = "NUMBER"; // Value type, can be "NUMBER", "STRING" or "BOOL" + defaultValue = "10"; // Default text filled in the input box + }; + }; + class ModuleDescription: ModuleDescription { + description = "Settings for lockpick strength and initial vehicle lock state. Removes ambiguous lock states.
Source: vehiclelock.pbo"; + }; + }; + + class ACE_VehicleLock_ModuleSyncedAssign: Module_F { + author = "$STR_ACE_Common_ACETeam"; + category = "ACE"; + displayName = "Vehicle Key Assign"; + function = QUOTE(DFUNC(moduleSync)); + scope = 2; + isGlobal = 0; + icon = QUOTE(PATHTOF(ui\IconLock_ca.paa)); + functionPriority = 0; + class Arguments {}; + class ModuleDescription: ModuleDescription { + description = "Sync with vehicles and players. Will handout custom keys to players for every synced vehicle. Only valid for objects present at mission start.
Source: vehiclelock.pbo"; + sync[] = {"AnyPlayer", "AnyVehicle"}; + }; }; - }; }; diff --git a/addons/vehiclelock/CfgWeapons.hpp b/addons/vehiclelock/CfgWeapons.hpp index 157fb4bf60..4b20de15d7 100644 --- a/addons/vehiclelock/CfgWeapons.hpp +++ b/addons/vehiclelock/CfgWeapons.hpp @@ -1,41 +1,41 @@ class CfgWeapons { - class InventoryItem_Base_F; - class ACE_ItemCore; + class InventoryItem_Base_F; + class ACE_ItemCore; - class ACE_key_master: ACE_ItemCore { - author = "$STR_ACE_Common_ACETeam"; - displayName = "Vehicle Key: Master"; - descriptionShort = "$STR_ACE_Vehicle_Item_Master_Description"; - model = "\A3\weapons_F\ammo\mag_univ.p3d"; - picture = QUOTE(PATHTOF(ui\keyBlack.paa)); - scope = 2; - class ItemInfo: InventoryItem_Base_F { - mass = 0.1; - }; - }; - class ACE_key_lockpick: ACE_key_master { - displayName = "Lockpick"; - descriptionShort = "$STR_ACE_Vehicle_Item_Lockpick_Description"; - picture = QUOTE(PATHTOF(ui\lockpick.paa)); - }; - class ACE_key_west: ACE_key_master { - displayName = "Vehicle Key: West"; - descriptionShort = "$STR_ACE_Vehicle_Item_West_Description"; - picture = QUOTE(PATHTOF(ui\keyBlue.paa)); - }; - class ACE_key_east: ACE_key_master { - displayName = "Vehicle Key: East"; - descriptionShort = "$STR_ACE_Vehicle_Item_East_Description"; - picture = QUOTE(PATHTOF(ui\keyRed.paa)); - }; - class ACE_key_indp: ACE_key_master { - displayName = "Vehicle Key: Independent"; - descriptionShort = "$STR_ACE_Vehicle_Item_Indp_Description"; - picture = QUOTE(PATHTOF(ui\keyPurple.paa)); - }; - class ACE_key_civ: ACE_key_master { - displayName = "Vehicle Key: Civilian"; - descriptionShort = "$STR_ACE_Vehicle_Item_Civ_Description"; - picture = QUOTE(PATHTOF(ui\keyGreen.paa)); - }; + class ACE_key_master: ACE_ItemCore { + author = "$STR_ACE_Common_ACETeam"; + displayName = "Vehicle Key: Master"; + descriptionShort = "$STR_ACE_Vehicle_Item_Master_Description"; + model = "\A3\weapons_F\ammo\mag_univ.p3d"; + picture = QUOTE(PATHTOF(ui\keyBlack.paa)); + scope = 2; + class ItemInfo: InventoryItem_Base_F { + mass = 0; + }; + }; + class ACE_key_lockpick: ACE_key_master { + displayName = "Lockpick"; + descriptionShort = "$STR_ACE_Vehicle_Item_Lockpick_Description"; + picture = QUOTE(PATHTOF(ui\lockpick.paa)); + }; + class ACE_key_west: ACE_key_master { + displayName = "Vehicle Key: West"; + descriptionShort = "$STR_ACE_Vehicle_Item_West_Description"; + picture = QUOTE(PATHTOF(ui\keyBlue.paa)); + }; + class ACE_key_east: ACE_key_master { + displayName = "Vehicle Key: East"; + descriptionShort = "$STR_ACE_Vehicle_Item_East_Description"; + picture = QUOTE(PATHTOF(ui\keyRed.paa)); + }; + class ACE_key_indp: ACE_key_master { + displayName = "Vehicle Key: Independent"; + descriptionShort = "$STR_ACE_Vehicle_Item_Indp_Description"; + picture = QUOTE(PATHTOF(ui\keyPurple.paa)); + }; + class ACE_key_civ: ACE_key_master { + displayName = "Vehicle Key: Civilian"; + descriptionShort = "$STR_ACE_Vehicle_Item_Civ_Description"; + picture = QUOTE(PATHTOF(ui\keyGreen.paa)); + }; }; diff --git a/addons/vehiclelock/XEH_postInit.sqf b/addons/vehiclelock/XEH_postInit.sqf new file mode 100644 index 0000000000..c635de2bd3 --- /dev/null +++ b/addons/vehiclelock/XEH_postInit.sqf @@ -0,0 +1,5 @@ +#include "script_component.hpp" + +//Add Event Handlers +["VehicleLock_SetupCustomKey", {_this call FUNC(serverSetupCustomKeyEH)}] call EFUNC(common,addEventHandler); +["VehicleLock_SetVehicleLock", {_this call FUNC(setVehicleLockEH)}] call EFUNC(common,addEventHandler); diff --git a/addons/vehiclelock/XEH_preInit.sqf b/addons/vehiclelock/XEH_preInit.sqf index 80d1d6335f..bdab28fc75 100644 --- a/addons/vehiclelock/XEH_preInit.sqf +++ b/addons/vehiclelock/XEH_preInit.sqf @@ -8,11 +8,8 @@ PREP(hasKeyForVehicle); PREP(lockpick); PREP(moduleInit); PREP(moduleSync); +PREP(onOpenInventory); PREP(serverSetupCustomKeyEH); PREP(setVehicleLockEH); -//Add Event Handlers -["SetupCustomKey", {_this call FUNC(serverSetupCustomKeyEH)}] call EFUNC(common,addEventHandler); -["SetVehicleLock", {_this call FUNC(setVehicleLockEH)}] call EFUNC(common,addEventHandler); - ADDON = true; diff --git a/addons/vehiclelock/config.cpp b/addons/vehiclelock/config.cpp index 9031987315..700e27b3cb 100644 --- a/addons/vehiclelock/config.cpp +++ b/addons/vehiclelock/config.cpp @@ -17,6 +17,10 @@ class ACE_Settings { value = 10; typeName = "SCALAR"; }; + class GVAR(LockVehicleInventory) { + value = 0; + typeName = "BOOL"; + }; }; #include "CfgEventHandlers.hpp" diff --git a/addons/vehiclelock/functions/fnc_addKeyForVehicle.sqf b/addons/vehiclelock/functions/fnc_addKeyForVehicle.sqf index c64a0f890d..d683073286 100644 --- a/addons/vehiclelock/functions/fnc_addKeyForVehicle.sqf +++ b/addons/vehiclelock/functions/fnc_addKeyForVehicle.sqf @@ -1,45 +1,40 @@ /* - Name: ACE_VehicleLock_fnc_addKeyForVehicle - - Author: Pabst Mirror - - Description: - Adds a key to a unit that will open a vehicle - - Parameters: - 0: OBJECT - unit - 1: OBJECT - vehicle - 2: BOOL - custom key (true: custom key (magazine) - false: side key (item)) - - Returns: - Nothing - - Example: - [bob, car1, true] call ACE_VehicleLock_fnc_addKeyForVehicle; -*/ - + * Author: PabstMirror + * Adds a key to a unit that will open a vehicle + * Note: has global effects for Unit (will add items to remote unit) + * + * Arguments: + * 0: Unit + * 1: Vehicle + * 2: custom key (true: custom key (magazine) - false: side key (item)) + * + * Return Value: + * None + * + * Example: + * [ACE_player, car, true] call ACE_VehicleLock_fnc_addKeyForVehicle + * + * Public: Yes + */ #include "script_component.hpp" -private ["_unit","_veh","_useCustom","_previousMags","_newMags","_keyMagazine","_keyName"]; +private ["_previousMags","_newMags","_keyMagazine","_keyName"]; -_unit = [_this, 0, objNull, [objNull]] call bis_fnc_param; -_veh = [_this, 1, objNull, [objNull]] call bis_fnc_param; -_useCustom = [_this, 2, false, [false]] call bis_fnc_param; +PARAMS_3(_unit,_veh,_useCustom); -if (isNull _unit) exitWith {["addKeyForVehicleClient: null unit"] call BIS_fnc_error;}; -if (isNull _veh) exitWith {["addKeyForVehicleClient: null vehicle"] call BIS_fnc_error;}; +if (isNull _unit) exitWith {ERROR("null unit");}; +if (isNull _veh) exitWith {ERROR("null vehicle");}; if (_useCustom) then { - _previousMags = magazinesDetail _unit; - _unit addMagazine ["ACE_key_customKeyMagazine", 1]; - _newMags = (magazinesDetail _unit) - _previousMags; - if ((count _newMags) == 0) exitWith { - ["ACE_VehicleLock_fnc_addKeyForVehicle: failed to add magazine (inventory full?)"] call BIS_fnc_error; - }; - _keyMagazine = _newMags select 0; - TRACE_2("setting up key on server",_veh,_keyMagazine); - ["SetupCustomKey", [_veh, _keyMagazine]] call EFUNC(common,serverEvent); + _previousMags = magazinesDetail _unit; + _unit addMagazine ["ACE_key_customKeyMagazine", 1]; //addMagazine array has global effects + _newMags = (magazinesDetail _unit) - _previousMags; + if ((count _newMags) == 0) exitWith {ERROR("failed to add magazine (inventory full?)");}; + _keyMagazine = _newMags select 0; + TRACE_2("setting up key on server",_veh,_keyMagazine); + //Have the server run add the key to the vehicle's key array: + ["VehicleLock_SetupCustomKey", [_veh, _keyMagazine]] call EFUNC(common,serverEvent); } else { - _keyName = [_veh] call FUNC(getVehicleSideKey); - _unit addItem _keyName; + _keyName = [_veh] call FUNC(getVehicleSideKey); + _unit addItem _keyName; //addItem has global effects }; diff --git a/addons/vehiclelock/functions/fnc_getVehicleSideKey.sqf b/addons/vehiclelock/functions/fnc_getVehicleSideKey.sqf index 819c13c332..999f471ac3 100644 --- a/addons/vehiclelock/functions/fnc_getVehicleSideKey.sqf +++ b/addons/vehiclelock/functions/fnc_getVehicleSideKey.sqf @@ -1,27 +1,25 @@ /* -Name: ACE_VehicleLock_fnc_getVehicleSideKey - -Author: Pabst Mirror - -Description: - Returns the side specifc key for a vehicle - -Parameters: - 0: OBJECT - vehicle - -Returns: - STRING - Key Classname - -Example: - [tank1] call ACE_VehicleLock_fnc_getVehicleSideKey; -*/ - + * Author: PabstMirror + * Returns the side specifc key for a vehicle + * + * Arguments: + * 0: Vehicle + * + * Return Value: + * The vehicle's side key classname + * + * Example: + * [tank1] call ACE_VehicleLock_fnc_getVehicleSideKey; + * + * Public: No + */ #include "script_component.hpp" -private ["_veh","_vehConfigSide","_vehSide","_returnValue"]; +private ["_vehConfigSide","_vehSide","_returnValue"]; -_veh = [_this, 0, objNull, [objNull]] call bis_fnc_param; -if (isNull _veh) exitWith {["ACE_VehicleLock_fnc_getVehicleSideKey: null vehicle"] call BIS_fnc_error; ""}; +PARAMS_1(_veh); + +if (isNull _veh) exitWith {ERROR("null vehicle"); "error"}; _vehConfigSide = [_veh, true] call BIS_fnc_objectSide; _vehSide = _veh getVariable [QGVAR(lockSide), _vehConfigSide]; @@ -32,7 +30,7 @@ switch (_vehSide) do { case (west): {_returnValue = "ACE_key_west"}; case (east): {_returnValue = "ACE_key_east"}; case (resistance): {_returnValue = "ACE_key_indp"}; -case (civilian): {_returnValue = "ACE_key_civ"}; + default {_returnValue = "ACE_key_civ"}; }; _returnValue diff --git a/addons/vehiclelock/functions/fnc_hasKeyForVehicle.sqf b/addons/vehiclelock/functions/fnc_hasKeyForVehicle.sqf index a1c899edad..779f4a363e 100644 --- a/addons/vehiclelock/functions/fnc_hasKeyForVehicle.sqf +++ b/addons/vehiclelock/functions/fnc_hasKeyForVehicle.sqf @@ -1,31 +1,27 @@ /* -Name: ACE_VehicleLock_fnc_hasKeyForVehicle - -Author: Pabst Mirror - -Description: - Returns if user has a valid key for the vehicle - -Parameters: - 0: OBJECT - unit - 1: OBJECT - vehicle - -Returns: - BOOL - unit has key for vehicle - -Example: - [bob, car] call ACE_VehicleLock_fnc_hasKeyForVehicle; -*/ - + * Author: PabstMirror + * Returns if user has a valid key for the vehicle + * + * Arguments: + * 0: Unit + * 1: Vehicle + * + * Return Value: + * unit has key for vehicle + * + * Example: + * [bob, car] call ACE_VehicleLock_fnc_hasKeyForVehicle; + * + * Public: No + */ #include "script_component.hpp" -private ["_unit","_veh","_returnValue","_sideKeyName","_customKeys"]; +private ["_returnValue","_sideKeyName","_customKeys"]; -_unit = [_this, 0, objNull, [objNull]] call bis_fnc_param; -_veh = [_this, 1, objNull, [objNull]] call bis_fnc_param; +PARAMS_2(_unit,_veh); -if (isNull _unit) exitWith {["ACE_VehicleLock_fnc_hasKeyForVehicle: null unit"] call BIS_fnc_error; false}; -if (isNull _veh) exitWith {["ACE_VehicleLock_fnc_hasKeyForVehicle: null vehicle"] call BIS_fnc_error; false}; +if (isNull _unit) exitWith {ERROR("null unit"); false}; +if (isNull _veh) exitWith {ERROR("null vehicle"); false}; _returnValue = false; @@ -39,7 +35,7 @@ if (_sideKeyName in (items _unit)) then {_returnValue = true}; //Check custom keys _customKeys = _veh getVariable [QGVAR(customKeys), []]; { - if (_x in (magazinesDetail _unit)) then {_returnValue = true;}; + if (_x in (magazinesDetail _unit)) then {_returnValue = true;}; } forEach _customKeys; _returnValue diff --git a/addons/vehiclelock/functions/fnc_lockpick.sqf b/addons/vehiclelock/functions/fnc_lockpick.sqf index c6a6369515..4fee354824 100644 --- a/addons/vehiclelock/functions/fnc_lockpick.sqf +++ b/addons/vehiclelock/functions/fnc_lockpick.sqf @@ -1,79 +1,66 @@ /* -Name: ACE_VehicleLock_fnc_lockpick - -Author: Pabst Mirror - -Description: - Handles lockpick functionality from action menu. - -Parameters: - 0: OBJECT - unit - 1: OBJECT - vehicle - 2: STRING - function type - "canLockpick": returns BOOL if lockpick is possible - "startLockpick": starts the process - "finishLockpick": on completions, opens the lock - -Returns: - BOOL - -Example: - [ACE_player, ACE_Interaction_Target, 'canLockpick'] call ACE_VehicleLock_fnc_lockpick -*/ - + * Author: PabstMirror + * Handles lockpick functionality. Three different functions: + * "canLockpick": returns BOOL if lockpick is possible + * "startLockpick": starts the process + * "finishLockpick": on completions, opens the lock + * + * Arguments: + * 0: Unit (player) + * 1: Vehicle + * 2: Function Type + * + * Return Value: + * "canLockpick" + * + * Example: + * [ACE_player, ACE_Interaction_Target, 'canLockpick'] call ACE_VehicleLock_fnc_lockpick + * + * Public: No + */ #include "script_component.hpp" -private ["_unit","_veh","_funcType","_vehLockpickStrenth","_returnValue", "_condition"]; +private ["_vehLockpickStrenth","_condition","_returnValue"]; -_unit = [_this, 0, objNull, [objNull]] call bis_fnc_param; -_veh = [_this, 1, objNull, [objNull]] call bis_fnc_param; -_funcType = [_this, 2, "", [""]] call bis_fnc_param; +PARAMS_3(_unit,_veh,_funcType); -if (isNull _unit) exitWith { - ["ACE_VehicleLock_fnc_lockpick: null unit"] call BIS_fnc_error; - false -}; -if (isNull _veh) exitWith { - ["ACE_VehicleLock_fnc_lockpick: null vehicle"] call BIS_fnc_error; - false -}; +if (isNull _unit) exitWith {ERROR("null unit"); false}; +if (isNull _veh) exitWith {ERROR("null vehicle"); false}; //need lockpick item -if (!("ACE_key_lockpick" in (items _unit))) exitWith { - false -}; +if (!("ACE_key_lockpick" in (items _unit))) exitWith {false}; _vehLockpickStrenth = _veh getVariable[QGVAR(lockpickStrength), GVAR(DefaultLockpickStrength)]; -if (typeName _vehLockpickStrenth != "SCALAR") exitWith { - ["ACE_VehicleLock_fnc_lockpick: 'ACE_vehicleLock_LockpickStrength' invalid: (%1)", _veh] call BIS_fnc_error; - false -}; +if (typeName _vehLockpickStrenth != "SCALAR") exitWith {ERROR("ACE_vehicleLock_LockpickStrength invalid"); false}; //-1 indicates unpickable lock -if (_vehLockpickStrenth < 0) exitWith { - false +if (_vehLockpickStrenth < 0) exitWith {false}; + +//Condition check for progressBar +_condition = { + PARAMS_1(_args); + EXPLODE_2_PVT(_args,_unit,_veh); + ((_unit distance _veh) < 5) && {(speed _veh) < 0.1} }; +if (!([[_unit, _veh]] call _condition)) exitWith {false}; + _returnValue = false; - switch (true) do { case (_funcType == "canLockpick"): { - _returnValue = true; - }; -case (_funcType == "startLockpick"): { - _condition = { - PARAMS_1(_args); - EXPLODE_2_PVT(_args,_unit,_veh); - ([_unit, objNull, []] call EFUNC(common,canInteractWith)) && ((_unit distance _veh) < 5) && ((speed _veh) < 1) + _returnValue = true; + }; +case (_funcType == "startLockpick"): { + [_vehLockpickStrenth, [_unit, _veh, "finishLockpick"], {(_this select 0) call FUNC(lockpick)}, {}, (localize "STR_ACE_Vehicle_Action_LockpickInUse"), _condition] call EFUNC(common,progressBar); + _returnValue = true; }; - [_vehLockpickStrenth, [_unit, _veh, "finishLockpick"], {(_this select 0) call FUNC(lockpick)}, {}, (localize "STR_ACE_Vehicle_Action_LockpickInUse"), _condition] call EFUNC(common,progressBar); - }; case (_funcType == "finishLockpick"): { - ["SetVehicleLock", [_veh], [_veh, false]] call EFUNC(common,targetEvent); - }; - default { - ["ACE_VehicleLock_fnc_lockpick: bad function type"] call BIS_fnc_error; - }; + ["VehicleLock_SetVehicleLock", [_veh], [_veh, false]] call EFUNC(common,targetEvent); + _returnValue = true; + }; + default { + ERROR("bad function type"); + }; }; -_returnValue; +_returnValue diff --git a/addons/vehiclelock/functions/fnc_moduleInit.sqf b/addons/vehiclelock/functions/fnc_moduleInit.sqf index a344185ab0..c26e8aacbd 100644 --- a/addons/vehiclelock/functions/fnc_moduleInit.sqf +++ b/addons/vehiclelock/functions/fnc_moduleInit.sqf @@ -1,22 +1,20 @@ /* -Name: ACE_VehicleLock_fnc_moduleInit - -Author: Pabst Mirror - -Description: - Function for setup module. Sets default lockpick strength, auto handout keys, and default lock state. - -Parameters: - 0: OBJECT - logic - 1: ignored - 2: BOOL - Module Activated -Returns: - Nothing - -Example: - called from module -*/ - + * Author: PabstMirror + * Function for setup module. Sets default lockpick strength and default lock state. + * + * Arguments: + * 0: The Module Logic Object + * 1: synced objects + * 2: Activated + * + * Return Value: + * None + * + * Example: + * [fromModule] call ACE_VehicleLock_fnc_hasKeyForVehicle; + * + * Public: No + */ #include "script_component.hpp" private ["_sideKeysAssignment", "_setLockState", "_lock"]; @@ -24,28 +22,28 @@ private ["_sideKeysAssignment", "_setLockState", "_lock"]; PARAMS_3(_logic,_syncedUnits,_activated); if (!_activated) exitWith {WARNING("Vehicle Lock Init Module - placed but not active");}; +if (!isServer) exitWith {}; + +//Set the GVAR for default lockpick strength +[_logic, QGVAR(DefaultLockpickStrength), "DefaultLockpickStrength"] call EFUNC(common,readSettingFromModule); +[_logic, QGVAR(LockVehicleInventory), "LockVehicleInventory"] call EFUNC(common,readSettingFromModule); -_sideKeysAssignment = _logic getVariable["SideKeysAssignment", 0]; _setLockState = _logic getVariable["SetLockState", 0]; - -if (isServer) then { - [_logic, QGVAR(DefaultLockpickStrength), "LockpickStrength"] call EFUNC(common,readSettingFromModule); -}; - -//Run at mission start (anyone besides JIPs) -if (isServer || {player == player}) then { - { - if ((local _x) && {(_x isKindOf "Car") || (_x isKindOf "Tank") || (_x isKindOf "Helicopter")}) then { - //set lock state (eliminates the ambigious 1-"Default" and 3-"Locked for Player" states) - _lock = switch (_setLockState) do { - case (0): {(locked _x) in [2, 3]}; - case (1):{true}; - case (2):{false}; - }; - if (((_lock) && {(locked _x) != 2}) || {(!_lock) && {(locked _x) != 0}}) then { - TRACE_3("Setting Lock State", _lock, (typeOf _x), _x); - ["SetVehicleLock", [_x, _lock]] call EFUNC(common,localEvent); - }; - }; - } forEach vehicles; -}; +[{ + PARAMS_1(_setLockState); + { + if ((_x isKindOf "Car") || {_x isKindOf "Tank"} || {_x isKindOf "Helicopter"}) then { + //set lock state (eliminates the ambigious 1-"Default" and 3-"Locked for Player" states) + _lock = switch (_setLockState) do { + case (0): {(locked _x) in [2, 3]}; + case (1):{true}; + case (2):{false}; + }; + if (((_lock) && {(locked _x) != 2}) || {(!_lock) && {(locked _x) != 0}}) then { + TRACE_3("Setting Lock State", _lock, (typeOf _x), _x); + ["VehicleLock_SetVehicleLock", [_x], [_x, _lock]] call EFUNC(common,targetEvent); + }; + }; + } forEach vehicles; + //Delay call until mission start (so everyone has the eventHandler's installed) +}, [_setLockState], 0.25, 0.25] call EFUNC(common,waitAndExecute); diff --git a/addons/vehiclelock/functions/fnc_moduleSync.sqf b/addons/vehiclelock/functions/fnc_moduleSync.sqf index 60c23c5195..feed42e3ab 100644 --- a/addons/vehiclelock/functions/fnc_moduleSync.sqf +++ b/addons/vehiclelock/functions/fnc_moduleSync.sqf @@ -1,22 +1,20 @@ /* -Name: ACE_VehicleLock_fnc_moduleSync - -Author: Pabst Mirror - -Description: - Function for sync module. Assigns keys for all synced vehicles to any players that are synced. - -Parameters: - 0: OBJECT - logic - 1: ARRAY - synced objects (only objects at mission start, so JIP without AI won't be present) - -Returns: - Nothing - -Example: - called from module -*/ - + * Author: PabstMirror + * Function for sync module. Assigns keys for all synced vehicles to any players that are synced. + * + * Arguments: + * 0: The Module Logic Object + * 1: synced objects + * 2: Activated + * + * Return Value: + * None + * + * Example: + * [fromModule] call ACE_VehicleLock_fnc_moduleSync; + * + * Public: No + */ #include "script_component.hpp" PARAMS_3(_logic,_syncedObjects,_activated); @@ -24,29 +22,28 @@ PARAMS_3(_logic,_syncedObjects,_activated); if !(_activated) exitWith {WARNING("Vehicle Lock Sync Module - placed but not active");}; if (!isServer) exitWith {}; -_addKeyAfterGearAssign = { - private ["_syncedObjects", "_listOfVehicles"]; - _syncedObjects = _this select 0; - _listOfVehicles = []; - { - if ((_x isKindOf "Car") || (_x isKindOf "Tank") || (_x isKindOf "Helicopter")) then { - _listOfVehicles pushBack _x; +[{ + private ["_listOfVehicles"]; + PARAMS_1(_syncedObjects); + _listOfVehicles = []; + { + if ((_x isKindOf "Car") || (_x isKindOf "Tank") || (_x isKindOf "Helicopter")) then { + _listOfVehicles pushBack _x; + }; + } forEach _syncedObjects; + + if ((count _listOfVehicles) == 0) exitWith { //Verbose error for mission makers (only shows on server) + ["ACE_VehicleLock_fnc_moduleSync: no vehicles synced"] call BIS_fnc_error; }; - } forEach _syncedObjects; - if ((count _listOfVehicles) == 0) exitWith { //Verbose error for mission makers - ["ACE_VehicleLock_fnc_moduleSync: no vehicles synced"] call BIS_fnc_error; - }; + { + _unit = _x; + if (_unit isKindOf "CAManBase") then { + { + [_unit, _x, true] call FUNC(addKeyForVehicle); + } forEach _listOfVehicles; + }; + } forEach _syncedObjects; - { - _unit = _x; - if (_unit isKindOf "CAManBase") then { - { - [_unit, _x, true] call FUNC(addKeyForVehicle); - } forEach _listOfVehicles; - }; - } forEach _syncedObjects; -}; - -//Wait to add keys until various gear assigns have finished (~5 seconds) -[_addKeyAfterGearAssign, [_syncedObjects], 5, 1] call EFUNC(common,waitAndExecute); + //Wait to add keys until various gear assigns have finished (~5 seconds) +}, [_syncedObjects], 5, 1] call EFUNC(common,waitAndExecute); diff --git a/addons/vehiclelock/functions/fnc_onOpenInventory.sqf b/addons/vehiclelock/functions/fnc_onOpenInventory.sqf new file mode 100644 index 0000000000..55fee28cc6 --- /dev/null +++ b/addons/vehiclelock/functions/fnc_onOpenInventory.sqf @@ -0,0 +1,40 @@ +/* + * Author: PabstMirror + * Handles the inventory opening. + * + * Arguments: + * 0: Unit + * 1: Container + * + * Return Value: + * Handeled + * + * Example: + * [player, car] call ACE_VehicleLock_fnc_onOpenInventory; + * + * Public: No + */ +#include "script_component.hpp" + +PARAMS_2(_unit,_container); + +//Only check for player: +if (_unit != ace_player) exitWith {false}; + +_handeled = false; + +if (GVAR(LockVehicleInventory) && //if setting not enabled + {(vehicle ace_player) == ace_player} && //Player dismounted + {(_container isKindOf "Car") || (_container isKindOf "Tank") || (_container isKindOf "Helicopter")} && //container is a lockable veh + {(locked _container) in [2,3]} && //Vehicle is locked + {!([ace_player, _container] call FUNC(hasKeyForVehicle))} //player doesn't have key + ) then { + //Give feedback that vehicle is locked + playSound "ACE_Sound_Click"; + //don't open the vehicles inventory + _handeled = true; + //Just opens a dummy groundContainer + ACE_player action ["Gear", objNull]; +}; + +_handeled diff --git a/addons/vehiclelock/functions/fnc_serverSetupCustomKeyEH.sqf b/addons/vehiclelock/functions/fnc_serverSetupCustomKeyEH.sqf index f9a420841e..9d8a396e31 100644 --- a/addons/vehiclelock/functions/fnc_serverSetupCustomKeyEH.sqf +++ b/addons/vehiclelock/functions/fnc_serverSetupCustomKeyEH.sqf @@ -1,22 +1,19 @@ - /* - Name: ACE_VehicleLock_fnc_serverSetupCustomKeyEH - - Author: Pabst Mirror - - Description: - Adds a key (magazineDetail name) to approved keys for a vehicle - - Parameters: - 0: OBJECT - vehicle - 1: STRING - Magazine Name - - Returns: - Nothing - - Example: - [tank1, "someMagainze [id xx:yy]"] call ACE_VehicleLock_fnc_serverSetupCustomKeyEH; -*/ - +/* + * Author: PabstMirror + * On the server: Adds a key (magazineDetail name) to approved keys for a vehicle. + * + * Arguments: + * 0: Vehicle + * 1: Magazine Name + * + * Return Value: + * None + * + * Example: + * [tank1, "someMagainze [id xx:yy]"] call ACE_VehicleLock_fnc_serverSetupCustomKeyEH + * + * Public: Yes + */ #include "script_component.hpp" private ["_currentKeys"]; @@ -24,6 +21,7 @@ private ["_currentKeys"]; PARAMS_2(_veh,_key); if (!isServer) exitWith {ERROR("only run on server");}; +if (isNull _veh) exitWith {ERROR("null vehicle");}; if (_key == "") exitWith {ERROR("empty key string");}; _currentKeys = _veh getVariable [QGVAR(customKeys), []]; diff --git a/addons/vehiclelock/functions/fnc_setVehicleLockEH.sqf b/addons/vehiclelock/functions/fnc_setVehicleLockEH.sqf index 7aaa9b154c..cb51cb27a8 100644 --- a/addons/vehiclelock/functions/fnc_setVehicleLockEH.sqf +++ b/addons/vehiclelock/functions/fnc_setVehicleLockEH.sqf @@ -1,33 +1,25 @@ /* - Name: ACE_VehicleLock_fnc_setVehicleLockEH - - Author: Pabst Mirror - - Description: - Sets a vehicle lock state because of a "SetVehicleLock" event - - Parameters: - 0: OBJECT - vehicle - 1: BOOL - new lock state - - Returns: - Nothing - - Example: - [tank1, false] call ACE_VehicleLock_fnc_setVehicleLockEH; -*/ - + * Author: PabstMirror + * Sets a vehicle lock state because of a "VehicleLock_SetVehicleLock" event + * + * Arguments: + * 0: Vehicle + * 1: New lock state + * + * Return Value: + * None + * + * Example: + * [tank1, false] call ACE_VehicleLock_fnc_setVehicleLockEH; + * + * Public: Yes + */ #include "script_component.hpp" -private ["_veh","_isLocked","_lockNumber"]; +private ["_lockNumber"]; -_veh = [_this, 0, objNull, [objNull]] call bis_fnc_param; -_isLocked = [_this, 1, false, [false]] call bis_fnc_param; +PARAMS_2(_veh,_isLocked); _lockNumber = if (_isLocked) then {2} else {0}; - TRACE_2("Setting Lock State", _veh, _lockNumber); - _veh lock _lockNumber; - -// _veh setVariable ["ACE_LockedInventory", _isLocked, true]; //todo inventory lock From f101d40450e21ae572f2de955a4dd4aa810e4222 Mon Sep 17 00:00:00 2001 From: PabstMirror Date: Sun, 15 Mar 2015 13:10:06 -0500 Subject: [PATCH 02/14] Readme cleanup --- addons/vehiclelock/readme.md | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/addons/vehiclelock/readme.md b/addons/vehiclelock/readme.md index a1bd223a52..b05248d5a8 100644 --- a/addons/vehiclelock/readme.md +++ b/addons/vehiclelock/readme.md @@ -5,7 +5,7 @@ Adds keys as an item, to lock and unlock vehicles. Primary target would be role play or TVT, but has uses in all game types, even co-ops (e.g.: DAC AI will steal unlocked vehicles) Two key modes (can be used together): -Simple Side based keys (e.g. "ACE_key_west" works on any hunter) +Simple Side based keys (e.g. "ACE_key_west" works on any [WEST] vehicle like the M-ATV//hunter) Custom keys (one key will only open a specific vehicle and nothing else) #### Items Added: @@ -18,24 +18,20 @@ Custom keys (one key will only open a specific vehicle and nothing else) `ACE_key_civ` #### Magazine added: -`ACE_key_customKeyMagazine` (should never be manualy added, needs to be 'programed' to work on a vehicle) +`ACE_key_customKeyMagazine` (should never be manualy added, needs to be "programed" to work on a vehicle, see `ACE_VehicleLock_fnc_addKeyForVehicle`) ## For Mission Makers: #### Modules: -* Vehicle Lock Setup - Settings for lockpick strength and initial vehicle lock state. -* Vehicle Key Assign - Sync with vehicles and players. Will handout custom keys to players for every synced vehicle. - -#### Global Variable: -* `ACE_VehicleLock_DefaultLockpickStrength` - Time in seconds to lock pick globaly, can also set per-vehicle (-1 would disable) +* Vehicle Lock Setup - Settings for locking inventory of locked vehicles, default lockpick time, and initial vehicle lock state. +* Vehicle Key Assign - Sync with vehicles and players. Will handout custom keys to players for every synced vehicle. Will NOT work for JIP units. #### Vehicle setVariables: * `ACE_VehicleLock_lockSide` - SIDE: overrides a vehicle's side, allows indfor to use little-bird's with indp keys * `ACE_vehicleLock_lockpickStrength` - NUMBER: secons, determines how long lockpicking with take, overrides ACE_VehicleLock_DefaultLockpickStrength -* `ACE_VehicleLock_customKeys` - ARRAY: array of strings of magazinesDetails, use the following function to modify -`[bob, car1, true] call ACE_VehicleLock_fnc_addKeyForVehicle;` -will add a `ACE_magazine_customKey` to bob and program it to work on car1 +#### Public Functions: +`[bob, car1, true] call ACE_VehicleLock_fnc_addKeyForVehicle;` - will add a `ACE_magazine_customKey` to bob and program it to work on car1 ## Maintainers From d4624982f651880cf2994f03f5a6aa028a59f7a1 Mon Sep 17 00:00:00 2001 From: PabstMirror Date: Sun, 15 Mar 2015 13:13:13 -0500 Subject: [PATCH 03/14] Update readme.md --- addons/vehiclelock/readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/vehiclelock/readme.md b/addons/vehiclelock/readme.md index b05248d5a8..dc013145aa 100644 --- a/addons/vehiclelock/readme.md +++ b/addons/vehiclelock/readme.md @@ -5,8 +5,8 @@ Adds keys as an item, to lock and unlock vehicles. Primary target would be role play or TVT, but has uses in all game types, even co-ops (e.g.: DAC AI will steal unlocked vehicles) Two key modes (can be used together): -Simple Side based keys (e.g. "ACE_key_west" works on any [WEST] vehicle like the M-ATV//hunter) -Custom keys (one key will only open a specific vehicle and nothing else) +* Simple Side based keys (e.g. "ACE_key_west" works on any [WEST] vehicle like the M-ATV//hunter) +* Custom keys (one key will only open a specific vehicle and nothing else) #### Items Added: From 3030b78ea24c5c0c5cb2a7357187cac4cc1ab554 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Badano?= Date: Tue, 17 Mar 2015 00:37:28 -0300 Subject: [PATCH 04/14] Refactor the interact_menu so options for multiple objects can coexist inside a single action point --- .../functions/fnc_collectActiveActionTree.sqf | 2 +- addons/interact_menu/functions/fnc_render.sqf | 4 ++-- .../functions/fnc_renderBaseMenu.sqf | 3 +-- .../interact_menu/functions/fnc_renderMenu.sqf | 18 ++++++++++-------- 4 files changed, 14 insertions(+), 13 deletions(-) diff --git a/addons/interact_menu/functions/fnc_collectActiveActionTree.sqf b/addons/interact_menu/functions/fnc_collectActiveActionTree.sqf index 42f762de3f..7e8da46014 100644 --- a/addons/interact_menu/functions/fnc_collectActiveActionTree.sqf +++ b/addons/interact_menu/functions/fnc_collectActiveActionTree.sqf @@ -69,4 +69,4 @@ if ((count _activeChildren) == 0 && ((_origActionData select 3) isEqualTo {})) e [] }; -[_origActionData, _activeChildren] +[_origActionData, _activeChildren, _object] diff --git a/addons/interact_menu/functions/fnc_render.sqf b/addons/interact_menu/functions/fnc_render.sqf index 3930068c25..bb902e849b 100644 --- a/addons/interact_menu/functions/fnc_render.sqf +++ b/addons/interact_menu/functions/fnc_render.sqf @@ -142,8 +142,8 @@ if(GVAR(keyDown) || GVAR(keyDownSelfAction)) then { drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [1,0,0,.75], _pos, 0.6*SafeZoneW, 0.6*SafeZoneW, GVAR(rotationAngle), "", 0.5, 0.025, "TahomaB"]; _foundTarget = true; GVAR(actionSelected) = true; - GVAR(selectedTarget) = (_closest select 0) select 0; GVAR(selectedAction) = (_closest select 0) select 1; + GVAR(selectedTarget) = (GVAR(selectedAction)) select 2; GVAR(selectedStatement) = ((GVAR(selectedAction)) select 0) select 3; _misMatch = false; @@ -153,7 +153,7 @@ if(GVAR(keyDown) || GVAR(keyDownSelfAction)) then { _misMatch = true; } else { { - if(_x != (_hoverPath select _forEachIndex)) exitWith { + if !(_x isEqualTo (_hoverPath select _forEachIndex)) exitWith { _misMatch = true; }; } forEach GVAR(lastPath); diff --git a/addons/interact_menu/functions/fnc_renderBaseMenu.sqf b/addons/interact_menu/functions/fnc_renderBaseMenu.sqf index e3a8a0c9a4..fd3cc4d668 100644 --- a/addons/interact_menu/functions/fnc_renderBaseMenu.sqf +++ b/addons/interact_menu/functions/fnc_renderBaseMenu.sqf @@ -66,12 +66,11 @@ _activeActionTree = [ _object, _uid, 0.2 ] call EFUNC(common,cachedCall); - // Check if there's something left for rendering if (count _activeActionTree == 0) exitWith {false}; //EXPLODE_2_PVT(_activeActionTree,_actionData,_actionChildren); -[_object, _activeActionTree, _pos, [180,360]] call FUNC(renderMenu); +[[], _activeActionTree, _pos, [180,360]] call FUNC(renderMenu); true diff --git a/addons/interact_menu/functions/fnc_renderMenu.sqf b/addons/interact_menu/functions/fnc_renderMenu.sqf index ad604b9fa5..459287424c 100644 --- a/addons/interact_menu/functions/fnc_renderMenu.sqf +++ b/addons/interact_menu/functions/fnc_renderMenu.sqf @@ -3,7 +3,7 @@ * Render an interaction menu and it's children recursively * * Argument: - * 0: Object + * 0: Parent path * 1: Action data * 2: 3D position * 3: Angle range available for rendering @@ -15,16 +15,18 @@ */ #include "script_component.hpp" -private ["_menuInSelectedPath", "_path", "_menuDepth", "_currentRenderDepth", "_x", "_offset", "_newPos", "_forEachIndex"]; +private ["_menuInSelectedPath", "_localPath", "_path", "_menuDepth", "_currentRenderDepth", "_x", "_offset", "_newPos", "_forEachIndex"]; -EXPLODE_4_PVT(_this,_object,_action,_pos,_angles); -EXPLODE_2_PVT(_action,_actionData,_activeChildren); +EXPLODE_4_PVT(_this,_parentPath,_action,_pos,_angles); +EXPLODE_3_PVT(_action,_actionData,_activeChildren,_actionObject); EXPLODE_2_PVT(_angles,_centerAngle,_maxAngleSpan); _menuDepth = (count GVAR(menuDepthPath)) - 1; // Store path to action -_path = [_object] + (_actionData select 7); +_localPath = _actionData select 7; +_path = +_parentPath; +_path pushBack [_localPath select ((count _localPath) - 1), _actionObject]; // Check if the menu is on the selected path _menuInSelectedPath = true; @@ -32,7 +34,7 @@ _menuInSelectedPath = true; if (_forEachIndex >= (count GVAR(menuDepthPath))) exitWith { _menuInSelectedPath = false; }; - if (_x != (GVAR(menuDepthPath) select _forEachIndex)) exitWith { + if !(_x isEqualTo (GVAR(menuDepthPath) select _forEachIndex)) exitWith { _menuInSelectedPath = false; }; } forEach _path; @@ -63,7 +65,7 @@ if (_angleSpan >= 305) then { _angle = _centerAngle - _angleSpan / 2; { - _target = _object; + _target = _actionObject; _player = ACE_player; _mod = (0.15 max (0.15 * ((positionCameraToWorld [0, 0, 0]) distance _pos))) / GVAR(selfMenuScale); @@ -74,7 +76,7 @@ _angle = _centerAngle - _angleSpan / 2; //drawLine3D [_pos, _newPos, [1,0,0,0.5]]; - [_object, _x, _newPos, [_angle, 140]] call FUNC(renderMenu); + [_path, _x, _newPos, [_angle, 140]] call FUNC(renderMenu); if (_angleSpan == 360) then { _angle = _angle + _angleSpan / (count _activeChildren); From acd3ca0d566ed53c47664985a146fcb70fec0c11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Badano?= Date: Thu, 19 Mar 2015 13:00:10 -0300 Subject: [PATCH 05/14] Interact menu: - Allow dynamically adding children actions just-in-time - Added optional custom parameters for actions --- addons/interact_menu/XEH_preInit.sqf | 1 + .../interact_menu/functions/fnc_addAction.sqf | 18 +++++- .../functions/fnc_addClassAction.sqf | 18 +++++- .../functions/fnc_collectActiveActionTree.sqf | 10 ++- .../functions/fnc_compileMenu.sqf | 10 ++- .../functions/fnc_compileMenuSelfAction.sqf | 14 +++-- .../functions/fnc_createAction.sqf | 63 +++++++++++++++++++ addons/interact_menu/functions/fnc_keyUp.sqf | 2 +- .../functions/fnc_keyUpSelfAction.sqf | 2 +- 9 files changed, 124 insertions(+), 14 deletions(-) create mode 100644 addons/interact_menu/functions/fnc_createAction.sqf diff --git a/addons/interact_menu/XEH_preInit.sqf b/addons/interact_menu/XEH_preInit.sqf index 487f1c017f..9d50eb0a1c 100644 --- a/addons/interact_menu/XEH_preInit.sqf +++ b/addons/interact_menu/XEH_preInit.sqf @@ -7,6 +7,7 @@ PREP(addClassAction); PREP(compileMenu); PREP(compileMenuSelfAction); PREP(collectActiveActionTree); +PREP(createAction); PREP(keyDown); PREP(keyDownSelfAction); PREP(keyUp); diff --git a/addons/interact_menu/functions/fnc_addAction.sqf b/addons/interact_menu/functions/fnc_addAction.sqf index c7dd6ecab3..ef3c2196e6 100644 --- a/addons/interact_menu/functions/fnc_addAction.sqf +++ b/addons/interact_menu/functions/fnc_addAction.sqf @@ -14,6 +14,8 @@ * 7: Condition * 8: Distance * 9: Other parameters (Optional) + * 10: Insert children code (Optional) + * 11: Action parameters (Optional) * * Return value: * The entry full path, which can be used to remove the entry, or add children entries . @@ -27,7 +29,7 @@ EXPLODE_9_PVT(_this,_object,_typeNum,_fullPath,_displayName,_icon,_position,_statement,_condition,_distance); -private ["_varName","_actions","_params","_entry"]; +private ["_varName","_actions","_params","_insertChildren","_parameters","_entry"]; _varName = [QGVAR(actions),QGVAR(selfActions)] select _typeNum; _actions = _object getVariable [_varName, []]; @@ -40,6 +42,16 @@ if (count _this > 9) then { _params = _this select 9; }; +_insertChildren = {}; +if (count _this > 10) then { + _insertChildren = _this select 10; +}; + +_parameters = []; +if (count _this > 11) then { + _parameters = _this select 11; +}; + _entry = [ [ _displayName, @@ -49,7 +61,9 @@ _entry = [ _condition, _distance, _params, - + _fullPath + + _fullPath, + _insertChildren, + _parameters ], [] ]; diff --git a/addons/interact_menu/functions/fnc_addClassAction.sqf b/addons/interact_menu/functions/fnc_addClassAction.sqf index 4931328af2..a389b5bd8b 100644 --- a/addons/interact_menu/functions/fnc_addClassAction.sqf +++ b/addons/interact_menu/functions/fnc_addClassAction.sqf @@ -14,6 +14,8 @@ * 7: Condition * 8: Distance * 9: Other parameters (Optional) + * 10: Insert children code (Optional) + * 11: Action parameters (Optional) * * Return value: * The entry full path, which can be used to remove the entry, or add children entries . @@ -34,7 +36,7 @@ if (_typeNum == 0) then { [_objectType] call FUNC(compileMenuSelfAction); }; -private ["_varName","_actions","_params","_entry", "_parentLevel", "_foundParentLevel", "_fnc_findFolder"]; +private ["_varName","_actions","_params","_insertChildren","_parameters","_entry", "_parentLevel", "_foundParentLevel", "_fnc_findFolder"]; _varName = format [[QGVAR(Act_%1), QGVAR(SelfAct_%1)] select _typeNum, _objectType]; _actions = missionNamespace getVariable [_varName, []]; @@ -47,6 +49,16 @@ if (count _this > 9) then { _params = _this select 9; }; +_insertChildren = {}; +if (count _this > 10) then { + _insertChildren = _this select 10; +}; + +_parameters = []; +if (count _this > 11) then { + _parameters = _this select 11; +}; + // Search the class action trees and find where to insert the entry _parentLevel = _actions; _foundParentLevel = false; @@ -84,7 +96,9 @@ _entry = [ _condition, _distance, _params, - + _fullPath + + _fullPath, + _insertChildren, + _parameters ], [] ]; diff --git a/addons/interact_menu/functions/fnc_collectActiveActionTree.sqf b/addons/interact_menu/functions/fnc_collectActiveActionTree.sqf index 7e8da46014..ca6dadd44f 100644 --- a/addons/interact_menu/functions/fnc_collectActiveActionTree.sqf +++ b/addons/interact_menu/functions/fnc_collectActiveActionTree.sqf @@ -22,12 +22,17 @@ _target = _object; _player = ACE_player; // Return nothing if the action itself is not active -if !([_target, ACE_player] call (_origActionData select 4)) exitWith { +if !([_target, ACE_player, _origActionData select 9] call (_origActionData select 4)) exitWith { [] }; _activeChildren = []; +// If there's a statement to dynamically insert children then execute it +if (count _origActionData > 8 && {!({} isEqualTo (_origActionData select 8))}) then { + _activeChildren = [_target, ACE_player, _origActionData select 9] call (_origActionData select 8); +}; + // Collect children class actions { _action = [_object, _x] call FUNC(collectActiveActionTree); @@ -64,9 +69,12 @@ _activeChildren = []; // If the original action has no statement, and no children, don't display it +/* if ((count _activeChildren) == 0 && ((_origActionData select 3) isEqualTo {})) exitWith { // @todo: Account for showDisabled? [] }; +*/ +//diag_log [_origActionData, _activeChildren, _object]; [_origActionData, _activeChildren, _object] diff --git a/addons/interact_menu/functions/fnc_compileMenu.sqf b/addons/interact_menu/functions/fnc_compileMenu.sqf index e6a2744f03..46e74fb220 100644 --- a/addons/interact_menu/functions/fnc_compileMenu.sqf +++ b/addons/interact_menu/functions/fnc_compileMenu.sqf @@ -27,7 +27,7 @@ if !(isNil {missionNamespace getVariable [_actionsVarName, nil]}) exitWith {}; private "_recurseFnc"; _recurseFnc = { private ["_actions", "_displayName", "_distance", "_icon", "_statement", "_selection", "_condition", "_showDisabled", - "_enableInside", "_canCollapse", "_runOnHover", "_children", "_entry", "_entryCfg", "_fullPath"]; + "_enableInside", "_canCollapse", "_runOnHover", "_children", "_entry", "_entryCfg", "_fullPath", "_insertChildren"]; EXPLODE_2_PVT(_this,_actionsCfg,_parentPath); _actions = []; @@ -46,7 +46,9 @@ _recurseFnc = { if (_condition == "") then {_condition = "true"}; // Add canInteract (including exceptions) and canInteractWith to condition - _condition = _condition + format [QUOTE( && {[ARR_3(ACE_player, _target, %1)] call EGVAR(common,canInteractWith)} ), getArray (_entryCfg >> "exceptions")]; + _condition = _condition + format [QUOTE( && {[ARR_3(ACE_player, _target, %1)] call EFUNC(common,canInteractWith)} ), getArray (_entryCfg >> "exceptions")]; + + _insertChildren = compile (getText (_entryCfg >> "insertChildren")); _showDisabled = (getNumber (_entryCfg >> "showDisabled")) > 0; _enableInside = (getNumber (_entryCfg >> "enableInside")) > 0; @@ -68,7 +70,9 @@ _recurseFnc = { _condition, _distance, [_showDisabled,_enableInside,_canCollapse,_runOnHover], - _fullPath + _fullPath, + _insertChildren, + [] ], _children ]; diff --git a/addons/interact_menu/functions/fnc_compileMenuSelfAction.sqf b/addons/interact_menu/functions/fnc_compileMenuSelfAction.sqf index 81f4a25ef1..5c613caec2 100644 --- a/addons/interact_menu/functions/fnc_compileMenuSelfAction.sqf +++ b/addons/interact_menu/functions/fnc_compileMenuSelfAction.sqf @@ -27,7 +27,7 @@ if !(isNil {missionNamespace getVariable [_actionsVarName, nil]}) exitWith {}; private "_recurseFnc"; _recurseFnc = { private ["_actions", "_displayName", "_distance", "_icon", "_statement", "_selection", "_condition", "_showDisabled", - "_enableInside", "_canCollapse", "_runOnHover", "_children", "_entry", "_entryCfg", "_fullPath"]; + "_enableInside", "_canCollapse", "_runOnHover", "_children", "_entry", "_entryCfg", "_fullPath", "_insertChildren"]; EXPLODE_2_PVT(_this,_actionsCfg,_parentPath); _actions = []; @@ -43,7 +43,9 @@ _recurseFnc = { if (_condition == "") then {_condition = "true"}; // Add canInteract (including exceptions) and canInteractWith to condition - _condition = _condition + format [QUOTE( && {[ARR_3(ACE_player, objNull, %1)] call EGVAR(common,canInteractWith)} ), getArray (_entryCfg >> "exceptions")]; + _condition = _condition + format [QUOTE( && {[ARR_3(ACE_player, objNull, %1)] call EFUNC(common,canInteractWith)} ), getArray (_entryCfg >> "exceptions")]; + + _insertChildren = compile (getText (_entryCfg >> "insertChildren")); _showDisabled = (getNumber (_entryCfg >> "showDisabled")) > 0; _enableInside = (getNumber (_entryCfg >> "enableInside")) > 0; @@ -65,7 +67,9 @@ _recurseFnc = { _condition, 10, //distace [_showDisabled,_enableInside,_canCollapse,_runOnHover], - _fullPath + _fullPath, + _insertChildren, + [] ], _children ]; @@ -89,7 +93,9 @@ _actions = [ { true }, 10, [false,true,false], - ["ACE_SelfActions"] + ["ACE_SelfActions"], + {}, + [] ], [_actionsCfg, ["ACE_SelfActions"]] call _recurseFnc ] diff --git a/addons/interact_menu/functions/fnc_createAction.sqf b/addons/interact_menu/functions/fnc_createAction.sqf new file mode 100644 index 0000000000..e7d53dab03 --- /dev/null +++ b/addons/interact_menu/functions/fnc_createAction.sqf @@ -0,0 +1,63 @@ +/* + * Author: CAA-Picard + * Creates an isolated ACE action + * Note: This function is NOT global. + * + * Argument: + * 0: Action name + * 1: Name of the action shown in the menu + * 2: Icon + * 3: Position (Position or Selection Name) or + * 4: Statement + * 5: Condition + * 6: Distance + * 7: Other parameters (Optional) + * 8: Insert children code (Optional) + * 9: Action parameters (Optional) + * + * Return value: + * Action + * + * Example: + * [[VulcanPinch"],"Vulcan Pinch","",[0,0,0],{_target setDamage 1;},{true},100,{},[parameters]] call ace_interact_menu_fnc_addAction; + * + * Public: No + */ +#include "script_component.hpp" + +EXPLODE_7_PVT(_this,_fullPath,_displayName,_icon,_position,_statement,_condition,_distance); + +private ["_actions","_params","_insertChildren","_parameters","_entry"]; + +_params = [false,false,false,false]; +if (count _this > 7) then { + _params = _this select 7; +}; + +_insertChildren = {}; +if (count _this > 8) then { + _insertChildren = _this select 8; +}; + +_parameters = []; +if (count _this > 9) then { + _parameters = _this select 9; +}; + +_entry = [ + [ + _displayName, + _icon, + _position, + _statement, + _condition, + _distance, + _params, + + _fullPath, + _insertChildren, + _parameters + ], + [] + ]; + +_entry diff --git a/addons/interact_menu/functions/fnc_keyUp.sqf b/addons/interact_menu/functions/fnc_keyUp.sqf index 716d6dafd8..fe60c438b6 100644 --- a/addons/interact_menu/functions/fnc_keyUp.sqf +++ b/addons/interact_menu/functions/fnc_keyUp.sqf @@ -16,7 +16,7 @@ if(GVAR(actionSelected)) then { this = GVAR(selectedTarget); _player = ACE_Player; _target = GVAR(selectedTarget); - [GVAR(selectedTarget), ACE_player] call GVAR(selectedStatement); + [GVAR(selectedTarget), ACE_player, (GVAR(selectedAction) select 0) select 9] call GVAR(selectedStatement); }; if (GVAR(keyDown)) then { diff --git a/addons/interact_menu/functions/fnc_keyUpSelfAction.sqf b/addons/interact_menu/functions/fnc_keyUpSelfAction.sqf index 6346696d53..4603479e87 100644 --- a/addons/interact_menu/functions/fnc_keyUpSelfAction.sqf +++ b/addons/interact_menu/functions/fnc_keyUpSelfAction.sqf @@ -20,7 +20,7 @@ if(GVAR(actionSelected)) then { this = GVAR(selectedTarget); _player = ACE_Player; _target = GVAR(selectedTarget); - [GVAR(selectedTarget), ACE_player] call GVAR(selectedStatement); + [GVAR(selectedTarget), ACE_player, (GVAR(selectedAction) select 0) select 9] call GVAR(selectedStatement); }; if (GVAR(keyDownSelfAction)) then { From f96126153cc2ec4fbde87f1261b43a8bad982ac4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Badano?= Date: Thu, 19 Mar 2015 14:45:05 -0300 Subject: [PATCH 06/14] Reenable hiding useless actions --- addons/interact_menu/functions/fnc_collectActiveActionTree.sqf | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/addons/interact_menu/functions/fnc_collectActiveActionTree.sqf b/addons/interact_menu/functions/fnc_collectActiveActionTree.sqf index ca6dadd44f..547d5bb707 100644 --- a/addons/interact_menu/functions/fnc_collectActiveActionTree.sqf +++ b/addons/interact_menu/functions/fnc_collectActiveActionTree.sqf @@ -69,12 +69,11 @@ if (count _origActionData > 8 && {!({} isEqualTo (_origActionData select 8))}) t // If the original action has no statement, and no children, don't display it -/* if ((count _activeChildren) == 0 && ((_origActionData select 3) isEqualTo {})) exitWith { // @todo: Account for showDisabled? [] }; -*/ + //diag_log [_origActionData, _activeChildren, _object]; [_origActionData, _activeChildren, _object] From a3b913ad8b2a0167f0a84117262debad16e5a9ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Badano?= Date: Thu, 19 Mar 2015 15:04:48 -0300 Subject: [PATCH 07/14] Interact menu usability improvements: - Submenu scale as a function of the number of children - Added menu expansion animation to better communicate where the options come from - Unused action point are faded as soon as the user hovers a certain action point --- addons/interact_menu/XEH_preInit.sqf | 1 + addons/interact_menu/functions/fnc_render.sqf | 1 + .../functions/fnc_renderMenu.sqf | 34 ++++++++++++++----- 3 files changed, 28 insertions(+), 8 deletions(-) diff --git a/addons/interact_menu/XEH_preInit.sqf b/addons/interact_menu/XEH_preInit.sqf index 9d50eb0a1c..2687cf781c 100644 --- a/addons/interact_menu/XEH_preInit.sqf +++ b/addons/interact_menu/XEH_preInit.sqf @@ -41,6 +41,7 @@ GVAR(lastPath) = []; GVAR(expanded) = false; GVAR(startHoverTime) = diag_tickTime; +GVAR(expandedTime) = diag_tickTime; GVAR(iconCtrls) = []; GVAR(iconCount) = 0; diff --git a/addons/interact_menu/functions/fnc_render.sqf b/addons/interact_menu/functions/fnc_render.sqf index bb902e849b..361b7031cc 100644 --- a/addons/interact_menu/functions/fnc_render.sqf +++ b/addons/interact_menu/functions/fnc_render.sqf @@ -166,6 +166,7 @@ if(GVAR(keyDown) || GVAR(keyDownSelfAction)) then { } else { if(!GVAR(expanded) && diag_tickTime-GVAR(startHoverTime) > 0.25) then { GVAR(expanded) = true; + GVAR(expandedTime) = diag_tickTime; GVAR(menuDepthPath) = +GVAR(lastPath); // Execute the current action if it's run on hover diff --git a/addons/interact_menu/functions/fnc_renderMenu.sqf b/addons/interact_menu/functions/fnc_renderMenu.sqf index 459287424c..c5615ce66a 100644 --- a/addons/interact_menu/functions/fnc_renderMenu.sqf +++ b/addons/interact_menu/functions/fnc_renderMenu.sqf @@ -21,7 +21,7 @@ EXPLODE_4_PVT(_this,_parentPath,_action,_pos,_angles); EXPLODE_3_PVT(_action,_actionData,_activeChildren,_actionObject); EXPLODE_2_PVT(_angles,_centerAngle,_maxAngleSpan); -_menuDepth = (count GVAR(menuDepthPath)) - 1; +_menuDepth = (count GVAR(menuDepthPath)); // Store path to action _localPath = _actionData select 7; @@ -44,7 +44,7 @@ _menuInSelectedPath = true; _color = "#FFFFFFFF"; if(!_menuInSelectedPath) then { //_menuDepth > 0 && if (_menuDepth > 0) then { - _color = format ["#%1FFFFFF", [255 * ((((count _path) - 2)/_menuDepth) max 0.25)] call EFUNC(common,toHex)]; + _color = format ["#%1FFFFFF", [255 * ((((count _path) - 1)/_menuDepth) max 0.25)] call EFUNC(common,toHex)]; } else { _color = format ["#%1FFFFFF", [255 * 0.75] call EFUNC(common,toHex)]; }; @@ -57,24 +57,42 @@ GVAR(currentOptions) pushBack [_this, _pos, _path]; // Exit without rendering children if it isn't if !(_menuInSelectedPath) exitWith {true}; -private ["_angleSpan","_angle"]; +private ["_angleSpan","_angle","_angleInterval","_scale"]; _angleSpan = _maxAngleSpan min (55 * ((count _activeChildren) - 1)); if (_angleSpan >= 305) then { _angleSpan = 360; }; +_angleInterval = 55; +if (_angleSpan < 360) then { + if (count _activeChildren > 1) then { + _angleInterval = _angleSpan / (count _activeChildren - 1); + }; +} else { + _angleSpan / (count _activeChildren); +}; +if (count _activeChildren == 1) then { + _angleInterval = 60; +}; + +// Scale menu based on distance +_scale = (0.15 max (0.15 * ((positionCameraToWorld [0, 0, 0]) distance _pos))) / GVAR(selfMenuScale); +// Scale menu based on the amount of children +_scale = _scale * (((0.8 * (0.46 / sin (0.5 * _angleInterval))) min 1.4) max 0.5); +// Animate menu scale +if (_menuInSelectedPath && (_menuDepth == count _path)) then { + _scale = _scale * (0.3 + 0.7 * (((diag_tickTime - GVAR(expandedTime)) * 8) min 1)); +}; _angle = _centerAngle - _angleSpan / 2; { _target = _actionObject; _player = ACE_player; - _mod = (0.15 max (0.15 * ((positionCameraToWorld [0, 0, 0]) distance _pos))) / GVAR(selfMenuScale); - - _offset = ((GVAR(refSystem) select 1) vectorMultiply (-_mod * cos _angle)) vectorAdd - ((GVAR(refSystem) select 2) vectorMultiply (-_mod * sin _angle)); + _offset = ((GVAR(refSystem) select 1) vectorMultiply (-_scale * cos _angle)) vectorAdd + ((GVAR(refSystem) select 2) vectorMultiply (-_scale * sin _angle)); _newPos = ((_pos call EFUNC(common,positionToASL)) vectorAdd _offset) call EFUNC(common,ASLToPosition); - //drawLine3D [_pos, _newPos, [1,0,0,0.5]]; + //drawLine3D [_pos, _newPos, [1,0,0,0.8]]; [_path, _x, _newPos, [_angle, 140]] call FUNC(renderMenu); From 84bf44e0261f6f5700da241902ec188a123ddd04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Badano?= Date: Thu, 19 Mar 2015 23:32:44 -0300 Subject: [PATCH 08/14] Refactoring of interact_menu: - Reordering of action members - Removed full path from actions, so they can be mounted under different paths if needed - Added api for creating actions - Api for adding actions for objects or classes --- addons/interact_menu/XEH_preInit.sqf | 12 +- .../interact_menu/functions/fnc_addAction.sqf | 73 ------------ .../functions/fnc_addActionToClass.sqf | 45 ++++++++ .../functions/fnc_addActionToObject.sqf | 35 ++++++ .../functions/fnc_addClassAction.sqf | 108 ------------------ .../functions/fnc_collectActiveActionTree.sqf | 40 +++---- .../functions/fnc_compileMenu.sqf | 27 +++-- .../functions/fnc_compileMenuSelfAction.sqf | 35 +++--- .../functions/fnc_createAction.sqf | 83 ++++++++------ .../functions/fnc_findActionNode.sqf | 56 +++++++++ addons/interact_menu/functions/fnc_keyUp.sqf | 2 +- .../functions/fnc_keyUpSelfAction.sqf | 2 +- .../functions/fnc_removeActionFromClass.sqf | 39 +++++++ ...ion.sqf => fnc_removeActionFromObject.sqf} | 63 +++++----- .../functions/fnc_removeClassAction.sqf | 72 ------------ addons/interact_menu/functions/fnc_render.sqf | 16 +-- .../functions/fnc_renderBaseMenu.sqf | 20 ++-- .../functions/fnc_renderMenu.sqf | 7 +- .../interact_menu/functions/fnc_splitPath.sqf | 23 ++++ 19 files changed, 353 insertions(+), 405 deletions(-) delete mode 100644 addons/interact_menu/functions/fnc_addAction.sqf create mode 100644 addons/interact_menu/functions/fnc_addActionToClass.sqf create mode 100644 addons/interact_menu/functions/fnc_addActionToObject.sqf delete mode 100644 addons/interact_menu/functions/fnc_addClassAction.sqf create mode 100644 addons/interact_menu/functions/fnc_findActionNode.sqf create mode 100644 addons/interact_menu/functions/fnc_removeActionFromClass.sqf rename addons/interact_menu/functions/{fnc_removeAction.sqf => fnc_removeActionFromObject.sqf} (53%) delete mode 100644 addons/interact_menu/functions/fnc_removeClassAction.sqf create mode 100644 addons/interact_menu/functions/fnc_splitPath.sqf diff --git a/addons/interact_menu/XEH_preInit.sqf b/addons/interact_menu/XEH_preInit.sqf index 2687cf781c..478b5b578d 100644 --- a/addons/interact_menu/XEH_preInit.sqf +++ b/addons/interact_menu/XEH_preInit.sqf @@ -2,22 +2,24 @@ ADDON = false; -PREP(addAction); -PREP(addClassAction); +PREP(addActionToClass); +PREP(addActionToObject); PREP(compileMenu); PREP(compileMenuSelfAction); PREP(collectActiveActionTree); PREP(createAction); +PREP(findActionNode); PREP(keyDown); PREP(keyDownSelfAction); PREP(keyUp); PREP(keyUpSelfAction); -PREP(removeAction); -PREP(removeClassAction); +PREP(removeActionFromClass); +PREP(removeActionFromObject); PREP(render); -PREP(renderIcon); PREP(renderBaseMenu); +PREP(renderIcon); PREP(renderMenu); +PREP(splitPath); GVAR(keyDown) = false; GVAR(keyDownSelfAction) = false; diff --git a/addons/interact_menu/functions/fnc_addAction.sqf b/addons/interact_menu/functions/fnc_addAction.sqf deleted file mode 100644 index ef3c2196e6..0000000000 --- a/addons/interact_menu/functions/fnc_addAction.sqf +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Author: commy2, NouberNou and CAA-Picard - * Add an ACE action to an object, under a certain config path - * Note: This function is NOT global. - * - * Argument: - * 0: Object the action should be assigned to - * 1: Type of action, 0 for actions, 1 for self-actions - * 2: Full path of the new action - * 3: Name of the action shown in the menu - * 4: Icon - * 5: Position (Position or Selection Name) or - * 6: Statement - * 7: Condition - * 8: Distance - * 9: Other parameters (Optional) - * 10: Insert children code (Optional) - * 11: Action parameters (Optional) - * - * Return value: - * The entry full path, which can be used to remove the entry, or add children entries . - * - * Example: - * [cursorTarget,0,["ACE_TapShoulderRight","VulcanPinch"],"Vulcan Pinch","",[0,0,0],{_target setDamage 1;},{true},100] call ace_interact_menu_fnc_addAction; - * - * Public: No - */ -#include "script_component.hpp" - -EXPLODE_9_PVT(_this,_object,_typeNum,_fullPath,_displayName,_icon,_position,_statement,_condition,_distance); - -private ["_varName","_actions","_params","_insertChildren","_parameters","_entry"]; - -_varName = [QGVAR(actions),QGVAR(selfActions)] select _typeNum; -_actions = _object getVariable [_varName, []]; -if((count _actions) == 0) then { - _object setVariable [_varName, _actions]; -}; - -_params = [false,false,false,false]; -if (count _this > 9) then { - _params = _this select 9; -}; - -_insertChildren = {}; -if (count _this > 10) then { - _insertChildren = _this select 10; -}; - -_parameters = []; -if (count _this > 11) then { - _parameters = _this select 11; -}; - -_entry = [ - [ - _displayName, - _icon, - _position, - _statement, - _condition, - _distance, - _params, - + _fullPath, - _insertChildren, - _parameters - ], - [] - ]; - -_actions pushBack _entry; - -_fullPath diff --git a/addons/interact_menu/functions/fnc_addActionToClass.sqf b/addons/interact_menu/functions/fnc_addActionToClass.sqf new file mode 100644 index 0000000000..c93342cfda --- /dev/null +++ b/addons/interact_menu/functions/fnc_addActionToClass.sqf @@ -0,0 +1,45 @@ +/* + * Author: CAA-Picard + * Insert an ACE action to a class, under a certain path + * Note: This function is NOT global. + * + * Argument: + * 0: TypeOf of the class + * 1: Type of action, 0 for actions, 1 for self-actions + * 2: Parent path of the new action + * 3: Action + * + * Return value: + * The entry full path, which can be used to remove the entry, or add children entries . + * + * Example: + * [typeOf cursorTarget, 0, ["ACE_TapShoulderRight"],VulcanPinchAction] call ace_interact_menu_fnc_addActionToClass; + * + * Public: No + */ +#include "script_component.hpp" + +EXPLODE_4_PVT(_this,_objectType,_typeNum,_parentPath,_action); + +// Ensure the config menu was compiled first +if (_typeNum == 0) then { + [_objectType] call FUNC(compileMenu); +} else { + [_objectType] call FUNC(compileMenuSelfAction); +}; + +private ["_varName","_actionTrees", "_parentNode"]; +_varName = format [[QGVAR(Act_%1), QGVAR(SelfAct_%1)] select _typeNum, _objectType]; +_actionTrees = missionNamespace getVariable [_varName, []]; +if((count _actionTrees) == 0) then { + missionNamespace setVariable [_varName, _actionTrees]; +}; + +_parentNode = [_actionTrees, _parentPath] call FUNC(findActionNode); +if (isNil {_parentNode}) exitWith {}; + +// Add action node as children of the correct node of action tree +(_parentNode select 1) pushBack [_action,[]]; + +// Return the full path +(+ _parentPath) pushBack (_action select 0) diff --git a/addons/interact_menu/functions/fnc_addActionToObject.sqf b/addons/interact_menu/functions/fnc_addActionToObject.sqf new file mode 100644 index 0000000000..223247057a --- /dev/null +++ b/addons/interact_menu/functions/fnc_addActionToObject.sqf @@ -0,0 +1,35 @@ +/* + * Author: CAA-Picard + * Insert an ACE action to an object, under a certain config path + * Note: This function is NOT global. + * + * Argument: + * 0: Object the action should be assigned to + * 1: Type of action, 0 for actions, 1 for self-actions + * 2: Parent path of the new action + * 3: Action + * + * Return value: + * The entry full path, which can be used to remove the entry, or add children entries . + * + * Example: + * [typeOf cursorTarget, 0, ["ACE_TapShoulderRight"],VulcanPinchAction] call ace_interact_menu_fnc_addActionToClass; + * + * Public: No + */ +#include "script_component.hpp" + +EXPLODE_4_PVT(_this,_object,_typeNum,_parentPath,_action); + +private ["_varName","_actionList"]; +_varName = [QGVAR(actions),QGVAR(selfActions)] select _typeNum; +_actionList = _object getVariable [_varName, []]; +if((count _actionList) == 0) then { + _object setVariable [_varName, _actionList]; +}; + +// Add action and parent path to the list of object actions +_actionList pushBack [_action, +_parentPath]; + +// Return the full path +(+ _parentPath) pushBack (_action select 0) diff --git a/addons/interact_menu/functions/fnc_addClassAction.sqf b/addons/interact_menu/functions/fnc_addClassAction.sqf deleted file mode 100644 index a389b5bd8b..0000000000 --- a/addons/interact_menu/functions/fnc_addClassAction.sqf +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Author: CAA-Picard - * Add an ACE action to a class, under a certain path - * Note: This function is NOT global. - * - * Argument: - * 0: TypeOf of the class - * 1: Type of action, 0 for actions, 1 for self-actions - * 2: Full path of the new action - * 3: Name of the action shown in the menu - * 4: Icon - * 5: Position (Position or Selection Name) or - * 6: Statement - * 7: Condition - * 8: Distance - * 9: Other parameters (Optional) - * 10: Insert children code (Optional) - * 11: Action parameters (Optional) - * - * Return value: - * The entry full path, which can be used to remove the entry, or add children entries . - * - * Example: - * [typeOf cursorTarget, 0,["ACE_TapShoulderRight","VulcanPinch"],"Vulcan Pinch","",[0,0,0],{_target setDamage 1;},{true},100] call ace_interact_menu_fnc_addClassAction; - * - * Public: No - */ -#include "script_component.hpp" - -EXPLODE_9_PVT(_this,_objectType,_typeNum,_fullPath,_displayName,_icon,_position,_statement,_condition,_distance); - -// Ensure the config menu was compiled first -if (_typeNum == 0) then { - [_objectType] call FUNC(compileMenu); -} else { - [_objectType] call FUNC(compileMenuSelfAction); -}; - -private ["_varName","_actions","_params","_insertChildren","_parameters","_entry", "_parentLevel", "_foundParentLevel", "_fnc_findFolder"]; - -_varName = format [[QGVAR(Act_%1), QGVAR(SelfAct_%1)] select _typeNum, _objectType]; -_actions = missionNamespace getVariable [_varName, []]; -if((count _actions) == 0) then { - missionNamespace setVariable [_varName, _actions]; -}; - -_params = [false,false,false,false]; -if (count _this > 9) then { - _params = _this select 9; -}; - -_insertChildren = {}; -if (count _this > 10) then { - _insertChildren = _this select 10; -}; - -_parameters = []; -if (count _this > 11) then { - _parameters = _this select 11; -}; - -// Search the class action trees and find where to insert the entry -_parentLevel = _actions; -_foundParentLevel = false; - -_fnc_findFolder = { - EXPLODE_3_PVT(_this,_fullPath,_level,_classActions); - - if (count _fullPath == _level + 1) then { - _parentLevel = _classActions; - _foundParentLevel = true; - }; - - if (_foundParentLevel) exitWith {}; - - { - EXPLODE_2_PVT(_x,_actionData,_actionChildren); - if (((_actionData select 7) select _level) isEqualTo (_fullPath select _level)) exitWith { - // The action should go somewhere in here - [_fullPath, _level + 1, _actionChildren] call _fnc_findFolder; - }; - } forEach _classActions; -}; - -[_fullPath, 0, _actions] call _fnc_findFolder; - -// Exit if there's no entry point to insert this action -if (!_foundParentLevel) exitWith {}; - -_entry = [ - [ - _displayName, - _icon, - _position, - _statement, - _condition, - _distance, - _params, - + _fullPath, - _insertChildren, - _parameters - ], - [] - ]; - -_parentLevel pushBack _entry; - -_fullPath diff --git a/addons/interact_menu/functions/fnc_collectActiveActionTree.sqf b/addons/interact_menu/functions/fnc_collectActiveActionTree.sqf index 547d5bb707..f4ae2ff5c1 100644 --- a/addons/interact_menu/functions/fnc_collectActiveActionTree.sqf +++ b/addons/interact_menu/functions/fnc_collectActiveActionTree.sqf @@ -5,6 +5,7 @@ * Argument: * 0: Object * 1: Original action tree + * 2: Parent path * * Return value: * Active children @@ -13,29 +14,32 @@ */ #include "script_component.hpp" -EXPLODE_2_PVT(_this,_object,_origAction); +EXPLODE_3_PVT(_this,_object,_origAction,_parentPath); EXPLODE_2_PVT(_origAction,_origActionData,_origActionChildren); -private ["_resultingAction","_target","_player","_activeChildren","_action","_actionData","_x"]; +private ["_target","_player","_fullPath","_activeChildren","_action","_actionData","_x"]; _target = _object; _player = ACE_player; // Return nothing if the action itself is not active -if !([_target, ACE_player, _origActionData select 9] call (_origActionData select 4)) exitWith { +if !([_target, ACE_player, _origActionData select 6] call (_origActionData select 4)) exitWith { [] }; _activeChildren = []; // If there's a statement to dynamically insert children then execute it -if (count _origActionData > 8 && {!({} isEqualTo (_origActionData select 8))}) then { - _activeChildren = [_target, ACE_player, _origActionData select 9] call (_origActionData select 8); +if !({} isEqualTo (_origActionData select 5)) then { + _activeChildren = [_target, ACE_player, _origActionData select 6] call (_origActionData select 5); }; +_fullPath = +_parentPath; +_fullPath pushBack (_origActionData select 0); + // Collect children class actions { - _action = [_object, _x] call FUNC(collectActiveActionTree); + _action = [_object, _x, _fullPath] call FUNC(collectActiveActionTree); if ((count _action) > 0) then { _activeChildren pushBack _action; }; @@ -43,26 +47,15 @@ if (count _origActionData > 8 && {!({} isEqualTo (_origActionData select 8))}) t // Collect children object actions { - _action = _x; - _actionData = _action select 0; + EXPLODE_2_PVT(_x,_actionData,_pPath); // Check if the action is children of the original action - if ((count (_actionData select 7)) == (count (_origActionData select 7) + 1)) then { + if (count _pPath == count _fullPath && + {_pPath isEqualTo _fullPath}) then { - // Compare parent path to see if it's a suitable child - private "_isChild"; - _isChild = true; - { - if !(_x isEqualTo ((_actionData select 7) select _forEachIndex)) exitWith { - _isChild = false; - }; - } forEach (_origActionData select 7); - - if (_isChild) then { - _action = [_object, _action] call FUNC(collectActiveActionTree); - if ((count _action) > 0) then { - _activeChildren pushBack _action; - }; + _action = [_object, _action, _fullPath] call FUNC(collectActiveActionTree); + if ((count _action) > 0) then { + _activeChildren pushBack _action; }; }; } forEach GVAR(objectActions); @@ -75,5 +68,4 @@ if ((count _activeChildren) == 0 && ((_origActionData select 3) isEqualTo {})) e }; -//diag_log [_origActionData, _activeChildren, _object]; [_origActionData, _activeChildren, _object] diff --git a/addons/interact_menu/functions/fnc_compileMenu.sqf b/addons/interact_menu/functions/fnc_compileMenu.sqf index 46e74fb220..0fd4f6adb4 100644 --- a/addons/interact_menu/functions/fnc_compileMenu.sqf +++ b/addons/interact_menu/functions/fnc_compileMenu.sqf @@ -27,8 +27,8 @@ if !(isNil {missionNamespace getVariable [_actionsVarName, nil]}) exitWith {}; private "_recurseFnc"; _recurseFnc = { private ["_actions", "_displayName", "_distance", "_icon", "_statement", "_selection", "_condition", "_showDisabled", - "_enableInside", "_canCollapse", "_runOnHover", "_children", "_entry", "_entryCfg", "_fullPath", "_insertChildren"]; - EXPLODE_2_PVT(_this,_actionsCfg,_parentPath); + "_enableInside", "_canCollapse", "_runOnHover", "_children", "_entry", "_entryCfg", "_insertChildren"]; + EXPLODE_1_PVT(_this,_actionsCfg); _actions = []; for "_i" from 0 to (count _actionsCfg) - 1 do { @@ -55,24 +55,21 @@ _recurseFnc = { _canCollapse = (getNumber (_entryCfg >> "canCollapse")) > 0; _runOnHover = (getNumber (_entryCfg >> "runOnHover")) > 0; - _fullPath = (+ _parentPath); - _fullPath pushBack (configName _entryCfg); - _condition = compile _condition; - _children = [_entryCfg, _fullPath] call _recurseFnc; + _children = [_entryCfg] call _recurseFnc; _entry = [ [ + configName _entryCfg, _displayName, _icon, - _selection, _statement, _condition, - _distance, - [_showDisabled,_enableInside,_canCollapse,_runOnHover], - _fullPath, _insertChildren, - [] + [], + _selection, + _distance, + [_showDisabled,_enableInside,_canCollapse,_runOnHover] ], _children ]; @@ -85,20 +82,22 @@ _recurseFnc = { private "_actionsCfg"; _actionsCfg = configFile >> "CfgVehicles" >> _objectType >> "ACE_Actions"; -missionNamespace setVariable [_actionsVarName, [_actionsCfg, []] call _recurseFnc]; +missionNamespace setVariable [_actionsVarName, [_actionsCfg] call _recurseFnc]; /* [ [ [ + "MyAction", "My Action", "\a3\ui_f\data\IGUI\Cfg\Actions\eject_ca.paa", - [0,0,0], { (_this select 0) setVelocity [0,0,10]; }, { true }, + {}, + [], + [0,0,0], 1, [false,false,false] - ["ACE_MainActions","TeamManagement","MyAction"] ], [children actions] ] diff --git a/addons/interact_menu/functions/fnc_compileMenuSelfAction.sqf b/addons/interact_menu/functions/fnc_compileMenuSelfAction.sqf index 5c613caec2..ebccc2ca42 100644 --- a/addons/interact_menu/functions/fnc_compileMenuSelfAction.sqf +++ b/addons/interact_menu/functions/fnc_compileMenuSelfAction.sqf @@ -27,8 +27,8 @@ if !(isNil {missionNamespace getVariable [_actionsVarName, nil]}) exitWith {}; private "_recurseFnc"; _recurseFnc = { private ["_actions", "_displayName", "_distance", "_icon", "_statement", "_selection", "_condition", "_showDisabled", - "_enableInside", "_canCollapse", "_runOnHover", "_children", "_entry", "_entryCfg", "_fullPath", "_insertChildren"]; - EXPLODE_2_PVT(_this,_actionsCfg,_parentPath); + "_enableInside", "_canCollapse", "_runOnHover", "_children", "_entry", "_entryCfg", "_insertChildren"]; + EXPLODE_1_PVT(_this,_actionsCfg); _actions = []; for "_i" from 0 to (count _actionsCfg) - 1 do { @@ -52,24 +52,21 @@ _recurseFnc = { _canCollapse = (getNumber (_entryCfg >> "canCollapse")) > 0; _runOnHover = (getNumber (_entryCfg >> "runOnHover")) > 0; - _fullPath = (+ _parentPath); - _fullPath pushBack (configName _entryCfg); - _condition = compile _condition; - _children = [_entryCfg, _fullPath] call _recurseFnc; + _children = [_entryCfg] call _recurseFnc; _entry = [ [ + configName _entryCfg, _displayName, _icon, - [0,0,0], _statement, _condition, - 10, //distace - [_showDisabled,_enableInside,_canCollapse,_runOnHover], - _fullPath, _insertChildren, - [] + [], + [0,0,0], + 10, //distace + [_showDisabled,_enableInside,_canCollapse,_runOnHover] ], _children ]; @@ -86,18 +83,18 @@ _actionsCfg = configFile >> "CfgVehicles" >> _objectType >> "ACE_SelfActions"; _actions = [ [ [ + "ACE_SelfActions", "Self Actions", "\a3\ui_f\data\IGUI\Cfg\Actions\eject_ca.paa", - "Spine3", - { true }, - { true }, - 10, - [false,true,false], - ["ACE_SelfActions"], {}, - [] + { true }, + {}, + [], + "Spine3", + 10, + [false,true,false] ], - [_actionsCfg, ["ACE_SelfActions"]] call _recurseFnc + [_actionsCfg] call _recurseFnc ] ]; diff --git a/addons/interact_menu/functions/fnc_createAction.sqf b/addons/interact_menu/functions/fnc_createAction.sqf index e7d53dab03..785db2c8b9 100644 --- a/addons/interact_menu/functions/fnc_createAction.sqf +++ b/addons/interact_menu/functions/fnc_createAction.sqf @@ -7,57 +7,68 @@ * 0: Action name * 1: Name of the action shown in the menu * 2: Icon - * 3: Position (Position or Selection Name) or - * 4: Statement - * 5: Condition - * 6: Distance - * 7: Other parameters (Optional) - * 8: Insert children code (Optional) - * 9: Action parameters (Optional) + * 3: Statement + * 4: Condition + * 5: Insert children code (Optional) + * 6: Action parameters (Optional) + * 7: Position (Position or Selection Name) or (Optional) + * 8: Distance (Optional) + * 9: Other parameters (Optional) * * Return value: - * Action + * Action * * Example: - * [[VulcanPinch"],"Vulcan Pinch","",[0,0,0],{_target setDamage 1;},{true},100,{},[parameters]] call ace_interact_menu_fnc_addAction; + * [VulcanPinch","Vulcan Pinch",{_target setDamage 1;},{true},{},[parameters], [0,0,0], 100] call ace_interact_menu_fnc_createAction; * * Public: No */ #include "script_component.hpp" -EXPLODE_7_PVT(_this,_fullPath,_displayName,_icon,_position,_statement,_condition,_distance); +EXPLODE_5_PVT(_this,_actionName,_displayName,_icon,_statement,_condition); -private ["_actions","_params","_insertChildren","_parameters","_entry"]; +private ["_insertChildren","_customParams","_position","_distance","_params"]; -_params = [false,false,false,false]; -if (count _this > 7) then { - _params = _this select 7; +_insertChildren = if (count _this > 5) then { + _this select 5 +} else { + {} }; -_insertChildren = {}; -if (count _this > 8) then { - _insertChildren = _this select 8; +_customParams = if (count _this > 6) then { + _this select 6 +} else { + [] }; -_parameters = []; -if (count _this > 9) then { - _parameters = _this select 9; +_position = if (count _this > 7) then { + _this select 7 +} else { + [0,0,0] }; -_entry = [ - [ - _displayName, - _icon, - _position, - _statement, - _condition, - _distance, - _params, - + _fullPath, - _insertChildren, - _parameters - ], - [] - ]; +_distance = if (count _this > 8) then { + _this select 8 +} else { + 2 +}; -_entry +_params = if (count _this > 9) then { + _this select 9 +} else { + [false,false,false,false] +}; + +[ + _actionName, + _displayName, + _icon, + _statement, + _condition, + + _insertChildren, + _customParams, + _position, + _distance, + _params +] diff --git a/addons/interact_menu/functions/fnc_findActionNode.sqf b/addons/interact_menu/functions/fnc_findActionNode.sqf new file mode 100644 index 0000000000..41dd32b7d8 --- /dev/null +++ b/addons/interact_menu/functions/fnc_findActionNode.sqf @@ -0,0 +1,56 @@ +/* + * Author: CAA-Picard + * Return action point from path + * Note: This function is NOT global. + * + * Argument: + * 0: List of Action Tree + * 1: Path + * + * Return value: + * Action node . + * + * Example: + * [_actionTree, ["ACE_TapShoulderRight","VulcanPinchAction"]] call ace_interact_menu_fnc_findActionNode; + * + * Public: No + */ +#include "script_component.hpp" + +EXPLODE_2_PVT(_this,_actionTreeList,_parentPath); + +private ["_parentNode", "_foundParentNode", "_fnc_findFolder"]; + +// Hack to make this work on the root node too +if (count _parentPath == 0) exitWith { + [[],_actionTreeList] +}; + +// Search the class action trees and find where to insert the entry +_parentNode = [[],_actionTreeList]; +_foundParentNode = false; + +_fnc_findFolder = { + EXPLODE_3_PVT(_this,_parentPath,_level,_actionNode); + + { + EXPLODE_2_PVT(_x,_actionData,_actionChildren); + if ((_actionData select 0) isEqualTo (_parentPath select _level)) exitWith { + + if (count _parentPath == _level + 1) exitWith { + _parentNode = _x; + _foundParentNode = true; + }; + + // The action should go somewhere in here + [_parentPath, _level + 1, _x] call _fnc_findFolder; + }; + } forEach (_actionNode select 1); +}; + +[_parentPath, 0, [[],_actionTreeList]] call _fnc_findFolder; + +// Exit if there's no entry point to insert this action +if (!_foundParentNode) exitWith {}; + +_parentNode diff --git a/addons/interact_menu/functions/fnc_keyUp.sqf b/addons/interact_menu/functions/fnc_keyUp.sqf index fe60c438b6..69f9697449 100644 --- a/addons/interact_menu/functions/fnc_keyUp.sqf +++ b/addons/interact_menu/functions/fnc_keyUp.sqf @@ -16,7 +16,7 @@ if(GVAR(actionSelected)) then { this = GVAR(selectedTarget); _player = ACE_Player; _target = GVAR(selectedTarget); - [GVAR(selectedTarget), ACE_player, (GVAR(selectedAction) select 0) select 9] call GVAR(selectedStatement); + [GVAR(selectedTarget), ACE_player, (GVAR(selectedAction) select 0) select 6] call GVAR(selectedStatement); }; if (GVAR(keyDown)) then { diff --git a/addons/interact_menu/functions/fnc_keyUpSelfAction.sqf b/addons/interact_menu/functions/fnc_keyUpSelfAction.sqf index 4603479e87..dd54490532 100644 --- a/addons/interact_menu/functions/fnc_keyUpSelfAction.sqf +++ b/addons/interact_menu/functions/fnc_keyUpSelfAction.sqf @@ -20,7 +20,7 @@ if(GVAR(actionSelected)) then { this = GVAR(selectedTarget); _player = ACE_Player; _target = GVAR(selectedTarget); - [GVAR(selectedTarget), ACE_player, (GVAR(selectedAction) select 0) select 9] call GVAR(selectedStatement); + [GVAR(selectedTarget), ACE_player, (GVAR(selectedAction) select 0) select 6] call GVAR(selectedStatement); }; if (GVAR(keyDownSelfAction)) then { diff --git a/addons/interact_menu/functions/fnc_removeActionFromClass.sqf b/addons/interact_menu/functions/fnc_removeActionFromClass.sqf new file mode 100644 index 0000000000..aee1675fa7 --- /dev/null +++ b/addons/interact_menu/functions/fnc_removeActionFromClass.sqf @@ -0,0 +1,39 @@ +/* + * Author: CAA-Picard + * Removes an action from a class + * + * Argument: + * 0: TypeOf of the class + * 1: Type of action, 0 for actions, 1 for self-actions + * 2: Full path of the new action + * + * Return value: + * None + * + * Example: + * [typeOf cursorTarget, 0,["ACE_TapShoulderRight","VulcanPinch"]] call ace_interact_menu_fnc_removeActionFromClass; + * + * Public: No + */ +#include "script_component.hpp" + +EXPLODE_3_PVT(_this,_objectType,_typeNum,_fullPath); + +private ["_res","_varName","_actionTrees"]; +_res = _fullPath call FUNC(splitPath); +EXPLODE_2_PVT(_res,_parentPath,_actionName); + +_varName = format [[QGVAR(Act_%1), QGVAR(SelfAct_%1)] select _typeNum, _objectType]; +_actionTrees = missionNamespace getVariable [_varName, []]; + +_parentNode = [_actionTrees, _parentPath] call FUNC(findActionNode); +if (isNil {_parentNode}) exitWith {}; + +// Iterate through children of the father +{ + if (((_x select 0) select 0) == _actionName) exitWith { + (_parentNode select 1) deleteAt _forEachIndex; + }; +} forEach (_parentNode select 1); + +_parentLevel deleteAt _actionIndex; diff --git a/addons/interact_menu/functions/fnc_removeAction.sqf b/addons/interact_menu/functions/fnc_removeActionFromObject.sqf similarity index 53% rename from addons/interact_menu/functions/fnc_removeAction.sqf rename to addons/interact_menu/functions/fnc_removeActionFromObject.sqf index 3c6988971d..dc5fdc05f0 100644 --- a/addons/interact_menu/functions/fnc_removeAction.sqf +++ b/addons/interact_menu/functions/fnc_removeActionFromObject.sqf @@ -1,30 +1,33 @@ -/* - * Author: commy2, NouberNou and CAA-Picard - * Remove an action from an object - * - * Argument: - * 0: Object the action is assigned to - * 1: Type of action, 0 for actions, 1 for self-actions - * 2: Full path of the action to remove - * - * Return value: - * None - * - * Example: - * [cursorTarget,0,["ACE_TapShoulderRight","VulcanPinch"]] call ace_interact_menu_fnc_removeAction; - * - * Public: No - */ -#include "script_component.hpp" - -EXPLODE_3_PVT(_this,_object,_typeNum,_fullPath); - -private ["_varName","_actions"]; -_varName = [QGVAR(actions),QGVAR(selfActions)] select _typeNum; -_actions = _object getVariable [_varName, []]; - -{ - if (((_x select 0) select 7) isEqualTo _fullPath) exitWith { - _actions deleteAt _forEachIndex; - }; -} forEach _actions; +/* + * Author: commy2, NouberNou and CAA-Picard + * Removes an action from an object + * + * Argument: + * 0: Object the action is assigned to + * 1: Type of action, 0 for actions, 1 for self-actions + * 2: Full path of the action to remove + * + * Return value: + * None + * + * Example: + * [cursorTarget,0,["ACE_TapShoulderRight","VulcanPinch"]] call ace_interact_menu_fnc_removeActionFromObject; + * + * Public: No + */ +#include "script_component.hpp" + +EXPLODE_3_PVT(_this,_object,_typeNum,_fullPath); + +private ["_res","_varName","_actionList"]; +_res = _fullPath call FUNC(splitPath); +EXPLODE_2_PVT(_res,_parentPath,_actionName); + +_varName = [QGVAR(actions),QGVAR(selfActions)] select _typeNum; +_actionList = _object getVariable [_varName, []]; +{ + if (((_x select 0) select 0) isEqualTo _actionName && + {(_x select 1) isEqualTo _parentPath}) exitWith { + _actionList deleteAt _forEachIndex; + }; +} forEach _actionList; diff --git a/addons/interact_menu/functions/fnc_removeClassAction.sqf b/addons/interact_menu/functions/fnc_removeClassAction.sqf deleted file mode 100644 index 9ba29cd357..0000000000 --- a/addons/interact_menu/functions/fnc_removeClassAction.sqf +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Author: CAA-Picard - * Removes a class action from a class - * Note: This function is NOT global. - * - * Argument: - * 0: TypeOf of the class - * 1: Type of action, 0 for actions, 1 for self-actions - * 2: Full path of the new action - * - * Return value: - * None - * - * Example: - * [typeOf cursorTarget, 0,["ACE_TapShoulderRight","VulcanPinch"]] call ace_interact_menu_fnc_removeClassAction; - * - * Public: No - */ -#include "script_component.hpp" - -EXPLODE_3_PVT(_this,_objectType,_typeNum,_fullPath); - -private ["_varName","_actions","_parentLevel", "_actionIndex", "_foundAction", "_fnc_findFolder"]; - -_varName = format [[QGVAR(Act_%1), QGVAR(SelfAct_%1)] select _typeNum, _objectType]; -_actions = missionNamespace getVariable [_varName, []]; - -// Search the class action trees and find where to insert the entry -_parentLevel = _actions; -_actionIndex = -1; -_foundAction = false; - -_fnc_findFolder = { - EXPLODE_3_PVT(_this,_fullPath,_level,_classActions); - - if (count _fullPath == _level + 1) then { - _parentLevel = _classActions; - }; - - { - EXPLODE_2_PVT(_x,_actionData,_actionChildren); - if (((_actionData select 7) select _level) isEqualTo (_fullPath select _level)) exitWith { - if (_level + 1 == count _fullPath) exitWith { - _actionIndex = _forEachIndex; - _foundAction = true; - }; - [_fullPath, _level + 1, _actionChildren] call _fnc_findFolder; - }; - if (_foundAction) exitWith {}; - } forEach _classActions; -}; - -[_fullPath, 0, _actions] call _fnc_findFolder; - -// Exit if the action was not found -if (!_foundAction) exitWith {}; - -_entry = [ - [ - _displayName, - _icon, - _position, - _statement, - _condition, - _distance, - _params, - + _fullPath - ], - [] - ]; - -_parentLevel deleteAt _actionIndex; diff --git a/addons/interact_menu/functions/fnc_render.sqf b/addons/interact_menu/functions/fnc_render.sqf index 361b7031cc..922027e2a0 100644 --- a/addons/interact_menu/functions/fnc_render.sqf +++ b/addons/interact_menu/functions/fnc_render.sqf @@ -41,17 +41,17 @@ if (GVAR(keyDown)) then { // Iterate through object actions, find base level actions and render them if appropiate _actionsVarName = format [QGVAR(Act_%1), typeOf _target]; - GVAR(objectActions) = _target getVariable [QGVAR(actions), []]; + GVAR(objectActionList) = _target getVariable [QGVAR(actions), []]; { - _action = _x; // Only render them directly if they are base level actions - if (count ((_action select 0) select 7) == 1) then { + if (count (_x select 1) == 0) then { // Try to render the menu + _action = [_x,[]]; if ([_target, _action] call FUNC(renderBaseMenu)) then { _numInteractions = _numInteractions + 1; }; }; - } forEach GVAR(objectActions); + } forEach GVAR(objectActionList); // Iterate through base level class actions and render them if appropiate _classActions = missionNamespace getVariable [_actionsVarName, []]; @@ -80,7 +80,7 @@ if (GVAR(keyDown)) then { // Iterate through object actions, find base level actions and render them if appropiate _actionsVarName = format [QGVAR(SelfAct_%1), typeOf _target]; - GVAR(objectActions) = _target getVariable [QGVAR(selfActions), []]; + GVAR(objectActionList) = _target getVariable [QGVAR(selfActions), []]; /* { _action = _x; @@ -88,7 +88,7 @@ if (GVAR(keyDown)) then { if (count (_action select 7) == 1) then { [_target, _action, 0, [180, 360]] call FUNC(renderMenu); }; - } forEach GVAR(objectActions); + } forEach GVAR(objectActionList); */ // Iterate through base level class actions and render them if appropiate @@ -171,12 +171,12 @@ if(GVAR(keyDown) || GVAR(keyDownSelfAction)) then { // Execute the current action if it's run on hover private "_runOnHover"; - _runOnHover = ((GVAR(selectedAction) select 0) select 6) select 3; + _runOnHover = ((GVAR(selectedAction) select 0) select 9) select 3; if (_runOnHover) then { this = GVAR(selectedTarget); _player = ACE_Player; _target = GVAR(selectedTarget); - [GVAR(selectedTarget), ACE_player] call GVAR(selectedStatement); + [GVAR(selectedTarget), ACE_player, (GVAR(selectedAction) select 0) select 6] call GVAR(selectedStatement); }; }; }; diff --git a/addons/interact_menu/functions/fnc_renderBaseMenu.sqf b/addons/interact_menu/functions/fnc_renderBaseMenu.sqf index fd3cc4d668..da01fa804f 100644 --- a/addons/interact_menu/functions/fnc_renderBaseMenu.sqf +++ b/addons/interact_menu/functions/fnc_renderBaseMenu.sqf @@ -4,7 +4,7 @@ * * Argument: * 0: Object - * 1: Action data + * 1: Action node * 2: 3D position (Optional) * * Return value: @@ -16,25 +16,25 @@ private ["_distance","_pos","_weaponDir","_ref","_cameraPos","_sPos","_activeActionTree"]; -EXPLODE_2_PVT(_this,_object,_baseAction); -EXPLODE_1_PVT(_baseAction,_actionData); +EXPLODE_2_PVT(_this,_object,_baseActionNode); +EXPLODE_1_PVT(_baseActionNode,_actionData); -_distance = _actionData select 5; +_distance = _actionData select 8; // Obtain a 3D position for the action if((count _this) > 2) then { _pos = _this select 2; } else { - if(typeName (_actionData select 2) == "ARRAY") then { - _pos = _object modelToWorld (_actionData select 2); + if(typeName (_actionData select 7) == "ARRAY") then { + _pos = _object modelToWorld (_actionData select 7); } else { - if ((_actionData select 2) == "weapon") then { + if ((_actionData select 7) == "weapon") then { // Craft a suitable position for weapon interaction _weaponDir = _object weaponDirection currentWeapon _object; _ref = _weaponDir call EFUNC(common,createOrthonormalReference); _pos = (_object modelToWorld (_object selectionPosition "righthand")) vectorAdd ((_ref select 2) vectorMultiply 0.1); } else { - _pos = _object modelToWorld (_object selectionPosition (_actionData select 2)); + _pos = _object modelToWorld (_object selectionPosition (_actionData select 7)); }; }; // Compensate for movement during the frame to get rid of jittering @@ -59,9 +59,9 @@ if ((_sPos select 1) < safeZoneY || (_sPos select 1) > safeZoneY + safeZon // Collect active tree private "_uid"; -_uid = format [QGVAR(ATCache_%1), (_actionData select 7) select 0]; +_uid = format [QGVAR(ATCache_%1), _actionData select 0]; _activeActionTree = [ - [_object, _baseAction], + [_object, _baseActionNode, []], DFUNC(collectActiveActionTree), _object, _uid, 0.2 ] call EFUNC(common,cachedCall); diff --git a/addons/interact_menu/functions/fnc_renderMenu.sqf b/addons/interact_menu/functions/fnc_renderMenu.sqf index c5615ce66a..26b07dd475 100644 --- a/addons/interact_menu/functions/fnc_renderMenu.sqf +++ b/addons/interact_menu/functions/fnc_renderMenu.sqf @@ -15,7 +15,7 @@ */ #include "script_component.hpp" -private ["_menuInSelectedPath", "_localPath", "_path", "_menuDepth", "_currentRenderDepth", "_x", "_offset", "_newPos", "_forEachIndex"]; +private ["_menuInSelectedPath", "_path", "_menuDepth", "_currentRenderDepth", "_x", "_offset", "_newPos", "_forEachIndex"]; EXPLODE_4_PVT(_this,_parentPath,_action,_pos,_angles); EXPLODE_3_PVT(_action,_actionData,_activeChildren,_actionObject); @@ -24,9 +24,8 @@ EXPLODE_2_PVT(_angles,_centerAngle,_maxAngleSpan); _menuDepth = (count GVAR(menuDepthPath)); // Store path to action -_localPath = _actionData select 7; _path = +_parentPath; -_path pushBack [_localPath select ((count _localPath) - 1), _actionObject]; +_path pushBack [_actionData select 0,_actionObject]; // Check if the menu is on the selected path _menuInSelectedPath = true; @@ -49,7 +48,7 @@ if(!_menuInSelectedPath) then { //_menuDepth > 0 && _color = format ["#%1FFFFFF", [255 * 0.75] call EFUNC(common,toHex)]; }; }; -[_actionData select 0, _color, _pos, 1, 1, 0, _actionData select 1, 0.5, 0.025, "TahomaB"] call FUNC(renderIcon); +[_actionData select 1, _color, _pos, 1, 1, 0, _actionData select 2, 0.5, 0.025, "TahomaB"] call FUNC(renderIcon); // Add the action to current options GVAR(currentOptions) pushBack [_this, _pos, _path]; diff --git a/addons/interact_menu/functions/fnc_splitPath.sqf b/addons/interact_menu/functions/fnc_splitPath.sqf new file mode 100644 index 0000000000..0bbe643adf --- /dev/null +++ b/addons/interact_menu/functions/fnc_splitPath.sqf @@ -0,0 +1,23 @@ +/* + * Author: CAA-Picard + * Take full path and split it between parent path and action name + * + * Argument: + * Full path of the action to remove + * + * Return value: + * 0: Parent path + * 1: Action name + * + * Public: No + */ +#include "script_component.hpp" + +private ["_parentPath","_actionName"]; +_parentPath = []; +for "_i" from 0 to (count _this) - 1 do { + _parentPath pushBack (_this select _i); +}; +_actionName = _this select ((count _this) - 1); + +[_parentPath, _actionName] From b854db0195f52f5a29c6aba5dc8c12f97f458032 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Badano?= Date: Thu, 19 Mar 2015 23:33:11 -0300 Subject: [PATCH 09/14] Updated interact_menu api calls on ace_dragging --- addons/dragging/functions/fnc_setCarryable.sqf | 7 +++++-- addons/dragging/functions/fnc_setDraggable.sqf | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/addons/dragging/functions/fnc_setCarryable.sqf b/addons/dragging/functions/fnc_setCarryable.sqf index d1dd9cf1a9..630f212b97 100644 --- a/addons/dragging/functions/fnc_setCarryable.sqf +++ b/addons/dragging/functions/fnc_setCarryable.sqf @@ -48,5 +48,8 @@ if (_type in _initializedClasses) exitWith {}; _initializedClasses pushBack _type; GVAR(initializedClasses_carry) = _initializedClasses; -[_type, 0, ["ACE_MainActions", QGVAR(carry)], localize "STR_ACE_Dragging_Carry", "", "", {[_player, _target] call FUNC(carryObject)}, {[_player, _target] call FUNC(canCarry)}, 2] call EFUNC(interact_menu,addClassAction); -[_type, 0, ["ACE_MainActions", QGVAR(drop_carry)], localize "STR_ACE_Dragging_Drop", "", "", {[_player, _target] call FUNC(dropObject_carry)}, {[_player, _target] call FUNC(canDrop_carry)}, 2] call EFUNC(interact_menu,addClassAction); +_carryAction = [QGVAR(drag), localize "STR_ACE_Dragging_Carry", "", {[_player, _target] call FUNC(carryObject)}, {[_player, _target] call FUNC(canCarry)}] call EFUNC(interact_menu,createAction); +_dropAction = [QGVAR(drop), localize "STR_ACE_Dragging_Drop", "", {[_player, _target] call FUNC(dropObject_carry)}, {[_player, _target] call FUNC(canDrop_carry)}] call EFUNC(interact_menu,createAction); + +[_type, 0, ["ACE_MainActions"], _carryAction] call EFUNC(interact_menu,addActionToClass); +[_type, 0, ["ACE_MainActions"], _dropAction] call EFUNC(interact_menu,addActionToClass); diff --git a/addons/dragging/functions/fnc_setDraggable.sqf b/addons/dragging/functions/fnc_setDraggable.sqf index 82ebc201e2..b6e26a6f0a 100644 --- a/addons/dragging/functions/fnc_setDraggable.sqf +++ b/addons/dragging/functions/fnc_setDraggable.sqf @@ -48,5 +48,8 @@ if (_type in _initializedClasses) exitWith {}; _initializedClasses pushBack _type; GVAR(initializedClasses) = _initializedClasses; -[_type, 0, ["ACE_MainActions", QGVAR(drag)], localize "STR_ACE_Dragging_Drag", "", "", {[_player, _target] call FUNC(startDrag)}, {[_player, _target] call FUNC(canDrag)}, 2] call EFUNC(interact_menu,addClassAction); -[_type, 0, ["ACE_MainActions", QGVAR(drop)], localize "STR_ACE_Dragging_Drop", "", "", {[_player, _target] call FUNC(dropObject)}, {[_player, _target] call FUNC(canDrop)}, 2] call EFUNC(interact_menu,addClassAction); +_dragAction = [QGVAR(drag), localize "STR_ACE_Dragging_Drag", "", {[_player, _target] call FUNC(startDrag)}, {[_player, _target] call FUNC(canDrag)}] call EFUNC(interact_menu,createAction); +_dropAction = [QGVAR(drop), localize "STR_ACE_Dragging_Drop", "", {[_player, _target] call FUNC(dropObject)}, {[_player, _target] call FUNC(canDrop)}] call EFUNC(interact_menu,createAction); + +[_type, 0, ["ACE_MainActions"], _dragAction] call EFUNC(interact_menu,addActionToClass); +[_type, 0, ["ACE_MainActions"], _dropAction] call EFUNC(interact_menu,addActionToClass); From 66731c9cdd228570e92f8bbcb807dce029ae051e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Badano?= Date: Fri, 20 Mar 2015 00:53:58 -0300 Subject: [PATCH 10/14] First rough implementation of the passengers menu, with mounted main actions --- addons/interaction/CfgVehicles.hpp | 63 ++++++++++++++++--- addons/interaction/XEH_preInit.sqf | 2 + addons/interaction/config.cpp | 2 +- .../functions/fnc_addPassengerActions.sqf | 32 ++++++++++ .../functions/fnc_addPassengersActions.sqf | 43 +++++++++++++ addons/interaction/stringtable.xml | 3 + 6 files changed, 137 insertions(+), 8 deletions(-) create mode 100644 addons/interaction/functions/fnc_addPassengerActions.sqf create mode 100644 addons/interaction/functions/fnc_addPassengersActions.sqf diff --git a/addons/interaction/CfgVehicles.hpp b/addons/interaction/CfgVehicles.hpp index 1bd1e81be2..a3b6187c6c 100644 --- a/addons/interaction/CfgVehicles.hpp +++ b/addons/interaction/CfgVehicles.hpp @@ -412,7 +412,14 @@ class CfgVehicles { condition = "true"; }; }; - class ACE_SelfActions {}; + class ACE_SelfActions { + class ACE_Passengers { + displayName = "$STR_ACE_Interaction_Passengers"; + condition = "true"; + statement = ""; + insertChildren = QUOTE(_this call FUNC(addPassengersActions)); + }; + }; }; class Tank: LandVehicle { class ACE_Actions { @@ -423,7 +430,14 @@ class CfgVehicles { condition = "true"; }; }; - class ACE_SelfActions {}; + class ACE_SelfActions { + class ACE_Passengers { + displayName = "$STR_ACE_Interaction_Passengers"; + condition = "true"; + statement = ""; + insertChildren = QUOTE(_this call FUNC(addPassengersActions)); + }; + }; }; class Air; @@ -436,7 +450,14 @@ class CfgVehicles { condition = "true"; }; }; - class ACE_SelfActions {}; + class ACE_SelfActions { + class ACE_Passengers { + displayName = "$STR_ACE_Interaction_Passengers"; + condition = "true"; + statement = ""; + insertChildren = QUOTE(_this call FUNC(addPassengersActions)); + }; + }; }; class Plane: Air { class ACE_Actions { @@ -447,7 +468,14 @@ class CfgVehicles { condition = "true"; }; }; - class ACE_SelfActions {}; + class ACE_SelfActions { + class ACE_Passengers { + displayName = "$STR_ACE_Interaction_Passengers"; + condition = "true"; + statement = ""; + insertChildren = QUOTE(_this call FUNC(addPassengersActions)); + }; + }; }; class Ship; @@ -469,7 +497,14 @@ class CfgVehicles { }; }; }; - class ACE_SelfActions {}; + class ACE_SelfActions { + class ACE_Passengers { + displayName = "$STR_ACE_Interaction_Passengers"; + condition = "true"; + statement = ""; + insertChildren = QUOTE(_this call FUNC(addPassengersActions)); + }; + }; }; class StaticWeapon: LandVehicle { @@ -481,7 +516,14 @@ class CfgVehicles { condition = "true"; }; }; - class ACE_SelfActions {}; + class ACE_SelfActions { + class ACE_Passengers { + displayName = "$STR_ACE_Interaction_Passengers"; + condition = "true"; + statement = ""; + insertChildren = QUOTE(_this call FUNC(addPassengersActions)); + }; + }; }; class StaticMortar; @@ -494,7 +536,14 @@ class CfgVehicles { condition = "true"; }; }; - class ACE_SelfActions {}; + class ACE_SelfActions { + class ACE_Passengers { + displayName = "$STR_ACE_Interaction_Passengers"; + condition = "true"; + statement = ""; + insertChildren = QUOTE(_this call FUNC(addPassengersActions)); + }; + }; }; class thingX; diff --git a/addons/interaction/XEH_preInit.sqf b/addons/interaction/XEH_preInit.sqf index 6efa72778e..671535c36d 100644 --- a/addons/interaction/XEH_preInit.sqf +++ b/addons/interaction/XEH_preInit.sqf @@ -2,6 +2,8 @@ ADDON = false; +PREP(addPassengerActions); +PREP(addPassengersActions); PREP(addSelectableItem); PREP(applyButtons); PREP(canInteractWithCivilian); diff --git a/addons/interaction/config.cpp b/addons/interaction/config.cpp index a39e8f8bf5..d5d9d63d69 100644 --- a/addons/interaction/config.cpp +++ b/addons/interaction/config.cpp @@ -5,7 +5,7 @@ class CfgPatches { units[] = {}; weapons[] = {}; requiredVersion = REQUIRED_VERSION; - requiredAddons[] = {"ace_common"}; + requiredAddons[] = {"ace_interact_menu"}; author[] = {"commy2", "KoffeinFlummi", "CAA-Picard", "bux578"}; authorUrl = "https://github.com/commy2/"; VERSION_CONFIG; diff --git a/addons/interaction/functions/fnc_addPassengerActions.sqf b/addons/interaction/functions/fnc_addPassengerActions.sqf new file mode 100644 index 0000000000..83b702a98b --- /dev/null +++ b/addons/interaction/functions/fnc_addPassengerActions.sqf @@ -0,0 +1,32 @@ +/* + * Author: CAA-Picard + * Mount unit actions inside passenger submenu + * Note: This function is NOT global. + * + * Argument: + * 0: Vehicle + * 1: Player + * 3: Parameters + * + * Return value: + * Children actions + * + * Public: No + */ +#include "script_component.hpp" + +EXPLODE_3_PVT(_this,_vehicle,_player,_parameters); + +diag_log "addPassengerActions"; + +private ["_unit","_actions"]; +_unit = _parameters select 0; + +_varName = format [QEGVAR(interact_menu,Act_%1), typeOf _unit]; +_actionTrees = missionNamespace getVariable [_varName, []]; + +_actions = []; +// Mount unit MainActions menu +_actions pushBack (_actionTrees select 0); + +_actions diff --git a/addons/interaction/functions/fnc_addPassengersActions.sqf b/addons/interaction/functions/fnc_addPassengersActions.sqf new file mode 100644 index 0000000000..678cbc55db --- /dev/null +++ b/addons/interaction/functions/fnc_addPassengersActions.sqf @@ -0,0 +1,43 @@ +/* + * Author: CAA-Picard + * Create one action per passenger + * Note: This function is NOT global. + * + * Argument: + * 0: Vehicle + * 1: Player + * 3: Parameters + * + * Return value: + * Children actions + * + * Public: No + */ +#include "script_component.hpp" + +EXPLODE_3_PVT(_this,_vehicle,_player,_parameters); + +private ["_actions"]; +_actions = []; + +{ + _unit = _x; + if (_x != _player) then { + _actions pushBack + [ + [ + str(_unit), + [_unit, true] call EFUNC(common,getName), + "", + {systemChat "selected passenger"}, + {true}, + {_this call FUNC(addPassengerActions);}, + [_unit] + ] call EFUNC(interact_menu,createAction), + [], + _unit + ]; + }; +} forEach crew _vehicle; + +_actions \ No newline at end of file diff --git a/addons/interaction/stringtable.xml b/addons/interaction/stringtable.xml index 76898cd227..4b82908f2f 100644 --- a/addons/interaction/stringtable.xml +++ b/addons/interaction/stringtable.xml @@ -650,5 +650,8 @@ Interakcja Interactuar + + Passengers >> + From 3e69123454a4598084377a80856019fe6d2ac56d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Badano?= Date: Fri, 20 Mar 2015 00:55:13 -0300 Subject: [PATCH 11/14] Make collectActiveActionTree follow mounts correctly --- .../functions/fnc_collectActiveActionTree.sqf | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/addons/interact_menu/functions/fnc_collectActiveActionTree.sqf b/addons/interact_menu/functions/fnc_collectActiveActionTree.sqf index f4ae2ff5c1..36d4dc548d 100644 --- a/addons/interact_menu/functions/fnc_collectActiveActionTree.sqf +++ b/addons/interact_menu/functions/fnc_collectActiveActionTree.sqf @@ -17,7 +17,7 @@ EXPLODE_3_PVT(_this,_object,_origAction,_parentPath); EXPLODE_2_PVT(_origAction,_origActionData,_origActionChildren); -private ["_target","_player","_fullPath","_activeChildren","_action","_actionData","_x"]; +private ["_target","_player","_fullPath","_activeChildren","_dynamicChildren","_action","_actionData","_x"]; _target = _object; _player = ACE_player; @@ -27,15 +27,22 @@ if !([_target, ACE_player, _origActionData select 6] call (_origActionData selec [] }; +_fullPath = +_parentPath; +_fullPath pushBack (_origActionData select 0); _activeChildren = []; // If there's a statement to dynamically insert children then execute it if !({} isEqualTo (_origActionData select 5)) then { - _activeChildren = [_target, ACE_player, _origActionData select 6] call (_origActionData select 5); -}; + _dynamicChildren = [_target, ACE_player, _origActionData select 6] call (_origActionData select 5); -_fullPath = +_parentPath; -_fullPath pushBack (_origActionData select 0); + // Collect dynamic children class actions + { + _action = [_x select 2, _x, _fullPath] call FUNC(collectActiveActionTree); + if ((count _action) > 0) then { + _activeChildren pushBack _action; + }; + } forEach _dynamicChildren; +}; // Collect children class actions { From b3aa7c8970abcc69c5552f4a7723a0b907f5eed3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Badano?= Date: Fri, 20 Mar 2015 22:44:25 -0300 Subject: [PATCH 12/14] Make collectActiveActionTree follow mounts correctly --- .../functions/fnc_collectActiveActionTree.sqf | 17 ++++++++++++----- .../functions/fnc_addPassengerActions.sqf | 2 +- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/addons/interact_menu/functions/fnc_collectActiveActionTree.sqf b/addons/interact_menu/functions/fnc_collectActiveActionTree.sqf index f4ae2ff5c1..36d4dc548d 100644 --- a/addons/interact_menu/functions/fnc_collectActiveActionTree.sqf +++ b/addons/interact_menu/functions/fnc_collectActiveActionTree.sqf @@ -17,7 +17,7 @@ EXPLODE_3_PVT(_this,_object,_origAction,_parentPath); EXPLODE_2_PVT(_origAction,_origActionData,_origActionChildren); -private ["_target","_player","_fullPath","_activeChildren","_action","_actionData","_x"]; +private ["_target","_player","_fullPath","_activeChildren","_dynamicChildren","_action","_actionData","_x"]; _target = _object; _player = ACE_player; @@ -27,15 +27,22 @@ if !([_target, ACE_player, _origActionData select 6] call (_origActionData selec [] }; +_fullPath = +_parentPath; +_fullPath pushBack (_origActionData select 0); _activeChildren = []; // If there's a statement to dynamically insert children then execute it if !({} isEqualTo (_origActionData select 5)) then { - _activeChildren = [_target, ACE_player, _origActionData select 6] call (_origActionData select 5); -}; + _dynamicChildren = [_target, ACE_player, _origActionData select 6] call (_origActionData select 5); -_fullPath = +_parentPath; -_fullPath pushBack (_origActionData select 0); + // Collect dynamic children class actions + { + _action = [_x select 2, _x, _fullPath] call FUNC(collectActiveActionTree); + if ((count _action) > 0) then { + _activeChildren pushBack _action; + }; + } forEach _dynamicChildren; +}; // Collect children class actions { diff --git a/addons/interaction/functions/fnc_addPassengerActions.sqf b/addons/interaction/functions/fnc_addPassengerActions.sqf index 83b702a98b..d4a5da3788 100644 --- a/addons/interaction/functions/fnc_addPassengerActions.sqf +++ b/addons/interaction/functions/fnc_addPassengerActions.sqf @@ -27,6 +27,6 @@ _actionTrees = missionNamespace getVariable [_varName, []]; _actions = []; // Mount unit MainActions menu -_actions pushBack (_actionTrees select 0); +_actions pushBack [(_actionTrees select 0) select 0, (_actionTrees select 0) select 1, _unit]; _actions From 3d6660b115e65183793975b11a1774d8385a2e1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Badano?= Date: Fri, 20 Mar 2015 22:44:36 -0300 Subject: [PATCH 13/14] Debug stuff --- .../interact_menu/functions/fnc_renderBaseMenu.sqf | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/addons/interact_menu/functions/fnc_renderBaseMenu.sqf b/addons/interact_menu/functions/fnc_renderBaseMenu.sqf index da01fa804f..277f79c141 100644 --- a/addons/interact_menu/functions/fnc_renderBaseMenu.sqf +++ b/addons/interact_menu/functions/fnc_renderBaseMenu.sqf @@ -65,7 +65,18 @@ _activeActionTree = [ DFUNC(collectActiveActionTree), _object, _uid, 0.2 ] call EFUNC(common,cachedCall); - +/* +diag_log "Printing: _activeActionTree"; +_fnc_print = { + EXPLODE_2_PVT(_this,_level,_node); + EXPLODE_3_PVT(_node,_actionData,_children,_object); + diag_log text format ["Level %1 -> %2 on %3", _level, _actionData select 0, _object]; + { + [_level + 1, _x] call _fnc_print; + } forEach _children; +}; +[0, _activeActionTree] call _fnc_print; +*/ // Check if there's something left for rendering if (count _activeActionTree == 0) exitWith {false}; From 4a8b5079a602dd0f15b4d97dda6d29e29064e8dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Badano?= Date: Sat, 21 Mar 2015 09:37:01 -0300 Subject: [PATCH 14/14] Fix #211 --- addons/interact_menu/XEH_preInit.sqf | 1 + .../interact_menu/functions/fnc_isSubPath.sqf | 29 +++++++++++++++++++ addons/interact_menu/functions/fnc_render.sqf | 10 +++++-- .../interact_menu/functions/fnc_splitPath.sqf | 8 +++-- 4 files changed, 43 insertions(+), 5 deletions(-) create mode 100644 addons/interact_menu/functions/fnc_isSubPath.sqf diff --git a/addons/interact_menu/XEH_preInit.sqf b/addons/interact_menu/XEH_preInit.sqf index 478b5b578d..2b5150a0ea 100644 --- a/addons/interact_menu/XEH_preInit.sqf +++ b/addons/interact_menu/XEH_preInit.sqf @@ -9,6 +9,7 @@ PREP(compileMenuSelfAction); PREP(collectActiveActionTree); PREP(createAction); PREP(findActionNode); +PREP(isSubPath); PREP(keyDown); PREP(keyDownSelfAction); PREP(keyUp); diff --git a/addons/interact_menu/functions/fnc_isSubPath.sqf b/addons/interact_menu/functions/fnc_isSubPath.sqf new file mode 100644 index 0000000000..e90aa12300 --- /dev/null +++ b/addons/interact_menu/functions/fnc_isSubPath.sqf @@ -0,0 +1,29 @@ +/* + * Author: CAA-Picard + * Check if the first path is a subpath of the other + * + * Argument: + * 0: LongPath + * 1: ShortPath + * + * Return value: + * Bool + * + * Public: No + */ +#include "script_component.hpp" + +EXPLODE_2_PVT(_this,_longPath,_shortPath); + +private ["_isSubPath","_i"]; +_isSubPath = true; + +if (count _shortPath > count _longPath) exitWith {false}; + +for [{_i = 0},{_i < (count _shortPath) - 1},{_i = _i + 1}] do { + if !((_longPath select _i) isEqualTo (_shortPath select _i)) exitWith { + _isSubPath = false; + }; +}; + +_isSubPath diff --git a/addons/interact_menu/functions/fnc_render.sqf b/addons/interact_menu/functions/fnc_render.sqf index 922027e2a0..df97b232de 100644 --- a/addons/interact_menu/functions/fnc_render.sqf +++ b/addons/interact_menu/functions/fnc_render.sqf @@ -159,14 +159,18 @@ if(GVAR(keyDown) || GVAR(keyDownSelfAction)) then { } forEach GVAR(lastPath); }; - if(_misMatch) then { - GVAR(lastPath) = _hoverPath; + if(_misMatch && {diag_tickTime-GVAR(expandedTime) > 0.25}) then { GVAR(startHoverTime) = diag_tickTime; + GVAR(lastPath) = _hoverPath; GVAR(expanded) = false; } else { if(!GVAR(expanded) && diag_tickTime-GVAR(startHoverTime) > 0.25) then { GVAR(expanded) = true; - GVAR(expandedTime) = diag_tickTime; + + // Start the expanding menu animation only if the user is not going up the menu + if !([GVAR(menuDepthPath),GVAR(lastPath)] call FUNC(isSubPath)) then { + GVAR(expandedTime) = diag_tickTime; + }; GVAR(menuDepthPath) = +GVAR(lastPath); // Execute the current action if it's run on hover diff --git a/addons/interact_menu/functions/fnc_splitPath.sqf b/addons/interact_menu/functions/fnc_splitPath.sqf index 0bbe643adf..87140d0482 100644 --- a/addons/interact_menu/functions/fnc_splitPath.sqf +++ b/addons/interact_menu/functions/fnc_splitPath.sqf @@ -15,9 +15,13 @@ private ["_parentPath","_actionName"]; _parentPath = []; -for "_i" from 0 to (count _this) - 1 do { +for [{_i = 0},{_i < (count _this) - 1},{_i = _i + 1}] do { _parentPath pushBack (_this select _i); }; -_actionName = _this select ((count _this) - 1); +_actionName = if (count _this > 0) then { + _this select ((count _this) - 1); +} else { + "" +}; [_parentPath, _actionName]