mirror of
https://github.com/acemod/ACE3.git
synced 2024-08-30 18:23:18 +00:00
f4f2dbaad9
* Interaction Exceptions * Additional Action Parameters
276 lines
11 KiB
Markdown
276 lines
11 KiB
Markdown
---
|
|
layout: wiki
|
|
title: Interaction Menu Framework
|
|
description: Explains how to add items to ACE's Interaction Menu.
|
|
group: framework
|
|
order: 0
|
|
parent: wiki
|
|
mod: ace
|
|
version:
|
|
major: 3
|
|
minor: 0
|
|
patch: 0
|
|
---
|
|
|
|
## 1. Types of actions
|
|
|
|
- **External** (Type 0 / `ACE_Actions`)
|
|
Something the user would do to an external object (eg. Tap another unit's shoulder)
|
|
- **Self** (Type 1 / `ACE_SelfActions`)
|
|
Something the user would do to themselves or to their vehicle (eg. Put in ear plugs / Check mounted Static Weapon's ammo)
|
|
- **Zeus** (`ACE_ZeusActions`)
|
|
Available to Zeus
|
|
|
|
`ACE_Actions` and `ACE_SelfActions` can be added via config or by calling functions. Be aware that the functions modify the UI, and therefore need to be executed on client-side to take effect.
|
|
|
|
The simplest action is just a condition and statement. The code to these are passed `[_target, _player, _actionParams]`. `_player` is `ace_player`; `_target` is the object being interacted with; and the 3rd argument is the optional action parameters (default `[]`).
|
|
|
|
## 2. Adding actions via config
|
|
|
|
Example:
|
|
|
|
```cpp
|
|
class CfgVehicles {
|
|
class Man;
|
|
class CAManBase: Man {
|
|
class ACE_SelfActions {
|
|
class danceParty {
|
|
displayName = "dance";
|
|
condition = "[_player] call onDanceFloor";
|
|
exceptions[] = {};
|
|
statement = "_player switchMove 'TestDance'";
|
|
icon = "\z\dance.paa";
|
|
};
|
|
};
|
|
};
|
|
};
|
|
```
|
|
|
|
| Config Name | Type | Description |
|
|
| ---------- | ----------- | ------------------- |
|
|
| `displayName` | String | Text shown to user |
|
|
| `condition` | String (of code) | Condition to show the action |
|
|
| `statement` | String (of code) | Statement run when selected |
|
|
| `icon` | String (file path) | Icon shown (OPTIONAL) |
|
|
| `exceptions` | Array (of strings) | Exceptions to `canInteractWith` conditions (e.g. `"notOnMap"`) (OPTIONAL) |
|
|
| `insertChildren` | String (of code) | Code to return sub actions (OPTIONAL) |
|
|
| `modifierFunction` | String (of code) | Code to modify this action (OPTIONAL) |
|
|
| `runOnHover` | Number or String | (1=true) OR Condition code - Will run the statement on hover (OPTIONAL) |
|
|
| `distance` | Number | External Base Actions Only, Max distance player can be from action point |
|
|
| `position` | String (of code) | External Base Actions Only, Code to return a position in model cords (priority over `selection`) |
|
|
| `selection` | String | External Base Actions Only, A memory point for `selectionPosition` |
|
|
| `doNotCheckLOS` | Number | (1=true) - Ignores blocked LOS to the interaction node even when beyond 1.2m |
|
|
| `showDisabled` | Number | Currently has no effect |
|
|
| `enableInside` | Number | Currently has no effect |
|
|
| `canCollapse` | Number | Currently has no effect |
|
|
|
|
Actions can be inserted anywhere on the config tree, e.g. hearing's earplugs is a sub action of `ACE_Equipment`:
|
|
|
|
```cpp
|
|
class CAManBase: Man {
|
|
class ACE_SelfActions {
|
|
class ACE_Equipment {
|
|
class ACE_PutInEarplugs {};
|
|
};
|
|
};
|
|
};
|
|
```
|
|
|
|
Interaction exceptions are defined by several components:
|
|
|
|
| Component | Exception | Description |
|
|
| ---------- | ----------- | ------------------- |
|
|
| `captives` | `"isNotEscorting"` | Can interact while escorting a captive |
|
|
| | `"isNotHandcuffed"` | Can interact while handcuffed |
|
|
| | `"isNotSurrendering"` | Can interact while surrendering |
|
|
| `common` | `"isNotDead"` | Can interact while dead |
|
|
| | `"notOnMap"` | Can interact while in Map |
|
|
| | `"isNotInside"` | Can interact while inside a vehicle |
|
|
| | `"isNotInZeus"` | Can interact while in the zeus interface |
|
|
| | `"isNotUnconscious"` | Can interact while unconscious |
|
|
| `dragging` | `"isNotDragging"` | Can interact while dragging |
|
|
| | `"isNotCarrying"` | Can interact while carrying |
|
|
| `interaction` | `"isNotSwimming"` | Can interact while swimming/diving |
|
|
| | `"isNotOnLadder"` | Can interact while climbing a ladder |
|
|
| `refuel` | `"isNotRefueling"` | Can interact while carrying refueling nozzle |
|
|
| `sitting` | `"isNotSitting"` | Can interact while sitting in a chair |
|
|
|
|
## 3. Adding actions via scripts
|
|
|
|
Two steps, creating an action (array) and then adding it to either a class or object.
|
|
Important: `ace_common_fnc_canInteractWith` is not automatically checked and needs to be explicitly called.
|
|
|
|
### 3.1 fnc_createAction
|
|
|
|
`ace_interact_menu_fnc_createAction`
|
|
|
|
```sqf
|
|
/*
|
|
* 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 array, Position code or Selection Name) <ARRAY>, <CODE> or <STRING> (Optional)
|
|
* 8: Distance <NUMBER> (Optional)
|
|
* 9: Other parameters [showDisabled,enableInside,canCollapse,runOnHover,doNotCheckLOS] <ARRAY> (Optional)
|
|
* 10: Modifier function <CODE> (Optional)
|
|
*/
|
|
```
|
|
|
|
### 3.2 fnc_addActionToClass
|
|
|
|
`ace_interact_menu_fnc_addActionToClass`
|
|
|
|
```sqf
|
|
/*
|
|
* 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>
|
|
* 4: Use Inheritance (Default: False) <BOOL><OPTIONAL>
|
|
* 5: Classes excluded from inheritance (children included) (Default: []) <ARRAY><OPTIONAL>
|
|
*/
|
|
```
|
|
By default this function will not use inheritance, so actions will only be added to the specific class.
|
|
|
|
### 3.3 fnc_addActionToObject
|
|
|
|
`ace_interact_menu_fnc_addActionToObject`
|
|
|
|
```sqf
|
|
/*
|
|
* 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> (Example: `["ACE_SelfActions", "ACE_Equipment"]`)
|
|
* 3: Action <ARRAY>
|
|
*/
|
|
```
|
|
|
|
### 3.4 fnc_addActionToZeus
|
|
|
|
`ace_interact_menu_fnc_addActionToZeus`
|
|
|
|
```sqf
|
|
/*
|
|
* Argument:
|
|
* 0: Parent path of the new action <ARRAY> (Example: `["ACE_ZeusActions"]`)
|
|
* 1: Action <ARRAY>
|
|
*/
|
|
```
|
|
|
|
### 3.5 Examples
|
|
|
|
External:
|
|
|
|
```sqf
|
|
_action = ["VulcanPinch","Vulcan Pinch","",{_target setDamage 1;},{true},{},[parameters], [0,0,0], 100] call ace_interact_menu_fnc_createAction;
|
|
[cursorTarget, 0, ["ACE_TapShoulderRight"], _action] call ace_interact_menu_fnc_addActionToObject;
|
|
```
|
|
|
|
Self:
|
|
|
|
```sqf
|
|
_condition = {
|
|
(!pabst_radioFinder_on) && {(backpack _player) in pabst_radioFinder_backpacks} && {[_player, _target, []] call ace_common_fnc_canInteractWith}
|
|
};
|
|
_statement = {
|
|
[true] call pabst_fnc_radioFinder_action;
|
|
};
|
|
_action = ["Open RDF","Radio Direction Finder","pabst\RDF.jpg",_statement,_condition] call ace_interact_menu_fnc_createAction;
|
|
[(typeOf _unit), 1, ["ACE_SelfActions"], _action] call ace_interact_menu_fnc_addActionToClass;
|
|
```
|
|
|
|
Using `addActionToClass` inheritance:
|
|
|
|
```sqf
|
|
// Adds action to check fuel levels for all land vehicles
|
|
_action = ["CheckFuel", "Check Fuel", "", {hint format ["Fuel: %1", fuel _target]}, {true}] call ace_interact_menu_fnc_createAction;
|
|
["LandVehicle", 0, ["ACE_MainActions"], _action, true] call ace_interact_menu_fnc_addActionToClass;
|
|
|
|
// Same as above, but children of "MRAP_01_Base" will not have the action
|
|
_action = ["CheckFuel", "Check Fuel", "", {hint format ["Fuel: %1", fuel _target]}, {true}] call ace_interact_menu_fnc_createAction;
|
|
["LandVehicle", 0, ["ACE_MainActions"], _action, true, ["MRAP_01_Base"]] call ace_interact_menu_fnc_addActionToClass;
|
|
|
|
// Adds action to check external fuel levels on tanks. Will be a sub action of the previous action.
|
|
_action = ["CheckExtTank","Check External Tank","",{hint format ["Ext Tank: %1", 5]},{true}] call ace_interact_menu_fnc_createAction;
|
|
["Tank_F", 0, ["ACE_MainActions", "CheckFuel"], _action, true] call ace_interact_menu_fnc_addActionToClass;
|
|
```
|
|
|
|
Zeus:
|
|
|
|
```sqf
|
|
_statement = {
|
|
playSound3D ["alarm.ogg", theBase]
|
|
};
|
|
_action = ["myMissionEvent1","Mission Event: Play Base Alarm","",_statement,{true}] call ace_interact_menu_fnc_createAction;
|
|
[["ACE_ZeusActions"], _action] call ace_interact_menu_fnc_addActionToZeus;
|
|
```
|
|
|
|
### 3.6 Advanced Example
|
|
|
|
This adds an interaction to a unit that allows passing items that the player is carrying.
|
|
|
|
- The child actions are generated dynamically based on the items in the player's inventory.
|
|
- The parent action's display name is modified based on the item count.
|
|
- When hovering on the action, a hint text is sent to the target.
|
|
|
|
```sqf
|
|
_condition = {
|
|
true
|
|
};
|
|
_statement = {
|
|
params ["_target", "_player", "_params"];
|
|
diag_log format ["_statement [%1, %2, %3]", _target, _player, _params];
|
|
|
|
// Run on hover:
|
|
["ace_common_displayTextStructured", ["someone is thinking of giving you items", 1.5, _target], [_target]] call CBA_fnc_targetEvent;
|
|
};
|
|
_insertChildren = {
|
|
params ["_target", "_player", "_params"];
|
|
diag_log format ["_insertChildren [%1, %2, %3]", _target, _player, _params];
|
|
|
|
// Add children to this action
|
|
private _actions = [];
|
|
{
|
|
private _childStatement = {diag_log format ["givingItem %1", _this]; _target addItem (_this select 2);};
|
|
private _action = [format ["item:%1",_x], _x, "", _childStatement, {true}, {}, _x] call ace_interact_menu_fnc_createAction;
|
|
_actions pushBack [_action, [], _target]; // New action, it's children, and the action's target
|
|
} forEach (items _player);
|
|
|
|
_actions
|
|
};
|
|
_modifierFunc = {
|
|
params ["_target", "_player", "_params", "_actionData"];
|
|
diag_log format ["_modifierFunc [%1, %2, %3]", _target, _player, _params];
|
|
|
|
// Modify the action - index 1 is the display name, 2 is the icon...
|
|
_actionData set [1, format ["Give Items: %1", count (items player)]];
|
|
};
|
|
|
|
_action = ["GiveItems", "?","",_statement,_condition,_insertChildren,[123],"",4,[false, false, false, true, false], _modifierFunc] call ace_interact_menu_fnc_createAction;
|
|
[q3, 0, ["ACE_MainActions"], _action] call ace_interact_menu_fnc_addActionToObject;
|
|
```
|
|
|
|
### 3.7 Using `ace_interact_menu_newControllableObject` event
|
|
|
|
CBA event `ace_interact_menu_newControllableObject` fires only once the first time the player controls a new object (new man, vehicle or controlled UAV)
|
|
This is the ideal way to add self interaction actions, as adding them via `addActionToClass` will force self interaction actions to be compiled for classes that may never be used.
|
|
|
|
```sqf
|
|
// Example: Add radio self-action to all civilian cars
|
|
["ace_interact_menu_newControllableObject", {
|
|
params ["_type"]; // string of the object's classname
|
|
if (!(_type isKindOf "Car")) exitWith {};
|
|
if ((getNumber (configFile >> "CfgVehicles" >> _type >> "side")) != 3) exitWith {};
|
|
|
|
private _action = ["playRadio","Play Radio","",{playMusic "NeverGonnaGiveYouUp"},{true}] call ace_interact_menu_fnc_createAction;
|
|
[_type, 1, ["ACE_SelfActions"], _action, true] call ace_interact_menu_fnc_addActionToClass;
|
|
}] call CBA_fnc_addEventHandler;
|
|
```
|