Merge branch 'master' of github.com:KoffeinFlummi/ACE3

This commit is contained in:
Nicolás Badano 2015-03-21 10:24:01 -03:00
commit f5f91c4802
45 changed files with 1045 additions and 775 deletions

View File

@ -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);

View File

@ -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);

View File

@ -2,21 +2,25 @@
ADDON = false;
PREP(addAction);
PREP(addClassAction);
PREP(addActionToClass);
PREP(addActionToObject);
PREP(compileMenu);
PREP(compileMenuSelfAction);
PREP(collectActiveActionTree);
PREP(createAction);
PREP(findActionNode);
PREP(isSubPath);
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;

View File

@ -1,59 +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 <OBJECT>
* 1: Type of action, 0 for actions, 1 for self-actions <NUMBER>
* 2: Full path of the new action <ARRAY>
* 3: Name of the action shown in the menu <STRING>
* 4: Icon <STRING>
* 5: Position (Position or Selection Name) <POSITION> or <STRING>
* 6: Statement <CODE>
* 7: Condition <CODE>
* 8: Distance <NUMBER>
* 9: Other parameters <ARRAY> (Optional)
*
* Return value:
* The entry full path, which can be used to remove the entry, or add children entries <ARRAY>.
*
* 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","_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;
};
_entry = [
[
_displayName,
_icon,
_position,
_statement,
_condition,
_distance,
_params,
+ _fullPath
],
[]
];
_actions pushBack _entry;
_fullPath

View File

@ -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 <STRING>
* 1: Type of action, 0 for actions, 1 for self-actions <NUMBER>
* 2: Parent path of the new action <ARRAY>
* 3: Action <ARRAY>
*
* Return value:
* The entry full path, which can be used to remove the entry, or add children entries <ARRAY>.
*
* 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)

View File

@ -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 <OBJECT>
* 1: Type of action, 0 for actions, 1 for self-actions <NUMBER>
* 2: Parent path of the new action <ARRAY>
* 3: Action <ARRAY>
*
* Return value:
* The entry full path, which can be used to remove the entry, or add children entries <ARRAY>.
*
* 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)

View File

@ -1,94 +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 <STRING>
* 1: Type of action, 0 for actions, 1 for self-actions <NUMBER>
* 2: Full path of the new action <ARRAY>
* 3: Name of the action shown in the menu <STRING>
* 4: Icon <STRING>
* 5: Position (Position or Selection Name) <POSITION> or <STRING>
* 6: Statement <CODE>
* 7: Condition <CODE>
* 8: Distance <NUMBER>
* 9: Other parameters <ARRAY> (Optional)
*
* Return value:
* The entry full path, which can be used to remove the entry, or add children entries <ARRAY>.
*
* 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","_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;
};
// 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
],
[]
];
_parentLevel pushBack _entry;
_fullPath

View File

@ -5,6 +5,7 @@
* Argument:
* 0: Object <OBJECT>
* 1: Original action tree <ARRAY>
* 2: Parent path <ARRAY>
*
* Return value:
* Active children <ARRAY>
@ -13,24 +14,39 @@
*/
#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","_dynamicChildren","_action","_actionData","_x"];
_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 6] call (_origActionData select 4)) exitWith {
[]
};
_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 {
_dynamicChildren = [_target, ACE_player, _origActionData select 6] call (_origActionData select 5);
// 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
{
_action = [_object, _x] call FUNC(collectActiveActionTree);
_action = [_object, _x, _fullPath] call FUNC(collectActiveActionTree);
if ((count _action) > 0) then {
_activeChildren pushBack _action;
};
@ -38,26 +54,15 @@ _activeChildren = [];
// 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);
@ -69,4 +74,5 @@ if ((count _activeChildren) == 0 && ((_origActionData select 3) isEqualTo {})) e
[]
};
[_origActionData, _activeChildren]
[_origActionData, _activeChildren, _object]

View File

@ -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"];
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 {
@ -48,27 +48,28 @@ _recurseFnc = {
// Add canInteract (including exceptions) and canInteractWith to condition
_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;
_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,
_insertChildren,
[],
_selection,
_distance,
[_showDisabled,_enableInside,_canCollapse,_runOnHover],
_fullPath
[_showDisabled,_enableInside,_canCollapse,_runOnHover]
],
_children
];
@ -81,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]
]

View File

@ -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"];
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 {
@ -45,27 +45,28 @@ _recurseFnc = {
// Add canInteract (including exceptions) and canInteractWith to condition
_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;
_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,
_insertChildren,
[],
[0,0,0],
10, //distace
[_showDisabled,_enableInside,_canCollapse,_runOnHover],
_fullPath
[_showDisabled,_enableInside,_canCollapse,_runOnHover]
],
_children
];
@ -82,16 +83,18 @@ _actionsCfg = configFile >> "CfgVehicles" >> _objectType >> "ACE_SelfActions";
_actions = [
[
[
"ACE_SelfActions",
"Self Actions",
"\a3\ui_f\data\IGUI\Cfg\Actions\eject_ca.paa",
{},
{ true },
{},
[],
"Spine3",
{ true },
{ true },
10,
[false,true,false],
["ACE_SelfActions"]
[false,true,false]
],
[_actionsCfg, ["ACE_SelfActions"]] call _recurseFnc
[_actionsCfg] call _recurseFnc
]
];

View File

@ -0,0 +1,74 @@
/*
* Author: CAA-Picard
* Creates an isolated ACE action
* Note: This function is NOT global.
*
* Argument:
* 0: Action name <STRING>
* 1: Name of the action shown in the menu <STRING>
* 2: Icon <STRING>
* 3: Statement <CODE>
* 4: Condition <CODE>
* 5: Insert children code <CODE> (Optional)
* 6: Action parameters <ANY> (Optional)
* 7: Position (Position or Selection Name) <POSITION> or <STRING> (Optional)
* 8: Distance <NUMBER> (Optional)
* 9: Other parameters <ARRAY> (Optional)
*
* Return value:
* Action <ARRAY>
*
* Example:
* [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_5_PVT(_this,_actionName,_displayName,_icon,_statement,_condition);
private ["_insertChildren","_customParams","_position","_distance","_params"];
_insertChildren = if (count _this > 5) then {
_this select 5
} else {
{}
};
_customParams = if (count _this > 6) then {
_this select 6
} else {
[]
};
_position = if (count _this > 7) then {
_this select 7
} else {
[0,0,0]
};
_distance = if (count _this > 8) then {
_this select 8
} else {
2
};
_params = if (count _this > 9) then {
_this select 9
} else {
[false,false,false,false]
};
[
_actionName,
_displayName,
_icon,
_statement,
_condition,
_insertChildren,
_customParams,
_position,
_distance,
_params
]

View File

@ -0,0 +1,56 @@
/*
* Author: CAA-Picard
* Return action point from path
* Note: This function is NOT global.
*
* Argument:
* 0: List of Action Tree <ARRAY>
* 1: Path <ARRAY>
*
* Return value:
* Action node <ARRAY>.
*
* 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

View File

@ -0,0 +1,29 @@
/*
* Author: CAA-Picard
* Check if the first path is a subpath of the other
*
* Argument:
* 0: LongPath <ARRAY>
* 1: ShortPath <STRING>
*
* 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

View File

@ -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 6] call GVAR(selectedStatement);
};
if (GVAR(keyDown)) then {

View File

@ -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 6] call GVAR(selectedStatement);
};
if (GVAR(keyDownSelfAction)) then {

View File

@ -0,0 +1,39 @@
/*
* Author: CAA-Picard
* Removes an action from a class
*
* Argument:
* 0: TypeOf of the class <STRING>
* 1: Type of action, 0 for actions, 1 for self-actions <NUMBER>
* 2: Full path of the new action <ARRAY>
*
* 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;

View File

@ -1,30 +1,33 @@
/*
* Author: commy2, NouberNou and CAA-Picard
* Remove an action from an object
*
* Argument:
* 0: Object the action is assigned to <OBJECT>
* 1: Type of action, 0 for actions, 1 for self-actions <NUMBER>
* 2: Full path of the action to remove <ARRAY>
*
* 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 <OBJECT>
* 1: Type of action, 0 for actions, 1 for self-actions <NUMBER>
* 2: Full path of the action to remove <ARRAY>
*
* 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;

View File

@ -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 <STRING>
* 1: Type of action, 0 for actions, 1 for self-actions <NUMBER>
* 2: Full path of the new action <ARRAY>
*
* 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;

View File

@ -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
@ -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,30 +153,34 @@ 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);
};
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
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);
};
};
};

View File

@ -4,7 +4,7 @@
*
* Argument:
* 0: Object <OBJECT>
* 1: Action data <ARRAY>
* 1: Action node <ARRAY>
* 2: 3D position <ARRAY> (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,19 +59,29 @@ 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);
/*
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};
//EXPLODE_2_PVT(_activeActionTree,_actionData,_actionChildren);
[_object, _activeActionTree, _pos, [180,360]] call FUNC(renderMenu);
[[], _activeActionTree, _pos, [180,360]] call FUNC(renderMenu);
true

View File

@ -3,7 +3,7 @@
* Render an interaction menu and it's children recursively
*
* Argument:
* 0: Object <OBJECT>
* 0: Parent path <ARRAY>
* 1: Action data <ARRAY>
* 2: 3D position <ARRAY>
* 3: Angle range available for rendering <ARRAY>
@ -17,14 +17,15 @@
private ["_menuInSelectedPath", "_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));
// Store path to action
_path = [_object] + (_actionData select 7);
_path = +_parentPath;
_path pushBack [_actionData select 0,_actionObject];
// Check if the menu is on the selected path
_menuInSelectedPath = true;
@ -32,7 +33,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;
@ -47,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];
@ -83,7 +84,7 @@ if (_menuInSelectedPath && (_menuDepth == count _path)) then {
_angle = _centerAngle - _angleSpan / 2;
{
_target = _object;
_target = _actionObject;
_player = ACE_player;
_offset = ((GVAR(refSystem) select 1) vectorMultiply (-_scale * cos _angle)) vectorAdd
@ -92,7 +93,7 @@ _angle = _centerAngle - _angleSpan / 2;
//drawLine3D [_pos, _newPos, [1,0,0,0.8]];
[_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);

View File

@ -0,0 +1,27 @@
/*
* Author: CAA-Picard
* Take full path and split it between parent path and action name
*
* Argument:
* Full path of the action to remove <ARRAY>
*
* Return value:
* 0: Parent path <ARRAY>
* 1: Action name <STRING>
*
* Public: No
*/
#include "script_component.hpp"
private ["_parentPath","_actionName"];
_parentPath = [];
for [{_i = 0},{_i < (count _this) - 1},{_i = _i + 1}] do {
_parentPath pushBack (_this select _i);
};
_actionName = if (count _this > 0) then {
_this select ((count _this) - 1);
} else {
""
};
[_parentPath, _actionName]

View File

@ -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;

View File

@ -2,6 +2,8 @@
ADDON = false;
PREP(addPassengerActions);
PREP(addPassengersActions);
PREP(addSelectableItem);
PREP(applyButtons);
PREP(canInteractWithCivilian);

View File

@ -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;

View File

@ -0,0 +1,32 @@
/*
* Author: CAA-Picard
* Mount unit actions inside passenger submenu
* Note: This function is NOT global.
*
* Argument:
* 0: Vehicle <OBJECT>
* 1: Player <OBJECT>
* 3: Parameters <ARRAY>
*
* Return value:
* Children actions <ARRAY>
*
* 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) select 0, (_actionTrees select 0) select 1, _unit];
_actions

View File

@ -0,0 +1,43 @@
/*
* Author: CAA-Picard
* Create one action per passenger
* Note: This function is NOT global.
*
* Argument:
* 0: Vehicle <OBJECT>
* 1: Player <OBJECT>
* 3: Parameters <ARRAY>
*
* Return value:
* Children actions <ARRAY>
*
* 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

View File

@ -650,5 +650,8 @@
<Polish>Interakcja</Polish>
<Spanish>Interactuar</Spanish>
</Key>
<Key ID="STR_ACE_Interaction_Passengers">
<English>Passengers &gt;&gt;</English>
</Key>
</Package>
</Project>

View File

@ -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););
};
};
};

View File

@ -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;
};
};

View File

@ -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.<br/>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.<br/>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.<br/>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.<br/>Source: vehiclelock.pbo";
sync[] = {"AnyPlayer", "AnyVehicle"};
};
};
};
};

View File

@ -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));
};
};

View File

@ -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);

View File

@ -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;

View File

@ -17,6 +17,10 @@ class ACE_Settings {
value = 10;
typeName = "SCALAR";
};
class GVAR(LockVehicleInventory) {
value = 0;
typeName = "BOOL";
};
};
#include "CfgEventHandlers.hpp"

View File

@ -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 <OBJECT>
* 1: Vehicle <OBJECT>
* 2: custom key (true: custom key (magazine) - false: side key (item)) <BOOL>
*
* 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
};

View File

@ -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 <OBJECT>
*
* Return Value:
* The vehicle's side key classname <STRING>
*
* 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

View File

@ -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 <OBJECT>
* 1: Vehicle <OBJECT>
*
* Return Value:
* unit has key for vehicle <BOOL>
*
* 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

View File

@ -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) <OBJECT>
* 1: Vehicle <OBJECT>
* 2: Function Type <OBJECT>
*
* Return Value:
* "canLockpick" <BOOL>
*
* 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

View File

@ -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 <OBJECT>
* 1: synced objects <ARRAY>
* 2: Activated <BOOL>
*
* 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);

View File

@ -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 <OBJECT>
* 1: synced objects <ARRAY>
* 2: Activated <BOOL>
*
* 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);

View File

@ -0,0 +1,40 @@
/*
* Author: PabstMirror
* Handles the inventory opening.
*
* Arguments:
* 0: Unit <OBJECT>
* 1: Container <OBJECT>
*
* Return Value:
* Handeled <BOOL>
*
* 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

View File

@ -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 <OBJECT>
* 1: Magazine Name <STRING>
*
* 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), []];

View File

@ -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 <OBJECT>
* 1: New lock state <BOOL>
*
* 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

View File

@ -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 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:
@ -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