Zone Event Callbacks#

Zone event callbacks fire whenever a player enters or exits any zone, regardless of zone type.

Interface#

class ZoneEventCallback
{
    // Called when a player enters any zone
    // @param player - The player entering the zone
    // @param zone - The zone being entered
    void OnZoneEnter(PlayerBase player, ZoneBase zone) {}
    
    // Called when a player exits any zone
    // @param player - The player exiting the zone
    // @param zone - The zone being exited
    void OnZoneExit(PlayerBase player, ZoneBase zone) {}
}

Registration#

Server-side only (zone events are server-side):

// In your mod's MissionServer.c file
modded class MissionServer
{
    override void OnInit()
    {
        super.OnInit();
        
        // Create and register the callback
        MyZoneCallback myCallback = new MyZoneCallback();
        PlayerZoneController.RegisterZoneEventCallback(myCallback);
    }
}

// Define your callback class
class MyZoneCallback : ZoneEventCallback
{
    override void OnZoneEnter(PlayerBase player, ZoneBase zone)
    {
        if (!player || !zone)
            return;
        
        string zoneName = zone.GetName();
        string playerName = "Unknown";
        if (player.GetIdentity())
            playerName = player.GetIdentity().GetName();
        
        // Your custom logic here (e.g., play sound, send notification)
        Print("[MyMod] " + playerName + " entered zone: " + zoneName);
    }
    
    override void OnZoneExit(PlayerBase player, ZoneBase zone)
    {
        if (!player || !zone)
            return;
        
        // Your custom logic here
    }
}

Unregistration#

PlayerZoneController.UnregisterZoneEventCallback(myCallback);

Example Code and Output#

Here's a complete example showing how to implement a zone event callback and what the output looks like:

Code:

// In your mod's MissionServer.c file
modded class MissionServer
{
    override void OnInit()
    {
        super.OnInit();
        
        // Create and register the callback
        MyZoneCallback myCallback = new MyZoneCallback();
        PlayerZoneController.RegisterZoneEventCallback(myCallback);
    }
}

// Define your callback class
class MyZoneCallback : ZoneEventCallback
{
    override void OnZoneEnter(PlayerBase player, ZoneBase zone)
    {
        if (!player || !zone)
            return;
        
        string zoneName = zone.GetName();
        string playerName = "Unknown";
        if (player.GetIdentity())
            playerName = player.GetIdentity().GetName();
        
        string zoneType = "Unknown";
        switch (zone.type)
        {
            case ZONE_TYPE_PVP: zoneType = "PvP"; break;
            case ZONE_TYPE_PVE: zoneType = "PvE"; break;
            case ZONE_TYPE_RAID: zoneType = "Raid"; break;
            case ZONE_TYPE_SAFEZONE: zoneType = "SafeZone"; break;
            case ZONE_TYPE_VISUAL: zoneType = "Visual"; break;
            case ZONE_TYPE_PAINTBALL: zoneType = "Paintball"; break;
        }
        
        Print("[MyMod] ===== ZONE ENTER =====");
        Print("[MyMod] Player: " + playerName);
        Print("[MyMod] Zone Name: " + zoneName);
        Print("[MyMod] Zone Type: " + zoneType);
        Print("[MyMod] Zone Priority: " + zone.priority);
        Print("[MyMod] ======================");
    }
    
    override void OnZoneExit(PlayerBase player, ZoneBase zone)
    {
        if (!player || !zone)
            return;
        
        string zoneName = zone.GetName();
        string playerName = "Unknown";
        if (player.GetIdentity())
            playerName = player.GetIdentity().GetName();
        
        string zoneType = "Unknown";
        switch (zone.type)
        {
            case ZONE_TYPE_PVP: zoneType = "PvP"; break;
            case ZONE_TYPE_PVE: zoneType = "PvE"; break;
            case ZONE_TYPE_RAID: zoneType = "Raid"; break;
            case ZONE_TYPE_SAFEZONE: zoneType = "SafeZone"; break;
            case ZONE_TYPE_VISUAL: zoneType = "Visual"; break;
            case ZONE_TYPE_PAINTBALL: zoneType = "Paintball"; break;
        }
        
        Print("[MyMod] ===== ZONE EXIT =====");
        Print("[MyMod] Player: " + playerName);
        Print("[MyMod] Zone Name: " + zoneName);
        Print("[MyMod] Zone Type: " + zoneType);
        Print("[MyMod] Zone Priority: " + zone.priority);
        Print("[MyMod] ======================");
    }
}

Output (from server log):

[ZoneCallback] Calling OnZoneEnter for zone: Zone 2
[MyMod] ===== ZONE ENTER =====
[MyMod] Player: Survivor
[MyMod] Zone Name: Zone 2
[MyMod] Zone Type: PvP
[MyMod] Zone Priority: 10
[MyMod] ======================

[ZoneCallback] Calling OnZoneExit for zone: Zone 2
[MyMod] ===== ZONE EXIT =====
[MyMod] Player: Survivor
[MyMod] Zone Name: Zone 2
[MyMod] Zone Type: PvP
[MyMod] Zone Priority: 10
[MyMod] ======================

This example shows a player named "Survivor" entering and exiting "Zone 2", which is a PvP zone with priority 10. Your callback receives the PlayerBase and ZoneBase objects, allowing you to access all zone information dynamically.

Use Cases#