Skip to content

Hero-Specific Plugins#

Create plugins that only activate for a particular hero.

Declaring a Hero-Specific Plugin#

Set the targetHeroId and add the HeroSpecific flag:

XENON_PLUGIN_INFO(
    "widow_aim",
    "Widow Aim",
    "Author",
    "Aim assist for Widowmaker",
    "1.0",
    HeroId::Widowmaker,
    PluginFlags::HasOverlay | PluginFlags::HasMenu | PluginFlags::HeroSpecific
)

The host will only load your plugin's on_render, on_frame, and on_menu when the local player is playing the specified hero.

on_hero_changed#

React to hero switches:

static bool g_isScoped = false;

extern "C" void on_hero_changed(uint64_t heroId)
{
    g_isScoped = false;  // Reset state on hero change

    if (heroId == HeroId::Widowmaker)
        Log("Widowmaker selected — plugin active");
}

This is called whenever the local player's hero changes, including at the start of a match.

HeroId Constants#

All hero IDs are in xenon::HeroId. See the full list in Constants.

Common examples:

HeroId::Widowmaker
HeroId::Ana
HeroId::Hanzo
HeroId::Soldier76
HeroId::Cassidy

Checking Enemy Heroes#

You can check any entity's hero, not just the local player:

for (Entity player : Players())
{
    if (!player.IsEnemy()) continue;
    if (player.GetHeroId() == HeroId::Mercy)
    {
        // Highlight Mercy
        Vector2 screen;
        if (WorldToScreen(player.GetBonePos(Bone::Head), screen))
            Draw::CircleFilled(screen, 8.f, Color::Yellow());
    }
}

Universal vs. Hero-Specific#

Universal Hero-Specific
targetHeroId 0 HeroId::*
PluginFlags::HeroSpecific Not set Set
Active when Always Only on the specified hero
on_hero_changed Still called Still called

See Also#