C#:
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Core.Libraries.Covalence;
using Oxide.Game.Rust.Cui;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("AmmoHUD", "Aevom", "1.1.8")]
[Description("Simple ammo display")]
public class AmmoHUD : RustPlugin
{
private const string PanelId = "AmmoHUDPanel";
private const string TextId = "AmmoHUDText";
private const string PermissionUse = "ammohud.use"; // permisssion
private readonly Dictionary<BasePlayer, bool> hudStates = new();
private Configuration config;
#region Configuration
private class Configuration
{
[JsonProperty("Panel Color (RGBA)")]
public string PanelColor { get; set; } = "0.4 0.4 0.4 0.5";
[JsonProperty("Panel Position Min")]
public string PanelMin { get; set; } = "0.92 0.18";
[JsonProperty("Panel Position Max")]
public string PanelMax { get; set; } = "0.989 0.22";
[JsonProperty("Ammo Text Font Size")]
public int FontSize { get; set; } = 15;
[JsonProperty("Ammo Image URL")]
public string AmmoIconUrl { get; set; } = "https://static.wikia.nocookie.net/play-rust/images/4/49/5.56_Rifle_Ammo_icon.png/revision/latest?cb=20150405103333";
[JsonProperty("Ammo Image Position Min")]
public string ImageMin { get; set; } = "0.05 0.1";
[JsonProperty("Ammo Image Position Max")]
public string ImageMax { get; set; } = "0.30 0.9";
[JsonProperty("Ammo Text Position Min")]
public string TextMin { get; set; } = "0.30 0";
[JsonProperty("Ammo Text Position Max")]
public string TextMax { get; set; } = "1 1";
}
protected override void LoadConfig()
{
base.LoadConfig();
try
{
config = Config.ReadObject<Configuration>();
SaveConfig();
}
catch
{
PrintWarning("Failed to read the config file. Loading default values.");
LoadDefaultConfig();
}
}
protected override void LoadDefaultConfig() => config = new Configuration();
protected override void SaveConfig() => Config.WriteObject(config);
#endregion
private void Init()
{
permission.RegisterPermission(PermissionUse, this);
foreach (var player in BasePlayer.activePlayerList)
OnPlayerInit(player);
}
private bool HasPermission(BasePlayer player) =>
permission.UserHasPermission(player.UserIDString, PermissionUse);
private void OnPlayerInit(BasePlayer player)
{
if (HasPermission(player))
ShowHUD(player);
}
private void OnPlayerDisconnected(BasePlayer player) => HideHUD(player);
private void RefreshHUDIfVisible(BasePlayer player)
{
if (hudStates.TryGetValue(player, out bool visible) && visible)
UpdateHUD(player);
}
private void OnPlayerSwitchWeapon(BasePlayer player, HeldEntity _) => RefreshHUDIfVisible(player);
private void OnActiveItemChanged(BasePlayer player, Item _, Item __) => RefreshHUDIfVisible(player);
private void OnPlayerRespawned(BasePlayer player) => RefreshHUDIfVisible(player);
private void OnPlayerSleepEnded(BasePlayer player) => RefreshHUDIfVisible(player);
private void OnPlayerSleepStart(BasePlayer player) => RefreshHUDIfVisible(player);
private void OnPlayerInventoryChanged(Item _, BasePlayer player) => RefreshHUDIfVisible(player);
private void OnReload(BasePlayer player) => RefreshHUDIfVisible(player);
private void OnPlayerTick(BasePlayer player) => RefreshHUDIfVisible(player);
private void OnPlayerWounded(BasePlayer player) => RefreshHUDIfVisible(player);
private void OnPlayerWakingUp(BasePlayer player) => RefreshHUDIfVisible(player);
private void ShowHUD(BasePlayer player)
{
HideHUD(player); // Clear any previous HUD
var container = new CuiElementContainer();
var panel = new CuiPanel
{
Image = { Color = config.PanelColor },
RectTransform = { AnchorMin = config.PanelMin, AnchorMax = config.PanelMax },
CursorEnabled = false
};
var panelGuid = container.Add(panel, "Hud", PanelId);
if (!string.IsNullOrEmpty(config.AmmoIconUrl))
{
container.Add(new CuiElement
{
Name = CuiHelper.GetGuid(),
Parent = panelGuid,
Components =
{
new CuiRawImageComponent
{
Url = config.AmmoIconUrl,
Sprite = "assets/content/ui/ui.background.tile.psd"
},
new CuiRectTransformComponent
{
AnchorMin = config.ImageMin,
AnchorMax = config.ImageMax
}
}
});
}
container.Add(new CuiLabel
{
Text = { Text = "0", FontSize = config.FontSize, Align = TextAnchor.MiddleLeft },
RectTransform = { AnchorMin = config.TextMin, AnchorMax = config.TextMax }
}, panelGuid, TextId);
CuiHelper.AddUi(player, container);
hudStates[player] = true;
UpdateHUD(player);
}
private void UpdateHUD(BasePlayer player)
{
if (!hudStates.TryGetValue(player, out var isEnabled) || !isEnabled)
return;
var activeItem = player.GetActiveItem();
string ammoDisplay = "0";
if (activeItem?.GetHeldEntity() is BaseProjectile weapon)
{
int current = weapon.primaryMagazine.contents;
int reserve = GetAmmoInInventory(player, weapon.primaryMagazine.ammoType);
ammoDisplay = $"{current} / {reserve}";
}
var updateContainer = new CuiElementContainer();
updateContainer.Add(new CuiLabel
{
Text = { Text = $"{ammoDisplay}", FontSize = config.FontSize, Align = TextAnchor.MiddleLeft },
RectTransform = { AnchorMin = config.TextMin, AnchorMax = config.TextMax }
}, PanelId, TextId);
CuiHelper.DestroyUi(player, TextId);
CuiHelper.AddUi(player, updateContainer);
}
private int GetAmmoInInventory(BasePlayer player, ItemDefinition ammoType)
{
int total = 0;
foreach (var item in player.inventory.containerMain.itemList)
if (item.info == ammoType)
total += item.amount;
foreach (var item in player.inventory.containerBelt.itemList)
if (item.info == ammoType)
total += item.amount;
// In the future Backpack plugins support
return total;
}
private void HideHUD(BasePlayer player)
{
if (hudStates.TryGetValue(player, out bool isVisible) && isVisible)
{
CuiHelper.DestroyUi(player, PanelId);
hudStates[player] = false;
}
}
[ChatCommand("ammo")]
private void ToggleAmmoHUD(BasePlayer player, string command, string[] args)
{
if (!HasPermission(player))
{
SendReply(player, "You don’t have permission to use this command.");
return;
}
if (hudStates.TryGetValue(player, out bool isVisible) && isVisible)
{
HideHUD(player);
SendReply(player, "AmmoHUD disabled.");
}
else
{
ShowHUD(player);
SendReply(player, "AmmoHUD enabled.");
}
}
private void Unload()
{
foreach (var player in BasePlayer.activePlayerList)
HideHUD(player);
}
}
}