Decompiled source of SpritesBloodMistFXRemastered v1.0.2

OPEN ME/Mods/Hitmarkers.dll

Decompiled a week ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using AudioImportLib;
using BoneLib;
using BoneLib.BoneMenu;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSLZ.Marrow;
using Il2CppSLZ.Marrow.AI;
using Il2CppSLZ.Marrow.Interaction;
using Il2CppSLZ.Marrow.PuppetMasta;
using Il2CppSLZ.Marrow.Utilities;
using Il2CppSystem;
using MelonLoader;
using MelonLoader.Preferences;
using MelonLoader.Utils;
using NEP.Hitmarkers;
using NEP.Hitmarkers.Data;
using UnityEngine;
using UnityEngine.Events;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("Simple hitmarkers mod for BONELAB.")]
[assembly: AssemblyDescription("Simple hitmarkers mod for BONELAB.")]
[assembly: AssemblyCompany("Not Enough Photons")]
[assembly: AssemblyProduct("Hitmarkers")]
[assembly: AssemblyCopyright("Created by Not Enough Photons")]
[assembly: AssemblyTrademark("Not Enough Photons")]
[assembly: AssemblyFileVersion("2.8.3")]
[assembly: MelonInfo(typeof(Main), "Hitmarkers", "2.8.3", "Not Enough Photons", null)]
[assembly: MelonColor]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.8.3.0")]
[module: UnverifiableCode]
namespace NEP.Hitmarkers
{
	public struct HitData
	{
		public Projectile projectile;

		public Vector3 worldHit;

		public Collider collider;

		public BehaviourBaseNav behaviour;

		public AIBrain brain;
	}
	public static class HitDirector
	{
		public static Action<HitData> OnHit;

		public static Action<PuppetMaster> OnKill;

		public static RigManager lastHitManager;

		public static void Initialize()
		{
			OnHit = (Action<HitData>)Delegate.Combine(OnHit, new Action<HitData>(OnProjectileHit));
			PuppetMaster.OnDeathStatsEvent += Action<PuppetMaster>.op_Implicit((Action<PuppetMaster>)OnPuppetDeath);
		}

		public static bool EvaluateHit(HitData data)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			if ((int)data.projectile._proxy.triggerType != 0)
			{
				return true;
			}
			if ((Object)(object)data.brain != (Object)null && data.brain.isDead)
			{
				return false;
			}
			GameObject gameObject = ((Component)data.collider).gameObject;
			if (gameObject.layer == LayerMask.NameToLayer("EnemyColliders"))
			{
				return true;
			}
			if (Object.op_Implicit((Object)(object)gameObject.GetComponent<HitmarkerProxy>()))
			{
				return true;
			}
			return false;
		}

		public static void OnProjectileHit(HitData data)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			if (EvaluateHit(data))
			{
				HitmarkerManager.Instance.SpawnMarker(data.worldHit);
			}
		}

		public static void OnPuppetDeath(PuppetMaster puppet)
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			Il2CppReferenceArray<BehaviourBase> behaviours = puppet.behaviours;
			object obj;
			if (behaviours == null)
			{
				obj = null;
			}
			else
			{
				BehaviourBase? obj2 = ((IEnumerable<BehaviourBase>)behaviours).FirstOrDefault();
				obj = ((obj2 != null) ? ((Il2CppObjectBase)obj2).TryCast<BehaviourBaseNav>() : null);
			}
			BehaviourBaseNav val = (BehaviourBaseNav)obj;
			if (!((Object)(object)val == (Object)null))
			{
				OnKill?.Invoke(puppet);
				HitmarkerManager.Instance.SpawnMarker(val.eyeTran.position, finisher: true);
			}
		}
	}
	[HarmonyPatch(typeof(Projectile))]
	[HarmonyPatch("Awake")]
	public static class ProjectilePatch
	{
		public static void Postfix(Projectile __instance)
		{
			((UnityEvent<Collider, Vector3, Vector3>)(object)__instance.onCollision).AddListener(UnityAction<Collider, Vector3, Vector3>.op_Implicit((Action<Collider, Vector3, Vector3>)delegate(Collider hitCol, Vector3 world, Vector3 normal)
			{
				//IL_003e: Unknown result type (might be due to invalid IL or missing references)
				//IL_003f: Unknown result type (might be due to invalid IL or missing references)
				MarrowBody val = MarrowBody.Cache.Get(((Component)hitCol).gameObject);
				if (!((Object)(object)val == (Object)null))
				{
					AIBrain component = ((Component)val.Entity).GetComponent<AIBrain>();
					HitData hitData = default(HitData);
					hitData.projectile = __instance;
					hitData.worldHit = world;
					hitData.collider = hitCol;
					hitData.brain = component;
					HitData obj = hitData;
					HitDirector.OnHit?.Invoke(obj);
				}
			}));
		}
	}
	[HarmonyPatch(typeof(PuppetMaster))]
	[HarmonyPatch("Awake")]
	public static class PuppetMasterPatch
	{
		public static void Postfix(PuppetMaster __instance)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			StateSettings stateSettings = __instance.stateSettings;
			stateSettings.killDuration = 0f;
			__instance.stateSettings = stateSettings;
		}
	}
	[RegisterTypeInIl2Cpp]
	public class Hitmarker : MonoBehaviour
	{
		private bool _isFinisher;

		private AudioClip[] _hitAudio;

		private AudioClip[] _finisherAudio;

		private Animator _markerAnimator;

		private Animator _finisherAnimator;

		private GameObject _markerObject;

		private GameObject _finisherObject;

		private Material _markerMaterial;

		private Material _finisherMaterial;

		private Material _finisherSkullMaterial;

		private AudioSource _source;

		private float _timerHide;

		private float _timeUntilHide = 1f;

		public AudioClip[] HitAudio => _hitAudio;

		public AudioClip[] FinisherAudio => _finisherAudio;

		public bool IsFinisher
		{
			get
			{
				return _isFinisher;
			}
			set
			{
				_isFinisher = value;
			}
		}

		public Hitmarker(IntPtr ptr)
			: base(ptr)
		{
		}

		private void Awake()
		{
			_markerObject = ((Component)((Component)this).transform.Find("Marker")).gameObject;
			_finisherObject = ((Component)((Component)this).transform.Find("Finisher")).gameObject;
			_markerAnimator = _markerObject.GetComponent<Animator>();
			_finisherAnimator = _finisherObject.GetComponent<Animator>();
			_source = ((Component)((Component)this).transform.Find("Source")).GetComponent<AudioSource>();
			_markerObject.SetActive(false);
			_finisherObject.SetActive(false);
			_markerMaterial = ((Renderer)_markerObject.GetComponent<MeshRenderer>()).material;
			_finisherMaterial = ((Renderer)_finisherObject.GetComponent<MeshRenderer>()).material;
			_finisherSkullMaterial = ((Renderer)((Component)_finisherObject.transform.Find("DeathSkull")).GetComponent<MeshRenderer>()).material;
		}

		private void OnEnable()
		{
			SetTextures();
			SetAudio();
			PlayAnimation();
			PlayAudio();
		}

		private void PlayAnimation()
		{
			if (_isFinisher)
			{
				_finisherObject.SetActive(true);
				_markerObject.SetActive(false);
				int value = Random.Range(1, 2);
				_finisherAnimator.Play($"finisher_appear_{value}");
			}
			else
			{
				_finisherObject.SetActive(false);
				_markerObject.SetActive(true);
				int value2 = Random.Range(1, 2);
				_markerAnimator.Play($"marker_appear_{value2}");
			}
		}

		private void Update()
		{
			if (((Component)this).gameObject.activeInHierarchy)
			{
				((Component)this).transform.LookAt(Player.Head);
				_timerHide += Time.deltaTime;
				if (_timerHide > _timeUntilHide)
				{
					((Component)this).gameObject.SetActive(false);
					_timerHide = 0f;
				}
			}
		}

		private void PlayAudio()
		{
			AudioClip[] array = ((!_isFinisher) ? _hitAudio : _finisherAudio);
			if (array != null)
			{
				Audio.Play2DOneShot(array, Audio.UI, Options.HitmarkerSFX, Options.HitmarkerPitch);
			}
		}

		private void SetAudio()
		{
			MarkerSkin skin = HitmarkerManager.Instance.Skin;
			MarkerSkin favoriteSkin = HitmarkerManager.Instance.FavoriteSkin;
			MarkerSkin defaultSkin = HitmarkerManager.Instance.DefaultSkin;
			if (skin == null)
			{
				_hitAudio = favoriteSkin.HitClips;
				_finisherAudio = favoriteSkin.FinisherClips;
				return;
			}
			if (skin == null && favoriteSkin == null)
			{
				_hitAudio = defaultSkin.HitClips;
				_finisherAudio = defaultSkin.FinisherClips;
				return;
			}
			if (defaultSkin == null)
			{
				throw new NullReferenceException("Default fallback skin is missing!");
			}
			_hitAudio = ((skin.HitClips != null) ? skin.HitClips : favoriteSkin.HitClips);
			_finisherAudio = ((skin.FinisherClips != null) ? skin.FinisherClips : favoriteSkin.FinisherClips);
		}

		private void SetTextures()
		{
			MarkerSkin skin = HitmarkerManager.Instance.Skin;
			MarkerSkin favoriteSkin = HitmarkerManager.Instance.FavoriteSkin;
			MarkerSkin defaultSkin = HitmarkerManager.Instance.DefaultSkin;
			if (skin == null)
			{
				_markerMaterial.mainTexture = (Texture)(object)favoriteSkin.Marker;
				_finisherMaterial.mainTexture = (Texture)(object)favoriteSkin.Finisher;
				_finisherSkullMaterial.mainTexture = (Texture)(object)favoriteSkin.FinisherSkull;
				return;
			}
			if (skin == null && favoriteSkin == null)
			{
				_markerMaterial.mainTexture = (Texture)(object)defaultSkin.Marker;
				_finisherMaterial.mainTexture = (Texture)(object)defaultSkin.Finisher;
				_finisherSkullMaterial.mainTexture = (Texture)(object)defaultSkin.FinisherSkull;
			}
			else if (defaultSkin == null)
			{
				throw new NullReferenceException("Default fallback skin is missing!");
			}
			_markerMaterial.mainTexture = (Texture)(object)(((Object)(object)skin.Marker != (Object)null) ? skin.Marker : favoriteSkin.Marker);
			_finisherMaterial.mainTexture = (Texture)(object)(((Object)(object)skin.Finisher != (Object)null) ? skin.Finisher : favoriteSkin.Finisher);
			_finisherSkullMaterial.mainTexture = (Texture)(object)(((Object)(object)skin.FinisherSkull != (Object)null) ? skin.FinisherSkull : favoriteSkin.FinisherSkull);
		}
	}
	[RegisterTypeInIl2Cpp]
	public class HitmarkerManager : MonoBehaviour
	{
		public static HitmarkerManager Instance;

		private List<Hitmarker> _hitmarkers;

		private List<Hitmarker> _finishers;

		private int _markerCount = 64;

		private Transform _poolHitmarker;

		private Transform _poolFinisher;

		public MarkerSkin Skin { get; private set; }

		public MarkerSkin FavoriteSkin => DataManager.GetMarkerSkin(Options.FavoriteSkin);

		public MarkerSkin DefaultSkin => DataManager.GetMarkerSkin("Default");

		public HitmarkerManager(IntPtr ptr)
			: base(ptr)
		{
		}

		private void Awake()
		{
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
			}
			Object.DontDestroyOnLoad((Object)(object)Instance);
			BuildPools();
			_hitmarkers = new List<Hitmarker>();
			_finishers = new List<Hitmarker>();
			for (int i = 0; i < _markerCount; i++)
			{
				_hitmarkers.Add(BuildHitmarker(isFinisher: false));
				_finishers.Add(BuildHitmarker(isFinisher: true));
			}
		}

		private void BuildPools()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			_poolHitmarker = new GameObject("Hitmarker Pool").transform;
			_poolFinisher = new GameObject("Finisher Pool").transform;
			((Component)_poolHitmarker).transform.SetParent(((Component)this).transform);
			((Component)_poolFinisher).transform.SetParent(((Component)this).transform);
		}

		private Hitmarker BuildHitmarker(bool isFinisher)
		{
			string name = ((!isFinisher) ? "Hitmarker" : "Finisher");
			GameObject obj = Object.Instantiate<GameObject>(DataManager.GetGameObject("Hitmarker"));
			((Object)obj).name = name;
			((Object)obj).hideFlags = (HideFlags)32;
			obj.transform.parent = ((!isFinisher) ? _poolHitmarker : _poolFinisher);
			obj.gameObject.SetActive(false);
			return obj.AddComponent<Hitmarker>();
		}

		private Hitmarker GetInactiveMarker(bool finisher)
		{
			List<Hitmarker> list = ((!finisher) ? _hitmarkers : _finishers);
			for (int i = 0; i < list.Count; i++)
			{
				if (!((Component)list[i]).gameObject.activeInHierarchy)
				{
					return list[i];
				}
			}
			return null;
		}

		public void SetMarkerSkin(MarkerSkin skin)
		{
			Skin = skin;
		}

		public void SpawnMarker(Vector3 position, bool finisher = false)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			if (Options.EnableHitmarkers)
			{
				Hitmarker inactiveMarker = GetInactiveMarker(finisher);
				inactiveMarker.IsFinisher = finisher;
				((Component)inactiveMarker).transform.position = position;
				((Component)inactiveMarker).gameObject.SetActive(true);
				float num = Vector3.Distance(((Component)inactiveMarker).transform.position, Player.Head.position);
				if (num < 5f)
				{
					((Component)inactiveMarker).transform.localScale = Vector3.one;
				}
				else
				{
					((Component)inactiveMarker).transform.localScale = Vector3.one * Mathf.Pow(2f, 1f + num / 50f);
				}
			}
		}
	}
	[RegisterTypeInIl2Cpp]
	public class HitmarkerProxy : MonoBehaviour
	{
		public HitmarkerProxy(IntPtr ptr)
			: base(ptr)
		{
		}
	}
	public static class BuildInfo
	{
		public const string Name = "Hitmarkers";

		public const string Description = "Simple hitmarkers mod for BONELAB.";

		public const string Author = "Not Enough Photons";

		public const string Company = "Not Enough Photons";

		public const string Version = "2.8.3";

		public const string DownloadLink = null;
	}
	public class Main : MelonMod
	{
		public static MelonLogger Logger = new MelonLogger();

		internal const string EmbeddedModule = "NEP.Hitmarkers.Resources.HitmarkersFusionModule.dll";

		public override void OnInitializeMelon()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Expected O, but got Unknown
			Logger = new MelonLogger();
			DataManager.Initialize();
			Options.Initialize();
			SetupBoneMenu();
			MarrowGame.RegisterOnReadyAction(Action.op_Implicit((Action)delegate
			{
				OnMarrowGameStart();
			}));
		}

		public void OnMarrowGameStart()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			new GameObject("Hitmarker Manager").AddComponent<HitmarkerManager>();
			HitDirector.Initialize();
		}

		private void SetupBoneMenu()
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			Page obj = Page.Root.CreatePage("Not Enough Photons", Color.white, 8, true).CreatePage("Hitmarkers", Color.white, 0, true);
			Page val = obj.CreatePage("Skins", Color.white, 8, true);
			obj.CreateBool("Enable Hitmarkers", Color.white, Options.EnableHitmarkers, (Action<bool>)delegate(bool value)
			{
				Options.SetEnableHitmarkers(value);
			});
			obj.CreateFloat("Hitmarker SFX", Color.white, 10f, Options.HitmarkerSFX, 0f, 100f, (Action<float>)delegate(float value)
			{
				Options.SetHitmarkerVolume(value);
			});
			obj.CreateFloat("Hitmarker Pitch", Color.white, 0.25f, Options.HitmarkerPitch, 0f, 2f, (Action<float>)delegate(float value)
			{
				Options.SetHitmarkerPitch(value);
			});
			Page val2 = obj.CreatePage("Set Default Marker", Color.white, 8, true);
			for (int i = 0; i < DataManager.Skins.Length; i++)
			{
				int index2 = i;
				val.CreateFunction(DataManager.Skins[index2].SkinName, Color.white, (Action)delegate
				{
					HitmarkerManager.Instance.SetMarkerSkin(DataManager.Skins[index2]);
				});
			}
			for (int j = 0; j < DataManager.Skins.Length; j++)
			{
				int index = j;
				val2.CreateFunction(DataManager.Skins[index].SkinName, Color.white, (Action)delegate
				{
					Options.SetDefaultSkin(DataManager.Skins[index].SkinName);
				});
			}
		}
	}
	public sealed class MarkerSkin
	{
		public string SkinName { get; private set; }

		public Texture2D Marker { get; private set; }

		public Texture2D Finisher { get; private set; }

		public Texture2D FinisherSkull { get; private set; }

		public AudioClip[] HitClips { get; private set; }

		public AudioClip[] FinisherClips { get; private set; }

		public MarkerSkin(string name, Texture2D marker, Texture2D finisher, Texture2D skull, AudioClip[] hitClips, AudioClip[] finisherClips)
		{
			SkinName = name;
			Marker = marker;
			Finisher = finisher;
			FinisherSkull = skull;
			HitClips = hitClips;
			FinisherClips = finisherClips;
		}
	}
	public enum MarkerType
	{
		Body,
		Head
	}
}
namespace NEP.Hitmarkers.Data
{
	public static class DataManager
	{
		private static readonly string path_UserData = MelonEnvironment.UserDataDirectory;

		private static readonly string path_Developer = Path.Combine(path_UserData, "Not Enough Photons");

		private static readonly string path_Mod = Path.Combine(path_Developer, "Hitmarkers");

		private static readonly string path_Skins = Path.Combine(path_Mod, "Skins");

		private static AssetBundle _bundle;

		private static Object[] _bundleObjects;

		private static MarkerSkin[] _skins;

		private static List<GameObject> _gameObjects;

		private static List<AnimationClip> _animations;

		internal static bool _initialized;

		public static AssetBundle Bundle => _bundle;

		public static Object[] BundleObjects => _bundleObjects;

		public static GameObject[] GameObjects => _gameObjects.ToArray();

		public static AnimationClip[] Animations => _animations.ToArray();

		public static MarkerSkin[] Skins => _skins;

		public static void Initialize()
		{
			if (!_initialized)
			{
				GenerateFolders();
				LoadBundles();
				LoadObjects();
				_initialized = true;
			}
		}

		public static GameObject GetGameObject(string name)
		{
			return _gameObjects.Find((GameObject match) => ((Object)match).name == name);
		}

		public static MarkerSkin GetMarkerSkin(string name)
		{
			foreach (MarkerSkin item in new HashSet<MarkerSkin>(_skins))
			{
				if (item.SkinName == name)
				{
					return item;
				}
			}
			return null;
		}

		public static MarkerSkin[] LoadMarkerSkins()
		{
			string[] directories = Directory.GetDirectories(path_Skins);
			MarkerSkin[] array = new MarkerSkin[directories.Length];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = CreateMarkerSkin(directories[i]);
			}
			return array;
		}

		public static MarkerSkin CreateMarkerSkin(string skinPath)
		{
			if (!Directory.Exists(skinPath))
			{
				throw new Exception("Path does not exist! " + skinPath);
			}
			string name = new DirectoryInfo(skinPath).Name;
			Texture2D marker = LoadTexture(skinPath, "marker.png");
			Texture2D finisher = LoadTexture(skinPath, "finisher_marker.png");
			Texture2D skull = LoadTexture(skinPath, "finisher_feedback.png");
			AudioClip[] hitClips = LoadClips(skinPath, "marker");
			AudioClip[] finisherClips = LoadClips(skinPath, "finisher");
			return new MarkerSkin(name, marker, finisher, skull, hitClips, finisherClips);
		}

		private static void LoadBundles()
		{
			string text = "NEP.Hitmarkers.Resources.";
			string text2 = (HelperMethods.IsAndroid() ? "resources_quest.pack" : "resources_pcvr.pack");
			_bundle = HelperMethods.LoadEmbeddedAssetBundle(Assembly.GetExecutingAssembly(), text + text2);
			_bundleObjects = Il2CppArrayBase<Object>.op_Implicit((Il2CppArrayBase<Object>)(object)_bundle.LoadAllAssets());
		}

		private static void LoadObjects()
		{
			_gameObjects = new List<GameObject>();
			_animations = new List<AnimationClip>();
			GetObjects<GameObject>(_gameObjects);
			GetObjects<AnimationClip>(_animations);
			_skins = LoadMarkerSkins();
		}

		private static void GenerateFolders()
		{
			Directory.CreateDirectory(path_Mod);
		}

		private static void GetObjects<T>(List<T> list) where T : Object
		{
			Object[] bundleObjects = _bundleObjects;
			for (int i = 0; i < bundleObjects.Length; i++)
			{
				T val = ((Il2CppObjectBase)bundleObjects[i]).TryCast<T>();
				if ((Object)(object)val != (Object)null)
				{
					((Object)val).hideFlags = (HideFlags)32;
					list.Add(val);
				}
			}
		}

		private static Texture2D LoadTexture(string skinPath, string textureName)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			string path = Path.Combine(skinPath, textureName);
			Texture2D val = new Texture2D(2, 2);
			if (!File.Exists(path))
			{
				Melon<Main>.Logger.Warning(textureName + " does not exist in " + skinPath + "!");
				return null;
			}
			byte[] array = File.ReadAllBytes(path);
			if (!ImageConversion.LoadImage(val, Il2CppStructArray<byte>.op_Implicit(array)))
			{
				Melon<Main>.Logger.Warning(textureName + " failed to load! The data is likely corrupted or invalid.");
				return null;
			}
			((Object)val).hideFlags = (HideFlags)32;
			return val;
		}

		private static AudioClip[] LoadClips(string skinPath, string searchTerm)
		{
			string path = Path.Combine(skinPath, "SFX");
			if (!Directory.Exists(path))
			{
				return null;
			}
			string[] files = Directory.GetFiles(path);
			List<AudioClip> list = new List<AudioClip>();
			for (int i = 0; i < files.Length; i++)
			{
				if (new DirectoryInfo(files[i]).Name.StartsWith(searchTerm))
				{
					list.Add(API.LoadAudioClip(files[i], true));
				}
			}
			return list.ToArray();
		}
	}
	public static class Options
	{
		private static MelonPreferences_Category _category;

		private static ModPref<string> _favoritedSkin;

		private static ModPref<bool> _enableHitmarkers;

		private static ModPref<float> _hitmarkerVolume;

		private static ModPref<float> _hitmarkerPitch;

		public static string FavoriteSkin { get; private set; }

		public static bool EnableHitmarkers { get; private set; }

		public static float HitmarkerSFX { get; private set; }

		public static float HitmarkerPitch { get; private set; }

		public static ModPref<string> Pref_DefaultSkin => _favoritedSkin;

		public static ModPref<bool> Pref_EnableHitmarkers => _enableHitmarkers;

		public static ModPref<float> Pref_Volume => _hitmarkerVolume;

		public static ModPref<float> Pref_Pitch => _hitmarkerPitch;

		public static void Initialize()
		{
			_category = MelonPreferences.CreateCategory("Hitmarkers");
			_favoritedSkin = new ModPref<string>(_category, "Favorite Skin", "Default", "Favorite", "The favorited skin to use in Hitmarkers.", false, false, (ValueValidator)null);
			_enableHitmarkers = new ModPref<bool>(_category, "Enable Hitmarkers", true, "Enable Hitmarkers", "Shows or hides hitmarkers.", false, false, (ValueValidator)null);
			_hitmarkerVolume = new ModPref<float>(_category, "Marker Volume", 100f, "Marker Volume", "Loudness value for when hits/finishers are made.", false, false, (ValueValidator)null);
			_hitmarkerPitch = new ModPref<float>(_category, "Marker Pitch", 1f, "Marker Pitch", "Pitch value that controls how high or low pitched the markers are.", false, false, (ValueValidator)null);
			FavoriteSkin = ModPref<string>.op_Implicit(_favoritedSkin);
			EnableHitmarkers = ModPref<bool>.op_Implicit(_enableHitmarkers);
			HitmarkerSFX = ModPref<float>.op_Implicit(_hitmarkerVolume);
			HitmarkerPitch = ModPref<float>.op_Implicit(_hitmarkerPitch);
			MelonPreferences.Save();
		}

		public static void SetDefaultSkin(string skin)
		{
			_favoritedSkin.entry.Value = skin;
			FavoriteSkin = ModPref<string>.op_Implicit(_favoritedSkin);
			MelonPreferences.Save();
		}

		public static void SetEnableHitmarkers(bool enable)
		{
			_enableHitmarkers.entry.Value = enable;
			EnableHitmarkers = ModPref<bool>.op_Implicit(_enableHitmarkers);
			MelonPreferences.Save();
		}

		public static void SetHitmarkerVolume(float volume)
		{
			_hitmarkerVolume.entry.Value = volume;
			HitmarkerSFX = ModPref<float>.op_Implicit(_hitmarkerVolume);
			MelonPreferences.Save();
		}

		public static void SetHitmarkerPitch(float pitch)
		{
			_hitmarkerPitch.entry.Value = pitch;
			HitmarkerPitch = ModPref<float>.op_Implicit(_hitmarkerPitch);
			MelonPreferences.Save();
		}
	}
}