Custom Events System - CBATeam/CBA_A3 GitHub Wiki

Custom Events System

What are custom events?

Custom events offer a way to manage your own events in a similar way to public variable events. However, the key thing is that they are easier to use and also manage events on a local level as well as remotely.

Custom events are never handled on JIP (Unless you are using CBA_fnc_globalEventJIP). That is, all events broadcast before a player joins are not handled, since they would be out-of-date. For state-changes, which you would want synced on JIP, use the standard publicVariable and addPublicVariableEventHandler commands instead.

Registering a handler for custom events

private _id = ["tag_testEvent", {systemChat str _this}] call CBA_fnc_addEventHandler;

Raise custom events

["tag_testEvent", "test message local"] call CBA_fnc_localEvent;

  • CBA_fnc_serverEvent: Raise an event which will be handled on only the server machine. The event will be executed in singleplayer mode.
["tag_testEvent", "test message server"] call CBA_fnc_serverEvent;

  • CBA_fnc_globalEvent: Raise an event which will be handled on all machines, including the local one.
["tag_testEvent", "test message global"] call CBA_fnc_globalEvent;

  • CBA_fnc_globalEventJIP: Raise an event which will be handled on all machines, including the local one. The event will also be executed on a client that joins in progress. The function returns an ID-string that can be used to overwrite the generated JIP-stack.
["tag_testEvent", "test message global (JIP)"] call CBA_fnc_globalEventJIP;

private _jipId = ["tag_testEvent", "test message global (JIP)"] call CBA_fnc_globalEventJIP;

[_jipId] call CBA_fnc_removeGlobalEventJIP;
[_jipId, _object] call CBA_fnc_removeGlobalEventJIP; // remove from JIP stack once _object is deleted

  • CBA_fnc_remoteEvent: Raise an event which will be handled on every other machine except the local one. The event will never be executed in singleplayer mode.
["tag_testEvent", "test message remote"] call CBA_fnc_remoteEvent;

  • CBA_fnc_targetEvent: Raise an event which will be handled on all machines where at least one provided "target" is local. The targets can be objects and/or groups. The event will only be executed once per function call, even if multiple local targets are provided.
["tag_testEvent", "test message target 1", cursorObject] call CBA_fnc_targetEvent;
["tag_testEvent", "test message target 2", [player, cursorObject]] call CBA_fnc_targetEvent;

  • CBA_fnc_turretEvent: Raise an event which will be handled on the machine where the provided turret on the provided vehicle is local.
["tag_testEvent", "test message turret", cursorObject, [0]] call CBA_fnc_turretEvent;

Parameter data type limitations

Only the following data types can be passed as arguments: <BOOLEAN>, <NUMBER>, <STRING>, <OBJECT>, <GROUP>, <TEAM_MEMBER>, <CODE> or <ARRAY>s consisting of any combination of these.

Naming custom events

Ensure that you use OFPEC tags in the naming of events, such as "MYTAG_barrelsExploded" if your tag was "MYTAG". This will prevent receipt of unexpected events from other users of the custom events system.

Using CBA's default events

CBA has a number of events that it routinely raises and any script can add a handler and deal with them.

["CBA_loadingScreenDone", {
    systemChat "Loading Screen Done.";
}] call CBA_fnc_addEventHandler;

["CBA_layoutEditorSaved", {
    systemChat "Layout Editor Saved.";
}] call CBA_fnc_addEventHandler;

["CBA_beforeSettingsInitialized", {
    diag_log text "Before Settings Initialized.";
}] call CBA_fnc_addEventHandler;

["CBA_SettingsInitialized", {
    diag_log text "Settings Initialized.";
}] call CBA_fnc_addEventHandler;

["CBA_SettingChanged", {
    params ["_setting", "_value"];
    systemChat format ["Setting %1 has now value %2.", _setting, _value];
}] call CBA_fnc_addEventHandler;

["CBA_attachmentSwitched", {
    params ["_unit", "_oldItem", "_newItem", "_currentWeaponType"];
    systemChat "Attachment Switched by script.";
}] call CBA_fnc_addEventHandler;

Examples

MP sideChat

sideChat is a command that only has an effect on clients, so rather than check whether we are on a client in the handler, it is best to only add handlers on client machines:

if (hasInterface) then {
    ["mySideChat", { (_this select 0) sideChat (_this select 1) }] call CBA_fnc_addEventHandler;
};

Later, we want everyone to see a sideChat message:

["mySideChat", [player, "Hello, nerds!"]] call CBA_fnc_globalEvent;

Running code without passing parameters

There is no requirement to pass parameters with the event. If no parameters are passed, then the receiving handler will not be passed _this.

Since we only want to create the vehicle on the server, it makes sense to only add a handler on the server:

if (isServer) then {
    ["mySummonUAZ", { "uaz" createVehicle (getMarkerPos "base") }] call CBA_fnc_addEventHandler;
};

Later, the player wants to create a UAZ (perhaps via an action) and runs:

["mySummonUAZ"] call CBA_fnc_globalEvent;

By broadcasting a global, rather than remote event, CBA guarantees that the server handles it, even if we are running as the MP host.

Service Bus

Using CBA's addEventhandler, globalEvent, localEvent, remoteEvent, serverEvent and targetEvent could be used to send localised messages to particular clients in the form of a service bus. This would assist in controlling communications between core and modules, and module to module comms.

⚠️ **GitHub.com Fallback** ⚠️