Decompiled source of CharacterAPI v0.9.4

plugins/viliger-CharacterAPI/CharacterAPI.dll

Decompiled 9 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using CharacterAPI.Hooks;
using IL.Reptile;
using Microsoft.CodeAnalysis;
using Mono.Cecil.Cil;
using MonoMod.Cil;
using On.Reptile;
using Reptile;
using Reptile.Phone;
using TMPro;
using UnityEngine;
using UnityEngine.Playables;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: AssemblyCompany("CharacterAPI")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("CharacterAPI")]
[assembly: AssemblyTitle("CharacterAPI")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace CharacterAPI
{
	[BepInPlugin("com.Viliger.CharacterAPI", "CharacterAPI", "0.9.4")]
	public class CharacterAPI : BaseUnityPlugin
	{
		public static ManualLogSource logger;

		public static string DllPath;

		public static string SavePath;

		public static string NewSavePath;

		public static ConfigEntry<bool> PerformSaveCleanUp;

		public void Awake()
		{
			AssetBundle val = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "Assets", "silence"));
			if (!Object.op_Implicit((Object)(object)val))
			{
				logger.LogError((object)"Asset bundle \"silence\" is either not present or broken. Please consider reinstalling CharacterAPI from scratch.");
				return;
			}
			CoreHooks.silence = val.LoadAsset<AudioClip>("silence");
			SavePath = Paths.ConfigPath;
			NewSavePath = Paths.BepInExRootPath + "\\CharacterAPI";
			DllPath = ((BaseUnityPlugin)this).Info.Location;
			logger = ((BaseUnityPlugin)this).Logger;
			PerformSaveCleanUp = ((BaseUnityPlugin)this).Config.Bind<bool>("Saving", "Save Clean Up", false, "Performs save clean up on each start. It removes saves for characters that are not curently enabled. Can be useful if save grows out of proportions with hundreds of characters or dozens save slots.");
			AudioManagerHooks.InitHooks();
			CharacterConstructorHooks.InitHooks();
			CharacterSelectCharacterHooks.InitHooks();
			CharacterSelectHooks.InitHooks();
			CharacterSelectUIHooks.InitHooks();
			CharacterVisualHooks.InitHooks();
			CoreHooks.InitHooks();
			GraffitiArtInfoHooks.InitHooks();
			OutfitSwitchMenuHooks.InitHooks();
			PlayerHooks.InitHooks();
			SaveSlotDataHooks.InitHooks();
			StyleSwitchMenuHooks.InitHooks();
			ModdedCharacterProgress.Load();
		}

		public static void AttemptToFixShaderCharacter(CharacterLoader? loader, Material material)
		{
			if (Object.op_Implicit((Object)(object)material) && loader != null)
			{
				Material characterMaterial = loader.GetCharacterMaterial((Characters)3, 0);
				material.shader = characterMaterial.shader;
			}
		}

		public static void AttemtToFixShaderGraffiti(GraffitiLoader? loader, Material material)
		{
			if (Object.op_Implicit((Object)(object)material) && loader != null)
			{
				Material graffitiMaterial = loader.graffitiArtInfo.FindByCharacter((Characters)3).graffitiMaterial;
				material.shader = graffitiMaterial.shader;
			}
		}
	}
	public class ModdedCharacter
	{
		public class SkatesPosition
		{
			public Vector3 scale;

			public Vector3 position;

			public Quaternion rotation;
		}

		internal static List<ModdedCharacter> ModdedCharacters = new List<ModdedCharacter>();

		public string Name;

		public string[] outfitNames;

		public Material[] loadedCharacterMaterials;

		public GameObject loadedCharacterFbxAssets;

		public GameObject characterVisual;

		public int defaultOutfit;

		public MoveStyle defaultMoveStyle;

		public Characters characterVoiceBase;

		public bool usePersonalGrafitti;

		public GraffitiArt? personalGrafitti;

		public Characters characterGraffitiBase;

		public int freestyleHash;

		public int bounceHash;

		public Characters characterEnum;

		public SfxCollectionID voiceId;

		public List<AudioClip> audioClips = new List<AudioClip>();

		public bool canBlink;

		public bool usesCustomShader;

		public SkatesPosition positionL;

		public SkatesPosition positionR;

		private int? Hash;

		public override int GetHashCode()
		{
			if (!Hash.HasValue)
			{
				int num = -2128831035;
				num = num * 16777619 + Name.GetHashCode();
				string[] array = outfitNames;
				foreach (string text in array)
				{
					num = num * 16777619 + text.GetHashCode();
				}
				num = num * 16777619 + usePersonalGrafitti.GetHashCode();
				num = num * 16777619 + ((object)(MoveStyle)(ref defaultMoveStyle)).GetHashCode();
				num = num * 16777619 + defaultOutfit.GetHashCode();
				Hash = num;
			}
			return Hash.Value;
		}

		public static ModdedCharacter GetModdedCharacter(Characters character)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			return ModdedCharacters.Find((ModdedCharacter x) => x.characterEnum == character);
		}

		public static ModdedCharacter GetModdedCharacter(int hash)
		{
			return ModdedCharacters.Find((ModdedCharacter x) => x.GetHashCode() == hash);
		}
	}
	public class ModdedCharacterConstructor : IDisposable
	{
		private struct Outfit
		{
			public string name;

			public Material material;
		}

		private struct PersonalGraffiti
		{
			public string name;

			public string author;

			public Material material;

			public Texture texture;
		}

		public enum FreestyleType
		{
			freestyle1,
			freestyle2,
			freestyle3,
			freestyle4,
			freestyle5,
			freestyle6,
			freestyle7,
			freestyle8,
			freestyle9,
			freestyle10,
			freestyle11,
			freestyle12,
			freestyle13,
			freestyle14,
			freestyle15,
			freestyle16,
			freestyle17,
			freestyle18,
			freestyle19
		}

		public enum BounceType
		{
			bounce,
			softbounce1,
			softbounce2,
			softbounce3,
			softbounce4,
			softbounce5,
			softbounce6,
			softbounce7,
			softbounce8,
			softbounce9,
			softbounce10,
			softbounce11,
			softbounce12,
			softbounce13,
			softbounce14,
			softbounce15
		}

		public enum Skate
		{
			Left,
			Right
		}

		private const int CHARACTER_STARTING_VALUE = 27;

		private const int VOICE_STARTING_VALUE = 67;

		public string? characterName;

		public GameObject? characterPrefab;

		public int defaultOutfit;

		public MoveStyle defaultMoveStyle = (MoveStyle)2;

		public Characters tempAudioBase = (Characters)3;

		public Characters personalGraffitiBase = (Characters)3;

		public FreestyleType freestyleType;

		public BounceType bounceType;

		public bool canBlink;

		public List<AudioClip> audioClips = new List<AudioClip>();

		public bool usesCustomShader;

		public bool skipTransformsCheck;

		private List<Outfit> outfits = new List<Outfit>();

		private PersonalGraffiti personalGraffiti;

		private ModdedCharacter.SkatesPosition positionL;

		private ModdedCharacter.SkatesPosition positionR;

		private static FieldInfo[] graffitiNamesFieldInfos = (from fi in typeof(Titles).GetFields(BindingFlags.Static | BindingFlags.Public | BindingFlags.FlattenHierarchy)
			where fi.IsLiteral && !fi.IsInitOnly
			select fi).ToArray();

		public void AddOutfit(Material material, string name = "")
		{
			if (outfits.Count > 3)
			{
				CharacterAPI.logger.LogWarning((object)("Can't have more than 4 outfits on character " + characterName + ". Skipping outfit " + name + "..."));
			}
			else if (!Object.op_Implicit((Object)(object)material))
			{
				CharacterAPI.logger.LogWarning((object)("Outfit material was empty for character " + characterName + ". Skipping outfit " + name + "..."));
			}
			else
			{
				outfits.Add(new Outfit
				{
					material = material,
					name = (string.IsNullOrEmpty(name) ? GetOutfitNameBasedOnIndex(outfits.Count) : name)
				});
			}
		}

		public void AddPersonalGraffiti(string name, string author, Material material, Texture texture)
		{
			if (!Object.op_Implicit((Object)(object)material))
			{
				CharacterAPI.logger.LogWarning((object)("Personal graffiti " + name + " for character " + characterName + " has no material. Skipping personal graffiti..."));
			}
			else if (!Object.op_Implicit((Object)(object)texture))
			{
				CharacterAPI.logger.LogWarning((object)("Personal graffiti " + name + " for character " + characterName + " has no texture. Skipping personal graffiti..."));
			}
			else if (!CheckGraffitiName(name))
			{
				CharacterAPI.logger.LogWarning((object)("Personal graffiti's name " + name + " for character " + characterName + " collides with existing game graffiti. Skipping personal graffiti..."));
			}
			else
			{
				personalGraffiti = new PersonalGraffiti
				{
					author = author,
					name = name,
					material = material,
					texture = texture
				};
			}
		}

		public bool CreateModdedCharacter()
		{
			//IL_00ac: 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_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0340: Unknown result type (might be due to invalid IL or missing references)
			//IL_0345: Unknown result type (might be due to invalid IL or missing references)
			//IL_0261: Unknown result type (might be due to invalid IL or missing references)
			//IL_026b: Expected O, but got Unknown
			//IL_02b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0310: Unknown result type (might be due to invalid IL or missing references)
			//IL_0315: Unknown result type (might be due to invalid IL or missing references)
			//IL_0380: Unknown result type (might be due to invalid IL or missing references)
			//IL_0366: Unknown result type (might be due to invalid IL or missing references)
			//IL_0395: Unknown result type (might be due to invalid IL or missing references)
			//IL_039b: Expected O, but got Unknown
			//IL_040c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0418: Unknown result type (might be due to invalid IL or missing references)
			if (string.IsNullOrEmpty(characterName))
			{
				CharacterAPI.logger.LogWarning((object)"Attempted to add a charcter without a name. Skipping this character...");
				return false;
			}
			if (!Object.op_Implicit((Object)(object)characterPrefab))
			{
				CharacterAPI.logger.LogWarning((object)("Character " + characterName + " doesn't have a prefab. Skipping this character..."));
				return false;
			}
			if (outfits.Count == 0)
			{
				CharacterAPI.logger.LogWarning((object)("Character " + characterName + " needs to have at least one outfit. Skipping this character..."));
				return false;
			}
			if (!CheckForTransforms() && !skipTransformsCheck)
			{
				return false;
			}
			ModdedCharacter moddedCharacter = new ModdedCharacter();
			moddedCharacter.Name = characterName;
			moddedCharacter.characterEnum = (Characters)(27 + ModdedCharacter.ModdedCharacters.Count);
			moddedCharacter.outfitNames = new string[4];
			moddedCharacter.loadedCharacterMaterials = (Material[])(object)new Material[4];
			for (int i = 0; i < 4; i++)
			{
				moddedCharacter.outfitNames[i] = outfits[i % outfits.Count].name;
				moddedCharacter.loadedCharacterMaterials[i] = outfits[i % outfits.Count].material;
			}
			moddedCharacter.loadedCharacterFbxAssets = characterPrefab;
			SkinnedMeshRenderer componentInChildren = characterPrefab.GetComponentInChildren<SkinnedMeshRenderer>();
			if (Object.op_Implicit((Object)(object)componentInChildren))
			{
				Mesh sharedMesh = componentInChildren.sharedMesh;
				if (Object.op_Implicit((Object)(object)sharedMesh) && sharedMesh.blendShapeCount < 2 && canBlink)
				{
					CharacterAPI.logger.LogWarning((object)("Character " + characterName + " doesn't have nessesary shape keys\\blend shapes to blink, yet is marked as capable of blinking. Setting canBlink to false."));
					canBlink = false;
				}
			}
			moddedCharacter.canBlink = canBlink;
			moddedCharacter.usesCustomShader = usesCustomShader;
			moddedCharacter.defaultOutfit = Mathf.Clamp(defaultOutfit, 0, 3);
			moddedCharacter.defaultMoveStyle = defaultMoveStyle;
			moddedCharacter.characterVoiceBase = tempAudioBase;
			moddedCharacter.freestyleHash = Animator.StringToHash("freestyle" + (int)(freestyleType + 1));
			if (bounceType == BounceType.bounce)
			{
				moddedCharacter.bounceHash = Animator.StringToHash("bounce");
			}
			else
			{
				int num = (int)freestyleType;
				moddedCharacter.bounceHash = Animator.StringToHash("softBounce" + num);
			}
			if (Object.op_Implicit((Object)(object)personalGraffiti.material) && Object.op_Implicit((Object)(object)personalGraffiti.texture))
			{
				moddedCharacter.usePersonalGrafitti = true;
				moddedCharacter.personalGrafitti = new GraffitiArt();
				moddedCharacter.personalGrafitti.graffitiMaterial = personalGraffiti.material;
				moddedCharacter.personalGrafitti.title = personalGraffiti.name;
				moddedCharacter.personalGrafitti.artistName = personalGraffiti.author;
				moddedCharacter.personalGrafitti.graffitiSize = (GraffitiSize)0;
				moddedCharacter.personalGrafitti.unlockable = ScriptableObject.CreateInstance<GraffitiAppEntry>();
				moddedCharacter.personalGrafitti.unlockable.Title = moddedCharacter.personalGrafitti.title;
				moddedCharacter.personalGrafitti.unlockable.Artist = moddedCharacter.personalGrafitti.artistName;
				moddedCharacter.personalGrafitti.unlockable.Size = moddedCharacter.personalGrafitti.graffitiSize;
				moddedCharacter.personalGrafitti.unlockable.GraffitiTexture = personalGraffiti.texture;
			}
			else
			{
				moddedCharacter.usePersonalGrafitti = false;
				moddedCharacter.characterGraffitiBase = personalGraffitiBase;
			}
			if (audioClips.Count > 0)
			{
				moddedCharacter.voiceId = (SfxCollectionID)(67 + ModdedCharacter.ModdedCharacters.Count);
				moddedCharacter.audioClips = new List<AudioClip>(audioClips);
			}
			else
			{
				moddedCharacter.voiceId = (SfxCollectionID)(-1);
			}
			GameObject val = new GameObject(moddedCharacter.Name + "Visuals");
			GameObject obj = Object.Instantiate<GameObject>(moddedCharacter.loadedCharacterFbxAssets);
			obj.transform.SetParent(val.transform, false);
			SkinnedMeshRenderer componentInChildren2 = obj.GetComponentInChildren<SkinnedMeshRenderer>();
			((Renderer)componentInChildren2).sharedMaterial = Object.Instantiate<Material>(moddedCharacter.loadedCharacterMaterials[0]);
			((Renderer)componentInChildren2).receiveShadows = false;
			obj.GetComponentInChildren<Animator>().applyRootMotion = false;
			val.SetActive(false);
			moddedCharacter.characterVisual = val;
			ModdedCharacter.ModdedCharacters.Add(moddedCharacter);
			CharacterAPI.logger.LogMessage((object)$"Character {characterName} with enum {moddedCharacter.characterEnum}{GetLogStringWithSfxAndGraffiti(moddedCharacter.voiceId, moddedCharacter.personalGrafitti)} successfully added.");
			return true;
		}

		public void AddSkatePosition(Skate skate, Vector3 position, Vector3 rotation, Vector3 scale)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			AddSkatePosition(skate, position, Quaternion.Euler(rotation), scale);
		}

		public void AddSkatePosition(Skate skate, Vector3 position, Quaternion rotation, Vector3 scale)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: 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_0017: Unknown result type (might be due to invalid IL or missing references)
			ModdedCharacter.SkatesPosition skatesPosition = new ModdedCharacter.SkatesPosition();
			skatesPosition.position = position;
			skatesPosition.rotation = rotation;
			skatesPosition.scale = scale;
			if (skate == Skate.Left)
			{
				positionL = skatesPosition;
			}
			else
			{
				positionR = skatesPosition;
			}
		}

		private string GetOutfitNameBasedOnIndex(int i)
		{
			return i switch
			{
				0 => "U_SKIN_SPRING", 
				1 => "U_SKIN_SUMMER", 
				2 => "U_SKIN_AUTUMN", 
				3 => "U_SKIN_WINTER", 
				_ => "U_SKIN_SPRING", 
			};
		}

		private string GetLogStringWithSfxAndGraffiti(SfxCollectionID voiceId, GraffitiArt personalGraffiti)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Invalid comparison between Unknown and I4
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			string text = "";
			if ((int)voiceId != -1)
			{
				text += $" and SfxCollectionID {voiceId}";
			}
			if (personalGraffiti != null)
			{
				text = string.Concat(text, " and personal graffiti named \"" + personalGraffiti.title + "\"");
			}
			return text;
		}

		private bool CheckGraffitiName(string name)
		{
			bool result = true;
			FieldInfo[] array = graffitiNamesFieldInfos;
			for (int i = 0; i < array.Length; i++)
			{
				if (((string)array[i].GetValue(null)).Equals(name))
				{
					return false;
				}
			}
			return result;
		}

		private bool CheckForTransforms()
		{
			bool bonesFound = true;
			Animator componentInChildren = characterPrefab.GetComponentInChildren<Animator>();
			if (!Object.op_Implicit((Object)(object)componentInChildren))
			{
				CharacterAPI.logger.LogWarning((object)("Character " + characterName + " doesn't have Animator component. Skipping this character..."));
				return false;
			}
			Transform val = ((Component)componentInChildren).transform.Find("root");
			if (!Object.op_Implicit((Object)(object)val))
			{
				CharacterAPI.logger.LogWarning((object)("Character " + characterName + " doesn't have \"root\" as animation bone base. Skipping this character..."));
				return false;
			}
			bonesFound = CheckForSpecificTransformInRoot(val, "head", bonesFound);
			bonesFound = CheckForSpecificTransformInRoot(val, "jetpack", bonesFound);
			bonesFound = CheckForSpecificTransformInRoot(val, "footr", bonesFound);
			bonesFound = CheckForSpecificTransformInRoot(val, "footl", bonesFound);
			bonesFound = CheckForSpecificTransformInRoot(val, "leg2r", bonesFound);
			bonesFound = CheckForSpecificTransformInRoot(val, "leg2l", bonesFound);
			bonesFound = CheckForSpecificTransformInRoot(val, "handr", bonesFound);
			bonesFound = CheckForSpecificTransformInRoot(val, "handl", bonesFound);
			bonesFound = CheckForSpecificTransformInRoot(val.parent, "handlIK", bonesFound);
			bonesFound = CheckForSpecificTransformInRoot(val.parent, "handrIK", bonesFound);
			bonesFound = CheckForSpecificTransformInRoot(val.parent, "bmxFrame", bonesFound);
			bonesFound = CheckForSpecificTransformInRoot(val.parent, "phoneDirectionRoot", bonesFound);
			return CheckForSpecificTransformInRoot(val.parent, "skateboard", bonesFound);
		}

		private bool CheckForSpecificTransformInRoot(Transform transform, string bone, bool bonesFound)
		{
			bool flag = Object.op_Implicit((Object)(object)transform.Find(bone));
			if (!flag)
			{
				flag = Object.op_Implicit((Object)(object)TransformExtentions.FindRecursive(transform, bone));
			}
			if (!flag)
			{
				CharacterAPI.logger.LogWarning((object)("Character " + characterName + " doesn't have transform \"" + bone + "\". Skipping this character..."));
			}
			return flag && bonesFound;
		}

		public void Dispose()
		{
			audioClips.Clear();
			outfits.Clear();
		}
	}
	public class ModdedCharacterProgress
	{
		public class ModdedSaveSlot
		{
			public List<ModdedCharacterProgressStruct> moddedCharacterProgress = new List<ModdedCharacterProgressStruct>();

			public int lastPlayedCharacter;

			public ModdedCharacterProgressStruct GetModdedCharacterProgress(int hash)
			{
				return moddedCharacterProgress.Find((ModdedCharacterProgressStruct x) => x.characterHash == hash);
			}
		}

		public class ModdedCharacterProgressStruct
		{
			public CharacterProgress characterProgress = new CharacterProgress();

			public int characterHash;
		}

		private const int MODDED_CHARACTER_SAVE_VERSION = 1;

		private const string MODDED_CHARACTER_SAVE_FOLDER = "CharacterAPISaves";

		private const string MODDED_CHARACTER_SAVE_FILE_NAME = "ModdedCharactersProgress.capi";

		private const string NEW_MODDED_CHARACTER_SAVE_FOLDER = "Saves";

		private static Dictionary<int, ModdedSaveSlot> moddedSaveSlots = new Dictionary<int, ModdedSaveSlot>();

		public static ModdedCharacterProgressStruct? GetCharacterProgress(int saveSlotId, int hash)
		{
			return GetModdedSaveSlot(saveSlotId)?.GetModdedCharacterProgress(hash);
		}

		public static ModdedCharacterProgressStruct CreateNewModdedCharacterProgress(int saveSlotId, int hash, Characters character, bool unlocked, int outfit, MoveStyle moveStyle, int moveStyleSkin)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: 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_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected O, but got Unknown
			ModdedSaveSlot moddedSaveSlot = GetModdedSaveSlot(saveSlotId);
			if (moddedSaveSlot == null)
			{
				moddedSaveSlot = CreateNewModdedSaveSlot(saveSlotId, hash);
			}
			ModdedCharacterProgressStruct moddedCharacterProgressStruct = new ModdedCharacterProgressStruct();
			moddedCharacterProgressStruct.characterHash = hash;
			if (moddedCharacterProgressStruct.characterProgress == null)
			{
				moddedCharacterProgressStruct.characterProgress = new CharacterProgress();
			}
			moddedCharacterProgressStruct.characterProgress.unlocked = unlocked;
			moddedCharacterProgressStruct.characterProgress.character = character;
			moddedCharacterProgressStruct.characterProgress.outfit = outfit;
			moddedCharacterProgressStruct.characterProgress.moveStyle = moveStyle;
			moddedCharacterProgressStruct.characterProgress.moveStyleSkin = moveStyleSkin;
			moddedSaveSlot.moddedCharacterProgress.Add(moddedCharacterProgressStruct);
			return moddedCharacterProgressStruct;
		}

		public static ModdedSaveSlot? GetModdedSaveSlot(int saveSlotId)
		{
			if (moddedSaveSlots.TryGetValue(saveSlotId, out ModdedSaveSlot value))
			{
				return value;
			}
			return null;
		}

		public static ModdedSaveSlot CreateNewModdedSaveSlot(int saveSlotId, int lastPlayerCharacter = -1)
		{
			ModdedSaveSlot moddedSaveSlot = new ModdedSaveSlot();
			if (moddedSaveSlot.moddedCharacterProgress == null)
			{
				moddedSaveSlot.moddedCharacterProgress = new List<ModdedCharacterProgressStruct>();
			}
			moddedSaveSlot.lastPlayedCharacter = lastPlayerCharacter;
			moddedSaveSlots.Add(saveSlotId, moddedSaveSlot);
			return moddedSaveSlot;
		}

		public static void SetLastPlayedCharacter(int saveSlotId, int lastPlayerCharacter)
		{
			ModdedSaveSlot moddedSaveSlot = GetModdedSaveSlot(saveSlotId);
			if (moddedSaveSlot == null)
			{
				moddedSaveSlot = CreateNewModdedSaveSlot(saveSlotId, lastPlayerCharacter);
			}
			moddedSaveSlot.lastPlayedCharacter = lastPlayerCharacter;
		}

		public static void PerformSaveCleanUp()
		{
			foreach (KeyValuePair<int, ModdedSaveSlot> moddedSaveSlot in moddedSaveSlots)
			{
				foreach (ModdedCharacterProgressStruct item in moddedSaveSlot.Value.moddedCharacterProgress)
				{
					if (ModdedCharacter.GetModdedCharacter(item.characterHash) == null)
					{
						moddedSaveSlot.Value.moddedCharacterProgress.Remove(item);
					}
				}
				if (moddedSaveSlot.Value.moddedCharacterProgress.Count == 0)
				{
					moddedSaveSlots.Remove(moddedSaveSlot.Key);
				}
			}
		}

		public static void PerformSaveValidation()
		{
			//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_0049: Unknown result type (might be due to invalid IL or missing references)
			foreach (KeyValuePair<int, ModdedSaveSlot> moddedSaveSlot in moddedSaveSlots)
			{
				foreach (ModdedCharacterProgressStruct item in moddedSaveSlot.Value.moddedCharacterProgress)
				{
					ModdedCharacter moddedCharacter = ModdedCharacter.GetModdedCharacter(item.characterHash);
					if (moddedCharacter == null)
					{
						item.characterProgress.character = (Characters)(-1);
					}
					else
					{
						item.characterProgress.character = moddedCharacter.characterEnum;
					}
				}
			}
		}

		public static void Save()
		{
			string path = Path.Combine(CharacterAPI.NewSavePath, "Saves", "ModdedCharactersProgress.capi");
			try
			{
				Directory.CreateDirectory(Path.GetDirectoryName(path));
				using FileStream fileStream = File.Open(path, FileMode.Create);
				using (BinaryWriter binaryWriter = new BinaryWriter(fileStream))
				{
					binaryWriter.Write(1);
					binaryWriter.Write(moddedSaveSlots.Count);
					foreach (KeyValuePair<int, ModdedSaveSlot> moddedSaveSlot in moddedSaveSlots)
					{
						binaryWriter.Write(moddedSaveSlot.Key);
						binaryWriter.Write(moddedSaveSlot.Value.lastPlayedCharacter);
						binaryWriter.Write(moddedSaveSlot.Value.moddedCharacterProgress.Count);
						foreach (ModdedCharacterProgressStruct item in moddedSaveSlot.Value.moddedCharacterProgress)
						{
							binaryWriter.Write(item.characterHash);
							item.characterProgress.Write(binaryWriter);
						}
					}
					binaryWriter.Close();
				}
				fileStream.Close();
			}
			catch (Exception ex)
			{
				CharacterAPI.logger.LogError((object)$"Exception during modded character save creation. Exception: {ex}, Message: {ex.Message}.");
				File.Delete(path);
			}
		}

		public static void Load()
		{
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Expected O, but got Unknown
			string text = Path.Combine(CharacterAPI.SavePath, "CharacterAPISaves", "ModdedCharactersProgress.capi");
			string text2 = Path.Combine(CharacterAPI.NewSavePath, "Saves", "ModdedCharactersProgress.capi");
			try
			{
				if (File.Exists(text))
				{
					Directory.CreateDirectory(Path.GetDirectoryName(text2));
					File.Move(text, text2);
					CharacterAPI.logger.LogMessage((object)"Save file is moved to BepInEx\\CharacterAPI\\Saves.");
				}
			}
			catch (Exception ex)
			{
				CharacterAPI.logger.LogWarning((object)$"Exception during moving save file to new location. Exception: {ex}, Message: {ex.Message}.");
			}
			try
			{
				if (!File.Exists(text2))
				{
					return;
				}
				int num = 0;
				int num2 = 0;
				using (FileStream fileStream = File.OpenRead(text2))
				{
					using (BinaryReader binaryReader = new BinaryReader(fileStream))
					{
						if (binaryReader.ReadInt32() < 1)
						{
							return;
						}
						int num3 = binaryReader.ReadInt32();
						for (int i = 0; i < num3; i++)
						{
							int key = binaryReader.ReadInt32();
							ModdedSaveSlot moddedSaveSlot = new ModdedSaveSlot();
							moddedSaveSlot.lastPlayedCharacter = binaryReader.ReadInt32();
							int num4 = binaryReader.ReadInt32();
							if (moddedSaveSlot.moddedCharacterProgress == null)
							{
								moddedSaveSlot.moddedCharacterProgress = new List<ModdedCharacterProgressStruct>();
							}
							for (int j = 0; j < num4; j++)
							{
								int characterHash = binaryReader.ReadInt32();
								CharacterProgress val = new CharacterProgress();
								val.Read(binaryReader);
								moddedSaveSlot.moddedCharacterProgress.Add(new ModdedCharacterProgressStruct
								{
									characterHash = characterHash,
									characterProgress = val
								});
								num++;
							}
							moddedSaveSlots.Add(key, moddedSaveSlot);
							num2++;
						}
						binaryReader.Close();
					}
					fileStream.Close();
				}
				CharacterAPI.logger.LogMessage((object)$"Successfully loaded {num2} saves with {num} characters total between them.");
			}
			catch (Exception ex2)
			{
				CharacterAPI.logger.LogError((object)$"Exception during modded character save reading. Exception: {ex2}, Message: {ex2.Message}.");
				File.Delete(text2);
			}
		}
	}
}
namespace CharacterAPI.Hooks
{
	public class AudioManagerHooks
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static hook_GetCharacterVoiceSfxCollection <0>__AudioManager_GetCharacterVoiceSfxCollection;

			public static Manipulator <1>__AudioManager_PlayVoice_Characters_AudioClipID;

			public static Manipulator <2>__AudioManager_PlayVoice_refVoicePriority_Characters_AudioClipID_AudioSource_VoicePriority;
		}

		public static void InitHooks()
		{
			//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_001b: Expected O, but got Unknown
			//IL_0030: 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_003b: Expected O, but got Unknown
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			object obj = <>O.<0>__AudioManager_GetCharacterVoiceSfxCollection;
			if (obj == null)
			{
				hook_GetCharacterVoiceSfxCollection val = AudioManager_GetCharacterVoiceSfxCollection;
				<>O.<0>__AudioManager_GetCharacterVoiceSfxCollection = val;
				obj = (object)val;
			}
			AudioManager.GetCharacterVoiceSfxCollection += (hook_GetCharacterVoiceSfxCollection)obj;
			object obj2 = <>O.<1>__AudioManager_PlayVoice_Characters_AudioClipID;
			if (obj2 == null)
			{
				Manipulator val2 = AudioManager_PlayVoice_Characters_AudioClipID;
				<>O.<1>__AudioManager_PlayVoice_Characters_AudioClipID = val2;
				obj2 = (object)val2;
			}
			AudioManager.PlayVoice_Characters_AudioClipID += (Manipulator)obj2;
			object obj3 = <>O.<2>__AudioManager_PlayVoice_refVoicePriority_Characters_AudioClipID_AudioSource_VoicePriority;
			if (obj3 == null)
			{
				Manipulator val3 = AudioManager_PlayVoice_refVoicePriority_Characters_AudioClipID_AudioSource_VoicePriority;
				<>O.<2>__AudioManager_PlayVoice_refVoicePriority_Characters_AudioClipID_AudioSource_VoicePriority = val3;
				obj3 = (object)val3;
			}
			AudioManager.PlayVoice_refVoicePriority_Characters_AudioClipID_AudioSource_VoicePriority += (Manipulator)obj3;
		}

		private static void AudioManager_PlayVoice_refVoicePriority_Characters_AudioClipID_AudioSource_VoicePriority(ILContext il)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(il);
			int num = default(int);
			if (val.TryGotoNext((MoveType)0, new Func<Instruction, bool>[2]
			{
				(Instruction x) => ILPatternMatchingExt.MatchLdarg(x, ref num),
				(Instruction x) => ILPatternMatchingExt.MatchLdfld<AudioManager>(x, "characterToVoiceCollection")
			}))
			{
				int index = val.Index;
				val.Index = index + 1;
				val.RemoveRange(3);
				val.Emit(OpCodes.Ldarg_2);
				val.EmitDelegate<Func<AudioManager, Characters, SfxCollectionID>>((Func<AudioManager, Characters, SfxCollectionID>)delegate(AudioManager am, Characters c)
				{
					//IL_000a: Unknown result type (might be due to invalid IL or missing references)
					//IL_0020: Unknown result type (might be due to invalid IL or missing references)
					//IL_001d: 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_002b: Unknown result type (might be due to invalid IL or missing references)
					//IL_0031: Invalid comparison between Unknown and I4
					//IL_0041: 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)
					if (Enum.IsDefined(typeof(Characters), c))
					{
						return am.characterToVoiceCollection[c];
					}
					ModdedCharacter moddedCharacter = ModdedCharacter.GetModdedCharacter(c);
					if (moddedCharacter == null)
					{
						CharacterAPI.logger.LogWarning((object)$"AudioManager::AudioManager_PlayVoice_refVoicePriority_Characters_AudioClipID_AudioSource_VoicePriority failed to find voice for character {c}, replacing it with {(object)(Characters)3}.");
						return am.characterToVoiceCollection[3];
					}
					return ((int)moddedCharacter.voiceId == -1) ? am.characterToVoiceCollection[moddedCharacter.characterVoiceBase] : moddedCharacter.voiceId;
				});
			}
			else
			{
				CharacterAPI.logger.LogError((object)"AudioManager::AudioManager_PlayVoice_refVoicePriority_Characters_AudioClipID_AudioSource_VoicePriority hook failed.");
			}
		}

		private static void AudioManager_PlayVoice_Characters_AudioClipID(ILContext il)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(il);
			int num = default(int);
			if (val.TryGotoNext((MoveType)0, new Func<Instruction, bool>[2]
			{
				(Instruction x) => ILPatternMatchingExt.MatchLdarg(x, ref num),
				(Instruction x) => ILPatternMatchingExt.MatchLdfld<AudioManager>(x, "characterToVoiceCollection")
			}))
			{
				val.RemoveRange(4);
				val.Emit(OpCodes.Ldarg_0);
				val.Emit(OpCodes.Ldarg_1);
				val.EmitDelegate<Func<AudioManager, Characters, SfxCollectionID>>((Func<AudioManager, Characters, SfxCollectionID>)delegate(AudioManager am, Characters c)
				{
					//IL_000a: Unknown result type (might be due to invalid IL or missing references)
					//IL_0020: Unknown result type (might be due to invalid IL or missing references)
					//IL_001d: 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_002b: Unknown result type (might be due to invalid IL or missing references)
					//IL_0031: Invalid comparison between Unknown and I4
					//IL_0041: 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)
					if (Enum.IsDefined(typeof(Characters), c))
					{
						return am.characterToVoiceCollection[c];
					}
					ModdedCharacter moddedCharacter = ModdedCharacter.GetModdedCharacter(c);
					if (moddedCharacter == null)
					{
						CharacterAPI.logger.LogWarning((object)$"AudioManager::PlayVoice_Characters_AudioClipID failed to find voice for character {c}, replacing it with {(object)(Characters)3}.");
						return am.characterToVoiceCollection[3];
					}
					return ((int)moddedCharacter.voiceId == -1) ? am.characterToVoiceCollection[moddedCharacter.characterVoiceBase] : moddedCharacter.voiceId;
				});
			}
			else
			{
				CharacterAPI.logger.LogError((object)"AudioManager::PlayVoice_Characters_AudioClipID hook failed.");
			}
		}

		private static SfxCollectionID AudioManager_GetCharacterVoiceSfxCollection(orig_GetCharacterVoiceSfxCollection orig, AudioManager self, Characters character)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: 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_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Invalid comparison between Unknown and I4
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			if (Enum.IsDefined(typeof(Characters), character))
			{
				return orig.Invoke(self, character);
			}
			ModdedCharacter moddedCharacter = ModdedCharacter.GetModdedCharacter(character);
			if (moddedCharacter != null)
			{
				if ((int)moddedCharacter.voiceId != -1)
				{
					return moddedCharacter.voiceId;
				}
				return orig.Invoke(self, moddedCharacter.characterVoiceBase);
			}
			CharacterAPI.logger.LogWarning((object)$"AudioManager::GetCharacterVoiceSfxCollection failed to find voice for character {character}, replacing it with {(object)(Characters)3}.");
			return orig.Invoke(self, (Characters)3);
		}
	}
	public class CharacterConstructorHooks
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static hook_CreateCharacterMaterial <0>__CharacterConstructor_CreateCharacterMaterial;

			public static hook_CreateNewCharacterVisual <1>__CharacterConstructor_CreateNewCharacterVisual;
		}

		public static void InitHooks()
		{
			//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_001b: Expected O, but got Unknown
			//IL_0030: 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_003b: Expected O, but got Unknown
			object obj = <>O.<0>__CharacterConstructor_CreateCharacterMaterial;
			if (obj == null)
			{
				hook_CreateCharacterMaterial val = CharacterConstructor_CreateCharacterMaterial;
				<>O.<0>__CharacterConstructor_CreateCharacterMaterial = val;
				obj = (object)val;
			}
			CharacterConstructor.CreateCharacterMaterial += (hook_CreateCharacterMaterial)obj;
			object obj2 = <>O.<1>__CharacterConstructor_CreateNewCharacterVisual;
			if (obj2 == null)
			{
				hook_CreateNewCharacterVisual val2 = CharacterConstructor_CreateNewCharacterVisual;
				<>O.<1>__CharacterConstructor_CreateNewCharacterVisual = val2;
				obj2 = (object)val2;
			}
			CharacterConstructor.CreateNewCharacterVisual += (hook_CreateNewCharacterVisual)obj2;
		}

		private static CharacterVisual CharacterConstructor_CreateNewCharacterVisual(orig_CreateNewCharacterVisual orig, CharacterConstructor self, Characters character, RuntimeAnimatorController controller, bool IK, float setGroundAngleLimit)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			if (Enum.IsDefined(typeof(Characters), character))
			{
				return orig.Invoke(self, character, controller, IK, setGroundAngleLimit);
			}
			ModdedCharacter moddedCharacter = ModdedCharacter.GetModdedCharacter(character);
			if (moddedCharacter != null)
			{
				CharacterVisual obj = Object.Instantiate<GameObject>(moddedCharacter.characterVisual).AddComponent<CharacterVisual>();
				SkinnedMeshRenderer componentInChildren = ((Component)obj).GetComponentInChildren<SkinnedMeshRenderer>();
				if (Object.op_Implicit((Object)(object)componentInChildren) && !moddedCharacter.usesCustomShader)
				{
					CharacterAPI.AttemptToFixShaderCharacter(self.characterLoader, ((Renderer)componentInChildren).material);
				}
				obj.Init(character, controller, IK, setGroundAngleLimit);
				((Component)obj).gameObject.SetActive(true);
				obj.canBlink = moddedCharacter.canBlink;
				return obj;
			}
			CharacterAPI.logger.LogWarning((object)$"CharacterConstructor::CreateNewCharacterVisual failed to find modded character {character}, replacing it with {(object)(Characters)3}.");
			return orig.Invoke(self, (Characters)3, controller, IK, setGroundAngleLimit);
		}

		private static Material CharacterConstructor_CreateCharacterMaterial(orig_CreateCharacterMaterial orig, CharacterConstructor self, Characters character, int outfit)
		{
			//IL_000a: 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_0019: 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)
			if (Enum.IsDefined(typeof(Characters), character))
			{
				return orig.Invoke(self, character, outfit);
			}
			ModdedCharacter moddedCharacter = ModdedCharacter.GetModdedCharacter(character);
			if (moddedCharacter != null)
			{
				Material val = moddedCharacter.loadedCharacterMaterials[outfit];
				if (!moddedCharacter.usesCustomShader)
				{
					CharacterAPI.AttemptToFixShaderCharacter(self.characterLoader, val);
				}
				return val;
			}
			CharacterAPI.logger.LogWarning((object)$"CharacterConstructor::CreateCharacterMaterial failed to find modded character {character}, replacing it with {(object)(Characters)3}.");
			return orig.Invoke(self, (Characters)3, outfit);
		}
	}
	internal class CharacterSelectCharacterHooks
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static hook_Init <0>__CharacterSelectCharacter_Init;
		}

		public static void InitHooks()
		{
			//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_001b: Expected O, but got Unknown
			object obj = <>O.<0>__CharacterSelectCharacter_Init;
			if (obj == null)
			{
				hook_Init val = CharacterSelectCharacter_Init;
				<>O.<0>__CharacterSelectCharacter_Init = val;
				obj = (object)val;
			}
			CharacterSelectCharacter.Init += (hook_Init)obj;
		}

		private static void CharacterSelectCharacter_Init(orig_Init orig, CharacterSelectCharacter self, CharacterSelect SetCharacterSelect, Characters setCharacter, GameObject collider, GameObject talkTrigger, Vector3 centerPosition, PlayableDirector swapCharacterSequence)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: 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)
			orig.Invoke(self, SetCharacterSelect, setCharacter, collider, talkTrigger, centerPosition, swapCharacterSequence);
			if (!Enum.IsDefined(typeof(Characters), setCharacter))
			{
				ModdedCharacter moddedCharacter = ModdedCharacter.GetModdedCharacter(setCharacter);
				if (moddedCharacter != null)
				{
					self.freeStyleHash = moddedCharacter.freestyleHash;
				}
			}
		}
	}
	public class CharacterSelectHooks
	{
		private struct SelectableCharacterWithMods
		{
			public bool IsModdedCharacter;

			public Characters characterEnum;
		}

		[CompilerGenerated]
		private static class <>O
		{
			public static hook_PopulateListOfSelectableCharacters <0>__CharacterSelect_PopulateListOfSelectableCharacters;

			public static hook_CreateCharacterSelectCharacter <1>__CharacterSelect_CreateCharacterSelectCharacter;

			public static Manipulator <2>__CharacterSelect_Init;

			public static Manipulator <3>__CharacterSelect_DefineLocations;

			public static Manipulator <4>__CharacterSelect_MoveSelection;

			public static Manipulator <5>__CharacterSelect_UpdateCharactersInCircle;

			public static hook_SetPlayerToCharacter <6>__CharacterSelect_SetPlayerToCharacter;
		}

		private static List<SelectableCharacterWithMods> selectableCharactesWithMods = new List<SelectableCharacterWithMods>();

		public static void InitHooks()
		{
			//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_001b: Expected O, but got Unknown
			//IL_0030: 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_003b: Expected O, but got Unknown
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Expected O, but got Unknown
			//IL_0090: 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_009b: Expected O, but got Unknown
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Expected O, but got Unknown
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Expected O, but got Unknown
			object obj = <>O.<0>__CharacterSelect_PopulateListOfSelectableCharacters;
			if (obj == null)
			{
				hook_PopulateListOfSelectableCharacters val = CharacterSelect_PopulateListOfSelectableCharacters;
				<>O.<0>__CharacterSelect_PopulateListOfSelectableCharacters = val;
				obj = (object)val;
			}
			CharacterSelect.PopulateListOfSelectableCharacters += (hook_PopulateListOfSelectableCharacters)obj;
			object obj2 = <>O.<1>__CharacterSelect_CreateCharacterSelectCharacter;
			if (obj2 == null)
			{
				hook_CreateCharacterSelectCharacter val2 = CharacterSelect_CreateCharacterSelectCharacter;
				<>O.<1>__CharacterSelect_CreateCharacterSelectCharacter = val2;
				obj2 = (object)val2;
			}
			CharacterSelect.CreateCharacterSelectCharacter += (hook_CreateCharacterSelectCharacter)obj2;
			object obj3 = <>O.<2>__CharacterSelect_Init;
			if (obj3 == null)
			{
				Manipulator val3 = CharacterSelect_Init;
				<>O.<2>__CharacterSelect_Init = val3;
				obj3 = (object)val3;
			}
			CharacterSelect.Init += (Manipulator)obj3;
			object obj4 = <>O.<3>__CharacterSelect_DefineLocations;
			if (obj4 == null)
			{
				Manipulator val4 = CharacterSelect_DefineLocations;
				<>O.<3>__CharacterSelect_DefineLocations = val4;
				obj4 = (object)val4;
			}
			CharacterSelect.DefineLocations += (Manipulator)obj4;
			object obj5 = <>O.<4>__CharacterSelect_MoveSelection;
			if (obj5 == null)
			{
				Manipulator val5 = CharacterSelect_MoveSelection;
				<>O.<4>__CharacterSelect_MoveSelection = val5;
				obj5 = (object)val5;
			}
			CharacterSelect.MoveSelection += (Manipulator)obj5;
			object obj6 = <>O.<5>__CharacterSelect_UpdateCharactersInCircle;
			if (obj6 == null)
			{
				Manipulator val6 = CharacterSelect_UpdateCharactersInCircle;
				<>O.<5>__CharacterSelect_UpdateCharactersInCircle = val6;
				obj6 = (object)val6;
			}
			CharacterSelect.UpdateCharactersInCircle += (Manipulator)obj6;
			object obj7 = <>O.<6>__CharacterSelect_SetPlayerToCharacter;
			if (obj7 == null)
			{
				hook_SetPlayerToCharacter val7 = CharacterSelect_SetPlayerToCharacter;
				<>O.<6>__CharacterSelect_SetPlayerToCharacter = val7;
				obj7 = (object)val7;
			}
			CharacterSelect.SetPlayerToCharacter += (hook_SetPlayerToCharacter)obj7;
		}

		private static void CharacterSelect_SetPlayerToCharacter(orig_SetPlayerToCharacter orig, CharacterSelect self, int index)
		{
			//IL_0018: 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)
			orig.Invoke(self, index);
			if (!Enum.IsDefined(typeof(Characters), self.player.character))
			{
				ModdedCharacter moddedCharacter = ModdedCharacter.GetModdedCharacter(self.player.character);
				if (moddedCharacter != null)
				{
					ModdedCharacterProgress.SetLastPlayedCharacter(Core.instance.saveManager.saveSlotHandler.currentSaveSlot.saveSlotId, moddedCharacter.GetHashCode());
				}
			}
			else
			{
				ModdedCharacterProgress.SetLastPlayedCharacter(Core.instance.saveManager.saveSlotHandler.currentSaveSlot.saveSlotId, -1);
			}
			ModdedCharacterProgress.Save();
		}

		private static void CharacterSelect_CreateCharacterSelectCharacter(orig_CreateCharacterSelectCharacter orig, CharacterSelect self, Characters character, int numInCircle, CharSelectCharState startState)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: 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_001b: Unknown result type (might be due to invalid IL or missing references)
			if (Enum.IsDefined(typeof(Characters), character))
			{
				orig.Invoke(self, character, numInCircle, startState);
				return;
			}
			Player player = self.player;
			CharacterVisual val = player.CharacterConstructor.CreateNewCharacterVisual(character, player.animatorController, true, player.motor.groundDetection.groundLimit);
			int outfit = Core.instance.SaveManager.CurrentSaveSlot.GetCharacterProgress(character).outfit;
			Material sharedMaterial = player.characterConstructor.CreateCharacterMaterial(character, outfit);
			((Renderer)val.mainRenderer).sharedMaterial = sharedMaterial;
			self.CharactersInCircle[numInCircle] = ((Component)val).gameObject.AddComponent<CharacterSelectCharacter>();
			((Component)self.charactersInCircle[numInCircle]).transform.position = self.characterPositions[numInCircle];
			((Component)self.charactersInCircle[numInCircle]).transform.rotation = Quaternion.LookRotation(self.characterDirections[numInCircle] * -1f);
			((Component)self.charactersInCircle[numInCircle]).transform.parent = self.tf;
			self.charactersInCircle[numInCircle].Init(self, character, self.charCollision, self.charTrigger, self.tf.position, Object.Instantiate<GameObject>(self.swapSequence, ((Component)self.charactersInCircle[numInCircle]).transform).GetComponent<PlayableDirector>());
			self.charactersInCircle[numInCircle].SetState(startState);
		}

		private static void CharacterSelect_PopulateListOfSelectableCharacters(orig_PopulateListOfSelectableCharacters orig, CharacterSelect self, Player player)
		{
			//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_0037: 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_0080: 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_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			orig.Invoke(self, player);
			selectableCharactesWithMods.Clear();
			foreach (Characters selectableCharacter in self.selectableCharacters)
			{
				selectableCharactesWithMods.Add(new SelectableCharacterWithMods
				{
					characterEnum = selectableCharacter,
					IsModdedCharacter = false
				});
			}
			foreach (ModdedCharacter moddedCharacter in ModdedCharacter.ModdedCharacters)
			{
				if (self.player.character != moddedCharacter.characterEnum)
				{
					selectableCharactesWithMods.Add(new SelectableCharacterWithMods
					{
						characterEnum = moddedCharacter.characterEnum,
						IsModdedCharacter = true
					});
				}
			}
		}

		private static void CharacterSelect_UpdateCharactersInCircle(ILContext il)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_01ec: 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)
			ILCursor val = new ILCursor(il);
			int num9 = default(int);
			int num8 = default(int);
			if (val.TryGotoNext((MoveType)0, new Func<Instruction, bool>[3]
			{
				(Instruction x) => ILPatternMatchingExt.MatchLdloc(x, ref num9),
				(Instruction x) => ILPatternMatchingExt.MatchLdarg(x, ref num8),
				(Instruction x) => ILPatternMatchingExt.MatchLdfld<CharacterSelect>(x, "selectableCharacters")
			}))
			{
				int index = val.Index;
				val.Index = index + 1;
				val.RemoveRange(3);
				val.EmitDelegate<Func<int>>((Func<int>)(() => selectableCharactesWithMods.Count));
			}
			else
			{
				CharacterAPI.logger.LogError((object)"First CharacterSelect::UpdateCharactersInCircle hook failed.");
			}
			int num7 = default(int);
			if (val.TryGotoNext((MoveType)0, new Func<Instruction, bool>[2]
			{
				(Instruction x) => ILPatternMatchingExt.MatchLdarg(x, ref num7),
				(Instruction x) => ILPatternMatchingExt.MatchLdfld<CharacterSelect>(x, "selectableCharacters")
			}))
			{
				val.RemoveRange(3);
				val.EmitDelegate<Func<int>>((Func<int>)(() => selectableCharactesWithMods.Count));
			}
			else
			{
				CharacterAPI.logger.LogError((object)"Second CharacterSelect::UpdateCharactersInCircle hook failed.");
			}
			int num6 = default(int);
			int num5 = default(int);
			if (val.TryGotoNext((MoveType)0, new Func<Instruction, bool>[3]
			{
				(Instruction x) => ILPatternMatchingExt.MatchLdarg(x, ref num6),
				(Instruction x) => ILPatternMatchingExt.MatchLdfld<CharacterSelect>(x, "charactersInCircle"),
				(Instruction x) => ILPatternMatchingExt.MatchLdloc(x, ref num5)
			}))
			{
				int index = val.Index;
				val.Index = index + 1;
				val.RemoveRange(37);
				val.Emit(OpCodes.Ldloc_1);
				val.Emit(OpCodes.Ldloc_0);
				val.EmitDelegate<Action<CharacterSelect, int, int>>((Action<CharacterSelect, int, int>)delegate(CharacterSelect cs, int num2, int num)
				{
					//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_005d: Unknown result type (might be due to invalid IL or missing references)
					if ((Object)(object)cs.charactersInCircle[num] == (Object)null || cs.charactersInCircle[num].character != selectableCharactesWithMods[num2].characterEnum)
					{
						if ((Object)(object)cs.charactersInCircle[num] != (Object)null)
						{
							Object.Destroy((Object)(object)((Component)cs.charactersInCircle[num]).gameObject);
						}
						cs.CreateCharacterSelectCharacter(selectableCharactesWithMods[num2].characterEnum, num, (CharSelectCharState)1);
					}
				});
			}
			else
			{
				CharacterAPI.logger.LogError((object)"Third CharacterSelect::UpdateCharactersInCircle hook failed.");
			}
			int num4 = default(int);
			int num3 = default(int);
			if (val.TryGotoNext((MoveType)0, new Func<Instruction, bool>[4]
			{
				(Instruction x) => ILPatternMatchingExt.MatchLdarg(x, ref num4),
				(Instruction x) => ILPatternMatchingExt.MatchLdfld<CharacterSelect>(x, "charactersInCircle"),
				(Instruction x) => ILPatternMatchingExt.MatchLdarg(x, ref num3),
				(Instruction x) => ILPatternMatchingExt.MatchLdfld<CharacterSelect>(x, "selectionInCircle")
			}))
			{
				int index = val.Index;
				val.Index = index + 1;
				val.RemoveRange(56);
				val.EmitDelegate<Action<CharacterSelect>>((Action<CharacterSelect>)delegate(CharacterSelect cs)
				{
					//IL_004b: Unknown result type (might be due to invalid IL or missing references)
					//IL_0060: Unknown result type (might be due to invalid IL or missing references)
					//IL_0022: 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_00a4: Unknown result type (might be due to invalid IL or missing references)
					if (((Object)(object)cs.charactersInCircle[cs.selectionInCircle] == (Object)null || cs.charactersInCircle[cs.selectionInCircle].character != selectableCharactesWithMods[cs.selection].characterEnum) && cs.charactersInCircle[cs.selectionInCircle].character != selectableCharactesWithMods[cs.selection].characterEnum)
					{
						if ((Object)(object)cs.charactersInCircle[cs.selectionInCircle] != (Object)null)
						{
							Object.Destroy((Object)(object)((Component)cs.charactersInCircle[cs.selectionInCircle]).gameObject);
						}
						cs.CreateCharacterSelectCharacter(selectableCharactesWithMods[cs.selection].characterEnum, cs.selectionInCircle, (CharSelectCharState)1);
					}
				});
			}
			else
			{
				CharacterAPI.logger.LogError((object)"Fourth CharacterSelect::UpdateCharactersInCircle hook failed.");
			}
		}

		private static void CharacterSelect_MoveSelection(ILContext il)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_0241: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(il);
			int num6 = default(int);
			int num5 = default(int);
			if (val.TryGotoNext((MoveType)0, new Func<Instruction, bool>[3]
			{
				(Instruction x) => ILPatternMatchingExt.MatchLdloc(x, ref num6),
				(Instruction x) => ILPatternMatchingExt.MatchLdarg(x, ref num5),
				(Instruction x) => ILPatternMatchingExt.MatchLdfld<CharacterSelect>(x, "selectableCharacters")
			}))
			{
				int index = val.Index;
				val.Index = index + 1;
				val.RemoveRange(3);
				val.EmitDelegate<Func<int>>((Func<int>)(() => selectableCharactesWithMods.Count));
			}
			else
			{
				CharacterAPI.logger.LogError((object)"First CharacterSelect::MoveSelection hook failed.");
			}
			int num4 = default(int);
			if (val.TryGotoNext((MoveType)0, new Func<Instruction, bool>[2]
			{
				(Instruction x) => ILPatternMatchingExt.MatchLdarg(x, ref num4),
				(Instruction x) => ILPatternMatchingExt.MatchLdfld<CharacterSelect>(x, "selectableCharacters")
			}))
			{
				val.RemoveRange(3);
				val.EmitDelegate<Func<int>>((Func<int>)(() => selectableCharactesWithMods.Count));
			}
			else
			{
				CharacterAPI.logger.LogError((object)"Second CharacterSelect::MoveSelection hook failed.");
			}
			int num3 = default(int);
			int num2 = default(int);
			int num = default(int);
			if (val.TryGotoNext((MoveType)0, new Func<Instruction, bool>[6]
			{
				(Instruction x) => ILPatternMatchingExt.MatchLdarg(x, ref num3),
				(Instruction x) => ILPatternMatchingExt.MatchLdfld<CharacterSelect>(x, "characterSelectUI"),
				(Instruction x) => ILPatternMatchingExt.MatchLdarg(x, ref num2),
				(Instruction x) => ILPatternMatchingExt.MatchLdfld<CharacterSelect>(x, "selectableCharacters"),
				(Instruction x) => ILPatternMatchingExt.MatchLdarg(x, ref num),
				(Instruction x) => ILPatternMatchingExt.MatchLdfld<CharacterSelect>(x, "selection")
			}))
			{
				val.RemoveRange(8);
				val.Emit(OpCodes.Ldarg_0);
				val.EmitDelegate<Action<CharacterSelect>>((Action<CharacterSelect>)delegate(CharacterSelect cs)
				{
					//IL_0016: Unknown result type (might be due to invalid IL or missing references)
					cs.characterSelectUI.SetCharacterInformation(selectableCharactesWithMods[cs.selection].characterEnum);
				});
			}
			else
			{
				CharacterAPI.logger.LogError((object)"Third CharacterSelect::MoveSelection hook failed.");
			}
		}

		private static void CharacterSelect_DefineLocations(ILContext il)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			ILCursor val = new ILCursor(il);
			if (val.TryGotoNext((MoveType)0, new Func<Instruction, bool>[1]
			{
				(Instruction x) => ILPatternMatchingExt.MatchLdfld<CharacterSelect>(x, "selectableCharacters")
			}))
			{
				int index = val.Index;
				val.Index = index - 1;
				val.RemoveRange(3);
				val.EmitDelegate<Func<int>>((Func<int>)(() => selectableCharactesWithMods.Count));
			}
			else
			{
				CharacterAPI.logger.LogError((object)"CharacterSelect::DefineLocations hook failed.");
			}
		}

		private static void CharacterSelect_Init(ILContext il)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_028e: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(il);
			int num7 = default(int);
			int num6 = default(int);
			ILLabel val2 = default(ILLabel);
			if (val.TryGotoNext((MoveType)0, new Func<Instruction, bool>[3]
			{
				(Instruction x) => ILPatternMatchingExt.MatchLdcI4(x, ref num7),
				(Instruction x) => ILPatternMatchingExt.MatchStloc(x, ref num6),
				(Instruction x) => ILPatternMatchingExt.MatchBr(x, ref val2)
			}))
			{
				val.RemoveRange(19);
				val.Emit(OpCodes.Ldarg_0);
				val.EmitDelegate<Action<CharacterSelect>>((Action<CharacterSelect>)delegate(CharacterSelect cs)
				{
					//IL_0012: Unknown result type (might be due to invalid IL or missing references)
					for (int i = 0; i < cs.charactersToPlaceInCircleCount; i++)
					{
						cs.CreateCharacterSelectCharacter(selectableCharactesWithMods[i].characterEnum, i, (CharSelectCharState)1);
					}
				});
			}
			else
			{
				CharacterAPI.logger.LogError((object)"First CharacterSelect::Init hook failed.");
			}
			int num5 = default(int);
			int num4 = default(int);
			if (val.TryGotoNext((MoveType)0, new Func<Instruction, bool>[4]
			{
				(Instruction x) => ILPatternMatchingExt.MatchLdarg(x, ref num5),
				(Instruction x) => ILPatternMatchingExt.MatchLdfld<CharacterSelect>(x, "characterSelectUI"),
				(Instruction x) => ILPatternMatchingExt.MatchLdarg(x, ref num4),
				(Instruction x) => ILPatternMatchingExt.MatchLdfld<CharacterSelect>(x, "selectableCharacters")
			}))
			{
				val.RemoveRange(6);
				val.Emit(OpCodes.Ldarg_0);
				val.EmitDelegate<Action<CharacterSelect>>((Action<CharacterSelect>)delegate(CharacterSelect cs)
				{
					cs.characterSelectUI.SetAvailableCharacterCount(selectableCharactesWithMods.Count);
				});
			}
			else
			{
				CharacterAPI.logger.LogError((object)"Second CharacterSelect::Init hook failed.");
			}
			int num3 = default(int);
			int num2 = default(int);
			int num = default(int);
			if (val.TryGotoNext((MoveType)0, new Func<Instruction, bool>[6]
			{
				(Instruction x) => ILPatternMatchingExt.MatchLdarg(x, ref num3),
				(Instruction x) => ILPatternMatchingExt.MatchLdfld<CharacterSelect>(x, "characterSelectUI"),
				(Instruction x) => ILPatternMatchingExt.MatchLdarg(x, ref num2),
				(Instruction x) => ILPatternMatchingExt.MatchLdfld<CharacterSelect>(x, "selectableCharacters"),
				(Instruction x) => ILPatternMatchingExt.MatchLdarg(x, ref num),
				(Instruction x) => ILPatternMatchingExt.MatchLdfld<CharacterSelect>(x, "selection")
			}))
			{
				val.RemoveRange(8);
				val.Emit(OpCodes.Ldarg_0);
				val.EmitDelegate<Action<CharacterSelect>>((Action<CharacterSelect>)delegate(CharacterSelect cs)
				{
					//IL_0016: Unknown result type (might be due to invalid IL or missing references)
					cs.characterSelectUI.SetCharacterInformation(selectableCharactesWithMods[cs.selection].characterEnum);
				});
			}
			else
			{
				CharacterAPI.logger.LogError((object)"Third CharacterSelect::Init hook failed.");
			}
		}
	}
	public class CharacterSelectUIHooks
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static hook_SetCharacterInformation <0>__CharacterSelectUI_SetCharacterInformation;
		}

		public static void InitHooks()
		{
			//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_001b: Expected O, but got Unknown
			object obj = <>O.<0>__CharacterSelectUI_SetCharacterInformation;
			if (obj == null)
			{
				hook_SetCharacterInformation val = CharacterSelectUI_SetCharacterInformation;
				<>O.<0>__CharacterSelectUI_SetCharacterInformation = val;
				obj = (object)val;
			}
			CharacterSelectUI.SetCharacterInformation += (hook_SetCharacterInformation)obj;
		}

		private static void CharacterSelectUI_SetCharacterInformation(orig_SetCharacterInformation orig, CharacterSelectUI self, Characters character)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: 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_0082: 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)
			if (Enum.IsDefined(typeof(Characters), character))
			{
				orig.Invoke(self, character);
				return;
			}
			ModdedCharacter moddedCharacter = ModdedCharacter.GetModdedCharacter(character);
			if (moddedCharacter != null)
			{
				((TMP_Text)self.characterUnlockedOutfitCountLabel).text = "4/4";
				((TMP_Text)self.characterNameLabel).text = moddedCharacter.Name;
				ModdedCharacterProgress.ModdedCharacterProgressStruct characterProgress = ModdedCharacterProgress.GetCharacterProgress(Core.instance.saveManager.CurrentSaveSlot.saveSlotId, moddedCharacter.GetHashCode());
				if (characterProgress != null)
				{
					self.SetCharacterSelectUIMoveStyle(characterProgress.characterProgress.moveStyle);
				}
				else
				{
					self.SetCharacterSelectUIMoveStyle(moddedCharacter.defaultMoveStyle);
				}
			}
			else
			{
				CharacterAPI.logger.LogWarning((object)$"CharacterSelectUI::SetCharacterInformation failed to setup character information for modded character {character}, replacing it with {(object)(Characters)3}.");
				orig.Invoke(self, (Characters)3);
			}
		}
	}
	public class CharacterVisualHooks
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static hook_GetCharacterFreestyleAnim <0>__CharacterVisual_GetCharacterFreestyleAnim;

			public static hook_GetCharacterBounceAnim <1>__CharacterVisual_GetCharacterBounceAnim;

			public static hook_SetInlineSkatesPropsMode <2>__CharacterVisual_SetInlineSkatesPropsMode;
		}

		public static void InitHooks()
		{
			//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_001b: Expected O, but got Unknown
			//IL_0030: 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_003b: Expected O, but got Unknown
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			object obj = <>O.<0>__CharacterVisual_GetCharacterFreestyleAnim;
			if (obj == null)
			{
				hook_GetCharacterFreestyleAnim val = CharacterVisual_GetCharacterFreestyleAnim;
				<>O.<0>__CharacterVisual_GetCharacterFreestyleAnim = val;
				obj = (object)val;
			}
			CharacterVisual.GetCharacterFreestyleAnim += (hook_GetCharacterFreestyleAnim)obj;
			object obj2 = <>O.<1>__CharacterVisual_GetCharacterBounceAnim;
			if (obj2 == null)
			{
				hook_GetCharacterBounceAnim val2 = CharacterVisual_GetCharacterBounceAnim;
				<>O.<1>__CharacterVisual_GetCharacterBounceAnim = val2;
				obj2 = (object)val2;
			}
			CharacterVisual.GetCharacterBounceAnim += (hook_GetCharacterBounceAnim)obj2;
			object obj3 = <>O.<2>__CharacterVisual_SetInlineSkatesPropsMode;
			if (obj3 == null)
			{
				hook_SetInlineSkatesPropsMode val3 = CharacterVisual_SetInlineSkatesPropsMode;
				<>O.<2>__CharacterVisual_SetInlineSkatesPropsMode = val3;
				obj3 = (object)val3;
			}
			CharacterVisual.SetInlineSkatesPropsMode += (hook_SetInlineSkatesPropsMode)obj3;
		}

		private static void CharacterVisual_SetInlineSkatesPropsMode(orig_SetInlineSkatesPropsMode orig, CharacterVisual self, MoveStylePropMode mode)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Invalid comparison between Unknown and I4
			//IL_0055: 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_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			orig.Invoke(self, mode);
			if ((int)mode == 1)
			{
				Transform val = self.footL.Find("skateOffsetL");
				Transform val2 = self.footR.Find("skateOffsetR");
				if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val2))
				{
					self.moveStyleProps.skateL.transform.SetLocalPositionAndRotation(val.localPosition, val.localRotation);
					self.moveStyleProps.skateL.transform.localScale = val.localScale;
					self.moveStyleProps.skateR.transform.SetLocalPositionAndRotation(val2.localPosition, val2.localRotation);
					self.moveStyleProps.skateR.transform.localScale = val2.localScale;
				}
			}
		}

		private static int CharacterVisual_GetCharacterBounceAnim(orig_GetCharacterBounceAnim orig, Characters c)
		{
			//IL_000a: 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_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			if (Enum.IsDefined(typeof(Characters), c))
			{
				return orig.Invoke(c);
			}
			ModdedCharacter moddedCharacter = ModdedCharacter.GetModdedCharacter(c);
			if (moddedCharacter != null)
			{
				return moddedCharacter.bounceHash;
			}
			CharacterAPI.logger.LogWarning((object)$"CharacterVisual::GetCharacterBounceAnim failed to find modded character {c}, replacing it with {(object)(Characters)3}.");
			return orig.Invoke((Characters)3);
		}

		private static int CharacterVisual_GetCharacterFreestyleAnim(orig_GetCharacterFreestyleAnim orig, Characters c)
		{
			//IL_000a: 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_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: 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)
			if (Enum.IsDefined(typeof(Characters), c))
			{
				return orig.Invoke(c);
			}
			ModdedCharacter moddedCharacter = ModdedCharacter.GetModdedCharacter(c);
			if (moddedCharacter != null)
			{
				return moddedCharacter.freestyleHash;
			}
			CharacterAPI.logger.LogWarning((object)$"CharacterVisual::GetCharacterFreestyleAnim failed to find modded character {c}, replacing it with {(object)(Characters)3}.");
			return orig.Invoke(c);
		}
	}
	public class CoreHooks
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static hook_CreateSubSystems <0>__Core_CreateSubSystems;
		}

		public const string VOICE_BOOST = "_boost";

		public const string VOICE_COMBO = "_combo";

		public const string VOICE_DIE = "_die";

		public const string VOICE_DIEFALL = "_falldamage";

		public const string VOICE_GETHIT = "_gethit";

		public const string VOICE_JUMP = "_jump";

		public const string VOICE_TALK = "_talk";

		internal static AudioClip silence;

		public static void InitHooks()
		{
			//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_001b: Expected O, but got Unknown
			object obj = <>O.<0>__Core_CreateSubSystems;
			if (obj == null)
			{
				hook_CreateSubSystems val = Core_CreateSubSystems;
				<>O.<0>__Core_CreateSubSystems = val;
				obj = (object)val;
			}
			Core.CreateSubSystems += (hook_CreateSubSystems)obj;
		}

		private static void Core_CreateSubSystems(orig_CreateSubSystems orig, Core self)
		{
			orig.Invoke(self);
			foreach (ModdedCharacter moddedCharacter in ModdedCharacter.ModdedCharacters)
			{
				AddModdedCharacterSfx(self, moddedCharacter);
			}
			if (CharacterAPI.PerformSaveCleanUp.Value)
			{
				ModdedCharacterProgress.PerformSaveCleanUp();
			}
		}

		private static void AddModdedCharacterSfx(Core self, ModdedCharacter moddedCharacter)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			if ((int)moddedCharacter.voiceId != -1)
			{
				SfxCollection val = ScriptableObject.CreateInstance<SfxCollection>();
				((Object)val).name = "Voice" + moddedCharacter.Name + "Collection";
				val.audioClipContainers = (RandomAudioClipContainer[])(object)new RandomAudioClipContainer[7];
				val.audioClipContainers[0] = CreateRandomAudioClipContainer((AudioClipID)498, moddedCharacter.audioClips, "_boost");
				val.audioClipContainers[1] = CreateRandomAudioClipContainer((AudioClipID)487, moddedCharacter.audioClips, "_combo");
				val.audioClipContainers[2] = CreateRandomAudioClipContainer((AudioClipID)484, moddedCharacter.audioClips, "_die");
				val.audioClipContainers[3] = CreateRandomAudioClipContainer((AudioClipID)485, moddedCharacter.audioClips, "_falldamage");
				val.audioClipContainers[4] = CreateRandomAudioClipContainer((AudioClipID)488, moddedCharacter.audioClips, "_gethit");
				val.audioClipContainers[5] = CreateRandomAudioClipContainer((AudioClipID)489, moddedCharacter.audioClips, "_jump");
				val.audioClipContainers[6] = CreateRandomAudioClipContainer((AudioClipID)486, moddedCharacter.audioClips, "_talk");
				self.sfxLibrary.sfxCollectionIDDictionary.Add(moddedCharacter.voiceId, val);
			}
		}

		private static RandomAudioClipContainer CreateRandomAudioClipContainer(AudioClipID audioClipID, List<AudioClip> audioClipSourceList, string nameCondition)
		{
			//IL_0033: 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_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Expected O, but got Unknown
			string nameCondition2 = nameCondition;
			List<AudioClip> list = audioClipSourceList.FindAll((AudioClip x) => ((Object)x).name.Contains(nameCondition2));
			if (list.Count == 0)
			{
				list.Add(silence);
			}
			return new RandomAudioClipContainer
			{
				clipID = audioClipID,
				lastRandomClip = 0,
				clips = list.ToArray()
			};
		}
	}
	public class GraffitiArtInfoHooks
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static hook_FindByCharacter <0>__GraffitiArtInfo_FindByCharacter;

			public static hook_FindByTitle <1>__GraffitiArtInfo_FindByTitle;
		}

		public static void InitHooks()
		{
			//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_001b: Expected O, but got Unknown
			//IL_0030: 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_003b: Expected O, but got Unknown
			object obj = <>O.<0>__GraffitiArtInfo_FindByCharacter;
			if (obj == null)
			{
				hook_FindByCharacter val = GraffitiArtInfo_FindByCharacter;
				<>O.<0>__GraffitiArtInfo_FindByCharacter = val;
				obj = (object)val;
			}
			GraffitiArtInfo.FindByCharacter += (hook_FindByCharacter)obj;
			object obj2 = <>O.<1>__GraffitiArtInfo_FindByTitle;
			if (obj2 == null)
			{
				hook_FindByTitle val2 = GraffitiArtInfo_FindByTitle;
				<>O.<1>__GraffitiArtInfo_FindByTitle = val2;
				obj2 = (object)val2;
			}
			GraffitiArtInfo.FindByTitle += (hook_FindByTitle)obj2;
		}

		private static GraffitiArt GraffitiArtInfo_FindByTitle(orig_FindByTitle orig, GraffitiArtInfo self, string grafTitle)
		{
			string grafTitle2 = grafTitle;
			GraffitiArt val = orig.Invoke(self, grafTitle2);
			if (val == null && !string.IsNullOrEmpty(grafTitle2))
			{
				ModdedCharacter moddedCharacter = ModdedCharacter.ModdedCharacters.Find((ModdedCharacter x) => x.personalGrafitti != null && x.personalGrafitti.title.Equals(grafTitle2));
				if (moddedCharacter != null)
				{
					if (moddedCharacter.personalGrafitti != null)
					{
						CharacterAPI.AttemtToFixShaderGraffiti(GetGraffitiLoader(), moddedCharacter.personalGrafitti.graffitiMaterial);
						return moddedCharacter.personalGrafitti;
					}
					return orig.Invoke(self, "Red");
				}
				CharacterAPI.logger.LogWarning((object)("Modded character with graffiti " + grafTitle2 + " doesn't exist, replacing it with graffiti Red."));
				return orig.Invoke(self, "Red");
			}
			return val;
		}

		private static GraffitiArt GraffitiArtInfo_FindByCharacter(orig_FindByCharacter orig, GraffitiArtInfo self, Characters character)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			if (Enum.IsDefined(typeof(Characters), character))
			{
				return orig.Invoke(self, character);
			}
			ModdedCharacter moddedCharacter = ModdedCharacter.GetModdedCharacter(character);
			if (moddedCharacter != null)
			{
				if (moddedCharacter.usePersonalGrafitti)
				{
					GraffitiArt personalGrafitti = moddedCharacter.personalGrafitti;
					CharacterAPI.AttemtToFixShaderGraffiti(GetGraffitiLoader(), personalGrafitti.graffitiMaterial);
					return personalGrafitti;
				}
				return orig.Invoke(self, moddedCharacter.characterGraffitiBase);
			}
			CharacterAPI.logger.LogWarning((object)$"GraffitiArtInfo::FindByCharacter couldn't find graffiti for character {character} because character does not exist, yet character is modded. Replacing graffiti with {(object)(Characters)3}.");
			return orig.Invoke(self, (Characters)3);
		}

		private static GraffitiLoader? GetGraffitiLoader()
		{
			return Core.Instance.assets.GetAssetsLoader<GraffitiLoader>();
		}
	}
	public class OutfitSwitchMenuHooks
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static hook_GetOutfitUnlockable <0>__OutfitSwitchMenu_GetOutfitUnlockable;

			public static Manipulator <1>__OutfitSwitchMenu_SkinButtonClicked;

			public static Manipulator <2>__OutfitSwitchMenu_SkinButtonSelected;
		}

		public static void InitHooks()
		{
			//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_001b: Expected O, but got Unknown
			//IL_0030: 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_003b: Expected O, but got Unknown
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			object obj = <>O.<0>__OutfitSwitchMenu_GetOutfitUnlockable;
			if (obj == null)
			{
				hook_GetOutfitUnlockable val = OutfitSwitchMenu_GetOutfitUnlockable;
				<>O.<0>__OutfitSwitchMenu_GetOutfitUnlockable = val;
				obj = (object)val;
			}
			OutfitSwitchMenu.GetOutfitUnlockable += (hook_GetOutfitUnlockable)obj;
			object obj2 = <>O.<1>__OutfitSwitchMenu_SkinButtonClicked;
			if (obj2 == null)
			{
				Manipulator val2 = OutfitSwitchMenu_SkinButtonClicked;
				<>O.<1>__OutfitSwitchMenu_SkinButtonClicked = val2;
				obj2 = (object)val2;
			}
			OutfitSwitchMenu.SkinButtonClicked += (Manipulator)obj2;
			object obj3 = <>O.<2>__OutfitSwitchMenu_SkinButtonSelected;
			if (obj3 == null)
			{
				Manipulator val3 = OutfitSwitchMenu_SkinButtonSelected;
				<>O.<2>__OutfitSwitchMenu_SkinButtonSelected = val3;
				obj3 = (object)val3;
			}
			OutfitSwitchMenu.SkinButtonSelected += (Manipulator)obj3;
		}

		private static void OutfitSwitchMenu_SkinButtonSelected(ILContext il)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_0095: 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)
			ILCursor val = new ILCursor(il);
			int num = default(int);
			if (val.TryGotoNext((MoveType)0, new Func<Instruction, bool>[3]
			{
				(Instruction x) => ILPatternMatchingExt.MatchLdarg(x, ref num),
				(Instruction x) => ILPatternMatchingExt.MatchLdfld<OutfitSwitchMenu>(x, "player"),
				(Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt<Player>(x, "get_CharacterConstructor")
			}))
			{
				int index = val.Index;
				val.Index = index + 1;
				val.RemoveRange(6);
				val.Emit(OpCodes.Ldloc_0);
				val.Emit(OpCodes.Ldarg_2);
				val.EmitDelegate<Func<OutfitSwitchMenu, int, int, Material>>((Func<OutfitSwitchMenu, int, int, Material>)delegate(OutfitSwitchMenu outfitSwitchMenu, int character, int skinIndex)
				{
					if (Enum.IsDefined(typeof(Characters), (object)(Characters)character))
					{
						return outfitSwitchMenu.player.CharacterConstructor.GetCharacterMaterials()[character, skinIndex];
					}
					ModdedCharacter moddedCharacter = ModdedCharacter.GetModdedCharacter((Characters)character);
					if (moddedCharacter != null)
					{
						Material val2 = moddedCharacter.loadedCharacterMaterials[skinIndex];
						if (Object.op_Implicit((Object)(object)val2) && !moddedCharacter.usesCustomShader)
						{
							CharacterAPI.AttemptToFixShaderCharacter(outfitSwitchMenu.player.characterConstructor.characterLoader, val2);
						}
						return val2;
					}
					CharacterAPI.logger.LogWarning((object)$"OutfitSwitchMenu::SkinButtonSelected failed to find modded character {character}, replacing it with {(object)(Characters)3}.");
					return outfitSwitchMenu.player.CharacterConstructor.GetCharacterMaterials()[3, skinIndex];
				});
			}
			else
			{
				CharacterAPI.logger.LogError((object)"OutfitSwitchMenu::SkinButtonSelected hook failed.");
			}
		}

		private static void OutfitSwitchMenu_SkinButtonClicked(ILContext il)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(il);
			int num = default(int);
			if (val.TryGotoNext((MoveType)0, new Func<Instruction, bool>[4]
			{
				(Instruction x) => ILPatternMatchingExt.MatchLdarg(x, ref num),
				(Instruction x) => ILPatternMatchingExt.MatchLdfld<OutfitSwitchMenu>(x, "player"),
				(Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt<Player>(x, "get_CharacterConstructor"),
				(Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt<CharacterConstructor>(x, "GetCharacterMaterials")
			}))
			{
				int index = val.Index;
				val.Index = index + 1;
				val.RemoveRange(8);
				val.Emit(OpCodes.Ldarg_2);
				val.EmitDelegate<Func<OutfitSwitchMenu, int, bool>>((Func<OutfitSwitchMenu, int, bool>)delegate(OutfitSwitchMenu osm, int skinIndex)
				{
					//IL_0006: Unknown result type (might be due to invalid IL or missing references)
					//IL_000b: Unknown result type (might be due to invalid IL or missing references)
					//IL_0016: 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_0033: Unknown result type (might be due to invalid IL or missing references)
					//IL_003a: Expected I4, but got Unknown
					//IL_0064: Unknown result type (might be due to invalid IL or missing references)
					Characters character = osm.player.character;
					if (Enum.IsDefined(typeof(Characters), character))
					{
						return (Object)(object)osm.player.CharacterConstructor.GetCharacterMaterials()[(int)character, skinIndex] != (Object)null;
					}
					ModdedCharacter moddedCharacter = ModdedCharacter.GetModdedCharacter(character);
					if (moddedCharacter != null)
					{
						return (Object)(object)moddedCharacter.loadedCharacterMaterials[skinIndex] != (Object)null;
					}
					CharacterAPI.logger.LogWarning((object)$"OutfitSwitchMenu::SkinButtonClicked failed to find modded character {character}, replacing it with {(object)(Characters)3}.");
					return (Object)(object)osm.player.CharacterConstructor.GetCharacterMaterials()[3, skinIndex] != (Object)null;
				});
			}
			else
			{
				CharacterAPI.logger.LogError((object)"OutfitSwitchMenu::SkinButtonClicked hook failed.");
			}
		}

		private static OutfitUnlockable OutfitSwitchMenu_GetOutfitUnlockable(orig_GetOutfitUnlockable orig, OutfitUnlockable[] outfitUnlockables, int[] characterIndexMap, int characterIndex, int outfitIndex)
		{
			//IL_0001: 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_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: 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)
			Characters val = (Characters)characterIndex;
			if (Enum.IsDefined(typeof(Characters), val))
			{
				return orig.Invoke(outfitUnlockables, characterIndexMap, characterIndex, outfitIndex);
			}
			ModdedCharacter moddedCharacter = ModdedCharacter.GetModdedCharacter(val);
			if (moddedCharacter != null)
			{
				string text = moddedCharacter.outfitNames[outfitIndex];
				OutfitUnlockable obj = ScriptableObject.CreateInstance<OutfitUnlockable>();
				obj.outfitName = ((text != null) ? text : moddedCharacter.Name);
				obj.character = val;
				obj.outfitIndex = outfitIndex;
				((AUnlockable)obj).IsDefault = true;
				return obj;
			}
			CharacterAPI.logger.LogWarning((object)$"OutfitSwitchMenu::SkinButtonClicked failed to find modded character {val}, replacing it with {(object)(Characters)3}.");
			return orig.Invoke(outfitUnlockables, characterIndexMap, 3, outfitIndex);
		}
	}
	public class PlayerHooks
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static Manipulator <0>__Player_PlayVoice;

			public static hook_SetOutfit <1>__Player_SetOutfit;

			public static Manipulator <2>__Player_Init;
		}

		public static void InitHooks()
		{
			//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_001b: Expected O, but got Unknown
			//IL_0030: 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_003b: Expected O, but got Unknown
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			object obj = <>O.<0>__Player_PlayVoice;
			if (obj == null)
			{
				Manipulator val = Player_PlayVoice;
				<>O.<0>__Player_PlayVoice = val;
				obj = (object)val;
			}
			Player.PlayVoice += (Manipulator)obj;
			object obj2 = <>O.<1>__Player_SetOutfit;
			if (obj2 == null)
			{
				hook_SetOutfit val2 = Player_SetOutfit;
				<>O.<1>__Player_SetOutfit = val2;
				obj2 = (object)val2;
			}
			Player.SetOutfit += (hook_SetOutfit)obj2;
			object obj3 = <>O.<2>__Player_Init;
			if (obj3 == null)
			{
				Manipulator val3 = Player_Init;
				<>O.<2>__Player_Init = val3;
				obj3 = (object)val3;
			}
			Player.Init += (Manipulator)obj3;
		}

		private static void Player_Init(ILContext il)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			ILCursor val = new ILCursor(il);
			int num3 = default(int);
			int num2 = default(int);
			int num = default(int);
			if (val.TryGotoNext((MoveType)0, new Func<Instruction, bool>[4]
			{
				(Instruction x) => ILPatternMatchingExt.MatchLdarg(x, ref num3),
				(Instruction x) => ILPatternMatchingExt.MatchLdarg(x, ref num2),
				(Instruction x) => ILPatternMatchingExt.MatchLdarg(x, ref num),
				(Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt<Player>(x, "SetCharacter")
			}))
			{
				val.Index += 3;
				val.Remove();
				val.EmitDelegate<Action<Player, Characters, int>>((Action<Player, Characters, int>)delegate(Player player, Characters character, int outfit)
				{
					//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
					//IL_0096: Unknown result type (might be due to invalid IL or missing references)
					//IL_006b: Unknown result type (might be due to invalid IL or missing references)
					if (!player.isAI)
					{
						ModdedCharacterProgress.ModdedSaveSlot moddedSaveSlot = ModdedCharacterProgress.GetModdedSaveSlot(Core.Instance.saveManager.CurrentSaveSlot.saveSlotId);
						if (moddedSaveSlot != null)
						{
							ModdedCharacter moddedCharacter = ModdedCharacter.GetModdedCharacter(moddedSaveSlot.lastPlayedCharacter);
							if (moddedCharacter != null)
							{
								CharacterAPI.logger.LogMessage((object)$"Modded character with hash {moddedSaveSlot.lastPlayedCharacter} is {moddedCharacter.Name}, loading as modded chacater.");
								ModdedCharacterProgress.ModdedCharacterProgressStruct moddedCharacterProgress = moddedSaveSlot.GetModdedCharacterProgress(moddedSaveSlot.lastPlayedCharacter);
								player.SetCharacter(moddedCharacter.characterEnum, moddedCharacterProgress.characterProgress.outfit);
								return;
							}
							CharacterAPI.logger.LogMessage((object)$"Modded character with hash {moddedSaveSlot.lastPlayedCharacter} could not be found, loading as {character}.");
						}
					}
					player.SetCharacter(character, outfit);
				});
			}
			else
			{
				CharacterAPI.logger.LogError((object)"Player::Init hook failed.");
			}
		}

		private static void Player_SetOutfit(orig_SetOutfit orig, Player self, int setOutfit)
		{
			orig.Invoke(self, setOutfit);
			ModdedCharacterProgress.Save();
		}

		private static void Player_PlayVoice(ILContext il)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(il);
			int num3 = default(int);
			int num2 = default(int);
			int num = default(int);
			if (val.TryGotoNext((MoveType)0, new Func<Instruction, bool>[7]
			{
				(Instruction x) => ILPatternMatchingExt.MatchLdarg(x, ref num3),
				(Instruction x) => ILPatternMatchingExt.MatchLdfld<Player>(x, "audioManager"),
				(Instruction x) => ILPatternMatchingExt.MatchLdarg(x, ref num2),
				(Instruction x) => ILPatternMatchingExt.MatchLdfld<Player>(x, "audioManager"),
				(Instruction x) => ILPatternMatchingExt.MatchLdfld<AudioManager>(x, "characterToVoiceCollection"),
				(Instruction x) => ILPatternMatchingExt.MatchLdarg(x, ref num),
				(Instruction x) => ILPatternMatchingExt.MatchLdfld<Player>(x, "character")
			}))
			{
				int index = val.Index;
				val.Index = index + 1;
				val.RemoveRange(10);
				val.Emit(OpCodes.Ldarg_1);
				val.EmitDelegate<Action<Player, AudioClipID>>((Action<Player, AudioClipID>)delegate(Player p, AudioClipID aci)
				{
					//IL_000b: 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_002e: 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_009f: 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_0050: Unknown result type (might be due to invalid IL or missing references)
					//IL_0056: Invalid comparison between Unknown and I4
					//IL_0082: 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_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)
					if (Enum.IsDefined(typeof(Characters), p.character))
					{
						p.audioManager.PlaySfxGameplay(p.audioManager.characterToVoiceCollection[p.character], aci, 0f);
					}
					else
					{
						ModdedCharacter moddedCharacter = ModdedCharacter.GetModdedCharacter(p.character);
						if (moddedCharacter != null)
						{
							if ((int)moddedCharacter.voiceId != -1)
							{
								p.audioManager.PlaySfxGameplay(moddedCharacter.voiceId, aci, 0f);
							}
							else
							{
								p.audioManager.PlaySfxGameplay(p.audioManager.characterToVoiceCollection[moddedCharacter.characterVoiceBase], aci, 0f);
							}
						}
						else
						{
							CharacterAPI.logger.LogWarning((object)$"Player::PlayVoice couldn't find modded character {p.character}, replacing with {(object)(Characters)3}.");
							p.audioManager.PlaySfxGameplay(p.audioManager.characterToVoiceCollection[3], aci, 0f);
						}
					}
				});
			}
			else
			{
				CharacterAPI.logger.LogError((object)"Player::PlayVoice hook failed.");
			}
		}
	}
	public class SaveSlotDataHooks
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static hook_GetCharacterProgress <0>__SaveSlotData_GetCharacterProgress;

			public static hook_Read <1>__SaveSlotData_Read;

			public static Manipulator <2>__SaveSlotData_Write;
		}

		public static void InitHooks()
		{
			//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_001b: Expected O, but got Unknown
			//IL_0030: 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_003b: Expected O, but got Unknown
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			object obj = <>O.<0>__SaveSlotData_GetCharacterProgress;
			if (obj == null)
			{
				hook_GetCharacterProgress val = SaveSlotData_GetCharacterProgress;
				<>O.<0>__SaveSlotData_GetCharacterProgress = val;
				obj = (object)val;
			}
			SaveSlotData.GetCharacterProgress += (hook_GetCharacterProgress)obj;
			object obj2 = <>O.<1>__SaveSlotData_Read;
			if (obj2 == null)
			{
				hook_Read val2 = SaveSlotData_Read;
				<>O.<1>__SaveSlotData_Read = val2;
				obj2 = (object)val2;
			}
			SaveSlotData.Read += (hook_Read)obj2;
			object obj3 = <>O.<2>__SaveSlotData_Write;
			if (obj3 == null)
			{
				Manipulator val3 = SaveSlotData_Write;
				<>O.<2>__SaveSlotData_Write = val3;
				obj3 = (object)val3;
			}
			SaveSlotData.Write += (Manipulator)obj3;
		}

		private static void SaveSlotData_Write(ILContext il)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			ILCursor val = new ILCursor(il);
			int num2 = default(int);
			int num = default(int);
			if (val.TryGotoNext((MoveType)0, new Func<Instruction, bool>[3]
			{
				(Instruction x) => ILPatternMatchingExt.MatchLdarg(x, ref num2),
				(Instruction x) => ILPatternMatchingExt.MatchLdarg(x, ref num),
				(Instruction x) => ILPatternMatchingExt.MatchLdflda<SaveSlotData>(x, "currentCharacter")
			}))
			{
				val.Index += 2;
				val.RemoveRange(4);
				val.EmitDelegate<Action<BinaryWriter, SaveSlotData>>((Action<BinaryWriter, SaveSlotData>)delegate(BinaryWriter bw, SaveSlotData ssd)
				{
					//IL_0001: Unknown result type (might be due to invalid IL or missing references)
					//IL_0006: Unknown result type (might be due to invalid IL or missing references)
					//IL_0011: 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)
					Characters currentCharacter = ssd.currentCharacter;
					if (Enum.IsDefined(typeof(Characters), currentCharacter))
					{
						bw.Write(((object)(Characters)(ref currentCharacter)).ToString());
					}
					else
					{
						Characters val2 = (Characters)3;
						bw.Write(((object)(Characters)(ref val2)).ToString());
					}
				});
			}
			else
			{
				CharacterAPI.logger.LogError((object)"SaveSlotData::Write hook failed.");
			}
		}

		private static void SaveSlotData_Read(orig_Read orig, SaveSlotData self, BinaryReader reader)
		{
			//IL_0013: 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)
			orig.Invoke(self, reader);
			if (!Enum.IsDefined(typeof(Characters), self.curr