Decompiled source of TFTItems v1.1.2

BepInEx/plugins/Phorg.TFTItems/ExamplePlugin.dll

Decompiled 2 months ago
using System;
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.Logging;
using Microsoft.CodeAnalysis;
using On.RoR2;
using R2API;
using RoR2;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Networking;

[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: AssemblyCompany("ExamplePlugin")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+55d03d1a44b7027c98ea24af5ab2afc50c10b02a")]
[assembly: AssemblyProduct("ExamplePlugin")]
[assembly: AssemblyTitle("ExamplePlugin")]
[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 ExamplePlugin
{
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("Phorg.TFTItems", "TFTItems", "1.1.2")]
	public class ExamplePlugin : BaseUnityPlugin
	{
		public static class AssetLoader
		{
			private static string pluginDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);

			private static string bundlePath = Path.Combine(pluginDir, "AssetBundles", "prefabs");

			private static AssetBundle bundle = AssetBundle.LoadFromFile(bundlePath);

			public static GameObject LoadAsset(string assetName)
			{
				if ((Object)(object)bundle == (Object)null)
				{
					Debug.LogError((object)("Failed to load bundle at " + bundlePath));
				}
				return bundle.LoadAsset<GameObject>(assetName);
			}

			public static void ListAllAssets()
			{
				string[] allAssetNames = bundle.GetAllAssetNames();
				foreach (string text in allAssetNames)
				{
					Chat.AddMessage("Bundle contains asset: " + text);
				}
			}
		}

		public const string PluginGUID = "Phorg.TFTItems";

		public const string PluginAuthor = "Phorg";

		public const string PluginName = "TFTItems";

		public const string PluginVersion = "1.1.2";

		public void Awake()
		{
			Log.Init(((BaseUnityPlugin)this).Logger);
			TempVFX.Load();
			PulseHitVFXListener.Init();
			AllyArmor.Define();
			AllyArmor.Hooks();
			FlickerBlade.Define();
			FlickerBlade.Hooks();
			HorizonFocus.Define();
			HorizonFocus.Hooks();
			UnendingDespair.Define();
			UnendingDespair.Hooks();
			SoulLink.Define();
			SoulLink.Hooks();
			RegisterLanguage();
		}

		private void Update()
		{
		}

		private static void RegisterLanguage()
		{
			LanguageAPI.Add("FLICKERBLADE_NAME", "Flicker Blade");
			LanguageAPI.Add("FLICKERBLADE_PICKUP", "Primary hits grant stacking attack-speed.");
			LanguageAPI.Add("FLICKERBLADE_DESC", "Hits with your <style=cIsUtility>Primary skill</style> grant a stacking buff that increases <style=cIsDamage>Attack Speed by 5% (+1% per stack)</style> for <style=cIsUtility>0.5s (+0.5s per stack)</style>. Duration refreshes on each hit.");
			LanguageAPI.Add("FLICKERBLADE_LORE", "“The blade is faster than thought…”");
			LanguageAPI.Add("LOCKET_OF_THE_IRON_SOLARI_NAME", "Locket of the Iron Solari");
			LanguageAPI.Add("LOCKET_OF_THE_IRON_SOLARI_PICKUP", "Allies gain armour from your presence.");
			LanguageAPI.Add("LOCKET_OF_THE_IRON_SOLARI_DESC", "<style=cIsHealing>Increase armor</style> for minions by <style=cIsHealing>10</style> (+10 per stack).");
			LanguageAPI.Add("LOCKET_OF_THE_IRON_SOLARI_LORE", "The sun’s protection, entrusted to you.");
			LanguageAPI.Add("UNENDING_DESPAIR_NAME", "Unending Despair");
			LanguageAPI.Add("UNENDING_DESPAIR_PICKUP", "Gain barrier out-of-combat. Lost barrier erupts in damaging pulses.");
			LanguageAPI.Add("UNENDING_DESPAIR_DESC", "Out-of-combat, regenerate a <style=cIsHealing>temporary barrier</style> for <style=cIsHealing>10%</style> max health.Losing more than <style=cIsHealing>10%</style> max health in barrier, will emit a pulse dealing <style=cIsDamage>250% of the lost amount</style> (+150% per stack). ");
			LanguageAPI.Add("UNENDING_DESPAIR_LORE", "Hope is a candle; despair the wind.");
			LanguageAPI.Add("HORIZON_FOCUS_NAME", "Horizon Focus");
			LanguageAPI.Add("HORIZON_FOCUS_PICKUP", "Stunned enemies lose a portion of their health.");
			LanguageAPI.Add("HORIZON_FOCUS_DESC", "When you <style=cIsDamage>stun or shock</style> an enemy, deal <style=cIsDamage>20%</style> of their current health (+5% per stack) as additional damage.");
			LanguageAPI.Add("HORIZON_FOCUS_LORE", "The world narrows to a single point…");
			LanguageAPI.Add("KNIGHTS_VOW_NAME", "Knight’s Vow");
			LanguageAPI.Add("KNIGHTS_VOW_PICKUP", "Bond to an ally; redirect damage and share healing.");
			LanguageAPI.Add("KNIGHTS_VOW_DESC", "Bond to an ally; redirect \n- If the ally is a <style=cIsUtility>Player</style>: Redirect <style=cIsHealing>20%</style> of their post-mitigated damage to you. When they deal damage, heal you for 15% of damage dealt.\n- If the ally is a <style=cIsUtility>Minion</style>: Redirect <style=cIsHealing>20%</style> of your post-mitigated damage to the minion. When you deal damage, heal the minion for 15% of damage dealt.");
			LanguageAPI.Add("KNIGHTS_VOW_LORE", "A pledge to stand between harm and those who cannot stand alone.");
		}

		public static Sprite LoadSpriteFromFile(string fileName)
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Expected O, but got Unknown
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
			string text = Path.Combine(directoryName, "icons", fileName);
			if (!File.Exists(text))
			{
				Debug.LogError((object)(fileName + " Icon not found at path: " + text));
				return null;
			}
			byte[] array = File.ReadAllBytes(text);
			Texture2D val = new Texture2D(2, 2, (TextureFormat)5, false);
			if (!ImageConversion.LoadImage(val, array))
			{
				Debug.LogError((object)(fileName + " Failed to load image data."));
				return null;
			}
			return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f));
		}
	}
	internal static class FlickerBlade
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static hook_ProcessHitEnemy <0>__AddAttackSpeedBuff;

			public static StatHookEventHandler <1>__ApplyRageBuff;
		}

		internal static ItemDef ItemDef;

		internal static BuffDef RageBuff;

		internal static void Define()
		{
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Expected O, but got Unknown
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Expected O, but got Unknown
			RageBuff = ScriptableObject.CreateInstance<BuffDef>();
			((Object)RageBuff).name = "RAGEBLADE_STACK";
			RageBuff.iconSprite = ExamplePlugin.LoadSpriteFromFile("FlickerBladeBuff.png");
			RageBuff.canStack = true;
			RageBuff.isDebuff = false;
			RageBuff.isCooldown = false;
			RageBuff.isHidden = false;
			ContentAddition.AddBuffDef(RageBuff);
			ItemDef = ScriptableObject.CreateInstance<ItemDef>();
			((Object)ItemDef).name = "FLICKERBLADE_NAME";
			ItemDef.nameToken = "FLICKERBLADE_NAME";
			ItemDef.pickupToken = "FLICKERBLADE_PICKUP";
			ItemDef.descriptionToken = "FLICKERBLADE_DESC";
			ItemDef.loreToken = "FLICKERBLADE_LORE";
			ItemDef.tier = (ItemTier)2;
			ItemDef._itemTierDef = Addressables.LoadAssetAsync<ItemTierDef>((object)"RoR2/Base/Common/Tier3Def.asset").WaitForCompletion();
			ItemDef.pickupIconSprite = ExamplePlugin.LoadSpriteFromFile("FlickerBlade.png");
			ItemDef.canRemove = true;
			ItemDef.hidden = false;
			GameObject pickupModelPrefab = ExamplePlugin.AssetLoader.LoadAsset("flickerBladeItem");
			ItemDef.pickupModelPrefab = pickupModelPrefab;
			ItemAPI.Add(new CustomItem(ItemDef, new ItemDisplayRuleDict((ItemDisplayRule[])null)));
		}

		internal static void Hooks()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected O, but got Unknown
			object obj = <>O.<0>__AddAttackSpeedBuff;
			if (obj == null)
			{
				hook_ProcessHitEnemy val = AddAttackSpeedBuff;
				<>O.<0>__AddAttackSpeedBuff = val;
				obj = (object)val;
			}
			GlobalEventManager.ProcessHitEnemy += (hook_ProcessHitEnemy)obj;
			object obj2 = <>O.<1>__ApplyRageBuff;
			if (obj2 == null)
			{
				StatHookEventHandler val2 = ApplyRageBuff;
				<>O.<1>__ApplyRageBuff = val2;
				obj2 = (object)val2;
			}
			RecalculateStatsAPI.GetStatCoefficients += (StatHookEventHandler)obj2;
		}

		private static void AddAttackSpeedBuff(orig_ProcessHitEnemy orig, GlobalEventManager self, DamageInfo di, GameObject victim)
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			orig.Invoke(self, di, victim);
			CharacterBody val = (Object.op_Implicit((Object)(object)di.attacker) ? di.attacker.GetComponent<CharacterBody>() : null);
			if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.inventory))
			{
				return;
			}
			bool flag = ((Enum)di.damageType.damageSource).HasFlag((Enum)(object)(DamageSource)1);
			int itemCount = val.inventory.GetItemCount(ItemDef.itemIndex);
			if (flag && itemCount != 0)
			{
				float num = 0.5f + 0.5f * (float)itemCount;
				int buffCount = val.GetBuffCount(RageBuff);
				val.ClearTimedBuffs(RageBuff);
				for (int i = 0; i <= buffCount; i++)
				{
					val.AddTimedBuff(RageBuff, num);
				}
			}
		}

		private static void ApplyRageBuff(CharacterBody body, StatHookEventArgs args)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			int buffCount = body.GetBuffCount(RageBuff);
			if (buffCount != 0)
			{
				int num = (Object.op_Implicit((Object)(object)body.inventory) ? body.inventory.GetItemCount(ItemDef.itemIndex) : 0);
				float num2 = 0.05f + 0.01f * (float)(num - 1);
				args.attackSpeedMultAdd += num2 * (float)buffCount;
			}
		}
	}
	internal static class HorizonFocus
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static hook_OnDeathStart <>9__6_0;

			internal void <Hooks>b__6_0(orig_OnDeathStart orig, CharacterBody self)
			{
				if (NetworkServer.active)
				{
					_victimReadyAt.Remove(self);
				}
				orig.Invoke(self);
			}
		}

		internal static ItemDef ItemDef;

		private const float BasePctCurrent = 0.1f;

		private const float StackBonusPct = 0.05f;

		private const float IcdSeconds = 1f;

		private static readonly Dictionary<CharacterBody, float> _victimReadyAt = new Dictionary<CharacterBody, float>();

		internal static void Define()
		{
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: 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 O, but got Unknown
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Expected O, but got Unknown
			ItemDef = ScriptableObject.CreateInstance<ItemDef>();
			((Object)ItemDef).name = "HORIZON_FOCUS_NAME";
			ItemDef.nameToken = "HORIZON_FOCUS_NAME";
			ItemDef.pickupToken = "HORIZON_FOCUS_PICKUP";
			ItemDef.descriptionToken = "HORIZON_FOCUS_DESC";
			ItemDef.loreToken = "HORIZON_FOCUS_LORE";
			ItemDef.tier = (ItemTier)1;
			ItemDef._itemTierDef = Addressables.LoadAssetAsync<ItemTierDef>((object)"RoR2/Base/Common/Tier2Def.asset").WaitForCompletion();
			ItemDef.pickupIconSprite = ExamplePlugin.LoadSpriteFromFile("HorizonFocus.png");
			ItemDef.canRemove = true;
			ItemDef.hidden = false;
			GameObject pickupModelPrefab = ExamplePlugin.AssetLoader.LoadAsset("horizonFocusItem");
			ItemDef.pickupModelPrefab = pickupModelPrefab;
			ItemAPI.Add(new CustomItem(ItemDef, new ItemDisplayRuleDict((ItemDisplayRule[])null)));
		}

		internal static void Hooks()
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Expected O, but got Unknown
			GlobalEventManager.onServerDamageDealt += OnServerDamageDealt;
			object obj = <>c.<>9__6_0;
			if (obj == null)
			{
				hook_OnDeathStart val = delegate(orig_OnDeathStart orig, CharacterBody self)
				{
					if (NetworkServer.active)
					{
						_victimReadyAt.Remove(self);
					}
					orig.Invoke(self);
				};
				<>c.<>9__6_0 = val;
				obj = (object)val;
			}
			CharacterBody.OnDeathStart += (hook_OnDeathStart)obj;
		}

		private static void OnServerDamageDealt(DamageReport report)
		{
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: 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_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: 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_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Expected O, but got Unknown
			if (!NetworkServer.active || report == null)
			{
				return;
			}
			CharacterBody victimBody = report.victimBody;
			CharacterBody attackerBody = report.attackerBody;
			if (!Object.op_Implicit((Object)(object)victimBody) || !Object.op_Implicit((Object)(object)attackerBody))
			{
				return;
			}
			Inventory inventory = attackerBody.inventory;
			int num = (Object.op_Implicit((Object)(object)inventory) ? inventory.GetItemCount(ItemDef) : 0);
			if (num <= 0)
			{
				return;
			}
			DamageTypeCombo damageType = report.damageInfo.damageType;
			if (DamageTypeCombo.op_Implicit(damageType & DamageTypeCombo.op_Implicit((DamageType)32)) == 0L && DamageTypeCombo.op_Implicit(damageType & DamageTypeCombo.op_Implicit((DamageType)16777216)) == 0)
			{
				return;
			}
			float time = Time.time;
			if (_victimReadyAt.TryGetValue(victimBody, out var value) && time < value)
			{
				return;
			}
			_victimReadyAt[victimBody] = time + 1f;
			HealthComponent healthComponent = victimBody.healthComponent;
			if (!Object.op_Implicit((Object)(object)healthComponent) || !healthComponent.alive)
			{
				return;
			}
			float num2 = 0.1f + 0.05f * (float)Mathf.Max(0, num - 1);
			if (victimBody.isBoss || victimBody.isChampion)
			{
				num2 *= 0.5f;
			}
			float num3 = healthComponent.combinedHealth * num2;
			if (!(num3 <= 0f))
			{
				DamageInfo val = new DamageInfo
				{
					attacker = ((Component)attackerBody).gameObject,
					inflictor = report.damageInfo.inflictor,
					damage = num3,
					position = victimBody.corePosition,
					damageType = DamageTypeCombo.op_Implicit((DamageType)2049),
					procCoefficient = 0f,
					crit = false,
					damageColorIndex = (DamageColorIndex)3
				};
				healthComponent.TakeDamage(val);
				GlobalEventManager instance = GlobalEventManager.instance;
				if (instance != null)
				{
					instance.OnHitEnemy(val, ((Component)victimBody).gameObject);
				}
			}
		}

		private static bool IsPlayer(CharacterBody b)
		{
			if (!Object.op_Implicit((Object)(object)b))
			{
				return false;
			}
			if (b.isPlayerControlled)
			{
				return true;
			}
			CharacterMaster master = b.master;
			return Object.op_Implicit((Object)(object)master) && (Object)(object)master.playerCharacterMasterController != (Object)null;
		}
	}
	internal static class AllyArmor
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static StatHookEventHandler <0>__GrantAllyArmor;
		}

		internal static ItemDef ItemDef;

		internal static void Define()
		{
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: 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 O, but got Unknown
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Expected O, but got Unknown
			ItemDef = ScriptableObject.CreateInstance<ItemDef>();
			((Object)ItemDef).name = "LOCKET_OF_THE_IRON_SOLARI_NAME";
			ItemDef.nameToken = "LOCKET_OF_THE_IRON_SOLARI_NAME";
			ItemDef.pickupToken = "LOCKET_OF_THE_IRON_SOLARI_PICKUP";
			ItemDef.descriptionToken = "LOCKET_OF_THE_IRON_SOLARI_DESC";
			ItemDef.loreToken = "LOCKET_OF_THE_IRON_SOLARI_LORE";
			ItemDef.tier = (ItemTier)0;
			ItemDef._itemTierDef = Addressables.LoadAssetAsync<ItemTierDef>((object)"RoR2/Base/Common/Tier1Def.asset").WaitForCompletion();
			ItemDef.pickupIconSprite = ExamplePlugin.LoadSpriteFromFile("Locket.png");
			ItemDef.canRemove = true;
			ItemDef.hidden = false;
			GameObject pickupModelPrefab = ExamplePlugin.AssetLoader.LoadAsset("locketItem");
			ItemDef.pickupModelPrefab = pickupModelPrefab;
			ItemAPI.Add(new CustomItem(ItemDef, new ItemDisplayRuleDict((ItemDisplayRule[])null)));
		}

		internal static void Hooks()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			object obj = <>O.<0>__GrantAllyArmor;
			if (obj == null)
			{
				StatHookEventHandler val = GrantAllyArmor;
				<>O.<0>__GrantAllyArmor = val;
				obj = (object)val;
			}
			RecalculateStatsAPI.GetStatCoefficients += (StatHookEventHandler)obj;
		}

		private static void GrantAllyArmor(CharacterBody body, StatHookEventArgs args)
		{
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)body) || !Object.op_Implicit((Object)(object)body.master))
			{
				return;
			}
			CharacterMaster master = body.master;
			if ((Object)(object)master.playerCharacterMasterController != (Object)null || !Object.op_Implicit((Object)(object)master.minionOwnership.ownerMaster))
			{
				return;
			}
			Inventory inventory = master.minionOwnership.ownerMaster.inventory;
			if (Object.op_Implicit((Object)(object)inventory))
			{
				int itemCount = inventory.GetItemCount(ItemDef.itemIndex);
				if (itemCount > 0)
				{
					float num = (float)itemCount * 10f;
					args.armorAdd += num;
				}
			}
		}

		private static void AfterRecalc(orig_RecalculateStats orig, CharacterBody body)
		{
			float armor = body.armor;
			orig.Invoke(body);
			float armor2 = body.armor;
			if (armor2 != armor)
			{
				Chat.AddMessage($"[DEBUG] {body.GetDisplayName()} armor: {armor} → {armor2}");
			}
		}
	}
	internal static class Log
	{
		private static ManualLogSource _logSource;

		internal static void Init(ManualLogSource logSource)
		{
			_logSource = logSource;
		}

		internal static void Debug(object data)
		{
			_logSource.LogDebug(data);
		}

		internal static void Error(object data)
		{
			_logSource.LogError(data);
		}

		internal static void Fatal(object data)
		{
			_logSource.LogFatal(data);
		}

		internal static void Info(object data)
		{
			_logSource.LogInfo(data);
		}

		internal static void Message(object data)
		{
			_logSource.LogMessage(data);
		}

		internal static void Warning(object data)
		{
			_logSource.LogWarning(data);
		}
	}
	internal static class SoulLink
	{
		public static class Targeting
		{
			[Serializable]
			[CompilerGenerated]
			private sealed class <>c
			{
				public static readonly <>c <>9 = new <>c();

				public static hook_Update <>9__3_0;

				public static hook_OnDestroy <>9__3_1;

				internal void <HookIndicator>b__3_0(orig_Update orig, EquipmentSlot self)
				{
					orig.Invoke(self);
					UpdateIndicator(self);
				}

				internal void <HookIndicator>b__3_1(orig_OnDestroy orig, EquipmentSlot self)
				{
					if (_inds.TryGetValue(self, out var value) && value != null)
					{
						value.active = false;
					}
					_inds.Remove(self);
					orig.Invoke(self);
				}
			}

			private static GameObject _visPrefab;

			private static readonly Dictionary<EquipmentSlot, Indicator> _inds = new Dictionary<EquipmentSlot, Indicator>();

			internal static void PreloadIndicatorPrefab()
			{
				//IL_002e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0033: Unknown result type (might be due to invalid IL or missing references)
				string[] array = new string[3] { "RoR2/Base/Equipment/PassiveHealing/WoodSpriteIndicator.prefab", "RoR2/Base/Lightning/LightningIndicator.prefab", "RoR2/Base/Recycler/RecyclerIndicator.prefab" };
				string[] array2 = array;
				foreach (string text in array2)
				{
					try
					{
						GameObject val = Addressables.LoadAssetAsync<GameObject>((object)text).WaitForCompletion();
						if (Object.op_Implicit((Object)(object)val))
						{
							_visPrefab = val;
							break;
						}
					}
					catch
					{
					}
				}
				bool flag = false;
			}

			internal static void HookIndicator()
			{
				//IL_0015: Unknown result type (might be due to invalid IL or missing references)
				//IL_001a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0020: Expected O, but got Unknown
				//IL_003a: Unknown result type (might be due to invalid IL or missing references)
				//IL_003f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0045: Expected O, but got Unknown
				object obj = <>c.<>9__3_0;
				if (obj == null)
				{
					hook_Update val = delegate(orig_Update orig, EquipmentSlot self)
					{
						orig.Invoke(self);
						UpdateIndicator(self);
					};
					<>c.<>9__3_0 = val;
					obj = (object)val;
				}
				EquipmentSlot.Update += (hook_Update)obj;
				object obj2 = <>c.<>9__3_1;
				if (obj2 == null)
				{
					hook_OnDestroy val2 = delegate(orig_OnDestroy orig, EquipmentSlot self)
					{
						if (_inds.TryGetValue(self, out var value) && value != null)
						{
							value.active = false;
						}
						_inds.Remove(self);
						orig.Invoke(self);
					};
					<>c.<>9__3_1 = val2;
					obj2 = (object)val2;
				}
				EquipmentSlot.OnDestroy += (hook_OnDestroy)obj2;
			}

			private static void UpdateIndicator(EquipmentSlot slot)
			{
				//IL_0047: Unknown result type (might be due to invalid IL or missing references)
				//IL_0051: Unknown result type (might be due to invalid IL or missing references)
				//IL_009d: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a3: Expected O, but got Unknown
				CharacterBody characterBody = slot.characterBody;
				Inventory val = (Object.op_Implicit((Object)(object)characterBody) ? characterBody.inventory : null);
				if (slot.stock <= 0 || slot.cooldownTimer > 0f)
				{
					return;
				}
				bool flag = Object.op_Implicit((Object)(object)val) && val.currentEquipmentIndex == ItemDef.equipmentIndex;
				if (!_inds.TryGetValue(slot, out var value) || value == null)
				{
					GameObject visPrefab = _visPrefab;
					if (!Object.op_Implicit((Object)(object)visPrefab))
					{
						return;
					}
					value = new Indicator(((Component)slot).gameObject, visPrefab);
					value.active = false;
					_inds[slot] = value;
				}
				if (!flag || !Object.op_Implicit((Object)(object)characterBody) || !Object.op_Implicit((Object)(object)characterBody.teamComponent))
				{
					value.active = false;
					value.targetTransform = null;
				}
				else
				{
					HurtBox val2 = FindFriendlyHurtboxInAim(slot, MaxRange, 20f);
					value.targetTransform = (Object.op_Implicit((Object)(object)val2) ? ((Component)val2).transform : null);
					value.active = Object.op_Implicit((Object)(object)val2);
				}
			}

			private static HurtBox FindFriendlyHurtboxInAim(EquipmentSlot slot, float maxRange, float maxAngle)
			{
				//IL_0038: Unknown result type (might be due to invalid IL or missing references)
				//IL_0045: Unknown result type (might be due to invalid IL or missing references)
				//IL_004a: Unknown result type (might be due to invalid IL or missing references)
				//IL_004b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0050: Unknown result type (might be due to invalid IL or missing references)
				//IL_0053: Unknown result type (might be due to invalid IL or missing references)
				//IL_0058: Unknown result type (might be due to invalid IL or missing references)
				//IL_005d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0060: Unknown result type (might be due to invalid IL or missing references)
				//IL_0065: 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_0071: Unknown result type (might be due to invalid IL or missing references)
				//IL_0073: Unknown result type (might be due to invalid IL or missing references)
				//IL_0078: 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_0089: Unknown result type (might be due to invalid IL or missing references)
				//IL_0092: Expected O, but got Unknown
				//IL_0094: Unknown result type (might be due to invalid IL or missing references)
				//IL_0099: 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)
				CharacterBody characterBody = slot.characterBody;
				TeamComponent val = ((characterBody != null) ? characterBody.teamComponent : null);
				if (!Object.op_Implicit((Object)(object)characterBody) || !Object.op_Implicit((Object)(object)val))
				{
					return null;
				}
				float num = default(float);
				Ray val2 = CameraRigController.ModifyAimRayIfApplicable(slot.GetAimRay(), ((Component)slot).gameObject, ref num);
				BullseyeSearch val3 = new BullseyeSearch
				{
					searchOrigin = ((Ray)(ref val2)).origin,
					searchDirection = ((Ray)(ref val2)).direction,
					filterByLoS = true,
					sortMode = (SortMode)2,
					maxAngleFilter = maxAngle,
					maxDistanceFilter = maxRange + num,
					viewer = characterBody
				};
				val3.teamMaskFilter = TeamMask.none;
				((TeamMask)(ref val3.teamMaskFilter)).AddTeam(val.teamIndex);
				val3.RefreshCandidates();
				val3.FilterOutGameObject(((Component)characterBody).gameObject);
				return val3.GetResults().FirstOrDefault();
			}

			public static CharacterBody FindFriendlyAllyInAim(EquipmentSlot slot, float maxRange, float maxAngle = 20f)
			{
				//IL_003e: Unknown result type (might be due to invalid IL or missing references)
				//IL_004b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0050: 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_005b: Unknown result type (might be due to invalid IL or missing references)
				//IL_005e: Unknown result type (might be due to invalid IL or missing references)
				//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_006b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0070: Unknown result type (might be due to invalid IL or missing references)
				//IL_0075: Unknown result type (might be due to invalid IL or missing references)
				//IL_007c: 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_0083: Unknown result type (might be due to invalid IL or missing references)
				//IL_008b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0094: Unknown result type (might be due to invalid IL or missing references)
				//IL_009d: Expected O, but got Unknown
				//IL_009f: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
				//IL_0137: Unknown result type (might be due to invalid IL or missing references)
				//IL_0143: Unknown result type (might be due to invalid IL or missing references)
				//IL_0151: Unknown result type (might be due to invalid IL or missing references)
				//IL_015d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0164: Unknown result type (might be due to invalid IL or missing references)
				//IL_0169: Unknown result type (might be due to invalid IL or missing references)
				//IL_016e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0172: Unknown result type (might be due to invalid IL or missing references)
				CharacterBody characterBody = slot.characterBody;
				TeamComponent val = ((characterBody != null) ? characterBody.teamComponent : null);
				if (!Object.op_Implicit((Object)(object)characterBody) || !Object.op_Implicit((Object)(object)val))
				{
					bool flag = false;
					return null;
				}
				float num = default(float);
				Ray val2 = CameraRigController.ModifyAimRayIfApplicable(slot.GetAimRay(), ((Component)slot).gameObject, ref num);
				bool flag2 = false;
				BullseyeSearch val3 = new BullseyeSearch
				{
					searchOrigin = ((Ray)(ref val2)).origin,
					searchDirection = ((Ray)(ref val2)).direction,
					filterByLoS = true,
					sortMode = (SortMode)2,
					maxAngleFilter = maxAngle,
					maxDistanceFilter = maxRange + num,
					viewer = characterBody
				};
				val3.teamMaskFilter = TeamMask.none;
				((TeamMask)(ref val3.teamMaskFilter)).AddTeam(val.teamIndex);
				val3.RefreshCandidates();
				int num2 = val3.GetResults().Count();
				bool flag3 = false;
				val3.FilterOutGameObject(((Component)characterBody).gameObject);
				List<HurtBox> list = val3.GetResults().ToList();
				bool flag4 = false;
				HurtBox val4 = ((list.Count > 0) ? list[0] : null);
				if (Object.op_Implicit((Object)(object)val4))
				{
					CharacterBody val5 = val4.healthComponent?.body;
					float num3 = Vector3.Distance(((Ray)(ref val2)).origin, ((Component)val4).transform.position);
					Vector3 direction = ((Ray)(ref val2)).direction;
					Vector3 val6 = ((Component)val4).transform.position - ((Ray)(ref val2)).origin;
					float num4 = Vector3.Angle(direction, ((Vector3)(ref val6)).normalized);
					string text = (Object.op_Implicit((Object)(object)val5) ? Util.GetBestBodyName(((Component)val5).gameObject) : "<?>");
					bool flag5 = false;
					return val5;
				}
				bool flag6 = false;
				return null;
			}
		}

		[CompilerGenerated]
		private static class <>O
		{
			public static hook_TakeDamage <0>__TakeDamage_PreMitRedirect;

			public static Action<DamageReport> <1>__GlobalOnServerDamageDealt;
		}

		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static hook_PerformEquipmentAction <>9__8_0;

			internal bool <Hooks>b__8_0(orig_PerformEquipmentAction orig, EquipmentSlot self, EquipmentDef equipmentDef)
			{
				if (NetworkServer.active && (Object)(object)equipmentDef == (Object)(object)ItemDef)
				{
					return OnUseKnightsVow(self);
				}
				return orig.Invoke(self, equipmentDef);
			}
		}

		internal static EquipmentDef ItemDef;

		public static float MaxRange;

		public static float Tank;

		public static float Heal;

		internal static readonly HashSet<ProtectorBondController> Active = new HashSet<ProtectorBondController>();

		internal static readonly ModdedDamageType RedirectTag = DamageAPI.ReserveDamageType();

		internal const bool DEBUG_CHAT = false;

		internal static void Define()
		{
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Expected O, but got Unknown
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Expected O, but got Unknown
			MaxRange = 50f;
			Tank = 0.2f;
			Heal = 0.15f;
			ItemDef = ScriptableObject.CreateInstance<EquipmentDef>();
			((Object)ItemDef).name = "KNIGHTS_VOW_NAME";
			ItemDef.nameToken = "KNIGHTS_VOW_NAME";
			ItemDef.pickupToken = "KNIGHTS_VOW_PICKUP";
			ItemDef.descriptionToken = "KNIGHTS_VOW_DESC";
			ItemDef.loreToken = "KNIGHTS_VOW_LORE";
			ItemDef.pickupIconSprite = ExamplePlugin.LoadSpriteFromFile("KnightsVow.png");
			ItemDef.isConsumed = false;
			ItemDef.canDrop = true;
			ItemDef.canBeRandomlyTriggered = false;
			ItemDef.isLunar = false;
			ItemDef.enigmaCompatible = false;
			ItemDef.cooldown = 15f;
			GameObject pickupModelPrefab = ExamplePlugin.AssetLoader.LoadAsset("KnightsVowItem");
			ItemDef.pickupModelPrefab = pickupModelPrefab;
			ItemDisplayRuleDict val = new ItemDisplayRuleDict((ItemDisplayRule[])null);
			ItemAPI.Add(new CustomEquipment(ItemDef, val));
		}

		internal static void Hooks()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Expected O, but got Unknown
			object obj = <>c.<>9__8_0;
			if (obj == null)
			{
				hook_PerformEquipmentAction val = (orig_PerformEquipmentAction orig, EquipmentSlot self, EquipmentDef equipmentDef) => (NetworkServer.active && (Object)(object)equipmentDef == (Object)(object)ItemDef) ? OnUseKnightsVow(self) : orig.Invoke(self, equipmentDef);
				<>c.<>9__8_0 = val;
				obj = (object)val;
			}
			EquipmentSlot.PerformEquipmentAction += (hook_PerformEquipmentAction)obj;
			Targeting.HookIndicator();
			Targeting.PreloadIndicatorPrefab();
			object obj2 = <>O.<0>__TakeDamage_PreMitRedirect;
			if (obj2 == null)
			{
				hook_TakeDamage val2 = TakeDamage_PreMitRedirect;
				<>O.<0>__TakeDamage_PreMitRedirect = val2;
				obj2 = (object)val2;
			}
			HealthComponent.TakeDamage += (hook_TakeDamage)obj2;
			GlobalEventManager.onServerDamageDealt += GlobalOnServerDamageDealt;
		}

		private static bool OnUseKnightsVow(EquipmentSlot slot)
		{
			//IL_008c: 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)
			if (!NetworkServer.active)
			{
				return false;
			}
			CharacterBody characterBody = slot.characterBody;
			CharacterBody val = Targeting.FindFriendlyAllyInAim(slot, MaxRange);
			if (!Object.op_Implicit((Object)(object)characterBody) || !Object.op_Implicit((Object)(object)val))
			{
				return false;
			}
			CharacterBody val2;
			CharacterBody val3;
			if (IsPlayer(val))
			{
				val2 = val;
				val3 = characterBody;
			}
			else
			{
				val2 = characterBody;
				val3 = val;
			}
			if (!Object.op_Implicit((Object)(object)val2.teamComponent) || !Object.op_Implicit((Object)(object)val3.teamComponent) || val2.teamComponent.teamIndex != val3.teamComponent.teamIndex || (Object)(object)val3 == (Object)(object)val2)
			{
				return false;
			}
			ProtectorBondController protectorBondController = ((Component)val2).GetComponent<ProtectorBondController>();
			if (!Object.op_Implicit((Object)(object)protectorBondController))
			{
				protectorBondController = ((Component)val2).gameObject.AddComponent<ProtectorBondController>();
			}
			protectorBondController.Initialize(val2, val3, Tank, Heal, MaxRange);
			bool flag = false;
			return true;
			static bool IsPlayer(CharacterBody b)
			{
				int result;
				if (Object.op_Implicit((Object)(object)b))
				{
					if (!b.isPlayerControlled)
					{
						CharacterMaster master = b.master;
						result = (((Object)(object)((master != null) ? master.playerCharacterMasterController : null) != (Object)null) ? 1 : 0);
					}
					else
					{
						result = 1;
					}
				}
				else
				{
					result = 0;
				}
				return (byte)result != 0;
			}
		}

		private static void TakeDamage_PreMitRedirect(orig_TakeDamage orig, HealthComponent self, DamageInfo di)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: 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_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Expected O, but got Unknown
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkServer.active || di == null || Active.Count == 0 || DamageAPI.HasModdedDamageType(di, RedirectTag))
			{
				orig.Invoke(self, di);
				return;
			}
			float damage = di.damage;
			ProtectorBondController[] array = Active.ToArray();
			foreach (ProtectorBondController protectorBondController in array)
			{
				if (Object.op_Implicit((Object)(object)protectorBondController) && protectorBondController.IsValidAndInRange() && (Object)(object)self.body == (Object)(object)protectorBondController.Wearer)
				{
					float num = Mathf.Max(0f, damage * protectorBondController.Tank);
					float damage2 = Mathf.Max(0f, damage - num);
					di.damage = damage2;
					DamageInfo val = new DamageInfo
					{
						attacker = di.attacker,
						inflictor = (di.inflictor ?? di.attacker),
						damage = num,
						position = protectorBondController.Ally.corePosition,
						damageType = (di.damageType | DamageTypeCombo.op_Implicit((DamageType)2048) | DamageTypeCombo.op_Implicit((DamageType)64) | DamageTypeCombo.op_Implicit((DamageType)2)),
						procCoefficient = 0f,
						crit = false
					};
					DamageAPI.AddModdedDamageType(val, RedirectTag);
					protectorBondController.Ally.healthComponent.TakeDamage(val);
					GlobalEventManager instance = GlobalEventManager.instance;
					if (instance != null)
					{
						instance.OnHitEnemy(val, ((Component)protectorBondController.Ally).gameObject);
					}
					bool flag = false;
					break;
				}
			}
			orig.Invoke(self, di);
		}

		private static void GlobalOnServerDamageDealt(DamageReport report)
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkServer.active || report == null || (Object)(object)report.victimBody == (Object)null || report.damageDealt <= 0f || DamageAPI.HasModdedDamageType(report.damageInfo, RedirectTag) || Active.Count == 0)
			{
				return;
			}
			foreach (ProtectorBondController item in Active)
			{
				if (Object.op_Implicit((Object)(object)item) && item.IsValidAndInRange() && (Object)(object)report.attackerBody == (Object)(object)item.Wearer)
				{
					HealthComponent healthComponent = item.Ally.healthComponent;
					if (healthComponent != null)
					{
						healthComponent.Heal(report.damageDealt * item.Heal, default(ProcChainMask), true);
					}
					bool flag = false;
				}
			}
		}
	}
	public class ProtectorBondController : MonoBehaviour
	{
		public CharacterBody Wearer { get; private set; }

		public CharacterBody Ally { get; private set; }

		public float Tank { get; private set; }

		public float Heal { get; private set; }

		public float MaxRange { get; private set; }

		public bool AllyIsPlayerControlled { get; private set; }

		public void Initialize(CharacterBody wearer, CharacterBody ally, float tank, float heal, float maxRange)
		{
			Wearer = wearer;
			Ally = ally;
			Tank = tank;
			Heal = heal;
			MaxRange = maxRange;
			AllyIsPlayerControlled = IsPlayer(ally);
			((Behaviour)this).enabled = true;
		}

		private void OnEnable()
		{
			SoulLink.Active.Add(this);
			bool flag = false;
		}

		private void OnDisable()
		{
			SoulLink.Active.Remove(this);
			bool flag = false;
		}

		private void Update()
		{
			if (!HasProtectorVowEquipped(Wearer))
			{
				bool flag = false;
				Object.Destroy((Object)(object)this);
			}
		}

		public bool IsValidAndInRange()
		{
			//IL_00b5: 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_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: 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_00f5: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)Wearer) || !Object.op_Implicit((Object)(object)Ally))
			{
				return false;
			}
			HealthComponent healthComponent = Wearer.healthComponent;
			HealthComponent healthComponent2 = Ally.healthComponent;
			if ((Object)(object)healthComponent == (Object)null || (Object)(object)healthComponent2 == (Object)null || !healthComponent.alive || !healthComponent2.alive)
			{
				return false;
			}
			if (!Object.op_Implicit((Object)(object)Wearer.teamComponent) || !Object.op_Implicit((Object)(object)Ally.teamComponent))
			{
				return false;
			}
			if (Wearer.teamComponent.teamIndex != Ally.teamComponent.teamIndex)
			{
				return false;
			}
			Vector3 val = Ally.corePosition - Wearer.corePosition;
			float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude;
			return sqrMagnitude <= MaxRange * MaxRange;
		}

		private static bool HasProtectorVowEquipped(CharacterBody body)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			Inventory val = ((body != null) ? body.inventory : null);
			if (!Object.op_Implicit((Object)(object)val))
			{
				return false;
			}
			return val.currentEquipmentIndex == SoulLink.ItemDef.equipmentIndex;
		}

		private static bool IsPlayer(CharacterBody body)
		{
			if (!Object.op_Implicit((Object)(object)body))
			{
				return false;
			}
			if (body.isPlayerControlled)
			{
				return true;
			}
			CharacterMaster master = body.master;
			return Object.op_Implicit((Object)(object)master) && Object.op_Implicit((Object)(object)master.playerCharacterMasterController);
		}
	}
	public class PulseMarker : MonoBehaviour
	{
		public Vector3 center;

		public float ttl = 1f;

		private void Update()
		{
			ttl -= Time.deltaTime;
			if (ttl <= 0f)
			{
				Object.Destroy((Object)(object)((Component)this).gameObject);
			}
		}
	}
	public class PulseHitVFXListener
	{
		public static GameObject OnHitVFXPrefab;

		public static void Init()
		{
			GlobalEventManager.onServerDamageDealt += OnServerDamageDealt;
		}

		private static void OnServerDamageDealt(DamageReport report)
		{
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: 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_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkServer.active || !Object.op_Implicit((Object)(object)report?.victimBody))
			{
				return;
			}
			GameObject inflictor = report.damageInfo.inflictor;
			if (!Object.op_Implicit((Object)(object)inflictor))
			{
				return;
			}
			PulseMarker component = inflictor.GetComponent<PulseMarker>();
			if (Object.op_Implicit((Object)(object)component))
			{
				Vector3 corePosition = report.victimBody.corePosition;
				Vector3 val = corePosition - component.center;
				if (((Vector3)(ref val)).sqrMagnitude > 1E-06f)
				{
					((Vector3)(ref val)).Normalize();
				}
				else
				{
					val = Vector3.up;
				}
				if (Object.op_Implicit((Object)(object)TempVFX.OnHitImpactPrefab))
				{
					Debug.LogWarning((object)"[UD] OnHitImpactPrefab exists");
					EffectManager.SimpleImpactEffect(TempVFX.OnHitImpactPrefab, corePosition, val, true);
				}
			}
		}
	}
	public static class TempVFX
	{
		public static GameObject OnHitImpactPrefab;

		public static void Load()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			OnHitImpactPrefab = Addressables.LoadAssetAsync<GameObject>((object)"RoR2/Base/Common/VFX/OmniExplosionVFX.prefab").WaitForCompletion();
			if (!Object.op_Implicit((Object)(object)OnHitImpactPrefab))
			{
				Debug.LogWarning((object)"[UD] TempVFX: Could not find OmniImpactVFX, on-hit effects will be skipped.");
			}
		}
	}
	internal static class UnendingDespair
	{
		private class BarrierPulseTracker : MonoBehaviour
		{
			private CharacterBody body;

			private HealthComponent hc;

			private float lastBarrier;

			private static readonly float BASE_THRESHOLD_FRAC = 0.1f;

			private float accumulatedLoss = 0f;

			private ItemIndex ItemIndex => ItemDef.itemIndex;

			private void Awake()
			{
				body = ((Component)this).GetComponent<CharacterBody>();
				hc = body.healthComponent;
				lastBarrier = hc.barrier;
			}

			private void FixedUpdate()
			{
				//IL_004b: Unknown result type (might be due to invalid IL or missing references)
				if (!Object.op_Implicit((Object)(object)body) || !Object.op_Implicit((Object)(object)hc))
				{
					return;
				}
				int num = (Object.op_Implicit((Object)(object)body.inventory) ? body.inventory.GetItemCount(ItemIndex) : 0);
				if (num == 0)
				{
					lastBarrier = hc.barrier;
					return;
				}
				float barrier = hc.barrier;
				if (barrier >= lastBarrier)
				{
					lastBarrier = barrier;
					return;
				}
				float num2 = lastBarrier - barrier;
				if (num2 <= 0f)
				{
					lastBarrier = barrier;
					return;
				}
				accumulatedLoss += num2;
				float num3 = BASE_THRESHOLD_FRAC * body.maxHealth;
				if (accumulatedLoss >= num3)
				{
					FirePulse(accumulatedLoss, num);
					accumulatedLoss = 0f;
				}
				lastBarrier = barrier;
			}

			private void FirePulse(float depletedBarrier, int stacks)
			{
				//IL_001b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0021: Expected O, but got Unknown
				//IL_002f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0034: Unknown result type (might be due to invalid IL or missing references)
				//IL_0044: Unknown result type (might be due to invalid IL or missing references)
				//IL_0049: Unknown result type (might be due to invalid IL or missing references)
				//IL_005a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0061: Unknown result type (might be due to invalid IL or missing references)
				//IL_0091: Unknown result type (might be due to invalid IL or missing references)
				//IL_007f: 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)
				//IL_009b: Unknown result type (might be due to invalid IL or missing references)
				//IL_009d: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
				//IL_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_00bf: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d9: 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)
				//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
				//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
				//IL_0106: Unknown result type (might be due to invalid IL or missing references)
				//IL_011e: Expected O, but got Unknown
				//IL_0120: Unknown result type (might be due to invalid IL or missing references)
				float num = 2.5f + 1.5f * (float)(stacks - 1);
				float baseDamage = depletedBarrier * num;
				GameObject val = new GameObject("UD_PulseMarker");
				PulseMarker pulseMarker = val.AddComponent<PulseMarker>();
				pulseMarker.center = body.corePosition;
				pulseMarker.ttl = 1f;
				BlastAttack val2 = new BlastAttack
				{
					attacker = ((Component)body).gameObject,
					inflictor = val,
					teamIndex = (Object.op_Implicit((Object)(object)body.teamComponent) ? body.teamComponent.teamIndex : TeamComponent.GetObjectTeam(((Component)body).gameObject)),
					attackerFiltering = (AttackerFiltering)2,
					baseDamage = baseDamage,
					baseForce = 0f,
					bonusForce = Vector3.zero,
					crit = body.RollCrit(),
					damageColorIndex = (DamageColorIndex)3,
					damageType = DamageTypeCombo.op_Implicit((DamageType)0),
					falloffModel = (FalloffModel)0,
					position = body.corePosition,
					procCoefficient = 0.25f,
					radius = 12f + 2f * (float)(stacks - 1)
				};
				val2.Fire();
			}
		}

		[CompilerGenerated]
		private static class <>O
		{
			public static Action<CharacterBody> <0>__AddTrackerIfNeeded;

			public static hook_FixedUpdate <1>__BarrierOutOfCombat;
		}

		internal static ItemDef ItemDef;

		internal static GameObject PulseVFX;

		internal static void Define()
		{
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: 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 O, but got Unknown
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Expected O, but got Unknown
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			ItemDef = ScriptableObject.CreateInstance<ItemDef>();
			((Object)ItemDef).name = "UNENDING_DESPAIR_NAME";
			ItemDef.nameToken = "UNENDING_DESPAIR_NAME";
			ItemDef.pickupToken = "UNENDING_DESPAIR_PICKUP";
			ItemDef.descriptionToken = "UNENDING_DESPAIR_DESC";
			ItemDef.loreToken = "UNENDING_DESPAIR_LORE";
			ItemDef.tier = (ItemTier)2;
			ItemDef._itemTierDef = Addressables.LoadAssetAsync<ItemTierDef>((object)"RoR2/Base/Common/Tier3Def.asset").WaitForCompletion();
			ItemDef.pickupIconSprite = ExamplePlugin.LoadSpriteFromFile("UnendingDespair.png");
			ItemDef.canRemove = true;
			ItemDef.hidden = false;
			GameObject pickupModelPrefab = ExamplePlugin.AssetLoader.LoadAsset("unendingDespairItem");
			ItemDef.pickupModelPrefab = pickupModelPrefab;
			ItemAPI.Add(new CustomItem(ItemDef, new ItemDisplayRuleDict((ItemDisplayRule[])null)));
			PulseVFX = Addressables.LoadAssetAsync<GameObject>((object)"RoR2/Base/Common/VFX/OmniExplosionVFX.prefab").WaitForCompletion();
		}

		internal static void Hooks()
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected O, but got Unknown
			CharacterBody.onBodyStartGlobal += AddTrackerIfNeeded;
			object obj = <>O.<1>__BarrierOutOfCombat;
			if (obj == null)
			{
				hook_FixedUpdate val = BarrierOutOfCombat;
				<>O.<1>__BarrierOutOfCombat = val;
				obj = (object)val;
			}
			CharacterBody.FixedUpdate += (hook_FixedUpdate)obj;
		}

		private static void AddTrackerIfNeeded(CharacterBody body)
		{
			if (!Object.op_Implicit((Object)(object)((Component)body).GetComponent<BarrierPulseTracker>()))
			{
				((Component)body).gameObject.AddComponent<BarrierPulseTracker>();
			}
		}

		private static void BarrierOutOfCombat(orig_FixedUpdate orig, CharacterBody body)
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			orig.Invoke(body);
			if (NetworkServer.active && !((Object)(object)body == (Object)null) && !((Object)(object)body.inventory == (Object)null) && body.inventory.GetItemCount(ItemDef.itemIndex) != 0 && body.outOfDanger)
			{
				float num = body.maxHealth * 0.1f;
				float num2 = num - body.healthComponent.barrier;
				if (num2 > 1f)
				{
					body.healthComponent.AddBarrier(num2);
				}
			}
		}
	}
}