Decompiled source of ModelSwapperSkins v1.6.0

plugins/ModelSwapperSkins/ModelSwapperSkins.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Logging;
using HG;
using HG.Coroutines;
using HG.Reflection;
using HarmonyLib;
using IL.RoR2;
using IL.RoR2.UI;
using Microsoft.CodeAnalysis;
using ModelSwapperSkins.BoneMapping;
using ModelSwapperSkins.BoneMapping.InitializerRules;
using ModelSwapperSkins.ModCompatibility;
using ModelSwapperSkins.ModelInfos;
using ModelSwapperSkins.ModelParts;
using ModelSwapperSkins.Utils;
using ModelSwapperSkins.Utils.Comparers;
using ModelSwapperSkins.Utils.Extensions;
using Mono.Cecil;
using Mono.Cecil.Cil;
using Mono.Cecil.Rocks;
using MonoMod.Cil;
using MonoMod.RuntimeDetour;
using MonoMod.Utils;
using On.RoR2;
using On.RoR2.UI;
using R2API.Utils;
using RoR2;
using RoR2.ContentManagement;
using RoR2.EntityLogic;
using RoR2.UI;
using RoR2BepInExPack.GameAssetPaths;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Events;
using UnityEngine.ResourceManagement.AsyncOperations;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: OptIn]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("ModelSwapperSkins")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+17d110deac87142fca65cffb0b2397566b5f8d75")]
[assembly: AssemblyProduct("ModelSwapperSkins")]
[assembly: AssemblyTitle("ModelSwapperSkins")]
[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;
		}
	}
	internal static class IsExternalInit
	{
	}
}
namespace ModelSwapperSkins
{
	public class AdditionalRendererInfoProvider : MonoBehaviour
	{
		public Material[] AdditionalMaterials = Array.Empty<Material>();

		public static void AddMaterials(Renderer renderer, Material[] additionalMaterials)
		{
			ArrayUtil.Append(ref UnityObjectExtensions.EnsureComponent<AdditionalRendererInfoProvider>(((Component)renderer).gameObject).AdditionalMaterials, additionalMaterials);
		}
	}
	public static class BodyIconCache
	{
		private record IconKey(Texture2D bodyPortrait);

		private static readonly Dictionary<IconKey, Sprite> _cachedIcons = new Dictionary<IconKey, Sprite>();

		public static Sprite GetOrCreatePortraitIcon(Texture2D bodyPortrait)
		{
			IconKey key = new IconKey(bodyPortrait);
			if (_cachedIcons.TryGetValue(key, out var value))
			{
				return value;
			}
			Sprite val = generateSkinIcon(bodyPortrait);
			_cachedIcons.Add(key, val);
			return val;
		}

		private static Sprite generateSkinIcon(Texture2D bodyPortrait)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			Sprite obj = Sprite.Create(bodyPortrait, new Rect(0f, 0f, (float)((Texture)bodyPortrait).width, (float)((Texture)bodyPortrait).height), Vector2.zero);
			((Object)obj).name = ((Object)bodyPortrait).name;
			return obj;
		}
	}
	public class BodySkinsInitializer
	{
		[StructLayout(LayoutKind.Auto)]
		[CompilerGenerated]
		private struct <>c__DisplayClass10_0
		{
			public BodySkinsInitializer <>4__this;

			public CharacterBody body;

			public Transform modelTransform;

			public ModelPartsProvider bodyModelPartsProvider;
		}

		[CompilerGenerated]
		private sealed class <createSkinsForBody>d__10 : IEnumerable<ModelSwappedSkinDef>, IEnumerable, IEnumerator<ModelSwappedSkinDef>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private ModelSwappedSkinDef <>2__current;

			private int <>l__initialThreadId;

			public BodySkinsInitializer <>4__this;

			private CharacterBody body;

			public CharacterBody <>3__body;

			private <>c__DisplayClass10_0 <>8__1;

			private ModelSkinController <modelSkinController>5__2;

			private SkinDef[] <>7__wrap2;

			private int <>7__wrap3;

			private SkinDef <bodySkin>5__5;

			private IEnumerator<SkinDef> <>7__wrap5;

			ModelSwappedSkinDef IEnumerator<ModelSwappedSkinDef>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <createSkinsForBody>d__10(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if (num == -3 || num == 1)
				{
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<>8__1 = default(<>c__DisplayClass10_0);
				<modelSkinController>5__2 = null;
				<>7__wrap2 = null;
				<bodySkin>5__5 = null;
				<>7__wrap5 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				try
				{
					int num = <>1__state;
					BodySkinsInitializer bodySkinsInitializer = <>4__this;
					switch (num)
					{
					default:
						return false;
					case 0:
					{
						<>1__state = -1;
						<>8__1.<>4__this = <>4__this;
						<>8__1.body = body;
						ModelLocator component = ((Component)<>8__1.body).GetComponent<ModelLocator>();
						<>8__1.modelTransform = component.modelTransform;
						<>8__1.bodyModelPartsProvider = ((Component)<>8__1.modelTransform).GetComponent<ModelPartsProvider>();
						SkinDef[] array = (Object.op_Implicit((Object)(object)bodySkinsInitializer._bodySkinController) ? bodySkinsInitializer._bodySkinController.skins : null);
						if (array == null || array.Length == 0)
						{
							array = (SkinDef[])(object)new SkinDef[1];
						}
						<modelSkinController>5__2 = ((Component)<>8__1.modelTransform).GetComponent<ModelSkinController>();
						<>7__wrap2 = array;
						<>7__wrap3 = 0;
						goto IL_01f2;
					}
					case 1:
						<>1__state = -3;
						goto IL_0196;
					case 2:
						{
							<>1__state = -1;
							<bodySkin>5__5 = null;
							goto IL_01e4;
						}
						IL_01e4:
						<>7__wrap3++;
						goto IL_01f2;
						IL_01f2:
						if (<>7__wrap3 < <>7__wrap2.Length)
						{
							<bodySkin>5__5 = <>7__wrap2[<>7__wrap3];
							if (Object.op_Implicit((Object)(object)<modelSkinController>5__2))
							{
								IEnumerable<SkinDef> enumerable = <modelSkinController>5__2.skins.Where((SkinDef s) => !(s is ModelSwappedSkinDef));
								if (enumerable.Any())
								{
									<>7__wrap5 = enumerable.GetEnumerator();
									<>1__state = -3;
									goto IL_0196;
								}
							}
							<>2__current = bodySkinsInitializer.<createSkinsForBody>g__createSkinDef|10_0(<bodySkin>5__5, null, ref <>8__1);
							<>1__state = 2;
							return true;
						}
						<>7__wrap2 = null;
						return false;
						IL_0196:
						if (<>7__wrap5.MoveNext())
						{
							SkinDef current = <>7__wrap5.Current;
							<>2__current = bodySkinsInitializer.<createSkinsForBody>g__createSkinDef|10_0(<bodySkin>5__5, current, ref <>8__1);
							<>1__state = 1;
							return true;
						}
						<>m__Finally1();
						<>7__wrap5 = null;
						goto IL_01e4;
					}
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			private void <>m__Finally1()
			{
				<>1__state = -1;
				if (<>7__wrap5 != null)
				{
					<>7__wrap5.Dispose();
				}
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}

			[DebuggerHidden]
			IEnumerator<ModelSwappedSkinDef> IEnumerable<ModelSwappedSkinDef>.GetEnumerator()
			{
				<createSkinsForBody>d__10 <createSkinsForBody>d__;
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					<createSkinsForBody>d__ = this;
				}
				else
				{
					<createSkinsForBody>d__ = new <createSkinsForBody>d__10(0)
					{
						<>4__this = <>4__this
					};
				}
				<createSkinsForBody>d__.body = <>3__body;
				return <createSkinsForBody>d__;
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<ModelSwappedSkinDef>)this).GetEnumerator();
			}
		}

		private readonly CharacterBody _bodyPrefab;

		private readonly ModelPartsProvider _bodyPartsProvider;

		private readonly BonesProvider _bodyBonesProvider;

		private readonly ModelSkinController _bodySkinController;

		private readonly HashSet<Transform> _usedModelTransforms = new HashSet<Transform>();

		public BodySkinsInitializer(CharacterBody bodyPrefab)
		{
			_bodyPrefab = bodyPrefab;
			ModelLocator val = default(ModelLocator);
			if (Object.op_Implicit((Object)(object)_bodyPrefab) && ((Component)_bodyPrefab).TryGetComponent<ModelLocator>(ref val))
			{
				Transform modelTransform = val.modelTransform;
				if (Object.op_Implicit((Object)(object)modelTransform))
				{
					_bodyPartsProvider = ((Component)modelTransform).GetComponent<ModelPartsProvider>();
					_bodyBonesProvider = ((Component)modelTransform).GetComponent<BonesProvider>();
					_bodySkinController = ((Component)modelTransform).GetComponent<ModelSkinController>();
				}
			}
		}

		private bool isSurvivorValidForSkins()
		{
			if (Object.op_Implicit((Object)(object)_bodyPrefab) && Object.op_Implicit((Object)(object)_bodyPartsProvider))
			{
				return Object.op_Implicit((Object)(object)_bodyBonesProvider);
			}
			return false;
		}

		public void TryCreateSkins(List<SkinDef> dest)
		{
			if (!isSurvivorValidForSkins())
			{
				return;
			}
			_usedModelTransforms.Clear();
			List<CharacterBody> list = BodyCatalog.allBodyPrefabBodyBodyComponents.ToList();
			list.Sort(delegate(CharacterBody a, CharacterBody b)
			{
				string sortName = getSortName(a);
				string sortName2 = getSortName(b);
				return sortName.CompareTo(sortName2);
			});
			foreach (CharacterBody item in list)
			{
				if (shouldCreateSkin(item))
				{
					dest.AddRange((IEnumerable<SkinDef>)createSkinsForBody(item));
				}
			}
			static string getSortName(CharacterBody body)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				return BodyCatalog.GetBodyName(body.bodyIndex) switch
				{
					"ScavLunar1Body" => "ScavengerLunar1", 
					"ScavLunar2Body" => "ScavengerLunar2", 
					"ScavLunar3Body" => "ScavengerLunar3", 
					"ScavLunar4Body" => "ScavengerLunar4", 
					_ => sanitizeName(Language.GetString(body.baseNameToken, "en")), 
				};
			}
			static string sanitizeName(string input)
			{
				StringBuilder stringBuilder = StringBuilderPool.RentStringBuilder();
				stringBuilder.EnsureCapacity(input.Length);
				string text = input;
				foreach (char c in text)
				{
					if (c <= '\u007f')
					{
						stringBuilder.Append(c);
					}
				}
				if (stringBuilder.Length > 0 && stringBuilder.Length < input.Length)
				{
					input = stringBuilder.ToString();
				}
				StringBuilderPool.ReturnStringBuilder(stringBuilder);
				return input;
			}
		}

		private bool hasEnoughBonesToMatchWith(BonesProvider otherBonesProvider)
		{
			if (anyBonesValidMatch(new BoneType[4]
			{
				BoneType.Head,
				BoneType.Chest,
				BoneType.Stomach,
				BoneType.Pelvis
			}))
			{
				if (!anyBonesValidMatch(new BoneType[4]
				{
					BoneType.ArmUpperL,
					BoneType.ArmLowerL,
					BoneType.ArmUpperR,
					BoneType.ArmLowerR
				}))
				{
					return anyBonesValidMatch(new BoneType[4]
					{
						BoneType.LegUpperL,
						BoneType.LegLowerL,
						BoneType.LegUpperR,
						BoneType.LegLowerR
					});
				}
				return true;
			}
			return false;
			bool anyBonesValidMatch(BoneType[] bones)
			{
				return Array.Exists(bones, boneTest);
			}
			bool boneTest(BoneType bone)
			{
				if (_bodyBonesProvider.HasMatchForBone(bone))
				{
					return otherBonesProvider.CanMatchToBone(bone);
				}
				return false;
			}
		}

		private bool shouldCreateSkin(CharacterBody body)
		{
			if (!Object.op_Implicit((Object)(object)body))
			{
				return false;
			}
			if ((Object)(object)body == (Object)(object)_bodyPrefab)
			{
				return false;
			}
			ModelLocator component = ((Component)body).GetComponent<ModelLocator>();
			if (!Object.op_Implicit((Object)(object)component))
			{
				return false;
			}
			Transform modelTransform = component.modelTransform;
			if (!Object.op_Implicit((Object)(object)modelTransform) || modelTransform.childCount == 0)
			{
				return false;
			}
			if (!Object.op_Implicit((Object)(object)((Component)modelTransform).GetComponent<ModelPartsProvider>()))
			{
				return false;
			}
			BonesProvider component2 = ((Component)modelTransform).GetComponent<BonesProvider>();
			if (!Object.op_Implicit((Object)(object)component2))
			{
				return false;
			}
			if (!hasEnoughBonesToMatchWith(component2))
			{
				return false;
			}
			if (!_usedModelTransforms.Add(modelTransform))
			{
				return false;
			}
			return true;
		}

		[IteratorStateMachine(typeof(<createSkinsForBody>d__10))]
		private IEnumerable<ModelSwappedSkinDef> createSkinsForBody(CharacterBody body)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <createSkinsForBody>d__10(-2)
			{
				<>4__this = this,
				<>3__body = body
			};
		}

		[CompilerGenerated]
		private ModelSwappedSkinDef <createSkinsForBody>g__createSkinDef|10_0(SkinDef baseSkin, SkinDef modelSkin, ref <>c__DisplayClass10_0 P_2)
		{
			ModelSwappedSkinDef modelSwappedSkinDef = ScriptableObject.CreateInstance<ModelSwappedSkinDef>();
			StringBuilder stringBuilder = StringBuilderPool.RentStringBuilder();
			stringBuilder.Append("skin").Append(((Object)_bodyPrefab).name);
			if (Object.op_Implicit((Object)(object)baseSkin))
			{
				stringBuilder.Append('_').Append(((Object)baseSkin).name);
			}
			stringBuilder.Append('_').Append(((Object)P_2.body).name);
			if (Object.op_Implicit((Object)(object)modelSkin))
			{
				stringBuilder.Append('_').Append(((Object)modelSkin).name);
			}
			string text2 = (((Object)modelSwappedSkinDef).name = stringBuilder.ToString());
			((SkinDef)modelSwappedSkinDef).nameToken = text2.ToUpper();
			stringBuilder = StringBuilderPool.ReturnStringBuilder(stringBuilder);
			ref Sprite icon = ref ((SkinDef)modelSwappedSkinDef).icon;
			Texture portraitIcon = P_2.body.portraitIcon;
			icon = BodyIconCache.GetOrCreatePortraitIcon((Texture2D)(object)((portraitIcon is Texture2D) ? portraitIcon : null));
			if (Object.op_Implicit((Object)(object)baseSkin))
			{
				((SkinDef)modelSwappedSkinDef).baseSkins = (SkinDef[])(object)new SkinDef[1] { baseSkin };
			}
			modelSwappedSkinDef.NewModelBodyPrefab = P_2.body;
			modelSwappedSkinDef.NewModelTransformPrefab = P_2.modelTransform;
			modelSwappedSkinDef.ModelSkin = modelSkin;
			UnlockableDef unlockableDef = null;
			if (Object.op_Implicit((Object)(object)modelSkin) && Object.op_Implicit((Object)(object)modelSkin.unlockableDef))
			{
				unlockableDef = modelSkin.unlockableDef;
			}
			else if (Object.op_Implicit((Object)(object)baseSkin) && Object.op_Implicit((Object)(object)baseSkin.unlockableDef))
			{
				unlockableDef = baseSkin.unlockableDef;
			}
			((SkinDef)modelSwappedSkinDef).unlockableDef = unlockableDef;
			SkinDefParams val = ScriptableObject.CreateInstance<SkinDefParams>();
			((Object)val).name = ((Object)modelSwappedSkinDef).name + "_params";
			((SkinDef)modelSwappedSkinDef).skinDefParams = val;
			((SkinDef)modelSwappedSkinDef).optimizedSkinDefParams = val;
			modelSwappedSkinDef.Initialize(_bodyPartsProvider, P_2.bodyModelPartsProvider);
			return modelSwappedSkinDef;
		}
	}
	public static class DynamicSkinAdder
	{
		public delegate void AddSkinDelegate(CharacterBody bodyPrefab, List<SkinDef> skins);

		private const bool AllowNonSurvivorSkinAdditions = false;

		public static event AddSkinDelegate AddSkins;

		[SystemInitializer(new Type[]
		{
			typeof(SurvivorCatalog),
			typeof(BodyCatalog),
			typeof(ModelPartsInitializer),
			typeof(BoneInitializer)
		})]
		private static void Init()
		{
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Invalid comparison between Unknown and I4
			if (SkinCatalog.skinCount > 0)
			{
				Log.Error("SkinCatalog already initialized", "X:\\Git\\RoR2\\ModelSwapperSkins\\ModelSwapperSkins\\DynamicSkinAdder.cs", "Init", 31);
			}
			HashSet<CharacterBody> hashSet = new HashSet<CharacterBody>();
			foreach (CharacterBody allBodyPrefabBodyBodyComponent in BodyCatalog.allBodyPrefabBodyBodyComponents)
			{
				try
				{
					addDefaultSkinIfMissing(allBodyPrefabBodyBodyComponent);
				}
				catch (Exception arg)
				{
					Log.Error_NoCallerPrefix($"Failed to generate default skin for {((Object)allBodyPrefabBodyBodyComponent).name}: {arg}");
					hashSet.Add(allBodyPrefabBodyBodyComponent);
				}
			}
			foreach (CharacterBody allBodyPrefabBodyBodyComponent2 in BodyCatalog.allBodyPrefabBodyBodyComponents)
			{
				if (!hashSet.Contains(allBodyPrefabBodyBodyComponent2) && (int)SurvivorCatalog.GetSurvivorIndexFromBodyIndex(allBodyPrefabBodyBodyComponent2.bodyIndex) != -1)
				{
					addSkinsTo(allBodyPrefabBodyBodyComponent2);
				}
			}
		}

		private static void addSkinsTo(CharacterBody body)
		{
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Invalid comparison between Unknown and I4
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)body))
			{
				return;
			}
			ModelLocator component = ((Component)body).GetComponent<ModelLocator>();
			if (!Object.op_Implicit((Object)(object)component))
			{
				return;
			}
			Transform modelTransform = component.modelTransform;
			if (!Object.op_Implicit((Object)(object)modelTransform))
			{
				return;
			}
			List<SkinDef> list = new List<SkinDef>();
			ModelSkinController component2 = ((Component)modelTransform).GetComponent<ModelSkinController>();
			if (!Object.op_Implicit((Object)(object)component2))
			{
				Log.Warning(((Object)body).name + " model is missing ModelSkinController", "X:\\Git\\RoR2\\ModelSwapperSkins\\ModelSwapperSkins\\DynamicSkinAdder.cs", "addSkinsTo", 86);
				return;
			}
			try
			{
				DynamicSkinAdder.AddSkins?.Invoke(body, list);
			}
			catch (Exception arg)
			{
				Log.Error_NoCallerPrefix($"Failed to generate skins for {((Object)body).name}: {arg}");
				return;
			}
			if (list.Count > 0)
			{
				for (int i = 0; i < list.Count; i++)
				{
					if (!Object.op_Implicit((Object)(object)list[i].rootObject))
					{
						list[i].rootObject = ((Component)modelTransform).gameObject;
					}
				}
				ArrayUtil.Append(ref component2.skins, list);
				SurvivorDef val = SurvivorCatalog.FindSurvivorDefFromBody(((Component)body).gameObject);
				if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val.displayPrefab))
				{
					ArrayUtil.Append(ref UnityObjectExtensions.EnsureComponent<ModelSkinController>(((Component)val.displayPrefab.GetComponentInChildren<CharacterModel>()).gameObject).skins, list);
				}
				BodyIndex bodyIndex = body.bodyIndex;
				if ((int)bodyIndex != -1)
				{
					SkinDef[][] skinsByBody = SkinCatalog.skinsByBody;
					if ((long)(ulong)bodyIndex < (long)skinsByBody.Length)
					{
						ArrayUtil.Append(ref skinsByBody[bodyIndex], list);
					}
				}
			}
			Log.Info_NoCallerPrefix($"Created {list.Count} skin(s) for {((Object)body).name}");
		}

		private static void addDefaultSkinIfMissing(CharacterBody bodyPrefab)
		{
			//IL_0331: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03be: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_055d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0562: Unknown result type (might be due to invalid IL or missing references)
			//IL_0564: Unknown result type (might be due to invalid IL or missing references)
			//IL_0567: Invalid comparison between Unknown and I4
			//IL_0570: Unknown result type (might be due to invalid IL or missing references)
			//IL_043c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0464: Unknown result type (might be due to invalid IL or missing references)
			//IL_0469: Unknown result type (might be due to invalid IL or missing references)
			//IL_048a: Unknown result type (might be due to invalid IL or missing references)
			//IL_048c: Unknown result type (might be due to invalid IL or missing references)
			//IL_057c: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			SurvivorDef val = SurvivorCatalog.FindSurvivorDefFromBody(((Component)bodyPrefab).gameObject);
			ModelLocator component = ((Component)bodyPrefab).GetComponent<ModelLocator>();
			if (!Object.op_Implicit((Object)(object)component))
			{
				return;
			}
			Transform modelTransform = component.modelTransform;
			if (!Object.op_Implicit((Object)(object)modelTransform))
			{
				return;
			}
			CharacterModel component2 = ((Component)modelTransform).GetComponent<CharacterModel>();
			if (!Object.op_Implicit((Object)(object)component2))
			{
				return;
			}
			ModelPartsProvider modelPartsProvider = default(ModelPartsProvider);
			ModelPart[] array = ((!((Component)modelTransform).TryGetComponent<ModelPartsProvider>(ref modelPartsProvider)) ? Array.Empty<ModelPart>() : modelPartsProvider.Parts);
			ModelSkinController val2 = default(ModelSkinController);
			if (((Component)modelTransform).TryGetComponent<ModelSkinController>(ref val2))
			{
				SkinDef[] skins = val2.skins;
				foreach (SkinDef val3 in skins)
				{
					if ((Object)(object)val3.rootObject != (Object)(object)((Component)modelTransform).gameObject)
					{
						Log.Warning("Incorrect skin root object for " + ((Object)val3).name + " on " + ((Object)bodyPrefab).name, "X:\\Git\\RoR2\\ModelSwapperSkins\\ModelSwapperSkins\\DynamicSkinAdder.cs", "addDefaultSkinIfMissing", 169);
						continue;
					}
					SkinDefParams val4 = val3.GetSkinParams().ReferenceOrDirect<SkinDefParams>().WaitForCompletion();
					List<GameObjectActivation> list;
					if (Object.op_Implicit((Object)(object)val4))
					{
						list = val4.gameObjectActivations.ToList();
					}
					else
					{
						GameObjectActivation[] gameObjectActivations = val3.gameObjectActivations;
						List<GameObjectActivation> list2 = new List<GameObjectActivation>(gameObjectActivations.Length);
						GameObjectActivation[] array2 = gameObjectActivations;
						foreach (GameObjectActivation val5 in array2)
						{
							list2.Add(GameObjectActivation.op_Implicit(val5));
						}
						list = list2;
					}
					bool flag = false;
					ModelPart[] array3 = array;
					foreach (ModelPart modelPart in array3)
					{
						bool flag2 = false;
						foreach (GameObjectActivation item in list)
						{
							if (Util.BuildPrefabTransformPath(val3.rootObject.transform, item.gameObject.transform, false, false) == modelPart.Path)
							{
								flag2 = true;
								break;
							}
						}
						if (!flag2)
						{
							Transform val6 = val3.rootObject.transform.Find(modelPart.Path);
							if (Object.op_Implicit((Object)(object)val6))
							{
								list.Add(new GameObjectActivation
								{
									gameObject = ((Component)val6).gameObject,
									shouldActivate = ((Component)val6).gameObject.activeSelf
								});
								flag = true;
							}
						}
					}
					if (!flag)
					{
						continue;
					}
					if (Object.op_Implicit((Object)(object)val4))
					{
						val4.gameObjectActivations = list.ToArray();
					}
					else
					{
						val3.gameObjectActivations = list.Select(delegate(GameObjectActivation g)
						{
							//IL_0002: Unknown result type (might be due to invalid IL or missing references)
							//IL_000a: Unknown result type (might be due to invalid IL or missing references)
							//IL_0017: Unknown result type (might be due to invalid IL or missing references)
							//IL_0022: Unknown result type (might be due to invalid IL or missing references)
							GameObjectActivation result2 = default(GameObjectActivation);
							result2.gameObject = g.gameObject;
							result2.shouldActivate = g.shouldActivate;
							return result2;
						}).ToArray();
					}
					val3._runtimeSkin = null;
				}
			}
			else
			{
				val2 = ((Component)modelTransform).gameObject.AddComponent<ModelSkinController>();
				SkinDef val7 = ScriptableObject.CreateInstance<SkinDef>();
				string text2 = (((Object)val7).name = "skin" + ((Object)bodyPrefab).name + "Default");
				val7.nameToken = text2.ToUpper();
				val7.rootObject = ((Component)modelTransform).gameObject;
				val7.baseSkins = Array.Empty<SkinDef>();
				SkinDefParams val8 = ScriptableObject.CreateInstance<SkinDefParams>();
				((Object)val8).name = ((Object)val7).name + "_params";
				val7.skinDefParams = val8;
				val7.optimizedSkinDefParams = val8;
				List<RendererInfo> list3 = component2.baseRendererInfos.ToList();
				for (int num = list3.Count - 1; num >= 0; num--)
				{
					Renderer renderer2 = list3[num].renderer;
					if (!Object.op_Implicit((Object)(object)renderer2) || !((Component)renderer2).transform.IsChildOf(val7.rootObject.transform))
					{
						list3.RemoveAt(num);
					}
				}
				List<MeshReplacement> list4 = new List<MeshReplacement>();
				SkinnedMeshRenderer[] componentsInChildren = ((Component)modelTransform).GetComponentsInChildren<SkinnedMeshRenderer>();
				foreach (SkinnedMeshRenderer val9 in componentsInChildren)
				{
					if (Object.op_Implicit((Object)(object)val9.sharedMesh))
					{
						list4.Add(new MeshReplacement
						{
							renderer = (Renderer)(object)val9,
							mesh = val9.sharedMesh
						});
					}
				}
				ModelPart[] array3 = array;
				Renderer renderer = default(Renderer);
				foreach (ModelPart modelPart2 in array3)
				{
					if (!modelPart2.RendererInfo.HasValue || !((Component)modelPart2.Transform).TryGetComponent<Renderer>(ref renderer))
					{
						continue;
					}
					Material[] sharedMaterials = renderer.sharedMaterials;
					if (sharedMaterials.Length != 0)
					{
						ModelPartRendererInfo value = modelPart2.RendererInfo.Value;
						RendererInfo val10 = default(RendererInfo);
						val10.renderer = renderer;
						val10.defaultMaterial = sharedMaterials[0];
						val10.defaultShadowCastingMode = renderer.shadowCastingMode;
						val10.ignoreOverlays = value.IgnoreOverlays;
						val10.hideOnDeath = value.HideOnDeath;
						RendererInfo val11 = val10;
						int num2 = list3.FindIndex((RendererInfo r) => (Object)(object)r.renderer == (Object)(object)renderer);
						if (num2 < 0)
						{
							list3.Add(val11);
						}
						else
						{
							list3[num2] = val11;
						}
						if (sharedMaterials.Length > 1)
						{
							Material[] array4 = (Material[])(object)new Material[sharedMaterials.Length - 1];
							Array.Copy(sharedMaterials, 1, array4, 0, array4.Length);
							AdditionalRendererInfoProvider.AddMaterials(renderer, array4);
						}
					}
				}
				val8.rendererInfos = list3.ToArray();
				val8.meshReplacements = list4.ToArray();
				val8.gameObjectActivations = Array.ConvertAll(array, delegate(ModelPart p)
				{
					//IL_0002: Unknown result type (might be due to invalid IL or missing references)
					//IL_0031: Unknown result type (might be due to invalid IL or missing references)
					GameObjectActivation result = default(GameObjectActivation);
					result.gameObject = ((Component)p.Transform).gameObject;
					result.shouldActivate = ((Component)p.Transform).gameObject.activeSelf;
					return result;
				});
				val2.skins = (SkinDef[])(object)new SkinDef[1] { val7 };
				BodyIndex bodyIndex = bodyPrefab.bodyIndex;
				if ((int)bodyIndex != -1)
				{
					SkinDef[][] skinsByBody = SkinCatalog.skinsByBody;
					if ((long)(ulong)bodyIndex < (long)skinsByBody.Length)
					{
						ArrayUtils.ArrayAppend<SkinDef>(ref skinsByBody[bodyIndex], ref val7);
					}
				}
			}
			if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val.displayPrefab))
			{
				CharacterModel componentInChildren = val.displayPrefab.GetComponentInChildren<CharacterModel>();
				if (Object.op_Implicit((Object)(object)componentInChildren))
				{
					UnityObjectExtensions.EnsureComponent<ModelSkinController>(((Component)componentInChildren).gameObject).skins = val2.skins;
				}
			}
		}
	}
	internal static class LanguageFolderHandler
	{
		public static void Register(string searchFolder, string langFolderName = "lang")
		{
			string langFolderPath = Path.Combine(searchFolder, langFolderName);
			if (Directory.Exists(langFolderPath))
			{
				Language.collectLanguageRootFolders += delegate(List<string> folders)
				{
					folders.Add(langFolderPath);
				};
			}
			else
			{
				Log.Error("Lang folder not found: " + langFolderPath, "X:\\Git\\RoR2\\ModelSwapperSkins\\ModelSwapperSkins\\LanguageFolderHandler.cs", "Register", 21);
			}
		}
	}
	internal static class Log
	{
		private static readonly StringBuilder _sharedStringBuilder;

		private static readonly int _cachedCallerPathPrefixLength;

		private static ManualLogSource _logSource;

		static Log()
		{
			_sharedStringBuilder = new StringBuilder(256);
			_cachedCallerPathPrefixLength = getCallerPathPrefixLength("X:\\Git\\RoR2\\ModelSwapperSkins\\ModelSwapperSkins\\Log.cs");
			static int getCallerPathPrefixLength([CallerFilePath] string callerPath = null)
			{
				int num = callerPath.LastIndexOf("ModelSwapperSkins\\");
				if (num >= 0)
				{
					return num + "ModelSwapperSkins\\".Length;
				}
				Debug.LogError((object)"[ModelSwapperSkins] Logger failed to determine caller path prefix length");
				return 0;
			}
		}

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

		private static StringBuilder AppendCallerPrefix(this StringBuilder stringBuilder, string callerPath, string callerMemberName, int callerLineNumber)
		{
			return stringBuilder.Append(callerPath, _cachedCallerPathPrefixLength, callerPath.Length - _cachedCallerPathPrefixLength).Append(':').Append(callerLineNumber)
				.Append(" (")
				.Append(callerMemberName)
				.Append("):");
		}

		private static StringBuilder buildCallerLogString(string callerPath, string callerMemberName, int callerLineNumber, object data)
		{
			return _sharedStringBuilder.Clear().AppendCallerPrefix(callerPath, callerMemberName, callerLineNumber).Append(' ')
				.Append(data);
		}

		[Conditional("DEBUG")]
		internal static void Debug(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1)
		{
			_logSource.LogDebug((object)buildCallerLogString(callerPath, callerMemberName, callerLineNumber, data));
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[Conditional("DEBUG")]
		internal static void Debug_NoCallerPrefix(object data)
		{
			_logSource.LogDebug(data);
		}

		internal static void Error(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1)
		{
			_logSource.LogError((object)buildCallerLogString(callerPath, callerMemberName, callerLineNumber, data));
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static void Error_NoCallerPrefix(object data)
		{
			_logSource.LogError(data);
		}

		internal static void Fatal(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1)
		{
			_logSource.LogFatal((object)buildCallerLogString(callerPath, callerMemberName, callerLineNumber, data));
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static void Fatal_NoCallerPrefix(object data)
		{
			_logSource.LogFatal(data);
		}

		internal static void Info(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1)
		{
			_logSource.LogInfo((object)buildCallerLogString(callerPath, callerMemberName, callerLineNumber, data));
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static void Info_NoCallerPrefix(object data)
		{
			_logSource.LogInfo(data);
		}

		internal static void Message(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1)
		{
			_logSource.LogMessage((object)buildCallerLogString(callerPath, callerMemberName, callerLineNumber, data));
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static void Message_NoCallerPrefix(object data)
		{
			_logSource.LogMessage(data);
		}

		internal static void Warning(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1)
		{
			_logSource.LogWarning((object)buildCallerLogString(callerPath, callerMemberName, callerLineNumber, data));
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static void Warning_NoCallerPrefix(object data)
		{
			_logSource.LogWarning(data);
		}

		internal static void LogType(LogLevel level, object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1)
		{
			//IL_0000: 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_000c: Unknown result type (might be due to invalid IL or missing references)
			if ((level & 0x20) == 0)
			{
				_logSource.Log(level, (object)buildCallerLogString(callerPath, callerMemberName, callerLineNumber, data));
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static void LogType_NoCallerPrefix(LogLevel level, object data)
		{
			//IL_0000: 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_000c: Unknown result type (might be due to invalid IL or missing references)
			if ((level & 0x20) == 0)
			{
				_logSource.Log(level, data);
			}
		}
	}
	[BepInPlugin("Gorakh.ModelSwapperSkins", "ModelSwapperSkins", "1.6.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Main : BaseUnityPlugin
	{
		public const string PluginGUID = "Gorakh.ModelSwapperSkins";

		public const string PluginAuthor = "Gorakh";

		public const string PluginName = "ModelSwapperSkins";

		public const string PluginVersion = "1.6.0";

		private void Awake()
		{
			Stopwatch stopwatch = Stopwatch.StartNew();
			Log.Init(((BaseUnityPlugin)this).Logger);
			LanguageFolderHandler.Register(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location));
			SystemInitializerInjector.InjectDependency(typeof(SkinCatalog), typeof(DynamicSkinAdder));
			DynamicSkinAdder.AddSkins += DynamicSkinAdder_AddSkins;
			stopwatch.Stop();
			Log.Info_NoCallerPrefix($"Initialized in {stopwatch.Elapsed.TotalSeconds:F2} seconds");
		}

		private static void DynamicSkinAdder_AddSkins(CharacterBody bodyPrefab, List<SkinDef> skins)
		{
			new BodySkinsInitializer(bodyPrefab).TryCreateSkins(skins);
		}
	}
	public class ModelSkinTracker : MonoBehaviour
	{
		public SkinDef CurrentSkin;
	}
	public class ModelSwappedSkinController : MonoBehaviour
	{
		public ModelSwappedSkinDef AppliedSkin;

		public GameObject SkinModelObject;

		private void OnDestroy()
		{
			if (Object.op_Implicit((Object)(object)SkinModelObject))
			{
				Object.Destroy((Object)(object)SkinModelObject);
			}
		}
	}
	public class ModelSwappedSkinDef : SkinDef
	{
		[CompilerGenerated]
		private sealed class <<InstantiateModelAsync>g__waitThenSetEnabled|6_5>d : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public Behaviour behaviour;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <<InstantiateModelAsync>g__waitThenSetEnabled|6_5>d(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				//IL_0022: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForEndOfFrame();
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					if (Object.op_Implicit((Object)(object)behaviour))
					{
						behaviour.enabled = true;
					}
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <<InstantiateModelAsync>g__waitUntilInitializedThenFixToolbotAnimator|6_0>d : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public Animator animator;

			private <>c__DisplayClass6_0 <>8__1;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <<InstantiateModelAsync>g__waitUntilInitializedThenFixToolbotAnimator|6_0>d(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>8__1 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_008f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0099: Expected O, but got Unknown
				//IL_012f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0139: Expected O, but got Unknown
				//IL_0063: Unknown result type (might be due to invalid IL or missing references)
				//IL_006d: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
				{
					<>1__state = -1;
					<>8__1 = new <>c__DisplayClass6_0();
					Transform val = ((Component)animator).transform.Find("ToolbotMesh");
					if (Object.op_Implicit((Object)(object)val) && ((Component)val).TryGetComponent<Renderer>(ref <>8__1.toolbotMeshRenderer))
					{
						<>2__current = (object)new WaitForEndOfFrame();
						<>1__state = 1;
						return true;
					}
					goto IL_00b8;
				}
				case 1:
					<>1__state = -1;
					<>2__current = (object)new WaitWhile((Func<bool>)(() => Object.op_Implicit((Object)(object)<>8__1.toolbotMeshRenderer) && !<>8__1.toolbotMeshRenderer.enabled));
					<>1__state = 2;
					return true;
				case 2:
					<>1__state = -1;
					if (!Object.op_Implicit((Object)(object)animator))
					{
						return false;
					}
					goto IL_00b8;
				case 3:
					{
						<>1__state = -1;
						if (Object.op_Implicit((Object)(object)animator))
						{
							((Behaviour)animator).enabled = false;
						}
						return false;
					}
					IL_00b8:
					animator.speed = 0f;
					animator.Update(0f);
					animator.SetInteger("weaponStance", 0);
					animator.Update(0f);
					animator.PlayInFixedTime("NailgunOut", animator.GetLayerIndex("Stance, Additive"), 0f);
					animator.Update(0f);
					<>2__current = (object)new WaitForEndOfFrame();
					<>1__state = 3;
					return true;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass6_0
		{
			public Renderer toolbotMeshRenderer;

			internal bool <InstantiateModelAsync>b__1()
			{
				if (Object.op_Implicit((Object)(object)toolbotMeshRenderer))
				{
					return !toolbotMeshRenderer.enabled;
				}
				return false;
			}
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass6_1
		{
			public List<Object> objectsToCleanupOnModelDestroy;

			internal void <InstantiateModelAsync>b__4(OnDestroyCallback _)
			{
				foreach (Object item in objectsToCleanupOnModelDestroy)
				{
					if (Object.op_Implicit(item))
					{
						Object.Destroy(item);
					}
				}
			}
		}

		[CompilerGenerated]
		private sealed class <InstantiateModelAsync>d__6 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public ModelSwappedSkinDef <>4__this;

			public Transform modelTransform;

			public List<AssetReferenceT<Material>> loadedMaterials;

			public List<AssetReferenceT<Mesh>> loadedMeshes;

			public AsyncReferenceHandleUnloadType unloadType;

			private Transform <skinModelTransfom>5__2;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <InstantiateModelAsync>d__6(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<skinModelTransfom>5__2 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0086: Unknown result type (might be due to invalid IL or missing references)
				//IL_0090: Unknown result type (might be due to invalid IL or missing references)
				//IL_0061: Unknown result type (might be due to invalid IL or missing references)
				//IL_0177: Unknown result type (might be due to invalid IL or missing references)
				//IL_0181: Unknown result type (might be due to invalid IL or missing references)
				//IL_0345: Unknown result type (might be due to invalid IL or missing references)
				//IL_03e3: Unknown result type (might be due to invalid IL or missing references)
				//IL_03ed: Unknown result type (might be due to invalid IL or missing references)
				//IL_03fc: Unknown result type (might be due to invalid IL or missing references)
				//IL_0406: Unknown result type (might be due to invalid IL or missing references)
				//IL_0415: Unknown result type (might be due to invalid IL or missing references)
				//IL_041f: Unknown result type (might be due to invalid IL or missing references)
				//IL_042c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0436: Unknown result type (might be due to invalid IL or missing references)
				//IL_0504: Unknown result type (might be due to invalid IL or missing references)
				//IL_050e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0668: Unknown result type (might be due to invalid IL or missing references)
				//IL_066d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0672: Unknown result type (might be due to invalid IL or missing references)
				//IL_0685: Unknown result type (might be due to invalid IL or missing references)
				//IL_06ce: Unknown result type (might be due to invalid IL or missing references)
				//IL_077f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0784: Unknown result type (might be due to invalid IL or missing references)
				//IL_078a: Unknown result type (might be due to invalid IL or missing references)
				//IL_078c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0822: Unknown result type (might be due to invalid IL or missing references)
				//IL_0827: Unknown result type (might be due to invalid IL or missing references)
				//IL_082d: Unknown result type (might be due to invalid IL or missing references)
				//IL_082f: Unknown result type (might be due to invalid IL or missing references)
				int num = <>1__state;
				ModelSwappedSkinDef modelSwappedSkinDef = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<skinModelTransfom>5__2 = Object.Instantiate<Transform>(modelSwappedSkinDef.NewModelTransformPrefab, modelTransform);
					if (Object.op_Implicit((Object)(object)modelSwappedSkinDef.ModelSkin))
					{
						<>2__current = modelSwappedSkinDef.ModelSkin.ApplyAsync(((Component)<skinModelTransfom>5__2).gameObject, loadedMaterials, loadedMeshes, unloadType);
						<>1__state = 1;
						return true;
					}
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				bool flag = modelSwappedSkinDef.NewModelBodyPrefab.bodyIndex == BodyCatalog.FindBodyIndex("VoidInfestorBody");
				HurtBox[] componentsInChildren = ((Component)<skinModelTransfom>5__2).GetComponentsInChildren<HurtBox>(true);
				foreach (HurtBox val in componentsInChildren)
				{
					if (flag)
					{
						StartEvent[] components = ((Component)val).GetComponents<StartEvent>();
						for (int j = 0; j < components.Length; j++)
						{
							((Behaviour)components[j]).enabled = false;
						}
						DelayedEvent[] components2 = ((Component)val).GetComponents<DelayedEvent>();
						for (int j = 0; j < components2.Length; j++)
						{
							((Behaviour)components2[j]).enabled = false;
						}
					}
					((Behaviour)val).enabled = false;
				}
				HitBox[] componentsInChildren2 = ((Component)<skinModelTransfom>5__2).GetComponentsInChildren<HitBox>(true);
				for (int i = 0; i < componentsInChildren2.Length; i++)
				{
					((Behaviour)componentsInChildren2[i]).enabled = false;
				}
				Collider[] componentsInChildren3 = ((Component)<skinModelTransfom>5__2).GetComponentsInChildren<Collider>(true);
				for (int i = 0; i < componentsInChildren3.Length; i++)
				{
					componentsInChildren3[i].enabled = false;
				}
				bool flag2 = modelSwappedSkinDef.NewModelBodyPrefab.bodyIndex == BodyCatalog.FindBodyIndex("ToolbotBody");
				Animator[] componentsInChildren4 = ((Component)<skinModelTransfom>5__2).GetComponentsInChildren<Animator>(true);
				CharacterModel val3 = default(CharacterModel);
				foreach (Animator val2 in componentsInChildren4)
				{
					if (flag2 && ((Component)val2).TryGetComponent<CharacterModel>(ref val3))
					{
						((MonoBehaviour)val3).StartCoroutine(<InstantiateModelAsync>g__waitUntilInitializedThenFixToolbotAnimator|6_0(val2));
					}
					else if (!modelSwappedSkinDef.KeepSkinModelAnimatorActive)
					{
						((Behaviour)val2).enabled = false;
					}
				}
				SkinnedMeshRenderer[] componentsInChildren5 = ((Component)<skinModelTransfom>5__2).GetComponentsInChildren<SkinnedMeshRenderer>();
				for (int i = 0; i < componentsInChildren5.Length; i++)
				{
					componentsInChildren5[i].updateWhenOffscreen = true;
				}
				Behaviour[] components3 = ((Component)<skinModelTransfom>5__2).GetComponents<Behaviour>();
				foreach (Behaviour val4 in components3)
				{
					if (Object.op_Implicit((Object)(object)val4) && ((object)val4).GetType().FullName == "Generics.Dynamics.InverseKinematics")
					{
						val4.enabled = false;
					}
				}
				PrintController[] componentsInChildren6 = ((Component)<skinModelTransfom>5__2).GetComponentsInChildren<PrintController>(true);
				for (int i = 0; i < componentsInChildren6.Length; i++)
				{
					((Behaviour)componentsInChildren6[i]).enabled = false;
				}
				AkEvent[] componentsInChildren7 = ((Component)<skinModelTransfom>5__2).GetComponentsInChildren<AkEvent>(true);
				for (int i = 0; i < componentsInChildren7.Length; i++)
				{
					Object.Destroy((Object)(object)componentsInChildren7[i]);
				}
				StriderLegController[] componentsInChildren8 = ((Component)<skinModelTransfom>5__2).GetComponentsInChildren<StriderLegController>();
				for (int i = 0; i < componentsInChildren8.Length; i++)
				{
					((Behaviour)componentsInChildren8[i]).enabled = false;
				}
				componentsInChildren4 = ((Component)modelTransform).GetComponents<Animator>();
				for (int i = 0; i < componentsInChildren4.Length; i++)
				{
					componentsInChildren4[i].cullingMode = (AnimatorCullingMode)0;
				}
				ModelInfo modelInfo = ModelInfoProvider.GetModelInfo(((Component)modelTransform).gameObject);
				ModelInfo modelInfo2 = ModelInfoProvider.GetModelInfo(((Component)<skinModelTransfom>5__2).gameObject);
				float num2 = modelInfo.HeightScale / modelInfo2.HeightScale;
				<skinModelTransfom>5__2.localScale = new Vector3(num2, num2, num2);
				BonesProvider other = default(BonesProvider);
				BonesProvider bonesProvider = default(BonesProvider);
				if (((Component)modelTransform).TryGetComponent<BonesProvider>(ref other) && ((Component)<skinModelTransfom>5__2).TryGetComponent<BonesProvider>(ref bonesProvider))
				{
					bonesProvider.MapBonesTo(other);
				}
				ModelPartsProvider modelPartsProvider = default(ModelPartsProvider);
				if (((Component)<skinModelTransfom>5__2).TryGetComponent<ModelPartsProvider>(ref modelPartsProvider))
				{
					ModelPart[] parts = modelPartsProvider.Parts;
					foreach (ModelPart modelPart in parts)
					{
						if (!modelPart.ShouldShow(isMainModel: false))
						{
							((Component)modelPart.Transform).gameObject.SetActive(false);
						}
					}
				}
				CharacterModel val5 = default(CharacterModel);
				if (((Component)modelTransform).TryGetComponent<CharacterModel>(ref val5))
				{
					<>c__DisplayClass6_1 CS$<>8__locals0 = new <>c__DisplayClass6_1();
					bool flag3 = modelSwappedSkinDef.NewModelBodyPrefab.bodyIndex == BodyCatalog.FindBodyIndex("VultureBody");
					bool flag4 = modelSwappedSkinDef.NewModelBodyPrefab.bodyIndex == BodyCatalog.FindBodyIndex("GravekeeperBody");
					bool flag5 = modelSwappedSkinDef.NewModelBodyPrefab.bodyIndex == BodyCatalog.FindBodyIndex("RoboBallBossBody") || modelSwappedSkinDef.NewModelBodyPrefab.bodyIndex == BodyCatalog.FindBodyIndex("SuperRoboBallBossBody");
					DynamicBone[] componentsInChildren9 = ((Component)<skinModelTransfom>5__2).GetComponentsInChildren<DynamicBone>();
					foreach (DynamicBone val6 in componentsInChildren9)
					{
						((Behaviour)val6).enabled = false;
						if (!(flag3 || flag5) && (!flag4 || !Object.op_Implicit((Object)(object)val6.m_Root) || !(((Object)val6.m_Root).name == "head")))
						{
							((MonoBehaviour)val5).StartCoroutine(<InstantiateModelAsync>g__waitThenSetEnabled|6_5((Behaviour)(object)val6));
						}
					}
					List<RendererInfo> list = new List<RendererInfo>();
					List<LightInfo> list2 = new List<LightInfo>();
					CharacterModel component = ((Component)<skinModelTransfom>5__2).GetComponent<CharacterModel>();
					if (Object.op_Implicit((Object)(object)component) && (component.baseRendererInfos.Length != 0 || component.baseLightInfos.Length != 0))
					{
						RendererInfo[] baseRendererInfos = component.baseRendererInfos;
						if (modelSwappedSkinDef.NewModelBodyPrefab.bodyIndex == BodyCatalog.FindBodyIndex("MiniVoidRaidCrabBodyBase"))
						{
							for (int k = 0; k < baseRendererInfos.Length; k++)
							{
								ref RendererInfo reference = ref baseRendererInfos[k];
								if (Object.op_Implicit((Object)(object)reference.renderer))
								{
									switch (((Object)reference.renderer).name)
									{
									case "EyePupilMesh":
									case "VoidRaidCrabEye":
										reference.ignoreOverlays = true;
										break;
									case "VoidRaidCrabHead":
									case "VoidRaidCrabMetalLegRingsMesh":
									case "VoidRaidCrabMetalMesh":
									case "VoidRaidCrabBrain":
										reference.ignoreOverlays = false;
										break;
									}
								}
							}
						}
						list.AddRange(baseRendererInfos);
						list2.AddRange(component.baseLightInfos);
						val5.mainSkinnedMeshRenderer = component.mainSkinnedMeshRenderer;
					}
					else
					{
						list.AddRange(((Component)<skinModelTransfom>5__2).GetComponentsInChildren<Renderer>().Select(delegate(Renderer r)
						{
							//IL_0002: Unknown result type (might be due to invalid IL or missing references)
							//IL_0020: Unknown result type (might be due to invalid IL or missing references)
							//IL_0025: Unknown result type (might be due to invalid IL or missing references)
							//IL_0042: Unknown result type (might be due to invalid IL or missing references)
							RendererInfo result = default(RendererInfo);
							result.renderer = r;
							result.defaultMaterial = r.sharedMaterial;
							result.defaultShadowCastingMode = r.shadowCastingMode;
							result.hideOnDeath = false;
							result.ignoreOverlays = r is ParticleSystemRenderer;
							return result;
						}));
						list2.AddRange(((IEnumerable<Light>)((Component)<skinModelTransfom>5__2).GetComponentsInChildren<Light>()).Select((Func<Light, LightInfo>)((Light l) => new LightInfo(l))));
					}
					CS$<>8__locals0.objectsToCleanupOnModelDestroy = new List<Object>();
					for (int m = 0; m < list.Count; m++)
					{
						RendererInfo val7 = list[m];
						bool flag6 = false;
						if (val7.defaultMaterial.IsKeywordEnabled("PRINT_CUTOFF"))
						{
							Material val8 = Object.Instantiate<Material>(val7.defaultMaterial);
							val8.DisableKeyword("PRINT_CUTOFF");
							val8.SetInt(ShaderIDs._PrintOn, 0);
							val7.defaultMaterial = val8;
							CS$<>8__locals0.objectsToCleanupOnModelDestroy.Add((Object)(object)val8);
							flag6 = true;
						}
						if (flag6)
						{
							list[m] = val7;
						}
					}
					if (CS$<>8__locals0.objectsToCleanupOnModelDestroy.Count > 0)
					{
						OnDestroyCallback.AddCallback(((Component)modelTransform).gameObject, (Action<OnDestroyCallback>)delegate
						{
							foreach (Object item in CS$<>8__locals0.objectsToCleanupOnModelDestroy)
							{
								if (Object.op_Implicit(item))
								{
									Object.Destroy(item);
								}
							}
						});
					}
					CharacterModel val9 = val5;
					RendererInfo[] baseRendererInfos2 = val5.baseRendererInfos;
					List<RendererInfo> list3 = list;
					int i = 0;
					RendererInfo[] array = (RendererInfo[])(object)new RendererInfo[baseRendererInfos2.Length + list3.Count];
					ReadOnlySpan<RendererInfo> readOnlySpan = new ReadOnlySpan<RendererInfo>(baseRendererInfos2);
					readOnlySpan.CopyTo(new Span<RendererInfo>(array).Slice(i, readOnlySpan.Length));
					i += readOnlySpan.Length;
					foreach (RendererInfo item2 in list3)
					{
						array[i] = item2;
						i++;
					}
					val9.baseRendererInfos = array;
					val9 = val5;
					LightInfo[] baseLightInfos = val5.baseLightInfos;
					List<LightInfo> list4 = list2;
					i = 0;
					LightInfo[] array2 = (LightInfo[])(object)new LightInfo[baseLightInfos.Length + list4.Count];
					ReadOnlySpan<LightInfo> readOnlySpan2 = new ReadOnlySpan<LightInfo>(baseLightInfos);
					readOnlySpan2.CopyTo(new Span<LightInfo>(array2).Slice(i, readOnlySpan2.Length));
					i += readOnlySpan2.Length;
					foreach (LightInfo item3 in list4)
					{
						array2[i] = item3;
						i++;
					}
					val9.baseLightInfos = array2;
					if (Object.op_Implicit((Object)(object)component))
					{
						((Behaviour)component).enabled = false;
					}
				}
				ModelSwappedSkinController modelSwappedSkinController = default(ModelSwappedSkinController);
				if (((Component)modelTransform).TryGetComponent<ModelSwappedSkinController>(ref modelSwappedSkinController))
				{
					modelSwappedSkinController.SkinModelObject = ((Component)<skinModelTransfom>5__2).gameObject;
				}
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		public CharacterBody NewModelBodyPrefab;

		public Transform NewModelTransformPrefab;

		public SkinDef ModelSkin;

		public bool KeepSkinModelAnimatorActive;

		public void Initialize(ModelPartsProvider modelPartsProvider, ModelPartsProvider skinModelPartsProvider)
		{
			//IL_0387: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_030f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0314: Unknown result type (might be due to invalid IL or missing references)
			//IL_031a: Unknown result type (might be due to invalid IL or missing references)
			//IL_031c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0321: Unknown result type (might be due to invalid IL or missing references)
			HashSet<SkinDef> encounteredSkinInstances = new HashSet<SkinDef>();
			List<SkinDef> baseSkinsApplyOrder = new List<SkinDef>();
			if (base.baseSkins != null)
			{
				SkinDef[] baseSkins = base.baseSkins;
				for (int i = 0; i < baseSkins.Length; i++)
				{
					addBaseSkinToApplyOrder(baseSkins[i]);
				}
			}
			SkinDefParams val = ((SkinDef)this).GetSkinParams().ReferenceOrDirect<SkinDefParams>().WaitForCompletion();
			val.gameObjectActivations = (GameObjectActivation[])(object)new GameObjectActivation[modelPartsProvider.Parts.Length];
			for (int j = 0; j < modelPartsProvider.Parts.Length; j++)
			{
				ModelPart modelPart = modelPartsProvider.Parts[j];
				GameObject partObject = ((Component)modelPart.Transform).gameObject;
				bool flag = modelPart.ShouldShow(isMainModel: true);
				bool flag2 = false;
				for (int num = baseSkinsApplyOrder.Count - 1; num >= 0; num--)
				{
					SkinDef val2 = baseSkinsApplyOrder[num];
					GameObjectActivation[] array = Array.Empty<GameObjectActivation>();
					AssetOrDirectReference<SkinDefParams> val3 = val2.GetSkinParams().ReferenceOrDirect<SkinDefParams>();
					if (Object.op_Implicit((Object)(object)val3.directRef) || ((AssetReference)val3.address).RuntimeKeyIsValid())
					{
						array = val3.WaitForCompletion().gameObjectActivations;
					}
					else
					{
						GameObjectActivation[] gameObjectActivations = val2.gameObjectActivations;
						int i = 0;
						GameObjectActivation[] array2 = (GameObjectActivation[])(object)new GameObjectActivation[gameObjectActivations.Length];
						GameObjectActivation[] array3 = gameObjectActivations;
						foreach (GameObjectActivation val4 in array3)
						{
							array2[i] = GameObjectActivation.op_Implicit(val4);
							i++;
						}
						array = array2;
					}
					int num2 = Array.FindIndex(array, (GameObjectActivation a) => (Object)(object)a.gameObject == (Object)(object)partObject);
					if (num2 >= 0)
					{
						bool shouldActivate = array[num2].shouldActivate;
						flag = flag && shouldActivate;
						flag2 = true;
						break;
					}
				}
				if (!flag2 && flag && !partObject.activeSelf)
				{
					flag = false;
				}
				val.gameObjectActivations[j] = new GameObjectActivation
				{
					gameObject = partObject,
					shouldActivate = flag
				};
			}
			if (base.baseSkins == null || base.baseSkins.Length == 0)
			{
				val.rendererInfos = ((Component)modelPartsProvider).GetComponent<CharacterModel>().baseRendererInfos;
			}
			else
			{
				HashSet<MinionSkinReplacement> hashSet = new HashSet<MinionSkinReplacement>(MinionSkinReplacementBodyComparer.Instance);
				HashSet<ProjectileGhostReplacement> hashSet2 = new HashSet<ProjectileGhostReplacement>(ProjectileGhostReplacementProjectileComparer.Instance);
				SkinDef[] baseSkins = base.baseSkins;
				foreach (SkinDef val5 in baseSkins)
				{
					if (!Object.op_Implicit((Object)(object)val5))
					{
						continue;
					}
					MinionSkinReplacement[] array4 = Array.Empty<MinionSkinReplacement>();
					ProjectileGhostReplacement[] array5 = Array.Empty<ProjectileGhostReplacement>();
					SkinDefParams val6 = val5.GetSkinParams().ReferenceOrDirect<SkinDefParams>().WaitForCompletion();
					if (Object.op_Implicit((Object)(object)val6))
					{
						array4 = val6.minionSkinReplacements;
						array5 = val6.projectileGhostReplacements;
					}
					else
					{
						MinionSkinReplacement[] minionSkinReplacements = val5.minionSkinReplacements;
						int k = 0;
						MinionSkinReplacement[] array6 = (MinionSkinReplacement[])(object)new MinionSkinReplacement[minionSkinReplacements.Length];
						MinionSkinReplacement[] array7 = minionSkinReplacements;
						foreach (MinionSkinReplacement val7 in array7)
						{
							array6[k] = MinionSkinReplacement.op_Implicit(val7);
							k++;
						}
						array4 = array6;
						ProjectileGhostReplacement[] projectileGhostReplacements = val5.projectileGhostReplacements;
						k = 0;
						ProjectileGhostReplacement[] array8 = (ProjectileGhostReplacement[])(object)new ProjectileGhostReplacement[projectileGhostReplacements.Length];
						ProjectileGhostReplacement[] array9 = projectileGhostReplacements;
						foreach (ProjectileGhostReplacement val8 in array9)
						{
							array8[k] = ProjectileGhostReplacement.op_Implicit(val8);
							k++;
						}
						array5 = array8;
					}
					if (array4.Length != 0)
					{
						hashSet.UnionWith(array4);
					}
					if (array5.Length != 0)
					{
						hashSet2.UnionWith(array5);
					}
				}
				val.minionSkinReplacements = hashSet.ToArray();
				val.projectileGhostReplacements = hashSet2.ToArray();
			}
			string bodyName = BodyCatalog.GetBodyName(NewModelBodyPrefab.bodyIndex);
			if (bodyName == null)
			{
				return;
			}
			switch (bodyName.Length)
			{
			case 13:
				switch (bodyName[0])
				{
				default:
					return;
				case 'A':
					if (!(bodyName == "AcidLarvaBody"))
					{
						return;
					}
					break;
				case 'N':
					if (!(bodyName == "NullifierBody"))
					{
						return;
					}
					break;
				}
				goto IL_0606;
			case 11:
				switch (bodyName[0])
				{
				default:
					return;
				case 'C':
					if (!(bodyName == "CaptainBody"))
					{
						return;
					}
					break;
				case 'I':
					if (!(bodyName == "ImpBossBody"))
					{
						return;
					}
					break;
				case 'T':
					if (!(bodyName == "TreebotBody"))
					{
						return;
					}
					break;
				}
				goto IL_0606;
			case 8:
				switch (bodyName[0])
				{
				default:
					return;
				case 'E':
					if (!(bodyName == "EngiBody"))
					{
						return;
					}
					break;
				case 'G':
					if (!(bodyName == "GeepBody"))
					{
						return;
					}
					break;
				case 'S':
					if (!(bodyName == "ScavBody"))
					{
						return;
					}
					break;
				}
				goto IL_0606;
			case 7:
				switch (bodyName[1])
				{
				default:
					return;
				case 'i':
					if (!(bodyName == "GipBody"))
					{
						return;
					}
					break;
				case 'u':
					if (!(bodyName == "GupBody"))
					{
						return;
					}
					break;
				case 'm':
					if (!(bodyName == "ImpBody"))
					{
						return;
					}
					break;
				}
				goto IL_0606;
			case 14:
				switch (bodyName[9])
				{
				default:
					return;
				case 'b':
					if (!(bodyName == "HermitCrabBody"))
					{
						return;
					}
					break;
				case '1':
					if (!(bodyName == "ScavLunar1Body"))
					{
						return;
					}
					break;
				case '2':
					if (!(bodyName == "ScavLunar2Body"))
					{
						return;
					}
					break;
				case '3':
					if (!(bodyName == "ScavLunar3Body"))
					{
						return;
					}
					break;
				case '4':
					if (!(bodyName == "ScavLunar4Body"))
					{
						return;
					}
					break;
				}
				goto IL_0606;
			case 16:
				switch (bodyName[0])
				{
				default:
					return;
				case 'M':
					if (!(bodyName == "MiniMushroomBody"))
					{
						return;
					}
					break;
				case 'V':
					if (!(bodyName == "VoidInfestorBody"))
					{
						return;
					}
					break;
				}
				goto IL_0606;
			case 24:
				if (!(bodyName == "MiniVoidRaidCrabBodyBase"))
				{
					break;
				}
				goto IL_0606;
			case 17:
				{
					if (!(bodyName == "NullifierAllyBody"))
					{
						break;
					}
					goto IL_0606;
				}
				IL_0606:
				KeepSkinModelAnimatorActive = true;
				break;
			}
			void addBaseSkinToApplyOrder(SkinDef skin)
			{
				if (encounteredSkinInstances.Add(skin))
				{
					if (skin.baseSkins != null)
					{
						SkinDef[] baseSkins2 = skin.baseSkins;
						for (int m = 0; m < baseSkins2.Length; m++)
						{
							addBaseSkinToApplyOrder(baseSkins2[m]);
						}
					}
					baseSkinsApplyOrder.Add(skin);
				}
			}
		}

		public void RemoveFrom(Transform modelTransform, GameObject skinModelObject)
		{
			//IL_0025: 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)
			CharacterModel val = default(CharacterModel);
			if (!((Component)modelTransform).TryGetComponent<CharacterModel>(ref val))
			{
				return;
			}
			List<LightInfo> list = val.baseLightInfos.ToList();
			bool flag = false;
			for (int num = list.Count - 1; num >= 0; num--)
			{
				if (!Object.op_Implicit((Object)(object)list[num].light) || ((Component)list[num].light).transform.IsChildOf(skinModelObject.transform))
				{
					list.RemoveAt(num);
					flag = true;
				}
			}
			if (flag)
			{
				val.baseLightInfos = list.ToArray();
			}
		}

		[IteratorStateMachine(typeof(<InstantiateModelAsync>d__6))]
		public IEnumerator InstantiateModelAsync(Transform modelTransform, List<AssetReferenceT<Material>> loadedMaterials, List<AssetReferenceT<Mesh>> loadedMeshes, AsyncReferenceHandleUnloadType unloadType)
		{
			//IL_0023: 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)
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <InstantiateModelAsync>d__6(0)
			{
				<>4__this = this,
				modelTransform = modelTransform,
				loadedMaterials = loadedMaterials,
				loadedMeshes = loadedMeshes,
				unloadType = unloadType
			};
		}

		[IteratorStateMachine(typeof(<<InstantiateModelAsync>g__waitUntilInitializedThenFixToolbotAnimator|6_0>d))]
		[CompilerGenerated]
		internal static IEnumerator <InstantiateModelAsync>g__waitUntilInitializedThenFixToolbotAnimator|6_0(Animator animator)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <<InstantiateModelAsync>g__waitUntilInitializedThenFixToolbotAnimator|6_0>d(0)
			{
				animator = animator
			};
		}

		[IteratorStateMachine(typeof(<<InstantiateModelAsync>g__waitThenSetEnabled|6_5>d))]
		[CompilerGenerated]
		internal static IEnumerator <InstantiateModelAsync>g__waitThenSetEnabled|6_5(Behaviour behaviour)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <<InstantiateModelAsync>g__waitThenSetEnabled|6_5>d(0)
			{
				behaviour = behaviour
			};
		}
	}
}
namespace ModelSwapperSkins.Utils
{
	public static class ArrayUtil
	{
		public static void Append<T>(ref T[] array, IEnumerable<T> other)
		{
			if (other != null && (!(other is ICollection collection) || collection.Count != 0))
			{
				List<T> list = new List<T>();
				list.AddRange(array);
				list.AddRange(other);
				array = list.ToArray();
			}
		}

		public static void Append<T>(ref T[] array, T[] other)
		{
			if (array == null || array.Length == 0)
			{
				array = other;
			}
			else if (other != null && other.Length != 0)
			{
				T[] array2 = array;
				int num = 0;
				T[] array3 = new T[array2.Length + other.Length];
				ReadOnlySpan<T> readOnlySpan = new ReadOnlySpan<T>(array2);
				readOnlySpan.CopyTo(new Span<T>(array3).Slice(num, readOnlySpan.Length));
				num += readOnlySpan.Length;
				ReadOnlySpan<T> readOnlySpan2 = new ReadOnlySpan<T>(other);
				readOnlySpan2.CopyTo(new Span<T>(array3).Slice(num, readOnlySpan2.Length));
				num += readOnlySpan2.Length;
				array = array3;
			}
		}
	}
	internal static class BoneVisualizer
	{
		private class ModelBonesDrawer : MonoBehaviour
		{
			private static readonly Mesh _lineMesh;

			private readonly List<MeshDrawer> _activeMeshDrawers = new List<MeshDrawer>();

			private CharacterModel _model;

			static ModelBonesDrawer()
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0006: Expected O, but got Unknown
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				//IL_0016: Unknown result type (might be due to invalid IL or missing references)
				WireMeshBuilder val = new WireMeshBuilder();
				try
				{
					val.AddLine(Vector3.zero, Color.yellow, Vector3.forward, Color.yellow);
					_lineMesh = val.GenerateMesh();
				}
				finally
				{
					((IDisposable)val)?.Dispose();
				}
			}

			private void Awake()
			{
				//IL_0078: Unknown result type (might be due to invalid IL or missing references)
				//IL_007d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0088: Unknown result type (might be due to invalid IL or missing references)
				//IL_0091: Expected O, but got Unknown
				//IL_0093: Unknown result type (might be due to invalid IL or missing references)
				//IL_0098: Unknown result type (might be due to invalid IL or missing references)
				//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
				//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
				//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
				_model = ((Component)this).GetComponent<CharacterModel>();
				BonesProvider component = ((Component)_model).GetComponent<BonesProvider>();
				if (Object.op_Implicit((Object)(object)component))
				{
					Bone[] bones = component.Bones;
					foreach (Bone bone in bones)
					{
						if (bone.Info.Type == BoneType.Root)
						{
							continue;
						}
						Transform boneTransform = bone.BoneTransform;
						if (Object.op_Implicit((Object)(object)boneTransform))
						{
							int childCount = boneTransform.childCount;
							for (int j = 0; j < childCount; j++)
							{
								Transform child = boneTransform.GetChild(j);
								MeshDrawer val = new MeshDrawer(boneTransform)
								{
									mesh = _lineMesh,
									hasMeshOwnership = false
								};
								Vector3 localPosition = child.localPosition;
								float magnitude = ((Vector3)(ref localPosition)).magnitude;
								val.transform.localPosition = Vector3.zero;
								val.transform.localRotation = Util.QuaternionSafeLookRotation(localPosition);
								val.transform.localScale = Vector3.one * magnitude;
								_activeMeshDrawers.Add(val);
							}
						}
					}
				}
				InstanceTracker.Add<ModelBonesDrawer>(this);
			}

			private void OnDestroy()
			{
				InstanceTracker.Remove<ModelBonesDrawer>(this);
				foreach (MeshDrawer activeMeshDrawer in _activeMeshDrawers)
				{
					if (Object.op_Implicit((Object)(object)activeMeshDrawer.gameObject))
					{
						activeMeshDrawer.Dispose();
					}
				}
				_activeMeshDrawers.Clear();
			}
		}

		[CompilerGenerated]
		private static class <>O
		{
			public static hook_Awake <0>__CharacterModel_Awake;
		}

		private static bool _drawModelBones;

		[ConCommand(commandName = "draw_model_bones")]
		private static void CCEnableBoneVisualizer(ConCommandArgs args)
		{
			_drawModelBones = !_drawModelBones;
			if (_drawModelBones)
			{
				foreach (CharacterModel instances in InstanceTracker.GetInstancesList<CharacterModel>())
				{
					((Component)instances).gameObject.AddComponent<ModelBonesDrawer>();
				}
				return;
			}
			List<ModelBonesDrawer> instancesList = InstanceTracker.GetInstancesList<ModelBonesDrawer>();
			for (int num = instancesList.Count - 1; num >= 0; num--)
			{
				Object.Destroy((Object)(object)instancesList[num]);
			}
		}

		[SystemInitializer(new Type[] { })]
		private static void Init()
		{
			//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>__CharacterModel_Awake;
			if (obj == null)
			{
				hook_Awake val = CharacterModel_Awake;
				<>O.<0>__CharacterModel_Awake = val;
				obj = (object)val;
			}
			CharacterModel.Awake += (hook_Awake)obj;
		}

		private static void CharacterModel_Awake(orig_Awake orig, CharacterModel self)
		{
			orig.Invoke(self);
			if (_drawModelBones)
			{
				((Component)self).gameObject.AddComponent<ModelBonesDrawer>();
			}
		}
	}
	internal static class ShaderIDs
	{
		public static readonly int _PrintOn = Shader.PropertyToID("_PrintOn");
	}
	internal static class ShaderKeywords
	{
		public const string PRINT_CUTOFF = "PRINT_CUTOFF";
	}
	public class TemporaryTexture : IDisposable
	{
		[CompilerGenerated]
		private bool <isTemporary>P;

		public readonly Texture2D Texture;

		public TemporaryTexture(Texture2D texture, bool isTemporary)
		{
			<isTemporary>P = isTemporary;
			Texture = texture;
			base..ctor();
		}

		public void Dispose()
		{
			if (<isTemporary>P)
			{
				Object.Destroy((Object)(object)Texture);
			}
		}
	}
	public static class TransformUtils
	{
		[CompilerGenerated]
		private sealed class <GetAllChildrenRecursive>d__1 : IEnumerable<Transform>, IEnumerable, IEnumerator<Transform>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private Transform <>2__current;

			private int <>l__initialThreadId;

			private Transform root;

			public Transform <>3__root;

			private int <i>5__2;

			private IEnumerator<Transform> <>7__wrap2;

			Transform IEnumerator<Transform>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <GetAllChildrenRecursive>d__1(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if (num == -3 || num == 2)
				{
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<>7__wrap2 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				try
				{
					switch (<>1__state)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						<>2__current = root;
						<>1__state = 1;
						return true;
					case 1:
						<>1__state = -1;
						<i>5__2 = 0;
						goto IL_00cc;
					case 2:
						{
							<>1__state = -3;
							goto IL_00a2;
						}
						IL_00cc:
						if (<i>5__2 < root.childCount)
						{
							<>7__wrap2 = GetAllChildrenRecursive(root.GetChild(<i>5__2)).GetEnumerator();
							<>1__state = -3;
							goto IL_00a2;
						}
						return false;
						IL_00a2:
						if (<>7__wrap2.MoveNext())
						{
							Transform current = <>7__wrap2.Current;
							<>2__current = current;
							<>1__state = 2;
							return true;
						}
						<>m__Finally1();
						<>7__wrap2 = null;
						<i>5__2++;
						goto IL_00cc;
					}
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			private void <>m__Finally1()
			{
				<>1__state = -1;
				if (<>7__wrap2 != null)
				{
					<>7__wrap2.Dispose();
				}
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}

			[DebuggerHidden]
			IEnumerator<Transform> IEnumerable<Transform>.GetEnumerator()
			{
				<GetAllChildrenRecursive>d__1 <GetAllChildrenRecursive>d__;
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					<GetAllChildrenRecursive>d__ = this;
				}
				else
				{
					<GetAllChildrenRecursive>d__ = new <GetAllChildrenRecursive>d__1(0);
				}
				<GetAllChildrenRecursive>d__.root = <>3__root;
				return <GetAllChildrenRecursive>d__;
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<Transform>)this).GetEnumerator();
			}
		}

		public static string GetObjectPath(Transform obj, Transform root)
		{
			if ((Object)(object)obj == (Object)(object)root)
			{
				return ((Object)obj).name;
			}
			StringBuilder stringBuilder = new StringBuilder();
			do
			{
				if (stringBuilder.Length == 0)
				{
					stringBuilder.Append(((Object)obj).name);
				}
				else
				{
					stringBuilder.Insert(0, ((Object)obj).name + "/");
				}
				obj = obj.parent;
			}
			while ((Object)(object)obj != (Object)null && (Object)(object)obj != (Object)(object)root);
			return stringBuilder.ToString();
		}

		[IteratorStateMachine(typeof(<GetAllChildrenRecursive>d__1))]
		public static IEnumerable<Transform> GetAllChildrenRecursive(Transform root)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <GetAllChildrenRecursive>d__1(-2)
			{
				<>3__root = root
			};
		}
	}
	public static class VectorUtils
	{
		public static Vector3 Divide(Vector3 a, Vector3 b)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			return new Vector3(a.x / b.x, a.y / b.y, a.z / b.z);
		}
	}
}
namespace ModelSwapperSkins.Utils.Extensions
{
	public static class AssetLoadExtensions
	{
		public static AssetOrDirectReference<T> ReferenceOrDirect<T>(this (T directDef, AssetReferenceT<T> assetRef) tuple) where T : Object
		{
			AssetOrDirectReference<T> obj = new AssetOrDirectReference<T>
			{
				address = tuple.assetRef
			};
			(obj.directRef, _) = tuple;
			return obj;
		}

		public static AssetOrDirectReference<T> ReferenceOrDirect<T>(this (AssetReferenceT<T> assetRef, T directDef) tuple) where T : Object
		{
			AssetOrDirectReference<T> obj = new AssetOrDirectReference<T>();
			(obj.address, obj.directRef) = tuple;
			return obj;
		}

		public static void CallOnSuccess<T>(this AsyncOperationHandle<T> handle, Action<T> onSuccess)
		{
			handle.Completed += delegate(AsyncOperationHandle<T> handle)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Invalid comparison between Unknown and I4
				if ((int)handle.Status == 2)
				{
					Log.Error("Failed to load asset '" + handle.LocationName + "'", "X:\\Git\\RoR2\\ModelSwapperSkins\\ModelSwapperSkins\\Utils\\Extensions\\AssetLoadExtensions.cs", "CallOnSuccess", 39);
				}
				else
				{
					onSuccess(handle.Result);
				}
			};
		}
	}
	public static class CollectionExtensions
	{
		public static void EnsureCapacity<T>(this List<T> list, int capacity)
		{
			if (list == null)
			{
				throw new ArgumentNullException("list");
			}
			if (list.Capacity < capacity)
			{
				list.Capacity = capacity;
			}
		}
	}
	public static class TextureExtensions
	{
		public static Sprite CreateSprite(this Texture2D texture)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			return Sprite.Create(texture, new Rect(0f, 0f, (float)((Texture)texture).width, (float)((Texture)texture).height), Vector2.zero);
		}

		public static TemporaryTexture AsReadable(this Texture2D texture)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Expected O, but got Unknown
			if (((Texture)texture).isReadable)
			{
				return new TemporaryTexture(texture, isTemporary: false);
			}
			RenderTexture temporary = RenderTexture.GetTemporary(((Texture)texture).width, ((Texture)texture).height, 0, (RenderTextureFormat)0, (RenderTextureReadWrite)2);
			Graphics.Blit((Texture)(object)texture, temporary);
			RenderTexture active = RenderTexture.active;
			RenderTexture.active = temporary;
			Texture2D val = new Texture2D(((Texture)texture).width, ((Texture)texture).height);
			val.ReadPixels(new Rect(0f, 0f, (float)((Texture)temporary).width, (float)((Texture)temporary).height), 0, 0);
			val.Apply();
			RenderTexture.active = active;
			RenderTexture.ReleaseTemporary(temporary);
			return new TemporaryTexture(val, isTemporary: true);
		}
	}
	public static class TransformExtensions
	{
		public static Transform FindChildRecursive(this Transform transform, string childName)
		{
			if (((Object)transform).name == childName)
			{
				return transform;
			}
			for (int i = 0; i < transform.childCount; i++)
			{
				Transform val = transform.GetChild(i).FindChildRecursive(childName);
				if (Object.op_Implicit((Object)(object)val))
				{
					return val;
				}
			}
			return null;
		}
	}
}
namespace ModelSwapperSkins.Utils.Comparers
{
	public sealed class GameObjectActivationObjectComparer : IEqualityComparer<GameObjectActivation>
	{
		public static GameObjectActivationObjectComparer Instance { get; } = new GameObjectActivationObjectComparer();


		private GameObjectActivationObjectComparer()
		{
		}

		public bool Equals(GameObjectActivation x, GameObjectActivation y)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return (Object)(object)x.gameObject == (Object)(object)y.gameObject;
		}

		public int GetHashCode(GameObjectActivation obj)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return ((object)obj.gameObject).GetHashCode();
		}
	}
	public class MinionSkinReplacementBodyComparer : IEqualityComparer<MinionSkinReplacement>
	{
		public static MinionSkinReplacementBodyComparer Instance { get; } = new MinionSkinReplacementBodyComparer();


		private MinionSkinReplacementBodyComparer()
		{
		}

		public bool Equals(MinionSkinReplacement x, MinionSkinReplacement y)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return (Object)(object)x.minionBodyPrefab == (Object)(object)y.minionBodyPrefab;
		}

		public int GetHashCode(MinionSkinReplacement obj)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return ((object)obj.minionBodyPrefab).GetHashCode();
		}
	}
	public class ProjectileGhostReplacementProjectileComparer : IEqualityComparer<ProjectileGhostReplacement>
	{
		public static ProjectileGhostReplacementProjectileComparer Instance { get; } = new ProjectileGhostReplacementProjectileComparer();


		private ProjectileGhostReplacementProjectileComparer()
		{
		}

		public bool Equals(ProjectileGhostReplacement x, ProjectileGhostReplacement y)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return (Object)(object)x.projectilePrefab == (Object)(object)y.projectilePrefab;
		}

		public int GetHashCode(ProjectileGhostReplacement obj)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return ((object)obj.projectilePrefab).GetHashCode();
		}
	}
	public class RendererInfoRendererComparer : IEqualityComparer<RendererInfo>
	{
		public static RendererInfoRendererComparer Instance { get; } = new RendererInfoRendererComparer();


		private RendererInfoRendererComparer()
		{
		}

		public bool Equals(RendererInfo x, RendererInfo y)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return (Object)(object)x.renderer == (Object)(object)y.renderer;
		}

		public int GetHashCode(RendererInfo obj)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return ((object)obj.renderer).GetHashCode();
		}
	}
}
namespace ModelSwapperSkins.Patches
{
	internal static class AdditionalRendererInfoApplyPatch
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static Manipulator <0>__CharacterModel_UpdateRendererMaterials;
		}

		[SystemInitializer(new Type[] { })]
		private static void Init()
		{
			//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>__CharacterModel_UpdateRendererMaterials;
			if (obj == null)
			{
				Manipulator val = CharacterModel_UpdateRendererMaterials;
				<>O.<0>__CharacterModel_UpdateRendererMaterials = val;
				obj = (object)val;
			}
			CharacterModel.UpdateRendererMaterials += (Manipulator)obj;
		}

		private static void CharacterModel_UpdateRendererMaterials(ILContext il)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Expected O, but got Unknown
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(il);
			if (val.TryGotoNext((MoveType)0, new Func<Instruction, bool>[1]
			{
				(Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt(x, (MethodBase)AccessTools.DeclaredPropertySetter(typeof(Renderer), "sharedMaterials"))
			}))
			{
				VariableDefinition val2 = new VariableDefinition((TypeReference)(object)TypeReferenceRocks.MakeArrayType(il.Import(typeof(Material))));
				il.Method.Body.Variables.Add(val2);
				val.Emit(OpCodes.Stloc, val2);
				val.Emit(OpCodes.Dup);
				val.Emit(OpCodes.Ldloc, val2);
				val.EmitDelegate<Func<Renderer, Material[], Material[]>>((Func<Renderer, Material[], Material[]>)delegate(Renderer renderer, Material[] materials)
				{
					AdditionalRendererInfoProvider additionalRendererInfoProvider = default(AdditionalRendererInfoProvider);
					if (((Component)renderer).TryGetComponent<AdditionalRendererInfoProvider>(ref additionalRendererInfoProvider))
					{
						ArrayUtil.Append(ref materials, additionalRendererInfoProvider.AdditionalMaterials);
					}
					return materials;
				});
			}
			else
			{
				Log.Error("Failed to find patch location", "X:\\Git\\RoR2\\ModelSwapperSkins\\ModelSwapperSkins\\Patches\\AdditionalRendererInfoApplyPatch.cs", "CharacterModel_UpdateRendererMaterials", 46);
			}
		}
	}
	internal static class CreateModelOnApplySkin
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static hook_ApplyAsync <0>__SkinDef_ApplyAsync;
		}

		[CompilerGenerated]
		private sealed class <SkinDef_ApplyAsync>d__1 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public GameObject modelObject;

			public orig_ApplyAsync orig;

			public SkinDef self;

			public List<AssetReferenceT<Material>> loadedMaterials;

			public List<AssetReferenceT<Mesh>> loadedMeshes;

			public AsyncReferenceHandleUnloadType unloadType;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <SkinDef_ApplyAsync>d__1(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_008d: Unknown result type (might be due to invalid IL or missing references)
				//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
				{
					<>1__state = -1;
					ModelSwappedSkinController modelSwappedSkinController = default(ModelSwappedSkinController);
					if (modelObject.TryGetComponent<ModelSwappedSkinController>(ref modelSwappedSkinController))
					{
						if (Object.op_Implicit((Object)(object)modelSwappedSkinController.AppliedSkin) && Object.op_Implicit((Object)(object)modelSwappedSkinController.SkinModelObject))
						{
							modelSwappedSkinController.AppliedSkin.RemoveFrom(modelObject.transform, modelSwappedSkinController.SkinModelObject);
						}
						Object.Destroy((Object)(object)modelSwappedSkinController);
					}
					<>2__current = orig.Invoke(self, modelObject, loadedMaterials, loadedMeshes, unloadType);
					<>1__state = 1;
					return true;
				}
				case 1:
					<>1__state = -1;
					UnityObjectExtensions.EnsureComponent<ModelSkinTracker>(modelObject).CurrentSkin = self;
					if (self is ModelSwappedSkinDef modelSwappedSkinDef)
					{
						UnityObjectExtensions.EnsureComponent<ModelSwappedSkinController>(modelObject).AppliedSkin = modelSwappedSkinDef;
						<>2__current = modelSwappedSkinDef.InstantiateModelAsync(modelObject.transform, loadedMaterials, loadedMeshes, unloadType);
						<>1__state = 2;
						return true;
					}
					break;
				case 2:
					<>1__state = -1;
					break;
				}
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[SystemInitializer(new Type[] { })]
		private static void Init()
		{
			//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>__SkinDef_ApplyAsync;
			if (obj == null)
			{
				hook_ApplyAsync val = SkinDef_ApplyAsync;
				<>O.<0>__SkinDef_ApplyAsync = val;
				obj = (object)val;
			}
			SkinDef.ApplyAsync += (hook_ApplyAsync)obj;
		}

		[IteratorStateMachine(typeof(<SkinDef_ApplyAsync>d__1))]
		private static IEnumerator SkinDef_ApplyAsync(orig_ApplyAsync orig, SkinDef self, GameObject modelObject, List<AssetReferenceT<Material>> loadedMaterials, List<AssetReferenceT<Mesh>> loadedMeshes, AsyncReferenceHandleUnloadType unloadType)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <SkinDef_ApplyAsync>d__1(0)
			{
				orig = orig,
				self = self,
				modelObject = modelObject,
				loadedMaterials = loadedMaterials,
				loadedMeshes = loadedMeshes,
				unloadType = unloadType
			};
		}
	}
	internal static class FixMissingSkinPathsPatch
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static hook_ApplyAsync <0>__RuntimeSkin_ApplyAsync;
		}

		[SystemInitializer(new Type[] { })]
		private static void Init()
		{
			//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>__RuntimeSkin_ApplyAsync;
			if (obj == null)
			{
				hook_ApplyAsync val = RuntimeSkin_ApplyAsync;
				<>O.<0>__RuntimeSkin_ApplyAsync = val;
				obj = (object)val;
			}
			RuntimeSkin.ApplyAsync += (hook_ApplyAsync)obj;
		}

		private static IEnumerator RuntimeSkin_ApplyAsync(orig_ApplyAsync orig, RuntimeSkin self, GameObject modelObject, List<AssetReferenceT<Material>> loadedMaterials, List<AssetReferenceT<Mesh>> loadedMeshes, AsyncReferenceHandleUnloadType unloadType)
		{
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: 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_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			if (self != null)
			{
				Transform transform = modelObject.transform;
				if (self.gameObjectActivationTemplates.src != null && self.gameObjectActivationTemplates.Length > 0)
				{
					ReadOnlyArray<GameObjectActivationTemplate> gameObjectActivationTemplates = self.gameObjectActivationTemplates;
					List<GameObjectActivationTemplate> list = new List<GameObjectActivationTemplate>(gameObjectActivationTemplates.Length);
					Enumerator<GameObjectActivationTemplate> enumerator = gameObjectActivationTemplates.GetEnumerator();
					try
					{
						while (enumerator.MoveNext())
						{
							GameObjectActivationTemplate current = enumerator.Current;
							list.Add(current);
						}
					}
					finally
					{
						((IDisposable)enumerator).Dispose();
					}
					List<GameObjectActivationTemplate> list2 = list;
					bool flag = false;
					for (int num = list2.Count - 1; num >= 0; num--)
					{
						if (!Object.op_Implicit((Object)(object)transform.Find(list2[num].transformPath)))
						{
							list2.RemoveAt(num);
							flag = true;
						}
					}
					if (flag)
					{
						self.gameObjectActivationTemplates = ReadOnlyArray<GameObjectActivationTemplate>.op_Implicit(list2.ToArray());
					}
				}
				if (self.meshReplacementTemplates.src != null && self.meshReplacementTemplates.Length > 0)
				{
					ReadOnlyArray<MeshReplacementTemplate> meshReplacementTemplates = self.meshReplacementTemplates;
					List<MeshReplacementTemplate> list3 = new List<MeshReplacementTemplate>(meshReplacementTemplates.Length);
					Enumerator<MeshReplacementTemplate> enumerator2 = meshReplacementTemplates.GetEnumerator();
					try
					{
						while (enumerator2.MoveNext())
						{
							MeshReplacementTemplate current2 = enumerator2.Current;
							list3.Add(current2);
						}
					}
					finally
					{
						((IDisposable)enumerator2).Dispose();
					}
					List<MeshReplacementTemplate> list4 = list3;
					bool flag2 = false;
					for (int num2 = list4.Count - 1; num2 >= 0; num2--)
					{
						if (!Object.op_Implicit((Object)(object)transform.Find(list4[num2].transformPath)))
						{
							list4.RemoveAt(num2);
							flag2 = true;
						}
					}
					if (flag2)
					{
						self.meshReplacementTemplates = ReadOnlyArray<MeshReplacementTemplate>.op_Implicit(list4.ToArray());
					}
				}
			}
			return orig.Invoke(self, modelObject, loadedMaterials, loadedMeshes, unloadType);
		}
	}
	internal static class LoadoutPanelModifications
	{
		private class LoadoutPanelModelSkinsHandler : MonoBehaviour
		{
			[Serializable]
			[CompilerGenerated]
			private sealed class <>c
			{
				public static readonly <>c <>9 = new <>c();

				public static UnityAction <>9__10_0;

				public static Func<Loadout, int> <>9__10_1;

				internal void <rebuildModelSkinRow>b__10_0()
				{
				}

				internal int <rebuildModelSkinRow>b__10_1(Loadout loadout)
				{
					return 0;
				}
			}

			[CompilerGenerated]
			private sealed class <>c__DisplayClass10_0
			{
				public LoadoutPanelModelSkinsHandler <>4__this;

				public BodyIndex bodyIndex;

				public SkinDef[] skins;

				public BodyIndex modelBodyIndex;
			}

			[CompilerGenerated]
			private sealed class <>c__Displa