Mod:Creation Kit/Custom Papyrus Events

Custom events allow any script in the game to send an event which any number of scripts can then receive. The receivers have to register with the sender, but the sender doesn't have to know about the receivers or manage them in any way. One way this could be used would be having an actor register to receive an event from a controlling script whenever it enters a location, and unregister when they leave. Then the controller script could send the event, and all actors in that location that register would get it without having to maintain any complicated list or setting up a bunch of aliases.

=How to Register= Registration is easy, just use the RegisterForCustomEvent function. Pass it the object you want to receive events from, and the name of the event you want to receive. Then, until you unregister (or are unregistered by the game) your specially-defined custom event will be triggered whenever source sends the event. Note that you must pass the event name to the function as a raw string, and cannot pass it a variable.

Examples
RegisterForCustomEvent(EarthquakeMarker, "Earthquake")
 * We want to know when the marker sends out an earthquake event

RegisterForCustomEvent(AmbushTrigger, "Ambush")
 * We want to know when a trigger wants us to spring an ambush

string myEvent = "Ambush" RegisterForCustomEvent(AmbushTrigger, myEvent)
 * This will fail to compile because you cannot pass a variable as the event name
 * (even though the variable's value contains a valid event name)

=How to Unregister= To stop receiving events, use the UnregisterForCustomEvent function. You will then no longer receive the specified event from the specified source object. You will be unregistered automatically if you are on an active magic effect which is removed, or are on a quest or alias when the quest restarts. Like the register call, you must pass the event name to the function as a raw string, and cannot pass it a variable.

Examples
UnregisterForCustomEvent(EarthquakeMarker, "Earthquake")
 * We no longer want to know when the marker sends out an earthquake event

UnregisterForCustomEvent(AmbushTrigger, "Ambush")
 * We no longer want to know when a trigger says to ambush

=How to Handle the Event= To handle the event, you'll need to define the event in your script in a special form. The event you define must have a name that consists of the script that the event comes from, followed by a dot, then followed by the name of the event itself. The two parameters the event receives are one of the same type as the script the event comes from, which will contain the event's sender, and a var array which will contain any parameters.

Note that the type used in the event name and in the first parameter of the event must contain the custom event definition.

In most cases, the compiler should catch any errors in the definition and give you a bit of advice on fixing the issue.

Examples
Event AmbushTriggerScript.Ambush(AmbushTriggerScript akSender, Var[] akArgs) Debug.Trace("Got Ambush event for " + akSender + " with arguments: " + akArgs) ; Whoever sends the event says that they send the target of the ambush as the first parameter, and the delay as the second one if (akArgs.Length == 2) Actor ktarget = akArgs[0] as Actor ; For objects, doing "as" and checking for None is faster then "Is" followed by "as" if ktarget && akArgs[1] is float float fdelay = akArgs[1] as float Debug.Trace("We are targeting: " + ktarget + " after " + fdelay + " seconds") endif endif EndEvent
 * This event is called when our trigger sends the ambush event. The trigger that sent the event is in the parameter

Event AmbushTriggerScript.Ambush(ObjectReference akSender, Var[] akArgs) Debug.Trace("Got Ambush event for " + akSender) EndEvent
 * This event will fail to compile because the type of the first parameter does not match the type in the
 * event name.

Event AmbushTriggerScript.Ambush(AmbushTriggerScript akSender, int aiParam1) Debug.Trace("Got Ambush event for " + akSender) EndEvent
 * This event will fail to compile because the parameters aren't the right type

=How to Define a Custom Event= In order for your script to send a custom event, it must define it. This is done similarly to a variable, but using "CustomEvent" rather then the variable type. You cannot name an event the same name as another function or event in your script or your parent script.

Examples
CustomEvent Ambush
 * Defines a custom event that this script can send called Ambush

=How to Send a Custom Event= To send a custom event, use the SendCustomEvent function. The two parameters are the raw string of the event to send (you cannot pass it a string variable) and an optional array of parameters. The compiler will make sure the event is defined in your own script, or in a parent script. The function will then return immediately and not wait for any scripts handling the event (if any) to finish. The sender given to the scripts that are listening is the object the SendCustomEvent function is called on, even if it's called from another script.

Examples

 * Assuming we've defined the Ambush event like above and we want to send the target as the first parameter and a delay as the second

Var[] kargs = new Var[2] kargs[0] = kTargetActor kargs[1] = 5.25 SendCustomEvent("Ambush", kargs)
 * Send the ambush event, passing ourselves as the sender

OtherTrigger.SendCustomEvent("Ambush")
 * Send the ambush event from the other trigger, the other trigger will be given as the sender, this time with no arguments

string myEvent = "Ambush" SendCustomEvent(myEvent)
 * Cannot use a variable, so this won't compile

=Additional Notes=
 * You cannot call the custom events directly in script. If you want the functionality to be shared, you should probably look at encapsulating the functionality in a separate function, which the custom event then calls.

=See Also=
 * Mod:Creation Kit/RegisterForCustomEvent - ScriptObject
 * Mod:Creation Kit/SendCustomEvent - ScriptObject
 * Mod:Creation Kit/UnregisterForCustomEvent - ScriptObject
 * Mod:Creation Kit/Events Reference