CanRotateSail
CanRotateSail is called on the server when a player presses to rotate a sail on a boat, before the game decides whether the rotation is allowed. Returning a bool overrides the game's own permission and busy checks for that request.
object CanRotateSail(Sail sail, BasePlayer player)Parameters
| Parameter | Type | Description |
|---|---|---|
sail | Sail | The Sail entity the player is trying to rotate. Use it to read the owner (OwnerID), the parent boat, position and current rotation state. |
player | BasePlayer | The BasePlayer who triggered the rotate action on the server. This is who an allow/deny decision should be based on. |
Return value
Return a bool to replace the game's own CanRotate result: true allows the rotation, false blocks it, and the game's busy/ownership checks are skipped either way. Return null (or nothing) to let vanilla Sail.CanRotate run unchanged.
How it works
The hook fires inside Sail.CanRotate(BasePlayer player), which the game calls when a player asks to rotate a sail (angling) on a boat. Oxide passes the sail instance and the requesting player, then checks whether your return value is a bool. If it is, that value becomes the result of CanRotate and the game skips its normal checks (IsBusy() and whatever follows). If you return null, the original method runs and the vanilla rules apply.
The parameters are enough to make ownership, team or permission decisions: sail.OwnerID gives the boat/sail owner, sail.GetParentEntity() gives the carrying boat, and player identifies the requester. You can narrow nothing usefully by declaring a more specific type here, because both arguments are already the exact runtime types (Sail and BasePlayer).
Keep the hook fast: it runs on player input, not on a timer. Do not print to console here, and do not assume sail or player is still valid on a boat that is being destroyed. Because the hook fires frequently while a player is adjusting sails, cache permission results rather than resolving complex state on every call.
Example plugin: Restrict sail rotation to the boat's owner and authed teammates
using System.Linq;
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("Sail Rotate Permission", "RustPluginGenerator", "1.0.0")]
[Description("Restricts sail rotation to the boat owner, their team, or players with a bypass permission.")]
public class SailRotatePermission : RustPlugin
{
private const string PermUse = "sailrotatepermission.use";
private PluginConfig config;
private class PluginConfig
{
[JsonProperty("Restrict sail rotation to owner and team")]
public bool Restrict { 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 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>
{
["NoPermission"] = "You are not allowed to rotate sails on this boat."
}, 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 object CanRotateSail(Sail sail, BasePlayer player)
{
if (sail == null || player == null) return null;
if (!config.Restrict) return null;
ulong ownerId = sail.OwnerID;
if (ownerId == 0) return null; // unowned boat, let vanilla decide
if (player.userID.Get() == ownerId) return true;
if (permission.UserHasPermission(player.UserIDString, PermUse)) return true;
if (player.IsAdmin) return true;
if (player.currentTeam != 0)
{
var team = RelationshipManager.ServerInstance.FindTeam(player.currentTeam);
if (team != null && team.members.Contains(ownerId)) return true;
}
player.ChatMessage(Msg("NoPermission", player.UserIDString));
return false;
}
}
}The plugin lets admins and members of the boat owner's team rotate a sail, while everyone else is blocked. When CanRotateSail fires, it reads the sail's OwnerID and the requesting player, and grants rotation if the player is the owner, shares the owner's team, or holds the configured bypass permission. Anonymous cases fall back to vanilla behavior by returning null when the owner cannot be found. The permission is registered in Init, and a config toggle disables the restriction entirely, letting the game decide. The hook returns a plain bool only when the plugin is enforcing the rule, so server operators can turn it off without touching code.
Common use cases
Lock sails to the boat owner
Block anyone who does not own the boat from rotating its sails, preventing cargo theft or griefing while parked.
Allow team-based sail control
When the boat is owned and the player shares the owner's team, permit rotation so a crew can manage sails together.
VIP or permission bypass
Grant a permission that overrides the restriction, letting trusted players or staff rotate sails on any boat.
Pitfalls
Returning a bool skips vanilla busy checks
Returning false unconditionally will also block rotations the game would have refused anyway, but returning true skips
IsBusy()and other internal checks, which can allow rotations at odd moments.OwnerID is not always the person at the helm
The boat may be owned by someone not currently aboard; base decisions on OwnerID and team membership rather than assuming the owner is driving.
Frequent input-driven calls
Players spam rotate while adjusting sails, so avoid expensive lookups, logging and permission calls that could be cached or done once.
Build a plugin with CanRotateSail
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 CanRotateSail
Generate