CanDeployItem
CanDeployItem is called before a Deployer places its object, letting you block or allow the deployment by returning a non-null value.
object CanDeployItem(BasePlayer player, Deployer deployer, NetworkableId networkableId)Parameters
| Parameter | Type | Description |
|---|---|---|
player | BasePlayer | The BasePlayer whose Deployer is being activated. It can be null in edge cases where the deploy path runs without a connected client, so null-check it. |
deployer | Deployer | The Deployer entity that is about to place something. Its GetDeployable() returns the Deployable component describing what is being placed and where. |
networkableId | NetworkableId | NetworkableId of the target entity the deployment is aimed at (for example the object a slot deploy attaches to). Use .Value to get the ulong id. |
Return value
Returning null lets the original DoDeploy logic continue and place the deployable normally. Returning any non-null value (a string, an empty string, a bool boxed as object) aborts the placement path entirely; DoDeploy returns void, so the value is only used as a signal and the client receives no success.
How it works
The hook fires inside Deployer.DoDeploy, after the deployer has read the player's aim ray and the target entity id from the deploy message, but before any of the actual placement code runs. It runs for both placement styles: free placement (barricades, traps, deployables on terrain or floors) and slot placement (items that snap into a target's slot, such as attachments).
player is the user performing the action and is used for permission checks, distance checks and messages. deployer is the in-world Deployer entity; call deployer.GetDeployable() to inspect the Deployable component, which exposes properties about what will be spawned. networkableId identifies the entity the deploy is aimed at, which is what you want when gating slot deployments such as weapon attachments. You can declare player as BasePlayer (already specific) and narrow nothing else meaningfully; Oxide overload matching is by argument type, so stick to the exact types here.
Because this hook fires only when a player commits a deploy action, not per frame, it is cheap to use even for distance or zone checks. It is the only supported place to veto deployment; blocking in OnItemDeployed is too late because the item is already placed.
Example plugin: Block deployment in building-blocked zones unless the player can build
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("Deploy Guard", "RustPluginGenerator", "1.0.0")]
[Description("Blocks deployable placement inside building-blocked zones unless the player has a bypass permission")]
public class DeployGuard : RustPlugin
{
private const string PermBypass = "deployguard.bypass";
private PluginConfig config;
private class PluginConfig
{
[JsonProperty("Blocked zone message")]
public string BlockedMessage { get; set; } = "You cannot place deployables in this blocked building zone.";
[JsonProperty("Check bypass permission")]
public bool UseBypass { get; set; } = true;
}
private string Msg(string key, string userId = null, params object[] args)
=> string.Format(lang.GetMessage(key, this, userId), args);
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>
{
["BlockedZone"] = "You cannot place deployables in this blocked building zone.",
["NoPermissionItem"] = "You are not allowed to place this deployable."
}, this);
}
private void Init()
{
permission.RegisterPermission(PermBypass, this);
}
private object CanDeployItem(BasePlayer player, Deployer deployer, NetworkableId networkableId)
{
if (player == null || deployer == null) return null;
if (!player.IsConnected) return null;
if (config.UseBypass && permission.UserHasPermission(player.UserIDString, PermBypass))
return null;
if (!player.IsBuildingBlocked()) return null;
player.ChatMessage(config.BlockedMessage);
return false;
}
}
}DeployGuard stops players from placing deployables where they are not allowed to build. In CanDeployItem it checks the player is valid and connected, then calls player.IsBuildingBlocked() to see whether the deploy position sits inside a blocked building zone. If so, the hook sends a language message and returns a non-null token, which makes Deployer.DoDeploy exit before anything spawns. A permission (deployguard.bypass) is registered in Init so admins and trusted ranks can still deploy, and the same permission is checked before the zone test. Messages are registered through Oxide lang so they can be translated, and the plugin keeps no timers or data, so Unload is not required.
Common use cases
Restrict deployables to map zones
Use the player's position to allow or deny placement inside monuments, safe zones or custom PvP regions, returning a non-null value outside the permitted area.
Permission-gated items
Inspect
deployer.GetDeployable()or the player's held item to let only players with a permission place specific deployables such as traps or SAM sites.Attachment control
Use
networkableIdto check which weapon or entity a slot deploy is aimed at and block attachments on certain item types.
Pitfalls
The blocked action is silent
Returning non-null just cancels the deploy, the game does not explain why. Send a chat or console message yourself, usually throttled so repeated attempts do not spam.
Returning false still blocks
The check is for a non-null result, so returning
falseaborts placement just like returning a string. Returnnullexplicitly to allow.Null player and target
playercan be null in unusual paths and the entity behindnetworkableIdmay already be gone. Null-check both before calling methods likeIsBuildingBlocked().
Build a plugin with CanDeployItem
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 CanDeployItem
Generate