OnEventCollectablePickup
OnEventCollectablePickup is called when a player triggers the pickup RPC on an Easter egg collectable during an active Egg Hunt event. Returning a non-null value cancels the pickup.
object OnEventCollectablePickup(BasePlayer player, CollectableEasterEgg collectableEasterEgg)Parameters
| Parameter | Type | Description |
|---|---|---|
player | BasePlayer | The BasePlayer who triggered the Easter egg pickup RPC, i.e. the player interacting with the collectable. Check for null and IsNpc before treating it as a real player. |
collectableEasterEgg | CollectableEasterEgg | The CollectableEasterEgg entity being picked up. It is a BaseEntity, so net.ID, transform.position and Kill() are available, but it is not consumed until the hook allows the call through. |
Return value
Return null (or simply fall through) to let the pickup continue and the egg be awarded normally. Return any non-null value, such as true, to stop the original method before EggHuntEvent.serverEvent.OnEggCollected runs, so the player receives nothing and the egg stays in the world.
How it works
This hook fires inside CollectableEasterEgg.RPC_PickUp, before the game decides whether the reward is granted. The surrounding code first confirms that the Egg Hunt event server is running and that the event is currently active; only then does it call the hook. So it only fires during an active Egg Hunt, not on arbitrary eggs left in the world.
The player parameter is the player who sent the pickup RPC. The collectableEasterEgg parameter is the egg entity that would be collected, useful for its world position, network ID or short prefab name. Neither is guaranteed to be non-null in theory, so check both. Declare both parameters with exactly these types; declaring BasePlayer is already the most specific useful type here, and narrowing the entity type is not possible because RPC_PickUp always passes a CollectableEasterEgg.
Because a non-null return halts the original method, this is the correct place to block a single pickup, for example for a permission gate, a distance check, or a cooldown. Note that the hook does not fire when the event is inactive: in that case the original method returns before the injection point.
Example plugin: Restrict egg hunting to a permission group with a cooldown
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("Egg Hunt Gate", "RustPluginGenerator", "1.0.0")]
[Description("Gates Easter egg pickups behind a permission and a per-player cooldown")]
public class EggHuntGate : RustPlugin
{
private const string PermUse = "egghuntgate.use";
private const string DataKey = "EggHuntGate/cooldowns";
private PluginConfig config;
private Dictionary<ulong, double> lastPickup = new Dictionary<ulong, double>();
private class PluginConfig
{
[JsonProperty("Cooldown seconds between pickups")]
public double CooldownSeconds = 10.0;
[JsonProperty("Message player when denied")]
public bool NotifyOnDeny = 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 need permission to collect Easter eggs.",
["Cooldown"] = "Wait {0} more seconds before collecting another egg."
}, 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()
{
lastPickup = Interface.Oxide.DataFileSystem.ReadObject<Dictionary<ulong, double>>(DataKey)
?? new Dictionary<ulong, double>();
}
private void Unload()
{
Interface.Oxide.DataFileSystem.WriteObject(DataKey, lastPickup);
}
private object OnEventCollectablePickup(BasePlayer player, CollectableEasterEgg collectableEasterEgg)
{
if (player == null || collectableEasterEgg == null) return null;
if (!player.IsAdmin && !permission.UserHasPermission(player.UserIDString, PermUse))
{
if (config.NotifyOnDeny) player.ChatMessage(Msg("NoPermission", player.UserIDString));
return true;
}
ulong userId = player.userID.Get();
double now = Time.realtimeSinceStartup;
double last;
if (lastPickup.TryGetValue(userId, out last))
{
double remaining = config.CooldownSeconds - (now - last);
if (remaining > 0)
{
if (config.NotifyOnDeny)
player.ChatMessage(Msg("Cooldown", player.UserIDString, Mathf.CeilToInt((float)remaining)));
return true;
}
}
lastPickup[userId] = now;
return null;
}
}
}The plugin registers egghuntgate.use in Init and blocks every egg pickup unless the player has it. When the pickup is allowed it records a Time.realtimeSinceStartup timestamp and enforces a configurable per-player cooldown between pickups, returning true to cancel the call when the player is still on cooldown. The hook never prints to console; it only reads and writes a cooldown dictionary and sends one chat message through the language file. Cooldown state is loaded in OnServerInitialized and written back with Interface.Oxide.DataFileSystem in Unload, so it survives plugin reloads and restarts.
Common use cases
Permission-based event access
Only allow players in a specific permission group to collect Easter eggs, returning true for everyone else so the pickup is cancelled silently. Combine with a chat message so players understand why nothing happened.
Cooldown or rate limit
Track the last pickup timestamp per SteamID and cancel pickups that happen too quickly. Useful on high-population servers where a single player could otherwise farm the event map quickly.
Team or area restrictions
Compare player position or team ID against the event zone before returning null. Returning true prevents the egg from being consumed, so it stays available for eligible players.
Pitfalls
The hook only fires during an active Egg Hunt
The game checks
EggHuntEvent.serverEvent.IsEventActive()before calling the hook. If the event is not running, eggs are not awarded through this path at all, so your hook will simply never run.Returning null is required to allow the pickup
Any non-null value, including
false, stops the original method. Do not returnfalseexpecting the pickup to proceed; return null to continue.Frequent calls during events
On a busy event this hook runs once per pickup across every player, so avoid logging, allocations or heavy queries inside it. Keep the body to simple checks and dictionary lookups.
Build a plugin with OnEventCollectablePickup
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 OnEventCollectablePickup
Generate