mirror of
https://github.com/acemod/ACE3.git
synced 2024-08-30 18:23:18 +00:00
314 lines
13 KiB
Markdown
314 lines
13 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
|
|
|
|
### 2.1 Class interactions
|
|
|
|
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 |
|
|
|
|
### 2.2 Vehicle interactions based on animations
|
|
|
|
Some classes (usually vehicles) might have `AnimationSources` defined, which can hide/show e.g. spare wheels, ammo boxes, tools, doors etc. ACE offers a framework to be able to interact with those animations, which would allow players to e.g. remove the spare wheel from the vehicle, by hiding the spare wheel and spawning in a wheel object.
|
|
|
|
{% raw %}
|
|
```cpp
|
|
class Car_F;
|
|
class Offroad_01_base_F: Car_F {
|
|
class ace_interaction_anims {
|
|
class HideBackpacks { // Class name of the animation (has to be defined in 'AnimationSources' of the class, with scope > 0)
|
|
phase = 0; // The phase which is set after the action has successfully completed (default: 1)
|
|
// At least 1 selection or position must be defined, otherwise an error will be raised and the interaction not added
|
|
// Both selections[] and positions[] can be used at the same time
|
|
selections[] = {"vhc_bags"}; // Selections where to have the interaction appear, equivalent to "_target selectionPosition 'vhc_bags'" if put in positions[] (default: [])
|
|
positions[] = {{-1.15, -1.15, -0.2}, "_target selectionPosition ['vhc_bags', 'FireGeometry', 'AveragePoint']"}; // Positions where to have the interaction appear. It can either be model coordinates (in the array format) or a string containing code which returns model coordinates (default: [])
|
|
items[] = {"B_TacticalPack_blk", "ACE_Wheel", "ACE_EntrenchingTool"}; // Items to spawn in when the progress bar finishes successfully (default: [])
|
|
name = "$STR_a3_cfgvehicleclasses_backpacks0"; // Interaction name to display when interacting with the object (default: localised version of "Take it off")
|
|
icon = "\A3\ui_f\data\igui\cfg\actions\take_ca.paa"; // Interaction icon to display when interacting with the object (default: "\A3\ui_f\data\igui\cfg\actions\take_ca.paa")
|
|
text = "Removing backpacks..."; // Text to display in the progress bar (default: "")
|
|
duration = 10; // Sets the progress bar duration (default: 10 seconds)
|
|
distance = 2; // Sets at which distance the interactions can be accessed (default: 2)
|
|
enabled = 1; // Enables (1) or disables (0) the interaction (default: 1)
|
|
};
|
|
};
|
|
};
|
|
```
|
|
{% endraw %}
|
|
|
|
Individual animations can have the items they spawn in changed dynamically using a variable. If you set the items to `[]`, it will disable the interaction from completing (the progress bar will play, but once it reaches the end, it will stop and fail):
|
|
```sqf
|
|
_target setVariable [format ["ace_interaction_animsItems_%1", _anim], ["B_TacticalPack_blk"], true];
|
|
|
|
// To disable the interaction from the example above
|
|
_target setVariable ["ace_interaction_animsItems_HideBackpacks", [], true];
|
|
```
|
|
|
|
## 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;
|
|
```
|