Latest versions of MelonLoader are known to have issues with some games. Use version 0.5.4 until the issue has been fixed!
Decompiled source of Hitmarkers v2.8.3
For BONELAB/Mods/Hitmarkers.dll
Decompiled 4 months agousing 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(); } } }
For BONEWORKS/Mods/Hitmarkers.dll
Decompiled 4 months agousing 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 HarmonyLib; using MelonLoader; using ModThatIsNotMod; using ModThatIsNotMod.BoneMenu; using NEP.Hitmarkers; using NEP.Hitmarkers.Audio; using NEP.Hitmarkers.Data; using PuppetMasta; using StressLevelZero.AI; using StressLevelZero.Combat; using UnhollowerBaseLib; 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.1.0")] [assembly: MelonInfo(typeof(Main), "Hitmarkers", "2.1.0", "Not Enough Photons", null)] [assembly: MelonColor] [assembly: MelonGame("Stress Level Zero", "BONEWORKS")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("2.1.0.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<AIBrain> OnKill; public static void Initialize() { OnHit = (Action<HitData>)Delegate.Combine(OnHit, new Action<HitData>(OnProjectileHit)); } public static void OnProjectileHit(HitData data) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) if ((int)data.projectile._proxy.triggerType == 0 && ((Component)data.collider).gameObject.layer == LayerMask.NameToLayer("EnemyColliders") && (!((Object)(object)data.brain != (Object)null) || !data.brain.isDead)) { HitmarkerManager.Instance.SpawnMarker(data.worldHit); } } public static void OnAIDeath(AIBrain brain) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) HitmarkerManager.Instance.SpawnMarker(brain.behaviour.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_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) HitData hitData = default(HitData); hitData.projectile = __instance; hitData.worldHit = world; hitData.collider = hitCol; hitData.brain = ((Component)hitCol).GetComponentInParent<AIBrain>(); HitData obj = hitData; HitDirector.OnHit?.Invoke(obj); })); } } [HarmonyPatch(typeof(AIBrain))] [HarmonyPatch("OnDeath")] public static class AIBrainPatch { public static void Postfix(AIBrain __instance) { HitDirector.OnAIDeath(__instance); } } [HarmonyPatch(typeof(PuppetMaster))] [HarmonyPatch("Awake")] public static class PuppetMasterPatch { public static void Postfix(PuppetMaster __instance) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) StateSettings val = default(StateSettings); val.deadMuscleDamper = __instance.stateSettings.deadMuscleDamper; val.deadMuscleWeight = __instance.stateSettings.deadMuscleWeight; val.enableAngularLimitsOnKill = __instance.stateSettings.enableAngularLimitsOnKill; val.enableInternalCollisionsOnKill = __instance.stateSettings.enableInternalCollisionsOnKill; val.killDuration = 0f; val.maxFreezeSqrVelocity = __instance.stateSettings.maxFreezeSqrVelocity; StateSettings stateSettings = val; __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 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() { _hitAudio = DataManager.HitClips; _finisherAudio = DataManager.FinisherClips; _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>(); SetTextures(); _markerObject.SetActive(false); _finisherObject.SetActive(false); } private void OnEnable() { UseSettings(); PlayAnimation(); PlayAudio(); } private void PlayAnimation() { if (_isFinisher) { _finisherObject.SetActive(true); _markerObject.SetActive(false); int num = Random.Range(1, 2); _finisherAnimator.Play($"finisher_appear_{num}"); } else { _finisherObject.SetActive(false); _markerObject.SetActive(true); int num2 = Random.Range(1, 2); _markerAnimator.Play($"marker_appear_{num2}"); } } private void Update() { if (((Component)this).gameObject.activeInHierarchy) { Transform transform = ((Component)this).transform; GameObject playerHead = Player.GetPlayerHead(); transform.LookAt((playerHead != null) ? playerHead.transform : null); _timerHide += Time.deltaTime; if (_timerHide > _timeUntilHide) { ((Component)this).gameObject.SetActive(false); _timerHide = 0f; } } } private void UseSettings() { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) float distanceFromShot = HitmarkerManager.Instance.DistanceFromShot; float hitmarkerDistanceScale = HitmarkerManager.Instance.HitmarkerDistanceScale; float hitmarkerDistanceUntilScale = HitmarkerManager.Instance.HitmarkerDistanceUntilScale; float hitmarkerVolume = HitmarkerManager.Instance.HitmarkerVolume; float hitmarkerAnimationSpeed = HitmarkerManager.Instance.HitmarkerAnimationSpeed; Vector3 val = Vector3.one * HitmarkerManager.Instance.HitmarkerScale; float num = hitmarkerDistanceScale * distanceFromShot; ((Component)this).transform.localScale = ((distanceFromShot >= hitmarkerDistanceUntilScale) ? (val * num) : val); _source.volume = hitmarkerVolume; _markerAnimator.speed = hitmarkerAnimationSpeed; _finisherAnimator.speed = hitmarkerAnimationSpeed; } private void PlayAudio() { AudioClip[] array = ((!_isFinisher) ? _hitAudio : _finisherAudio); AudioClip clip = array[Random.Range(0, array.Length)]; _source.clip = clip; } private void SetTextures() { Material material = ((Renderer)_markerObject.GetComponent<MeshRenderer>()).material; Material material2 = ((Renderer)_finisherObject.GetComponent<MeshRenderer>()).material; Material material3 = ((Renderer)((Component)_finisherObject.transform.Find("DeathSkull")).GetComponent<MeshRenderer>()).material; material.mainTexture = (Texture)(object)DataManager.GetTexture("marker.png"); material2.mainTexture = (Texture)(object)DataManager.GetTexture("finisher_marker.png"); material3.mainTexture = (Texture)(object)DataManager.GetTexture("finisher_feedback.png"); } } [RegisterTypeInIl2Cpp] public class HitmarkerManager : MonoBehaviour { public static HitmarkerManager Instance; public bool EnableHitmarkers = true; public float HitmarkerScale = 1f; public float DistanceFromShot; public float HitmarkerDistanceScale = 0.15f; public float HitmarkerDistanceUntilScale = 10f; public float HitmarkerVolume = 1f; public float HitmarkerAnimationSpeed = 1f; public bool UseDeathSkull = true; private List<Hitmarker> _hitmarkers; private List<Hitmarker> _finishers; private int _markerCount = 64; private Transform _poolHitmarker; private Transform _poolFinisher; public HitmarkerManager(IntPtr ptr) : base(ptr) { } private void Awake() { Instance = this; 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 SpawnMarker(Vector3 position, bool finisher = false) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) if (EnableHitmarkers) { Hitmarker inactiveMarker = GetInactiveMarker(finisher); inactiveMarker.IsFinisher = finisher; ((Component)inactiveMarker).transform.position = position; ((Component)inactiveMarker).gameObject.SetActive(true); } } } 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.1.0"; public const string DownloadLink = null; } public class Main : MelonMod { public override void OnApplicationStart() { DataManager.Initialize(); SetupOptions(); } public override void OnSceneWasLoaded(int buildIndex, string sceneName) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) new GameObject("Hitmarker Manager").AddComponent<HitmarkerManager>(); new GameObject("Hitmarker Audio").AddComponent<HitmarkerAudio>(); HitDirector.Initialize(); } private void SetupOptions() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) MenuCategory obj = MenuManager.CreateCategory("Hitmarkers", Color.white); MenuCategory val = obj.CreateSubCategory("Visuals", Color.white); MenuCategory val2 = obj.CreateSubCategory("Audio", Color.white); obj.CreateBoolElement("Enable Hitmarkers", Color.white, true, (Action<bool>)delegate(bool enabled) { HitmarkerManager.Instance.EnableHitmarkers = enabled; }); val.CreateFloatElement("Hitmarker Scale", Color.white, 1f, (Action<float>)delegate(float num) { HitmarkerManager.Instance.HitmarkerScale = num; }, 0.25f, 0.25f, 2f, true); val.CreateFloatElement("Distance Scale", Color.white, 0.15f, (Action<float>)delegate(float num) { HitmarkerManager.Instance.HitmarkerDistanceScale = num; }, 0.05f, 0.05f, 1f, true); val.CreateFloatElement("Distance Until Scale", Color.white, 5f, (Action<float>)delegate(float num) { HitmarkerManager.Instance.HitmarkerDistanceUntilScale = num; }, 1f, 1f, float.PositiveInfinity, true); val.CreateFloatElement("Animation Speed", Color.white, 1f, (Action<float>)delegate(float num) { HitmarkerManager.Instance.HitmarkerAnimationSpeed = num; }, 0.25f, 0.25f, 2f, true); val2.CreateFloatElement("Volume", Color.white, 1f, (Action<float>)delegate(float num) { HitmarkerManager.Instance.HitmarkerVolume = num; }, 0.25f, 0f, 3f, true); } } } namespace NEP.Hitmarkers.Data { public static class DataManager { private static readonly string path_UserData = MelonUtils.UserDataDirectory; private static readonly string path_Developer = path_UserData + "/Not Enough Photons"; private static readonly string path_Mod = path_Developer + "/Hitmarkers"; private static readonly string path_Resources = path_Mod + "/resources.pack"; private static readonly string path_Audio = path_Mod + "/Audio"; private static readonly string path_Textures = path_Mod + "/Textures"; private static AssetBundle _bundle; private static Object[] _bundleObjects; private static List<GameObject> _gameObjects; private static List<AnimationClip> _animations; private static List<AudioClip> _clipHitmarkers; private static List<AudioClip> _clipFinishers; private static List<Texture2D> _textures; public static AssetBundle Bundle => _bundle; public static Object[] BundleObjects => _bundleObjects; public static GameObject[] GameObjects => _gameObjects.ToArray(); public static AnimationClip[] Animations => _animations.ToArray(); public static Texture2D[] Textures => _textures.ToArray(); public static AudioClip[] HitClips => _clipHitmarkers.ToArray(); public static AudioClip[] FinisherClips => _clipFinishers.ToArray(); public static void Initialize() { GenerateFolders(); _gameObjects = new List<GameObject>(); _animations = new List<AnimationClip>(); _textures = new List<Texture2D>(); _clipHitmarkers = new List<AudioClip>(); _clipFinishers = new List<AudioClip>(); _bundle = AssetBundle.LoadFromFile(path_Resources); _bundleObjects = Il2CppArrayBase<Object>.op_Implicit((Il2CppArrayBase<Object>)(object)_bundle.LoadAllAssets()); GetGameObjects(); GetAnimations(); GetAudio(); GetTextures(); } public static GameObject GetGameObject(string name) { return _gameObjects.Find((GameObject match) => ((Object)match).name == name); } public static Texture2D GetTexture(string name) { return _textures.Find((Texture2D match) => ((Object)match).name == name); } private static void GenerateFolders() { Directory.CreateDirectory(path_Mod); Directory.CreateDirectory(path_Textures); Directory.CreateDirectory(path_Audio); } private static void GetGameObjects() { Object[] bundleObjects = _bundleObjects; for (int i = 0; i < bundleObjects.Length; i++) { GameObject val = ((Il2CppObjectBase)bundleObjects[i]).TryCast<GameObject>(); if ((Object)(object)val != (Object)null) { ((Object)val).hideFlags = (HideFlags)32; _gameObjects.Add(val); } } } private static void GetAnimations() { Object[] bundleObjects = _bundleObjects; for (int i = 0; i < bundleObjects.Length; i++) { AnimationClip val = ((Il2CppObjectBase)bundleObjects[i]).TryCast<AnimationClip>(); if ((Object)(object)val != (Object)null) { ((Object)val).hideFlags = (HideFlags)32; _animations.Add(val); } } } private static void GetAudio() { string[] files = Directory.GetFiles(path_Audio); foreach (string text in files) { string text2 = text.Substring(path_Audio.Length + 1); MelonLogger.Msg("Loading Clip " + text2 + "..."); if (text2.StartsWith("marker_")) { _clipHitmarkers.Add(API.LoadAudioClip(text, true)); } else if (text2.StartsWith("finisher_")) { _clipFinishers.Add(API.LoadAudioClip(text, true)); } MelonLogger.Msg("Successfully Loaded " + text2 + "!"); } } private static void GetTextures() { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Expected O, but got Unknown string[] files = Directory.GetFiles(path_Textures); foreach (string text in files) { string text2 = text.Substring(path_Textures.Length + 1); MelonLogger.Msg("Loading Texture " + text2 + "..."); Texture2D val = new Texture2D(2, 2); if (!File.Exists(text)) { MelonLogger.Warning("Couldn't load " + text2 + "! Going to use a white square instead."); } else { byte[] array = File.ReadAllBytes(text); ImageConversion.LoadImage(val, Il2CppStructArray<byte>.op_Implicit(array)); } ((Object)val).hideFlags = (HideFlags)32; ((Object)val).name = text2; MelonLogger.Msg("Successfully loaded " + ((Object)val).name + "!"); _textures.Add(val); } } } } namespace NEP.Hitmarkers.Audio { [RegisterTypeInIl2Cpp] public class HitmarkerAudio : MonoBehaviour { public static HitmarkerAudio Instance; public static AudioClip[] HitAudio; public static AudioClip[] FinisherAudio; private static List<GameObject> pooledAudioObjects; public HitmarkerAudio(IntPtr ptr) : base(ptr) { } private void Awake() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown Instance = this; pooledAudioObjects = new List<GameObject>(); GameObject val = new GameObject("Pooled Audio List"); val.transform.parent = ((Component)this).transform; for (int i = 0; i < 64; i++) { GameObject val2 = new GameObject("Poolee Audio"); val2.transform.parent = val.transform; AudioSource obj = val2.AddComponent<AudioSource>(); obj.playOnAwake = true; obj.volume = 5f; val2.AddComponent<PooledAudio>(); val2.SetActive(false); pooledAudioObjects.Add(val2); } HitAudio = DataManager.HitClips; FinisherAudio = DataManager.FinisherClips; } public static void PlayAtPoint(AudioClip clip, Vector3 position) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) GameObject val = ((IEnumerable<GameObject>)pooledAudioObjects).FirstOrDefault((Func<GameObject, bool>)((GameObject inactive) => !inactive.activeInHierarchy)); AudioSource component = val.GetComponent<AudioSource>(); if ((Object)(object)val != (Object)null) { component.clip = clip; val.transform.position = position; val.SetActive(true); } } } [RegisterTypeInIl2Cpp] public class PooledAudio : MonoBehaviour { private AudioSource source; private float time; public PooledAudio(IntPtr ptr) : base(ptr) { } private void Start() { source = ((Component)this).GetComponent<AudioSource>(); } private void Update() { time += Time.deltaTime; if (time >= source.clip.length) { ((Component)this).gameObject.SetActive(false); time = 0f; } } } }