Decompiled source of VoiceActedMithrixRedux v1.0.4

plugins/Voice Acted Mithrix.dll

Decompiled a day ago
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using On.RoR2.CharacterSpeech;
using On.RoR2.UI.MainMenu;
using R2API;
using R2API.Networking;
using R2API.Networking.Interfaces;
using RoR2;
using RoR2.CharacterSpeech;
using RoR2.UI;
using RoR2.UI.MainMenu;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Events;
using UnityEngine.Networking;
using UnityEngine.UI;
using VoiceActedMithrix.UI;

[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("Voice Acted Mithrix")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Voice Acted Mithrix")]
[assembly: AssemblyTitle("Voice Acted Mithrix")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Voice_Acted_Mithrix.Properties
{
	[GeneratedCode("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
	[DebuggerNonUserCode]
	[CompilerGenerated]
	internal class Resources
	{
		private static ResourceManager resourceMan;

		private static CultureInfo resourceCulture;

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		internal static ResourceManager ResourceManager
		{
			get
			{
				if (resourceMan == null)
				{
					ResourceManager resourceManager = new ResourceManager("Voice_Acted_Mithrix.Properties.Resources", typeof(Resources).Assembly);
					resourceMan = resourceManager;
				}
				return resourceMan;
			}
		}

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		internal static CultureInfo Culture
		{
			get
			{
				return resourceCulture;
			}
			set
			{
				resourceCulture = value;
			}
		}

		internal Resources()
		{
		}
	}
}
namespace VoiceActedMithrix
{
	internal class BossLineEvent
	{
		public string eventName;

		public GameObject source;

		public bool angyLine;

		public BossLineEvent(string name, GameObject gameObject, bool angy = false)
		{
			eventName = name;
			source = gameObject;
			angyLine = angy;
		}

		public uint Play()
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			if (Configuration.PlayerSourcedVoice.Value)
			{
				source = ((Component)VoiceActedMithrix.GetLocalPlayer()).gameObject;
			}
			uint result = AkSoundEngine.PostEvent(eventName, source, 1u, new EventCallback(EndEventCallback), (object)null);
			if (NetworkServer.active)
			{
				NetMessageExtensions.Send((INetMessage)(object)new NetworkBossVoiceMessage
				{
					name = eventName,
					source = source
				}, (NetworkDestination)1);
			}
			return result;
		}

		private void EndEventCallback(object in_cookie, AkCallbackType callbackType, object in_info)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			if ((int)callbackType == 1 && NetworkServer.active && Object.op_Implicit((Object)(object)source))
			{
				BossVoiceComponent bossVoiceComponent = source.GetComponent<BossVoiceComponent>();
				if (!Object.op_Implicit((Object)(object)bossVoiceComponent))
				{
					bossVoiceComponent = source.AddComponent<BossVoiceComponent>();
				}
				if (angyLine)
				{
					bossVoiceComponent.angy = false;
				}
				bossVoiceComponent.playingLine = false;
			}
		}
	}
	internal class BossVoiceComponent : MonoBehaviour
	{
		internal bool playingLine = false;

		internal bool delaying = false;

		private List<BossLineEvent> queuedLines = new List<BossLineEvent>();

		internal bool gone = false;

		internal bool angy = false;

		private bool hurt = false;

		private int angyCounter = 2;

		private float timer;

		private float baseDelay = 1f;

		private float deltaDelay = 0.3f;

		private void Start()
		{
			timer = baseDelay + Random.Range(0f - deltaDelay, deltaDelay);
		}

		internal void FixedUpdate()
		{
			if (timer > 0f)
			{
				timer -= Time.fixedDeltaTime;
			}
			else
			{
				delaying = false;
			}
			if (queuedLines.Count > 0 && !playingLine && !delaying)
			{
				PlaySound(queuedLines[0]);
				queuedLines.RemoveAt(0);
			}
		}

		internal void TryVoiceLine(BossLineEvent sound)
		{
			if (!angy)
			{
				if (!hurt && sound.eventName.Contains("BROTHERHURT"))
				{
					hurt = true;
				}
				if (queuedLines.Count > 2)
				{
					BecomePissed(sound.source);
				}
				else if (playingLine || delaying || queuedLines.Count > 0)
				{
					queuedLines.Add(sound);
				}
				else
				{
					PlaySound(sound);
				}
			}
		}

		internal void BecomePissed(GameObject source)
		{
			queuedLines.Clear();
			if (Random.Range(0, angyCounter * 4 + 1) == 0)
			{
				angy = true;
				BossLineEvent item = ((!((Object)((Component)this).gameObject).name.Contains("FalseSon")) ? (hurt ? new BossLineEvent("VAMR_" + Configuration.MithrixVoice.Value + "_BROTHERHURT_QUEUEFULL", source, angy: true) : new BossLineEvent("VAMR_" + Configuration.MithrixVoice.Value + "_BROTHER_QUEUEFULL", source, angy: true)) : new BossLineEvent("VAMR_" + Configuration.FalseSonVoice.Value + "_FALSESON_QUEUEFULL", source, angy: true));
				queuedLines.Add(item);
				angyCounter = 2;
			}
			else
			{
				angyCounter--;
			}
		}

		internal void PlaySound(BossLineEvent soundEvent)
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Invalid comparison between Unknown and I4
			timer = baseDelay + Random.Range(0f - deltaDelay, deltaDelay);
			playingLine = true;
			delaying = true;
			uint value = soundEvent.Play();
			uint[] array = new uint[10];
			uint num = (uint)array.Length;
			AKRESULT playingIDsFromGameObject = AkSoundEngine.GetPlayingIDsFromGameObject(soundEvent.source, ref num, array);
			if ((int)playingIDsFromGameObject != 1 || !array.Contains(value))
			{
				playingLine = (angy = false);
			}
		}
	}
	internal class Configuration
	{
		private static ConfigFile configFile;

		internal const int DefaultMithrixVoice = 0;

		internal const int DefaultFalseSonVoice = 0;

		internal const bool DefaultPlayerSourcedVoice = false;

		internal const bool DefaultDisplayUI = true;

		internal static ConfigEntry<int> MithrixVoice { get; private set; }

		internal static ConfigEntry<int> FalseSonVoice { get; private set; }

		internal static ConfigEntry<bool> PlayerSourcedVoice { get; private set; }

		internal static ConfigEntry<bool> DisplayUI { get; private set; }

		internal static void LoadConfig()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			configFile = new ConfigFile(Paths.ConfigPath + "/VAMithrix.cfg", true);
			MithrixVoice = configFile.Bind<int>("Voices", "Mithrix VA", 0, "Voice actor to use for Mithrix boss.  0: MotherEgg | 1: KKing");
			FalseSonVoice = configFile.Bind<int>("Voices", "False Son VA", 0, "Voice actor to use for False Son boss.  0: SkellyVA | 1: KKing");
			PlayerSourcedVoice = configFile.Bind<bool>("Settings", "Use Player As Voice Source", false, "If true, the voice will source directly from the player object rather than the boss, giving more consistent volume without scaling over distance");
			DisplayUI = configFile.Bind<bool>("Settings", "Display Voice Changing UI", true, "If false, will no longer display the UI on the title screen and will not allow changing voice without opening config file");
		}
	}
	internal class NetworkBossVoiceMessage : INetMessage, ISerializableObject
	{
		internal string name;

		internal GameObject source;

		public void Serialize(NetworkWriter writer)
		{
			writer.Write(name);
			writer.Write(source);
		}

		public void Deserialize(NetworkReader reader)
		{
			name = reader.ReadString();
			source = reader.ReadGameObject();
		}

		public void OnReceived()
		{
			if (Object.op_Implicit((Object)(object)source) && !NetworkServer.active)
			{
				if (Configuration.PlayerSourcedVoice.Value)
				{
					source = ((Component)VoiceActedMithrix.GetLocalPlayer()).gameObject;
				}
				AkSoundEngine.PostEvent(name, source);
			}
		}
	}
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("com.Egg.VoiceActedMithrix", "Voice Acted Mithrix Redux", "1.0.4")]
	public class VoiceActedMithrix : BaseUnityPlugin
	{
		public const string MODNAME = "com.Egg.VoiceActedMithrix";

		public const string MODTITLE = "Voice Acted Mithrix Redux";

		public const string MODVERS = "1.0.4";

		internal static string BankPathBrother;

		internal static string BankPathFalseson;

		private static string[] brotherFileNames = new string[2] { "vamithrixredux.bnk", "vakkingmithrix.bnk" };

		private static string[] falseSonFileNames = new string[2] { "vafalseson.bnk", "vakkingfalseson.bnk" };

		internal static uint currentMithrixVoiceBank;

		internal static uint currentFalseSonVoiceBank;

		public static PluginInfo PInfo { get; private set; }

		private void Awake()
		{
			PInfo = ((BaseUnityPlugin)this).Info;
			Configuration.LoadConfig();
			BankPathBrother = GetBrotherPath(Configuration.MithrixVoice.Value);
			BankPathFalseson = GetFalseSonPath(Configuration.FalseSonVoice.Value);
			currentMithrixVoiceBank = SoundBanks.Add(BankPathBrother);
			currentFalseSonVoiceBank = SoundBanks.Add(BankPathFalseson);
			NetworkingAPI.RegisterMessageType<NetworkBossVoiceMessage>();
			if (Configuration.MithrixVoice.Value == 0)
			{
				HereticKurskanFix();
			}
			if (Configuration.DisplayUI.Value)
			{
				UIManager.Init();
			}
		}

		internal static string GetBrotherPath(int index)
		{
			return Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "soundbanks", brotherFileNames[index]);
		}

		internal static string GetFalseSonPath(int index)
		{
			return Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "soundbanks", falseSonFileNames[index]);
		}

		internal static void LoadBrotherVoice()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			SoundBanks.Remove(currentMithrixVoiceBank);
			currentMithrixVoiceBank = SoundBanks.Add(GetBrotherPath(Configuration.MithrixVoice.Value));
		}

		internal static void LoadFalseSonVoice()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			SoundBanks.Remove(currentFalseSonVoiceBank);
			currentFalseSonVoiceBank = SoundBanks.Add(GetFalseSonPath(Configuration.FalseSonVoice.Value));
		}

		private void OnEnable()
		{
			//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
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Expected O, but got Unknown
			BrotherSpeechDriver.SendReponseFromPool += new hook_SendReponseFromPool(BrotherSpeechDriver_SendReponseFromPool);
			FalseSonBossSpeechDriver.SendReponseFromPool += new hook_SendReponseFromPool(FalseSonBossSpeechDriver_SendReponseFromPool);
			CharacterSpeechController.SpeakNow += new hook_SpeakNow(OnSpeak);
			if (Configuration.DisplayUI.Value)
			{
				MainMenuController.Start += new hook_Start(UIManager.AddUI);
			}
		}

		private void OnDisable()
		{
			//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
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Expected O, but got Unknown
			BrotherSpeechDriver.SendReponseFromPool -= new hook_SendReponseFromPool(BrotherSpeechDriver_SendReponseFromPool);
			FalseSonBossSpeechDriver.SendReponseFromPool -= new hook_SendReponseFromPool(FalseSonBossSpeechDriver_SendReponseFromPool);
			CharacterSpeechController.SpeakNow -= new hook_SpeakNow(OnSpeak);
			if (Configuration.DisplayUI.Value)
			{
				MainMenuController.Start -= new hook_Start(UIManager.AddUI);
			}
		}

		private static void OnSpeak(orig_SpeakNow orig, CharacterSpeechController self, ref SpeechInfo speechInfo)
		{
			orig.Invoke(self, ref speechInfo);
			GameObject val = ((Component)self.currentCharacterBody).gameObject;
			string text = "VAMR_" + (((Object)val).name.Contains("Brother") ? Configuration.MithrixVoice.Value : Configuration.FalseSonVoice.Value) + "_" + speechInfo.token;
			BossVoiceComponent bossVoiceComponent = val.GetComponent<BossVoiceComponent>();
			if (!Object.op_Implicit((Object)(object)bossVoiceComponent))
			{
				bossVoiceComponent = val.AddComponent<BossVoiceComponent>();
			}
			if (text.Contains("FALSESONBOSS") && (text.Contains("_DEATH_") || text.Contains("PURIFICATION")))
			{
				val = GameObject.Find("MeridianEventTriggerCore");
			}
			bossVoiceComponent.TryVoiceLine(new BossLineEvent(text, val));
		}

		private void HereticKurskanFix()
		{
			LanguageAPI.Add("BROTHER_SEE_HERETIC_1", "Regret this journey, Kur-skan.", "en");
			LanguageAPI.Add("BROTHER_KILL_HERETIC_2", "Die again, Kur-skan.", "en");
			LanguageAPI.Add("BROTHERHURT_KILL_HERETIC_2", "DIE AGAIN, KUR-SKAN.", "en");
		}

		internal static CharacterMaster GetLocalPlayer()
		{
			return CharacterMaster.readOnlyInstancesList[0];
		}

		private static void FalseSonBossSpeechDriver_SendReponseFromPool(orig_SendReponseFromPool orig, FalseSonBossSpeechDriver self, SpeechInfo[] responsePool)
		{
			if (responsePool.Length != 0)
			{
				((BaseCharacterSpeechDriver)self).characterSpeechController.EnqueueSpeech(ref responsePool[Random.Range(0, responsePool.Length)]);
			}
		}

		private static void BrotherSpeechDriver_SendReponseFromPool(orig_SendReponseFromPool orig, BrotherSpeechDriver self, SpeechInfo[] responsePool)
		{
			if (responsePool.Length != 0)
			{
				((BaseCharacterSpeechDriver)self).characterSpeechController.EnqueueSpeech(ref responsePool[Random.Range(0, responsePool.Length)]);
			}
		}
	}
}
namespace VoiceActedMithrix.UI
{
	internal class UIManager
	{
		private static AssetBundle bundle;

		private static GameObject prefab;

		private static GameObject instance;

		private static Sprite sprite;

		private const string BUNDLE_NAME = "vamithrixbundle";

		private const string FOLDER_NAME = "assets";

		private static ColorBlock colors;

		internal static void Init()
		{
			RegisterTokens();
			RegisterPrefab();
		}

		private static void RegisterPrefab()
		{
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			string text = Path.Combine(Path.GetDirectoryName(VoiceActedMithrix.PInfo.Location), "assets", "vamithrixbundle");
			bundle = AssetBundle.LoadFromFile(text);
			prefab = bundle.LoadAsset<GameObject>("VoiceSelectionPanel");
			GameObject gameObject = ((Component)prefab.transform.Find("Canvas/B1")).gameObject;
			GameObject gameObject2 = ((Component)prefab.transform.Find("Canvas/B2")).gameObject;
			Image component = gameObject.GetComponent<Image>();
			Sprite val2 = (gameObject2.GetComponent<Image>().sprite = Addressables.LoadAssetAsync<Sprite>((object)"RoR2/Base/UI/texUICleanPanel.png").WaitForCompletion());
			component.sprite = val2;
			ModifyButton(gameObject).hoverToken = "VMR_TITLE_MITHRIXVOICE_DESC";
			ModifyButton(gameObject2).hoverToken = "VMR_TITLE_FALSESONVOICE_DESC";
		}

		private static HGButton ModifyButton(GameObject button)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			VoiceChanger voiceChanger = button.AddComponent<VoiceChanger>();
			HGButton val = button.AddComponent<HGButton>();
			((Selectable)val).targetGraphic = (Graphic)(object)button.GetComponent<Image>();
			((MPButton)val).selectOnPointerEnter = true;
			((MPButton)val).submitOnPointerUp = true;
			val.updateTextOnHover = true;
			((MPButton)val).allowAllEventSystems = true;
			((Selectable)val).colors = colors;
			LanguageTextMeshController val2 = button.AddComponent<LanguageTextMeshController>();
			return val;
		}

		private static void RegisterTokens()
		{
			LanguageAPI.Add("VMR_TITLE_MITHRIXVOICE_DESC", "Cycle through which voice actor to use for the Mithrix voice.", "en");
			LanguageAPI.Add("VMR_TITLE_FALSESONVOICE_DESC", "Cycle through which voice actor to use for the False Son voice.", "en");
		}

		internal static void AddUI(orig_Start orig, MainMenuController self)
		{
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: 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
			orig.Invoke(self);
			Transform val = ((Component)self).transform.Find("MENU: Title/TitleMenu/SafeZone");
			if (!((Object)(object)val == (Object)null))
			{
				instance = Object.Instantiate<GameObject>(prefab, val);
				GameObject gameObject = ((Component)instance.transform.Find("Canvas/B1")).gameObject;
				GameObject gameObject2 = ((Component)instance.transform.Find("Canvas/B2")).gameObject;
				HGButton component = gameObject.GetComponent<HGButton>();
				VoiceChanger b1Component = gameObject.GetComponent<VoiceChanger>();
				HGButton component2 = gameObject2.GetComponent<HGButton>();
				VoiceChanger b2Component = gameObject2.GetComponent<VoiceChanger>();
				component.hoverLanguageTextMeshController = (component2.hoverLanguageTextMeshController = ((Component)val.Find("GenericMenuButtonPanel/JuicePanel/DescriptionPanel, Naked/ContentSizeFitter/DescriptionText")).GetComponent<LanguageTextMeshController>());
				((UnityEvent)((Button)component).onClick).AddListener((UnityAction)delegate
				{
					b1Component.UpdateText(changeConfig: true);
				});
				((UnityEvent)((Button)component2).onClick).AddListener((UnityAction)delegate
				{
					b2Component.UpdateText(changeConfig: true);
				});
			}
		}

		static UIManager()
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: 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_006d: 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_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			ColorBlock val = default(ColorBlock);
			((ColorBlock)(ref val)).colorMultiplier = 1f;
			((ColorBlock)(ref val)).disabledColor = new Color(0.254f, 0.2f, 0.2f, 0.713f);
			((ColorBlock)(ref val)).highlightedColor = new Color(0.988f, 1f, 0.693f, 0.733f);
			((ColorBlock)(ref val)).normalColor = new Color(0.327f, 0.402f, 0.471f, 1f);
			((ColorBlock)(ref val)).pressedColor = new Color(0.739f, 0.754f, 0.444f, 0.984f);
			((ColorBlock)(ref val)).selectedColor = new Color(0.988f, 1f, 0.693f, 0.733f);
			colors = val;
		}
	}
	public class VoiceChanger : MonoBehaviour
	{
		private static string MithrixPreface = "Mithrix Voice Actor: ";

		private static string FalseSonPreface = "False Son Voice Actor: ";

		private bool voiceM;

		private Text textAsset;

		private static string[] voiceMapM = new string[2] { "MotherEgg", "KKing" };

		private static string[] voiceMapFS = new string[2] { "SkellyVA", "KKing" };

		private void Start()
		{
			voiceM = ((Object)((Component)this).gameObject).name == "B1";
			textAsset = ((Component)((Component)this).transform.Find("Text")).GetComponent<Text>();
			UpdateText(changeConfig: false);
		}

		public void UpdateText(bool changeConfig)
		{
			if (changeConfig)
			{
				if (voiceM)
				{
					Configuration.MithrixVoice.Value = (Configuration.MithrixVoice.Value + 1) % voiceMapM.Length;
					VoiceActedMithrix.LoadBrotherVoice();
				}
				else
				{
					Configuration.FalseSonVoice.Value = (Configuration.FalseSonVoice.Value + 1) % voiceMapFS.Length;
					VoiceActedMithrix.LoadFalseSonVoice();
				}
			}
			if (voiceM)
			{
				textAsset.text = MithrixPreface + voiceMapM[Configuration.MithrixVoice.Value];
			}
			else
			{
				textAsset.text = FalseSonPreface + voiceMapFS[Configuration.FalseSonVoice.Value];
			}
		}
	}
}