Extended Event Handlers (new) - CBATeam/CBA_A3 GitHub Wiki
Introduction
The Extended Event Handler system was originally created by Solus for Arma 1 and allows a virtually infinite amount of event handlers to be used together from different addons. The event handlers are executed for the matching class and all inheriting classes.
Normally event handlers can only be added in configs, and trying to add a new event handler caused all previous event handlers to be overwritten. This addon allows that limitation to be overcome. This is mostly useful for having addons that can add different functionality, for example visual effects and medical systems.
Once per mission event handlers
In addition to the normal set of game events that XEH can handle, you can create event handlers that run only once per game session. These are the PreInit and PostInit event handlers.
Extended_PreInit_EventHandlers
- The PreInit event handlers will run once at a point in time before all the mission units and vehicles have their own init event handlers processed.
class Extended_PreInit_EventHandlers {
class My_pre_init_event {
init = "call compile preprocessFileLineNumbers 'XEH_preInit.sqf'";
};
};
Extended_PostInit_EventHandlers
- The PostInit event handlers will run once and after all the units and vehicles have had both their init event handlers and the code in the mission editor "init" lines processed.
class Extended_PostInit_EventHandlers {
class My_post_init_event {
init = "call compile preprocessFileLineNumbers 'XEH_postInit.sqf'";
};
};
Extended_PreStart_EventHandlers
- The PreStart event handlers will run once per game session, before the main menu is shown.
- Note that these events are executed in
uiNamespace
by default. This is because their main purpose is to do function caching.
class Extended_PreStart_EventHandlers {
class My_event_on_game_start {
init = "diag_log isClass (configFile >> 'CfgPatches' >> 'CBA_Keybinding')";
};
};
Execution order
- in order of requiredAddons in CfgPatches
- mission after config.cpp
Event handlers related to objects
Extended_Init_EventHandlers
stub
class Extended_Init_EventHandlers {
class CAManBase {
class My_Soldier_init_eh {
init = "diag_log _this";
};
};
};
Extended_InitPost_EventHandlers
The InitPost is a special Extended Event Handler type that is similar to the usual Init event handler, but is executed at a later point after mission start.
- Executed after the extended PostInit event handlers
- Executed after all other Init event handlers
class Extended_InitPost_EventHandlers {
class Car_F {
class My_car_initpost_eh {
init = "systemChat str _this";
};
};
};
Extended_XX_EventHandlers
stub
class Extended_InventoryOpened_EventHandlers {
class CAManBase {
class My_Inventory_eh {
inventoryOpened = "hint 'you opened your inventory'";
};
};
};
class Extended_Engine_EventHandlers {
class Helicopter_F {
class My_chopper_engine_on_off_eh {
engine = "systemChat format ['The engines are now: ', ['off', 'on'] select (_this select 1)]";
};
};
};
Extended_FiredBIS_EventHandlers and Extended_Fired_EventHandlers
For historical reasons, the XEH fired event handler is special. To implement a "fired" event in XEH, you should use an Extended_FiredBIS_Eventhandlers
event handler.
Background
When the Extended Event Handler system was created back in the days of the first Arma game, a fired event handler passed the following five parameters by the game engine:
[unit, weapon, muzzle, mode, ammo]
The then-XEH fired event handler system added another item to the parameters passed - the actual projectile object that was just fired. That meant that an Arma XEH fired event was passed an array of the form
[unit, weapon, muzzle, mode, ammo, projectile]
Later, as XEH was ported to Arma II, this parameter form was kept for the XEH fired event. However, in A2, BIS added a magazine parameter to the fired event data:
[unit, weapon, muzzle, mode, ammo, magazine, projectile]
As you can see, that is different from the data the XEH fired event handler receives. For this reason, a new XEH firedBIS event handler was introduced in CBA for Arma 2. A Extended_FiredBIS_Eventhandlers
handler will be provided with exactly what the game engine in Arma 2 and Arma 3 gives it.
client and server prefix
One can limit the Extended Event Handlers to just clients or just servers by placing it in a server***
or client***
entry.
- Events with the client prefix will be executed on every machine, except on dedicated servers. (
!isDedicated
) - Events with the server prefix will be executed on only the server machine. (
isServer
)
clientInit = "diag_log 'You are a client'";
serverInit = "diag_log 'You are a server'";
exclude[]
You can exclude one or more subtypes of a vehicle from getting a certain Extended Event Handler. To do this, you add a directive, exclude, in an inner, Extended Event Handlers class.
class Extended_Init_EventHandlers {
class BWA3_recon_Radioman_Fleck {
class BWA3_GiveFleckRadio {
init = "[_this select 0, 'tf_rt1523g_big_bwmod'] call BWA3_fnc_addBackpackRadio;";
exclude = "BWA3_recon_Radioman_Tropen";
};
};
class BWA3_recon_Radioman_Tropen {
class BWA3_GiveTropenRadio {
init = "[_this select 0, 'tf_rt1523g_big_bwmod_tropen'] call BWA3_fnc_addBackpackRadio;";
};
};
};
Note: You can exclude multiple classes by using an array (exclude[] = {..., ...};
).
Emulation of object oriented inheritance
Similar to the exclude
entry, but more versatile. You can overwrite the event handler of a vehicles parent class by adding an Extended Event Handler with the same class name to a child class.
class CfgVehicles {
class BWA3_recon_Radioman_Fleck;
class BWA3_recon_Radioman_Tropen: BWA3_recon_Radioman_Fleck {};
};
class Extended_Init_EventHandlers {
class BWA3_recon_Radioman_Fleck {
class BWA3_GiveRadio {
init = "[_this select 0, 'tf_rt1523g_big_bwmod'] call BWA3_fnc_addBackpackRadio;";
};
};
class BWA3_recon_Radioman_Tropen {
class BWA3_GiveRadio {
init = "[_this select 0, 'tf_rt1523g_big_bwmod_tropen'] call BWA3_fnc_addBackpackRadio;";
};
};
};
Note that both add an action called BWA3_GiveRadio
. The "Tropen"-Retexture overwrites the back pack script from the "Fleck" parent class.
Locality of killed and respawn
The same limitations of the usual event handlers added via the addEventHandler
scripting command regarding locality also apply to Extended Event Handlers. Usually the events will be executed on every machine, but certain events require the assigned object to be local. The most common examples are the respawn
and the killed
events.
A full list can be found on the on the BI Arma Wiki.
Supported events
- AnimChanged
- AnimStateChanged
- AnimDone
- ContainerClosed
- ContainerOpened
- ControlsShifted
- Dammaged [sic]
- Engine
- EpeContact
- EpeContactEnd
- EpeContactStart
- Explosion
- Fired*
- FiredNear
- Fuel
- Gear
- GetIn
- GetInMan
- GetOut
- GetOutMan
- HandleHeal
- Hit
- HitPart
- IncomingMissile
- Init
- InventoryClosed
- InventoryOpened
- Killed
- LandedTouchDown
- LandedStopped
- Local
- Reloaded
- Respawn
- Put
- Take
- SeatSwitched
- SoundPlayed
- WeaponAssembled
- WeaponDisassembled
- WeaponDeployed
- WeaponRested
(*) See Extended_FiredBIS_EventHandlers
Custom events
- InitPost
- FiredBIS
Not supported events
- HandleDamage
- HandleRating
- HandleScore
- PostReset
- RopeAttach
- RopeBreak
- TaskSetAsCurrent
- Any of the MPEventHandlers (MPHit, MPKilled and MPRespawn)
The full list of events in Arma 3 can be seen here
In missions (mission makers)
Extended Event Handlers is not limited to just addons - mission makers can create Extended Event Handlers that appear in specific missions or a campaign by adding an Extended Event Handlers class in the mission or campaign 'description.ext' file.
class Extended_FiredBIS_Eventhandlers {
class B_Rifleman_F {
kls_test_fired = "(_this select 0) sideChat str _this";
};
};
Compatibility without dependance
Since CBA v2.3.0., you no longer have to make your addon dependant on CBA and can still fully support addons that require Extended Event Handlers.
- Inheriting the EventHandlers class.
If you inherit theEventHandlers
class from an already Extended Event Handlers compatible object, your object will be compatible as well.
class B_Soldier_base_F;
class B_Soldier_F: B_Soldier_base_F {
class EventHandlers;
};
class My_NATO_Retexture: B_Soldier_F {
...
class EventHandlers: EventHandlers {
init = "_this call My_randomizeHelmet";
};
};
- Inheriting the DefaultEventhandlers class.
If you inherit theDefaultEventhandlers
class (required by vehicles to trigger some particle effects when exploding or firing a weapon), your vehicle already supports CBA Extended Event Handlers!
class Plane {
class MyAwesome_StealthFighter: Plane {
...
class Eventhandlers: DefaultEventhandlers {};
};
- Adding the CBA_Extended_EventHandlers sub class
You can also manually add the Extended Event Handlers class to your object by inheriting the base class calledCBA_Extended_EventHandlers
inside theEventHandlers
class of your object. Note that this still does not require CBA to be loaded even though you are using this class.
class CBA_Extended_EventHandlers_base;
class CfgVehicles {
class C_man_1;
class MyAwesome_Civilian: C_man_1 {
...
class EventHandlers {
init = "_this call MyAwesome_fnc_addRandomEquipment";
class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers_base {};
};
};
};
Should an object not support Extended Event Handlers, the event handlers might never be executed. Starting the game with CBA will print RPT warnings that mention every incompatible object:
[XEH]: BWA3_Box_Gear does not support Extended Event Handlers! Addon: @bwa3
Using one of the three methods described above will make your objects compatible.
Removing Extended Event Handlers from a class
class CfgVehicles {
class My_CargoBox;
class My_CargoBox_Dummy: My_CargoBox {
class EventHandlers {
class CBA_Extended_EventHandlers {};
};
};
};
Event handlers related to displays
class Extended_DisplayLoad_EventHandlers {
class RscUnitInfo {
TAG_test_hudInit = "_this call TAG_fnc_hudOnLoad";
};
};
class Extended_DisplayUnload_EventHandlers {
class RscUnitInfo {
TAG_test_hudTerminate = "_this call TAG_fnc_hudOnUnload";
};
};