Decompiled source of Vektor CP1 v1.0.1

Vektor_CP1.dll

Decompiled 13 hours ago
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using FistVR;
using H3VRUtils;
using HarmonyLib;
using OtherLoader;
using UnityEngine;
using UnityEngine.UI;

[assembly: Debuggable(DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
namespace Iqsbasiczz.Vektor_CP1;

[BepInPlugin("Iqsbasiczz.Vektor_CP1", "Vektor_CP1", "1.0.1")]
[BepInProcess("h3vr.exe")]
[Description("Built with MeatKit")]
[BepInDependency("h3vr.otherloader", "1.3.0")]
public class Vektor_CP1Plugin : BaseUnityPlugin
{
	private static readonly string BasePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);

	internal static ManualLogSource Logger;

	private void Awake()
	{
		Logger = ((BaseUnityPlugin)this).Logger;
		LoadAssets();
	}

	private void LoadAssets()
	{
		Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "Iqsbasiczz.Vektor_CP1");
		OtherLoader.RegisterDirectLoad(BasePath, "Iqsbasiczz.Vektor_CP1", "", "", "vekcp1", "");
	}
}
public class ExpandedAmmoDisplay : MonoBehaviour
{
	[Header("Ammo Counter Settings")]
	[Tooltip("Text to display ammo left in the gun.")]
	public Text UItext;

	[Tooltip("Text to display maximum ammo.")]
	public Text MaxAmmoText;

	[Tooltip("Text to display the type of ammo.")]
	public Text ammoTypeText;

	[Tooltip("Adds a minimum character count. See tooltip for MinCharLength for more.")]
	public bool AddMinCharLength;

	[Tooltip("i.e if MinCharLength is 2 and the amount of rounds left is 5, it will display 05 instead of 5.")]
	public int MinCharLength;

	[Tooltip("Will not instantly be the correct amount of rounds, but will tick up/down until it is.")]
	public bool enableDispLerp;

	[Tooltip("MaxAmmo will also lerp according to the DispLerpAmt")]
	public bool enableLerpForMaxAmmo;

	[Tooltip("EnabledObjects will also lerp according to the DispLerpAmt")]
	public bool enableLerpForEnabledObjects;

	[Tooltip("From 0-1. The % amount moved towards its correct amount every 50th of a second.")]
	[Range(0f, 0.2f)]
	public float DispLerpAmt;

	[Header("Alternate Displays")]
	[Tooltip("Enables enabling/disabling objects based on rounds left in mag.")]
	public bool EnabledObjects;

	[Tooltip("Object enabled when there is no magazine.")]
	public GameObject ObjectWhenEmpty;

	[Tooltip("Element no. corresponds to rounds left. 0 means no rounds, 1 means one round. Enables the 5th object if there are 5 rounds, and so on.")]
	public List<GameObject> Objects;

	[Tooltip("Enables all objects under the round count. Enables the 0th, 1st, 2nd, 3rd objects if there are 3 rounds left, and so on.")]
	public bool EnableAllUnderAmount;

	[Tooltip("Overrides Objects. #0 means Objects' #0 displays from 0% to #0%, #1 means Objects' #1 displays from #0% to #1%, etc- written normally, not mathmatically (e.g 57.32)")]
	public bool EnableBasedOnPercentage;

	public List<float> ObjectPercentages;

	[Header("Fire Mode Display")]
	[Tooltip("Text to display the fire mode (e.g., Safe, Single, FullAuto, Burst).")]
	public Text fireModeText;

	[Tooltip("Image to display fire mode visually.")]
	public Image fireModeImage;

	[Tooltip("Sprites for each fire mode: 0=Safe, 1=Single, 2=FullAuto, 3=Burst, 4=Other.")]
	public Sprite[] fireModeSprites;

	[Header("Low Ammo Warning")]
	[Tooltip("Enable sound and blink effects when ammo drops to a percentage of max.")]
	public bool enableLowAmmoWarning;

	[Tooltip("Percentage of max ammo at which the warning triggers (e.g. 25 means 25%).")]
	[Range(0f, 100f)]
	public float lowAmmoThresholdPercent = 25f;

	[Tooltip("AudioSource used to play warning sounds.")]
	public AudioSource warningAudioSource;

	[Tooltip("Sound played once when ammo drops to or below the low ammo threshold.")]
	public AudioClip lowAmmoClip;

	[Tooltip("Sound played once when ammo is fully depleted (0 rounds).")]
	public AudioClip depletedAmmoClip;

	[Tooltip("Enable blinking on the ammo text when at or below the low ammo threshold.")]
	public bool enableLowAmmoBlink;

	[Tooltip("How many times per second the text blinks on/off.")]
	public float blinkRate = 4f;

	[Header("Chamber Indicator (optional)")]
	[Tooltip("Enable a visual/text indicator when there is a round in the chamber.")]
	public bool showChamberIndicator = false;

	[Tooltip("If true the indicator will use an Image; otherwise it will use Text.")]
	public bool chamberIndicatorUseImage = true;

	[Tooltip("Image used to indicate a round is chambered. Assign only if using image mode.")]
	public Image chamberIndicatorImage;

	[Tooltip("Text used to indicate a round is chambered. Assign only if using text mode.")]
	public Text chamberIndicatorText;

	[Tooltip("Text shown when a round is chambered (used when chamberIndicatorUseImage == false).")]
	public string chamberIndicatorString = "CH";

	private FVRFireArm _fa;

	private FVRFireArmMagazine _mag;

	private FVRFirearmMovingProxyRound[] proxies;

	private FVRFireArmChamber[] chambers;

	private int lastAmountOfBullets;

	private int lastAmountOfMaxBullets;

	private int lastAmountOfBulletsForEnableObjects;

	private bool _hasPlayedLowAmmoSound;

	private bool _hasPlayedDepletedSound;

	private bool _isBlinking;

	private float _blinkTimer;

	private int _previousAmmoCount = -1;

	private bool _hadMagLastFrame;

	private bool _isChamberIndicatorImageNotNull;

	private bool _isChamberIndicatorTextNotNull;

	private bool _isUItextNotNull;

	private bool _isMaxAmmoTextNotNull;

	private bool _isammoTypeTextNotNull;

	private bool _isfireModeTextNotNull;

	private bool _isfireModeImageNotNull;

	private void Start()
	{
		NullCheck();
	}

	private void GetFirearmAndMag()
	{
		_fa = ((Component)this).GetComponent<FVRFireArm>() ?? ((Component)this).GetComponentInParent<FVRFireArm>();
		if ((Object)(object)_fa != (Object)null)
		{
			_mag = _fa.Magazine;
			if (chambers == null)
			{
				chambers = GetFireArmDeets.GetFireArmChamber(_fa);
			}
			proxies = GetFireArmDeets.GetFireArmProxySwitch(_fa, false);
		}
		else
		{
			_mag = null;
			chambers = null;
			proxies = null;
		}
	}

	private void Update()
	{
		GetFirearmAndMag();
		int ammoCount = GetAmmoCount();
		int maxAmmoCount = GetMaxAmmoCount();
		bool flag = (Object)(object)_mag != (Object)null;
		if (_isUItextNotNull)
		{
			string text = CalculateAmmoCounterAmount(ammoCount, ref lastAmountOfBullets, enableDispLerp, DispLerpAmt, AddMinCharLength, MinCharLength);
			UItext.text = text;
		}
		if (_isMaxAmmoTextNotNull)
		{
			string text2 = CalculateAmmoCounterAmount(maxAmmoCount, ref lastAmountOfMaxBullets, enableLerpForMaxAmmo, DispLerpAmt, AddMinCharLength, MinCharLength);
			MaxAmmoText.text = text2;
		}
		if (_isammoTypeTextNotNull)
		{
			ammoTypeText.text = GetAmmoType();
		}
		if (_isfireModeTextNotNull || _isfireModeImageNotNull)
		{
			string fireMode = GetFireMode();
			if (_isfireModeTextNotNull)
			{
				fireModeText.text = fireMode;
			}
			if (_isfireModeImageNotNull && fireModeSprites != null && fireModeSprites.Length > 0)
			{
				int spriteIndexForMode = GetSpriteIndexForMode(fireMode);
				if (spriteIndexForMode >= 0 && spriteIndexForMode < fireModeSprites.Length)
				{
					fireModeImage.sprite = fireModeSprites[spriteIndexForMode];
				}
			}
		}
		if (EnabledObjects)
		{
			int num = int.Parse(CalculateAmmoCounterAmount(ammoCount, ref lastAmountOfBulletsForEnableObjects, enableLerpForEnabledObjects, DispLerpAmt));
			if (EnableBasedOnPercentage)
			{
				SetEnabledObjectsPercentage(num);
			}
			else
			{
				SetEnabledObjects(num);
			}
		}
		if (enableLowAmmoWarning)
		{
			UpdateLowAmmoWarning(ammoCount, maxAmmoCount, flag);
		}
		else
		{
			ResetWarningState();
		}
		if (showChamberIndicator)
		{
			int num2 = 0;
			if (chambers != null)
			{
				num2 = chambers.Count((FVRFireArmChamber chamber) => chamber.IsFull && !chamber.IsSpent);
			}
			bool flag2 = num2 > 0;
			if (chamberIndicatorUseImage)
			{
				if (_isChamberIndicatorImageNotNull && (Object)(object)chamberIndicatorImage != (Object)null)
				{
					((Component)chamberIndicatorImage).gameObject.SetActive(flag2);
				}
			}
			else if (_isChamberIndicatorTextNotNull && (Object)(object)chamberIndicatorText != (Object)null)
			{
				((Component)chamberIndicatorText).gameObject.SetActive(flag2);
				if (flag2)
				{
					chamberIndicatorText.text = chamberIndicatorString;
				}
			}
		}
		else
		{
			if (_isChamberIndicatorImageNotNull && (Object)(object)chamberIndicatorImage != (Object)null)
			{
				((Component)chamberIndicatorImage).gameObject.SetActive(false);
			}
			if (_isChamberIndicatorTextNotNull && (Object)(object)chamberIndicatorText != (Object)null)
			{
				((Component)chamberIndicatorText).gameObject.SetActive(false);
			}
		}
		_previousAmmoCount = ammoCount;
		_hadMagLastFrame = flag;
	}

	private void UpdateLowAmmoWarning(int currentAmmo, int maxAmmo, bool hasMag)
	{
		if (!hasMag)
		{
			ResetWarningState();
			return;
		}
		bool flag = hasMag && !_hadMagLastFrame;
		bool flag2 = false;
		bool flag3 = false;
		if (maxAmmo > 0)
		{
			if (currentAmmo > 0)
			{
				float num = (float)currentAmmo / (float)maxAmmo * 100f;
				flag2 = num <= lowAmmoThresholdPercent;
			}
			if (_previousAmmoCount > 0)
			{
				float num2 = (float)_previousAmmoCount / (float)maxAmmo * 100f;
				flag3 = num2 <= lowAmmoThresholdPercent;
			}
		}
		if (flag2 && (!flag3 || flag))
		{
			PlayWarningClip(lowAmmoClip);
		}
		if (currentAmmo <= 0)
		{
			bool flag4 = _previousAmmoCount > 0;
			bool flag5 = flag;
			if ((flag4 || flag5) && !_hasPlayedDepletedSound)
			{
				PlayWarningClip(depletedAmmoClip);
				_hasPlayedDepletedSound = true;
			}
		}
		if (maxAmmo > 0 && currentAmmo > 0)
		{
			float num3 = (float)currentAmmo / (float)maxAmmo * 100f;
			if (num3 > lowAmmoThresholdPercent)
			{
				_hasPlayedDepletedSound = false;
			}
		}
		if (enableLowAmmoBlink && _isUItextNotNull && (flag2 || _hasPlayedDepletedSound))
		{
			_isBlinking = true;
			_blinkTimer += Time.deltaTime;
			float num4 = ((!(blinkRate > 0f)) ? 1f : (1f / blinkRate));
			bool enabled = _blinkTimer % num4 < num4 * 0.5f;
			((Behaviour)UItext).enabled = enabled;
		}
		else if (_isBlinking)
		{
			_isBlinking = false;
			_blinkTimer = 0f;
			if (_isUItextNotNull)
			{
				((Behaviour)UItext).enabled = true;
			}
		}
	}

	private void ResetWarningState()
	{
		if (_isBlinking)
		{
			_isBlinking = false;
			_blinkTimer = 0f;
			if (_isUItextNotNull)
			{
				((Behaviour)UItext).enabled = true;
			}
		}
		_hasPlayedLowAmmoSound = false;
		_hasPlayedDepletedSound = false;
	}

	private void PlayWarningClip(AudioClip clip)
	{
		if ((Object)(object)clip != (Object)null && (Object)(object)warningAudioSource != (Object)null)
		{
			warningAudioSource.PlayOneShot(clip);
		}
	}

	private int GetAmmoCount()
	{
		if ((Object)(object)_mag != (Object)null)
		{
			return _mag.m_numRounds;
		}
		int num = 0;
		if ((Object)(object)_fa != (Object)null)
		{
			if (chambers != null)
			{
				num += chambers.Count((FVRFireArmChamber chamber) => chamber.IsFull && !chamber.IsSpent);
			}
			if (proxies != null)
			{
				FVRFirearmMovingProxyRound[] array = proxies;
				foreach (FVRFirearmMovingProxyRound val in array)
				{
					if (val.IsFull)
					{
						num++;
					}
				}
			}
			if ((Object)(object)_fa.BeltDD != (Object)null)
			{
				num += _fa.BeltDD.m_roundsOnBelt;
			}
		}
		return num;
	}

	private int GetMaxAmmoCount()
	{
		if ((Object)(object)_mag != (Object)null)
		{
			return _mag.m_capacity;
		}
		if ((Object)(object)_fa != (Object)null && !_fa.UsesMagazines)
		{
			return (chambers != null) ? chambers.Length : 0;
		}
		return 0;
	}

	private string GetAmmoType()
	{
		//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_009b: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)_fa != (Object)null)
		{
			List<FireArmRoundClass> chamberRoundList = _fa.GetChamberRoundList();
			if (chamberRoundList != null && chamberRoundList.Count > 0)
			{
				return AM.GetFullRoundName(_fa.RoundType, chamberRoundList[0]);
			}
			if ((Object)(object)_fa.BeltDD != (Object)null && _fa.BeltDD.m_roundsOnBelt > 0)
			{
				return AM.GetFullRoundName(_fa.RoundType, _fa.BeltDD.BeltRounds[0].LR_Class);
			}
		}
		if ((Object)(object)_mag != (Object)null && _mag.m_numRounds > 0)
		{
			return AM.GetFullRoundName(_mag.RoundType, _mag.LoadedRounds[0].LR_Class);
		}
		return string.Empty;
	}

	private string GetFireMode()
	{
		if ((Object)(object)_fa == (Object)null)
		{
			return "N/A";
		}
		FVRFireArm fa = _fa;
		Handgun val = (Handgun)(object)((fa is Handgun) ? fa : null);
		if ((Object)(object)val == (Object)null)
		{
			return "N/A";
		}
		if (val.IsSafetyEngaged)
		{
			return "Safe";
		}
		if (val.FireSelectorModes != null && val.FireSelectorModes.Length > 0)
		{
			FireSelectorMode val2 = val.FireSelectorModes[val.FireSelectorModeIndex];
			return ((object)(FireSelectorModeType)(ref val2.ModeType)).ToString();
		}
		return "N/A";
	}

	private int GetSpriteIndexForMode(string mode)
	{
		return mode switch
		{
			"Safe" => 0, 
			"Single" => 1, 
			"FullAuto" => 2, 
			"Burst" => 3, 
			_ => 4, 
		};
	}

	public static string CalculateAmmoCounterAmount(int currentammo, ref int lastammo, bool lerp = false, float lerpAmt = 0f, bool pad = false, int padAmt = 0)
	{
		if (lerp)
		{
			currentammo = LerpInt(lastammo, currentammo, lerpAmt);
		}
		string text = currentammo.ToString();
		if (pad)
		{
			text = PadStringNumberToAmt(text, padAmt);
		}
		lastammo = currentammo;
		return text;
	}

	public static string PadStringNumberToAmt(string str, int minCharLength)
	{
		int num = minCharLength - str.Length;
		for (int i = 0; i < num; i++)
		{
			str = "0" + str;
		}
		return str;
	}

	public static int LerpInt(int a, int b, float lerp)
	{
		bool flag = a == 0;
		a = Mathf.CeilToInt(Mathf.Lerp((float)a, (float)b, lerp));
		if (a == 1 && flag)
		{
			a = 0;
		}
		return a;
	}

	private void SetEnabledObjects(int amt)
	{
		amt = Mathf.Clamp(amt, 0, Objects.Count - 1);
		for (int i = 0; i < Objects.Count; i++)
		{
			Objects[i].SetActive(false);
		}
		if ((Object)(object)ObjectWhenEmpty != (Object)null)
		{
			ObjectWhenEmpty.SetActive(false);
		}
		if ((Object)(object)_mag == (Object)null && (Object)(object)ObjectWhenEmpty != (Object)null)
		{
			ObjectWhenEmpty.SetActive(true);
			return;
		}
		for (int j = 0; j < Objects.Count; j++)
		{
			if (j < amt)
			{
				if (EnableAllUnderAmount)
				{
					Objects[j].SetActive(true);
				}
			}
			else if (j == amt)
			{
				Objects[j].SetActive(true);
			}
		}
	}

	private void SetEnabledObjectsPercentage(int amt)
	{
		amt = Mathf.Clamp(amt, 0, Objects.Count - 1);
		int maxAmmoCount = GetMaxAmmoCount();
		if (maxAmmoCount <= 0)
		{
			return;
		}
		float num = (float)amt / (float)maxAmmoCount;
		for (int i = 0; i < Objects.Count; i++)
		{
			Objects[i].SetActive(false);
		}
		if ((Object)(object)ObjectWhenEmpty != (Object)null)
		{
			ObjectWhenEmpty.SetActive(false);
		}
		if ((Object)(object)_mag == (Object)null && (Object)(object)ObjectWhenEmpty != (Object)null)
		{
			ObjectWhenEmpty.SetActive(true);
			return;
		}
		for (int j = 0; j < Objects.Count; j++)
		{
			float num2 = ObjectPercentages[j] / 100f;
			float num3 = 0f;
			if (j > 0)
			{
				num3 = ObjectPercentages[j - 1] / 100f;
			}
			if (!(num > num2))
			{
				continue;
			}
			if (num > num3)
			{
				if (EnableAllUnderAmount)
				{
					Objects[j].SetActive(true);
				}
			}
			else
			{
				Objects[j].SetActive(true);
			}
		}
	}

	public void NullCheck()
	{
		_isammoTypeTextNotNull = (Object)(object)ammoTypeText != (Object)null;
		_isMaxAmmoTextNotNull = (Object)(object)MaxAmmoText != (Object)null;
		_isUItextNotNull = (Object)(object)UItext != (Object)null;
		_isfireModeTextNotNull = (Object)(object)fireModeText != (Object)null;
		_isfireModeImageNotNull = (Object)(object)fireModeImage != (Object)null;
		_isChamberIndicatorImageNotNull = (Object)(object)chamberIndicatorImage != (Object)null;
		_isChamberIndicatorTextNotNull = (Object)(object)chamberIndicatorText != (Object)null;
	}
}