Events
CLEO Redux 1.0.6 adds initial support for event-driven scripting. This feature allows you to write scripts that react to events that happen in the game or another scripts.
Listening to events
A globally available addEventListener
function creates a new event listener. It takes two arguments: an event name and a function that will be called when the event is triggered (a callback).
The event name argument corresponds to built-in or custom event names.
The callback receives a single argument. This argument is a JavaScript object with two fields: name
(the event name) and data
(custom data associated with this event).
Event listeners only work in async context. Scripts willing to react to game events must not use a blocking
wait
function. UseasyncWait
instead.
addEventListener("OnVehicleCreate", (event) => {
log("A vehicle is created!");
log(event.name); // logs "OnVehicleCreate"
});
addEventListener
returns a function that can be used to stop listening to the event. This is useful when you want to stop listening to the event after a certain condition is met.
const cancel = addEventListener("OnVehicleCreate", (event) => {
log("A vehicle is created!");
});
// ...
cancel(); // the event callback won't be called anymore
List of events
The following documentation describes the Events.cleo plugin shipped with CLEO Redux 1.0.6+. Other plugins may add their own events. Events are game- and version- specific. Some of them might not be available on certain games or versions.
OnVehicleCreate
Triggered after the game creates a new vehicle of any type in the world. An event's data
object contains the address of the vehicle structure.
Supported in: re3
, reVC
, GTA III
, GTA VC
, GTA SA
, GTA III: DE (1.0.17.39540)
, GTA VC: DE (1.0.17.39540)
, GTA SA: DE (1.0.17.39540)
interface OnVehicleCreateEvent {
name: string;
data: {
address: int;
}
}
addEventListener("OnVehicleCreate", (event: OnVehicleCreateEvent) => {
const name = event.name;
log(`Event ${name} is triggered!`}); // logs "Event OnVehicleCreate is triggered!"
const address = event.data.address;
log("A vehicle is created! Its address is " + address); // logs "A vehicle is created! Its address is 0x12345678"
});
OnPedCreate
Triggered after the game creates a new ped of any type in the world. An event's data
object contains the address of the ped structure.
Supported in: re3
, reVC
, GTA III
, GTA VC
, GTA SA
, GTA III: DE (1.0.17.39540)
, GTA VC: DE (1.0.17.39540)
, GTA SA: DE (1.0.17.39540)
interface OnPedCreateEvent {
name: string;
data: {
address: int;
};
}
addEventListener("OnPedCreate", (event: OnPedCreateEvent) => {
const name = event.name;
log(`Event ${name} is triggered!`); // logs "Event OnPedCreate is triggered!"
const address = event.data.address;
log("A ped is created! Its address is " + address); // logs "A ped is created! Its address is 0x12345678"
});
OnObjectCreate
Triggered after the game creates a new object of any type in the world. An event's data
object contains the address of the object structure.
Supported in: re3
, reVC
, GTA III
, GTA VC
, GTA SA
, GTA III: DE (1.0.17.39540)
, GTA VC: DE (1.0.17.39540)
, GTA SA: DE (1.0.17.39540)
interface OnObjectCreateEvent {
name: string;
data: {
address: int;
};
}
addEventListener("OnObjectCreate", (event: OnObjectCreateEvent) => {
const name = event.name;
log(`Event ${name} is triggered!`); // logs "Event OnObjectCreate is triggered!"
const address = event.data.address;
log("An object is created! Its address is " + address); // logs "An object is created! Its address is 0x12345678"
});
OnVehicleDelete
Triggered before the game deletes a vehicle from the world. An event's data
object contains the address of the vehicle structure.
Supported in: re3
, reVC
, GTA III
, GTA VC
, GTA SA
, GTA III: DE (1.0.17.39540)
, GTA VC: DE (1.0.17.39540)
, GTA SA: DE (1.0.17.39540)
interface OnVehicleDeleteEvent {
name: string;
data: {
address: int;
};
}
addEventListener("OnVehicleDelete", (event: OnVehicleDeleteEvent) => {
const name = event.name;
log(`Event ${name} is triggered!`); // logs "Event OnVehicleDelete is triggered!"
const address = event.data.address;
log("A vehicle is about to be deleted! Its address is " + address); // logs "A vehicle is about to be deleted! Its address is 0x12345678"
});
OnPedDelete
Triggered before the game deletes a ped from the world. An event's data
object contains the address of the ped structure.
Supported in: re3
, reVC
, GTA III
, GTA VC
, GTA SA
, GTA III: DE (1.0.17.39540)
, GTA VC: DE (1.0.17.39540)
, GTA SA: DE (1.0.17.39540)
interface OnPedDeleteEvent {
name: string;
data: {
address: int;
};
}
addEventListener("OnPedDelete", (event: OnPedDeleteEvent) => {
const name = event.name;
log(`Event ${name} is triggered!`); // logs "Event OnPedDelete is triggered!"
const address = event.data.address;
log("A ped is about to be deleted! Its address is " + address); // logs "A ped is about to be deleted! Its address is 0x12345678"
});
OnObjectDelete
Triggered before the game deletes an object from the world. An event's data
object contains the address of the object structure.
Supported in: re3
, reVC
, GTA III
, GTA VC
, GTA SA
, GTA III: DE (1.0.17.39540)
, GTA VC: DE (1.0.17.39540)
, GTA SA: DE (1.0.17.39540)
interface OnObjectDeleteEvent {
name: string;
data: {
address: int;
};
}
addEventListener("OnObjectDelete", (event: OnObjectDeleteEvent) => {
const name = event.name;
log(`Event ${name} is triggered!`); // logs "Event OnObjectDelete is triggered!"
const address = event.data.address;
log("An object is about to be deleted! Its address is " + address); // logs "An object is about to be deleted! Its address is 0x12345678"
});
Creating your own events
CLEO Redux SDK provides a method called TriggerEvent
that can be used to emit a new event along with some payload. The plugin must decide when the event should be triggered (usually by hooking into a game function). See the Events.cleo plugin source code for an example.
TriggerEvent
has two parameters: an event name and a serialized JSON. It will be passed to the event listeners as the data
property of the event object.
Dispatching events from scripts
Dispatching events is a safe way for scripts to communicate with each other. For example, one script can dispatch an event when the player enters a specific area, and another script can listen to that event and perform some action. dispatchEvent
function creates a new custom event. It has the following signature:
function dispatchEvent(name: string, data: any): void;
The name
parameter is the name of the event to dispatch. It corresponds to the name
argument in addEventListener
. The data
is an optional payload that will be passed to the event listeners as the data
property of the event object. The payload can be any JSON-serializable value (e.g. functions are not allowed).
// Dispatch an event from a script
dispatchEvent("OnMyCustomEvent", { foo: "bar" });
// Listen to the event in a script
addEventListener("OnMyCustomEvent", (event) => {
log(event.data.foo); // logs "bar"
});
Using events in TypeScript
Both addEventListener
and dispatchEvent
are generic functions that can be used to type-check event names and payloads. The following example shows how to use them in TypeScript:
// Define an event payload
export interface WantedLevelChangeEvent {
oldWantedLevel: number;
newWantedLevel: number;
change: number;
}
// Dispatch an event
dispatchEvent<WantedLevelChangeEvent>("OnWantedLevelChange", {
oldWantedLevel: 0,
newWantedLevel: 1,
change: 1,
});
// Listen to the event
addEventListener<WantedLevelChangeEvent>("OnWantedLevelChange", (event) => {
log(event.data.oldWantedLevel); // logs 0
log(event.data.newWantedLevel); // logs 1
log(event.data.change); // logs 1
});
WantedLevelChangeEvent
type allows VS Code to provide auto-completion and type-checking for the event payload.