Decompiled source of More Afflictions v1.0.1
BepInEx/plugins/MoreAfflictions.dll
Decompiled a year 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 year 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) { } } } }