====== ArmA 2 Eventhandler Tutorial ======
[[https://www.pmctactical.org/forum/viewforum.php?f=50|ArmA 2 Forum]], [[:arma2|ArmA 2 Home]], [[arma2:config|ArmA 2 Config]], [[arma2:file_formats|ArmA 2 File Formats]], [[arma2:missions|ArmA 2 Missions]], [[arma2:modeling|ArmA 2 3D Modeling]], [[arma2:scripting|ArmA 2 Scripting]], [[arma2:terrain|ArmA 2 Terrain]], [[arma2:texturing|ArmA 2 Texturing]], [[arma2:tools|ArmA 2 Tools]]
Eventhandlers allow you to execute code every time a specific event occurs. There are a number of different Eventhandler types, all of which you can find on the Wiki. Every object can have any number of Eventhandlers of any type assigned to them.
**Adding Eventhandlers**
player addEventHandler ["killed",{hint "You are dead!"}];
Here we added a killed Eventhandler to the player. The type, "killed" here, can be any of the ones listed on the Wiki. The code we executed was 'hint "You are dead!"'. You can call any code you want inside of an eventhandler.
**Indices**
When you add an Eventhandler to an object via addEventHandler, it returns an index. You can use the index to reference the Eventhandler (usually for removal). These indices are different for each object and each type of eventhandler. The indices start at 0.
killedEH = player addEventHandler ["killed",{hint "You are dead!"}]; // returns 0
firedEH = player addEventHandler ["fired",{_this execVM "myScript.sqf"}]; // returns 0
killed2EH = player addEventHandler ["killed",{_this execVM "playerKilled.sqf"}]; // returns 1
fired2EH = tank1 addEventHandler ["fired",{_this execVM "tankFired.sqf"}]; // returns 0
**Removing Eventhandlers**
Simply refer to the type and index:
player removeEventHandler ["killed",0];
Removing an Eventhandler will decrease the indices of the other Eventhandlers of that type. So 0 will always refer to the next Eventhandler, until the object has no more Eventhandlers of that type.
You can also remove all Eventhandlers of a given type.
player removeAllEventHandlers "killed";
**Arguments**
Like most things in SQF, Eventhandlers reserve a special variable called _this. _this contains a set of arguments (in an array) that differs for each Eventhandler type. Usually (and I'm pretty sure for all of the current existing event types), the first argument is the object that the Eventhandler is attached to. The arguments are very useful, and allow you to get information specific to the cirumstances of the event that you otherwise could not.
You can pass these arguments on to a script as seen in the above indices examples.
**"Fired" Eventhandler**
One of the most (perhaps the most) commonly used Eventhandlers is the "fired" Eventhandler. It can be attached on vehicles or infantry units, and fires (no pun intended) every time the unit or vehicle fires any weapon. This includes hand grenades, mines, and satchel charges. It does not include car horns, and will only execute when a weapon is actually fired (so it excludes empty weapon "clicks").
There fired Eventhandler produces 5 arguments:
- Object that the Eventhandler is attached to (ie the firing object)
- The classname of the weapon that was fired
- The classname of the muzzle that was fired
- The classname of the mode that was fired
- The classname of the ammo that was fired
In many cases, when we use a fired Eventhandler, we want to get the actual projectile object that is created. You can easily do this by using the first and fifth arguments and the nearestObject command.
_projectile = nearestObject[_this select 0,_this select 4];
Now, depending on the speed of the projectile, sometimes you can "miss" it with nearestObject (which only searches in a 50m radius around the object it is called on) by the time the script reaches the command. You can avoid this by either calling your script as a function (I won't go into detail about this here) or by grabbing the projectile right inside the Eventhandler's initial scope, and then passing it to your script as an additional argument:
player addEventHandler ["fired",{_this+[nearestObject[_this select 0,_this select 1]] execVM "myScript.sqf"}];
This appends the projectile object to the end of the _this array, so you can access it in your script like so:
_projectile = _this select 5;