Game Events
Namespace:
DeadworksManaged.Api
A game event is a notice the game sends out when something happens: a player dies, picks a hero, or uses an ability. Your plugin can listen for any of them.
Find an event
The event database lists every event in the game. Each event has its own page, such as player_death, that shows its fields.
Some useful ones:
player_deathwhen a hero diesplayer_respawnedwhen a player respawnsplayer_hero_changedwhen a player picks or changes heroplayer_used_abilitywhen a player uses an ability, shoots or meleesability_addedwhen a player gets an ability or an item
Run code when an event happens
Put [GameEventHandler] on a method, with the event's name. Every event has a class to go with it.
[GameEventHandler("player_hero_changed")]
public HookResult OnPlayerHeroChanged(PlayerHeroChangedEvent args)
{
var pawn = args.Userid?.As<CCitadelPlayerPawn>();
if (pawn == null) return HookResult.Continue;
// The player has a hero now
return HookResult.Continue;
}
Run code when a player dies
[GameEventHandler("player_death")]
public HookResult OnPlayerDeath(PlayerDeathEvent args)
{
var victim = args.UseridController;
var killer = args.AttackerController;
// killer is null when they weren't killed by a player
if (victim == null || killer == null) return HookResult.Continue;
Console.WriteLine($"{killer.PlayerName} killed {victim.PlayerName}");
if (args.Headshot)
Console.WriteLine("It was a headshot.");
return HookResult.Continue;
}
args.UseridPawn and args.AttackerPawn are their heroes.
Run code when a player spawns
Listen for player_respawned. It fires each time a player comes back to life.
[GameEventHandler("player_respawned")]
public HookResult OnPlayerRespawned(PlayerRespawnedEvent args)
{
var pawn = args.Userid?.As<CCitadelPlayerPawn>();
if (pawn == null) return HookResult.Continue;
pawn.Teleport(position: new Vector3(100, 200, 300));
return HookResult.Continue;
}
Don't use player_spawn for this. The first time a player joins, it fires before their hero is ready.
Run code when a player uses an ability
[GameEventHandler("player_used_ability")]
public HookResult OnPlayerUsedAbility(PlayerUsedAbilityEvent args)
{
var pawn = args.Player?.As<CCitadelPlayerPawn>();
if (pawn == null) return HookResult.Continue;
Console.WriteLine($"{pawn.Controller?.PlayerName} used {args.Abilityname}");
return HookResult.Continue;
}
The abilities database lists every ability name.
Run code when a player attacks
player_used_ability also fires for gunshots and melee hits.
[GameEventHandler("player_used_ability")]
public HookResult OnPlayerAttacked(PlayerUsedAbilityEvent args)
{
if (args.Abilityname.StartsWith("citadel_weapon_"))
{
// They fired their gun
}
if (args.Annotation == "heavy_melee")
{
// They did a heavy melee
}
if (args.Annotation == "light_melee")
{
// They did a light melee
}
return HookResult.Continue;
}
Run code when a player gets an item
ability_added fires for abilities and items. Item names start with upgrade_.
[GameEventHandler("ability_added")]
public HookResult OnAbilityAdded(AbilityAddedEvent args)
{
var pawn = args.Userid?.As<CCitadelPlayerPawn>();
var name = args.Ability?.SubclassVData?.Name;
if (pawn == null || name == null) return HookResult.Continue;
if (name == "upgrade_unstoppable")
Console.WriteLine($"{pawn.Controller?.PlayerName} got Unstoppable!");
return HookResult.Continue;
}
Read an event's fields by name
You don't normally need to do this. The event's class already has a property for each field. Only do it when an event has no class, or its class has a field typed wrong.
Take a GameEvent and read each field by its name. The names are on the event's database page, and capitals matter.
[GameEventHandler("player_used_ability")]
public HookResult OnAbility(GameEvent ev)
{
var name = ev.GetString("abilityname", "");
Console.WriteLine($"Someone used {name}");
return HookResult.Continue;
}
There is a GetInt, GetFloat, GetBool, GetPlayerPawn, GetPlayerController and GetEHandle too.
Fire an event yourself
Create one of the game's events, fill in its fields, and fire it.
var ev = GameEvents.Create("player_hintmessage");
if (ev != null)
{
ev.SetString("hintmessage", "Hello");
ev.Fire();
}
Create returns null when the game has no event with that name, so you can't make up new ones. Don't use ev again after Fire().