OnTurretRotate
OnTurretRotate is called when an authorized player toggles an online AutoTurret's aim, before the turret flips its forward direction and sends the network update.
object OnTurretRotate(AutoTurret autoTurret, BasePlayer player)Parameters
| Parameter | Type | Description |
|---|---|---|
autoTurret | AutoTurret | The AutoTurret whose aim is being flipped. Use it to inspect position, ownership, authorization state and settings. |
player | BasePlayer | The BasePlayer who sent the request, already verified as authorized on the turret. Only connected, authed players reach the hook. |
Return value
Returning null (or nothing) lets the original code run, and the turret flips its rotation and sends a network update. Returning any non-null value (for example true or a string) skips the rotation entirely, since the game only executes the flip when the hook returns null.
How it works
The hook fires inside AutoTurret.FlipAim with an RPC message. The game only reaches this point when the turret is not online-and-booting (the check is !IsOnline() && IsAuthed(rpc.player) && !booting), so the caller is an authorized player interacting with a turret that is currently passive. autoTurret gives you the entity for ownership, position and authorization lookups; player is the player who requested the flip, already past the authorization check. The hook fires only on this manual aim flip, not on target tracking or turret movement while online. Because the parameter types are already the most specific ones the hook exposes (AutoTurret and BasePlayer), you cannot narrow the dispatch further — every call has both objects. Returning a non-null value suppresses the rotation; it does not change the direction, so you can only allow or deny the flip. Typical uses are logging turret access, blocking rotation during a raid timer, or requiring an extra permission before turrets can be re-aimed by hand.
Example plugin: Log turret aim changes and restrict manual flipping to a permission
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
namespace Oxide.Plugins
{
[Info("Turret Rotate Guard", "RustPluginGenerator", "1.0.0")]
[Description("Restricts manual AutoTurret aim flips to a permission and logs every attempt")]
public class TurretRotateGuard : RustPlugin
{
private const string PermRotate = "turretrotateguard.rotate";
private PluginConfig config;
private Dictionary<string, int> flipCounts = new Dictionary<string, int>();
private Timer saveTimer;
private class PluginConfig
{
[JsonProperty("Require permission to rotate turrets")]
public bool RequirePermission = true;
[JsonProperty("Log rotations to server console")]
public bool LogToConsole = 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 re-aim this turret.",
["Logged"] = "Turret aim change recorded ({0} total)."
}, 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(PermRotate, this);
}
private void OnServerInitialized()
{
flipCounts = Interface.Oxide.DataFileSystem.ReadObject<Dictionary<string, int>>(Name)
?? new Dictionary<string, int>();
saveTimer = timer.Every(300f, SaveData);
}
private void SaveData()
{
Interface.Oxide.DataFileSystem.WriteObject(Name, flipCounts);
}
private object OnTurretRotate(AutoTurret autoTurret, BasePlayer player)
{
if (autoTurret == null || player == null) return null;
if (config.RequirePermission && !permission.UserHasPermission(player.UserIDString, PermRotate))
{
player.ChatMessage(Msg("NoPermission", player.UserIDString));
return true;
}
int count;
flipCounts.TryGetValue(player.UserIDString, out count);
flipCounts[player.UserIDString] = count + 1;
if (config.LogToConsole)
{
Puts($"{player.displayName} ({player.UserIDString}) flipped turret {autoTurret.net.ID.Value} at {autoTurret.transform.position}");
}
return null;
}
private void Unload()
{
if (saveTimer != null) saveTimer.Destroy();
SaveData();
}
}
}The plugin checks a configurable permission (turretrotateguard.rotate) when a player tries to flip a passive turret. If the player lacks the permission the hook returns a non-null value, which blocks the rotation; otherwise it returns null and the flip proceeds normally. Every attempt is recorded to a per-player counter in oxide/data/TurretRotateGuard and written to the server console with the turret's position, so admins can audit who is re-aiming base defenses. The player also gets a chat message when blocked, sent through the language file. Data is flushed on unload and briefly every few minutes so the log survives restarts without frequent disk writes.
Common use cases
Permission-gated turret control
Only players with a specific permission may hand-flip turrets, useful on servers where turret placement and orientation are managed by staff or building owners.
Raid and event locks
Block aim changes while a raid event or purging window is active so defenders cannot quickly re-orient turrets mid-fight.
Audit trail for base defenses
Record who flipped which turret and when, together with the position, to investigate griefing or unauthorised base changes.
Pitfalls
Only fires for passive turrets
The game skips the hook when the turret is online and tracking (plus booting and authorization checks), so this is not a general turret interaction event.
Rotation is never changed by the return value
Returning a value only cancels the flip. To enforce a different facing you would need to manipulate the transform yourself after the fact.
Player can be null in unexpected paths
rpc.playercomes from the RPC message; always null-check the player before calling permission or chat methods even though the injection normally passes a valid player.
Build a plugin with OnTurretRotate
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 OnTurretRotate
Generate