Decompiled source of MountRidingHints v1.0.0

MountRidingHints.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("assembly_guiutils")]
[assembly: IgnoresAccessChecksTo("assembly_utils")]
[assembly: IgnoresAccessChecksTo("assembly_valheim")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("MountRidingHints")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+80ade407e142e5ee74a9ef118975f530bcf1bbb6")]
[assembly: AssemblyProduct("MountRidingHints")]
[assembly: AssemblyTitle("MountRidingHints")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[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 MountRidingHints
{
	internal static class MountHints
	{
		private struct Hint
		{
			public readonly string Name;

			public readonly ConfigEntry<string> Label;

			public readonly string Key;

			public readonly string JoyKey;

			public Hint(string name, ConfigEntry<string> label, string key, string joyKey)
			{
				Name = name;
				Label = label;
				Key = key;
				JoyKey = joyKey;
			}
		}

		public const string GroupName = "MountRidingHints";

		private const string KeyboardTemplateName = "Block";

		private const string GamepadTemplateName = "Text - Block";

		private const string TemplateName = "Template";

		private const string LabelObjectName = "Text";

		private const string KeyObjectName = "Key";

		private static GameObject group;

		private static Transform keyboardRoot;

		private static Transform gamepadRoot;

		private static GameObject keyboardTemplate;

		private static GameObject gamepadTemplate;

		private static readonly List<GameObject> items = new List<GameObject>();

		private static bool rebuild;

		private static Hint[] Hints()
		{
			return new Hint[5]
			{
				new Hint("Walk", Plugin.WalkLabel, "Forward", "JoyLStickUp"),
				new Hint("Gallop", Plugin.GallopLabel, "Run", "JoyRun"),
				new Hint("Stop", Plugin.StopLabel, "Backward", "JoyLStickDown"),
				new Hint("Turn", Plugin.TurnLabel, "Block", "JoyBlock"),
				new Hint("Dismount", Plugin.DismountLabel, "Use", "JoyUse")
			};
		}

		public static void Build(KeyHints keyHints)
		{
			Forget();
			GameObject val = (((Object)(object)keyHints != (Object)null) ? keyHints.m_combatHints : null);
			if ((Object)(object)val == (Object)null)
			{
				Plugin.Log.LogWarning((object)"The game's combat hints group was not found; the riding hints are skipped");
				return;
			}
			group = Object.Instantiate<GameObject>(val, val.transform.parent);
			((Object)group).name = "MountRidingHints";
			group.SetActive(false);
			UIInputHint component = group.GetComponent<UIInputHint>();
			if ((Object)(object)component == (Object)null)
			{
				Plugin.Log.LogWarning((object)"The combat hints group has no UIInputHint in this game version; the riding hints are skipped");
				Forget();
				return;
			}
			component.m_inputLayoutSettings.Clear();
			keyboardRoot = (((Object)(object)component.m_mouseKeyboardHint != (Object)null) ? component.m_mouseKeyboardHint.transform : null);
			gamepadRoot = (((Object)(object)component.m_gamepadHint != (Object)null) ? component.m_gamepadHint.transform : null);
			keyboardTemplate = TakeTemplate(keyboardRoot, "Block");
			gamepadTemplate = TakeTemplate(gamepadRoot, "Text - Block");
			if ((Object)(object)keyboardTemplate == (Object)null)
			{
				Plugin.Log.LogWarning((object)"The combat hints have no \"Block\" item in this game version; the riding hints are skipped");
				Forget();
				return;
			}
			if ((Object)(object)gamepadTemplate == (Object)null)
			{
				Plugin.Log.LogDebug((object)"The combat hints have no \"Text - Block\" gamepad item; the riding hints show on the keyboard only");
			}
			Fill();
			Plugin.Log.LogDebug((object)$"Riding hints built under {((Object)val.transform.parent).name} with {items.Count} items");
		}

		public static void Forget()
		{
			if ((Object)(object)group != (Object)null)
			{
				Object.Destroy((Object)(object)group);
			}
			group = null;
			keyboardRoot = null;
			gamepadRoot = null;
			keyboardTemplate = null;
			gamepadTemplate = null;
			items.Clear();
		}

		public static void Invalidate()
		{
			rebuild = true;
		}

		public static void Update(KeyHints keyHints)
		{
			if (!((Object)(object)group == (Object)null) && !((Object)(object)keyHints == (Object)null))
			{
				Player localPlayer = Player.m_localPlayer;
				bool flag = (Object)(object)localPlayer != (Object)null && ((Character)localPlayer).IsRiding() && GameWouldShowHints(keyHints, localPlayer);
				if (flag && rebuild)
				{
					rebuild = false;
					Fill();
				}
				if (group.activeSelf != flag)
				{
					group.SetActive(flag);
				}
			}
		}

		private static bool GameWouldShowHints(KeyHints keyHints, Player player)
		{
			if (!keyHints.m_keyHintsEnabled || ((Character)player).IsDead() || Game.IsPaused())
			{
				return false;
			}
			if ((Object)(object)Chat.instance != (Object)null && Chat.instance.IsChatDialogWindowVisible())
			{
				return false;
			}
			if (InventoryGui.IsVisible() || Hud.InRadial())
			{
				return false;
			}
			InventoryGui instance = InventoryGui.instance;
			if (!((Object)(object)instance == (Object)null))
			{
				if (!instance.IsSkillsPanelOpen && !instance.IsTrophisPanelOpen && !instance.IsAchievementsPanelOpen)
				{
					return !instance.IsTextPanelOpen;
				}
				return false;
			}
			return true;
		}

		private static GameObject TakeTemplate(Transform parent, string childName)
		{
			if ((Object)(object)parent == (Object)null)
			{
				return null;
			}
			GameObject val = null;
			List<GameObject> list = new List<GameObject>();
			for (int i = 0; i < parent.childCount; i++)
			{
				GameObject gameObject = ((Component)parent.GetChild(i)).gameObject;
				if ((Object)(object)val == (Object)null && ((Object)gameObject).name == childName)
				{
					val = gameObject;
				}
				else
				{
					list.Add(gameObject);
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			foreach (GameObject item in list)
			{
				Object.Destroy((Object)(object)item);
			}
			((Object)val).name = "Template";
			val.SetActive(false);
			return val;
		}

		private static void Fill()
		{
			ClearItems();
			Hint[] array = Hints();
			for (int i = 0; i < array.Length; i++)
			{
				Hint hint = array[i];
				string text = ((hint.Label != null && hint.Label.Value != null) ? hint.Label.Value.Trim() : string.Empty);
				if (text.Length == 0)
				{
					continue;
				}
				if ((Object)(object)keyboardRoot != (Object)null && (Object)(object)keyboardTemplate != (Object)null)
				{
					GameObject val = Object.Instantiate<GameObject>(keyboardTemplate, keyboardRoot);
					((Object)val).name = hint.Name;
					SetText(val, "Text", text);
					SetText(val, "Key", "$KEY_" + hint.Key);
					val.SetActive(true);
					items.Add(val);
				}
				if ((Object)(object)gamepadRoot != (Object)null && (Object)(object)gamepadTemplate != (Object)null)
				{
					GameObject val2 = Object.Instantiate<GameObject>(gamepadTemplate, gamepadRoot);
					((Object)val2).name = "Text - " + hint.Name;
					TMP_Text component = val2.GetComponent<TMP_Text>();
					if ((Object)(object)component != (Object)null)
					{
						component.text = text + " <mspace=0.6em> $KEY_" + hint.JoyKey + "</mspace>";
					}
					val2.SetActive(true);
					items.Add(val2);
				}
			}
			if (Localization.instance != null && (Object)(object)group != (Object)null)
			{
				Localization.instance.Localize(group.transform);
			}
		}

		private static void ClearItems()
		{
			foreach (GameObject item in items)
			{
				if ((Object)(object)item == (Object)null)
				{
					continue;
				}
				if (Localization.instance != null)
				{
					TMP_Text[] componentsInChildren = item.GetComponentsInChildren<TMP_Text>(true);
					foreach (TMP_Text val in componentsInChildren)
					{
						Localization.instance.RemoveTextFromCache(val);
					}
				}
				Object.Destroy((Object)(object)item);
			}
			items.Clear();
		}

		private static void SetText(GameObject item, string objectName, string value)
		{
			TMP_Text[] componentsInChildren = item.GetComponentsInChildren<TMP_Text>(true);
			foreach (TMP_Text val in componentsInChildren)
			{
				if (((Object)val).name == objectName)
				{
					val.text = value;
					return;
				}
			}
			Plugin.Log.LogDebug((object)(((Object)item).name + ": no \"" + objectName + "\" text in the hint item (the game changed); left as copied"));
		}
	}
	[BepInPlugin("rhenn.mountridinghints", "MountRidingHints", "1.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		public const string PluginGUID = "rhenn.mountridinghints";

		public const string PluginName = "MountRidingHints";

		public const string PluginVersion = "1.0.0";

		internal static ManualLogSource Log;

		internal static ConfigEntry<bool> Enabled;

		internal static ConfigEntry<string> WalkLabel;

		internal static ConfigEntry<string> GallopLabel;

		internal static ConfigEntry<string> StopLabel;

		internal static ConfigEntry<string> TurnLabel;

		internal static ConfigEntry<string> DismountLabel;

		private readonly Harmony harmony = new Harmony("rhenn.mountridinghints");

		private void Awake()
		{
			Log = ((BaseUnityPlugin)this).Logger;
			Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Master switch, read when the game starts. false: the mod loads nothing and the key hints stay as the game has them.");
			WalkLabel = ((BaseUnityPlugin)this).Config.Bind<string>("Hints", "Walk", "Walk", "Text of the hint for the key that makes the mount walk (the game's Forward key, W). Empty hides this hint.");
			GallopLabel = ((BaseUnityPlugin)this).Config.Bind<string>("Hints", "Gallop", "Gallop", "Text of the hint for the key that makes the mount run (the game's Run key, Shift). Empty hides this hint.");
			StopLabel = ((BaseUnityPlugin)this).Config.Bind<string>("Hints", "Stop", "Stop", "Text of the hint for the key that stops the mount (the game's Backward key, S). Empty hides this hint.");
			TurnLabel = ((BaseUnityPlugin)this).Config.Bind<string>("Hints", "Turn", "Turn", "Text of the hint for the key that turns the mount on the spot to face where you look (the game's Block key, right mouse button). Empty hides this hint.");
			DismountLabel = ((BaseUnityPlugin)this).Config.Bind<string>("Hints", "Dismount", "Dismount", "Text of the hint for the key that gets you off the mount (the game's Use key, E). Empty hides this hint.");
			WalkLabel.SettingChanged += OnLabelChanged;
			GallopLabel.SettingChanged += OnLabelChanged;
			StopLabel.SettingChanged += OnLabelChanged;
			TurnLabel.SettingChanged += OnLabelChanged;
			DismountLabel.SettingChanged += OnLabelChanged;
			if (!Enabled.Value)
			{
				Log.LogInfo((object)"MountRidingHints 1.0.0 is disabled in the config; nothing is patched.");
				return;
			}
			harmony.PatchAll(Assembly.GetExecutingAssembly());
			Log.LogInfo((object)"MountRidingHints 1.0.0 loaded.");
		}

		private static void OnLabelChanged(object sender, EventArgs e)
		{
			MountHints.Invalidate();
		}

		private void OnDestroy()
		{
			harmony.UnpatchSelf();
		}
	}
}
namespace MountRidingHints.Patches
{
	[HarmonyPatch(typeof(KeyHints), "Awake")]
	internal static class KeyHints_Awake_Patch
	{
		private static void Postfix(KeyHints __instance)
		{
			MountHints.Build(__instance);
		}
	}
	[HarmonyPatch(typeof(KeyHints), "UpdateHints")]
	internal static class KeyHints_UpdateHints_Patch
	{
		private static void Postfix(KeyHints __instance)
		{
			MountHints.Update(__instance);
		}
	}
	[HarmonyPatch(typeof(KeyHints), "OnDestroy")]
	internal static class KeyHints_OnDestroy_Patch
	{
		private static void Postfix()
		{
			MountHints.Forget();
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}