CanFireLiquidWeapon
CanFireLiquidWeapon is called when a liquid weapon (flamethrower, water gun) checks whether it can fire, just before the game evaluates pump pressure and fuel. Returning a bool overrides the game's decision.
object CanFireLiquidWeapon(BasePlayer player, LiquidWeapon liquidWeapon)Parameters
| Parameter | Type | Description |
|---|---|---|
player | BasePlayer | The BasePlayer holding the liquid weapon and attempting to fire it. Always non-null in practice, but check it before touching inventory or player state. |
liquidWeapon | LiquidWeapon | The LiquidWeapon component instance calling CanFire, e.g. a Flame Thrower or Water Gun. Access its pressure, fuel state, and BaseEntity members such as OwnerID and net.ID for ownership checks. |
Return value
Returning a bool replaces the game's fire decision: true forces the weapon to fire even if it lacks pressure or fuel, false always blocks firing. Returning null or any non-bool value lets the original pressure and fuel logic run unchanged.
How it works
The hook fires inside LiquidWeapon.CanFire, the method the weapon calls to decide if a trigger pull should produce a shot. That check runs before the internal conditions, so the hook sees every attempt including ones that would fail because the tank is empty or the pump pressure is too low. player is the player holding the weapon and liquidWeapon is the weapon entity itself, so you can inspect OwnerID, ShortPrefabName, or send network updates from inside the hook.
The only way to override the result is to return a bool. Returning true lets the shot through even when the weapon is out of pressure or fuel; returning false blocks it regardless of state. Returning null (or any non-bool) leaves the normal pump and fuel checks in charge. Because the hook is only called on attempt, not per tick, it is cheap to run a permission check or a cooldown comparison here. Use it to gate weapon use by permission, zone, or custom cooldown rather than to modify damage, which belongs in OnEntityTakeDamage.
Example plugin: Restrict flamethrowers to a permission
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("Liquid Weapon Permission Gate", "RustPluginGenerator", "1.0.0")]
[Description("Restricts who can fire liquid weapons and enforces a per-player cooldown.")]
public class LiquidWeaponPermissionGate : RustPlugin
{
private const string PermUse = "liquidweaponpermissiongate.use";
private PluginConfig config;
private readonly Dictionary<string, float> lastShot = new Dictionary<string, float>();
private readonly Dictionary<string, float> lastNotice = new Dictionary<string, float>();
private class PluginConfig
{
[JsonProperty("Require permission to fire liquid weapons")]
public bool RequirePermission = true;
[JsonProperty("Cooldown between shots in seconds (0 = disabled)")]
public float CooldownSeconds = 0f;
[JsonProperty("Minimum seconds between cooldown messages")]
public float NoticeInterval = 2f;
}
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>
{
["NoPermission"] = "You do not have permission to use liquid weapons.",
["Cooldown"] = "Your liquid weapon is still cooling down."
}, 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 Unload()
{
lastShot.Clear();
lastNotice.Clear();
}
private object CanFireLiquidWeapon(BasePlayer player, LiquidWeapon liquidWeapon)
{
if (player == null || liquidWeapon == null) return null;
string userId = player.UserIDString;
if (config.RequirePermission && !permission.UserHasPermission(userId, PermUse))
{
Notify(player, "NoPermission", userId);
return false;
}
if (config.CooldownSeconds > 0f)
{
float last;
if (lastShot.TryGetValue(userId, out last))
{
if (Time.realtimeSinceStartup - last < config.CooldownSeconds)
{
Notify(player, "Cooldown", userId);
return false;
}
}
lastShot[userId] = Time.realtimeSinceStartup;
}
return null;
}
private void Notify(BasePlayer player, string key, string userId)
{
float last;
if (lastNotice.TryGetValue(userId, out last) &&
Time.realtimeSinceStartup - last < config.NoticeInterval)
{
return;
}
lastNotice[userId] = Time.realtimeSinceStartup;
player.ChatMessage(Msg(key, userId));
}
}
}The plugin registers a permission liquidweaponpermissiongate.use and, optionally, a per-player shot cooldown from the config. In CanFireLiquidWeapon it looks up the player's permission and checks the stored last-shot timestamp against Time.realtimeSinceStartup. When the player lacks permission or is still cooling down, the hook returns false and sends a lang message at most once per second so the chat does not spam. Otherwise it records the timestamp and returns null, letting the vanilla pressure and fuel checks decide. Cooldown state is kept per UserIDString in a dictionary, cleared on unload, so no data files are needed.
Common use cases
Permission-gated flamethrowers
Only allow players with a specific permission to fire liquid weapons, useful on servers that reserve the flamethrower for a donor or event tier.
Custom cooldown per player
Track the last shot time per user and block rapid re-triggering with a
falsereturn, enforced before the game's own pressure check.Zone or spawn protection
Block firing while the player is inside a safe zone or near a spawn point, without needing to disable the held item or interfere with the pressure system.
Pitfalls
Returning true bypasses pressure and fuel
A
truereturn lets the weapon fire even when the tank is empty or the pump is under pressure, so gate this on explicit conditions rather than always allowing.Hook fires on every attempt, not just successful shots
The check runs before internal validation, so a player holding an empty flamethrower still triggers it. Keep the work in the hook cheap and avoid chat spam.
Chat spam from blocked attempts
Players tap fire repeatedly. Throttle denial messages with a per-player timestamp instead of sending one on every blocked attempt.
Build a plugin with CanFireLiquidWeapon
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 CanFireLiquidWeapon
Generate