using 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.");
}
}
}