Decompiled source of NyxLib v0.4.0
NyxLib.dll
Decompiled 4 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using GameConsole; using HarmonyLib; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Nyxpiri.Collections.Generic; using Nyxpiri.ULTRAKILL.NyxLib; using Nyxpiri.ULTRAKILL.NyxLib.AnimScript; using Nyxpiri.ULTRAKILL.NyxLib.Assets; using Nyxpiri.ULTRAKILL.NyxLib.Diagnostics.Debug; using TMPro; using ULTRAKILL.Cheats; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.Assertions; using UnityEngine.Events; using UnityEngine.InputSystem; using UnityEngine.Rendering; using UnityEngine.ResourceManagement.AsyncOperations; using UnityEngine.ResourceManagement.ResourceProviders; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyVersion("0.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } public static class StackDebug { public static string GetStackString() { StackTrace arg = new StackTrace(1, fNeedFileInfo: false); return $"{arg}"; } public static void PrintStack(bool includeFileInfo = false) { StackTrace arg = new StackTrace(1, includeFileInfo); Log.Message($"Stack debug! {arg}"); } } public class EnemyModifier : MonoBehaviour { } public class EnemyComponents : MonoBehaviour { public delegate void PreHurtEventHandler(EventMethodCanceler canceler, GameObject target, Vector3 force, Vector3? hitPoint, float multiplier, bool tryForExplode, float critMultiplier, GameObject sourceWeapon, bool ignoreTotalDamageTakenMultiplier, bool fromExplosion); public delegate void PostHurtEventHandler(EventMethodCancelInfo cancelInfo, GameObject target, Vector3 force, Vector3? hitPoint, float multiplier, bool tryForExplode, float critMultiplier, GameObject sourceWeapon, bool ignoreTotalDamageTakenMultiplier, bool fromExplosion); public delegate void PreAnyEnemyHurtEventHandler(EventMethodCanceler canceler, EnemyComponents enemy, GameObject target, Vector3 force, Vector3? hitPoint, float multiplier, bool tryForExplode, float critMultiplier, GameObject sourceWeapon, bool ignoreTotalDamageTakenMultiplier, bool fromExplosion); public delegate void PostAnyEnemyHurtEventHandler(EventMethodCancelInfo cancelInfo, EnemyComponents enemy, GameObject target, Vector3 force, Vector3? hitPoint, float multiplier, bool tryForExplode, float critMultiplier, GameObject sourceWeapon, bool ignoreTotalDamageTakenMultiplier, bool fromExplosion); public delegate void PreEnrageEventHandler(EventMethodCanceler canceler); public delegate void PostEnrageEventHandler(EventMethodCancelInfo cancelInfo); public delegate void PreUnEnrageEventHandler(EventMethodCanceler canceler); public delegate void PostUnEnrageEventHandler(EventMethodCancelInfo cancelInfo); public delegate void PreDeathEventHandler(EventMethodCanceler canceler, bool instakill); public delegate void PostDeathEventHandler(EventMethodCancelInfo cancelInfo, bool instakill); public static MonoRegistrar MonoRegistrar = new MonoRegistrar(); [SerializeField] private EnemyCloning _Cloning = null; [SerializeField] private EnemyRadiance _Radiance = null; [SerializeField] private bool _hasDoneSetup = false; [SerializeField] private EnemyRoot _enemyRootMono; public bool AvoidHealthBasedSlowDown = false; [NonSerialized] public bool QueuedForDestruction = false; public EnemyIdentifier Eid = null; public Enemy Enemy = null; public static FieldAccess<EnemyIdentifier, string> OverrideFullNameFA; public Vector3 CollisionCenterOffset = Vector3.zero; [SerializeField] private Collider[] _colliders = null; [SerializeField] private List<MonoBehaviour> _monoBehaviours = null; private bool _isEnemyCompInitializer = false; private object DeathPatchCallerObject = null; private bool PreDeathCalled = false; private bool PostDeathCalled = false; private bool DeathCalled = false; private bool InTheProcessOfHurting = false; private object HurtPatchCallerObject = null; public EnemyCloning Cloning { get { return _Cloning; } private set { _Cloning = value; } } public EnemyRadiance Radiance { get { return _Radiance; } private set { _Radiance = value; } } public EnemyRoot EnemyRootMono => _enemyRootMono; public bool HasDoneSetup => _hasDoneSetup; public bool UniquelySolo { get; private set; } = false; public bool IsEnemyCompInitializer => _isEnemyCompInitializer; public bool EidStarted { get; internal set; } = false; [SerializeField] public float InitialHealth { get; private set; } = -1f; [SerializeField] public float HighestHealth { get; private set; } = -1f; public float Health { get { if ((Object)(object)Enemy != (Object)null) { return Enemy.health; } return Eid.health; } set { if ((Object)(object)Enemy != (Object)null) { Enemy.health = value; } else { Eid.health = value; } } } public GameObject RootGameObject => ((int)Eid.enemyType == 4) ? ((Component)((Component)this).transform.parent).gameObject : ((Component)this).gameObject; public bool InstaKilled { get; private set; } = false; public IReadOnlyList<Collider> Colliders => _colliders; public string OverrideFullName { get { return OverrideFullNameFA.GetValue(Eid); } set { OverrideFullNameFA.SetValue(Eid, value); } } public Vector3 CollisionCenter => ((Component)this).transform.TransformPoint(CollisionCenterOffset); public event PreHurtEventHandler PreHurt; public event PostHurtEventHandler PostHurt; public static event PreAnyEnemyHurtEventHandler PreAnyEnemyHurt; public static event PostAnyEnemyHurtEventHandler PostAnyEnemyHurt; public event PreEnrageEventHandler PreEnrage = null; public event PostEnrageEventHandler PostEnrage = null; public event PreUnEnrageEventHandler PreUnEnrage = null; public event PostUnEnrageEventHandler PostUnEnrage = null; public event PreDeathEventHandler PreDeath; public event PostDeathEventHandler PostDeath; public T GetMonoByIndex<T>(int idx) where T : MonoBehaviour { if (idx < 0) { throw new IndexOutOfRangeException($"Index {idx} was less than 0"); } if (idx > _monoBehaviours.Count) { return default(T); } MonoBehaviour obj = _monoBehaviours[idx]; return (T)(object)((obj is T) ? obj : null); } public void MarkAsUniquelySolo() { UniquelySolo = true; } public void InstaDestroy() { Object.Destroy((Object)(object)RootGameObject); } private void Awake() { Log.TraceExpectedInfo($"EnemyComponents '{((Object)this).name}:{((Object)((Component)this).gameObject).GetInstanceID()}' awakens..."); Setup(); EnemyRootMono.Enemy = this; } internal void Setup() { if (!HasDoneSetup) { Log.TraceExpectedInfo($"EnemyComponents '{((Object)this).name}:{((Object)((Component)this).gameObject).GetInstanceID()}' is setting up..."); Eid = ((Component)this).GetComponent<EnemyIdentifier>(); Enemy = ((Component)this).GetComponent<Enemy>(); Assert.IsNotNull((Object)(object)Eid); _isEnemyCompInitializer = true; _hasDoneSetup = true; _enemyRootMono = GameObjectExtensions.GetOrAddComponent<EnemyRoot>(RootGameObject); CreateMods(); Eid.ForceGetHealth(); InitialHealth = Health; UpdateHighestHealth(); _colliders = ((Component)this).GetComponentsInChildren<Collider>(true); Cloning?.StorePrefab(); } } public void ResetHealthInfo() { Eid.ForceGetHealth(); InitialHealth = Health; HighestHealth = -100f; UpdateHighestHealth(); } private void UpdateHighestHealth() { if (Health > HighestHealth) { HighestHealth = Health; } } private void Start() { //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) Log.TraceExpectedInfo($"enemy '{((Object)this).name}:{((Object)((Component)this).gameObject).GetInstanceID()}' starts..."); if (_isEnemyCompInitializer) { _colliders = ((Component)this).GetComponentsInChildren<Collider>(); } if (InitialHealth <= 0f) { Eid.ForceGetHealth(); InitialHealth = Health; } Cloning?.StorePrefab(); UpdateHighestHealth(); Transform transform = ((Component)this).transform; Bounds val = this.SolveEnemyBounds(); CollisionCenterOffset = transform.InverseTransformPoint(((Bounds)(ref val)).center); } private void OnDestroy() { Log.TraceExpectedInfo($"enemy '{((Object)this).name}:{((Object)((Component)this).gameObject).GetInstanceID()}' gets instantaneously obliterated (destroyed)..."); } protected void Update() { if (QueuedForDestruction) { Log.TraceExpectedInfo($"enemy '{((Object)this).name}:{((Object)((Component)this).gameObject).GetInstanceID()}' was queued for destruction, so its time has come."); Object.Destroy((Object)(object)RootGameObject); } if (InTheProcessOfHurting) { InTheProcessOfHurting = false; Log.UnexpectedInfo(((Object)this).name + ": InTheProcessOfHurting had to be set to false by Update"); } } protected void FixedUpdate() { UpdateHighestHealth(); } private void OnDisable() { Log.TraceExpectedInfo($"enemy '{((Object)this).name}:{((Object)((Component)this).gameObject).GetInstanceID()}' gets disabled..."); if (QueuedForDestruction) { Log.TraceExpectedInfo($"enemy '{((Object)this).name}:{((Object)((Component)this).gameObject).GetInstanceID()}' was queued for destruction, so its time has come."); Object.Destroy((Object)(object)RootGameObject); } } private void OnEnable() { Log.TraceExpectedInfo($"enemy '{((Object)this).name}:{((Object)((Component)this).gameObject).GetInstanceID()}' gets enabled..."); } private void CreateMods() { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Expected O, but got Unknown Log.TraceExpectedInfo(((Object)this).name + ".EnemyAdditions is creating new modules..."); _monoBehaviours = new List<MonoBehaviour>(MonoRegistrar.RegisteredTypes.Count); foreach (Type registeredType in MonoRegistrar.RegisteredTypes) { _monoBehaviours.Add((MonoBehaviour)((Component)this).gameObject.AddComponent(registeredType)); } if (!Options.DontCreateEnemyRadianceComp.Value) { Radiance = GameObjectExtensions.GetOrAddComponent<EnemyRadiance>(((Component)this).gameObject); } if (!Options.DontCreateEnemyPrefabComp.Value) { Cloning = ((Component)this).gameObject.AddComponent<EnemyCloning>(); } } internal void TryCallPreDeath(EventMethodCanceler canceler, bool instakill, object patchCallerObject) { if (!PreDeathCalled) { DeathPatchCallerObject = patchCallerObject; PreDeathCalled = true; InstaKilled = instakill; this.PreDeath?.Invoke(canceler, InstaKilled); EnemyEvents.PreDeath?.Invoke(this, InstaKilled); } } internal void TryCallPostDeath(EventMethodCancelInfo cancelInfo, object patchCallerObject) { if (!PostDeathCalled && DeathPatchCallerObject == patchCallerObject) { PostDeathCalled = true; this.PostDeath?.Invoke(cancelInfo, InstaKilled); EnemyEvents.PostDeath?.Invoke(this, InstaKilled); } } internal void TryCallDeath() { if (!DeathCalled) { DeathCalled = true; EnemyEvents.Death?.Invoke(this); } } internal void NotifyOfPreHurt(EventMethodCanceler canceler, GameObject target, Vector3 force, Vector3? hitPoint, float multiplier, float critMultiplier, GameObject sourceWeapon, bool tryForExplode, bool ignoreTotalDamageTakenMultiplier, bool fromExplosion, object hurtPatchCallerObject) { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) if (InTheProcessOfHurting) { if (HurtPatchCallerObject == hurtPatchCallerObject) { Log.TraceExpectedInfo(((Object)this).name + ": had NotifyOfPreHurt called by the same hurtPatchCallerObject when we were in the process of hurting already? ignoring"); } else { Log.TraceExpectedInfo(((Object)this).name + ": had NotifyOfPreHurt called by differing hurtPatchCallerObject when we were in the process of hurting already, ignoring"); } } else { this.PreHurt?.Invoke(canceler, target, force, hitPoint, multiplier, tryForExplode, critMultiplier, sourceWeapon, ignoreTotalDamageTakenMultiplier, fromExplosion); EnemyComponents.PreAnyEnemyHurt?.Invoke(canceler, this, target, force, hitPoint, multiplier, tryForExplode, critMultiplier, sourceWeapon, ignoreTotalDamageTakenMultiplier, fromExplosion); HurtPatchCallerObject = hurtPatchCallerObject; InTheProcessOfHurting = true; } } internal void NotifyOfPostHurt(EventMethodCancelInfo cancellationInfo, GameObject target, Vector3 force, Vector3? hitPoint, float multiplier, float critMultiplier, GameObject sourceWeapon, bool tryForExplode, bool ignoreTotalDamageTakenMultiplier, bool fromExplosion, object hurtPatchCallerObject) { //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) if (!InTheProcessOfHurting) { Log.TraceExpectedInfo(((Object)this).name + ": had NotifyOfPostHurt called when we were NOT in the process of hurting already, ignoring"); return; } if (HurtPatchCallerObject != hurtPatchCallerObject) { Log.TraceExpectedInfo(((Object)this).name + ": had NotifyOfPostHurt called when we were in the process of hurting already BUT the hurtPatchCallerObject did not match, ignoring"); return; } this.PostHurt?.Invoke(cancellationInfo, target, force, hitPoint, multiplier, tryForExplode, critMultiplier, sourceWeapon, ignoreTotalDamageTakenMultiplier, fromExplosion); EnemyComponents.PostAnyEnemyHurt?.Invoke(cancellationInfo, this, target, force, hitPoint, multiplier, tryForExplode, critMultiplier, sourceWeapon, ignoreTotalDamageTakenMultiplier, fromExplosion); HurtPatchCallerObject = null; InTheProcessOfHurting = false; } internal bool CallPreEnrage(EventMethodCancellationTracker cancellationTracker) { cancellationTracker.Reset(); this.PreEnrage?.Invoke(cancellationTracker.GetCanceler()); cancellationTracker.TryInvokeReimplementation(); return cancellationTracker.ShouldRunMethod; } internal void CallPostEnrage(EventMethodCancellationTracker cancellationTracker) { this.PostEnrage?.Invoke(cancellationTracker.GetCancelInfo()); } internal bool CallPreUnEnrage(EventMethodCancellationTracker cancellationTracker) { cancellationTracker.Reset(); this.PreUnEnrage?.Invoke(cancellationTracker.GetCanceler()); cancellationTracker.TryInvokeReimplementation(); return cancellationTracker.ShouldRunMethod; } internal void CallPostUnEnrage(EventMethodCancellationTracker cancellationTracker) { this.PostUnEnrage?.Invoke(cancellationTracker.GetCancelInfo()); } static EnemyComponents() { EnemyComponents.PreAnyEnemyHurt = null; EnemyComponents.PostAnyEnemyHurt = null; OverrideFullNameFA = new FieldAccess<EnemyIdentifier, string>("overrideFullName"); } } public class EnemyRoot : MonoBehaviour { public EnemyComponents Enemy { get; internal set; } = null; protected void Awake() { } } public static class GamePrefs { [HarmonyPatch(typeof(PrefsManager), "Awake", new Type[] { })] private static class PrefsManagerAwakePatch { public static void Prefix(PrefsManager __instance) { } public static void Postfix(PrefsManager __instance) { _manager = __instance; } } private static PrefsManager _manager; public static PrefsManager Manager { get { if ((Object)(object)_manager == (Object)null && (Object)(object)MonoSingleton<PrefsManager>.Instance != (Object)null) { Log.ExpectedInfo("Had to get PrefsManager via PrefsManager.Instance (then cached the value)"); _manager = MonoSingleton<PrefsManager>.Instance; } return _manager; } } } public class ToggleCheat : ICheat { public Action<ToggleCheat> OnDisable = null; public Action<ToggleCheat, CheatsManager> OnEnable = null; private static Dictionary<string, bool> ToggleCheatStateStore = new Dictionary<string, bool>(); public string LongName { get; private set; } = "Unnamed ToggleCheat"; public string Identifier { get; private set; } = "ukaiw.unnamed-toggle-cheat"; public string ButtonEnabledOverride { get; set; } = null; public string ButtonDisabledOverride { get; set; } = null; public string Icon => null; public bool DefaultState { get; private set; } = false; public StatePersistenceMode PersistenceMode => (StatePersistenceMode)1; public bool IsActive => ToggleCheatStateStore.GetValueOrDefault(Identifier, defaultValue: false); public ToggleCheat(string longName, string identifier, Action<ToggleCheat> onDisable, Action<ToggleCheat, CheatsManager> onEnable) { LongName = longName; Identifier = identifier; DefaultState = ToggleCheatStateStore.GetValueOrDefault(Identifier, defaultValue: false); OnDisable = onDisable; OnEnable = onEnable; } public void Disable() { ToggleCheatStateStore[Identifier] = false; OnDisable?.Invoke(this); } public void Enable(CheatsManager manager) { ToggleCheatStateStore[Identifier] = true; OnEnable?.Invoke(this, manager); } } namespace Nyxpiri { public class ObjPool<T> where T : class, new() { public Func<T> ConstructObject = null; public Action<T> PrepareObject = delegate { }; public Action<T> UnprepareObject = delegate { }; public Action<T> DestructObject = delegate { }; private Stack<int> _FreeList = new Stack<int>(); private T[] Array = new T[0]; public int Size => Array.Length; public int NumFree => _FreeList.Count; public int NumTaken => Array.Length - _FreeList.Count; public ObjPool(Func<T> constructObject, Action<T> destructObject) { Assert.IsNotNull((object)constructObject, ""); DestructObject = destructObject; ConstructObject = constructObject; } public void Clear() { T[] array = Array; foreach (T obj in array) { DestructObject(obj); } Array = new T[0]; _FreeList.Clear(); } public void EnsureSize(int size) { if (Array.Length < size) { T[] array = Array; Array = new T[size]; for (int i = 0; i < array.Length; i++) { Array[i] = array[i]; } for (int j = array.Length; j < Array.Length; j++) { Array[j] = ConstructObject(); _FreeList.Push(j); Assert.IsNotNull((object)Array[j], ""); } } } public (T, int) TakeUnsafe() { if (_FreeList.Count == 0) { EnsureSize(Size * 2); } int num = _FreeList.Pop(); T val = Array[num]; PrepareObject?.Invoke(val); return (val, num); } public PoolObject<T> Take() { return new PoolObject<T>(this, TakeUnsafe()); } public void Return((T, int) element) { UnprepareObject?.Invoke(element.Item1); _FreeList.Push(element.Item2); } public void Return(PoolObject<T> obj) { obj.Dispose(); } ~ObjPool() { Clear(); } } public class PoolObject<T> : IDisposable where T : class, new() { private ObjPool<T> Pool; private (T, int) Element; public T Obj => Element.Item1; public T Value => Obj; public bool IsValid => Pool != null; internal PoolObject(ObjPool<T> pool, (T, int) element) { Pool = pool; Element = element; } public void Dispose() { if (IsValid) { Pool.Return(Element); Element = (null, -1); Pool = null; } } ~PoolObject() { Dispose(); } } public class RegistrationTracker { private bool _Registered = false; public Func<bool> RegisterAction { private get; set; } = null; public Func<bool> UnregisterAction { private get; set; } = null; public bool Registered { get { return _Registered; } private set { _Registered = value; } } public RegistrationTracker(Func<bool> registerAction, Func<bool> unregisterAction) { RegisterAction = registerAction; UnregisterAction = unregisterAction; } public void Register() { if (!Registered && (RegisterAction?.Invoke() ?? false)) { _Registered = true; } } public void Unregister() { if (Registered && (UnregisterAction?.Invoke() ?? false)) { _Registered = false; } } } } namespace Nyxpiri.Unity.Collections { public static class CollectionSorting { public static void Shuffle<T>(this IList<T> list) { for (int i = 0; i < list.Count; i++) { int index = Random.Range(0, list.Count - 1); T item = list[i]; list.RemoveAt(i); list.Insert(index, item); } } } } namespace Nyxpiri.Collections.Generic { public class ReserveList<T> : IReadOnlyCollection<T>, IEnumerable<T>, IEnumerable { private struct ReserveListElem { public T Obj; public bool Free; public ReserveListElem(T obj, bool free) { Obj = obj; Free = free; } } private List<ReserveListElem> _List; private Stack<int> _FreeList; public int Count { get; private set; } = 0; public int SoftCapacity => _List.Count; public int Capacity => _List.Capacity; public T this[int index] { get { if (_List[index].Free) { throw new IndexOutOfRangeException("Attempt to access an index that was in the _FreeList"); } return _List[index].Obj; } set { if (_List[index].Free) { throw new IndexOutOfRangeException("Attempt to access an index that was in the _FreeList"); } ReserveListElem value2 = _List[index]; value2.Obj = value; _List[index] = value2; } } ~ReserveList() { } public ReserveList() { _List = new List<ReserveListElem>(); _FreeList = new Stack<int>(); } public ReserveList(int capacity) { _List = new List<ReserveListElem>(capacity); _FreeList = new Stack<int>(capacity); } public int Add(T elem) { Count++; int count; if (_FreeList.Count == 0) { count = _List.Count; _List.Add(new ReserveListElem(elem, free: false)); return count; } count = _FreeList.Pop(); _List[count] = new ReserveListElem(elem, free: false); return count; } public void RemoveAt(int idx) { if (_List[idx].Free) { throw new IndexOutOfRangeException("Attempt to free already freed index"); } Count--; _List[idx] = new ReserveListElem(default(T), free: true); _FreeList.Push(idx); } public bool IsIndexValid(int idx) { if (idx < 0) { return false; } if (_List.Count <= idx) { return false; } if (_List[idx].Free) { return false; } return true; } public IEnumerator<T> GetEnumerator() { foreach (ReserveListElem elem in _List) { if (!elem.Free) { yield return elem.Obj; } } } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } } namespace Nyxpiri.ULTRAKILL.NyxLib { public class ExternalAssetManager(string path) { public string Path = path; private Dictionary<string, ExternalAsset> _assets = new Dictionary<string, ExternalAsset>(); public T GetAsset<T>(string subPath) where T : ExternalAsset, new() { if (_assets.TryGetValue(subPath, out var value) && value is T result) { return result; } T val = new T(); if (val is IManagerAwareAsset managerAwareAsset) { managerAwareAsset.AssetManager = this; } val.Path = path + "/" + subPath; _assets[subPath] = val; return val; } public void Reload() { List<ExternalAsset> list = _assets.Values.ToList(); foreach (ExternalAsset item in list) { item.MarkUnloaded(); } foreach (ExternalAsset item2 in list) { if (item2.TryLoad()) { Log.Message($"Reloaded asset {item2}"); } else { Log.Error($"Reload asset {item2} failed!"); } } } } public interface IManagerAwareAsset { ExternalAssetManager AssetManager { get; internal set; } } public abstract class ExternalAsset { public string Path = null; private bool _loaded = false; public bool Loaded => _loaded; public void MarkUnloaded() { _loaded = false; } public bool TryLoad() { if (Loaded) { return Loaded; } _loaded = Load(); return Loaded; } public override string ToString() { return "(" + GetType().Name + " @ '" + Path + "')"; } public abstract bool Load(); } public class TextureAsset : ExternalAsset { private Texture2D _texture = null; private FilterMode FilterMode = (FilterMode)0; public Texture2D Texture { get { if (!TryLoad()) { Log.Error("Loading Texture at '" + Path + "' failed"); } return _texture; } } public override bool Load() { //IL_0052: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_texture == (Object)null) { ImageLoader.TryLoadImageOrDefault(Path, out _texture, out var successfullyLoaded); if (!successfullyLoaded) { return false; } } if ((Object)(object)_texture == (Object)null) { return false; } ((Texture)_texture).filterMode = FilterMode; return ImageLoader.TryLoadImage(_texture, Path); } } public class AnimScriptAsset : ExternalAsset { private Animation _animation = null; public Animation Animation { get { TryLoad(); return _animation; } } public override bool Load() { if ((Object)(object)_animation == (Object)null) { _animation = ScriptableObject.CreateInstance<Animation>(); } if ((Object)(object)_animation == (Object)null) { return false; } if (!File.Exists(Path)) { Log.Error("failed to load animscript asset due file at " + Path + " not existing"); return false; } try { _animation.ParseScript(File.ReadAllText(Path)); } catch (FormatException ex) { Log.Error($"failed to parse animscript due to format exception: {ex.Message}\nfull exception info{ex}"); return false; } return true; } } public class ObjAsset : ExternalAsset { private List<Mesh> _meshes = new List<Mesh>(); public IReadOnlyList<Mesh> Meshes { get { TryLoad(); return _meshes; } } public Mesh FindMesh(string meshName) { //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Expected O, but got Unknown foreach (Mesh mesh in Meshes) { if (((Object)mesh).name == meshName) { return mesh; } } Log.Message("ExternalAsset making a new " + meshName); Mesh val = new Mesh(); ((Object)val).name = meshName; _meshes.Add(val); return val; } public override bool Load() { if (!File.Exists(Path)) { Log.Error("Failed to load mesh at path " + Path + " due to file not existing"); ClearMeshes(); return false; } try { ObjLoader.LoadMeshes(File.ReadAllText(Path), _meshes); return true; } catch (Exception arg) { ClearMeshes(); Log.Error($"failed to load mesh at '{Path}', exception: {arg}"); return false; } } private void ClearMeshes() { foreach (Mesh mesh in _meshes) { Object.Destroy((Object)(object)mesh); } _meshes.Clear(); } } public class MaterialAsset : ExternalAsset, IManagerAwareAsset { private Material _material = null; public Material Material { get { if (!base.Loaded) { TryLoad(); } return _material; } } public ExternalAssetManager AssetManager { get; set; } public override bool Load() { if ((Object)(object)_material == (Object)null) { _material = Materials.CreateLitMaterial(); } if ((Object)(object)_material == (Object)null) { return false; } if (!File.Exists(Path)) { Log.Error("Failed to load material at path " + Path + " due to file not existing"); return false; } try { string jsonText = File.ReadAllText(Path); if (!JsonMaterial.ApplyTo(_material, AssetManager, jsonText)) { return false; } } catch (Exception arg) { Log.Error($"Failed to load material at path {Path}, exception caught {arg}"); } return true; } } public class BalanceComposite { public const string DefaultSheetID = "default"; private List<string> SheetPriorities = new List<string>(); private Dictionary<string, BalanceSheet> _sheets = new Dictionary<string, BalanceSheet>(); private Dictionary<string, BalanceEntry> _entries = new Dictionary<string, BalanceEntry>(); private BalanceSheet _defaultSheet = null; public SerializerSet Serializers { protected get; set; } = null; public IReadOnlyDictionary<string, BalanceSheet> Sheets => _sheets; public BalanceComposite(SerializerSet serializers) { _defaultSheet = CreateSheet("default"); Serializers = serializers; } public BalanceEntryRef<T> AddEntry<T>(string id, T defaultValue, string description) where T : struct { BalanceEntry balanceEntry = new BalanceEntry(id, description, defaultValue); BalanceEntryRef<T> result = new BalanceEntryRef<T>(balanceEntry); _entries.Add(id, balanceEntry); _defaultSheet.SetValue<T>(id, defaultValue); return result; } public BalanceEntryRef<T> GetEntry<T>(string id) { return new BalanceEntryRef<T>(_entries[id]); } public BalanceSheet CreateSheet(string id) { BalanceSheet balanceSheet = new BalanceSheet(_entries); _sheets.Add(id, balanceSheet); foreach (KeyValuePair<string, BalanceEntry> entry in _entries) { balanceSheet.SetValue(typeof(object), entry.Key, null); } SheetPriorities.Add(id); EvaluatePriorities(); return balanceSheet; } private void EvaluatePriorities() { foreach (KeyValuePair<string, BalanceEntry> entry in _entries) { BalanceSheet sheet = null; string text = null; for (int i = 0; i < SheetPriorities.Count; i++) { text = SheetPriorities[i]; sheet = _sheets[text]; if (sheet.GetValue(entry.Key, out var value) && value != null) { break; } } Assert.IsNotNull((object)sheet, ""); entry.Value.GetterFunc = () => sheet.GetValue(entry.Key); entry.Value.ValueSource = text; } } } public class BalanceDirectory { public BalanceComposite Composite = null; public string Path = null; public BalanceDirectory(BalanceComposite composite, string path) { Assert.IsFalse(string.IsNullOrWhiteSpace(path)); Assert.IsNotNull((object)Composite, ""); Composite = composite; Path = path; } public void Load() { if (!Directory.Exists(Path)) { Directory.CreateDirectory(Path); } IEnumerable<string> enumerable = Directory.EnumerateFiles(Path); foreach (string item in enumerable) { if (!item.EndsWith(".balancesheet")) { continue; } string text = item.Substring(item.LastIndexOf('.') - 1, item.Length).Substring(item.LastIndexOfAny(new char[2] { '/', '\\' })); if (!string.IsNullOrWhiteSpace(text)) { string data = File.ReadAllText(item); string text2 = "custom." + text; if (!Composite.Sheets.TryGetValue(text2, out var value)) { value = Composite.CreateSheet(text2); } try { value.Deserialize(data); } catch (Exception arg) { Log.Error($"exception thrown whilst parsing BalanceSheet! {arg}"); } } } } } [Serializable] public class BalanceEntry { public string Description; public Func<object> GetterFunc = null; public string ValueSource = ""; public string ID { get; private set; } public object DefaultValue { get; private set; } public Type Type { get { Assert.IsNotNull(DefaultValue); return DefaultValue.GetType(); } } public object Value => GetterFunc?.Invoke(); public bool IsValid => GetterFunc != null; public BalanceEntry(string id, string description, object defaultValue) { ID = id; Description = description; DefaultValue = defaultValue; ResetToDefaultValue(); } public void ResetToDefaultValue() { GetterFunc = GetDefaultValue; } private object GetDefaultValue() { return DefaultValue; } } public struct BalanceEntryRef<T> { private BalanceEntryRef _rawRef; public bool IsValid => _rawRef.IsValid; public readonly T Value => (T)_rawRef.Value; public BalanceEntryRef(BalanceEntry entry) { _rawRef = default(BalanceEntryRef); Assert.IsTrue(entry.Type == typeof(T)); _rawRef = new BalanceEntryRef(entry); } public readonly BalanceEntryRef ToRawReference() { return _rawRef; } } [Serializable] public struct BalanceEntryRef { [SerializeField] [SerializeReference] private readonly BalanceEntry _entry; public readonly bool IsValid => _entry != null && _entry.IsValid; public readonly object Value { get { object value = _entry.Value; Assert.IsNotNull(value); return value; } } public BalanceEntryRef(BalanceEntry entry) { _entry = entry; } } public class BalanceSheet { public SerializerSet Serializers = null; private IReadOnlyDictionary<string, BalanceEntry> Entries = null; private Dictionary<string, object> _values = new Dictionary<string, object>(); public BalanceSheet(IReadOnlyDictionary<string, BalanceEntry> entries) { Entries = entries; } public void SetValue(Type type, string id, object value) { if (!Entries.TryGetValue(id, out var value2)) { throw new KeyNotFoundException(); } Assert.IsTrue(value2.Type == type || value == null); _values[id] = value; } public void SetValue<T>(string id, T? value) where T : struct { if (!Entries.TryGetValue(id, out var value2)) { throw new KeyNotFoundException(); } Assert.IsTrue(value2.Type == typeof(T) || !value.HasValue); _values[id] = value; } public object GetValue(string id) { if (!_values.TryGetValue(id, out var value)) { return null; } return value; } public bool GetValue(string id, out object value) { if (!_values.TryGetValue(id, out value)) { return false; } return true; } public string Serialize() { StringBuilder stringBuilder = new StringBuilder(); StringBuilder stringBuilder2 = new StringBuilder(); foreach (KeyValuePair<string, object> value2 in _values) { if (stringBuilder.Length > 0) { stringBuilder.Append("\n"); } object value = value2.Value; BalanceEntry balanceEntry = Entries[value2.Key]; Type type = balanceEntry.Type; string text = Serializers.Serialize(value); stringBuilder2.Clear(); stringBuilder2.Append("# " + balanceEntry.Description + "\n"); stringBuilder2.Append("# type: " + balanceEntry.Type.FullName); if (text == null) { throw new NotImplementedException(); } stringBuilder.Append($"{stringBuilder2}\n{balanceEntry.ID} = {text}\n"); } return stringBuilder.ToString(); } public void Deserialize(string data) { StringQueue stringQueue = new StringQueue(data); char[] spaces = new char[2] { ' ', '\t' }; while (!stringQueue.Finished) { string text = stringQueue.PopUntil(new <>z__ReadOnlySingleElementList<char>('\n'), out var _); text = text.TrimStart(spaces); if (text.StartsWith('#')) { continue; } StringQueue stringQueue2 = new StringQueue(text); char? stopper2; string text2 = stringQueue2.PopUntil(new <>z__ReadOnlySingleElementList<char>('='), out stopper2).Trim(spaces); if (text2.Any((char c) => spaces.Contains(c))) { Log.Warning("BalanceSheet line '" + text + "' seemingly contains invalid variable id due to spaces being in the variable."); continue; } string text3 = stringQueue2.GetRemaining().Trim(spaces); if (!Entries.TryGetValue(text2, out var value)) { Log.Warning("Unknown BalanceSheet entry '" + text2 + "' with value '" + text3 + "'"); continue; } object value2; try { value2 = Serializers.Deserialize(value.Type, text3); } catch (Exception ex) { Log.Error($"Error reading value string: '{text3}' for variable named: '{text2}'. {ex.Message}\nFull Line: {text}\nFull Exception: {ex}"); continue; } SetValue(value.Type, text2, value2); } } } [Serializable] public struct BalanceFloat { public bool UseBase; public float BaseValue; [SerializeField] private BalanceEntryRef _ref; public float Value => (UseBase || !_ref.IsValid) ? BaseValue : ((float)_ref.Value); public BalanceFloat(BalanceEntryRef<float> reference) { UseBase = false; BaseValue = 0f; _ref = reference.ToRawReference(); } } [Serializable] public struct BalanceBool { public bool UseBase; public bool BaseValue; [SerializeField] private readonly BalanceEntryRef _ref; public readonly bool Value => (UseBase || !_ref.IsValid) ? BaseValue : ((bool)_ref.Value); public BalanceBool(BalanceEntryRef<bool> reference) { UseBase = false; BaseValue = false; _ref = reference.ToRawReference(); } } public class SerializerSet { private Dictionary<Type, Func<object, string>> _serializers = new Dictionary<Type, Func<object, string>>(); private Dictionary<Type, Func<string, object>> _deserializers = new Dictionary<Type, Func<string, object>>(); public string Serialize(object value) { if (!_serializers.TryGetValue(value.GetType(), out var value2)) { return null; } return value2(value); } public object Deserialize(Type type, string data) { if (!_deserializers.TryGetValue(type, out var value)) { return null; } return value(data); } public void Add<T>(Func<T, string> serializer, Func<string, T?> deserializer) where T : struct { Assert.IsFalse(ContainsType<T>()); Assert.IsNotNull((object)serializer, ""); Assert.IsNotNull((object)deserializer, ""); Add(typeof(T), (object obj) => (obj != null) ? serializer((T)obj) : "null", (string data) => (data != "null") ? deserializer(data) : ((T?)null)); } public void Add(Type type, Func<object, string> serializer, Func<string, object> deserializer) { Assert.IsFalse(ContainsType(type)); Assert.IsNotNull((object)type, ""); Assert.IsNotNull((object)serializer, ""); Assert.IsNotNull((object)deserializer, ""); _serializers.Add(type, serializer); _deserializers.Add(type, deserializer); } public bool ContainsType<T>() { return ContainsType(typeof(T)); } public bool ContainsType(Type type) { if (!_serializers.TryGetValue(type, out var value)) { return false; } if (value == null) { return false; } return true; } } public static class CompositeManager { public static SerializerSet Serializers = new SerializerSet(); private static Dictionary<string, BalanceComposite> _composites = new Dictionary<string, BalanceComposite>(); public static T CreateComposite<T>(string id) where T : BalanceComposite, new() { T val = new T(); _composites[id] = val; val.Serializers = Serializers; return val; } } public static class StandardSerializerSet { public static void AddStandardSerializers(this SerializerSet set) { set.Add((float val) => val.ToString(CultureInfo.InvariantCulture).TrimEnd('0'), delegate(string data) { if (!float.TryParse(data, NumberStyles.Float, CultureInfo.InvariantCulture, out var result)) { throw new FormatException("malformed float format '" + data + "'"); } return result; }); set.Add((bool val) => val ? "true" : "false", delegate(string data) { if (data == "true") { return true; } if (!(data == "false")) { throw new ArgumentException(); } return false; }); } } public static class Cheats { public delegate void ReadyForCheatRegistrationEventHandler(CheatsManager cheatsManager); [HarmonyPatch(typeof(CheatsManager), "Start", new Type[] { })] private static class CheatsManagerStartPatch { public static void Prefix(CheatsManager __instance) { _manager = __instance; MaybeWaitForCheatRegistration(); } public static void Postfix(CheatsManager __instance) { TryRegisterCheats(); } } [HarmonyPatch(typeof(TeleportCheat), "Teleport")] private static class TeleportCheatTeleportPatch { public static void Prefix(TeleportCheat __instance, Transform target) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) if (Enabled) { PlayerActivator val = Object.FindAnyObjectByType<PlayerActivator>(); if ((Object)(object)val != (Object)null) { ((Component)val).transform.position = target.position; } } } public static void Postfix(TeleportCheat __instance, Transform target) { } } private static CheatsManager _manager; public const string RadiantAllEnemies = "nyxpiri.radiant-all-enemies"; public const string Immortality = "nyxpiri.immortality"; public const string SandAllEnemies = "nyxpiri.sand-all-enemies"; public const string OverrideCybergrindStartingWave = "nyxpiri.override-cybergrind-starting-wave"; public const string DisableStops = "nyxpiri.disable-stops"; public const string DisableSlowdown = "nyxpiri.disable-slowdown"; public const string UltraStop = "nyxpiri.ultra-stop"; public const string ShortHitStop = "nyxpiri.short-hit-stop"; public const string PlayCleanMusicWithBattle = "nyxpiri.clean-music-with-battle"; public const string AlwaysBattleMusic = "nyxpiri.always-battle-music"; public const string LogEIDInfo = "nyxpiri.dev.log-eid-info"; private static bool WaitingForCheatRegistration; public static CheatsManager Manager { get { if ((Object)(object)_manager == (Object)null && (Object)(object)MonoSingleton<CheatsManager>.Instance != (Object)null) { Log.ExpectedInfo("Had to get CheatsManager via CheatsManager.Instance (then cached the value)"); _manager = MonoSingleton<CheatsManager>.Instance; } return _manager; } } public static bool Enabled => MonoSingleton<CheatsController>.Instance?.cheatsEnabled ?? false; public static event ReadyForCheatRegistrationEventHandler ReadyForCheatRegistration; public static bool IsCheatEnabled(string cheatID) { if (!Enabled) { return false; } return Manager.GetCheatState(cheatID); } public static bool IsCheatDisabled(string cheatID) { return !IsCheatEnabled(cheatID); } public static void Initialize() { SceneEvents.OnSceneLoad += OnSceneWasLoaded; UpdateEvents.OnUpdate += LateUpdate; PlayerEvents.PredictedDeath += PlayerPredictedDeath; } private static void PlayerPredictedDeath(EventMethodCanceler canceler, PlayerComponents player, int damage) { if (IsCheatEnabled("nyxpiri.immortality")) { canceler.CancelMethod(); } } private static void LateUpdate() { TryRegisterCheats(); } private static void TryRegisterCheats() { if (!((Object)(object)MonoSingleton<CheatsController>.Instance == (Object)null) && WaitingForCheatRegistration && !((Object)(object)Manager == (Object)null)) { if (Manager.GetCheatState("nyxpiri.radiant-all-enemies")) { OptionsManager.forceRadiance = true; } if (Manager.GetCheatState("nyxpiri.sand-all-enemies")) { OptionsManager.forceSand = true; } WaitingForCheatRegistration = false; RegisterCheats(); } } private static void OnSceneWasLoaded(Scene scene, string levelName, string unitySceneName) { MaybeWaitForCheatRegistration(); } private static void MaybeWaitForCheatRegistration() { if (!((Object)(object)Manager == (Object)null)) { WaitingForCheatRegistration = Manager.GetCheatInstance<ToggleCheat>() == null; } } private static void RegisterCheats() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown if (Options.RegisterHideCheatsStatusCheat.Value) { Manager.RegisterCheat((ICheat)new HideCheatsStatus(), "meta"); } if (Options.RegisterForceNextWaveCheat.Value) { Manager.RegisterCheat((ICheat)(object)new ToggleCheat("Force Next Wave", "nyxpiri.force-next-cybergrind-wave", delegate { }, delegate { Manager.DisableCheat("nyxpiri.force-next-cybergrind-wave"); if (Cybergrind.IsActive && Cybergrind.IsInCybergrindLevel) { ((Component)Cybergrind.EndlessGrid).GetComponent<ActivateNextWave>().deadEnemies = 99999; } }), "CYBERGRIND"); } if (Options.RegisterOverrideCybergrindStartingWaveCheat.Value) { Manager.RegisterCheat((ICheat)(object)new ToggleCheat("Override Starting Wave", "nyxpiri.override-cybergrind-starting-wave", delegate { }, delegate { }), "CYBERGRIND"); } Manager.RegisterCheat((ICheat)(object)new ToggleCheat("Radiant All Enemies", "nyxpiri.radiant-all-enemies", delegate { }, delegate { }), "SELF SABOTAGE"); if (Options.RegisterSandAllEnemiesCheat.Value) { Manager.RegisterCheat((ICheat)(object)new ToggleCheat("Sand All Enemies", "nyxpiri.sand-all-enemies", delegate { OptionsManager.forceSand = false; }, delegate { OptionsManager.forceSand = true; }), "SELF SABOTAGE"); } if (Options.RegisterImmortalityCheat.Value) { Manager.RegisterCheat((ICheat)(object)new ToggleCheat("Immortality", "nyxpiri.immortality", delegate { }, delegate { }), "I FORGOT"); } Cheats.ReadyForCheatRegistration?.Invoke(Manager); Manager.RebuildMenu(); } } [HarmonyPatch(typeof(CheckPoint), "ActivateCheckPoint", new Type[] { })] internal static class CheckpointGetPatch { public static void Prefix(CheckPoint __instance) { } public static void Postfix(CheckPoint __instance) { } } public class StringQueue { private int Index = 0; private string Str = null; public bool Finished => Str.Length <= Index; public StringQueue(string str) { Str = str; } public char Peek() { return Str[Index]; } public char Pop() { char result = Str[Index]; Index++; return result; } public string PopUntil(IReadOnlyCollection<char> chars, out char? stopper) { StringBuilder stringBuilder = new StringBuilder(); stopper = null; while (!Finished) { char value = Peek(); if (chars.Contains(value)) { stopper = value; break; } stringBuilder.Append(Pop()); } return stringBuilder.ToString(); } public void Reset(string str) { Str = str; } public string GetRemaining() { string str = Str; int index = Index; return str.Substring(index, str.Length - index); } } public struct CommandScope { private HashSet<char> _Flags; private Dictionary<string, CommandScope> _Scopes; private List<string> _Parameters; public string Name { get; private set; } public IReadOnlyCollection<char> Flags => _Flags; public IReadOnlyDictionary<string, CommandScope> Scopes => _Scopes; public IReadOnlyList<string> Parameters => _Parameters; public bool HasFlag(char flag) { return Flags.Contains(flag); } public bool HasScope(string scopeName) { return Scopes.ContainsKey(scopeName); } public void HaveScopeOrThrow(string scopeName, Exception e) { if (!HasScope(scopeName)) { throw e; } } public bool HasParam(string paramStr) { return Parameters.Contains(paramStr); } public bool HasNumParams(int num) { return Parameters.Count >= num; } public void HaveNumParamsOrThrow(int num, Exception e) { if (!HasNumParams(num)) { throw e; } } public bool HasChain(string chainStr) { StringQueue stringQueue = new StringQueue(chainStr); bool flag = false; CommandScope commandScope = this; while (!stringQueue.Finished) { char? stopper; string text = stringQueue.PopUntil(new <>z__ReadOnlyArray<char>(new char[2] { '/', ':' }), out stopper); if (text.Length > 0) { if (!flag) { if (int.TryParse(text, out var result)) { if (!commandScope.HasNumParams(result)) { return false; } return true; } throw new FormatException("invalid int formatting on '" + text + "', in chainStr " + chainStr); } if (!commandScope.Scopes.TryGetValue(text, out var value)) { return false; } commandScope = value; } flag = stopper.HasValue && stopper.Value == '/'; stringQueue.Pop(); } return true; } public void HaveChainOrThrow(string chainStr, Exception e) { if (!HasChain(chainStr)) { throw e; } } public CommandScope(string name) { Name = null; _Flags = null; _Scopes = null; _Parameters = null; Name = name; _Parameters = new List<string>(); _Flags = new HashSet<char>(); _Scopes = new Dictionary<string, CommandScope>(); } public CommandScope(StringQueue strQueue, string name) { Name = null; _Flags = null; _Scopes = null; _Parameters = null; Name = name; _Parameters = new List<string>(); _Flags = new HashSet<char>(); _Scopes = new Dictionary<string, CommandScope>(); ParseScope(strQueue); } public void ParseScope(StringQueue strQueue) { bool buildingFlags = false; bool flag = false; StringBuilder currentToken = new StringBuilder(); CommandScope self = this; Action addFlags = delegate { string text = currentToken.ToString(); string text2 = text; foreach (char item in text2) { self._Flags.Add(item); } }; Action action = delegate { if (currentToken.Length != 0) { StringBuilder stringBuilder = currentToken; if (stringBuilder[stringBuilder.Length - 1] == ':') { currentToken.Remove(currentToken.Length - 1, 1); if (!self._Scopes.ContainsKey(currentToken.ToString())) { self._Scopes[currentToken.ToString()] = new CommandScope(strQueue, currentToken.ToString()); } else { self._Scopes[currentToken.ToString()].ParseScope(strQueue); } currentToken.Clear(); } else { if (!buildingFlags) { self._Parameters.Add(currentToken.ToString()); } else { buildingFlags = false; addFlags(); } currentToken.Clear(); } } }; while (!strQueue.Finished) { char c = strQueue.Peek(); switch (c) { case '\t': case '\n': case ' ': strQueue.Pop(); action(); if (!flag && (_Parameters.Count > 0 || Scopes.Count > 0 || _Flags.Count > 0)) { return; } break; case '{': if (currentToken.Length > 0) { throw new FormatException("Unexpected '{' after first character of token in CommandScope string"); } flag = true; strQueue.Pop(); break; case '}': if (flag) { strQueue.Pop(); action(); return; } strQueue.Pop(); action(); if (_Parameters.Count > 0 || Scopes.Count > 0 || _Flags.Count > 0) { return; } throw new FormatException("Unexpected '}' in non-bracket-scope CommandScope by name '" + Name + "'"); case '~': strQueue.Pop(); if (currentToken.Length == 0) { buildingFlags = true; } else { currentToken.Append(c); } break; default: strQueue.Pop(); currentToken.Append(c); break; } } action(); } public string ToDebugString(int depth = 0) { StringBuilder stringBuilder = new StringBuilder(512); StringBuilder stringBuilder2 = new StringBuilder(depth + 1); stringBuilder2.Append('\n'); for (int i = 0; i < depth; i++) { stringBuilder2.Append('\t'); } string text = stringBuilder2.ToString(); stringBuilder.Append("Flags: -"); foreach (char flag in Flags) { stringBuilder.Append(flag); } stringBuilder.Append(text); stringBuilder.Append("Parameters:"); foreach (string parameter in Parameters) { stringBuilder.Append(text); stringBuilder.Append("\t" + parameter); } stringBuilder.Append(text); stringBuilder.Append("Scopes:"); foreach (CommandScope value in Scopes.Values) { stringBuilder.Append(text); stringBuilder.Append("\t" + value.Name + ": {"); stringBuilder.Append(text + "\t\t"); stringBuilder.Append(value.ToDebugString(depth + 2) ?? ""); stringBuilder.Append(text + "\t}"); } return stringBuilder.ToString(); } } public class Command { public IReadOnlyCollection<char> Flags => MainScope.Flags; public IReadOnlyList<string> Parameters => MainScope.Parameters; public bool HasParams => Parameters.Count > 0; public bool HasNoParams => !HasParams; public IReadOnlyDictionary<string, CommandScope> Scopes => MainScope.Scopes; public CommandScope MainScope { get; private set; } public bool HasFlag(char flag) { return MainScope.HasFlag(flag); } public bool HasScope(string scopeName) { return MainScope.HasScope(scopeName); } public void HaveScopeOrThrow(string scopeName, Exception e) { MainScope.HaveScopeOrThrow(scopeName, e); } public bool HasParam(string paramStr) { return MainScope.HasParam(paramStr); } public bool HasNumParams(int num) { return MainScope.HasNumParams(num); } public void HaveNumParamsOrThrow(int count, Exception e) { MainScope.HaveNumParamsOrThrow(count, e); } public bool HasChain(string chainStr) { return MainScope.HasChain(chainStr); } public void HaveChainOrThrow(string chainStr, Exception e) { MainScope.HaveChainOrThrow(chainStr, e); } public Command() { MainScope = default(CommandScope); } public Command(string command) { ParseCommand(command); } public void ParseCommand(string command) { StringQueue stringQueue = new StringQueue("{" + command + "}"); MainScope = new CommandScope(stringQueue, null); if (!stringQueue.Finished) { string remaining = stringQueue.GetRemaining(); throw new FormatException("Unexpected continuation of command from where it seemingly should've ended, remaining string is '" + remaining + "'"); } } public string ToDebugString() { return MainScope.ToDebugString(); } } public static class Cybergrind { public delegate void CybergrindPreBeginEventHandler(EventMethodCanceler canceler, EndlessGrid endlessGrid); public delegate void CybergrindPostBeginEventHandler(EventMethodCancelInfo cancelInfo, EndlessGrid endlessGrid); public delegate void CybergrindPreNextWaveEventHandler(EventMethodCanceler canceler, EndlessGrid endlessGrid); public delegate void CybergrindPostNextWaveEventHandler(EventMethodCancelInfo cancelInfo, EndlessGrid endlessGrid); [HarmonyPatch(typeof(EndlessGrid), "OnTriggerEnter", new Type[] { typeof(Collider) })] private static class CybergrindStartPatch { private static EventMethodCancellationTracker _cancellationTracker = new EventMethodCancellationTracker(); public static bool Prefix(EndlessGrid __instance, Collider other) { if (!((Component)other).CompareTag("Player")) { return true; } _cancellationTracker.Reset(); Cybergrind.PreCybergrindBegin?.Invoke(_cancellationTracker.GetCanceler(), __instance); _cancellationTracker.TryInvokeReimplementation(); return !_cancellationTracker.Cancelled; } public static void Postfix(EndlessGrid __instance, Collider other) { if (((Component)other).CompareTag("Player")) { Cybergrind.PostCybergrindBegin?.Invoke(_cancellationTracker.GetCancelInfo(), __instance); IsActive = true; } } } [HarmonyPatch(typeof(EndlessGrid), "Start")] private static class EndlessGridStartPatch { public static void Prefix(EndlessGrid __instance) { } public static void Postfix(EndlessGrid __instance) { EndlessGrid = __instance; } } [HarmonyPatch(typeof(EndlessGrid), "NextWave", null)] private static class EndlessGridNextWavePatch { private static EventMethodCancellationTracker _cancellationTracker = new EventMethodCancellationTracker(); public static bool Prefix(EndlessGrid __instance) { _cancellationTracker.Reset(); Cybergrind.PreCybergrindNextWave?.Invoke(_cancellationTracker.GetCanceler(), __instance); _cancellationTracker.TryInvokeReimplementation(); return !_cancellationTracker.Cancelled; } public static void Postfix(EndlessGrid __instance) { Cybergrind.PostCybergrindNextWave?.Invoke(_cancellationTracker.GetCancelInfo(), __instance); } } private static EndlessGrid _endlessGrid; public static EndlessGrid EndlessGrid { get { if ((Object)(object)_endlessGrid != (Object)null) { return _endlessGrid; } _endlessGrid = MonoSingleton<EndlessGrid>.Instance; return _endlessGrid; } set { _endlessGrid = value; } } public static bool IsActive { get; private set; } public static bool IsInCybergrindLevel => (Object)(object)EndlessGrid != (Object)null; public static event CybergrindPreBeginEventHandler PreCybergrindBegin; public static event CybergrindPostBeginEventHandler PostCybergrindBegin; public static event CybergrindPreNextWaveEventHandler PreCybergrindNextWave; public static event CybergrindPostNextWaveEventHandler PostCybergrindNextWave; public static void Initialize() { UpdateEvents.OnFixedUpdate += OnFixedUpdate; SceneEvents.OnSceneLoad += OnSceneWasLoaded; SceneEvents.OnSceneUnload += OnSceneWasUnloaded; PreCybergrindBegin += PreBegin; } private static void PreBegin(EventMethodCanceler canceler, EndlessGrid endlessGrid) { if (Cheats.Enabled && Cheats.IsCheatEnabled("nyxpiri.override-cybergrind-starting-wave")) { endlessGrid.startWave = Options.CybergrindStartingWaveOverride.Value; } } private static void OnSceneWasUnloaded(Scene scene, string levelName, string unitySceneName) { IsActive = false; } private static void OnSceneWasLoaded(Scene scene, string levelName, string unitySceneName) { IsActive = false; } private static void OnFixedUpdate() { } } public static class Assert { public static void IsTrue(bool condition, string additionalMsg = "") { //IL_0020: Unknown result type (might be due to invalid IL or missing references) if (!condition) { throw new AssertionException("Assertion Failed: Condition was false :c; " + additionalMsg, "Assertion Failed: Condition was false :c; " + additionalMsg); } } public static void IsFalse(bool condition, string additionalMsg = "") { //IL_001d: Unknown result type (might be due to invalid IL or missing references) if (condition) { throw new AssertionException("Assertion Failed: Condition was true :c; " + additionalMsg, "Assertion Failed: Condition was false :c; " + additionalMsg); } } public static void IsNotNull(object obj, string additionalMsg = "") { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) if (obj == null) { if (obj == null) { throw new AssertionException("Assertion Failed: Object was null :c; " + additionalMsg, "Assertion Failed: Object was null :c; " + additionalMsg); } throw new AssertionException("Assertion Failed: Object equals null but *'is' not* null :c; " + additionalMsg, "Assertion Failed: Object was null :c; " + additionalMsg); } } public static void IsNull(object obj, string additionalMsg = "") { //IL_0020: Unknown result type (might be due to invalid IL or missing references) if (obj != null) { throw new AssertionException("Assertion Failed: Object is not null :c; " + additionalMsg, "Assertion Failed: Object is not null :c; " + additionalMsg); } } public static void IsNotNull(Object obj, string additionalMsg = "") { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) if (obj == (Object)null) { if (obj == null) { throw new AssertionException("Assertion Failed: Object was null :c; " + additionalMsg, "Assertion Failed: Object was null :c; " + additionalMsg); } throw new AssertionException("Assertion Failed: Object equals null but *'is' not* null :c; " + additionalMsg, "Assertion Failed: Object was null :c; " + additionalMsg); } } } public static class AssetInspecting { public unsafe static void DebugPrintMaterialProperties(this Material material) { //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Expected I4, but got Unknown //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) Log.Message("----------========== Material Debug Print of properties for " + ((Object)material).name + " (shader: " + ((Object)material.shader).name + ") start! ==========----------"); StringBuilder stringBuilder = new StringBuilder(); foreach (object value in Enum.GetValues(typeof(MaterialPropertyType))) { string[] propertyNames = material.GetPropertyNames((MaterialPropertyType)value); foreach (string text in propertyNames) { string text2 = null; string text3 = null; MaterialPropertyType val = (MaterialPropertyType)value; MaterialPropertyType val2 = val; switch ((int)val2) { case 0: text2 = material.GetFloat(text).ToString(); text3 = text2; break; case 1: text2 = material.GetInt(text).ToString(); text3 = text2; break; case 2: { Vector4 vector = material.GetVector(text); text2 = ((object)(*(Vector4*)(&vector))/*cast due to .constrained prefix*/).ToString(); text3 = $"[{vector.x}, {vector.y}, {vector.z}, {vector.w}]"; break; } case 3: text2 = ((object)material.GetMatrix(text)/*cast due to .constrained prefix*/).ToString(); break; case 4: { Texture texture = material.GetTexture(text); text2 = ((texture != null) ? ((Object)texture).name : null) ?? "null"; break; } case 5: text2 = $"{material.GetConstantBuffer(text)}"; break; case 6: text2 = $"{material.GetBuffer(text)}"; break; } Log.Message($"Material Debug! There's a {value} named {text}, with a value of {text2}"); if (text3 != null) { stringBuilder.AppendLine("\"" + text + "\": " + text3 + ","); } } } stringBuilder.Remove(stringBuilder.Length - 2, 1); Log.Message("------ FORMATTED VERSION START! -------"); Log.Message($"{stringBuilder}"); Log.Message("------ FORMATTED VERSION END! -------"); Log.Message("----------========== Material Debug Print of properties for " + ((Object)material).name + " END! ==========----------"); } public static void DebugPrintMaterialKeywords(this Material material) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: 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_0067: Unknown result type (might be due to invalid IL or missing references) Log.Message("----------========== Material Debug Print of keywords for " + ((Object)material).name + " (shader: " + ((Object)material.shader).name + ") start! ==========----------"); LocalKeywordSpace keywordSpace = material.shader.keywordSpace; int num = ((LocalKeywordSpace)(ref keywordSpace)).keywordNames.Length; for (int i = 0; i < num; i++) { keywordSpace = material.shader.keywordSpace; string text = ((LocalKeywordSpace)(ref keywordSpace)).keywordNames[i]; if (material.IsKeywordEnabled(text)) { Log.Message("\"" + text + "\": true" + ((i == num - 1) ? "" : ",")); } else { Log.Message("\"" + text + "\": false" + ((i == num - 1) ? "" : ",")); } } Log.Message("----------========== Material Debug Print of keywords for " + ((Object)material).name + " END! ==========----------"); } public static void DebugPrintMaterialShaderPasses(this Material material) { Log.Message("----------========== Material Debug Print of passes for " + ((Object)material).name + " (shader: " + ((Object)material.shader).name + ") start! ==========----------"); for (int i = 0; i < material.passCount; i++) { string passName = material.GetPassName(i); if (material.GetShaderPassEnabled(passName)) { Log.Message($"{passName} [{i}] is ENABLED"); } else { Log.Message($"{passName} [{i}] is DISABLED"); } } Log.Message($"{material.shader.passCount} shader passes"); Log.Message("----------========== Material Debug Print of passes for " + ((Object)material).name + " END! ==========----------"); } } public static class TryLog { public static void Action(Action action) { try { action(); } catch (Exception arg) { Log.Error($"Exception caught! :c\n{arg}"); throw; } } } [HarmonyPatch(typeof(ActivateNextWave), "AddDeadEnemy")] internal static class CybergrindStartPatch { public static void Prefix() { } public static void Postfix() { } } public enum EnemyGameplayRank { Normal, Miniboss, Boss, Ultraboss } public enum EnemySpeciesType { Husk, Machine, Demon, Angel, Soul, OrganicMachine, Puppet, Unknown, UltraUnknown } public enum EnemySpeciesRank { NotApplicable, Lesser, Greater, Supreme, Prime } public static class EnemyUtils { public static int NumGameplayRanks = 4; public static bool IsEnraged(this EnemyIdentifier eid) { if (eid.Dead) { return false; } IEnrage component = ((Component)eid).GetComponent<IEnrage>(); return ((component != null) ? new bool?(component.isEnraged) : ((bool?)null)) ?? false; } public static bool TryEnrage(this EnemyIdentifier eid) { //IL_0064: 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_006b: Unknown result type (might be due to invalid IL or missing references) //IL_006d: 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_009e: Expected I4, but got Unknown //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Invalid comparison between Unknown and I4 if (eid.Dead) { return false; } IEnrage component = ((Component)eid).GetComponent<IEnrage>(); if (((component != null) ? new bool?(component.isEnraged) : ((bool?)null)) ?? false) { return false; } if (component != null) { component.Enrage(); return true; } EnemyType enemyType = eid.enemyType; EnemyType val = enemyType; switch ((int)val) { default: if ((int)val != 33) { break; } if (!eid.dead) { Gutterman component4 = ((Component)eid).GetComponent<Gutterman>(); if (component4 != null) { component4.Enrage(); } return true; } return false; case 7: { SwordsMachine component10 = ((Component)eid).GetComponent<SwordsMachine>(); if (component10 != null) { component10.Enrage(); } return true; } case 0: { StatueBoss component7 = ((Component)eid).GetComponent<StatueBoss>(); if (component7 != null) { component7.Enrage(); } return true; } case 1: case 9: { Drone component3 = ((Component)eid).GetComponent<Drone>(); if (component3 != null) { component3.Enrage(); } return true; } case 8: { V2 component8 = ((Component)eid).GetComponent<V2>(); if (component8 != null) { component8.Enrage(); } return true; } case 5: { Mindflayer component9 = ((Component)eid).GetComponent<Mindflayer>(); if (component9 != null) { component9.Enrage(); } return true; } case 2: { Mass component5 = ((Component)eid).GetComponent<Mass>(); if (!(((component5 == null) ? ((bool?)null) : ((Component)component5).GetComponentInChildren<EnemySimplifier>()?.enraged) ?? true)) { Mass component6 = ((Component)eid).GetComponent<Mass>(); if (component6 != null) { component6.Enrage(); } return true; } return false; } case 4: { SpiderBody component2 = ((Component)eid).GetComponent<SpiderBody>(); if (component2 != null) { component2.Enrage(); } return true; } case 3: case 6: break; } return false; } public static bool TryUnenrage(this EnemyIdentifier eid) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001a: 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_001c: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected I4, but got Unknown //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Invalid comparison between Unknown and I4 if (eid.Dead) { return false; } EnemyType enemyType = eid.enemyType; EnemyType val = enemyType; switch ((int)val) { default: if ((int)val != 33) { break; } if (!eid.dead) { Gutterman component2 = ((Component)eid).GetComponent<Gutterman>(); if (component2 != null) { component2.UnEnrage(); } return true; } return false; case 7: { SwordsMachine component5 = ((Component)eid).GetComponent<SwordsMachine>(); if (component5 != null) { component5.UnEnrage(); } return true; } case 0: { StatueBoss component3 = ((Component)eid).GetComponent<StatueBoss>(); if (component3 != null) { component3.UnEnrage(); } return true; } case 1: case 9: { Drone component6 = ((Component)eid).GetComponent<Drone>(); if (component6 != null) { component6.UnEnrage(); } return true; } case 8: { V2 component7 = ((Component)eid).GetComponent<V2>(); if (component7 != null) { component7.UnEnrage(); } return true; } case 5: { Mindflayer component4 = ((Component)eid).GetComponent<Mindflayer>(); if (component4 != null) { component4.UnEnrage(); } return true; } case 4: { SpiderBody component = ((Component)eid).GetComponent<SpiderBody>(); if (component != null) { component.UnEnrage(); } return true; } case 2: case 3: case 6: break; } return false; } public static void ApplyDamage(this EnemyIdentifier eid, Vector3 force, Vector3 hitPoint, float multiplier, float critMultiplier, GameObject sourceWeapon, bool fromExplosion) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) eid.DeliverDamage(((Component)eid).gameObject, force, hitPoint, multiplier, false, critMultiplier, sourceWeapon, false, fromExplosion); } public static EnemyGameplayRank GetEnemyGameplayRank(this EnemyIdentifier eid) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Expected I4, but got Unknown EnemyType enemyType = eid.enemyType; if (1 == 0) { } EnemyGameplayRank result = (int)enemyType switch { 37 => EnemyGameplayRank.Ultraboss, 23 => EnemyGameplayRank.Normal, 35 => EnemyGameplayRank.Boss, 0 => eid.isBoss ? EnemyGameplayRank.Boss : EnemyGameplayRank.Normal, 1 => EnemyGameplayRank.Normal, 26 => EnemyGameplayRank.Miniboss, 3 => EnemyGameplayRank.Normal, 30 => EnemyGameplayRank.Ultraboss, 17 => EnemyGameplayRank.Ultraboss, 16 => EnemyGameplayRank.Boss, 28 => EnemyGameplayRank.Boss, 33 => EnemyGameplayRank.Normal, 34 => EnemyGameplayRank.Normal, 2 => (!eid.isBoss) ? EnemyGameplayRank.Miniboss : EnemyGameplayRank.Boss, 21 => EnemyGameplayRank.Normal, 27 => EnemyGameplayRank.Boss, 4 => eid.isBoss ? EnemyGameplayRank.Boss : EnemyGameplayRank.Normal, 25 => EnemyGameplayRank.Ultraboss, 31 => EnemyGameplayRank.Normal, 5 => (!eid.isBoss) ? EnemyGameplayRank.Miniboss : EnemyGameplayRank.Boss, 11 => EnemyGameplayRank.Ultraboss, 18 => EnemyGameplayRank.Ultraboss, 32 => EnemyGameplayRank.Boss, 36 => EnemyGameplayRank.Normal, 14 => EnemyGameplayRank.Normal, 19 => EnemyGameplayRank.Miniboss, 29 => EnemyGameplayRank.Ultraboss, 15 => EnemyGameplayRank.Normal, 12 => EnemyGameplayRank.Normal, 13 => EnemyGameplayRank.Normal, 6 => EnemyGameplayRank.Normal, 7 => (!eid.isBoss) ? EnemyGameplayRank.Miniboss : EnemyGameplayRank.Boss, 20 => EnemyGameplayRank.Normal, 8 => EnemyGameplayRank.Boss, 22 => EnemyGameplayRank.Boss, 24 => EnemyGameplayRank.Boss, 9 => EnemyGameplayRank.Normal, 10 => EnemyGameplayRank.Ultraboss, 38 => EnemyGameplayRank.Normal, 40 => EnemyGameplayRank.Normal, 41 => EnemyGameplayRank.Miniboss, 42 => EnemyGameplayRank.Boss, 39 => EnemyGameplayRank.Normal, _ => throw new NotImplementedException(), }; if (1 == 0) { } return result; } public static EnemySpeciesType GetSpeciesType(this EnemyType enemyType) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Expected I4, but got Unknown if (1 == 0) { } EnemySpeciesType result = (int)enemyType switch { 3 => EnemySpeciesType.Husk, 37 => EnemySpeciesType.UltraUnknown, 23 => EnemySpeciesType.UltraUnknown, 35 => EnemySpeciesType.Machine, 0 => EnemySpeciesType.Demon, 1 => EnemySpeciesType.Machine, 26 => EnemySpeciesType.Husk, 30 => EnemySpeciesType.OrganicMachine, 17 => EnemySpeciesType.OrganicMachine, 16 => EnemySpeciesType.Angel, 28 => EnemySpeciesType.Angel, 33 => EnemySpeciesType.Machine, 34 => EnemySpeciesType.Machine, 2 => EnemySpeciesType.Demon, 21 => EnemySpeciesType.Demon, 27 => EnemySpeciesType.Demon, 4 => EnemySpeciesType.Demon, 25 => EnemySpeciesType.UltraUnknown, 31 => EnemySpeciesType.Demon, 5 => EnemySpeciesType.Machine, 11 => EnemySpeciesType.Husk, 18 => EnemySpeciesType.Soul, 32 => EnemySpeciesType.Demon, 36 => EnemySpeciesType.Puppet, 14 => EnemySpeciesType.Husk, 19 => EnemySpeciesType.Husk, 29 => EnemySpeciesType.Soul, 15 => EnemySpeciesType.Husk, 12 => EnemySpeciesType.Husk, 13 => EnemySpeciesType.Husk, 6 => EnemySpeciesType.Machine, 7 => EnemySpeciesType.Machine, 20 => EnemySpeciesType.Machine, 8 => EnemySpeciesType.Machine, 22 => EnemySpeciesType.Machine, 24 => EnemySpeciesType.UltraUnknown, 9 => EnemySpeciesType.Angel, 38 => EnemySpeciesType.Angel, 40 => EnemySpeciesType.Angel, 41 => EnemySpeciesType.Husk, 42 => EnemySpeciesType.Demon, 39 => EnemySpeciesType.Demon, 10 => EnemySpeciesType.Unknown, _ => throw new NotImplementedException(), }; if (1 == 0) { } return result; } public static EnemySpeciesRank GetSpeciesRank(this EnemyType enemyType) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Expected I4, but got Unknown if (1 == 0) { } EnemySpeciesRank result = (int)enemyType switch { 37 => EnemySpeciesRank.NotApplicable, 23 => EnemySpeciesRank.Supreme, 35 => EnemySpeciesRank.Supreme, 0 => EnemySpeciesRank.Lesser, 1 => EnemySpeciesRank.Lesser, 26 => EnemySpeciesRank.Supreme, 3 => EnemySpeciesRank.Lesser, 30 => EnemySpeciesRank.Greater, 17 => EnemySpeciesRank.Lesser, 16 => EnemySpeciesRank.Supreme, 28 => EnemySpeciesRank.Supreme, 33 => EnemySpeciesRank.Greater, 34 => EnemySpeciesRank.Greater, 2 => EnemySpeciesRank.Greater, 21 => EnemySpeciesRank.Lesser, 27 => EnemySpeciesRank.Supreme, 4 => EnemySpeciesRank.Lesser, 25 => EnemySpeciesRank.NotApplicable, 31 => EnemySpeciesRank.Lesser, 5 => EnemySpeciesRank.Greater, 11 => EnemySpeciesRank.Supreme, 18 => EnemySpeciesRank.Prime, 32 => EnemySpeciesRank.Supreme, 36 => EnemySpeciesRank.NotApplicable, 14 => EnemySpeciesRank.Greater, 19 => EnemySpeciesRank.Supreme, 29 => EnemySpeciesRank.Prime, 15 => EnemySpeciesRank.Greater, 12 => EnemySpeciesRank.Lesser, 13 => EnemySpeciesRank.Lesser, 6 => EnemySpeciesRank.Lesser, 7 => EnemySpeciesRank.Greater, 20 => EnemySpeciesRank.Greater, 8 => EnemySpeciesRank.Supreme, 22 => EnemySpeciesRank.Supreme, 24 => EnemySpeciesRank.Prime, 9 => EnemySpeciesRank.Lesser, 41 => EnemySpeciesRank.Supreme, 39 => EnemySpeciesRank.Lesser, 42 => EnemySpeciesRank.Supreme, 38 => EnemySpeciesRank.Lesser, 40 => EnemySpeciesRank.Greater, 10 => EnemySpeciesRank.NotApplicable, _ => throw new NotImplementedException(), }; if (1 == 0) { } return result; } public static EnemySpeciesRank GetSpeciesRank(this EnemyIdentifier eid) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) return eid.enemyType.GetSpeciesRank(); } public static EnemySpeciesType GetSpeciesType(this EnemyIdentifier eid) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) return eid.enemyType.GetSpeciesType(); } public static Bounds SolveEnemyBounds(this EnemyComponents enemy) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) return ((Component)enemy).gameObject.SolveEnemyBounds(); } public static Bounds SolveEnemyBounds(this GameObject enemyGo) { //IL_0003: 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_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0049: 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_0227: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: 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) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0222: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: 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_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Unknown result type (might be due to invalid IL or missing references) //IL_0208: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_01f4: Unknown result type (might be due to invalid IL or missing references) Bounds result = default(Bounds); Collider component = enemyGo.GetComponent<Collider>(); Collider[] componentsInChildren = enemyGo.GetComponentsInChildren<Collider>(); if ((Object)(object)component != (Object)null) { result = component.bounds; } Vector3 extents = ((Bounds)(ref result)).extents; if (((Vector3)(ref extents)).magnitude > 2f) { return result; } Collider[] array = componentsInChildren; foreach (Collider val in array) { Vector3 min = ((Bounds)(ref result)).min; Vector3 max = ((Bounds)(ref result)).max; float x = min.x; Bounds bounds = val.bounds; if (x > ((Bounds)(ref bounds)).min.x) { bounds = val.bounds; min.x = ((Bounds)(ref bounds)).min.x; } float y = min.y; bounds = val.bounds; if (y > ((Bounds)(ref bounds)).min.y) { bounds = val.bounds; min.y = ((Bounds)(ref bounds)).min.y; } float z = min.z; bounds = val.bounds; if (z > ((Bounds)(ref bounds)).min.z) { bounds = val.bounds; min.z = ((Bounds)(ref bounds)).min.z; } float x2 = max.x; bounds = val.bounds; if (x2 < ((Bounds)(ref bounds)).max.x) { bounds = val.bounds; max.x = ((Bounds)(ref bounds)).max.x; } float y2 = max.y; bounds = val.bounds; if (y2 < ((Bounds)(ref bounds)).max.y) { bounds = val.bounds; max.y = ((Bounds)(ref bounds)).max.y; } float z2 = max.z; bounds = val.bounds; if (z2 < ((Bounds)(ref bounds)).max.z) { bounds = val.bounds; max.z = ((Bounds)(ref bounds)).max.z; } ((Bounds)(ref result)).SetMinMax(min, max); } return result; } } [HarmonyPatch(typeof(EnemyIdentifier), "Awake")] internal static class EnemyPreSpawnPatch { public static void Prefix(EnemyIdentifier __instance) { GameObject gameObject = ((Component)__instance).gameObject; try { EnemyComponents orAddComponent = GameObjectExtensions.GetOrAddComponent<EnemyComponents>(gameObject); } catch (Exception arg) { Log.Error($"{arg}"); } } public static void Postfix(EnemyIdentifier __instance) { GameObject gameObject = ((Component)__instance).gameObject; } } [HarmonyPatch(typeof(EnemyIdentifier), "Start")] internal static class EnemyStartPatch { public static void Prefix(EnemyIdentifier __instance) { GameObject gameObject = ((Component)__instance).gameObject; TryLog.Action(delegate { EnemyEvents.PreStart?.Invoke(((Component)__instance).GetComponent<EnemyComponents>()); }); } public static void Postfix(EnemyIdentifier __instance) { //IL_007b: Unknown result type (might be due to invalid IL or missing references) GameObject gameObject = ((Component)__instance).gameObject; EnemyComponents ec = ((Component)__instance).GetComponent<EnemyComponents>(); TryLog.Action(delegate { EnemyEvents.PostStart?.Invoke(ec); }); if (Cheats.IsCheatEnabled("nyxpiri.dev.log-eid-info")) { ec.RootGameObject.DebugPrintChildren(); } ec.EidStarted = true; if (Options.LogEnemyTypeOnStart.Value) { Log.Message($"{((Object)gameObject).name}: enemy type is: {__instance.enemyType}"); } } } [HarmonyPatch(typeof(EnemyComponents), "OnDisable")] internal static class EnemyDisablePatch { public static void Prefix(EnemyComponents __instance) { EnemyComponents enemyComponents = __instance; GameObject gameObject = ((Component)enemyComponents).gameObject; TryLog.Action(delegate { EnemyEvents.PreDisabled?.Invoke(__instance); }); } public static void Postfix(EnemyComponents __instance) { GameObject gameObject = ((Component)__instance).gameObject; } } [HarmonyPatch(typeof(EnemyComponents), "OnDestroy")] internal static class EnemyDestroyPatch { public static void Prefix(EnemyComponents __instance) { EnemyComponents enemyComponents = __instance; GameObject gameObject = ((Component)enemyComponents).gameObject; TryLog.Action(delegate { EnemyEvents.PreDestroy?.Invoke(__instance); }); } public static void Postfix(EnemyComponents __instance) { GameObject gameObject = ((Component)__instance).gameObject; } } [HarmonyPatch(typeof(SpiderBody), "Die", new Type[] { })] internal static class SpiderDiePatch { private static EventMethodCancellationTracker _cancellationTracker = new EventMethodCancellationTracker(); public static bool Prefix(SpiderBody __instance) { return EidDeathPatch.PreDeath(((Component)__instance).gameObject.GetComponent<EnemyIdentifier>(), instakill: false, typeof(SpiderDiePatch), _cancellationTracker); } public static void Postfix(SpiderBody __instance) { EidDeathPatch.PostDeath(((Component)__instance).gameObject.GetComponent<EnemyIdentifier>(), typeof(SpiderDiePatch), _cancellationTracker); } } [HarmonyPatch(typeof(Enemy), "GoLimp", new Type[] { typeof(bool) })] internal static class EnemyLimpPatch { private static EventMethodCancellationTracker _cancellationTracker = new EventMethodCancellationTracker(); public static bool Prefix(Enemy __instance, bool fromExplosion) { return EidDeathPatch.PreDeath(__instance.EID, instakill: false, typeof(EnemyLimpPatch), _cancellationTracker); } public static void Postfix(Enemy __instance, bool fromExplosion) { EidDeathPatch.PostDeath(__instance.EID, typeof(EnemyLimpPatch), _cancellationTracker); } } [HarmonyPatch(typeof(Drone), "Death", new Type[] { typeof(bool) })] internal static class DroneDeathPatch { private static EventMethodCancellationTracker _cancellationTracker = new EventMethodCancellationTracker(); public static bool Prefix(Drone __instance, bool fromExplosion) { return EidDeathPatch.PreDeath(((Component)__instance).gameObject.GetComponent<EnemyIdentifier>(), instakill: false, typeof(DroneDeathPatch), _cancellationTracker); } public static void Postfix(Drone __instance, bool fromExplosion) { EidDeathPatch.PostDeath(((Component)__instance).gameObject.GetComponent<EnemyIdentifier>(), typeof(DroneDeathPatch), _cancellationTracker); } } [HarmonyPatch(typeof(EnemyIdentifier), "InstaKill")] internal static class EnemyIdentifierInstakill { private static EventMethodCancellationTracker _cancellationTracker = new EventMethodCancellationTracker(); public static bool Prefix(EnemyIdentifier __instance) { _cancellationTracker.Reset(); EnemyComponents component = ((Component)__instance).GetComponent<EnemyComponents>(); component.NullInvalid<EnemyComponents>()?.TryCallPreDeath(_cancellationTracker.GetCanceler(), instakill: true, typeof(EnemyIdentifierInstakill)); _cancellationTracker.TryInvokeReimplementation(); return _cancellationTracker.ShouldRunMethod; } public static void Postfix(EnemyIdentifier __instance) { EnemyComponents component = ((Component)__instance).GetComponent<EnemyComponents>(); component.NullInvalid<EnemyComponents>()?.TryCallPostDeath(_cancellationTracker.GetCancelInfo(), typeof(EnemyIdentifierInstakill)); } } [HarmonyPatch(typeof(EnemyIdentifier), "Explode")] internal static class EnemyIdentifierExplodePatch { private static EventMethodCancellationTracker _cancellationTracker = new EventMethodCancellationTracker(); public static bool Prefix(EnemyIdentifier __instance) { _cancellationTracker.Reset(); EnemyComponents component = ((Component)__instance).GetComponent<EnemyComponents>(); component.NullInvalid<EnemyComponents>()?.TryCallPreDeath(_cancellationTracker.GetCanceler(), instakill: true, typeof(EnemyIdentifierExplodePatch)); _cancellationTracker.TryInvokeReimplementation(); return _cancellationTracker.ShouldRunMethod; } public static void Postfix(EnemyIdentifier __instance) { EnemyComponents component = ((Component)__instance).GetComponent<EnemyComponents>(); component.NullInvalid<EnemyComponents>()?.TryCallPostDeath(_cancellationTracker.GetCancelInfo(), typeof(EnemyIdentifierExplodePatch)); } } [HarmonyPatch(typeof(EnemyIdentifier), "ProcessDeath", new Type[] { typeof(bool) })] internal static class EidDeathPatch { public static GameObject[] ActivateOnDeath; public static bool CalledPreDeath = false; private static EventMethodCancellationTracker _cancellationTracker = new EventMethodCancellationTracker(); public static bool PreDeath(EnemyIdentifier eid, bool instakill, object callerObj, EventMethodCancellationTracker cancellationTracker) { cancellationTracker.Reset(); EnemyComponents component = ((Component)eid).GetComponent<EnemyComponents>(); component.NullInvalid<EnemyComponents>()?.TryCallPreDeath(cancellationTracker.GetCanceler(), instakill, callerObj); cancellationTracker.TryInvokeReimplementation(); return cancellationTracker.ShouldRunMethod; } public static void PostDeath(EnemyIdentifier eid, object callerObj, EventMethodCancellationTracker cancellationTracker) { EnemyComponents component = ((Component)eid).GetComponent<EnemyComponents>(); component.NullInvalid<EnemyComponents>()?.TryCallPostDeath(cancellationTracker.GetCancelInfo(), callerObj); } public static bool Prefix(EnemyIdentifier __instance, bool fromExplosion) { _cancellationTracker.Reset(); EnemyComponents component = ((Component)__instance).GetComponent<EnemyComponents>(); component.NullInvalid<EnemyComponents>()?.TryCallPreDeath(_cancellationTracker.GetCanceler(), instakill: false, typeof(EidDeathPatch)); _cancellationTracker.TryInvokeReimplementation(); component.NullInvalid<EnemyComponents>()?.TryCallDeath(); return _cancellationTracker.ShouldRunMethod; } public static void Postfix(EnemyIdentifier __instance, bool fromExplosion) { EnemyComponents component = ((Component)__instance).GetComponent<EnemyComponents>(); component.NullInvalid<EnemyComponents>()?.TryCallPostDeath(_cancellationTracker.GetCancelInfo(), typeof(EidDeathPatch)); } } [HarmonyPatch(typeof(StatueBoss), "Enrage")] internal static class StatueEnragePatch { private static EventMethodCancellationTracker _cancellationTracker = new EventMethodCancellationTracker(); public static void Prefix(StatueBoss __instance) { ((Component)__instance).GetComponent<EnemyComponents>().CallPreEnrage(_cancellationTracker); } public static void Postfix(StatueBoss __instance) { ((Component)__instance).GetComponent<EnemyComponents>().CallPostEnrage(_cancellationTracker); } } [HarmonyPatch(typeof(StatueBoss), "UnEnrage")] internal static class StatueBossUnEnragePatch { private static EventMethodCancellationTracker _cancellationTracker = new EventMethodCancellationTracker(); public static void Prefix(StatueBoss __instance) { ((Component)__instance).GetComponent<EnemyComponents>().CallPreUnEnrage(_cancellationTracker); } public static void Postfix(StatueBoss __instance) { ((Component)__instance).GetComponent<EnemyComponents>().CallPostUnEnrage(_cancellationTracker); } } [HarmonyPatch(typeof(SwordsMachine), "Enrage")] internal static class SwordsMachineEnragePatch { private static EventMethodCancellationTracker _cancellationTracker = new EventMethodCancellationTracker(); public static void Prefix(SwordsMachine __instance) { ((Component)__instance).GetComponent<EnemyComponents>().CallPreEnrage(_cancellationTracker); } public static void Postfix(SwordsMachine __instance) { ((Component)__instance).GetComponent<EnemyComponents>().CallPostEnrage(_cancellationTracker); } } [HarmonyPatch(typeof(SwordsMachine), "UnEnrage")] internal static class SwordsMachineUnEnragePatch { private static EventMethodCancellationTracker _cancellationTracker = new EventMethodCancellationTracker(); public static void Prefix(SwordsMachine __instance) { ((Component)__instance).GetComponent<EnemyComponents>().CallPreUnEnrage(_cancellationTracker); } public static void Postfix(SwordsMachine __instance) { ((Component)__instance).GetComponent<EnemyComponents>().CallPostUnEnrage(_cancellationTracker); } } [HarmonyPatch(typeof(Drone), "Enrage")] internal static class DroneEnragePatch { private static EventMethodCancellationTracker _cancellationTracker = new EventMethodCancellationTracker(); public static void Prefix(Drone __instance) { ((Component)__instance).GetComponent<EnemyComponents>().CallPreEnrage(_cancellationTracker); } public static void Postfix(Drone __instance) { ((Component)__instance).GetComponent<EnemyComponents>().CallPostEnrage(_cancellationTracker); } } [HarmonyPatch(typeof(Drone), "UnEnrage")] internal static class DroneUnEnragePatch { private static EventMethodCancellationTracker _cancellationTracker = new EventMethodCancellationTracker(); public static void Prefix(Drone __instance) { ((Component)__instance).GetComponent<EnemyComponents>().CallPreUnEnrage(_cancellationTracker); } public static void Postfix(Drone __instance) { ((Component)__instance).GetComponent<EnemyComponents>().CallPostUnEnrage(_cancellationTracker); } } [HarmonyPatch(typeof(V2), "Enrage", new Type[] { typeof(string) })] internal static class V2EnragePatch { private static EventMethodCancellationTracker _cancellationTracker = new EventMethodCancellationTracker(); public static void Prefix(V2 __instance) { ((Component)__instance).GetComponent<EnemyComponents>().CallPreEnrage(_cancellationTracker); } public static void Postfix(V2 __instance) { ((Component)__instance).GetComponent<EnemyComponents>().CallPostEnrage(_cancellationTracker); } } [HarmonyPatch(typeof(V2), "UnEnrage")] internal static class V2UnEnragePatch { private static EventMethodCancellationTracker _cancellationTracker = new EventMethodCancellationTracker(); public static void Prefix(V2 __instance) { ((Component)__instance).GetComponent<EnemyComponents>().CallPreUnEnrage(_cancellationTracker); } public static void Postfix(V2 __instance) { ((Component)__instance).GetComponent<EnemyComponents>().CallPostUnEnrage(_cancellationTracker); } } [HarmonyPatch(typeof(Mindflayer), "Enrage")] internal static class MindflayerEnragePatch { private static EventMethodCancellationTracker _cancellationTracker = new EventMethodCancellationTracker(); public static void Prefix(Mindflayer __instance) { ((Component)__instance).GetComponent<EnemyComponents>().CallPreEnrage(_cancellationTracker); } public static void Postfix(Mindflayer __instance) { ((Component)__instance).GetComponent<EnemyComponents>().CallPostEnrage(_cancellationTracker); } } [HarmonyPatch(typeof(Mindflayer), "UnEnrage")] internal static class MindflayerUnEnragePatch { private static EventMethodCancellationTracker _cancellationTracker = new EventMethodCancellationTracker(); public static void Prefix(Mindflayer __instance) { ((Component)__instance).GetComponent<EnemyComponents>().CallPreUnEnrage(_cancellationTracker); } public static void Postfix(Mindflayer __instance) { ((Component)__instance).GetComponent<EnemyComponents>().CallPostUnEnrage(_cancellationTracker); } } [HarmonyPatch(typeof(SpiderBody), "Enrage")] internal static class SpiderBodyEnragePatch { private static EventMethodCancellationTracker _cancellationTracker = new EventMethodCancellationTracker(); public static void Prefix(SpiderBody __instance) { ((Component)__instance).GetComponent<EnemyComponents>().CallPreEnrage(_cancellationTracker); } public static void Postfix(SpiderBody __instance) { ((Component)__instance).GetComponent<EnemyComponents>().CallPostEnrage(_cancellationTracker); } } [HarmonyPatch(typeof(SpiderBody), "UnEnrage")] internal static class SpiderBodyUnEnragePatch { private static EventMethodCancellationTracker _cancellationTracker = new EventMethodCancellationTracker(); public static void Prefix(SpiderBody __instance) { ((Component)__instance).GetComponent<EnemyComponents>().CallPreUnEnrage(_cancellationTracker); } public static void Postfix(SpiderBody __instanc