Decompiled source of SuperchargedFollowers v1.0.4

plugins/SuperchargedFollowers/SuperchargedFollowers.dll

Decompiled 3 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
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 COTL_API.CustomInventory;
using COTL_API.CustomStructures;
using COTL_API.Helpers;
using DG.Tweening;
using DG.Tweening.Core;
using DG.Tweening.Plugins.Options;
using HarmonyLib;
using Lamb.UI;
using Lamb.UI.BuildMenu;
using Lamb.UI.FollowerSelect;
using MMBiomeGeneration;
using Microsoft.CodeAnalysis;
using Spine.Unity;
using SuperchargedFollowers.Helpers;
using SuperchargedFollowers.Interactions;
using SuperchargedFollowers.ProxyItems;
using SuperchargedFollowers.Structures;
using TMPro;
using UnityEngine;
using src.Extensions;
using src.UI.Menus;

[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.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: AssemblyCompany("SuperchargedFollowers")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+67b254773966b2e37d65b99aa7c1ddea20f5df58")]
[assembly: AssemblyProduct("SuperchargedFollowers")]
[assembly: AssemblyTitle("SuperchargedFollowers")]
[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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace SuperchargedFollowers
{
	[BepInPlugin("InfernoDragon0.cotl.SuperchargedFollowers", "SuperchargedFollowers", "1.0.4")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[HarmonyPatch]
	public class Plugin : BaseUnityPlugin
	{
		public const string PluginGuid = "InfernoDragon0.cotl.SuperchargedFollowers";

		public const string PluginName = "SuperchargedFollowers";

		public const string PluginVer = "1.0.4";

		internal static ManualLogSource Log;

		internal static readonly Harmony Harmony = new Harmony("InfernoDragon0.cotl.SuperchargedFollowers");

		internal static string PluginPath;

		internal static ConfigEntry<float> followerTransparency;

		internal static ConfigEntry<bool> shouldCommanderTransparent;

		public static List<FollowerInfo> summonList = new List<FollowerInfo>();

		public static FollowerInfo commander;

		public static bool summoned = false;

		public static List<Follower> tempSummoned = new List<Follower>();

		public static ITEM_TYPE holiday;

		public static ITEM_TYPE prayer;

		public static ITEM_TYPE missionary;

		public static ITEM_TYPE warrior;

		public static ITEM_TYPE undertaker;

		public static ITEM_TYPE prestige;

		public static TYPES rally;

		public static TYPES rallymulti;

		public static TYPES barracks;

		public static List<int> allJobs;

		private void Awake()
		{
			//IL_006a: 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_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: 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)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Expected I4, but got Unknown
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Expected I4, but got Unknown
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Expected I4, but got Unknown
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Expected I4, but got Unknown
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Expected I4, but got Unknown
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			PluginPath = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
			followerTransparency = ((BaseUnityPlugin)this).Config.Bind<float>("SuperchargedFollowers", "FollowerTransparency", 0.5f, "Transparency of the followers, from 0 to 1");
			shouldCommanderTransparent = ((BaseUnityPlugin)this).Config.Bind<bool>("SuperchargedFollowers", "CommanderTransparency", true, "Should the commander be transparent?");
			holiday = CustomItemManager.Add((CustomInventoryItem)(object)new Holiday());
			prayer = CustomItemManager.Add((CustomInventoryItem)(object)new Prayer());
			missionary = CustomItemManager.Add((CustomInventoryItem)(object)new Missionary());
			warrior = CustomItemManager.Add((CustomInventoryItem)(object)new Warrior());
			undertaker = CustomItemManager.Add((CustomInventoryItem)(object)new Undertaker());
			prestige = CustomItemManager.Add((CustomInventoryItem)(object)new Prestige());
			allJobs = new List<int>
			{
				(int)holiday,
				(int)prayer,
				(int)missionary,
				(int)warrior,
				(int)undertaker
			};
			rally = CustomStructureManager.Add((CustomStructure)(object)new RallyStructure());
			rallymulti = CustomStructureManager.Add((CustomStructure)(object)new RallyMultiStructure());
			barracks = CustomStructureManager.Add((CustomStructure)(object)new BarracksStructure());
		}

		private void OnEnable()
		{
			Harmony.PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Loaded SuperchargedFollowers!");
		}

		private void OnDisable()
		{
			Harmony.UnpatchSelf();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Unloaded SuperchargedFollowers!");
		}
	}
}
namespace SuperchargedFollowers.Structures
{
	public class BarracksStructure : CustomStructure
	{
		public override string InternalName => "BARRACKS_STRUCTURE";

		public override Type Interaction => typeof(Interaction_Barracks);

		public override Sprite Sprite => TextureHelper.CreateSpriteFromPath(Path.Combine(Plugin.PluginPath, "Assets/Barracks.png"));

		public override int BuildDurationMinutes => 30;

		public override Vector2Int Bounds => new Vector2Int(2, 2);

		public override Category Category => (Category)0;

		public override Categories StructureCategories => (Categories)2;

		public override string GetLocalizedName()
		{
			return "Barracks";
		}

		public override string GetLocalizedDescription()
		{
			return "[Supercharged Series] Upgrade your followers for battle here.";
		}

		public override string GetLocalizedLore()
		{
			return "[Supercharged Series]";
		}
	}
	public class RallyMultiStructure : CustomStructure
	{
		public override string InternalName => "RALLY_MULTI_STRUCTURE";

		public override Type Interaction => typeof(Interaction_RallyMulti);

		public override Sprite Sprite => TextureHelper.CreateSpriteFromPath(Path.Combine(Plugin.PluginPath, "Assets/RallyMulti.png"));

		public override int BuildDurationMinutes => 30;

		public override Vector2Int Bounds => new Vector2Int(2, 2);

		public override Category Category => (Category)0;

		public override Categories StructureCategories => (Categories)2;

		public override string GetLocalizedName()
		{
			return "Super Rally Flag";
		}

		public override string GetLocalizedDescription()
		{
			return "[Supercharged Series] Rally / Unrally all followers at once.";
		}

		public override string GetLocalizedLore()
		{
			return "[Supercharged Series]";
		}
	}
	public class RallyStructure : CustomStructure
	{
		public override string InternalName => "RALLY_STRUCTURE";

		public override Type Interaction => typeof(Interaction_Rally);

		public override Sprite Sprite => TextureHelper.CreateSpriteFromPath(Path.Combine(Plugin.PluginPath, "Assets/Rally.png"));

		public override int BuildDurationMinutes => 30;

		public override Vector2Int Bounds => new Vector2Int(2, 2);

		public override Category Category => (Category)0;

		public override Categories StructureCategories => (Categories)2;

		public override string GetLocalizedName()
		{
			return "Rally Flag";
		}

		public override string GetLocalizedDescription()
		{
			return "[Supercharged Series] Rally your followers to bring them to battle.";
		}

		public override string GetLocalizedLore()
		{
			return "[Supercharged Series]";
		}
	}
}
namespace SuperchargedFollowers.ProxyItems
{
	public class Holiday : CustomInventoryItem
	{
		public override string InternalName => "Holiday_Proxy";

		public override Sprite Sprite => TextureHelper.CreateSpriteFromPath(Path.Combine(Plugin.PluginPath, "Assets/proxy.png"));

		public override Sprite InventoryIcon { get; } = TextureHelper.CreateSpriteFromPath(Path.Combine(Plugin.PluginPath, "Assets/proxy.png"));


		public override string LocalizedName()
		{
			return "Holiday";
		}

		public override string LocalizedDescription()
		{
			return "A Proxy Item for Supercharged Followers.";
		}
	}
	public class Missionary : CustomInventoryItem
	{
		public override string InternalName => "Missionary_Proxy";

		public override Sprite Sprite => TextureHelper.CreateSpriteFromPath(Path.Combine(Plugin.PluginPath, "Assets/proxy.png"));

		public override Sprite InventoryIcon { get; } = TextureHelper.CreateSpriteFromPath(Path.Combine(Plugin.PluginPath, "Assets/proxy.png"));


		public override string LocalizedName()
		{
			return "Missionary";
		}

		public override string LocalizedDescription()
		{
			return "A Proxy Item for Supercharged Followers.";
		}
	}
	public class Prayer : CustomInventoryItem
	{
		public override string InternalName => "Prayer_Proxy";

		public override Sprite Sprite => TextureHelper.CreateSpriteFromPath(Path.Combine(Plugin.PluginPath, "Assets/proxy.png"));

		public override Sprite InventoryIcon { get; } = TextureHelper.CreateSpriteFromPath(Path.Combine(Plugin.PluginPath, "Assets/proxy.png"));


		public override string LocalizedName()
		{
			return "Prayer";
		}

		public override string LocalizedDescription()
		{
			return "A Proxy Item for Supercharged Followers.";
		}
	}
	public class Undertaker : CustomInventoryItem
	{
		public override string InternalName => "Undertaker_Proxy";

		public override Sprite Sprite => TextureHelper.CreateSpriteFromPath(Path.Combine(Plugin.PluginPath, "Assets/proxy.png"));

		public override Sprite InventoryIcon { get; } = TextureHelper.CreateSpriteFromPath(Path.Combine(Plugin.PluginPath, "Assets/proxy.png"));


		public override string LocalizedName()
		{
			return "Undertaker";
		}

		public override string LocalizedDescription()
		{
			return "A Proxy Item for Supercharged Followers.";
		}
	}
	public class Warrior : CustomInventoryItem
	{
		public override string InternalName => "Warrior_Proxy";

		public override Sprite Sprite => TextureHelper.CreateSpriteFromPath(Path.Combine(Plugin.PluginPath, "Assets/proxy.png"));

		public override Sprite InventoryIcon { get; } = TextureHelper.CreateSpriteFromPath(Path.Combine(Plugin.PluginPath, "Assets/proxy.png"));


		public override string LocalizedName()
		{
			return "Warrior";
		}

		public override string LocalizedDescription()
		{
			return "A Proxy Item for Supercharged Followers.";
		}
	}
	public class Prestige : CustomInventoryItem
	{
		public override string InternalName => "Prestige";

		public override Sprite Sprite => TextureHelper.CreateSpriteFromPath(Path.Combine(Plugin.PluginPath, "Assets/prestige.png"));

		public override Sprite InventoryIcon { get; } = TextureHelper.CreateSpriteFromPath(Path.Combine(Plugin.PluginPath, "Assets/prestige.png"));


		public override string LocalizedName()
		{
			return "Prestige";
		}

		public override string LocalizedDescription()
		{
			return "Give this to your followers via the Barracks to upgrade their battle stats.";
		}
	}
}
namespace SuperchargedFollowers.Patches
{
	[HarmonyPatch]
	internal class FollowerJoinRoomPatch
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static RoomEvent <0>__OnRoomCleared;
		}

		private static SpawnedFollower SpawnAllyFollower(FollowerInfo followerInfo, Vector3 position)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0270: Unknown result type (might be due to invalid IL or missing references)
			SpawnedFollower val = FollowerManager.SpawnCopyFollower(FollowerManager.CombatFollowerPrefab, followerInfo, position, ((Component)PlayerFarming.Instance).transform.parent, BiomeGenerator.Instance.DungeonLocation);
			val.Follower.State.CURRENT_STATE = (State)49;
			val.Follower.Spine.AnimationState.SetAnimation(1, "spawn-in", false);
			val.Follower.Spine.AnimationState.AddAnimation(1, "Reactions/react-worried1", true, 0f);
			((Behaviour)((Component)val.Follower).GetComponent<EnemyFollower>()).enabled = true;
			((Component)((Component)val.Follower).GetComponent<EnemyFollower>()).gameObject.AddComponent<FollowerRoutines>();
			EnemyFollower component = ((Component)val.Follower).GetComponent<EnemyFollower>();
			BuffStats prestigeBonuses = Bonuses.GetPrestigeBonuses(val.FollowerBrain._directInfoAccess);
			BuffStats classBonuses = Bonuses.GetClassBonuses(val.FollowerBrain._directInfoAccess);
			BuffStats commanderBonuses = Bonuses.GetCommanderBonuses(val.FollowerBrain._directInfoAccess);
			BuffStats necklaceBonuses = Bonuses.GetNecklaceBonuses(val.FollowerBrain._directInfoAccess);
			if (followerInfo == Plugin.commander)
			{
				TweenSettingsExtensions.SetEase<TweenerCore<Vector3, Vector3, VectorOptions>>(ShortcutExtensions.DOScale(((Component)val.Follower).transform, 1f + commanderBonuses.SizeBonus, 0.25f), (Ease)30);
				component.variant = 1;
				if (Plugin.shouldCommanderTransparent.Value)
				{
					((SkeletonRenderer)val.Follower.Spine).skeleton.A = Plugin.followerTransparency.Value;
				}
			}
			else
			{
				component.variant = 0;
				((SkeletonRenderer)val.Follower.Spine).skeleton.A = Plugin.followerTransparency.Value;
			}
			component.Damage = 0.5f + prestigeBonuses.AttackBonus + classBonuses.AttackBonus + commanderBonuses.AttackBonus + necklaceBonuses.AttackBonus;
			((UnitObject)component).speed = 0.08f + prestigeBonuses.MovementSpeedBonus + classBonuses.MovementSpeedBonus + commanderBonuses.MovementSpeedBonus + necklaceBonuses.MovementSpeedBonus;
			((UnitObject)component).maxSpeed = 0.08f + prestigeBonuses.MovementSpeedBonus + classBonuses.MovementSpeedBonus + commanderBonuses.MovementSpeedBonus + necklaceBonuses.MovementSpeedBonus;
			Health component2 = ((Component)val.Follower).GetComponent<Health>();
			component2.ImmuneToPlayer = true;
			component2.totalHP = 10f + prestigeBonuses.HealthBonus + classBonuses.HealthBonus + commanderBonuses.HealthBonus + necklaceBonuses.HealthBonus;
			component2.HP = component2.totalHP;
			Plugin.tempSummoned.Add(val.Follower);
			component2.team = (Team)1;
			component2.isPlayerAlly = true;
			return val;
		}

		[HarmonyPatch(typeof(Door), "ChangeRoom")]
		[HarmonyPrefix]
		public static bool Door_ChangeRoom()
		{
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Expected O, but got Unknown
			if (Plugin.summoned)
			{
				Plugin.Log.LogInfo((object)"Already summoned, repositioning to player if outside of room");
				foreach (Follower item in Plugin.tempSummoned)
				{
					if (item.Health.HP > 0f)
					{
						try
						{
							((MonoBehaviour)item).StartCoroutine((IEnumerator)((Component)((Component)item).GetComponent<EnemyFollower>()).gameObject.GetComponent<FollowerRoutines>().RepositionSelfIfOutside());
						}
						catch (Exception)
						{
							Plugin.Log.LogInfo((object)"FollowerRoutines may not have initialized yet, skipping");
						}
					}
				}
				return true;
			}
			Plugin.summoned = true;
			Plugin.Log.LogInfo((object)"Summoning followers");
			for (int i = 0; i < Plugin.summonList.Count; i++)
			{
				SpawnAllyFollower(Plugin.summonList[i], ((Component)PlayerFarming.Instance).transform.position);
			}
			object obj = <>O.<0>__OnRoomCleared;
			if (obj == null)
			{
				RoomEvent val = OnRoomCleared;
				<>O.<0>__OnRoomCleared = val;
				obj = (object)val;
			}
			RoomLockController.OnRoomCleared += (RoomEvent)obj;
			return true;
		}

		[HarmonyPatch(typeof(Door), "OnTriggerEnter2D")]
		[HarmonyPrefix]
		public static bool Door_OnTriggerEnter2D(Door __instance)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			Plugin.Log.LogInfo((object)__instance.ConnectionType);
			__instance.Used = false;
			return true;
		}

		[HarmonyPatch(typeof(Health), "DealDamage")]
		[HarmonyPrefix]
		public static bool Health_DealDamage(Health __instance, GameObject Attacker)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Invalid comparison between Unknown and I4
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Invalid comparison between Unknown and I4
			Health component = Attacker.GetComponent<Health>();
			if ((Object)(object)component == (Object)null)
			{
				return true;
			}
			if ((int)component.team == 1 && (int)__instance.team == 1)
			{
				Plugin.Log.LogInfo((object)"No attack self teams");
				return false;
			}
			return true;
		}

		[HarmonyPatch(typeof(EnemyFollower), "WaitForTarget")]
		[HarmonyPrefix]
		public static bool EnemyFollower_WaitForTarget(EnemyFollower __instance)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Invalid comparison between Unknown and I4
			if ((int)((UnitObject)__instance).health.team == 1 && ((UnitObject)__instance).health.isPlayerAlly)
			{
				Plugin.Log.LogInfo((object)"waiting for target");
				return false;
			}
			return true;
		}

		[HarmonyPatch(typeof(EnemyFollower), "ChasePlayer")]
		[HarmonyPrefix]
		public static bool EnemyFollower_ChasePlayer(EnemyFollower __instance)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Invalid comparison between Unknown and I4
			Plugin.Log.LogInfo((object)"start chasing");
			if ((int)((UnitObject)__instance).health.team == 1 && ((UnitObject)__instance).health.isPlayerAlly)
			{
				Plugin.Log.LogInfo((object)"start chasing 2");
				((MonoBehaviour)__instance).StartCoroutine((IEnumerator)((Component)__instance).GetComponent<FollowerRoutines>().RunFollowerAI());
				return false;
			}
			return true;
		}

		public static void OnRoomCleared()
		{
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Invalid comparison between Unknown and I4
			//IL_0268: Unknown result type (might be due to invalid IL or missing references)
			//IL_032c: Unknown result type (might be due to invalid IL or missing references)
			Plugin.Log.LogInfo((object)"Room wascleared");
			Plugin.Log.LogInfo((object)("is this the boss room: " + BiomeGenerator.Instance.CurrentRoom.IsBoss));
			List<Follower> list = new List<Follower>();
			foreach (Follower item in Plugin.tempSummoned)
			{
				Plugin.Log.LogInfo((object)(item.Health.HP + " over " + item.Health.totalHP));
				if (item.Health.HP <= 0f)
				{
					ManualLogSource log = Plugin.Log;
					ITEM_TYPE necklace = item.Brain.Info.Necklace;
					log.LogInfo((object)("currently wearing " + ((object)(ITEM_TYPE)(ref necklace)).ToString()));
					if ((int)item.Brain.Info.Necklace == 127)
					{
						Plugin.Log.LogInfo((object)"Golden Skull found, revive");
						CollectionExtensions.AddItem<Follower>((IEnumerable<Follower>)list, item);
					}
				}
				else
				{
					BuffStats necklaceBonuses = Bonuses.GetNecklaceBonuses(item.Brain._directInfoAccess);
					BuffStats commanderBonuses = Bonuses.GetCommanderBonuses(item.Brain._directInfoAccess);
					BuffStats classBonuses = Bonuses.GetClassBonuses(item.Brain._directInfoAccess);
					Health health = item.Health;
					health.HP += necklaceBonuses.RegenBonus + commanderBonuses.RegenBonus + classBonuses.RegenBonus;
					Plugin.Log.LogInfo((object)("Regenerated " + item.Brain._directInfoAccess.Name + " to " + item.Health.HP + " HP"));
				}
			}
			if (list != null && !BiomeGenerator.Instance.CurrentRoom.IsBoss)
			{
				Plugin.Log.LogInfo((object)"Resummon all necklace followers");
				Plugin.tempSummoned.RemoveAll(list.Contains);
				foreach (Follower item2 in list)
				{
					SpawnAllyFollower(item2.Brain._directInfoAccess, ((Component)PlayerFarming.Instance).transform.position);
				}
			}
			if (!BiomeGenerator.Instance.CurrentRoom.IsBoss)
			{
				return;
			}
			Plugin.Log.LogInfo((object)"Boss completed, give reward");
			int num = 0;
			foreach (Follower item3 in Plugin.tempSummoned)
			{
				if (item3.Health.HP > 0f)
				{
					num++;
				}
			}
			Plugin.Log.LogInfo((object)("Total alive: " + num));
			Inventory.AddItem(Plugin.prestige, Math.Min(num, 12), false);
		}
	}
}
namespace SuperchargedFollowers.Interactions
{
	public class Interaction_Barracks : Interaction
	{
		public Structure Structure;

		private bool Activating = false;

		private GameObject Player;

		private float Delay = 0.04f;

		public float DistanceToTriggerDeposits = 5f;

		public StructuresData StructureInfo => Structure.Structure_Info;

		public BarracksStructure BarracksStructure => Structure.Brain as BarracksStructure;

		public override void GetLabel()
		{
			base.label = "Change Follower Class";
		}

		public override void GetSecondaryLabel()
		{
			base.secondaryLabel = "Follower Prestige Levels";
		}

		private void Start()
		{
			base.HasSecondaryInteraction = true;
		}

		public override void OnEnable()
		{
			((Interaction)this).OnEnable();
			Plugin.Log.LogInfo((object)"Barracks OnEnable");
			Structure = ((Component)((Component)this).GetComponentInParent<Transform>()).GetComponent<Structure>();
		}

		public override void OnInteract(StateMachine state)
		{
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Invalid comparison between Unknown and I4
			if (Activating)
			{
				return;
			}
			((Interaction)this).OnInteract(state);
			Activating = true;
			GameManager.GetInstance().OnConversationNew(true, true, (PlayerFarming)null);
			HUD_Manager.Instance.Hide(false, 0, false);
			UIMissionaryMenuController followerSelectMenu = GameObjectExtensions.Instantiate<UIMissionaryMenuController>(MonoSingleton<UIManager>.Instance.MissionaryMenuTemplate);
			List<FollowerInfo> list = new List<FollowerInfo>();
			foreach (FollowerInfo follower in DataManager.Instance.Followers)
			{
				if ((int)follower.CursedState == 146)
				{
					list.Add(follower);
				}
			}
			((UIFollowerSelectMenuController)followerSelectMenu).Show(MissionaryManager.FollowersAvailableForMission(), false, (Type)117, true, true, true, false);
			Plugin.Log.LogInfo((object)"on chosen 6");
			MissionInfoCardController missionInfoCardController = followerSelectMenu._missionInfoCardController;
			((UIInfoCardController<MissionInfoCard, FollowerInfo>)(object)missionInfoCardController).OnInfoCardShown = (Action<MissionInfoCard>)Delegate.Combine(((UIInfoCardController<MissionInfoCard, FollowerInfo>)(object)missionInfoCardController).OnInfoCardShown, (Action<MissionInfoCard>)delegate(MissionInfoCard mic)
			{
				//IL_0142: Unknown result type (might be due to invalid IL or missing references)
				//IL_0147: Unknown result type (might be due to invalid IL or missing references)
				//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
				//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
				//IL_0201: Unknown result type (might be due to invalid IL or missing references)
				//IL_0206: Unknown result type (might be due to invalid IL or missing references)
				//IL_025c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0261: Unknown result type (might be due to invalid IL or missing references)
				//IL_02b7: Unknown result type (might be due to invalid IL or missing references)
				//IL_02bc: Unknown result type (might be due to invalid IL or missing references)
				Plugin.Log.LogInfo((object)"SHOWN");
				MissionButton val = mic.MissionButtons[0];
				MissionButton val2 = Object.Instantiate<MissionButton>(val, ((Component)val).transform.parent);
				MissionButton val3 = Object.Instantiate<MissionButton>(val, ((Component)val).transform.parent);
				MissionButton val4 = Object.Instantiate<MissionButton>(val, ((Component)val).transform.parent);
				MissionButton val5 = Object.Instantiate<MissionButton>(val, ((Component)val).transform.parent);
				MissionButton val6 = Object.Instantiate<MissionButton>(val, ((Component)val).transform.parent);
				List<MissionButton> list2 = new List<MissionButton> { val2, val3, val4, val5, val6 };
				val2.Configure(mic._followerInfo);
				val3.Configure(mic._followerInfo);
				val4.Configure(mic._followerInfo);
				val5.Configure(mic._followerInfo);
				val6.Configure(mic._followerInfo);
				((TMP_Text)val2._titleText).text = "Warrior: <sprite name=\"icon_GoodTrait\"><sprite name=\"icon_GoodTrait\">  ATK, <sprite name=\"icon_GoodTrait\"> HP";
				((TMP_Text)val2._amountText).text = "1";
				val2._type = Plugin.warrior;
				val2.OnMissionSelected = (Action<ITEM_TYPE>)Delegate.Combine(val2.OnMissionSelected, (Action<ITEM_TYPE>)delegate(ITEM_TYPE a)
				{
					//IL_0039: Unknown result type (might be due to invalid IL or missing references)
					Plugin.Log.LogInfo((object)("selected " + ((object)(ITEM_TYPE)(ref a)).ToString()));
					OnClassChosen(mic._followerInfo, a, followerSelectMenu);
				});
				val2.Start();
				Plugin.Log.LogInfo((object)"on chosen 7");
				((TMP_Text)val3._titleText).text = "Prayer: +10% Lamb Curse Damage";
				((TMP_Text)val3._amountText).text = "1";
				val3._type = Plugin.prayer;
				val3.OnMissionSelected = (Action<ITEM_TYPE>)Delegate.Combine(val3.OnMissionSelected, (Action<ITEM_TYPE>)delegate(ITEM_TYPE a)
				{
					//IL_0039: Unknown result type (might be due to invalid IL or missing references)
					Plugin.Log.LogInfo((object)("selected " + ((object)(ITEM_TYPE)(ref a)).ToString()));
					OnClassChosen(mic._followerInfo, a, followerSelectMenu);
				});
				val3.Start();
				((TMP_Text)val4._titleText).text = "Holiday: <sprite name=\"icon_GoodTrait\">  ASPD, <sprite name=\"icon_BadTrait\"> ATK";
				((TMP_Text)val4._amountText).text = "1";
				val4._type = Plugin.holiday;
				val4.OnMissionSelected = (Action<ITEM_TYPE>)Delegate.Combine(val4.OnMissionSelected, (Action<ITEM_TYPE>)delegate(ITEM_TYPE a)
				{
					//IL_0039: Unknown result type (might be due to invalid IL or missing references)
					Plugin.Log.LogInfo((object)("selected " + ((object)(ITEM_TYPE)(ref a)).ToString()));
					OnClassChosen(mic._followerInfo, a, followerSelectMenu);
				});
				val4.Start();
				((TMP_Text)val5._titleText).text = "Missionary: <sprite name=\"icon_GoodTrait\">  SPD, <sprite name=\"icon_GoodTrait\"> ATK";
				((TMP_Text)val5._amountText).text = "1";
				val5._type = Plugin.missionary;
				val5.OnMissionSelected = (Action<ITEM_TYPE>)Delegate.Combine(val5.OnMissionSelected, (Action<ITEM_TYPE>)delegate(ITEM_TYPE a)
				{
					//IL_0017: Unknown result type (might be due to invalid IL or missing references)
					OnClassChosen(mic._followerInfo, a, followerSelectMenu);
					Plugin.Log.LogInfo((object)("selected " + ((object)(ITEM_TYPE)(ref a)).ToString()));
				});
				val5.Start();
				((TMP_Text)val6._titleText).text = "Undertaker: <sprite name=\"icon_GoodTrait\"> HP Regen";
				((TMP_Text)val6._amountText).text = "1";
				val6._type = Plugin.undertaker;
				val6.OnMissionSelected = (Action<ITEM_TYPE>)Delegate.Combine(val6.OnMissionSelected, (Action<ITEM_TYPE>)delegate(ITEM_TYPE a)
				{
					//IL_0017: Unknown result type (might be due to invalid IL or missing references)
					OnClassChosen(mic._followerInfo, a, followerSelectMenu);
					Plugin.Log.LogInfo((object)("selected " + ((object)(ITEM_TYPE)(ref a)).ToString()));
				});
				val6.Start();
				MissionButton[] missionButtons = mic._missionButtons;
				foreach (MissionButton val7 in missionButtons)
				{
					((Component)val7).gameObject.SetActive(false);
				}
				mic._missionButtons = list2.ToArray();
			});
			UIMissionaryMenuController obj = followerSelectMenu;
			((UIMenuBase)obj).OnShown = (Action)Delegate.Combine(((UIMenuBase)obj).OnShown, (Action)delegate
			{
				foreach (FollowerInformationBox followerInfoBox in ((UIFollowerSelectBase<FollowerInformationBox>)(object)followerSelectMenu)._followerInfoBoxes)
				{
					BuffStats prestigeBonuses = Bonuses.GetPrestigeBonuses(((FollowerSelectItem)followerInfoBox).FollowerInfo);
					BuffStats classBonuses = Bonuses.GetClassBonuses(((FollowerSelectItem)followerInfoBox).FollowerInfo);
					((TMP_Text)followerInfoBox.FollowerRole).text = classBonuses.ClassName + " | Prestige " + prestigeBonuses.Level + " |  Health: " + (0.5 + (double)((FollowerSelectItem)followerInfoBox)._followerInfo.DwellingLevel) + " | Attack: " + (double)((FollowerSelectItem)followerInfoBox)._followerInfo.DwellingLevel * 0.5;
				}
			});
			UIMissionaryMenuController obj2 = followerSelectMenu;
			((UIMenuBase)obj2).OnHidden = (Action)Delegate.Combine(((UIMenuBase)obj2).OnHidden, (Action)delegate
			{
				followerSelectMenu = null;
				OnHidden();
			});
			UIMissionaryMenuController obj3 = followerSelectMenu;
			((UIMenuBase)obj3).OnCancel = (Action)Delegate.Combine(((UIMenuBase)obj3).OnCancel, (Action)delegate
			{
				followerSelectMenu = null;
				OnHidden();
			});
		}

		public override void OnSecondaryInteract(StateMachine state)
		{
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Invalid comparison between Unknown and I4
			if (Activating)
			{
				return;
			}
			((Interaction)this).OnSecondaryInteract(state);
			Activating = true;
			GameManager.GetInstance().OnConversationNew(true, true, (PlayerFarming)null);
			HUD_Manager.Instance.Hide(false, 0, false);
			UIFollowerSelectMenuController followerSelectMenu = GameObjectExtensions.Instantiate<UIFollowerSelectMenuController>(MonoSingleton<UIManager>.Instance.FollowerSelectMenuTemplate);
			List<FollowerInfo> list = new List<FollowerInfo>();
			foreach (FollowerInfo follower in DataManager.Instance.Followers)
			{
				if ((int)follower.CursedState == 146)
				{
					list.Add(follower);
				}
			}
			followerSelectMenu.Show(MissionaryManager.FollowersAvailableForMission(), false, (Type)117, true, true, true, false);
			UIFollowerSelectMenuController obj = followerSelectMenu;
			((UIFollowerSelectBase<FollowerInformationBox>)(object)obj).OnFollowerSelected = (Action<FollowerInfo>)Delegate.Combine(((UIFollowerSelectBase<FollowerInformationBox>)(object)obj).OnFollowerSelected, new Action<FollowerInfo>(OnPrestigeChosen));
			UIFollowerSelectMenuController obj2 = followerSelectMenu;
			((UIMenuBase)obj2).OnShown = (Action)Delegate.Combine(((UIMenuBase)obj2).OnShown, (Action)delegate
			{
				foreach (FollowerInformationBox followerInfoBox in ((UIFollowerSelectBase<FollowerInformationBox>)(object)followerSelectMenu)._followerInfoBoxes)
				{
					BuffStats prestigeBonuses = Bonuses.GetPrestigeBonuses(((FollowerSelectItem)followerInfoBox).FollowerInfo);
					int num = Bonuses.PrestigeToNextLevel(((FollowerSelectItem)followerInfoBox).FollowerInfo);
					((TMP_Text)followerInfoBox.FollowerRole).text = "Prestige " + prestigeBonuses.Level + "| " + num + " to next Prestige | Bonuses: " + prestigeBonuses.HealthBonus + "HP, " + prestigeBonuses.AttackBonus + "ATK, " + prestigeBonuses.MovementSpeedBonus + "MOV, " + prestigeBonuses.DelayBonus + "SPD";
				}
			});
			UIFollowerSelectMenuController obj3 = followerSelectMenu;
			((UIMenuBase)obj3).OnHidden = (Action)Delegate.Combine(((UIMenuBase)obj3).OnHidden, (Action)delegate
			{
				followerSelectMenu = null;
				OnHidden();
			});
			UIFollowerSelectMenuController obj4 = followerSelectMenu;
			((UIMenuBase)obj4).OnCancel = (Action)Delegate.Combine(((UIMenuBase)obj4).OnCancel, (Action)delegate
			{
				followerSelectMenu = null;
				OnHidden();
			});
		}

		public void OnHidden()
		{
			Activating = false;
			HUD_Manager.Instance.Show(1, false);
			GameManager.GetInstance().OnConversationEnd(true, true);
		}

		public void OnPrestigeChosen(FollowerInfo followerInfo)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			int num = Bonuses.PrestigeToNextLevel(followerInfo);
			if (num <= 0)
			{
				NotificationCentreScreen.Play("Follower is already at max level!");
				OnHidden();
				return;
			}
			int itemQuantity = Inventory.GetItemQuantity(Plugin.prestige);
			if (itemQuantity >= num)
			{
				Inventory.ChangeItemQuantity(Plugin.prestige, -num, 0);
				for (int i = 0; i < num; i++)
				{
					followerInfo.Inventory.Add(new InventoryItem(Plugin.prestige, 1));
				}
				NotificationCentreScreen.Play("Prestige level increased for " + followerInfo.Name);
			}
			else
			{
				NotificationCentreScreen.Play("Not enough Prestige to level, need " + num + " Prestige");
			}
			OnHidden();
		}

		public void OnClassChosen(FollowerInfo followerInfo, ITEM_TYPE classType, UIMissionaryMenuController followerSelectMenu)
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Expected O, but got Unknown
			Plugin.Log.LogInfo((object)("class chosen " + ((object)(ITEM_TYPE)(ref classType)).ToString()));
			followerInfo.Inventory.RemoveAll((InventoryItem item) => Plugin.allJobs.Contains(item.type));
			followerInfo.Inventory.Add(new InventoryItem(classType, 1));
			((UIMenuBase)followerSelectMenu).Hide(false);
			OnHidden();
		}
	}
	public class Interaction_Rally : Interaction
	{
		public Structure Structure;

		private bool Activating = false;

		private GameObject Player;

		private float Delay = 0.04f;

		public float DistanceToTriggerDeposits = 5f;

		public StructuresData StructureInfo => Structure.Structure_Info;

		public RallyStructure RallyStructure => Structure.Brain as RallyStructure;

		public override void GetLabel()
		{
			base.secondaryLabel = "Select Commander";
			base.label = "Rally Followers";
		}

		private void Start()
		{
			base.HasSecondaryInteraction = true;
		}

		public override void OnEnable()
		{
			((Interaction)this).OnEnable();
			Plugin.Log.LogInfo((object)"Rally OnEnable");
			Structure = ((Component)((Component)this).GetComponentInParent<Transform>()).GetComponent<Structure>();
		}

		public override void OnInteract(StateMachine state)
		{
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Invalid comparison between Unknown and I4
			Plugin.summoned = false;
			if (Activating)
			{
				return;
			}
			((Interaction)this).OnInteract(state);
			Activating = true;
			GameManager.GetInstance().OnConversationNew(true, true, (PlayerFarming)null);
			HUD_Manager.Instance.Hide(false, 0, false);
			UIFollowerSelectMenuController followerSelectMenu = GameObjectExtensions.Instantiate<UIFollowerSelectMenuController>(MonoSingleton<UIManager>.Instance.FollowerSelectMenuTemplate);
			List<FollowerInfo> list = new List<FollowerInfo>();
			foreach (FollowerInfo follower in DataManager.Instance.Followers)
			{
				if ((int)follower.CursedState == 146)
				{
					list.Add(follower);
				}
			}
			followerSelectMenu.Show(MissionaryManager.FollowersAvailableForMission(), false, (Type)117, true, true, true, false);
			UIFollowerSelectMenuController obj = followerSelectMenu;
			((UIFollowerSelectBase<FollowerInformationBox>)(object)obj).OnFollowerSelected = (Action<FollowerInfo>)Delegate.Combine(((UIFollowerSelectBase<FollowerInformationBox>)(object)obj).OnFollowerSelected, new Action<FollowerInfo>(OnFollowerChosen));
			UIFollowerSelectMenuController obj2 = followerSelectMenu;
			((UIMenuBase)obj2).OnShown = (Action)Delegate.Combine(((UIMenuBase)obj2).OnShown, (Action)delegate
			{
				foreach (FollowerInformationBox followerInfoBox in ((UIFollowerSelectBase<FollowerInformationBox>)(object)followerSelectMenu)._followerInfoBoxes)
				{
					if (Plugin.summonList.Contains(((FollowerSelectItem)followerInfoBox)._followerInfo))
					{
						((TMP_Text)followerInfoBox.FollowerRole).text = "Currently Rallied! |  Health: " + (0.5 + (double)((FollowerSelectItem)followerInfoBox)._followerInfo.DwellingLevel) + " | Attack: " + (double)((FollowerSelectItem)followerInfoBox)._followerInfo.DwellingLevel * 0.5;
						followerInfoBox.FollowerSpine.AnimationState.SetAnimation(0, "attack-impact-multi", true);
					}
					else
					{
						((TMP_Text)followerInfoBox.FollowerRole).text = "Rally | Health: " + (0.5 + (double)((FollowerSelectItem)followerInfoBox)._followerInfo.DwellingLevel) + " | Attack: " + (double)((FollowerSelectItem)followerInfoBox)._followerInfo.DwellingLevel * 0.5;
					}
				}
			});
			UIFollowerSelectMenuController obj3 = followerSelectMenu;
			((UIMenuBase)obj3).OnHidden = (Action)Delegate.Combine(((UIMenuBase)obj3).OnHidden, (Action)delegate
			{
				followerSelectMenu = null;
				OnHidden();
			});
			UIFollowerSelectMenuController obj4 = followerSelectMenu;
			((UIMenuBase)obj4).OnCancel = (Action)Delegate.Combine(((UIMenuBase)obj4).OnCancel, (Action)delegate
			{
				followerSelectMenu = null;
				OnHidden();
			});
		}

		public override void OnSecondaryInteract(StateMachine state)
		{
			if (Activating)
			{
				return;
			}
			((Interaction)this).OnSecondaryInteract(state);
			Activating = true;
			GameManager.GetInstance().OnConversationNew(true, true, (PlayerFarming)null);
			HUD_Manager.Instance.Hide(false, 0, false);
			UIFollowerSelectMenuController followerSelectMenu = GameObjectExtensions.Instantiate<UIFollowerSelectMenuController>(MonoSingleton<UIManager>.Instance.FollowerSelectMenuTemplate);
			List<FollowerInfo> list = new List<FollowerInfo>();
			foreach (FollowerInfo follower in DataManager.Instance.Followers)
			{
				if (!Plugin.summonList.Contains(follower))
				{
					list.Add(follower);
				}
			}
			followerSelectMenu.Show(MissionaryManager.FollowersAvailableForMission(), false, (Type)117, true, true, true, false);
			UIFollowerSelectMenuController obj = followerSelectMenu;
			((UIFollowerSelectBase<FollowerInformationBox>)(object)obj).OnFollowerSelected = (Action<FollowerInfo>)Delegate.Combine(((UIFollowerSelectBase<FollowerInformationBox>)(object)obj).OnFollowerSelected, new Action<FollowerInfo>(OnCommanderChosen));
			UIFollowerSelectMenuController obj2 = followerSelectMenu;
			((UIMenuBase)obj2).OnShown = (Action)Delegate.Combine(((UIMenuBase)obj2).OnShown, (Action)delegate
			{
				foreach (FollowerInformationBox followerInfoBox in ((UIFollowerSelectBase<FollowerInformationBox>)(object)followerSelectMenu)._followerInfoBoxes)
				{
					if (Plugin.commander == ((FollowerSelectItem)followerInfoBox)._followerInfo)
					{
						((TMP_Text)followerInfoBox.FollowerRole).text = "Current Commander | Base Health: " + 4 + " | Attack: " + 3;
					}
					else
					{
						((TMP_Text)followerInfoBox.FollowerRole).text = "Select As Commander | Base Health: " + 4 + " | Attack: " + 3;
					}
				}
			});
			UIFollowerSelectMenuController obj3 = followerSelectMenu;
			((UIMenuBase)obj3).OnHidden = (Action)Delegate.Combine(((UIMenuBase)obj3).OnHidden, (Action)delegate
			{
				followerSelectMenu = null;
				OnHidden();
			});
			UIFollowerSelectMenuController obj4 = followerSelectMenu;
			((UIMenuBase)obj4).OnCancel = (Action)Delegate.Combine(((UIMenuBase)obj4).OnCancel, (Action)delegate
			{
				followerSelectMenu = null;
				OnHidden();
			});
			Activating = false;
		}

		public void OnHidden()
		{
			Activating = false;
			HUD_Manager.Instance.Show(1, false);
			GameManager.GetInstance().OnConversationEnd(true, true);
		}

		public void OnFollowerChosen(FollowerInfo followerInfo)
		{
			if (Plugin.summonList.Contains(followerInfo))
			{
				Plugin.summonList.Remove(followerInfo);
			}
			else
			{
				Plugin.summonList.Add(followerInfo);
			}
		}

		public void OnCommanderChosen(FollowerInfo followerInfo)
		{
			Plugin.commander = followerInfo;
		}
	}
	public class Interaction_RallyMulti : Interaction
	{
		public Structure Structure;

		private bool Activating = false;

		private GameObject Player;

		private float Delay = 0.04f;

		public float DistanceToTriggerDeposits = 5f;

		public StructuresData StructureInfo => Structure.Structure_Info;

		public RallyStructure RallyStructure => Structure.Brain as RallyStructure;

		public override void GetLabel()
		{
			base.secondaryLabel = "Unrally All followers";
			base.label = "Rally All Followers";
		}

		private void Start()
		{
			base.HasSecondaryInteraction = true;
		}

		public override void OnEnable()
		{
			((Interaction)this).OnEnable();
			Plugin.Log.LogInfo((object)"RallyMulti OnEnable");
			Structure = ((Component)((Component)this).GetComponentInParent<Transform>()).GetComponent<Structure>();
		}

		public override void OnInteract(StateMachine state)
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Invalid comparison between Unknown and I4
			Plugin.summoned = false;
			if (Activating)
			{
				return;
			}
			((Interaction)this).OnInteract(state);
			Activating = true;
			List<FollowerInfo> list = new List<FollowerInfo>();
			foreach (FollowerInfo follower in DataManager.Instance.Followers)
			{
				if ((int)follower.CursedState != 146)
				{
					list.Add(follower);
				}
			}
			Plugin.summonList.Clear();
			Plugin.summonList.AddRange(list);
			NotificationCentreScreen.Play("Rallied " + list.Count + " followers!");
			Activating = false;
		}

		public override void OnSecondaryInteract(StateMachine state)
		{
			if (!Activating)
			{
				((Interaction)this).OnSecondaryInteract(state);
				Activating = true;
				Plugin.summonList.Clear();
				NotificationCentreScreen.Play("Unrallied all followers!");
				Activating = false;
			}
		}

		public void OnHidden()
		{
			Activating = false;
			HUD_Manager.Instance.Show(1, false);
			GameManager.GetInstance().OnConversationEnd(true, true);
		}

		public void OnFollowerChosen(FollowerInfo followerInfo)
		{
			if (Plugin.summonList.Contains(followerInfo))
			{
				Plugin.summonList.Remove(followerInfo);
			}
			else
			{
				Plugin.summonList.Add(followerInfo);
			}
		}
	}
}
namespace SuperchargedFollowers.Helpers
{
	public class Bonuses
	{
		public static BuffStats GetClassBonuses(FollowerInfo followerInfo)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Invalid comparison between I4 and Unknown
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Invalid comparison between I4 and Unknown
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Invalid comparison between I4 and Unknown
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Invalid comparison between I4 and Unknown
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Invalid comparison between I4 and Unknown
			BuffStats buffStats = new BuffStats();
			foreach (InventoryItem item in followerInfo.Inventory)
			{
				if (item.type == (int)Plugin.holiday)
				{
					buffStats.HealthBonus = 4f;
					buffStats.ClassName = "Holiday";
					break;
				}
				if (item.type == (int)Plugin.warrior)
				{
					buffStats.AttackBonus = 2f;
					buffStats.HealthBonus = 2f;
					buffStats.ClassName = "Warrior";
					break;
				}
				if (item.type == (int)Plugin.missionary)
				{
					buffStats.HealthBonus = 1f;
					buffStats.MovementSpeedBonus = 0.02f;
					buffStats.ClassName = "Missionary";
					break;
				}
				if (item.type == (int)Plugin.undertaker)
				{
					buffStats.RegenBonus = 0.5f;
					buffStats.ClassName = "Undertaker";
					break;
				}
				if (item.type == (int)Plugin.prayer)
				{
					buffStats.AttackBonus = 4f;
					buffStats.ClassName = "Prayer";
					break;
				}
			}
			return buffStats;
		}

		public static BuffStats GetNecklaceBonuses(FollowerInfo followerInfo)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected I4, but got Unknown
			BuffStats buffStats = new BuffStats();
			ITEM_TYPE necklace = followerInfo.Necklace;
			ITEM_TYPE val = necklace;
			switch (val - 45)
			{
			case 0:
				buffStats.DelayBonus = 0.5f;
				break;
			case 1:
				buffStats.MovementSpeedBonus = 0.02f;
				break;
			case 2:
				buffStats.AttackBonus = 1f;
				break;
			case 3:
				buffStats.HealthBonus = 1f;
				break;
			case 4:
				buffStats.RegenBonus = 0.25f;
				break;
			}
			return buffStats;
		}

		public static BuffStats GetCommanderBonuses(FollowerInfo followerInfo)
		{
			BuffStats buffStats = new BuffStats();
			if (Plugin.commander == followerInfo)
			{
				buffStats.AttackBonus = 3f;
				buffStats.HealthBonus = 10f;
				buffStats.DelayBonus = 1f;
				buffStats.MovementSpeedBonus = 0.09f;
				buffStats.RegenBonus = 1.5f;
				buffStats.SizeBonus = 1f;
			}
			return buffStats;
		}

		public static BuffStats GetPrestigeBonuses(FollowerInfo followerInfo)
		{
			BuffStats buffStats = new BuffStats();
			int num = followerInfo.Inventory.Count((InventoryItem x) => x.type == (int)Plugin.prestige);
			if (num >= 100)
			{
				buffStats.CritChance = 0.1f;
				buffStats.Level = 10f;
			}
			if (num >= 80)
			{
				buffStats.DropPrestigeChance = 0.1f;
				buffStats.Level = 9f;
			}
			if (num >= 60)
			{
				buffStats.CurseRegenBonus = 1f;
				buffStats.Level = 8f;
			}
			if (num >= 40)
			{
				buffStats.BlueHealthChance = 0.2f;
				buffStats.Level = 7f;
			}
			if (num >= 20)
			{
				buffStats.RegenBonus = 0.5f;
				buffStats.Level = 6f;
			}
			if (num >= 15)
			{
				buffStats.HealthBonus = 0.5f;
				buffStats.DelayBonus = 0.5f;
				buffStats.Level = 5f;
			}
			if (num >= 12)
			{
				buffStats.HealthBonus += 0.5f;
				buffStats.AttackBonus += 0.5f;
				buffStats.Level = 4f;
			}
			if (num >= 9)
			{
				buffStats.HealthBonus += 1f;
				buffStats.MovementSpeedBonus += 0.03f;
				buffStats.Level = 3f;
			}
			if (num >= 6)
			{
				buffStats.HealthBonus += 0.5f;
				buffStats.AttackBonus += 0.25f;
				buffStats.Level = 2f;
			}
			if (num >= 3)
			{
				buffStats.HealthBonus += 0.5f;
				buffStats.AttackBonus += 0.5f;
				buffStats.Level = 1f;
			}
			return buffStats;
		}

		public static int PrestigeToNextLevel(FollowerInfo followerInfo)
		{
			int prestigeTotal = followerInfo.Inventory.Count((InventoryItem x) => x.type == (int)Plugin.prestige);
			List<int> source = new List<int> { 3, 6, 9, 12, 15, 20, 40, 60, 80, 100 };
			int num = source.FirstOrDefault((int x) => x > prestigeTotal);
			return num - prestigeTotal;
		}
	}
	public class BuffStats
	{
		public float AttackBonus { get; set; }

		public float HealthBonus { get; set; }

		public float DelayBonus { get; set; }

		public float MovementSpeedBonus { get; set; }

		public float RegenBonus { get; set; }

		public float BlueHealthChance { get; set; }

		public float CurseRegenBonus { get; set; }

		public float DropPrestigeChance { get; set; }

		public float CritChance { get; set; }

		public float Level { get; set; }

		public float SizeBonus { get; set; }

		public string ClassName { get; set; }
	}
	public class FollowerRoutines : MonoBehaviour
	{
		private EnemyFollower follower;

		private SuperchargedFollowersAIState myState = SuperchargedFollowersAIState.Idle;

		public void Start()
		{
			follower = ((Component)this).GetComponent<EnemyFollower>();
			Plugin.Log.LogInfo((object)("follower is " + (object)follower));
		}

		public Health GetRandomEnemy()
		{
			List<Health> team = Health.team2;
			int num = 10;
			int num2 = 0;
			if (team.Count > 0)
			{
				int index = Random.Range(0, team.Count);
				while (team[index].HP <= 0f && num2 < num)
				{
					Plugin.Log.LogInfo((object)"Attempting to find random enemy again as targeted a dead enemy");
					index = Random.Range(0, team.Count);
					num2++;
				}
				return team[index];
			}
			Plugin.Log.LogInfo((object)"Returning none");
			return null;
		}

		public IEnumerator<object> RunFollowerAI()
		{
			while (!GameManager.RoomActive)
			{
				yield return null;
			}
			((SkeletonRenderer)follower.Spine).Initialize(false);
			((UnitObject)follower).state.CURRENT_STATE = (State)0;
			follower.Spine.AnimationState.SetAnimation(0, "Conversations/idle-nice", true);
			Follower followerData = ((Component)follower).GetComponentInParent<Follower>();
			myState = SuperchargedFollowersAIState.Searching;
			Plugin.Log.LogInfo((object)("[STATE: " + myState.ToString() + "]" + followerData.Brain.Info.Name + " is ready for battle"));
			bool Loop = true;
			while (Loop)
			{
				while (!GameManager.RoomActive)
				{
					yield return null;
				}
				while (Health.team2.Count == 0)
				{
					follower.Spine.AnimationState.SetAnimation(1, "Conversations/idle-nice", true);
					myState = SuperchargedFollowersAIState.Idle;
					yield return (object)new WaitForSeconds(1f);
				}
				switch (myState)
				{
				case SuperchargedFollowersAIState.Searching:
				{
					Health nextTarget = GetRandomEnemy();
					if ((Object)(object)nextTarget != (Object)null && (int)nextTarget.team != 1)
					{
						follower.TargetObject = ((Component)nextTarget).gameObject;
						myState = SuperchargedFollowersAIState.Chasing;
					}
					else
					{
						myState = SuperchargedFollowersAIState.Idle;
						yield return (object)new WaitForSeconds(0.05f);
					}
					yield return null;
					break;
				}
				case SuperchargedFollowersAIState.Chasing:
				{
					follower.MyState = (State)0;
					((UnitObject)follower).state.CURRENT_STATE = (State)0;
					follower.Spine.AnimationState.SetAnimation(0, "Conversations/idle-nice", true);
					follower.AttackDelay = Random.Range(follower.AttackDelayRandomRange.x, follower.AttackDelayRandomRange.y);
					if (((UnitObject)follower).health.HasShield)
					{
						follower.AttackDelay = 2.5f;
					}
					follower.MaxAttackDelay = Random.Range(follower.MaxAttackDelayRandomRange.x, follower.MaxAttackDelayRandomRange.y);
					bool chasing = true;
					while (chasing)
					{
						if ((Object)(object)follower.TargetObject == (Object)null || (int)follower.TargetObject.GetComponent<Health>().team == 1)
						{
							Plugin.Log.LogInfo((object)("[STATE: " + myState.ToString() + "]" + followerData.Brain.Info.Name + " was chasing, now null"));
							yield return (object)new WaitForSeconds(0.2f);
							myState = SuperchargedFollowersAIState.Searching;
							break;
						}
						if ((Object)(object)follower.damageColliderEvents != (Object)null)
						{
							follower.damageColliderEvents.SetActive(false);
						}
						EnemyFollower obj3 = follower;
						obj3.TeleportDelay -= Time.deltaTime;
						EnemyFollower obj4 = follower;
						obj4.AttackDelay -= Time.deltaTime;
						EnemyFollower obj5 = follower;
						obj5.MaxAttackDelay -= Time.deltaTime;
						if ((int)follower.MyState == 0)
						{
							yield return (object)new WaitForSeconds(0.02f);
							if ((Object)(object)follower.TargetObject == (Object)null)
							{
								Plugin.Log.LogInfo((object)("[STATE: " + myState.ToString() + "]" + followerData.Brain.Info.Name + " was chasing, now null after waiting"));
								myState = SuperchargedFollowersAIState.Searching;
								break;
							}
							if (follower.Spine.AnimationName != "roll-stop" && (int)((UnitObject)follower).state.CURRENT_STATE == 1 && follower.Spine.AnimationName != "run")
							{
								follower.Spine.AnimationState.SetAnimation(1, "run", true);
							}
							((UnitObject)follower).state.LookAngle = Utils.GetAngle(((Component)follower).transform.position, follower.TargetObject.transform.position);
							((SkeletonRenderer)follower.Spine).skeleton.ScaleX = (((double)((UnitObject)follower).state.LookAngle <= 90.0 || (double)((UnitObject)follower).state.LookAngle >= 270.0) ? (-1f) : 1f);
							int num2;
							if ((int)((UnitObject)follower).state.CURRENT_STATE == 0)
							{
								EnemyFollower obj6 = follower;
								num2 = (((double)(obj6.RepathTimer -= Time.deltaTime) < 0.0) ? 1 : 0);
							}
							else
							{
								num2 = 0;
							}
							if (num2 != 0)
							{
								if (follower.CustomAttackLogic())
								{
									break;
								}
								if ((double)follower.MaxAttackDelay < 0.0 || (double)Vector3.Distance(((Component)follower).transform.position, follower.TargetObject.transform.position) < (double)follower.AttackWithinRange)
								{
									if (follower.ChargeAndAttack && ((double)follower.MaxAttackDelay < 0.0 || (double)follower.AttackDelay < 0.0))
									{
										try
										{
											Health health = follower.TargetObject.GetComponent<Health>();
											if (health.HP <= 0f)
											{
												Plugin.Log.LogInfo((object)("[STATE: " + myState.ToString() + "]" + followerData.Brain.Info.Name + " attacked at 0 hp, so find new target"));
												myState = SuperchargedFollowersAIState.Searching;
											}
											else
											{
												((UnitObject)follower).health.invincible = false;
												myState = SuperchargedFollowersAIState.Attacking;
											}
										}
										catch (Exception ex)
										{
											Exception e = ex;
											Plugin.Log.LogInfo((object)("[STATE: " + myState.ToString() + "]" + followerData.Brain.Info.Name + " attacked a null enemy, reset to Searching"));
											Plugin.Log.LogInfo((object)("Attacking an null enemy " + e.Message));
											myState = SuperchargedFollowersAIState.Searching;
										}
										break;
									}
									if (!((UnitObject)follower).health.HasShield)
									{
										follower.Angle = (float)(((double)Utils.GetAngle(follower.TargetObject.transform.position, ((Component)follower).transform.position) + (double)Random.Range(-20, 20)) * (Math.PI / 180.0));
										follower.TargetPosition = follower.TargetObject.transform.position + new Vector3(follower.MaintainTargetDistance * Mathf.Cos(follower.Angle), follower.MaintainTargetDistance * Mathf.Sin(follower.Angle));
										follower.FindPath(follower.TargetPosition);
									}
								}
								else if ((double)Vector3.Distance(((Component)follower).transform.position, follower.TargetObject.transform.position) > (double)follower.MoveCloserDistance + (((UnitObject)follower).health.HasShield ? 0.0 : 1.0))
								{
									follower.Angle = (float)(((double)Utils.GetAngle(follower.TargetObject.transform.position, ((Component)follower).transform.position) + (double)Random.Range(-20, 20)) * (Math.PI / 180.0));
									follower.TargetPosition = follower.TargetObject.transform.position + new Vector3(follower.MaintainTargetDistance * Mathf.Cos(follower.Angle), follower.MaintainTargetDistance * Mathf.Sin(follower.Angle));
									follower.FindPath(follower.TargetPosition);
								}
							}
						}
						yield return null;
					}
					yield return null;
					break;
				}
				case SuperchargedFollowersAIState.Attacking:
				{
					if ((Object)(object)follower.TargetObject == (Object)null)
					{
						Plugin.Log.LogInfo((object)("[STATE: " + myState.ToString() + "]" + followerData.Brain.Info.Name + " precheck: lost enemy, reset to search"));
						myState = SuperchargedFollowersAIState.Searching;
						break;
					}
					follower.MyState = (State)2;
					((UnitObject)follower).UsePathing = true;
					((UnitObject)follower).givePath(follower.TargetObject.transform.position, (GameObject)null, false);
					follower.Spine.AnimationState.SetAnimation(1, "run", true);
					follower.RepathTimer = 0f;
					int NumAttacks = ((!follower.DoubleAttack) ? 1 : 2);
					int AttackCount = 1;
					float attackDistance = 1.5f;
					float MaxAttackSpeed = 15f;
					float AttackSpeed = MaxAttackSpeed;
					bool attacking = true;
					float SignPostDelay = 0.5f;
					while (attacking)
					{
						State val2;
						try
						{
							((UnitObject)follower).Seperate(0.5f, false);
							if ((Object)(object)follower.TargetObject == (Object)null)
							{
								Plugin.Log.LogInfo((object)("[STATE: " + myState.ToString() + "]" + followerData.Brain.Info.Name + " lost enemy, reset to search"));
								myState = SuperchargedFollowersAIState.Searching;
								break;
							}
							if ((int)((UnitObject)follower).state.CURRENT_STATE == 0)
							{
								((UnitObject)follower).state.CURRENT_STATE = (State)1;
							}
							State cURRENT_STATE = ((UnitObject)follower).state.CURRENT_STATE;
							State val = cURRENT_STATE;
							val2 = val;
							switch (val2 - 1)
							{
							case 0:
								((UnitObject)follower).state.LookAngle = Utils.GetAngle(((Component)follower).transform.position, follower.TargetObject.transform.position);
								((SkeletonRenderer)follower.Spine).skeleton.ScaleX = (((double)((UnitObject)follower).state.LookAngle <= 90.0 || (double)((UnitObject)follower).state.LookAngle >= 270.0) ? (-1f) : 1f);
								((UnitObject)follower).state.LookAngle = (((UnitObject)follower).state.facingAngle = Utils.GetAngle(((Component)follower).transform.position, follower.TargetObject.transform.position));
								if ((double)Vector2.Distance(Vector2.op_Implicit(((Component)follower).transform.position), Vector2.op_Implicit(follower.TargetObject.transform.position)) < (double)attackDistance)
								{
									((UnitObject)follower).state.CURRENT_STATE = (State)4;
									string animationName3 = "attack-charge";
									follower.Spine.AnimationState.SetAnimation(1, animationName3, false);
								}
								else
								{
									EnemyFollower obj = follower;
									if ((double)(obj.RepathTimer += Time.deltaTime) > 0.20000000298023224)
									{
										follower.RepathTimer = 0f;
										((UnitObject)follower).givePath(follower.TargetObject.transform.position, (GameObject)null, false);
									}
									if ((Object)(object)follower.damageColliderEvents != (Object)null)
									{
										if ((double)((UnitObject)follower).state.Timer < 0.20000000298023224 && !((UnitObject)follower).health.WasJustParried)
										{
											follower.damageColliderEvents.SetActive(true);
										}
										else
										{
											follower.damageColliderEvents.SetActive(false);
										}
									}
								}
								if ((Object)(object)follower.damageColliderEvents != (Object)null)
								{
									follower.damageColliderEvents.SetActive(false);
								}
								break;
							case 3:
							{
								if ((Object)(object)follower.damageColliderEvents != (Object)null)
								{
									follower.damageColliderEvents.SetActive(false);
								}
								StateMachine state2 = ((UnitObject)follower).state;
								state2.Timer += Time.deltaTime;
								if ((double)((UnitObject)follower).state.Timer >= (double)SignPostDelay - (double)EnemyFollower.signPostParryWindow)
								{
									follower.canBeParried = true;
								}
								if ((int)((UnitObject)follower).health.team == 1 && (Object)(object)follower.TargetObject != (Object)null)
								{
									((UnitObject)follower).state.LookAngle = Utils.GetAngle(((Component)follower).transform.position, follower.TargetObject.transform.position);
									((SkeletonRenderer)follower.Spine).skeleton.ScaleX = (((double)((UnitObject)follower).state.LookAngle <= 90.0 || (double)((UnitObject)follower).state.LookAngle >= 270.0) ? (-1f) : 1f);
									((UnitObject)follower).state.LookAngle = (((UnitObject)follower).state.facingAngle = Utils.GetAngle(((Component)follower).transform.position, follower.TargetObject.transform.position));
								}
								if ((double)((UnitObject)follower).state.Timer >= (double)SignPostDelay)
								{
									((UnitObject)follower).state.CURRENT_STATE = (State)5;
									string animationName2 = ((follower.variant == 0) ? "attack-impact" : "attack-impact-multi");
									follower.Spine.AnimationState.SetAnimation(1, animationName2, false);
									follower.canBeParried = true;
									((MonoBehaviour)follower).StartCoroutine(follower.EnableDamageCollider(0f));
									if (follower.variant == 1)
									{
										((MonoBehaviour)follower).StartCoroutine(follower.EnableDamageCollider(0.7f));
										((MonoBehaviour)follower).StartCoroutine(follower.EnableDamageCollider(1.4f));
									}
									if (!string.IsNullOrEmpty(follower.attackSoundPath))
									{
										AudioManager.Instance.PlayOneShot(follower.attackSoundPath, ((Component)follower).transform.position);
									}
								}
								break;
							}
							case 4:
							{
								if ((double)AttackSpeed > 0.0)
								{
									AttackSpeed -= 1f * GameManager.DeltaTime;
								}
								follower.Spine.AnimationState.SetAnimation(0, "Conversations/idle-nice", true);
								follower.canBeParried = ((UnitObject)follower).state.Timer <= EnemyFollower.attackParryWindow;
								StateMachine state = ((UnitObject)follower).state;
								if ((double)(state.Timer += Time.deltaTime) >= 0.6)
								{
									int num = AttackCount + 1;
									AttackCount = num;
									if (num <= NumAttacks)
									{
										AttackSpeed = MaxAttackSpeed + (float)((3 - NumAttacks) * 2);
										((UnitObject)follower).state.CURRENT_STATE = (State)4;
										follower.variant = Random.Range(0, 2);
										string animationName = "attack-charge";
										follower.Spine.AnimationState.SetAnimation(1, animationName, false);
										SignPostDelay = 0.3f;
									}
									else
									{
										attacking = false;
									}
								}
								break;
							}
							}
							goto IL_185a;
						}
						catch (Exception ex)
						{
							Exception e2 = ex;
							ManualLogSource log = Plugin.Log;
							string[] obj2 = new string[8]
							{
								"[STATE: ",
								myState.ToString(),
								"]",
								followerData.Brain.Info.Name,
								" hard reset to idle due to something went wrong when attacking at state [",
								null,
								null,
								null
							};
							val2 = ((UnitObject)follower).state.CURRENT_STATE;
							obj2[5] = ((object)(State)(ref val2)).ToString();
							obj2[6] = "]: ";
							obj2[7] = e2.Message;
							log.LogInfo((object)string.Concat(obj2));
							myState = SuperchargedFollowersAIState.Searching;
						}
						break;
						IL_185a:
						yield return null;
					}
					myState = SuperchargedFollowersAIState.Chasing;
					yield return null;
					break;
				}
				case SuperchargedFollowersAIState.Idle:
					myState = SuperchargedFollowersAIState.Searching;
					yield return null;
					break;
				default:
					Plugin.Log.LogInfo((object)("[STATE: " + myState.ToString() + "]" + followerData.Brain.Info.Name + " is fallback to default state, will search again"));
					myState = SuperchargedFollowersAIState.Searching;
					yield return null;
					break;
				}
				yield return null;
			}
			yield return null;
		}

		public IEnumerator<object> RepositionSelfIfOutside()
		{
			yield return (object)new WaitForSeconds(2f);
			if (BiomeGenerator.Instance.CurrentRoom.Completed)
			{
				Plugin.Log.LogInfo((object)"Follower reposition to player");
				((Component)follower).transform.position = ((Component)PlayerFarming.Instance).transform.position;
			}
		}
	}
	public enum SuperchargedFollowersAIState
	{
		Idle,
		Searching,
		Chasing,
		Attacking
	}
}