OnMeleeThrown
OnMeleeThrown is called when a player throws a melee weapon from their inventory (for example a rock, spear, or knife), right after the game detaches the item and before the weapon-thrown noise is broadcast to NPCs.
void OnMeleeThrown(BasePlayer player, Item item)Parameters
| Parameter | Type | Description |
|---|---|---|
player | BasePlayer | The BasePlayer who threw the melee weapon. Use it to identify the thrower, read their position, or check permissions and team membership. |
item | Item | The Item that was thrown. By the time the hook fires the item has already been detached from the player's inventory when its amount reached zero, so treat it as an item leaving the player's hands. |
Return value
The return value is ignored. The hook is patched in with the continue behavior, so returning null or any value has no effect and the original code path, including the NPC noise broadcast, completes normally.
How it works
This hook fires in BaseMelee.CLProject, inside the server-side handling of a throw. The game reaches that path when the client sends a throw request for a held melee weapon that allows throwing, and the server has already consumed the amount of the item; if the amount dropped to zero the item is unparented from its container first. player is the thrower and item is the melee item that left their hands. Because the injection point is the same method that handles the projectile launch, it fires once per actual throw, not per input press that the server rejects.
Declaring the parameters with more specific types is possible in principle (BasePlayer and Item are already the concrete types), but there is no base type to narrow from here, so the standard signature is the one to use. The hook is informational: the patcher ignores any return value, and the thrown noise call to the NPC noise manager still runs after it.
The item reference may already be detached from a container, so do not rely on item.parent being set. If you need to give a replacement or a returned weapon, create a fresh item with ItemManager.CreateByName and call player.GiveItem.
Example plugin: Return thrown melee weapons above a permission-gated rank
using UnityEngine;
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
namespace Oxide.Plugins
{
[Info("Melee Throw Return", "RustPluginGenerator", "1.0.0")]
[Description("Gives players with permission their melee weapon back after they throw it.")]
public class MeleeThrowReturn : RustPlugin
{
private const string PermUse = "meleethrowreturn.use";
private PluginConfig config;
private readonly Dictionary<ulong, float> cooldowns = new Dictionary<ulong, float>();
private class PluginConfig
{
[JsonProperty("Cooldown seconds between refunds")]
public float CooldownSeconds = 2f;
[JsonProperty("Notify player on refund")]
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>
{
["Returned"] = "Your {0} was returned to you.",
["Cooldown"] = "You can only have one weapon returned every {0}s."
}, 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 OnMeleeThrown(BasePlayer player, Item item)
{
if (player == null || item == null || item.info == null) return;
if (!permission.UserHasPermission(player.UserIDString, PermUse)) return;
float now = UnityEngine.Time.realtimeSinceStartup;
float last;
if (cooldowns.TryGetValue(player.userID, out last) && now - last < config.CooldownSeconds)
{
if (config.Notify)
player.ChatMessage(Msg("Cooldown", player.UserIDString, config.CooldownSeconds));
return;
}
cooldowns[player.userID] = now;
Item replacement = ItemManager.CreateByName(item.info.shortname, item.amount > 0 ? item.amount : 1, item.skin);
if (replacement == null) return;
if (item.maxCondition > 0f)
replacement.condition = item.condition;
player.GiveItem(replacement);
if (config.Notify)
player.ChatMessage(Msg("Returned", player.UserIDString, item.info.displayName.english));
}
private void Unload()
{
cooldowns.Clear();
}
}
}The plugin gives players with the meleethrowreturn.use permission their melee weapon back after a throw. OnMeleeThrown builds a replacement item from the thrown item's shortname, skin and amount, copies the condition where the thrown instance still has any, and hands it to the player with GiveItem. A per-player cooldown stored in a dictionary prevents a fast throw spam from cloning items faster than the original loop. Throws from players without the permission are ignored. A short chat notice confirms the refund, and the cooldown dictionary is cleared on unload.
Common use cases
Rank perk that refunds thrown spears
Give donators or a server rank the ability to keep thrown melee weapons by creating a fresh item copy on the hook and giving it back. Gate it behind a permission so the perk stays exclusive.
Track thrown weapon statistics
Increment a per-player counter or write a data file entry every time a melee item is thrown, useful for leaderboards or quests that ask players to throw a certain number of weapons.
Block thrown rocks during a PvE event
When the thrown item's shortname is a rock and a server-wide event flag is active, compensate the player with a different item or notify them, keeping the event area free of throw damage.
Pitfalls
The item is already detached
When the item's amount hit zero the game unparented it before the hook runs, so
item.parentcan be null. Readitem.info.shortnamefor identity instead of walking container references.The hook cannot cancel the throw
The injection uses the continue behavior, so your return value is ignored and the weapon is gone from the inventory by the time you react. If you want to give it back, create a new item and call
player.GiveItem.Condition and skin are not copied automatically
A replacement created with
ItemManager.CreateByNamestarts at default condition and skin 0. Copyitem.skinanditem.conditionexplicitly if the thrown item was modified.
Build a plugin with OnMeleeThrown
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 OnMeleeThrown
Generate