Suggested QoL improvementsSuggestion

I’ve been using Rocket Guns and made two small changes that make it easier to control for server owners:

  1. Config-driven allowlist of 5.56 guns
  2. Config option to require toggling (or always-on mode)
These changes keep the original behavior by default (so existing servers don’t break).

Disclaimer: I am not proficient with C#, so I had help from ChatGPT.

Configurable allowlist of 5.56 guns (by shortname)

Instead of applying to all guns that use 5.56 ammo, the mod can now read a list of allowed gun shortnames from the config:
  • If the fired gun’s shortname is in the list → it shoots rockets
  • If not in the list → it fires normal bullets
If the list is empty, the plugin behaves like the original Rocket Guns (all 5.56 guns are enabled).

Config JSON
"Enabled 5.56 guns (shortnames). Empty list = all 5.56 guns": [
  "rifle.ak",
  "rifle.lr300"
]

Code changes
New config field:

[JsonProperty("Enabled 5.56 guns (shortnames). Empty list = all 5.56 guns")]
public List<string> Enabled556Guns = new List<string>();
Allowlist loader & check:
private readonly HashSet<string> allowed556Guns =
    new HashSet<string>(StringComparer.OrdinalIgnoreCase);

private void RefreshAllowedGuns()
{
    allowed556Guns.Clear();
    if (config?.Enabled556Guns == null) return;

    foreach (var s in config.Enabled556Guns)
    {
        if (string.IsNullOrWhiteSpace(s)) continue;
        allowed556Guns.Add(s.Trim());
    }
}

private bool IsAllowedWeapon(BaseProjectile weapon)
{
    if (weapon == null) return false;

    // Empty list = original behaviour (all 5.56 guns enabled)
    if (allowed556Guns.Count == 0) return true;

    var shortname = weapon.GetItem()?.info?.shortname;
    return !string.IsNullOrEmpty(shortname) && allowed556Guns.Contains(shortname);
}​

Hook gating (example):

if (IsRocketsEnabledFor(player)
    && ammo.ammoType == Rust.AmmoTypes.RIFLE_556MM
    && IsAllowedWeapon(weapon))
{
    ...
}



Config option: require toggle OR always-on

Adds a config boolean that controls whether players must run the toggle command:
  • true (default): original behavior (player must toggle on)
  • false: bypass toggle requirement → rockets are always enabled for permitted players
Config JSON
"Require players to toggle rockets on (true) or always enabled for permitted players (false)": true​

This does not remove permissions. The mod still requires rocketguns.use — it just bypasses the toggle requirement if set to false.

Code changes
New config field:
[JsonProperty("Require players to toggle rockets on (true) or always enabled for permitted players (false)")]
public bool RequirePlayersToToggle = true;​

Centralized “is enabled?” check (handles permission & toggle mode):

private const string PermUse = "rocketguns.use";

private bool IsRocketsEnabledFor(BasePlayer player)
{
    if (player == null) return false;
    if (!permission.UserHasPermission(player.userID.ToString(), PermUse)) return false;

    // Always-on mode
    if (!config.RequirePlayersToToggle) return true;

    // Toggle-required mode
    return ActiveGUNS.Contains(player.userID);
}​
Toggle command behavior when always-on:
if (!config.RequirePlayersToToggle)
{
    SendReply(basePlayer, "Rockets are always enabled on this server.");
    UpdateIcon(basePlayer);
    return;
}​


Icon behavior

The “ammo icon” UI is now gated the same way as firing rockets:
  • only shows for allowed 5.56 guns
  • only shows if rockets are enabled (toggle-on OR always-on mode)


The full code  is below:
using Newtonsoft.Json;
using Oxide.Game.Rust.Cui;
using UnityEngine;
using System;
using System.Collections.Generic;
using Oxide.Core.Libraries.Covalence;
using Oxide.Core;

namespace Oxide.Plugins
{
    [Info("Rocket Guns", "Sapnu Puas #3696", "1.2.4")]
    [Description("Allow 556 guns to fire rockets based on ammo type")]
    public class RocketGuns : RustPlugin
    {
        List<ulong> ActiveGUNS = new List<ulong>();
        
        private HashSet<string> allowed556Guns = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

        private const string PermUse = "rocketguns.use";
        #region[Rocket prefabs]
        public string Rocket = "assets/prefabs/ammo/rocket/rocket_basic.prefab";
        public string Hv = "assets/prefabs/ammo/rocket/rocket_hv.prefab";
        public string Fire = "assets/prefabs/ammo/rocket/rocket_fire.prefab";
        // public string Mrls = "assets/content/vehicles/mlrs/rocket_mlrs.prefab";
        #endregion[Rocket prefabs]

        #region GUI
        void DestroyCUI(BasePlayer player)
        {
            CuiHelper.DestroyUi(player, "GunUI");
        }
        public void CreateAmmoIcon(BasePlayer player, int ammo)
        {
            DestroyCUI(player);
            CuiElementContainer elements = new CuiElementContainer();
            string panel = elements.Add(new CuiPanel
            {
                Image = { Color = "0.5 0.5 0.5 0.0" },
                RectTransform = { AnchorMin = config.ImageAnchorMin, AnchorMax = config.ImageAnchorMax }
            }, "Hud.Menu", "GunUI");
            elements.Add(new CuiElement
            {
                Parent = panel,
                Components =
                {
                    new CuiImageComponent { ItemId = ammo },
                    new CuiRectTransformComponent {AnchorMin = "0 0", AnchorMax = "1 1"}
                }
            });
            CuiHelper.AddUi(player, elements);
        }
        #endregion GUI

        #region[Commands]
        private void ToggleRocketCMD(IPlayer player, string command, string[] args)
        {
            if (player.IsServer)
                return;

            BasePlayer basePlayer = player.Object as BasePlayer;
            if(basePlayer != null)
            {
                if (!permission.UserHasPermission(basePlayer.userID.ToString(), PermUse))
                {
                    SendReply(basePlayer, lang.GetMessage("NoPerm", this, basePlayer.userID.ToString()));
                    return;
                }

                // Optional: allow server owners to disable per-player toggling.
                // When disabled, rockets are always enabled for players with permission.
                if (config != null && !config.RequireToggle)
                {
                    SendReply(basePlayer, lang.GetMessage("AlwaysOn", this, basePlayer.userID.ToString()));
                    UpdateIcon(basePlayer);
                    return;
                }
                if (ActiveGUNS.Contains(basePlayer.userID))
                {
                    SendReply(basePlayer, lang.GetMessage("Off", this, basePlayer.userID.ToString()));
                    ActiveGUNS.Remove(basePlayer.userID);
                    DestroyCUI(basePlayer);
                    return;
                }
                else
                {
                    SendReply(basePlayer, lang.GetMessage("On", this, basePlayer.userID.ToString()));
                    ActiveGUNS.Add(basePlayer.userID);
                    UpdateIcon(basePlayer);
                    return;
                }
            }


           

        }
        #endregion[Commands]

        #region[Hooks]

        #region[load/unload]
        void Unload()
        {
            foreach (BasePlayer player in BasePlayer.activePlayerList)
            {
                DestroyCUI(player);
            }
            ActiveGUNS = null;
        }
        private void Init()
        {
            permission.RegisterPermission(PermUse, this);
            AddCovalenceCommand(config.Command, nameof(ToggleRocketCMD));
            RefreshAllowedGuns();
        }
        #endregion[load/unload]

        #region[gui Hooks]
        void OnPlayerDisconnected(BasePlayer player) => DestroyCUI(player);
        void OnPlayerDeath(BasePlayer player, HitInfo info) => DestroyCUI(player);
        object OnWeaponReload(BaseProjectile weapon, BasePlayer player)
        {
            if (player != null && player.userID.IsSteamId())
            {
                if (IsEnabledForPlayer(player))
                {
                   

                   
                    timer.Once(weapon.reloadTime + 0.2f, () =>
                    {
                        
                        UpdateIcon(player);
                    });

                   
                }
            }
            return null;
        }
        void OnActiveItemChanged(BasePlayer player, Item oldItem, Item newItem)
        {
           DestroyCUI(player);
            var heldEntity = player.GetActiveItem();
            if (heldEntity != null)
            {
                var weapon = heldEntity.GetHeldEntity() as BaseProjectile;
                if (weapon != null)
                {
                    if (!IsAllowedWeapon(weapon)) return;
                    if (IsEnabledForPlayer(player))
                    {
                        NextFrame(() =>
                        {
                            UpdateIcon(player);
                        });

                    }
                }
            }
        }
        void OnAmmoUnload(BaseProjectile weapon, Item item, BasePlayer player)
        {

            if (IsEnabledForPlayer(player))
            {
                NextFrame(() =>
                {
                    UpdateIcon(player);
                });

            }
            return;
        }
        #endregion[gui hooks]

        void OnWeaponFired(BaseProjectile weapon, BasePlayer player, ItemModProjectile ammo, ProtoBuf.ProjectileShoot projectiles)
        {
            if (player == null) return;
            if (IsEnabledForPlayer(player) && ammo.ammoType == Rust.AmmoTypes.RIFLE_556MM && IsAllowedWeapon(weapon))
            {
                string rocket = string.Empty;

                switch (ammo.name)
                {
                    case "ammo_rifle.item":
                        rocket = RocketToFire(config.Normal);
                        break;

                    case "ammo_rifle_hv.item":
                        rocket = RocketToFire(config.Hv);
                        break;

                    case "ammo_rifle_fire.item":
                        rocket = RocketToFire(config.Fire);
                        break;

                    case "ammo_rifle_explosive.item":
                        rocket = RocketToFire(config.Explo);
                        break;

                    default:
                        break;
                }

                if (string.IsNullOrEmpty(rocket))
                {
                    return;
                }
                FireRockets(player, rocket);
            }
            else return;
        }

        #endregion[Hooks]

        #region[Methods]

        private bool HasUsePermission(BasePlayer player)
        {
            if (player == null) return false;
            return permission.UserHasPermission(player.userID.ToString(), PermUse);
        }

        private bool IsEnabledForPlayer(BasePlayer player)
        {
            if (!HasUsePermission(player)) return false;
            // If toggling is disabled in config, rockets are always enabled for permitted players.
            if (config != null && !config.RequireToggle) return true;
            return ActiveGUNS.Contains(player.userID);
        }

        private void RefreshAllowedGuns()
        {
            allowed556Guns.Clear();
            if (config?.Enabled556Guns == null) return;

            foreach (var s in config.Enabled556Guns)
            {
                if (string.IsNullOrWhiteSpace(s)) continue;
                allowed556Guns.Add(s.Trim());
            }
        }

        private bool IsAllowedWeapon(BaseProjectile weapon)
        {
            if (weapon == null) return false;
            // Empty list = keep original behaviour (all 5.56 guns are enabled)
            if (allowed556Guns == null || allowed556Guns.Count == 0) return true;

            var item = weapon.GetItem();
            var shortname = item?.info?.shortname;
            if (string.IsNullOrEmpty(shortname)) return false;

            return allowed556Guns.Contains(shortname);
        }

        public string RocketToFire(int id)
        {
            switch (id)
            {
                case 1:
                    return Rocket;

                case 2:
                    return Hv;

                case 3:
                    return Fire;

                default:
                    return string.Empty;
            }

        }
        public int RocketIcon(int id)
        {
            switch (id)
            {
                case 1:
                    return -742865266;

                case 2:
                    return -1841918730;

                case 3:
                    return 1638322904;

                default:
                    return 0;
            }
        }
        public void UpdateIcon(BasePlayer player)
        {
            DestroyCUI(player);
            var heldEntity = player.GetActiveItem();
            if (heldEntity != null)
            {
                var weapon = heldEntity.GetHeldEntity() as BaseProjectile;
                if (weapon != null)
                {
                    if (!IsAllowedWeapon(weapon)) return;
                    var ammodef = weapon.primaryMagazine.ammoType;
                    ItemDefinition itemDefinition = ItemManager.FindItemDefinition(ammodef.itemid);
                    ItemModProjectile ammo = itemDefinition.GetComponent<ItemModProjectile>();
                    if (ammo.ammoType == Rust.AmmoTypes.RIFLE_556MM)
                    {
                        int rocketicon = 0;
                        var ammount = weapon.primaryMagazine.contents;

                        if (ammount < 1) return;
                        

                        var ammotype = weapon.primaryMagazine.ammoType;

                        switch (ammo.name)
                        {
                            case "ammo_rifle.item":
                                rocketicon = RocketIcon(config.Normal);
                                break;

                            case "ammo_rifle_hv.item":
                                rocketicon = RocketIcon(config.Hv);
                                break;

                            case "ammo_rifle_fire.item":
                                rocketicon = RocketIcon(config.Fire);
                                break;

                            case "ammo_rifle_explosive.item":
                                rocketicon = RocketIcon(config.Explo);
                                break;

                            default:
                                break;
                        }

                        if (rocketicon == 0)
                        {
                            rocketicon = ammotype.itemid;
                        }

                        CreateAmmoIcon(player, rocketicon);
                    }
                }
            }

        }
        public void FireRockets(BasePlayer player, string rocketPrefab)
        {
            if (player == null) return;
            var rocket = GameManager.server.CreateEntity(rocketPrefab, player.eyes.position, new Quaternion());
            if (rocket != null)
            {
                if(rocketPrefab != null)
                {
                    float speed = 0;

                    switch (rocketPrefab)
                    {
                        case "assets/prefabs/ammo/rocket/rocket_basic.prefab":
                            speed = config.NormalSpeed;
                            break;

                        case "assets/prefabs/ammo/rocket/rocket_hv.prefab":
                            speed = config.HvSpeed;
                            break;

                        case "assets/prefabs/ammo/rocket/rocket_fire.prefab":
                            speed = config.FireSpeed;
                            break;

                        default:
                            break;
                    }
                    rocket.creatorEntity = player;
                    rocket.SendMessage("InitializeVelocity", player.eyes.HeadForward() * speed);
                    rocket.OwnerID = player.userID;
                    rocket.Spawn();
                    rocket.ClientRPC(null, "RPCFire");


                    Interface.CallHook("OnRocketLaunched", player,rocket);


                }
                
            }
        }

        
        #endregion[Methods]

        #region Config
        public Configuration config;
        public class Configuration
        {
            [JsonProperty("Toggle command")]
            public string Command = "togglegun";

            [JsonProperty("Require players to toggle rockets on (true) or always enabled for permitted players (false)")]
            public bool RequireToggle = true;

            [JsonProperty("1 = normal rocket, 2 = hv rocket , 3 = incendiary rocket , 0 = none")]
            public int notused = 0;

            [JsonProperty("rocket type to fire when using normall 5.56")]
            public int Normal = 1;

            [JsonProperty("rocket type to fire when using hv 5.56")]
            public int Hv = 2;

            [JsonProperty("rocket type to fire when using Incendiary 5.56")]
            public int Fire = 3;

            [JsonProperty("rocket type to fire when using explosive 5.56")]
            public int Explo = 0;


            
            [JsonProperty("Enabled 5.56 guns (shortnames). Empty list = all 5.56 guns")]
            public List<string> Enabled556Guns = new List<string>();

//[JsonProperty("Allow Incendiary rockets (may cause server lag if too many fired)")]
           // public bool UseFire = false;

            [JsonProperty("Hv rocket speed ")]
            public float HvSpeed = 200;

            [JsonProperty("Normal rocket speed")]
            public float NormalSpeed = 100;

            [JsonProperty("Incendiary rocket speed")]
            public float FireSpeed = 100;

            [JsonProperty("Image AnchorMin")]
            public string ImageAnchorMin = "0.645 0.023";

            [JsonProperty("Image AnchorMax")]
            public string ImageAnchorMax = "0.688 0.095";

        }
        protected override void LoadConfig()
        {
            base.LoadConfig();
            try
            {
                config = Config.ReadObject<Configuration>();
                if (config == null) LoadDefaultConfig();
                SaveConfig();
                RefreshAllowedGuns();
            }
            catch (Exception e)
            {
                Debug.LogException(e);
                PrintWarning("Creating new config file.");
                LoadDefaultConfig();
            }
        }
        protected override void LoadDefaultConfig() => config = new Configuration();
        protected override void SaveConfig() => Config.WriteObject(config);
        #endregion

        #region[Localization]
        protected override void LoadDefaultMessages()
        {
            lang.RegisterMessages(new Dictionary<string, string>
            {
                ["NoPerm"] = "You dont have permission to use this command",
                ["Off"] = "Raid gun disengaged",
                ["On"] = "Raid gun engaged",
                ["AlwaysOn"] = "Rockets are always enabled on this server."
            }, this);
        }
        #endregion[Localization]
    }
}​

im currently in the process of rewriting the whole plugin to enclude all weapons so ill try and incorporate these settings 

Great! I've tested with other options that could benefit servers with shops or rewards. Specifically, being able to lock the rocket ability to a specific gun with a specific skin ID. I got the idea from the latest post before this by Tanki, and it works.

the new update will also include the option to only work with guns with a certain skinid also . you will also need to have the rockets in your inventory . it will work like loading a rocket launcher 

Any update on the updated plugin will release? And could you possibly make it where you can control the damage of the rockets say like when using the command it does like a flat 100 damage because right now it seems a little OP especially for like raid bases and such just a suggestion I'm sure other server owners would like that also.