Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of BrackenAngerMeter v1.0.2
BrackenAngerMeter.dll
Decompiled 3 days agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using GameNetcodeStuff; using HarmonyLib; using TMPro; using Unity.Netcode; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; 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: AssemblyTitle("BrackenAngerMeter")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("BrackenAngerMeter")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("a5e42522-7099-4e31-a6a9-8f83387caecc")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("1.0.0.0")] namespace BrackenAngerMeter; [BepInPlugin("azumi.brackenangermeter", "BrackenAngerMeter", "1.0.2")] public class Plugin : BaseUnityPlugin { public static ConfigEntry<bool> ShowMeter; public static ConfigEntry<bool> ShowInfoText; public static ConfigEntry<Key> NextBrackenKey; public static ConfigEntry<Key> PrevBrackenKey; public static ConfigEntry<bool> EnableInitialAnger; public static ConfigEntry<float> InitialAngerMeterValue; internal static Plugin Instance; internal static ManualLogSource Log; private Harmony harmony; private void Awake() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; harmony = new Harmony("azumi.brackenangermeter"); harmony.PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"BrackenAngerMeter loaded."); ShowMeter = ((BaseUnityPlugin)this).Config.Bind<bool>("UI", "Show Meter", true, "Show anger meter."); ShowInfoText = ((BaseUnityPlugin)this).Config.Bind<bool>("UI", "Show Info Text", true, "Show detailed information text."); NextBrackenKey = ((BaseUnityPlugin)this).Config.Bind<Key>("Controls", "Next Bracken Key", (Key)67, "Switch to next Bracken."); PrevBrackenKey = ((BaseUnityPlugin)this).Config.Bind<Key>("Controls", "Prev Bracken Key", (Key)66, "Switch to previous Bracken."); EnableInitialAnger = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enable Initial Anger", false, "Apply the Initial Anger Meter Value."); InitialAngerMeterValue = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Initial Anger Meter Value", 0f, new ConfigDescription("Bracken anger meter applied when Anger builds up or detected.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 12f), Array.Empty<object>())); } } [HarmonyPatch(typeof(StartOfRound))] internal class StartOfRoundPatch { private static GameObject meterObject; private static Image meterImage; private static TextMeshProUGUI infoText; private static GameObject backgroundmeterObject; private static Image backgroundmeterImage; private const float MaxAnger = 12f; private static readonly FieldInfo threatField = typeof(FlowermanAI).GetField("timesThreatened", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static Dictionary<ulong, FlowermanAI> trackedBrackens = new Dictionary<ulong, FlowermanAI>(); private static ulong? currentTargetId = null; private static Dictionary<ulong, int> lastThreats = new Dictionary<ulong, int>(); private static HashSet<ulong> initializedBrackens = new HashSet<ulong>(); private static List<ulong> aliveBrackenIds = new List<ulong>(); private static int currentIndex = 0; [HarmonyPatch("LateUpdate")] [HarmonyPostfix] private static void LateUpdatePostfix(StartOfRound __instance) { //IL_0297: Unknown result type (might be due to invalid IL or missing references) //IL_029c: Unknown result type (might be due to invalid IL or missing references) //IL_02a3: Unknown result type (might be due to invalid IL or missing references) //IL_02a8: Unknown result type (might be due to invalid IL or missing references) //IL_02aa: Unknown result type (might be due to invalid IL or missing references) //IL_02b3: Unknown result type (might be due to invalid IL or missing references) //IL_030f: Unknown result type (might be due to invalid IL or missing references) //IL_0318: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)__instance == (Object)null || (Object)(object)GameNetworkManager.Instance == (Object)null) { return; } PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController; if ((Object)(object)localPlayerController == (Object)null) { return; } CreateUI(localPlayerController); FlowermanAI[] source = Object.FindObjectsOfType<FlowermanAI>(); List<FlowermanAI> list = source.Where((FlowermanAI b) => (Object)(object)b != (Object)null && !((EnemyAI)b).isEnemyDead).ToList(); trackedBrackens.Clear(); foreach (FlowermanAI item in list) { if ((Object)(object)((EnemyAI)item).thisNetworkObject == (Object)null) { continue; } ulong networkObjectId = ((EnemyAI)item).thisNetworkObject.NetworkObjectId; trackedBrackens[networkObjectId] = item; if (initializedBrackens.Contains(networkObjectId) || !((Object)(object)NetworkManager.Singleton != (Object)null) || !NetworkManager.Singleton.IsHost) { continue; } if (Plugin.EnableInitialAnger.Value) { float num = (item.angerMeter = Mathf.Clamp(Plugin.InitialAngerMeterValue.Value, 0f, 12f)); if (threatField != null) { threatField.SetValue(item, Mathf.RoundToInt(num)); } Plugin.Log.LogInfo((object)$"Initialized Bracken {networkObjectId} anger={num}"); } initializedBrackens.Add(networkObjectId); } aliveBrackenIds = (from kv in trackedBrackens where (Object)(object)kv.Value != (Object)null && !((EnemyAI)kv.Value).isEnemyDead orderby kv.Key select kv.Key).ToList(); if (aliveBrackenIds.Count == 0) { currentIndex = 0; } else if (currentIndex >= aliveBrackenIds.Count) { currentIndex = 0; } if (Keyboard.current != null) { Key value = Plugin.NextBrackenKey.Value; Key value2 = Plugin.PrevBrackenKey.Value; if ((int)value != 0 && ((ButtonControl)Keyboard.current[value]).wasPressedThisFrame && aliveBrackenIds.Count > 0) { currentIndex = (currentIndex + 1) % aliveBrackenIds.Count; currentTargetId = aliveBrackenIds[currentIndex]; } if ((int)value2 != 0 && ((ButtonControl)Keyboard.current[value2]).wasPressedThisFrame && aliveBrackenIds.Count > 0) { currentIndex--; if (currentIndex < 0) { currentIndex = aliveBrackenIds.Count - 1; } currentTargetId = aliveBrackenIds[currentIndex]; } } if (list.Count == 0) { HideUI(); return; } List<ulong> list2 = (from kv in trackedBrackens where (Object)(object)kv.Value == (Object)null || ((EnemyAI)kv.Value).isEnemyDead select kv.Key).ToList(); foreach (ulong item2 in list2) { trackedBrackens.Remove(item2); initializedBrackens.Remove(item2); } FlowermanAI val = null; if (currentTargetId.HasValue && trackedBrackens.TryGetValue(currentTargetId.Value, out var value3)) { val = value3; } else { val = trackedBrackens.Values.OrderByDescending((FlowermanAI b) => b.angerMeter).FirstOrDefault(); if ((Object)(object)((EnemyAI)(val?)).thisNetworkObject != (Object)null) { currentTargetId = ((EnemyAI)val).thisNetworkObject.NetworkObjectId; currentIndex = aliveBrackenIds.IndexOf(currentTargetId.Value); if (currentIndex < 0) { currentIndex = 0; } } } if ((Object)(object)val == (Object)null) { HideUI(); return; } float angerMeter = val.angerMeter; int currentBehaviourStateIndex = ((EnemyAI)val).currentBehaviourStateIndex; if ((Object)(object)meterObject != (Object)null) { meterObject.SetActive(Plugin.ShowMeter.Value); } if ((Object)(object)backgroundmeterObject != (Object)null) { backgroundmeterObject.SetActive(Plugin.ShowMeter.Value); } if ((Object)(object)infoText != (Object)null) { ((Component)infoText).gameObject.SetActive(Plugin.ShowInfoText.Value); } if (Plugin.ShowMeter.Value) { UpdateMeter(angerMeter); } if (Plugin.ShowInfoText.Value) { UpdateText(val, angerMeter, currentBehaviourStateIndex); } } catch (Exception ex) { Plugin.Log.LogError((object)ex); } } private static void CreateUI(PlayerControllerB player) { //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Invalid comparison between Unknown and I4 //IL_01fd: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Invalid comparison between Unknown and I4 //IL_025f: Unknown result type (might be due to invalid IL or missing references) //IL_02e5: Unknown result type (might be due to invalid IL or missing references) //IL_02fc: Unknown result type (might be due to invalid IL or missing references) //IL_0313: Unknown result type (might be due to invalid IL or missing references) //IL_032a: Unknown result type (might be due to invalid IL or missing references) //IL_0376: Unknown result type (might be due to invalid IL or missing references) //IL_0380: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)meterObject != (Object)null && (Object)(object)backgroundmeterObject != (Object)null && (Object)(object)infoText != (Object)null) { return; } Image sprintMeterUI = player.sprintMeterUI; if ((Object)(object)sprintMeterUI == (Object)null) { return; } GameObject gameObject = ((Component)sprintMeterUI).gameObject; meterObject = Object.Instantiate<GameObject>(gameObject, gameObject.transform.parent); ((Object)meterObject).name = "BrackenAngerMeter"; backgroundmeterObject = Object.Instantiate<GameObject>(gameObject, gameObject.transform.parent); ((Object)backgroundmeterObject).name = "BrackenAngerMeterBackground"; backgroundmeterObject.transform.SetAsFirstSibling(); RectTransform component = gameObject.GetComponent<RectTransform>(); RectTransform component2 = meterObject.GetComponent<RectTransform>(); RectTransform component3 = backgroundmeterObject.GetComponent<RectTransform>(); component2.anchoredPosition = new Vector2(component.anchoredPosition.x + 3f, component.anchoredPosition.y - 4f); ((Transform)component2).localScale = ((Transform)component).localScale * 1.2f; component3.anchoredPosition = component2.anchoredPosition; ((Transform)component3).localScale = ((Transform)component2).localScale; Image[] componentsInChildren = meterObject.GetComponentsInChildren<Image>(true); Image[] array = componentsInChildren; foreach (Image val in array) { Plugin.Log.LogInfo((object)$"Image: {((Object)val).name} Type: {val.type}"); } Image[] array2 = componentsInChildren; foreach (Image val2 in array2) { if ((int)val2.type == 3) { meterImage = val2; Plugin.Log.LogInfo((object)("Bracken meter image found: " + ((Object)val2).name)); break; } } Image[] componentsInChildren2 = backgroundmeterObject.GetComponentsInChildren<Image>(true); Image[] array3 = componentsInChildren2; foreach (Image val3 in array3) { if ((int)val3.type == 3) { backgroundmeterImage = val3; break; } } if ((Object)(object)backgroundmeterImage != (Object)null) { backgroundmeterImage.fillAmount = 0.9101f; ((Graphic)backgroundmeterImage).color = new Color(0f, 0f, 0f, 0.35f); } if ((Object)(object)HUDManager.Instance != (Object)null && (Object)(object)HUDManager.Instance.weightCounter != (Object)null) { infoText = Object.Instantiate<TextMeshProUGUI>(HUDManager.Instance.weightCounter, ((TMP_Text)HUDManager.Instance.weightCounter).transform.parent); ((Object)infoText).name = "BrackenAngerText"; RectTransform component4 = ((Component)infoText).GetComponent<RectTransform>(); component4.anchorMin = new Vector2(0.5f, 1f); component4.anchorMax = new Vector2(0.5f, 1f); component4.pivot = new Vector2(0.5f, 1f); component4.anchoredPosition = new Vector2(40f, -120f); ((TMP_Text)infoText).fontSize = 12f; ((TMP_Text)infoText).alignment = (TextAlignmentOptions)513; ((TMP_Text)infoText).enableWordWrapping = false; ((TMP_Text)infoText).overflowMode = (TextOverflowModes)0; component4.sizeDelta = new Vector2(300f, component4.sizeDelta.y); } } private static void UpdateMeter(float anger) { //IL_004f: 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_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)meterImage == (Object)null)) { float num = Mathf.Clamp01(anger / 12f); meterImage.fillAmount = Mathf.Lerp(0.2976f, 0.9101f, num); if (anger < 2f) { ((Graphic)meterImage).color = Color.green; } else if (anger < 5f) { ((Graphic)meterImage).color = Color.yellow; } else if (anger < 8f) { ((Graphic)meterImage).color = new Color(1f, 0.5f, 0f); } else { ((Graphic)meterImage).color = Color.red; } } } private static void UpdateText(FlowermanAI bracken, float anger, int state) { //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) string text = "UNKNOWN"; string text2 = "NONE"; string text3 = "--"; int num = -1; if ((Object)(object)bracken != (Object)null && threatField != null) { num = (int)threatField.GetValue(bracken); } if (num < 0) { Plugin.Log.LogWarning((object)"Threat value not found!"); } if ((Object)(object)bracken != (Object)null && (Object)(object)((EnemyAI)bracken).thisNetworkObject != (Object)null) { ulong networkObjectId = ((EnemyAI)bracken).thisNetworkObject.NetworkObjectId; if (!lastThreats.ContainsKey(networkObjectId)) { lastThreats[networkObjectId] = num; } else { int num2 = lastThreats[networkObjectId]; if (num2 != num) { Plugin.Log.LogInfo((object)$"[Bracken {networkObjectId}] Threat changed: {num2} -> {num} | Anger: {anger:F2}"); lastThreats[networkObjectId] = num; } } } if ((Object)(object)bracken != (Object)null && (Object)(object)((EnemyAI)bracken).targetPlayer != (Object)null) { text2 = ((EnemyAI)bracken).targetPlayer.playerUsername; float num3 = Vector3.Distance(((Component)bracken).transform.position, ((Component)((EnemyAI)bracken).targetPlayer).transform.position); text3 = $"{num3:F1}m"; } if ((Object)(object)bracken != (Object)null && (Object)(object)((EnemyAI)bracken).thisNetworkObject != (Object)null) { text = $"BRACKEN #{((EnemyAI)bracken).thisNetworkObject.NetworkObjectId}"; } if (!((Object)(object)infoText == (Object)null)) { string text4 = state switch { 0 => "SNEAKING", 1 => "EVADING", 2 => "ANGRY", _ => "UNKNOWN", }; float num4 = Mathf.Clamp(0.09f * anger, 0f, 0.99f); int num5 = Mathf.RoundToInt(num4 * 100f); string text5 = ""; if (state == 2) { text5 = $"ANGER TIME LEFT: {anger:F1}s\n"; } float num6 = anger / 12f * 100f; float num7 = ((num >= 0) ? ((float)num / 1.75f) : 0f); ((TMP_Text)infoText).text = "DETAILED INFORMATION\n" + text + "\n" + $"ANGER: {anger:F2} / {12f:F0} ({num6:F1}%)\n" + $"ANGER CHANCE: {num5}%\n" + text5 + "STATE: " + text4 + "\n" + $"ANGER STACKS: {num}\n" + $"ANGER BONUS: +{num7:F2}\n" + "TARGET: " + text2 + "\nDISTANCE: " + text3 + "\n"; } } private static void HideUI() { //IL_008e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)meterObject != (Object)null) { meterObject.SetActive(false); } if ((Object)(object)backgroundmeterObject != (Object)null) { backgroundmeterObject.SetActive(false); } if ((Object)(object)infoText != (Object)null) { ((TMP_Text)infoText).text = ""; ((Component)infoText).gameObject.SetActive(false); } if ((Object)(object)meterImage != (Object)null) { meterImage.fillAmount = 0.2976f; ((Graphic)meterImage).color = Color.green; } } [HarmonyPatch("Start")] [HarmonyPostfix] private static void StartPostfix() { initializedBrackens.Clear(); } }