Decompiled source of effigy v1.0.1

BepInEx/plugins/AnimaEffigy/AnimaEffigy.dll

Decompiled 15 hours 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 BepInEx;
using BepInEx.Configuration;
using EntityStates;
using EntityStates.Acolyte;
using EntityStates.Acolyte.Weapon;
using HG.BlendableTypes;
using HarmonyLib;
using KinematicCharacterController;
using Microsoft.CodeAnalysis;
using RoR2;
using RoR2.ContentManagement;
using RoR2.Networking;
using RoR2.Orbs;
using RoR2.Skills;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Networking;
using UnityEngine.ResourceManagement.AsyncOperations;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("AnimaEffigy")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("AnimaEffigy")]
[assembly: AssemblyTitle("AnimaEffigy")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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 AnimaEffigy
{
	internal readonly struct DebuffCarry
	{
		internal readonly BuffIndex Index;

		internal readonly float Expires;

		internal DebuffCarry(BuffIndex index, float expires)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			Index = index;
			Expires = expires;
		}
	}
	internal static class Debuffs
	{
		private static readonly Dictionary<BuffDef, bool> DotBuffs = new Dictionary<BuffDef, bool>();

		private static bool IsDotBuff(BuffDef def)
		{
			if (DotBuffs.TryGetValue(def, out var value))
			{
				return value;
			}
			bool flag = ScanDotBuff(def);
			DotBuffs[def] = flag;
			return flag;
		}

		private static bool ScanDotBuff(BuffDef def)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			if ((int)DotController.GetDotDefIndex(def) != -1)
			{
				return true;
			}
			for (int i = 0; i < 14; i++)
			{
				if ((Object)(object)DotController.GetDotDef((DotIndex)i)?.terminalTimedBuff == (Object)(object)def)
				{
					return true;
				}
			}
			return false;
		}

		internal static List<DebuffCarry> Capture(CharacterBody source)
		{
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: 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)
			List<DebuffCarry> list = new List<DebuffCarry>();
			if (!Object.op_Implicit((Object)(object)source))
			{
				return list;
			}
			int[] array = default(int[]);
			List<TimedBuff> list2 = default(List<TimedBuff>);
			source.CacheBuffs(ref array, ref list2);
			Dictionary<BuffIndex, int> dictionary = new Dictionary<BuffIndex, int>();
			list2.Sort((TimedBuff a, TimedBuff b) => b.timer.CompareTo(a.timer));
			foreach (TimedBuff item in list2)
			{
				BuffDef buffDef = BuffCatalog.GetBuffDef(item.buffIndex);
				if (Object.op_Implicit((Object)(object)buffDef) && buffDef.isDebuff && !(item.timer <= 0f) && !IsDotBuff(buffDef))
				{
					dictionary.TryGetValue(item.buffIndex, out var value);
					if (value < ((!buffDef.canStack) ? 1 : 8))
					{
						list.Add(new DebuffCarry(item.buffIndex, Time.fixedTime + item.timer));
						dictionary[item.buffIndex] = value + 1;
					}
				}
			}
			return list;
		}

		internal static void Apply(CharacterBody target, List<DebuffCarry> carried)
		{
			//IL_0071: 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_00b4: 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_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)target) || carried == null || carried.Count == 0)
			{
				return;
			}
			Dictionary<BuffIndex, int> dictionary = new Dictionary<BuffIndex, int>();
			List<DebuffCarry> list = new List<DebuffCarry>(carried);
			list.Sort((DebuffCarry a, DebuffCarry b) => b.Expires.CompareTo(a.Expires));
			int[] array = default(int[]);
			List<TimedBuff> list2 = default(List<TimedBuff>);
			foreach (DebuffCarry item in list)
			{
				float num = item.Expires - Time.fixedTime;
				if (num <= 0f)
				{
					continue;
				}
				BuffDef buffDef = BuffCatalog.GetBuffDef(item.Index);
				if (!Object.op_Implicit((Object)(object)buffDef))
				{
					continue;
				}
				dictionary.TryGetValue(item.Index, out var value);
				if (value >= ((!buffDef.canStack) ? 1 : 8))
				{
					continue;
				}
				value++;
				dictionary[item.Index] = value;
				if (target.GetBuffCount(item.Index) < value)
				{
					target.AddTimedBuff(buffDef, num);
				}
				else
				{
					if (buffDef.canStack)
					{
						continue;
					}
					target.CacheBuffs(ref array, ref list2);
					float num2 = 0f;
					foreach (TimedBuff item2 in list2)
					{
						if (item2.buffIndex == item.Index)
						{
							num2 = Math.Max(num2, item2.timer);
						}
					}
					if (num > num2)
					{
						target.AddTimedBuff(buffDef, num);
					}
				}
			}
		}
	}
	public sealed class EffigyController : MonoBehaviour
	{
		private AcolyteFormController form;

		private float ritualStart;

		private float ritualEnd;

		private bool ritualSummon;

		private Vector3 ritualOffset;

		private int ritualStage;

		private float presentationEnd;

		private readonly List<GameObject> orbitGhosts = new List<GameObject>();

		private Vector3 peakDirection;

		private bool networkManifested;

		private int networkStage;

		private uint outgoingSequence;

		private uint receivedSequence;

		private Vector3 hoverCenter;

		private Vector3 hoverVelocity;

		private bool hoverInitialized;

		private float displayedScale = -1f;

		private readonly Queue<int> pending = new Queue<int>();

		private Coroutine attacks;

		private GameObject visual;

		private Vector3 spiritMeshCenter;

		private bool segmentActive;

		private Vector3 segmentFrom;

		private Vector3 segmentTo;

		private float segmentStart;

		private float segmentDuration;

		private int segmentStage;

		private static readonly WaitForFixedUpdate FixedTick = new WaitForFixedUpdate();

		private static readonly WaitForSeconds ChainPause = new WaitForSeconds(0.05f);

		private readonly BullseyeSearch targetSearch = new BullseyeSearch();

		private readonly HashSet<HealthComponent> passiveVisited = new HashSet<HealthComponent>();

		private float segmentHeight;

		private float segmentSway;

		private Vector3 segmentSide;

		private readonly RecoveryLedger recoveryLedger = new RecoveryLedger();

		public CharacterBody Body { get; private set; }

		public bool Equipped
		{
			get
			{
				if (Object.op_Implicit((Object)(object)Body) && Object.op_Implicit((Object)(object)form) && Object.op_Implicit((Object)(object)form.transformSkillSlot))
				{
					return (Object)(object)form.transformSkillSlot.skillDef == (Object)(object)Plugin.Skill;
				}
				return false;
			}
		}

		public int RequiredConvictions
		{
			get
			{
				if (!Object.op_Implicit((Object)(object)form))
				{
					return 7;
				}
				return form.maxSoul;
			}
		}

		public bool Manifested
		{
			get
			{
				if (Object.op_Implicit((Object)(object)Body) && Object.op_Implicit((Object)(object)Plugin.Manifested))
				{
					if (!Body.HasBuff(Plugin.Manifested))
					{
						if (!NetworkServer.active)
						{
							return networkManifested;
						}
						return false;
					}
					return true;
				}
				return false;
			}
		}

		public int Stage
		{
			get
			{
				if (!Object.op_Implicit((Object)(object)Body) || !Object.op_Implicit((Object)(object)Plugin.Infusion))
				{
					return 0;
				}
				return Mathf.Max(Body.GetBuffCount(Plugin.Infusion), (!NetworkServer.active) ? networkStage : 0);
			}
		}

		public int Resource
		{
			get
			{
				if (!Object.op_Implicit((Object)(object)form))
				{
					return 0;
				}
				return form.souls;
			}
		}

		public bool PeakActive { get; private set; }

		public bool PresentationBusy
		{
			get
			{
				if (!PeakActive && !(Time.time < ritualEnd))
				{
					return Time.time < presentationEnd;
				}
				return true;
			}
		}

		public int PendingAttacks => pending.Count;

		private Vector3 IdleForward
		{
			get
			{
				//IL_002f: Unknown result type (might be due to invalid IL or missing references)
				//IL_001d: 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_0057: Unknown result type (might be due to invalid IL or missing references)
				//IL_004f: Unknown result type (might be due to invalid IL or missing references)
				Vector3 val = (Object.op_Implicit((Object)(object)Body.characterDirection) ? Body.characterDirection.forward : ((Component)Body).transform.forward);
				val.y = 0f;
				if (!(((Vector3)(ref val)).sqrMagnitude > 0.001f))
				{
					return Vector3.forward;
				}
				return ((Vector3)(ref val)).normalized;
			}
		}

		private Vector3 HoverAnchor => Body.corePosition + Vector3.up * Plugin.Options.HoverHeight.Value - IdleForward * Plugin.Options.FollowDistance.Value + Vector3.Cross(Vector3.up, IdleForward) * 1.25f;

		private Vector3 HoverOscillation
		{
			get
			{
				//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)
				//IL_0022: Unknown result type (might be due to invalid IL or missing references)
				//IL_004f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0054: 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_005f: 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)
				NetworkInstanceId netId = ((NetworkBehaviour)Body).netId;
				float num = (float)((NetworkInstanceId)(ref netId)).Value * 0.73f;
				float time = Time.time;
				return Vector3.up * (Mathf.Sin(time * Plugin.Options.BobSpeed.Value + num) * Plugin.Options.BobAmplitude.Value) + Vector3.Cross(Vector3.up, IdleForward) * (Mathf.Sin(time * 1.15f + num + 0.7f) * Plugin.Options.SwayAmplitude.Value);
			}
		}

		private Vector3 IdlePosition => (hoverInitialized ? hoverCenter : HoverAnchor) + HoverOscillation;

		public void HoldPresentation(float duration)
		{
			presentationEnd = Time.time + duration;
		}

		internal uint NextSequence()
		{
			outgoingSequence++;
			if (outgoingSequence == 0)
			{
				outgoingSequence++;
			}
			return outgoingSequence;
		}

		private void Awake()
		{
			Body = ((Component)this).GetComponent<CharacterBody>();
			form = ((Component)this).GetComponent<AcolyteFormController>();
		}

		internal void RecoverFromDamage(DamageReport report)
		{
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//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_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Expected O, but got Unknown
			if (NetworkServer.active && Equipped && Object.op_Implicit((Object)(object)form) && Object.op_Implicit((Object)(object)Body.healthComponent) && Body.healthComponent.alive)
			{
				float num = Rules.RecoveryHealAmount(report.damageDealt, form.regainPercentOfDealtDamageEcho, Body.healthComponent.regainableHealth, form.inTransformation);
				if (!(num <= 0f) && Object.op_Implicit((Object)(object)Body.mainHurtBox))
				{
					RegainableHealthHealOrb val = new RegainableHealthHealOrb
					{
						origin = report.damageInfo.position,
						target = Body.mainHurtBox,
						regainHealthAmount = num
					};
					OrbManager.instance.AddOrb((Orb)(object)val);
				}
			}
		}

		private void FixedUpdate()
		{
			if (!Equipped || !Object.op_Implicit((Object)(object)Body.healthComponent) || !Body.healthComponent.alive)
			{
				Object.Destroy((Object)(object)this);
				return;
			}
			if (NetworkServer.active)
			{
				HealthComponent healthComponent = Body.healthComponent;
				recoveryLedger.Observe(healthComponent.regainableHealth);
				float num = recoveryLedger.DecayAmount(healthComponent.fullHealth, Time.fixedDeltaTime, healthComponent.regainableHealthDepleteDisabledCounter > 0, HealthComponent.regainableHealthPercentReductionPerSecond / 100f);
				if (num > 0f)
				{
					healthComponent.SpendRegainableHealthServer(num);
					recoveryLedger.Observe(healthComponent.regainableHealth);
				}
			}
			if (NetworkServer.active && Manifested && pending.Count > 0 && attacks == null && !PresentationBusy)
			{
				attacks = ((MonoBehaviour)this).StartCoroutine(DrainAttacks());
			}
		}

		private void ResetHover()
		{
			//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)
			hoverInitialized = false;
			hoverVelocity = Vector3.zero;
		}

		private void UpdateHover()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: 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)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: 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_005f: 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_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: 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_0075: 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_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: 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)
			Vector3 hoverAnchor = HoverAnchor;
			if (!hoverInitialized)
			{
				hoverCenter = hoverAnchor;
				hoverVelocity = Vector3.zero;
				hoverInitialized = true;
			}
			hoverCenter = Vector3.SmoothDamp(hoverCenter, hoverAnchor, ref hoverVelocity, Plugin.Options.FollowLag.Value, float.PositiveInfinity, Time.deltaTime);
			Vector3 val = hoverCenter - hoverAnchor;
			if (((Vector3)(ref val)).sqrMagnitude > 64f)
			{
				hoverCenter = hoverAnchor + ((Vector3)(ref val)).normalized * 8f;
				hoverVelocity = Vector3.zero;
			}
		}

		private void LateUpdate()
		{
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0205: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: 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_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: 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_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0572: Unknown result type (might be due to invalid IL or missing references)
			//IL_051e: Unknown result type (might be due to invalid IL or missing references)
			//IL_053b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0553: Unknown result type (might be due to invalid IL or missing references)
			//IL_0558: Unknown result type (might be due to invalid IL or missing references)
			//IL_055d: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_04aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_04af: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_04da: Unknown result type (might be due to invalid IL or missing references)
			//IL_04df: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0401: Unknown result type (might be due to invalid IL or missing references)
			//IL_040c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0411: Unknown result type (might be due to invalid IL or missing references)
			//IL_0413: Unknown result type (might be due to invalid IL or missing references)
			//IL_0418: Unknown result type (might be due to invalid IL or missing references)
			//IL_043c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0442: Unknown result type (might be due to invalid IL or missing references)
			//IL_0447: Unknown result type (might be due to invalid IL or missing references)
			//IL_044c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0459: Unknown result type (might be due to invalid IL or missing references)
			//IL_045e: Unknown result type (might be due to invalid IL or missing references)
			//IL_039b: Unknown result type (might be due to invalid IL or missing references)
			//IL_039d: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0330: Unknown result type (might be due to invalid IL or missing references)
			//IL_0318: Unknown result type (might be due to invalid IL or missing references)
			//IL_031b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0320: Unknown result type (might be due to invalid IL or missing references)
			//IL_0325: Unknown result type (might be due to invalid IL or missing references)
			//IL_0329: Unknown result type (might be due to invalid IL or missing references)
			//IL_046e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0479: Unknown result type (might be due to invalid IL or missing references)
			//IL_0337: Unknown result type (might be due to invalid IL or missing references)
			//IL_033c: Unknown result type (might be due to invalid IL or missing references)
			//IL_058a: Unknown result type (might be due to invalid IL or missing references)
			//IL_058b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0590: Unknown result type (might be due to invalid IL or missing references)
			//IL_05cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c8: Unknown result type (might be due to invalid IL or missing references)
			if (!Equipped || !Manifested)
			{
				if (Object.op_Implicit((Object)(object)visual))
				{
					visual.SetActive(false);
				}
				{
					foreach (GameObject orbitGhost in orbitGhosts)
					{
						if (Object.op_Implicit((Object)(object)orbitGhost))
						{
							orbitGhost.SetActive(false);
						}
					}
					return;
				}
			}
			if (!Object.op_Implicit((Object)(object)visual) && Object.op_Implicit((Object)(object)Plugin.VisualPrefab))
			{
				visual = Object.Instantiate<GameObject>(Plugin.VisualPrefab);
				((Object)visual).name = "Anima Effigy (visual)";
				visual.SetActive(true);
				bool flag = false;
				Bounds val = default(Bounds);
				Renderer[] componentsInChildren = visual.GetComponentsInChildren<Renderer>(true);
				foreach (Renderer val2 in componentsInChildren)
				{
					if (val2 is MeshRenderer || val2 is SkinnedMeshRenderer)
					{
						if (!flag)
						{
							val = val2.bounds;
							flag = true;
						}
						else
						{
							((Bounds)(ref val)).Encapsulate(val2.bounds);
						}
					}
				}
				spiritMeshCenter = (flag ? visual.transform.InverseTransformPoint(((Bounds)(ref val)).center) : Vector3.zero);
				ResetHover();
			}
			if (!Object.op_Implicit((Object)(object)visual))
			{
				return;
			}
			visual.SetActive(true);
			int infusion = ((segmentActive && !PeakActive) ? Mathf.Max(Stage, segmentStage) : Stage);
			float num = Rules.VisualScale(Plugin.Options.BaseScale.Value, Plugin.Options.FullScale.Value, infusion);
			if (displayedScale < 0f)
			{
				displayedScale = num;
			}
			displayedScale = Mathf.Lerp(displayedScale, num, 1f - Mathf.Exp(-5f * Time.deltaTime));
			visual.transform.localScale = Vector3.one * displayedScale;
			Vector3 val3 = IdleForward;
			bool flag2 = PeakActive || segmentActive || Time.time < ritualEnd;
			if (Time.time < ritualEnd)
			{
				float num2 = Mathf.Clamp01((Time.time - ritualStart) / 0.625f);
				float num3 = Rules.VisualScale(Plugin.Options.BaseScale.Value, Plugin.Options.FullScale.Value, Mathf.Max(0, ritualStage - 1));
				float num4 = Rules.VisualScale(Plugin.Options.BaseScale.Value, Plugin.Options.FullScale.Value, ritualStage);
				Vector3 corePosition = Body.corePosition;
				Vector3 val4 = corePosition + Vector3.up * 8f;
				if (num2 < 0.3f)
				{
					float num5 = Mathf.SmoothStep(0f, 1f, num2 / 0.3f);
					visual.transform.position = (ritualSummon ? val4 : Vector3.Lerp(corePosition + ritualOffset, val4, num5));
					val3 = Vector3.down;
					displayedScale = (ritualSummon ? (num4 * Mathf.Lerp(0.08f, 1f, num5)) : num3);
				}
				else if (num2 < 0.65f)
				{
					float num6 = Mathf.SmoothStep(0f, 1f, (num2 - 0.3f) / 0.35f);
					visual.transform.position = Vector3.Lerp(val4, corePosition, num6);
					val3 = Vector3.down;
					displayedScale = Mathf.Lerp(num3, num3 * 0.08f, num6);
				}
				else
				{
					float num7 = Mathf.SmoothStep(0f, 1f, (num2 - 0.65f) / 0.35f);
					visual.transform.position = Vector3.Lerp(corePosition, HoverAnchor, num7);
					val3 = HoverAnchor - corePosition;
					displayedScale = Mathf.Lerp(num4 * 0.08f, num4, num7);
					hoverCenter = visual.transform.position - HoverOscillation;
					hoverInitialized = true;
					hoverVelocity = Vector3.zero;
				}
				visual.transform.localScale = Vector3.one * displayedScale;
			}
			else if (PeakActive)
			{
				if (((Vector3)(ref peakDirection)).sqrMagnitude > 0.1f)
				{
					val3 = peakDirection;
				}
				Quaternion val5 = Util.QuaternionSafeLookRotation(val3);
				visual.transform.position = Body.corePosition - val5 * (spiritMeshCenter * displayedScale);
			}
			else if (segmentActive)
			{
				float num8 = Mathf.Clamp01((Time.time - segmentStart) / segmentDuration);
				visual.transform.position = HopPosition(num8);
				val3 = HopPosition(Mathf.Min(1f, num8 + 0.015f)) - HopPosition(Mathf.Max(0f, num8 - 0.015f));
			}
			else
			{
				UpdateHover();
				visual.transform.position = IdlePosition;
			}
			if (((Vector3)(ref val3)).sqrMagnitude > 0.001f)
			{
				Quaternion val6 = Util.QuaternionSafeLookRotation(val3);
				visual.transform.rotation = (flag2 ? val6 : Quaternion.Slerp(visual.transform.rotation, val6, 1f - Mathf.Exp(-3f * Time.deltaTime)));
			}
			UpdateOrbitGhosts();
		}

		private void UpdateOrbitGhosts()
		{
			//IL_00db: 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_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: 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)
			int num = Rules.OrbitGhostCount(Stage);
			while (orbitGhosts.Count > num)
			{
				int index = orbitGhosts.Count - 1;
				if (Object.op_Implicit((Object)(object)orbitGhosts[index]))
				{
					Object.Destroy((Object)(object)orbitGhosts[index]);
				}
				orbitGhosts.RemoveAt(index);
			}
			while (orbitGhosts.Count < num && Object.op_Implicit((Object)(object)Plugin.OrbitGhostPrefab))
			{
				GameObject val = Object.Instantiate<GameObject>(Plugin.OrbitGhostPrefab);
				((Object)val).name = "Effigy orbiting Haunt ghost";
				orbitGhosts.Add(val);
			}
			Vector3 val3 = default(Vector3);
			for (int i = 0; i < orbitGhosts.Count; i++)
			{
				GameObject val2 = orbitGhosts[i];
				if (Object.op_Implicit((Object)(object)val2))
				{
					val2.SetActive(true);
					float num2 = Time.time * 2.5f + (float)i * MathF.PI;
					NetworkInstanceId netId = ((NetworkBehaviour)Body).netId;
					float num3 = num2 + (float)((NetworkInstanceId)(ref netId)).Value * 0.73f;
					float num4 = Mathf.Max(1.2f, displayedScale * 2f);
					((Vector3)(ref val3))..ctor(Mathf.Cos(num3) * num4, Mathf.Sin(num3 * 2f) * 0.3f, Mathf.Sin(num3) * num4);
					val2.transform.position = (PeakActive ? Body.corePosition : visual.transform.position) + val3;
					val2.transform.localScale = Vector3.one * 0.3f;
					val2.transform.rotation = Util.QuaternionSafeLookRotation(new Vector3(0f - Mathf.Sin(num3), 0f, Mathf.Cos(num3)));
				}
			}
		}

		private Vector3 HopPosition(float t)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: 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_0044: 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_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			float num = t * t * (3f - 2f * t);
			return Vector3.Lerp(segmentFrom, segmentTo, num) + Vector3.up * (4f * t * (1f - t) * segmentHeight) + segmentSide * (Mathf.Sin(t * MathF.PI) * segmentSway);
		}

		public bool InvokeServer(Invocation requested)
		{
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: 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_00dd: 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_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: 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_0102: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkServer.active || !Equipped || PresentationBusy || !Object.op_Implicit((Object)(object)form))
			{
				return false;
			}
			if (requested == Invocation.None || Rules.ReadyInvocation(Manifested, Stage, Resource, RequiredConvictions) != requested)
			{
				return false;
			}
			if (!form.TrySpendSouls(RequiredConvictions))
			{
				return false;
			}
			switch (requested)
			{
			case Invocation.Summon:
				Body.SetBuffCount(Plugin.Manifested.buffIndex, 1);
				Body.SetBuffCount(Plugin.Infusion.buffIndex, 0);
				Wire.Send(this, VisualEvent.Summon, Body.corePosition, IdlePosition, 0.625f, 0);
				break;
			case Invocation.Infuse:
			{
				int num = Stage + 1;
				Vector3 val = (Object.op_Implicit((Object)(object)visual) ? visual.transform.position : IdlePosition);
				Body.SetBuffCount(Plugin.Infusion.buffIndex, num);
				Wire.Send(this, VisualEvent.Infuse, val, Body.corePosition, 0.625f, num);
				break;
			}
			}
			if (Plugin.Verbose)
			{
				Plugin.Trace($"Litany {requested}: owner={((NetworkBehaviour)Body).netId}, stage={Stage}, Conviction={Resource}");
			}
			return true;
		}

		public void SacrificeUsed()
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkServer.active && Equipped && Manifested)
			{
				pending.Enqueue(Stage);
				if (Plugin.Verbose)
				{
					Plugin.Trace($"Sacrifice attack queued: owner={((NetworkBehaviour)Body).netId}, stage={Stage}, queued={pending.Count}");
				}
			}
		}

		public void BeginPeak()
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			PeakActive = true;
			segmentActive = false;
			peakDirection = (Object.op_Implicit((Object)(object)Body.inputBank) ? Body.inputBank.aimDirection : ((Component)Body).transform.forward);
		}

		public void EndPeak()
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: 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_00b7: Expected O, but got Unknown
			if (!PeakActive)
			{
				return;
			}
			PeakActive = false;
			segmentActive = false;
			ResetHover();
			if (NetworkServer.active && Object.op_Implicit((Object)(object)Body))
			{
				Wire.Send(this, VisualEvent.PeakEnd, Body.corePosition, ((Component)Body).transform.position, 0f, Stage);
				if (Manifested && Object.op_Implicit((Object)(object)Body.healthComponent) && Body.healthComponent.alive)
				{
					EffectManager.SpawnEffect(Plugin.ImpactPrefab, new EffectData
					{
						origin = IdlePosition,
						scale = 1f
					}, true);
				}
			}
		}

		internal void Receive(EffigyMessage message)
		{
			//IL_004d: 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_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: 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_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: 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_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0256: Unknown result type (might be due to invalid IL or missing references)
			//IL_025b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0262: Unknown result type (might be due to invalid IL or missing references)
			//IL_0267: Unknown result type (might be due to invalid IL or missing references)
			//IL_026d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0273: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_0249: Unknown result type (might be due to invalid IL or missing references)
			//IL_024e: Unknown result type (might be due to invalid IL or missing references)
			if (!Rules.NewerSequence(message.Sequence, receivedSequence) || message.Stage > 3 || (int)message.Kind > 5 || float.IsNaN(message.Duration) || float.IsInfinity(message.Duration) || message.Duration < 0f || !Finite(message.From) || !Finite(message.To))
			{
				return;
			}
			receivedSequence = message.Sequence;
			if (!NetworkServer.active)
			{
				networkManifested = true;
				networkStage = message.Stage;
			}
			if (message.Kind == VisualEvent.PeakEnd)
			{
				PeakActive = false;
				segmentActive = false;
				ResetHover();
				if (!NetworkServer.active)
				{
					if (Object.op_Implicit((Object)(object)Body.characterMotor))
					{
						((BaseCharacterController)Body.characterMotor).Motor.SetPosition(message.To, true);
						Body.characterMotor.velocity = Vector3.zero;
					}
					else
					{
						((Component)Body).transform.position = message.To;
					}
				}
			}
			else if (message.Kind == VisualEvent.Summon || message.Kind == VisualEvent.Infuse)
			{
				ritualStart = Time.time;
				ritualEnd = ritualStart + message.Duration;
				ritualSummon = message.Kind == VisualEvent.Summon;
				ritualStage = message.Stage;
				ritualOffset = message.From - Body.corePosition;
				if (((Vector3)(ref ritualOffset)).sqrMagnitude < 1f)
				{
					ritualOffset = HoverAnchor - Body.corePosition;
				}
				ritualOffset = Vector3.ClampMagnitude(ritualOffset, 4f);
				segmentActive = false;
				ResetHover();
			}
			else if (message.Kind == VisualEvent.Reform)
			{
				PeakActive = false;
				segmentActive = false;
				ResetHover();
			}
			else if (message.Kind == VisualEvent.PeakPosition)
			{
				PeakActive = true;
				segmentActive = false;
				peakDirection = message.From;
				if (!NetworkServer.active && Object.op_Implicit((Object)(object)Body.characterMotor))
				{
					((BaseCharacterController)Body.characterMotor).Motor.SetPosition(message.To, true);
					Body.characterMotor.velocity = Vector3.zero;
				}
			}
			else
			{
				segmentFrom = message.From;
				segmentTo = message.To;
				float num = Vector3.Distance(segmentFrom, segmentTo);
				segmentHeight = Rules.HopHeight(num);
				segmentSway = Mathf.Min(1.2f, num * 0.06f);
				Vector3 val = Vector3.Cross(Vector3.up, segmentTo - segmentFrom);
				segmentSide = ((Vector3)(ref val)).normalized;
				segmentStart = Time.time;
				segmentDuration = Mathf.Max(0.02f, message.Duration);
				segmentStage = message.Stage;
				segmentActive = true;
			}
		}

		private static bool Finite(Vector3 value)
		{
			//IL_0000: 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_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: 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_0041: Unknown result type (might be due to invalid IL or missing references)
			if (!float.IsNaN(value.x) && !float.IsInfinity(value.x) && !float.IsNaN(value.y) && !float.IsInfinity(value.y) && !float.IsNaN(value.z))
			{
				return !float.IsInfinity(value.z);
			}
			return false;
		}

		private IEnumerator DrainAttacks()
		{
			yield return null;
			while (pending.Count > 0 && Equipped && Manifested && Body.healthComponent.alive)
			{
				while (PresentationBusy)
				{
					yield return FixedTick;
				}
				int stage = pending.Dequeue();
				HashSet<HealthComponent> visited = passiveVisited;
				visited.Clear();
				List<DebuffCarry> carried = new List<DebuffCarry>();
				Vector3 from = IdlePosition;
				int strikes = Rules.PassiveStrikes(stage);
				for (int hit = 0; hit < strikes; hit++)
				{
					while (PresentationBusy)
					{
						yield return FixedTick;
						from = IdlePosition;
					}
					HurtBox target = FindTarget(from, (hit == 0) ? Plugin.Options.SearchRange.Value : Plugin.Options.RicochetRange.Value, visited);
					if (!Object.op_Implicit((Object)(object)target))
					{
						if (Plugin.Verbose)
						{
							Plugin.Trace($"Chain ended without next target: owner={((NetworkBehaviour)Body).netId}, strike={hit}, stage={stage}");
						}
						break;
					}
					visited.Add(target.healthComponent);
					Vector3 to = ((Component)target).transform.position;
					float duration = Rules.HopDuration(Vector3.Distance(from, to), Plugin.Options.Speed.Value);
					Wire.Send(this, VisualEvent.Segment, from, to, duration, stage);
					float elapsed = 0f;
					while (elapsed < duration)
					{
						if (PresentationBusy)
						{
							while (PresentationBusy)
							{
								yield return FixedTick;
							}
							from = IdlePosition;
							if (!Object.op_Implicit((Object)(object)target) || !Object.op_Implicit((Object)(object)target.healthComponent) || !target.healthComponent.alive)
							{
								break;
							}
							to = ((Component)target).transform.position;
							duration = Rules.HopDuration(Vector3.Distance(from, to), Plugin.Options.Speed.Value);
							elapsed = 0f;
							Wire.Send(this, VisualEvent.Segment, from, to, duration, stage);
						}
						elapsed += Time.fixedDeltaTime;
						yield return FixedTick;
					}
					if (Object.op_Implicit((Object)(object)target) && Object.op_Implicit((Object)(object)target.healthComponent) && target.healthComponent.alive && Vector3.Distance(to, ((Component)target).transform.position) <= 3f + target.healthComponent.body.radius)
					{
						Vector3 val = from;
						Vector3 position = ((Component)target).transform.position;
						LayerIndex world = LayerIndex.world;
						if (!Physics.Linecast(val, position, LayerMask.op_Implicit(((LayerIndex)(ref world)).mask), (QueryTriggerInteraction)1))
						{
							carried = Strike(target, stage, peak: false, carried, out var _);
						}
					}
					from = to;
				}
				while (PresentationBusy)
				{
					yield return FixedTick;
				}
				Wire.Send(this, VisualEvent.Reform, from, IdlePosition, 0f, stage);
				yield return ChainPause;
			}
			attacks = null;
		}

		internal HurtBox FindTarget(Vector3 origin, float range, HashSet<HealthComponent> visited)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: 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_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: 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_0060: Unknown result type (might be due to invalid IL or missing references)
			BullseyeSearch obj = targetSearch;
			obj.searchOrigin = origin;
			obj.searchDirection = Vector3.forward;
			obj.minDistanceFilter = 0f;
			obj.maxDistanceFilter = range;
			obj.maxAngleFilter = 180f;
			obj.teamMaskFilter = TeamMask.GetEnemyTeams(Body.teamComponent.teamIndex);
			obj.filterByDistinctEntity = true;
			obj.filterByLoS = true;
			obj.sortMode = (SortMode)1;
			obj.viewer = Body;
			obj.RefreshCandidates();
			foreach (HurtBox result in obj.GetResults())
			{
				if (Object.op_Implicit((Object)(object)result) && Object.op_Implicit((Object)(object)result.healthComponent) && Object.op_Implicit((Object)(object)result.healthComponent.body) && result.healthComponent.alive && (Object)(object)result.healthComponent != (Object)(object)Body.healthComponent && !visited.Contains(result.healthComponent))
				{
					return result;
				}
			}
			return null;
		}

		internal List<DebuffCarry> Strike(HurtBox target, int stage, bool peak, List<DebuffCarry> carried, out bool successful)
		{
			//IL_0066: 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_007c: 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_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_009e: 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_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: 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_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Expected O, but got Unknown
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0263: Unknown result type (might be due to invalid IL or missing references)
			//IL_026a: Unknown result type (might be due to invalid IL or missing references)
			//IL_026c: Invalid comparison between Unknown and I4
			//IL_0389: Unknown result type (might be due to invalid IL or missing references)
			//IL_038e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0390: Unknown result type (might be due to invalid IL or missing references)
			//IL_039a: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ab: Expected O, but got Unknown
			//IL_02a7: Unknown result type (might be due to invalid IL or missing references)
			successful = false;
			if (!NetworkServer.active || !Object.op_Implicit((Object)(object)target) || !Object.op_Implicit((Object)(object)target.healthComponent) || !target.healthComponent.alive)
			{
				return carried;
			}
			HealthComponent healthComponent = target.healthComponent;
			List<DebuffCarry> list = ((stage >= 2 && Plugin.Options.CopyTimedDebuffs.Value) ? Debuffs.Capture(healthComponent.body) : new List<DebuffCarry>());
			float combinedHealth = healthComponent.combinedHealth;
			DamageInfo val = new DamageInfo
			{
				attacker = ((Component)Body).gameObject,
				inflictor = ((Component)Body).gameObject,
				position = ((Component)target).transform.position,
				damage = Body.damage * (peak ? Plugin.Options.PeakDamage.Value : Plugin.Options.Damage.Value),
				crit = Util.CheckRoll(Body.crit, Body.master),
				procCoefficient = 1f,
				damageType = new DamageTypeCombo
				{
					damageSource = (DamageSource)8
				},
				force = Vector3.zero
			};
			healthComponent.TakeDamage(val);
			float num = Mathf.Max(0f, combinedHealth - healthComponent.combinedHealth);
			if (num <= 0f || val.rejected)
			{
				return carried;
			}
			successful = true;
			if (Plugin.Verbose)
			{
				Plugin.Trace($"Effigy hit: owner={((NetworkBehaviour)Body).netId}, victim={((Object)healthComponent.body).name}, damage={num:0.0}, peak={peak}, stage={stage}");
			}
			if (peak && healthComponent.alive && (healthComponent.body.isBoss || healthComponent.body.isChampion))
			{
				SetStateOnHurt component = ((Component)healthComponent).GetComponent<SetStateOnHurt>();
				if (Object.op_Implicit((Object)(object)component))
				{
					bool canBeStunned = component.canBeStunned;
					try
					{
						component.canBeStunned = true;
						component.SetStun(1f);
					}
					finally
					{
						component.canBeStunned = canBeStunned;
					}
				}
			}
			if (stage >= 2 && Plugin.Options.CopyTimedDebuffs.Value)
			{
				if (healthComponent.alive)
				{
					Debuffs.Apply(healthComponent.body, carried);
					list = Debuffs.Capture(healthComponent.body);
				}
				else
				{
					list.AddRange(carried);
				}
			}
			if (healthComponent.alive && Rules.CanExecute(healthComponent.healthFraction, stage, (healthComponent.body.bodyFlags & 0x10) > 0, healthComponent.body.isChampion, Plugin.Options.ExecuteChampions.Value))
			{
				healthComponent.Suicide(((Component)Body).gameObject, ((Component)Body).gameObject, val.damageType);
			}
			HealthComponent healthComponent2 = Body.healthComponent;
			recoveryLedger.Observe(healthComponent2.regainableHealth);
			float num2 = healthComponent2.GrantRegainableHealthServer(Rules.RecoveryAmount(healthComponent2.fullHealth, Plugin.Options.Recovery.Value));
			recoveryLedger.Grant(num2, healthComponent2.regainableHealth);
			if (Plugin.Verbose)
			{
				Plugin.Trace($"Recovery granted={num2:0.00}, tracked={recoveryLedger.Credit:0.00}, pool={healthComponent2.regainableHealth:0.00}, nativeDecayBlocked={healthComponent2.regainableHealthDepleteDisabledCounter > 0}");
			}
			GlobalEventManager.instance.OnHitEnemy(val, ((Component)healthComponent).gameObject);
			GlobalEventManager.instance.OnHitAll(val, ((Component)healthComponent).gameObject);
			EffectManager.SpawnEffect(Plugin.ImpactPrefab, new EffectData
			{
				origin = val.position,
				scale = 1f
			}, true);
			return list;
		}

		private void OnDestroy()
		{
			//IL_0043: 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)
			((MonoBehaviour)this).StopAllCoroutines();
			pending.Clear();
			attacks = null;
			if (NetworkServer.active && Object.op_Implicit((Object)(object)Body))
			{
				if (Object.op_Implicit((Object)(object)Plugin.Manifested))
				{
					Body.SetBuffCount(Plugin.Manifested.buffIndex, 0);
				}
				if (Object.op_Implicit((Object)(object)Plugin.Infusion))
				{
					Body.SetBuffCount(Plugin.Infusion.buffIndex, 0);
				}
			}
			foreach (GameObject orbitGhost in orbitGhosts)
			{
				if (Object.op_Implicit((Object)(object)orbitGhost))
				{
					Object.Destroy((Object)(object)orbitGhost);
				}
			}
			orbitGhosts.Clear();
			if (Object.op_Implicit((Object)(object)visual))
			{
				Object.Destroy((Object)(object)visual);
			}
		}
	}
	[BepInPlugin("local.animaeffigy", "Anima Effigy", "1.0.1")]
	public sealed class Plugin : BaseUnityPlugin, IContentPackProvider
	{
		public const string Id = "local.animaeffigy";

		public const string Version = "1.0.1";

		internal static Plugin Instance;

		internal static Settings Options;

		internal static EffigySkillDef Skill;

		internal static BuffDef Manifested;

		internal static BuffDef Infusion;

		internal static GameObject VisualPrefab;

		internal static GameObject OrbitGhostPrefab;

		internal static GameObject ImpactPrefab;

		internal static GameObject TransformChargePrefab;

		internal static GameObject TransformBurstPrefab;

		private readonly ContentPack content = new ContentPack();

		private readonly List<AsyncOperationHandle<GameObject>> handles = new List<AsyncOperationHandle<GameObject>>();

		private Harmony harmony;

		private GameObject templates;

		private Texture2D iconTexture;

		private Sprite iconSprite;

		public string identifier => "local.animaeffigy";

		internal static bool Verbose
		{
			get
			{
				if (Object.op_Implicit((Object)(object)Instance) && Options != null)
				{
					return Options.AggressiveLogging.Value;
				}
				return false;
			}
		}

		private void Awake()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Expected O, but got Unknown
			Instance = this;
			Options = new Settings(((BaseUnityPlugin)this).Config);
			harmony = new Harmony("local.animaeffigy");
			harmony.PatchAll(typeof(Plugin).Assembly);
			ContentManager.collectContentPackProviders += new CollectContentPackProvidersDelegate(AddProvider);
			CharacterBody.onBodyStartGlobal += OnBodyStart;
			NetworkManagerSystem.onStartClientGlobal += Wire.OnStartClient;
			RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(AdvertiseNetworkVersion));
			NetworkManagerSystem.onStopClientGlobal += Wire.OnStopClient;
			if (Verbose)
			{
				Trace("Anima Effigy 1.0.1: native Litany slot; Sacrifice retained; Conviction stored as AcolyteSoul.");
			}
		}

		private static void AdvertiseNetworkVersion()
		{
			string text = "local.animaeffigy;1.0.1";
			if (!NetworkModCompatibilityHelper.networkModList.Contains(text))
			{
				NetworkModCompatibilityHelper.networkModList = NetworkModCompatibilityHelper.networkModList.Concat(new string[1] { text });
			}
		}

		private void AddProvider(AddContentPackProviderDelegate add)
		{
			add.Invoke((IContentPackProvider)(object)this);
		}

		public IEnumerator LoadStaticContentAsync(LoadStaticContentAsyncArgs args)
		{
			AccessTools.Property(typeof(ContentPack), "identifier").SetValue(content, "local.animaeffigy");
			AsyncOperationHandle<GameObject> ghost = Addressables.LoadAssetAsync<GameObject>((object)"RoR2/Junk_DLC4/WightProjectile/WightProjectileGhost.prefab");
			handles.Add(ghost);
			yield return ghost;
			AsyncOperationHandle<GameObject> orbitGhost = Addressables.LoadAssetAsync<GameObject>((object)"RoR2/DLC4/Acolyte/HauntWightGhost.prefab");
			handles.Add(orbitGhost);
			yield return orbitGhost;
			if ((int)orbitGhost.Status != 1)
			{
				throw new InvalidOperationException("Anima Effigy: Haunt ghost visual failed to load.");
			}
			AsyncOperationHandle<GameObject> hit = Addressables.LoadAssetAsync<GameObject>((object)"RoR2/Junk_DLC4/WightProjectile/WightHit.prefab");
			handles.Add(hit);
			yield return hit;
			AsyncOperationHandle<GameObject> acolyte = Addressables.LoadAssetAsync<GameObject>((object)"RoR2/DLC4/Acolyte/AcolyteBody.prefab");
			handles.Add(acolyte);
			yield return acolyte;
			if ((int)ghost.Status != 1 || (int)hit.Status != 1 || (int)acolyte.Status != 1)
			{
				throw new InvalidOperationException("Anima Effigy: required installed-game Addressables failed to load.");
			}
			AsyncOperationHandle<GameObject> charge = Addressables.LoadAssetAsync<GameObject>((object)"a9702ea9b4efdcd46956371f32712917");
			handles.Add(charge);
			yield return charge;
			AsyncOperationHandle<GameObject> burst = Addressables.LoadAssetAsync<GameObject>((object)"66372c622519d5441a5c23734ffbe925");
			handles.Add(burst);
			yield return burst;
			if ((int)charge.Status != 1 || (int)burst.Status != 1)
			{
				throw new InvalidOperationException("Anima Effigy: native transformation VFX failed to load.");
			}
			templates = new GameObject("AnimaEffigyTemplates");
			templates.SetActive(false);
			Object.DontDestroyOnLoad((Object)(object)templates);
			TransformChargePrefab = CloneTransformationEffect(charge.Result, "AnimaEffigyTransformCharge");
			TransformBurstPrefab = CloneTransformationEffect(burst.Result, "AnimaEffigyTransformBurst");
			VisualPrefab = Object.Instantiate<GameObject>(ghost.Result, templates.transform);
			((Object)VisualPrefab).name = "AnimaEffigyVisual";
			VisualPrefab.SetActive(false);
			MonoBehaviour[] componentsInChildren = VisualPrefab.GetComponentsInChildren<MonoBehaviour>(true);
			foreach (MonoBehaviour val in componentsInChildren)
			{
				if (!(((object)val).GetType().Name == "FlickerLight"))
				{
					Object.DestroyImmediate((Object)(object)val);
				}
			}
			ParticleSystem[] componentsInChildren2 = VisualPrefab.GetComponentsInChildren<ParticleSystem>(true);
			for (int i = 0; i < componentsInChildren2.Length; i++)
			{
				MainModule main = componentsInChildren2[i].main;
				((MainModule)(ref main)).scalingMode = (ParticleSystemScalingMode)0;
			}
			Collider[] componentsInChildren3 = VisualPrefab.GetComponentsInChildren<Collider>(true);
			for (int i = 0; i < componentsInChildren3.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren3[i]);
			}
			Rigidbody[] componentsInChildren4 = VisualPrefab.GetComponentsInChildren<Rigidbody>(true);
			for (int i = 0; i < componentsInChildren4.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren4[i]);
			}
			OrbitGhostPrefab = Object.Instantiate<GameObject>(orbitGhost.Result, templates.transform);
			((Object)OrbitGhostPrefab).name = "AnimaEffigyOrbitHauntGhost";
			OrbitGhostPrefab.SetActive(false);
			componentsInChildren = OrbitGhostPrefab.GetComponentsInChildren<MonoBehaviour>(true);
			foreach (MonoBehaviour val2 in componentsInChildren)
			{
				if (!(((object)val2).GetType().Name == "FlickerLight"))
				{
					Object.DestroyImmediate((Object)(object)val2);
				}
			}
			componentsInChildren3 = OrbitGhostPrefab.GetComponentsInChildren<Collider>(true);
			for (int i = 0; i < componentsInChildren3.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren3[i]);
			}
			componentsInChildren4 = OrbitGhostPrefab.GetComponentsInChildren<Rigidbody>(true);
			for (int i = 0; i < componentsInChildren4.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren4[i]);
			}
			componentsInChildren2 = OrbitGhostPrefab.GetComponentsInChildren<ParticleSystem>(true);
			for (int i = 0; i < componentsInChildren2.Length; i++)
			{
				MainModule main2 = componentsInChildren2[i].main;
				((MainModule)(ref main2)).scalingMode = (ParticleSystemScalingMode)0;
			}
			ImpactPrefab = Object.Instantiate<GameObject>(hit.Result, templates.transform);
			((Object)ImpactPrefab).name = "AnimaEffigyImpact";
			ImpactPrefab.SetActive(true);
			AcolyteFormController component = acolyte.Result.GetComponent<AcolyteFormController>();
			if (!Object.op_Implicit((Object)(object)component) || !Object.op_Implicit((Object)(object)component.transformSkillSlot) || !Object.op_Implicit((Object)(object)component.transformSkillSlot.skillFamily))
			{
				throw new InvalidOperationException("Acolyte Litany/transformation skill family missing.");
			}
			component.transformSkillSlot.hideInCharacterSelect = false;
			SkillFamily skillFamily = component.transformSkillSlot.skillFamily;
			SkillDef defaultSkillDef = skillFamily.defaultSkillDef;
			Manifested = ScriptableObject.CreateInstance<BuffDef>();
			((Object)Manifested).name = "AnimaEffigyManifested";
			Manifested.isHidden = true;
			Manifested.canStack = false;
			Manifested.isDebuff = false;
			Manifested.buffColor = new Color(0.4f, 1f, 0.3f);
			Infusion = ScriptableObject.CreateInstance<BuffDef>();
			((Object)Infusion).name = "AnimaEffigyInfusion";
			Infusion.isHidden = true;
			Infusion.canStack = true;
			Infusion.isDebuff = false;
			Infusion.buffColor = new Color(0.6f, 1f, 0.4f);
			Skill = ScriptableObject.CreateInstance<EffigySkillDef>();
			((Object)Skill).name = "AnimaEffigy";
			((SkillDef)Skill).skillName = "AnimaEffigy";
			((SkillDef)Skill).skillNameToken = "ANIMA_EFFIGY_NAME";
			((SkillDef)Skill).skillDescriptionToken = "ANIMA_EFFIGY_DESCRIPTION";
			using (Stream stream = typeof(Plugin).Assembly.GetManifestResourceStream("AnimaEffigy.icon.png"))
			{
				if (stream == null)
				{
					throw new InvalidOperationException("Embedded Effigy icon missing.");
				}
				byte[] array = new byte[stream.Length];
				int num;
				for (int j = 0; j < array.Length; j += num)
				{
					num = stream.Read(array, j, array.Length - j);
					if (num == 0)
					{
						throw new InvalidOperationException("Incomplete Effigy icon.");
					}
				}
				iconTexture = new Texture2D(2, 2, (TextureFormat)4, false);
				if (!ImageConversion.LoadImage(iconTexture, array))
				{
					throw new InvalidOperationException("Effigy icon decode failed.");
				}
			}
			iconSprite = Sprite.Create(iconTexture, new Rect(0f, 0f, (float)((Texture)iconTexture).width, (float)((Texture)iconTexture).height), new Vector2(0.5f, 0.5f));
			((SkillDef)Skill).icon = iconSprite;
			Manifested.iconSprite = ((SkillDef)Skill).icon;
			Infusion.iconSprite = ((SkillDef)Skill).icon;
			((SkillDef)Skill).activationState = new SerializableEntityStateType(typeof(ActivateEffigy));
			((SkillDef)Skill).activationStateMachineName = "Body";
			((SkillDef)Skill).interruptPriority = (InterruptPriority)2;
			((SkillDef)Skill).baseRechargeInterval = defaultSkillDef.baseRechargeInterval;
			((SkillDef)Skill).baseMaxStock = defaultSkillDef.baseMaxStock;
			((SkillDef)Skill).rechargeStock = defaultSkillDef.rechargeStock;
			((SkillDef)Skill).requiredStock = defaultSkillDef.requiredStock;
			((SkillDef)Skill).stockToConsume = defaultSkillDef.stockToConsume;
			((SkillDef)Skill).fullRestockOnAssign = defaultSkillDef.fullRestockOnAssign;
			((SkillDef)Skill).mustKeyPress = true;
			((SkillDef)Skill).beginSkillCooldownOnSkillEnd = true;
			((SkillDef)Skill).cancelSprintingOnActivation = true;
			((SkillDef)Skill).keywordTokens = new string[2] { "KEYWORD_ANIMA_IMBUE", "KEYWORD_ANIMA_LASH_OUT" };
			content.skillDefs.Add((SkillDef[])(object)new SkillDef[1] { Skill });
			content.buffDefs.Add((BuffDef[])(object)new BuffDef[2] { Manifested, Infusion });
			content.entityStateTypes.Add(new Type[3]
			{
				typeof(ActivateEffigy),
				typeof(PeakEffigy),
				typeof(ReformEffigy)
			});
			content.effectDefs.Add((EffectDef[])(object)new EffectDef[2]
			{
				new EffectDef(ImpactPrefab),
				new EffectDef(TransformBurstPrefab)
			});
			Variant[] array2 = skillFamily.variants;
			Array.Resize(ref array2, array2.Length + 1);
			Variant[] array3 = array2;
			int num2 = array2.Length - 1;
			Variant val3 = new Variant
			{
				skillDef = (SkillDef)(object)Skill
			};
			((Variant)(ref val3)).viewableNode = new Node(((SkillDef)Skill).skillNameToken, false, (Node)null);
			array3[num2] = val3;
			skillFamily.variants = array2;
			if (Verbose)
			{
				Trace("Registered Anima Effigy in AcolyteTransformationSkillFamily (Litany); native Sacrifice special unchanged.");
			}
			args.ReportProgress(1f);
		}

		private GameObject CloneTransformationEffect(GameObject source, string name)
		{
			//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)
			//IL_0059: 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)
			GameObject val = Object.Instantiate<GameObject>(source, templates.transform);
			((Object)val).name = name;
			Transform transform = val.transform;
			transform.localScale *= 1.5f;
			EffectComponent component = val.GetComponent<EffectComponent>();
			if (Object.op_Implicit((Object)(object)component))
			{
				component.applyScale = false;
			}
			ParticleSystem[] componentsInChildren = val.GetComponentsInChildren<ParticleSystem>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				MainModule main = componentsInChildren[i].main;
				((MainModule)(ref main)).scalingMode = (ParticleSystemScalingMode)0;
			}
			val.SetActive(true);
			return val;
		}

		public IEnumerator GenerateContentPackAsync(GetContentPackAsyncArgs args)
		{
			ContentPack.Copy(content, args.output);
			args.ReportProgress(1f);
			yield break;
		}

		public IEnumerator FinalizeAsync(FinalizeAsyncArgs args)
		{
			args.ReportProgress(1f);
			yield break;
		}

		internal static EffigyController Ensure(CharacterBody body)
		{
			if (!Object.op_Implicit((Object)(object)body) || !Object.op_Implicit((Object)(object)Skill))
			{
				return null;
			}
			AcolyteFormController component = ((Component)body).GetComponent<AcolyteFormController>();
			if (!Object.op_Implicit((Object)(object)component) || !Object.op_Implicit((Object)(object)component.transformSkillSlot) || (Object)(object)component.transformSkillSlot.skillDef != (Object)(object)Skill)
			{
				return null;
			}
			return ((Component)body).GetComponent<EffigyController>() ?? ((Component)body).gameObject.AddComponent<EffigyController>();
		}

		private static void OnBodyStart(CharacterBody body)
		{
			Ensure(body);
		}

		internal static void Trace(string message)
		{
			if (Object.op_Implicit((Object)(object)Instance) && Options != null && Options.AggressiveLogging.Value)
			{
				((BaseUnityPlugin)Instance).Logger.LogInfo((object)message);
			}
		}

		private void OnDestroy()
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			CharacterBody.onBodyStartGlobal -= OnBodyStart;
			ContentManager.collectContentPackProviders -= new CollectContentPackProvidersDelegate(AddProvider);
			NetworkManagerSystem.onStartClientGlobal -= Wire.OnStartClient;
			RoR2Application.onLoad = (Action)Delegate.Remove(RoR2Application.onLoad, new Action(AdvertiseNetworkVersion));
			NetworkManagerSystem.onStopClientGlobal -= Wire.OnStopClient;
			Wire.OnStopClient();
			Harmony obj = harmony;
			if (obj != null)
			{
				obj.UnpatchSelf();
			}
			if (Object.op_Implicit((Object)(object)templates))
			{
				Object.Destroy((Object)(object)templates);
			}
			if (Object.op_Implicit((Object)(object)iconSprite))
			{
				Object.Destroy((Object)(object)iconSprite);
			}
			if (Object.op_Implicit((Object)(object)iconTexture))
			{
				Object.Destroy((Object)(object)iconTexture);
			}
			foreach (AsyncOperationHandle<GameObject> handle in handles)
			{
				if (handle.IsValid())
				{
					Addressables.Release<GameObject>(handle);
				}
			}
			if ((Object)(object)Instance == (Object)(object)this)
			{
				Instance = null;
			}
		}
	}
	public sealed class EffigySkillDef : SkillDef
	{
		private SerializableEntityStateType peakState = new SerializableEntityStateType(typeof(PeakEffigy));

		public override ref SerializableEntityStateType GetActivationState(GenericSkill slot)
		{
			EffigyController effigyController = Plugin.Ensure(slot.characterBody);
			if (Object.op_Implicit((Object)(object)effigyController) && effigyController.Manifested && effigyController.Stage >= 3)
			{
				return ref peakState;
			}
			return ref base.activationState;
		}

		public override BaseSkillInstanceData OnAssigned(GenericSkill slot)
		{
			Plugin.Ensure(slot.characterBody);
			return ((SkillDef)this).OnAssigned(slot);
		}

		public override void OnUnassigned(GenericSkill slot)
		{
			EffigyController effigyController = (Object.op_Implicit((Object)(object)slot.characterBody) ? ((Component)slot.characterBody).GetComponent<EffigyController>() : null);
			AcolyteFormController val = (Object.op_Implicit((Object)(object)slot.characterBody) ? ((Component)slot.characterBody).GetComponent<AcolyteFormController>() : null);
			if (Object.op_Implicit((Object)(object)effigyController) && Object.op_Implicit((Object)(object)val) && (Object)(object)slot == (Object)(object)val.transformSkillSlot)
			{
				Object.Destroy((Object)(object)effigyController);
			}
			((SkillDef)this).OnUnassigned(slot);
		}

		public override bool IsReady(GenericSkill slot)
		{
			if (!((SkillDef)this).IsReady(slot))
			{
				return false;
			}
			EffigyController effigyController = Plugin.Ensure(slot.characterBody);
			if (!Object.op_Implicit((Object)(object)effigyController) || effigyController.PresentationBusy)
			{
				return false;
			}
			return Rules.ReadyInvocation(effigyController.Manifested, effigyController.Stage, effigyController.Resource, effigyController.RequiredConvictions) != Invocation.None;
		}
	}
	[HarmonyPatch(typeof(Language), "GetLocalizedStringByToken")]
	internal static class LanguagePatch
	{
		private static bool Prefix(string __0, ref string __result)
		{
			switch (__0)
			{
			case "ANIMA_EFFIGY_NAME":
				__result = "Anima Effigy";
				return false;
			case "KEYWORD_ANIMA_IMBUE":
				__result = "<style=cKeywordName>Imbue</style><style=cSub>Each stack increases its strength by <style=cIsDamage>100%</style> and allows it to ricochet an additional time. Stacks up to three times. At max stacks, it causes the spirit to carry you while it <style=cIsDamage>lashes out</style>.</style>";
				return false;
			case "KEYWORD_ANIMA_LASH_OUT":
				__result = "<style=cKeywordName>Lash Out</style><style=cSub>Ram an enemy dealing <style=cIsDamage>300% damage</style> and granting you <style=cIsHealing>Recoverable Health</style> for <style=cIsHealing>15% of your max health</style>.</style>";
				return false;
			default:
				if (__0 != "ANIMA_EFFIGY_DESCRIPTION")
				{
					return true;
				}
				__result = "Summon an anima spirit or <style=cIsUtility>imbue</style> it. Every <style=cIsUtility>Sacrifice</style> causes the spirit to <style=cIsDamage>lash out</style>.";
				return false;
			}
		}
	}
	[HarmonyPatch(typeof(Sacrifice), "OnEnter")]
	internal static class SacrificeUsePatch
	{
		private static void Postfix(Sacrifice __instance)
		{
			if (NetworkServer.active)
			{
				EffigyController effigyController = Plugin.Ensure(((Component)((EntityState)__instance).outer).GetComponent<CharacterBody>());
				if (Object.op_Implicit((Object)(object)effigyController))
				{
					effigyController.SacrificeUsed();
				}
			}
		}
	}
	[HarmonyPatch(typeof(AcolyteFormController), "OnDamageDealtServer")]
	internal static class DamageRecoveryPatch
	{
		private static void Postfix(AcolyteFormController __instance, DamageReport __0)
		{
			if (NetworkServer.active && Object.op_Implicit((Object)(object)__instance.characterBody))
			{
				EffigyController component = ((Component)__instance.characterBody).GetComponent<EffigyController>();
				if (Object.op_Implicit((Object)(object)component))
				{
					component.RecoverFromDamage(__0);
				}
			}
		}
	}
	public enum Invocation
	{
		None,
		Infuse,
		Peak,
		Summon
	}
	public static class Rules
	{
		public const int MaxInfusions = 3;

		public const float PeakWindup = 0.625f;

		public const float PeakReform = 0.625f;

		public const float RitualDuration = 0.625f;

		public static bool NewerSequence(uint current, uint previous)
		{
			if (current == 0)
			{
				return false;
			}
			if (previous == 0)
			{
				return true;
			}
			return (int)(current - previous) > 0;
		}

		public static Invocation ReadyInvocation(int infusion, int convictions, int required)
		{
			if (required <= 0 || convictions < required)
			{
				return Invocation.None;
			}
			if (infusion < 3)
			{
				return Invocation.Infuse;
			}
			return Invocation.Peak;
		}

		public static Invocation ReadyInvocation(bool manifested, int infusion, int convictions, int required)
		{
			if (required <= 0 || convictions < required)
			{
				return Invocation.None;
			}
			if (!manifested)
			{
				return Invocation.Summon;
			}
			return ReadyInvocation(infusion, convictions, required);
		}

		public static int OrbitGhostCount(int infusion)
		{
			if (infusion >= 3)
			{
				return 2;
			}
			if (infusion >= 2)
			{
				return 1;
			}
			return 0;
		}

		public static float HopHeight(float distance)
		{
			return Math.Min(5f, Math.Max(0.6f, distance * 0.18f));
		}

		public static float HopDuration(float distance, float speed)
		{
			return Math.Max(0.35f, distance / Math.Max(1f, speed));
		}

		public static float VisualScale(float baseScale, float fullScale, int infusion)
		{
			float num = Math.Max(baseScale, fullScale);
			int num2 = Math.Max(0, Math.Min(3, infusion));
			float num3 = (num - baseScale) * (float)num2 / 3f;
			return baseScale + num3;
		}

		public static float RecoveryAmount(float maximumHealth, float fraction)
		{
			return Math.Max(0f, maximumHealth) * Math.Max(0f, Math.Min(1f, fraction));
		}

		public static float RecoveryHealAmount(float damage, float fraction, float recoverableHealth, bool nativeTransformation)
		{
			if (nativeTransformation || damage <= 0f || fraction <= 0f || recoverableHealth <= 0f)
			{
				return 0f;
			}
			return Math.Min(damage * fraction, recoverableHealth);
		}

		public static int PassiveStrikes(int infusion)
		{
			return 1 + Math.Max(0, Math.Min(3, infusion));
		}

		public static bool CanExecute(float healthFraction, int infusion, bool immune, bool champion, bool allowChampion)
		{
			if (infusion >= 3 && !immune && (!champion || allowChampion))
			{
				return healthFraction < 0.25f;
			}
			return false;
		}
	}
	public sealed class RecoveryLedger
	{
		private float observedPool;

		private float decayAccumulator;

		public float Credit { get; private set; }

		public void Observe(float pool)
		{
			pool = Math.Max(0f, pool);
			float num = Math.Max(0f, observedPool - pool);
			float val = Math.Max(0f, Credit - num);
			Credit = Math.Min(pool, val);
			observedPool = pool;
		}

		public void Grant(float actualGranted, float pool)
		{
			Credit = Math.Min(Math.Max(0f, pool), Credit + Math.Max(0f, actualGranted));
			observedPool = Math.Max(0f, pool);
		}

		public float DecayAmount(float maxHealth, float deltaTime, bool nativeBlocked, float nativeFractionPerSecond = 0.01f)
		{
			if (Credit <= 0f)
			{
				decayAccumulator = 0f;
				return 0f;
			}
			float num = Math.Max(0f, 0.05f - (nativeBlocked ? 0f : nativeFractionPerSecond));
			decayAccumulator += Math.Max(0f, maxHealth) * num * Math.Max(0f, deltaTime);
			if (decayAccumulator <= 1f)
			{
				return 0f;
			}
			float num2 = Math.Min(Credit, (float)Math.Floor(decayAccumulator));
			decayAccumulator -= num2;
			return num2;
		}
	}
	public sealed class PeakBudget
	{
		public readonly float MaxDistance;

		public readonly int MaxRicochets;

		public float Distance { get; private set; }

		public int Strikes { get; private set; }

		public float Remaining => Math.Max(0f, MaxDistance - Distance);

		public bool Finished
		{
			get
			{
				if (!(Remaining <= 0.001f))
				{
					return Strikes >= MaxRicochets + 1;
				}
				return true;
			}
		}

		public PeakBudget(float maxDistance = 1000f, int maxRicochets = 10)
		{
			if (float.IsNaN(maxDistance) || float.IsInfinity(maxDistance) || maxDistance <= 0f)
			{
				throw new ArgumentOutOfRangeException("maxDistance");
			}
			if (maxRicochets < 0)
			{
				throw new ArgumentOutOfRangeException("maxRicochets");
			}
			MaxDistance = maxDistance;
			MaxRicochets = maxRicochets;
		}

		public float LimitStep(float requested)
		{
			if (Finished)
			{
				return 0f;
			}
			return Math.Min(Math.Max(0f, requested), Remaining);
		}

		public void RecordTravel(float actual)
		{
			Distance = Math.Min(MaxDistance, Distance + Math.Max(0f, actual));
		}

		public bool RecordStrike()
		{
			if (Strikes >= MaxRicochets + 1)
			{
				return false;
			}
			Strikes++;
			return true;
		}
	}
	internal sealed class Settings
	{
		internal readonly ConfigEntry<float> Damage;

		internal readonly ConfigEntry<float> PeakDamage;

		internal readonly ConfigEntry<float> Recovery;

		internal readonly ConfigEntry<float> Speed;

		internal readonly ConfigEntry<float> PeakSpeed;

		internal readonly ConfigEntry<float> SearchRange;

		internal readonly ConfigEntry<float> RicochetRange;

		internal readonly ConfigEntry<float> BaseScale;

		internal readonly ConfigEntry<float> FullScale;

		internal readonly ConfigEntry<float> HoverHeight;

		internal readonly ConfigEntry<float> FollowDistance;

		internal readonly ConfigEntry<float> FollowLag;

		internal readonly ConfigEntry<float> BobAmplitude;

		internal readonly ConfigEntry<float> BobSpeed;

		internal readonly ConfigEntry<float> SwayAmplitude;

		internal readonly ConfigEntry<bool> ExecuteChampions;

		internal readonly ConfigEntry<bool> CopyTimedDebuffs;

		internal readonly ConfigEntry<bool> AggressiveLogging;

		internal Settings(ConfigFile config)
		{
			Damage = Float(config, "Damage", "PassiveCoefficient", 3f, 0f, 100f, "Damage per passive strike, as a multiple of Acolyte damage.");
			PeakDamage = Float(config, "Damage", "PeakCoefficient", 5f, 0f, 100f, "Damage per peak strike.");
			Recovery = Float(config, "Damage", "RecoverableHealthFraction", 0.15f, 0f, 1f, "Fraction of Acolyte maximum health granted as Recoverable Health on each successful passive or peak hit. Capped by missing health; native decay remains active.");
			Speed = Float(config, "Movement", "EffigySpeed", 55f, 20f, 500f, "Meters per second for spirit attacks.");
			PeakSpeed = Float(config, "Movement", "PeakSpeed", 160f, 20f, 500f, "Meters per second during the spectral missile state.");
			SearchRange = Float(config, "Targeting", "InitialRange", 60f, 5f, 150f, "Initial target search range.");
			RicochetRange = Float(config, "Targeting", "RicochetRange", 64f, 5f, 150f, "Maximum distance to the next distinct target. Default matches native HauntWight lookRange (64 meters).");
			BaseScale = Float(config, "Visual", "BaseScale", 0.45f, 0.1f, 10f, "Small starting manifestation; grows across three infusions.");
			FullScale = Float(config, "Visual", "FullScale", 1.5f, 0.1f, 10f, "Size at infusion III. Default matches the previous prototype's oversized base, not its doubled final size.");
			HoverHeight = Float(config, "Visual", "HoverHeight", 2f, 0f, 10f, "Hover height above Acolyte's center.");
			FollowDistance = Float(config, "Visual", "FollowDistance", 2.8f, 0f, 10f, "Idle trailing distance behind Acolyte.");
			FollowLag = Float(config, "Visual", "FollowLag", 0.5f, 0.05f, 2f, "Seconds of damped follow response. Higher values give more drag behind movement and turns.");
			BobAmplitude = Float(config, "Visual", "BobAmplitude", 0.35f, 0f, 2f, "Gentle vertical hover amplitude in meters.");
			BobSpeed = Float(config, "Visual", "BobSpeed", 1.8f, 0.1f, 6f, "Vertical hover oscillation speed, in radians per second.");
			SwayAmplitude = Float(config, "Visual", "SwayAmplitude", 0.25f, 0f, 2f, "Slow horizontal idle sway in meters.");
			ConfigEntry<int> val = config.Bind<int>("General", "SettingsVersion", 0, "Internal settings migration version.");
			if (val.Value < 2)
			{
				if (Math.Abs(BaseScale.Value - 1.5f) < 0.001f)
				{
					BaseScale.Value = 0.45f;
				}
				val.Value = 2;
				config.Save();
			}
			if (val.Value < 3)
			{
				if (Math.Abs(Speed.Value - 180f) < 0.001f)
				{
					Speed.Value = 55f;
				}
				Recovery.Value = 0.15f;
				val.Value = 3;
				config.Save();
			}
			if (val.Value < 4)
			{
				if (Math.Abs(RicochetRange.Value - 40f) < 0.001f)
				{
					RicochetRange.Value = 64f;
				}
				val.Value = 4;
				config.Save();
			}
			ExecuteChampions = config.Bind<bool>("Damage", "ExecuteBosses", true, "Allow executes on champion bodies; native ImmuneToExecutes is always respected. Elites are eligible.");
			CopyTimedDebuffs = config.Bind<bool>("Damage", "CopyTimedDebuffs", true, "Infusion II+: copy timed non-DOT debuffs without removing them from the source; retain remaining duration, cap each type at 8 copied stacks. Permanent buffs and DOT payloads are excluded.");
			AggressiveLogging = config.Bind<bool>("Debug", "AggressiveLogging", false, "Enable detailed Effigy lifecycle, Sacrifice, targeting, hit, and network visual logs. Disabled by default.");
		}

		private static ConfigEntry<float> Float(ConfigFile config, string section, string key, float value, float min, float max, string description)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			return config.Bind<float>(section, key, value, new ConfigDescription(description, (AcceptableValueBase)(object)new AcceptableValueRange<float>(min, max), Array.Empty<object>()));
		}
	}
	public abstract class VanillaEffigyTransformation : BaseSkillState
	{
		private EnterBodySwap native;

		private GameObject charge;

		private CameraParamsOverrideHandle transformCamera;

		private bool transforming;

		private bool completed;

		private bool hadBuddha;

		private float priorWalkPenalty;

		protected void BeginTransformation()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected O, but got Unknown
			//IL_0101: 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_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_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Invalid comparison between Unknown and I4
			//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			native = (EnterBodySwap)EntityStateCatalog.InstantiateState(typeof(EnterBodySwap));
			transforming = true;
			completed = false;
			if (Object.op_Implicit((Object)(object)((EntityState)this).characterMotor))
			{
				priorWalkPenalty = ((EntityState)this).characterMotor.walkSpeedPenaltyCoefficient;
				((EntityState)this).characterMotor.walkSpeedPenaltyCoefficient = native.walkSpeedCoefficient;
				((BaseState)this).SmallHop(((EntityState)this).characterMotor, native.enterHopStrength);
			}
			((BaseState)this).StartAimMode(2f, false);
			((EntityState)this).PlayAnimation(native.animLayer, native.animState, native.animParam, native.baseDuration / native.animFireTime, 0f);
			Util.PlaySound(native.enterSoundString, ((EntityState)this).gameObject);
			if (Object.op_Implicit((Object)(object)native.cameraParams) && Object.op_Implicit((Object)(object)((EntityState)this).cameraTargetParams))
			{
				transformCamera = ((EntityState)this).cameraTargetParams.AddParamsOverride(new CameraParamsOverrideRequest
				{
					cameraParamsData = native.cameraParams.data
				}, native.cameraStartTime);
			}
			Transform val = ((BaseState)this).FindModelChild(native.effectMuzzle) ?? ((EntityState)this).characterBody.coreTransform;
			if (Object.op_Implicit((Object)(object)Plugin.TransformChargePrefab) && Object.op_Implicit((Object)(object)val))
			{
				charge = EntityState.Instantiate<GameObject>(Plugin.TransformChargePrefab, val.position, val.rotation);
				charge.transform.SetParent(val, true);
				ScaleParticleSystemDuration component = charge.GetComponent<ScaleParticleSystemDuration>();
				if (Object.op_Implicit((Object)(object)component))
				{
					component.newDuration = native.baseDuration;
				}
			}
			hadBuddha = (((EntityState)this).characterBody.bodyFlags & 0x800000) > 0;
			CharacterBody characterBody = ((EntityState)this).characterBody;
			characterBody.bodyFlags = (BodyFlags)(characterBody.bodyFlags | 0x800000);
		}

		protected bool TickTransformation()
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			if (!transforming)
			{
				return true;
			}
			if (((EntityState)this).isAuthority && Object.op_Implicit((Object)(object)((EntityState)this).characterMotor))
			{
				((EntityState)this).characterMotor.moveDirection = ((EntityState)this).inputBank.moveVector;
				((EntityState)this).characterMotor.velocity.y += native.antigravityStrength * ((EntityState)this).GetDeltaTime() * (1f - Mathf.Clamp01(((EntityState)this).fixedAge / native.baseDuration));
			}
			if (((EntityState)this).fixedAge < native.baseDuration)
			{
				return false;
			}
			if (!completed)
			{
				completed = true;
				if (Object.op_Implicit((Object)(object)Plugin.TransformBurstPrefab))
				{
					EffectManager.SimpleMuzzleFlash(Plugin.TransformBurstPrefab, ((EntityState)this).gameObject, native.effectMuzzle, false);
				}
				if (((EntityState)this).isAuthority && Object.op_Implicit((Object)(object)((EntityState)this).characterMotor))
				{
					((BaseState)this).SmallHop(((EntityState)this).characterMotor, native.exitHopStrength);
				}
			}
			EndTransformation();
			return true;
		}

		protected void EndTransformation()
		{
			//IL_008c: 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_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: 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)
			if (transforming)
			{
				transforming = false;
				if (Object.op_Implicit((Object)(object)charge))
				{
					EntityState.Destroy((Object)(object)charge);
				}
				if (Object.op_Implicit((Object)(object)((EntityState)this).characterMotor))
				{
					((EntityState)this).characterMotor.walkSpeedPenaltyCoefficient = priorWalkPenalty;
				}
				if (((CameraParamsOverrideHandle)(ref transformCamera)).isValid && Object.op_Implicit((Object)(object)((EntityState)this).cameraTargetParams))
				{
					((EntityState)this).cameraTargetParams.RemoveParamsOverride(transformCamera, native.cameraEndTime);
				}
				if (!hadBuddha)
				{
					CharacterBody characterBody = ((EntityState)this).characterBody;
					characterBody.bodyFlags = (BodyFlags)(characterBody.bodyFlags & -8388609);
				}
			}
		}

		public override void OnExit()
		{
			EndTransformation();
			((EntityState)this).OnExit();
		}
	}
	public sealed class ActivateEffigy : VanillaEffigyTransformation
	{
		public override void OnEnter()
		{
			((BaseState)this).OnEnter();
			BeginTransformation();
			EffigyController effigyController = Plugin.Ensure(((EntityState)this).characterBody);
			if (NetworkServer.active && Object.op_Implicit((Object)(object)effigyController))
			{
				effigyController.InvokeServer(effigyController.Manifested ? Invocation.Infuse : Invocation.Summon);
			}
		}

		public override void FixedUpdate()
		{
			((EntityState)this).FixedUpdate();
			if (TickTransformation() && ((EntityState)this).isAuthority)
			{
				((EntityState)this).outer.SetNextStateToMain();
			}
		}

		public override InterruptPriority GetMinimumInterruptPriority()
		{
			return (InterruptPriority)8;
		}
	}
	public sealed class PeakEffigy : VanillaEffigyTransformation
	{
		private EffigyController owner;

		private readonly HashSet<HealthComponent> visited = new HashSet<HealthComponent>();

		private List<DebuffCarry> carried = new List<DebuffCarry>();

		private PeakBudget budget;

		private HurtBox target;

		private Vector3 direction;

		private Vector3 coreOffset;

		private bool addedAntiGravity;

		private bool finished;

		private bool homingUnlocked;

		private float snapshotTimer;

		private bool launched;

		private Animator pilotAnimator;

		private float priorAnimatorSpeed;

		private bool holdingPilotPose;

		private bool surfaceRestored;

		private bool phaseMotorDisabled;

		private bool motorWasEnabled;

		private bool crossedTerrain;

		private readonly RaycastHit[] initialHits = (RaycastHit[])(object)new RaycastHit[64];

		private bool hasDetour;

		private Vector3 detourPoint;

		private float nextRouteCheck;

		private static readonly float[] DetourOffsets = new float[4] { 2f, 4f, 8f, 16f };

		private readonly Vector3[] detourAxes = (Vector3[])(object)new Vector3[5];

		private CameraParamsOverrideHandle cameraOverride;

		private Vector3 CorePosition => ((Component)((EntityState)this).characterBody).transform.position + coreOffset;

		public override void OnEnter()
		{
			//IL_00c7: 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_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: 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)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: 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_0094: Unknown result type (might be due to invalid IL or missing references)
			((BaseState)this).OnEnter();
			owner = Plugin.Ensure(((EntityState)this).characterBody);
			budget = new PeakBudget();
			if (!Object.op_Implicit((Object)(object)owner) || (NetworkServer.active && (!owner.Manifested || owner.Stage < 3)))
			{
				finished = true;
				return;
			}
			if (NetworkServer.active && !owner.InvokeServer(Invocation.Peak))
			{
				finished = true;
				Wire.Send(owner, VisualEvent.Reform, ((EntityState)this).characterBody.corePosition, ((EntityState)this).characterBody.corePosition, 0f, owner.Stage);
				return;
			}
			BeginTransformation();
			owner.BeginPeak();
			coreOffset = ((EntityState)this).characterBody.corePosition - ((Component)((EntityState)this).characterBody).transform.position;
			Vector3 aimDirection = ((EntityState)this).inputBank.aimDirection;
			direction = ((Vector3)(ref aimDirection)).normalized;
			if (((Vector3)(ref direction)).sqrMagnitude < 0.01f)
			{
				direction = ((Component)((EntityState)this).characterBody).transform.forward;
			}
			if (NetworkServer.active)
			{
				SendPosition();
			}
		}

		public override void FixedUpdate()
		{
			//IL_0232: Unknown result type (might be due to invalid IL or missing references)
			//IL_0242: Unknown result type (might be due to invalid IL or missing references)
			//IL_0247: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: 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)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_032f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0334: Unknown result type (might be due to invalid IL or missing references)
			//IL_034a: Unknown result type (might be due to invalid IL or missing references)
			//IL_034c: Unknown result type (might be due to invalid IL or missing references)
			//IL_035c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0361: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0378: Unknown result type (might be due to invalid IL or missing references)
			//IL_0373: Unknown result type (might be due to invalid IL or missing references)
			//IL_0381: Unknown result type (might be due to invalid IL or missing references)
			//IL_0383: Unknown result type (might be due to invalid IL or missing references)
			//IL_0388: Unknown result type (might be due to invalid IL or missing references)
			//IL_038d: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0403: Unknown result type (might be due to invalid IL or missing references)
			//IL_0404: Unknown result type (might be due to invalid IL or missing references)
			//IL_0409: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0422: Unknown result type (might be due to invalid IL or missing references)
			//IL_0419: Unknown result type (might be due to invalid IL or missing references)
			//IL_0427: Unknown result type (might be due to invalid IL or missing references)
			//IL_044c: Unknown result type (might be due to invalid IL or missing references)
			//IL_044d: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_05aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_046f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0486: Unknown result type (might be due to invalid IL or missing references)
			//IL_0493: Unknown result type (might be due to invalid IL or missing references)
			//IL_0498: Unknown result type (might be due to invalid IL or missing references)
			//IL_049c: Unknown result type (might be due to invalid IL or missing references)
			//IL_04bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0630: Unknown result type (might be due to invalid IL or missing references)
			//IL_0637: Unknown result type (might be due to invalid IL or missing references)
			//IL_063c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0691: Unknown result type (might be due to invalid IL or missing references)
			//IL_0696: Unknown result type (might be due to invalid IL or missing references)
			//IL_0698: Unknown result type (might be due to invalid IL or missing references)
			//IL_0661: Unknown result type (might be due to invalid IL or missing references)
			//IL_0666: Unknown result type (might be due to invalid IL or missing references)
			//IL_0668: Unknown result type (might be due to invalid IL or missing references)
			//IL_0679: Unknown result type (might be due to invalid IL or missing references)
			//IL_067e: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_04de: Unknown result type (might be due to invalid IL or missing references)
			//IL_06c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_06e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0739: Unknown result type (might be due to invalid IL or missing references)
			//IL_0749: Unknown result type (might be due to invalid IL or missing references)
			//IL_07dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_054d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0827: Unknown result type (might be due to invalid IL or missing references)
			//IL_082d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0832: Unknown result type (might be due to invalid IL or missing references)
			//IL_0837: Unknown result type (might be due to invalid IL or missing references)
			//IL_083b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0840: Unknown result type (might be due to invalid IL or missing references)
			//IL_0859: Unknown result type (might be due to invalid IL or missing references)
			((EntityState)this).FixedUpdate();
			if (!Object.op_Implicit((Object)(object)owner) || !owner.Equipped || !((EntityState)this).characterBody.healthComponent.alive)
			{
				finished = true;
			}
			if (!NetworkServer.active && Object.op_Implicit((Object)(object)owner) && !owner.PeakActive && ((EntityState)this).fixedAge > 0.1f)
			{
				finished = true;
			}
			if (finished)
			{
				if (((EntityState)this).isAuthority)
				{
					((EntityState)this).outer.SetNextState((EntityState)(object)new ReformEffigy());
				}
				return;
			}
			if (!launched)
			{
				if (!TickTransformation())
				{
					return;
				}
				launched = true;
				pilotAnimator = ((EntityState)this).GetModelAnimator();
				if (Object.op_Implicit((Object)(object)pilotAnimator))
				{
					int layerIndex = pilotAnimator.GetLayerIndex("FullBody, Override");
					if (layerIndex >= 0)
					{
						priorAnimatorSpeed = pilotAnimator.speed;
						pilotAnimator.Play("SpectralAvatar", layerIndex, 0.55f);
						pilotAnimator.speed = 0f;
						holdingPilotPose = true;
					}
				}
				if (Object.op_Implicit((Object)(object)((EntityState)this).cameraTargetParams))
				{
					cameraOverride = ((EntityState)this).cameraTargetParams.AddParamsOverride(new CameraParamsOverrideRequest
					{
						cameraParamsData = new CharacterCameraParamsData
						{
							idealLocalCameraPos = BlendableVector3.op_Implicit(new Vector3(0f, 1.5f, -14f)),
							fov = BlendableFloat.op_Implicit(75f)
						},
						priority = 1f
					}, 0.2f);
				}
				if (Object.op_Implicit((Object)(object)((EntityState)this).characterMotor))
				{
					CharacterGravityParameters gravityParameters = ((EntityState)this).characterMotor.gravityParameters;
					gravityParameters.channeledAntiGravityGranterCount++;
					((EntityState)this).characterMotor.gravityParameters = gravityParameters;
					addedAntiGravity = true;
					((BaseCharacterController)((EntityState)this).characterMotor).Motor.ForceUnground(0.1f);
					motorWasEnabled = ((Behaviour)((BaseCharacterController)((EntityState)this).characterMotor).Motor).enabled;
					((Behaviour)((BaseCharacterController)((EntityState)this).characterMotor).Motor).enabled = false;
					phaseMotorDisabled = true;
				}
				if (NetworkServer.active)
				{
					target = null;
				}
			}
			if (Object.op_Implicit((Object)(object)((EntityState)this).characterMotor))
			{
				((EntityState)this).characterMotor.moveDirection = Vector3.zero;
				((EntityState)this).characterMotor.velocity = Vector3.zero;
			}
			if (!NetworkServer.active)
			{
				return;
			}
			if (budget.Finished || ((EntityState)this).fixedAge >= 0.625f + budget.MaxDistance / Mathf.Max(1f, Plugin.Options.PeakSpeed.Value) + 2f)
			{
				FinishServer();
				return;
			}
			if (Object.op_Implicit((Object)(object)target) && (!Object.op_Implicit((Object)(object)target.healthComponent) || !target.healthComponent.alive))
			{
				target = null;
			}
			if (!Object.op_Implicit((Object)(object)target) && homingUnlocked)
			{
				target = owner.FindTarget(CorePosition, Plugin.Options.RicochetRange.Value, visited);
				if (!Object.op_Implicit((Object)(object)target))
				{
					FinishServer();
					return;
				}
			}
			Vector3 corePosition = CorePosition;
			Vector3 val = ((homingUnlocked && Object.op_Implicit((Object)(object)target)) ? ((Component)target).transform.position : (corePosition + direction * budget.Remaining));
			Vector3 val2;
			if (hasDetour)
			{
				val2 = corePosition - detourPoint;
				if (((Vector3)(ref val2)).sqrMagnitude < 0.5625f)
				{
					hasDetour = false;
					nextRouteCheck = 0f;
				}
			}
			if