Panels/WeaponSwitcher.razor
@using Sandbox;
@using Sandbox.UI;

@inherits PanelComponent
@namespace Sandbox

<root>
	<label class="title">Weapons</label>
	<div class="weapons">

		@{
			var i = 0;

			@foreach (var weapon in GameObject.Root.GetComponentsInChildren<TestWeapon>(true))
			{
				i++;

				<div class="weapon @GetClass(weapon)">
					<label class="number">@i</label>
					<label class="name">@weapon.GameObject.Name.ToUpperInvariant()</label>

					@if (weapon.Active && weapon.MaxAmmo > 0)
					{
						<label class="ammo">@(weapon.Ammo) / @(weapon.MaxAmmo)</label>
					}
				</div>
			}
		}
	</div>

</root>

@code
{
	/// <summary>
	/// the hash determines if the system should be rebuilt. If it changes, it will be rebuilt
	/// </summary>
	protected override int BuildHash() => System.HashCode.Combine( Time.Now );

	string GetClass( TestWeapon weapon )
	{
		if ( weapon.Active )
			return "equipped";
		return string.Empty;
	}

	private bool isSwitching = false;

	private async Task Switch(TestWeapon newWeapon)
	{
		if (isSwitching) return;

		isSwitching = true;

		var weapons = GameObject.Root.GetComponentsInChildren<TestWeapon>(true);
		var currentWeapon = weapons.FirstOrDefault(x => x.Active);

		if (currentWeapon is not null)
		{
			await currentWeapon.Holster();
			currentWeapon.GameObject.Enabled = false;
		}

		newWeapon.GameObject.Enabled = true;
		isSwitching = false;
	}

	protected override void OnUpdate()
	{
		if (isSwitching) return;

		var weapons = GameObject.Root.GetComponentsInChildren<TestWeapon>(true).ToList();
		var currentIndex = weapons.FindIndex(x => x.Active);
		if (currentIndex == -1) return;

		for (int i = 0; i < weapons.Count; i++)
		{
			if (Input.Pressed($"Slot{i + 1}"))
			{
				_ = Switch(weapons[i]);
				return;
			}
		}

		if (Input.MouseWheel.y == 0) return;

		var wheelDir = -Input.MouseWheel.y;
		var nextIndex = currentIndex;

		if (wheelDir > 0)
			nextIndex = (currentIndex + 1) % weapons.Count;
		else
			nextIndex = (currentIndex - 1 + weapons.Count) % weapons.Count;

		_ = Switch(weapons[nextIndex]);
	}
}