Decompiled source of ModelSwapperSkins v1.2.0

plugins/ModelSwapperSkins/ModelSwapperSkins.dll

Decompiled an hour ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Logging;
using HG;
using HG.Reflection;
using Microsoft.CodeAnalysis;
using ModelSwapperSkins.BoneMapping;
using ModelSwapperSkins.BoneMapping.InitializerRules;
using ModelSwapperSkins.ModelInfos;
using ModelSwapperSkins.ModelParts;
using ModelSwapperSkins.Utils;
using ModelSwapperSkins.Utils.Extensions;
using On.RoR2;
using R2API;
using R2API.Utils;
using RoR2;
using UnityEngine;
using UnityEngine.AddressableAssets;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: OptIn]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: AssemblyCompany("ModelSwapperSkins")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+ae24bbb47a071e0d17cdac4f7658d71b9439486f")]
[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]
	internal sealed class IsReadOnlyAttribute : Attribute
	{
	}
	[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 static class DynamicSkinAdder
	{
		public delegate void AddSkinDelegate(SurvivorDef survivor, List<SkinDef> skins);

		private static bool _skinBakeDisabled;

		public static event AddSkinDelegate AddSkins;

		[SystemInitializer(new Type[]
		{
			typeof(SurvivorCatalog),
			typeof(ModelPartsInitializer),
			typeof(BoneInitializer)
		})]
		private static void Init()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Expected O, but got Unknown
			SkinDef.Bake += new hook_Bake(SkinDef_Bake);
			foreach (SurvivorDef allSurvivorDef in SurvivorCatalog.allSurvivorDefs)
			{
				addSkinsTo(allSurvivorDef);
			}
			SkinDef.Bake -= new hook_Bake(SkinDef_Bake);
			static void SkinDef_Bake(orig_Bake orig, SkinDef self)
			{
				if (!_skinBakeDisabled)
				{
					orig.Invoke(self);
				}
			}
		}

		private static void addSkinsTo(SurvivorDef survivor)
		{
			//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_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Invalid comparison between Unknown and I4
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Invalid comparison between Unknown and I4
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)survivor))
			{
				return;
			}
			GameObject bodyPrefab = survivor.bodyPrefab;
			if (!Object.op_Implicit((Object)(object)bodyPrefab))
			{
				return;
			}
			ModelLocator component = bodyPrefab.GetComponent<ModelLocator>();
			if (!Object.op_Implicit((Object)(object)component))
			{
				return;
			}
			Transform modelTransform = component.modelTransform;
			if (!Object.op_Implicit((Object)(object)modelTransform))
			{
				return;
			}
			ModelSkinController component2 = ((Component)modelTransform).GetComponent<ModelSkinController>();
			if (!Object.op_Implicit((Object)(object)component2))
			{
				Log.Warning($"Survivor {survivor.cachedName} body prefab ({bodyPrefab}) model is missing ModelSkinController", "X:\\Git\\RoR2\\ModelSwapperSkins\\ModelSwapperSkins\\DynamicSkinAdder.cs", "addSkinsTo", 60);
				return;
			}
			List<SkinDef> list = new List<SkinDef>();
			_skinBakeDisabled = true;
			DynamicSkinAdder.AddSkins?.Invoke(survivor, list);
			_skinBakeDisabled = false;
			if (list.Count > 0)
			{
				foreach (SkinDef item in list)
				{
					SkinDef val = item;
					if (val.baseSkins == null)
					{
						val.baseSkins = Array.Empty<SkinDef>();
					}
					if (!Object.op_Implicit((Object)(object)item.rootObject))
					{
						item.rootObject = ((Component)modelTransform).gameObject;
					}
					item.Bake();
				}
				ArrayUtil.Append(ref component2.skins, list);
				BodyIndex val2 = BodyCatalog.FindBodyIndex(bodyPrefab);
				if ((int)val2 != -1)
				{
					SkinDef[][] skins = BodyCatalog.skins;
					if ((int)val2 < skins.Length)
					{
						ArrayUtil.Append(ref skins[val2], list);
					}
				}
			}
			Log.Info_NoCallerPrefix($"Created {list.Count} skin(s) for {survivor.cachedName}");
		}
	}
	internal static class Log
	{
		internal static ManualLogSource _logSource;

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

		private static string getLogPrefix(string callerPath, string callerMemberName, int callerLineNumber)
		{
			int num = callerPath.LastIndexOf("ModelSwapperSkins");
			if (num >= 0)
			{
				callerPath = callerPath.Substring(num + "ModelSwapperSkins".Length + 1);
			}
			return $"{callerPath}:{callerLineNumber} ({callerMemberName}) ";
		}

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

		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)(getLogPrefix(callerPath, callerMemberName, callerLineNumber) + data));
		}

		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)(getLogPrefix(callerPath, callerMemberName, callerLineNumber) + data));
		}

		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)(getLogPrefix(callerPath, callerMemberName, callerLineNumber) + data));
		}

		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)(getLogPrefix(callerPath, callerMemberName, callerLineNumber) + data));
		}

		internal static void Warning_NoCallerPrefix(object data)
		{
			_logSource.LogWarning(data);
		}
	}
	[BepInPlugin("Gorakh.ModelSwapperSkins", "ModelSwapperSkins", "1.2.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[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.2.0";

		private void Awake()
		{
			Stopwatch stopwatch = Stopwatch.StartNew();
			Log.Init(((BaseUnityPlugin)this).Logger);
			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(SurvivorDef survivor, List<SkinDef> skins)
		{
			new SurvivorSkinsInitializer(survivor).TryCreateSkins(skins);
		}
	}
	public class ModelSwappedSkinDef : SkinDef
	{
		public CharacterBody NewModelBodyPrefab;

		public Transform NewModelTransformPrefab;

		public SkinDef ModelSkin;

		public void Initialize(ModelPartsProvider modelPartsProvider, ModelPartsProvider skinModelPartsProvider)
		{
			base.gameObjectActivations = modelPartsProvider.Parts.Where((ModelPart m) => !m.ShouldShow(isMainModel: true)).Select(delegate(ModelPart m)
			{
				//IL_0002: 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 result = default(GameObjectActivation);
				result.gameObject = ((Component)m.Transform).gameObject;
				result.shouldActivate = false;
				return result;
			}).ToArray();
			base.rendererInfos = ((Component)modelPartsProvider).GetComponent<CharacterModel>().baseRendererInfos;
		}

		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();
			}
		}

		public Transform OnAppliedTo(Transform modelTransform)
		{
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0318: Unknown result type (might be due to invalid IL or missing references)
			//IL_0322: Unknown result type (might be due to invalid IL or missing references)
			Transform val = Object.Instantiate<Transform>(NewModelTransformPrefab, modelTransform);
			if (Object.op_Implicit((Object)(object)ModelSkin))
			{
				ModelSkin.Apply(((Component)val).gameObject);
			}
			HurtBox[] componentsInChildren = ((Component)val).GetComponentsInChildren<HurtBox>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				((Behaviour)componentsInChildren[i]).enabled = false;
			}
			Collider[] componentsInChildren2 = ((Component)val).GetComponentsInChildren<Collider>(true);
			for (int i = 0; i < componentsInChildren2.Length; i++)
			{
				componentsInChildren2[i].enabled = false;
			}
			bool flag = NewModelBodyPrefab.bodyIndex == BodyCatalog.FindBodyIndex("ToolbotBody");
			Animator[] componentsInChildren3 = ((Component)val).GetComponentsInChildren<Animator>(true);
			CharacterModel val3 = default(CharacterModel);
			foreach (Animator val2 in componentsInChildren3)
			{
				if (flag && ((Component)val2).TryGetComponent<CharacterModel>(ref val3))
				{
					((MonoBehaviour)val3).StartCoroutine(waitUntilInitializedThenFixToolbotAnimator(val2));
				}
				else
				{
					((Behaviour)val2).enabled = false;
				}
			}
			Behaviour[] components = ((Component)val).GetComponents<Behaviour>();
			foreach (Behaviour val4 in components)
			{
				if (Object.op_Implicit((Object)(object)val4) && ((object)val4).GetType().FullName == "Generics.Dynamics.InverseKinematics")
				{
					val4.enabled = false;
				}
			}
			PrintController[] componentsInChildren4 = ((Component)val).GetComponentsInChildren<PrintController>(true);
			for (int i = 0; i < componentsInChildren4.Length; i++)
			{
				((Behaviour)componentsInChildren4[i]).enabled = false;
			}
			AkEvent[] componentsInChildren5 = ((Component)val).GetComponentsInChildren<AkEvent>(true);
			for (int i = 0; i < componentsInChildren5.Length; i++)
			{
				((Behaviour)componentsInChildren5[i]).enabled = false;
			}
			StriderLegController[] componentsInChildren6 = ((Component)val).GetComponentsInChildren<StriderLegController>();
			for (int i = 0; i < componentsInChildren6.Length; i++)
			{
				((Behaviour)componentsInChildren6[i]).enabled = false;
			}
			componentsInChildren3 = ((Component)modelTransform).GetComponents<Animator>();
			for (int i = 0; i < componentsInChildren3.Length; i++)
			{
				componentsInChildren3[i].cullingMode = (AnimatorCullingMode)0;
			}
			ModelInfo modelInfo = ModelInfoProvider.GetModelInfo(((Component)modelTransform).gameObject);
			ModelInfo modelInfo2 = ModelInfoProvider.GetModelInfo(((Component)val).gameObject);
			float num = modelInfo.HeightScale / modelInfo2.HeightScale;
			val.localScale = new Vector3(num, num, num);
			BonesProvider other = default(BonesProvider);
			BonesProvider bonesProvider = default(BonesProvider);
			if (((Component)modelTransform).TryGetComponent<BonesProvider>(ref other) && ((Component)val).TryGetComponent<BonesProvider>(ref bonesProvider))
			{
				bonesProvider.MapBonesTo(other);
			}
			ModelPartsProvider modelPartsProvider = default(ModelPartsProvider);
			if (((Component)val).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);
			ModelPartsProvider mainModelPartsProvider;
			if (((Component)modelTransform).TryGetComponent<CharacterModel>(ref val5))
			{
				DynamicBone[] componentsInChildren7 = ((Component)val).GetComponentsInChildren<DynamicBone>();
				foreach (DynamicBone val6 in componentsInChildren7)
				{
					((Behaviour)val6).enabled = false;
					((MonoBehaviour)val5).StartCoroutine(waitThenSetEnabled((Behaviour)(object)val6));
				}
				mainModelPartsProvider = ((Component)modelTransform).GetComponent<ModelPartsProvider>();
				IEnumerable<RendererInfo> first = val5.baseRendererInfos.Where((RendererInfo r) => shouldShow((Component)(object)r.renderer, isMainModel: true));
				IEnumerable<LightInfo> first2 = val5.baseLightInfos.Where((LightInfo l) => shouldShow((Component)(object)l.light, isMainModel: true));
				CharacterModel val7 = default(CharacterModel);
				if (((Component)val).TryGetComponent<CharacterModel>(ref val7) && (val7.baseRendererInfos.Length != 0 || val7.baseLightInfos.Length != 0))
				{
					IEnumerable<RendererInfo> enumerable = val7.baseRendererInfos;
					if (NewModelBodyPrefab.bodyIndex == BodyCatalog.FindBodyIndex("MiniVoidRaidCrabBodyBase"))
					{
						enumerable = enumerable.Select(delegate(RendererInfo r)
						{
							//IL_0000: Unknown result type (might be due to invalid IL or missing references)
							//IL_007b: 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)
							if (Object.op_Implicit((Object)(object)r.renderer))
							{
								switch (((Object)r.renderer).name)
								{
								case "EyePupilMesh":
								case "VoidRaidCrabEye":
									r.ignoreOverlays = true;
									break;
								case "VoidRaidCrabHead":
								case "VoidRaidCrabMetalLegRingsMesh":
								case "VoidRaidCrabMetalMesh":
								case "VoidRaidCrabBrain":
									r.ignoreOverlays = false;
									break;
								}
							}
							return r;
						});
					}
					first = first.Concat(enumerable);
					first2 = first2.Concat(val7.baseLightInfos);
					val5.mainSkinnedMeshRenderer = val7.mainSkinnedMeshRenderer;
					((Behaviour)val7).enabled = false;
				}
				else
				{
					first = first.Concat(((Component)val).GetComponentsInChildren<Renderer>().Select(delegate(Renderer renderer)
					{
						//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 = renderer;
						result.defaultMaterial = renderer.sharedMaterial;
						result.defaultShadowCastingMode = renderer.shadowCastingMode;
						result.hideOnDeath = false;
						result.ignoreOverlays = renderer is ParticleSystemRenderer;
						return result;
					}));
					first2 = first2.Concat(((IEnumerable<Light>)((Component)val).GetComponentsInChildren<Light>()).Select((Func<Light, LightInfo>)((Light light) => new LightInfo(light))));
				}
				val5.baseRendererInfos = first.ToArray();
				val5.baseLightInfos = first2.ToArray();
			}
			return val;
			bool shouldShow(Component component, bool isMainModel)
			{
				if (!Object.op_Implicit((Object)(object)mainModelPartsProvider))
				{
					return true;
				}
				if (!Object.op_Implicit((Object)(object)component))
				{
					return false;
				}
				return mainModelPartsProvider.Parts.Where((ModelPart p) => (Object)(object)component.transform == (Object)(object)p.Transform || component.transform.IsChildOf(p.Transform)).All((ModelPart p) => p.ShouldShow(isMainModel));
			}
			static IEnumerator waitThenSetEnabled(Behaviour behaviour)
			{
				yield return (object)new WaitForEndOfFrame();
				if (Object.op_Implicit((Object)(object)behaviour))
				{
					behaviour.enabled = true;
				}
			}
			static IEnumerator waitUntilInitializedThenFixToolbotAnimator(Animator animator)
			{
				Transform val8 = ((Component)animator).transform.Find("ToolbotMesh");
				Renderer toolbotMeshRenderer = default(Renderer);
				if (Object.op_Implicit((Object)(object)val8) && ((Component)val8).TryGetComponent<Renderer>(ref toolbotMeshRenderer))
				{
					yield return (object)new WaitForEndOfFrame();
					yield return (object)new WaitWhile((Func<bool>)(() => Object.op_Implicit((Object)(object)toolbotMeshRenderer) && !toolbotMeshRenderer.enabled));
					if (!Object.op_Implicit((Object)(object)animator))
					{
						yield break;
					}
				}
				animator.speed = 0f;
				animator.Update(0f);
				animator.SetInteger("weaponStance", 0);
				animator.Update(0f);
				animator.PlayInFixedTime("NailgunOut", animator.GetLayerIndex("Stance, Additive"), 0f);
				animator.Update(0f);
				yield return (object)new WaitForEndOfFrame();
				if (Object.op_Implicit((Object)(object)animator))
				{
					((Behaviour)animator).enabled = false;
				}
			}
		}
	}
	public static class SkinIconGenerator
	{
		private record SkinIconKey(Texture2D bodyPortrait, Sprite background);

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

		public static Sprite GetOrCreateSkinIcon(Texture2D bodyPortrait, SkinDef backgroundSkin)
		{
			return GetOrCreateSkinIcon(bodyPortrait, Object.op_Implicit((Object)(object)backgroundSkin) ? backgroundSkin.icon : null);
		}

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

		private static Sprite generateSkinIcon(Texture2D bodyPortrait, Sprite background)
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Expected O, but got Unknown
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: 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_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)bodyPortrait) || !Object.op_Implicit((Object)(object)background))
			{
				if (Object.op_Implicit((Object)(object)bodyPortrait))
				{
					return bodyPortrait.CreateSprite();
				}
				if (Object.op_Implicit((Object)(object)background))
				{
					return background;
				}
				return null;
			}
			Rect baseRect2 = default(Rect);
			((Rect)(ref baseRect2))..ctor(0f, 0f, (float)((Texture)bodyPortrait).width, (float)((Texture)bodyPortrait).height);
			Rect rect = background.rect;
			using TemporaryTexture temporaryTexture = bodyPortrait.AsReadable();
			using TemporaryTexture temporaryTexture2 = background.texture.AsReadable();
			int width = ((Texture)bodyPortrait).width;
			int height = ((Texture)bodyPortrait).height;
			Texture2D val = new Texture2D(width, height, (TextureFormat)5, false);
			int x;
			for (x = 0; x < width; x++)
			{
				int y;
				for (y = 0; y < height; y++)
				{
					Color val2 = getCurrentPixelColor(temporaryTexture.Texture, baseRect2);
					Color val3 = getCurrentPixelColor(temporaryTexture2.Texture, rect);
					val.SetPixel(x, y, Color.Lerp(val2, val3, 1f - val2.a));
				}
				Color getCurrentPixelColor(Texture2D texture, Rect baseRect)
				{
					//IL_006c: Unknown result type (might be due to invalid IL or missing references)
					int num = Mathf.FloorToInt(Util.Remap((float)x, 0f, (float)width, ((Rect)(ref baseRect)).x, ((Rect)(ref baseRect)).x + ((Rect)(ref baseRect)).width));
					int num2 = Mathf.FloorToInt(Util.Remap((float)y, 0f, (float)height, ((Rect)(ref baseRect)).y, ((Rect)(ref baseRect)).y + ((Rect)(ref baseRect)).height));
					return texture.GetPixel(num, num2);
				}
			}
			val.Apply();
			return val.CreateSprite();
		}
	}
	public class SurvivorSkinsInitializer
	{
		private readonly SurvivorDef _survivor;

		private readonly ModelPartsProvider _survivorPartsProvider;

		private readonly BonesProvider _survivorBonesProvider;

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

		public SurvivorSkinsInitializer(SurvivorDef survivor)
		{
			_survivor = survivor;
			ModelLocator val = default(ModelLocator);
			if (Object.op_Implicit((Object)(object)survivor) && Object.op_Implicit((Object)(object)survivor.bodyPrefab) && survivor.bodyPrefab.TryGetComponent<ModelLocator>(ref val))
			{
				Transform modelTransform = val.modelTransform;
				if (Object.op_Implicit((Object)(object)modelTransform))
				{
					_survivorPartsProvider = ((Component)modelTransform).GetComponent<ModelPartsProvider>();
					_survivorBonesProvider = ((Component)modelTransform).GetComponent<BonesProvider>();
				}
			}
		}

		private bool isSurvivorValidForSkins()
		{
			if (Object.op_Implicit((Object)(object)_survivor) && Object.op_Implicit((Object)(object)_survivor.bodyPrefab) && Object.op_Implicit((Object)(object)_survivorPartsProvider))
			{
				return Object.op_Implicit((Object)(object)_survivorBonesProvider);
			}
			return false;
		}

		public void TryCreateSkins(List<SkinDef> dest)
		{
			if (!isSurvivorValidForSkins())
			{
				return;
			}
			_usedModelTransforms.Clear();
			foreach (CharacterBody allBodyPrefabBodyBodyComponent in BodyCatalog.allBodyPrefabBodyBodyComponents)
			{
				if (shouldCreateSkin(allBodyPrefabBodyBodyComponent))
				{
					dest.AddRange(createSkinsForBody(allBodyPrefabBodyBodyComponent));
				}
			}
		}

		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 (_survivorBonesProvider.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)((Component)body).gameObject == (Object)(object)_survivor.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;
		}

		private IEnumerable<SkinDef> createSkinsForBody(CharacterBody body)
		{
			ModelLocator component = ((Component)body).GetComponent<ModelLocator>();
			Transform modelTransform = component.modelTransform;
			ModelPartsProvider bodyModelPartsProvider = ((Component)modelTransform).GetComponent<ModelPartsProvider>();
			ModelSkinController val = default(ModelSkinController);
			if (((Component)modelTransform).TryGetComponent<ModelSkinController>(ref val))
			{
				IEnumerable<SkinDef> enumerable = val.skins.Where((SkinDef s) => !(s is ModelSwappedSkinDef));
				if (enumerable.Any())
				{
					int skinIndex = 0;
					foreach (SkinDef item in enumerable)
					{
						yield return (SkinDef)(object)createSkinDef("_" + ((Object)item).name, item, skinIndex++);
					}
					yield break;
				}
			}
			yield return (SkinDef)(object)createSkinDef(string.Empty, null, -1);
			ModelSwappedSkinDef createSkinDef(string nameSuffix, SkinDef baseSkin, int baseSkinIndex)
			{
				ModelSwappedSkinDef modelSwappedSkinDef = ScriptableObject.CreateInstance<ModelSwappedSkinDef>();
				((Object)modelSwappedSkinDef).name = "skin" + _survivor.cachedName + "_" + ((Object)body).name + nameSuffix;
				string key = (((SkinDef)modelSwappedSkinDef).nameToken = "SKIN_" + _survivor.cachedName.ToUpper() + "_" + ((Object)body).name.ToUpper() + nameSuffix.ToUpper());
				Dictionary<string, Dictionary<string, string>> dictionary = new Dictionary<string, Dictionary<string, string>>();
				foreach (Language allLanguage in Language.GetAllLanguages())
				{
					if (!dictionary.TryGetValue(allLanguage.name, out var value))
					{
						value = new Dictionary<string, string>();
						dictionary.Add(allLanguage.name, value);
					}
					string text = (Language.IsTokenInvalid(body.baseNameToken) ? "???" : Language.GetString(body.baseNameToken, allLanguage.name));
					if (Object.op_Implicit((Object)(object)baseSkin))
					{
						string text2 = ((!Language.IsTokenInvalid(baseSkin.nameToken)) ? Language.GetString(baseSkin.nameToken, allLanguage.name) : ((baseSkinIndex >= 0) ? $"Variant {baseSkinIndex + 1}" : string.Empty));
						if (!string.IsNullOrWhiteSpace(text2))
						{
							text = text + " (" + text2 + ")";
						}
					}
					value.Add(key, text);
				}
				LanguageAPI.Add(dictionary);
				ref Sprite icon = ref ((SkinDef)modelSwappedSkinDef).icon;
				Texture portraitIcon = body.portraitIcon;
				icon = SkinIconGenerator.GetOrCreateSkinIcon((Texture2D)(object)((portraitIcon is Texture2D) ? portraitIcon : null), baseSkin);
				modelSwappedSkinDef.Initialize(_survivorPartsProvider, bodyModelPartsProvider);
				modelSwappedSkinDef.NewModelBodyPrefab = body;
				modelSwappedSkinDef.NewModelTransformPrefab = modelTransform;
				modelSwappedSkinDef.ModelSkin = baseSkin;
				return modelSwappedSkinDef;
			}
		}
	}
}
namespace ModelSwapperSkins.Utils
{
	public static class ArrayUtil
	{
		public static void Append<T>(ref T[] array, IEnumerable<T> collection)
		{
			if (array == null)
			{
				throw new ArgumentNullException("array");
			}
			if (collection == null)
			{
				throw new ArgumentNullException("collection");
			}
			T[] array2 = collection.ToArray();
			if (array2.Length != 0)
			{
				int num = array.Length;
				Array.Resize(ref array, num + array2.Length);
				Array.Copy(array2, 0, array, num, array2.Length);
			}
		}
	}
	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
	{
		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();
		}

		public static IEnumerable<Transform> GetAllChildrenRecursive(Transform root)
		{
			yield return root;
			for (int i = 0; i < root.childCount; i++)
			{
				foreach (Transform item in GetAllChildrenRecursive(root.GetChild(i)))
				{
					yield return item;
				}
			}
		}
	}
	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 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.Patches
{
	internal static class CreateModelOnApplySkin
	{
		private class SkinModelObjectTracker : MonoBehaviour
		{
			public ModelSwappedSkinDef AppliedSkin;

			public GameObject SkinModelObject;

			private void OnDestroy()
			{
				if (Object.op_Implicit((Object)(object)SkinModelObject))
				{
					Object.Destroy((Object)(object)SkinModelObject);
				}
			}
		}

		[CompilerGenerated]
		private static class <>O
		{
			public static hook_Apply <0>__SkinDef_Apply;
		}

		[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_Apply;
			if (obj == null)
			{
				hook_Apply val = SkinDef_Apply;
				<>O.<0>__SkinDef_Apply = val;
				obj = (object)val;
			}
			SkinDef.Apply += (hook_Apply)obj;
		}

		private static void SkinDef_Apply(orig_Apply orig, SkinDef self, GameObject modelObject)
		{
			SkinModelObjectTracker skinModelObjectTracker = default(SkinModelObjectTracker);
			if (modelObject.TryGetComponent<SkinModelObjectTracker>(ref skinModelObjectTracker))
			{
				skinModelObjectTracker.AppliedSkin.RemoveFrom(modelObject.transform, skinModelObjectTracker.SkinModelObject);
				Object.Destroy((Object)(object)skinModelObjectTracker);
			}
			orig.Invoke(self, modelObject);
			if (self is ModelSwappedSkinDef modelSwappedSkinDef)
			{
				Transform val = modelSwappedSkinDef.OnAppliedTo(modelObject.transform);
				SkinModelObjectTracker skinModelObjectTracker2 = modelObject.AddComponent<SkinModelObjectTracker>();
				skinModelObjectTracker2.SkinModelObject = ((Component)val).gameObject;
				skinModelObjectTracker2.AppliedSkin = modelSwappedSkinDef;
			}
		}
	}
	internal static class FixMissingSkinPathsPatch
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static hook_Apply <0>__RuntimeSkin_Apply;
		}

		[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_Apply;
			if (obj == null)
			{
				hook_Apply val = RuntimeSkin_Apply;
				<>O.<0>__RuntimeSkin_Apply = val;
				obj = (object)val;
			}
			RuntimeSkin.Apply += (hook_Apply)obj;
		}

		private static void RuntimeSkin_Apply(orig_Apply orig, object self, GameObject modelObject)
		{
			RuntimeSkin val = (RuntimeSkin)((self is RuntimeSkin) ? self : null);
			if (val != null)
			{
				Transform transform = modelObject.transform;
				if (val.gameObjectActivationTemplates != null)
				{
					for (int num = val.gameObjectActivationTemplates.Length - 1; num >= 0; num--)
					{
						if (!Object.op_Implicit((Object)(object)transform.Find(val.gameObjectActivationTemplates[num].path)))
						{
							ArrayUtils.ArrayRemoveAtAndResize<GameObjectActivationTemplate>(ref val.gameObjectActivationTemplates, num, 1);
						}
					}
				}
				if (val.meshReplacementTemplates != null)
				{
					for (int num2 = val.meshReplacementTemplates.Length - 1; num2 >= 0; num2--)
					{
						if (!Object.op_Implicit((Object)(object)transform.Find(val.meshReplacementTemplates[num2].path)))
						{
							ArrayUtils.ArrayRemoveAtAndResize<MeshReplacementTemplate>(ref val.meshReplacementTemplates, num2, 1);
						}
					}
				}
			}
			orig.Invoke(self, modelObject);
		}
	}
}
namespace ModelSwapperSkins.ModelParts
{
	[Serializable]
	public class ModelPart
	{
		public ModelPartFlags Flags;

		public Transform Transform;

		public string Path;

		public ModelPart(Transform transform, Transform root, ModelPartFlags type)
			: this(transform, type, TransformUtils.GetObjectPath(transform, root))
		{
		}

		public ModelPart(Transform transform, ModelPartFlags type, string path)
		{
			Flags = type;
			Transform = transform;
			Path = path;
		}

		public bool ShouldShow(bool isMainModel)
		{
			if (isMainModel)
			{
				return (Flags & ModelPartFlags.ShowForMain) != 0;
			}
			return (Flags & ModelPartFlags.ShowForSkin) != 0;
		}
	}
	[Flags]
	public enum ModelPartFlags : byte
	{
		None = 0,
		ShowForSkin = 1,
		ShowForMain = 2,
		AlwaysShow = 3,
		Body = 1,
		Weapon = 2,
		Decoration = 2,
		BodyFeature = 3
	}
	public static class ModelPartsInitializer
	{
		public readonly record struct ModelPartConstructor(string ModelPath, ModelPartFlags Type)
		{
			public ModelPart Construct(Transform modelTransform)
			{
				Transform obj = modelTransform.Find(ModelPath);
				if (!Object.op_Implicit((Object)(object)obj))
				{
					Log.Warning($"Could not find object at path \"{ModelPath}\" relative to {modelTransform}", "X:\\Git\\RoR2\\ModelSwapperSkins\\ModelSwapperSkins\\ModelParts\\ModelPartsInitializer.cs", "Construct", 20);
				}
				return new ModelPart(obj, Type, ModelPath);
			}
		}

		public static void OverrideParts(string bodyPrefabPath, params ModelPartConstructor[] partOverrides)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			if (partOverrides.Length != 0)
			{
				GameObject val = Addressables.LoadAssetAsync<GameObject>((object)bodyPrefabPath).WaitForCompletion();
				if (!Object.op_Implicit((Object)(object)val))
				{
					Log.Warning(bodyPrefabPath + " is not a valid GameObject asset", "X:\\Git\\RoR2\\ModelSwapperSkins\\ModelSwapperSkins\\ModelParts\\ModelPartsInitializer.cs", "OverrideParts", 35);
				}
				else
				{
					OverrideParts(val, partOverrides);
				}
			}
		}

		public static void OverrideParts(GameObject bodyPrefab, params ModelPartConstructor[] partOverrides)
		{
			if (partOverrides.Length == 0)
			{
				return;
			}
			if (!Object.op_Implicit((Object)(object)bodyPrefab))
			{
				throw new ArgumentNullException("bodyPrefab");
			}
			ModelLocator val = default(ModelLocator);
			if (!bodyPrefab.TryGetComponent<ModelLocator>(ref val))
			{
				Log.Warning($"{bodyPrefab} has no ModelLocator component", "X:\\Git\\RoR2\\ModelSwapperSkins\\ModelSwapperSkins\\ModelParts\\ModelPartsInitializer.cs", "OverrideParts", 54);
				return;
			}
			Transform modelTransform = val.modelTransform;
			if (!Object.op_Implicit((Object)(object)modelTransform))
			{
				Log.Warning($"{bodyPrefab} has no model transform", "X:\\Git\\RoR2\\ModelSwapperSkins\\ModelSwapperSkins\\ModelParts\\ModelPartsInitializer.cs", "OverrideParts", 61);
				return;
			}
			ModelPart[] array = (from p in partOverrides
				select p.Construct(modelTransform) into p
				where Object.op_Implicit((Object)(object)p.Transform)
				select p).ToArray();
			ModelPartsProvider partsProvider = default(ModelPartsProvider);
			if (((Component)modelTransform).TryGetComponent<ModelPartsProvider>(ref partsProvider))
			{
				List<ModelPart> list = array.ToList();
				list.RemoveAll(delegate(ModelPart part)
				{
					int num = Array.FindIndex(partsProvider.Parts, (ModelPart p) => (Object)(object)p.Transform == (Object)(object)part.Transform);
					if (num == -1)
					{
						return false;
					}
					ModelPart modelPart = partsProvider.Parts[num];
					if (part.Flags != modelPart.Flags)
					{
						modelPart.Flags = part.Flags;
					}
					else
					{
						Log.Info($"Unnecessary override of model part {part.Path} ({part.Flags}) for {((Object)modelTransform).name} ({((Object)bodyPrefab).name})", "X:\\Git\\RoR2\\ModelSwapperSkins\\ModelSwapperSkins\\ModelParts\\ModelPartsInitializer.cs", "OverrideParts", 88);
					}
					return true;
				});
				if (list.Count > 0)
				{
					ArrayUtil.Append(ref partsProvider.Parts, list);
				}
			}
			else
			{
				partsProvider = ((Component)modelTransform).gameObject.AddComponent<ModelPartsProvider>();
				partsProvider.Parts = array;
			}
			List<ModelPart> list2 = partsProvider.Parts.ToList();
			if (list2.RemoveAll((ModelPart p) => p.Flags == ModelPartFlags.None) > 0)
			{
				partsProvider.Parts = list2.ToArray();
			}
		}

		[SystemInitializer(new Type[]
		{
			typeof(BodyCatalog),
			typeof(SurvivorCatalog)
		})]
		private static void Init()
		{
			CharacterModel characterModel = default(CharacterModel);
			foreach (CharacterBody allBodyPrefabBodyBodyComponent in BodyCatalog.allBodyPrefabBodyBodyComponents)
			{
				if (!Object.op_Implicit((Object)(object)allBodyPrefabBodyBodyComponent))
				{
					continue;
				}
				ModelLocator component = ((Component)allBodyPrefabBodyBodyComponent).GetComponent<ModelLocator>();
				if (!Object.op_Implicit((Object)(object)component))
				{
					continue;
				}
				Transform modelTransform = component.modelTransform;
				if (!Object.op_Implicit((Object)(object)modelTransform) || Object.op_Implicit((Object)(object)((Component)modelTransform).GetComponent<ModelPartsProvider>()))
				{
					continue;
				}
				ModelPartsProvider modelPartsProvider = ((Component)modelTransform).gameObject.AddComponent<ModelPartsProvider>();
				IEnumerable<ModelPart> enumerable = Enumerable.Empty<ModelPart>();
				if (((Component)modelTransform).TryGetComponent<CharacterModel>(ref characterModel))
				{
					if (characterModel.baseRendererInfos != null)
					{
						enumerable = enumerable.Concat(from rendererInfo in characterModel.baseRendererInfos
							where Object.op_Implicit((Object)(object)rendererInfo.renderer)
							select new ModelPart(((Component)rendererInfo.renderer).transform, modelTransform, pickPartTypeFromComponent((Component)(object)rendererInfo.renderer)));
					}
					if (characterModel.baseLightInfos != null)
					{
						enumerable = enumerable.Concat(from lightInfo in characterModel.baseLightInfos
							where Object.op_Implicit((Object)(object)lightInfo.light)
							select new ModelPart(((Component)lightInfo.light).transform, modelTransform, pickPartTypeFromComponent((Component)(object)lightInfo.light)));
					}
				}
				if (!enumerable.Any())
				{
					enumerable = enumerable.Concat(from renderer in ((Component)modelTransform).GetComponentsInChildren<Renderer>()
						where !Object.op_Implicit((Object)(object)characterModel) || characterModel.baseRendererInfos == null || !Array.Exists(characterModel.baseRendererInfos, (RendererInfo r) => (Object)(object)r.renderer == (Object)(object)renderer)
						select new ModelPart(((Component)renderer).transform, modelTransform, pickPartTypeFromComponent((Component)(object)renderer)));
					enumerable = enumerable.Concat(from light in ((Component)modelTransform).GetComponentsInChildren<Light>()
						where !Object.op_Implicit((Object)(object)characterModel) || characterModel.baseLightInfos == null || !Array.Exists(characterModel.baseLightInfos, (LightInfo l) => (Object)(object)l.light == (Object)(object)light)
						select new ModelPart(((Component)light).transform, modelTransform, pickPartTypeFromComponent((Component)(object)light)));
				}
				modelPartsProvider.Parts = enumerable.ToArray();
				SurvivorDef val = SurvivorCatalog.FindSurvivorDefFromBody(((Component)allBodyPrefabBodyBodyComponent).gameObject);
				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) && !Object.op_Implicit((Object)(object)((Component)componentInChildren).GetComponent<ModelPartsProvider>()))
					{
						ModelPartsProvider other = ((Component)componentInChildren).gameObject.AddComponent<ModelPartsProvider>();
						modelPartsProvider.CopyTo(other);
					}
				}
			}
			OverrideParts("RoR2/Junk/AncientWisp/AncientWispBody.prefab", new ModelPartConstructor("AncientWispArmature/Head/GameObject", ModelPartFlags.ShowForMain));
			OverrideParts("RoR2/Junk/Assassin/AssassinBody.prefab", new ModelPartConstructor("AssassinArmature/ROOT,CENTER/ROOT/base/stomach/chest/clavicle.l/upper_arm.l/lower_arm.l/hand.l/Dagger.l/AssassinDaggerMesh", ModelPartFlags.ShowForMain), new ModelPartConstructor("AssassinArmature/ROOT,CENTER/ROOT/base/stomach/chest/clavicle.r/upper_arm.r/lower_arm.r/hand.r/Dagger.r/AssassinDaggerMesh.001", ModelPartFlags.ShowForMain));
			OverrideParts("RoR2/Base/Drones/BackupDroneBody.prefab", new ModelPartConstructor("BackupDroneArmature/ROOT/Body/MissileDroneBladeActive/Blades", ModelPartFlags.AlwaysShow), new ModelPartConstructor("BackupDroneArmature/ROOT/Body/MissileDroneBladeActive/Blades", ModelPartFlags.AlwaysShow));
			OverrideParts("RoR2/Junk/BackupDroneOld/BackupDroneOldBody.prefab", new ModelPartConstructor("DroneBackupArmature/BladeRoot/BladeActive", ModelPartFlags.AlwaysShow), new ModelPartConstructor("DroneBackupArmature/BladeRoot (1)/BladeActive", ModelPartFlags.AlwaysShow), new ModelPartConstructor("DroneBackupArmature/BladeRoot (2)/BladeActive", ModelPartFlags.AlwaysShow));
			OverrideParts("RoR2/Base/Bandit2/Bandit2Body.prefab", new ModelPartConstructor("Bandit2AccessoriesMesh", ModelPartFlags.AlwaysShow), new ModelPartConstructor("BanditArmature/ROOT/base/MainWeapon/BanditShotgunMesh", ModelPartFlags.ShowForMain), new ModelPartConstructor("BanditArmature/SideWeapon/SideWeaponSpinner/BanditPistolMesh", ModelPartFlags.ShowForMain), new ModelPartConstructor("BanditArmature/ROOT/base/stomach/chest/clavicle.l/upper_arm.l/lower_arm.l/hand.l/BladeMesh", ModelPartFlags.None));
			OverrideParts("RoR2/Junk/Bandit/BanditBody.prefab", new ModelPartConstructor("BanditArmature/ROOT/base/stomach/BanditPistolMeshHip", ModelPartFlags.ShowForMain), new ModelPartConstructor("BanditArmature/ROOT/base/stomach/chest/upper_arm.l/lower_arm.l/hand.l/ShotgunBone/BanditShotgunMesh", ModelPartFlags.ShowForMain));
			OverrideParts("RoR2/Base/Beetle/BeetleWard.prefab", new ModelPartConstructor("Indicator", ModelPartFlags.ShowForMain));
			OverrideParts("RoR2/Base/Brother/BrotherBody.prefab", new ModelPartConstructor("BrotherClothPieces", ModelPartFlags.AlwaysShow), new ModelPartConstructor("BrotherHammerConcrete", ModelPartFlags.ShowForMain), new ModelPartConstructor("BrotherArmature/ROOT/base/stomach/chest/clavicle.l/upper_arm.l/BrotherShoulderArmor", ModelPartFlags.AlwaysShow));
			OverrideParts("RoR2/Junk/BrotherGlass/BrotherGlassBody.prefab", new ModelPartConstructor("BrotherHammerConcrete", ModelPartFlags.ShowForMain));
			OverrideParts("RoR2/Base/Brother/BrotherHurtBody.prefab", new ModelPartConstructor("BrotherClothPieces", ModelPartFlags.AlwaysShow), new ModelPartConstructor("BrotherArmature/ROOT/base/stomach/chest/clavicle.l/upper_arm.l/BrotherShoulderArmor", ModelPartFlags.AlwaysShow));
			OverrideParts("RoR2/Base/Captain/CaptainBody.prefab", new ModelPartConstructor("CaptainGunArm", ModelPartFlags.AlwaysShow));
			OverrideParts("RoR2/Junk/ClayMan/ClayBody.prefab", new ModelPartConstructor("ClaymanArmature/ROOT/base/stomach/chest/clavicle.l/upper_arm.l/lower_arm.l/hand.l/shield/ClaymanShieldMesh", ModelPartFlags.ShowForMain), new ModelPartConstructor("ClaymanArmature/ROOT/base/stomach/chest/clavicle.r/upper_arm.r/lower_arm.r/hand.r/sword/ClaymanSwordMesh", ModelPartFlags.ShowForMain));
			OverrideParts("RoR2/Base/ClayBruiser/ClayBruiserBody.prefab", new ModelPartConstructor("ClayBruiserCannonMesh", ModelPartFlags.ShowForMain));
			OverrideParts("RoR2/Base/Commando/CommandoBody.prefab", new ModelPartConstructor("CommandoArmature/ROOT/base/stomach/chest/upper_arm.l/lower_arm.l/hand.l/gun.l/GunMesh.001", ModelPartFlags.ShowForMain), new ModelPartConstructor("CommandoArmature/ROOT/base/stomach/chest/upper_arm.r/lower_arm.r/hand.r/gun.r/GunMesh", ModelPartFlags.ShowForMain));
			OverrideParts("RoR2/Base/Croco/CrocoBody.prefab", new ModelPartConstructor("CrocoSpineMesh", ModelPartFlags.AlwaysShow));
			OverrideParts("RoR2/Base/Drones/Drone1Body.prefab", new ModelPartConstructor("Drone1BladeActive", ModelPartFlags.AlwaysShow));
			OverrideParts("RoR2/DLC1/DroneCommander/DroneCommanderBody.prefab", new ModelPartConstructor("mdlDroneHat", ModelPartFlags.AlwaysShow));
			OverrideParts("RoR2/Base/ElectricWorm/ElectricWormBody.prefab", new ModelPartConstructor("WormArmature/Head/PPVolume", ModelPartFlags.ShowForMain));
			OverrideParts("RoR2/Base/Drones/EquipmentDroneBody.prefab", new ModelPartConstructor("EquipmentDroneArmature/BladeOn/DroneBladeActive", ModelPartFlags.AlwaysShow), new ModelPartConstructor("EquipmentDroneArmature/BladeOn/DroneBladeActive", ModelPartFlags.AlwaysShow), new ModelPartConstructor("EquipmentDroneArmature/BladeOn/DroneBladeActive", ModelPartFlags.AlwaysShow));
			OverrideParts("RoR2/Base/Drones/FlameDroneBody.prefab", new ModelPartConstructor("BladeOn/DroneBladeActive", ModelPartFlags.AlwaysShow), new ModelPartConstructor("BladeOn/DroneBladeActive", ModelPartFlags.AlwaysShow));
			OverrideParts("RoR2/Base/Golem/GolemBody.prefab", new ModelPartConstructor("GolemArmature/ROOT/base/pelvis/thigh.l/Debris", ModelPartFlags.ShowForMain), new ModelPartConstructor("GolemArmature/ROOT/base/pelvis/thigh.r/Debris", ModelPartFlags.ShowForMain), new ModelPartConstructor("GolemArmature/ROOT/base/stomach/chest/upper_arm.l/Debris", ModelPartFlags.ShowForMain), new ModelPartConstructor("GolemArmature/ROOT/base/stomach/chest/upper_arm.l/upper_arm.l.001/Debris", ModelPartFlags.ShowForMain), new ModelPartConstructor("GolemArmature/ROOT/base/stomach/chest/upper_arm.r/Debris", ModelPartFlags.ShowForMain), new ModelPartConstructor("GolemArmature/ROOT/base/stomach/chest/upper_arm.r/upper_arm.r.001/upper_arm.r.002/Debris", ModelPartFlags.ShowForMain));
			OverrideParts("RoR2/Base/Grandparent/GrandParentBody.prefab", new ModelPartConstructor("GrandparentLowMesh", ModelPartFlags.ShowForMain));
			OverrideParts("RoR2/Base/Gravekeeper/GravekeeperBody.prefab", new ModelPartConstructor("GravekeeperMaskMesh", ModelPartFlags.AlwaysShow), new ModelPartConstructor("Sphere", ModelPartFlags.ShowForMain));
			OverrideParts("RoR2/Junk/HAND/HANDBody.prefab", new ModelPartConstructor("HANDArmature/hammerBone/HANDHammerMesh", ModelPartFlags.ShowForMain));
			OverrideParts("RoR2/Base/Huntress/HuntressBody.prefab", new ModelPartConstructor("BowString", ModelPartFlags.ShowForMain), new ModelPartConstructor("BowMesh", ModelPartFlags.ShowForMain), new ModelPartConstructor("HuntressArmature/ROOT/base/BowRoot/BowStringIKTarget/ArrowDisplay/Quad 1", ModelPartFlags.None), new ModelPartConstructor("HuntressArmature/ROOT/base/BowRoot/BowStringIKTarget/ArrowDisplay/Quad 2", ModelPartFlags.None), new ModelPartConstructor("HuntressArmature/ROOT/base/BowRoot/BowStringIKTarget/ArrowDisplay/Flash", ModelPartFlags.None), new ModelPartConstructor("HuntressArmature/ROOT/base/BowRoot/BowStringIKTarget/ArrowDisplay", ModelPartFlags.ShowForMain), new ModelPartConstructor("HuntressArmature/ROOT/base/BowRoot/BowStringIKTarget/ClusterArrowDisplay/Quad Cluster 1", ModelPartFlags.None), new ModelPartConstructor("HuntressArmature/ROOT/base/BowRoot/BowStringIKTarget/ClusterArrowDisplay/Quad Cluster 2", ModelPartFlags.None), new ModelPartConstructor("HuntressArmature/ROOT/base/BowRoot/BowStringIKTarget/ClusterArrowDisplay/Quad Cluster 3", ModelPartFlags.None), new ModelPartConstructor("HuntressArmature/ROOT/base/BowRoot/BowStringIKTarget/ClusterArrowDisplay/Quad Cluster 4", ModelPartFlags.None), new ModelPartConstructor("HuntressArmature/ROOT/base/BowRoot/BowStringIKTarget/ClusterArrowDisplay/Quad Cluster 5", ModelPartFlags.None), new ModelPartConstructor("HuntressArmature/ROOT/base/BowRoot/BowStringIKTarget/ClusterArrowDisplay", ModelPartFlags.ShowForMain));
			OverrideParts("RoR2/Base/Loader/LoaderBody.prefab", new ModelPartConstructor("LoaderMechMesh", ModelPartFlags.ShowForMain));
			OverrideParts("RoR2/Base/Mage/MageBody.prefab", new ModelPartConstructor("MageCapeMesh", ModelPartFlags.AlwaysShow));
			OverrideParts("RoR2/Base/Merc/MercBody.prefab", new ModelPartConstructor("MercSwordMesh", ModelPartFlags.ShowForMain));
			OverrideParts("RoR2/DLC1/Railgunner/RailgunnerBody.prefab", new ModelPartConstructor("mdlRailgunBackpackMesh", ModelPartFlags.ShowForMain), new ModelPartConstructor("mdlRailGunBackpackScreen", ModelPartFlags.ShowForMain), new ModelPartConstructor("RailGunnerArmature/ROOT/base/stomach/backpack/AllBackpackVFX Root/Idle/Monitor, Charging", ModelPartFlags.None), new ModelPartConstructor("RailGunnerArmature/ROOT/base/stomach/backpack/AllBackpackVFX Root", ModelPartFlags.ShowForMain), new ModelPartConstructor("mdlRailgunProto", ModelPartFlags.ShowForMain), new ModelPartConstructor("RailGunnerArmature/ROOT/base/GunRoot/GunBarrel/SMG/SMGBarrel/SMGLaser", ModelPartFlags.ShowForMain));
			OverrideParts("RoR2/Base/Scav/ScavBody.prefab", new ModelPartConstructor("ScavArmature/ROOT/base/WeaponParent/ScavWeaponMesh", ModelPartFlags.ShowForMain), new ModelPartConstructor("ScavBackpackMesh", ModelPartFlags.ShowForMain));
			OverrideParts("RoR2/Base/ScavLunar/ScavLunar1Body.prefab", new ModelPartConstructor("ScavArmature/ROOT/base/WeaponParent/ScavWeaponMesh", ModelPartFlags.ShowForMain), new ModelPartConstructor("ScavBackpackMesh", ModelPartFlags.ShowForMain));
			OverrideParts("RoR2/Base/ScavLunar/ScavLunar2Body.prefab", new ModelPartConstructor("ScavArmature/ROOT/base/WeaponParent/ScavWeaponMesh", ModelPartFlags.ShowForMain), new ModelPartConstructor("ScavBackpackMesh", ModelPartFlags.ShowForMain));
			OverrideParts("RoR2/Base/ScavLunar/ScavLunar3Body.prefab", new ModelPartConstructor("ScavArmature/ROOT/base/WeaponParent/ScavWeaponMesh", ModelPartFlags.ShowForMain), new ModelPartConstructor("ScavBackpackMesh", ModelPartFlags.ShowForMain));
			OverrideParts("RoR2/Base/ScavLunar/ScavLunar4Body.prefab", new ModelPartConstructor("ScavArmature/ROOT/base/WeaponParent/ScavWeaponMesh", ModelPartFlags.ShowForMain), new ModelPartConstructor("ScavBackpackMesh", ModelPartFlags.ShowForMain));
			OverrideParts("RoR2/Base/Titan/TitanGoldBody.prefab", new ModelPartConstructor("TitanArmature/ROOT/base/stomach/chest/upper_arm.r/lower_arm.r/hand.r/RightFist/Sword", ModelPartFlags.ShowForMain));
			OverrideParts("RoR2/Base/Treebot/TreebotBody.prefab", new ModelPartConstructor("TreebotFlowerMesh", ModelPartFlags.AlwaysShow), new ModelPartConstructor("TreebotRootMesh", ModelPartFlags.AlwaysShow));
			OverrideParts("RoR2/DLC1/VoidSurvivor/VoidSurvivorBody.prefab", new ModelPartConstructor("mdlVoidSurvivorMetal", ModelPartFlags.AlwaysShow), new ModelPartConstructor("metalcollar.001", ModelPartFlags.ShowForSkin));
			OverrideParts("RoR2/Base/Vulture/VultureBody.prefab", new ModelPartConstructor("VultureWingFeatherMesh", ModelPartFlags.ShowForMain), new ModelPartConstructor("VultureWingFeatherMeshSet2", ModelPartFlags.ShowForMain));
			static ModelPartFlags pickPartTypeFromComponent(Component behaviour)
			{
				if (behaviour is ParticleSystemRenderer || behaviour is TrailRenderer)
				{
					return ModelPartFlags.ShowForMain;
				}
				if (behaviour is Renderer)
				{
					return ModelPartFlags.ShowForSkin;
				}
				if (behaviour is Light)
				{
					return ModelPartFlags.ShowForMain;
				}
				return ModelPartFlags.ShowForSkin;
			}
		}
	}
	public class ModelPartsProvider : MonoBehaviour
	{
		public ModelPart[] Parts = Array.Empty<ModelPart>();

		public void CopyTo(ModelPartsProvider other)
		{
			other.Parts = (from p in Parts
				select new ModelPart(((Component)other).transform.Find(p.Path), p.Flags, p.Path) into p
				where Object.op_Implicit((Object)(object)p.Transform)
				select p).ToArray();
		}
	}
}
namespace ModelSwapperSkins.ModelInfos
{
	[Serializable]
	public record struct ModelInfo
	{
		public static readonly ModelInfo Default = new ModelInfo(1f);

		public float HeightScale;

		public ModelInfo(float HeightScale)
		{
			this.HeightScale = HeightScale;
		}

		[CompilerGenerated]
		public readonly void Deconstruct(out float HeightScale)
		{
			HeightScale = this.HeightScale;
		}
	}
	public static class ModelInfoInitializer
	{
		public static void AutoCalculateModelInfo(CharacterBody bodyPrefab)
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			ModelLocator val = default(ModelLocator);
			if (Object.op_Implicit((Object)(object)bodyPrefab) && ((Component)bodyPrefab).TryGetComponent<ModelLocator>(ref val))
			{
				Transform modelTransform = val.modelTransform;
				Bounds val2 = default(Bounds);
				if (!Object.op_Implicit((Object)(object)modelTransform))
				{
					Log.Warning($"{bodyPrefab} has no model transform", "X:\\Git\\RoR2\\ModelSwapperSkins\\ModelSwapperSkins\\ModelInfos\\ModelInfoInitializer.cs", "AutoCalculateModelInfo", 20);
				}
				else if (!Object.op_Implicit((Object)(object)((Component)modelTransform).GetComponent<ModelInfoProvider>()) && Util.GuessRenderBoundsMeshOnly(((Component)modelTransform).gameObject, ref val2))
				{
					float heightScale = (((Bounds)(ref val2)).max.y - ((Bounds)(ref val2)).min.y) / modelTransform.localScale.y;
					ModelInfo modelInfo = new ModelInfo(heightScale);
					SetModelInfo(bodyPrefab, modelInfo);
				}
			}
		}

		public static void SetModelInfo(string bodyName, ModelInfo modelInfo)
		{
			//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)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Invalid comparison between Unknown and I4
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			if (string.IsNullOrWhiteSpace(bodyName))
			{
				throw new ArgumentException("'bodyName' cannot be null or whitespace.", "bodyName");
			}
			BodyIndex val = BodyCatalog.FindBodyIndex(bodyName);
			if ((int)val != -1)
			{
				CharacterBody bodyPrefabBodyComponent = BodyCatalog.GetBodyPrefabBodyComponent(val);
				if (Object.op_Implicit((Object)(object)bodyPrefabBodyComponent))
				{
					SetModelInfo(bodyPrefabBodyComponent, modelInfo);
				}
			}
		}

		public static void SetModelInfo(CharacterBody bodyPrefab, ModelInfo modelInfo)
		{
			ModelLocator val = default(ModelLocator);
			if (!Object.op_Implicit((Object)(object)bodyPrefab) || !((Component)bodyPrefab).TryGetComponent<ModelLocator>(ref val))
			{
				return;
			}
			Transform modelTransform = val.modelTransform;
			if (!Object.op_Implicit((Object)(object)modelTransform))
			{
				Log.Warning($"{bodyPrefab} has no model transform", "X:\\Git\\RoR2\\ModelSwapperSkins\\ModelSwapperSkins\\ModelInfos\\ModelInfoInitializer.cs", "SetModelInfo", 70);
				return;
			}
			ModelInfoProvider modelInfoProvider = default(ModelInfoProvider);
			if (!((Component)modelTransform).TryGetComponent<ModelInfoProvider>(ref modelInfoProvider))
			{
				modelInfoProvider = ((Component)modelTransform).gameObject.AddComponent<ModelInfoProvider>();
			}
			modelInfoProvider.ModelInfo = modelInfo;
			SurvivorDef val2 = SurvivorCatalog.FindSurvivorDefFromBody(((Component)bodyPrefab).gameObject);
			if (!Object.op_Implicit((Object)(object)val2) || !Object.op_Implicit((Object)(object)val2.displayPrefab))
			{
				return;
			}
			CharacterModel componentInChildren = val2.displayPrefab.GetComponentInChildren<CharacterModel>();
			if (Object.op_Implicit((Object)(object)componentInChildren))
			{
				ModelInfoProvider other = default(ModelInfoProvider);
				if (!((Component)componentInChildren).TryGetComponent<ModelInfoProvider>(ref other))
				{
					other = ((Component)componentInChildren).gameObject.AddComponent<ModelInfoProvider>();
				}
				modelInfoProvider.CopyTo(other);
			}
		}

		public static bool TryGetModelInfo(BodyIndex bodyIndex, out ModelInfo modelInfo)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return TryGetModelInfo(BodyCatalog.GetBodyPrefabBodyComponent(bodyIndex), out modelInfo);
		}

		public static bool TryGetModelInfo(CharacterBody bodyPrefab, out ModelInfo modelInfo)
		{
			ModelLocator val = default(ModelLocator);
			if (Object.op_Implicit((Object)(object)bodyPrefab) && ((Component)bodyPrefab).TryGetComponent<ModelLocator>(ref val))
			{
				Transform modelTransform = val.modelTransform;
				ModelInfoProvider modelInfoProvider = default(ModelInfoProvider);
				if (Object.op_Implicit((Object)(object)modelTransform) && ((Component)modelTransform).TryGetComponent<ModelInfoProvider>(ref modelInfoProvider))
				{
					modelInfo = modelInfoProvider.ModelInfo;
					return true;
				}
			}
			modelInfo = default(ModelInfo);
			return false;
		}

		[SystemInitializer(new Type[]
		{
			typeof(BodyCatalog),
			typeof(SurvivorCatalog)
		})]
		private static void Init()
		{
			SetModelInfo("AcidLarvaBody", new ModelInfo(15f));
			SetModelInfo("AltarSkeletonBody", new ModelInfo(2f));
			SetModelInfo("BeetleQueen2Body", new ModelInfo(20f));
			SetModelInfo("BrotherBody", new ModelInfo(2f));
			SetModelInfo("BrotherGlassBody", new ModelInfo(2f));
			SetModelInfo("BrotherHurtBody", new ModelInfo(2f));
			SetModelInfo("ClayBruiserBody", new ModelInfo(3.7f));
			SetModelInfo("ClayGrenadierBody", new ModelInfo(3f));
			SetModelInfo("CrocoBody", new ModelInfo(22.5f));
			SetModelInfo("FlyingVerminBody", new ModelInfo(5f));
			SetModelInfo("GolemBody", new ModelInfo(5.5f));
			SetModelInfo("GrandParentBody", new ModelInfo(50f));
			SetModelInfo("HereticBody", new ModelInfo(4f));
			SetModelInfo("ImpBody", new ModelInfo(2f));
			SetModelInfo("ImpBossBody", new ModelInfo(12.5f));
			SetModelInfo("JellyfishBody", new ModelInfo(7.5f));
			SetModelInfo("LemurianBody", new ModelInfo(20f));
			SetModelInfo("LemurianBruiserBody", new ModelInfo(25f));
			SetModelInfo("LunarExploderBody", new ModelInfo(5f));
			SetModelInfo("MiniMushroomBody", new ModelInfo(4.5f));
			SetModelInfo("MiniVoidRaidCrabBodyBase", new ModelInfo(250f));
			SetModelInfo("NullifierBody", new ModelInfo(10f));
			SetModelInfo("NullifierAllyBody", new ModelInfo(10f));
			SetModelInfo("RailgunnerBody", new ModelInfo(2f));
			SetModelInfo("ToolbotBody", new ModelInfo(20f));
			SetModelInfo("TreebotBody", new ModelInfo(5f));
			SetModelInfo("VerminBody", new ModelInfo(5f));
			foreach (CharacterBody allBodyPrefabBodyBodyComponent in BodyCatalog.allBodyPrefabBodyBodyComponents)
			{
				AutoCalculateModelInfo(allBodyPrefabBodyBodyComponent);
			}
		}

		[ConCommand(commandName = "model_height_scale", helpText = "Overrides the height of a character's model. Used if the automatic scale calculation isn't correct. 1-2 arguments: [body name] (optional: [new height]). if no height is provided, the current height is printed to the console")]
		private static void CCModelHeightScale(ConCommandArgs args)
		{
			//IL_0008: 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_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Invalid comparison between Unknown and I4
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			((ConCommandArgs)(ref args)).CheckArgumentCount(1);
			BodyIndex argBodyIndex = ConCommandArgExtensions.GetArgBodyIndex(args, 0);
			if ((int)argBodyIndex == -1)
			{
				return;
			}
			CharacterBody bodyPrefabBodyComponent = BodyCatalog.GetBodyPrefabBodyComponent(argBodyIndex);
			if (!Object.op_Implicit((Object)(object)bodyPrefabBodyComponent))
			{
				return;
			}
			if (((ConCommandArgs)(ref args)).Count == 1)
			{
				if (TryGetModelInfo(bodyPrefabBodyComponent, out var modelInfo))
				{
					Debug.Log((object)$"{((Object)bodyPrefabBodyComponent).name} height scale: {modelInfo.HeightScale}");
				}
				else
				{
					Debug.Log((object)(((Object)bodyPrefabBodyComponent).name + " has no model info provider"));
				}
			}
			else
			{
				float argFloat = ((ConCommandArgs)(ref args)).GetArgFloat(1);
				SetModelInfo(bodyPrefabBodyComponent, new ModelInfo(argFloat));
			}
		}
	}
	public class ModelInfoProvider : MonoBehaviour
	{
		public ModelInfo ModelInfo;

		public void CopyTo(ModelInfoProvider other)
		{
			other.ModelInfo = ModelInfo;
		}

		public static ModelInfo GetModelInfo(GameObject obj)
		{
			ModelInfoProvider modelInfoProvider = default(ModelInfoProvider);
			if (!obj.TryGetComponent<ModelInfoProvider>(ref modelInfoProvider))
			{
				return ModelInfo.Default;
			}
			return modelInfoProvider.ModelInfo;
		}
	}
}
namespace ModelSwapperSkins.BoneMapping
{
	[Serializable]
	public class Bone : ICloneable
	{
		public BoneInfo Info;

		public Transform BoneTransform;

		public string ModelPath;

		public Bone(BoneInfo info, Transform boneTransform, string modelPath)
		{
			Info = info;
			BoneTransform = boneTransform;
			ModelPath = modelPath;
		}

		public Bone(Bone other)
			: this(other.Info, other.BoneTransform, other.ModelPath)
		{
		}

		public Bone(BoneInfo info, string modelPath, Transform rootTransform)
			: this(info, rootTransform.Find(modelPath), modelPath)
		{
		}

		public Bone(BoneInfo info, Transform rootTransform, Transform boneTransform)
			: this(info, boneTransform, TransformUtils.GetObjectPath(boneTransform, rootTransform))
		{
		}

		public Bone MakeCopyFor(BonesProvider displayBonesProvider)
		{
			return new Bone(Info, ModelPath, ((Component)displayBonesProvider).transform);
		}

		public Bone Clone()
		{
			return new Bone(this);
		}

		object ICloneable.Clone()
		{
			return Clone();
		}

		public override string ToString()
		{
			return $"{Info.Type} ({Info.MatchFlags}): {ModelPath}";
		}
	}
	[Serializable]
	public record struct BoneInfo
	{
		public readonly Matrix4x4 OffsetMatrix => Matrix4x4.TRS(PositionOffset, RotationOffset, Scale);

		public static readonly BoneInfo None = new BoneInfo(BoneType.None);

		public BoneType Type;

		public Vector3 PositionOffset;

		public Quaternion RotationOffset;

		public Vector3 Scale;

		public BoneMatchFlags MatchFlags;

		public BoneInfo(BoneType Type, Vector3 PositionOffset, Quaternion RotationOffset, Vector3 Scale)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			this.Type = Type;
			this.PositionOffset = PositionOffset;
			this.RotationOffset = RotationOffset;
			this.Scale = Scale;
			MatchFlags = BoneMatchFlags.AllowCompleteMatch;
		}

		public BoneInfo(BoneType type)
			: this(type, Vector3.zero, Quaternion.identity, Vector3.one)
		{
		}//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//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)


		[CompilerGenerated]
		private readonly bool PrintMembers(StringBuilder builder)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: 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_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			builder.Append("Type = ");
			builder.Append(Type.ToString());
			builder.Append(", PositionOffset = ");
			Vector3 val = PositionOffset;
			builder.Append(((object)(Vector3)(ref val)).ToString());
			builder.Append(", RotationOffset = ");
			Quaternion rotationOffset = RotationOffset;
			builder.Append(((object)(Quaternion)(ref rotationOffset)).ToString());
			builder.Append(", Scale = ");
			val = Scale;
			builder.Append(((object)(Vector3)(ref val)).ToString());
			builder.Append(", MatchFlags = ");
			builder.Append(MatchFlags.ToString());
			builder.Append(", OffsetMatrix = ");
			Matrix4x4 offsetMatrix = OffsetMatrix;
			builder.Append(((object)(Matrix4x4)(ref offsetMatrix)).ToString());
			return true;
		}

		[CompilerGenerated]
		public readonly void Deconstruct(out BoneType Type, out Vector3 PositionOffset, out Quaternion RotationOffset, out Vector3 Scale)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			Type = this.Type;
			PositionOffset = this.PositionOffset;
			RotationOffset = this.RotationOffset;
			Scale = this.Scale;
		}
	}
	public static class BoneInitializer
	{
		public static readonly BoneInitializerRules DefaultBoneRules = BoneInitializerRules_AutoName.Instance;

		private static readonly HashSet<BoneInitializerRules> _overrideInitializerRules = new HashSet<BoneInitializerRules>();

		public static void AddCustomBoneInitializerRules(BoneInitializerRules initializerRules)
		{
			if (!_overrideInitializerRules.Add(initializerRules))
			{
				Log.Warning($"Attempting to add duplicate initializer rules: {initializerRules}", "X:\\Git\\RoR2\\ModelSwapperSkins\\ModelSwapperSkins\\BoneMapping\\BoneInitializer.cs", "AddCustomBoneInitializerRules", 21);
			}
		}

		public static BoneInitializerRules FindInitializerRulesFor(BodyIndex bodyIndex)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			return _overrideInitializerRules.FirstOrDefault((BoneInitializerRules r) => r.AppliesTo(bodyIndex)) ?? DefaultBoneRules;
		}

		public static bool HasCustomIntializerRules(BodyIndex bodyIndex)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return FindInitializerRulesFor(bodyIndex) != DefaultBoneRules;
		}

		[SystemInitializer(new Type[] { typeof(BodyCatalog) })]
		private static void Init()
		{
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			AddCustomBoneInitializerRules(BoneInitializerRules_AcidLarva.Instance);
			AddCustomBoneInitializerRules(BoneInitializerRules_AltarSkeleton.Instance);
			AddCustomBoneInitializerRules(BoneInitializerRules_Assassin2.Instance);
			AddCustomBoneInitializerRules(BoneInitializerRules_Bandit2.Instance);
			AddCustomBoneInitializerRules(BoneInitializerRules_BeetleQueen2.Instance);
			AddCustomBoneInitializerRules(BoneInitializerRules_Bison.Instance);
			AddCustomBoneInitializerRules(BoneInitializerRules_Brother.Instance);
			AddCustomBoneInitializerRules(BoneInitializerRules_Captain.Instance);
			AddCustomBoneInitializerRules(BoneInitializerRules_ClayBruiser.Instance);
			AddCustomBoneInitializerRules(BoneInitializerRules_ClayGrenadier.Instance);
			AddCustomBoneInitializerRules(BoneInitializerRules_Clay.Instance);
			AddCustomBoneInitializerRules(BoneInitializerRules_Croco.Instance);
			AddCustomBoneInitializerRules(BoneInitializerRules_Engi.Instance);
			AddCustomBoneInitializerRules(BoneInitializerRules_FlyingVermin.Instance);
			AddCustomBoneInitializerRules(BoneInitializerRules_GrandParent.Instance);
			AddCustomBoneInitializerRules(BoneInitializerRules_Gravekeeper.Instance);
			AddCustomBoneInitializerRules(BoneInitializerRules_GreaterWisp.Instance);
			AddCustomBoneInitializerRules(BoneInitializerRules_Heretic.Instance);
			AddCustomBoneInitializerRules(BoneInitializerRules_HermitCrab.Instance);
			AddCustomBoneInitializerRules(BoneInitializerRules_Huntress.Instance);
			AddCustomBoneInitializerRules(BoneInitializerRules_Jellyfish.Instance);
			AddCustomBoneInitializerRules(BoneInitializerRules_Lemurian.Instance);
			AddCustomBoneInitializerRules(BoneInitializerRules_LemurianBruiser.Instance);
			AddCustomBoneInitializerRules(BoneInitializerRules_LunarExploder.Instance);
			AddCustomBoneInitializerRules(BoneInitializerRules_Mage.Instance);
			AddCustomBoneInitializerRules(BoneInitializerRules_Merc.Instance);
			AddCustomBoneInitializerRules(BoneInitializerRules_MiniMushroom.Instance);
			AddCustomBoneInitializerRules(BoneInitializerRules_MiniVoidRaidCrab.Instance);
			AddCustomBoneInitializerRules(BoneInitializerRules_Nullifier.Instance);
			AddCustomBoneInitializerRules(BoneInitializerRules_Parent.Instance);
			AddCustomBoneInitializerRules(BoneInitializerRules_Railgunner.Instance);
			AddCustomBoneInitializerRules(BoneInitializerRules_Scav.Instance);
			AddCustomBoneInitializerRules(BoneInitializerRules_Shopkeeper.Instance);
			AddCustomBoneInitializerRules(BoneInitializerRules_Toolbot.Instance);
			AddCustomBoneInitializerRules(BoneInitializerRules_Treebot.Instance);
			AddCustomBoneInitializerRules(BoneInitializerRules_Vermin.Instance);
			AddCustomBoneInitializerRules(BoneInitializerRules_VoidJailer.Instance);
			AddCustomBoneInitializerRules(BoneInitializerRules_VoidSurvivor.Instance);
			AddCustomBoneInitializerRules(BoneInitializerRules_Vulture.Instance);
			foreach (CharacterBody allBodyPrefabBodyBodyComponent in BodyCatalog.allBodyPrefabBodyBodyComponents)
			{
				BoneInitializerRules boneInitializerRules = FindInitializerRulesFor(allBodyPrefabBodyBodyComponent.bodyIndex);
				if (boneInitializerRules == DefaultBoneRules)
				{
					switch (((Object)allBodyPrefabBodyBodyComponent).name)
					{
					case "BeetleBody":
					case "BomberBody":
					case "SniperBody":
					case "AncientWispBody":
					case "BeetleCrystalBody":
					case "BeetleGuardCrystalBody":
					case "CommandoPerformanceTestBody":
					case "EnforcerBody":
					case "GolemBodyInvincible":
					case "VoidMegaCrabBody":
					case "VoidMegaCrabAllyBody":
						continue;
					}
				}
				initializeBones(allBodyPrefabBodyBodyComponent, boneInitializerRules);
			}
		}

		private static void initializeBones(CharacterBody bodyPrefab, BoneInitializerRules rules)
		{
			if (!Object.op_Implicit((Object)(object)bodyPrefab))
			{
				throw new ArgumentNullException("bodyPrefab");
			}
			if (rules == null)
			{
				throw new ArgumentNullException("rules");
			}
			ModelLocator val = default(ModelLocator);
			if (!((Component)bodyPrefab).TryGetComponent<ModelLocator>(ref val))
			{
				return;
			}
			Transform modelTransform = val.modelTransform;
			if (!Object.op_Implicit((Object)(object)modelTransform))
			{
				Log.Warning($"{bodyPrefab} has no model transform", "X:\\Git\\RoR2\\ModelSwapperSkins\\ModelSwapperSkins\\BoneMapping\\BoneInitializer.cs", "initializeBones", 128);
			}
			else
			{
				if (Object.op_Implicit((Object)(object)((Component)modelTransform).GetComponent<BonesProvider>()))
				{
					return;
				}
				BonesProvider bonesProvider = ((Component)modelTransform).gameObject.AddComponent<BonesProvider>();
				List<Bone> list = (from b in TransformUtils.GetAllChildrenRecursive(modelTransform).Select(delegate(Transform boneTransform)
					{
						BoneInfo boneInfo = rules.GetBoneInfo(modelTransform, boneTransform);
						return (boneInfo.Type == BoneType.None) ? null : new Bone(boneInfo, modelTransform, boneTransform);
					})
					where b != null
					select b).ToList();
				list.AddRange(rules.GetAdditionalBones(modelTransform, list));
				bonesProvider.Bones = list.ToArray();
				SurvivorDef val2 = SurvivorCatalog.FindSurvivorDefFromBody(((Component)bodyPrefab).gameObject);
				if (Object.op_Implicit((Object)(object)val2) && Object.op_Implicit((Object)(object)val2.displayPrefab))
				{
					CharacterModel componentInChildren = val2.displayPrefab.GetComponentInChildren<CharacterModel>();
					if (Object.op_Implicit((Object)(object)componentInChildren) && !Object.op_Implicit((Object)(object)((Component)componentInChildren).GetComponent<BonesProvider>()))
					{
						BonesProvider other = ((Component)componentInChildren).gameObject.AddComponent<BonesProvider>();
						bonesProvider.CopyTo(other);
					}
				}
			}
		}
	}
	[Flags]
	public enum BoneMatchFlags : byte
	{
		None = 0,
		MatchToOther = 1,
		AllowMatchTo = 2,
		AllowCompleteMatch = 3
	}
	public class BonesProvider : MonoBehaviour
	{
		[SerializeField]
		private BoneType[] _matchableBoneTypes;

		[SerializeField]
		private BoneType[] _canMatchToBoneTypes;

		[SerializeField]
		private Bone[] _bones;

		public Bone[] Bones
		{
			get
			{
				return _bones;
			}
			set
			{
				_bones = value;
				_matchableBoneTypes = (from b in (from b in value
						where (b.Info.MatchFlags & BoneMatchFlags.AllowMatchTo) != 0
						select b.Info.Type).Distinct()
					orderby b
					select b).ToArray();
				_canMatchToBoneTypes = (from b in (from b in value
						where (b.Info.MatchFlags & BoneMatchFlags.MatchToOther) != 0
						select b.Info.Type).Distinct()
					orderby b
					select b).ToArray();
			}
		}

		public bool HasMatchForBone(BoneType boneType)
		{
			return Array.BinarySearch(_matchableBoneTypes, boneType) >= 0;
		}

		public bool CanMatchToBone(BoneType boneType)
		{
			return Array.BinarySearch(_canMatchToBoneTypes, boneType) >= 0;
		}

		public void MapBonesTo(BonesProvider other)
		{
			List<MatchBoneTransform> list = new List<MatchBoneTransform>();
			Bone[] bones = Bones;
			foreach (Bone bone in bones)
			{
				if ((bone.Info.MatchFlags & BoneMatchFlags.MatchToOther) != 0)
				{
					Bone bone2 = other.Bones.FirstOrDefault((Bone b) => (b.Info.MatchFlags & BoneMatchFlags.AllowMatchTo) != 0 && b.Info.Type == bone.Info.Type);
					if (bone2 != null)
					{
						MatchBoneTransform matchBoneTransform = ((Component)bone.BoneTransform).gameObject.AddComponent<MatchBoneTransform>();
						matchBoneTransform.Bone = bone;
						matchBoneTransform.TargetBone = bone2;
						list.Add(matchBoneTransform);
					}
				}
			}
			foreach (MatchBoneTransform item in list)
			{
				Transform val = item.Bone?.BoneTransform;
				if (!Object.op_Implicit((Object)(object)val))
				{
					continue;
				}
				Transform parent = val.parent;
				if (Object.op_Implicit((Object)(object)parent))
				{
					MatchBoneTransform componentInParent = ((Component)parent).GetComponentInParent<MatchBoneTransform>();
					if (Object.op_Implicit((Object)(object)componentInParent))
					{
						item.ParentBone = componentInParent;
					}
				}
			}
		}

		public void CopyTo(BonesProvider other)
		{
			other.Bones = (from b in Bones
				select b.MakeCopyFor(other) into b
				where Object.op_Implicit((Object)(object)b.BoneTransform)
				select b).ToArray();
		}
	}
	public enum BoneType : byte
	{
		None,
		Root,
		Base,
		Pelvis,
		LegUpperL,
		LegLowerL,
		FootL,
		Toe1L,
		Toe2L,
		Toe3L,
		LegUpperR,
		LegLowerR,
		FootR,
		Toe1R,
		Toe2R,
		Toe3R,
		Stomach,
		Chest,
		Neck1,
		Neck2,
		Neck3,
		Neck4,
		Neck5,
		Neck6,
		Neck7,
		Neck8,
		Neck9,
		Neck10,
		Neck11,
		Neck12,
		Neck13,
		Neck14,
		Neck15,
		Neck16,
		Head,
		Jaw,
		Tongue1,
		Tongue2,
		Tongue3,
		Tongue4,
		ShoulderL,
		ArmUpperL,
		ArmLowerL,
		HandL,
		HandPalmL,
		IndexFinger1L,
		IndexFinger2L,
		IndexFinger3L,
		MiddleFinger1L,
		MiddleFinger2L,
		MiddleFinger3L,
		RingFinger1L,
		RingFinger2L,
		RingFinger3L,
		PinkyFinger1L,
		PinkyFinger2L,
		PinkyFinger3L,
		Thumb1L,
		Thumb2L,
		Thumb2L_end,
		ShoulderR,
		ArmUpperR,
		ArmLowerR,
		HandR,
		HandR_end,
		HandPalmR,
		IndexFinger1R,
		IndexFinger2R,
		IndexFinger3R,
		MiddleFinger1R,
		MiddleFinger2R,
		MiddleFinger3R,
		RingFinger1R,
		RingFinger2R,
		RingFinger3R,
		PinkyFinger1R,
		PinkyFinger2R,
		PinkyFinger3R,
		Thumb1R,
		Thumb2R,
		Tail1,
		Tail2,
		Tail3,
		Tail4,
		Tail5,
		Tail6,
		Tail7
	}
	public class MatchBoneTransform : MonoBehaviour
	{
		private Transform _boneTransform;

		private Bone _bone;

		private Transform _targetTransform;

		private Bone _targetBone;

		private MatchBoneTransform _parentBone;

		private Vector3 _localTargetPositionOffset;

		private Quaternion _localTargetRotationOffset;

		private Vector3 _localTargetScaleMultiplier;

		private Vector3 _baseLocalScale;

		public Bone Bone
		{
			get
			{
				return _bone;
			}
			set
			{
				//IL_0030: Unknown result type (might be due to invalid IL or missing references)
				//IL_0035: Unknown result type (might be due to invalid IL or missing references)
				if (_bone != value)
				{
					_bone = value;
					_boneTransform = _bone?.BoneTransform;
					_baseLocalScale = _boneTransform.localScale;
					recalculateOffsets();
				}
			}
		}

		public Bone TargetBone
		{
			get
			{
				return _targetBone;
			}
			set
			{
				if (_targetBone != value)
				{
					_targetBone = value;
					_targetTransform = _targetBone?.BoneTransform;
					recalculateOffsets();
				}
			}
		}

		public MatchBoneTransform ParentBone
		{
			get
			{
				return _parentBone;
			}
			set
			{
				if (!((Object)(object)_parentBone == (Object)(object)value))
				{
					_parentBone = value;
					recalculateOffsets();
				}
			}
		}

		private Vector3 calculateTargetScaleMultiplier()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			Vector3 a = ((_targetBone != null) ? _targetBone.Info.Scale : Vector3.one);
			Vector3 b = ((_bone != null) ? _bone.Info.Scale : Vector3.one);
			return VectorUtils.Divide(a, b);
		}

		private void Awake()
		{
			recalculateOffsets();
		}

		private void recalculateOffsets()
		{
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: 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_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			if (_targetBone != null && _bone != null)
			{
				_localTargetPositionOffset = _targetBone.Info.PositionOffset - _bone.Info.PositionOffset;
				_localTargetRotationOffset = _targetBone.Info.RotationOffset * Quaternion.Inverse(_bone.Info.RotationOffset);
				_localTargetScaleMultiplier = calculateTargetScaleMultiplier();
				if (Object.op_Implicit((Object)(object)ParentBone))
				{
					_localTargetScaleMultiplier = VectorUtils.Divide(_localTargetScaleMultiplier, ParentBone.calculateTargetScaleMultiplier());
				}
			}
			else
			{
				_localTargetPositionOffset = Vector3.zero;
				_localTargetRotationOffset = Quaternion.identity;
				_localTargetScaleMultiplier = Vector3.one;
			}
		}

		private void LateUpdate()
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: 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_00d0: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)_boneTransform) && Object.op_Implicit((Object)(object)_targetTransform))
			{
				Transform boneTransform = _boneTransform;
				Matrix4x4 val = Matrix4x4.Translate(_targetTransform.position) * (_targetTransform.localToWorldMatrix * Matrix4x4.Translate(_localTargetPositionOffset) * _targetTransform.worldToLocalMatrix);
				boneTransform.position = Vector4.op_Implicit(((Matrix4x4)(ref val)).GetColumn(3));
				Vector3 val2 = _targetTransform.TransformDirection(_localTargetRotationOffset * Vector3.forward);
				Vector3 val3 = _targetTransform.TransformDirection(_localTargetRotationOffset * Vector3.up);
				_boneTransform.rotation = Quaternion.LookRotation(val2, val3);
				_boneTransform.localScale = Vector3.Scale(_baseLocalScale, _localTargetScaleMultiplier);
			}
		}
	}
}
namespace ModelSwapperSkins.BoneMapping.InitializerRules
{
	public abstract class BoneInitializerRules
	{
		public abstract bool AppliesTo(BodyIndex bodyIndex);

		protected abstract BoneInfo getBoneInfo(Transform modelTransform, Transform potentialBoneTransform);

		public BoneInfo GetBoneInfo(Transform modelTransform, Transform potentialBoneTransform)
		{
			return getBoneInfo(modelTransform, potentialBoneTransform);
		}

		public virtual IEnumerable<Bone> GetAdditionalBones(Transform modelTransform, List<Bone> existingBones)
		{
			yield break;
		}
	}
	public sealed class BoneInitializerRules_AcidLarva : BoneInitializerRules
	{
		public static BoneInitializerRules_AcidLarva Instance { get; } = new BoneInitializerRules_AcidLarva();


		private BoneInitializerRules_AcidLarva()
		{
		}

		public override bool AppliesTo(BodyIndex bodyIndex)
		{
			//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 bodyIndex == BodyCatalog.FindBodyIndex("AcidLarvaBody");
		}

		protected override BoneInfo getBoneInfo(Transform modelTransform, Transform potentialBoneTransform)
		{
			//IL_0241: Unknown result type (might be due to invalid IL or missing references)
			//IL_0246: Unknown result type (might be due to invalid IL or missing references)
			//IL_025c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0261: Unknown result type (might be due to invalid IL or missing references)
			//IL_0282: Unknown result type (might be due to invalid IL or missing references)
			//IL_0287: Unknown result type (might be due to invalid IL or missing references)
			//IL_029d: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02eb: Unknown result type (might be due to invalid IL or missing references)
			switch (((Object)potentialBoneTransform).name)
			{
			case "Root":
				return new BoneInfo(BoneType.Root);
			case "BodyBase":
			{
				BoneInfo result = new BoneInfo(BoneType.Stomach);
				result.PositionOffset = new Vector3(0f, -0.2f, 0f);
				result.RotationOffset = Quaternion.Euler(90f, 0f, 0f);
				return result;
			}
			case "Beak.Lower":
			{
				BoneInfo result = new BoneInfo(BoneType.Head);
				result.PositionOffset = new Vector3(0f, 0f, -0.1f);
				result.RotationOffset = Quaternion.Euler(300f, 180f, 0f);
				result.MatchFlags = BoneMatchFlags.MatchToOther;
				return result;
			}
			case "Beak.Upper":
			{
				BoneInfo result = new BoneInfo(BoneType.Head);
				result.PositionOffset = new Vector3(0f, 0f, -0.1f);
				result.RotationOffset = Quaternion.Euler(305f, 180f, 0f);
				return result;
			}
			case "FrontLeg_Thigh1.L":
				return new BoneInfo(BoneType.ArmUpperL);
			case "FrontLeg_Calf.L":
				return new BoneInfo(BoneType.ArmLowerL);
			case "FrontLeg_Foot.L":
				return new BoneInfo(BoneType.HandL);
			case "FrontLeg_Thigh1.R":
				return new BoneInfo(BoneType.ArmUpperR);
			case "FrontLeg_Calf.R":
				return new BoneInfo(BoneType.ArmLowerR);
			case "FrontLeg_Foot.R":
				return new BoneInfo(BoneType.HandR);
			case "RearLeg_Thigh1.L":
				return new BoneInfo(BoneType.LegUpperL);
			case "RearLeg_Calf.L":
				return new BoneInfo(BoneType.LegLowerL);
			case "RearLeg_Foot.L":
				return new BoneInfo(BoneType.FootL);
			case "RearLeg_Thigh1.R":
				return new BoneInfo(BoneType.LegUpperR);
			case "RearLeg_Calf.R":
				return new BoneInfo(BoneType.LegLowerR);
			case "RearLeg_Foot.R":
				return new BoneInfo(BoneType.FootR);
			default:
				return BoneInfo.None;
			}
		}
	}
	public sealed class BoneInitializerRules_AltarSkeleton : BoneInitializerRules_AutoName
	{
		public new static BoneInitializerRules_AltarSkeleton Instance { get; } = new BoneInitializerRules_AltarSkeleton();


		private BoneInitializerRules_AltarSkeleton()
		{
		}

		public override bool AppliesTo(BodyIndex bodyIndex)
		{
			//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 bodyIndex == BodyCatalog.FindBodyIndex("AltarSkeletonBody");
		}

		protected override BoneInfo getBoneInfo(Transform modelTransform, Transform potentialBoneTransform)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			BoneInfo boneInfo = base.getBoneInfo(modelTransform, potentialBoneTransform);
			if (boneInfo.Type == BoneType.Head)
			{
				ref Vector3 positionOffset = ref boneInfo.PositionOffset;
				positionOffset += new Vector3(0f, -0.08f, 0f);
			}
			return boneInfo;
		}
	}
	public sealed class BoneInitializerRules_Assassin2 : BoneInitializerRules_AutoName
	{
		public new static BoneInitializerRules_Assassin2 Instance { get; } = new BoneInitializerRules_Assassin2();


		private BoneInitializerRules_Assassin2()
		{
		}

		public override bool AppliesTo(BodyIndex bodyIndex)
		{
			//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 bodyIndex == BodyCatalog.FindBodyIndex("Assassin2Body");
		}

		protected override BoneInfo getBoneInfo(Transform modelTransform, Transform potentialBoneTransform)
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f4: 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_041a: 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_0424: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0226: Unknown result type (might be due to invalid IL or missing references)
			//IL_023a: Unknown result type (might be due to invalid IL or missing references)
			//IL_023f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Unknown result type (might be due to invalid IL or missing references)
			//IL_0256: Unknown result type (might be due to invalid IL or missing references)
			//IL_026a: Unknown result type (might be due to invalid IL or missing references)
			//IL_026f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0274: Unknown result type (might be due to invalid IL or missing references)
			//IL_0286: Unknown result type (might be due to invalid IL or missing references)
			//IL_029a: Unknown result type (might be due to invalid IL or missing references)
			//IL_029f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0304: Unknown result type (might be due to invalid IL or missing references)
			//IL_0316: Unknown result type (might be due to invalid IL or missing references)
			//IL_032a: Unknown result type (might be due to invalid IL or missing references)
			//IL_032f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0334: Unknown result type (might be due to invalid IL or missing references)
			//IL_0346: Unknown result type (might be due to invalid IL or missing references)
			//IL_035a: Unknown result type (might be due to invalid IL or missing references)
			//IL_035f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0364: Unknown result type (might be due to invalid IL or missing references)
			//IL_0376: Unknown result type (might be due to invalid IL or missing references)
			//IL_038a: Unknown result type (might be due to invalid IL or missing references)
			//IL_038f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0394: Unknown result type (might be due to invalid