Decompiled source of LucarioHuntress v3.0.0

plugins/LucarioHuntress/huntress.Assets.dll

Decompiled 13 hours ago
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace LucarioHuntress;

[CreateAssetMenu(menuName = "Lucario Huntress/Skin Assets", fileName = "LucarioSkinAssets")]
public sealed class LucarioSkinAssets : ScriptableObject
{
	[Header("Normal Lucario")]
	public Mesh lucarioBodyMesh;

	public Mesh lucarioBowMesh;

	public Material lucarioBodyMaterial;

	public Material lucarioBowMaterial;

	public Sprite lucarioIcon;

	[Header("Shiny Lucario")]
	public Mesh shinyBodyMesh;

	public Mesh shinyBowMesh;

	public Material shinyBodyMaterial;

	public Material shinyBowMaterial;

	public Sprite shinyIcon;

	[Header("Accessories")]
	public GameObject tailPrefab;

	public GameObject leftEarPrefab;

	public GameObject rightEarPrefab;

	public GameObject leftFeelerAPrefab;

	public GameObject leftFeelerBPrefab;

	public GameObject rightFeelerAPrefab;

	public GameObject rightFeelerBPrefab;
}

plugins/LucarioHuntress/huntress.Plugin.dll

Decompiled 13 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Logging;
using MonoMod.RuntimeDetour;
using R2API;
using RoR2;
using RoR2.ContentManagement;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace LucarioHuntress;

[BepInPlugin("com.sussybnuuy.lucariohuntress", "Lucario Huntress", "3.0.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public sealed class LucarioHuntressPlugin : BaseUnityPlugin
{
	private static class BoneChainManager
	{
		private sealed class BonePhysics
		{
			public readonly float Damping;

			public readonly float Elasticity;

			public readonly float Stiffness;

			public readonly AnimationCurve StiffnessDistrib;

			public readonly float Inert;

			public readonly float Radius;

			public readonly AnimationCurve RadiusDistrib;

			public BonePhysics(float damping, float elasticity, float stiffness, AnimationCurve stiffnessDistrib, float inert, float radius, AnimationCurve radiusDistrib)
			{
				Damping = damping;
				Elasticity = elasticity;
				Stiffness = stiffness;
				StiffnessDistrib = stiffnessDistrib;
				Inert = inert;
				Radius = radius;
				RadiusDistrib = radiusDistrib;
			}
		}

		private sealed class BoneChainSpec
		{
			public readonly GameObject Prefab;

			public readonly string ParentBoneName;

			public readonly int BoneIndex;

			public readonly BonePhysics Physics;

			public BoneChainSpec(GameObject prefab, string parentBoneName, int boneIndex, BonePhysics physics)
			{
				Prefab = prefab;
				ParentBoneName = parentBoneName;
				BoneIndex = boneIndex;
				Physics = physics;
			}
		}

		private sealed class AppliedMod
		{
			public GameObject Instance;

			public int BoneIndex;

			public int BoneCount;
		}

		private static readonly Dictionary<string, List<BoneChainSpec>> SpecsByToken = new Dictionary<string, List<BoneChainSpec>>();

		private static readonly Dictionary<GameObject, List<AppliedMod>> AppliedByModel = new Dictionary<GameObject, List<AppliedMod>>();

		private static Hook _hook;

		public static void Register(string nameToken, LucarioSkinAssets assets)
		{
			//IL_0021: 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_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: 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_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: 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_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0200: Unknown result type (might be due to invalid IL or missing references)
			//IL_0205: Unknown result type (might be due to invalid IL or missing references)
			BonePhysics physics = new BonePhysics(0.5f, 0.05f, 0.5f, MakeCurve(new Keyframe(0f, 1f), new Keyframe(1f, 1f)), 0.5f, 0.075f, MakeCurve(new Keyframe(0f, 1f), new Keyframe(0.6188343f, 0.7994766f), new Keyframe(0.9374898f, 0.4150935f)));
			BonePhysics physics2 = new BonePhysics(0.2f, 0.05f, 0.7f, MakeCurve(new Keyframe(0f, 1f), new Keyframe(0.376561f, 0.9664193f), new Keyframe(1.008331f, 0.4976413f)), 0.5f, 0.09f, MakeCurve(new Keyframe(0.2695274f, 0.4551086f), new Keyframe(0.8795762f, 1.058899f), new Keyframe(1.007802f, 0.5145006f)));
			BonePhysics physics3 = new BonePhysics(0.2f, 0.05f, 1f, MakeCurve(new Keyframe(0f, 0f), new Keyframe(1f, 1f)), 0.5f, 0.15f, MakeCurve(new Keyframe(0.0625f, 0.287735f), new Keyframe(0.3043687f, 0.6709288f), new Keyframe(0.6287277f, 0.9080764f), new Keyframe(0.9791565f, 0.1698112f)));
			List<BoneChainSpec> list = new List<BoneChainSpec>
			{
				new BoneChainSpec(assets.rightEarPrefab, "head", 39, physics),
				new BoneChainSpec(assets.leftEarPrefab, "head", 41, physics),
				new BoneChainSpec(assets.rightFeelerAPrefab, "head", 43, physics2),
				new BoneChainSpec(assets.rightFeelerBPrefab, "head", 47, physics2),
				new BoneChainSpec(assets.leftFeelerAPrefab, "head", 51, physics2),
				new BoneChainSpec(assets.leftFeelerBPrefab, "head", 55, physics2),
				new BoneChainSpec(assets.tailPrefab, "pelvis", 68, physics3)
			};
			list.Sort((BoneChainSpec a, BoneChainSpec b) => a.BoneIndex.CompareTo(b.BoneIndex));
			foreach (BoneChainSpec item in list)
			{
				if (!Object.op_Implicit((Object)(object)item.Prefab))
				{
					throw new InvalidOperationException("A Lucario bone-chain prefab is missing for '" + nameToken + "'.");
				}
			}
			SpecsByToken[nameToken] = list;
		}

		private static AnimationCurve MakeCurve(params Keyframe[] keys)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			return new AnimationCurve(keys)
			{
				preWrapMode = (WrapMode)8,
				postWrapMode = (WrapMode)8
			};
		}

		public static void InstallHook()
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Expected O, but got Unknown
			if (_hook == null)
			{
				MethodInfo? method = typeof(ModelSkinController).GetMethod("ApplySkinAsync", BindingFlags.Instance | BindingFlags.Public, null, new Type[2]
				{
					typeof(int),
					typeof(AsyncReferenceHandleUnloadType)
				}, null);
				if (method == null)
				{
					throw new InvalidOperationException("Could not find ModelSkinController.ApplySkinAsync to hook.");
				}
				_hook = new Hook((MethodBase)method, (Delegate)new Func<Func<ModelSkinController, int, AsyncReferenceHandleUnloadType, IEnumerator>, ModelSkinController, int, AsyncReferenceHandleUnloadType, IEnumerator>(ApplySkinAsyncHook));
				Log.LogInfo((object)"BoneChainManager hooked ModelSkinController.ApplySkinAsync.");
			}
		}

		private static IEnumerator ApplySkinAsyncHook(Func<ModelSkinController, int, AsyncReferenceHandleUnloadType, IEnumerator> orig, ModelSkinController self, int skinIndex, AsyncReferenceHandleUnloadType unloadType)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			IEnumerator inner = orig(self, skinIndex, unloadType);
			while (inner.MoveNext())
			{
				yield return inner.Current;
			}
			try
			{
				UpdateModel(self, skinIndex);
			}
			catch (Exception ex)
			{
				Log.LogError((object)("Lucario bone-chain update failed:\n" + ex));
			}
		}

		private static void UpdateModel(ModelSkinController self, int skinIndex)
		{
			if (!Object.op_Implicit((Object)(object)self) || self.skins == null || self.skins.Length == 0)
			{
				return;
			}
			PruneDestroyedModels();
			if ((uint)skinIndex >= self.skins.Length)
			{
				skinIndex = 0;
			}
			SkinDef val = self.skins[skinIndex];
			GameObject gameObject = ((Component)self).gameObject;
			string text = (Object.op_Implicit((Object)(object)val) ? val.nameToken : null);
			bool num = text != null && SpecsByToken.ContainsKey(text);
			AppliedByModel.TryGetValue(gameObject, out var value);
			if (!num)
			{
				if (value != null)
				{
					RemoveMods(gameObject, value);
					AppliedByModel.Remove(gameObject);
				}
			}
			else if (value == null)
			{
				List<AppliedMod> list = new List<AppliedMod>();
				AppliedByModel[gameObject] = list;
				InsertMods(gameObject, SpecsByToken[text], list);
			}
		}

		private static void InsertMods(GameObject modelObject, List<BoneChainSpec> specs, List<AppliedMod> applieds)
		{
			foreach (BoneChainSpec spec in specs)
			{
				Transform val = FindChildInTree(modelObject.transform, spec.ParentBoneName);
				if (!Object.op_Implicit((Object)(object)val))
				{
					Log.LogWarning((object)("Bone-chain parent '" + spec.ParentBoneName + "' not found; skipping " + ((Object)spec.Prefab).name));
					continue;
				}
				SkinnedMeshRenderer[] baseSkinRenderers = GetBaseSkinRenderers(modelObject);
				if (baseSkinRenderers.Length == 0)
				{
					break;
				}
				GameObject val2 = Object.Instantiate<GameObject>(spec.Prefab, val, false);
				((Object)val2).name = RemoveCloneSuffix(((Object)val2).name);
				List<Transform> list = baseSkinRenderers[0].bones.ToList();
				Transform[] array = BuildBoneArray(val2.transform);
				int num = Mathf.Clamp(spec.BoneIndex, 0, list.Count);
				list.InsertRange(num, array);
				Transform[] bones = list.ToArray();
				SkinnedMeshRenderer[] array2 = baseSkinRenderers;
				for (int i = 0; i < array2.Length; i++)
				{
					array2[i].bones = bones;
				}
				ApplyDynamicBone(val2, spec.Physics);
				applieds.Add(new AppliedMod
				{
					Instance = val2,
					BoneIndex = num,
					BoneCount = array.Length
				});
			}
		}

		private static void ApplyDynamicBone(GameObject instance, BonePhysics physics)
		{
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			if (physics != null)
			{
				DynamicBone obj = instance.AddComponent<DynamicBone>();
				obj.m_Root = instance.transform;
				obj.m_Damping = physics.Damping;
				obj.m_Elasticity = physics.Elasticity;
				obj.m_Stiffness = physics.Stiffness;
				obj.m_StiffnessDistrib = physics.StiffnessDistrib;
				obj.m_Inert = physics.Inert;
				obj.m_Radius = physics.Radius;
				obj.m_RadiusDistrib = physics.RadiusDistrib;
				obj.m_EndLength = 0f;
				obj.m_EndOffset = Vector3.zero;
				obj.m_Gravity = Vector3.zero;
				obj.m_Force = Vector3.zero;
				obj.m_Colliders = new List<DynamicBoneCollider>();
				obj.m_Exclusions = new List<Transform>();
				obj.m_FreezeAxis = (FreezeAxis)0;
			}
		}

		private static void RemoveMods(GameObject modelObject, List<AppliedMod> applieds)
		{
			for (int num = applieds.Count - 1; num >= 0; num--)
			{
				AppliedMod appliedMod = applieds[num];
				if (Object.op_Implicit((Object)(object)modelObject))
				{
					SkinnedMeshRenderer[] baseSkinRenderers = GetBaseSkinRenderers(modelObject);
					if (baseSkinRenderers.Length != 0)
					{
						List<Transform> list = baseSkinRenderers[0].bones.ToList();
						if (appliedMod.BoneIndex >= 0 && appliedMod.BoneIndex + appliedMod.BoneCount <= list.Count)
						{
							list.RemoveRange(appliedMod.BoneIndex, appliedMod.BoneCount);
							Transform[] bones = list.ToArray();
							SkinnedMeshRenderer[] array = baseSkinRenderers;
							for (int i = 0; i < array.Length; i++)
							{
								array[i].bones = bones;
							}
						}
					}
				}
				if (Object.op_Implicit((Object)(object)appliedMod.Instance))
				{
					Object.Destroy((Object)(object)appliedMod.Instance);
				}
			}
			applieds.Clear();
		}

		private static void PruneDestroyedModels()
		{
			List<GameObject> list = null;
			foreach (GameObject key in AppliedByModel.Keys)
			{
				if (!Object.op_Implicit((Object)(object)key))
				{
					(list ?? (list = new List<GameObject>())).Add(key);
				}
			}
			if (list == null)
			{
				return;
			}
			foreach (GameObject item in list)
			{
				AppliedByModel.Remove(item);
			}
		}

		private static SkinnedMeshRenderer[] GetBaseSkinRenderers(GameObject modelObject)
		{
			return (from r in modelObject.GetComponentsInChildren<SkinnedMeshRenderer>(true)
				where (Object)(object)((Component)r).transform.parent == (Object)(object)modelObject.transform
				select r).ToArray();
		}

		private static Transform[] BuildBoneArray(Transform root)
		{
			List<Transform> list = new List<Transform>();
			BuildBoneArrayHelper(root, list);
			return list.ToArray();
		}

		private static void BuildBoneArrayHelper(Transform parent, List<Transform> list)
		{
			if (!((Object)parent).name.EndsWith("_end", StringComparison.Ordinal))
			{
				list.Add(parent);
			}
			for (int i = 0; i < parent.childCount; i++)
			{
				BuildBoneArrayHelper(parent.GetChild(i), list);
			}
		}

		private static Transform FindChildInTree(Transform root, string name)
		{
			Queue<Transform> queue = new Queue<Transform>();
			queue.Enqueue(root);
			while (queue.Count != 0)
			{
				Transform val = queue.Dequeue();
				if (string.Equals(((Object)val).name, name, StringComparison.OrdinalIgnoreCase))
				{
					return val;
				}
				for (int i = 0; i < val.childCount; i++)
				{
					queue.Enqueue(val.GetChild(i));
				}
			}
			return null;
		}

		private static string RemoveCloneSuffix(string name)
		{
			int num = name.IndexOf("(Clone)", StringComparison.Ordinal);
			if (num < 0)
			{
				return name;
			}
			return name.Substring(0, num);
		}
	}

	public const string PluginGuid = "com.sussybnuuy.lucariohuntress";

	public const string PluginName = "Lucario Huntress";

	public const string PluginVersion = "3.0.0";

	private const string HuntressBodyAddress = "RoR2/Base/Huntress/HuntressBody.prefab";

	internal static ManualLogSource Log;

	private void Awake()
	{
		//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)
		Log = ((BaseUnityPlugin)this).Logger;
		try
		{
			LucarioSkinAssets assets = LoadSkinAssetSet(LoadBundle());
			GameObject val = Addressables.LoadAssetAsync<GameObject>((object)"RoR2/Base/Huntress/HuntressBody.prefab").WaitForCompletion();
			if (!Object.op_Implicit((Object)(object)val))
			{
				throw new InvalidOperationException("Could not load RoR2/Base/Huntress/HuntressBody.prefab");
			}
			RegisterSkins(val, assets);
		}
		catch (Exception ex)
		{
			((BaseUnityPlugin)this).Logger.LogError((object)("Lucario skin registration failed:\n" + ex));
		}
	}

	private AssetBundle LoadBundle()
	{
		string path = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location) ?? throw new InvalidOperationException("Could not determine plugin directory.");
		string[] obj = new string[4] { "lucariohuntress", "lucariohuntress.bundle", "huntressassets", "huntressassets.bundle" };
		List<string> list = new List<string>();
		string[] array = obj;
		foreach (string text in array)
		{
			string[] array2 = new string[2]
			{
				Path.Combine(path, text),
				Path.Combine(path, "assetbundles", text)
			};
			foreach (string text2 in array2)
			{
				list.Add(text2);
				if (File.Exists(text2))
				{
					AssetBundle val = AssetBundle.LoadFromFile(text2);
					if (Object.op_Implicit((Object)(object)val))
					{
						((BaseUnityPlugin)this).Logger.LogInfo((object)("Loaded Lucario asset bundle: " + text2));
						return val;
					}
				}
			}
		}
		throw new FileNotFoundException("Could not locate the Lucario asset bundle. Checked:\n" + string.Join("\n", list));
	}

	private static LucarioSkinAssets LoadSkinAssetSet(AssetBundle bundle)
	{
		LucarioSkinAssets[] array = bundle.LoadAllAssets<LucarioSkinAssets>();
		if (array == null || array.Length == 0)
		{
			throw new InvalidOperationException("The bundle contains no LucarioSkinAssets object. Bundle assets:\n" + string.Join("\n", bundle.GetAllAssetNames()));
		}
		if (array.Length != 1)
		{
			throw new InvalidOperationException("Expected exactly one LucarioSkinAssets object; found " + array.Length + ".");
		}
		return array[0];
	}

	private void RegisterSkins(GameObject bodyPrefab, LucarioSkinAssets assets)
	{
		//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
		//IL_0124: Unknown result type (might be due to invalid IL or missing references)
		//IL_0129: Unknown result type (might be due to invalid IL or missing references)
		//IL_012c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0141: Unknown result type (might be due to invalid IL or missing references)
		ModelLocator component = bodyPrefab.GetComponent<ModelLocator>();
		if (!Object.op_Implicit((Object)(object)component) || !Object.op_Implicit((Object)(object)component.modelTransform))
		{
			throw new InvalidOperationException("HuntressBody has no usable ModelLocator.");
		}
		GameObject gameObject = ((Component)component.modelTransform).gameObject;
		SkinnedMeshRenderer bodyRenderer = FindRenderer(gameObject, "HuntressMesh");
		SkinnedMeshRenderer bowRenderer = FindRenderer(gameObject, "BowMesh");
		Renderer scarfRenderer = FindAnyRenderer(gameObject, "HuntressScarfMesh");
		ModelSkinController component2 = gameObject.GetComponent<ModelSkinController>();
		if (!Object.op_Implicit((Object)(object)component2) || component2.skins == null || component2.skins.Length == 0)
		{
			throw new InvalidOperationException("Huntress model has no default skin.");
		}
		SkinDef defaultSkin = component2.skins[0];
		RendererInfo[] defaultRendererInfos = GetDefaultRendererInfos(defaultSkin, gameObject);
		Shader hgShader = ResolveHgStandardShader(defaultRendererInfos);
		FixMaterialShaders(assets, hgShader);
		LogSkinDiagnostics(assets, bodyRenderer, bowRenderer, scarfRenderer, defaultRendererInfos, hgShader);
		SkinDefParamsInfo val = BuildSkinInfo("skinLucarioHuntress", "LUCARIO_HUNTRESS_SKIN_NAME", assets.lucarioIcon, gameObject, defaultSkin, defaultRendererInfos, bodyRenderer, bowRenderer, scarfRenderer, assets.lucarioBodyMesh, assets.lucarioBowMesh, assets.lucarioBodyMaterial, assets.lucarioBowMaterial);
		SkinDefParamsInfo val2 = BuildSkinInfo("skinShinyLucarioHuntress", "SHINY_LUCARIO_HUNTRESS_SKIN_NAME", assets.shinyIcon, gameObject, defaultSkin, defaultRendererInfos, bodyRenderer, bowRenderer, scarfRenderer, assets.shinyBodyMesh, assets.shinyBowMesh, assets.shinyBodyMaterial, assets.shinyBowMaterial);
		if (!Skins.AddSkinToCharacter(bodyPrefab, val))
		{
			throw new InvalidOperationException("R2API.Skins rejected the Lucario skin.");
		}
		if (!Skins.AddSkinToCharacter(bodyPrefab, val2))
		{
			throw new InvalidOperationException("R2API.Skins rejected the shiny Lucario skin.");
		}
		BoneChainManager.Register("LUCARIO_HUNTRESS_SKIN_NAME", assets);
		BoneChainManager.Register("SHINY_LUCARIO_HUNTRESS_SKIN_NAME", assets);
		BoneChainManager.InstallHook();
		((BaseUnityPlugin)this).Logger.LogInfo((object)"Registered Lucario and Shiny Lucario through R2API.Skins.");
	}

	private static void LogSkinDiagnostics(LucarioSkinAssets assets, SkinnedMeshRenderer bodyRenderer, SkinnedMeshRenderer bowRenderer, Renderer scarfRenderer, RendererInfo[] defaultInfos, Shader hgShader)
	{
		//IL_010e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0113: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			Log.LogInfo((object)"=== Lucario skin diagnostics ===");
			Log.LogInfo((object)("hgstandard shader resolved: " + (Object.op_Implicit((Object)(object)hgShader) ? ((Object)hgShader).name : "<null>")));
			DumpSkinnedMesh("HuntressMesh (vanilla body)", bodyRenderer);
			DumpSkinnedMesh("BowMesh (vanilla bow)", bowRenderer);
			DumpReplacementMesh("lucarioBodyMesh", assets.lucarioBodyMesh, bodyRenderer);
			DumpReplacementMesh("lucarioBowMesh", assets.lucarioBowMesh, bowRenderer);
			DumpReplacementMesh("shinyBodyMesh", assets.shinyBodyMesh, bodyRenderer);
			DumpReplacementMesh("shinyBowMesh", assets.shinyBowMesh, bowRenderer);
			DumpMaterial("lucarioBodyMaterial", assets.lucarioBodyMaterial);
			DumpMaterial("lucarioBowMaterial", assets.lucarioBowMaterial);
			DumpMaterial("shinyBodyMaterial", assets.shinyBodyMaterial);
			DumpMaterial("shinyBowMaterial", assets.shinyBowMaterial);
			Log.LogInfo((object)("default RendererInfo count: " + ((defaultInfos != null) ? defaultInfos.Length : 0)));
			if (defaultInfos != null)
			{
				foreach (RendererInfo val in defaultInfos)
				{
					Renderer renderer = val.renderer;
					Material defaultMaterial = val.defaultMaterial;
					Log.LogInfo((object)("  renderer=" + (Object.op_Implicit((Object)(object)renderer) ? ((Object)renderer).name : "<null>") + " mat=" + (Object.op_Implicit((Object)(object)defaultMaterial) ? ((Object)defaultMaterial).name : "<null>") + " shader=" + ((Object.op_Implicit((Object)(object)defaultMaterial) && Object.op_Implicit((Object)(object)defaultMaterial.shader)) ? ((Object)defaultMaterial.shader).name : "<null>")));
				}
			}
			Log.LogInfo((object)"=== end diagnostics ===");
		}
		catch (Exception ex)
		{
			Log.LogWarning((object)("Diagnostics dump failed (non-fatal):\n" + ex));
		}
	}

	private static void DumpSkinnedMesh(string label, SkinnedMeshRenderer renderer)
	{
		if (!Object.op_Implicit((Object)(object)renderer))
		{
			Log.LogInfo((object)(label + ": <null renderer>"));
			return;
		}
		Mesh sharedMesh = renderer.sharedMesh;
		Transform[] bones = renderer.bones;
		Material sharedMaterial = ((Renderer)renderer).sharedMaterial;
		Log.LogInfo((object)(label + ": renderer.enabled=" + ((Renderer)renderer).enabled + " bones=" + ((bones != null) ? bones.Length : 0) + " rootBone=" + (Object.op_Implicit((Object)(object)renderer.rootBone) ? ((Object)renderer.rootBone).name : "<null>") + " mesh=" + (Object.op_Implicit((Object)(object)sharedMesh) ? ((Object)sharedMesh).name : "<null>") + " meshBindposes=" + (Object.op_Implicit((Object)(object)sharedMesh) ? sharedMesh.bindposes.Length : 0) + " meshBoneWeights=" + (Object.op_Implicit((Object)(object)sharedMesh) ? sharedMesh.boneWeights.Length : 0) + " mat=" + (Object.op_Implicit((Object)(object)sharedMaterial) ? ((Object)sharedMaterial).name : "<null>") + " shader=" + ((Object.op_Implicit((Object)(object)sharedMaterial) && Object.op_Implicit((Object)(object)sharedMaterial.shader)) ? ((Object)sharedMaterial.shader).name : "<null>")));
	}

	private static void DumpReplacementMesh(string label, Mesh mesh, SkinnedMeshRenderer targetRenderer)
	{
		//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
		if (!Object.op_Implicit((Object)(object)mesh))
		{
			Log.LogInfo((object)(label + ": <null mesh>"));
			return;
		}
		int num = ((Object.op_Implicit((Object)(object)targetRenderer) && targetRenderer.bones != null) ? targetRenderer.bones.Length : 0);
		int num2 = mesh.bindposes.Length;
		string text = ((num2 != num) ? ("  <-- BINDPOSE/BONE MISMATCH vs target renderer bones=" + num) : "");
		ManualLogSource log = Log;
		string[] obj = new string[12]
		{
			label,
			": bindposes=",
			num2.ToString(),
			" boneWeights=",
			mesh.boneWeights.Length.ToString(),
			" verts=",
			mesh.vertexCount.ToString(),
			" subMeshes=",
			mesh.subMeshCount.ToString(),
			" bounds=",
			null,
			null
		};
		Bounds bounds = mesh.bounds;
		obj[10] = ((object)((Bounds)(ref bounds)).size/*cast due to .constrained prefix*/).ToString();
		obj[11] = text;
		log.LogInfo((object)string.Concat(obj));
	}

	private unsafe static void DumpMaterial(string label, Material material)
	{
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
		if (!Object.op_Implicit((Object)(object)material))
		{
			Log.LogInfo((object)(label + ": <null material>"));
			return;
		}
		Shader shader = material.shader;
		Texture val = (material.HasProperty("_MainTex") ? material.GetTexture("_MainTex") : null);
		Color val2 = (material.HasProperty("_Color") ? material.GetColor("_Color") : Color.white);
		ManualLogSource log = Log;
		string[] obj = new string[11]
		{
			label,
			": shader=",
			Object.op_Implicit((Object)(object)shader) ? ((Object)shader).name : "<null>",
			" renderQueue=",
			material.renderQueue.ToString(),
			" _MainTex=",
			Object.op_Implicit((Object)(object)val) ? ((Object)val).name : "<null>",
			" _Color=",
			null,
			null,
			null
		};
		Color val3 = val2;
		obj[8] = ((object)(*(Color*)(&val3))/*cast due to .constrained prefix*/).ToString();
		obj[9] = " keywords=";
		obj[10] = string.Join(",", material.shaderKeywords);
		log.LogInfo((object)string.Concat(obj));
	}

	private static Shader ResolveHgStandardShader(RendererInfo[] defaultInfos)
	{
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		Shader val = null;
		for (int i = 0; i < defaultInfos.Length; i++)
		{
			Material defaultMaterial = defaultInfos[i].defaultMaterial;
			if (Object.op_Implicit((Object)(object)defaultMaterial) && Object.op_Implicit((Object)(object)defaultMaterial.shader))
			{
				if (((Object)defaultMaterial.shader).name.IndexOf("Hopoo Games/Deferred/Standard", StringComparison.OrdinalIgnoreCase) >= 0 || ((Object)defaultMaterial.shader).name.IndexOf("hgstandard", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					return defaultMaterial.shader;
				}
				if (!Object.op_Implicit((Object)(object)val))
				{
					val = defaultMaterial.shader;
				}
			}
		}
		if (!Object.op_Implicit((Object)(object)val))
		{
			return Shader.Find("Hopoo Games/Deferred/Standard");
		}
		return val;
	}

	private static void FixMaterialShaders(LucarioSkinAssets assets, Shader hgShader)
	{
		if (!Object.op_Implicit((Object)(object)hgShader))
		{
			throw new InvalidOperationException("Could not resolve the RoR2 hgstandard shader to fix Lucario materials.");
		}
		SwapToHgStandard(assets.lucarioBodyMaterial, hgShader);
		SwapToHgStandard(assets.lucarioBowMaterial, hgShader);
		SwapToHgStandard(assets.shinyBodyMaterial, hgShader);
		SwapToHgStandard(assets.shinyBowMaterial, hgShader);
	}

	private static void SwapToHgStandard(Material material, Shader hgShader)
	{
		if (Object.op_Implicit((Object)(object)material) && !((Object)(object)material.shader == (Object)(object)hgShader))
		{
			Texture val = (material.HasProperty("_BumpMap") ? material.GetTexture("_BumpMap") : null);
			material.shader = hgShader;
			if (Object.op_Implicit((Object)(object)val) && material.HasProperty("_NormalTex"))
			{
				material.SetTexture("_NormalTex", val);
			}
		}
	}

	private static SkinDefParamsInfo BuildSkinInfo(string internalName, string nameToken, Sprite icon, GameObject modelRoot, SkinDef defaultSkin, RendererInfo[] defaultInfos, SkinnedMeshRenderer bodyRenderer, SkinnedMeshRenderer bowRenderer, Renderer scarfRenderer, Mesh bodyMesh, Mesh bowMesh, Material bodyMaterial, Material bowMaterial)
	{
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_009e: 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_00b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00db: Unknown result type (might be due to invalid IL or missing references)
		//IL_010a: 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_004a: Unknown result type (might be due to invalid IL or missing references)
		RendererInfo[] array = CloneRendererInfos(defaultInfos);
		ReplaceMaterial(array, (Renderer)(object)bodyRenderer, bodyMaterial);
		ReplaceMaterial(array, (Renderer)(object)bowRenderer, bowMaterial);
		List<GameObjectActivation> list = new List<GameObjectActivation>();
		if (Object.op_Implicit((Object)(object)scarfRenderer))
		{
			list.Add(new GameObjectActivation
			{
				gameObject = ((Component)scarfRenderer).gameObject,
				shouldActivate = false
			});
		}
		return new SkinDefParamsInfo
		{
			Name = internalName,
			NameToken = nameToken,
			Icon = icon,
			RootObject = modelRoot,
			BaseSkins = (SkinDef[])(object)new SkinDef[1] { defaultSkin },
			RendererInfos = array,
			MeshReplacements = (MeshReplacement[])(object)new MeshReplacement[2]
			{
				new MeshReplacement
				{
					renderer = (Renderer)(object)bodyRenderer,
					mesh = bodyMesh
				},
				new MeshReplacement
				{
					renderer = (Renderer)(object)bowRenderer,
					mesh = bowMesh
				}
			},
			GameObjectActivations = list.ToArray(),
			ProjectileGhostReplacements = Array.Empty<ProjectileGhostReplacement>(),
			MinionSkinReplacements = Array.Empty<MinionSkinReplacement>()
		};
	}

	private static RendererInfo[] GetDefaultRendererInfos(SkinDef defaultSkin, GameObject modelRoot)
	{
		CharacterModel component = modelRoot.GetComponent<CharacterModel>();
		if (Object.op_Implicit((Object)(object)component) && component.baseRendererInfos != null && component.baseRendererInfos.Length != 0)
		{
			return CloneRendererInfos(component.baseRendererInfos);
		}
		if (Object.op_Implicit((Object)(object)defaultSkin.skinDefParams) && defaultSkin.skinDefParams.rendererInfos != null && defaultSkin.skinDefParams.rendererInfos.Length != 0)
		{
			return CloneRendererInfos(defaultSkin.skinDefParams.rendererInfos);
		}
		SkinDefParams val = LoadSkinDefParams(defaultSkin);
		if (Object.op_Implicit((Object)(object)val) && val.rendererInfos != null && val.rendererInfos.Length != 0)
		{
			return CloneRendererInfos(val.rendererInfos);
		}
		if (defaultSkin.rendererInfos != null && defaultSkin.rendererInfos.Length != 0)
		{
			return CloneRendererInfos(defaultSkin.rendererInfos);
		}
		return BuildRendererInfosFromModel(modelRoot);
	}

	private static SkinDefParams LoadSkinDefParams(SkinDef skin)
	{
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		(AssetReferenceT<SkinDefParams>, SkinDefParams) skinParams = skin.GetSkinParams();
		SkinDefParams item = skinParams.Item2;
		if (Object.op_Implicit((Object)(object)item))
		{
			return item;
		}
		var (val, _) = skinParams;
		if (val != null && ((AssetReference)val).RuntimeKeyIsValid())
		{
			return Addressables.LoadAssetAsync<SkinDefParams>(((AssetReference)val).RuntimeKey).WaitForCompletion();
		}
		return null;
	}

	private static RendererInfo[] BuildRendererInfosFromModel(GameObject modelRoot)
	{
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		List<RendererInfo> list = new List<RendererInfo>();
		Renderer[] componentsInChildren = modelRoot.GetComponentsInChildren<Renderer>(true);
		foreach (Renderer val in componentsInChildren)
		{
			if (!(val is ParticleSystemRenderer) && Object.op_Implicit((Object)(object)val.sharedMaterial))
			{
				list.Add(new RendererInfo
				{
					renderer = val,
					defaultMaterial = val.sharedMaterial,
					defaultShadowCastingMode = (ShadowCastingMode)1,
					ignoreOverlays = false,
					hideOnDeath = false
				});
			}
		}
		if (list.Count == 0)
		{
			throw new InvalidOperationException("Huntress model has no usable renderers to build renderer information.");
		}
		return list.ToArray();
	}

	private static RendererInfo[] CloneRendererInfos(RendererInfo[] source)
	{
		RendererInfo[] array = (RendererInfo[])(object)new RendererInfo[source.Length];
		Array.Copy(source, array, source.Length);
		return array;
	}

	private static void ReplaceMaterial(RendererInfo[] infos, Renderer renderer, Material material)
	{
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: 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)
		for (int i = 0; i < infos.Length; i++)
		{
			if (!((Object)(object)infos[i].renderer != (Object)(object)renderer))
			{
				RendererInfo val = infos[i];
				val.defaultMaterial = material;
				val.defaultMaterialAddress = null;
				infos[i] = val;
				return;
			}
		}
		throw new InvalidOperationException("Default skin does not contain renderer '" + ((Object)renderer).name + "'.");
	}

	private static SkinnedMeshRenderer FindRenderer(GameObject root, string exactName)
	{
		SkinnedMeshRenderer? obj = ((IEnumerable<SkinnedMeshRenderer>)root.GetComponentsInChildren<SkinnedMeshRenderer>(true)).FirstOrDefault((Func<SkinnedMeshRenderer, bool>)((SkinnedMeshRenderer r) => string.Equals(((Object)r).name, exactName, StringComparison.OrdinalIgnoreCase)));
		if (!Object.op_Implicit((Object)(object)obj))
		{
			throw new InvalidOperationException("Could not find SkinnedMeshRenderer '" + exactName + "'.");
		}
		return obj;
	}

	private static Renderer FindAnyRenderer(GameObject root, string exactName)
	{
		return ((IEnumerable<Renderer>)root.GetComponentsInChildren<Renderer>(true)).FirstOrDefault((Func<Renderer, bool>)((Renderer r) => string.Equals(((Object)r).name, exactName, StringComparison.OrdinalIgnoreCase)));
	}
}