Modded Keybinding – Arma 3

From Bohemia Interactive Community
Jump to navigation Jump to search
m (Remove dot in title)
(Add link to DIK KeyCodes and explanatory table)
 
(16 intermediate revisions by 5 users not shown)
Line 1: Line 1:
Update {{GVI|arma3|2.06}} allows for mods to define keys that can be bound by the user in their keybindings.
{{TOC|side}}
As of {{GVI|arma3|2.06}}, mods are able to define keys that can be bound by the user in the keybindings.


<syntaxhighlight lang="cpp">
<syntaxhighlight lang="cpp">
class CfgUserActions
class CfgUserActions
{
{
class Mod_MyActionName // name, also used for inputAction script command and for internal representation
class TAG_MyActionName // This class name is used for internal representation and also for the inputAction command.
{
{
displayName = "";
displayName = "";
tooltip = "";
tooltip = "";
onActivate = "['Mod_MyActionName', true] call Mod_Myhandler"; // _this is always true
onActivate = "['TAG_MyActionName', true] call TAG_fnc_MyHandler"; // _this is always true.
onDeactivate = "['Mod_MyActionName', false] call Mod_Myhandler"; // _this is always false
onDeactivate = "['TAG_MyActionName', false] call TAG_fnc_MyHandler"; // _this is always false.
onAnalog = "['Mod_MyActionName', _this] call Mod_MyAnalogHandler"; // _this is the scalar analog value
onAnalog = "['TAG_MyActionName', _this] call TAG_fnc_MyAnalogHandler"; // _this is the scalar analog value.
analogChangeThreshold = 0.01; // minimum change required to trigger onAnalog EH, default 0.01
analogChangeThreshold = 0.01; // Minimum change required to trigger the onAnalog EH (default: 0.01).
}
modifierBlocking = 1; // Whether this action would block other actions if the assigned key has modifier keys on it. (Since Arma 2.12)
}
};
};
</syntaxhighlight>
</syntaxhighlight>


== Key combination enumerations ==
 
== Key Combination Enumerations ==


<syntaxhighlight lang="cpp">
<syntaxhighlight lang="cpp">
// Secondary combo types
// Secondary combo types:
#define INPUT_DEVICE_COMBO_KB 0x00100000 // keyboard button (key)
#define INPUT_DEVICE_COMBO_KB 0x00100000 // Keyboard button (key)
#define INPUT_DEVICE_COMBO_MB 0x00300000 // mouse button
#define INPUT_DEVICE_COMBO_MB 0x00300000 // Mouse button
#define INPUT_DEVICE_COMBO_JB 0x00500000 // joystick button
#define INPUT_DEVICE_COMBO_JB 0x00500000 // Joystick button
#define INPUT_DEVICE_COMBO_JP 0x00600000 // joystick POV
#define INPUT_DEVICE_COMBO_JP 0x00600000 // Joystick POV
#define INPUT_DEVICE_COMBO_XI 0x00900000 // XBox controller (XInput)
#define INPUT_DEVICE_COMBO_XI 0x00900000 // Xbox controller (XInput)


// Main combo types
// Main combo types:
#define INPUT_DEVICE_MAIN_MB 0x00010000 // mouse button
#define INPUT_DEVICE_MAIN_MB 0x00010000 // Mouse button
#define INPUT_DEVICE_MAIN_MA 0x00020000 // mouse axis
#define INPUT_DEVICE_MAIN_MA 0x00020000 // Mouse axis
#define INPUT_DEVICE_MAIN_KB 0x00030000 // keyboard button (key)
#define INPUT_DEVICE_MAIN_KB 0x00030000 // Keyboard button (key)
#define INPUT_DEVICE_MAIN_JB 0x00040000 // joystick button
#define INPUT_DEVICE_MAIN_JB 0x00040000 // Joystick button
#define INPUT_DEVICE_MAIN_JA 0x00050000 // joystick axis
#define INPUT_DEVICE_MAIN_JA 0x00050000 // Joystick axis
#define INPUT_DEVICE_MAIN_JP 0x00060000 // joystick POV
#define INPUT_DEVICE_MAIN_JP 0x00060000 // Joystick POV
#define INPUT_DEVICE_MAIN_XI 0x00070000 // XBox controller (XInput)
#define INPUT_DEVICE_MAIN_XI 0x00070000 // Xbox controller (XInput)
#define INPUT_DEVICE_MAIN_TR 0x00080000 // movement tracking device
#define INPUT_DEVICE_MAIN_TR 0x00080000 // Movement tracking device


// Device types
// Device types:
#define INPUT_DEVICE_SOLO_KB 0x00000000 // keyboard button (key)
#define INPUT_DEVICE_SOLO_KB 0x00000000 // Keyboard button (key)
#define INPUT_DEVICE_SOLO_MB 0x00010000 // mouse button
#define INPUT_DEVICE_SOLO_MB 0x00010000 // Mouse button
#define INPUT_DEVICE_SOLO_JB 0x00020000 // stick button
#define INPUT_DEVICE_SOLO_JB 0x00020000 // Stick button
#define INPUT_DEVICE_SOLO_JA 0x00030000 // stick axis
#define INPUT_DEVICE_SOLO_JA 0x00030000 // Stick axis
#define INPUT_DEVICE_SOLO_JP 0x00040000 // stick POV
#define INPUT_DEVICE_SOLO_JP 0x00040000 // Stick POV
#define INPUT_DEVICE_SOLO_XI 0x00050000 // XInput device
#define INPUT_DEVICE_SOLO_XI 0x00050000 // XInput device
#define INPUT_DEVICE_SOLO_TR 0x00080000 // eyexTracker, trackIR, freeTrack, ... exclusive, in this preference
#define INPUT_DEVICE_SOLO_TR 0x00080000 // EyeXTracker, TrackIR, FreeTrack, ... exclusive, in this preference
#define INPUT_DEVICE_SOLO_MA 0x00100000 // mouse axis
#define INPUT_DEVICE_SOLO_MA 0x00100000 // Mouse axis
</syntaxhighlight>
</syntaxhighlight>


Line 57: Line 60:
MOUSE_BUTTONS_CUSTOM_3 = 5,
MOUSE_BUTTONS_CUSTOM_3 = 5,
MOUSE_BUTTONS_CUSTOM_4 = 6,
MOUSE_BUTTONS_CUSTOM_4 = 6,
MOUSE_BUTTONS_CUSTOM_5 = 7,
MOUSE_BUTTONS_CUSTOM_5 = 7
};
};


#define INPUT_DOUBLE_TAP_OFFSET     0x100   // offset for double click (used as mask)
#define INPUT_DOUBLE_TAP_OFFSET 0x100 // Offset for double click (used as mask)
#define MOUSE_CLICK_OFFSET         0x80     // offset for mouse button click (compared to hold)
#define MOUSE_CLICK_OFFSET 0x80 // Offset for mouse button click (compared to hold)
</syntaxhighlight>
</syntaxhighlight>


Example:
Examples:
* Left click = 0x80
* Left click: 0x80
* Left click hold = 0x0
* Left click hold: 0x0
* Left click doubletap = 0x100
* Left click doubletap: 0x100
* Right click hold = 0x1
* Right click hold: 0x1
There are 256 stick buttons
There are 256 stick buttons.


<syntaxhighlight lang="cpp">
<syntaxhighlight lang="cpp">
Line 76: Line 79:
</syntaxhighlight>
</syntaxhighlight>


TrackIR axis
TrackIR axis:
<syntaxhighlight lang="cpp">
<syntaxhighlight lang="cpp">
enum MovementTrackerAxis
enum MovementTrackerAxis
{
{
TRACK_PITCH = 0, // up/down rotation
TRACK_PITCH = 0, // Up / down rotation
TRACK_YAW = 1, // left/right rotation
TRACK_YAW = 1, // Left / right rotation
TRACK_ROLL = 2, // side roll
TRACK_ROLL = 2, // Side roll
TRACK_X = 3, // left/right move
TRACK_X = 3, // Left / right move
TRACK_Y = 4, // up/down move
TRACK_Y = 4, // Up / down move
TRACK_Z = 5, // forward/backward move
TRACK_Z = 5 // Forward / backward move
};
};
</syntaxhighlight>
</syntaxhighlight>
Line 95: Line 98:
MOUSE_AXIS_RIGHT = 1,
MOUSE_AXIS_RIGHT = 1,
MOUSE_AXIS_UP = 2,
MOUSE_AXIS_UP = 2,
MOUSE_AXIS_DOWN = 3, // last actual mouse axis, change N_MOUSE_AXES if adding new axis
MOUSE_AXIS_DOWN = 3, // Last actual mouse axis, change N_MOUSE_AXES if adding new axis
MOUSE_AXIS_WHEEL_UP = 4,
MOUSE_AXIS_WHEEL_UP = 4,
MOUSE_AXIS_WHEEL_DOWN = 5,
MOUSE_AXIS_WHEEL_DOWN = 5
};
};
</syntaxhighlight>
</syntaxhighlight>


= How to add a new key =


=== Define your new action in CfgUserActions ===
== Adding a new key ==
 
=== Defining a new action in CfgUserActions ===


<syntaxhighlight lang="cpp">
<syntaxhighlight lang="cpp">
class CfgUserActions
class CfgUserActions
{
{
class Mod_MyActionName // name, also used for inputAction script command and for internal representation
class TAG_MyActionName // This class name is used for internal representation and also for the inputAction command.
{
{
displayName = "My test action";
displayName = "My Test Action";
tooltip = "This action does test things";
tooltip = "This action is for testing.";
onActivate = "_this call Mod_Myhandler"; // _this == bool, always true on activate
onActivate = "_this call TAG_fnc_MyHandler"; // _this is always true.
onDeactivate = "_this call Mod_Myhandler"; // _this == bool, always false on deactivate
onDeactivate = "_this call TAG_fnc_MyHandler"; // _this is always false.
onActionAnalog = "_this call Mod_MyAnalogHandler"; // _this == scalar (action analog state has changed)
onAnalog = "_this call TAG_fnc_MyAnalogHandler"; // _this is the scalar analog value.
analogChangeThreshold = 0.1; // minimum change required to trigger onAnalog EH, default 0.01
analogChangeThreshold = 0.1; // Minimum change required to trigger the onAnalog EH (default: 0.01).
};
};
};
};
</syntaxhighlight>
</syntaxhighlight>


=== Define your default keybind in CfgDefaultKeysPresets ===
=== Defining a default keybind in CfgDefaultKeysPresets ===
 
<syntaxhighlight lang="cpp">
<syntaxhighlight lang="cpp">
class CfgDefaultKeysPresets
class CfgDefaultKeysPresets
{
{
class Arma2// Arma2 is inherited by all other presets
class Arma2 // Arma2 is inherited by all other presets.
{
{
class Mappings
class Mappings
{
{
Mod_MyActionName[] = {
TAG_MyActionName[] = {
0x25, // DIK_K
0x25, // DIK_K
"256+0x25", // 256 == bitflag for "doubletap"/2x, 0x25 == DIK code for K
"256 + 0x25", // 256 is the bitflag for "doubletap", 0x25 is the DIK code for K.
"0x00010000 + 2", // 0x00010000 bitflag for "mouse button"
"0x00010000 + 2" // 0x00010000 is the bitflag for "mouse button".
};  
};
};
};
};
};
};
};
</syntaxhighlight>
</syntaxhighlight>
{{Feature|warning|
If the key code is large enough, for example {{hl|0x1D130023}} ({{Controls|Ctrl|H}}), then adding values may lead to a wrong result due to rounding errors (see {{Link|Number#Floating-point Precision}}).
As such, it is recommended to do the calculation manually and use that value instead.
}}


=== Add your keybind to the keybind options dialog ===
=== Adding a keybind to the keybind options dialog ===


<syntaxhighlight lang="cpp">
<syntaxhighlight lang="cpp">
class UserActionGroups
class UserActionGroups
{
{
class ModSection // unique classname for your category
class ModSection // Unique classname of your category.
{
{
name = "Mod Section"; // display name of your category
name = "Mod Section"; // Display name of your category.
group[] = {
isAddon = 1;
"Mod_MyActionName"
group[] = { "TAG_MyActionName" }; // List of all actions inside this category.
};
};
};
};
};
</syntaxhighlight>
</syntaxhighlight>


=== Set up a collision group (optional) ===
=== Setting up a collision group (optional) ===
 
class UserActionsConflictGroups gives you the ability to configure where to check for keybinding collisions.
 
For example if you want to check that your input doesn't conflict with car movement keybindings you can do


Class UserActionsConflictGroups provides the ability to configure checks for keybinding collisions. The following example demonstrates how to ensure that the input does not conflict with car movement keybindings:
<syntaxhighlight lang="cpp">
<syntaxhighlight lang="cpp">
class UserActionsConflictGroups
class UserActionsConflictGroups
Line 165: Line 168:
class ActionGroups
class ActionGroups
{
{
Mod_MyActionGroup[] = {"Mod_MyActionName"};
TAG_MyActionGroup[] = { "TAG_MyActionName" };
};
};


class CollisionGroups
class CollisionGroups
{
{
// add your group to existing collision group
// Add your group to an existing collision group:
carMove[] += { "Mod_MyActionGroup" };
carMove[] += { "TAG_MyActionGroup" };


// or alternatvely add your own collision group, which is usually preferrable
// Or alternatively add your own collision group (which is usually preferrable):
Mod_MyActionGroupCollisions[] = { "basic", "vehBasic", "HeadMove", "Mod_MyActionGroup" };
TAG_MyActionGroupCollisions[] = { "basic", "vehBasic", "HeadMove", "TAG_MyActionGroup" };
};
};
};
};
Line 180: Line 183:




== Scripted Eventhandler ==
== Scripted Event Handlers ==
 
<sqf>
addUserActionEventHandler ["ReloadMagazine", "Activate", {
systemChat "Reloading!";
removeUserActionEventHandler ["ReloadMagazine", "Activate", _thisEventHandler];
}];
</sqf>
The persistence of these EHs is the same as that of [[Arma 3: Mission Event Handlers|Mission Event Handlers]] - they are scoped per mission and get removed when the mission ends.


See
'''See Also:'''
* [[addUserActionEventHandler]]
* [[addUserActionEventHandler]]
* [[removeUserActionEventHandler]]
* [[removeUserActionEventHandler]]
* [[removeAllUserActionEventHandlers]]
* [[removeAllUserActionEventHandlers]]
<code>[[addUserActionEventHandler]] ["ReloadMagazine", "activate", {
[[systemChat]] "reload!";
[[removeUserActionEventHandler]] ["ReloadMagazine", "activate", _thisEventHandler];
}];</code>
Persistence of these handlers is the same as for [[addMissionEventHandler|mission Event Handlers]] - they are scoped per mission and get removed on mission end.




== Additional documentation on key bitflags (CfgDefaultKeysPresets) ==
== Additional documentation on key bitflags (CfgDefaultKeysPresets) ==


<syntaxhighlight lang="cpp">
{{Feature|informative|
// dik = 0xaaBBccDD
* See also [[DIK KeyCodes]]
// aa = combo KB key (second key of combo always keyboard)
* The format is as follows (here for {{Controls|Ctrl|W}} with a value of {{hl|487784465}}, hexadecimal {{hl|0x1D130011}}):
// BB = device type of first key (joy, mouse, KB,...) (or in case of combo, first half secondary combo type, second half main combo type)
: {{{!}} class{{=}}"wikitable align-center"
// cc = offset for joys or double tap info for KB
! Value
// DD = key/button/axis identification
{{!}} 0x
{{!}} 1D
{{!}} 13
{{!}} 00
{{!}} 11
{{!}}-
! Title
{{!}} hexPrefix
{{!}} comboKB
{{!}} deviceType
{{!}} doubleTapInfo
{{!}} keyId
{{!}}-
! Translated
{{!}} rowspan{{=}}"2" {{n/a}}
{{!}} {{hl|DIK_LCONTROL}}
{{!}} {{hl|INPUT_DEVICE_COMBO_KB}}  + {{hl|INPUT_DEVICE_MAIN_KB}}
{{!}} 0
{{!}} DIK_W
{{!}}-
! Details
{{!}} combo keyboard key (second key of a combo is always keyboard)
{{!}} device type of first key (joystick, mouse, KB, ...)<br>or in case of combo, first half secondary combo type, second half main combo type
{{!}} offset for joysticks or double tap info for keyboard
{{!}} key/button/axis identification
{{!}}}
}}


// BBccDD = whole info about first key
<sqf>
// ccDD = button info (doubleTap or joyID+btnID)
// dik = 0xAABBCCDD
// DD = button local ID
// BBCCDD = whole info about first key
</syntaxhighlight>
// CCDD = button info (doubleTap or joyID + btnID)
// DD = button local ID
</sqf>


; Example for keyboard combo of A + 2xB keys
; Example for {{Controls|A|2×B}}
  DIK_A = 0x1E, DIK_B = 0x30
  DIK_A = 0x1E, DIK_B = 0x30
  Combined code = 0x1E130130
  Combined code = 0x1E130130
combo key is DIK_A (1E), combo key device type is INPUT_DEVICE_COMBO_KB (1), main key device type is INPUT_DEVICE_MAIN_KB (3), doubletap (01), main key is IDK_B (30)
combo key is DIK_A (1E), combo key device type is INPUT_DEVICE_COMBO_KB (1), main key device type is INPUT_DEVICE_MAIN_KB (3), doubletap (01), main key is IDK_B (30)


; Example for combo A + middle mouse
; Example for {{Controls|A|MMB}}
  DIK_A = 0x1E, middle mouse hold = 0x2
  DIK_A = 0x1E, middle mouse hold = 0x2
  Combined code 0x1E110002
  Combined code 0x1E110002
Combo key is DIK_A (1E), combo key device type is INPUT_DEVICE_COMBO_KB (1), main key device is INPUT_DEVICE_MAIN_MB (1), no double tap (00), main key is MOUSE_BUTTONS_MIDDLE (2)
Combo key is DIK_A (1E), combo key device type is INPUT_DEVICE_COMBO_KB (1), main key device is INPUT_DEVICE_MAIN_MB (1), no double tap (00), main key is MOUSE_BUTTONS_MIDDLE (2)


; Example for combo A + Mouse Left (move)
; Example for A + Mouse Left (move)
  DIK_A = 0x1E, MOUSE_AXIS_LEFT = 0
  DIK_A = 0x1E, MOUSE_AXIS_LEFT = 0
  Combined code 0x1E120001
  Combined code 0x1E120001
Combo key is DIK_A (1E), combo key device type is INPUT_DEVICE_COMBO_KB (1), main key device is INPUT_DEVICE_MAIN_MA (2), no double tap (00), main key is MOUSE_AXIS_RIGHT (1)
Combo key is DIK_A (1E), combo key device type is INPUT_DEVICE_COMBO_KB (1), main key device is INPUT_DEVICE_MAIN_MA (2), no double tap (00), main key is MOUSE_AXIS_RIGHT (1)


; Example for combo Left mouse button + middle mouse button
; Example for {{Controls|LMB|MMB}}
  MOUSE_BUTTONS_LEFT = 0, MOUSE_BUTTONS_MIDDLE = 2
  MOUSE_BUTTONS_LEFT = 0, MOUSE_BUTTONS_MIDDLE = 2
  Combined code 0x02310000
  Combined code 0x02310000
Combo key is MOUSE_BUTTONS_MIDDLE (2), combo key device type is INPUT_DEVICE_COMBO_MB (3), main key device is INPUT_DEVICE_MAIN_MB (1), no double tap (00), main key is MOUSE_BUTTONS_LEFT (0)
Combo key is MOUSE_BUTTONS_MIDDLE (2), combo key device type is INPUT_DEVICE_COMBO_MB (3), main key device is INPUT_DEVICE_MAIN_MB (1), no double tap (00), main key is MOUSE_BUTTONS_LEFT (0)




{{GameCategory|arma3|Controls}}
{{GameCategory|arma3|Editing}}
[[Category:Introduced with {{arma3}} version 2.06]]
[[Category:Introduced with Arma 3 version 2.06]]

Latest revision as of 20:34, 3 April 2024

As of Arma 3 logo black.png2.06, mods are able to define keys that can be bound by the user in the keybindings.

class CfgUserActions
{
	class TAG_MyActionName // This class name is used for internal representation and also for the inputAction command.
	{
		displayName = "";
		tooltip = "";
		onActivate = "['TAG_MyActionName', true] call TAG_fnc_MyHandler";		// _this is always true.
		onDeactivate = "['TAG_MyActionName', false] call TAG_fnc_MyHandler";	// _this is always false.
		onAnalog = "['TAG_MyActionName', _this] call TAG_fnc_MyAnalogHandler";	// _this is the scalar analog value.
		analogChangeThreshold = 0.01; // Minimum change required to trigger the onAnalog EH (default: 0.01).
		modifierBlocking = 1; // Whether this action would block other actions if the assigned key has modifier keys on it. (Since Arma 2.12)
	};
};


Key Combination Enumerations

// Secondary combo types:
#define INPUT_DEVICE_COMBO_KB 0x00100000 // Keyboard button (key)
#define INPUT_DEVICE_COMBO_MB 0x00300000 // Mouse button
#define INPUT_DEVICE_COMBO_JB 0x00500000 // Joystick button
#define INPUT_DEVICE_COMBO_JP 0x00600000 // Joystick POV
#define INPUT_DEVICE_COMBO_XI 0x00900000 // Xbox controller (XInput)

// Main combo types:
#define INPUT_DEVICE_MAIN_MB 0x00010000 // Mouse button
#define INPUT_DEVICE_MAIN_MA 0x00020000 // Mouse axis
#define INPUT_DEVICE_MAIN_KB 0x00030000 // Keyboard button (key)
#define INPUT_DEVICE_MAIN_JB 0x00040000 // Joystick button
#define INPUT_DEVICE_MAIN_JA 0x00050000 // Joystick axis
#define INPUT_DEVICE_MAIN_JP 0x00060000 // Joystick POV
#define INPUT_DEVICE_MAIN_XI 0x00070000 // Xbox controller (XInput)
#define INPUT_DEVICE_MAIN_TR 0x00080000 // Movement tracking device

// Device types:
#define INPUT_DEVICE_SOLO_KB 0x00000000 // Keyboard button (key)
#define INPUT_DEVICE_SOLO_MB 0x00010000 // Mouse button
#define INPUT_DEVICE_SOLO_JB 0x00020000 // Stick button
#define INPUT_DEVICE_SOLO_JA 0x00030000 // Stick axis
#define INPUT_DEVICE_SOLO_JP 0x00040000 // Stick POV
#define INPUT_DEVICE_SOLO_XI 0x00050000 // XInput device
#define INPUT_DEVICE_SOLO_TR 0x00080000 // EyeXTracker, TrackIR, FreeTrack, ... exclusive, in this preference
#define INPUT_DEVICE_SOLO_MA 0x00100000 // Mouse axis
enum MouseButtons
{
	MOUSE_BUTTONS_LEFT		= 0,
	MOUSE_BUTTONS_RIGHT		= 1,
	MOUSE_BUTTONS_MIDDLE	= 2,
	MOUSE_BUTTONS_CUSTOM_1	= 3,
	MOUSE_BUTTONS_CUSTOM_2	= 4,
	MOUSE_BUTTONS_CUSTOM_3	= 5,
	MOUSE_BUTTONS_CUSTOM_4	= 6,
	MOUSE_BUTTONS_CUSTOM_5	= 7
};

#define INPUT_DOUBLE_TAP_OFFSET		0x100	// Offset for double click (used as mask)
#define MOUSE_CLICK_OFFSET			0x80	// Offset for mouse button click (compared to hold)

Examples:

  • Left click: 0x80
  • Left click hold: 0x0
  • Left click doubletap: 0x100
  • Right click hold: 0x1

There are 256 stick buttons.

#define N_JOYSTICK_AXES		8 // 3 normal, 3 rotate, 2 sliders
#define N_JOYSTICK_POV		8 // 8 directional stick

TrackIR axis:

enum MovementTrackerAxis
{
	TRACK_PITCH = 0,	// Up / down rotation
	TRACK_YAW = 1,		// Left / right rotation
	TRACK_ROLL = 2,		// Side roll
	TRACK_X = 3,		// Left / right move
	TRACK_Y = 4,		// Up / down move
	TRACK_Z = 5			// Forward / backward move
};
enum MouseAxis
{
	MOUSE_AXIS_LEFT = 0,
	MOUSE_AXIS_RIGHT = 1,
	MOUSE_AXIS_UP = 2,
	MOUSE_AXIS_DOWN = 3, // Last actual mouse axis, change N_MOUSE_AXES if adding new axis
	MOUSE_AXIS_WHEEL_UP = 4,
	MOUSE_AXIS_WHEEL_DOWN = 5
};


Adding a new key

Defining a new action in CfgUserActions

class CfgUserActions
{
	class TAG_MyActionName // This class name is used for internal representation and also for the inputAction command.
	{
		displayName = "My Test Action";
		tooltip = "This action is for testing.";
		onActivate = "_this call TAG_fnc_MyHandler";		// _this is always true.
		onDeactivate = "_this call TAG_fnc_MyHandler";		// _this is always false.
		onAnalog = "_this call TAG_fnc_MyAnalogHandler";	// _this is the scalar analog value.
		analogChangeThreshold = 0.1; // Minimum change required to trigger the onAnalog EH (default: 0.01).
	};
};

Defining a default keybind in CfgDefaultKeysPresets

class CfgDefaultKeysPresets
{
	class Arma2 // Arma2 is inherited by all other presets.
	{
		class Mappings
		{
			TAG_MyActionName[] = {
				0x25, // DIK_K
				"256 + 0x25", // 256 is the bitflag for "doubletap", 0x25 is the DIK code for K.
				"0x00010000 + 2" // 0x00010000 is the bitflag for "mouse button".
			};
		};
	};
};
If the key code is large enough, for example 0x1D130023 (Ctrl + H), then adding values may lead to a wrong result due to rounding errors (see Number - Floating-point Precision). As such, it is recommended to do the calculation manually and use that value instead.

Adding a keybind to the keybind options dialog

class UserActionGroups
{
	class ModSection // Unique classname of your category.
	{
		name = "Mod Section"; // Display name of your category.
		isAddon = 1;
		group[] = { "TAG_MyActionName" }; // List of all actions inside this category.
	};
};

Setting up a collision group (optional)

Class UserActionsConflictGroups provides the ability to configure checks for keybinding collisions. The following example demonstrates how to ensure that the input does not conflict with car movement keybindings:

class UserActionsConflictGroups
{
	class ActionGroups
	{
		TAG_MyActionGroup[] = { "TAG_MyActionName" };
	};

	class CollisionGroups
	{
		// Add your group to an existing collision group:
		carMove[] += { "TAG_MyActionGroup" };

		// Or alternatively add your own collision group (which is usually preferrable):
		TAG_MyActionGroupCollisions[] = { "basic", "vehBasic", "HeadMove", "TAG_MyActionGroup" };
	};
};


Scripted Event Handlers

addUserActionEventHandler ["ReloadMagazine", "Activate", { systemChat "Reloading!"; removeUserActionEventHandler ["ReloadMagazine", "Activate", _thisEventHandler]; }];

The persistence of these EHs is the same as that of Mission Event Handlers - they are scoped per mission and get removed when the mission ends.

See Also:


Additional documentation on key bitflags (CfgDefaultKeysPresets)

  • See also DIK KeyCodes
  • The format is as follows (here for Ctrl + W with a value of 487784465, hexadecimal 0x1D130011):
Value 0x 1D 13 00 11
Title hexPrefix comboKB deviceType doubleTapInfo keyId
Translated N/A DIK_LCONTROL INPUT_DEVICE_COMBO_KB + INPUT_DEVICE_MAIN_KB 0 DIK_W
Details combo keyboard key (second key of a combo is always keyboard) device type of first key (joystick, mouse, KB, ...)
or in case of combo, first half secondary combo type, second half main combo type
offset for joysticks or double tap info for keyboard key/button/axis identification

// dik = 0xAABBCCDD // BBCCDD = whole info about first key // CCDD = button info (doubleTap or joyID + btnID) // DD = button local ID

Example for A + 2×B
DIK_A = 0x1E, DIK_B = 0x30
Combined code = 0x1E130130

combo key is DIK_A (1E), combo key device type is INPUT_DEVICE_COMBO_KB (1), main key device type is INPUT_DEVICE_MAIN_KB (3), doubletap (01), main key is IDK_B (30)

Example for A + Middle Mouse Button
DIK_A = 0x1E, middle mouse hold = 0x2
Combined code 0x1E110002

Combo key is DIK_A (1E), combo key device type is INPUT_DEVICE_COMBO_KB (1), main key device is INPUT_DEVICE_MAIN_MB (1), no double tap (00), main key is MOUSE_BUTTONS_MIDDLE (2)

Example for A + Mouse Left (move)
DIK_A = 0x1E, MOUSE_AXIS_LEFT = 0
Combined code 0x1E120001

Combo key is DIK_A (1E), combo key device type is INPUT_DEVICE_COMBO_KB (1), main key device is INPUT_DEVICE_MAIN_MA (2), no double tap (00), main key is MOUSE_AXIS_RIGHT (1)

Example for Left Mouse Button + Middle Mouse Button
MOUSE_BUTTONS_LEFT = 0, MOUSE_BUTTONS_MIDDLE = 2
Combined code 0x02310000

Combo key is MOUSE_BUTTONS_MIDDLE (2), combo key device type is INPUT_DEVICE_COMBO_MB (3), main key device is INPUT_DEVICE_MAIN_MB (1), no double tap (00), main key is MOUSE_BUTTONS_LEFT (0)