Skip to content
RustPluginGenerator

OnVehicleHornPressed

OnVehicleHornPressed is called when a seated player presses the horn key on a vehicle whose seating module supports a horn.

Signature
void OnVehicleHornPressed(VehicleModuleSeating vehicleModuleSeating, BasePlayer player)

Parameters

Hook parameters
ParameterTypeDescription
vehicleModuleSeatingVehicleModuleSeatingThe VehicleModuleSeating module the player is currently seated in. Use vehicleModuleSeating.VehicleParent() to reach the vehicle entity when you need its position or type.
playerBasePlayerThe BasePlayer who pressed the horn key while seated. Already validated as connected by the game before the call, but null-check it anyway.

Return value

Returning a value has no effect: the hook is called with the return value discarded, and the game proceeds to set hornPlayer and send the horn flag exactly as if the hook did not exist. You cannot cancel the horn from this hook.

How it works

This hook fires from VehicleModuleSeating.PlayerServerInput at the moment the game registers a horn press and has decided to set the horn flag on the module. It is the same code path that later records hornPlayer and sends the horn network update, so the hook runs every time a player taps the horn key in a vehicle seat that has a horn (cars, minicopters, boats and similar modular vehicles). The seating module argument is the module entity itself, which is a child of the vehicle; player is the driver or passenger who pressed the key. Declaring the seating parameter as a more specific type does nothing useful here because the game only passes VehicleModuleSeating, but you can filter by player type or by checking which vehicle the module belongs to. Use it for cooldown checks, chat or console feedback, CUI prompts, or to drive server events when a horn sounds. The return value is ignored, so the press always continues into the vanilla horn handling.

Example plugin: Horn cooldown with chat feedback

VehicleHornCooldown.cs
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
using UnityEngine;

namespace Oxide.Plugins
{
    [Info("VehicleHornCooldown", "RustPluginGenerator", "1.0.0")]
    [Description("Rate-limits horn presses on vehicles with a configurable cooldown and chat feedback.")]
    public class VehicleHornCooldown : RustPlugin
    {
        private const string PermUse = "vehiclehorncooldown.use";

        private class PluginConfig
        {
            [JsonProperty("Cooldown seconds")]
            public float CooldownSeconds = 3f;

            [JsonProperty("Max warnings before silent")]
            public int MaxWarnings = 5;

            [JsonProperty("Send console note")]
            public bool ConsoleNote = true;
        }

        private PluginConfig config;
        private readonly Dictionary<ulong, float> lastPress = new Dictionary<ulong, float>();
        private readonly Dictionary<ulong, int> warningCount = new Dictionary<ulong, int>();

        protected override void LoadDefaultConfig() => config = new PluginConfig();

        protected override void LoadConfig()
        {
            base.LoadConfig();
            try
            {
                config = Config.ReadObject<PluginConfig>();
                if (config == null) throw new Exception();
            }
            catch
            {
                PrintWarning("Configuration file is invalid, using defaults");
                LoadDefaultConfig();
            }
            SaveConfig();
        }

        protected override void SaveConfig() => Config.WriteObject(config);

        protected override void LoadDefaultMessages()
        {
            lang.RegisterMessages(new Dictionary<string, string>
            {
                ["Cooldown"] = "Horn is cooling down: {0:0.0}s remaining.",
                ["Count"] = "You have honked {0} times in this session.",
                ["Permission"] = "You do not have permission to use the horn."
            }, this);
        }

        private string Msg(string key, string userId = null, params object[] args) =>
            string.Format(lang.GetMessage(key, this, userId), args);

        private void Init()
        {
            permission.RegisterPermission(PermUse, this);
        }

        private void OnVehicleHornPressed(VehicleModuleSeating vehicleModuleSeating, BasePlayer player)
        {
            if (player == null || vehicleModuleSeating == null || vehicleModuleSeating.IsDestroyed) return;

            string userId = player.UserIDString;
            if (!permission.UserHasPermission(userId, PermUse))
            {
                player.ChatMessage(Msg("Permission", userId));
                return;
            }

            float now = Time.realtimeSinceStartup;
            float last;
            if (lastPress.TryGetValue(player.userID, out last))
            {
                float remaining = config.CooldownSeconds - (now - last);
                if (remaining > 0f)
                {
                    int warnings;
                    warningCount.TryGetValue(player.userID, out warnings);
                    if (warnings < config.MaxWarnings)
                    {
                        player.ChatMessage(Msg("Cooldown", userId, remaining));
                        warningCount[player.userID] = warnings + 1;
                    }
                    return;
                }
            }

            lastPress[player.userID] = now;
            warningCount.Remove(player.userID);

            if (config.ConsoleNote)
                player.SendConsoleCommand("echo " + Msg("Count", userId, lastPress.Count));
        }

        private void Unload()
        {
            lastPress.Clear();
            warningCount.Clear();
        }
    }
}

The plugin stores a per-player timestamp of the last horn press in memory. When OnVehicleHornPressed fires, it compares Time.realtimeSinceStartup against the configured cooldown and, if the player is pressing too often, sends a localized chat message with the remaining seconds. A separate dictionary tracks horn counts per player so admins can see who is spamming; the count is cut off with a configurable MaxWarnings value so the chat does not get flooded. Unload clears the dictionaries, and the config lets an admin choose the cooldown length and whether the notification should be a chat message or just a console note. It is small but shows how to react to the horn event without blocking the vanilla horn sound.

Common use cases

  • Rate-limit horn spam

    Track the last press time per player and send a chat reminder when they exceed a configurable cooldown. The vanilla horn still plays, so this only changes the feedback.

  • Reward passengers for honking

    Give a small item or currency deposit when a player honks while driving a specific vehicle type, using a cooldown so it cannot be farmed.

  • Broadcast vehicle events

    Send a server-wide message or UI prompt to nearby players when someone honks, useful for roleplay or racing servers where the horn signals an event.

Pitfalls

  • You cannot cancel the horn

    The hook uses continue semantics, so returning false or any other value does nothing. The game still sets hornPlayer and sends the horn flag after the hook returns.

  • The module may be destroyed

    If the vehicle is destroyed or the player dismounts between frames, the seating module can be null or destroyed. Always check vehicleModuleSeating != null && !vehicleModuleSeating.IsDestroyed before using it.

  • Horn is not available on every vehicle

    Only vehicles whose seating module has a horn will trigger this hook. Do not assume every car press or key click results in a call; check the module's parent vehicle if you need to be type-specific.

Build a plugin with OnVehicleHornPressed

Describe what should happen and get a compiled plugin that uses this hook.

Prompt: Rate-limit horn spam using the OnVehicleHornPressed hook, with a config file and a permission
Generate this plugin

Edit the prompt on the next screen. 2 free plugins a month, no card.

Last updated Oct 26, 2026. Found a mistake? Email support@rustplugingenerator.com.

Build a plugin with OnVehicleHornPressed

Generate