OnCoalingTowerGather
OnCoalingTowerGather is called once per item while a CoalingTower empties its storage into a receiving container. Returning a non-null value discards that item instead of moving it.
object OnCoalingTowerGather(CoalingTower coalingTower, Item item)Parameters
| Parameter | Type | Description |
|---|---|---|
coalingTower | CoalingTower | The CoalingTower entity whose unload routine is pulling items out of its storage. Use it to check position, owner or flags before deciding what to do with the item. |
item | Item | The Item currently being processed by the tower's unload pass. Inspect item.info.shortname, item.amount or item.skin to filter which items you intercept. |
Return value
Returning null lets the item continue to the destination container. Returning any non-null object makes Oxide skip the move and call item.Remove() on it, so the item is destroyed rather than stored.
How it works
The hook fires inside CoalingTower.EmptyTenPercent, the routine a coaling tower runs when it pushes its stored loot toward a linked wagon or container. For every item the tower processes, Oxide calls this hook before the item is moved. Items of the Lootboxes wagon type are removed first and never reach the hook, so you only see ordinary items.
Declare coalingTower as CoalingTower (or a broader type such as BaseEntity) and Oxide will only invoke your method where the argument matches. Narrow coalingTower to a specific subtype and calls for other towers are skipped.
Use it to vet what leaves the tower: block contraband, cap output, log transfers or award bonuses. Keep the body cheap because it runs per item, and never print diagnostics here. Because the Item is live, changing its amount or skin in the hook affects what actually lands in the destination when you return null.
Example plugin: Whitelist items allowed out of coaling towers
using System.Linq;
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
namespace Oxide.Plugins
{
[Info("Coaling Tower Filter", "RustPluginGenerator", "1.0.0")]
[Description("Blocks items that are not on a whitelist from leaving coaling towers")]
public class CoalingTowerFilter : RustPlugin
{
private const string PermAdmin = "coalingtowerfilter.admin";
private PluginConfig config;
private class PluginConfig
{
[JsonProperty("Allowed shortnames (empty = allow all)")]
public List<string> AllowedShortnames = new List<string>
{
"charcoal",
"coal",
"wood",
"scrap",
"metal.fragments",
"sulfur.ore",
"stone"
};
}
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"] = "Coaling tower blocked item: {0}",
["Reloaded"] = "Coaling tower whitelist reloaded ({0} entries).",
["NoPermission"] = "You do not have permission to use this command."
}, 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(PermAdmin, this);
}
private object OnCoalingTowerGather(CoalingTower coalingTower, Item item)
{
if (coalingTower == null || item == null || item.info == null) return null;
if (config.AllowedShortnames == null || config.AllowedShortnames.Count == 0) return null;
string shortname = item.info.shortname;
if (config.AllowedShortnames.Contains(shortname)) return null;
return true;
}
[ChatCommand("coaltower")]
private void CmdCoalTower(BasePlayer player, string command, string[] args)
{
if (player == null) return;
if (!player.IsAdmin && !permission.UserHasPermission(player.UserIDString, PermAdmin))
{
SendReply(player, Msg("NoPermission", player.UserIDString));
return;
}
if (args == null || args.Length == 0 || args[0].ToLower() != "reload")
{
SendReply(player, Msg("Reloaded", player.UserIDString, config.AllowedShortnames.Count));
return;
}
LoadConfig();
SendReply(player, Msg("Reloaded", player.UserIDString, config.AllowedShortnames.Count));
}
}
}The plugin reads an allowed-shortname list from its config and, in OnCoalingTowerGather, checks each item the tower tries to unload. Items whose shortname is not on the list return a non-null value, which makes the game remove them instead of moving them into the wagon. Allowed items return null and transfer normally. /coaltower reload (admin only) reloads the config so staff can update the whitelist without restarting. Messages go through the language file rather than hard-coded text.
Common use cases
Block contraband from leaving towers
Reject explosives, weapons or any shortname you do not want a coaling tower to hand out by returning a value for those items.
Log tower output for audits
Record each item leaving a tower to a data file so admins can trace where resources on the map came from. Return null to let transfers proceed.
Reward players for processed loot
Track amounts and hand out a pre-agreed reward through a referenced economy plugin when the total exceeds a threshold.
Pitfalls
Non-null return destroys the item
The game calls
item.Remove()when you return anything other than null, so the item is gone, not held back in the tower. If you want it kept, resist the urge to return false; use a non-null return only to delete.Lootbox wagon items skip the hook
Items pulled from a wagon of type
Lootboxesare removed before the hook is reached, so you cannot intercept or log them here.It runs per item under load
A busy tower with a large stack list fires the hook many times in one pass. Avoid allocations, logging or plugin calls inside the method if you expect heavy traffic.
Build a plugin with OnCoalingTowerGather
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 OnCoalingTowerGather
Generate