OnRidableAnimalClaim
OnRidableAnimalClaim is called when a player tries to claim a RidableHorse by sending the SERVER_Claim network message with a purchase token. Returning a non-null value cancels the claim.
object OnRidableAnimalClaim(RidableHorse ridableHorse, BasePlayer player, Item purchaseToken)Parameters
| Parameter | Type | Description |
|---|---|---|
ridableHorse | RidableHorse | The RidableHorse entity the player is trying to claim. Use it to read position, owner, or the health of the animal. |
player | BasePlayer | The BasePlayer sending the claim request. Use it for permission checks, team lookups and chat feedback. |
purchaseToken | Item | The Item the player is paying with, resolved by the game from the token item ID sent in the network message. The saddle check happens after this hook. |
Return value
Return null to let the claim proceed to the game's saddle check. Return any non-null object to stop the original code path, so the horse is not claimed and the Reserved2 flag is not cleared; the returned value itself is discarded because SERVER_Claim returns void.
How it works
The hook fires inside RidableHorse.SERVER_Claim, on the server, after the client's message has been read and the game has located the item the player wants to spend as a purchase token. It runs before the saddle check and before the game clears the Reserved2 flag that marks the animal as claimed by the current owner.
The parameters cover the whole attempt: ridableHorse is the animal being claimed, player is the sender, and purchaseToken is the actual Item the game resolved from the sent item ID. Since the item exists at this point you can inspect its shortname, skin, amount or condition before deciding.
Declaring a narrower type such as RidableHorse is already what the signature uses; there is no broader base class that would widen dispatch, so keep the parameter types as given. Because the claim only reaches this hook when a token was found, a null purchaseToken will not occur, but still check player and the horse for validity.
Practical uses are gating claims by permission, by how many horses a player already owns, or by a cooldown tracked in data. Returning any non-null object refuses the claim; the game's own saddle validation is skipped in that case.
Example plugin: Limit how many horses a player can claim
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("Ridable Horse Claim Limit", "RustPluginGenerator", "1.0.0")]
[Description("Caps how many ridable horses a single player may own.")]
public class RidableHorseClaimLimit : RustPlugin
{
private const string PermUse = "ridablehorseclaimlimit.use";
private PluginConfig config;
private class PluginConfig
{
[JsonProperty("Maximum horses per player")]
public int MaxHorses { get; set; } = 2;
[JsonProperty("Require permission to claim")]
public bool RequirePermission { 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 claim horses on this server.",
["LimitReached"] = "You already own {0} horses, the limit is {1}."
}, 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 OnRidableAnimalClaim(RidableHorse ridableHorse, BasePlayer player, Item purchaseToken)
{
if (player == null || !player.IsConnected)
return "Invalid player";
if (config.RequirePermission && !permission.UserHasPermission(player.UserIDString, PermUse))
{
player.ChatMessage(Msg("NoPermission", player.UserIDString));
return "No permission";
}
int owned = CountOwnedHorses(player.userID.Get());
if (owned >= config.MaxHorses)
{
player.ChatMessage(Msg("LimitReached", player.UserIDString, owned, config.MaxHorses));
return "Limit reached";
}
return null;
}
private int CountOwnedHorses(ulong userId)
{
int count = 0;
foreach (var entity in BaseNetworkable.serverEntities)
{
var horse = entity as RidableHorse;
if (horse == null || horse.IsDestroyed)
continue;
if (horse.OwnerID == userId)
count++;
}
return count;
}
}
}The plugin counts live RidableHorse entities owned by the claiming player and refuses the claim when the limit from the config is already reached. Ownership comes from OwnerID, compared against the player's user ID, so horses a player bought earlier still count after a server restart.
The hook returns a non-null string to cancel the claim and sends the player a localized message through the language file. The limit and the feedback text live in the config, and LoadConfig falls back to defaults when the JSON is malformed. No state is stored, so there is nothing to save in Unload.
Common use cases
Cap horses per player
Count RidableHorse entities owned by the player and refuse the claim once a configured maximum is reached, keeping the animal market from being monopolized.
Require a permission to claim
Return non-null for players without a
ridablehorseclaimlimit.usepermission so only whitelisted or donator ranks can ride and own horses.Claim cooldown
Record the last claim time per player in oxide/data and refuse new claims until a cooldown has elapsed, returning a message through chat.
Pitfalls
The saddle check is skipped on refusal
The game validates that the purchase token is a saddle only after this hook returns null. Refusing here just aborts the claim, so do not try to reuse this hook to inspect or enforce saddle rules.
Hook fires only when a token was resolved
The call sits behind a null check on the token item, so a claim attempt with an invalid item ID never reaches
OnRidableAnimalClaim. Gate other checks in a hook that always runs if you need full coverage.Do not remove the token yourself
The claim flow consumes the purchase token later. Removing or moving the item inside the hook can leave the claim half-finished or produce an error in the server method.
Build a plugin with OnRidableAnimalClaim
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 OnRidableAnimalClaim
Generate