Decompiled source of Umamusume Skulls v1.2.0

Umamusume Skulls/UmamusumeSkulls.dll

Decompiled a month ago
using System.Collections;
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 HarmonyLib;
using PluginConfig.API;
using PluginConfig.API.Fields;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: AssemblyCompany("UmamusumeSkulls")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("UmamusumeSkulls")]
[assembly: AssemblyTitle("UmamusumeSkulls")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace UmamusumeSkulls
{
	internal class UmamusumeSkullTag : MonoBehaviour
	{
		internal Renderer[] hidden;

		private void OnDestroy()
		{
			if (hidden == null)
			{
				return;
			}
			Renderer[] array = hidden;
			foreach (Renderer val in array)
			{
				if ((Object)(object)val != (Object)null)
				{
					val.enabled = true;
				}
			}
		}
	}
	internal static class Replacer
	{
		private const float SweepInterval = 0.5f;

		internal static IEnumerator SweepForever()
		{
			WaitForSeconds wait = new WaitForSeconds(0.5f);
			while (true)
			{
				SweepNow();
				yield return wait;
			}
		}

		internal static void SweepNow()
		{
			ItemIdentifier[] array = Object.FindObjectsOfType<ItemIdentifier>(true);
			for (int i = 0; i < array.Length; i++)
			{
				TryReplace(array[i]);
			}
		}

		internal static void ClearReplacements()
		{
			UmamusumeSkullTag[] array = Object.FindObjectsOfType<UmamusumeSkullTag>(true);
			for (int i = 0; i < array.Length; i++)
			{
				Object.Destroy((Object)(object)((Component)array[i]).gameObject);
			}
		}

		internal static void TryReplace(ItemIdentifier item)
		{
			//IL_001b: 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_003a: Invalid comparison between Unknown and I4
			if (!((Object)(object)item == (Object)null) && !((Object)(object)((Component)item).GetComponentInChildren<UmamusumeSkullTag>(true) != (Object)null) && TryCharacterFor(item.itemType, out var character) && HasPrefab(character))
			{
				if ((int)item.itemType == 5)
				{
					TorchReplacer.Replace(item, character);
				}
				else
				{
					SkullReplacer.Replace(item, character);
				}
			}
		}

		internal static GameObject Attach(Character character, Transform anchor, Renderer[] hidden, Vector3 position, Vector3 euler, float scale)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			GameObject obj = Object.Instantiate<GameObject>(UmamusumeSkullsPlugin.Prefabs[character]);
			((Object)obj).name = "UmamusumeSkull";
			obj.AddComponent<UmamusumeSkullTag>().hidden = hidden;
			obj.transform.SetParent(anchor, false);
			obj.transform.localPosition = position;
			obj.transform.localRotation = Quaternion.Euler(euler);
			obj.transform.localScale = Vector3.one * scale;
			return obj;
		}

		internal static void CenterOn(GameObject model, Renderer[] target)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			if (TryGetBounds(target, out var bounds) && TryGetBounds(model.GetComponentsInChildren<Renderer>(true), out var bounds2))
			{
				Transform transform = model.transform;
				transform.position += ((Bounds)(ref bounds)).center - ((Bounds)(ref bounds2)).center;
			}
		}

		private static bool TryGetBounds(Renderer[] renderers, out Bounds bounds)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			bounds = default(Bounds);
			bool flag = false;
			foreach (Renderer val in renderers)
			{
				if (!((Object)(object)val == (Object)null))
				{
					if (flag)
					{
						((Bounds)(ref bounds)).Encapsulate(val.bounds);
						continue;
					}
					bounds = val.bounds;
					flag = true;
				}
			}
			return flag;
		}

		internal static Renderer[] HideMeshes(GameObject root)
		{
			List<Renderer> list = new List<Renderer>();
			Renderer[] componentsInChildren = root.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren)
			{
				if (val.enabled && (val is MeshRenderer || val is SkinnedMeshRenderer))
				{
					val.enabled = false;
					list.Add(val);
				}
			}
			return list.ToArray();
		}

		internal static bool HasPrefab(Character character)
		{
			if (UmamusumeSkullsPlugin.Prefabs.TryGetValue(character, out var value))
			{
				return (Object)(object)value != (Object)null;
			}
			return false;
		}

		private static bool TryCharacterFor(ItemType type, out Character character)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected I4, but got Unknown
			switch (type - 1)
			{
			case 0:
				if (SkullConfig.BlueEnabled)
				{
					character = SkullConfig.Blue;
					return true;
				}
				break;
			case 1:
				if (SkullConfig.RedEnabled)
				{
					character = SkullConfig.Red;
					return true;
				}
				break;
			case 4:
				if (SkullConfig.TorchEnabled)
				{
					character = SkullConfig.Torch;
					return true;
				}
				break;
			}
			character = Character.AdmireGroove;
			return false;
		}

		internal static void PlayPickupVoice(ItemIdentifier item)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Expected O, but got Unknown
			if (!((Object)(object)item == (Object)null) && SkullConfig.PickupLinesEnabled && TryCharacterFor(item.itemType, out var character) && UmamusumeSkullsPlugin.Clips.TryGetValue(character, out var value))
			{
				GameObject val = new GameObject("UmamusumeSkullVoice");
				val.transform.position = ((Component)item).transform.position;
				AudioSource val2 = val.AddComponent<AudioSource>();
				val2.clip = value;
				val2.spatialBlend = 0f;
				AudioSource componentInChildren = ((Component)item).GetComponentInChildren<AudioSource>();
				if ((Object)(object)componentInChildren != (Object)null)
				{
					val2.outputAudioMixerGroup = componentInChildren.outputAudioMixerGroup;
				}
				val2.Play();
				Object.Destroy((Object)val, value.length + 0.5f);
			}
		}
	}
	[HarmonyPatch(typeof(ItemIdentifier), "PickUp")]
	internal static class ItemIdentifierPickUpPatch
	{
		private static void Postfix(ItemIdentifier __instance)
		{
			Replacer.PlayPickupVoice(__instance);
		}
	}
	[HarmonyPatch(typeof(ItemIdentifier), "CreateCopy")]
	internal static class ItemIdentifierCreateCopyPatch
	{
		private static void Postfix(ItemIdentifier __result)
		{
			Replacer.TryReplace(__result);
		}
	}
	[HarmonyPatch(typeof(Grenade), "Awake")]
	internal static class GrenadeAwakePatch
	{
		private static void Postfix(Grenade __instance)
		{
			RocketReplacer.Replace(__instance);
		}
	}
	[BepInPlugin("com.achelia.umamusumeskulls", "Umamusume Skulls", "1.2.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class UmamusumeSkullsPlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "com.achelia.umamusumeskulls";

		public const string PluginName = "Umamusume Skulls";

		public const string PluginVersion = "1.2.0";

		private const string BundleResource = "UmamusumeSkulls.Resources.umamusumeskulls";

		private static readonly Dictionary<Character, string> PrefabNames = new Dictionary<Character, string>
		{
			{
				Character.Verxina,
				"Verxina"
			},
			{
				Character.Gentildonna,
				"Gentildonna"
			},
			{
				Character.AdmireGroove,
				"AdmireGroove"
			},
			{
				Character.StillInLove,
				"StillInLove"
			},
			{
				Character.OguriCap,
				"OguriCap"
			},
			{
				Character.TamamoCross,
				"TamamoCross"
			}
		};

		private static readonly Dictionary<Character, string> ClipNames = new Dictionary<Character, string>
		{
			{
				Character.Verxina,
				"VerxinaPickup"
			},
			{
				Character.Gentildonna,
				"GentildonnaPickup"
			},
			{
				Character.AdmireGroove,
				"AdmireGroovePickup"
			},
			{
				Character.StillInLove,
				"StillInLovePickup"
			},
			{
				Character.OguriCap,
				"OguriCapPickup"
			},
			{
				Character.TamamoCross,
				"TamamoCrossPickup"
			}
		};

		internal static ManualLogSource Log;

		internal static readonly Dictionary<Character, GameObject> Prefabs = new Dictionary<Character, GameObject>();

		internal static readonly Dictionary<Character, AudioClip> Clips = new Dictionary<Character, AudioClip>();

		private static AssetBundle bundle;

		private Harmony harmony;

		private void Awake()
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			if (LoadBundle())
			{
				SkullConfig.Build();
				harmony = new Harmony("com.achelia.umamusumeskulls");
				harmony.PatchAll(Assembly.GetExecutingAssembly());
				SceneManager.sceneLoaded += OnSceneLoaded;
				((MonoBehaviour)this).StartCoroutine(Replacer.SweepForever());
				Log.LogInfo((object)"Umamusume Skulls loaded successfully.");
			}
		}

		private void OnDestroy()
		{
			SceneManager.sceneLoaded -= OnSceneLoaded;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}

		private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			SkullReplacer.ResetAnchorScale();
			Replacer.SweepNow();
		}

		private bool LoadBundle()
		{
			using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("UmamusumeSkulls.Resources.umamusumeskulls"))
			{
				if (stream == null)
				{
					return false;
				}
				bundle = AssetBundle.LoadFromStream(stream);
			}
			if ((Object)(object)bundle == (Object)null)
			{
				return false;
			}
			foreach (KeyValuePair<Character, string> prefabName in PrefabNames)
			{
				GameObject val = bundle.LoadAsset<GameObject>(prefabName.Value);
				if ((Object)(object)val == (Object)null)
				{
					Log.LogError((object)("Prefab '" + prefabName.Value + "' missing from the bundle."));
				}
				else
				{
					Prefabs[prefabName.Key] = val;
				}
			}
			foreach (KeyValuePair<Character, string> clipName in ClipNames)
			{
				AudioClip val2 = bundle.LoadAsset<AudioClip>(clipName.Value);
				if ((Object)(object)val2 != (Object)null)
				{
					Clips[clipName.Key] = val2;
				}
			}
			return Prefabs.Count > 0;
		}
	}
	internal static class RocketReplacer
	{
		private const float SizeFactor = 1.8f;

		private static readonly Vector3 Euler = new Vector3(-85f, 180f, 0f);

		internal static void Replace(Grenade grenade)
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)grenade == (Object)null || !grenade.rocket || !SkullConfig.RocketEnabled || (Object)(object)((Component)grenade).GetComponentInChildren<UmamusumeSkullTag>(true) != (Object)null)
			{
				return;
			}
			Character rocket = SkullConfig.Rocket;
			if (!Replacer.HasPrefab(rocket))
			{
				return;
			}
			Renderer[] array = Replacer.HideMeshes(((Component)grenade).gameObject);
			if (array.Length != 0)
			{
				float num = Mathf.Abs(((Component)grenade).transform.lossyScale.x);
				if (num < 0.0001f)
				{
					num = 1f;
				}
				float scale = 0.3485f * SkullReplacer.AnchorScale * 1.8f / num;
				Replacer.CenterOn(Replacer.Attach(rocket, ((Component)grenade).transform, array, Vector3.zero, Euler, scale), array);
			}
		}
	}
	public enum Character
	{
		AdmireGroove,
		Gentildonna,
		OguriCap,
		StillInLove,
		TamamoCross,
		Verxina
	}
	internal static class SkullConfig
	{
		private const string IconUrl = "https://i.imgur.com/Dcb8ORF.png";

		private static PluginConfigurator configurator;

		private static BoolField swapBlue;

		private static BoolField swapRed;

		private static BoolField swapTorch;

		private static BoolField swapRocket;

		private static BoolField pickupLines;

		private static EnumField<Character> blueSkull;

		private static EnumField<Character> redSkull;

		private static EnumField<Character> torch;

		private static EnumField<Character> rocket;

		internal static bool BlueEnabled => swapBlue.value;

		internal static bool RedEnabled => swapRed.value;

		internal static bool TorchEnabled => swapTorch.value;

		internal static bool RocketEnabled => swapRocket.value;

		internal static bool PickupLinesEnabled => pickupLines.value;

		internal static Character Blue => blueSkull.value;

		internal static Character Red => redSkull.value;

		internal static Character Torch => torch.value;

		internal static Character Rocket => rocket.value;

		internal static void Build()
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Expected O, but got Unknown
			//IL_0065: 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_009b: Expected O, but got Unknown
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Expected O, but got Unknown
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Expected O, but got Unknown
			configurator = PluginConfigurator.Create("Umamusume Skulls", "com.achelia.umamusumeskulls");
			configurator.SetIconWithURL("https://i.imgur.com/Dcb8ORF.png");
			ConfigPanel rootPanel = configurator.rootPanel;
			swapBlue = new BoolField(rootPanel, "Swap Blue Skull", "swapBlue", true);
			blueSkull = new EnumField<Character>(rootPanel, "Blue Skull", "blueSkull", Character.Verxina);
			swapRed = new BoolField(rootPanel, "Swap Red Skull", "swapRed", true);
			redSkull = new EnumField<Character>(rootPanel, "Red Skull", "redSkull", Character.Gentildonna);
			swapTorch = new BoolField(rootPanel, "Swap Torch", "swapTorch", true);
			torch = new EnumField<Character>(rootPanel, "Torch", "torch", Character.StillInLove);
			swapRocket = new BoolField(rootPanel, "Swap Rocket", "swapRocket", true);
			rocket = new EnumField<Character>(rootPanel, "Rocket", "rocket", Character.Gentildonna);
			pickupLines = new BoolField(rootPanel, "Enable Pickup Lines", "pickupLines", true);
			Link(swapBlue, blueSkull);
			Link(swapRed, redSkull);
			Link(swapTorch, torch);
			Link(swapRocket, rocket);
		}

		private static void Link(BoolField toggle, EnumField<Character> field)
		{
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Expected O, but got Unknown
			field.SetEnumDisplayName(Character.AdmireGroove, "Admire Groove");
			field.SetEnumDisplayName(Character.OguriCap, "Oguri Cap");
			field.SetEnumDisplayName(Character.StillInLove, "Still in Love");
			field.SetEnumDisplayName(Character.TamamoCross, "Tamamo Cross");
			((ConfigField)field).interactable = toggle.value;
			field.onValueChange += delegate
			{
				Replacer.ClearReplacements();
			};
			toggle.onValueChange += (BoolValueChangeEventDelegate)delegate(BoolValueChangeEvent e)
			{
				((ConfigField)field).interactable = e.value;
				Replacer.ClearReplacements();
			};
		}
	}
	internal static class SkullReplacer
	{
		internal const float Scale = 0.3485f;

		private const float FallbackAnchorScale = 5.4f;

		private static readonly Vector3 Offset = new Vector3(0.0037f, 0.0037f, -0.0942f);

		private static readonly Vector3 Euler = new Vector3(70f, 180f, 180f);

		private static float anchorScale = float.PositiveInfinity;

		internal static float AnchorScale
		{
			get
			{
				if (!float.IsInfinity(anchorScale))
				{
					return anchorScale;
				}
				return 5.4f;
			}
		}

		internal static void ResetAnchorScale()
		{
			anchorScale = float.PositiveInfinity;
		}

		internal static void Replace(ItemIdentifier item, Character character)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			ModifyMaterial componentInChildren = ((Component)item).GetComponentInChildren<ModifyMaterial>(true);
			if ((Object)(object)componentInChildren == (Object)null)
			{
				return;
			}
			componentInChildren.SetValues();
			if (!((Object)(object)componentInChildren.rend == (Object)null))
			{
				Transform transform = ((Component)componentInChildren.rend).transform;
				float num = Mathf.Abs(transform.lossyScale.x);
				if (num > 0.0001f && num < anchorScale)
				{
					anchorScale = num;
				}
				Replacer.Attach(character, transform, Replacer.HideMeshes(((Component)item).gameObject), Offset, Euler, 0.3485f);
			}
		}
	}
	internal static class TorchReplacer
	{
		private const float Scale = 1.7696f;

		private static readonly Vector3 Offset = new Vector3(0.0106f, -0.5699f, 0.0561f);

		private static readonly Vector3 Euler = new Vector3(5f, 93f, 0f);

		internal static void Replace(ItemIdentifier item, Character character)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			MeshRenderer componentInChildren = ((Component)item).GetComponentInChildren<MeshRenderer>(true);
			if (!((Object)(object)componentInChildren == (Object)null))
			{
				Transform anchor = ((Component)componentInChildren).transform.parent ?? ((Component)componentInChildren).transform;
				Replacer.Attach(character, anchor, Replacer.HideMeshes(((Component)item).gameObject), Offset, Euler, 1.7696f);
			}
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		internal IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}