using 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 BepInEx.Bootstrap;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.AddressableAssets;
[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("GabrielAlly")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("GabrielAlly")]
[assembly: AssemblyTitle("GabrielAlly")]
[assembly: AssemblyVersion("1.0.0.0")]
[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.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace GabrielAlly
{
[BepInPlugin("GabrielAlly.adry.ultrakill", "Gabriel Ally", "1.1.1")]
public class Plugin : BaseUnityPlugin
{
private GameObject gabrielInstance;
private static readonly ManualLogSource logger = Logger.CreateLogSource("GabrielAlly");
private static float timeWithoutTarget = 0f;
private void Awake()
{
Harmony.CreateAndPatchAll(typeof(Plugin), (string)null);
logger.LogInfo((object)"Gabriel Ally mod initialized.");
}
[HarmonyPatch(typeof(ActivateArena), "Activate")]
[HarmonyPostfix]
private static void ActivateArena_Activate_Postfix(ActivateArena __instance)
{
if (CheckArenaDoorsLocked(__instance))
{
SpawnGabriel();
}
else
{
logger.LogInfo((object)"Arena activated, but doors are not locked. Gabriel will not be spawned.");
}
}
[HarmonyPatch(typeof(NewMovement), "GetHurt")]
[HarmonyPostfix]
private static void NewMovement_GetHurt_Postfix(NewMovement __instance)
{
if (__instance.hp <= 0)
{
DespawnGabriel("Player died.");
}
}
[HarmonyPatch(typeof(CheckPoint), "OnRespawn")]
[HarmonyPostfix]
private static void CheckPoint_OnRespawn_Postfix()
{
DespawnGabriel("Player used a checkpoint.");
}
private static void SpawnGabriel()
{
//IL_006f: Unknown result type (might be due to invalid IL or missing references)
//IL_0074: Unknown result type (might be due to invalid IL or missing references)
//IL_007b: Unknown result type (might be due to invalid IL or missing references)
//IL_0080: Unknown result type (might be due to invalid IL or missing references)
//IL_0095: Unknown result type (might be due to invalid IL or missing references)
//IL_0096: Unknown result type (might be due to invalid IL or missing references)
Plugin plugin = (Plugin)(object)Chainloader.ManagerObject.GetComponent(typeof(Plugin));
logger.LogInfo((object)"Attempting to spawn Gabriel (blessed) at player's position.");
try
{
if ((Object)(object)plugin.gabrielInstance == (Object)null)
{
NewMovement instance = MonoSingleton<NewMovement>.Instance;
if ((Object)(object)instance == (Object)null)
{
logger.LogError((object)"Player not found. Unable to spawn Gabriel.");
return;
}
Vector3 position = ((Component)instance).transform.position;
plugin.gabrielInstance = Addressables.LoadAssetAsync<GameObject>((object)"Assets/Prefabs/Enemies/Gabriel.prefab").WaitForCompletion();
plugin.gabrielInstance = Object.Instantiate<GameObject>(plugin.gabrielInstance, position, Quaternion.identity);
EnemyIdentifier component = plugin.gabrielInstance.GetComponent<EnemyIdentifier>();
if ((Object)(object)component != (Object)null)
{
SetGabrielAsAlly(component);
logger.LogInfo((object)"Gabriel (blessed) spawned successfully at player's position.");
}
else
{
logger.LogError((object)"EnemyIdentifier not found on Gabriel!");
}
}
else
{
logger.LogWarning((object)"An instance of Gabriel already exists. Ignoring spawn.");
}
}
catch (Exception arg)
{
logger.LogError((object)$"Error loading Gabriel prefab: {arg}");
}
}
private static void DespawnGabriel(string reason)
{
Plugin plugin = (Plugin)(object)Chainloader.ManagerObject.GetComponent(typeof(Plugin));
if ((Object)(object)plugin.gabrielInstance != (Object)null)
{
logger.LogInfo((object)("Removing Gabriel: " + reason));
Object.Destroy((Object)(object)plugin.gabrielInstance);
plugin.gabrielInstance = null;
}
}
[HarmonyPatch(typeof(ActivateNextWave), "EndWaves")]
[HarmonyPostfix]
private static void ActivateNextWave_EndWaves_Postfix(ActivateNextWave __instance)
{
if (__instance.lastWave)
{
DespawnGabriel("Last wave completed.");
}
}
private static bool CheckArenaDoorsLocked(ActivateArena arena)
{
if (arena.doors == null || arena.doors.Length == 0)
{
return false;
}
Door[] doors = arena.doors;
foreach (Door val in doors)
{
if ((Object)(object)val != (Object)null && !val.locked)
{
return false;
}
}
return true;
}
private static void SetGabrielAsAlly(EnemyIdentifier gabrielEid)
{
gabrielEid.ignorePlayer = true;
gabrielEid.attackEnemies = true;
gabrielEid.blessed = true;
}
[HarmonyPatch(typeof(EnemyIdentifier), "Update")]
[HarmonyPostfix]
private static void EnemyIdentifier_Update_Postfix(EnemyIdentifier __instance)
{
Plugin plugin = (Plugin)(object)Chainloader.ManagerObject.GetComponent(typeof(Plugin));
if ((Object)(object)plugin.gabrielInstance != (Object)null && (Object)(object)((Component)__instance).gameObject == (Object)(object)plugin.gabrielInstance)
{
SetGabrielAsAlly(__instance);
}
}
[HarmonyPatch(typeof(Gabriel), "Update")]
[HarmonyPostfix]
private static void Gabriel_Update_Postfix(Gabriel __instance)
{
//IL_0224: Unknown result type (might be due to invalid IL or missing references)
//IL_0230: Unknown result type (might be due to invalid IL or missing references)
//IL_0244: Unknown result type (might be due to invalid IL or missing references)
//IL_0249: Unknown result type (might be due to invalid IL or missing references)
//IL_0259: Unknown result type (might be due to invalid IL or missing references)
//IL_02c2: Unknown result type (might be due to invalid IL or missing references)
//IL_02cc: Expected O, but got Unknown
//IL_0192: Unknown result type (might be due to invalid IL or missing references)
//IL_019c: Expected O, but got Unknown
Plugin plugin = (Plugin)(object)Chainloader.ManagerObject.GetComponent(typeof(Plugin));
if (!((Object)(object)plugin.gabrielInstance != (Object)null) || !((Object)(object)((Component)__instance).gameObject == (Object)(object)plugin.gabrielInstance))
{
return;
}
EnemyIdentifier gabrielEid = ((Component)__instance).GetComponent<EnemyIdentifier>();
if (!((Object)(object)gabrielEid != (Object)null))
{
return;
}
List<EnemyIdentifier> list = (from eid in MonoSingleton<EnemyTracker>.Instance.GetCurrentEnemies()
where ((Component)eid).gameObject.activeInHierarchy && (int)eid.enemyType != 21 && !eid.dead
select eid).ToList();
if (list.Count > 0)
{
if (gabrielEid.target == null || (Object)(object)gabrielEid.target.trackedTransform == (Object)null || !((Component)gabrielEid.target.trackedTransform).gameObject.activeInHierarchy || gabrielEid.target.enemyIdentifier.dead)
{
timeWithoutTarget += Time.deltaTime;
if (timeWithoutTarget > 0.5f)
{
logger.LogWarning((object)"Gabriel has been without a target for more than 0.5s! Forcing a new target.");
EnemyIdentifier val = list.OrderBy((EnemyIdentifier e) => Vector3.Distance(((Component)gabrielEid).transform.position, ((Component)e).transform.position)).FirstOrDefault();
if ((Object)(object)val != (Object)null)
{
if ((Object)(object)val != (Object)(object)gabrielEid)
{
gabrielEid.target = new EnemyTarget(val);
logger.LogWarning((object)("Gabriel locked on a new target: " + ((Object)val).name));
}
else
{
logger.LogWarning((object)"The nearest target is Gabriel himself. Ignoring.");
}
}
timeWithoutTarget = 0f;
}
}
else
{
timeWithoutTarget = 0f;
}
}
else
{
gabrielEid.target = null;
timeWithoutTarget = 0f;
NewMovement instance = MonoSingleton<NewMovement>.Instance;
if ((Object)(object)instance != (Object)null)
{
((Component)__instance).transform.position = Vector3.MoveTowards(((Component)__instance).transform.position, ((Component)instance).transform.position + new Vector3(0f, 5f, 0f), 10f * Time.deltaTime);
}
}
if (gabrielEid.target != null)
{
EnemyIdentifier enemyIdentifier = gabrielEid.target.enemyIdentifier;
if ((Object)(object)enemyIdentifier != (Object)null && (Object)(object)enemyIdentifier != (Object)(object)gabrielEid.target.enemyIdentifier)
{
gabrielEid.target = new EnemyTarget(enemyIdentifier);
}
}
}
[HarmonyPatch(typeof(EnemyIdentifier), "Death", new Type[] { })]
[HarmonyPostfix]
private static void EnemyIdentifier_Death_Postfix(EnemyIdentifier __instance)
{
Plugin plugin = (Plugin)(object)Chainloader.ManagerObject.GetComponent(typeof(Plugin));
if ((Object)(object)plugin.gabrielInstance != (Object)null && (Object)(object)((Component)__instance).gameObject != (Object)(object)plugin.gabrielInstance)
{
EnemyIdentifier component = plugin.gabrielInstance.GetComponent<EnemyIdentifier>();
if (component.target != null && (Object)(object)component.target.enemyIdentifier == (Object)(object)__instance)
{
component.target = null;
logger.LogWarning((object)("Gabriel's target (" + ((Object)__instance).name + ") has been killed. Removing target."));
}
}
}
}
}