Skip to content
RustPluginGenerator

CanCastFishingRod

CanCastFishingRod is called after the game validates the cast position and before the fishing bobber entity is created. Returning false blocks the cast.

Signature
object CanCastFishingRod(BasePlayer ownerPlayer, BaseFishingRod fishingRod, Item currentLure, Vector3 pos)

Parameters

Hook parameters
ParameterTypeDescription
ownerPlayerBasePlayerThe player trying to cast. Use it for permission checks, cooldowns and team comparisons.
fishingRodBaseFishingRodThe BaseFishingRod entity being cast. Read its OwnerID, transform position or flags if you need entity-level context.
currentLureItemThe item currently attached as lure, or null when the rod has none. Handy for forbidding specific bait items.
posVector3The validated world position the bobber will spawn at, produced by the game's fishing position check.

Return value

Return false (or any truthy non-bool object) to abort the cast: the bobber entity is never created and the player sees the normal failure path. Return true or null to let the original cast continue and spawn the bobber.

How it works

The hook fires inside BaseFishingRod.Server_RequestCast, after EvaluateFishingPosition has already returned true. That means the position check (water in front of the player, valid terrain, no obstruction) passed; a failed check calls FailedCast and the hook never runs. At this point no FishingBobber exists yet.

Use ownerPlayer for permission and cooldown gates, fishingRod for the entity itself (owner ID, skin, flags), currentLure to inspect or restrict bait (it can be null when no lure is attached), and pos if you need to allow or deny specific water areas by coordinates.

Declaring the first parameter as BasePlayer is already the most specific usable type. Declaring currentLure as a plain Item is required; do not try to narrow it further.

Because the hook only returns void on the game side, the only useful return value is a bool. Returning false stops the bobber from being created; returning true or null lets the cast proceed normally. This hook does not fire for reeling in, biting, or catching fish.

Example plugin: Restrict fishing rods to permitted players with a cooldown

FishingCastGuard.cs
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
using UnityEngine;

namespace Oxide.Plugins
{
    [Info("Fishing Cast Guard", "RustPluginGenerator", "1.0.0")]
    [Description("Gates fishing rod casts behind a permission and a per-player cooldown")]
    public class FishingCastGuard : RustPlugin
    {
        private const string PermUse = "fishingcastguard.use";

        private PluginConfig config;
        private Dictionary<ulong, double> lastCast;
        private bool dirty;

        private class PluginConfig
        {
            [JsonProperty("Cooldown in seconds between casts")]
            public float CooldownSeconds = 15f;

            [JsonProperty("Require permission to cast")]
            public bool RequirePermission = 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 use a fishing rod.",
                ["Cooldown"] = "Wait {0} more second(s) before casting again."
            }, 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 void OnServerInitialized()
        {
            lastCast = Interface.Oxide.DataFileSystem.ReadObject<Dictionary<ulong, double>>(Name) ?? new Dictionary<ulong, double>();
        }

        private object CanCastFishingRod(BasePlayer ownerPlayer, BaseFishingRod fishingRod, Item currentLure, Vector3 pos)
        {
            if (ownerPlayer == null || !ownerPlayer.IsConnected) return null;

            if (config.RequirePermission && !permission.UserHasPermission(ownerPlayer.UserIDString, PermUse))
            {
                ownerPlayer.ChatMessage(Msg("NoPermission", ownerPlayer.UserIDString));
                return false;
            }

            if (config.CooldownSeconds > 0f)
            {
                double last;
                if (lastCast.TryGetValue(ownerPlayer.userID.Get(), out last))
                {
                    double elapsed = UnityEngine.Time.realtimeSinceStartupAsDouble - last;
                    double remaining = config.CooldownSeconds - elapsed;
                    if (remaining > 0d)
                    {
                        ownerPlayer.ChatMessage(Msg("Cooldown", ownerPlayer.UserIDString, Math.Ceiling(remaining)));
                        return false;
                    }
                }
            }

            lastCast[ownerPlayer.userID.Get()] = UnityEngine.Time.realtimeSinceStartupAsDouble;
            dirty = true;
            return true;
        }

        private void Unload()
        {
            if (dirty && lastCast != null)
            {
                Interface.Oxide.DataFileSystem.WriteObject(Name, lastCast);
            }
        }
    }
}

The plugin registers a fishingcastguard.use permission plus a configurable per-player cooldown. When a player requests a cast, CanCastFishingRod checks the permission first and then the stored last-cast timestamp from a data file keyed by user ID. Denied attempts send a language message and return false, which prevents the bobber from spawning. Successful casts update the timestamp and save the file. The data is written in Unload so the file does not churn on every cast.

Common use cases

  • Permission-gated fishing

    Only players with a dedicated permission can cast a rod, useful on servers that sell fishing as a donor perk.

  • Cast cooldown

    Stop players from spamming casts to flood the server with bobber entities by tracking a last-cast timestamp per player.

  • Bait restrictions

    Inspect currentLure and refuse the cast when an unwanted item is attached, or when a lure is required but none is present.

Pitfalls

  • Only fires after position validation

    A denied or invalid position returns before the hook runs, so you cannot use this hook to log failed casts. Hook OnFishingRodCast or listen to chat instead.

  • Item lookup may be null

    currentLure is null when no lure is attached. Always null-check before reading currentLure.info.shortname or the cast will throw inside the hook.

  • Return type matters

    Returning a non-bool truthy object still allows the cast, while any falsy value blocks it. Be explicit and return true or false.

Build a plugin with CanCastFishingRod

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

Prompt: Permission-gated fishing using the CanCastFishingRod 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 CanCastFishingRod

Generate