Skip to content
RustPluginGenerator

OnLivestockAnimalFamiliarityAdd

OnLivestockAnimalFamiliarityAdd is called when a livestock animal is about to credit a player with familiarity seconds, before any value is stored. Returning a non-null value cancels the increase.

Signature
object OnLivestockAnimalFamiliarityAdd(Rust.Ai.Gen2.LivestockAnimal livestockAnimal, ulong userId, float seconds, Rust.Ai.Gen2.LivestockAnimal.FamiliarityReason reason)

Parameters

Hook parameters
ParameterTypeDescription
livestockAnimalRust.Ai.Gen2.LivestockAnimalThe livestock animal (horse, cow, etc.) the familiarity is being added to. Cast to a more specific type such as RidableAnimal if you need mount-specific members.
userIdulongThe player's raw Steam ID (ulong) that is gaining familiarity with the animal; not a string.
secondsfloatHow many seconds of familiarity are about to be credited before husbandry clocks are refreshed.
reasonRust.Ai.Gen2.LivestockAnimal.FamiliarityReasonWhy familiarity is being added, as a LivestockAnimal.FamiliarityReason value (for example Handled by default); useful to distinguish passive from deliberate interactions.

Return value

Returning null lets the game credit familiarity, refresh husbandry clocks and fire OnLivestockAnimalFamiliarityAdded. Returning any non-null value stops the original method before CreditFamiliarity runs, so no familiarity is added and the Added hook is skipped.

How it works

This hook fires inside LivestockAnimal.AddFamiliarity, which the game calls whenever a player earns familiarity with a livestock animal. It runs before CreditFamiliarity and RefreshHusbandryClocks, so at this point nothing has been recorded yet. The animal, the player's Steam ID, the seconds being credited and the FamiliarityReason are all passed in. Return a non-null value to stop the whole sequence: familiarity is not credited, husbandry clocks are not refreshed, and OnLivestockAnimalFamiliarityAdded never fires. Return null to let the game proceed normally.

Use it to inspect or gate familiarity gains - for example to scale down rewards, block them for animals owned by other players, or react to a specific reason. The reason value lets you separate deliberate handling from other sources of familiarity. You can declare a more specific parameter type such as RidableAnimal so Oxide only calls your method for mounts, but keep it in mind that animals of other types will skip your hook entirely. Do not call AddFamiliarity again from inside this hook, since it would re-enter the same path.

Example plugin: Block familiarity gains from other players' animals

FamiliarityGuard.cs
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;

namespace Oxide.Plugins
{
    [Info("Familiarity Guard", "RustPluginGenerator", "1.0.0")]
    [Description("Blocks or caps livestock familiarity gains for players who do not own the animal")]
    public class FamiliarityGuard : RustPlugin
    {
        private const string PermBypass = "familiarityguard.bypass";

        private PluginConfig config;

        private class PluginConfig
        {
            [JsonProperty("Allow same team members")]
            public bool AllowTeam { get; set; } = false;

            [JsonProperty("Maximum seconds credited per call (0 = unlimited)")]
            public float MaxSeconds { get; set; } = 0f;
        }

        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>
            {
                ["Blocked"] = "You cannot gain familiarity with an animal you do not own."
            }, this);
        }

        private string Msg(string key, string userId = null) => lang.GetMessage(key, this, userId);

        private void Init()
        {
            permission.RegisterPermission(PermBypass, this);
        }

        private object OnLivestockAnimalFamiliarityAdd(Rust.Ai.Gen2.LivestockAnimal livestockAnimal, ulong userId, float seconds, Rust.Ai.Gen2.LivestockAnimal.FamiliarityReason reason)
        {
            if (livestockAnimal == null || userId == 0 || seconds <= 0f) return null;

            var player = BasePlayer.FindByID(userId);
            if (player == null) return null;

            if (permission.UserHasPermission(player.UserIDString, PermBypass)) return null;

            var ownerId = livestockAnimal.OwnerID;
            if (ownerId != 0 && ownerId != userId)
            {
                if (config.AllowTeam && player.currentTeam != 0)
                {
                    var owner = BasePlayer.FindByID(ownerId);
                    if (owner != null && owner.currentTeam != 0 && owner.currentTeam == player.currentTeam) return null;
                }

                player.ChatMessage(Msg("Blocked", player.UserIDString));
                return true;
            }

            if (config.MaxSeconds > 0f && seconds > config.MaxSeconds)
            {
                return true;
            }

            return null;
        }
    }
}

The plugin listens on OnLivestockAnimalFamiliarityAdd and looks up the animal's owner. If the player handling familiarity is not the animal's OwnerID, it returns true to cancel the credit. Optional config toggles let admins allow same-team handling and cap the maximum seconds credited per call. It also honours a familiarityguard.bypass permission for staff. Because the hook runs before CreditFamiliarity, returning a value prevents both the familiarity gain and the OnLivestockAnimalFamiliarityAdded follow-up, keeping the animal's husbandry state untouched for players who should not be progressing it.

Common use cases

  • Scale familiarity gains

    Inspect the seconds argument and cancel casts above a threshold to keep animal husbandry progression within the limits your server wants.

  • Reason-aware restrictions

    Use the FamiliarityReason to allow deliberate handling while blocking familiarity earned through other paths you consider unintended.

  • Owner-only progression

    Compare the animal's OwnerID with userId and block familiarity for players who are interacting with animals they do not own.

Pitfalls

  • Returning false still cancels

    The hook uses a non-null check, so returning false stops the increase just like true. Only return a value when you actually want to block it.

  • Do not call AddFamiliarity inside the hook

    Calling AddFamiliarity from your handler re-enters the same hook and can loop or double-count credits. Change state elsewhere if you need side effects.

  • Overly specific parameter types

    Declaring RidableAnimal narrows dispatch to mounts; other livestock animals will not reach your method. Declare LivestockAnimal unless you specifically need mount-only behaviour.

Build a plugin with OnLivestockAnimalFamiliarityAdd

Describe what should happen and get a compiled plugin that uses this hook.

Prompt: Scale familiarity gains using the OnLivestockAnimalFamiliarityAdd hook, with a config file and a permission
Generate this plugin

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 OnLivestockAnimalFamiliarityAdd

Generate