Decompiled source of Bobs Heretics v1.1.0

BobsHeretics.dll

Decompiled a week ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using BobsHeretics.Skins;
using BobsHeretics.Skins.ArtificerSkins;
using EntityStates.Missions.Arena.NullWard;
using Microsoft.CodeAnalysis;
using On.EntityStates.Missions.Arena.NullWard;
using On.RoR2;
using R2API;
using RoR2;
using RoR2.Achievements;
using UnityEngine;

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace BobsHeretics
{
	public static class Assets
	{
		private static Shader _hgStandardShader;

		public static AssetBundle MainAssetBundle { get; private set; }

		public static Material MatAngelBody { get; private set; }

		public static Material MatAngelClothes { get; private set; }

		public static Material MatAngelFeathers { get; private set; }

		public static Material MatAngelEye { get; private set; }

		public static Material MatDecompiledBody { get; private set; }

		public static Material MatDecompiledClothes { get; private set; }

		public static Material MatDecompiledFeathers { get; private set; }

		public static Material MatDecompiledEye { get; private set; }

		public static Sprite TexAngelHereticIcon { get; private set; }

		public static Sprite TexDecompiledHereticIcon { get; private set; }

		public static SkinConfig AngelSkinConfig { get; private set; }

		internal static string AssemblyDir => Path.GetDirectoryName(BobsHereticsPlugin.PluginInfo.Location);

		public static void Init()
		{
			using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("BobsHeretics.bobshereticsassets"))
			{
				MainAssetBundle = AssetBundle.LoadFromStream(stream);
			}
			if ((Object)(object)MainAssetBundle == (Object)null)
			{
				BobsHereticsPlugin.Log.LogError((object)"Failed to load asset bundle!");
				return;
			}
			MatAngelBody = MainAssetBundle.LoadAsset<Material>("matHereticAngel");
			MatAngelClothes = MainAssetBundle.LoadAsset<Material>("matAngelClothes");
			MatAngelFeathers = MainAssetBundle.LoadAsset<Material>("matAngelFeathers");
			MatAngelEye = MainAssetBundle.LoadAsset<Material>("matAngelEye");
			MatDecompiledBody = MainAssetBundle.LoadAsset<Material>("matDecompiledBody");
			MatDecompiledClothes = MainAssetBundle.LoadAsset<Material>("matDecompiledClothes");
			MatDecompiledFeathers = MainAssetBundle.LoadAsset<Material>("matDecompiledFeathers");
			MatDecompiledEye = MainAssetBundle.LoadAsset<Material>("matDecompiledEye");
			TexAngelHereticIcon = MainAssetBundle.LoadAsset<Sprite>("texAngelHereticIcon");
			TexDecompiledHereticIcon = MainAssetBundle.LoadAsset<Sprite>("texDecompiledHereticIcon");
			AngelSkinConfig = MainAssetBundle.LoadAsset<SkinConfig>("AngelSkinConfig");
			if ((Object)(object)MatAngelBody == (Object)null)
			{
				BobsHereticsPlugin.Log.LogWarning((object)"matHereticAngel not found in asset bundle!");
			}
			if ((Object)(object)MatAngelClothes == (Object)null)
			{
				BobsHereticsPlugin.Log.LogWarning((object)"matAngelClothes not found in asset bundle!");
			}
			if ((Object)(object)MatAngelFeathers == (Object)null)
			{
				BobsHereticsPlugin.Log.LogWarning((object)"matAngelFeathers not found in asset bundle!");
			}
			if ((Object)(object)MatAngelEye == (Object)null)
			{
				BobsHereticsPlugin.Log.LogWarning((object)"matAngelEye not found in asset bundle!");
			}
			if ((Object)(object)MatDecompiledBody == (Object)null)
			{
				BobsHereticsPlugin.Log.LogWarning((object)"matDecompiledBody not found in asset bundle!");
			}
			if ((Object)(object)MatDecompiledClothes == (Object)null)
			{
				BobsHereticsPlugin.Log.LogWarning((object)"matDecompiledClothes not found in asset bundle!");
			}
			if ((Object)(object)MatDecompiledFeathers == (Object)null)
			{
				BobsHereticsPlugin.Log.LogWarning((object)"matDecompiledFeathers not found in asset bundle!");
			}
			if ((Object)(object)MatDecompiledEye == (Object)null)
			{
				BobsHereticsPlugin.Log.LogWarning((object)"matDecompiledEye not found in asset bundle!");
			}
		}

		public static void FixMaterialShaders()
		{
			_hgStandardShader = Shader.Find("Hopoo Games/Deferred/Standard");
			if ((Object)(object)_hgStandardShader == (Object)null)
			{
				Material val = LegacyResourcesAPI.Load<Material>("Materials/matCommando");
				if ((Object)(object)val != (Object)null)
				{
					_hgStandardShader = val.shader;
				}
			}
			if ((Object)(object)_hgStandardShader == (Object)null)
			{
				BobsHereticsPlugin.Log.LogError((object)"Failed to find shader - materials will appear pink!");
				return;
			}
			FixShader(MatAngelBody, "MatAngelBody");
			FixShader(MatAngelClothes, "MatAngelClothes");
			FixShader(MatAngelFeathers, "MatAngelFeathers");
			FixShader(MatAngelEye, "MatAngelEye");
			FixShader(MatDecompiledBody, "MatDecompiledBody");
			FixShader(MatDecompiledClothes, "MatDecompiledClothes");
			FixShader(MatDecompiledFeathers, "MatDecompiledFeathers");
			FixShader(MatDecompiledEye, "MatDecompiledEye");
		}

		private static void FixShader(Material mat, string name)
		{
			if (!((Object)(object)mat == (Object)null) && ((Object)(object)mat.shader == (Object)null || ((Object)mat.shader).name == "Hidden/InternalErrorShader"))
			{
				mat.shader = _hgStandardShader;
				BobsHereticsPlugin.Log.LogInfo((object)("Fixed shader on " + name));
			}
		}
	}
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("bob.bobs-heretics", "bobs-heretics", "1.0.0")]
	public class BobsHereticsPlugin : BaseUnityPlugin
	{
		public const string PluginGUID = "bob.bobs-heretics";

		public const string PluginName = "bobs-heretics";

		public const string PluginVersion = "1.0.0";

		public static PluginInfo PluginInfo { get; private set; }

		public static ManualLogSource Log { get; private set; }

		public static BodyIndex HereticBodyIndex { get; private set; }

		public void Awake()
		{
			PluginInfo = ((BaseUnityPlugin)this).Info;
			Log = ((BaseUnityPlugin)this).Logger;
			Log.LogInfo((object)"bobs-heretics v1.0.0 initializing...");
			Assets.Init();
			Tokens.Init();
			AngelHereticSkin.RegisterUnlockable();
			DecompiledHereticSkin.RegisterUnlockable();
			RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(OnGameLoad));
		}

		private void OnGameLoad()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Invalid comparison between Unknown and I4
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Invalid comparison between Unknown and I4
			HereticBodyIndex = BodyCatalog.FindBodyIndex("HereticBody");
			if ((int)HereticBodyIndex == -1)
			{
				Log.LogError((object)"Could not find HereticBody! Heretic skins will not be added.");
			}
			Assets.FixMaterialShaders();
			if ((int)HereticBodyIndex != -1)
			{
				SkinManager.Init();
				AngelHereticSkin.SetupSkinHooks();
			}
			ArtificerSkinBase.CacheBodyIndex();
			ArtificerSkinBase.InitializeSkins();
			ArtificerSkinBase.SetupSkinHooks();
			Log.LogInfo((object)"bobs-heretics loaded successfully!");
		}
	}
	public class SkinConfig : ScriptableObject
	{
		[Serializable]
		public class PrefabAttachment
		{
			public string name = "Effect";

			public GameObject prefab;

			public string parentBoneName = "Head_M";

			public Vector3 positionOffset = Vector3.zero;

			public Vector3 rotationOffset = Vector3.zero;

			public Vector3 scale = Vector3.one;
		}

		public List<string> meshesToHide = new List<string>();

		public List<PrefabAttachment> prefabAttachments = new List<PrefabAttachment>();
	}
	public static class Tokens
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static hook_SetFolders <0>__Language_SetFolders;
		}

		public static void Init()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			object obj = <>O.<0>__Language_SetFolders;
			if (obj == null)
			{
				hook_SetFolders val = Language_SetFolders;
				<>O.<0>__Language_SetFolders = val;
				obj = (object)val;
			}
			Language.SetFolders += (hook_SetFolders)obj;
		}

		private static void Language_SetFolders(orig_SetFolders orig, Language self, IEnumerable<string> newFolders)
		{
			orig.Invoke(self, newFolders);
			if (self.name == "en")
			{
				self.SetStringByToken("BOBSHERETICS_SKIN_ANGEL_HERETIC_NAME", "Angel");
				self.SetStringByToken("ACHIEVEMENT_BOBSHERETICS_ACHIEVEMENT_ANGELHERETIC_NAME", "Heretic: Ascension");
				self.SetStringByToken("ACHIEVEMENT_BOBSHERETICS_ACHIEVEMENT_ANGELHERETIC_DESCRIPTION", "As Heretic, complete a run on any difficulty.");
				self.SetStringByToken("BOBSHERETICS_SKIN_DECOMPILED_HERETIC_NAME", "Decompiled");
				self.SetStringByToken("ACHIEVEMENT_BOBSHERETICS_DECOMPILED_HERETIC_NAME", "Heretic: Assimilated");
				self.SetStringByToken("ACHIEVEMENT_BOBSHERETICS_DECOMPILED_HERETIC_DESCRIPTION", "As Heretic, enter the Neural Sanctum.");
			}
		}
	}
}
namespace BobsHeretics.Skins
{
	public static class AngelHereticSkin
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static hook_Awake <0>__DisableAwake;

			public static hook_UpdateMaterials <1>__OnUpdateMaterials;
		}

		public const string SKIN_NAME = "BOBSHERETICS_SKIN_ANGEL_HERETIC";

		public const string SKIN_NAME_TOKEN = "BOBSHERETICS_SKIN_ANGEL_HERETIC_NAME";

		public const string UNLOCKABLE_IDENTIFIER = "Skins.AngelHeretic";

		public static readonly string[] MeshesToHide = new string[3] { "Mesh_HereticTabard", "Mesh_HereticFeathersSmall", "Mesh_HereticBodyFeathers" };

		public static UnlockableDef AngelHereticUnlockableDef { get; private set; }

		public static void RegisterUnlockable()
		{
			AngelHereticUnlockableDef = ScriptableObject.CreateInstance<UnlockableDef>();
			AngelHereticUnlockableDef.cachedName = "Skins.AngelHeretic";
			AngelHereticUnlockableDef.nameToken = "BOBSHERETICS_SKIN_ANGEL_HERETIC_NAME";
			AngelHereticUnlockableDef.achievementIcon = Assets.TexAngelHereticIcon;
			ContentAddition.AddUnlockableDef(AngelHereticUnlockableDef);
		}

		public static SkinDef CreateSkin(GameObject modelObject, CharacterModel characterModel)
		{
			if ((Object)(object)Assets.MatAngelBody == (Object)null)
			{
				BobsHereticsPlugin.Log.LogError((object)"Cannot create Angel Heretic skin: materials not loaded!");
				return null;
			}
			Sprite val = Assets.TexAngelHereticIcon;
			if ((Object)(object)val == (Object)null)
			{
				ModelSkinController component = modelObject.GetComponent<ModelSkinController>();
				if (component != null && component.skins?.Length > 0)
				{
					val = component.skins[0].icon;
				}
			}
			RendererInfo[] rendererInfos = CreateRendererInfos(characterModel.baseRendererInfos);
			return CreateSkinDef(modelObject, rendererInfos, val);
		}

		private static RendererInfo[] CreateRendererInfos(RendererInfo[] baseInfos)
		{
			//IL_0013: 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_0052: 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_007e: Unknown result type (might be due to invalid IL or missing references)
			RendererInfo[] array = (RendererInfo[])(object)new RendererInfo[baseInfos.Length];
			for (int i = 0; i < baseInfos.Length; i++)
			{
				array[i] = new RendererInfo
				{
					renderer = baseInfos[i].renderer,
					defaultMaterial = GetMaterial(baseInfos[i].renderer),
					defaultShadowCastingMode = baseInfos[i].defaultShadowCastingMode,
					ignoreOverlays = baseInfos[i].ignoreOverlays,
					hideOnDeath = baseInfos[i].hideOnDeath
				};
			}
			return array;
		}

		private static Material GetMaterial(Renderer renderer)
		{
			string text = ((Object)((Component)renderer).gameObject).name.ToLower();
			if (text.Contains("eye"))
			{
				return Assets.MatAngelEye ?? Assets.MatAngelBody;
			}
			if (text.Contains("feather"))
			{
				return Assets.MatAngelFeathers ?? Assets.MatAngelBody;
			}
			if (text.Contains("cloth") || text.Contains("cape") || text.Contains("sash") || text.Contains("tabard") || text.Contains("band"))
			{
				return Assets.MatAngelClothes ?? Assets.MatAngelBody;
			}
			return Assets.MatAngelBody;
		}

		private static SkinDef CreateSkinDef(GameObject modelObject, RendererInfo[] rendererInfos, Sprite icon)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Expected O, but got Unknown
			object obj = <>O.<0>__DisableAwake;
			if (obj == null)
			{
				hook_Awake val = DisableAwake;
				<>O.<0>__DisableAwake = val;
				obj = (object)val;
			}
			SkinDef.Awake += (hook_Awake)obj;
			SkinDef val2 = ScriptableObject.CreateInstance<SkinDef>();
			((Object)val2).name = "BOBSHERETICS_SKIN_ANGEL_HERETIC";
			val2.nameToken = "BOBSHERETICS_SKIN_ANGEL_HERETIC_NAME";
			val2.icon = icon;
			val2.rootObject = modelObject;
			val2.unlockableDef = AngelHereticUnlockableDef;
			val2.baseSkins = Array.Empty<SkinDef>();
			SkinDefParams val3 = ScriptableObject.CreateInstance<SkinDefParams>();
			((Object)val3).name = "BOBSHERETICS_SKIN_ANGEL_HERETIC_Params";
			val3.rendererInfos = rendererInfos;
			val3.gameObjectActivations = Array.Empty<GameObjectActivation>();
			val3.meshReplacements = Array.Empty<MeshReplacement>();
			val3.projectileGhostReplacements = Array.Empty<ProjectileGhostReplacement>();
			val3.minionSkinReplacements = Array.Empty<MinionSkinReplacement>();
			val2.skinDefParams = val3;
			object obj2 = <>O.<0>__DisableAwake;
			if (obj2 == null)
			{
				hook_Awake val4 = DisableAwake;
				<>O.<0>__DisableAwake = val4;
				obj2 = (object)val4;
			}
			SkinDef.Awake -= (hook_Awake)obj2;
			return val2;
		}

		private static void DisableAwake(orig_Awake orig, SkinDef self)
		{
		}

		public static void SetupSkinHooks()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			object obj = <>O.<1>__OnUpdateMaterials;
			if (obj == null)
			{
				hook_UpdateMaterials val = OnUpdateMaterials;
				<>O.<1>__OnUpdateMaterials = val;
				obj = (object)val;
			}
			CharacterModel.UpdateMaterials += (hook_UpdateMaterials)obj;
			BobsHereticsPlugin.Log.LogInfo((object)"Angel skin mesh hook ready");
		}

		private static void OnUpdateMaterials(orig_UpdateMaterials orig, CharacterModel self)
		{
			orig.Invoke(self);
			if (!((Object)((Component)self).gameObject).name.ToLower().Contains("heretic"))
			{
				return;
			}
			ModelSkinController component = ((Component)self).GetComponent<ModelSkinController>();
			if ((Object)(object)component == (Object)null || component.skins == null)
			{
				return;
			}
			int currentSkinIndex = component.currentSkinIndex;
			if (currentSkinIndex >= 0 && currentSkinIndex < component.skins.Length)
			{
				string name = ((Object)component.skins[currentSkinIndex]).name;
				bool flag = name == "BOBSHERETICS_SKIN_ANGEL_HERETIC";
				bool flag2 = name == "BOBSHERETICS_SKIN_DECOMPILED_HERETIC";
				ReEnableAllMeshes(((Component)self).transform, MeshesToHide);
				ReEnableAllMeshes(((Component)self).transform, DecompiledHereticSkin.MeshesToHide);
				if (flag)
				{
					ApplyMeshVisibility(((Component)self).transform, MeshesToHide, shouldHide: true);
				}
				else if (flag2)
				{
					ApplyMeshVisibility(((Component)self).transform, DecompiledHereticSkin.MeshesToHide, shouldHide: true);
				}
			}
		}

		private static void ReEnableAllMeshes(Transform root, string[] meshNames)
		{
			if (meshNames == null || meshNames.Length == 0)
			{
				return;
			}
			foreach (string name in meshNames)
			{
				Transform val = FindChildRecursive(root, name);
				if ((Object)(object)val != (Object)null)
				{
					((Component)val).gameObject.SetActive(true);
					Renderer component = ((Component)val).GetComponent<Renderer>();
					if ((Object)(object)component != (Object)null)
					{
						component.enabled = true;
					}
				}
			}
		}

		private static void ApplyMeshVisibility(Transform root, string[] meshesToHide, bool shouldHide)
		{
			if (meshesToHide == null || meshesToHide.Length == 0)
			{
				return;
			}
			foreach (string name in meshesToHide)
			{
				Transform val = FindChildRecursive(root, name);
				if ((Object)(object)val != (Object)null)
				{
					((Component)val).gameObject.SetActive(!shouldHide);
					Renderer component = ((Component)val).GetComponent<Renderer>();
					if ((Object)(object)component != (Object)null)
					{
						component.enabled = !shouldHide;
					}
				}
			}
		}

		private static Transform FindChildRecursive(Transform parent, string name)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			if (((Object)parent).name == name)
			{
				return parent;
			}
			foreach (Transform item in parent)
			{
				Transform parent2 = item;
				Transform val = FindChildRecursive(parent2, name);
				if ((Object)(object)val != (Object)null)
				{
					return val;
				}
			}
			return null;
		}
	}
	public static class DecompiledHereticSkin
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static hook_Awake <0>__DisableAwake;
		}

		public const string SKIN_NAME = "BOBSHERETICS_SKIN_DECOMPILED_HERETIC";

		public const string SKIN_NAME_TOKEN = "BOBSHERETICS_SKIN_DECOMPILED_HERETIC_NAME";

		public const string UNLOCKABLE_IDENTIFIER = "Skins.DecompiledHeretic";

		public static readonly string[] MeshesToHide = new string[9] { "Mesh_HereticFeathersLarge", "Mesh_HereticFeathersSmall", "Mesh_HereticBodyFeathers", "Mesh_HereticClothes", "Mesh_HereticCape", "Mesh_HereticSash", "Mesh_HereticTabard", "Mesh_HereticBandArms", "Mesh_HereticBandTorso" };

		public static UnlockableDef DecompiledHereticUnlockableDef { get; private set; }

		public static void RegisterUnlockable()
		{
			DecompiledHereticUnlockableDef = ScriptableObject.CreateInstance<UnlockableDef>();
			DecompiledHereticUnlockableDef.cachedName = "Skins.DecompiledHeretic";
			DecompiledHereticUnlockableDef.nameToken = "BOBSHERETICS_SKIN_DECOMPILED_HERETIC_NAME";
			DecompiledHereticUnlockableDef.achievementIcon = Assets.TexDecompiledHereticIcon;
			ContentAddition.AddUnlockableDef(DecompiledHereticUnlockableDef);
		}

		public static SkinDef CreateSkin(GameObject modelObject, CharacterModel characterModel)
		{
			if ((Object)(object)Assets.MatDecompiledBody == (Object)null)
			{
				BobsHereticsPlugin.Log.LogError((object)"Cannot create Decompiled Heretic skin: materials not loaded!");
				return null;
			}
			Sprite val = Assets.TexDecompiledHereticIcon;
			if ((Object)(object)val == (Object)null)
			{
				ModelSkinController component = modelObject.GetComponent<ModelSkinController>();
				if (component != null && component.skins?.Length > 0)
				{
					val = component.skins[0].icon;
				}
			}
			RendererInfo[] rendererInfos = CreateRendererInfos(characterModel.baseRendererInfos);
			return CreateSkinDef(modelObject, rendererInfos, val);
		}

		private static RendererInfo[] CreateRendererInfos(RendererInfo[] baseInfos)
		{
			//IL_0013: 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_0052: 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_007e: Unknown result type (might be due to invalid IL or missing references)
			RendererInfo[] array = (RendererInfo[])(object)new RendererInfo[baseInfos.Length];
			for (int i = 0; i < baseInfos.Length; i++)
			{
				array[i] = new RendererInfo
				{
					renderer = baseInfos[i].renderer,
					defaultMaterial = GetMaterial(baseInfos[i].renderer),
					defaultShadowCastingMode = baseInfos[i].defaultShadowCastingMode,
					ignoreOverlays = baseInfos[i].ignoreOverlays,
					hideOnDeath = baseInfos[i].hideOnDeath
				};
			}
			return array;
		}

		private static Material GetMaterial(Renderer renderer)
		{
			string text = ((Object)((Component)renderer).gameObject).name.ToLower();
			if (text.Contains("eye"))
			{
				return Assets.MatDecompiledEye ?? Assets.MatDecompiledBody;
			}
			if (text.Contains("feather"))
			{
				return Assets.MatDecompiledFeathers ?? Assets.MatDecompiledBody;
			}
			if (text.Contains("cloth") || text.Contains("cape") || text.Contains("sash") || text.Contains("tabard") || text.Contains("band"))
			{
				return Assets.MatDecompiledClothes ?? Assets.MatDecompiledBody;
			}
			return Assets.MatDecompiledBody;
		}

		private static SkinDef CreateSkinDef(GameObject modelObject, RendererInfo[] rendererInfos, Sprite icon)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Expected O, but got Unknown
			object obj = <>O.<0>__DisableAwake;
			if (obj == null)
			{
				hook_Awake val = DisableAwake;
				<>O.<0>__DisableAwake = val;
				obj = (object)val;
			}
			SkinDef.Awake += (hook_Awake)obj;
			SkinDef val2 = ScriptableObject.CreateInstance<SkinDef>();
			((Object)val2).name = "BOBSHERETICS_SKIN_DECOMPILED_HERETIC";
			val2.nameToken = "BOBSHERETICS_SKIN_DECOMPILED_HERETIC_NAME";
			val2.icon = icon;
			val2.rootObject = modelObject;
			val2.unlockableDef = DecompiledHereticUnlockableDef;
			val2.baseSkins = Array.Empty<SkinDef>();
			SkinDefParams val3 = ScriptableObject.CreateInstance<SkinDefParams>();
			((Object)val3).name = "BOBSHERETICS_SKIN_DECOMPILED_HERETIC_Params";
			val3.rendererInfos = rendererInfos;
			val3.gameObjectActivations = Array.Empty<GameObjectActivation>();
			val3.meshReplacements = Array.Empty<MeshReplacement>();
			val3.projectileGhostReplacements = Array.Empty<ProjectileGhostReplacement>();
			val3.minionSkinReplacements = Array.Empty<MinionSkinReplacement>();
			val2.skinDefParams = val3;
			object obj2 = <>O.<0>__DisableAwake;
			if (obj2 == null)
			{
				hook_Awake val4 = DisableAwake;
				<>O.<0>__DisableAwake = val4;
				obj2 = (object)val4;
			}
			SkinDef.Awake -= (hook_Awake)obj2;
			return val2;
		}

		private static void DisableAwake(orig_Awake orig, SkinDef self)
		{
		}
	}
	public static class SkinManager
	{
		private static bool _initialized;

		public static void Init()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
			if (_initialized)
			{
				return;
			}
			_initialized = true;
			GameObject bodyPrefab = BodyCatalog.GetBodyPrefab(BobsHereticsPlugin.HereticBodyIndex);
			if ((Object)(object)bodyPrefab == (Object)null)
			{
				BobsHereticsPlugin.Log.LogError((object)"HereticBody prefab not found!");
				return;
			}
			ModelLocator component = bodyPrefab.GetComponent<ModelLocator>();
			if ((Object)(object)component == (Object)null || (Object)(object)component.modelTransform == (Object)null)
			{
				BobsHereticsPlugin.Log.LogError((object)"ModelLocator or modelTransform not found on HereticBody!");
				return;
			}
			GameObject gameObject = ((Component)component.modelTransform).gameObject;
			CharacterModel component2 = gameObject.GetComponent<CharacterModel>();
			if ((Object)(object)component2 == (Object)null)
			{
				BobsHereticsPlugin.Log.LogError((object)"CharacterModel not found on Heretic model!");
				return;
			}
			BobsHereticsPlugin.Log.LogInfo((object)"=== HERETIC BONE HIERARCHY ===");
			LogBoneHierarchy(gameObject.transform, 0);
			BobsHereticsPlugin.Log.LogInfo((object)"=== END BONE HIERARCHY ===");
			ModelSkinController component3 = gameObject.GetComponent<ModelSkinController>();
			if ((Object)(object)component3 == (Object)null)
			{
				BobsHereticsPlugin.Log.LogError((object)"ModelSkinController not found on Heretic model!");
				return;
			}
			int num = 0;
			SkinDef val = AngelHereticSkin.CreateSkin(gameObject, component2);
			if ((Object)(object)val != (Object)null)
			{
				bool flag = Skins.AddSkinToCharacter(bodyPrefab, val);
				BobsHereticsPlugin.Log.LogInfo((object)$"Skins.AddSkinToCharacter returned: {flag}");
				if (flag)
				{
					num++;
					BobsHereticsPlugin.Log.LogInfo((object)"Angel Heretic skin added successfully.");
					UpdateSkinCatalog(val, BobsHereticsPlugin.HereticBodyIndex);
					UpdateDisplayPrefab(val);
				}
				else
				{
					BobsHereticsPlugin.Log.LogError((object)"Failed to add Angel Heretic skin via R2API.Skins!");
				}
			}
			SkinDef val2 = DecompiledHereticSkin.CreateSkin(gameObject, component2);
			if ((Object)(object)val2 != (Object)null)
			{
				bool flag2 = Skins.AddSkinToCharacter(bodyPrefab, val2);
				BobsHereticsPlugin.Log.LogInfo((object)$"Skins.AddSkinToCharacter (Decompiled) returned: {flag2}");
				if (flag2)
				{
					num++;
					BobsHereticsPlugin.Log.LogInfo((object)"Decompiled Heretic skin added successfully.");
					UpdateSkinCatalog(val2, BobsHereticsPlugin.HereticBodyIndex);
					UpdateDisplayPrefab(val2);
				}
				else
				{
					BobsHereticsPlugin.Log.LogError((object)"Failed to add Decompiled Heretic skin via R2API.Skins!");
				}
			}
			BobsHereticsPlugin.Log.LogInfo((object)$"Successfully added {num} skin(s) to Heretic.");
		}

		private static void UpdateDisplayPrefab(SkinDef newSkin)
		{
			//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)
			SurvivorDef val = null;
			foreach (SurvivorDef allSurvivorDef in SurvivorCatalog.allSurvivorDefs)
			{
				if ((Object)(object)allSurvivorDef.bodyPrefab != (Object)null && BodyCatalog.FindBodyIndex(allSurvivorDef.bodyPrefab) == BobsHereticsPlugin.HereticBodyIndex)
				{
					val = allSurvivorDef;
					break;
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				BobsHereticsPlugin.Log.LogWarning((object)"Could not find Heretic SurvivorDef - display prefab not updated");
				return;
			}
			if ((Object)(object)val.displayPrefab == (Object)null)
			{
				BobsHereticsPlugin.Log.LogWarning((object)"Heretic SurvivorDef has no displayPrefab");
				return;
			}
			BobsHereticsPlugin.Log.LogInfo((object)("Found Heretic display prefab: " + ((Object)val.displayPrefab).name));
			ModelSkinController val2 = val.displayPrefab.GetComponentInChildren<ModelSkinController>();
			if ((Object)(object)val2 == (Object)null)
			{
				CharacterModel componentInChildren = val.displayPrefab.GetComponentInChildren<CharacterModel>();
				if (!((Object)(object)componentInChildren != (Object)null))
				{
					BobsHereticsPlugin.Log.LogWarning((object)"Could not find suitable object for ModelSkinController on display prefab");
					return;
				}
				val2 = ((Component)componentInChildren).gameObject.AddComponent<ModelSkinController>();
				val2.skins = (SkinDef[])(object)new SkinDef[0];
				BobsHereticsPlugin.Log.LogInfo((object)"Added ModelSkinController to display prefab");
			}
			SkinDef[] skins = val2.skins;
			int num = ((skins != null) ? skins.Length : 0);
			SkinDef[] array = (SkinDef[])(object)new SkinDef[num + 1];
			for (int i = 0; i < num; i++)
			{
				array[i] = val2.skins[i];
			}
			array[num] = newSkin;
			val2.skins = array;
			BobsHereticsPlugin.Log.LogInfo((object)$"Updated display prefab skins array from {num} to {array.Length}");
		}

		private static void UpdateSkinCatalog(SkinDef newSkin, BodyIndex bodyIndex)
		{
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Expected I4, but got Unknown
			try
			{
				FieldInfo field = typeof(SkinCatalog).GetField("skinsByBody", BindingFlags.Static | BindingFlags.NonPublic);
				if (field == null)
				{
					BobsHereticsPlugin.Log.LogWarning((object)"Could not find SkinCatalog.skinsByBody field");
					return;
				}
				SkinDef[][] array = (SkinDef[][])field.GetValue(null);
				if (array == null)
				{
					BobsHereticsPlugin.Log.LogWarning((object)"SkinCatalog.skinsByBody is null");
					return;
				}
				int num = (int)bodyIndex;
				if (num < 0 || num >= array.Length)
				{
					BobsHereticsPlugin.Log.LogWarning((object)$"Body index {num} out of range for skinsByBody");
					return;
				}
				SkinDef[] array2 = array[num];
				SkinDef[] array3 = array2;
				foreach (SkinDef val in array3)
				{
					if ((Object)(object)val == (Object)(object)newSkin)
					{
						BobsHereticsPlugin.Log.LogInfo((object)"Skin already in SkinCatalog, skipping update");
						return;
					}
				}
				int num2 = array2.Length;
				SkinDef[] array4 = (SkinDef[])(object)new SkinDef[num2 + 1];
				Array.Copy(array2, array4, num2);
				array4[num2] = newSkin;
				array[num] = array4;
				BobsHereticsPlugin.Log.LogInfo((object)$"Updated skinsByBody[{num}] from {num2} to {array4.Length} skins");
				FieldInfo field2 = typeof(SkinCatalog).GetField("allSkinDefs", BindingFlags.Static | BindingFlags.NonPublic);
				if (field2 != null)
				{
					SkinDef[] array5 = (SkinDef[])field2.GetValue(null);
					if (array5 != null)
					{
						int num3 = array5.Length;
						SkinDef[] array6 = (SkinDef[])(object)new SkinDef[num3 + 1];
						Array.Copy(array5, array6, num3);
						array6[num3] = newSkin;
						field2.SetValue(null, array6);
						BobsHereticsPlugin.Log.LogInfo((object)$"Updated allSkinDefs from {num3} to {array6.Length}, new skin index: {num3}");
					}
				}
				BobsHereticsPlugin.Log.LogInfo((object)"SkinCatalog updated via reflection");
			}
			catch (Exception ex)
			{
				BobsHereticsPlugin.Log.LogError((object)("Failed to update SkinCatalog: " + ex.Message));
			}
		}

		private static void LogBoneHierarchy(Transform t, int depth)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			string text = new string(' ', depth * 2);
			BobsHereticsPlugin.Log.LogInfo((object)(text + ((Object)t).name));
			foreach (Transform item in t)
			{
				Transform t2 = item;
				LogBoneHierarchy(t2, depth + 1);
			}
		}
	}
}
namespace BobsHeretics.Skins.ArtificerSkins
{
	public static class ArtificerSkinBase
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static hook_UpdateMaterials <0>__OnUpdateMaterials;
		}

		private static bool _hooksInitialized = false;

		public static readonly string[] KnownMeshes = new string[0];

		public static BodyIndex ArtificerBodyIndex { get; private set; }

		public static void CacheBodyIndex()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Invalid comparison between Unknown and I4
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Expected I4, but got Unknown
			ArtificerBodyIndex = BodyCatalog.FindBodyIndex("MageBody");
			if ((int)ArtificerBodyIndex == -1)
			{
				BobsHereticsPlugin.Log.LogError((object)"Could not find MageBody (Artificer)!");
			}
			else
			{
				BobsHereticsPlugin.Log.LogInfo((object)$"Found Artificer body index: {(int)ArtificerBodyIndex}");
			}
		}

		public static void InitializeSkins()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			if ((int)ArtificerBodyIndex == -1)
			{
				BobsHereticsPlugin.Log.LogError((object)"Cannot initialize Artificer skins - body index not found!");
				return;
			}
			GameObject bodyPrefab = BodyCatalog.GetBodyPrefab(ArtificerBodyIndex);
			if ((Object)(object)bodyPrefab == (Object)null)
			{
				BobsHereticsPlugin.Log.LogError((object)"Artificer body prefab not found!");
				return;
			}
			ModelLocator component = bodyPrefab.GetComponent<ModelLocator>();
			if ((Object)(object)component == (Object)null || (Object)(object)component.modelTransform == (Object)null)
			{
				BobsHereticsPlugin.Log.LogError((object)"ModelLocator not found on Artificer!");
				return;
			}
			GameObject gameObject = ((Component)component.modelTransform).gameObject;
			CharacterModel component2 = gameObject.GetComponent<CharacterModel>();
			if ((Object)(object)component2 == (Object)null)
			{
				BobsHereticsPlugin.Log.LogError((object)"CharacterModel not found on Artificer!");
				return;
			}
			BobsHereticsPlugin.Log.LogInfo((object)"=== ARTIFICER HIERARCHY ===");
			LogHierarchy(gameObject.transform, 0);
			BobsHereticsPlugin.Log.LogInfo((object)"=== END ARTIFICER HIERARCHY ===");
			BobsHereticsPlugin.Log.LogInfo((object)"=== ARTIFICER RENDERERS ===");
			RendererInfo[] baseRendererInfos = component2.baseRendererInfos;
			foreach (RendererInfo val in baseRendererInfos)
			{
				if ((Object)(object)val.renderer != (Object)null)
				{
					BobsHereticsPlugin.Log.LogInfo((object)("  Renderer: " + ((Object)((Component)val.renderer).gameObject).name));
				}
			}
			BobsHereticsPlugin.Log.LogInfo((object)"=== END ARTIFICER RENDERERS ===");
			int num = 0;
			BobsHereticsPlugin.Log.LogInfo((object)$"Added {num} skin(s) to Artificer.");
		}

		public static bool AddSkinToCharacter(GameObject bodyPrefab, SkinDef skinDef)
		{
			bool flag = Skins.AddSkinToCharacter(bodyPrefab, skinDef);
			if (flag)
			{
				BobsHereticsPlugin.Log.LogInfo((object)("Added skin '" + ((Object)skinDef).name + "' to Artificer"));
			}
			else
			{
				BobsHereticsPlugin.Log.LogError((object)("Failed to add skin '" + ((Object)skinDef).name + "' to Artificer"));
			}
			return flag;
		}

		public static void SetupSkinHooks()
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			if (!_hooksInitialized)
			{
				_hooksInitialized = true;
				object obj = <>O.<0>__OnUpdateMaterials;
				if (obj == null)
				{
					hook_UpdateMaterials val = OnUpdateMaterials;
					<>O.<0>__OnUpdateMaterials = val;
					obj = (object)val;
				}
				CharacterModel.UpdateMaterials += (hook_UpdateMaterials)obj;
				BobsHereticsPlugin.Log.LogInfo((object)"Artificer skin hooks initialized");
			}
		}

		private static void OnUpdateMaterials(orig_UpdateMaterials orig, CharacterModel self)
		{
			orig.Invoke(self);
			if (!((Object)((Component)self).gameObject).name.ToLower().Contains("mage"))
			{
				return;
			}
			ModelSkinController component = ((Component)self).GetComponent<ModelSkinController>();
			if (!((Object)(object)component == (Object)null) && component.skins != null)
			{
				int currentSkinIndex = component.currentSkinIndex;
				if (currentSkinIndex >= 0 && currentSkinIndex < component.skins.Length)
				{
					string name = ((Object)component.skins[currentSkinIndex]).name;
				}
			}
		}

		private static void ApplyMeshVisibility(Transform root, string[] meshesToHide, bool shouldHide)
		{
			if (meshesToHide == null || meshesToHide.Length == 0)
			{
				return;
			}
			foreach (string name in meshesToHide)
			{
				Transform val = FindChildRecursive(root, name);
				if ((Object)(object)val != (Object)null)
				{
					((Component)val).gameObject.SetActive(!shouldHide);
					Renderer component = ((Component)val).GetComponent<Renderer>();
					if ((Object)(object)component != (Object)null)
					{
						component.enabled = !shouldHide;
					}
				}
			}
		}

		private static Transform FindChildRecursive(Transform parent, string name)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			if (((Object)parent).name == name)
			{
				return parent;
			}
			foreach (Transform item in parent)
			{
				Transform parent2 = item;
				Transform val = FindChildRecursive(parent2, name);
				if ((Object)(object)val != (Object)null)
				{
					return val;
				}
			}
			return null;
		}

		private static void LogHierarchy(Transform t, int depth)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			string text = new string(' ', depth * 2);
			BobsHereticsPlugin.Log.LogInfo((object)(text + ((Object)t).name));
			foreach (Transform item in t)
			{
				Transform t2 = item;
				LogHierarchy(t2, depth + 1);
			}
		}
	}
	public static class ExampleArtificerSkin
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static hook_Awake <0>__DisableAwake;
		}

		public const string SKIN_NAME = "BOBSHERETICS_SKIN_EXAMPLE_ARTIFICER";

		public const string SKIN_NAME_TOKEN = "BOBSHERETICS_SKIN_EXAMPLE_ARTIFICER_NAME";

		public const string UNLOCKABLE_IDENTIFIER = "Skins.ExampleArtificer";

		public static readonly string[] MeshesToHide = new string[0];

		public static UnlockableDef UnlockableDef { get; private set; }

		public static void RegisterUnlockable()
		{
		}

		public static SkinDef CreateSkin(GameObject modelObject, CharacterModel characterModel)
		{
			return null;
		}

		private static RendererInfo[] CreateRendererInfos(RendererInfo[] baseInfos)
		{
			//IL_0013: 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_0052: 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_007e: Unknown result type (might be due to invalid IL or missing references)
			RendererInfo[] array = (RendererInfo[])(object)new RendererInfo[baseInfos.Length];
			for (int i = 0; i < baseInfos.Length; i++)
			{
				array[i] = new RendererInfo
				{
					renderer = baseInfos[i].renderer,
					defaultMaterial = GetMaterial(baseInfos[i].renderer),
					defaultShadowCastingMode = baseInfos[i].defaultShadowCastingMode,
					ignoreOverlays = baseInfos[i].ignoreOverlays,
					hideOnDeath = baseInfos[i].hideOnDeath
				};
			}
			return array;
		}

		private static Material GetMaterial(Renderer renderer)
		{
			string text = ((Object)((Component)renderer).gameObject).name.ToLower();
			return null;
		}

		private static SkinDef CreateSkinDef(GameObject modelObject, RendererInfo[] rendererInfos, Sprite icon)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Expected O, but got Unknown
			object obj = <>O.<0>__DisableAwake;
			if (obj == null)
			{
				hook_Awake val = DisableAwake;
				<>O.<0>__DisableAwake = val;
				obj = (object)val;
			}
			SkinDef.Awake += (hook_Awake)obj;
			SkinDef val2 = ScriptableObject.CreateInstance<SkinDef>();
			((Object)val2).name = "BOBSHERETICS_SKIN_EXAMPLE_ARTIFICER";
			val2.nameToken = "BOBSHERETICS_SKIN_EXAMPLE_ARTIFICER_NAME";
			val2.icon = icon;
			val2.rootObject = modelObject;
			val2.unlockableDef = UnlockableDef;
			val2.baseSkins = Array.Empty<SkinDef>();
			SkinDefParams val3 = ScriptableObject.CreateInstance<SkinDefParams>();
			((Object)val3).name = "BOBSHERETICS_SKIN_EXAMPLE_ARTIFICER_Params";
			val3.rendererInfos = rendererInfos;
			val3.gameObjectActivations = Array.Empty<GameObjectActivation>();
			val3.meshReplacements = Array.Empty<MeshReplacement>();
			val3.projectileGhostReplacements = Array.Empty<ProjectileGhostReplacement>();
			val3.minionSkinReplacements = Array.Empty<MinionSkinReplacement>();
			val2.skinDefParams = val3;
			object obj2 = <>O.<0>__DisableAwake;
			if (obj2 == null)
			{
				hook_Awake val4 = DisableAwake;
				<>O.<0>__DisableAwake = val4;
				obj2 = (object)val4;
			}
			SkinDef.Awake -= (hook_Awake)obj2;
			BobsHereticsPlugin.Log.LogInfo((object)"Created skin: BOBSHERETICS_SKIN_EXAMPLE_ARTIFICER");
			return val2;
		}

		private static void DisableAwake(orig_Awake orig, SkinDef self)
		{
		}
	}
}
namespace BobsHeretics.Achievements
{
	[RegisterAchievement("BOBSHERETICS_ACHIEVEMENT_ANGELHERETIC", "Skins.AngelHeretic", null, 5u, null)]
	public class AngelHereticAchievement : BaseEndingAchievement
	{
		public const string ACHIEVEMENT_ID = "BOBSHERETICS_ACHIEVEMENT_ANGELHERETIC";

		public const string UNLOCKABLE_IDENTIFIER = "Skins.AngelHeretic";

		public override BodyIndex LookUpRequiredBodyIndex()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			return BodyCatalog.FindBodyIndex("HereticBody");
		}

		public override bool ShouldGrant(RunReport runReport)
		{
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			if (runReport == null || (Object)(object)runReport.gameEnding == (Object)null)
			{
				return false;
			}
			if (!runReport.gameEnding.isWin)
			{
				return false;
			}
			if (((BaseAchievement)this).localUser == null || (Object)(object)((BaseAchievement)this).localUser.cachedBody == (Object)null)
			{
				return false;
			}
			if (((BaseAchievement)this).localUser.cachedBody.bodyIndex != ((BaseAchievement)this).requiredBodyIndex)
			{
				return false;
			}
			return true;
		}
	}
	[RegisterAchievement("BOBSHERETICS_DECOMPILED_HERETIC", "Skins.DecompiledHeretic", null, 5u, null)]
	public class DecompiledHereticAchievement : BaseAchievement
	{
		public override BodyIndex LookUpRequiredBodyIndex()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			return BodyCatalog.FindBodyIndex("HereticBody");
		}

		public override void OnInstall()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected O, but got Unknown
			((BaseAchievement)this).OnInstall();
			ArenaMissionController.EndRound += new hook_EndRound(OnEndRound);
			Active.FixedUpdate += new hook_FixedUpdate(OnNullWardUpdate);
			VoidSurvivorController.OnInventoryChanged += new hook_OnInventoryChanged(OnVoidSurvivorInventoryChanged);
			BobsHereticsPlugin.Log.LogInfo((object)"DecompiledHereticAchievement installed");
		}

		public override void OnUninstall()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			ArenaMissionController.EndRound -= new hook_EndRound(OnEndRound);
			Active.FixedUpdate -= new hook_FixedUpdate(OnNullWardUpdate);
			VoidSurvivorController.OnInventoryChanged -= new hook_OnInventoryChanged(OnVoidSurvivorInventoryChanged);
			((BaseAchievement)this).OnUninstall();
		}

		private void OnEndRound(orig_EndRound orig, ArenaMissionController self)
		{
			orig.Invoke(self);
			CheckAchievement();
		}

		private void OnNullWardUpdate(orig_FixedUpdate orig, Active self)
		{
			orig.Invoke(self);
			CheckAchievement();
		}

		private void OnVoidSurvivorInventoryChanged(orig_OnInventoryChanged orig, VoidSurvivorController self)
		{
			orig.Invoke(self);
			CheckAchievement();
		}

		private void CheckAchievement()
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			LocalUser localUser = ((BaseAchievement)this).localUser;
			if (!((Object)(object)((localUser != null) ? localUser.cachedBody : null) == (Object)null) && ((BaseAchievement)this).localUser.cachedBody.bodyIndex == ((BaseAchievement)this).requiredBodyIndex)
			{
				SceneDef sceneDefForCurrentScene = SceneCatalog.GetSceneDefForCurrentScene();
				string text = ((sceneDefForCurrentScene != null) ? sceneDefForCurrentScene.baseSceneName : null) ?? "";
				if (text.ToLower().Contains("neuralsanctum") || text.ToLower().Contains("neural") || text.ToLower().Contains("sanctum") || text.ToLower().Contains("collective"))
				{
					BobsHereticsPlugin.Log.LogInfo((object)("Heretic on Neural Sanctum: " + text + ", granting achievement!"));
					((BaseAchievement)this).Grant();
				}
			}
		}
	}
	public class DecompiledHereticEndingAchievement : BaseEndingAchievement
	{
		public override BodyIndex LookUpRequiredBodyIndex()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			return BodyCatalog.FindBodyIndex("HereticBody");
		}

		public override bool ShouldGrant(RunReport runReport)
		{
			if (runReport == null)
			{
				return false;
			}
			if ((Object)(object)runReport.gameEnding != (Object)null)
			{
				string text = runReport.gameEnding.cachedName?.ToLower() ?? "";
				BobsHereticsPlugin.Log.LogInfo((object)("Run ended with ending: " + text));
				if (text.Contains("collective") || text.Contains("neural") || text.Contains("alloyed") || text.Contains("sanctum"))
				{
					return true;
				}
			}
			return false;
		}
	}
}