Arma 3: Modded Keybinding

From Bohemia Interactive Community
Jump to navigation Jump to search

Update Arma 3 logo black.png2.06 allows for mods to define keys that can be bound by the user in their keybindings.

class CfgUserActions
{
	class Mod_MyActionName // name, also used for inputAction script command and for internal representation
	{
		displayName = "";
		tooltip = "";
		onActivate = "['Mod_MyActionName', true] call Mod_Myhandler";		// _this is always true
		onDeactivate = "['Mod_MyActionName', false] call Mod_Myhandler";	// _this is always false
		onAnalog = "['Mod_MyActionName', _this] call Mod_MyAnalogHandler";	// _this is the scalar analog value
		analogChangeThreshold = 0.01;			// minimum change required to trigger onAnalog EH, default 0.01
	}
}

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)

Example:

  • 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,
};

How to add a new key

Define your new action in CfgUserActions

class CfgUserActions
{
	class Mod_MyActionName // name, also used for inputAction script command and for internal representation
	{
		displayName = "My test action";
		tooltip = "This action does test things";
		onActivate = "_this call Mod_Myhandler";			// _this == bool, always true on activate
		onDeactivate = "_this call Mod_Myhandler";			// _this == bool, always false on deactivate
		onActionAnalog = "_this call Mod_MyAnalogHandler";	// _this == scalar (action analog state has changed)
		analogChangeThreshold = 0.1;			// minimum change required to trigger onAnalog EH, default 0.01
	};
};

Define your default keybind in CfgDefaultKeysPresets

class CfgDefaultKeysPresets
{
	class Arma2// Arma2 is inherited by all other presets
	{
		class Mappings
		{
			Mod_MyActionName[] = {
				0x25, // DIK_K
				"256+0x25", // 256 == bitflag for "doubletap"/2x, 0x25 == DIK code for K
				"0x00010000 + 2", // 0x00010000 bitflag for "mouse button"
			};
		};
	};
};

Add your keybind to the keybind options dialog

class UserActionGroups
{
	class ModSection // unique classname for your category
	{
		name = "Mod Section"; // display name of your category
		group[] = {
			"Mod_MyActionName"
		};
	};
};

Set 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
{
	class ActionGroups
	{
		Mod_MyActionGroup[] = {"Mod_MyActionName"};
	};

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

		// or alternatvely add your own collision group, which is usually preferrable
		Mod_MyActionGroupCollisions[] = { "basic", "vehBasic", "HeadMove", "Mod_MyActionGroup" };
	};
};


Scripted Eventhandler

See

addUserActionEventHandler ["ReloadMagazine", "activate", { systemChat "reload!"; removeUserActionEventHandler ["ReloadMagazine", "activate", _thisEventHandler]; }]; Persistence of these handlers is the same as for mission Event Handlers - they are scoped per mission and get removed on mission end.


Additional documentation on key bitflags (CfgDefaultKeysPresets)

// dik = 0xaaBBccDD
// aa		= combo KB key (second key of combo always keyboard)
// BB		= device type of first key (joy, mouse, KB,...) (or in case of combo, first half secondary combo type, second half main combo type)
// cc		= offset for joys or double tap info for KB
// DD		= key/button/axis identification

// BBccDD	= whole info about first key
// ccDD		= button info (doubleTap or joyID+btnID)
// DD		= button local ID
Example for keyboard combo of A + 2xB keys
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 combo A + middle mouse
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 combo 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 combo 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)