Decompiled source of SkinDetailPicker v2.0.1

DetailPicker.dll

Decompiled 6 months ago
using System;
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 BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using HG;
using HG.Reflection;
using IL.RoR2;
using LobbySkinsFix;
using Microsoft.CodeAnalysis;
using Mono.Cecil.Cil;
using MonoMod.Cil;
using MonoMod.RuntimeDetour;
using On.RoR2;
using On.RoR2.UI;
using Pathfinder.Components;
using R2API.Utils;
using RedGuyMod;
using RedGuyMod.Content.Components;
using RiskOfOptions;
using RiskOfOptions.Options;
using RiskOfRuinaMod.Modules;
using RiskOfRuinaMod.Modules.Components;
using RoR2;
using RoR2.Projectile;
using RoR2.Skills;
using RoR2.SurvivorMannequins;
using RoR2.UI;
using RoR2BepInExPack.Utilities;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Networking;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: OptIn]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: AssemblyCompany("DetailPicker")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+7d419db9e7e69fafc19c4ae46119fa0760e2284a")]
[assembly: AssemblyProduct("DetailPicker")]
[assembly: AssemblyTitle("DetailPicker")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace DetailPicker
{
	[BepInPlugin("xyz.yekoc.DetailPicker", "Skin Detail Picker", "2.0.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	public class SkinDetailPickerPlugin : BaseUnityPlugin
	{
		public class CharacterDetail<T>
		{
			public T detail;

			public SkinDef sourceSkin;

			public int index;

			public string path;

			public Action<GameObject> applyAction;
		}

		public class CharacterDetailCatalog
		{
			public Dictionary<BodyIndex, List<CharacterDetail<MinionSkinReplacement>>> minionSkins = new Dictionary<BodyIndex, List<CharacterDetail<MinionSkinReplacement>>>();

			public Dictionary<GameObject, List<CharacterDetail<ProjectileGhostReplacement>>> projectiles = new Dictionary<GameObject, List<CharacterDetail<ProjectileGhostReplacement>>>();

			public Dictionary<Renderer, List<CharacterDetail<RendererInfo>>> infoTs = new Dictionary<Renderer, List<CharacterDetail<RendererInfo>>>();

			public Dictionary<Renderer, List<CharacterDetail<MeshReplacement>>> meshTs = new Dictionary<Renderer, List<CharacterDetail<MeshReplacement>>>();

			public Dictionary<GameObject, List<CharacterDetail<bool>>> actT = new Dictionary<GameObject, List<CharacterDetail<bool>>>();
		}

		public class OverlaySkin
		{
			public SkinDef orig;

			public RuntimeSkin rSkin;

			public BodyIndex bodyIndex;

			public bool seperateMaterials;

			public List<MinionSkinReplacement> minions;

			public List<ProjectileGhostReplacement> projectiles;

			public int[] syncInfo;

			public Action<GameObject> onApply;

			public int FindIndex(int category)
			{
				return (syncInfo != null && category < syncInfo.Length) ? syncInfo[category] : 0;
			}

			public static void GenerateSyncFromSkinRows(ref int[] sync, SkinDef skin, IEnumerable<Row> detailRows)
			{
				int num = 0;
				foreach (Row item in detailRows.Reverse())
				{
					int num2 = item.buttons.FindIndex(delegate(MPButton b)
					{
						string overrideTitleText3 = ((Component)b).GetComponent<TooltipProvider>().overrideTitleText;
						return overrideTitleText3.Contains(Language.GetString(skin.nameToken));
					});
					if (num2 == -1 && skin.baseSkins.Any())
					{
						num2 = item.buttons.FindIndex(delegate(MPButton b)
						{
							string overrideTitleText2 = ((Component)b).GetComponent<TooltipProvider>().overrideTitleText;
							return overrideTitleText2.Contains(Language.GetString(skin.baseSkins.Last().nameToken));
						});
					}
					if (num2 == -1)
					{
						num2 = ((item.buttons.FindIndex(delegate(MPButton b)
						{
							string overrideTitleText = ((Component)b).GetComponent<TooltipProvider>().overrideTitleText;
							return overrideTitleText.Contains(Language.GetString("Disabled"));
						}) != -1) ? (-2) : (-1));
					}
					if (num2 != -1)
					{
						sync[rowCountStore - 1 - num] = num2;
						item.UpdateHighlightedChoice();
					}
					num++;
				}
			}

			public void BuildRSkin(int[] syncInfo)
			{
				//IL_0014: Unknown result type (might be due to invalid IL or missing references)
				//IL_0019: Unknown result type (might be due to invalid IL or missing references)
				//IL_0034: Unknown result type (might be due to invalid IL or missing references)
				//IL_004f: Unknown result type (might be due to invalid IL or missing references)
				//IL_006f: Expected O, but got Unknown
				//IL_0091: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
				//IL_022f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0a03: Unknown result type (might be due to invalid IL or missing references)
				//IL_06a4: Unknown result type (might be due to invalid IL or missing references)
				//IL_03b2: Unknown result type (might be due to invalid IL or missing references)
				//IL_03ca: Unknown result type (might be due to invalid IL or missing references)
				//IL_03cf: Unknown result type (might be due to invalid IL or missing references)
				//IL_0777: Unknown result type (might be due to invalid IL or missing references)
				//IL_078f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0794: Unknown result type (might be due to invalid IL or missing references)
				//IL_0848: Unknown result type (might be due to invalid IL or missing references)
				//IL_0860: Unknown result type (might be due to invalid IL or missing references)
				//IL_0865: Unknown result type (might be due to invalid IL or missing references)
				//IL_0bb0: Unknown result type (might be due to invalid IL or missing references)
				orig.Bake();
				rSkin = new RuntimeSkin
				{
					meshReplacementTemplates = ArrayUtils.Clone<MeshReplacementTemplate>(orig.runtimeSkin.meshReplacementTemplates),
					rendererInfoTemplates = ArrayUtils.Clone<RendererInfoTemplate>(orig.runtimeSkin.rendererInfoTemplates),
					gameObjectActivationTemplates = ArrayUtils.Clone<GameObjectActivationTemplate>(orig.runtimeSkin.gameObjectActivationTemplates)
				};
				minions.Clear();
				projectiles.Clear();
				onApply = null;
				int num = 0;
				SkinDef[] bodySkins = BodyCatalog.GetBodySkins(bodyIndex);
				if (!detailCatalog.ContainsKey(bodyIndex) || syncInfo.Length == 0)
				{
					minions.AddRange(orig.minionSkinReplacements);
					projectiles.AddRange(orig.projectileGhostReplacements);
					return;
				}
				CharacterDetailCatalog details = detailCatalog[bodyIndex];
				if (seperateMaterials)
				{
					foreach (KeyValuePair<Renderer, List<CharacterDetail<MeshReplacement>>> l in details.meshTs)
					{
						if (l.Value.Count <= 1)
						{
							continue;
						}
						int num2 = syncInfo[num];
						if (num2 >= l.Value.Count)
						{
							num++;
							continue;
						}
						if (num2 == -2 || (num2 == 0 && !bodySkins[0].meshReplacements.Any((MeshReplacement r) => (Object)(object)r.renderer == (Object)(object)l.Key)))
						{
							int num3 = Array.FindIndex(rSkin.meshReplacementTemplates, (MeshReplacementTemplate r) => r.path == l.Value[0].path);
							if (num3 != -1)
							{
								ArrayUtils.ArrayRemoveAtAndResize<MeshReplacementTemplate>(ref rSkin.meshReplacementTemplates, num3, 1);
							}
						}
						else
						{
							CharacterDetail<MeshReplacement> characterDetail = l.Value[num2];
							ref MeshReplacementTemplate[] meshReplacementTemplates = ref rSkin.meshReplacementTemplates;
							MeshReplacementTemplate val = new MeshReplacementTemplate
							{
								path = characterDetail.path,
								mesh = characterDetail.detail.mesh
							};
							ArrayUtils.ArrayAppend<MeshReplacementTemplate>(ref meshReplacementTemplates, ref val);
							onApply = (Action<GameObject>)Delegate.Combine(onApply, characterDetail.applyAction);
						}
						num++;
					}
					foreach (KeyValuePair<Renderer, List<CharacterDetail<RendererInfo>>> j in details.infoTs)
					{
						if (j.Value.Count <= 1)
						{
							continue;
						}
						int num4 = syncInfo[num];
						if (num4 >= j.Value.Count)
						{
							num++;
							continue;
						}
						int num5 = Array.FindIndex(rSkin.rendererInfoTemplates, (RendererInfoTemplate r) => r.path == j.Value[0].path);
						if (num5 != -1)
						{
							ArrayUtils.ArrayRemoveAtAndResize<RendererInfoTemplate>(ref rSkin.rendererInfoTemplates, num5, 1);
						}
						if (num4 != -2 && (num4 != 0 || bodySkins[0].rendererInfos.Any((RendererInfo r) => (Object)(object)r.renderer == (Object)(object)j.Key)))
						{
							CharacterDetail<RendererInfo> characterDetail2 = j.Value[num4];
							ref RendererInfoTemplate[] rendererInfoTemplates = ref rSkin.rendererInfoTemplates;
							RendererInfoTemplate val2 = new RendererInfoTemplate
							{
								path = characterDetail2.path,
								data = characterDetail2.detail
							};
							ArrayUtils.ArrayAppend<RendererInfoTemplate>(ref rendererInfoTemplates, ref val2);
							onApply = (Action<GameObject>)Delegate.Combine(onApply, characterDetail2.applyAction);
						}
						num++;
					}
				}
				else
				{
					foreach (Renderer r2 in details.meshTs.Keys.Union(details.infoTs.Keys).Distinct())
					{
						int num6 = 0;
						if (details.meshTs.ContainsKey(r2))
						{
							num6 += details.meshTs[r2].Count;
							int num7 = Array.FindIndex(rSkin.meshReplacementTemplates, (MeshReplacementTemplate t) => t.path == details.meshTs[r2][0].path);
							if (num7 != -1)
							{
								ArrayUtils.ArrayRemoveAtAndResize<MeshReplacementTemplate>(ref rSkin.meshReplacementTemplates, num7, 1);
							}
						}
						if (details.infoTs.ContainsKey(r2))
						{
							num6 += details.infoTs[r2].Count;
							int num8 = Array.FindIndex(rSkin.rendererInfoTemplates, (RendererInfoTemplate t) => t.path == details.infoTs[r2][0].path);
							if (num8 != -1)
							{
								ArrayUtils.ArrayRemoveAtAndResize<RendererInfoTemplate>(ref rSkin.rendererInfoTemplates, num8, 1);
							}
						}
						if (num6 <= 1)
						{
							continue;
						}
						int num9 = syncInfo[num];
						if (num9 != -2 && (num9 != 0 || bodySkins[0].meshReplacements.Any((MeshReplacement m) => (Object)(object)m.renderer == (Object)(object)r2) || bodySkins[0].rendererInfos.Any((RendererInfo i) => (Object)(object)i.renderer == (Object)(object)r2)))
						{
							SkinDef val3 = null;
							if (details.meshTs.ContainsKey(r2) && details.meshTs[r2].Count > num9)
							{
								CharacterDetail<MeshReplacement> repl = details.meshTs[r2][num9];
								val3 = repl.sourceSkin;
								ref MeshReplacementTemplate[] meshReplacementTemplates2 = ref rSkin.meshReplacementTemplates;
								MeshReplacementTemplate val = new MeshReplacementTemplate
								{
									path = repl.path,
									mesh = repl.detail.mesh
								};
								ArrayUtils.ArrayAppend<MeshReplacementTemplate>(ref meshReplacementTemplates2, ref val);
								onApply = (Action<GameObject>)Delegate.Combine(onApply, repl.applyAction);
								if (details.infoTs.ContainsKey(r2))
								{
									CharacterDetail<RendererInfo> characterDetail3 = details.infoTs[r2].FirstOrDefault((CharacterDetail<RendererInfo> i) => (Object)(object)i.sourceSkin == (Object)(object)repl.sourceSkin);
									if (Object.op_Implicit((Object)(object)characterDetail3.sourceSkin))
									{
										ref RendererInfoTemplate[] rendererInfoTemplates2 = ref rSkin.rendererInfoTemplates;
										RendererInfoTemplate val2 = new RendererInfoTemplate
										{
											path = characterDetail3.path,
											data = characterDetail3.detail
										};
										ArrayUtils.ArrayAppend<RendererInfoTemplate>(ref rendererInfoTemplates2, ref val2);
										onApply = (Action<GameObject>)Delegate.Combine(onApply, characterDetail3.applyAction);
									}
								}
							}
							else if (details.infoTs.ContainsKey(r2) && details.infoTs[r2].Count > num9)
							{
								CharacterDetail<RendererInfo> characterDetail4 = details.infoTs[r2][num9];
								ref RendererInfoTemplate[] rendererInfoTemplates3 = ref rSkin.rendererInfoTemplates;
								RendererInfoTemplate val2 = new RendererInfoTemplate
								{
									path = characterDetail4.path,
									data = characterDetail4.detail
								};
								ArrayUtils.ArrayAppend<RendererInfoTemplate>(ref rendererInfoTemplates3, ref val2);
								onApply = (Action<GameObject>)Delegate.Combine(onApply, characterDetail4.applyAction);
							}
						}
						num++;
					}
				}
				foreach (KeyValuePair<BodyIndex, List<CharacterDetail<MinionSkinReplacement>>> k in details.minionSkins)
				{
					int num10 = syncInfo[num];
					if (num10 >= k.Value.Count)
					{
						num++;
						continue;
					}
					if (num10 == -2)
					{
						minions.RemoveAll((MinionSkinReplacement r) => BodyCatalog.FindBodyIndex(r.minionBodyPrefab) == k.Key);
						foreach (CharacterDetail<MinionSkinReplacement> item in k.Value)
						{
							onApply = (Action<GameObject>)Delegate.Remove(onApply, item.applyAction);
							if (item.index == -2)
							{
								onApply = (Action<GameObject>)Delegate.Combine(onApply, item.applyAction);
							}
						}
					}
					else if (Object.op_Implicit((Object)(object)k.Value[num10].detail.minionSkin))
					{
						minions.Add(k.Value[num10].detail);
						onApply = (Action<GameObject>)Delegate.Combine(onApply, k.Value[num10].applyAction);
					}
					num++;
				}
				foreach (KeyValuePair<GameObject, List<CharacterDetail<ProjectileGhostReplacement>>> p in details.projectiles)
				{
					int num11 = syncInfo[num];
					if (num11 >= p.Value.Count)
					{
						num++;
						continue;
					}
					if (num11 == -2)
					{
						projectiles.RemoveAll((ProjectileGhostReplacement r) => (Object)(object)r.projectilePrefab == (Object)(object)p.Key);
						foreach (CharacterDetail<ProjectileGhostReplacement> item2 in p.Value)
						{
							onApply = (Action<GameObject>)Delegate.Remove(onApply, item2.applyAction);
							if (item2.index == -2)
							{
								onApply = (Action<GameObject>)Delegate.Combine(onApply, item2.applyAction);
							}
						}
					}
					else if (Object.op_Implicit((Object)(object)p.Value[num11].detail.projectileGhostReplacementPrefab))
					{
						projectiles.Add(p.Value[num11].detail);
						onApply = (Action<GameObject>)Delegate.Combine(onApply, p.Value[num11].applyAction);
					}
					num++;
				}
			}
		}

		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static Func<KeyValuePair<Renderer, List<CharacterDetail<MeshReplacement>>>, IEnumerable<CharacterDetail<MeshReplacement>>> <>9__20_0;

			public static Func<KeyValuePair<Renderer, List<CharacterDetail<RendererInfo>>>, IEnumerable<CharacterDetail<RendererInfo>>> <>9__20_2;

			public static Func<KeyValuePair<Renderer, List<CharacterDetail<MeshReplacement>>>, IEnumerable<CharacterDetail<MeshReplacement>>> <>9__22_3;

			public static Func<Instruction, bool> <>9__22_5;

			public static Func<Instruction, bool> <>9__22_6;

			public static Func<Component, bool> <>9__22_7;

			public static Func<Instruction, bool> <>9__22_8;

			public static Func<Instruction, bool> <>9__22_9;

			public static Func<Instruction, bool> <>9__22_10;

			public static hook_FindProjectileGhostPrefab <>9__24_0;

			public static Func<Instruction, bool> <>9__24_11;

			public static Func<MinionSkinReplacement[], MasterSummon, MinionSkinReplacement[]> <>9__24_10;

			public static Manipulator <>9__24_1;

			public static hook_Apply <>9__24_2;

			public static Func<Instruction, bool> <>9__24_13;

			public static Func<bool, BodyLoadoutManager, int, bool> <>9__24_12;

			public static Manipulator <>9__24_4;

			public static hook_Serialize <>9__24_6;

			public static hook_Deserialize <>9__24_7;

			public static hook_Copy <>9__24_8;

			internal IEnumerable<CharacterDetail<MeshReplacement>> <HandleRuina>b__20_0(KeyValuePair<Renderer, List<CharacterDetail<MeshReplacement>>> x)
			{
				return x.Value;
			}

			internal IEnumerable<CharacterDetail<RendererInfo>> <HandleRuina>b__20_2(KeyValuePair<Renderer, List<CharacterDetail<RendererInfo>>> x)
			{
				return x.Value;
			}

			internal IEnumerable<CharacterDetail<MeshReplacement>> <HandleRavager>b__22_3(KeyValuePair<Renderer, List<CharacterDetail<MeshReplacement>>> x)
			{
				return x.Value;
			}

			internal bool <HandleRavager>b__22_5(Instruction x)
			{
				return ILPatternMatchingExt.MatchStfld(x, typeof(RedGuyController).GetField("cachedSkinDef", (BindingFlags)(-1)));
			}

			internal bool <HandleRavager>b__22_6(Instruction x)
			{
				ILLabel val = default(ILLabel);
				return ILPatternMatchingExt.MatchBrfalse(x, ref val);
			}

			internal bool <HandleRavager>b__22_7(Component self)
			{
				return <HandleRavager>g__SmhWhyIsThisRequired|22_1(self);
			}

			internal bool <HandleRavager>b__22_8(Instruction x)
			{
				return ILPatternMatchingExt.MatchLdstr(x, "SwordElectricity");
			}

			internal bool <HandleRavager>b__22_9(Instruction x)
			{
				return ILPatternMatchingExt.MatchLdarg(x, 0);
			}

			internal bool <HandleRavager>b__22_10(Instruction x)
			{
				return ILPatternMatchingExt.MatchCallOrCallvirt(x, (MethodBase)typeof(ParticleSystemRenderer).GetProperty("trailMaterial").GetSetMethod());
			}

			internal GameObject <Awake>b__24_0(orig_FindProjectileGhostPrefab orig, ProjectileController projcontroller)
			{
				//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
				//IL_009c: Unknown result type (might be due to invalid IL or missing references)
				<>c__DisplayClass24_0 CS$<>8__locals0 = new <>c__DisplayClass24_0();
				GameObject val = orig.Invoke(projcontroller);
				CS$<>8__locals0.prefab = ProjectileCatalog.GetProjectilePrefab(projcontroller.catalogIndex);
				GameObject owner = projcontroller.owner;
				object obj;
				if (owner == null)
				{
					obj = null;
				}
				else
				{
					CharacterBody component = owner.GetComponent<CharacterBody>();
					obj = ((component == null) ? null : component.master?.loadout);
				}
				Loadout val2 = (Loadout)obj;
				OverlaySkin overlaySkin = default(OverlaySkin);
				ProjectileGhostReplacement? val3 = ((val2 == null || !networkOSkins.TryGetValue(val2, ref overlaySkin)) ? null : overlaySkin?.projectiles?.Find((ProjectileGhostReplacement p) => (Object)(object)p.projectilePrefab == (Object)(object)CS$<>8__locals0.prefab));
				return (val3.HasValue && Object.op_Implicit((Object)(object)val3.Value.projectilePrefab)) ? val3.Value.projectileGhostReplacementPrefab : val;
			}

			internal void <Awake>b__24_1(ILContext il)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Expected O, but got Unknown
				//IL_003d: Unknown result type (might be due to invalid IL or missing references)
				ILCursor val = new ILCursor(il);
				if (!val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1]
				{
					(Instruction x) => ILPatternMatchingExt.MatchLdfld(x, typeof(SkinDef).GetField("minionSkinReplacements"))
				}))
				{
					return;
				}
				val.Emit(OpCodes.Ldarg_0);
				val.EmitDelegate<Func<MinionSkinReplacement[], MasterSummon, MinionSkinReplacement[]>>((Func<MinionSkinReplacement[], MasterSummon, MinionSkinReplacement[]>)delegate(MinionSkinReplacement[] reps, MasterSummon self)
				{
					GameObject summonerBodyObject = self.summonerBodyObject;
					object obj;
					if (summonerBodyObject == null)
					{
						obj = null;
					}
					else
					{
						CharacterBody component = summonerBodyObject.GetComponent<CharacterBody>();
						obj = ((component == null) ? null : component.master?.loadout);
					}
					Loadout val2 = (Loadout)obj;
					OverlaySkin overlaySkin = default(OverlaySkin);
					return (val2 != null && networkOSkins.TryGetValue(val2, ref overlaySkin) && overlaySkin.minions != null) ? overlaySkin.minions.ToArray() : reps;
				});
			}

			internal bool <Awake>b__24_11(Instruction x)
			{
				return ILPatternMatchingExt.MatchLdfld(x, typeof(SkinDef).GetField("minionSkinReplacements"));
			}

			internal MinionSkinReplacement[] <Awake>b__24_10(MinionSkinReplacement[] reps, MasterSummon self)
			{
				GameObject summonerBodyObject = self.summonerBodyObject;
				object obj;
				if (summonerBodyObject == null)
				{
					obj = null;
				}
				else
				{
					CharacterBody component = summonerBodyObject.GetComponent<CharacterBody>();
					obj = ((component == null) ? null : component.master?.loadout);
				}
				Loadout val = (Loadout)obj;
				OverlaySkin overlaySkin = default(OverlaySkin);
				return (val != null && networkOSkins.TryGetValue(val, ref overlaySkin) && overlaySkin.minions != null) ? overlaySkin.minions.ToArray() : reps;
			}

			internal void <Awake>b__24_2(orig_Apply orig, SkinDef self, GameObject model)
			{
				orig.Invoke(self, model);
				CharacterModel component = model.GetComponent<CharacterModel>();
				object obj;
				if (component == null)
				{
					obj = null;
				}
				else
				{
					CharacterBody body = component.body;
					obj = ((body == null) ? null : body.master?.loadout);
				}
				Loadout val = (Loadout)obj;
				if (val == null)
				{
					val = model.GetComponentInParent<SurvivorMannequinSlotController>()?.currentLoadout;
					if (val != null)
					{
						bool flag = true;
					}
				}
				OverlaySkin overlaySkin = default(OverlaySkin);
				if (val != null && networkOSkins.TryGetValue(val, ref overlaySkin) && (Object)(object)overlaySkin.orig == (Object)(object)self)
				{
					RuntimeSkin rSkin = overlaySkin.rSkin;
					if (rSkin != null)
					{
						rSkin.Apply(model);
					}
					overlaySkin.onApply?.Invoke(model);
				}
			}

			internal void <Awake>b__24_4(ILContext il)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Expected O, but got Unknown
				//IL_003c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0048: Unknown result type (might be due to invalid IL or missing references)
				ILCursor val = new ILCursor(il);
				ILLabel val2 = default(ILLabel);
				if (val.TryGotoNext(new Func<Instruction, bool>[1]
				{
					(Instruction x) => ILPatternMatchingExt.MatchBrfalse(x, ref val2)
				}))
				{
					val.Emit(OpCodes.Ldarg_0);
					val.Emit(OpCodes.Ldarg_1);
					val.EmitDelegate<Func<bool, BodyLoadoutManager, int, bool>>((Func<bool, BodyLoadoutManager, int, bool>)((bool orig, BodyLoadoutManager self, int index) => orig && (!detailCatalog.ContainsKey(self.modifiedBodyLoadouts[index].bodyIndex) || oSkin.bodyIndex != self.modifiedBodyLoadouts[index].bodyIndex)));
				}
			}

			internal bool <Awake>b__24_13(Instruction x)
			{
				ILLabel val = default(ILLabel);
				return ILPatternMatchingExt.MatchBrfalse(x, ref val);
			}

			internal bool <Awake>b__24_12(bool orig, BodyLoadoutManager self, int index)
			{
				//IL_0010: Unknown result type (might be due to invalid IL or missing references)
				//IL_0021: Unknown result type (might be due to invalid IL or missing references)
				//IL_002e: Unknown result type (might be due to invalid IL or missing references)
				return orig && (!detailCatalog.ContainsKey(self.modifiedBodyLoadouts[index].bodyIndex) || oSkin.bodyIndex != self.modifiedBodyLoadouts[index].bodyIndex);
			}

			internal void <Awake>b__24_6(orig_Serialize orig, Loadout self, NetworkWriter writer)
			{
				//IL_002d: Unknown result type (might be due to invalid IL or missing references)
				//IL_005e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0068: Expected I4, but got Unknown
				//IL_006b: Unknown result type (might be due to invalid IL or missing references)
				orig.Invoke(self, writer);
				OverlaySkin orCreateValue = networkOSkins.GetOrCreateValue(self);
				if (orCreateValue == null || (Object)(object)orCreateValue.orig == (Object)null || !detailCatalog.ContainsKey(orCreateValue.bodyIndex) || orCreateValue.syncInfo.Length == 0)
				{
					writer.Write(-1);
					return;
				}
				writer.Write((int)orCreateValue.orig.skinIndex);
				NetworkExtensions.WriteBodyIndex(writer, orCreateValue.bodyIndex);
				writer.Write(orCreateValue.seperateMaterials);
				writer.Write(orCreateValue.syncInfo.Length);
				int[] syncInfo = orCreateValue.syncInfo;
				foreach (int num in syncInfo)
				{
					writer.Write(num);
				}
			}

			internal void <Awake>b__24_7(orig_Deserialize orig, Loadout self, NetworkReader reader)
			{
				//IL_0010: Unknown result type (might be due to invalid IL or missing references)
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				//IL_0013: Invalid comparison between Unknown and I4
				//IL_002c: 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_003e: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
				orig.Invoke(self, reader);
				SkinIndex val = (SkinIndex)reader.ReadInt32();
				if ((int)val != -1)
				{
					OverlaySkin orCreateValue = networkOSkins.GetOrCreateValue(self);
					orCreateValue.orig = SkinCatalog.GetSkinDef(val);
					orCreateValue.bodyIndex = NetworkExtensions.ReadBodyIndex(reader);
					orCreateValue.seperateMaterials = reader.ReadBoolean();
					int num = reader.ReadInt32();
					orCreateValue.syncInfo = new int[num];
					for (int i = 0; i < num; i++)
					{
						orCreateValue.syncInfo[i] = reader.ReadInt32();
					}
					orCreateValue.minions = new List<MinionSkinReplacement>();
					orCreateValue.projectiles = new List<ProjectileGhostReplacement>();
					if (detailCatalog.ContainsKey(orCreateValue.bodyIndex))
					{
						orCreateValue.BuildRSkin(orCreateValue.syncInfo);
					}
				}
			}

			internal void <Awake>b__24_8(orig_Copy orig, Loadout self, Loadout target)
			{
				orig.Invoke(self, target);
				OverlaySkin overlaySkin = default(OverlaySkin);
				if (networkOSkins.TryGetValue(self, ref overlaySkin))
				{
					networkOSkins.Remove(target);
					networkOSkins.Add(target, overlaySkin);
				}
			}
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass24_0
		{
			public GameObject prefab;

			internal bool <Awake>b__9(ProjectileGhostReplacement p)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				return (Object)(object)p.projectilePrefab == (Object)(object)prefab;
			}
		}

		public static Dictionary<BodyIndex, CharacterDetailCatalog> detailCatalog = new Dictionary<BodyIndex, CharacterDetailCatalog>();

		public static List<string> blacklist = new List<string> { "RobHunkBody" };

		public static bool lobbySkinFix = false;

		public static bool ravagerFix = false;

		public static bool pathfinderFix = false;

		public Sprite icon = LegacyResourcesAPI.Load<SkillDef>("SkillDefs/CaptainBody/CaptainSkillUsedUp").icon;

		public static FixedConditionalWeakTable<Loadout, OverlaySkin> networkOSkins = new FixedConditionalWeakTable<Loadout, OverlaySkin>();

		public ConfigEntry<bool> seperateMaterials;

		public static UserProfile localProfile;

		public List<Row> detailRows = new List<Row>();

		public static int rowCountStore;

		public static OverlaySkin oSkin
		{
			get
			{
				return networkOSkins.GetOrCreateValue(localProfile.loadout);
			}
			set
			{
				networkOSkins.Remove(localProfile.loadout);
				networkOSkins.Add(localProfile.loadout, value);
			}
		}

		[SystemInitializer(new Type[]
		{
			typeof(SurvivorCatalog),
			typeof(SkinCatalog)
		})]
		public static void CreateCatalog()
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: 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_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_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Unknown result type (might be due to invalid IL or missing references)
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: Unknown result type (might be due to invalid IL or missing references)
			//IL_024a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0278: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0547: Unknown result type (might be due to invalid IL or missing references)
			//IL_0679: Unknown result type (might be due to invalid IL or missing references)
			//IL_067e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0680: Unknown result type (might be due to invalid IL or missing references)
			//IL_0681: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0311: Unknown result type (might be due to invalid IL or missing references)
			//IL_068f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0695: Unknown result type (might be due to invalid IL or missing references)
			//IL_0327: Unknown result type (might be due to invalid IL or missing references)
			//IL_0329: Unknown result type (might be due to invalid IL or missing references)
			//IL_0350: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_06ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_06b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_070a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0388: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_06cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_06d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0401: Unknown result type (might be due to invalid IL or missing references)
			//IL_0428: Unknown result type (might be due to invalid IL or missing references)
			//IL_0637: Unknown result type (might be due to invalid IL or missing references)
			//IL_06e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_06ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0460: Unknown result type (might be due to invalid IL or missing references)
			foreach (SurvivorDef allSurvivorDef in SurvivorCatalog.allSurvivorDefs)
			{
				BodyIndex val = SurvivorCatalog.survivorIndexToBodyIndex[allSurvivorDef.survivorIndex];
				if (blacklist.Contains(((Object)allSurvivorDef.bodyPrefab).name) || detailCatalog.ContainsKey(val))
				{
					continue;
				}
				CharacterDetailCatalog characterDetailCatalog = new CharacterDetailCatalog();
				SkinDef[] bodySkinDefs = SkinCatalog.GetBodySkinDefs(val);
				SkinDef[] array = bodySkinDefs;
				foreach (SkinDef val2 in array)
				{
					string @string = Language.GetString(val2.nameToken);
					MinionSkinReplacement[] minionSkinReplacements = val2.minionSkinReplacements;
					foreach (MinionSkinReplacement val3 in minionSkinReplacements)
					{
						BodyIndex key = BodyCatalog.FindBodyIndex(val3.minionBodyPrefab);
						List<CharacterDetail<MinionSkinReplacement>> list = (characterDetailCatalog.minionSkins.ContainsKey(key) ? characterDetailCatalog.minionSkins[key] : new List<CharacterDetail<MinionSkinReplacement>>());
						list.Add(new CharacterDetail<MinionSkinReplacement>
						{
							detail = val3,
							sourceSkin = val2,
							index = list.Count
						});
						if (list.Count <= 1)
						{
							characterDetailCatalog.minionSkins.Add(key, list);
						}
					}
					ProjectileGhostReplacement[] projectileGhostReplacements = val2.projectileGhostReplacements;
					foreach (ProjectileGhostReplacement val4 in projectileGhostReplacements)
					{
						List<CharacterDetail<ProjectileGhostReplacement>> list2 = (characterDetailCatalog.projectiles.ContainsKey(val4.projectilePrefab) ? characterDetailCatalog.projectiles[val4.projectilePrefab] : new List<CharacterDetail<ProjectileGhostReplacement>>());
						list2.Add(new CharacterDetail<ProjectileGhostReplacement>
						{
							detail = val4,
							sourceSkin = val2,
							index = list2.Count
						});
						if (list2.Count <= 1)
						{
							characterDetailCatalog.projectiles.Add(val4.projectilePrefab, list2);
						}
					}
					GameObjectActivation[] gameObjectActivations = val2.gameObjectActivations;
					foreach (GameObjectActivation val5 in gameObjectActivations)
					{
						List<CharacterDetail<bool>> list3 = (characterDetailCatalog.actT.ContainsKey(val5.gameObject) ? characterDetailCatalog.actT[val5.gameObject] : new List<CharacterDetail<bool>>());
						list3.Add(new CharacterDetail<bool>
						{
							detail = val5.shouldActivate,
							sourceSkin = val2,
							index = list3.Count,
							path = Util.BuildPrefabTransformPath(val2.rootObject.transform, val5.gameObject.transform, false, false)
						});
						if (list3.Count <= 1)
						{
							characterDetailCatalog.actT.Add(val5.gameObject, list3);
						}
					}
					RendererInfo[] rendererInfos = val2.rendererInfos;
					foreach (RendererInfo val6 in rendererInfos)
					{
						List<CharacterDetail<RendererInfo>> list4 = (characterDetailCatalog.infoTs.ContainsKey(val6.renderer) ? characterDetailCatalog.infoTs[val6.renderer] : new List<CharacterDetail<RendererInfo>>());
						list4.Add(new CharacterDetail<RendererInfo>
						{
							detail = val6,
							sourceSkin = val2,
							index = list4.Count,
							path = Util.BuildPrefabTransformPath(val2.rootObject.transform, ((Component)val6.renderer).transform, false, false)
						});
						if (list4.Count <= 1)
						{
							characterDetailCatalog.infoTs.Add(val6.renderer, list4);
						}
					}
					MeshReplacement[] meshReplacements = val2.meshReplacements;
					foreach (MeshReplacement val7 in meshReplacements)
					{
						List<CharacterDetail<MeshReplacement>> list5 = (characterDetailCatalog.meshTs.ContainsKey(val7.renderer) ? characterDetailCatalog.meshTs[val7.renderer] : new List<CharacterDetail<MeshReplacement>>());
						list5.Add(new CharacterDetail<MeshReplacement>
						{
							detail = val7,
							sourceSkin = val2,
							index = list5.Count,
							path = Util.BuildPrefabTransformPath(val2.rootObject.transform, ((Component)val7.renderer).transform, false, false)
						});
						if (list5.Count <= 1)
						{
							characterDetailCatalog.meshTs.Add(val7.renderer, list5);
						}
					}
				}
				foreach (KeyValuePair<BodyIndex, List<CharacterDetail<MinionSkinReplacement>>> mini in characterDetailCatalog.minionSkins)
				{
					if (bodySkinDefs[0].minionSkinReplacements.Any((MinionSkinReplacement m) => BodyCatalog.FindBodyIndex(m.minionBodyPrefab) == mini.Key))
					{
						continue;
					}
					foreach (CharacterDetail<MinionSkinReplacement> item in mini.Value)
					{
						item.index++;
					}
					mini.Value.Insert(0, new CharacterDetail<MinionSkinReplacement>
					{
						detail = default(MinionSkinReplacement),
						sourceSkin = bodySkinDefs[0],
						index = -2
					});
				}
				foreach (KeyValuePair<GameObject, List<CharacterDetail<ProjectileGhostReplacement>>> proj in characterDetailCatalog.projectiles)
				{
					if (bodySkinDefs[0].projectileGhostReplacements.Any((ProjectileGhostReplacement m) => (Object)(object)m.projectilePrefab == (Object)(object)proj.Key))
					{
						continue;
					}
					foreach (CharacterDetail<ProjectileGhostReplacement> item2 in proj.Value)
					{
						item2.index++;
					}
					proj.Value.Insert(0, new CharacterDetail<ProjectileGhostReplacement>
					{
						detail = default(ProjectileGhostReplacement),
						sourceSkin = bodySkinDefs[0],
						index = -2
					});
				}
				BodyIndex val8 = BodyCatalog.FindBodyIndex("EngiBody");
				if (val != val8)
				{
					if (val == BodyCatalog.FindBodyIndex("RobPaladinBody"))
					{
						HandlePaladin(characterDetailCatalog);
					}
					else if (val == BodyCatalog.FindBodyIndex("RobRavagerBody"))
					{
						HandleRavager(characterDetailCatalog);
					}
					else if (val == BodyCatalog.FindBodyIndex("PathfinderBody"))
					{
						HandlePathfinder(characterDetailCatalog);
					}
					else if (val == BodyCatalog.FindBodyIndex("RedMistBody"))
					{
						HandleRuina(characterDetailCatalog);
					}
				}
				detailCatalog.Add(val, characterDetailCatalog);
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public void HandleRiskOfOptions()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			ModSettingsManager.SetModDescription("Mix and Match Skins");
			ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(seperateMaterials));
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public void HandleLobbySkinFix()
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			new Hook((MethodBase)typeof(ReverseSkin).GetMethod("Initialize", (BindingFlags)(-1)), (Delegate)new Action<Action<ReverseSkin, GameObject, SkinDef>, ReverseSkin, GameObject, SkinDef>(hook));
			[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
			static void hook(Action<ReverseSkin, GameObject, SkinDef> orig, ReverseSkin self, GameObject model, SkinDef skin)
			{
				RuntimeSkin runtimeSkin = skin.runtimeSkin;
				CharacterModel component = model.GetComponent<CharacterModel>();
				object obj;
				if (component == null)
				{
					obj = null;
				}
				else
				{
					CharacterBody body = component.body;
					obj = ((body == null) ? null : body.master?.loadout);
				}
				Loadout val = (Loadout)obj;
				OverlaySkin overlaySkin = default(OverlaySkin);
				skin.runtimeSkin = ((val != null && networkOSkins.TryGetValue(val, ref overlaySkin) && (Object)(object)overlaySkin.orig == (Object)(object)skin) ? overlaySkin.rSkin : runtimeSkin);
				orig(self, model, skin);
				skin.runtimeSkin = runtimeSkin;
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static void HandleRuina(CharacterDetailCatalog details)
		{
			foreach (CharacterDetail<MeshReplacement> repl2 in details.meshTs.SelectMany((KeyValuePair<Renderer, List<CharacterDetail<MeshReplacement>>> x) => x.Value))
			{
				CharacterDetail<MeshReplacement> characterDetail = repl2;
				characterDetail.applyAction = (Action<GameObject>)Delegate.Combine(characterDetail.applyAction, (Action<GameObject>)delegate(GameObject model)
				{
					CharacterModel component2 = model.GetComponent<CharacterModel>();
					object obj2;
					if (component2 == null)
					{
						obj2 = null;
					}
					else
					{
						CharacterBody body2 = component2.body;
						obj2 = ((body2 != null) ? ((Component)body2).GetComponent<RedMistStatTracker>() : null);
					}
					RedMistStatTracker val2 = (RedMistStatTracker)obj2;
					if (Object.op_Implicit((Object)(object)val2))
					{
						if (repl2.sourceSkin.nameToken == "COF_REDMIST_BODY_MASTERY_SKIN_NAME")
						{
							if (repl2.path.Contains("Body"))
							{
								ChildLocator componentInChildren = ((Component)val2).gameObject.GetComponentInChildren<ChildLocator>();
								val2.EGOActivatePrefab = Assets.argaliaEGOActivate;
								val2.musicName = "Play_ArgaliaMusic";
								if (Object.op_Implicit((Object)(object)componentInChildren))
								{
									val2.mistEffect = ((Component)componentInChildren.FindChild("ArgaliaCloud")).GetComponent<ParticleSystem>();
									((Component)componentInChildren.FindChild("ParticleHair").GetChild(0)).gameObject.SetActive(false);
									((Component)componentInChildren.FindChild("ParticleHair").GetChild(1)).gameObject.SetActive(true);
								}
							}
						}
						else if (repl2.sourceSkin.nameToken == "COF_REDMIST_BODY_DEFAULT_SKIN_NAME" && repl2.path.Contains("Body"))
						{
							ChildLocator componentInChildren2 = ((Component)val2).gameObject.GetComponentInChildren<ChildLocator>();
							val2.musicName = "Play_Ruina_Boss_Music";
							val2.EGOActivatePrefab = Assets.argaliaEGOActivate;
							if (Object.op_Implicit((Object)(object)componentInChildren2))
							{
								val2.mistEffect = ((Component)componentInChildren2.FindChild("BloodCloud")).GetComponent<ParticleSystem>();
								((Component)componentInChildren2.FindChild("ParticleHair").GetChild(0)).gameObject.SetActive(true);
								((Component)componentInChildren2.FindChild("ParticleHair").GetChild(1)).gameObject.SetActive(false);
							}
						}
					}
				});
			}
			foreach (CharacterDetail<RendererInfo> repl in details.infoTs.SelectMany((KeyValuePair<Renderer, List<CharacterDetail<RendererInfo>>> x) => x.Value))
			{
				CharacterDetail<RendererInfo> characterDetail2 = repl;
				characterDetail2.applyAction = (Action<GameObject>)Delegate.Combine(characterDetail2.applyAction, (Action<GameObject>)delegate(GameObject model)
				{
					CharacterModel component = model.GetComponent<CharacterModel>();
					object obj;
					if (component == null)
					{
						obj = null;
					}
					else
					{
						CharacterBody body = component.body;
						obj = ((body != null) ? ((Component)body).GetComponent<RedMistStatTracker>() : null);
					}
					RedMistStatTracker val = (RedMistStatTracker)obj;
					if (Object.op_Implicit((Object)(object)val))
					{
						if (repl.sourceSkin.nameToken == "COF_REDMIST_BODY_MASTERY_SKIN_NAME")
						{
							if (repl.path.Contains("Mimicry"))
							{
								val.slashPrefab = Assets.argaliaSwordSwingEffect;
								val.piercePrefab = Assets.argaliaSpearPierceEffect;
								val.EGOSlashPrefab = Assets.argaliaEGOSwordSwingEffect;
								val.EGOPiercePrefab = Assets.argaliaEGOSpearPierceEffect;
								val.hitEffect = Assets.argaliaSwordHitEffect;
								val.phaseEffect = Assets.argaliaPhaseEffect;
								val.groundPoundEffect = Assets.argaliaGroundPoundEffect;
								val.spinPrefab = Assets.argaliaSwordSpinEffect;
								val.spinPrefabTwo = Assets.argaliaSwordSpinEffectTwo;
								val.counterBurst = Assets.argaliaCounterBurst;
								val.afterimageBlock = Assets.argaliaAfterimageBlock;
								val.afterimageSlash = Assets.argaliaAfterimageSlash;
							}
						}
						else if (repl.sourceSkin.nameToken == "COF_REDMIST_BODY_DEFAULT_SKIN_NAME" && repl.path.Contains("Mimicry"))
						{
							val.slashPrefab = Assets.swordSwingEffect;
							val.piercePrefab = Assets.spearPierceEffect;
							val.EGOSlashPrefab = Assets.EGOSwordSwingEffect;
							val.EGOPiercePrefab = Assets.EGOSpearPierceEffect;
							val.hitEffect = Assets.swordHitEffect;
							val.phaseEffect = Assets.phaseEffect;
							val.groundPoundEffect = Assets.groundPoundEffect;
							val.spinPrefab = Assets.swordSpinEffect;
							val.spinPrefabTwo = Assets.swordSpinEffectTwo;
							val.counterBurst = Assets.counterBurst;
							val.afterimageBlock = Assets.afterimageBlock;
							val.afterimageSlash = Assets.afterimageSlash;
						}
					}
				});
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static void HandlePathfinder(CharacterDetailCatalog details)
		{
			//IL_0048: 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)
			if (!pathfinderFix)
			{
				new Hook((MethodBase)typeof(SquallController).GetMethod("Start", (BindingFlags)(-1)), (Delegate)new Action<Action<SquallController>, SquallController>(hook));
				pathfinderFix = true;
			}
			foreach (CharacterDetail<MinionSkinReplacement> repl in details.minionSkins[BodyCatalog.FindBodyIndex("SquallBody")])
			{
				CharacterDetail<MinionSkinReplacement> characterDetail = repl;
				characterDetail.applyAction = (Action<GameObject>)Delegate.Combine(characterDetail.applyAction, (Action<GameObject>)delegate(GameObject model)
				{
					CharacterSelectSurvivorPreviewDisplayController component3 = model.GetComponent<CharacterSelectSurvivorPreviewDisplayController>();
					int num = Math.Max(0, repl.index);
					if (Object.op_Implicit((Object)(object)component3) && component3.skinChangeResponses.Length > num && Object.op_Implicit((Object)(object)model.GetComponentInParent<SurvivorMannequinSlotController>()))
					{
						UnityEvent response = component3.skinChangeResponses[num].response;
						if (response != null)
						{
							response.Invoke();
						}
					}
				});
			}
			[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
			static void hook(Action<SquallController> orig, SquallController self)
			{
				//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c8: 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_00e9: Unknown result type (might be due to invalid IL or missing references)
				orig(self);
				if (Object.op_Implicit((Object)(object)self.owner) && Object.op_Implicit((Object)(object)self.selfBody))
				{
					FixedConditionalWeakTable<Loadout, OverlaySkin> obj = networkOSkins;
					CharacterBody component = self.owner.GetComponent<CharacterBody>();
					OverlaySkin overlaySkin = default(OverlaySkin);
					if (obj.TryGetValue((component == null) ? null : component.master?.loadout, ref overlaySkin))
					{
						ModelLocator component2 = ((Component)self).GetComponent<ModelLocator>();
						ModelSkinController val = ((component2 != null) ? ((Component)component2.modelTransform).GetComponent<ModelSkinController>() : null);
						MinionSkinReplacement val2 = ((IEnumerable<MinionSkinReplacement>)overlaySkin.minions).FirstOrDefault((Func<MinionSkinReplacement, bool>)((MinionSkinReplacement m) => (Object)(object)m.minionBodyPrefab == (Object)(object)self.selfBody.master.bodyPrefab));
						if (Object.op_Implicit((Object)(object)val))
						{
							val.ApplySkin(Object.op_Implicit((Object)(object)val2.minionSkin) ? SkinCatalog.FindLocalSkinIndexForBody(self.selfBody.bodyIndex, val2.minionSkin) : 0);
						}
					}
				}
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static void HandleRavager(CharacterDetailCatalog details)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			if (!ravagerFix)
			{
				new ILHook((MethodBase)typeof(RedGuyController).GetMethod("ApplySkin"), new Manipulator(Ilhook));
				ravagerFix = true;
			}
			foreach (CharacterDetail<MeshReplacement> repl in details.meshTs.SelectMany((KeyValuePair<Renderer, List<CharacterDetail<MeshReplacement>>> x) => x.Value))
			{
				CharacterDetail<MeshReplacement> characterDetail = repl;
				characterDetail.applyAction = (Action<GameObject>)Delegate.Combine(characterDetail.applyAction, (Action<GameObject>)delegate(GameObject model)
				{
					//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
					//IL_0149: Unknown result type (might be due to invalid IL or missing references)
					//IL_014e: Unknown result type (might be due to invalid IL or missing references)
					RavagerSkinDef val6 = RecreateRedGuySkin(model);
					if (Object.op_Implicit((Object)(object)val6))
					{
						RavagerSkinDef skin = RavagerSkinCatalog.GetSkin(repl.sourceSkin.nameToken);
						if (repl.path.Contains("meshSword"))
						{
							val6.basicSwingEffectPrefab = skin.basicSwingEffectPrefab;
							val6.bigSwingEffectPrefab = skin.bigSwingEffectPrefab;
							val6.slashEffectPrefab = skin.slashEffectPrefab;
							ChildLocator component = model.GetComponent<ChildLocator>();
							((Component)component.FindChild("SwordElectricity")).gameObject.GetComponent<ParticleSystemRenderer>().trailMaterial = skin.electricityMat;
							((Component)component.FindChild("SwordLight")).gameObject.GetComponent<Light>().color = skin.glowColor;
						}
						if (repl.path.Contains("meshBody"))
						{
							val6.bloodBombEffectPrefab = skin.bloodBombEffectPrefab;
							val6.bloodOrbEffectPrefab = skin.bloodOrbEffectPrefab;
							val6.bloodOrbOverlayMaterial = skin.bloodOrbOverlayMaterial;
							val6.bloodRushActivationEffectPrefab = skin.bloodRushActivationEffectPrefab;
							val6.bloodRushOverlayMaterial = skin.bloodRushOverlayMaterial;
							val6.consumeSoundString = skin.consumeSoundString;
							val6.healSoundString = skin.healSoundString;
							val6.swordElectricityMat = skin.swordElectricityMat;
							val6.electricityMat = skin.electricityMat;
							val6.glowColor = skin.glowColor;
							val6.leapEffectPrefab = skin.leapEffectPrefab;
						}
						if (repl.path.Contains("ImpWrap"))
						{
							val6.useAltAnimSet = skin.nameToken.Contains("MAHORAGA") || skin.useAltAnimSet;
						}
					}
				});
			}
			[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
			static void Ilhook(ILContext il)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Expected O, but got Unknown
				//IL_0077: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
				//IL_015c: Unknown result type (might be due to invalid IL or missing references)
				ILCursor val2 = new ILCursor(il);
				if (val2.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1]
				{
					(Instruction x) => ILPatternMatchingExt.MatchStfld(x, typeof(RedGuyController).GetField("cachedSkinDef", (BindingFlags)(-1)))
				}))
				{
					ILLabel val3 = val2.MarkLabel();
					ILLabel val5 = default(ILLabel);
					val2.GotoPrev((MoveType)2, new Func<Instruction, bool>[1]
					{
						(Instruction x) => ILPatternMatchingExt.MatchBrfalse(x, ref val5)
					});
					val2.Emit(OpCodes.Ldarg_0);
					val2.EmitDelegate<Func<Component, bool>>((Func<Component, bool>)((Component self) => SmhWhyIsThisRequired(self)));
					val2.Emit(OpCodes.Brtrue, (object)val3);
					val2.GotoNext(new Func<Instruction, bool>[1]
					{
						(Instruction x) => ILPatternMatchingExt.MatchLdstr(x, "SwordElectricity")
					});
					val2.GotoPrev(new Func<Instruction, bool>[1]
					{
						(Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 0)
					});
					ILLabel val4 = val2.MarkLabel();
					val2.GotoNext((MoveType)2, new Func<Instruction, bool>[1]
					{
						(Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt(x, (MethodBase)typeof(ParticleSystemRenderer).GetProperty("trailMaterial").GetSetMethod())
					});
					val3 = val2.MarkLabel();
					val2.GotoLabel(val4, (MoveType)1, false);
					val2.Emit(OpCodes.Br, (object)val3);
				}
			}
			[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
			static RavagerSkinDef RecreateRedGuySkin(GameObject model)
			{
				CharacterModel componentInChildren = model.GetComponentInChildren<CharacterModel>();
				object obj;
				if (componentInChildren == null)
				{
					obj = null;
				}
				else
				{
					CharacterBody body = componentInChildren.body;
					obj = ((body != null) ? ((Component)body).GetComponentInChildren<RedGuyController>() : null);
				}
				RedGuyController val = (RedGuyController)obj;
				if (!Object.op_Implicit((Object)(object)val))
				{
					return null;
				}
				val.skinController = ((Component)val).GetComponentInChildren<ModelSkinController>();
				if (!Object.op_Implicit((Object)(object)val.cachedSkinDef))
				{
					val.cachedSkinDef = RavagerSkinCatalog.GetSkin(val.skinController.skins[model.GetComponent<CharacterModel>().body.skinIndex].nameToken);
				}
				if (RavagerSkinCatalog.skinDefs.Contains(val.cachedSkinDef))
				{
					val.cachedSkinDef = Object.Instantiate<RavagerSkinDef>(val.cachedSkinDef);
				}
				return val.cachedSkinDef;
			}
			[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
			static bool SmhWhyIsThisRequired(Component controller)
			{
				return Object.op_Implicit((Object)(object)((RedGuyController)(((controller is RedGuyController) ? controller : null)?)).cachedSkinDef);
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static void HandlePaladin(CharacterDetailCatalog details)
		{
			List<Renderer> list = new List<Renderer>();
			foreach (Renderer key in details.meshTs.Keys)
			{
				if (((Object)key).name == "Crystal")
				{
					list.Add(key);
				}
			}
			foreach (Renderer key2 in details.infoTs.Keys)
			{
				if (((Object)key2).name == "Crystal")
				{
					list.Add(key2);
				}
			}
			foreach (Renderer item in list)
			{
				details.meshTs.Remove(item);
				details.infoTs.Remove(item);
			}
		}

		private void Awake()
		{
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Expected O, but got Unknown
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Expected O, but got Unknown
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Expected O, but got Unknown
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Expected O, but got Unknown
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Expected O, but got Unknown
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Expected O, but got Unknown
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Expected O, but got Unknown
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Expected O, but got Unknown
			lobbySkinFix = Chainloader.PluginInfos.ContainsKey("com.KingEnderBrine.LobbySkinsFix");
			seperateMaterials = ((BaseUnityPlugin)this).Config.Bind<bool>("Configuration", "Seperate Materials", false, "Present extra selections for materials (the default merges them with mesh replacements)");
			if (lobbySkinFix)
			{
				HandleLobbySkinFix();
			}
			if (Chainloader.PluginInfos.ContainsKey("com.rune580.riskofoptions"))
			{
				HandleRiskOfOptions();
			}
			object obj = <>c.<>9__24_0;
			if (obj == null)
			{
				hook_FindProjectileGhostPrefab val = delegate(orig_FindProjectileGhostPrefab orig, ProjectileController projcontroller)
				{
					//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
					//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
					//IL_009c: Unknown result type (might be due to invalid IL or missing references)
					GameObject val22 = orig.Invoke(projcontroller);
					GameObject prefab = ProjectileCatalog.GetProjectilePrefab(projcontroller.catalogIndex);
					GameObject owner = projcontroller.owner;
					object obj30;
					if (owner == null)
					{
						obj30 = null;
					}
					else
					{
						CharacterBody component3 = owner.GetComponent<CharacterBody>();
						obj30 = ((component3 == null) ? null : component3.master?.loadout);
					}
					Loadout val23 = (Loadout)obj30;
					OverlaySkin overlaySkin5 = default(OverlaySkin);
					ProjectileGhostReplacement? val24 = ((val23 == null || !networkOSkins.TryGetValue(val23, ref overlaySkin5)) ? null : overlaySkin5?.projectiles?.Find((ProjectileGhostReplacement p) => (Object)(object)p.projectilePrefab == (Object)(object)prefab));
					return (val24.HasValue && Object.op_Implicit((Object)(object)val24.Value.projectilePrefab)) ? val24.Value.projectileGhostReplacementPrefab : val22;
				};
				<>c.<>9__24_0 = val;
				obj = (object)val;
			}
			ProjectileGhostReplacementManager.FindProjectileGhostPrefab += (hook_FindProjectileGhostPrefab)obj;
			object obj2 = <>c.<>9__24_1;
			if (obj2 == null)
			{
				Manipulator val2 = delegate(ILContext il)
				{
					//IL_0002: Unknown result type (might be due to invalid IL or missing references)
					//IL_0008: Expected O, but got Unknown
					//IL_003d: Unknown result type (might be due to invalid IL or missing references)
					ILCursor val20 = new ILCursor(il);
					if (val20.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1]
					{
						(Instruction x) => ILPatternMatchingExt.MatchLdfld(x, typeof(SkinDef).GetField("minionSkinReplacements"))
					}))
					{
						val20.Emit(OpCodes.Ldarg_0);
						val20.EmitDelegate<Func<MinionSkinReplacement[], MasterSummon, MinionSkinReplacement[]>>((Func<MinionSkinReplacement[], MasterSummon, MinionSkinReplacement[]>)delegate(MinionSkinReplacement[] reps, MasterSummon self)
						{
							GameObject summonerBodyObject = self.summonerBodyObject;
							object obj29;
							if (summonerBodyObject == null)
							{
								obj29 = null;
							}
							else
							{
								CharacterBody component2 = summonerBodyObject.GetComponent<CharacterBody>();
								obj29 = ((component2 == null) ? null : component2.master?.loadout);
							}
							Loadout val21 = (Loadout)obj29;
							OverlaySkin overlaySkin4 = default(OverlaySkin);
							return (val21 != null && networkOSkins.TryGetValue(val21, ref overlaySkin4) && overlaySkin4.minions != null) ? overlaySkin4.minions.ToArray() : reps;
						});
					}
				};
				<>c.<>9__24_1 = val2;
				obj2 = (object)val2;
			}
			MasterSummon.Perform += (Manipulator)obj2;
			object obj3 = <>c.<>9__24_2;
			if (obj3 == null)
			{
				hook_Apply val3 = delegate(orig_Apply orig, SkinDef self, GameObject model)
				{
					orig.Invoke(self, model);
					CharacterModel component = model.GetComponent<CharacterModel>();
					object obj28;
					if (component == null)
					{
						obj28 = null;
					}
					else
					{
						CharacterBody body = component.body;
						obj28 = ((body == null) ? null : body.master?.loadout);
					}
					Loadout val19 = (Loadout)obj28;
					if (val19 == null)
					{
						val19 = model.GetComponentInParent<SurvivorMannequinSlotController>()?.currentLoadout;
						if (val19 != null)
						{
							bool flag2 = true;
						}
					}
					OverlaySkin overlaySkin3 = default(OverlaySkin);
					if (val19 != null && networkOSkins.TryGetValue(val19, ref overlaySkin3) && (Object)(object)overlaySkin3.orig == (Object)(object)self)
					{
						RuntimeSkin rSkin = overlaySkin3.rSkin;
						if (rSkin != null)
						{
							rSkin.Apply(model);
						}
						overlaySkin3.onApply?.Invoke(model);
					}
				};
				<>c.<>9__24_2 = val3;
				obj3 = (object)val3;
			}
			SkinDef.Apply += (hook_Apply)obj3;
			UserProfile.onLoadoutChangedGlobal += delegate(UserProfile u)
			{
				//IL_0017: Unknown result type (might be due to invalid IL or missing references)
				//IL_001c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0021: Unknown result type (might be due to invalid IL or missing references)
				//IL_0022: Unknown result type (might be due to invalid IL or missing references)
				//IL_002e: Unknown result type (might be due to invalid IL or missing references)
				//IL_003f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0044: Unknown result type (might be due to invalid IL or missing references)
				//IL_0087: 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_00c5: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
				//IL_0111: Expected O, but got Unknown
				if (u == localProfile)
				{
					BodyIndex bodyIndexFromSurvivorIndex = SurvivorCatalog.GetBodyIndexFromSurvivorIndex(u.survivorPreference.survivorIndex);
					SkinDef bodySkinDef2 = SkinCatalog.GetBodySkinDef(bodyIndexFromSurvivorIndex, (int)u.loadout.bodyLoadoutManager.GetSkinIndex(bodyIndexFromSurvivorIndex));
					if ((oSkin.bodyIndex != bodyIndexFromSurvivorIndex || (Object)(object)oSkin.orig != (Object)(object)bodySkinDef2) && detailRows.Any())
					{
						bodySkinDef2.Bake();
						oSkin = new OverlaySkin
						{
							orig = bodySkinDef2,
							bodyIndex = bodyIndexFromSurvivorIndex,
							minions = bodySkinDef2.minionSkinReplacements.ToList(),
							projectiles = bodySkinDef2.projectileGhostReplacements.ToList(),
							seperateMaterials = seperateMaterials.Value,
							rSkin = new RuntimeSkin
							{
								meshReplacementTemplates = ArrayUtils.Clone<MeshReplacementTemplate>(bodySkinDef2.runtimeSkin.meshReplacementTemplates),
								rendererInfoTemplates = ArrayUtils.Clone<RendererInfoTemplate>(bodySkinDef2.runtimeSkin.rendererInfoTemplates),
								gameObjectActivationTemplates = ArrayUtils.Clone<GameObjectActivationTemplate>(bodySkinDef2.runtimeSkin.gameObjectActivationTemplates)
							},
							syncInfo = new int[rowCountStore]
						};
						OverlaySkin.GenerateSyncFromSkinRows(ref oSkin.syncInfo, bodySkinDef2, detailRows);
					}
				}
			};
			object obj4 = <>c.<>9__24_4;
			if (obj4 == null)
			{
				Manipulator val4 = delegate(ILContext il)
				{
					//IL_0002: Unknown result type (might be due to invalid IL or missing references)
					//IL_0008: Expected O, but got Unknown
					//IL_003c: Unknown result type (might be due to invalid IL or missing references)
					//IL_0048: Unknown result type (might be due to invalid IL or missing references)
					ILCursor val17 = new ILCursor(il);
					ILLabel val18 = default(ILLabel);
					if (val17.TryGotoNext(new Func<Instruction, bool>[1]
					{
						(Instruction x) => ILPatternMatchingExt.MatchBrfalse(x, ref val18)
					}))
					{
						val17.Emit(OpCodes.Ldarg_0);
						val17.Emit(OpCodes.Ldarg_1);
						val17.EmitDelegate<Func<bool, BodyLoadoutManager, int, bool>>((Func<bool, BodyLoadoutManager, int, bool>)((bool orig, BodyLoadoutManager self, int index) => orig && (!detailCatalog.ContainsKey(self.modifiedBodyLoadouts[index].bodyIndex) || oSkin.bodyIndex != self.modifiedBodyLoadouts[index].bodyIndex)));
					}
				};
				<>c.<>9__24_4 = val4;
				obj4 = (object)val4;
			}
			BodyLoadoutManager.RemoveBodyLoadoutIfDefault_int += (Manipulator)obj4;
			LoadoutPanelController.Rebuild += (hook_Rebuild)delegate(orig_Rebuild orig, LoadoutPanelController self)
			{
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0014: Unknown result type (might be due to invalid IL or missing references)
				//IL_0015: Unknown result type (might be due to invalid IL or missing references)
				//IL_0017: Invalid comparison between Unknown and I4
				//IL_0057: Unknown result type (might be due to invalid IL or missing references)
				//IL_0063: Unknown result type (might be due to invalid IL or missing references)
				//IL_0079: Unknown result type (might be due to invalid IL or missing references)
				//IL_0090: Unknown result type (might be due to invalid IL or missing references)
				//IL_0095: Unknown result type (might be due to invalid IL or missing references)
				//IL_0179: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
				//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
				//IL_0115: Unknown result type (might be due to invalid IL or missing references)
				//IL_011a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0130: Unknown result type (might be due to invalid IL or missing references)
				//IL_0146: Unknown result type (might be due to invalid IL or missing references)
				//IL_0161: Expected O, but got Unknown
				//IL_07ab: Unknown result type (might be due to invalid IL or missing references)
				//IL_07b3: Unknown result type (might be due to invalid IL or missing references)
				//IL_07bd: Expected O, but got Unknown
				//IL_01de: Unknown result type (might be due to invalid IL or missing references)
				//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
				//IL_0209: Expected O, but got Unknown
				//IL_098b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0998: Unknown result type (might be due to invalid IL or missing references)
				//IL_02e2: Unknown result type (might be due to invalid IL or missing references)
				//IL_02ef: Unknown result type (might be due to invalid IL or missing references)
				//IL_04db: Unknown result type (might be due to invalid IL or missing references)
				//IL_04fc: Unknown result type (might be due to invalid IL or missing references)
				//IL_0506: Expected O, but got Unknown
				//IL_08ba: Unknown result type (might be due to invalid IL or missing references)
				//IL_08c7: Unknown result type (might be due to invalid IL or missing references)
				//IL_0b71: Unknown result type (might be due to invalid IL or missing references)
				//IL_0b74: Unknown result type (might be due to invalid IL or missing references)
				//IL_0b7e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0b88: Expected O, but got Unknown
				//IL_03fd: Unknown result type (might be due to invalid IL or missing references)
				//IL_040a: Unknown result type (might be due to invalid IL or missing references)
				//IL_041b: Expected O, but got Unknown
				//IL_09c0: Expected O, but got Unknown
				//IL_0317: Expected O, but got Unknown
				//IL_0599: Unknown result type (might be due to invalid IL or missing references)
				//IL_05a6: Unknown result type (might be due to invalid IL or missing references)
				//IL_0a9d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0aaa: Unknown result type (might be due to invalid IL or missing references)
				//IL_0abb: Expected O, but got Unknown
				//IL_08ef: Expected O, but got Unknown
				//IL_0e20: Unknown result type (might be due to invalid IL or missing references)
				//IL_0e2d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0e37: Expected O, but got Unknown
				//IL_0d0d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0d1a: Unknown result type (might be due to invalid IL or missing references)
				//IL_05ce: Expected O, but got Unknown
				//IL_06b4: Unknown result type (might be due to invalid IL or missing references)
				//IL_06c1: Unknown result type (might be due to invalid IL or missing references)
				//IL_06d2: Expected O, but got Unknown
				//IL_0d4c: Expected O, but got Unknown
				//IL_0c4d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0c5a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0fbc: Unknown result type (might be due to invalid IL or missing references)
				//IL_0fc9: Unknown result type (might be due to invalid IL or missing references)
				//IL_0c8c: Expected O, but got Unknown
				//IL_0ffb: Expected O, but got Unknown
				//IL_0efc: Unknown result type (might be due to invalid IL or missing references)
				//IL_0f09: Unknown result type (might be due to invalid IL or missing references)
				//IL_0f3b: Expected O, but got Unknown
				orig.Invoke(self);
				BodyIndex bodyIndex = self.currentDisplayData.bodyIndex;
				if ((int)bodyIndex != -1)
				{
					localProfile = self.currentDisplayData.userProfile;
					SurvivorMannequinSlotController diorama = GameObject.Find("SurvivorMannequinDiorama").GetComponent<SurvivorMannequinDioramaController>().mannequinSlots[0];
					SkinDef defaultSkin = SkinCatalog.GetBodySkinDef(bodyIndex, 0);
					SkinDef bodySkinDef = SkinCatalog.GetBodySkinDef(bodyIndex, (int)self.currentDisplayData.userProfile.loadout.bodyLoadoutManager.GetSkinIndex(bodyIndex));
					int num3 = 0;
					bool flag = false;
					if (oSkin.bodyIndex != bodyIndex || (Object)(object)oSkin.orig != (Object)(object)bodySkinDef)
					{
						flag = true;
						if (bodySkinDef != null)
						{
							bodySkinDef.Bake();
						}
						oSkin = new OverlaySkin
						{
							orig = bodySkinDef,
							bodyIndex = self.currentDisplayData.bodyIndex,
							seperateMaterials = seperateMaterials.Value,
							minions = bodySkinDef.minionSkinReplacements.ToList(),
							projectiles = bodySkinDef.projectileGhostReplacements.ToList(),
							rSkin = new RuntimeSkin
							{
								meshReplacementTemplates = ArrayUtils.Clone<MeshReplacementTemplate>(bodySkinDef.runtimeSkin.meshReplacementTemplates),
								rendererInfoTemplates = ArrayUtils.Clone<RendererInfoTemplate>(bodySkinDef.runtimeSkin.rendererInfoTemplates),
								gameObjectActivationTemplates = ArrayUtils.Clone<GameObjectActivationTemplate>(bodySkinDef.runtimeSkin.gameObjectActivationTemplates)
							}
						};
					}
					detailRows.Clear();
					if (detailCatalog.TryGetValue(bodyIndex, out var value))
					{
						if (seperateMaterials.Value)
						{
							foreach (KeyValuePair<Renderer, List<CharacterDetail<MeshReplacement>>> meshT in value.meshTs)
							{
								List<CharacterDetail<MeshReplacement>> value2 = meshT.Value;
								Row row5 = new Row(self, bodyIndex, ((Object)value2.First().detail.renderer).name + " Mesh");
								int catVal5 = num3;
								row5.findCurrentChoice = delegate
								{
									int num6 = oSkin.FindIndex(catVal5);
									return (num6 >= 0) ? num6 : (row5.buttons.Count - 1);
								};
								string text = string.Empty;
								foreach (CharacterDetail<MeshReplacement> repl4 in value2)
								{
									if (!Object.op_Implicit((Object)(object)repl4.detail.mesh))
									{
										text = text + Language.GetString(repl4.sourceSkin.nameToken) + "\n";
									}
									else
									{
										SkinDef sourceSkin = repl4.sourceSkin;
										Row obj8 = row5;
										Sprite obj9 = sourceSkin.icon;
										string nameToken = sourceSkin.nameToken;
										string nameToken2 = sourceSkin.nameToken;
										Color primaryColor = row5.primaryColor;
										UnityAction val9 = delegate
										{
											oSkin.syncInfo[catVal5] = repl4.index;
											oSkin.BuildRSkin(oSkin.syncInfo);
											row5.UpdateHighlightedChoice();
											diorama.loadoutDirty = true;
										};
										UnlockableDef unlockableDef = sourceSkin.unlockableDef;
										obj8.AddButton(self, obj9, nameToken, nameToken2, primaryColor, val9, ((unlockableDef != null) ? unlockableDef.cachedName : null) ?? "", (Node)null, false);
									}
								}
								if (value.actT.ContainsKey(((Component)meshT.Key).gameObject))
								{
									foreach (CharacterDetail<bool> item in value.actT[((Component)meshT.Key).gameObject])
									{
										if (!item.detail)
										{
											text = text + Language.GetString(item.sourceSkin.nameToken) + "\n";
										}
									}
								}
								if (text != string.Empty)
								{
									row5.AddButton(self, icon, "Disabled", text, row5.primaryColor, (UnityAction)delegate
									{
										oSkin.syncInfo[catVal5] = -2;
										oSkin.BuildRSkin(oSkin.syncInfo);
										row5.UpdateHighlightedChoice();
										diorama.loadoutDirty = true;
									}, "", (Node)null, false);
								}
								if (row5.buttons.Count > 1)
								{
									row5.FinishSetup(false);
									self.rows.Add(row5);
									detailRows.Add(row5);
									num3++;
								}
								else
								{
									row5.Dispose();
								}
							}
							foreach (KeyValuePair<Renderer, List<CharacterDetail<RendererInfo>>> infoT in value.infoTs)
							{
								List<CharacterDetail<RendererInfo>> value3 = infoT.Value;
								Row row4 = new Row(self, bodyIndex, ((Object)value3.First().detail.renderer).name + " Material");
								int catVal4 = num3;
								row4.findCurrentChoice = delegate
								{
									int num5 = oSkin.FindIndex(catVal4);
									return (num5 >= 0) ? num5 : (row4.buttons.Count - 1);
								};
								string text2 = string.Empty;
								foreach (CharacterDetail<RendererInfo> repl3 in value3)
								{
									SkinDef sourceSkin2 = repl3.sourceSkin;
									Row obj10 = row4;
									Sprite obj11 = sourceSkin2.icon;
									string nameToken3 = sourceSkin2.nameToken;
									string nameToken4 = sourceSkin2.nameToken;
									Color primaryColor2 = row4.primaryColor;
									UnityAction val10 = delegate
									{
										oSkin.syncInfo[catVal4] = repl3.index;
										oSkin.BuildRSkin(oSkin.syncInfo);
										row4.UpdateHighlightedChoice();
										diorama.loadoutDirty = true;
									};
									UnlockableDef unlockableDef2 = sourceSkin2.unlockableDef;
									obj10.AddButton(self, obj11, nameToken3, nameToken4, primaryColor2, val10, ((unlockableDef2 != null) ? unlockableDef2.cachedName : null) ?? "", (Node)null, false);
								}
								if (value.actT.ContainsKey(((Component)infoT.Key).gameObject))
								{
									foreach (CharacterDetail<bool> item2 in value.actT[((Component)infoT.Key).gameObject])
									{
										if (!item2.detail)
										{
											text2 = text2 + Language.GetString(item2.sourceSkin.nameToken) + "\n";
										}
									}
								}
								if (text2 != string.Empty)
								{
									row4.AddButton(self, icon, "Disabled", text2, row4.primaryColor, (UnityAction)delegate
									{
										oSkin.syncInfo[catVal4] = -2;
										oSkin.BuildRSkin(oSkin.syncInfo);
										row4.UpdateHighlightedChoice();
										diorama.loadoutDirty = true;
									}, "", (Node)null, false);
								}
								if (row4.buttons.Count > 1)
								{
									row4.FinishSetup(false);
									self.rows.Add(row4);
									detailRows.Add(row4);
									num3++;
								}
								else
								{
									row4.Dispose();
								}
							}
						}
						else
						{
							foreach (Renderer item3 in value.meshTs.Keys.Concat(value.infoTs.Keys).Distinct())
							{
								Row row3 = new Row(self, bodyIndex, ((Object)item3).name);
								int catVal3 = num3;
								row3.findCurrentChoice = delegate
								{
									int num4 = oSkin.FindIndex(catVal3);
									return (num4 >= 0) ? num4 : (row3.buttons.Count - 1);
								};
								string text3 = string.Empty;
								if (value.meshTs.ContainsKey(item3))
								{
									foreach (CharacterDetail<MeshReplacement> repl2 in value.meshTs[item3])
									{
										if (!Object.op_Implicit((Object)(object)repl2.detail.mesh))
										{
											text3 = text3 + Language.GetString(repl2.sourceSkin.nameToken) + "\n";
										}
										else
										{
											SkinDef sourceSkin3 = repl2.sourceSkin;
											Row obj12 = row3;
											Sprite obj13 = sourceSkin3.icon;
											string nameToken5 = sourceSkin3.nameToken;
											string nameToken6 = sourceSkin3.nameToken;
											Color primaryColor3 = row3.primaryColor;
											UnityAction val11 = delegate
											{
												oSkin.syncInfo[catVal3] = repl2.index;
												oSkin.BuildRSkin(oSkin.syncInfo);
												row3.UpdateHighlightedChoice();
												diorama.loadoutDirty = true;
											};
											UnlockableDef unlockableDef3 = sourceSkin3.unlockableDef;
											obj12.AddButton(self, obj13, nameToken5, nameToken6, primaryColor3, val11, ((unlockableDef3 != null) ? unlockableDef3.cachedName : null) ?? "", (Node)null, false);
										}
									}
								}
								else
								{
									foreach (CharacterDetail<RendererInfo> repl in value.infoTs[item3])
									{
										SkinDef sourceSkin4 = repl.sourceSkin;
										Row obj14 = row3;
										Sprite obj15 = sourceSkin4.icon;
										string nameToken7 = sourceSkin4.nameToken;
										string nameToken8 = sourceSkin4.nameToken;
										Color primaryColor4 = row3.primaryColor;
										UnityAction val12 = delegate
										{
											oSkin.syncInfo[catVal3] = repl.index;
											oSkin.BuildRSkin(oSkin.syncInfo);
											row3.UpdateHighlightedChoice();
											diorama.loadoutDirty = true;
										};
										UnlockableDef unlockableDef4 = sourceSkin4.unlockableDef;
										obj14.AddButton(self, obj15, nameToken7, nameToken8, primaryColor4, val12, ((unlockableDef4 != null) ? unlockableDef4.cachedName : null) ?? "", (Node)null, false);
									}
								}
								if (value.actT.ContainsKey(((Component)item3).gameObject))
								{
									foreach (CharacterDetail<bool> item4 in value.actT[((Component)item3).gameObject])
									{
										if (!item4.detail)
										{
											text3 = text3 + Language.GetString(item4.sourceSkin.nameToken) + "\n";
										}
									}
								}
								if (text3 != string.Empty)
								{
									row3.AddButton(self, icon, "Disabled", text3, row3.primaryColor, (UnityAction)delegate
									{
										oSkin.syncInfo[catVal3] = -2;
										oSkin.BuildRSkin(oSkin.syncInfo);
										row3.UpdateHighlightedChoice();
										diorama.loadoutDirty = true;
									}, "", (Node)null, false);
								}
								if (row3.buttons.Count > 1)
								{
									row3.FinishSetup(false);
									self.rows.Add(row3);
									detailRows.Add(row3);
									num3++;
								}
								else
								{
									row3.Dispose();
								}
							}
						}
						foreach (KeyValuePair<BodyIndex, List<CharacterDetail<MinionSkinReplacement>>> minionSkin in value.minionSkins)
						{
							Row row2 = new Row(self, bodyIndex, BodyCatalog.GetBodyName(minionSkin.Key));
							int catVal2 = num3;
							row2.findCurrentChoice = (Loadout l) => Math.Max(0, oSkin.FindIndex(catVal2));
							if (!minionSkin.Value.Any((CharacterDetail<MinionSkinReplacement> r) => (Object)(object)r.sourceSkin == (Object)(object)defaultSkin))
							{
								Row obj16 = row2;
								Sprite obj17 = defaultSkin?.icon;
								string obj18 = defaultSkin?.nameToken;
								string obj19 = defaultSkin?.nameToken;
								Color primaryColor5 = row2.primaryColor;
								UnityAction val13 = delegate
								{
									oSkin.syncInfo[catVal2] = -2;
									oSkin.BuildRSkin(oSkin.syncInfo);
									row2.UpdateHighlightedChoice();
									diorama.loadoutDirty = true;
								};
								UnlockableDef unlockableDef5 = defaultSkin.unlockableDef;
								obj16.AddButton(self, obj17, obj18, obj19, primaryColor5, val13, ((unlockableDef5 != null) ? unlockableDef5.cachedName : null) ?? "", (Node)null, false);
							}
							foreach (CharacterDetail<MinionSkinReplacement> miniS in minionSkin.Value)
							{
								Row obj20 = row2;
								Sprite obj21 = miniS.sourceSkin.icon;
								string nameToken9 = miniS.sourceSkin.nameToken;
								string nameToken10 = miniS.sourceSkin.nameToken;
								Color primaryColor6 = row2.primaryColor;
								UnityAction val14 = delegate
								{
									oSkin.syncInfo[catVal2] = miniS.index;
									oSkin.BuildRSkin(oSkin.syncInfo);
									row2.UpdateHighlightedChoice();
									diorama.loadoutDirty = true;
								};
								UnlockableDef unlockableDef6 = miniS.sourceSkin.unlockableDef;
								obj20.AddButton(self, obj21, nameToken9, nameToken10, primaryColor6, val14, ((unlockableDef6 != null) ? unlockableDef6.cachedName : null) ?? "", (Node)null, false);
							}
							if (row2.buttons.Count > 1)
							{
								row2.FinishSetup(false);
								self.rows.Add(row2);
								detailRows.Add(row2);
								num3++;
							}
							else
							{
								row2.Dispose();
							}
						}
						foreach (KeyValuePair<GameObject, List<CharacterDetail<ProjectileGhostReplacement>>> projectile in value.projectiles)
						{
							Row row = new Row(self, bodyIndex, ((Object)projectile.Key).name);
							int catVal = num3;
							row.findCurrentChoice = (Loadout l) => Math.Max(0, oSkin.FindIndex(catVal));
							if (!projectile.Value.Any((CharacterDetail<ProjectileGhostReplacement> r) => (Object)(object)r.sourceSkin == (Object)(object)defaultSkin))
							{
								Row obj22 = row;
								Sprite obj23 = defaultSkin?.icon;
								string obj24 = defaultSkin?.nameToken;
								string obj25 = defaultSkin?.nameToken;
								Color primaryColor7 = row.primaryColor;
								UnityAction val15 = delegate
								{
									oSkin.syncInfo[catVal] = -2;
									oSkin.BuildRSkin(oSkin.syncInfo);
									row.UpdateHighlightedChoice();
									diorama.loadoutDirty = true;
								};
								UnlockableDef unlockableDef7 = defaultSkin.unlockableDef;
								obj22.AddButton(self, obj23, obj24, obj25, primaryColor7, val15, ((unlockableDef7 != null) ? unlockableDef7.cachedName : null) ?? "", (Node)null, false);
							}
							foreach (CharacterDetail<ProjectileGhostReplacement> ghost in projectile.Value)
							{
								Row obj26 = row;
								Sprite obj27 = ghost.sourceSkin.icon;
								string nameToken11 = ghost.sourceSkin.nameToken;
								string nameToken12 = ghost.sourceSkin.nameToken;
								Color primaryColor8 = row.primaryColor;
								UnityAction val16 = delegate
								{
									oSkin.syncInfo[catVal] = ghost.index;
									oSkin.BuildRSkin(oSkin.syncInfo);
									row.UpdateHighlightedChoice();
									diorama.loadoutDirty = true;
								};
								UnlockableDef unlockableDef8 = ghost.sourceSkin.unlockableDef;
								obj26.AddButton(self, obj27, nameToken11, nameToken12, primaryColor8, val16, ((unlockableDef8 != null) ? unlockableDef8.cachedName : null) ?? "", (Node)null, false);
							}
							if (row.buttons.Count > 1)
							{
								row.FinishSetup(false);
								self.rows.Add(row);
								detailRows.Add(row);
								num3++;
							}
							else
							{
								row.Dispose();
							}
						}
						rowCountStore = num3;
						if (flag)
						{
							OverlaySkin overlaySkin2 = oSkin;
							if (overlaySkin2.syncInfo == null)
							{
								overlaySkin2.syncInfo = new int[num3];
							}
							OverlaySkin.GenerateSyncFromSkinRows(ref oSkin.syncInfo, bodySkinDef, detailRows);
							oSkin.BuildRSkin(oSkin.syncInfo);
						}
						diorama.loadoutDirty = true;
						ArrayUtils.EnsureCapacity<int>(ref oSkin.syncInfo, num3);
						bool saveRequestPending = localProfile.saveRequestPending;
						localProfile.OnLoadoutChanged();
						localProfile.saveRequestPending = saveRequestPending;
					}
				}
			};
			object obj5 = <>c.<>9__24_6;
			if (obj5 == null)
			{
				hook_Serialize val5 = delegate(orig_Serialize orig, Loadout self, NetworkWriter writer)
				{
					//IL_002d: Unknown result type (might be due to invalid IL or missing references)
					//IL_005e: Unknown result type (might be due to invalid IL or missing references)
					//IL_0068: Expected I4, but got Unknown
					//IL_006b: Unknown result type (might be due to invalid IL or missing references)
					orig.Invoke(self, writer);
					OverlaySkin orCreateValue2 = networkOSkins.GetOrCreateValue(self);
					if (orCreateValue2 == null || (Object)(object)orCreateValue2.orig == (Object)null || !detailCatalog.ContainsKey(orCreateValue2.bodyIndex) || orCreateValue2.syncInfo.Length == 0)
					{
						writer.Write(-1);
					}
					else
					{
						writer.Write((int)orCreateValue2.orig.skinIndex);
						NetworkExtensions.WriteBodyIndex(writer, orCreateValue2.bodyIndex);
						writer.Write(orCreateValue2.seperateMaterials);
						writer.Write(orCreateValue2.syncInfo.Length);
						int[] syncInfo = orCreateValue2.syncInfo;
						foreach (int num2 in syncInfo)
						{
							writer.Write(num2);
						}
					}
				};
				<>c.<>9__24_6 = val5;
				obj5 = (object)val5;
			}
			Loadout.Serialize += (hook_Serialize)obj5;
			object obj6 = <>c.<>9__24_7;
			if (obj6 == null)
			{
				hook_Deserialize val6 = delegate(orig_Deserialize orig, Loadout self, NetworkReader reader)
				{
					//IL_0010: Unknown result type (might be due to invalid IL or missing references)
					//IL_0011: Unknown result type (might be due to invalid IL or missing references)
					//IL_0013: Invalid comparison between Unknown and I4
					//IL_002c: 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_003e: Unknown result type (might be due to invalid IL or missing references)
					//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
					orig.Invoke(self, reader);
					SkinIndex val8 = (SkinIndex)reader.ReadInt32();
					if ((int)val8 != -1)
					{
						OverlaySkin orCreateValue = networkOSkins.GetOrCreateValue(self);
						orCreateValue.orig = SkinCatalog.GetSkinDef(val8);
						orCreateValue.bodyIndex = NetworkExtensions.ReadBodyIndex(reader);
						orCreateValue.seperateMaterials = reader.ReadBoolean();
						int num = reader.ReadInt32();
						orCreateValue.syncInfo = new int[num];
						for (int i = 0; i < num; i++)
						{
							orCreateValue.syncInfo[i] = reader.ReadInt32();
						}
						orCreateValue.minions = new List<MinionSkinReplacement>();
						orCreateValue.projectiles = new List<ProjectileGhostReplacement>();
						if (detailCatalog.ContainsKey(orCreateValue.bodyIndex))
						{
							orCreateValue.BuildRSkin(orCreateValue.syncInfo);
						}
					}
				};
				<>c.<>9__24_7 = val6;
				obj6 = (object)val6;
			}
			Loadout.Deserialize += (hook_Deserialize)obj6;
			object obj7 = <>c.<>9__24_8;
			if (obj7 == null)
			{
				hook_Copy val7 = delegate(orig_Copy orig, Loadout self, Loadout target)
				{
					orig.Invoke(self, target);
					OverlaySkin overlaySkin = default(OverlaySkin);
					if (networkOSkins.TryGetValue(self, ref overlaySkin))
					{
						networkOSkins.Remove(target);
						networkOSkins.Add(target, overlaySkin);
					}
				};
				<>c.<>9__24_8 = val7;
				obj7 = (object)val7;
			}
			Loadout.Copy += (hook_Copy)obj7;
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		[CompilerGenerated]
		internal static bool <HandleRavager>g__SmhWhyIsThisRequired|22_1(Component controller)
		{
			return Object.op_Implicit((Object)(object)((RedGuyController)(((controller is RedGuyController) ? controller : null)?)).cachedSkinDef);
		}
	}
}