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 Enemy Indicators v1.0.0
EnemyIndicators.dll
Decompiled 10 months agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; 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(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("")] [assembly: AssemblyCompany("NoteBoxz")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("EnemyIndicators")] [assembly: AssemblyTitle("EnemyIndicators")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace EnemyIndicators { [BepInPlugin("NoteBoxz.EnemyIndicators", "EnemyIndicators", "1.0.0")] public class EnemyIndicators : BaseUnityPlugin { public IndicatorUI UIInstance = null; public GameObject indicatorSlotPrefab = null; public GameObject IndicatorHolderPrefab = null; public Sprite ClockSprite = null; public Sprite SkullSprite = null; public Sprite ActiveSprite = null; public Sprite ZzzSprite = null; internal static EnemyIndicators Instance { get; private set; } internal static ManualLogSource Logger => Instance._logger; private ManualLogSource _logger => ((BaseUnityPlugin)this).Logger; internal Harmony? Harmony { get; set; } internal static AssetBundle assetBundle { get; private set; } public ConfigEntry<bool> ShowRespawnTimers { get; private set; } = null; private void Awake() { Instance = this; ((Component)this).gameObject.transform.parent = null; ((Object)((Component)this).gameObject).hideFlags = (HideFlags)61; Patch(); LoadAssetBundle(); PreInitAssets(); BindConfigs(); Logger.LogInfo((object)$"{((BaseUnityPlugin)this).Info.Metadata.GUID} v{((BaseUnityPlugin)this).Info.Metadata.Version} has loaded!"); } private void PreInitAssets() { //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) IndicatorHolderPrefab = assetBundle.LoadAsset<GameObject>("Assets/EnemyIdicatorAssets/InidcatorContainer.prefab"); indicatorSlotPrefab = assetBundle.LoadAsset<GameObject>("Assets/EnemyIdicatorAssets/IndicatorSlot.prefab"); ClockSprite = assetBundle.LoadAsset<Sprite>("Assets/EnemyIdicatorAssets/clock.png"); SkullSprite = assetBundle.LoadAsset<Sprite>("Assets/EnemyIdicatorAssets/skull.png"); ActiveSprite = assetBundle.LoadAsset<Sprite>("Assets/EnemyIdicatorAssets/active.png"); ZzzSprite = assetBundle.LoadAsset<Sprite>("Assets/EnemyIdicatorAssets/zzz.png"); IndicatorUI indicatorUI = IndicatorHolderPrefab.GetComponent<IndicatorUI>(); if ((Object)(object)IndicatorHolderPrefab.GetComponent<IndicatorUI>() == (Object)null) { Logger.LogInfo((object)"Adding IndicatorUI component to IndicatorHolderPrefab."); indicatorUI = IndicatorHolderPrefab.AddComponent<IndicatorUI>(); } ((SemiUI)indicatorUI).showPosition = new Vector2(270f, 0f); ((SemiUI)indicatorUI).hidePosition = new Vector2(900f, 0f); if ((Object)(object)indicatorSlotPrefab.GetComponent<indicatorSlot>() == (Object)null) { Logger.LogInfo((object)"Adding indicatorSlot component to indicatorSlotPrefab."); indicatorSlotPrefab.AddComponent<indicatorSlot>(); } } internal static void LoadAssetBundle() { string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); if (directoryName == null) { throw new InvalidOperationException("Unable to determine assembly location."); } string text = Path.Combine(directoryName, "enemyindicatorassets"); assetBundle = AssetBundle.LoadFromFile(text); if ((Object)(object)assetBundle == (Object)null) { throw new InvalidOperationException("Failed to load AssetBundle."); } } private void BindConfigs() { ShowRespawnTimers = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Show Respawn Timers", true, "Show respawn timers for enemies."); } internal void Patch() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown //IL_0026: Expected O, but got Unknown if (Harmony == null) { Harmony val = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID); Harmony val2 = val; Harmony = val; } Harmony.PatchAll(); } internal void Unpatch() { Harmony? harmony = Harmony; if (harmony != null) { harmony.UnpatchSelf(); } } private void Update() { } } [HarmonyPatch(typeof(EnemyParent))] internal static class EnemyParentPatch { [HarmonyPrefix] [HarmonyPatch("Awake")] private static void Awake_Prefix(EnemyParent __instance) { try { IndicatorUI.Instance.AddEnemyToIndicator(__instance); } catch (Exception arg) { EnemyIndicators.Logger.LogError((object)$"Error in EnemyParentPatch.Awake_Prefix: {arg}"); } } } [HarmonyPatch(typeof(HUD))] internal static class HUDPatch { [HarmonyPrefix] [HarmonyPatch("Awake")] private static void Awake_Prefix(HUD __instance) { try { EnemyIndicators.Logger.LogInfo((object)"HUD Awake Prefix called, initializing Enemy Indicators UI..."); if ((Object)(object)EnemyIndicators.Instance.UIInstance == (Object)null) { EnemyIndicators.Logger.LogInfo((object)"Instantiating IndicatorUI and assigning it to EnemyIndicators.Instance.UIInstance."); EnemyIndicators.Instance.UIInstance = Object.Instantiate<GameObject>(EnemyIndicators.Instance.IndicatorHolderPrefab, ((Component)((Component)__instance).transform).transform.Find("HUD Canvas/HUD/Game Hud")).GetComponent<IndicatorUI>(); } } catch (Exception arg) { EnemyIndicators.Logger.LogError((object)$"Error in HUDPatch.Start_Prefix: {arg}"); } } } [HarmonyPatch(typeof(RoundDirector))] internal static class RoundDirectorPatch { [HarmonyPrefix] [HarmonyPatch("Start")] private static void Start_Prefix(RoundDirector __instance) { try { IndicatorUI.Instance.ClearAllSlots(); } catch (Exception arg) { EnemyIndicators.Logger.LogError((object)$"Error in RoundDirectorPatch.Start_Prefix: {arg}"); } } } public class indicatorSlot : MonoBehaviour { public EnemyParent enemyParent = null; public TMP_Text NameText = null; public TMP_Text TimerText = null; public Image StatusImage = null; public InidcatorStatus status = InidcatorStatus.Active; private void Awake() { TMP_Text[] componentsInChildren = ((Component)this).GetComponentsInChildren<TMP_Text>(); foreach (TMP_Text val in componentsInChildren) { if (((Object)val).name == "Text (TMP)") { NameText = val; } else if (((Object)val).name == "Text (TMP) (1)") { TimerText = val; } } StatusImage = ((Component)this).GetComponentInChildren<Image>(); } private void Update() { if ((Object)(object)enemyParent == (Object)null) { EnemyIndicators.Logger.LogWarning((object)"EnemyParent is null in indicatorSlot.Update, removing this slot."); IndicatorUI.Instance.indicatorSlots.Remove(this); if ((Object)(object)((Component)this).gameObject != (Object)null) { Object.Destroy((Object)(object)((Component)this).gameObject); } } else { UpdateStatus(); UpdateVisuals(); UpdateTimer(); } } private void UpdateStatus() { //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Invalid comparison between Unknown and I4 if (enemyParent.Enemy.HasHealth && enemyParent.Enemy.Health.dead) { status = InidcatorStatus.Dead; return; } if (EnemyDirector.instance.spawnIdlePauseTimer > 0f) { status = InidcatorStatus.Waiting; return; } EnemyState currentState = enemyParent.Enemy.CurrentState; EnemyState val = currentState; if ((int)val == 11) { status = InidcatorStatus.Dipped; } else { status = InidcatorStatus.Active; } } private void UpdateVisuals() { NameText.text = enemyParent.enemyName; switch (status) { case InidcatorStatus.Active: StatusImage.sprite = EnemyIndicators.Instance.ActiveSprite; break; case InidcatorStatus.Waiting: StatusImage.sprite = EnemyIndicators.Instance.ClockSprite; break; case InidcatorStatus.Dipped: StatusImage.sprite = EnemyIndicators.Instance.ZzzSprite; break; case InidcatorStatus.Dead: StatusImage.sprite = EnemyIndicators.Instance.SkullSprite; break; } } private void UpdateTimer() { if (!EnemyIndicators.Instance.ShowRespawnTimers.Value) { ((Component)TimerText).gameObject.SetActive(false); return; } switch (status) { case InidcatorStatus.Waiting: ((Component)TimerText).gameObject.SetActive(true); TimerText.text = TimeSpan.FromSeconds(EnemyDirector.instance.spawnIdlePauseTimer).ToString("mm\\:ss"); break; case InidcatorStatus.Dipped: case InidcatorStatus.Dead: ((Component)TimerText).gameObject.SetActive(true); TimerText.text = TimeSpan.FromSeconds(enemyParent.DespawnedTimer).ToString("mm\\:ss"); break; default: ((Component)TimerText).gameObject.SetActive(false); break; } } } public enum InidcatorStatus { Active, Waiting, Dipped, Dead } public class IndicatorUI : SemiUI { public List<indicatorSlot> indicatorSlots = new List<indicatorSlot>(); public static IndicatorUI Instance { get; private set; } private MapToolController Map => PlayerAvatar.instance.mapToolController; private void Awake() { Instance = this; } public override void Start() { ((SemiUI)this).Start(); ((SemiUI)this).Hide(); } public override void Update() { ((SemiUI)this).Update(); if (!((Object)(object)Map == (Object)null)) { if (Map.Active) { ((SemiUI)this).Show(); } else { ((SemiUI)this).Hide(); } } } public void AddEnemyToIndicator(EnemyParent enemyParent) { GameObject val = Object.Instantiate<GameObject>(EnemyIndicators.Instance.indicatorSlotPrefab, ((Component)this).transform); indicatorSlot component = val.GetComponent<indicatorSlot>(); component.enemyParent = enemyParent; indicatorSlots.Add(component); base.allChildren.Add(((Component)component).gameObject); EnemyIndicators.Logger.LogInfo((object)$"Added enemy {enemyParent.enemyName} to indicator slots. Total slots: {indicatorSlots.Count}"); } public void RemoveEnemyFromIndicator(EnemyParent enemyParent) { EnemyParent enemyParent2 = enemyParent; indicatorSlot indicatorSlot2 = indicatorSlots.Find((indicatorSlot slot) => (Object)(object)slot.enemyParent == (Object)(object)enemyParent2); if ((Object)(object)indicatorSlot2 != (Object)null) { if ((Object)(object)((Component)indicatorSlot2).gameObject != (Object)null) { Object.Destroy((Object)(object)((Component)indicatorSlot2).gameObject); } indicatorSlots.Remove(indicatorSlot2); base.allChildren.Remove(((Component)indicatorSlot2).gameObject); EnemyIndicators.Logger.LogInfo((object)$"Removed enemy {enemyParent2.enemyName} from indicator slots. Remaining slots: {indicatorSlots.Count}"); } else { EnemyIndicators.Logger.LogWarning((object)("Tried to remove enemy " + enemyParent2.enemyName + " from indicators, but it was not found.")); } } public void ClearAllSlots() { foreach (indicatorSlot indicatorSlot in indicatorSlots) { if ((Object)(object)indicatorSlot != (Object)null && (Object)(object)((Component)indicatorSlot).gameObject != (Object)null) { Object.Destroy((Object)(object)((Component)indicatorSlot).gameObject); } } indicatorSlots.Clear(); base.allChildren.Clear(); EnemyIndicators.Logger.LogInfo((object)"Cleared all indicator slots."); } } }