Game Events

How to listen to Source 2 style game events.

Overview

Events are informational notification messages passed between objects in the server. Many are also passed from the server to the client. They are defined in .res files under the hl2/resource folder and resource folders of specific mods. For a basic listing, see Source2 Game Events.

It is important to note a few concepts about events:

  • They are almost always informational. That is, blocking player_death will not stop a player from dying. It may block a HUD or console message or something else minor.
  • Just because it is in a resource file does not mean it is ever called, or works the way you expect it to.

Quick Example: Player Death Event

public void RegisterEvents()
{
    HookEvent("player_death", Event_PlayerDeath);
}

public static void Event_PlayerDeath(string name, nint @event, bool dontBroadcast)
{
    EventInfo event = new EventInfo(@event);
    
    // Use typed methods on the EventInfo instance
    int victim_id = event.GetPlayerSlot("userid");
    int attacker_id = event.GetPlayerSlot("attacker");

    int victim = victim_id + 1;
    int attacker = attacker_id + 1;

    /* CODE */
}

Adding an Event Listener

You can bind event listeners in the OnPluginStart (or anywhere you like).

c#
c++
python
go
js
lua
using Plugify;
using static s2sdk.s2sdk;

public unsafe class Sample : Plugin
{
    public void OnPluginStart()
    {
        HookEvent("player_death", (string name, nint event, bool dontBroadcast) =>
        {
            int playerSlot = GetEventPlayerSlot(event, "userid");
            PrintToServer("event called.\n");
            return ResultType.Continue;
        }, HookMode.Post);
    }
}

Accessing Event Parameters

Access event parameters using typed methods on the EventInfo instance:

// Reading event parameters
int playerSlot = event.GetPlayerSlot("userid");
float damage = event.GetFloat("damage");
string weaponName = event.GetString("weapon");
bool headshot = event.GetBool("headshot");

// Get entity references
nint playerController = event.GetPlayerController("userid");
nint playerPawn = event.GetPlayerPawn("userid");
nint entity = event.GetEntity("entityid");

Setting event parameters is equally simple:

// Setting event parameters
event.SetInt("userid", 123);
event.SetFloat("damage", 50.0f);
event.SetString("weapon", "ak47");
event.SetBool("headshot", true);

// Set entity references
event.SetPlayerController("userid", controllerHandle);
event.SetEntity("entityid", entityHandle);

Creating and Firing Events

Create and fire custom events using the EventInfo class:

// Create a new event
using (var customEvent = new EventInfo("player_hurt"))
{
    // Set event parameters
    customEvent.SetInt("userid", 1);
    customEvent.SetInt("attacker", 2);
    customEvent.SetInt("health", 50);
    customEvent.SetString("weapon", "ak47");

    // Fire to all players
    customEvent.Fire();

    // Or fire to specific player
    customEvent.FireToClient(playerSlot);
} // Automatically cleaned up

Preventing Broadcast

Prevent an event from being broadcast to clients:

event.SetBroadcast(false);

Cancelling an Event

In a pre-event hook, you can prevent the event from continuing to other plugins by returning ResultType.Handled or ResultType.Stop.

public void OnPluginStart()
{
    HookEvent("player_death", OnPlayerDeathPre, HookMode.Pre);
}

private static ResultType OnPlayerDeathPre(string name, nint @event, bool dontBroadcast)
{
    EventInfo event = new EventInfo(@event);
    int victim = event.GetPlayerSlot("userid");

    // Cancel death event for admin players
    if (IsPlayerAdmin(victim))
    {
        PrintToServer("Prevented admin death event\n");
        return ResultType.Handled;
    }

    return ResultType.Continue;
}