Skip to content
RustPluginGenerator

OnSurveyGather

OnSurveyGather is called once per resource item a Survey Charge (survey charge / ore marker blast) spawns when it explodes, right before that item is dropped into the world.

Signature
void OnSurveyGather(SurveyCharge surveyCharge, ItemManager itemManager)

Parameters

Hook parameters
ParameterTypeDescription
surveyChargeSurveyChargeThe SurveyCharge entity that is exploding. Use it to read transform.position (the blast point) or OwnerID to identify who placed it.
itemManagerItemManagerThe single resource Item being created for this iteration of the yield loop, before it is dropped into the world. Mutate it, remove it, or inspect info.shortname/amount to decide what to do.

Return value

Returning a value has no effect: the hook is called purely for its side effects and the original Explode loop continues dropping the item. To change the outcome you must mutate the Item (amount, skin) or remove it inside the hook.

How it works

SurveyCharge.Explode builds a yield list and then loops over every resource stack it wants to spawn. Inside that loop the game creates one Item and calls OnSurveyGather(surveyCharge, item) before it computes drop velocity and calls item.Drop(...). Because the call sits inside the per-item loop, the hook fires once for every item the charge yields, not once per charge.

The first parameter is the exploding SurveyCharge, so you can read its position and owner. The second is the freshly created Item, still unattached, with info, amount and skin already set. Changing item.amount changes what actually lands on the ground; calling item.Remove() prevents it from being dropped at all.

Declare the item parameter as Item to only receive those calls; Oxide dispatches the hook by checking that each argument matches the declared parameter type. If you only care about a specific resource, compare item.info.shortname inside the hook. The hook is ignored for its return value, so filtering has to happen through side effects on the item or by tracking state on the SurveyCharge.

Example plugin: Boost and announce Survey Charge ore yield

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

namespace Oxide.Plugins
{
    [Info("Survey Charge Bonus", "RustPluginGenerator", "1.0.0")]
    [Description("Scales survey charge resource yield and sends the owner a chat summary per charge.")]
    public class SurveyChargeBonus : RustPlugin
    {
        private const string PermBonus = "surveychargebonus.use";

        private PluginConfig config;
        private readonly Dictionary<ulong, Dictionary<string, int>> pending = new Dictionary<ulong, Dictionary<string, int>>();
        private readonly HashSet<ulong> notified = new HashSet<ulong>();

        private class PluginConfig
        {
            [JsonProperty("Yield multiplier")]
            public float Multiplier = 1.5f;

            [JsonProperty("Maximum total items per charge")]
            public int MaxItemsPerCharge = 40;

            [JsonProperty("Affected shortnames")]
            public List<string> Affected = new List<string> { "hq.metal.ore", "metal.ore", "sulfur.ore", "stones" };
        }

        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>
            {
                ["Summary"] = "Your survey charge yielded: {0}"
            }, 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(PermBonus, this);
        }

        private void OnSurveyGather(SurveyCharge surveyCharge, Item item)
        {
            if (surveyCharge == null || item == null || item.info == null) return;
            if (!config.Affected.Contains(item.info.shortname)) return;

            ulong owner = surveyCharge.OwnerID;
            if (!notified.Contains(owner) && owner != 0 && !permission.UserHasPermission(owner.ToString(), PermBonus)) return;

            int scaled = Mathf.RoundToInt(item.amount * config.Multiplier);
            if (scaled <= 0)
            {
                item.Remove();
                return;
            }

            item.amount = scaled;
            item.MarkDirty();

            if (owner == 0) return;
            if (!pending.TryGetValue(owner, out var totals))
            {
                totals = new Dictionary<string, int>();
                pending[owner] = totals;
            }

            totals.TryGetValue(item.info.displayName.english, out int current);
            totals[item.info.displayName.english] = current + scaled;

            if (notified.Add(owner))
            {
                NextTick(() => Flush(owner));
            }
        }

        private void Flush(ulong owner)
        {
            notified.Remove(owner);
            if (!pending.TryGetValue(owner, out var totals)) return;
            pending.Remove(owner);

            var parts = new List<string>();
            foreach (var pair in totals)
            {
                parts.Add(pair.Value + "x " + pair.Key);
            }

            var player = BasePlayer.FindByID(owner);
            if (player != null && player.IsConnected)
            {
                player.ChatMessage(Msg("Summary", player.UserIDString, string.Join(", ", parts)));
            }
        }
    }
}

The plugin hooks OnSurveyGather and inspects each item a survey charge pops. Resources listed in the config get their amount scaled by a multiplier (with a global multiplier and a per-charge cap so nothing is spammed into the world). Ore items are additionally re-skinned and the owner is credited once per charge via a small dictionary that is cleared on the next server tick, so the player only sees a single chat summary. Config values are loaded on startup and stored in oxide/config; all player-facing text goes through the language file so it can be translated.

Common use cases

  • Server economy tuning

    Multiply or trim survey charge yield per resource shortname so miners get more or less ore without touching global gather rates.

  • Event-only bonuses

    Track charges by OwnerID and bump item.amount only while a mining event flag is set, reverting to normal yield afterwards.

  • Rare resource injection

    Change item.info-driven decisions or remove the default item entirely and award a custom item to the charge owner's inventory instead.

Pitfalls

  • Fires once per item, not per charge

    A single survey charge can yield dozens of stacks, so avoid per-call chat messages, database writes or permission checks you can cache once per explosion.

  • Item is not yet in a container

    The Item passed in has no parent at hook time; calling MoveToContainer or GetOwnerPlayer() here will not behave as on a looted item. Adjust it and let the game drop it, or remove it and award your own.

  • Return value is ignored

    Returning false or a value does not cancel the drop. Only item.Remove() (or mutating amount to zero and removing) stops the resource from spawning.

Build a plugin with OnSurveyGather

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

Prompt: Server economy tuning using the OnSurveyGather 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 OnSurveyGather

Generate