Decompiled source of vikingoldrepublictheme v1.0.1

vikingoldrepublictheme.dll

Decompiled 2 days ago
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Cryptography;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using JetBrains.Annotations;
using Microsoft.CodeAnalysis;
using ServerSync;
using TMPro;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.UI;
using YamlDotNet.Core;
using YamlDotNet.Core.Events;
using YamlDotNet.Core.ObjectPool;
using YamlDotNet.Core.Tokens;
using YamlDotNet.Helpers;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.BufferedDeserialization;
using YamlDotNet.Serialization.BufferedDeserialization.TypeDiscriminators;
using YamlDotNet.Serialization.Callbacks;
using YamlDotNet.Serialization.Converters;
using YamlDotNet.Serialization.EventEmitters;
using YamlDotNet.Serialization.NamingConventions;
using YamlDotNet.Serialization.NodeDeserializers;
using YamlDotNet.Serialization.NodeTypeResolvers;
using YamlDotNet.Serialization.ObjectFactories;
using YamlDotNet.Serialization.ObjectGraphTraversalStrategies;
using YamlDotNet.Serialization.ObjectGraphVisitors;
using YamlDotNet.Serialization.Schemas;
using YamlDotNet.Serialization.TypeInspectors;
using YamlDotNet.Serialization.TypeResolvers;
using YamlDotNet.Serialization.Utilities;
using YamlDotNet.Serialization.ValueDeserializers;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("vikingoldrepublictheme")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Azathoth")]
[assembly: AssemblyProduct("vikingoldrepublictheme")]
[assembly: AssemblyCopyright("Copyright ©  2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("4358610B-F3F4-4843-B7AF-98B7BC60DCDE")]
[assembly: AssemblyFileVersion("1.0.1")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[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 LocalizationManager
{
	[PublicAPI]
	public class Localizer
	{
		private static readonly Dictionary<string, Dictionary<string, Func<string>>> PlaceholderProcessors;

		private static readonly Dictionary<string, Dictionary<string, string>> loadedTexts;

		private static readonly ConditionalWeakTable<Localization, string> localizationLanguage;

		private static readonly List<WeakReference<Localization>> localizationObjects;

		private static BaseUnityPlugin? _plugin;

		private static readonly List<string> fileExtensions;

		private static BaseUnityPlugin plugin
		{
			get
			{
				//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b2: Expected O, but got Unknown
				if (_plugin == null)
				{
					IEnumerable<TypeInfo> source;
					try
					{
						source = Assembly.GetExecutingAssembly().DefinedTypes.ToList();
					}
					catch (ReflectionTypeLoadException ex)
					{
						source = from t in ex.Types
							where t != null
							select t.GetTypeInfo();
					}
					_plugin = (BaseUnityPlugin)Chainloader.ManagerObject.GetComponent((Type)source.First((TypeInfo t) => t.IsClass && typeof(BaseUnityPlugin).IsAssignableFrom(t)));
				}
				return _plugin;
			}
		}

		public static event Action? OnLocalizationComplete;

		private static void UpdatePlaceholderText(Localization localization, string key)
		{
			localizationLanguage.TryGetValue(localization, out string value);
			string text = loadedTexts[value][key];
			if (PlaceholderProcessors.TryGetValue(key, out Dictionary<string, Func<string>> value2))
			{
				text = value2.Aggregate(text, (string current, KeyValuePair<string, Func<string>> kv) => current.Replace("{" + kv.Key + "}", kv.Value()));
			}
			localization.AddWord(key, text);
		}

		public static void AddPlaceholder<T>(string key, string placeholder, ConfigEntry<T> config, Func<T, string>? convertConfigValue = null) where T : notnull
		{
			if (convertConfigValue == null)
			{
				convertConfigValue = (T val) => val.ToString();
			}
			if (!PlaceholderProcessors.ContainsKey(key))
			{
				PlaceholderProcessors[key] = new Dictionary<string, Func<string>>();
			}
			config.SettingChanged += delegate
			{
				UpdatePlaceholder();
			};
			if (loadedTexts.ContainsKey(Localization.instance.GetSelectedLanguage()))
			{
				UpdatePlaceholder();
			}
			void UpdatePlaceholder()
			{
				PlaceholderProcessors[key][placeholder] = () => convertConfigValue(config.Value);
				UpdatePlaceholderText(Localization.instance, key);
			}
		}

		public static void AddText(string key, string text)
		{
			List<WeakReference<Localization>> list = new List<WeakReference<Localization>>();
			foreach (WeakReference<Localization> localizationObject in localizationObjects)
			{
				if (localizationObject.TryGetTarget(out var target))
				{
					Dictionary<string, string> dictionary = loadedTexts[localizationLanguage.GetOrCreateValue(target)];
					if (!target.m_translations.ContainsKey(key))
					{
						dictionary[key] = text;
						target.AddWord(key, text);
					}
				}
				else
				{
					list.Add(localizationObject);
				}
			}
			foreach (WeakReference<Localization> item in list)
			{
				localizationObjects.Remove(item);
			}
		}

		public static void Load()
		{
			_ = plugin;
		}

		public static void LoadLocalizationLater(Localization __instance)
		{
			LoadLocalization(Localization.instance, __instance.GetSelectedLanguage());
		}

		public static void SafeCallLocalizeComplete()
		{
			Localizer.OnLocalizationComplete?.Invoke();
		}

		private static void LoadLocalization(Localization __instance, string language)
		{
			if (!localizationLanguage.Remove(__instance))
			{
				localizationObjects.Add(new WeakReference<Localization>(__instance));
			}
			localizationLanguage.Add(__instance, language);
			Dictionary<string, string> dictionary = new Dictionary<string, string>();
			foreach (string item in from f in Directory.GetFiles(Path.GetDirectoryName(Paths.PluginPath), plugin.Info.Metadata.Name + ".*", SearchOption.AllDirectories)
				where fileExtensions.IndexOf(Path.GetExtension(f)) >= 0
				select f)
			{
				string[] array = Path.GetFileNameWithoutExtension(item).Split(new char[1] { '.' });
				if (array.Length >= 2)
				{
					string text = array[1];
					if (dictionary.ContainsKey(text))
					{
						Debug.LogWarning((object)("Duplicate key " + text + " found for " + plugin.Info.Metadata.Name + ". The duplicate file found at " + item + " will be skipped."));
					}
					else
					{
						dictionary[text] = item;
					}
				}
			}
			byte[] array2 = LoadTranslationFromAssembly("English");
			if (array2 == null)
			{
				throw new Exception("Found no English localizations in mod " + plugin.Info.Metadata.Name + ". Expected an embedded resource translations/English.json or translations/English.yml.");
			}
			Dictionary<string, string> dictionary2 = new DeserializerBuilder().IgnoreFields().Build().Deserialize<Dictionary<string, string>>(Encoding.UTF8.GetString(array2));
			if (dictionary2 == null)
			{
				throw new Exception("Localization for mod " + plugin.Info.Metadata.Name + " failed: Localization file was empty.");
			}
			string text2 = null;
			if (language != "English")
			{
				if (dictionary.TryGetValue(language, out var value))
				{
					text2 = File.ReadAllText(value);
				}
				else
				{
					byte[] array3 = LoadTranslationFromAssembly(language);
					if (array3 != null)
					{
						text2 = Encoding.UTF8.GetString(array3);
					}
				}
			}
			if (text2 == null && dictionary.TryGetValue("English", out var value2))
			{
				text2 = File.ReadAllText(value2);
			}
			if (text2 != null)
			{
				foreach (KeyValuePair<string, string> item2 in new DeserializerBuilder().IgnoreFields().Build().Deserialize<Dictionary<string, string>>(text2) ?? new Dictionary<string, string>())
				{
					dictionary2[item2.Key] = item2.Value;
				}
			}
			loadedTexts[language] = dictionary2;
			foreach (KeyValuePair<string, string> item3 in dictionary2)
			{
				UpdatePlaceholderText(__instance, item3.Key);
			}
		}

		static Localizer()
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Expected O, but got Unknown
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Expected O, but got Unknown
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Expected O, but got Unknown
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Expected O, but got Unknown
			PlaceholderProcessors = new Dictionary<string, Dictionary<string, Func<string>>>();
			loadedTexts = new Dictionary<string, Dictionary<string, string>>();
			localizationLanguage = new ConditionalWeakTable<Localization, string>();
			localizationObjects = new List<WeakReference<Localization>>();
			fileExtensions = new List<string>(2) { ".json", ".yml" };
			Harmony val = new Harmony("org.bepinex.helpers.LocalizationManager");
			val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Localization), "SetupLanguage", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Localizer), "LoadLocalization", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(FejdStartup), "SetupGui", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Localizer), "LoadLocalizationLater", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(FejdStartup), "Start", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Localizer), "SafeCallLocalizeComplete", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}

		private static byte[]? LoadTranslationFromAssembly(string language)
		{
			foreach (string fileExtension in fileExtensions)
			{
				byte[] array = ReadEmbeddedFileBytes("translations." + language + fileExtension);
				if (array != null)
				{
					return array;
				}
			}
			return null;
		}

		public static byte[]? ReadEmbeddedFileBytes(string resourceFileName, Assembly? containingAssembly = null)
		{
			using MemoryStream memoryStream = new MemoryStream();
			if ((object)containingAssembly == null)
			{
				containingAssembly = Assembly.GetCallingAssembly();
			}
			string text = containingAssembly.GetManifestResourceNames().FirstOrDefault((string str) => str.EndsWith(resourceFileName, StringComparison.Ordinal));
			if (text != null)
			{
				containingAssembly.GetManifestResourceStream(text)?.CopyTo(memoryStream);
			}
			return (memoryStream.Length == 0L) ? null : memoryStream.ToArray();
		}
	}
	public static class LocalizationManagerVersion
	{
		public const string Version = "1.4.1";
	}
}
namespace vikingoldrepublictheme
{
	internal static class VORAshlandsMusicState
	{
		public static bool ForceAshlandsMusicActive;
	}
	[HarmonyPatch(typeof(Player), "Awake")]
	internal static class Player_AshlandsMusicControllerPatch
	{
		private static void Postfix(Player __instance)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			if (!((Object)(object)VORAshlandsMusicController.Instance != (Object)null))
			{
				GameObject val = new GameObject("VOR_AshlandsMusicController");
				Object.DontDestroyOnLoad((Object)(object)val);
				val.AddComponent<VORAshlandsMusicController>();
			}
		}
	}
	[HarmonyPatch]
	internal static class MusicMan_BlockAshlandsLocationMusicPatch
	{
		private static IEnumerable<MethodBase> TargetMethods()
		{
			MethodInfo[] methods = typeof(MusicMan).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			MethodInfo[] array = methods;
			foreach (MethodInfo method in array)
			{
				if (!(method == null))
				{
					string name = method.Name.ToLowerInvariant();
					if (name.Contains("triggermusic") || name.Contains("updatemusic") || name.Contains("startmusic") || name.Contains("playmusic"))
					{
						yield return method;
					}
				}
			}
		}

		private static bool Prefix()
		{
			return !VORAshlandsMusicState.ForceAshlandsMusicActive;
		}
	}
	public class VORAshlandsMusicController : MonoBehaviour
	{
		private struct SavedAudioState
		{
			public float Volume;

			public bool Mute;
		}

		public static VORAshlandsMusicController Instance;

		private const string AshlandsThemeAssetName = "ashlandteme";

		private const float CheckInterval = 0.35f;

		private const float SilenceInterval = 0.25f;

		private const float AshlandsVolume = 0.65f;

		private const float FadeSpeed = 0.65f;

		private AudioSource _ashlandsSource;

		private AudioClip _ashlandsClip;

		private float _nextCheckTime;

		private float _nextSilenceTime;

		private float _targetVolume;

		private bool _isInAshlands;

		private bool _isStopping;

		private readonly Dictionary<AudioSource, SavedAudioState> _savedMusicSources = new Dictionary<AudioSource, SavedAudioState>();

		private IEnumerator Start()
		{
			Instance = this;
			yield return (object)new WaitForSeconds(1f);
			LoadAshlandsTheme();
			CreateAudioSource();
		}

		private void OnDestroy()
		{
			VORAshlandsMusicState.ForceAshlandsMusicActive = false;
			RestoreVanillaMusic();
			if ((Object)(object)Instance == (Object)(object)this)
			{
				Instance = null;
			}
		}

		private void LoadAshlandsTheme()
		{
			if ((Object)(object)vikingoldrepublicthemePlugin.ThemeBundle == (Object)null)
			{
				vikingoldrepublicthemePlugin.vikingoldrepublicthemeLogger.LogWarning((object)"[VOR Ashlands Music] ThemeBundle es null. No puedo cargar ashlandteme.");
				return;
			}
			_ashlandsClip = vikingoldrepublicthemePlugin.ThemeBundle.LoadAsset<AudioClip>("ashlandteme");
			if ((Object)(object)_ashlandsClip == (Object)null)
			{
				vikingoldrepublicthemePlugin.vikingoldrepublicthemeLogger.LogWarning((object)"[VOR Ashlands Music] No encontré el AudioClip 'ashlandteme' en el AssetBundle 'starthemes'.");
			}
			else
			{
				vikingoldrepublicthemePlugin.vikingoldrepublicthemeLogger.LogInfo((object)("[VOR Ashlands Music] Música de Ashlands cargada: " + ((Object)_ashlandsClip).name));
			}
		}

		private void CreateAudioSource()
		{
			_ashlandsSource = ((Component)this).gameObject.AddComponent<AudioSource>();
			_ashlandsSource.playOnAwake = false;
			_ashlandsSource.loop = true;
			_ashlandsSource.spatialBlend = 0f;
			_ashlandsSource.volume = 0f;
			_ashlandsSource.priority = 25;
			_ashlandsSource.bypassListenerEffects = true;
			_ashlandsSource.bypassReverbZones = true;
		}

		private void Update()
		{
			if ((Object)(object)_ashlandsClip == (Object)null || (Object)(object)_ashlandsSource == (Object)null)
			{
				return;
			}
			if (Time.time >= _nextCheckTime)
			{
				_nextCheckTime = Time.time + 0.35f;
				bool flag = IsLocalPlayerInAshlands() && !IsCustomBossMusicActive();
				if (flag && !_isInAshlands)
				{
					StartAshlandsMusic();
				}
				else if (!flag && _isInAshlands)
				{
					StopAshlandsMusic();
				}
				_isInAshlands = flag;
			}
			if (_isInAshlands && Time.time >= _nextSilenceTime)
			{
				_nextSilenceTime = Time.time + 0.25f;
				SilenceVanillaMusicAggressively();
			}
			UpdateFade();
		}

		private bool IsLocalPlayerInAshlands()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return false;
			}
			string text = ((object)Heightmap.FindBiome(((Component)localPlayer).transform.position)/*cast due to .constrained prefix*/).ToString().ToLowerInvariant();
			return text.Contains("ash");
		}

		private bool IsCustomBossMusicActive()
		{
			Type type = Type.GetType("vikingoldrepublictheme.VORBossMusicState");
			if (type == null)
			{
				return false;
			}
			FieldInfo field = type.GetField("CustomBossMusicActive", BindingFlags.Static | BindingFlags.Public);
			if (field == null)
			{
				return false;
			}
			object value = field.GetValue(null);
			bool flag = default(bool);
			int num;
			if (value is bool)
			{
				flag = (bool)value;
				num = 1;
			}
			else
			{
				num = 0;
			}
			return (byte)((uint)num & (flag ? 1u : 0u)) != 0;
		}

		private void StartAshlandsMusic()
		{
			if (!((Object)(object)_ashlandsSource == (Object)null) && !((Object)(object)_ashlandsClip == (Object)null))
			{
				VORAshlandsMusicState.ForceAshlandsMusicActive = true;
				SilenceVanillaMusicAggressively();
				_ashlandsSource.clip = _ashlandsClip;
				_ashlandsSource.loop = true;
				if (!_ashlandsSource.isPlaying)
				{
					_ashlandsSource.volume = 0f;
					_ashlandsSource.Play();
				}
				_targetVolume = 0.65f;
				_isStopping = false;
				vikingoldrepublicthemePlugin.vikingoldrepublicthemeLogger.LogInfo((object)"[VOR Ashlands Music] Entraste a Ashlands. Forzando ashlandteme.");
			}
		}

		private void StopAshlandsMusic()
		{
			_targetVolume = 0f;
			_isStopping = true;
			VORAshlandsMusicState.ForceAshlandsMusicActive = false;
			vikingoldrepublicthemePlugin.vikingoldrepublicthemeLogger.LogInfo((object)"[VOR Ashlands Music] Saliste de Ashlands o entró música de boss. Deteniendo ashlandteme.");
		}

		private void UpdateFade()
		{
			if (!((Object)(object)_ashlandsSource == (Object)null))
			{
				_ashlandsSource.volume = Mathf.MoveTowards(_ashlandsSource.volume, _targetVolume, 0.65f * Time.deltaTime);
				if (_isStopping && _ashlandsSource.volume <= 0.01f)
				{
					_ashlandsSource.Stop();
					_ashlandsSource.time = 0f;
					_isStopping = false;
					RestoreVanillaMusic();
				}
			}
		}

		private void SilenceVanillaMusicAggressively()
		{
			MusicMan instance = MusicMan.instance;
			if ((Object)(object)instance != (Object)null)
			{
				AudioSource[] componentsInChildren = ((Component)instance).GetComponentsInChildren<AudioSource>(true);
				AudioSource[] array = componentsInChildren;
				foreach (AudioSource source in array)
				{
					SilenceSource(source);
				}
			}
			AudioSource[] array2 = Object.FindObjectsOfType<AudioSource>(true);
			AudioSource[] array3 = array2;
			foreach (AudioSource val in array3)
			{
				if (!((Object)(object)val == (Object)null) && !((Object)(object)val == (Object)(object)_ashlandsSource) && !((Object)(object)val.clip == (Object)null) && !((Object)(object)val.clip == (Object)(object)_ashlandsClip) && !((Object)((Component)val).gameObject).name.StartsWith("VOR_") && LooksLikeMusicSource(val))
				{
					SilenceSource(val);
				}
			}
		}

		private void SilenceSource(AudioSource source)
		{
			if (!((Object)(object)source == (Object)null) && !((Object)(object)source == (Object)(object)_ashlandsSource))
			{
				if (!_savedMusicSources.ContainsKey(source))
				{
					_savedMusicSources[source] = new SavedAudioState
					{
						Volume = source.volume,
						Mute = source.mute
					};
				}
				source.Stop();
				source.volume = 0f;
				source.mute = true;
			}
		}

		private bool LooksLikeMusicSource(AudioSource source)
		{
			if ((Object)(object)source == (Object)null)
			{
				return false;
			}
			string text = ((Object)((Component)source).gameObject).name.ToLowerInvariant();
			string text2 = (((Object)(object)source.clip != (Object)null) ? ((Object)source.clip).name.ToLowerInvariant() : "");
			if ((Object)(object)source.clip != (Object)null && source.clip.length < 8f)
			{
				return false;
			}
			return text.Contains("music") || text.Contains("musicman") || text.Contains("audio_mus") || text2.Contains("music") || text2.Contains("theme") || text2.Contains("ash") || text2.Contains("ashland") || text2.Contains("ashlands") || text2.Contains("location") || text2.Contains("fortress") || text2.Contains("dungeon") || text2.Contains("combat") || text2.Contains("battle");
		}

		private void RestoreVanillaMusic()
		{
			foreach (KeyValuePair<AudioSource, SavedAudioState> savedMusicSource in _savedMusicSources)
			{
				AudioSource key = savedMusicSource.Key;
				if (!((Object)(object)key == (Object)null))
				{
					key.volume = savedMusicSource.Value.Volume;
					key.mute = savedMusicSource.Value.Mute;
				}
			}
			_savedMusicSources.Clear();
			try
			{
				if ((Object)(object)MusicMan.instance != (Object)null)
				{
					MusicMan.instance.Reset();
				}
			}
			catch
			{
			}
		}
	}
	internal static class VORBlackForestMusicState
	{
		public static bool ForceBlackForestMusicActive;
	}
	[HarmonyPatch(typeof(Player), "Awake")]
	internal static class Player_BlackForestMusicControllerPatch
	{
		private static void Postfix(Player __instance)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			if (!((Object)(object)VORBlackForestMusicController.Instance != (Object)null))
			{
				GameObject val = new GameObject("VOR_BlackForestMusicController");
				Object.DontDestroyOnLoad((Object)(object)val);
				val.AddComponent<VORBlackForestMusicController>();
			}
		}
	}
	[HarmonyPatch]
	internal static class MusicMan_BlockBlackForestLocationMusicPatch
	{
		private static IEnumerable<MethodBase> TargetMethods()
		{
			MethodInfo[] methods = typeof(MusicMan).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			MethodInfo[] array = methods;
			foreach (MethodInfo method in array)
			{
				if (!(method == null))
				{
					string name = method.Name.ToLowerInvariant();
					if (name.Contains("triggermusic") || name.Contains("updatemusic") || name.Contains("startmusic") || name.Contains("playmusic"))
					{
						yield return method;
					}
				}
			}
		}

		private static bool Prefix()
		{
			return !VORBlackForestMusicState.ForceBlackForestMusicActive;
		}
	}
	public class VORBlackForestMusicController : MonoBehaviour
	{
		private struct SavedAudioState
		{
			public float Volume;

			public bool Mute;
		}

		public static VORBlackForestMusicController Instance;

		private const string BlackForestThemeAssetName = "blackforestheme";

		private const float CheckInterval = 0.35f;

		private const float SilenceInterval = 0.25f;

		private const float BlackForestVolume = 0.48f;

		private const float FadeSpeed = 0.65f;

		private AudioSource _blackForestSource;

		private AudioClip _blackForestClip;

		private float _nextCheckTime;

		private float _nextSilenceTime;

		private float _targetVolume;

		private bool _isInBlackForest;

		private bool _isStopping;

		private readonly Dictionary<AudioSource, SavedAudioState> _savedMusicSources = new Dictionary<AudioSource, SavedAudioState>();

		private IEnumerator Start()
		{
			Instance = this;
			yield return (object)new WaitForSeconds(1f);
			LoadBlackForestTheme();
			CreateAudioSource();
		}

		private void OnDestroy()
		{
			VORBlackForestMusicState.ForceBlackForestMusicActive = false;
			RestoreVanillaMusic();
			if ((Object)(object)Instance == (Object)(object)this)
			{
				Instance = null;
			}
		}

		private void LoadBlackForestTheme()
		{
			if ((Object)(object)vikingoldrepublicthemePlugin.ThemeBundle == (Object)null)
			{
				vikingoldrepublicthemePlugin.vikingoldrepublicthemeLogger.LogWarning((object)"[VOR BlackForest Music] ThemeBundle es null. No puedo cargar blackforestheme.");
				return;
			}
			_blackForestClip = vikingoldrepublicthemePlugin.ThemeBundle.LoadAsset<AudioClip>("blackforestheme");
			if ((Object)(object)_blackForestClip == (Object)null)
			{
				vikingoldrepublicthemePlugin.vikingoldrepublicthemeLogger.LogWarning((object)"[VOR BlackForest Music] No encontré el AudioClip 'blackforestheme' en el AssetBundle 'starthemes'.");
			}
			else
			{
				vikingoldrepublicthemePlugin.vikingoldrepublicthemeLogger.LogInfo((object)("[VOR BlackForest Music] Música de Bosque Negro cargada: " + ((Object)_blackForestClip).name));
			}
		}

		private void CreateAudioSource()
		{
			_blackForestSource = ((Component)this).gameObject.AddComponent<AudioSource>();
			_blackForestSource.playOnAwake = false;
			_blackForestSource.loop = true;
			_blackForestSource.spatialBlend = 0f;
			_blackForestSource.volume = 0f;
			_blackForestSource.priority = 25;
			_blackForestSource.bypassListenerEffects = true;
			_blackForestSource.bypassReverbZones = true;
		}

		private void Update()
		{
			if ((Object)(object)_blackForestClip == (Object)null || (Object)(object)_blackForestSource == (Object)null)
			{
				return;
			}
			if (Time.time >= _nextCheckTime)
			{
				_nextCheckTime = Time.time + 0.35f;
				bool flag = IsLocalPlayerInBlackForest() && !IsCustomBossMusicActive();
				if (flag && !_isInBlackForest)
				{
					StartBlackForestMusic();
				}
				else if (!flag && _isInBlackForest)
				{
					StopBlackForestMusic();
				}
				_isInBlackForest = flag;
			}
			if (_isInBlackForest && Time.time >= _nextSilenceTime)
			{
				_nextSilenceTime = Time.time + 0.25f;
				SilenceVanillaMusicAggressively();
			}
			UpdateFade();
		}

		private bool IsLocalPlayerInBlackForest()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Invalid comparison between Unknown and I4
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return false;
			}
			Biome val = Heightmap.FindBiome(((Component)localPlayer).transform.position);
			return (int)val == 8;
		}

		private bool IsCustomBossMusicActive()
		{
			Type type = Type.GetType("vikingoldrepublictheme.VORBossMusicState");
			if (type == null)
			{
				return false;
			}
			FieldInfo field = type.GetField("CustomBossMusicActive", BindingFlags.Static | BindingFlags.Public);
			if (field == null)
			{
				return false;
			}
			object value = field.GetValue(null);
			bool flag = default(bool);
			int num;
			if (value is bool)
			{
				flag = (bool)value;
				num = 1;
			}
			else
			{
				num = 0;
			}
			return (byte)((uint)num & (flag ? 1u : 0u)) != 0;
		}

		private void StartBlackForestMusic()
		{
			if (!((Object)(object)_blackForestSource == (Object)null) && !((Object)(object)_blackForestClip == (Object)null))
			{
				VORBlackForestMusicState.ForceBlackForestMusicActive = true;
				SilenceVanillaMusicAggressively();
				_blackForestSource.clip = _blackForestClip;
				_blackForestSource.loop = true;
				if (!_blackForestSource.isPlaying)
				{
					_blackForestSource.volume = 0f;
					_blackForestSource.Play();
				}
				_targetVolume = 0.48f;
				_isStopping = false;
				vikingoldrepublicthemePlugin.vikingoldrepublicthemeLogger.LogInfo((object)"[VOR BlackForest Music] Entraste a Bosque Negro. Forzando blackforestheme.");
			}
		}

		private void StopBlackForestMusic()
		{
			_targetVolume = 0f;
			_isStopping = true;
			VORBlackForestMusicState.ForceBlackForestMusicActive = false;
			vikingoldrepublicthemePlugin.vikingoldrepublicthemeLogger.LogInfo((object)"[VOR BlackForest Music] Saliste de Bosque Negro o entró música de boss. Deteniendo blackforestheme.");
		}

		private void UpdateFade()
		{
			if (!((Object)(object)_blackForestSource == (Object)null))
			{
				_blackForestSource.volume = Mathf.MoveTowards(_blackForestSource.volume, _targetVolume, 0.65f * Time.deltaTime);
				if (_isStopping && _blackForestSource.volume <= 0.01f)
				{
					_blackForestSource.Stop();
					_blackForestSource.time = 0f;
					_isStopping = false;
					RestoreVanillaMusic();
				}
			}
		}

		private void SilenceVanillaMusicAggressively()
		{
			MusicMan instance = MusicMan.instance;
			if ((Object)(object)instance != (Object)null)
			{
				AudioSource[] componentsInChildren = ((Component)instance).GetComponentsInChildren<AudioSource>(true);
				AudioSource[] array = componentsInChildren;
				foreach (AudioSource source in array)
				{
					SilenceSource(source);
				}
			}
			AudioSource[] array2 = Object.FindObjectsOfType<AudioSource>(true);
			AudioSource[] array3 = array2;
			foreach (AudioSource val in array3)
			{
				if (!((Object)(object)val == (Object)null) && !((Object)(object)val == (Object)(object)_blackForestSource) && !((Object)(object)val.clip == (Object)null) && !((Object)(object)val.clip == (Object)(object)_blackForestClip) && !((Object)((Component)val).gameObject).name.StartsWith("VOR_") && LooksLikeMusicSource(val))
				{
					SilenceSource(val);
				}
			}
		}

		private void SilenceSource(AudioSource source)
		{
			if (!((Object)(object)source == (Object)null) && !((Object)(object)source == (Object)(object)_blackForestSource))
			{
				if (!_savedMusicSources.ContainsKey(source))
				{
					_savedMusicSources[source] = new SavedAudioState
					{
						Volume = source.volume,
						Mute = source.mute
					};
				}
				source.Stop();
				source.volume = 0f;
				source.mute = true;
			}
		}

		private bool LooksLikeMusicSource(AudioSource source)
		{
			if ((Object)(object)source == (Object)null)
			{
				return false;
			}
			string text = ((Object)((Component)source).gameObject).name.ToLowerInvariant();
			string text2 = (((Object)(object)source.clip != (Object)null) ? ((Object)source.clip).name.ToLowerInvariant() : "");
			if ((Object)(object)source.clip != (Object)null && source.clip.length < 8f)
			{
				return false;
			}
			return text.Contains("music") || text.Contains("musicman") || text.Contains("audio_mus") || text2.Contains("music") || text2.Contains("theme") || text2.Contains("blackforest") || text2.Contains("black_forest") || text2.Contains("forest") || text2.Contains("greydwarf") || text2.Contains("troll") || text2.Contains("crypt") || text2.Contains("burial") || text2.Contains("chamber") || text2.Contains("location") || text2.Contains("dungeon") || text2.Contains("combat") || text2.Contains("battle");
		}

		private void RestoreVanillaMusic()
		{
			foreach (KeyValuePair<AudioSource, SavedAudioState> savedMusicSource in _savedMusicSources)
			{
				AudioSource key = savedMusicSource.Key;
				if (!((Object)(object)key == (Object)null))
				{
					key.volume = savedMusicSource.Value.Volume;
					key.mute = savedMusicSource.Value.Mute;
				}
			}
			_savedMusicSources.Clear();
			try
			{
				if ((Object)(object)MusicMan.instance != (Object)null)
				{
					MusicMan.instance.Reset();
				}
			}
			catch
			{
			}
		}
	}
	internal static class VORBossMusicState
	{
		public static bool CustomBossMusicActive;
	}
	[HarmonyPatch(typeof(Player), "Awake")]
	internal static class Player_BossBattleThemePatch
	{
		private static void Postfix(Player __instance)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			if (!((Object)(object)BossBattleThemeController.Instance != (Object)null))
			{
				GameObject val = new GameObject("VOR_BossBattleThemeController");
				Object.DontDestroyOnLoad((Object)(object)val);
				val.AddComponent<BossBattleThemeController>();
			}
		}
	}
	[HarmonyPatch]
	internal static class MusicMan_BlockVanillaBossMusicPatch
	{
		private static IEnumerable<MethodBase> TargetMethods()
		{
			if (typeof(MusicMan) == null)
			{
				yield break;
			}
			MethodInfo[] methods = typeof(MusicMan).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			MethodInfo[] array = methods;
			foreach (MethodInfo method in array)
			{
				if (!(method == null))
				{
					string name = method.Name.ToLowerInvariant();
					if (name.Contains("triggermusic") || name.Contains("updatemusic") || name.Contains("startmusic") || name.Contains("playmusic"))
					{
						yield return method;
					}
				}
			}
		}

		private static bool Prefix()
		{
			return !VORBossMusicState.CustomBossMusicActive;
		}
	}
	public class BossBattleThemeController : MonoBehaviour
	{
		private struct SavedAudioState
		{
			public float Volume;

			public bool Mute;
		}

		public static BossBattleThemeController Instance;

		private const string BattleThemeAssetName = "battle_teme";

		private const string BattleThemeFallbackAssetName = "battle_theme";

		private const float BossDetectionRange = 95f;

		private const float CheckInterval = 0.75f;

		private const float MusicManSilenceInterval = 0.2f;

		private const float BattleVolume = 0.55f;

		private const float FadeSpeed = 0.65f;

		private AudioSource _battleSource;

		private AudioClip _battleClip;

		private float _nextCheckTime;

		private float _nextSilenceTime;

		private float _targetVolume;

		private bool _bossActive;

		private bool _isStopping;

		private readonly Dictionary<AudioSource, SavedAudioState> _savedMusicSources = new Dictionary<AudioSource, SavedAudioState>();

		private IEnumerator Start()
		{
			Instance = this;
			yield return (object)new WaitForSeconds(1f);
			LoadBattleTheme();
			CreateAudioSource();
		}

		private void OnDestroy()
		{
			VORBossMusicState.CustomBossMusicActive = false;
			RestoreVanillaMusic();
			if ((Object)(object)Instance == (Object)(object)this)
			{
				Instance = null;
			}
		}

		private void LoadBattleTheme()
		{
			if ((Object)(object)vikingoldrepublicthemePlugin.ThemeBundle == (Object)null)
			{
				vikingoldrepublicthemePlugin.vikingoldrepublicthemeLogger.LogWarning((object)"[VOR Boss Music] ThemeBundle es null. No puedo cargar battle_teme.");
				return;
			}
			_battleClip = vikingoldrepublicthemePlugin.ThemeBundle.LoadAsset<AudioClip>("battle_teme");
			if ((Object)(object)_battleClip == (Object)null)
			{
				_battleClip = vikingoldrepublicthemePlugin.ThemeBundle.LoadAsset<AudioClip>("battle_theme");
			}
			if ((Object)(object)_battleClip == (Object)null)
			{
				vikingoldrepublicthemePlugin.vikingoldrepublicthemeLogger.LogWarning((object)"[VOR Boss Music] No encontré 'battle_teme' ni 'battle_theme' en el AssetBundle 'starthemes'.");
			}
			else
			{
				vikingoldrepublicthemePlugin.vikingoldrepublicthemeLogger.LogInfo((object)("[VOR Boss Music] Música de boss cargada: " + ((Object)_battleClip).name));
			}
		}

		private void CreateAudioSource()
		{
			_battleSource = ((Component)this).gameObject.AddComponent<AudioSource>();
			_battleSource.playOnAwake = false;
			_battleSource.loop = true;
			_battleSource.spatialBlend = 0f;
			_battleSource.volume = 0f;
			_battleSource.priority = 10;
			_battleSource.bypassListenerEffects = true;
			_battleSource.bypassReverbZones = true;
		}

		private void Update()
		{
			if ((Object)(object)_battleClip == (Object)null || (Object)(object)_battleSource == (Object)null)
			{
				return;
			}
			if (Time.time >= _nextCheckTime)
			{
				_nextCheckTime = Time.time + 0.75f;
				bool flag = IsBossNearLocalPlayer();
				if (flag && !_bossActive)
				{
					StartBattleMusic();
				}
				else if (!flag && _bossActive)
				{
					StopBattleMusic();
				}
				_bossActive = flag;
			}
			if (_bossActive && Time.time >= _nextSilenceTime)
			{
				_nextSilenceTime = Time.time + 0.2f;
				SilenceMusicManAggressively();
			}
			UpdateFade();
		}

		private bool IsBossNearLocalPlayer()
		{
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return false;
			}
			Character[] array = Object.FindObjectsOfType<Character>();
			Character[] array2 = array;
			foreach (Character val in array2)
			{
				if (!((Object)(object)val == (Object)null) && !((Object)(object)val == (Object)(object)localPlayer) && val.m_boss && !val.IsDead())
				{
					float num = Vector3.Distance(((Component)localPlayer).transform.position, ((Component)val).transform.position);
					if (num <= 95f)
					{
						return true;
					}
				}
			}
			return false;
		}

		private void StartBattleMusic()
		{
			if (!((Object)(object)_battleSource == (Object)null) && !((Object)(object)_battleClip == (Object)null))
			{
				VORBossMusicState.CustomBossMusicActive = true;
				SilenceMusicManAggressively();
				_battleSource.clip = _battleClip;
				_battleSource.loop = true;
				if (!_battleSource.isPlaying)
				{
					_battleSource.volume = 0f;
					_battleSource.Play();
				}
				_targetVolume = 0.55f;
				_isStopping = false;
				vikingoldrepublicthemePlugin.vikingoldrepublicthemeLogger.LogInfo((object)"[VOR Boss Music] Boss detectado. MusicMan bloqueado. Iniciando battle_teme.");
			}
		}

		private void StopBattleMusic()
		{
			_targetVolume = 0f;
			_isStopping = true;
			vikingoldrepublicthemePlugin.vikingoldrepublicthemeLogger.LogInfo((object)"[VOR Boss Music] Boss fuera de rango o muerto. Deteniendo battle_teme.");
		}

		private void UpdateFade()
		{
			if (!((Object)(object)_battleSource == (Object)null))
			{
				_battleSource.volume = Mathf.MoveTowards(_battleSource.volume, _targetVolume, 0.65f * Time.deltaTime);
				if (_isStopping && _battleSource.volume <= 0.01f)
				{
					_battleSource.Stop();
					_battleSource.time = 0f;
					_isStopping = false;
					VORBossMusicState.CustomBossMusicActive = false;
					RestoreVanillaMusic();
				}
			}
		}

		private void SilenceMusicManAggressively()
		{
			MusicMan instance = MusicMan.instance;
			if ((Object)(object)instance != (Object)null)
			{
				AudioSource[] componentsInChildren = ((Component)instance).GetComponentsInChildren<AudioSource>(true);
				AudioSource[] array = componentsInChildren;
				foreach (AudioSource source in array)
				{
					SilenceSource(source);
				}
			}
			AudioSource[] array2 = Object.FindObjectsOfType<AudioSource>(true);
			AudioSource[] array3 = array2;
			foreach (AudioSource val in array3)
			{
				if (!((Object)(object)val == (Object)null) && !((Object)(object)val == (Object)(object)_battleSource) && !((Object)(object)val.clip == (Object)null) && LooksLikeMusicSource(val))
				{
					SilenceSource(val);
				}
			}
		}

		private void SilenceSource(AudioSource source)
		{
			if (!((Object)(object)source == (Object)null) && !((Object)(object)source == (Object)(object)_battleSource))
			{
				if (!_savedMusicSources.ContainsKey(source))
				{
					_savedMusicSources[source] = new SavedAudioState
					{
						Volume = source.volume,
						Mute = source.mute
					};
				}
				source.Stop();
				source.volume = 0f;
				source.mute = true;
			}
		}

		private bool LooksLikeMusicSource(AudioSource source)
		{
			if ((Object)(object)source == (Object)null)
			{
				return false;
			}
			string text = ((Object)((Component)source).gameObject).name.ToLowerInvariant();
			string text2 = (((Object)(object)source.clip != (Object)null) ? ((Object)source.clip).name.ToLowerInvariant() : "");
			if ((Object)(object)_battleClip != (Object)null && (Object)(object)source.clip == (Object)(object)_battleClip)
			{
				return false;
			}
			if ((Object)(object)source.clip != (Object)null && source.clip.length < 8f)
			{
				return false;
			}
			return text.Contains("music") || text.Contains("musicman") || text.Contains("audio_mus") || text2.Contains("music") || text2.Contains("theme") || text2.Contains("boss") || text2.Contains("battle") || text2.Contains("combat") || text2.Contains("eikthyr") || text2.Contains("eiktyr") || text2.Contains("elder") || text2.Contains("bonemass") || text2.Contains("moder") || text2.Contains("yagluth") || text2.Contains("queen") || text2.Contains("fader");
		}

		private void RestoreVanillaMusic()
		{
			foreach (KeyValuePair<AudioSource, SavedAudioState> savedMusicSource in _savedMusicSources)
			{
				AudioSource key = savedMusicSource.Key;
				if (!((Object)(object)key == (Object)null))
				{
					key.volume = savedMusicSource.Value.Volume;
					key.mute = savedMusicSource.Value.Mute;
				}
			}
			_savedMusicSources.Clear();
			try
			{
				if ((Object)(object)MusicMan.instance != (Object)null)
				{
					MusicMan.instance.Reset();
				}
			}
			catch
			{
			}
		}
	}
	[HarmonyPatch(typeof(Game), "Start")]
	internal static class Game_IntroStoryChangerPatch
	{
		private static void Postfix()
		{
			IntroStoryChanger.EnsureInstance();
		}
	}
	[HarmonyPatch]
	internal static class TextViewer_IntroStoryChanger_ShowTextPatch
	{
		private static IEnumerable<MethodBase> TargetMethods()
		{
			MethodInfo[] methods = typeof(TextViewer).GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			MethodInfo[] array = methods;
			foreach (MethodInfo method in array)
			{
				if (!(method == null) && method.Name == "ShowText")
				{
					yield return method;
				}
			}
		}

		private static void Prefix(object[] __args)
		{
			if (__args == null || __args.Length == 0)
			{
				return;
			}
			int num = -1;
			for (int i = 0; i < __args.Length; i++)
			{
				if (__args[i] is string text && IntroStoryChanger.LooksLikeVanillaIntroText(text))
				{
					num = i;
					break;
				}
			}
			if (num < 0)
			{
				return;
			}
			__args[num] = IntroStoryChanger.GetLocalizedIntroText();
			for (int j = 0; j < __args.Length; j++)
			{
				if (j != num && __args[j] is string text2 && IntroStoryChanger.LooksLikeIntroTopic(text2))
				{
					__args[j] = "";
				}
			}
			IntroStoryChanger.EnsureInstance();
			IntroStoryChanger.RequestStylePass();
			vikingoldrepublicthemePlugin.vikingoldrepublicthemeLogger.LogInfo((object)"[VOR Intro] TextViewer.ShowText interceptado. Historia reemplazada.");
		}

		private static void Postfix()
		{
			IntroStoryChanger.EnsureInstance();
			IntroStoryChanger.RequestStylePass();
		}
	}
	public class IntroStoryChanger : MonoBehaviour
	{
		public static IntroStoryChanger Instance;

		private static bool _stylePassRequested;

		private static TMP_FontAsset _starWarsIntroFont;

		private const bool UseSpanishIfDetected = true;

		private const bool UseCustomIntroFont = false;

		private const string StarWarsIntroFontAssetName = "starwars_intro_font";

		private const string CustomIntroTextEnglish = "EPISODE I\r\n\r\nTHE OLD REPUBLIC'S EDGE\r\n\r\nIn a distant age, beyond the known stars, an impossible war tore open the paths between worlds.\r\n\r\nThe network collapsed.\r\n\r\nThe jump failed.\r\n\r\nEntire fleets, lost warriors, and the remains of forgotten empires were cast through a fracture in the void. What should have been a route back to the stars became a fall without return.\r\n\r\nThe abyss did not lead to death.\r\n\r\nIt led to Valheim.\r\n\r\nIn this primitive world, beneath strange skies and ancient roots, fallen technology lies among forests, mountains, and ruins swallowed by the earth. The gods watch from mist and flame, while beasts claim the wreckage of a war that should never have reached these realms.\r\n\r\nYour memory has shattered.\r\n\r\nYour name, your past, and the banner beneath which you marched were lost in the great fracture. You do not know whether you were a soldier, an exile, a hunter, or a warlord. You only know that you still breathe.\r\n\r\nYou are not alone.\r\n\r\nOthers have been dragged into this green purgatory: souls from distant eras, bound by the same fate. Some will seek a path back to the stars. Others will raise new kingdoms upon the ashes of fallen worlds.\r\n\r\nNow you must rise.\r\n\r\nGather the fragments of your broken mind.\r\n\r\nMaster the force that still whispers within you.\r\n\r\nAnd decide whether Valheim shall become your prison...\r\n\r\nor the birth of a new Republic.";

		private const string CustomIntroTextSpanish = "EPISODIO I\r\n\r\nEL FILO DE LA ANTIGUA REPÚBLICA\r\n\r\nEn una era remota, más allá de las estrellas conocidas, una guerra imposible desgarró los caminos entre mundos.\r\n\r\nLa red colapsó.\r\n\r\nEl salto falló.\r\n\r\nFlotas enteras, guerreros perdidos y restos de imperios olvidados fueron arrojados a través de una fractura en el vacío. Lo que debía ser una ruta hacia las estrellas se convirtió en una caída sin retorno.\r\n\r\nEl abismo no condujo a la muerte.\r\n\r\nCondujo a Valheim.\r\n\r\nEn este mundo primitivo, bajo cielos extraños y raíces antiguas, la tecnología caída yace entre bosques, montañas y ruinas devoradas por la tierra. Los dioses observan desde la niebla y las llamas, mientras las bestias reclaman los restos de una guerra que nunca debió llegar a estos reinos.\r\n\r\nTu memoria se ha quebrado.\r\n\r\nTu nombre, tu pasado y la bandera bajo la que marchabas se perdieron en la gran fractura. No sabes si fuiste soldado, exiliado, cazador o señor de guerra. Solo sabes que aún respiras.\r\n\r\nNo estás solo.\r\n\r\nOtros han sido arrastrados hasta este purgatorio verde: almas de eras distintas, unidas por el mismo destino. Algunos buscarán regresar a las estrellas. Otros levantarán nuevos reinos sobre las cenizas de los mundos caídos.\r\n\r\nAhora debes ponerte en pie.\r\n\r\nReúne los fragmentos de tu mente.\r\n\r\nDomina la fuerza que aún susurra en tu interior.\r\n\r\nY decide si Valheim será tu prisión...\r\n\r\no el nacimiento de una nueva República.";

		public static void EnsureInstance()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			if (!((Object)(object)Instance != (Object)null))
			{
				GameObject val = new GameObject("VOR_IntroStoryChanger");
				Object.DontDestroyOnLoad((Object)(object)val);
				val.AddComponent<IntroStoryChanger>();
			}
		}

		public static void RequestStylePass()
		{
			EnsureInstance();
			if (!((Object)(object)Instance == (Object)null) && !_stylePassRequested)
			{
				_stylePassRequested = true;
				((MonoBehaviour)Instance).StartCoroutine(Instance.ApplyStyleAndFallbackRepeatedly());
			}
		}

		private void Awake()
		{
			Instance = this;
		}

		private void OnDestroy()
		{
			if ((Object)(object)Instance == (Object)(object)this)
			{
				Instance = null;
			}
		}

		public static string GetLocalizedIntroText()
		{
			bool flag = false;
			string currentLanguageSafe = GetCurrentLanguageSafe();
			if (currentLanguageSafe.Contains("spanish") || currentLanguageSafe.Contains("español") || currentLanguageSafe.Contains("espanol") || currentLanguageSafe.Contains("castellano") || currentLanguageSafe == "es")
			{
				return "EPISODIO I\r\n\r\nEL FILO DE LA ANTIGUA REPÚBLICA\r\n\r\nEn una era remota, más allá de las estrellas conocidas, una guerra imposible desgarró los caminos entre mundos.\r\n\r\nLa red colapsó.\r\n\r\nEl salto falló.\r\n\r\nFlotas enteras, guerreros perdidos y restos de imperios olvidados fueron arrojados a través de una fractura en el vacío. Lo que debía ser una ruta hacia las estrellas se convirtió en una caída sin retorno.\r\n\r\nEl abismo no condujo a la muerte.\r\n\r\nCondujo a Valheim.\r\n\r\nEn este mundo primitivo, bajo cielos extraños y raíces antiguas, la tecnología caída yace entre bosques, montañas y ruinas devoradas por la tierra. Los dioses observan desde la niebla y las llamas, mientras las bestias reclaman los restos de una guerra que nunca debió llegar a estos reinos.\r\n\r\nTu memoria se ha quebrado.\r\n\r\nTu nombre, tu pasado y la bandera bajo la que marchabas se perdieron en la gran fractura. No sabes si fuiste soldado, exiliado, cazador o señor de guerra. Solo sabes que aún respiras.\r\n\r\nNo estás solo.\r\n\r\nOtros han sido arrastrados hasta este purgatorio verde: almas de eras distintas, unidas por el mismo destino. Algunos buscarán regresar a las estrellas. Otros levantarán nuevos reinos sobre las cenizas de los mundos caídos.\r\n\r\nAhora debes ponerte en pie.\r\n\r\nReúne los fragmentos de tu mente.\r\n\r\nDomina la fuerza que aún susurra en tu interior.\r\n\r\nY decide si Valheim será tu prisión...\r\n\r\no el nacimiento de una nueva República.";
			}
			return "EPISODE I\r\n\r\nTHE OLD REPUBLIC'S EDGE\r\n\r\nIn a distant age, beyond the known stars, an impossible war tore open the paths between worlds.\r\n\r\nThe network collapsed.\r\n\r\nThe jump failed.\r\n\r\nEntire fleets, lost warriors, and the remains of forgotten empires were cast through a fracture in the void. What should have been a route back to the stars became a fall without return.\r\n\r\nThe abyss did not lead to death.\r\n\r\nIt led to Valheim.\r\n\r\nIn this primitive world, beneath strange skies and ancient roots, fallen technology lies among forests, mountains, and ruins swallowed by the earth. The gods watch from mist and flame, while beasts claim the wreckage of a war that should never have reached these realms.\r\n\r\nYour memory has shattered.\r\n\r\nYour name, your past, and the banner beneath which you marched were lost in the great fracture. You do not know whether you were a soldier, an exile, a hunter, or a warlord. You only know that you still breathe.\r\n\r\nYou are not alone.\r\n\r\nOthers have been dragged into this green purgatory: souls from distant eras, bound by the same fate. Some will seek a path back to the stars. Others will raise new kingdoms upon the ashes of fallen worlds.\r\n\r\nNow you must rise.\r\n\r\nGather the fragments of your broken mind.\r\n\r\nMaster the force that still whispers within you.\r\n\r\nAnd decide whether Valheim shall become your prison...\r\n\r\nor the birth of a new Republic.";
		}

		private static string GetCurrentLanguageSafe()
		{
			try
			{
				if (Localization.instance == null)
				{
					return "";
				}
				string selectedLanguage = Localization.instance.GetSelectedLanguage();
				return (selectedLanguage != null) ? selectedLanguage.ToLowerInvariant() : "";
			}
			catch
			{
				return "";
			}
		}

		public static bool LooksLikeIntroTopic(string text)
		{
			if (string.IsNullOrWhiteSpace(text))
			{
				return false;
			}
			string text2 = text.ToLowerInvariant();
			return text2.Contains("you died") || text2.Contains("has muerto") || text2.Contains("moriste") || text2.Contains("$menu_you_died");
		}

		public static bool LooksLikeVanillaIntroText(string text)
		{
			if (string.IsNullOrWhiteSpace(text))
			{
				return false;
			}
			string text2 = text.ToLowerInvariant();
			bool flag = text2.Contains("odin") || text2.Contains("odín") || text2.Contains("allfather") || text2.Contains("padre todopoderoso") || text2.Contains("valkyries") || text2.Contains("valquirias");
			bool flag2 = text2.Contains("valheim") || text2.Contains("tenth world") || text2.Contains("décimo mundo") || text2.Contains("decimo mundo") || text2.Contains("world-tree") || text2.Contains("árbol del mundo") || text2.Contains("arbol del mundo");
			bool flag3 = text2.Contains("long ago") || text2.Contains("hace mucho tiempo") || text2.Contains("for centuries") || text2.Contains("durante siglos") || text2.Contains("exile") || text2.Contains("exilio") || text2.Contains("renacerían") || text2.Contains("renacerian") || text2.Contains("would be born again");
			return flag && flag2 && flag3;
		}

		private IEnumerator ApplyStyleAndFallbackRepeatedly()
		{
			for (int i = 0; i < 70; i++)
			{
				ApplyStyleAndFallbackToVisibleIntro();
				yield return (object)new WaitForSecondsRealtime(0.2f);
			}
			_stylePassRequested = false;
		}

		private void ApplyStyleAndFallbackToVisibleIntro()
		{
			TMP_Text[] array = Resources.FindObjectsOfTypeAll<TMP_Text>();
			TMP_Text[] array2 = array;
			foreach (TMP_Text val in array2)
			{
				if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).gameObject == (Object)null)
				{
					continue;
				}
				string text = val.text ?? "";
				Transform root = val.transform.root;
				string text2 = ((Object)((Component)val).gameObject).name.ToLowerInvariant();
				string text3 = (((Object)(object)val.transform.parent != (Object)null) ? ((Object)val.transform.parent).name.ToLowerInvariant() : "");
				string text4 = (((Object)(object)root != (Object)null) ? ((Object)root).name.ToLowerInvariant() : "");
				if ((text4.Contains("textroot_intro") || text3.Contains("crawl") || text3.Contains("textroot_intro") || text2 == "text") && LooksLikeIntroTopic(text))
				{
					val.text = "";
					continue;
				}
				if (LooksLikeVanillaIntroText(text))
				{
					val.text = GetLocalizedIntroText();
					text = val.text;
					vikingoldrepublicthemePlugin.vikingoldrepublicthemeLogger.LogInfo((object)"[VOR Intro] Texto vanilla visible reemplazado por fallback.");
				}
				if (text.Contains("EPISODIO I") || text.Contains("EPISODE I") || text.Contains("EL FILO DE LA ANTIGUA REPÚBLICA") || text.Contains("THE OLD REPUBLIC'S EDGE"))
				{
					ApplyFlatIntroStyle(val);
					DisableVanillaIntroAnimator(root);
					ConfigureFlatScroll(val);
				}
			}
		}

		private static TMP_FontAsset GetStarWarsIntroFont()
		{
			if ((Object)(object)_starWarsIntroFont != (Object)null)
			{
				return _starWarsIntroFont;
			}
			if ((Object)(object)vikingoldrepublicthemePlugin.ThemeBundle == (Object)null)
			{
				return null;
			}
			_starWarsIntroFont = vikingoldrepublicthemePlugin.ThemeBundle.LoadAsset<TMP_FontAsset>("starwars_intro_font");
			if ((Object)(object)_starWarsIntroFont == (Object)null)
			{
				vikingoldrepublicthemePlugin.vikingoldrepublicthemeLogger.LogWarning((object)"[VOR Intro] No encontré el TMP Font Asset 'starwars_intro_font' en starthemes. Usaré la fuente vanilla.");
			}
			else
			{
				try
				{
					_starWarsIntroFont.atlasPopulationMode = (AtlasPopulationMode)1;
				}
				catch
				{
				}
				vikingoldrepublicthemePlugin.vikingoldrepublicthemeLogger.LogInfo((object)("[VOR Intro] Fuente custom cargada: " + ((Object)_starWarsIntroFont).name));
			}
			return _starWarsIntroFont;
		}

		private void ApplyFlatIntroStyle(TMP_Text text)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: 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_0158: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)text == (Object)null))
			{
				bool flag = false;
				Color color = default(Color);
				((Color)(ref color))..ctor(1f, 0.82f, 0.05f, 1f);
				((Graphic)text).color = color;
				text.fontSize = 23f;
				text.enableWordWrapping = true;
				text.overflowMode = (TextOverflowModes)0;
				text.alignment = (TextAlignmentOptions)258;
				text.fontStyle = (FontStyles)0;
				text.characterSpacing = 0f;
				text.wordSpacing = 0.8f;
				text.lineSpacing = 5f;
				text.margin = new Vector4(35f, 0f, 35f, 0f);
				text.outlineColor = Color32.op_Implicit(new Color(0.75f, 0.35f, 0.02f, 1f));
				text.outlineWidth = 0.02f;
				RectTransform component = ((Component)text).GetComponent<RectTransform>();
				if ((Object)(object)component != (Object)null)
				{
					component.anchorMin = new Vector2(0.5f, 0.5f);
					component.anchorMax = new Vector2(0.5f, 0.5f);
					component.pivot = new Vector2(0.5f, 1f);
					component.sizeDelta = new Vector2(850f, 6200f);
					((Transform)component).localScale = Vector3.one;
					((Transform)component).localRotation = Quaternion.identity;
				}
				text.ForceMeshUpdate(true, true);
			}
		}

		private void DisableVanillaIntroAnimator(Transform root)
		{
			//IL_007f: 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_00a3: 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_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: 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)
			if ((Object)(object)root == (Object)null)
			{
				return;
			}
			Animator val = ((Component)root).GetComponent<Animator>();
			if ((Object)(object)val == (Object)null)
			{
				val = ((Component)root).GetComponentInChildren<Animator>(true);
			}
			if ((Object)(object)val != (Object)null)
			{
				((Behaviour)val).enabled = false;
			}
			Transform val2 = FindChildByName(root, "Crawl");
			if ((Object)(object)val2 != (Object)null)
			{
				RectTransform component = ((Component)val2).GetComponent<RectTransform>();
				if ((Object)(object)component != (Object)null)
				{
					((Transform)component).localRotation = Quaternion.identity;
					((Transform)component).localScale = Vector3.one;
					component.anchorMin = new Vector2(0.5f, 0.5f);
					component.anchorMax = new Vector2(0.5f, 0.5f);
					component.pivot = new Vector2(0.5f, 0.5f);
					component.sizeDelta = new Vector2(1200f, 6600f);
					component.anchoredPosition = Vector2.zero;
				}
			}
		}

		private void ConfigureFlatScroll(TMP_Text text)
		{
			if ((Object)(object)text == (Object)null)
			{
				return;
			}
			RectTransform component = ((Component)text).GetComponent<RectTransform>();
			if (!((Object)(object)component == (Object)null))
			{
				VORFlatIntroScrollMotion vORFlatIntroScrollMotion = ((Component)component).gameObject.GetComponent<VORFlatIntroScrollMotion>();
				if ((Object)(object)vORFlatIntroScrollMotion == (Object)null)
				{
					vORFlatIntroScrollMotion = ((Component)component).gameObject.AddComponent<VORFlatIntroScrollMotion>();
				}
				vORFlatIntroScrollMotion.Configure(component, -350f, 5600f, 170f);
			}
		}

		private Transform FindChildByName(Transform root, string childName)
		{
			if ((Object)(object)root == (Object)null || string.IsNullOrWhiteSpace(childName))
			{
				return null;
			}
			Transform[] componentsInChildren = ((Component)root).GetComponentsInChildren<Transform>(true);
			Transform[] array = componentsInChildren;
			foreach (Transform val in array)
			{
				if ((Object)(object)val != (Object)null && ((Object)val).name.Equals(childName, StringComparison.OrdinalIgnoreCase))
				{
					return val;
				}
			}
			return null;
		}
	}
	public class VORFlatIntroScrollMotion : MonoBehaviour
	{
		private RectTransform _target;

		private float _startTime;

		private float _duration;

		private float _startY;

		private float _endY;

		private bool _configured;

		public void Configure(RectTransform target, float startY, float endY, float duration)
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			if (!_configured && !((Object)(object)target == (Object)null))
			{
				_target = target;
				_startY = startY;
				_endY = endY;
				_duration = duration;
				_startTime = Time.unscaledTime;
				_configured = true;
				Vector2 anchoredPosition = _target.anchoredPosition;
				anchoredPosition.x = 0f;
				anchoredPosition.y = _startY;
				_target.anchoredPosition = anchoredPosition;
			}
		}

		private void Update()
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			if (_configured && !((Object)(object)_target == (Object)null))
			{
				float num = Mathf.Clamp01((Time.unscaledTime - _startTime) / _duration);
				Vector2 anchoredPosition = _target.anchoredPosition;
				anchoredPosition.x = 0f;
				anchoredPosition.y = Mathf.Lerp(_startY, _endY, num);
				_target.anchoredPosition = anchoredPosition;
			}
		}
	}
	internal static class VORMeadowsMusicState
	{
		public static bool ForceMeadowsMusicActive;
	}
	[HarmonyPatch(typeof(Player), "Awake")]
	internal static class Player_MeadowsMusicControllerPatch
	{
		private static void Postfix(Player __instance)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			if (!((Object)(object)VORMeadowsMusicController.Instance != (Object)null))
			{
				GameObject val = new GameObject("VOR_MeadowsMusicController");
				Object.DontDestroyOnLoad((Object)(object)val);
				val.AddComponent<VORMeadowsMusicController>();
			}
		}
	}
	[HarmonyPatch]
	internal static class MusicMan_BlockMeadowsLocationMusicPatch
	{
		private static IEnumerable<MethodBase> TargetMethods()
		{
			MethodInfo[] methods = typeof(MusicMan).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			MethodInfo[] array = methods;
			foreach (MethodInfo method in array)
			{
				if (!(method == null))
				{
					string name = method.Name.ToLowerInvariant();
					if (name.Contains("triggermusic") || name.Contains("updatemusic") || name.Contains("startmusic") || name.Contains("playmusic"))
					{
						yield return method;
					}
				}
			}
		}

		private static bool Prefix()
		{
			return !VORMeadowsMusicState.ForceMeadowsMusicActive;
		}
	}
	public class VORMeadowsMusicController : MonoBehaviour
	{
		private struct SavedAudioState
		{
			public float Volume;

			public bool Mute;
		}

		public static VORMeadowsMusicController Instance;

		private const string MeadowsThemeAssetName = "MeadowsTheme";

		private const float CheckInterval = 0.35f;

		private const float SilenceInterval = 0.25f;

		private const float MeadowsVolume = 0.65f;

		private const float FadeSpeed = 0.65f;

		private AudioSource _meadowsSource;

		private AudioClip _meadowsClip;

		private float _nextCheckTime;

		private float _nextSilenceTime;

		private float _targetVolume;

		private bool _isInMeadows;

		private bool _isStopping;

		private readonly Dictionary<AudioSource, SavedAudioState> _savedMusicSources = new Dictionary<AudioSource, SavedAudioState>();

		private IEnumerator Start()
		{
			Instance = this;
			yield return (object)new WaitForSeconds(1f);
			LoadMeadowsTheme();
			CreateAudioSource();
		}

		private void OnDestroy()
		{
			VORMeadowsMusicState.ForceMeadowsMusicActive = false;
			RestoreVanillaMusic();
			if ((Object)(object)Instance == (Object)(object)this)
			{
				Instance = null;
			}
		}

		private void LoadMeadowsTheme()
		{
			if ((Object)(object)vikingoldrepublicthemePlugin.ThemeBundle == (Object)null)
			{
				vikingoldrepublicthemePlugin.vikingoldrepublicthemeLogger.LogWarning((object)"[VOR Meadows Music] ThemeBundle es null. No puedo cargar MeadowsTheme.");
				return;
			}
			_meadowsClip = vikingoldrepublicthemePlugin.ThemeBundle.LoadAsset<AudioClip>("MeadowsTheme");
			if ((Object)(object)_meadowsClip == (Object)null)
			{
				vikingoldrepublicthemePlugin.vikingoldrepublicthemeLogger.LogWarning((object)"[VOR Meadows Music] No encontré el AudioClip 'MeadowsTheme' en el AssetBundle 'starthemes'.");
			}
			else
			{
				vikingoldrepublicthemePlugin.vikingoldrepublicthemeLogger.LogInfo((object)("[VOR Meadows Music] Música de Meadows cargada: " + ((Object)_meadowsClip).name));
			}
		}

		private void CreateAudioSource()
		{
			_meadowsSource = ((Component)this).gameObject.AddComponent<AudioSource>();
			_meadowsSource.playOnAwake = false;
			_meadowsSource.loop = true;
			_meadowsSource.spatialBlend = 0f;
			_meadowsSource.volume = 0f;
			_meadowsSource.priority = 25;
			_meadowsSource.bypassListenerEffects = true;
			_meadowsSource.bypassReverbZones = true;
		}

		private void Update()
		{
			if ((Object)(object)_meadowsClip == (Object)null || (Object)(object)_meadowsSource == (Object)null)
			{
				return;
			}
			if (Time.time >= _nextCheckTime)
			{
				_nextCheckTime = Time.time + 0.35f;
				bool flag = IsLocalPlayerInMeadows() && !IsCustomBossMusicActive();
				if (flag && !_isInMeadows)
				{
					StartMeadowsMusic();
				}
				else if (!flag && _isInMeadows)
				{
					StopMeadowsMusic();
				}
				_isInMeadows = flag;
			}
			if (_isInMeadows && Time.time >= _nextSilenceTime)
			{
				_nextSilenceTime = Time.time + 0.25f;
				SilenceVanillaMusicAggressively();
			}
			UpdateFade();
		}

		private bool IsLocalPlayerInMeadows()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Invalid comparison between Unknown and I4
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return false;
			}
			Biome val = Heightmap.FindBiome(((Component)localPlayer).transform.position);
			return (int)val == 1;
		}

		private bool IsCustomBossMusicActive()
		{
			Type type = Type.GetType("vikingoldrepublictheme.VORBossMusicState");
			if (type == null)
			{
				return false;
			}
			FieldInfo field = type.GetField("CustomBossMusicActive", BindingFlags.Static | BindingFlags.Public);
			if (field == null)
			{
				return false;
			}
			object value = field.GetValue(null);
			bool flag = default(bool);
			int num;
			if (value is bool)
			{
				flag = (bool)value;
				num = 1;
			}
			else
			{
				num = 0;
			}
			return (byte)((uint)num & (flag ? 1u : 0u)) != 0;
		}

		private void StartMeadowsMusic()
		{
			if (!((Object)(object)_meadowsSource == (Object)null) && !((Object)(object)_meadowsClip == (Object)null))
			{
				VORMeadowsMusicState.ForceMeadowsMusicActive = true;
				SilenceVanillaMusicAggressively();
				_meadowsSource.clip = _meadowsClip;
				_meadowsSource.loop = true;
				if (!_meadowsSource.isPlaying)
				{
					_meadowsSource.volume = 0f;
					_meadowsSource.Play();
				}
				_targetVolume = 0.65f;
				_isStopping = false;
				vikingoldrepublicthemePlugin.vikingoldrepublicthemeLogger.LogInfo((object)"[VOR Meadows Music] Entraste a Meadows. Forzando MeadowsTheme.");
			}
		}

		private void StopMeadowsMusic()
		{
			_targetVolume = 0f;
			_isStopping = true;
			VORMeadowsMusicState.ForceMeadowsMusicActive = false;
			vikingoldrepublicthemePlugin.vikingoldrepublicthemeLogger.LogInfo((object)"[VOR Meadows Music] Saliste de Meadows o entró música de boss. Deteniendo MeadowsTheme.");
		}

		private void UpdateFade()
		{
			if (!((Object)(object)_meadowsSource == (Object)null))
			{
				_meadowsSource.volume = Mathf.MoveTowards(_meadowsSource.volume, _targetVolume, 0.65f * Time.deltaTime);
				if (_isStopping && _meadowsSource.volume <= 0.01f)
				{
					_meadowsSource.Stop();
					_meadowsSource.time = 0f;
					_isStopping = false;
					RestoreVanillaMusic();
				}
			}
		}

		private void SilenceVanillaMusicAggressively()
		{
			MusicMan instance = MusicMan.instance;
			if ((Object)(object)instance != (Object)null)
			{
				AudioSource[] componentsInChildren = ((Component)instance).GetComponentsInChildren<AudioSource>(true);
				AudioSource[] array = componentsInChildren;
				foreach (AudioSource source in array)
				{
					SilenceSource(source);
				}
			}
			AudioSource[] array2 = Object.FindObjectsOfType<AudioSource>(true);
			AudioSource[] array3 = array2;
			foreach (AudioSource val in array3)
			{
				if (!((Object)(object)val == (Object)null) && !((Object)(object)val == (Object)(object)_meadowsSource) && !((Object)(object)val.clip == (Object)null) && !((Object)(object)val.clip == (Object)(object)_meadowsClip) && !((Object)((Component)val).gameObject).name.StartsWith("VOR_") && LooksLikeMusicSource(val))
				{
					SilenceSource(val);
				}
			}
		}

		private void SilenceSource(AudioSource source)
		{
			if (!((Object)(object)source == (Object)null) && !((Object)(object)source == (Object)(object)_meadowsSource))
			{
				if (!_savedMusicSources.ContainsKey(source))
				{
					_savedMusicSources[source] = new SavedAudioState
					{
						Volume = source.volume,
						Mute = source.mute
					};
				}
				source.Stop();
				source.volume = 0f;
				source.mute = true;
			}
		}

		private bool LooksLikeMusicSource(AudioSource source)
		{
			if ((Object)(object)source == (Object)null)
			{
				return false;
			}
			string text = ((Object)((Component)source).gameObject).name.ToLowerInvariant();
			string text2 = (((Object)(object)source.clip != (Object)null) ? ((Object)source.clip).name.ToLowerInvariant() : "");
			if ((Object)(object)source.clip != (Object)null && source.clip.length < 8f)
			{
				return false;
			}
			return text.Contains("music") || text.Contains("musicman") || text.Contains("audio_mus") || text2.Contains("music") || text2.Contains("theme") || text2.Contains("meadow") || text2.Contains("location") || text2.Contains("forest") || text2.Contains("crypt") || text2.Contains("dungeon") || text2.Contains("combat") || text2.Contains("battle");
		}

		private void RestoreVanillaMusic()
		{
			foreach (KeyValuePair<AudioSource, SavedAudioState> savedMusicSource in _savedMusicSources)
			{
				AudioSource key = savedMusicSource.Key;
				if (!((Object)(object)key == (Object)null))
				{
					key.volume = savedMusicSource.Value.Volume;
					key.mute = savedMusicSource.Value.Mute;
				}
			}
			_savedMusicSources.Clear();
			try
			{
				if ((Object)(object)MusicMan.instance != (Object)null)
				{
					MusicMan.instance.Reset();
				}
			}
			catch
			{
			}
		}
	}
	[HarmonyPatch(typeof(FejdStartup), "SetupGui")]
	internal static class FejdStartup_MenuCameraChanger_SetupGuiPatch
	{
		private static void Postfix(FejdStartup __instance)
		{
			if (!((Object)(object)__instance == (Object)null))
			{
				MenuCameraChanger component = ((Component)__instance).gameObject.GetComponent<MenuCameraChanger>();
				if ((Object)(object)component == (Object)null)
				{
					component = ((Component)__instance).gameObject.AddComponent<MenuCameraChanger>();
				}
			}
		}
	}
	[HarmonyPatch(typeof(FejdStartup), "ShowCharacterSelection")]
	internal static class FejdStartup_MenuCameraChanger_ShowCharacterSelectionPatch
	{
		private static void Postfix(FejdStartup __instance)
		{
			if (!((Object)(object)__instance == (Object)null))
			{
				MenuCameraChanger component = ((Component)__instance).gameObject.GetComponent<MenuCameraChanger>();
				if ((Object)(object)component != (Object)null)
				{
					component.ApplyCharacterSelectionView();
				}
			}
		}
	}
	[HarmonyPatch(typeof(FejdStartup), "OnCharacterStart")]
	internal static class FejdStartup_MenuCameraChanger_OnCharacterStartPatch
	{
		private static void Prefix(FejdStartup __instance)
		{
			if (!((Object)(object)__instance == (Object)null))
			{
				MenuCameraChanger component = ((Component)__instance).gameObject.GetComponent<MenuCameraChanger>();
				if ((Object)(object)component != (Object)null)
				{
					component.ApplyCharacterSelectionView();
				}
			}
		}
	}
	public class MenuCameraChanger : MonoBehaviour
	{
		private bool _mainApplied;

		private GameObject _fireClone;

		private static readonly Vector3 MainCameraPosition = new Vector3(-208.54f, 32.2f, 131.38f);

		private static readonly Vector3 MainCameraRotation = new Vector3(0.72f, -211f, 0f);

		private static readonly Vector3 CharacterCameraPosition = new Vector3(-206.2f, 39.34f, 162.26f);

		private static readonly Vector3 CharacterCameraRotation = new Vector3(19.6f, -211f, 0f);

		private static readonly Vector3 CharacterPreviewPosition = new Vector3(-204.51f, 36.5f, 157.53f);

		private static readonly Vector3 FirePosition = new Vector3(-203.51f, 36.5f, 158.53f);

		private IEnumerator Start()
		{
			yield return (object)new WaitForSeconds(1f);
			ApplyMainMenuView();
			yield return (object)new WaitForSeconds(0.5f);
			EnsureMenuFire();
		}

		public void ApplyMainMenuView()
		{
			//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_0048: 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_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//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_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			if (!_mainApplied && !((Object)(object)FejdStartup.instance == (Object)null))
			{
				FejdStartup instance = FejdStartup.instance;
				SetMarker(instance.m_cameraMarkerMain, MainCameraPosition, MainCameraRotation);
				SetMarker(instance.m_cameraMarkerStart, MainCameraPosition, MainCameraRotation);
				SetMarker(instance.m_cameraMarkerGame, MainCameraPosition, MainCameraRotation);
				SetMarker(instance.m_cameraMarkerSaves, MainCameraPosition, MainCameraRotation);
				SetMarker(instance.m_cameraMarkerCredits, MainCameraPosition, MainCameraRotation);
				SetMarker(instance.m_cameraMarkerCharacter, CharacterCameraPosition, CharacterCameraRotation);
				ApplyCharacterPreviewPosition(instance);
				EnsureMenuFire();
				_mainApplied = true;
				vikingoldrepublicthemePlugin.vikingoldrepublicthemeLogger.LogInfo((object)"[VOR Camera] Vista principal aplicada.");
			}
		}

		public void ApplyCharacterSelectionView()
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)FejdStartup.instance == (Object)null))
			{
				FejdStartup instance = FejdStartup.instance;
				SetMarker(instance.m_cameraMarkerCharacter, CharacterCameraPosition, CharacterCameraRotation);
				ApplyCharacterPreviewPosition(instance);
				EnsureMenuFire();
				vikingoldrepublicthemePlugin.vikingoldrepublicthemeLogger.LogInfo((object)"[VOR Camera] Vista de personaje aplicada.");
			}
		}

		private void ApplyCharacterPreviewPosition(FejdStartup startup)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: 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)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)startup == (Object)null))
			{
				Quaternion facingCameraRotation = GetFacingCameraRotation();
				if ((Object)(object)startup.m_characterPreviewPoint != (Object)null)
				{
					startup.m_characterPreviewPoint.position = CharacterPreviewPosition;
					startup.m_characterPreviewPoint.rotation = facingCameraRotation;
				}
				if ((Object)(object)startup.m_playerInstance != (Object)null)
				{
					startup.m_playerInstance.transform.position = CharacterPreviewPosition;
					startup.m_playerInstance.transform.rotation = facingCameraRotation;
				}
			}
		}

		private Quaternion GetFacingCameraRotation()
		{
			//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_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: 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_0053: 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_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = CharacterCameraPosition - CharacterPreviewPosition;
			val.y = 0f;
			if (((Vector3)(ref val)).sqrMagnitude < 0.01f)
			{
				return Quaternion.Euler(0f, -31f, 0f);
			}
			return Quaternion.LookRotation(((Vector3)(ref val)).normalized, Vector3.up);
		}

		private void EnsureMenuFire()
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: 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)
			GameObject val = FindGameObjectIncludingInactive("MenuFire");
			if ((Object)(object)val == (Object)null && (Object)(object)_fireClone == (Object)null)
			{
				vikingoldrepublicthemePlugin.vikingoldrepublicthemeLogger.LogWarning((object)"[VOR Camera] No encontré MenuFire para mover o clonar.");
				return;
			}
			if ((Object)(object)_fireClone == (Object)null && (Object)(object)val != (Object)null)
			{
				_fireClone = Object.Instantiate<GameObject>(val, FirePosition, Quaternion.identity);
				((Object)_fireClone).name = "VOR_MenuFire_Clone";
			}
			if ((Object)(object)val != (Object)null)
			{
				val.SetActive(true);
				val.transform.position = FirePosition;
			}
			if ((Object)(object)_fireClone != (Object)null)
			{
				_fireClone.SetActive(true);
				_fireClone.transform.position = FirePosition;
			}
		}

		private GameObject FindGameObjectIncludingInactive(string objectName)
		{
			GameObject val = GameObject.Find(objectName);
			if ((Object)(object)val != (Object)null)
			{
				return val;
			}
			GameObject[] array = Resources.FindObjectsOfTypeAll<GameObject>();
			GameObject[] array2 = array;
			foreach (GameObject val2 in array2)
			{
				if (!((Object)(object)val2 == (Object)null) && ((Object)val2).name == objectName)
				{
					return val2;
				}
			}
			return null;
		}

		private void SetMarker(Transform marker, Vector3 position, Vector3 rotationEuler)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)marker == (Object)null))
			{
				marker.position = position;
				marker.rotation = Quaternion.Euler(rotationEuler);
			}
		}
	}
	[HarmonyPatch(typeof(FejdStartup), "Awake")]
	public static class FejdStartup_MenuLogoPatch
	{
		private static void Postfix(FejdStartup __instance)
		{
			if (!((Object)(object)__instance == (Object)null))
			{
				MenuLogoController component = ((Component)__instance).gameObject.GetComponent<MenuLogoController>();
				if ((Object)(object)component == (Object)null)
				{
					component = ((Component)__instance).gameObject.AddComponent<MenuLogoController>();
				}
			}
		}
	}
	public class MenuLogoController : MonoBehaviour
	{
		private const string LogoAssetName = "starwars_logo";

		private Sprite _customLogoSprite;

		private bool _applied;

		private IEnumerator Start()
		{
			for (int i = 0; i < 40; i++)
			{
				if (TryApplyLogo())
				{
					yield break;
				}
				yield return (object)new WaitForSeconds(0.25f);
			}
			vikingoldrepublicthemePlugin.vikingoldrepublicthemeLogger.LogWarning((object)"[VOR Theme Logo] No pude encontrar el logo de Valheim para reemplazarlo.");
		}

		private bool TryApplyLogo()
		{
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: 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_00ea: Unknown result type (might be due to invalid IL or missing references)
			if (_applied)
			{
				return true;
			}
			Sprite val = LoadLogoSprite();
			if ((Object)(object)val == (Object)null)
			{
				return true;
			}
			Image val2 = FindValheimLogoImage();
			if ((Object)(object)val2 == (Object)null)
			{
				return false;
			}
			val2.sprite = val;
			val2.overrideSprite = val;
			val2.preserveAspect = true;
			((Graphic)val2).color = Color.white;
			RectTransform component = ((Component)val2).GetComponent<RectTransform>();
			if ((Object)(object)component != (Object)null)
			{
				component.anchorMin = new Vector2(0.5f, 1f);
				component.anchorMax = new Vector2(0.5f, 1f);
				component.pivot = new Vector2(0.5f, 1f);
				component.anchoredPosition = new Vector2(0f, -85f);
				component.sizeDelta = new Vector2(1400f, 310f);
			}
			_applied = true;
			vikingoldrepublicthemePlugin.vikingoldrepublicthemeLogger.LogInfo((object)("[VOR Theme Logo] Logo reemplazado correctamente en: " + ((Object)((Component)val2).gameObject).name));
			return true;
		}

		private Sprite LoadLogoSprite()
		{
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_customLogoSprite != (Object)null)
			{
				return _customLogoSprite;
			}
			if ((Object)(object)vikingoldrepublicthemePlugin.ThemeBundle == (Object)null)
			{
				vikingoldrepublicthemePlugin.vikingoldrepublicthemeLogger.LogWarning((object)"[VOR Theme Logo] ThemeBundle es null. No se puede cargar el logo.");
				return null;
			}
			Sprite val = vikingoldrepublicthemePlugin.ThemeBundle.LoadAsset<Sprite>("starwars_logo");
			if ((Object)(object)val != (Object)null)
			{
				_customLogoSprite = val;
				vikingoldrepublicthemePlugin.vikingoldrepublicthemeLogger.LogInfo((object)"[VOR Theme Logo] Logo cargado como Sprite desde el AssetBundle.");
				return _customLogoSprite;
			}
			Texture2D val2 = vikingoldrepublicthemePlugin.ThemeBundle.LoadAsset<Texture2D>("starwars_logo");
			if ((Object)(object)val2 == (Object)null)
			{
				vikingoldrepublicthemePlugin.vikingoldrepublicthemeLogger.LogWarning((object)"[VOR Theme Logo] No encontré el asset 'starwars_logo' en el AssetBundle 'starthemes'.");
				return null;
			}
			_customLogoSprite = Sprite.Create(val2, new Rect(0f, 0f, (float)((Texture)val2).width, (float)((Texture)val2).height), new Vector2(0.5f, 0.5f), 100f);
			((Object)_customLogoSprite).name = "VOR_StarWars_MenuLogo";
			vikingoldrepublicthemePlugin.vikingoldrepublicthemeLogger.LogInfo((object)"[VOR Theme Logo] Logo cargado como Texture2D y convertido a Sprite.");
			return _customLogoSprite;
		}

		private Image FindValheimLogoImage()
		{
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			Image[] array = Object.FindObjectsOfType<Image>(true);
			Image result = null;
			float num = 0f;
			Image[] array2 = array;
			foreach (Image val in array2)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				string text = ((Object)((Component)val).gameObject).name.ToLowerInvariant();
				string text2 = (((Object)(object)val.sprite != (Object)null) ? ((Object)val.sprite).name.ToLowerInvariant() : "");
				string text3 = (((Object)(object)val.sprite != (Object)null && (Object)(object)val.sprite.texture != (Object)null) ? ((Object)val.sprite.texture).name.ToLowerInvariant() : "");
				if (text.Contains("logo") || text.Contains("valheim") || text2.Contains("logo") || text2.Contains("valheim") || text3.Contains("logo") || text3.Contains("valheim"))
				{
					RectTransform component = ((Component)val).GetComponent<RectTransform>();
					float num2;
					if (!((Object)(object)component != (Object)null))
					{
						num2 = 1f;
					}
					else
					{
						Rect rect = component.rect;
						float width = ((Rect)(ref rect)).width;
						rect = component.rect;
						num2 = width * ((Rect)(ref rect)).height;
					}
					float num3 = num2;
					if (num3 > num)
					{
						num = num3;
						result = val;
					}
				}
			}
			return result;
		}
	}
	[HarmonyPatch(typeof(FejdStartup), "SetupGui")]
	internal static class FejdStartup_MenuNightOverridePatch
	{
		private static void Postfix(FejdStartup __instance)
		{
			if (!((Object)(object)__instance == (Object)null))
			{
				MenuNightOverride component = ((Component)__instance).gameObject.GetComponent<MenuNightOverride>();
				if ((Object)(object)component == (Object)null)
				{
					component = ((Component)__instance).gameObject.AddComponent<MenuNightOverride>();
				}
			}
		}
	}
	public class MenuNightOverride : MonoBehaviour
	{
		private bool _applied;

		private IEnumerator Start()
		{
			yield return (object)new WaitForSeconds(1.5f);
			ApplyNightLookOnce();
		}

		private void ApplyNightLookOnce()
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Invalid comparison between Unknown and I4
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			if (_applied)
			{
				return;
			}
			_applied = true;
			RenderSettings.fog = true;
			RenderSettings.fogColor = new Color(0.015f, 0.035f, 0.075f, 1f);
			RenderSettings.fogDensity = 0.01f;
			RenderSettings.ambientMode = (AmbientMode)3;
			RenderSettings.ambientLight = new Color(0.055f, 0.075f, 0.12f, 1f);
			RenderSettings.ambientIntensity = 0.65f;
			Light[] array = Object.FindObjectsOfType<Light>(true);
			Light[] array2 = array;
			foreach (Light val in array2)
			{
				if (!((Object)(object)val == (Object)null))
				{
					string text = ((Object)((Component)val).gameObject).name.ToLowerInvariant();
					if ((int)val.type == 1 || text.Contains("sun") || text.Contains("main light"))
					{
						val.intensity = Mathf.Min(val.intensity, 0.28f);
						val.color = new Color(0.48f, 0.58f, 0.82f, 1f);
					}
				}
			}
			vikingoldrepublicthemePlugin.vikingoldrepublicthemeLogger.LogInfo((object)"[VOR Night] Look nocturno aplicado una vez.");
		}
	}
	[HarmonyPatch(typeof(FejdStartup), "SetupGui")]
	internal static class FejdStartup_MenuScenarioCleanerPatch
	{
		private static void Postfix(FejdStartup __instance)
		{
			if (!((Object)(object)__instance == (Object)null))
			{
				MenuScenarioCleaner component = ((Component)__instance).gameObject.GetComponent<MenuScenarioCleaner>();
				if ((Object)(object)component == (Object)null)
				{
					component = ((Component)__instance).gameObject.AddComponent<MenuScenarioCleaner>();
				}
			}
		}
	}
	public class MenuScenarioCleaner : MonoBehaviour
	{
		private const bool HideVanillaShips = true;

		private const bool HideTreesAndVegetation = true;

		private IEnumerator Start()
		{
			for (int i = 0; i < 6; i++)
			{
				yield return (object)new WaitForSeconds(0.5f);
				CleanScenario();
			}
		}

		private void CleanScenario()
		{
			bool flag = true;
			HideVanillaMenuShips();
			bool flag2 = true;
			HideTreesVegetationAndForestProps();
		}

		private void HideVanillaMenuShips()
		{
			int num = 0;
			GameObject val = GameObject.Find("Static");
			if ((Object)(object)val != (Object)null)
			{
				num += HideChildrenByExactOrPartialName(val.transform, new string[6] { "ships", "ship", "boat", "karve", "viking_ship", "menu_ship" });
			}
			GameObject val2 = GameObject.Find("Backgroundscene");
			if ((Object)(object)val2 != (Object)null)
			{
				num += HideChildrenByExactOrPartialName(val2.transform, new string[6] { "ships", "ship", "boat", "karve", "viking_ship", "menu_ship" });
			}
			if (num > 0)
			{
				vikingoldrepublicthemePlugin.vikingoldrepublicthemeLogger.LogInfo((object)$"[VOR Scenario Cleaner] Barcos vanilla ocultados: {num}");
			}
		}

		private void HideTreesVegetationAndForestProps()
		{
			int num = 0;
			GameObject val = GameObject.Find("Static");
			if ((Object)(object)val != (Object)null)
			{
				num += HideChildrenByExactOrPartialName(val.transform, new string[9] { "tree", "trees", "forest", "fir", "pine", "beech", "bush", "shrub", "vegetation" });
			}
			GameObject val2 = GameObject.Find("Backgroundscene");
			if ((Object)(object)val2 != (Object)null)
			{
				num += HideChildrenByExactOrPartialName(val2.transform, new string[9] { "tree", "trees", "forest", "fir", "pine", "beech", "bush", "shrub", "vegetation" });
			}
			if (num > 0)
			{
				vikingoldrepublicthemePlugin.vikingoldrepublicthemeLogger.LogInfo((object)$"[VOR Scenario Cleaner] Árboles/vegetación ocultados: {num}");
			}
		}

		private int HideChildrenByExactOrPartialName(Transform root, string[] keywords)
		{
			if ((Object)(object)root == (Object)null || keywords == null)
			{
				return 0;
			}
			int num = 0;
			Transform[] componentsInChildren = ((Component)root).GetComponentsInChildren<Transform>(true);
			Transform[] array = componentsInChildren;
			foreach (Transform val in array)
			{
				if ((Object)(object)val == (Object)null || (Object)(object)val == (Object)(object)root)
				{
					continue;
				}
				GameObject gameObject = ((Component)val).gameObject;
				if ((Object)(object)gameObject == (Object)null)
				{
					continue;
				}
				string text = ((Object)gameObject).name.ToLowerInvariant();
				if (ShouldNeverHide(text))
				{
					continue;
				}
				foreach (string text2 in keywords)
				{
					if (string.IsNullOrWhiteSpace(text2))
					{
						continue;
					}
					string value = text2.ToLowerInvariant();
					if (text.Contains(value))
					{
						if (gameObject.activeSelf)
						{
							gameObject.SetActive(false);
							num++;
						}
						break;
					}
				}
			}
			return num;
		}

		private bool ShouldNeverHide(string objectName)
		{
			if (string.IsNullOrWhiteSpace(objectName))
			{
				return true;
			}
			return objectName.Contains("vor_") || objectName.Contains("starwars") || objectName.Contains("xwing") || objectName.Contains("tie") || objectName.Contains("menu_xwing") || objectName.Contains("menu_tie") || objectName.Contains("fire") || objectName.Contains("campfire") || objectName.Contains("bonfire") || objectName.Contains("menufire") || objectName.Contains("wood") || objectName.Contains("log") || objectName.Contains("ember") || objectName.Contains("flame") || objectName.Contains("smoke");
		}
	}
	[HarmonyPatch(typeof(FejdStartup), "SetupGui")]
	internal static class FejdStartup_MenuStarWarsChasePatch
	{
		private static void Postfix(FejdStartup __instance)
		{
			if (!((Object)(object)__instance == (Object)null))
			{
				MenuStarWarsChaseController component = ((Component)__instance).gameObject.GetComponent<MenuStarWarsChaseController>();
				if ((Object)(object)component == (Object)null)
				{
					component = ((Component)__instance).gameObject.AddComponent<MenuStarWarsChaseController>();
				}
			}
		}
	}
	public class MenuStarWarsChaseController : MonoBehaviour
	{
		private const string XWingPrefabName = "Menu_XWing_Visual";

		private const string TiePrefabName = "Menu_TIE_Visual";

		private const int TieCount = 3;

		private const float ChaseDuration = 7.2f;

		private const float PauseBetweenChases = 12f;

		private const float InitialDelay = 4f;

		private const float DistanceFromCamera = 30f;

		private const float StartHorizontal = -34f;

		private const float EndHorizontal = 40f;

		private const float VerticalOffset = 7.4f;

		private const float XWingScale = 0.24f;

		private const float TieScale = 0.23f;

		private const float BankAngle = 10f;

		private const float TieBoostVolume = 0.3f;

		private readonly float[] _tieLagOffsets = new float[3] { 5.8f, 9.8f, 14f };

		private readonly float[] _tieVerticalOffsets = new float[3] { -0.8f, 0.55f, -1.45f };

		private static readonly Vector3 XWingRotationOffset = new Vector3(0f, 0f, 0f);

		private static readonly Vector3 TieRotationOffset = new Vector3(0f, 0f, 0f);

		private GameObject _root;

		private GameObject _xWing;

		private readonly GameObject[] _ties = (GameObject[])(object)new GameObject[3];

		private float _timer;

		private bool _ready;

		private bool _wasInChase;

		private bool _warnedMissingTieAudio;

		private IEnumerator Start()
		{
			yield return (object)new WaitForSeconds(1.2f);
			SpawnChase();
		}

		private void SpawnChase()
		{
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Expected O, but got Unknown
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			if (_ready)
			{
				return;
			}
			if ((Object)(object)vikingoldrepublicthemePlugin.ThemeBundle == (Object)null)
			{
				vikingoldrepublicthemePlugin.vikingoldrepublicthemeLogger.LogWarning((object)"[VOR Menu Chase] ThemeBundle es null. No puedo cargar las naves.");
				return;
			}
			GameObject val = vikingoldrepublicthemePlugin.ThemeBundle.LoadAsset<GameObject>("Menu_XWing_Visual");
			GameObject val2 = vikingoldrepublicthemePlugin.ThemeBundle.LoadAsset<GameObject>("Menu_TIE_Visual");
			if ((Object)(object)val == (Object)null)
			{
				vikingoldrepublicthemePlugin.vikingoldrepublicthemeLogger.LogWarning((object)"[VOR Menu Chase] No encontré el prefab 'Menu_XWing_Visual' en starthemes.");
			}
			if ((Object)(object)val2 == (Object)null)
			{
				vikingoldrepublicthemePlugin.vikingoldrepublicthemeLogger.LogWarning((object)"[VOR Menu Chase] No encontré el prefab 'Menu_TIE_Visual' en starthemes.");
			}
			if (!((Object)(object)val == (Object)null) && !((Object)(object)val2 == (Object)null))
			{
				if ((Object)(object)_root != (Object)null)
				{
					Object.Destroy((Object)(object)_root);
				}
				_root = new GameObject("VOR_Menu_StarWars_Chase");
				_root.transform.SetParent(((Component)this).transform, false);
				_xWing = Object.Instantiate<GameObject>(val, _root.transform);
				((Object)_xWing).name = "VOR_Menu_XWing_Chase";
				PrepareVisualShip(_xWing, isTie: false);
				_xWing.transform.localScale = Vector3.one * 0.24f;
				for (int i = 0; i < 3; i++)
				{
					GameObject val3 = Object.Instantiate<GameObject>(val2, _root.transform);
					((Object)val3).name = $"VOR_Menu_TIE_Chase_{i + 1}";
					PrepareVisualShip(val3, isTie: true);
					val3.transform.localScale = Vector3.one * 0.23f;
					_ties[i] = val3;
				}
				_timer = -4f;
				_ready = true;
				_wasInChase = false;
				SetShipsVisible(visible: false);
				StopLoopSounds();
				vikingoldrepublicthemePlugin.vikingoldrepublicthemeLogger.LogInfo((object)"[VOR Menu Chase] X-Wing y 3 TIE cargados correctamente.");
			}
		}

		private void Update()
		{
			if (!_ready || (Object)(object)_xWing == (Object)null)
			{
				return;
			}
			Camera menuCamera = GetMenuCamera();
			if ((Object)(object)menuCamera == (Object)null)
			{
				return;
			}
			_timer += Time.deltaTime;
			if (_timer < 0f)
			{
				SetShipsVisible(visible: false);
				StopLoopSounds();
				return;
			}
			float num = 19.2f;
			float num2 = Mathf.Repeat(_timer, num);
			if (!(num2 <= 7.2f))
			{
				if (_wasInChase)
				{
					StopLoopSounds();
					SetShipsVisible(visible: false);
				}
				_wasInChase = false;
				return;
			}
			if (!_wasInChase)
			{
				SetShipsVisible(visible: true);
				RestartParticles();
				PlayLoopSounds();
			}
			_wasInChase = true;
			float t = Mathf.Clamp01(num2 / 7.2f);
			UpdateShipPositions(menuCamera, t);
		}

		private void UpdateShipPositions(Camera cam, float t)
		{
			//IL_002b: 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_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: 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_005a: 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)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: 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_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: 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_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: 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)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: 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_00d7: 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_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: