Skip to content
RustPluginGenerator

OnLiquidWeaponFiringStopped

OnLiquidWeaponFiringStopped is called on the server after a LiquidWeapon (flamethrower) finishes its firing sequence in LiquidWeapon.StopFiring, before control returns to the caller.

Signature
void OnLiquidWeaponFiringStopped(LiquidWeapon liquidWeapon)

Parameters

Hook parameters
ParameterTypeDescription
liquidWeaponLiquidWeaponThe LiquidWeapon entity (flamethrower) that has just stopped firing. Use it to read its owner, position, mounted state and short prefab name.

Return value

The original method returns void, and Oxide ignores whatever your hook returns, so return nothing. The game's StopFiring logic always completes regardless of your return value.

How it works

The hook fires inside LiquidWeapon.StopFiring on the server, immediately after the method has applied its firing-state changes and sent the network update. Any action that reaches StopFiring triggers it: a player releasing the fire button, running out of fuel, the weapon being unequipped or dropped, or the parent entity being destroyed.

The single parameter is the LiquidWeapon entity itself. From it you can read OwnerID, GetOwnerPlayer(), transform.position, ShortPrefabName and the mounted state of the holder. That is enough to attribute the stop event to a player, a position and a weapon type without extra lookups.

Declaring the parameter as LiquidWeapon (or a base type such as BaseEntity) keeps Oxide's dispatch working; a narrower type would simply skip calls where the argument does not match. This is Oxide hook dispatch, not patcher behavior.

The hook is informational: the method returns void, so any value you return is ignored and the game continues normally. It fires once per stop, not per frame, so it is safe for short-lived logic such as cooldown tracking or statistics, but it can still fire for NPC or server-spawned liquid weapons, so filter on OwnerID when you only care about players.

No state is exposed about how long the weapon fired or how much fuel was consumed, so record that separately in CanFireLiquidWeapon or OnLiquidWeaponFired if you need it.

Example plugin: Cooldown flamethrower users with a chat warning

LiquidWeaponCooldown.cs
using System.Linq;
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
using UnityEngine;

namespace Oxide.Plugins
{
    [Info("LiquidWeaponCooldown", "RustPluginGenerator", "1.0.0")]
    [Description("Enforces a per-player cooldown after a flamethrower stops firing")]
    public class LiquidWeaponCooldown : RustPlugin
    {
        private const string PermShortCooldown = "liquidweaponcooldown.vip";

        private PluginConfig config;
        private readonly Dictionary<string, float> lastStop = new Dictionary<string, float>();
        private Timer cleanupTimer;

        private class PluginConfig
        {
            [JsonProperty("Default cooldown in seconds")]
            public float DefaultCooldown = 3f;

            [JsonProperty("VIP cooldown in seconds")]
            public float VipCooldown = 1f;
        }

        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>
            {
                ["Cooldown"] = "Flamethrower cooling down. Wait {0}s.",
                ["Ready"] = "Flamethrower ready."
            }, 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(PermShortCooldown, this);
            cleanupTimer = timer.Every(120f, Cleanup);
        }

        private void Unload()
        {
            cleanupTimer?.Destroy();
            lastStop.Clear();
        }

        private void OnLiquidWeaponFiringStopped(LiquidWeapon liquidWeapon)
        {
            if (liquidWeapon == null) return;

            BasePlayer player = liquidWeapon.GetOwnerPlayer();
            if (player == null || player.IsNpc) return;

            float cooldown = GetCooldown(player);
            lastStop[player.UserIDString] = Time.realtimeSinceStartup;

            if (player.IsConnected)
            {
                player.ChatMessage(Msg("Cooldown", player.UserIDString, cooldown.ToString("0.#")));
            }
        }

        private object CanFireLiquidWeapon(LiquidWeapon liquidWeapon, BasePlayer player)
        {
            if (liquidWeapon == null || player == null) return null;

            float stoppedAt;
            if (!lastStop.TryGetValue(player.UserIDString, out stoppedAt)) return null;

            float cooldown = GetCooldown(player);
            float elapsed = Time.realtimeSinceStartup - stoppedAt;
            if (elapsed >= cooldown) return null;

            player.ChatMessage(Msg("Cooldown", player.UserIDString, (cooldown - elapsed).ToString("0.#")));
            return false;
        }

        private float GetCooldown(BasePlayer player)
        {
            return permission.UserHasPermission(player.UserIDString, PermShortCooldown)
                ? Mathf.Max(0f, config.VipCooldown)
                : Mathf.Max(0f, config.DefaultCooldown);
        }

        private void Cleanup()
        {
            float now = Time.realtimeSinceStartup;
            List<string> stale = null;
            foreach (KeyValuePair<string, float> entry in lastStop)
            {
                if (now - entry.Value > 300f)
                {
                    if (stale == null) stale = new List<string>();
                    stale.Add(entry.Key);
                }
            }
            if (stale == null) return;
            foreach (string id in stale) lastStop.Remove(id);
        }
    }
}

The plugin puts a configurable cooldown on flamethrowers per player. OnLiquidWeaponFiringStopped looks up the owner of the stopped LiquidWeapon, records Time.realtimeSinceStartup in a dictionary, and sends a localized chat message telling the player when they can fire again. CanFireLiquidWeapon checks the same dictionary and returns false while the cooldown is active, which prevents the next firing attempt. The dictionary is keyed by the player's userID string so it survives reconnects within the session. Unload clears the timers and the dictionary, and permissions (liquidweaponcooldown.vip) allow a shorter cooldown for selected groups. All player-facing text goes through the language file, so server owners can translate it.

Common use cases

  • Per-player flamethrower cooldowns

    Record the stop time and reject the next CanFireLiquidWeapon attempt until a configured cooldown elapses. This curbs sustained flame spam on PvP servers without disabling the weapon.

  • Usage statistics

    Accumulate a per-player counter and persist it with Interface.Oxide.DataFileSystem on a timer or on OnServerSave. Compare counts to find players who lean on flamethrowers in raids.

  • Event logging for admins

    Write a line with the owner's name, weapon prefab and world position to a data file or console output so staff can review suspicious flamethrower activity around a base.

Pitfalls

  • NPC and server liquid weapons also fire this hook

    OwnerID can be zero for weapons spawned by the server. Check GetOwnerPlayer() for null before treating the event as player-driven.

  • Not every stop is a release of the fire button

    Running out of fuel, unequipping and destroying the weapon all reach StopFiring. If you only want manual releases, compare ammo or inventory state before and after rather than assuming intent.

  • The hook cannot cancel the stop

    The return value is discarded, so you cannot keep the weapon firing from here. Prevent firing earlier through CanFireLiquidWeapon instead.

Build a plugin with OnLiquidWeaponFiringStopped

Describe what should happen and get a compiled plugin that uses this hook.

Prompt: Per-player flamethrower cooldowns using the OnLiquidWeaponFiringStopped 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 OnLiquidWeaponFiringStopped

Generate