Decompiled source of AoiTodo v1.2.1

plugins/AoiTodo/AoiTodo.dll

Decompiled 2 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using EntityStates;
using GojoSatoruMod.Components;
using GojoSatoruMod.Content;
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.UI;
using TMPro;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.Rendering;
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.2.1.0")]
[assembly: AssemblyInformationalVersion("1.2.1+fd97d1e734adcd9e1245285b6bc69f1c40353929")]
[assembly: AssemblyProduct("AoiTodo")]
[assembly: AssemblyTitle("AoiTodo")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.2.1.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)"Todo extra skins: todo-skins.model is absent, so only his own outfit is offered.");
					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)($"Todo extra skins: registered {list.Count} skins on " + ((Object)bodyPrefab).name + "."));
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"Todo extra skins could not be registered: {arg}");
			}
		}

		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)"Todo extra skins: the rig has no skinned renderer to take a material from. Skipped.");
					return;
				}
				int found;
				Transform[] bones = ResolveBones(characterModel, out found);
				Plugin.Log.LogInfo((object)($"Todo extra skins: {found} of {boneNames.Length} bones " + "found on the live rig by name."));
				if (found < boneNames.Length / 2)
				{
					Plugin.Log.LogWarning((object)"Todo extra skins: too few bones resolved. Skipped.");
					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)($"Todo extra skins: built {num} outfit renderers on " + ((Object)characterModel).name + "."));
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"Todo extra skins could not be applied: {arg}");
			}
		}

		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_0043: 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_003c: 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_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: 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_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_008f: 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)
			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;
			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;
				num = Mathf.Max(num, ((Vector3)(ref offsets[i])).magnitude);
			}
			Plugin.Log.LogInfo((object)($"Todo extra skins: outfits scaled by {scale:0.000} onto the " + $"rig, worst joint shift {num * 100f:0.0} cm."));
		}

		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)("Todo skin texture was not found: " + text));
				return Texture2D.whiteTexture;
			}
			Texture2D val = JujutsuTextures.Load(text, "texTodoSkin_" + Path.GetFileNameWithoutExtension(textureName), (TextureWrapMode)1, false);
			if (!Object.op_Implicit((Object)(object)val))
			{
				Plugin.Log.LogWarning((object)("Todo skin texture could not be decoded: " + text));
				return Texture2D.whiteTexture;
			}
			textureCache[textureName] = val;
			return val;
		}

		private static bool Load()
		{
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: 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_00fb: 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_0106: 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_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: 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_0165: 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_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: 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_0222: Unknown result type (might be due to invalid IL or missing references)
			//IL_0231: 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_0250: 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_0265: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d5: 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)"Todo extra skins: todo-skins.model is absent.");
				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)($"Todo extra skins: loaded {parts.Count} mesh part(s) over " + $"{num2} bones."));
			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("dev.marmennz.satorugojo", "1.2.1")]
	[BepInPlugin("dev.marmennz.aoitodo", "Aoi Todo", "1.2.1")]
	public sealed class TodoPlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "dev.marmennz.aoitodo";

		public const string PluginVersion = "1.2.1";

		public const string PluginName = "Aoi Todo";

		private void Awake()
		{
			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);
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Aoi Todo 1.2.1 loaded.");
		}
	}
	internal static class GeneratedVersion
	{
		internal const string Value = "1.2.1";
	}
}
namespace GojoSatoruMod.States
{
	public sealed class TodoConsecutiveState : BaseSkillState
	{
		private static readonly float[] StepDurations = new float[4] { 0.4f, 0.38f, 0.42f, 0.58f };

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

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

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

		private const int FinisherStep = 3;

		private float duration;

		private Vector3 aimDirection;

		private bool struck;

		private bool rightHand;

		private int step;

		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_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			((BaseState)this).OnEnter();
			TodoRhythm component = ((Component)((EntityState)this).characterBody).GetComponent<TodoRhythm>();
			step = Mathf.Clamp(Object.op_Implicit((Object)(object)component) ? component.ConsumeComboStep() : 0, 0, StepDurations.Length - 1);
			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 % 2 == 1;
			((EntityState)this).characterBody.SetAimTimer(duration + 0.2f);
			if (((EntityState)this).isAuthority)
			{
				CursedEnergyController component2 = ((Component)((EntityState)this).characterBody).GetComponent<CursedEnergyController>();
				if (component2 != null)
				{
					component2.DrainPriced(2f);
				}
			}
			GojoModelAnimator val = GojoModelAnimator.Find(((EntityState)this).characterBody);
			if (Object.op_Implicit((Object)(object)val))
			{
				val.TriggerPunch(rightHand, duration, step, StepContact[step]);
			}
			JujutsuSfxAssets.PlayMeleeLight(((EntityState)this).characterBody.corePosition);
			if (step == 3)
			{
				JujutsuSfxAssets.PlayHeavyWhoosh(((EntityState)this).characterBody.corePosition, 0.7f);
			}
			else
			{
				JujutsuSfxAssets.PlayLightWhoosh(((EntityState)this).characterBody.corePosition, 0.55f);
			}
		}

		public override void FixedUpdate()
		{
			//IL_004d: 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_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: 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_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: 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_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_021a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: 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_0112: 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_0131: 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_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: 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);
			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 == 3) ? 4600f : 900f) + Vector3.up * ((step == 3) ? 1100f : 120f), ((BaseState)this).RollCrit() || ((Prepared)(ref val4)).Landed, DamageTypeCombo.GenericPrimary) > 0)
					{
						if (((Prepared)(ref val4)).Landed)
						{
							BlackFlash.Land(val3, "Todo", true);
						}
						TodoRhythm.ReportHit(((EntityState)this).characterBody);
						JujutsuSfxAssets.PlayMeleeHeavy(val3);
						CursedEnergyController component = ((Component)((EntityState)this).characterBody).GetComponent<CursedEnergyController>();
						if (component != null)
						{
							component.RestoreFromMelee((step == 3) ? 14f : 9f);
						}
					}
				}
				float num = TodoFx.Reach(((EntityState)this).characterBody, StepRadius[step]);
				JujutsuImpact.Strike(val3, val2, TodoLanguage.Colour, num, JujutsuFxScale.Weight(StepDamage[step]), false);
				if (step == 3)
				{
					JujutsuFxHitStop.Hold(((EntityState)this).characterBody, 0.06f, false);
					JujutsuMotes.Burst(val3, val2, TodoLanguage.Colour, num * 0.7f, (JujutsuMoteKind)0, 12);
				}
				GojoStateUtils.StepIntoBlow(((EntityState)this).characterMotor, ((EntityState)this).isAuthority, aimDirection, (step == 3) ? 2.6f : 1.4f);
			}
			if (((EntityState)this).fixedAge >= duration && ((EntityState)this).isAuthority)
			{
				((EntityState)this).outer.SetNextStateToMain();
			}
		}

		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 Hang = 0.16f;

		private const float DiveSpeed = 42f;

		private 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;

		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_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_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: 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_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: 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_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			((BaseState)this).OnEnter();
			Vector3 val;
			if (!fromWire)
			{
				Ray aimRay = ((BaseState)this).GetAimRay();
				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;
			}
			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);
			fallsIgnored = true;
			startedFalling = ((EntityState)this).characterBody.footPosition.y;
			lastPoint = ((EntityState)this).characterBody.corePosition;
			val = Vector3.down + heading * 0.55f;
			dive = ((Vector3)(ref val)).normalized;
			Announce();
		}

		private void Announce()
		{
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: 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, 4, 0.92f);
				}
				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, 4, 0.42f);
				}
				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)
			((BaseSkillState)this).OnSerialize(writer);
			writer.Write(airborne);
			writer.Write(heading);
		}

		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_0027: 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_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_0041: 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)
			((BaseSkillState)this).OnDeserialize(reader);
			bool flag = airborne;
			airborne = reader.ReadBoolean();
			heading = reader.ReadVector3();
			Vector3 val = Vector3.down + heading * 0.55f;
			dive = ((Vector3)(ref val)).normalized;
			fromWire = true;
			if (entered && airborne != flag)
			{
				Announce();
			}
		}

		public override void FixedUpdate()
		{
			//IL_004e: 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)
			((EntityState)this).FixedUpdate();
			if (airborne)
			{
				Dive();
				return;
			}
			GojoStateUtils.SlowMovementDuringAttack(((EntityState)this).characterMotor, ((EntityState)this).isAuthority, 0.2f);
			if (!smashed && ((EntityState)this).fixedAge >= planted * 0.42f)
			{
				Smash(((EntityState)this).characterBody.footPosition, 8.5f, 1f);
				GojoStateUtils.StepIntoBlow(((EntityState)this).characterMotor, ((EntityState)this).isAuthority, heading, 1.2f);
			}
			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_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: 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_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: 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_017a: 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_0184: 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_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: 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) > 0)
				{
					if (((Prepared)(ref val)).Landed)
					{
						BlackFlash.Land(centre, "Todo", true);
					}
					TodoRhythm.ReportHit(((EntityState)this).characterBody);
					CursedEnergyController component = ((Component)((EntityState)this).characterBody).GetComponent<CursedEnergyController>();
					if (component != null)
					{
						component.RestoreFromMelee(12f);
					}
				}
			}
			if (airborne)
			{
				GojoModelAnimator val2 = GojoModelAnimator.Find(((EntityState)this).characterBody);
				if (Object.op_Implicit((Object)(object)val2))
				{
					val2.TriggerPunch(true, 0.34f, 4, 0.18f);
				}
			}
			float num = TodoFx.Reach(((EntityState)this).characterBody, radius);
			float num2 = JujutsuFxScale.Weight(13f);
			JujutsuImpact.Detonate(centre, TodoLanguage.Colour, num, num2, false);
			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);
				fallsIgnored = false;
			}
			((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 = 26f;

		private 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 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 int stalled;

		private int trailTick;

		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 (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: 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_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			((BaseState)this).OnEnter();
			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;
			}
			TodoRhythm component = ((Component)((EntityState)this).characterBody).GetComponent<TodoRhythm>();
			zone = Object.op_Implicit((Object)(object)component) && component.Stacks >= 6;
			reachLimit = 26f * (zone ? 1.35f : 1f);
			((EntityState)this).characterBody.SetAimTimer(reachLimit / 52f + 0.46f + 0.2f);
			if (Object.op_Implicit((Object)(object)((EntityState)this).characterDirection))
			{
				((EntityState)this).characterDirection.forward = heading;
			}
			if (((EntityState)this).isAuthority && Object.op_Implicit((Object)(object)((EntityState)this).characterMotor))
			{
				((EntityState)this).characterMotor.useGravity = false;
				gravityHeld = true;
				KinematicCharacterMotor motor = ((BaseCharacterController)((EntityState)this).characterMotor).Motor;
				if (motor != null)
				{
					motor.ForceUnground(0.1f);
				}
				((EntityState)this).characterMotor.velocity = heading * 52f;
			}
			JujutsuCloseDash.IgnoreFalls(((EntityState)this).characterBody, true);
			fallsIgnored = true;
			lastPoint = ((EntityState)this).characterBody.corePosition;
			GojoModelAnimator obj = GojoModelAnimator.Find(((EntityState)this).characterBody);
			if (obj != null)
			{
				obj.ClearAttackPose();
			}
			JujutsuSfxAssets.PlayHeavyWhoosh(((EntityState)this).characterBody.corePosition, 0.85f);
			TodoFx.Gather(((EntityState)this).characterBody, 1.2f, 0.2f, 7f / 52f, TodoFx.Reach(((EntityState)this).characterBody, 1.7600001f));
		}

		public override void FixedUpdate()
		{
			((EntityState)this).FixedUpdate();
			if (dashing)
			{
				Travel();
				return;
			}
			GojoStateUtils.SlowMovementDuringAttack(((EntityState)this).characterMotor, ((EntityState)this).isAuthority, 0.15f);
			if (!kicked && ((EntityState)this).fixedAge >= kickedAt + 0.15640001f)
			{
				Kick();
			}
			if (((EntityState)this).fixedAge >= kickedAt + 0.46f && ((EntityState)this).isAuthority)
			{
				((EntityState)this).outer.SetNextStateToMain();
			}
		}

		private void Travel()
		{
			//IL_005e: 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_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: 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_002c: 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)
			//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_009f: 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_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: 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_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			if (((EntityState)this).isAuthority && Object.op_Implicit((Object)(object)((EntityState)this).characterMotor))
			{
				((EntityState)this).characterMotor.moveDirection = Vector3.zero;
				((EntityState)this).characterMotor.velocity = heading * 52f;
			}
			if (++trailTick % 4 == 0)
			{
				JujutsuMotes.Burst(((EntityState)this).characterBody.footPosition, -heading, TodoLanguage.Colour, TodoFx.Reach(((EntityState)this).characterBody, 1.1f), (JujutsuMoteKind)1, 3);
			}
			if (!((EntityState)this).isAuthority)
			{
				return;
			}
			Vector3 corePosition = ((EntityState)this).characterBody.corePosition;
			Vector3 val = corePosition - lastPoint;
			float magnitude = ((Vector3)(ref val)).magnitude;
			bool flag = BlackFlash.AnythingToHit(((BaseState)this).GetTeam(), lastPoint, corePosition, 3.4f);
			travelled += magnitude;
			stalled = ((magnitude < 52f * Time.fixedDeltaTime * 0.25f) ? (stalled + 1) : 0);
			lastPoint = corePosition;
			if (stalled >= 3)
			{
				Stop();
			}
			else if (!(travelled < 7f) || flag)
			{
				bool flag2 = Object.op_Implicit((Object)(object)((EntityState)this).inputBank) && ((EntityState)this).inputBank.skill4.down;
				if (flag || travelled >= reachLimit || !flag2)
				{
					Stop();
				}
			}
		}

		private void Stop()
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: 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_0078: Unknown result type (might be due to invalid IL or missing references)
			dashing = false;
			kickedAt = ((EntityState)this).fixedAge;
			if (Object.op_Implicit((Object)(object)((EntityState)this).characterMotor))
			{
				((EntityState)this).characterMotor.velocity = heading * 10.400001f;
				((EntityState)this).characterMotor.useGravity = true;
				gravityHeld = false;
			}
			GojoModelAnimator val = GojoModelAnimator.Find(((EntityState)this).characterBody);
			if (Object.op_Implicit((Object)(object)val))
			{
				val.TriggerSpinKick(0.46f, 0.34f);
			}
			JujutsuSfxAssets.PlayHeavyWhoosh(((EntityState)this).characterBody.corePosition, 0.9f);
		}

		private Vector3 ImpactPoint()
		{
			//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_0016: 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)
			return ((EntityState)this).characterBody.corePosition + heading * 2.4f;
		}

		private void Kick()
		{
			//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_0036: 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_003d: 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_0054: 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_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: 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_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: 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)
			kicked = true;
			Vector3 val = ImpactPoint();
			float num = 4.4f * (zone ? 1.2f : 1f);
			float num2 = TodoFx.Reach(((EntityState)this).characterBody, num);
			JujutsuImpact.Strike(val, heading, TodoLanguage.Colour, num2, JujutsuFxScale.Weight(13f), true);
			GojoTechniqueVisuals.CreateBurst(val, TodoLanguage.Colour, num2, 0.32f, (GojoTechniqueStyle)5, heading);
			JujutsuSfxAssets.PlayMeleeHeavy(val);
			if (!((EntityState)this).isAuthority)
			{
				return;
			}
			float num3 = Mathf.Max(1f, JujutsuConfig.BlackFlashMultiplier.Value);
			float num4 = ((BaseState)this).damageStat * 13f * num3 * (zone ? 1.25f : 1f);
			int num5 = GojoMeleeAttackUtility.Fire(((EntityState)this).gameObject, ((EntityState)this).characterBody, ((BaseState)this).GetTeam(), val, num, num4, heading * 4600f + Vector3.up * 1400f, true, DamageTypeCombo.GenericSpecial);
			if (num5 > 0)
			{
				BlackFlash.Land(val, "Todo", true);
				JujutsuFxHitStop.Hold(((EntityState)this).characterBody, 0.07f, false);
				TodoRhythm.ReportHit(((EntityState)this).characterBody);
				CursedEnergyController component = ((Component)((EntityState)this).characterBody).GetComponent<CursedEnergyController>();
				if (component != null)
				{
					component.RestoreFromMelee(12f);
				}
				JujutsuCharacters.ForBody(((EntityState)this).characterBody)?.RewardFlash?.Invoke(((EntityState)this).characterBody, num5);
			}
		}

		public override void OnExit()
		{
			//IL_001c: 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_002b: 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 = heading * 10.400001f;
				((EntityState)this).characterMotor.useGravity = true;
			}
			gravityHeld = false;
			if (fallsIgnored)
			{
				JujutsuCloseDash.IgnoreFalls(((EntityState)this).characterBody, false);
				fallsIgnored = false;
			}
			((EntityState)this).OnExit();
		}

		public override InterruptPriority GetMinimumInterruptPriority()
		{
			return (InterruptPriority)2;
		}
	}
	public sealed class TodoThrowStoneState : BaseSkillState
	{
		private const float Duration = 0.45f;

		private const float MaximumHold = 2.5f;

		private TodoThrowPreview preview;

		private JujutsuAimWheel wheel;

		private TodoBoogieWoogie boogie;

		private bool released;

		private float releasedAt;

		private bool thrown;

		private float Reach
		{
			get
			{
				if (!Object.op_Implicit((Object)(object)boogie))
				{
					return 70f;
				}
				return boogie.ThrowReach;
			}
		}

		public override void OnEnter()
		{
			((BaseState)this).OnEnter();
			((EntityState)this).characterBody.SetAimTimer(0.65f);
			boogie = ((Component)((EntityState)this).characterBody).GetComponent<TodoBoogieWoogie>();
			if (((EntityState)this).isAuthority)
			{
				preview = TodoThrowPreview.Attach(((EntityState)this).characterBody);
				wheel = JujutsuAimWheel.Attach(((Component)((EntityState)this).characterBody).gameObject);
				JujutsuAimWheel obj = wheel;
				if (obj != null)
				{
					obj.Begin();
				}
			}
		}

		public override void FixedUpdate()
		{
			//IL_0050: 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)
			((EntityState)this).FixedUpdate();
			if (!((EntityState)this).isAuthority)
			{
				return;
			}
			if (!released)
			{
				Aim();
				return;
			}
			float num = ((EntityState)this).fixedAge - releasedAt;
			if (!thrown && num >= 0.17999999f)
			{
				thrown = true;
				boogie?.PlaceStone(TodoBoogieWoogie.ThrowDestination(((BaseState)this).GetAimRay(), Reach));
			}
			if (num >= 0.45f)
			{
				((EntityState)this).outer.SetNextStateToMain();
			}
		}

		private void Aim()
		{
			//IL_0065: 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)
			((EntityState)this).characterBody.SetAimTimer(0.3f);
			float num = (Object.op_Implicit((Object)(object)wheel) ? wheel.Consume() : 0f);
			if (num != 0f && Object.op_Implicit((Object)(object)boogie))
			{
				boogie.AimThrow(num);
			}
			preview?.Aim(((EntityState)this).characterBody, ((BaseState)this).GetAimRay(), Reach);
			if (!Object.op_Implicit((Object)(object)((EntityState)this).inputBank) || !((EntityState)this).inputBank.skill3.down || !(((EntityState)this).fixedAge < 2.5f))
			{
				released = true;
				releasedAt = ((EntityState)this).fixedAge;
				preview?.Hide();
				JujutsuSfxAssets.PlayMeleeLight(((EntityState)this).characterBody.corePosition);
				Let();
			}
		}

		private void Let()
		{
			//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_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: 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_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_0033: 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_0035: 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_0047: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = TodoBoogieWoogie.ThrowOrigin(((EntityState)this).characterBody);
			Ray aimRay = ((BaseState)this).GetAimRay();
			Vector3 direction = ((Ray)(ref aimRay)).direction;
			Vector3 normalized = ((Vector3)(ref direction)).normalized;
			float num = TodoFx.Reach(((EntityState)this).characterBody, 1.1f);
			JujutsuImpact.Strike(val, normalized, TodoLanguage.Colour, num, 0.12f, true);
			JujutsuMotes.Burst(val, normalized, TodoLanguage.Colour, num, (JujutsuMoteKind)0, 8);
		}

		public override void OnExit()
		{
			preview?.Hide();
			JujutsuAimWheel obj = wheel;
			if (obj != null)
			{
				obj.End();
			}
			((EntityState)this).OnExit();
		}

		public override InterruptPriority GetMinimumInterruptPriority()
		{
			return (InterruptPriority)1;
		}
	}
	public sealed class TodoCycleTargetState : BaseSkillState
	{
		public override void OnEnter()
		{
			((BaseState)this).OnEnter();
			if (((EntityState)this).isAuthority)
			{
				Choose();
			}
			((EntityState)this).outer.SetNextStateToMain();
		}

		private void Choose()
		{
			//IL_001e: 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_003c: 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)
			TodoBoogieWoogie component = ((Component)((EntityState)this).characterBody).GetComponent<TodoBoogieWoogie>();
			if (Object.op_Implicit((Object)(object)component))
			{
				TodoBoogieWoogie.ClapTarget mark = component.Mark;
				Vector3 foot = component.PositionOf(mark);
				component.MarkAimed();
				TodoBoogieWoogie.ClapTarget mark2 = component.Mark;
				if (mark2.Exists)
				{
					TodoFx.Seal(component.PositionOf(mark2), set: true);
				}
				else if (mark.Exists)
				{
					TodoFx.Seal(foot, set: false);
				}
			}
		}

		public override InterruptPriority GetMinimumInterruptPriority()
		{
			return (InterruptPriority)0;
		}
	}
	public sealed class TodoSwapState : BaseSkillState
	{
		private const float Duration = 0.3f;

		public override void OnEnter()
		{
			//IL_0018: 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_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_0063: Unknown result type (might be due to invalid IL or missing references)
			((BaseState)this).OnEnter();
			TodoBoogieWoogie component = ((Component)((EntityState)this).characterBody).GetComponent<TodoBoogieWoogie>();
			TodoFx.SealAt(((EntityState)this).characterBody.corePosition + ((EntityState)this).characterBody.transform.forward * 0.55f, set: true);
			if (Object.op_Implicit((Object)(object)component) && ((EntityState)this).isAuthority && component.Swap())
			{
				TodoAssets.PlayClap(((EntityState)this).characterBody.corePosition);
			}
			else if (((EntityState)this).isAuthority)
			{
				Plugin.Log.LogInfo((object)("Boogie Woogie refused: " + Excuse(component)));
			}
		}

		private static string Excuse(TodoBoogieWoogie boogie)
		{
			if (!Object.op_Implicit((Object)(object)boogie))
			{
				return "the technique is not on this body at all.";
			}
			return boogie.LastRefusal switch
			{
				TodoBoogieWoogie.ClapRefusal.NothingChosen => "nothing was marked and nothing was under the crosshair.", 
				TodoBoogieWoogie.ClapRefusal.NoStone => "the far end fell back to the stone and there is no stone out.", 
				TodoBoogieWoogie.ClapRefusal.NotAffordable => "not enough cursed energy for that pairing; nothing was spent.", 
				TodoBoogieWoogie.ClapRefusal.NoRoom => "one of the two ends had nowhere to stand, so neither travelled and nothing was spent.", 
				_ => "no reason was recorded, which is itself a fault.", 
			};
		}

		public override void FixedUpdate()
		{
			((EntityState)this).FixedUpdate();
			if (((EntityState)this).fixedAge >= 0.3f && ((EntityState)this).isAuthority)
			{
				((EntityState)this).outer.SetNextStateToMain();
			}
		}

		public override InterruptPriority GetMinimumInterruptPriority()
		{
			return (InterruptPriority)2;
		}
	}
}
namespace GojoSatoruMod.Content
{
	internal static class TodoAssets
	{
		private enum Shape
		{
			Blow,
			Slam,
			Stone,
			Cycle,
			Swap,
			Ultra,
			StancePair,
			StanceCrowd
		}

		private const int Size = 128;

		private static readonly Color Backing = new Color(0.06f, 0.04f, 0.1f, 1f);

		private static readonly Color Ink = new Color(0.72f, 0.55f, 0.94f, 1f);

		private static DecodedAttackSound clap;

		private static DecodedAttackSound[] voiceLines;

		private static DecodedAttackSound bestFriend;

		private static float nextVoiceAllowedTime = -1000f;

		private const float VoiceInterval = 12f;

		internal static Sprite BlowIcon { get; private set; }

		internal static Sprite SlamIcon { get; private set; }

		internal static Sprite StoneIcon { get; private set; }

		internal static Sprite CycleIcon { get; private set; }

		internal static Sprite SwapIcon { get; private set; }

		internal static Sprite UltraIcon { get; private set; }

		internal static Sprite StancePairIcon { get; private set; }

		internal static Sprite StanceCrowdIcon { get; private set; }

		private static float ClapVolume => GameVolume.VoiceLevel;

		internal static DecodedAttackSound SpawnVoice { get; private set; }

		internal static IEnumerator LoadSounds()
		{
			clap = GojoAssets.LoadSound("todo-boogie-woogie.mp3", 1f, "Todo", 0f);
			yield return null;
			SpawnVoice = GojoAssets.LoadSound("todo-spawn.mp3", 1f, "Todo", 0f);
			yield return null;
			bestFriend = GojoAssets.LoadSound("besto-friendo.mp3", 1f, "Todo", 0f);
			yield return null;
			string[] chatter = new string[9] { "todo-voice1.mp3", "todo-voice2.mp3", "todo-voice3.mp3", "todo-voice4.mp3", "todo-voice5.mp3", "todo-voice6.mp3", "todo-voice7.mp3", "todo-voice8.mp3", "todo-voice9.mp3" };
			DecodedAttackSound[] lines = (DecodedAttackSound[])(object)new DecodedAttackSound[chatter.Length];
			for (int index = 0; index < chatter.Length; index++)
			{
				lines[index] = GojoAssets.LoadSound(chatter[index], 1f, "Todo", 0f);
				yield return null;
			}
			voiceLines = lines;
		}

		internal static void TryPlayVoice(Vector3 position, float chance)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			if (voiceLines != null && voiceLines.Length != 0 && !(Time.realtimeSinceStartup < nextVoiceAllowedTime) && !(Random.value > Mathf.Clamp01(chance)))
			{
				DecodedAttackSound val = GojoAssets.PickVoice(voiceLines);
				if (val != null)
				{
					GojoAssets.PlayAttackSound(val, position, 1f, 0f, "Todo", true, false);
					nextVoiceAllowedTime = Time.realtimeSinceStartup + 12f;
				}
			}
		}

		internal static void PlayBestFriend(Vector3 position)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			GojoAssets.PlayAttackSound(bestFriend, position, 1f, 0f, "Todo", true, false);
		}

		internal static void PlayClap(Vector3 position)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			GojoAssets.PlayAttackSound(clap, position, ClapVolume, 0.08f, "Todo", false, false);
		}

		internal static void Initialize()
		{
			BlowIcon = GojoAssets.LoadIcon("todo-blow", (Func<Sprite>)(() => Draw("texTodoBlow", Shape.Blow)));
			SlamIcon = GojoAssets.LoadIcon("todo-slam", (Func<Sprite>)(() => Draw("texTodoSlam", Shape.Slam)));
			StoneIcon = GojoAssets.LoadIcon("todo-stone", (Func<Sprite>)(() => Draw("texTodoStone", Shape.Stone)));
			CycleIcon = GojoAssets.LoadIcon("todo-cycle", (Func<Sprite>)(() => Draw("texTodoCycle", Shape.Cycle)));
			SwapIcon = GojoAssets.LoadIcon("todo-swap", (Func<Sprite>)(() => Draw("texTodoSwap", Shape.Swap)));
			UltraIcon = GojoAssets.LoadIcon("todo-ultra", (Func<Sprite>)(() => Draw("texTodoUltra", Shape.Ultra)));
			StancePairIcon = GojoAssets.LoadIcon("todo-stance-pair", (Func<Sprite>)(() => Draw("texTodoStancePair", Shape.StancePair)));
			StanceCrowdIcon = GojoAssets.LoadIcon("todo-stance-crowd", (Func<Sprite>)(() => Draw("texTodoStanceCrowd", Shape.StanceCrowd)));
		}

		private static Sprite Draw(string name, Shape shape)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//IL_00be: 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_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(128, 128, (TextureFormat)4, false);
			((Object)val).name = name;
			((Texture)val).wrapMode = (TextureWrapMode)1;
			Color[] array = (Color[])(object)new Color[16384];
			for (int i = 0; i < 128; i++)
			{
				for (int j = 0; j < 128; j++)
				{
					float u = ((float)j + 0.5f) / 128f * 2f - 1f;
					float v = ((float)i + 0.5f) / 128f * 2f - 1f;
					array[i * 128 + j] = Sample(shape, u, v);
				}
			}
			val.SetPixels(array);
			val.Apply();
			Sprite obj = Sprite.Create(val, new Rect(0f, 0f, 128f, 128f), new Vector2(0.5f, 0.5f), 100f);
			((Object)obj).name = "sprite" + name;
			GojoAssets.PreparePersistentSprite(obj);
			return obj;
		}

		private static Color Sample(Shape shape, float u, float v)
		{
			//IL_001e: 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_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d0: 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_0176: 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_044e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0453: 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_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: 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_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_0227: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0280: Unknown result type (might be due to invalid IL or missing references)
			//IL_0285: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_041d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0422: Unknown result type (might be due to invalid IL or missing references)
			if (Mathf.Max(Mathf.Abs(u), Mathf.Abs(v)) > 0.94f)
			{
				return Color.clear;
			}
			Color result = Backing;
			switch (shape)
			{
			case Shape.Blow:
			{
				float num3 = 0.1f + 0.26f * (u + 0.7f);
				if (u > -0.7f && u < 0.62f && Mathf.Abs(v - (u * 0.55f - 0.05f)) < num3 * 0.5f)
				{
					result = Ink;
				}
				break;
			}
			case Shape.Slam:
			{
				float num7 = Mathf.Sqrt(u * u + (v + 0.3f) * (v + 0.3f));
				if (num7 < 0.17f)
				{
					result = Ink;
				}
				else if (Mathf.Abs(num7 - 0.4f) < 0.07f)
				{
					((Color)(ref result))..ctor(Ink.r, Ink.g, Ink.b, 0.8f);
				}
				else if (Mathf.Abs(num7 - 0.66f) < 0.05f)
				{
					((Color)(ref result))..ctor(Ink.r, Ink.g, Ink.b, 0.5f);
				}
				break;
			}
			case Shape.Stone:
				if (Mathf.Sqrt(u * u + (v + 0.42f) * (v + 0.42f)) < 0.2f)
				{
					result = Ink;
				}
				else if (Mathf.Abs(u) < 0.05f && v > -0.16f && v < 0.62f)
				{
					result = Ink;
				}
				break;
			case Shape.Cycle:
			{
				for (int j = 0; j < 4; j++)
				{
					float num4 = MathF.PI / 2f * (float)j + MathF.PI / 4f;
					float num5 = u - Mathf.Cos(num4) * 0.52f;
					float num6 = v - Mathf.Sin(num4) * 0.52f;
					if (num5 * num5 + num6 * num6 < 0.028f)
					{
						result = (Color)((j == 0) ? Ink : new Color(Ink.r, Ink.g, Ink.b, 0.55f));
					}
				}
				break;
			}
			case Shape.Swap:
				if (v > 0.1f && v < 0.36f && u > -0.62f && u < 0.34f)
				{
					result = Ink;
				}
				else if (v < -0.1f && v > -0.36f && u < 0.62f && u > -0.34f)
				{
					result = Ink;
				}
				else if (u > 0.34f && u < 0.62f && Mathf.Abs(v - 0.23f) < 0.62f - u + 0.34f)
				{
					result = Ink;
				}
				else if (u < -0.34f && u > -0.62f && Mathf.Abs(v + 0.23f) < u + 0.62f + 0.34f)
				{
					result = Ink;
				}
				break;
			case Shape.Ultra:
			{
				for (int i = 0; i < 3; i++)
				{
					float num = -0.3f + (float)i * 0.3f;
					float num2 = -0.8f + (float)Mathf.Abs(i - 1) * 0.2f;
					if (u > num2 && u < 0.02f && Mathf.Abs(v - num * 0.55f) < 0.062f)
					{
						((Color)(ref result))..ctor(Ink.r, Ink.g, Ink.b, (i == 1) ? 1f : 0.6f);
					}
				}
				if (u > 0.06f && u < 0.52f && Mathf.Abs(v - (u * 0.3f - 0.06f)) < 0.2f)
				{
					result = Ink;
				}
				else if (u > 0.44f && u < 0.78f && v > -0.1f && v < 0.4f && Mathf.Abs(u - 0.56f) + Mathf.Abs(v - 0.14f) < 0.34f)
				{
					result = Ink;
				}
				break;
			}
			case Shape.StancePair:
			case Shape.StanceCrowd:
				if (Dot(u, v, -0.58f, 0f) || Dot(u, v, 0.58f, 0f))
				{
					result = Ink;
				}
				else if (shape != Shape.StancePair && (Dot(u, v, -0.3f, 0.34f) || Dot(u, v, -0.3f, -0.34f) || Dot(u, v, 0.3f, 0.34f) || Dot(u, v, 0.3f, -0.34f)))
				{
					((Color)(ref result))..ctor(Ink.r, Ink.g, Ink.b, 0.62f);
				}
				break;
			}
			return result;
		}

		private static bool Dot(float u, float v, float cx, float cy)
		{
			float num = u - cx;
			float num2 = v - cy;
			return num * num + num2 * num2 < 0.032f;
		}
	}
	internal static class TodoLanguage
	{
		internal const string Prefix = "CODEX_TODO_";

		internal static readonly Color Colour = new Color(0.55f, 0.36f, 0.72f, 1f);

		private static float FlashMultiplier
		{
			get
			{
				if (JujutsuConfig.BlackFlashMultiplier == null)
				{
					return 2.5f;
				}
				return Mathf.Max(1f, JujutsuConfig.BlackFlashMultiplier.Value);
			}
		}

		internal static void Register()
		{
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			LanguageAPI.Add("CODEX_TODO_NAME", "Aoi Todo");
			LanguageAPI.Add("CODEX_TODO_SUBTITLE", "The Best Friend");
			LanguageAPI.Add("CODEX_TODO_DESCRIPTION", "Todo is heavier and better armoured than the rest, and he moves by <style=cIsUtility>trading places</style> rather than by running. Throw a stone to make somewhere to be, mark what you want moved, and clap it to whatever you are looking at — yourself, a teammate, or whatever is trying to kill you.");
			LanguageAPI.Add("CODEX_TODO_SKIN_DEFAULT_NAME", "Jujutsu High");
			LanguageAPI.Add("CODEX_TODO_SKIN_OFFDUTY_NAME", "Off Duty");
			LanguageAPI.Add("CODEX_TODO_SKIN_JACKETOFF_NAME", "Jacket Off");
			LanguageAPI.Add("CODEX_TODO_STANCE_NAME", "Pair / Crowd");
			LanguageAPI.Add("CODEX_TODO_STANCE_DESCRIPTION", StatText.Utility(JujutsuInput.Describe(JujutsuConfig.StanceKey.Value)) + " changes which reading of the technique the clap uses. " + StatText.Utility("Pair") + " is the clap as described above: two things trade places. " + StatText.Damage("Crowd") + " trades the two places instead — every enemy the arrival's blow catches changes ends with it, up to six at each end, keeping the ground it stood on. So in this stance you cannot clap out of a pile; you take the pile with you, which is the set-up the Overhead Smash wants. Only on the claps that land a blow.");
			LanguageAPI.Add("CODEX_TODO_PASSIVE_NAME", "Impact");
			LanguageAPI.Add("CODEX_TODO_PASSIVE_DESCRIPTION", "Every clap " + StatText.Damage("lands") + ". Both ends of a swap take " + StatText.Damage(StatText.Percent(4f) + " damage") + " in " + StatText.Utility(StatText.Metres(6f)) + " and are thrown outward — where you left and where you arrived. The clap has no cooldown, so the blow does: " + StatText.Utility("once every " + StatText.Number(1.2f) + " seconds") + ".\n\nAnd he fights to a beat. Every blow that lands adds to it, up to " + StatText.Utility(StatText.Number(6f)) + ", each worth " + StatText.Utility(StatText.Fraction(0.12f) + " attack speed") + " and " + StatText.Healing(StatText.Number(8f) + " armor") + ". From " + StatText.Utility(StatText.Number(3f)) + " up, landing one also " + StatText.Healing("heals " + StatText.Fraction(0.015f) + " of your maximum health") + ". Land nothing and it slips a step every " + StatText.Number(1.4f) + " seconds — but " + StatText.Utility("a clap fills it outright") + ", so arriving is how the beat starts.\n\nAnd he " + StatText.Utility("never takes fall damage") + " — from any height, however he got there.\n\n" + StatText.EnergyRule());
			LanguageAPI.Add("CODEX_TODO_PRIMARY_NAME", "Consecutive Blows");
			LanguageAPI.Add("CODEX_TODO_PRIMARY_DESCRIPTION", StatText.Utility(StatText.Number((float)TodoConsecutiveState.Steps) + " blows") + " thrown one after another for " + StatText.Damage(StatText.Percent(TodoConsecutiveState.Coefficient) + " damage") + " in all. The first three barely move what they hit — the fourth is a hook that throws it. Stop swinging for " + StatText.Number(1.2f) + " seconds and the run starts again from the first.\n\nEach blow spends " + StatText.Utility(StatText.Number(2f) + " cursed energy") + " and pays back " + StatText.Healing(StatText.Number(9f) + " where it lands") + " — " + StatText.Healing(StatText.Number(14f)) + " on the hook. It never refuses for want of energy: " + StatText.Utility("punching is how the bar fills") + ", and only a run swung at nothing is down on the deal.");
			LanguageAPI.Add("CODEX_TODO_SECONDARY_NAME", "Overhead Smash");
			LanguageAPI.Add("CODEX_TODO_SECONDARY_DESCRIPTION", "Both fists into the ground for " + StatText.Damage(StatText.Percent(13f) + " damage") + " to everything within " + StatText.Metres(8.5f) + " and throws it outward. Centred on him, not aimed — clap into a crowd, then smash.\n\n" + StatText.Utility("Used in the air") + " he hangs for a moment and then comes down the way he is facing instead, landing for the same damage across " + StatText.Metres(9.5f) + " — and the further he fell, up to " + StatText.Metres(18f) + ", the harder it lands, to " + StatText.Damage("+" + StatText.Fraction(0.25f)) + ". Anything he catches on the way down stops him there. " + StatText.Seconds(4f) + " second cooldown, and " + StatText.Utility(StatText.Number(14f) + " cursed energy") + " — of which " + StatText.Healing(StatText.Number(12f) + " comes straight back") + " if it hits anything.");
			LanguageAPI.Add("CODEX_TODO_UTILITY_NAME", "Boogie Woogie: Stone");
			LanguageAPI.Add("CODEX_TODO_UTILITY_DESCRIPTION", StatText.Utility("Hold to aim") + " — the arc it will take is drawn for you, and the " + StatText.Utility("mouse wheel throws it harder or softer") + ", from " + StatText.Metres(15f) + " out to " + StatText.Metres(140f) + " — and release to throw. It becomes a " + StatText.Utility("destination you can clap to") + ", and clapping leaves the stone where you were — so the same throw takes you there and back. " + StatText.Utility(StatText.Number(2f) + " stones") + ", one back every " + StatText.Seconds(5f) + " seconds.");
			LanguageAPI.Add("CODEX_TODO_CYCLE_NAME", "Mark");
			LanguageAPI.Add("CODEX_TODO_CYCLE_DESCRIPTION", "Mark whatever you are aiming at — " + StatText.Utility("a teammate, an enemy, or the stone") + ", out to " + StatText.Metres(140f) + ". Aim at nothing to clear it. Costs nothing and takes no time.");
			LanguageAPI.Add("CODEX_TODO_SWAP_NAME", "Boogie Woogie");
			LanguageAPI.Add("CODEX_TODO_SWAP_DESCRIPTION", "Clap, and two things " + StatText.Utility("trade places") + ". " + StatText.Utility("No cooldown") + " — what it spends is " + StatText.Utility("cursed energy") + ", and how much depends on what you ask it to move: " + StatText.Utility(StatText.Number(4f) + " to your own stone") + ", " + StatText.Utility(StatText.Number(9f) + " with an enemy") + ", " + StatText.Utility(StatText.Number(20f) + " with an ally") + ", and " + StatText.Utility(StatText.Number(32f) + " for two things that are not you") + ".\n\nThe " + StatText.Utility("marked") + " thing trades with whatever you are " + StatText.Utility("aiming at") + ". With nothing marked, you are one end. With nothing under your crosshair, the other end is the stone.\n\nSo: aim and clap to go somewhere. Mark an ally and aim at the stone to pull them out. Mark an enemy and aim at another to rearrange the fight.\n\n" + StatText.Utility("Crowd stance:") + " the clap trades the two " + StatText.Utility("places") + " instead of the two things in them. Every enemy the arrival's blow catches — up to " + StatText.Utility(StatText.Number(6f) + " at each end, within " + StatText.Metres(6f)) + " — changes ends with it, keeping the ground they stood on. Only on the claps that land a blow, so at most " + StatText.Utility("once every " + StatText.Number(1.2f) + " seconds") + ". You cannot step out of a fight in this stance: whatever is on you comes too." + StatText.Sub("\n\n< ! > A clap that moves anybody but Todo is handed to the host and run there, so it works from a joined game as well as from one you are hosting."));
			LanguageAPI.Add("CODEX_TODO_SPECIAL_NAME", "Plus Ultra");
			LanguageAPI.Add("CODEX_TODO_SPECIAL_DESCRIPTION", "Dash at whatever you are looking at and kick it. That kick is " + StatText.Damage("always a Black Flash") + ": " + StatText.Damage(StatText.Percent(13f * FlashMultiplier) + " damage") + " across " + StatText.Metres(4.4f) + ", every time.\n\n" + StatText.Utility("Hold to dash further") + " — from " + StatText.Metres(7f) + " on a tap out to " + StatText.Metres(26f) + ". The dash stops at the first thing it reaches, so a hold aimed across a room is a closer as much as a finisher.\n\nAt a " + StatText.Utility("full beat") + " it goes " + StatText.Utility(StatText.Fraction(0.35f) + " further") + ", lands " + StatText.Utility(StatText.Fraction(0.2f) + " wider") + " and hits for " + StatText.Damage("+" + StatText.Fraction(0.25f)) + " — and a clap fills the beat outright. " + StatText.Seconds(9f) + " second cooldown, and " + StatText.Utility(StatText.Number(30f) + " cursed energy") + " — very nearly what a clap between two other things costs, so a bar buys the kick or the rearrangement and not both.");
			LanguageAPI.Add("CODEX_TODO_OUTRO_FLAVOR", "..and so he left, asking everyone he met what their type was.");
			LanguageAPI.Add("CODEX_TODO_OUTRO_FAILURE", "..and so he vanished, with nobody left to call his brother.");
			LogResolvedNumbers();
		}

		private static void LogResolvedNumbers()
		{
			Plugin.Log.LogInfo((object)"Todo skill text assembled from live values:");
			Plugin.Log.LogInfo((object)("  passive : clap " + StatText.Percent(4f) + " across " + StatText.Metres(6f) + ", once every " + StatText.Number(1.2f) + "s"));
			Plugin.Log.LogInfo((object)($"  stance  : crowd carries up to {6}" + " enemies an end, from the same " + StatText.Metres(6f) + " the blow uses"));
			Plugin.Log.LogInfo((object)($"  rhythm  : up to {6} stacks" + ", +" + StatText.Fraction(0.12f) + " attack speed and +" + StatText.Number(8f) + " armour each" + $", heals {StatText.Fraction(0.015f)} from stack {3}" + ", slips one every " + StatText.Number(1.4f) + "s"));
			Plugin.Log.LogInfo((object)($"  blows   : {TodoConsecutiveState.Steps} steps" + ", " + StatText.Percent(TodoConsecutiveState.Coefficient) + " in all over " + StatText.Number(TodoConsecutiveState.RunSeconds) + "s, resets after " + StatText.Number(1.2f) + "s"));
			Plugin.Log.LogInfo((object)("  blow fee: " + StatText.Number(2f) + " a swing (" + StatText.Number(2f * (float)TodoConsecutiveState.Steps) + " a run, drained not gated), pays " + StatText.Number(9f) + " a hit and " + StatText.Number(14f) + " on the hook = " + StatText.Number(9f * (float)(TodoConsecutiveState.Steps - 1) + 14f - 2f * (float)TodoConsecutiveState.Steps) + " net on a run that all lands"));
			Plugin.Log.LogInfo((object)("  overhead: " + StatText.Percent(13f) + " across " + StatText.Metres(8.5f) + " planted, " + StatText.Metres(9.5f) + " diving (+" + StatText.Fraction(0.25f) + " at " + StatText.Metres(18f) + " of fall), cooldown " + StatText.Seconds(4f) + "s, energy " + StatText.Number(14f) + " less " + StatText.Number(12f) + " back on a hit"));
			Plugin.Log.LogInfo((object)("  stone   : " + StatText.Number(2f) + " charges, " + StatText.Seconds(5f) + "s each, mark range " + StatText.Metres(140f)));
			Plugin.Log.LogInfo((object)("  ultra   : " + StatText.Percent(13f) + $" x{FlashMultiplier:0.##} guaranteed flash" + " = " + StatText.Percent(13f * FlashMultiplier) + ", dash " + StatText.Metres(7f) + "-" + StatText.Metres(26f) + ", cooldown " + StatText.Seconds(9f) + "s, energy " + StatText.Number(30f) + " against a remote clap's " + StatText.Number(32f)));
		}
	}
	internal static class TodoSurvivor
	{
		internal static class Costs
		{
			internal const float ConsecutiveCooldown = 0f;

			internal const float ConsecutiveEnergy = 2f;

			internal const float OverheadCooldown = 4f;

			internal const float OverheadEnergy = 14f;

			internal const float ThrowStoneCooldown = 5f;

			internal const int StoneCharges = 2;

			internal const float PlusUltraCooldown = 9f;

			internal const float PlusUltraEnergy = 30f;

			internal const float CycleCooldown = 0f;

			internal const float SwapCooldown = 0f;
		}

		internal static SurvivorDef SurvivorDef { get; private set; }

		internal static void Initialize()
		{
			//IL_0019: 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_008d: 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_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: 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_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Expected O, but got Unknown
			//IL_00e7: 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_00f7: 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_0112: 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_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Expected O, but got Unknown
			//IL_013e: 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_014e: 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_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: 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_018b: Expected O, but got Unknown
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: 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_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Expected O, but got Unknown
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_020f: Unknown result type (might be due to invalid IL or missing references)
			//IL_021f: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0235: Unknown result type (might be due to invalid IL or missing references)
			//IL_0237: Unknown result type (might be due to invalid IL or missing references)
			//IL_0241: Expected O, but got Unknown
			//IL_0247: Unknown result type (might be due to invalid IL or missing references)
			//IL_024c: 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_0262: Unknown result type (might be due to invalid IL or missing references)
			//IL_0272: Unknown result type (might be due to inva