OnLoseCondition
OnLoseCondition is called by Oxide right before a condition loss is subtracted from an item. Changing the amount parameter changes how much condition the item actually loses.
void OnLoseCondition(Item item, ref float amount)Parameters
| Parameter | Type | Description |
|---|---|---|
item | Item | The Item instance whose condition is about to drop. Use item.info.shortname, item.skin or item.GetOwnerPlayer() to decide whether to act. |
amount | ref float | Condition loss about to be applied, passed by reference. Set it to 0 to negate the loss, lower it to reduce wear, or raise it to make the item degrade faster. |
Return value
The return value is ignored. Whether you return null, true or anything else, Oxide reads back the amount argument and applies it. Only modifying amount (including setting it to 0) changes the outcome.
How it works
Oxide invokes OnLoseCondition from its RustCore.IOnLoseCondition wrapper immediately before it subtracts the wear value from item.condition and, if the total drops to zero or below, calls item.OnBroken(). The call happens for every condition-loss request routed through that wrapper, which covers ordinary weapon and tool wear as well as scripted damage to condition.
item is the affected Item: check item.info.shortname, item.skin, item.condition, item.maxCondition or item.GetOwnerPlayer() to target specific gear. amount is the raw wear value; because it is passed by reference, whatever you leave in it is what the game subtracts. Returning a value from the hook is ignored, so all adjustments must happen through amount.
Because the hook fires on every wear event, keep the body cheap. Do not print, allocate or scan inventories here. Balance multipliers, indestructible starter kits and per-skin durability tweaks are the usual reasons to touch the value. Setting amount to 0 skips the loss entirely, which also prevents the item from breaking on that event.
Example plugin: Scale condition loss for whitelisted tool shortnames
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("Tool Durability Tuner", "RustPluginGenerator", "1.0.0")]
[Description("Scales or removes condition loss for configured item shortnames.")]
public class ToolDurabilityTuner : RustPlugin
{
private const string PermAdmin = "tooldurabilitytuner.admin";
private PluginConfig config;
private readonly Dictionary<string, Entry> entries = new Dictionary<string, Entry>();
private class Entry
{
[JsonProperty("Wear multiplier (0 = no wear)")]
public float Multiplier { get; set; } = 1f;
}
private class PluginConfig
{
[JsonProperty("Only apply to items held by a player")]
public bool PlayerOwnedOnly { get; set; } = true;
[JsonProperty("Per item shortname settings")]
public Dictionary<string, Entry> Items { get; set; } = new Dictionary<string, Entry>
{
["rock"] = new Entry { Multiplier = 0f },
["hatchet"] = new Entry { Multiplier = 0.5f },
["pickaxe"] = new Entry { Multiplier = 0.5f },
["hammer"] = new Entry { Multiplier = 0.25f }
};
}
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);
private void Init()
{
permission.RegisterPermission(PermAdmin, this);
RebuildEntries();
}
private void RebuildEntries()
{
entries.Clear();
if (config.Items == null) return;
foreach (var kvp in config.Items)
{
if (string.IsNullOrEmpty(kvp.Key) || kvp.Value == null) continue;
entries[kvp.Key.ToLowerInvariant()] = kvp.Value;
}
}
private void OnLoseCondition(Item item, ref float amount)
{
if (item?.info == null || amount <= 0f) return;
if (config.PlayerOwnedOnly && item.GetOwnerPlayer() == null) return;
Entry entry;
if (!entries.TryGetValue(item.info.shortname, out entry)) return;
float multiplier = Mathf.Clamp(entry.Multiplier, 0f, 10f);
amount *= multiplier;
}
[ChatCommand("tuner.reload")]
private void CmdReload(BasePlayer player, string command, string[] args)
{
if (player != null && !player.IsAdmin && !permission.UserHasPermission(player.UserIDString, PermAdmin))
{
SendReply(player, "You do not have permission to use this command.");
return;
}
LoadConfig();
RebuildEntries();
if (player != null) SendReply(player, "Durability settings reloaded.");
else Puts("Durability settings reloaded.");
}
}
}The plugin reads a config object listing tool shortnames with a wear multiplier and an optional flag that makes them take no wear at all. In OnLoseCondition it first resolves the owner with item.GetOwnerPlayer() and bails out when the item has no player owner, so loot on the ground is untouched. It looks the shortname up in a dictionary built in LoadDefaultConfig, sets amount to 0 for indestructible entries and otherwise multiplies the incoming value by the configured factor. Because the hook only does a dictionary lookup and one multiplication, it stays cheap even with many players hitting rocks and trees at once. /tuner.reload re-reads the config without restarting the server.
Common use cases
Server-wide durability multiplier
Multiply
amountby a configured factor to make all gear last longer or wear out faster, which is a common knob on PvE and hardcore servers.Indestructible starter tools
Check the owner's permission or a whitelist of shortnames and set
amountto 0 so a rock or hatchet never loses condition and never breaks.Skins that wear differently
Compare
item.skinagainst a set of premium skin IDs and reduce the wear so cosmetic purchases carry a gameplay benefit.
Pitfalls
Returning false does not cancel the wear
Unlike many Can* hooks, the return value of OnLoseCondition is thrown away. Only
amount = 0prevents the condition loss and the possible break.Zeroing amount also blocks breaking
When
amountbecomes 0 the condition never reaches zero through this path, soitem.OnBroken()is not called. If you only want slower wear, keep a small positive value instead of zero.Not every condition change goes through here
Direct assignments to
item.conditionby other plugins or code paths bypass this wrapper, so the hook is not a complete audit of an item's durability.
Plugin recipes that use OnLoseCondition
Build a plugin with OnLoseCondition
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 OnLoseCondition
Generate