OnDispenserBonusReceived
OnDispenserBonusReceived is called when a ResourceDispenser has finished granting its bonus item for a gather, right before the bonus is handed to the player. It fires from ResourceDispenser.AssignFinishBonus, after ownership is applied and just before the item is split into stackable chunks and given.
void OnDispenserBonusReceived(ResourceDispenser resourceDispenser, BasePlayer player, Item item)Parameters
| Parameter | Type | Description |
|---|---|---|
resourceDispenser | ResourceDispenser | The ResourceDispenser component on the gatherable entity (tree, ore node, animal corpse, etc.) whose finish bonus was just created. Use it to read the entity, its position or its prefab. |
player | BasePlayer | The BasePlayer who will receive the bonus item. This is the player you reward, message or check permissions for. |
item | Item | The bonus Item instance that was just created and is about to be split down to stack size and given to the player. You can inspect its info.shortname and amount, or change them. |
Return value
The hook's return value is ignored; this signature returns void in the game method. Returning anything has no effect on the item, the amount or the delivery, so mutate item directly if you need to change the reward.
How it works
This hook fires inside ResourceDispenser.AssignFinishBonus, the step where a gatherer receives the bonus item that a dispenser grants after a resource node, corpse or similar object is finished. The game has already created the item, applied item ownership to the player and logged the gather analytics; the hook runs immediately before the while loop that splits the item into stackable pieces and calls player.GiveItem. The parameters let you inspect the dispenser entity, the receiving player and the exact bonus Item (its info.shortname, amount, skin). Because the hook fires before the stack-splitting loop, changing item.amount here changes what the player actually receives. Narrowing the signature does not help much here since ResourceDispenser, BasePlayer and Item are model classes; Oxide still passes the same arguments. The hook is not tied to ordinary per-hit gather events, so use OnDispenserGather for that and this hook for the end-of-node bonus. It fires once per finishing bonus, not once per hit, so it is reasonably safe for light logic, though you should still avoid heavy logging.
Example plugin: Multiply the finish bonus for players with a permission
using System.Collections.Generic;
using System;
using Newtonsoft.Json;
using Oxide.Core;
namespace Oxide.Plugins
{
[Info("BonusBoost", "RustPluginGenerator", "1.0.0")]
[Description("Multiplies resource dispenser finish bonuses for players with a permission.")]
public class BonusBoost : RustPlugin
{
private const string PermUse = "bonusboost.vip";
private PluginConfig config;
public class PluginConfig
{
[JsonProperty("Bonus multiplier")]
public float Multiplier = 2f;
[JsonProperty("Notify player in chat")]
public bool Notify = 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>
{
["Boosted"] = "Bonus boosted: {0} x {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 void OnDispenserBonusReceived(ResourceDispenser resourceDispenser, BasePlayer player, Item item)
{
if (resourceDispenser == null || player == null || item == null || item.info == null) return;
if (config.Multiplier <= 1f) return;
if (!permission.UserHasPermission(player.UserIDString, PermUse)) return;
int original = item.amount;
int boosted = (int)Math.Round(original * config.Multiplier);
if (boosted <= original) return;
item.amount = boosted;
item.MarkDirty();
if (config.Notify && player.IsConnected)
{
player.ChatMessage(Msg("Boosted", player.UserIDString, item.info.displayName.english, boosted));
}
}
}
}The plugin registers a bonusboost.vip permission and a configurable multiplier. When OnDispenserBonusReceived fires it null-checks the dispenser, player and item, verifies the player still has the permission, and then scales item.amount by the multiplier. Because the hook runs before the game splits the item into stackable chunks, the increased amount flows straight into the player's inventory. The adjusted amount is not allowed to exceed the item's max stack multiplied out, so the game's split loop handles overflow. A short chat message tells the player they received a boosted bonus, and Unload cleans up the registered permission.
Common use cases
Boost bonuses for donators
Scale
item.amountfor players with a permission so VIPs get more stone, wood or ore from finish bonuses without touching the rest of the economy.Log bonus economy data
Collect the shortname and amount per player to feed an external balance or stats system; keep it cheap because it only fires on finish bonuses.
Swap the reward item
Change
item.infoby removing the default item and giving a different ItemDefinition viaItemManager.CreateByNameandplayer.GiveItemyourself.
Pitfalls
Not the same as OnDispenserGather
OnDispenserBonusReceivedfires once for the finishing bonus, not on every hit. UseOnDispenserGatherfor per-hit adjustments; mixing them up produces double counting.Amount is split afterwards
The game splits the item down to
item.MaxStackable()inside the loop that follows the hook. Very large amounts still end up in multiple stacks, so do not assume one stack in inventory logic.Item may already be owned
Ownership is applied before the hook fires, so
item.GetOwnerPlayer()is the receiving player. Rely on theplayerparameter rather than inspecting ownership flags.
Build a plugin with OnDispenserBonusReceived
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 OnDispenserBonusReceived
Generate