The BepInEx console will not appear when launching like it does for other games on Thunderstore (you can turn it back on in your BepInEx.cfg file). If your PEAK crashes on startup, add -dx12 to your launch parameters.
Decompiled source of More Afflictions v1.0.1
BepInEx/plugins/MoreAfflictions.dll
Decompiled a week agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using HarmonyLib; using MoreAfflictionsPlugin.APIs; using UnityEngine; 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(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("MoreAfflictions")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+870be8ef85b9f6f98f4c54cc1df5fe45959856fc")] [assembly: AssemblyProduct("MoreAfflictions")] [assembly: AssemblyTitle("MoreAfflictions")] [assembly: AssemblyVersion("1.0.0.0")] public class BarAfflictionCustom : MonoBehaviour { [Header("Required")] public RectTransform rtf; [Header("Status Identity")] public string statusName; public int statusIndex = -1; [Header("Runtime")] public float size; private Image _iconImg; public float width { get { //IL_001a: Unknown result type (might be due to invalid IL or missing references) return Object.op_Implicit((Object)(object)rtf) ? rtf.sizeDelta.x : 0f; } set { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)rtf)) { rtf.sizeDelta = new Vector2(value, rtf.sizeDelta.y); } } } public void TryApplyIconOnce() { //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Invalid comparison between Unknown and I4 if (string.IsNullOrWhiteSpace(statusName)) { return; } if ((Object)(object)_iconImg == (Object)null) { Image[] componentsInChildren = ((Component)this).GetComponentsInChildren<Image>(true); foreach (Image val in componentsInChildren) { if (Object.op_Implicit((Object)(object)val)) { string text = (Object.op_Implicit((Object)(object)((Component)val).gameObject) ? ((Object)((Component)val).gameObject).name : null); if (!string.IsNullOrEmpty(text) && text.IndexOf("icon", StringComparison.OrdinalIgnoreCase) >= 0) { _iconImg = val; break; } } } if ((Object)(object)_iconImg == (Object)null) { Image[] componentsInChildren2 = ((Component)this).GetComponentsInChildren<Image>(true); foreach (Image val2 in componentsInChildren2) { if (Object.op_Implicit((Object)(object)val2) && (int)val2.type == 0) { _iconImg = val2; break; } } } } if (Object.op_Implicit((Object)(object)_iconImg)) { Sprite statusIcon = AfflictionsAPI.GetStatusIcon(statusName); if ((Object)(object)statusIcon != (Object)null) { _iconImg.sprite = statusIcon; _iconImg.preserveAspect = true; ((Behaviour)_iconImg).enabled = true; } } } } [HarmonyPatch] internal static class BarAfflictionDrivePatches { [HarmonyPostfix] [HarmonyPatch(typeof(BarAffliction), "ChangeAffliction")] private static void ChangeAffliction_Postfix(BarAffliction __instance, StaminaBar bar) { //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)__instance) || !Object.op_Implicit((Object)(object)bar)) { return; } BarAfflictionCustom component = ((Component)__instance).GetComponent<BarAfflictionCustom>(); if (!Object.op_Implicit((Object)(object)component)) { return; } Character observedCharacter = Character.observedCharacter; CharacterAfflictions val = ((!Object.op_Implicit((Object)(object)observedCharacter)) ? null : observedCharacter.refs?.afflictions); if (!((Object)(object)val == (Object)null)) { RectTransform fullBar = bar.fullBar; float minAfflictionWidth = bar.minAfflictionWidth; float status = val.GetStatus(component.statusName); component.size = (Object.op_Implicit((Object)(object)fullBar) ? fullBar.sizeDelta.x : 0f) * Mathf.Clamp01(status); bool flag = status > 0.01f; if (flag && component.size < minAfflictionWidth) { component.size = minAfflictionWidth; } GameObject gameObject = ((Component)component).gameObject; if (gameObject.activeSelf != flag) { gameObject.SetActive(flag); } if (Object.op_Implicit((Object)(object)component.rtf)) { component.rtf.sizeDelta = new Vector2(component.size, component.rtf.sizeDelta.y); } component.TryApplyIconOnce(); } } [HarmonyPostfix] [HarmonyPatch(typeof(BarAffliction), "UpdateAffliction")] private static void UpdateAffliction_Postfix(BarAffliction __instance, StaminaBar bar) { //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)__instance) && Object.op_Implicit((Object)(object)bar)) { BarAfflictionCustom component = ((Component)__instance).GetComponent<BarAfflictionCustom>(); if (Object.op_Implicit((Object)(object)component) && Object.op_Implicit((Object)(object)component.rtf)) { float num = Mathf.Min(Time.deltaTime * 10f, 0.12f); float num2 = Mathf.Lerp(component.rtf.sizeDelta.x, component.size, num); component.rtf.sizeDelta = new Vector2(num2, component.rtf.sizeDelta.y); } } } } namespace MoreAfflictionsPlugin { [BepInPlugin("com.khakixd.moreafflictions", "More Afflictions", "0.4.2")] public sealed class MoreAfflictionsPlugin : BaseUnityPlugin { public const string PluginGuid = "com.khakixd.moreafflictions"; public const string PluginName = "More Afflictions"; public const string PluginVersion = "0.4.2"; private Harmony _harmony; private void Awake() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown _harmony = new Harmony("com.khakixd.moreafflictions"); _harmony.PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"[MoreAfflictions] Awake: Harmony patches applied."); EnsureTestStatus(); List<string> registeredCustomNames = AfflictionsAPI.GetRegisteredCustomNames(); } private void OnDestroy() { try { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } catch { } } private static void EnsureTestStatus() { if (!AfflictionsAPI.TryGetIndex("ThirstTest", out var _)) { int num = AfflictionsAPI.RegisterStatus("ThirstTest", 1f, null, null); } } private static void DumpRegistry(string where) { List<string> registeredCustomNames = AfflictionsAPI.GetRegisteredCustomNames(); Debug.Log((object)string.Format("[MoreAfflictions] Registry dump ({0}): count={1} [{2}]", where, registeredCustomNames.Count, string.Join(", ", registeredCustomNames))); foreach (string item in registeredCustomNames) { if (AfflictionsAPI.TryGetIndex(item, out var index)) { Debug.Log((object)$"[MoreAfflictions] Name→Index: {item} => {index}"); } else { Debug.LogWarning((object)("[MoreAfflictions] Name→Index FAILED: " + item)); } } } } [HarmonyPatch(typeof(StaminaBar))] internal static class StaminaBar_CustomAfflictions { private static readonly FieldInfo F_BarAffliction_Type = AccessTools.Field(typeof(BarAffliction), "type"); [HarmonyPostfix] [HarmonyPatch("Start")] private static void Start_Post(StaminaBar __instance) { Debug.Log((object)"[MoreAfflictions] StaminaBar.Start → bootstrap custom bars"); SafePrune(__instance); EnsureCustomAfflictionsPresent(__instance); RefreshCache(__instance); DumpAfflictions(__instance, "Start_Post"); } [HarmonyPrefix] [HarmonyPatch("ChangeBar")] private static void ChangeBar_Pre(StaminaBar __instance) { SafePrune(__instance); EnsureCustomAfflictionsPresent(__instance); RefreshCache(__instance); } [HarmonyPrefix] [HarmonyPatch("Update")] private static void Update_Pre(StaminaBar __instance) { SafePrune(__instance); if ((Time.frameCount & 0x3F) == 0) { DumpAfflictions(__instance, "Update_Pre"); } } private static void SafePrune(StaminaBar bar) { if (Object.op_Implicit((Object)(object)bar)) { BarAffliction[] array = bar.afflictions ?? Array.Empty<BarAffliction>(); BarAffliction[] array2 = array.Where((BarAffliction a) => Object.op_Implicit((Object)(object)a) && !((object)a).Equals((object?)null)).ToArray(); if (array != array2) { bar.afflictions = array2; } } } private static void RefreshCache(StaminaBar bar) { if (Object.op_Implicit((Object)(object)bar)) { BarAffliction[] componentsInChildren = ((Component)bar).GetComponentsInChildren<BarAffliction>(true); if (componentsInChildren != bar.afflictions) { bar.afflictions = componentsInChildren; } } } private static BarAffliction PickTemplate(StaminaBar bar) { if (!Object.op_Implicit((Object)(object)bar)) { return null; } BarAffliction val = null; if (bar.afflictions != null && bar.afflictions.Length != 0) { val = ((IEnumerable<BarAffliction>)bar.afflictions).FirstOrDefault((Func<BarAffliction, bool>)((BarAffliction a) => Object.op_Implicit((Object)(object)a) && !((object)a).Equals((object?)null))); } if (!Object.op_Implicit((Object)(object)val)) { val = ((Component)bar).GetComponentInChildren<BarAffliction>(true); } return val; } private static void EnsureCustomAfflictionsPresent(StaminaBar bar) { if (!Object.op_Implicit((Object)(object)bar)) { return; } BarAffliction val = PickTemplate(bar); if (!Object.op_Implicit((Object)(object)val)) { return; } List<string> registeredCustomNames = AfflictionsAPI.GetRegisteredCustomNames(); if (registeredCustomNames == null || registeredCustomNames.Count == 0) { Debug.Log((object)"[MoreAfflictions] No custom statuses registered yet."); return; } int num = 0; int num2 = 0; int num3 = 0; foreach (string item in registeredCustomNames) { if (!AfflictionsAPI.TryGetIndex(item, out var index) || index < 0) { Debug.LogWarning((object)("[MoreAfflictions] '" + item + "' has no valid index (TryGetIndex failed).")); num3++; } else if (HasEntryFor(bar, index)) { num2++; } else { CreateClone(bar, val, item, index); num++; } } } private static bool HasEntryFor(StaminaBar bar, int statusIndex) { //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Invalid comparison between Unknown and I4 BarAffliction[] componentsInChildren = ((Component)bar).GetComponentsInChildren<BarAffliction>(true); BarAffliction[] array = componentsInChildren; foreach (BarAffliction val in array) { if (!Object.op_Implicit((Object)(object)val)) { continue; } BarAfflictionCustom component = ((Component)val).GetComponent<BarAfflictionCustom>(); if (Object.op_Implicit((Object)(object)component) && component.statusIndex == statusIndex) { return true; } if (!(F_BarAffliction_Type != null)) { continue; } try { STATUSTYPE val2 = (STATUSTYPE)F_BarAffliction_Type.GetValue(val); if ((int)val2 == statusIndex) { return true; } } catch { } } return false; } private static void CreateClone(StaminaBar bar, BarAffliction template, string statusName, int statusIndex) { //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: 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) try { Transform parent = ((Component)template).transform.parent; GameObject val = Object.Instantiate<GameObject>(((Component)template).gameObject, parent, false); ((Object)val).name = "Affliction_Custom_" + statusName; val.transform.SetSiblingIndex(((Component)template).transform.GetSiblingIndex() + 1); BarAffliction component = val.GetComponent<BarAffliction>(); if (Object.op_Implicit((Object)(object)component) && F_BarAffliction_Type != null) { F_BarAffliction_Type.SetValue(component, (object)(STATUSTYPE)statusIndex); } BarAfflictionCustom barAfflictionCustom = val.GetComponent<BarAfflictionCustom>(); if (!Object.op_Implicit((Object)(object)barAfflictionCustom)) { barAfflictionCustom = val.AddComponent<BarAfflictionCustom>(); } barAfflictionCustom.statusName = statusName; barAfflictionCustom.statusIndex = statusIndex; barAfflictionCustom.rtf = val.GetComponent<RectTransform>(); barAfflictionCustom.TryApplyIconOnce(); Color deterministicColor = GetDeterministicColor(statusName); ApplyColorToHierarchy(val.transform, deterministicColor); val.SetActive(false); } catch (Exception arg) { Debug.LogError((object)$"[MoreAfflictions] CreateClone failed for '{statusName}': {arg}"); } } private static Color GetDeterministicColor(string input) { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) int num = 23; foreach (char c in input) { num = num * 31 + c; } float num2 = (float)(num & 0xFFFFFF) / 16777215f; float num3 = 0.8f; float num4 = 0.9f; return Color.HSVToRGB(num2, num3, num4); } private static void ApplyColorToHierarchy(Transform root, Color rgbColor) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003c: 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) Image[] componentsInChildren = ((Component)root).GetComponentsInChildren<Image>(true); Color color = default(Color); foreach (Image val in componentsInChildren) { if (!((Object)(object)val == (Object)null)) { float a = ((Graphic)val).color.a; ((Color)(ref color))..ctor(rgbColor.r, rgbColor.g, rgbColor.b, a); ((Graphic)val).color = color; } } } private static void DumpAfflictions(StaminaBar bar, string where) { if (!Object.op_Implicit((Object)(object)bar)) { return; } try { BarAffliction[] componentsInChildren = ((Component)bar).GetComponentsInChildren<BarAffliction>(true); int num = componentsInChildren.Length; int num2 = 0; BarAffliction[] array = componentsInChildren; foreach (BarAffliction val in array) { if (Object.op_Implicit((Object)(object)val)) { BarAfflictionCustom component = ((Component)val).GetComponent<BarAfflictionCustom>(); if (Object.op_Implicit((Object)(object)component)) { num2++; } } } } catch (Exception) { } } } } namespace MoreAfflictionsPlugin.APIs { public static class AfflictionsAPI { private class CustomStatus { public string Name; public int Index; public float Cap; public Action<CharacterAfflictions, float> OnAdded; } private static readonly object _lockObj = new object(); private static readonly List<CustomStatus> _customs = new List<CustomStatus>(); private static readonly Dictionary<string, int> _nameToIndex = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase); private static readonly Dictionary<string, Sprite> _nameToIcon = new Dictionary<string, Sprite>(StringComparer.OrdinalIgnoreCase); private static int _cachedBaseCount = -1; private static int BaseCount { get { if (_cachedBaseCount < 0) { _cachedBaseCount = Enum.GetNames(typeof(STATUSTYPE)).Length; } return _cachedBaseCount; } } internal static int TotalCount { get { lock (_lockObj) { return BaseCount + _customs.Count; } } } public static int RegisterStatus(string name, float cap, Action<CharacterAfflictions, float> onAdded, Sprite icon) { if (string.IsNullOrEmpty(name)) { throw new ArgumentException("name"); } lock (_lockObj) { if (_nameToIndex.TryGetValue(name, out var value)) { if ((Object)(object)icon != (Object)null) { _nameToIcon[name] = icon; } return value; } value = BaseCount + _customs.Count; CustomStatus item = new CustomStatus { Name = name, Index = value, Cap = Mathf.Max(0f, cap), OnAdded = onAdded }; _customs.Add(item); _nameToIndex[name] = value; if ((Object)(object)icon != (Object)null) { _nameToIcon[name] = icon; } return value; } } public static void SetStatusIcon(string name, Sprite icon) { if (string.IsNullOrEmpty(name)) { return; } lock (_lockObj) { _nameToIcon[name] = icon; } } public static int RegisterStatus(string name, float cap, Action<CharacterAfflictions, float> onAdded) { return RegisterStatus(name, cap, onAdded, null); } public static bool TryGetIndex(string name, out int index) { if (string.IsNullOrEmpty(name)) { index = -1; return false; } lock (_lockObj) { if (_nameToIndex.TryGetValue(name, out index)) { return true; } } string[] names = Enum.GetNames(typeof(STATUSTYPE)); for (int i = 0; i < names.Length; i++) { if (string.Equals(names[i], name, StringComparison.OrdinalIgnoreCase)) { index = i; return true; } } index = -1; return false; } internal static float GetCapOr(float fallback, int index) { if (index < BaseCount) { return fallback; } return GetCustomByIndex(index)?.Cap ?? fallback; } internal static void InvokeOnAdded(CharacterAfflictions ca, int index, float amount) { CustomStatus customByIndex = GetCustomByIndex(index); if (customByIndex != null && customByIndex.OnAdded != null) { customByIndex.OnAdded(ca, amount); } } public static List<string> GetRegisteredCustomNames() { lock (_lockObj) { List<string> list = new List<string>(_customs.Count); for (int i = 0; i < _customs.Count; i++) { list.Add(_customs[i].Name); } return list; } } public static Sprite GetStatusIcon(string name) { if (string.IsNullOrEmpty(name)) { return null; } lock (_lockObj) { Sprite value; return _nameToIcon.TryGetValue(name, out value) ? value : null; } } public static bool TryGetCustomIcon(string name, out Sprite sprite) { lock (_lockObj) { return _nameToIcon.TryGetValue(name, out sprite); } } public static float GetStatus(this CharacterAfflictions ca, string name) { int index; return TryGetIndex(name, out index) ? ca.GetCurrentStatus((STATUSTYPE)index) : 0f; } public static void SetStatus(this CharacterAfflictions ca, string name, float value) { if (TryGetIndex(name, out var index)) { ca.SetStatus((STATUSTYPE)index, value); } } public static bool AddStatus(this CharacterAfflictions ca, string name, float amount) { int index; return TryGetIndex(name, out index) && ca.AddStatus((STATUSTYPE)index, amount, false); } public static void SubtractStatus(this CharacterAfflictions ca, string name, float amount) { if (TryGetIndex(name, out var index)) { ca.SubtractStatus((STATUSTYPE)index, amount, false); } } private static CustomStatus GetCustomByIndex(int index) { int num = index - BaseCount; if (num < 0) { return null; } lock (_lockObj) { return (num >= 0 && num < _customs.Count) ? _customs[num] : null; } } } [HarmonyPatch] internal static class CharacterAfflictionsPatches { private static readonly FieldInfo F_Current = AccessTools.Field(typeof(CharacterAfflictions), "currentStatuses"); private static readonly FieldInfo F_Inc = AccessTools.Field(typeof(CharacterAfflictions), "currentIncrementalStatuses"); private static readonly FieldInfo F_Dec = AccessTools.Field(typeof(CharacterAfflictions), "currentDecrementalStatuses"); private static readonly FieldInfo F_Last = AccessTools.Field(typeof(CharacterAfflictions), "lastAddedStatus"); private static readonly FieldInfo F_LastInc = AccessTools.Field(typeof(CharacterAfflictions), "lastAddedIncrementalStatus"); [HarmonyPostfix] [HarmonyPatch(typeof(CharacterAfflictions), "InitStatusArrays")] private static void InitStatusArrays_Postfix(CharacterAfflictions __instance) { try { int totalCount = AfflictionsAPI.TotalCount; float[] array = (float[])F_Current.GetValue(__instance); if (array == null || array.Length < totalCount) { float[] array2 = (float[])F_Inc.GetValue(__instance); float[] array3 = (float[])F_Dec.GetValue(__instance); float[] array4 = (float[])F_Last.GetValue(__instance); float[] array5 = (float[])F_LastInc.GetValue(__instance); float[] array6 = new float[totalCount]; if (array != null) { Array.Copy(array, array6, array.Length); } float[] array7 = new float[totalCount]; if (array2 != null) { Array.Copy(array2, array7, array2.Length); } float[] array8 = new float[totalCount]; if (array3 != null) { Array.Copy(array3, array8, array3.Length); } float[] array9 = new float[totalCount]; if (array4 != null) { Array.Copy(array4, array9, array4.Length); } float[] array10 = new float[totalCount]; if (array5 != null) { Array.Copy(array5, array10, array5.Length); } F_Current.SetValue(__instance, array6); F_Inc.SetValue(__instance, array7); F_Dec.SetValue(__instance, array8); F_Last.SetValue(__instance, array9); F_LastInc.SetValue(__instance, array10); } } catch (Exception) { } } [HarmonyPostfix] [HarmonyPatch(typeof(CharacterAfflictions), "GetStatusCap")] private static void GetStatusCap_Postfix(ref float __result, STATUSTYPE type) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected I4, but got Unknown try { __result = AfflictionsAPI.GetCapOr(__result, (int)type); } catch (Exception) { } } [HarmonyPostfix] [HarmonyPatch(typeof(CharacterAfflictions), "AddStatus")] private static void AddStatus_Postfix(CharacterAfflictions __instance, STATUSTYPE statusType, float amount, bool fromRPC) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Expected I4, but got Unknown try { AfflictionsAPI.InvokeOnAdded(__instance, (int)statusType, amount); } catch (Exception) { } } } }
plugins/MoreAfflictions.dll
Decompiled a week agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using HarmonyLib; using MoreAfflictionsPlugin.APIs; using UnityEngine; 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(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("MoreAfflictions")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+870be8ef85b9f6f98f4c54cc1df5fe45959856fc")] [assembly: AssemblyProduct("MoreAfflictions")] [assembly: AssemblyTitle("MoreAfflictions")] [assembly: AssemblyVersion("1.0.0.0")] public class BarAfflictionCustom : MonoBehaviour { [Header("Required")] public RectTransform rtf; [Header("Status Identity")] public string statusName; public int statusIndex = -1; [Header("Runtime")] public float size; private Image _iconImg; public float width { get { //IL_001a: Unknown result type (might be due to invalid IL or missing references) return Object.op_Implicit((Object)(object)rtf) ? rtf.sizeDelta.x : 0f; } set { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)rtf)) { rtf.sizeDelta = new Vector2(value, rtf.sizeDelta.y); } } } public void TryApplyIconOnce() { //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Invalid comparison between Unknown and I4 if (string.IsNullOrWhiteSpace(statusName)) { return; } if ((Object)(object)_iconImg == (Object)null) { Image[] componentsInChildren = ((Component)this).GetComponentsInChildren<Image>(true); foreach (Image val in componentsInChildren) { if (Object.op_Implicit((Object)(object)val)) { string text = (Object.op_Implicit((Object)(object)((Component)val).gameObject) ? ((Object)((Component)val).gameObject).name : null); if (!string.IsNullOrEmpty(text) && text.IndexOf("icon", StringComparison.OrdinalIgnoreCase) >= 0) { _iconImg = val; break; } } } if ((Object)(object)_iconImg == (Object)null) { Image[] componentsInChildren2 = ((Component)this).GetComponentsInChildren<Image>(true); foreach (Image val2 in componentsInChildren2) { if (Object.op_Implicit((Object)(object)val2) && (int)val2.type == 0) { _iconImg = val2; break; } } } } if (Object.op_Implicit((Object)(object)_iconImg)) { Sprite statusIcon = AfflictionsAPI.GetStatusIcon(statusName); if ((Object)(object)statusIcon != (Object)null) { _iconImg.sprite = statusIcon; _iconImg.preserveAspect = true; ((Behaviour)_iconImg).enabled = true; } } } } [HarmonyPatch] internal static class BarAfflictionDrivePatches { [HarmonyPostfix] [HarmonyPatch(typeof(BarAffliction), "ChangeAffliction")] private static void ChangeAffliction_Postfix(BarAffliction __instance, StaminaBar bar) { //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)__instance) || !Object.op_Implicit((Object)(object)bar)) { return; } BarAfflictionCustom component = ((Component)__instance).GetComponent<BarAfflictionCustom>(); if (!Object.op_Implicit((Object)(object)component)) { return; } Character observedCharacter = Character.observedCharacter; CharacterAfflictions val = ((!Object.op_Implicit((Object)(object)observedCharacter)) ? null : observedCharacter.refs?.afflictions); if (!((Object)(object)val == (Object)null)) { RectTransform fullBar = bar.fullBar; float minAfflictionWidth = bar.minAfflictionWidth; float status = val.GetStatus(component.statusName); component.size = (Object.op_Implicit((Object)(object)fullBar) ? fullBar.sizeDelta.x : 0f) * Mathf.Clamp01(status); bool flag = status > 0.01f; if (flag && component.size < minAfflictionWidth) { component.size = minAfflictionWidth; } GameObject gameObject = ((Component)component).gameObject; if (gameObject.activeSelf != flag) { gameObject.SetActive(flag); } if (Object.op_Implicit((Object)(object)component.rtf)) { component.rtf.sizeDelta = new Vector2(component.size, component.rtf.sizeDelta.y); } component.TryApplyIconOnce(); } } [HarmonyPostfix] [HarmonyPatch(typeof(BarAffliction), "UpdateAffliction")] private static void UpdateAffliction_Postfix(BarAffliction __instance, StaminaBar bar) { //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)__instance) && Object.op_Implicit((Object)(object)bar)) { BarAfflictionCustom component = ((Component)__instance).GetComponent<BarAfflictionCustom>(); if (Object.op_Implicit((Object)(object)component) && Object.op_Implicit((Object)(object)component.rtf)) { float num = Mathf.Min(Time.deltaTime * 10f, 0.12f); float num2 = Mathf.Lerp(component.rtf.sizeDelta.x, component.size, num); component.rtf.sizeDelta = new Vector2(num2, component.rtf.sizeDelta.y); } } } } namespace MoreAfflictionsPlugin { [BepInPlugin("com.khakixd.moreafflictions", "More Afflictions", "0.4.2")] public sealed class MoreAfflictionsPlugin : BaseUnityPlugin { public const string PluginGuid = "com.khakixd.moreafflictions"; public const string PluginName = "More Afflictions"; public const string PluginVersion = "0.4.2"; private Harmony _harmony; private void Awake() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown _harmony = new Harmony("com.khakixd.moreafflictions"); _harmony.PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"[MoreAfflictions] Awake: Harmony patches applied."); EnsureTestStatus(); List<string> registeredCustomNames = AfflictionsAPI.GetRegisteredCustomNames(); } private void OnDestroy() { try { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } catch { } } private static void EnsureTestStatus() { if (!AfflictionsAPI.TryGetIndex("ThirstTest", out var _)) { int num = AfflictionsAPI.RegisterStatus("ThirstTest", 1f, null, null); } } private static void DumpRegistry(string where) { List<string> registeredCustomNames = AfflictionsAPI.GetRegisteredCustomNames(); Debug.Log((object)string.Format("[MoreAfflictions] Registry dump ({0}): count={1} [{2}]", where, registeredCustomNames.Count, string.Join(", ", registeredCustomNames))); foreach (string item in registeredCustomNames) { if (AfflictionsAPI.TryGetIndex(item, out var index)) { Debug.Log((object)$"[MoreAfflictions] Name→Index: {item} => {index}"); } else { Debug.LogWarning((object)("[MoreAfflictions] Name→Index FAILED: " + item)); } } } } [HarmonyPatch(typeof(StaminaBar))] internal static class StaminaBar_CustomAfflictions { private static readonly FieldInfo F_BarAffliction_Type = AccessTools.Field(typeof(BarAffliction), "type"); [HarmonyPostfix] [HarmonyPatch("Start")] private static void Start_Post(StaminaBar __instance) { Debug.Log((object)"[MoreAfflictions] StaminaBar.Start → bootstrap custom bars"); SafePrune(__instance); EnsureCustomAfflictionsPresent(__instance); RefreshCache(__instance); DumpAfflictions(__instance, "Start_Post"); } [HarmonyPrefix] [HarmonyPatch("ChangeBar")] private static void ChangeBar_Pre(StaminaBar __instance) { SafePrune(__instance); EnsureCustomAfflictionsPresent(__instance); RefreshCache(__instance); } [HarmonyPrefix] [HarmonyPatch("Update")] private static void Update_Pre(StaminaBar __instance) { SafePrune(__instance); if ((Time.frameCount & 0x3F) == 0) { DumpAfflictions(__instance, "Update_Pre"); } } private static void SafePrune(StaminaBar bar) { if (Object.op_Implicit((Object)(object)bar)) { BarAffliction[] array = bar.afflictions ?? Array.Empty<BarAffliction>(); BarAffliction[] array2 = array.Where((BarAffliction a) => Object.op_Implicit((Object)(object)a) && !((object)a).Equals((object?)null)).ToArray(); if (array != array2) { bar.afflictions = array2; } } } private static void RefreshCache(StaminaBar bar) { if (Object.op_Implicit((Object)(object)bar)) { BarAffliction[] componentsInChildren = ((Component)bar).GetComponentsInChildren<BarAffliction>(true); if (componentsInChildren != bar.afflictions) { bar.afflictions = componentsInChildren; } } } private static BarAffliction PickTemplate(StaminaBar bar) { if (!Object.op_Implicit((Object)(object)bar)) { return null; } BarAffliction val = null; if (bar.afflictions != null && bar.afflictions.Length != 0) { val = ((IEnumerable<BarAffliction>)bar.afflictions).FirstOrDefault((Func<BarAffliction, bool>)((BarAffliction a) => Object.op_Implicit((Object)(object)a) && !((object)a).Equals((object?)null))); } if (!Object.op_Implicit((Object)(object)val)) { val = ((Component)bar).GetComponentInChildren<BarAffliction>(true); } return val; } private static void EnsureCustomAfflictionsPresent(StaminaBar bar) { if (!Object.op_Implicit((Object)(object)bar)) { return; } BarAffliction val = PickTemplate(bar); if (!Object.op_Implicit((Object)(object)val)) { return; } List<string> registeredCustomNames = AfflictionsAPI.GetRegisteredCustomNames(); if (registeredCustomNames == null || registeredCustomNames.Count == 0) { Debug.Log((object)"[MoreAfflictions] No custom statuses registered yet."); return; } int num = 0; int num2 = 0; int num3 = 0; foreach (string item in registeredCustomNames) { if (!AfflictionsAPI.TryGetIndex(item, out var index) || index < 0) { Debug.LogWarning((object)("[MoreAfflictions] '" + item + "' has no valid index (TryGetIndex failed).")); num3++; } else if (HasEntryFor(bar, index)) { num2++; } else { CreateClone(bar, val, item, index); num++; } } } private static bool HasEntryFor(StaminaBar bar, int statusIndex) { //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Invalid comparison between Unknown and I4 BarAffliction[] componentsInChildren = ((Component)bar).GetComponentsInChildren<BarAffliction>(true); BarAffliction[] array = componentsInChildren; foreach (BarAffliction val in array) { if (!Object.op_Implicit((Object)(object)val)) { continue; } BarAfflictionCustom component = ((Component)val).GetComponent<BarAfflictionCustom>(); if (Object.op_Implicit((Object)(object)component) && component.statusIndex == statusIndex) { return true; } if (!(F_BarAffliction_Type != null)) { continue; } try { STATUSTYPE val2 = (STATUSTYPE)F_BarAffliction_Type.GetValue(val); if ((int)val2 == statusIndex) { return true; } } catch { } } return false; } private static void CreateClone(StaminaBar bar, BarAffliction template, string statusName, int statusIndex) { //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: 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) try { Transform parent = ((Component)template).transform.parent; GameObject val = Object.Instantiate<GameObject>(((Component)template).gameObject, parent, false); ((Object)val).name = "Affliction_Custom_" + statusName; val.transform.SetSiblingIndex(((Component)template).transform.GetSiblingIndex() + 1); BarAffliction component = val.GetComponent<BarAffliction>(); if (Object.op_Implicit((Object)(object)component) && F_BarAffliction_Type != null) { F_BarAffliction_Type.SetValue(component, (object)(STATUSTYPE)statusIndex); } BarAfflictionCustom barAfflictionCustom = val.GetComponent<BarAfflictionCustom>(); if (!Object.op_Implicit((Object)(object)barAfflictionCustom)) { barAfflictionCustom = val.AddComponent<BarAfflictionCustom>(); } barAfflictionCustom.statusName = statusName; barAfflictionCustom.statusIndex = statusIndex; barAfflictionCustom.rtf = val.GetComponent<RectTransform>(); barAfflictionCustom.TryApplyIconOnce(); Color deterministicColor = GetDeterministicColor(statusName); ApplyColorToHierarchy(val.transform, deterministicColor); val.SetActive(false); } catch (Exception arg) { Debug.LogError((object)$"[MoreAfflictions] CreateClone failed for '{statusName}': {arg}"); } } private static Color GetDeterministicColor(string input) { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) int num = 23; foreach (char c in input) { num = num * 31 + c; } float num2 = (float)(num & 0xFFFFFF) / 16777215f; float num3 = 0.8f; float num4 = 0.9f; return Color.HSVToRGB(num2, num3, num4); } private static void ApplyColorToHierarchy(Transform root, Color rgbColor) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003c: 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) Image[] componentsInChildren = ((Component)root).GetComponentsInChildren<Image>(true); Color color = default(Color); foreach (Image val in componentsInChildren) { if (!((Object)(object)val == (Object)null)) { float a = ((Graphic)val).color.a; ((Color)(ref color))..ctor(rgbColor.r, rgbColor.g, rgbColor.b, a); ((Graphic)val).color = color; } } } private static void DumpAfflictions(StaminaBar bar, string where) { if (!Object.op_Implicit((Object)(object)bar)) { return; } try { BarAffliction[] componentsInChildren = ((Component)bar).GetComponentsInChildren<BarAffliction>(true); int num = componentsInChildren.Length; int num2 = 0; BarAffliction[] array = componentsInChildren; foreach (BarAffliction val in array) { if (Object.op_Implicit((Object)(object)val)) { BarAfflictionCustom component = ((Component)val).GetComponent<BarAfflictionCustom>(); if (Object.op_Implicit((Object)(object)component)) { num2++; } } } } catch (Exception) { } } } } namespace MoreAfflictionsPlugin.APIs { public static class AfflictionsAPI { private class CustomStatus { public string Name; public int Index; public float Cap; public Action<CharacterAfflictions, float> OnAdded; } private static readonly object _lockObj = new object(); private static readonly List<CustomStatus> _customs = new List<CustomStatus>(); private static readonly Dictionary<string, int> _nameToIndex = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase); private static readonly Dictionary<string, Sprite> _nameToIcon = new Dictionary<string, Sprite>(StringComparer.OrdinalIgnoreCase); private static int _cachedBaseCount = -1; private static int BaseCount { get { if (_cachedBaseCount < 0) { _cachedBaseCount = Enum.GetNames(typeof(STATUSTYPE)).Length; } return _cachedBaseCount; } } internal static int TotalCount { get { lock (_lockObj) { return BaseCount + _customs.Count; } } } public static int RegisterStatus(string name, float cap, Action<CharacterAfflictions, float> onAdded, Sprite icon) { if (string.IsNullOrEmpty(name)) { throw new ArgumentException("name"); } lock (_lockObj) { if (_nameToIndex.TryGetValue(name, out var value)) { if ((Object)(object)icon != (Object)null) { _nameToIcon[name] = icon; } return value; } value = BaseCount + _customs.Count; CustomStatus item = new CustomStatus { Name = name, Index = value, Cap = Mathf.Max(0f, cap), OnAdded = onAdded }; _customs.Add(item); _nameToIndex[name] = value; if ((Object)(object)icon != (Object)null) { _nameToIcon[name] = icon; } return value; } } public static void SetStatusIcon(string name, Sprite icon) { if (string.IsNullOrEmpty(name)) { return; } lock (_lockObj) { _nameToIcon[name] = icon; } } public static int RegisterStatus(string name, float cap, Action<CharacterAfflictions, float> onAdded) { return RegisterStatus(name, cap, onAdded, null); } public static bool TryGetIndex(string name, out int index) { if (string.IsNullOrEmpty(name)) { index = -1; return false; } lock (_lockObj) { if (_nameToIndex.TryGetValue(name, out index)) { return true; } } string[] names = Enum.GetNames(typeof(STATUSTYPE)); for (int i = 0; i < names.Length; i++) { if (string.Equals(names[i], name, StringComparison.OrdinalIgnoreCase)) { index = i; return true; } } index = -1; return false; } internal static float GetCapOr(float fallback, int index) { if (index < BaseCount) { return fallback; } return GetCustomByIndex(index)?.Cap ?? fallback; } internal static void InvokeOnAdded(CharacterAfflictions ca, int index, float amount) { CustomStatus customByIndex = GetCustomByIndex(index); if (customByIndex != null && customByIndex.OnAdded != null) { customByIndex.OnAdded(ca, amount); } } public static List<string> GetRegisteredCustomNames() { lock (_lockObj) { List<string> list = new List<string>(_customs.Count); for (int i = 0; i < _customs.Count; i++) { list.Add(_customs[i].Name); } return list; } } public static Sprite GetStatusIcon(string name) { if (string.IsNullOrEmpty(name)) { return null; } lock (_lockObj) { Sprite value; return _nameToIcon.TryGetValue(name, out value) ? value : null; } } public static bool TryGetCustomIcon(string name, out Sprite sprite) { lock (_lockObj) { return _nameToIcon.TryGetValue(name, out sprite); } } public static float GetStatus(this CharacterAfflictions ca, string name) { int index; return TryGetIndex(name, out index) ? ca.GetCurrentStatus((STATUSTYPE)index) : 0f; } public static void SetStatus(this CharacterAfflictions ca, string name, float value) { if (TryGetIndex(name, out var index)) { ca.SetStatus((STATUSTYPE)index, value); } } public static bool AddStatus(this CharacterAfflictions ca, string name, float amount) { int index; return TryGetIndex(name, out index) && ca.AddStatus((STATUSTYPE)index, amount, false); } public static void SubtractStatus(this CharacterAfflictions ca, string name, float amount) { if (TryGetIndex(name, out var index)) { ca.SubtractStatus((STATUSTYPE)index, amount, false); } } private static CustomStatus GetCustomByIndex(int index) { int num = index - BaseCount; if (num < 0) { return null; } lock (_lockObj) { return (num >= 0 && num < _customs.Count) ? _customs[num] : null; } } } [HarmonyPatch] internal static class CharacterAfflictionsPatches { private static readonly FieldInfo F_Current = AccessTools.Field(typeof(CharacterAfflictions), "currentStatuses"); private static readonly FieldInfo F_Inc = AccessTools.Field(typeof(CharacterAfflictions), "currentIncrementalStatuses"); private static readonly FieldInfo F_Dec = AccessTools.Field(typeof(CharacterAfflictions), "currentDecrementalStatuses"); private static readonly FieldInfo F_Last = AccessTools.Field(typeof(CharacterAfflictions), "lastAddedStatus"); private static readonly FieldInfo F_LastInc = AccessTools.Field(typeof(CharacterAfflictions), "lastAddedIncrementalStatus"); [HarmonyPostfix] [HarmonyPatch(typeof(CharacterAfflictions), "InitStatusArrays")] private static void InitStatusArrays_Postfix(CharacterAfflictions __instance) { try { int totalCount = AfflictionsAPI.TotalCount; float[] array = (float[])F_Current.GetValue(__instance); if (array == null || array.Length < totalCount) { float[] array2 = (float[])F_Inc.GetValue(__instance); float[] array3 = (float[])F_Dec.GetValue(__instance); float[] array4 = (float[])F_Last.GetValue(__instance); float[] array5 = (float[])F_LastInc.GetValue(__instance); float[] array6 = new float[totalCount]; if (array != null) { Array.Copy(array, array6, array.Length); } float[] array7 = new float[totalCount]; if (array2 != null) { Array.Copy(array2, array7, array2.Length); } float[] array8 = new float[totalCount]; if (array3 != null) { Array.Copy(array3, array8, array3.Length); } float[] array9 = new float[totalCount]; if (array4 != null) { Array.Copy(array4, array9, array4.Length); } float[] array10 = new float[totalCount]; if (array5 != null) { Array.Copy(array5, array10, array5.Length); } F_Current.SetValue(__instance, array6); F_Inc.SetValue(__instance, array7); F_Dec.SetValue(__instance, array8); F_Last.SetValue(__instance, array9); F_LastInc.SetValue(__instance, array10); } } catch (Exception) { } } [HarmonyPostfix] [HarmonyPatch(typeof(CharacterAfflictions), "GetStatusCap")] private static void GetStatusCap_Postfix(ref float __result, STATUSTYPE type) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected I4, but got Unknown try { __result = AfflictionsAPI.GetCapOr(__result, (int)type); } catch (Exception) { } } [HarmonyPostfix] [HarmonyPatch(typeof(CharacterAfflictions), "AddStatus")] private static void AddStatus_Postfix(CharacterAfflictions __instance, STATUSTYPE statusType, float amount, bool fromRPC) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Expected I4, but got Unknown try { AfflictionsAPI.InvokeOnAdded(__instance, (int)statusType, amount); } catch (Exception) { } } } }