Skip to content
RustPluginGenerator

CanSwapToSeat

CanSwapToSeat is called when a player tries to move into a different seat of the same vehicle or mount they are already on. Returning false blocks the swap; returning null or true keeps the default behavior.

Signature
object CanSwapToSeat(BasePlayer player, BaseMountable mountable)

Parameters

Hook parameters
ParameterTypeDescription
playerBasePlayerThe player attempting to move into the seat. Use it for permission checks, team lookups or per-player cooldowns.
mountableBaseMountableThe seat or mountable the player wants to switch into. For vehicles it is a ModularCarSeat; for mounted animals, chairs, boats and similar it is the base BaseMountable instance.

Return value

Return false to deny the swap: the patched method returns false and the game does not move the player into the seat. Return null to keep vanilla behavior, or true to explicitly allow the seat check to pass. Any other return type is ignored.

How it works

The hook fires from BaseMountable.CanSwapToThis and, in two-seat and larger vehicles, from the overriding ModularCarSeat.CanSwapToThis. Both run when the game checks whether player is allowed to occupy that specific seat. This is the swap path: the player is already mounted on the same entity and is moving to another position (driver to passenger, passenger to another modular seat). The first parameter is the swapping player, the second is the target seat entity; on modular cars cast it to ModularCarSeat, on everything else keep BaseMountable.

Declaring the second parameter as ModularCarSeat narrows the hook to car seats only, because Oxide only invokes a hook method when every argument matches the declared type. Keep BaseMountable if you want to police horses, boats and chairs too.

A returned false makes the original method return false, so the swap is refused and the player stays where they are. Returning true or null lets the seat's own logic continue. The hook does not fire for the initial mount, only for moving between seats.

Other signatures

Oxide also calls CanSwapToSeat from other places in the game with these parameter types. Declare the overload you need, or several:

  • object CanSwapToSeat(BasePlayer player, ModularCarSeat modularCarSeat)

Example plugin: Block passenger-to-driver swaps on modular cars while the driver is seated

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

namespace Oxide.Plugins
{
    [Info("Seat Swap Guard", "RustPluginGenerator", "1.0.0")]
    [Description("Blocks other players from swapping into an occupied driver seat on modular cars")]
    public class SeatSwapGuard : RustPlugin
    {
        private const string PermBypass = "seatswapguard.bypass";

        private PluginConfig config;

        private class PluginConfig
        {
            [JsonProperty("Notify blocked players")]
            public bool NotifyPlayers { get; set; } = true;

            [JsonProperty("Allow players with bypass permission")]
            public bool AllowBypass { get; set; } = true;
        }

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

        protected override void LoadConfig()
        {
            base.LoadConfig();
            try
            {
                config = Config.ReadObject<PluginConfig>();
                if (config == null) throw new System.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>
            {
                ["DriverOccupied"] = "You cannot take the driver seat while it is occupied."
            }, 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(PermBypass, this);
        }

        private object CanSwapToSeat(BasePlayer player, ModularCarSeat seat)
        {
            if (player == null || seat == null) return null;

            var car = seat.GetParentEntity() as ModularCar;
            if (car == null) return null;

            BasePlayer currentDriver = car.GetDriver();

            // Only guard the driver seat: it is the seat currently held by the driver.
            if (currentDriver == null || currentDriver == player) return null;
            if (seat.GetMounted() != currentDriver) return null;

            if (config.AllowBypass && permission.UserHasPermission(player.UserIDString, PermBypass)) return null;

            if (config.NotifyPlayers)
                player.ChatMessage(Msg("DriverOccupied", player.UserIDString));

            return false;
        }
    }
}

The plugin inspects every seat swap on a modular car through the CanSwapToSeat hook. It casts the second argument to ModularCarSeat, gets the owning ModularCar from the seat's parent entity, and calls car.GetDriver(). If the car has a driver who is not the requesting player and that driver is currently mounted in the requested seat, the hook returns false, blocking the swap. A config option toggles the chat notice sent to blocked players, and another option controls whether players with the seatswapguard.bypass permission are allowed through. Returning null in every other case keeps normal vehicle behavior intact, including empty driver seats and passenger seating.

Common use cases

  • Reserve the driver seat

    Prevent other players from stealing the driver position of an occupied car, helicopter or boat while the current driver is still mounted.

  • VIP-only rear seats

    Allow moving into passenger seats only for players holding a permission, keeping premium vehicles restricted to paying players on your server.

  • Team-only vehicle access

    Compare player.currentTeam with the owner of the mountable before allowing a swap, so random players cannot relocate inside an enemy crew's car.

Pitfalls

  • This is not the initial mount

    CanSwapToSeat only covers moving between seats on an entity the player is already mounted on. Blocking a first-time enter requires CanMountEntity or OnPlayerWantsMount.

  • Over-narrow parameter type

    Declaring ModularCarSeat makes Oxide skip the hook for horses, boats and chairs. Use BaseMountable if the rule should apply to all mountables.

  • Seat owner lookups can be null

    GetParentEntity() or the car helper can return null if the seat is being destroyed or the entity is being killed, so null-check before using the vehicle object.

Build a plugin with CanSwapToSeat

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

Prompt: Reserve the driver seat using the CanSwapToSeat 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 CanSwapToSeat

Generate