Skip to content
RustPluginGenerator

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.

Signature
void OnLoseCondition(Item item, ref float amount)

Parameters

Hook parameters
ParameterTypeDescription
itemItemThe Item instance whose condition is about to drop. Use item.info.shortname, item.skin or item.GetOwnerPlayer() to decide whether to act.
amountref floatCondition 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

ToolDurabilityTuner.cs
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 amount by 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 amount to 0 so a rock or hatchet never loses condition and never breaks.

  • Skins that wear differently

    Compare item.skin against 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 = 0 prevents the condition loss and the possible break.

  • Zeroing amount also blocks breaking

    When amount becomes 0 the condition never reaches zero through this path, so item.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.condition by 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.

Prompt: Server-wide durability multiplier using the OnLoseCondition 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 OnLoseCondition

Generate