Mission Event Handlers – Arma 3

From Bohemia Interactive Community
Revision as of 21:46, 16 May 2024 by Lou Montana (talk | contribs) (Text replacement - "{{Feature | Warning | " to "{{Feature|warning|")
Jump to navigation Jump to search

LELocal

Mission event handlers are specific EHs that are anchored to the running mission and automatically removed when mission is over. These events fire only on the machine where they have been added.
For all other available EHs see the Event Handlers main page.

OnUser... mission event handlers used in combination with getUserInfo provide a way to track server users from the very early stage of joining a server to the very last stage of leaving the server. All these event handlers are designed to be used server side and return unique user network id in String format as the first param. These ids could also be obtained via getPlayerID and allUsers script commands. There may be other params specific to each event. See:


Related Commands


Events

BuildingChanged

Fired each time a building model changes, for example due to stages of destruction.

addMissionEventHandler ["BuildingChanged", { params ["_from", "_to", "_isRuin"]; }];

  • from: Object - building it changes from
  • to: Object - building it changes to
  • isRuin: Boolean - true if changes to ruins


CommandModeChanged

Executes assigned code when user switches to/from HC command mode (⇧ Shift + Space). Stackable version of onCommandModeChanged.

addMissionEventHandler ["CommandModeChanged", { params ["_isHighCommand", "_isForced"]; }];

  • isHighCommand: Boolean - same as _isHighCommand param
  • isForced: Boolean - true if command mode was forced


ControlsShifted

Triggers when control of a vehicle is shifted (pilot->co-pilot, co-pilot->pilot), usually when user performs an action such as TakeVehicleControl, SuspendVehicleControl, UnlockVehicleControl, LockVehicleControl, or when enableCopilot command is used. This event handler will always fire on the PC where action is triggered as well as where the vehicle is local at the time. When control of the vehicle is shifted, the locality of the vehicle changes to the locality of the new controller. Since Arma 3 v1.96 this EH is extended with additional params.

addMissionEventHandler ["ControlsShifted", { params ["_newController", "_oldController", "_vehicle", "_copilotEnabled", "_controlsUnlocked"]; }];

  • newController: Object - unit currently controlling the vehicle
  • oldController: Object - unit previously controlling the vehicle
  • vehicle: Object - the vehicle for which controls shifted
  • copilotEnabled: Boolean - true if copilot is enabled
  • controlsUnlocked: Boolean - true if controls are unlocked


Draw3D

Runs the EH code each frame in unscheduled environment. Client side EH only (presence of UI). Will stop executing when UI loses focus (if user Alt+Tabs for example). Usually used with drawIcon3D, drawLine3D.

addMissionEventHandler ["Draw3D", { // no params }];

Drowned

Runs when a vehicle gets drowned (the vehicle is submerged below 'maxFord' for longer than 'waterResistance'). This will cause engine damage and for some vehicles that will render engine unusable until the vehicle/engine is fully repared. Some vehicles can drown but would still be recoverable as they wouldn't be destroyed. The event handler will also fire when vehicle is removed from water, in which case 'drowned' param will change to false. To check if the engine was damaged by water use waterDamaged command.

addMissionEventHandler ["Drowned", { params ["_vehicle", "_drowned"]; }];


EachFrame

Executes assigned code each frame. Stackable version of onEachFrame.

addMissionEventHandler ["EachFrame", { // no params }];


Ended

Triggered when mission ends, either using trigger of type "End", endMission command, BIS_fnc_endMission function or ENDMISSION cheat.

addMissionEventHandler ["Ended", { params ["_endType"]; }];


MPEnded

Triggered when the server switches off from "playing" state (mission ends, server closes, etc.) It's only for MP games, it is called on server and also on clients. It is not called on clients when client disconnects from server (and mission continues). This EH has no arguments passed to the code.

addMissionEventHandler ["MPEnded", { // no params }];
If client code must be executed on disconnect, this code can be used instead:
0 spawn { waitUntil { !isNull findDisplay 46 }; findDisplay 46 displayAddEventHandler ["Unload", { // code here gets executed on the client at end of mission, whether due to player abort, loss of connection, or mission ended by server; might not work on headless clients }]; };


EntityCreated

Triggered when an entity is created.

Unlike most event handlers, the argument is entity Object and not an array containing the entity. However, it is recommended to use params to make sure the code remains compatible in case the event arguments are expanded in the future.
This event is called before variable namespace is copied to remote respawning entity, keep this in mind so your setVariables are not overwritten in the next frame. EntityRespawned always fires after variable namespace is copied to new entity regardless of locality.

addMissionEventHandler ["EntityCreated", { params ["_entity"]; }];


EntityDeleted

Triggered when an entity is deleted. It only triggers for objects that support the "Deleted" event handler, such as vehicles, soldiers, animals, and houses. Simple objects for example are not supported.

Unlike most event handlers, the argument is entity Object and not an array containing the entity. However, it is recommended to use params to make sure the code remains compatible in case the event arguments are expanded in the future.

addMissionEventHandler ["EntityDeleted", { params ["_entity"]; }];


EntityKilled

Triggered when an entity is killed.

addMissionEventHandler ["EntityKilled", { params ["_unit", "_killer", "_instigator", "_useEffects"]; }];

  • unit: Object - entity that was killed
  • killer: Object - the killer (vehicle or person)
  • Arma 3 logo black.png1.66 instigator: Object - person who pulled the trigger
  • Arma 3 logo black.png1.68 useEffects: Boolean - same as useEffects in setDamage alt syntax

It's worth noting that instigator param is objNull during road kill. To work around this issue try:

addMissionEventHandler ["EntityKilled", { params ["_killed", "_killer", "_instigator"]; if (isNull _instigator) then { _instigator = UAVControl vehicle _killer select 0 }; // UAV/UGV player operated road kill if (isNull _instigator) then { _instigator = _killer }; // player driven vehicle road kill hint format ["Killed By %1", name _instigator]; }];


EntityRespawned

Triggered when an entity is respawned.

addMissionEventHandler ["EntityRespawned", { params ["_newEntity", "_oldEntity"]; }];

  • newEntity: Object - respawned entity
  • oldEntity: Object - corpse/wreck


ExtensionCallback

Triggered when an extension calls provided function pointer with 3 params.

addMissionEventHandler ["ExtensionCallback", { params ["_name", "_function", "_data"]; }];

  • name: String - user provided param
  • function: String - user provided param
  • data: String - user provided param


GroupCreated

Triggered when a Group is created. Note that the group contains no units at that point!

addMissionEventHandler ["GroupCreated", { params ["_group"]; }];

  • group: Group - the created group


GroupDeleted

Triggered when a Group is manually or automatically deleted.

addMissionEventHandler ["GroupDeleted", { params ["_group"]; }];

  • group: Group - the deleted group


GroupIconClick

Executes assigned code when user clicks on the HC group icon on the map. If groupIconSelectable is true, LMB clicking (firing) at the HC group icon on the HUD will also trigger the event. To set group icon selectable use setGroupIconsSelectable. Stackable version of onGroupIconClick.

addMissionEventHandler ["GroupIconClick", { params [ "_is3D", "_group", "_waypointId", "_mouseButton", "_posX", "_posY", "_shift", "_control", "_alt" ]; }];

  • is3D: Boolean - true if HUD icon, false if main map icon
  • group: Group - group the icon belonds to
  • waypointId: Number - waypoint ID
  • mouseButton: Number - mouse button: 0 - Left Mouse Button, 1 - Right Mouse Button (only applicable to IconClick)
  • posX: Number - screen X of the mouse
  • posY: Number - screen Y of the mouse
  • shift: Boolean - true if ⇧ Shift key was pressed
  • ctrl: Boolean - true if Ctrl key was pressed
  • alt: Boolean - true if Alt key was pressed


GroupIconOverEnter

Continuously executes assigned code when user hovers with pointer over the HC group icon, either on the HUD or the main map. groupIconSelectable must be set to true for this EH to work at all. To set group icon selectable use setGroupIconsSelectable. When EH fires over the HUD icon, X and Y coordinates will change depending on the position of the pointer in relation to the icon area. When over main map, the X and Y do not change and indicate icon center. Stackable version of onGroupIconOverEnter.

addMissionEventHandler ["GroupIconOverEnter", { params [ "_is3D", "_group", "_waypointId", "_posX", "_posY", "_shift", "_control", "_alt" ]; }];


GroupIconOverLeave

Executes assigned code when user moves the pointer away from HC group icon it was over. Fires either for on the HUD icons or the main map HC icons. groupIconSelectable must be set to true for this EH to work at all. To set group icon selectable use setGroupIconsSelectable. Stackable version of onGroupIconOverLeave.

addMissionEventHandler ["GroupIconOverLeave", { params [ "_is3D", "_group", "_waypointId", "_posX", "_posY", "_shift", "_control", "_alt" ]; }];

  • is3D: Boolean - true if HUD icon, false if main map icon
  • group: Group - group the icon belonds to
  • waypointId: Number - waypoint ID
  • posX: Number - screen X of the mouse
  • posY: Number - screen Y of the mouse (Y is always 0 when leaving HUD icon for some reason)
  • shift: Boolean - true if ⇧ Shift key was pressed
  • ctrl: Boolean - true if Ctrl key was pressed
  • alt: Boolean - true if Alt key was pressed


HandleAccTime

Fires when user changes time acceleration with +/- keys in SP or setAccTime command. If the code returns true the on-screen message confirming the change is not displayed. Doesn't fire if desired value is already set.

addMissionEventHandler ["HandleAccTime", { params ["_currentTimeAcc", "_prevTimeAcc", "_messageSuppressed"]; }];

  • currentTimeAcc: Number - current value
  • prevTimeAcc: Number - previous value
  • messageSuppressed: Boolean - true if on-screen message was suppressed


HandleChatMessage

Fires when a message is received, before adding it to the chat feed. Fires clientside. The output message could be overridden:

  • Return true to block incoming chat message from being added to the chat feed.
  • Return String to replace the chat message content but not the sender name.
  • Return Array [from, text] to replace both the chat message content and the the sender's name.
Only the last added EH with override will be used to override the message.
Do not put any of the chat related script command such as systemChat, sideChat, etc in this EH code as it would naturally cause recursion and the game will freeze.

addMissionEventHandler ["HandleChatMessage", { params ["_channel", "_owner", "_from", "_text", "_person", "_name", "_strID", "_forcedDisplay", "_isPlayerMessage", "_sentenceType", "_chatMessageType", "_params"]; }];

  • channel: Number - see radio channel indices (16 for system chat message for example)
  • owner: Number - owner id of the sender:
  • from: String - sender's formatted name as appeared on the chat
  • text: String - the chat message
  • person: Object - sender's object
  • name: String - sender's name, could be different from from
  • strID: String - sender's network player ID (marker id):
  • forcedDisplay: Boolean - if the message should be displayed when the chat list is disabled (when enableRadio is set to false radio protocol messages won't display)
  • isPlayerMessage: Boolean - if the message is addressed to player
  • sentenceType: Number - 0: Normal type, 1: Protocol type
  • chatMessageType: Number - 0: Generic type, 1: SimpleMove type, 2: KillConfirmation type
  • params: Array of Strings - sentence parameters, if any


HandleDisconnect

Triggered when player disconnects from the game. Similar to onPlayerDisconnected event but can be stacked and contains the unit occupied by player before disconnect. Must be added on the server and triggers only on the server.

addMissionEventHandler ["HandleDisconnect", { params ["_unit", "_id", "_uid", "_name"]; true; }];

Override: if this EH code returns true, the unit, previously occupied by player, gets transferred to the server, becomes AI and continues to live, even with description.ext param disabledAI = 1;.


HCGroupSelectionChanged

Executes assigned code when user selects available HC group (F1, F2…). Stackable version of onHCGroupSelectionChanged.

addMissionEventHandler ["HCGroupSelectionChanged", { params ["_group", "_isSelected"]; }];

  • group: Group - group selected (same as _group param)
  • isSelected: Boolean - true if selected (same as _isSelected param)


Loaded

Triggered when mission is loaded from save.

"Loaded" event handler should be added BEFORE the mission is loaded from save. Placing it in a function with preInit = 1; usually does the trick.

addMissionEventHandler ["Loaded", { params ["_saveType"]; }];

  • saveType: String - save type, can be have following values:
    • "save" - custom save, achieved by pressing SAVE button in the pause menu
    • "autosave" - automatic checkpoint, saved using saveGame command
    • "continue" - saved when leaving a mission to the main menu


Map

Triggered when map is opened or closed either by user action or script command openMap.

addMissionEventHandler ["Map", { params ["_mapIsOpened", "_mapIsForced"]; }];


MapSingleClick

Executes when the player clicks anywhere on the main map. Stackable version of onMapSingleClick with the limitation that it does not have the ability to override the click (e.g. to prevent the player from placing the custom waypoint with ⇧ Shift + Left Mouse Button). Since the introduction of _thisArgs for addMissionEventHandler in Arma 3 logo black.png2.04, this EH also supports custom arguments (just like onMapSingleClick).

addMissionEventHandler ["MapSingleClick", { params ["_units", "_pos", "_alt", "_shift"]; }];


MarkerCreated

Executes when a marker is created either by a user or via script command.

addMissionEventHandler ["MarkerCreated", { params ["_marker", "_channelNumber", "_owner", "_local"]; }];


MarkerDeleted

Executes immediately before a marker is deleted either by a user or via script command.

addMissionEventHandler ["MarkerDeleted", { params ["_marker", "_local", "_deleter"]; }];

  • marker: String - the name of the deleted marker
  • Arma 3 logo black.png2.04 local: Boolean - true if the event originated locally, false if it came over the network
  • Arma 3 logo black.png2.18 deleter: Object - the player/curator unit that deleted the marker


MarkerUpdated

Executes when a marker is changed.

Changing the marker in the EH code will lead to an infinite loop and the game will crash!

addMissionEventHandler ["MarkerUpdated", { params ["_marker", "_local"]; }];

  • marker: String - the name of the marker
  • Arma 3 logo black.png2.04 local: Boolean - true if the event originated locally, false if it came over the network


OnUserConnected

Executes assigned code on user joining server.

addMissionEventHandler ["OnUserConnected", { params ["_networkId", "_clientStateNumber", "_clientState"]; }];


OnUserDisconnected

Executes assigned code on user leaving server.

addMissionEventHandler ["OnUserDisconnected", { params ["_networkId", "_clientStateNumber", "_clientState"]; }];


OnUserClientStateChanged

Executes assigned code for every stage of user client state change.

addMissionEventHandler ["OnUserClientStateChanged", { params ["_networkId", "_clientStateNumber", "_clientState"]; }];


OnUserAdminStateChanged

Executes assigned code after user logs in, gets voted in or logs out as admin.

addMissionEventHandler ["OnUserAdminStateChanged", { params ["_networkId", "_loggedIn", "_votedIn"]; }];


OnUserSelectedPlayer

Executes assigned code after player object is selected for user to take over control, the ownership information is broadcast and request to sync is made but the object is still owned by previous owner for a short time.

addMissionEventHandler ["OnUserSelectedPlayer", { params ["_networkId", "_playerObject", "_attempts"]; }];

  • networkId: String - user network id (see getPlayerID, allUsers)
  • playerObject: Object - player object to be controlled by the user (see player, selectPlayer)
  • Arma 3 logo black.png2.18 attempts: Number - how many times server was trying to obtain non-null playerObject. Current threshold after which the event will fire anyway is 50.
This is the earliest the player object is known when player joins the server, but it is not local to the user yet, so there is a wait time depending on network connection. When player respawns, the unit created on the client and so it might take a while before server has valid player object. From Arma 3 v2.18 the server will pospone this event until the object is not null, or until it tried 50 times, whichever is earlier. The best approach to handle this matter and get notified about completion of the transfer of the ownership is to use "Local" entity event handler, like so:

addMissionEventHandler ["OnUserSelectedPlayer", { params ["_networkId", "_playerObject", "_attempts"]; _playerObject addEventHandler ["Local", { params ["_player"]; _player removeEventHandler ["Local", _thisEventHandler]; // code to handle _player }]; }];

Note that the player object would change locality again if the user goes to lobby.


OnUserKicked

Executes assigned code after after a user has been kicked from the server providing kick reason. The possible values for 'kickTypeNumber' and 'kickType' are:
0 : "TIMEOUT", 1 : "DISCONNECTED", 2 : "KICKED", 3 : "BANNED", 4 : "MISSING ADDON", 5 : "BAD CD KEY", 6 : "CD KEY IN USE", 7 : "SESSION LOCKED", 8 : "BATTLEYE", 9 : "STEAM CHECK", 10 : "DLC CONTENT", 11 : "GS TIMEOUT", 12 : "SCRIPT", 13 : "OTHER"

addMissionEventHandler ["OnUserKicked", { params ["_networkId", "_kickTypeNumber", "_kickType", "_kickReason", "_kickMessageIncReason"]; }];

  • networkId: String - user network id (see getPlayerID, allUsers)
  • kickTypeNumber: Number - kick type number (see above)
  • kickType: String - kick type (see above)
  • kickReason: String - reason given for the kick by the admin or by other means
  • kickMessageIncReason: String - formatted engine message including the given reason


PlayerConnected

Executes assigned code when client joins the mission in MP. Stackable version of onPlayerConnected.

addMissionEventHandler ["PlayerConnected", { params ["_id", "_uid", "_name", "_jip", "_owner", "_idstr"]; }];

  • id: Number - unique DirectPlay ID (very large number). It is also the same id used for user placed markers (same as _id param)
  • uid: String - getPlayerUID of the joining client. The same as Steam ID (same as _uid param)
  • name: String - profileName of the joining client (same as _name param)
  • jip: Boolean - didJIP of the joining client (same as _jip param)
  • owner: Number - owner id of the joining client (same as _owner param)
  • idstr: String - same as id but in string format, so could be exactly compared to user marker ids

If dedicated server was started without '-autoInit' option and this EH was created on server, on first GUI client this EH also fires against server, but after first client. In mission's initServer.sqf:

addMissionEventHandler ["PlayerConnected", { diag_log "Client connected"; diag_log _this; }];

In RPT:

2016/12/16, 15:39:09 "Client connected"
2016/12/16, 15:39:09 [1.51343e+009,"7xxxxxxxxxxxxxxx1","longbow",false,3,"1513430065"]
2016/12/16, 15:39:34  Mission id: 5071d20b183e9580d0ee4f95f413ca18681d6165
2016/12/16, 15:39:34 "Client connected"
2016/12/16, 15:39:34 [2,"","__SERVER__",false,2,"2"]

That happens only for GUI clients, if HC client connects first, EH does not fire for server.
If dedicated server was started with -autoInit option, this EH does not fire against server, only for future clients, and all further clients appear to be JIP'ed.
Interesting moment for headless clients, for headless clients instead of getPlayerUID, handler gets string like "HC12160", where '12160' is headless client process ID (matches HC's PID observed in windows task manager)


PlayerDisconnected

Executes assigned code when client leaves the mission in MP. Stackable version of onPlayerDisconnected.

addMissionEventHandler ["PlayerDisconnected", { params ["_id", "_uid", "_name", "_jip", "_owner", "_idstr"]; }];

  • id: Number - unique DirectPlay ID (very large number). It is also the same id used for user placed markers (same as _id param)
  • uid: String - getPlayerUID of the leaving client. The same as Steam ID (same as _uid param)
  • name: String - profileName of the leaving client (same as _name param)
  • jip: Boolean - didJIP of the leaving client (same as _jip param)
  • owner: Number - owner id of the leaving client (same as _owner param)
  • idstr: String - same as id but in string format, so could be exactly compared to user marker ids


PlayerViewChanged

Fired on player view change. Player view changes when player is changing body due to teamSwitch, gets in out of a vehicle or operates UAV for example.

addMissionEventHandler ["PlayerViewChanged", { params [ "_oldUnit", "_newUnit", "_vehicleIn", "_oldCameraOn", "_newCameraOn", "_uav" ]; }];

  • oldUnit: Object - player body before EH fired
  • newUnit: Object - player body after EH fired
  • vehicleIn: Object - vehicle player is in (objNull if not in vehicle)
  • oldCameraOn: Object - cameraOn before EH fired
  • newCameraOn: Object - cameraOn after EH fired
  • uav: Object - UAV reference if player is operating one (objNull if not operating UAV)


PreloadStarted

Executes assigned code before the mission preload screen. Stackable version of onPreloadStarted.

This event handler also fires on client after user closes the main map.

addMissionEventHandler ["PreloadStarted", { // no params }];


PreloadFinished

Executes assigned code after the mission preload screen. Stackable version of onPreloadFinished.

This event handler also fires on client after user closes the main map.

addMissionEventHandler ["PreloadFinished", { // no params }];

ProjectileCreated

Triggered when a projectile is created.

addMissionEventHandler ["ProjectileCreated", { params ["_projectile"]; }];


ScriptError

Triggered when a script error occurs. See also the -showScriptErrors startup parameter.

Event Handlers have a recursion check. Most of them have a level limit set to 1; ScriptError has it set to 2 - meaning that an error occuring inside the Event Handler will trigger once more the EH, but no more than two times total.

addMissionEventHandler ["ScriptError", { params ["_errorText", "_sourceFile", "_lineNumber", "_errorPos", "_content", "_stackTraceOutput"]; }];


SelectedActionPerformed

RTM helicopter user action event

addMissionEventHandler ["SelectedActionPerformed", { params ["_caller", "_target", "_enumNumber", "_actionId"]; }];

Limited or non-existent functionality


SelectedActionChanged

RTM helicopter user action event

addMissionEventHandler ["SelectedActionChanged", { params ["_caller", "_target", "_enumNumber", "_actionId"]; }];

Limited or non-existent functionality


SelectedRotorLibActionPerformed

RTM helicopter user action event

addMissionEventHandler ["SelectedRotorLibActionPerformed", { params ["_caller", "_target", "_enumNumber", "_actionId"]; }];

Works only for key press combination RightCtrl + W, which is the binding for helicopter wheels brakes. It fires with or without Advanced Flight Model enabled. The enum number returned is 4 and 5, probably because the enum is structured like this:

0: HelicopterAutoTrimOn
1: HelicopterAutoTrimOff
2: HelicopterTrimOn
3: HelicopterTrimOff
4: WheelsBrakeOn

5: WheelsBrakeOff


SelectedRotorLibActionChanged

RTM helicopter user action event

addMissionEventHandler ["SelectedRotorLibActionChanged", { params ["_caller", "_target", "_enumNumber", "_actionId"]; }];

Limited or non-existent functionality

Service

Executes assigned code when a serviced vehicle gets rearmed, repaired or refueled. The code executes with interval while the serviced vehicle receives service. If the code returns true the default on-screen service message is not shown.

addMissionEventHandler ["Service", { params ["_serviceVehicle", "_servicedVehicle", "_serviceType", "_needsService", "_autoSupply"]; }];

  • serviceVehicle: Object - service vehicle
  • servicedVehicle: Object - vehicle receiving service
  • serviceType: Number - 0 - MINOR REPAIR, 1 - REPAIR, 2 - REFUEL, 3 - REARM
  • needsService: Number - how much serviced vehicle needsSevice, 0..1 where 0 - no need, 1 - need a lot
  • autoSupply: Boolean - true if supply started by proximity, false if supply started due to user action

TeamSwitch

Executes assigned code when player teamswitches. Stackable version of onTeamSwitch.

addMissionEventHandler ["TeamSwitch", { params ["_previousUnit", "_newUnit"]; }];

  • previousUnit: Object - switching from unit (same as _from param)
  • newUnit: Object - switching to unit (same as _to param)

UAVCrewCreated

Fires when UAV or UGV is assembled from Backpack after the AI crew is created

addMissionEventHandler ["UAVCrewCreated", { params ["_uav", "_driver", "_gunner"]; }];