Decompiled source of AoiTodo v1.4.1

plugins/AoiTodo/AoiTodo.dll

Decompiled 16 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using EntityStates;
using GojoSatoruMod.Components;
using GojoSatoruMod.Content;
using GojoSatoruMod.Guide;
using GojoSatoruMod.States;
using GojoSatoruMod.Visuals;
using KinematicCharacterController;
using On.RoR2;
using On.RoR2.UI;
using R2API;
using R2API.Networking;
using R2API.Networking.Interfaces;
using R2API.Utils;
using RoR2;
using RoR2.Skills;
using RoR2.UI;
using TMPro;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[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("AoiTodo")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.4.1.0")]
[assembly: AssemblyInformationalVersion("1.4.1+821034880680daa23233a71eadd31af6da27dc72")]
[assembly: AssemblyProduct("AoiTodo")]
[assembly: AssemblyTitle("AoiTodo")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace GojoSatoruMod.Visuals
{
	internal static class TodoExtraSkins
	{
		private sealed class Part
		{
			internal string Name;

			internal int Outfit;

			internal string Texture;

			internal bool IsCutout;

			internal Vector3[] Vertices;

			internal Vector3[] Normals;

			internal Vector2[] Uvs;

			internal BoneWeight[] Weights;

			internal int[] Triangles;
		}

		private const string ModelFileName = "todo-skins.model";

		private const string TextureDirectoryName = "todo-skins";

		private static readonly string[] SkinNames = new string[2] { "OFFDUTY", "JACKETOFF" };

		private static readonly (Color Primary, Color Secondary)[] SkinIconColors = new(Color, Color)[3]
		{
			(new Color(0.07f, 0.07f, 0.09f), new Color(0.88f, 0.88f, 0.9f)),
			(new Color(0.43f, 0.59f, 0.42f), new Color(0.18f, 0.23f, 0.27f)),
			(new Color(0.74f, 0.69f, 0.62f), new Color(0.05f, 0.05f, 0.08f))
		};

		private static readonly Dictionary<string, Texture2D> textureCache = new Dictionary<string, Texture2D>();

		private static string[] boneNames;

		private static Matrix4x4[] rest;

		private static List<Part> parts;

		private static readonly HashSet<int> applied = new HashSet<int>();

		internal static void RegisterOnPrefab(GameObject bodyPrefab)
		{
			try
			{
				ModelSkinController val = (Object.op_Implicit((Object)(object)bodyPrefab) ? bodyPrefab.GetComponentInChildren<ModelSkinController>(true) : null);
				if (!Object.op_Implicit((Object)(object)val))
				{
					return;
				}
				if (!File.Exists(JujutsuAssetPaths.Find(new string[2] { "assets", "todo-skins.model" })))
				{
					Plugin.Log.LogInfo((object)"skins: model missing file=todo-skins.model offered=default", "C:\\Users\\user\\Documents\\risk of rain 2\\src\\Todo\\Visuals\\TodoExtraSkins.cs");
					return;
				}
				Transform val2 = (Object.op_Implicit((Object)(object)val.characterModel) ? ((Component)val.characterModel).transform : ((Component)val).transform);
				GameObject[] array = (GameObject[])(object)new GameObject[SkinNames.Length];
				for (int i = 0; i < array.Length; i++)
				{
					array[i] = MakeGroup(val2, "TodoOutfit" + SkinNames[i]);
					array[i].SetActive(false);
				}
				GameObject val3 = MakeGroup(val2, "TodoOutfitDEFAULT");
				val3.SetActive(true);
				SkinnedMeshRenderer[] componentsInChildren = ((Component)val2).GetComponentsInChildren<SkinnedMeshRenderer>(true);
				foreach (SkinnedMeshRenderer val4 in componentsInChildren)
				{
					if ((Object)(object)((Component)val4).gameObject != (Object)(object)val3 && !IsInside(((Component)val4).transform, array) && !((Component)val4).transform.IsChildOf(val3.transform))
					{
						((Component)val4).transform.SetParent(val3.transform, true);
					}
				}
				List<GameObject> ownMeshes = new List<GameObject> { val3 };
				List<SkinDef> list = new List<SkinDef> { BuildSkin("DEFAULT", -1, 0, ((Component)val2).gameObject, array, ownMeshes) };
				for (int k = 0; k < array.Length; k++)
				{
					list.Add(BuildSkin(SkinNames[k], k, k + 1, ((Component)val2).gameObject, array, ownMeshes));
				}
				val.skins = list.ToArray();
				Plugin.Log.LogInfo((object)$"skins: registered count={list.Count} body={((Object)bodyPrefab).name}", "C:\\Users\\user\\Documents\\risk of rain 2\\src\\Todo\\Visuals\\TodoExtraSkins.cs");
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"skins: register failed ex={arg}", "C:\\Users\\user\\Documents\\risk of rain 2\\src\\Todo\\Visuals\\TodoExtraSkins.cs");
			}
		}

		private static GameObject MakeGroup(Transform root, string name)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			Transform val = root.Find(name);
			object obj = (Object.op_Implicit((Object)(object)val) ? ((object)((Component)val).gameObject) : ((object)new GameObject(name)));
			((GameObject)obj).layer = ((Component)root).gameObject.layer;
			((GameObject)obj).transform.SetParent(root, false);
			return (GameObject)obj;
		}

		private static bool IsInside(Transform candidate, GameObject[] groups)
		{
			foreach (GameObject val in groups)
			{
				if (candidate.IsChildOf(val.transform))
				{
					return true;
				}
			}
			return false;
		}

		private static SkinDef BuildSkin(string skinName, int shown, int colorIndex, GameObject root, GameObject[] groups, List<GameObject> ownMeshes)
		{
			//IL_00f5: 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_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			SkinDef val = ScriptableObject.CreateInstance<SkinDef>();
			((Object)val).name = "skinTodo" + skinName;
			val.nameToken = "CODEX_TODO_SKIN_" + skinName + "_NAME";
			int index = Mathf.Clamp(colorIndex, 0, SkinIconColors.Length - 1);
			val.icon = GojoAssets.LoadIcon("todo-skin-" + skinName.ToLowerInvariant(), (Func<Sprite>)(() => GojoAssets.CreateSkinIcon("texTodoSkin" + skinName, SkinIconColors[index].Primary, SkinIconColors[index].Secondary)));
			val.rootObject = root;
			val.baseSkins = Array.Empty<SkinDef>();
			val.unlockableDef = null;
			SkinDefParams val2 = ScriptableObject.CreateInstance<SkinDefParams>();
			((Object)val2).name = "skinParamsTodo" + skinName;
			val2.rendererInfos = Array.Empty<RendererInfo>();
			val2.meshReplacements = Array.Empty<MeshReplacement>();
			val2.projectileGhostReplacements = Array.Empty<ProjectileGhostReplacement>();
			val2.minionSkinReplacements = Array.Empty<MinionSkinReplacement>();
			List<GameObjectActivation> list = new List<GameObjectActivation>();
			for (int num = 0; num < groups.Length; num++)
			{
				list.Add(new GameObjectActivation
				{
					gameObject = groups[num],
					shouldActivate = (num == shown)
				});
			}
			foreach (GameObject ownMesh in ownMeshes)
			{
				list.Add(new GameObjectActivation
				{
					gameObject = ownMesh,
					shouldActivate = (shown < 0)
				});
			}
			val2.gameObjectActivations = list.ToArray();
			val.skinDefParams = val2;
			val.Bake();
			return val;
		}

		internal static void Apply(CharacterModel characterModel)
		{
			try
			{
				if (!Object.op_Implicit((Object)(object)characterModel))
				{
					return;
				}
				GameObject[] array = FindGroups(characterModel);
				if (array == null || !Load() || !applied.Add(((Object)characterModel).GetInstanceID()))
				{
					return;
				}
				SkinnedMeshRenderer val = FindTemplate(characterModel);
				if (!Object.op_Implicit((Object)(object)val))
				{
					Plugin.Log.LogWarning((object)"skins: no template renderer on rig, skipped", "C:\\Users\\user\\Documents\\risk of rain 2\\src\\Todo\\Visuals\\TodoExtraSkins.cs");
					return;
				}
				int found;
				Transform[] bones = ResolveBones(characterModel, out found);
				Plugin.Log.LogInfo((object)$"skins: bones resolved found={found} total={boneNames.Length}", "C:\\Users\\user\\Documents\\risk of rain 2\\src\\Todo\\Visuals\\TodoExtraSkins.cs");
				if (found < boneNames.Length / 2)
				{
					Plugin.Log.LogWarning((object)"skins: too few bones resolved, skipped", "C:\\Users\\user\\Documents\\risk of rain 2\\src\\Todo\\Visuals\\TodoExtraSkins.cs");
					return;
				}
				MeasureAgainstRig(bones, ((Component)characterModel).transform, out var bindPoses, out var offsets, out var scale);
				int num = 0;
				foreach (Part part in parts)
				{
					if ((uint)part.Outfit < (uint)array.Length)
					{
						BuildRenderer(part, bones, bindPoses, offsets, scale, val, array[part.Outfit].transform);
						num++;
					}
				}
				Plugin.Log.LogInfo((object)$"skins: built renderers={num} model={((Object)characterModel).name}", "C:\\Users\\user\\Documents\\risk of rain 2\\src\\Todo\\Visuals\\TodoExtraSkins.cs");
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"skins: apply failed ex={arg}", "C:\\Users\\user\\Documents\\risk of rain 2\\src\\Todo\\Visuals\\TodoExtraSkins.cs");
			}
		}

		private static SkinnedMeshRenderer FindTemplate(CharacterModel characterModel)
		{
			SkinnedMeshRenderer val = null;
			SkinnedMeshRenderer[] componentsInChildren = ((Component)characterModel).GetComponentsInChildren<SkinnedMeshRenderer>(true);
			foreach (SkinnedMeshRenderer val2 in componentsInChildren)
			{
				if (Object.op_Implicit((Object)(object)val2.sharedMesh) && !((Object)(object)((Renderer)val2).sharedMaterial == (Object)null) && ((Object)(object)val == (Object)null || val2.sharedMesh.vertexCount > val.sharedMesh.vertexCount))
				{
					val = val2;
				}
			}
			return val;
		}

		private static GameObject[] FindGroups(CharacterModel characterModel)
		{
			GameObject[] array = (GameObject[])(object)new GameObject[SkinNames.Length];
			for (int i = 0; i < array.Length; i++)
			{
				Transform val = ((Component)characterModel).transform.Find("TodoOutfit" + SkinNames[i]);
				if (!Object.op_Implicit((Object)(object)val))
				{
					return null;
				}
				array[i] = ((Component)val).gameObject;
			}
			return array;
		}

		private static Transform[] ResolveBones(CharacterModel characterModel, out int found)
		{
			Dictionary<string, Transform> dictionary = new Dictionary<string, Transform>(StringComparer.Ordinal);
			Transform[] componentsInChildren = ((Component)characterModel).GetComponentsInChildren<Transform>(true);
			foreach (Transform val in componentsInChildren)
			{
				if (!dictionary.ContainsKey(((Object)val).name))
				{
					dictionary[((Object)val).name] = val;
				}
			}
			found = 0;
			Transform[] array = (Transform[])(object)new Transform[boneNames.Length];
			for (int j = 0; j < boneNames.Length; j++)
			{
				if (dictionary.TryGetValue(boneNames[j], out var value))
				{
					array[j] = value;
					found++;
					continue;
				}
				foreach (KeyValuePair<string, Transform> item in dictionary)
				{
					if (item.Key.EndsWith(boneNames[j], StringComparison.Ordinal))
					{
						array[j] = item.Value;
						found++;
						break;
					}
				}
				if (!Object.op_Implicit((Object)(object)array[j]))
				{
					array[j] = ((Component)characterModel).transform;
				}
			}
			return array;
		}

		private static Vector3 ToRigSpace(Vector3 stored)
		{
			//IL_0000: 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_000c: 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)
			return new Vector3(stored.x, stored.z, 0f - stored.y);
		}

		private static float MeasureScale(Transform[] bones, Matrix4x4 toRoot)
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			int num = Array.IndexOf(boneNames, "mixamorig:Hips");
			int num2 = Array.IndexOf(boneNames, "mixamorig:Head");
			if (num < 0 || num2 < 0 || !Object.op_Implicit((Object)(object)bones[num]) || !Object.op_Implicit((Object)(object)bones[num2]))
			{
				return 1f;
			}
			float num3 = Vector3.Distance(((Matrix4x4)(ref toRoot)).MultiplyPoint3x4(bones[num].position), ((Matrix4x4)(ref toRoot)).MultiplyPoint3x4(bones[num2].position));
			float num4 = Vector3.Distance(Vector4.op_Implicit(((Matrix4x4)(ref rest[num])).GetColumn(3)), Vector4.op_Implicit(((Matrix4x4)(ref rest[num2])).GetColumn(3)));
			if (!(num4 > 0.0001f))
			{
				return 1f;
			}
			return num3 / num4;
		}

		private static void MeasureAgainstRig(Transform[] bones, Transform root, out Matrix4x4[] bindPoses, out Vector3[] offsets, out float scale)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: 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_0090: 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_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Unknown result type (might be due to invalid IL or missing references)
			//IL_026e: 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_0278: Unknown result type (might be due to invalid IL or missing references)
			bindPoses = (Matrix4x4[])(object)new Matrix4x4[bones.Length];
			offsets = (Vector3[])(object)new Vector3[bones.Length];
			Matrix4x4 worldToLocalMatrix = root.worldToLocalMatrix;
			scale = MeasureScale(bones, worldToLocalMatrix);
			float num = 0f;
			int num2 = -1;
			for (int i = 0; i < bones.Length; i++)
			{
				Matrix4x4 val = (Object.op_Implicit((Object)(object)bones[i]) ? (worldToLocalMatrix * bones[i].localToWorldMatrix) : Matrix4x4.identity);
				bindPoses[i] = ((Matrix4x4)(ref val)).inverse;
				offsets[i] = Vector4.op_Implicit(((Matrix4x4)(ref val)).GetColumn(3)) - ToRigSpace(Vector4.op_Implicit(((Matrix4x4)(ref rest[i])).GetColumn(3))) * scale;
				if (((Vector3)(ref offsets[i])).magnitude > num)
				{
					num = ((Vector3)(ref offsets[i])).magnitude;
					num2 = i;
				}
			}
			Transform val2 = (Object.op_Implicit((Object)(object)root.parent) ? root.parent : root);
			int num3 = Array.IndexOf(boneNames, "mixamorig:Hips");
			Transform val3 = ((num3 >= 0) ? bones[num3] : null);
			Transform val4 = (Object.op_Implicit((Object)(object)val3) ? ImportedRoot(val3, root) : null);
			Plugin.Log.LogInfo((object)($"skins: fit scale={scale:0.000} worstShiftCm={num * 100f:0.0} " + "worstBone=" + ((num2 >= 0) ? boneNames[num2] : "none") + " worstShift=" + Describe((num2 >= 0) ? offsets[num2] : Vector3.zero) + " holder=" + ((Object)val2).name + " model=" + Describe(root.localPosition) + " modelYaw=" + root.localEulerAngles.y.ToString("0.0", CultureInfo.InvariantCulture) + " modelScale=" + Describe(root.localScale) + " imported=" + (Object.op_Implicit((Object)(object)val4) ? Describe(val4.localPosition) : "none") + " importedScale=" + (Object.op_Implicit((Object)(object)val4) ? Describe(val4.localScale) : "none") + " hipsX=" + (Object.op_Implicit((Object)(object)val3) ? val2.InverseTransformPoint(val3.position).x.ToString("0.000", CultureInfo.InvariantCulture) : "none")), "C:\\Users\\user\\Documents\\risk of rain 2\\src\\Todo\\Visuals\\TodoExtraSkins.cs");
		}

		private static Transform ImportedRoot(Transform bone, Transform model)
		{
			Transform val = bone;
			while (Object.op_Implicit((Object)(object)val.parent) && (Object)(object)val.parent != (Object)(object)model)
			{
				val = val.parent;
			}
			if (!((Object)(object)val.parent == (Object)(object)model))
			{
				return null;
			}
			return val;
		}

		private static string Describe(Vector3 value)
		{
			return value.x.ToString("0.000", CultureInfo.InvariantCulture) + "/" + value.y.ToString("0.000", CultureInfo.InvariantCulture) + "/" + value.z.ToString("0.000", CultureInfo.InvariantCulture);
		}

		private static void BuildRenderer(Part part, Transform[] bones, Matrix4x4[] bindPoses, Vector3[] offsets, float scale, SkinnedMeshRenderer template, Transform parent)
		{
			//IL_0009: 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_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			//IL_0055: 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_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: 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_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: 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_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: 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_011e: 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_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			int num = part.Vertices.Length;
			Mesh val = new Mesh
			{
				name = "meshTodo_" + part.Name,
				indexFormat = (IndexFormat)(num > 65000)
			};
			Vector3[] array = (Vector3[])(object)new Vector3[num];
			Vector3[] array2 = (Vector3[])(object)new Vector3[num];
			for (int i = 0; i < num; i++)
			{
				BoneWeight val2 = part.Weights[i];
				Vector3 val3 = offsets[((BoneWeight)(ref val2)).boneIndex0] * ((BoneWeight)(ref val2)).weight0 + offsets[((BoneWeight)(ref val2)).boneIndex1] * ((BoneWeight)(ref val2)).weight1 + offsets[((BoneWeight)(ref val2)).boneIndex2] * ((BoneWeight)(ref val2)).weight2 + offsets[((BoneWeight)(ref val2)).boneIndex3] * ((BoneWeight)(ref val2)).weight3;
				float num2 = ((BoneWeight)(ref val2)).weight0 + ((BoneWeight)(ref val2)).weight1 + ((BoneWeight)(ref val2)).weight2 + ((BoneWeight)(ref val2)).weight3;
				array[i] = ToRigSpace(part.Vertices[i]) * scale + ((num2 > 0.0001f) ? (val3 / num2) : Vector3.zero);
				array2[i] = ToRigSpace(part.Normals[i]);
			}
			val.vertices = array;
			val.normals = array2;
			val.uv = part.Uvs;
			val.boneWeights = part.Weights;
			val.bindposes = bindPoses;
			val.triangles = part.Triangles;
			val.RecalculateBounds();
			GameObject val4 = new GameObject(part.Name)
			{
				layer = ((Component)parent).gameObject.layer
			};
			val4.transform.SetParent(parent, false);
			SkinnedMeshRenderer obj = val4.AddComponent<SkinnedMeshRenderer>();
			obj.sharedMesh = val;
			obj.bones = bones;
			obj.rootBone = ((bones.Length != 0 && Object.op_Implicit((Object)(object)bones[0])) ? bones[0] : parent);
			((Renderer)obj).sharedMaterial = BuildMaterial(template, part);
			obj.quality = (SkinQuality)4;
			obj.updateWhenOffscreen = true;
		}

		private static Material BuildMaterial(SkinnedMeshRenderer template, Part part)
		{
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			Material val = Object.Instantiate<Material>(((Renderer)template).sharedMaterial);
			((Object)val).name = "matTodoSkin_" + part.Name;
			Texture2D val2 = LoadTexture(part.Texture);
			if (val.HasProperty("_MainTex"))
			{
				val.SetTexture("_MainTex", (Texture)(object)val2);
			}
			if (val.HasProperty("_Color"))
			{
				val.SetColor("_Color", Color.white);
			}
			if (part.IsCutout && val.HasProperty("_EnableCutout"))
			{
				val.SetFloat("_EnableCutout", 1f);
				val.EnableKeyword("CUTOUT");
			}
			return val;
		}

		private static Texture2D LoadTexture(string textureName)
		{
			if (string.IsNullOrEmpty(textureName))
			{
				return Texture2D.whiteTexture;
			}
			if (textureCache.TryGetValue(textureName, out var value) && Object.op_Implicit((Object)(object)value))
			{
				return value;
			}
			string text = JujutsuAssetPaths.Find(new string[3] { "assets", "todo-skins", textureName });
			bool flag = File.Exists(text);
			TextureAudit.Record("todo-skins", textureName, flag);
			if (!flag)
			{
				Plugin.Log.LogWarning((object)("texture: not found path=" + text), "C:\\Users\\user\\Documents\\risk of rain 2\\src\\Todo\\Visuals\\TodoExtraSkins.cs");
				return Texture2D.whiteTexture;
			}
			Texture2D val = JujutsuTextures.Load(text, "texTodoSkin_" + Path.GetFileNameWithoutExtension(textureName), (TextureWrapMode)1, false, (Action<Texture2D>)null);
			if (!Object.op_Implicit((Object)(object)val))
			{
				Plugin.Log.LogWarning((object)("texture: decode failed path=" + text), "C:\\Users\\user\\Documents\\risk of rain 2\\src\\Todo\\Visuals\\TodoExtraSkins.cs");
				return Texture2D.whiteTexture;
			}
			textureCache[textureName] = val;
			return val;
		}

		private static bool Load()
		{
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			//IL_0236: Unknown result type (might be due to invalid IL or missing references)
			//IL_023b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0255: Unknown result type (might be due to invalid IL or missing references)
			//IL_025a: 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_02d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02da: Unknown result type (might be due to invalid IL or missing references)
			if (parts != null)
			{
				return parts.Count > 0;
			}
			parts = new List<Part>();
			string path = JujutsuAssetPaths.Find(new string[2] { "assets", "todo-skins.model" });
			if (!File.Exists(path))
			{
				Plugin.Log.LogInfo((object)"skins: model missing file=todo-skins.model", "C:\\Users\\user\\Documents\\risk of rain 2\\src\\Todo\\Visuals\\TodoExtraSkins.cs");
				return false;
			}
			using FileStream input = File.OpenRead(path);
			using BinaryReader binaryReader = new BinaryReader(input);
			if (new string(binaryReader.ReadChars(8)) != "SUKNMDL1")
			{
				throw new InvalidDataException("Todo skin model header is invalid.");
			}
			int num = binaryReader.ReadInt32();
			if (num != 2)
			{
				throw new InvalidDataException($"Unsupported Todo skin model version {num}.");
			}
			int num2 = binaryReader.ReadInt32();
			boneNames = new string[num2];
			int[] array = new int[num2];
			Matrix4x4[] array2 = (Matrix4x4[])(object)new Matrix4x4[num2];
			for (int i = 0; i < num2; i++)
			{
				boneNames[i] = binaryReader.ReadString();
				array[i] = binaryReader.ReadInt32();
				Vector3 val = ReadVector3(binaryReader);
				Quaternion val2 = ReadQuaternion(binaryReader);
				Vector3 val3 = ReadVector3(binaryReader);
				array2[i] = Matrix4x4.TRS(val, val2, val3);
			}
			rest = (Matrix4x4[])(object)new Matrix4x4[num2];
			for (int j = 0; j < num2; j++)
			{
				rest[j] = ((array[j] < 0) ? array2[j] : (rest[array[j]] * array2[j]));
			}
			int num3 = binaryReader.ReadInt32();
			for (int k = 0; k < num3; k++)
			{
				Part part = new Part
				{
					Name = binaryReader.ReadString(),
					Outfit = binaryReader.ReadInt32()
				};
				binaryReader.ReadString();
				part.Texture = binaryReader.ReadString();
				part.IsCutout = binaryReader.ReadBoolean();
				int num4 = binaryReader.ReadInt32();
				part.Vertices = (Vector3[])(object)new Vector3[num4];
				part.Normals = (Vector3[])(object)new Vector3[num4];
				part.Uvs = (Vector2[])(object)new Vector2[num4];
				part.Weights = (BoneWeight[])(object)new BoneWeight[num4];
				for (int l = 0; l < num4; l++)
				{
					part.Vertices[l] = ReadVector3(binaryReader);
					part.Normals[l] = ReadVector3(binaryReader);
					part.Uvs[l] = new Vector2(binaryReader.ReadSingle(), binaryReader.ReadSingle());
					BoneWeight[] weights = part.Weights;
					int num5 = l;
					BoneWeight val4 = default(BoneWeight);
					((BoneWeight)(ref val4)).boneIndex0 = binaryReader.ReadInt32();
					((BoneWeight)(ref val4)).boneIndex1 = binaryReader.ReadInt32();
					((BoneWeight)(ref val4)).boneIndex2 = binaryReader.ReadInt32();
					((BoneWeight)(ref val4)).boneIndex3 = binaryReader.ReadInt32();
					((BoneWeight)(ref val4)).weight0 = binaryReader.ReadSingle();
					((BoneWeight)(ref val4)).weight1 = binaryReader.ReadSingle();
					((BoneWeight)(ref val4)).weight2 = binaryReader.ReadSingle();
					((BoneWeight)(ref val4)).weight3 = binaryReader.ReadSingle();
					weights[num5] = val4;
				}
				int num6 = binaryReader.ReadInt32();
				part.Triangles = new int[num6];
				for (int m = 0; m < num6; m++)
				{
					part.Triangles[m] = binaryReader.ReadInt32();
				}
				if ((uint)part.Outfit < (uint)SkinNames.Length)
				{
					parts.Add(part);
				}
			}
			Plugin.Log.LogInfo((object)$"skins: loaded parts={parts.Count} bones={num2}", "C:\\Users\\user\\Documents\\risk of rain 2\\src\\Todo\\Visuals\\TodoExtraSkins.cs");
			return parts.Count > 0;
		}

		private static Vector3 ReadVector3(BinaryReader reader)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			return new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
		}

		private static Quaternion ReadQuaternion(BinaryReader reader)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			return new Quaternion(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
		}
	}
}
namespace GojoSatoruMod.Todo
{
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency("dev.marmennz.satorugojo", "1.4.1")]
	[BepInPlugin("dev.marmennz.aoitodo", "Aoi Todo", "1.4.1")]
	public sealed class TodoPlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "dev.marmennz.aoitodo";

		public const string PluginVersion = "1.4.1";

		public const string PluginName = "Aoi Todo";

		private void Awake()
		{
			if (JujutsuCoreContract.Accepts(1, "Aoi Todo", "1.4.1", ((BaseUnityPlugin)this).Logger))
			{
				int num = JujutsuStartup.FailureMark();
				JujutsuStartup.UseHost((MonoBehaviour)(object)this);
				JujutsuAssetPaths.AddPlugin(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location));
				JujutsuStartup.Step("Todo's text", (Action)TodoLanguage.Register);
				JujutsuStartup.Step("Todo's assets", (Action)TodoAssets.Initialize);
				JujutsuStartup.Step("Todo's sounds", (Func<IEnumerator>)TodoAssets.LoadSounds);
				JujutsuStartup.Step("Todo's clap networking", (Action)TodoStoneSync.Initialize);
				JujutsuStartup.Step("Todo's target HUD", (Action)TodoTargetHud.Initialize);
				JujutsuStartup.Step("Todo's rhythm", (Action)TodoRhythm.Initialize);
				JujutsuStartup.Survivor("Todo", (Action)TodoSurvivor.Initialize);
				JujutsuStartup.Loaded("Aoi Todo", "1.4.1", num, ((BaseUnityPlugin)this).Logger);
			}
		}
	}
	internal static class GeneratedVersion
	{
		internal const string Value = "1.4.1";
	}
}
namespace GojoSatoruMod.States
{
	internal static class TodoRevised
	{
		private sealed class Window
		{
			internal readonly HashSet<CharacterBody> Taken = new HashSet<CharacterBody>();

			internal int Pulled;

			internal float OpenedAt;

			internal Vector3 Forward;
		}

		private static readonly float[] StoneAngles = new float[10] { 0f, 36f, -36f, 72f, -72f, 108f, -108f, 144f, -144f, 180f };

		private const float StoneRing = 4.5f;

		private const float OriginSlack = 12f;

		private const float WindowGrace = 1f;

		private const int FitAttempts = 3;

		private static readonly Dictionary<CharacterBody, Window> windows = new Dictionary<CharacterBody, Window>();

		private static readonly Dictionary<CharacterBody, bool> settled = new Dictionary<CharacterBody, bool>();

		private static int emptyStrikesLogged;

		private static int unpaidLogged;

		private static bool landingHitLogged;

		internal static CharacterBody PickTarget(CharacterBody todo, Vector3 aimOrigin, Vector3 aimDirection, HashSet<CharacterBody> taken)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: 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_00df: 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_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: 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_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)todo) || ((Vector3)(ref aimDirection)).sqrMagnitude < 0.0001f)
			{
				return null;
			}
			ReadOnlyCollection<CharacterBody> readOnlyInstancesList = CharacterBody.readOnlyInstancesList;
			if (readOnlyInstancesList == null)
			{
				return null;
			}
			TeamIndex val = (TeamIndex)((!Object.op_Implicit((Object)(object)todo.teamComponent)) ? (-1) : ((int)todo.teamComponent.teamIndex));
			Vector3 corePosition = todo.corePosition;
			float num = 45f;
			CharacterBody result = null;
			float num2 = float.MaxValue;
			for (int i = 0; i < readOnlyInstancesList.Count; i++)
			{
				CharacterBody val2 = readOnlyInstancesList[i];
				if (Object.op_Implicit((Object)(object)val2) && !((Object)(object)val2 == (Object)(object)todo) && !val2.isChampion && Object.op_Implicit((Object)(object)val2.teamComponent) && val2.teamComponent.teamIndex != val && Object.op_Implicit((Object)(object)val2.healthComponent) && val2.healthComponent.alive && (taken == null || !taken.Contains(val2)))
				{
					Vector3 corePosition2 = val2.corePosition;
					Vector3 val3 = corePosition2 - corePosition;
					float sqrMagnitude = ((Vector3)(ref val3)).sqrMagnitude;
					if (!(sqrMagnitude > num * num) && !(sqrMagnitude >= num2) && !Physics.Linecast(corePosition, corePosition2, LayerMask.op_Implicit(((LayerIndex)(ref LayerIndex.world)).mask), (QueryTriggerInteraction)1))
					{
						result = val2;
						num2 = sqrMagnitude;
					}
				}
			}
			return result;
		}

		internal static Vector3 StonePoint(Vector3 stompPoint, Vector3 forward, int index)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//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_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: 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_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = Vector3.ProjectOnPlane(forward, Vector3.up);
			if (((Vector3)(ref val)).sqrMagnitude < 0.0001f)
			{
				val = Vector3.forward;
			}
			((Vector3)(ref val)).Normalize();
			int num = Mathf.Clamp(index, 0, StoneAngles.Length - 1);
			return stompPoint + Quaternion.AngleAxis(StoneAngles[num], Vector3.up) * val * 4.5f;
		}

		internal static bool ServerStrike(CharacterBody todo, Vector3 aimOrigin, Vector3 aimDirection, Vector3 stompPoint, int index)
		{
			//IL_0080: 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_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: 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_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: 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_00e6: 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_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: 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)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: 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_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: 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_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: 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_0191: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkServer.active || !Object.op_Implicit((Object)(object)todo) || !Object.op_Implicit((Object)(object)todo.healthComponent) || !todo.healthComponent.alive || !Object.op_Implicit((Object)(object)((Component)todo).GetComponent<TodoBoogieWoogie>()))
			{
				return false;
			}
			index = Mathf.Clamp(index, 0, 9);
			if (((Vector3)(ref aimDirection)).sqrMagnitude < 0.0001f)
			{
				aimDirection = (Object.op_Implicit((Object)(object)todo.inputBank) ? todo.inputBank.aimDirection : todo.transform.forward);
			}
			((Vector3)(ref aimDirection)).Normalize();
			Vector3 val = aimOrigin - todo.corePosition;
			if (((Vector3)(ref val)).sqrMagnitude > 144f)
			{
				aimOrigin = (Object.op_Implicit((Object)(object)todo.inputBank) ? todo.inputBank.aimOrigin : todo.corePosition);
			}
			Vector3 val2 = JujutsuTeleport.FootOf(todo);
			float num = 45f;
			val = stompPoint - val2;
			if (((Vector3)(ref val)).sqrMagnitude > num * num)
			{
				stompPoint = val2;
			}
			Window window = Open(todo, index, aimDirection);
			if (window.Pulled >= 10)
			{
				return false;
			}
			Vector3 val3 = StonePoint(stompPoint, window.Forward, index);
			List<CharacterBody> list = null;
			CharacterBody val4 = null;
			for (int i = 0; i < 3; i++)
			{
				if (Object.op_Implicit((Object)(object)val4))
				{
					break;
				}
				CharacterBody val5 = PickTarget(todo, aimOrigin, aimDirection, window.Taken);
				if (!Object.op_Implicit((Object)(object)val5))
				{
					break;
				}
				window.Taken.Add(val5);
				Vector3 val6 = JujutsuTeleport.FootOf(val5);
				Vector3 val7 = JujutsuTeleport.UnblockedPoint(val3, val5, val6, (Footing)2, "revised");
				if (val7 == val6)
				{
					(list ?? (list = new List<CharacterBody>())).Add(val5);
					continue;
				}
				TodoStoneSync.Order(val5, val7, report: false);
				TodoBoogieWoogie.StunClapped(val5, todo);
				JujutsuImpact.Surface(val7, Vector3.up, TodoFx.Reach(val5, 2.2f), true);
				LandingHit(todo, val5);
				val4 = val5;
			}
			if (list != null)
			{
				foreach (CharacterBody item in list)
				{
					window.Taken.Remove(item);
				}
			}
			if (Object.op_Implicit((Object)(object)val4))
			{
				window.Pulled++;
				if (window.Pulled == 1)
				{
					Landed(todo);
				}
				return true;
			}
			if (emptyStrikesLogged < 12)
			{
				emptyStrikesLogged++;
				Plugin.Log.LogInfo((object)((list == null) ? ("revised: nobody found strike=" + (index + 1) + " reach=" + StatText.Number(num) + "m filter=non-boss,in-sight,unpulled") : ("revised: nobody moved strike=" + (index + 1) + " stone=" + (index + 1) + " unfit=" + list.Count + " why=over-drop-or-in-wall")), "C:\\Users\\user\\Documents\\risk of rain 2\\src\\Todo\\States\\TodoRevisedState.cs");
			}
			return false;
		}

		private static void LandingHit(CharacterBody todo, CharacterBody target)
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkServer.active && Object.op_Implicit((Object)(object)todo) && Object.op_Implicit((Object)(object)target) && Object.op_Implicit((Object)(object)target.healthComponent) && target.healthComponent.alive)
			{
				float num = todo.damage * 13f;
				bool flag = Util.CheckRoll(todo.crit, todo.master);
				GojoDamageUtility.ApplyDamage(((Component)todo).gameObject, target.healthComponent, num, Vector3.zero, flag, 1f, DamageTypeCombo.GenericSpecial, (DamageColorIndex)0, (Color?)TodoFx.Colour, (float?)null, (float?)null, false);
				if (!landingHitLogged)
				{
					landingHitLogged = true;
					Plugin.Log.LogInfo((object)("revised: landing hit who=" + target.GetDisplayName() + " " + $"dmg={num:F0} ({StatText.Percent(13f)}) crit={flag} proc=1"), "C:\\Users\\user\\Documents\\risk of rain 2\\src\\Todo\\States\\TodoRevisedState.cs");
				}
			}
		}

		private static void Landed(CharacterBody todo)
		{
			if (Util.HasEffectiveAuthority(((Component)todo).gameObject))
			{
				FirstLanded(todo);
			}
			else
			{
				TodoStoneSync.ReportRevisedLanded(todo);
			}
		}

		internal static void OwnerOpened(CharacterBody todo)
		{
			if (Object.op_Implicit((Object)(object)todo))
			{
				Forget(settled);
				settled[todo] = false;
			}
		}

		internal static bool OwnerSettled(CharacterBody todo)
		{
			bool value = default(bool);
			return Object.op_Implicit((Object)(object)todo) && settled.TryGetValue(todo, out value) && value;
		}

		internal static void FirstLanded(CharacterBody todo)
		{
			bool value = default(bool);
			if (!Object.op_Implicit((Object)(object)todo) || !settled.TryGetValue(todo, out value) || value)
			{
				return;
			}
			settled[todo] = true;
			CursedEnergyController component = ((Component)todo).GetComponent<CursedEnergyController>();
			float num = 30f;
			if (Object.op_Implicit((Object)(object)component))
			{
				if (component.CanAfford(num))
				{
					component.TrySpendPriced(num);
				}
				else if (unpaidLogged < 12)
				{
					unpaidLogged++;
					Plugin.Log.LogInfo((object)("revised: first body unpaid price=" + StatText.Number(component.Price(num)) + " bar=short"), "C:\\Users\\user\\Documents\\risk of rain 2\\src\\Todo\\States\\TodoRevisedState.cs");
				}
			}
		}

		private static Window Open(CharacterBody todo, int index, Vector3 aimDirection)
		{
			//IL_0059: 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_0040: 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)
			float time = Time.time;
			float num = 5.35f;
			if (windows.TryGetValue(todo, out var value) && index > 0 && time - value.OpenedAt <= num)
			{
				return value;
			}
			Forget(windows);
			if (!TryStateForward(todo, out var forward))
			{
				forward = Vector3.ProjectOnPlane(aimDirection, Vector3.up);
			}
			value = new Window
			{
				OpenedAt = time,
				Forward = forward
			};
			windows[todo] = value;
			return value;
		}

		private static bool TryStateForward(CharacterBody todo, out Vector3 forward)
		{
			//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_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: 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_004f: Unknown result type (might be due to invalid IL or missing references)
			forward = Vector3.zero;
			EntityStateMachine val = EntityStateMachine.FindByCustomName(((Component)todo).gameObject, "Weapon");
			if (Object.op_Implicit((Object)(object)val) && val.state is TodoRevisedState { Forward: var forward2 } todoRevisedState && ((Vector3)(ref forward2)).sqrMagnitude > 0.01f)
			{
				forward = todoRevisedState.Forward;
				return true;
			}
			return false;
		}

		private static void Forget<T>(Dictionary<CharacterBody, T> table)
		{
			if (table.Count < 8)
			{
				return;
			}
			List<CharacterBody> list = null;
			foreach (KeyValuePair<CharacterBody, T> item in table)
			{
				if (!Object.op_Implicit((Object)(object)item.Key))
				{
					(list ?? (list = new List<CharacterBody>())).Add(item.Key);
				}
			}
			if (list == null)
			{
				return;
			}
			foreach (CharacterBody item2 in list)
			{
				table.Remove(item2);
			}
		}
	}
	public sealed class TodoRevisedSkillDef : SkillDef
	{
		public override bool CanExecute(GenericSkill skillSlot)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)skillSlot) || !((SkillDef)this).HasRequiredStockAndDelay(skillSlot) || !Object.op_Implicit((Object)(object)skillSlot.stateMachine) || skillSlot.stateMachine.state is TodoRevisedState || skillSlot.stateMachine.HasPendingState() || !skillSlot.stateMachine.CanInterruptState(base.interruptPriority))
			{
				return false;
			}
			CursedEnergyController val = Energy(skillSlot);
			float num = 30f;
			if (Object.op_Implicit((Object)(object)val) && !val.CanAfford(num))
			{
				val.MarkRefused(val.Price(num));
				return false;
			}
			return ((SkillDef)this).CanExecute(skillSlot);
		}

		public override bool IsReady(GenericSkill skillSlot)
		{
			CursedEnergyController val = Energy(skillSlot);
			if (((SkillDef)this).IsReady(skillSlot))
			{
				if (Object.op_Implicit((Object)(object)val))
				{
					return val.CanAfford(30f);
				}
				return true;
			}
			return false;
		}

		private static CursedEnergyController Energy(GenericSkill skillSlot)
		{
			if (!Object.op_Implicit((Object)(object)skillSlot) || !Object.op_Implicit((Object)(object)skillSlot.characterBody))
			{
				return null;
			}
			return ((Component)skillSlot.characterBody).GetComponent<CursedEnergyController>();
		}
	}
	public sealed class TodoRevisedState : BaseSkillState
	{
		private const float StompContact = 0.7f;

		private const float StompDrawnAs = 6.5f;

		private const float StompReach = 5f;

		private const float StrikePose = 0.22f;

		private const float StoneRise = 0.45f;

		private const float StoneFade = 0.3f;

		private const float SpentStone = 0.3f;

		private static int refusalsLogged;

		private bool refused;

		private Vector3 stompPoint;

		private Vector3 forward;

		private bool fromWire;

		private bool stomped;

		private float stompedAt;

		private bool ended;

		private int strikes;

		private bool primaryWasDown;

		private bool secondaryWasDown;

		private bool utilityWasDown;

		private readonly HashSet<CharacterBody> sent = new HashSet<CharacterBody>();

		private TodoFxPart[] stones;

		private TodoFxPart[] rings;

		private float[] stoneLevels;

		private Vector3[] stoneFeet;

		internal Vector3 Forward => forward;

		public override void OnEnter()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: 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_0106: 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)
			((BaseState)this).OnEnter();
			if (!fromWire)
			{
				stompPoint = JujutsuTeleport.FootOf(((EntityState)this).characterBody);
				Ray aimRay = ((BaseState)this).GetAimRay();
				Vector3 val = Vector3.ProjectOnPlane(((Ray)(ref aimRay)).direction, Vector3.up);
				forward = ((((Vector3)(ref val)).sqrMagnitude > 0.0001f) ? ((Vector3)(ref val)).normalized : ((EntityState)this).characterBody.transform.forward);
			}
			if (((EntityState)this).isAuthority)
			{
				string text = Excuse();
				if (text != null)
				{
					Refuse(text);
					return;
				}
				TodoRevised.OwnerOpened(((EntityState)this).characterBody);
			}
			if (!refused)
			{
				if (Object.op_Implicit((Object)(object)((EntityState)this).inputBank))
				{
					primaryWasDown = ((EntityState)this).inputBank.skill1.down;
					secondaryWasDown = ((EntityState)this).inputBank.skill2.down;
					utilityWasDown = ((EntityState)this).inputBank.skill3.down;
				}
				((EntityState)this).characterBody.SetAimTimer(4.35f);
				if (Object.op_Implicit((Object)(object)((EntityState)this).characterDirection))
				{
					((EntityState)this).characterDirection.forward = forward;
				}
				GojoModelAnimator obj = GojoModelAnimator.Find(((EntityState)this).characterBody);
				if (obj != null)
				{
					obj.TriggerPunch(true, 0.5f, 3, 0.7f, true);
				}
				JujutsuSfxAssets.PlayHeavyWhoosh(((EntityState)this).characterBody.corePosition, 0.7f);
			}
		}

		private string Excuse()
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			CursedEnergyController component = ((Component)((EntityState)this).characterBody).GetComponent<CursedEnergyController>();
			float num = 30f;
			if (Object.op_Implicit((Object)(object)component) && !component.CanAfford(num))
			{
				component.MarkRefused(component.Price(num));
				return "energy=short spent=0";
			}
			Ray aimRay = ((BaseState)this).GetAimRay();
			if (!Object.op_Implicit((Object)(object)TodoRevised.PickTarget(((EntityState)this).characterBody, ((Ray)(ref aimRay)).origin, ((Ray)(ref aimRay)).direction, null)))
			{
				return "nobody to pull reach=" + StatText.Number(45f) + "m filter=non-boss,in-sight,beyond-stones spent=0 cooldown=refunded";
			}
			return null;
		}

		private void Refuse(string excuse)
		{
			//IL_0014: 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_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			refused = true;
			ended = true;
			TodoFx.SealAt(((EntityState)this).characterBody.corePosition + ((EntityState)this).characterBody.transform.forward * 0.55f, set: false);
			JujutsuCharacters.ForBody(((EntityState)this).characterBody)?.EffortVoice?.Invoke(((EntityState)this).characterBody.corePosition, 0.9f);
			if (refusalsLogged < 12)
			{
				refusalsLogged++;
				Plugin.Log.LogInfo((object)("revised: refused why=" + excuse), "C:\\Users\\user\\Documents\\risk of rain 2\\src\\Todo\\States\\TodoRevisedState.cs");
			}
			((EntityState)this).outer.SetNextStateToMain();
		}

		public override void FixedUpdate()
		{
			((EntityState)this).FixedUpdate();
			if (refused)
			{
				return;
			}
			if (!stomped)
			{
				GojoStateUtils.SlowMovementDuringAttack(((EntityState)this).characterMotor, ((EntityState)this).isAuthority, 0.2f);
				if (((EntityState)this).fixedAge >= 0.35f)
				{
					Stomp();
					if (((EntityState)this).isAuthority && !ended)
					{
						Batch();
					}
				}
			}
			else if (((EntityState)this).isAuthority && !ended && ((EntityState)this).fixedAge >= stompedAt + 4f)
			{
				End();
			}
		}

		public override void Update()
		{
			((EntityState)this).Update();
			if (((EntityState)this).isAuthority && !refused && !ended && Object.op_Implicit((Object)(object)((EntityState)this).inputBank))
			{
				if (((EntityState)this).inputBank.skill4.down)
				{
					((EntityState)this).inputBank.skill4.hasPressBeenClaimed = true;
				}
				if (Fresh(((EntityState)this).inputBank.skill1.down, ref primaryWasDown) | Fresh(((EntityState)this).inputBank.skill2.down, ref secondaryWasDown) | Fresh(((EntityState)this).inputBank.skill3.down, ref utilityWasDown))
				{
					End();
				}
			}
		}

		private void Batch()
		{
			int num = 0;
			for (int i = 0; i < 10; i++)
			{
				if (ended)
				{
					break;
				}
				if (!Strike(num == 0))
				{
					break;
				}
				num++;
			}
			End();
		}

		private static bool Fresh(bool down, ref bool wasDown)
		{
			bool result = down && !wasDown;
			wasDown = down;
			return result;
		}

		private void Stomp()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0083: 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)
			stomped = true;
			stompedAt = ((EntityState)this).fixedAge;
			Color colour = TodoLanguage.Colour;
			float num = TodoFx.Reach(((EntityState)this).characterBody, 5f);
			JujutsuImpact.Detonate(stompPoint, colour, num, JujutsuFxScale.Weight(6.5f), false, true);
			TodoFx.GroundWave(stompPoint, colour, num, 0.5f);
			JujutsuSfxAssets.PlayMeleeHeavy(stompPoint);
			JujutsuMotes.Burst(stompPoint, Vector3.up, colour, num * 0.5f, (JujutsuMoteKind)1, 10);
			if (NetworkServer.active)
			{
				JujutsuImpact.Surface(stompPoint, Vector3.up, num, true);
			}
			RaiseStones();
		}

		private void RaiseStones()
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: 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_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)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			int num = 10;
			stones = new TodoFxPart[num];
			rings = new TodoFxPart[num];
			stoneLevels = new float[num];
			stoneFeet = (Vector3[])(object)new Vector3[num];
			float life = 4.5f;
			Color colour = TodoLanguage.Colour;
			for (int i = 0; i < num; i++)
			{
				Vector3 val = Floor(TodoRevised.StonePoint(stompPoint, forward, i));
				stoneFeet[i] = val;
				stoneLevels[i] = 1f;
				stones[i] = TodoFx.Flare("TodoRevisedStone", val + Vector3.up * 0.45f, colour, 0.7f, (i % 2 == 0) ? 24f : (-24f), life);
				rings[i] = TodoFx.FloorRing(val, colour, 0.55f, life);
			}
		}

		private static Vector3 Floor(Vector3 point)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: 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_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			RaycastHit val = default(RaycastHit);
			if (!Physics.Raycast(point + Vector3.up * 2.5f, Vector3.down, ref val, 6f, LayerMask.op_Implicit(((LayerIndex)(ref LayerIndex.world)).mask), (QueryTriggerInteraction)1))
			{
				return point;
			}
			return ((RaycastHit)(ref val)).point;
		}

		private bool Strike(bool loud)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: 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_0044: 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_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: 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_00fa: 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_0107: 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_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			if (strikes >= 10)
			{
				return false;
			}
			Ray aimRay = ((BaseState)this).GetAimRay();
			CharacterBody val = TodoRevised.PickTarget(((EntityState)this).characterBody, ((Ray)(ref aimRay)).origin, ((Ray)(ref aimRay)).direction, sent);
			if (!Object.op_Implicit((Object)(object)val))
			{
				if (loud)
				{
					TodoFx.SealAt(((EntityState)this).characterBody.corePosition + ((EntityState)this).characterBody.transform.forward * 0.55f, set: false);
				}
				return false;
			}
			if (!TodoRevised.OwnerSettled(((EntityState)this).characterBody))
			{
				CursedEnergyController component = ((Component)((EntityState)this).characterBody).GetComponent<CursedEnergyController>();
				float num = 30f;
				if (Object.op_Implicit((Object)(object)component) && !component.CanAfford(num))
				{
					component.MarkRefused(component.Price(num));
					JujutsuCharacters.ForBody(((EntityState)this).characterBody)?.EffortVoice?.Invoke(((EntityState)this).characterBody.corePosition, 0.9f);
					End();
					return false;
				}
			}
			bool flag = true;
			if (NetworkServer.active)
			{
				flag = TodoRevised.ServerStrike(((EntityState)this).characterBody, ((Ray)(ref aimRay)).origin, ((Ray)(ref aimRay)).direction, stompPoint, strikes);
			}
			else
			{
				TodoStoneSync.RequestRevisedStrike(((EntityState)this).characterBody, ((Ray)(ref aimRay)).origin, ((Ray)(ref aimRay)).direction, stompPoint, strikes);
			}
			if (flag)
			{
				sent.Add(val);
				Answer(strikes, loud);
			}
			else
			{
				if (loud)
				{
					TodoFx.SealAt(((EntityState)this).characterBody.corePosition + ((EntityState)this).characterBody.transform.forward * 0.55f, set: false);
				}
				Dim(strikes);
			}
			strikes++;
			return true;
		}

		private void Answer(int index, bool loud)
		{
			//IL_0009: 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_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: 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_008a: Unknown result type (might be due to invalid IL or missing references)
			if (loud)
			{
				TodoFx.SealAt(((EntityState)this).characterBody.corePosition + ((EntityState)this).characterBody.transform.forward * 0.55f, set: true);
				TodoAssets.PlayClap(((EntityState)this).characterBody.corePosition);
				GojoModelAnimator obj = GojoModelAnimator.Find(((EntityState)this).characterBody);
				if (obj != null)
				{
					obj.TriggerPunch(false, 0.22f, 0, 0.5f, true);
				}
			}
			if (stoneFeet != null && index >= 0 && index < stoneFeet.Length)
			{
				TodoFx.Ping(stoneFeet[index], TodoLanguage.Colour, 1.6f, 0.45f);
				Dim(index);
			}
		}

		private void Dim(int index)
		{
			if (stoneLevels != null && index >= 0 && index < stoneLevels.Length)
			{
				stoneLevels[index] = 0.3f;
				TodoFxPart todoFxPart = ((stones != null) ? stones[index] : null);
				if (todoFxPart != null && todoFxPart.Alive)
				{
					todoFxPart.Envelope(0.3f);
				}
			}
		}

		private void End()
		{
			if (!ended)
			{
				ended = true;
				((EntityState)this).outer.SetNextStateToMain();
			}
		}

		public override void OnExit()
		{
			if (((EntityState)this).isAuthority && strikes == 0)
			{
				CursedEnergySkillDef.Refund(((BaseSkillState)this).activatorSkillSlot);
			}
			FadeStones();
			((EntityState)this).OnExit();
		}

		private void FadeStones()
		{
			if (stones == null)
			{
				return;
			}
			TodoFxPart[] fading = stones;
			TodoFxPart[] array = rings;
			float[] levels = stoneLevels;
			stones = null;
			JujutsuFxSequence.Run(0.3f).While((Action<float>)delegate(float t)
			{
				for (int i = 0; i < fading.Length; i++)
				{
					if (fading[i] != null && fading[i].Alive)
					{
						fading[i].Envelope(levels[i] * (1f - t));
					}
				}
			});
			for (int num = 0; num < fading.Length; num++)
			{
				if (fading[num] != null && fading[num].Alive)
				{
					Object.Destroy((Object)(object)fading[num].Item, 0.35000002f);
				}
				if (array != null && array[num] != null && array[num].Alive)
				{
					Object.Destroy((Object)(object)array[num].Item, 0.35000002f);
				}
			}
		}

		public override void OnSerialize(NetworkWriter writer)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			((BaseSkillState)this).OnSerialize(writer);
			writer.Write(refused);
			writer.Write(stompPoint);
			writer.Write(forward);
		}

		public override void OnDeserialize(NetworkReader reader)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			((BaseSkillState)this).OnDeserialize(reader);
			refused = reader.ReadBoolean();
			stompPoint = reader.ReadVector3();
			forward = reader.ReadVector3();
			fromWire = true;
		}

		public override InterruptPriority GetMinimumInterruptPriority()
		{
			return (InterruptPriority)2;
		}
	}
	public sealed class TodoConsecutiveState : BaseSkillState
	{
		private static readonly float[] StepDurations = new float[3] { 0.4f, 0.38f, 0.58f };

		private static readonly float[] StepDamage = new float[3] { 1.4f, 1.5f, 2.2f };

		private static readonly float[] StepImpact = new float[3] { 2.5f, 2.6f, 4f };

		private static readonly float[] StepRadius = new float[3] { 2.9f, 2.9f, 3.6f };

		private static readonly float[] StepContact = new float[3] { 0.5f, 0.42f, 0.52f };

		private static readonly float[] StepTravel = new float[3] { 1.4f, 1.4f, 2.6f };

		private const int FinisherStep = 2;

		internal const float PerfectFrom = 0f;

		internal const float PerfectUntil = 0.8f;

		private float duration;

		private Vector3 aimDirection;

		private bool struck;

		private bool rightHand;

		private int step;

		private float pressedAt;

		private bool stepFromWire;

		private bool entered;

		internal static float Coefficient
		{
			get
			{
				float num = 0f;
				for (int i = 0; i < StepDamage.Length; i++)
				{
					num += StepDamage[i];
				}
				return num;
			}
		}

		internal static int Steps => StepDurations.Length;

		internal static float RunSeconds
		{
			get
			{
				float num = 0f;
				for (int i = 0; i < StepDurations.Length; i++)
				{
					num += StepDurations[i];
				}
				return num;
			}
		}

		public override void OnEnter()
		{
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: 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_0155: Unknown result type (might be due to invalid IL or missing references)
			((BaseState)this).OnEnter();
			TodoRhythm component = ((Component)((EntityState)this).characterBody).GetComponent<TodoRhythm>();
			if (!stepFromWire)
			{
				bool flag = Object.op_Implicit((Object)(object)component) && component.ConsumeHookPrime();
				TodoBoogieWoogie component2 = ((Component)((EntityState)this).characterBody).GetComponent<TodoBoogieWoogie>();
				if (!flag && Object.op_Implicit((Object)(object)component) && Object.op_Implicit((Object)(object)component2))
				{
					component.RestartRunAfter(component2.LastBodyClapAt);
				}
				step = (flag ? 2 : Mathf.Clamp(Object.op_Implicit((Object)(object)component) ? component.ConsumeComboStep() : 0, 0, StepDurations.Length - 1));
			}
			entered = true;
			pressedAt = Time.time;
			duration = StepDurations[step] / Mathf.Max(0.1f, ((BaseState)this).attackSpeedStat);
			Ray aimRay = ((BaseState)this).GetAimRay();
			Vector3 direction = ((Ray)(ref aimRay)).direction;
			aimDirection = ((Vector3)(ref direction)).normalized;
			rightHand = step != 0;
			((EntityState)this).characterBody.SetAimTimer(duration + 0.2f);
			GojoModelAnimator val = GojoModelAnimator.Find(((EntityState)this).characterBody);
			if (Object.op_Implicit((Object)(object)val))
			{
				val.TriggerPunch(rightHand, duration, step, StepContact[step], true);
			}
			JujutsuSfxAssets.PlayMeleeLight(((EntityState)this).characterBody.corePosition);
			if (step == 2)
			{
				JujutsuSfxAssets.PlayHeavyWhoosh(((EntityState)this).characterBody.corePosition, 0.7f);
			}
			else
			{
				JujutsuSfxAssets.PlayLightWhoosh(((EntityState)this).characterBody.corePosition, 0.55f);
			}
		}

		public override void FixedUpdate()
		{
			//IL_0029: 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_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_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_021c: Unknown result type (might be due to invalid IL or missing references)
			//IL_021d: Unknown result type (might be due to invalid IL or missing references)
			//IL_021e: 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_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: 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_0257: Unknown result type (might be due to invalid IL or missing references)
			//IL_0258: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: 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_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			((EntityState)this).FixedUpdate();
			GojoStateUtils.SlowMovementDuringAttack(((EntityState)this).characterMotor, ((EntityState)this).isAuthority, 0.7f);
			GojoStateUtils.GlideIntoBlow(((EntityState)this).characterMotor, ((EntityState)this).isAuthority, aimDirection, StepTravel[step], ((EntityState)this).fixedAge, duration, StepContact[step], false);
			if (!struck && ((EntityState)this).fixedAge >= duration * StepContact[step])
			{
				struck = true;
				Vector3 val = Vector3.ProjectOnPlane(aimDirection, Vector3.up);
				Vector3 val2 = ((Vector3)(ref val)).normalized;
				if (((Vector3)(ref val2)).sqrMagnitude < 0.01f)
				{
					val2 = ((EntityState)this).characterBody.transform.forward;
				}
				Vector3 val3 = ((EntityState)this).characterBody.corePosition + val2 * 2.3f;
				if (((EntityState)this).isAuthority)
				{
					Prepared val4 = BlackFlash.Roll(1f, ((EntityState)this).characterBody);
					if (GojoMeleeAttackUtility.Fire(((EntityState)this).gameObject, ((EntityState)this).characterBody, ((BaseState)this).GetTeam(), val3, StepRadius[step], ((BaseState)this).damageStat * StepDamage[step] * ((Prepared)(ref val4)).Multiplier, val2 * ((step == 2) ? 4600f : 900f) + Vector3.up * ((step == 2) ? 1100f : 120f), ((BaseState)this).RollCrit() || ((Prepared)(ref val4)).Landed, DamageTypeCombo.GenericPrimary, ((Prepared)(ref val4)).ProcMask) > 0)
					{
						if (((Prepared)(ref val4)).Landed)
						{
							BlackFlash.Land(val3, "Todo", true);
							BlackFlash.Landed(((EntityState)this).characterBody, val3, false);
						}
						TodoRhythm.ReportHit(((EntityState)this).characterBody);
						JujutsuSfxAssets.PlayMeleeHeavy(val3);
						CursedEnergyController component = ((Component)((EntityState)this).characterBody).GetComponent<CursedEnergyController>();
						if (component != null)
						{
							component.RestoreFromMelee((step == 2) ? 4f : 2f);
						}
						if (step == 0)
						{
							PerfectSwap();
						}
					}
				}
				float num = TodoFx.Reach(((EntityState)this).characterBody, StepRadius[step]);
				JujutsuImpact.Strike(val3, val2, TodoLanguage.Colour, num, JujutsuFxScale.Weight(StepImpact[step]), false, true);
				if (step == 2)
				{
					JujutsuFxHitStop.Hold(((EntityState)this).characterBody, 0.06f, false);
					JujutsuMotes.Burst(val3, val2, TodoLanguage.Colour, num * 0.7f, (JujutsuMoteKind)0, 12);
				}
			}
			if (((EntityState)this).fixedAge >= duration && ((EntityState)this).isAuthority)
			{
				((EntityState)this).outer.SetNextStateToMain();
			}
		}

		private void PerfectSwap()
		{
			TodoBoogieWoogie component = ((Component)((EntityState)this).characterBody).GetComponent<TodoBoogieWoogie>();
			if (!Object.op_Implicit((Object)(object)component))
			{
				return;
			}
			float lastBodyClapAt = component.LastBodyClapAt;
			float num = Time.time - lastBodyClapAt;
			if (!(pressedAt < lastBodyClapAt) && !(num < 0f) && !(num > 0.8f))
			{
				TodoRhythm component2 = ((Component)((EntityState)this).characterBody).GetComponent<TodoRhythm>();
				if (!Object.op_Implicit((Object)(object)component2) || component2.ClaimPerfect(lastBodyClapAt))
				{
					component.PerfectSwap();
				}
			}
		}

		public override void OnSerialize(NetworkWriter writer)
		{
			((BaseSkillState)this).OnSerialize(writer);
			writer.Write((byte)step);
		}

		public override void OnDeserialize(NetworkReader reader)
		{
			((BaseSkillState)this).OnDeserialize(reader);
			int num = reader.ReadByte();
			if (!entered)
			{
				step = Mathf.Clamp(num, 0, StepDurations.Length - 1);
				stepFromWire = true;
			}
		}

		public override InterruptPriority GetMinimumInterruptPriority()
		{
			return (InterruptPriority)1;
		}
	}
	public sealed class TodoOverheadState : BaseSkillState
	{
		internal const float Coefficient = 13f;

		internal const float Radius = 8.5f;

		internal const float DiveRadius = 9.5f;

		internal const float FullFall = 18f;

		internal const float FallBonus = 0.25f;

		private const float GroundDuration = 0.72f;

		private const float GroundContact = 0.42f;

		private const float GroundTravel = 1.2f;

		private const float Hang = 0.16f;

		private const float DiveSpeed = 42f;

		internal const float MaximumDive = 1.5f;

		private const float DiveLean = 0.55f;

		private const float DiveCatch = 2.6f;

		private const float LandingRecovery = 0.34f;

		private const int StallTicks = 3;

		private const float StallFraction = 0.25f;

		internal const float FollowWindow = 2f;

		internal const float FollowReach = 45f;

		internal const float FollowShallowest = 20f;

		private static int followsLogged;

		private bool airborne;

		private float planted;

		private bool smashed;

		private float smashedAt;

		private Vector3 heading;

		private Vector3 dive;

		private float startedFalling;

		private Vector3 lastPoint;

		private bool gravityHeld;

		private bool fallsIgnored;

		private int stalled;

		private int trailTick;

		private bool fromWire;

		private bool entered;

		public override void OnEnter()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: 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_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: 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_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: 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_00a1: 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)
			((BaseState)this).OnEnter();
			if (!fromWire)
			{
				Ray aimRay = ((BaseState)this).GetAimRay();
				Vector3 val = Vector3.ProjectOnPlane(((Ray)(ref aimRay)).direction, Vector3.up);
				heading = ((Vector3)(ref val)).normalized;
				if (((Vector3)(ref heading)).sqrMagnitude < 0.01f)
				{
					heading = ((EntityState)this).characterBody.transform.forward;
				}
				airborne = Object.op_Implicit((Object)(object)((EntityState)this).characterMotor) && !((EntityState)this).characterMotor.isGrounded;
				val = Vector3.down + heading * 0.55f;
				dive = ((Vector3)(ref val)).normalized;
				if (airborne && ((EntityState)this).isAuthority)
				{
					FollowClapped();
				}
			}
			entered = true;
			planted = 0.72f / Mathf.Max(0.1f, ((BaseState)this).attackSpeedStat);
			((EntityState)this).characterBody.SetAimTimer(1.86f);
			if (Object.op_Implicit((Object)(object)((EntityState)this).characterDirection))
			{
				((EntityState)this).characterDirection.forward = heading;
			}
			JujutsuCloseDash.IgnoreFalls(((EntityState)this).characterBody, true, false);
			fallsIgnored = true;
			startedFalling = ((EntityState)this).characterBody.footPosition.y;
			lastPoint = ((EntityState)this).characterBody.corePosition;
			Announce();
		}

		private void FollowClapped()
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: 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_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: 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_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			TodoRhythm component = ((Component)((EntityState)this).characterBody).GetComponent<TodoRhythm>();
			if (!Object.op_Implicit((Object)(object)component) || !component.Follow(2f, out var enemy, out var point) || !Object.op_Implicit((Object)(object)enemy.healthComponent) || !enemy.healthComponent.alive)
			{
				return;
			}
			if (Util.HasEffectiveAuthority(((Component)enemy).gameObject))
			{
				point = JujutsuTeleport.FootOf(enemy);
			}
			Vector3 val = point - JujutsuTeleport.FootOf(((EntityState)this).characterBody);
			float magnitude = ((Vector3)(ref val)).magnitude;
			if (!(magnitude < 0.5f) && !(magnitude > 45f) && !(0f - val.y < magnitude * Mathf.Sin(0.34906584f)))
			{
				dive = val / magnitude;
				Vector3 val2 = Vector3.ProjectOnPlane(val, Vector3.up);
				if (((Vector3)(ref val2)).sqrMagnitude > 0.01f)
				{
					heading = ((Vector3)(ref val2)).normalized;
				}
				if (followsLogged < 12)
				{
					followsLogged++;
					Plugin.Log.LogInfo((object)($"overhead: dive at clapped target={((Object)enemy).name} dist={magnitude:F1}m " + $"underHorizon={Mathf.Asin((0f - val.y) / magnitude) * 57.29578f:F0}deg"), "C:\\Users\\user\\Documents\\risk of rain 2\\src\\Todo\\States\\TodoStates.cs");
				}
			}
		}

		private void Announce()
		{
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			if (airborne)
			{
				if (((EntityState)this).isAuthority && Object.op_Implicit((Object)(object)((EntityState)this).characterMotor))
				{
					((EntityState)this).characterMotor.useGravity = false;
					gravityHeld = true;
					((EntityState)this).characterMotor.velocity = Vector3.zero;
				}
				GojoModelAnimator val = GojoModelAnimator.Find(((EntityState)this).characterBody);
				if (Object.op_Implicit((Object)(object)val))
				{
					val.TriggerPunch(true, 1.66f, 3, 0.92f, true);
				}
				JujutsuSfxAssets.PlayHeavyWhoosh(((EntityState)this).characterBody.corePosition, 0.6f);
			}
			else
			{
				GojoModelAnimator val2 = GojoModelAnimator.Find(((EntityState)this).characterBody);
				if (Object.op_Implicit((Object)(object)val2))
				{
					val2.TriggerPunch(true, planted, 3, 0.42f, true);
				}
				JujutsuSfxAssets.PlayHeavyWhoosh(((EntityState)this).characterBody.corePosition, 0.8f);
			}
		}

		public override void OnSerialize(NetworkWriter writer)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			((BaseSkillState)this).OnSerialize(writer);
			writer.Write(airborne);
			writer.Write(heading);
			writer.Write(dive);
		}

		public override void OnDeserialize(NetworkReader reader)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			((BaseSkillState)this).OnDeserialize(reader);
			bool flag = airborne;
			airborne = reader.ReadBoolean();
			heading = reader.ReadVector3();
			dive = reader.ReadVector3();
			fromWire = true;
			if (entered && airborne != flag)
			{
				Announce();
			}
		}

		public override void FixedUpdate()
		{
			//IL_0038: 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)
			((EntityState)this).FixedUpdate();
			if (airborne)
			{
				Dive();
				return;
			}
			GojoStateUtils.SlowMovementDuringAttack(((EntityState)this).characterMotor, ((EntityState)this).isAuthority, 0.2f);
			GojoStateUtils.GlideIntoBlow(((EntityState)this).characterMotor, ((EntityState)this).isAuthority, heading, 1.2f, ((EntityState)this).fixedAge, planted, 0.42f, false);
			if (!smashed && ((EntityState)this).fixedAge >= planted * 0.42f)
			{
				Smash(((EntityState)this).characterBody.footPosition, 8.5f, 1f);
			}
			if (((EntityState)this).fixedAge >= planted && ((EntityState)this).isAuthority)
			{
				((EntityState)this).outer.SetNextStateToMain();
			}
		}

		private void Dive()
		{
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: 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_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_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: 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_020b: Unknown result type (might be due to invalid IL or missing references)
			//IL_024d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0252: Unknown result type (might be due to invalid IL or missing references)
			if (smashed)
			{
				if (((EntityState)this).fixedAge >= smashedAt + 0.34f && ((EntityState)this).isAuthority)
				{
					((EntityState)this).outer.SetNextStateToMain();
				}
				return;
			}
			if (((EntityState)this).fixedAge < 0.16f)
			{
				if (((EntityState)this).isAuthority && Object.op_Implicit((Object)(object)((EntityState)this).characterMotor))
				{
					((EntityState)this).characterMotor.velocity = Vector3.zero;
					((EntityState)this).characterMotor.moveDirection = Vector3.zero;
				}
				return;
			}
			if (++trailTick % 5 == 0)
			{
				JujutsuMotes.Burst(((EntityState)this).characterBody.corePosition, -dive, TodoLanguage.Colour, TodoFx.Reach(((EntityState)this).characterBody, 0.9f), (JujutsuMoteKind)0, 4);
			}
			if (!((EntityState)this).isAuthority || !Object.op_Implicit((Object)(object)((EntityState)this).characterMotor))
			{
				if (((EntityState)this).isAuthority)
				{
					((EntityState)this).outer.SetNextStateToMain();
				}
				return;
			}
			Vector3 corePosition = ((EntityState)this).characterBody.corePosition;
			((EntityState)this).characterMotor.moveDirection = Vector3.zero;
			((EntityState)this).characterMotor.velocity = dive * 42f;
			Vector3 val = corePosition - lastPoint;
			float magnitude = ((Vector3)(ref val)).magnitude;
			stalled = ((magnitude < 42f * Time.fixedDeltaTime * 0.25f) ? (stalled + 1) : 0);
			float num = Mathf.Max(0f, startedFalling - ((EntityState)this).characterBody.footPosition.y);
			bool flag = BlackFlash.AnythingToHit(((BaseState)this).GetTeam(), lastPoint, corePosition, 2.6f);
			lastPoint = corePosition;
			if (flag || (Object.op_Implicit((Object)(object)((EntityState)this).characterMotor) && ((EntityState)this).characterMotor.isGrounded) || stalled >= 3 || ((EntityState)this).fixedAge >= 1.66f)
			{
				Vector3 centre = (flag ? (corePosition - Vector3.up * 0.4f) : ((EntityState)this).characterBody.footPosition);
				float num2 = Mathf.Clamp01(num / 18f);
				Smash(centre, 9.5f * (1f + num2 * 0.25f * 0.8f), 1f + num2 * 0.25f);
				if (Object.op_Implicit((Object)(object)((EntityState)this).characterMotor))
				{
					((EntityState)this).characterMotor.velocity = Vector3.zero;
					((EntityState)this).characterMotor.useGravity = true;
					gravityHeld = false;
				}
			}
		}

		private void Smash(Vector3 centre, float radius, float scale)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: 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_0118: 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_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0092: 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_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			smashed = true;
			smashedAt = ((EntityState)this).fixedAge;
			if (((EntityState)this).isAuthority)
			{
				Prepared val = BlackFlash.Roll(1f, ((EntityState)this).characterBody);
				if (GojoMeleeAttackUtility.FireRadial(((EntityState)this).gameObject, ((EntityState)this).characterBody, ((BaseState)this).GetTeam(), centre, radius, ((BaseState)this).damageStat * 13f * scale * ((Prepared)(ref val)).Multiplier, 2800f, 1400f, ((BaseState)this).RollCrit() || ((Prepared)(ref val)).Landed, DamageTypeCombo.GenericSecondary, ((Prepared)(ref val)).ProcMask) > 0)
				{
					if (((Prepared)(ref val)).Landed)
					{
						BlackFlash.Land(centre, "Todo", true);
						BlackFlash.Landed(((EntityState)this).characterBody, centre, false);
					}
					TodoRhythm.ReportHit(((EntityState)this).characterBody);
					CursedEnergyController component = ((Component)((EntityState)this).characterBody).GetComponent<CursedEnergyController>();
					if (component != null)
					{
						component.RestoreFromMelee(6f);
					}
				}
			}
			if (airborne)
			{
				GojoModelAnimator val2 = GojoModelAnimator.Find(((EntityState)this).characterBody);
				if (Object.op_Implicit((Object)(object)val2))
				{
					val2.TriggerPunch(true, 0.34f, 3, 0.18f, true);
				}
			}
			float num = TodoFx.Reach(((EntityState)this).characterBody, radius);
			float num2 = JujutsuFxScale.Weight(13f);
			JujutsuImpact.Detonate(centre, TodoLanguage.Colour, num, num2, false, true);
			TodoFx.GroundWave(((EntityState)this).characterBody.footPosition, TodoLanguage.Colour, num, 0.6f);
			JujutsuFxHitStop.Hold(((EntityState)this).characterBody, airborne ? 0.09f : 0.08f, false);
			JujutsuSfxAssets.PlayMeleeHeavy(centre);
			JujutsuFxScorch.Mark(((EntityState)this).characterBody.footPosition, TodoLanguage.Colour, num * 0.78f, 9f, true);
			JujutsuMotes.Burst(((EntityState)this).characterBody.footPosition, Vector3.up, TodoLanguage.Colour, num * 0.5f, (JujutsuMoteKind)1, airborne ? 22 : 14);
			if (NetworkServer.active)
			{
				JujutsuImpact.Surface(((EntityState)this).characterBody.footPosition, Vector3.up, num, true);
			}
		}

		public override void OnExit()
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			if (gravityHeld && Object.op_Implicit((Object)(object)((EntityState)this).characterMotor))
			{
				((EntityState)this).characterMotor.velocity = Vector3.zero;
				((EntityState)this).characterMotor.useGravity = true;
			}
			gravityHeld = false;
			if (fallsIgnored)
			{
				JujutsuCloseDash.IgnoreFalls(((EntityState)this).characterBody, false, false);
				fallsIgnored = false;
			}
			if (((EntityState)this).isAuthority)
			{
				TodoStates.RecordExit(((EntityState)this).characterBody, ((BaseSkillState)this).activatorSkillSlot, smashed);
			}
			((EntityState)this).OnExit();
		}

		public override InterruptPriority GetMinimumInterruptPriority()
		{
			return (InterruptPriority)1;
		}
	}
	public sealed class TodoPlusUltraState : BaseSkillState, IPosedState
	{
		internal const float Coefficient = 13f;

		internal const float KickRadius = 4.4f;

		private const float KickForward = 2.4f;

		internal const float MinimumDistance = 7f;

		internal const float MaximumDistance = 32f;

		internal const float Speed = 52f;

		private const float SweepReach = 3.4f;

		private const float KickDuration = 0.46f;

		private const float KickContact = 0.34f;

		internal const float ZoneDistanceBonus = 0.35f;

		internal const float ZoneDamageBonus = 0.25f;

		internal const float ZoneRadiusBonus = 0.2f;

		private const int StallTicks = 3;

		private const float StallFraction = 0.25f;

		private const float SurfaceProbe = 5f;

		private const float FollowDrop = 3f;

		private const float RideSpeed = 26f;

		private const float SurfaceSkim = 0.1f;

		private const float RideDeadzone = 0.02f;

		internal const float BuriedLimit = 3f;

		private Vector3 heading;

		private bool zone;

		private float reachLimit;

		private float travelled;

		private Vector3 lastPoint;

		private bool dashing = true;

		private bool kicked;

		private float kickedAt;

		private bool gravityHeld;

		private bool fallsIgnored;

		private bool phasing;

		private bool follows;

		private bool ridingSurface;

		private float buried;

		private Vector3 lastFreeFoot;

		private int stalled;

		private int trailTick;

		private const float PerchLift = 1f;

		private const float PerchDrop = 0.5f;

		bool IPosedState.DrivesPose => dashing;

		GojoCpuPose IPosedState.Pose => (GojoCpuPose)24;

		float IPosedState.PosePhase => Mathf.Clamp01(((EntityState)this).fixedAge / Mathf.Max(0.01f, reachLimit / 52f));

		float IPosedState.PoseBob => 0.1f;

		float IPosedState.PosePitch => -12f;

		bool IPosedState.HoldsSlashPose => false;

		int IPosedState.PosePriority => 35;

		public override void OnEnter()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (mig