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. New : The EventInfo class provides a cleaner way to work with game events, with automatic resource management and typed methods.
With Classes (Recommended) Without Classes
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 */
}
public void RegisterEvents ()
{
HookEvent ( "player_death" , Event_PlayerDeath);
}
public static void Event_PlayerDeath ( string name , nint event , bool dontBroadcast )
{
// Use functions with explicit event handle
int victim = GetEventPlayerSlot (event, "userid" );
int attacker = GetEventPlayerSlot (event, "attacker" );
/* CODE */
}
You can bind event listeners in the OnPluginStart (or anywhere you like).
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);
}
}
#include <plg/plugin.hpp>
#include "s2sdk.hpp"
using namespace s2sdk ;
class Sample : public plg :: IPluginEntry {
public:
void OnPluginStart () override {
HookEvent ( "player_death" , []( const plg :: string & name , void* event , bool dontBroadcast ) -> ResultType {
int playerSlot = GetEventPlayerSlot (event, "userid" );
PrintToServer ( "event called. \n " );
return ResultType.Continue;
}, HookMode ::Post);
}
}
from plugify.plugin import Plugin
from plugify.pps import s2sdk as s2
class Sample ( Plugin ):
def plugin_start (self):
s2.HookEvent( "player_death" , lambda name, event, dontBroadcast: (
ResultType.Continue
after (
playerSlot := s2.GetEventPlayerSlot(event, "userid" ),
s2.PrintToServer( "event called. \n " )
)[ 1 ]
), s2.HookMode.Post)
package main
import (
" fmt "
" s2sdk "
" github.com/untrustedmodders/go-plugify "
)
func init () {
plugify. OnPluginStart ( func () {
s2sdk. HookEvent ( "player_death" , func ( name string , event uintptr , dontBroadcast bool ) {
playerSlot := s2sdk. GetEventPlayerSlot (event, "userid" );
s2sdk. PrintToServer ( "event called. \n " );
return s2sdk.ResultType.Continue;
}, s2sdk.HookMode.Post)
})
}
import { Plugin } from 'plugify' ;
import * as s2 from ':s2sdk' ;
export class Sample extends Plugin {
pluginStart () {
s2. HookEvent ( "player_death" , ( name , event , dontBroadcast ) => {
const playerSlot = s2. GetEventPlayerSlot (event, "userid" );
s2. PrintToServer ( "event called. \n " );
return s2.ResultType.Continue;
}, s2.HookMode.Post);
}
}
local plugify = require 'plugify'
local Plugin = plugify. Plugin
local s2 = require 's2sdk'
local Sample = {}
setmetatable (Sample, { __index = Plugin })
function Sample : plugin_start ()
s2 : HookEvent ( "player_death" , function (name, event, dontBroadcast)
local playerSlot = s2 : GetEventPlayerSlot (event, "userid" );
s2 : PrintToServer ( "event called. \n " );
return s2 : ResultType . Continue ;
end , s2. HookMode . Post )
end
local M = {}
M. Sample = Sample
return M
With Classes (Recommended) Without Classes
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);
Access event parameters using explicit functions with the event handle:
// Reading event parameters
int playerSlot = GetEventPlayerSlot (event, "userid" );
float damage = GetEventFloat (event, "damage" );
string weaponName = GetEventString (event, "weapon" );
bool headshot = GetEventBool (event, "headshot" );
// Get entity references
nint playerController = GetEventPlayerController (event, "userid" );
nint playerPawn = GetEventPlayerPawn (event, "userid" );
nint entity = GetEventEntity (event, "entityid" );
Setting event parameters requires explicit function calls:
// Setting event parameters
SetEventInt (event, "userid" , 123 );
SetEventFloat (event, "damage" , 50.0f );
SetEventString (event, "weapon" , "ak47" );
SetEventBool (event, "headshot" , true );
// Set entity references
SetEventPlayerController (event, "userid" , controllerHandle);
SetEventEntity (event, "entityid" , entityHandle);
With Classes (Recommended) Without Classes
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
Create and fire custom events using explicit functions:
// Create a new event
nint customEvent = CreateEvent ( "player_hurt" );
// Set event parameters
SetEventInt (customEvent, "userid" , 1 );
SetEventInt (customEvent, "attacker" , 2 );
SetEventInt (customEvent, "health" , 50 );
SetEventString (customEvent, "weapon" , "ak47" );
// Fire to all players
FireEvent (customEvent);
// Or fire to specific player
FireEventToClient (customEvent, playerSlot);
// Note: Event is automatically freed after firing
With Classes (Recommended) Without Classes
Prevent an event from being broadcast to clients:
event. SetBroadcast ( false );
Prevent an event from being broadcast to clients:
SetEventBroadcast (event, false );
In a pre-event hook, you can prevent the event from continuing to other plugins by returning ResultType.Handled or ResultType.Stop.
With Classes (Recommended) Without Classes
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;
}
public void OnPluginStart ()
{
HookEvent ( "player_death" , OnPlayerDeathPre, HookMode.Pre);
}
private static ResultType OnPlayerDeathPre ( string name , nint event , bool dontBroadcast )
{
int victim = GetEventPlayerSlot (event, "userid" );
// Cancel death event for admin players
if ( IsPlayerAdmin (victim))
{
PrintToServer ( "Prevented admin death event \n " );
return ResultType.Handled;
}
return ResultType.Continue;
}