CanElevatorLiftMove
CanElevatorLiftMove is called when an ElevatorLift evaluates whether it is allowed to move, before the built-in vehicle-contents check runs. Returning a bool replaces the game's decision for that call.
object CanElevatorLiftMove(ElevatorLift elevatorLift)Parameters
| Parameter | Type | Description |
|---|---|---|
elevatorLift | ElevatorLift | The ElevatorLift entity whose movement is being evaluated. Its net.ID identifies the lift and its transform.position gives the current location for proximity checks. |
Return value
Return null (or nothing, for a method declared object) to let the game run its own check and decide. Return true to force the lift to be allowed to move, or false to block it; any other returned type is ignored and the default logic runs.
How it works
The hook fires inside ElevatorLift.CanMove, which the lift calls whenever it is about to start or continue travelling between floors. At that moment the game asks plugin code first, then falls back to its own rule: the lift refuses to move while a vehicle is sitting in its trigger volume. A non-null bool you return short-circuits that logic entirely, so the game never inspects the vehicle trigger.
The only parameter is the lift itself. Use elevatorLift.net.ID.Value to keep a per-lift record, and elevatorLift.transform.position if you need to compare against players, vehicles or a configured zone. Because ElevatorLift is a concrete type, declaring the parameter as anything else would make Oxide skip the call; keep the declared type as ElevatorLift.
Note that CanMove can be polled repeatedly while a lift is in motion, not only once when a button is pressed, so keep the body cheap: no chat output, no data writes, no entity scans over BaseNetworkable.serverEntities. Cache configuration in LoadConfig and do simple lookups in the hook.
Example plugin: Block elevator travel while a player is wounded
using System.Linq;
using System;
using Newtonsoft.Json;
using Oxide.Core;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("Elevator Wounded Guard", "RustPluginGenerator", "1.0.0")]
[Description("Blocks elevator lifts from moving while a wounded player is nearby")]
public class ElevatorWoundedGuard : RustPlugin
{
private const string PermAdmin = "elevatorwoundedguard.admin";
private PluginConfig config;
public class PluginConfig
{
[JsonProperty("Block lift travel near wounded players")]
public bool Enabled { get; set; } = true;
[JsonProperty("Detection radius in meters")]
public float Radius { get; set; } = 5f;
}
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);
private void Init()
{
permission.RegisterPermission(PermAdmin, this);
}
private object CanElevatorLiftMove(ElevatorLift elevatorLift)
{
if (!config.Enabled || elevatorLift == null) return null;
Vector3 liftPosition = elevatorLift.transform.position;
float radius = Mathf.Max(0.5f, config.Radius);
foreach (BasePlayer player in BasePlayer.activePlayerList)
{
if (player == null || player.IsNpc || !player.IsConnected) continue;
if (!player.IsWounded() && !player.IsDead()) continue;
if (Vector3.Distance(player.transform.position, liftPosition) <= radius)
return false;
}
return null;
}
[ConsoleCommand("elevatorwoundedguard.toggle")]
private void CmdToggle(ConsoleSystem.Arg arg)
{
var player = arg.Player();
if (player != null && !permission.UserHasPermission(player.UserIDString, PermAdmin))
{
arg.ReplyWith("You do not have permission to use this command.");
return;
}
config.Enabled = !config.Enabled;
SaveConfig();
arg.ReplyWith($"Wounded guard is now {(config.Enabled ? "enabled" : "disabled")}.");
}
}
}The plugin configures a radius around the lift and a toggle. When the game asks whether the lift may move, the hook walks BasePlayer.activePlayerList, skips dead, sleeping, NPC and disconnected players, and measures distance with Vector3.Distance against elevatorLift.transform.position. If a wounded or dead-but-connected player is inside the radius, it returns false, which makes the lift refuse to travel. Otherwise it returns null so the normal vehicle-contents rule still applies, meaning a lift with a car parked inside stays blocked. A console command toggles the guard at runtime, and the state lives in the config file.
Common use cases
Stop elevators from moving next to wounded players
Prevent lifts from carrying bodies out of a fight zone by returning false when a wounded player is within a configured radius of the lift.
Force lifts to ignore parked vehicles
Return true when the server owner wants vehicle-laden lifts to travel anyway, bypassing the built-in trigger check that normally blocks movement.
Disable lifts in a restricted area
Compare the lift position against a set of saved coordinates from an admin command and return false while it sits inside a no-travel region.
Pitfalls
Returning true skips the vehicle check
A forced true lets a lift with a car inside travel. The vehicle can be left behind or clipped, so only override the default when you have accounted for that.
Called repeatedly during travel
CanMove is evaluated while the lift is in motion, not just on button press. Avoid chat messages, data writes and full entity enumerations inside the hook.
Returning a non-bool does nothing
Only a bool short-circuits the method. Returning a string, int or other object is ignored and the original logic proceeds, which can look like the hook is not firing.
Build a plugin with CanElevatorLiftMove
Describe what should happen and get a compiled plugin that uses this hook.
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 CanElevatorLiftMove
Generate