Decompiled source of Odins Dusk Horn v0.1.3

plugins/OdinsDuskHorn.dll

Decompiled 19 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.Audio;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("OdinsDuskHorn")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.3.0")]
[assembly: AssemblyInformationalVersion("0.1.3+a00355e325940d5f4cd0804ed0438c0518135b1e")]
[assembly: AssemblyProduct("OdinsDuskHorn")]
[assembly: AssemblyTitle("OdinsDuskHorn")]
[assembly: AssemblyVersion("0.1.3.0")]
[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 OdinsDuskHorn
{
	internal class DuskWatch : MonoBehaviour
	{
		private const float NightStart = 0.75f;

		private const float NightEnd = 0.25f;

		private const float CheckInterval = 1f;

		private const float FallbackRunSpeed = 7f;

		private static readonly MethodInfo RunSpeedFactor = AccessTools.Method(typeof(Character), "GetRunSpeedFactor", (Type[])null, (Type[])null);

		private static readonly string[] MakeIt = new string[4] { "You'll make it.", "You'll make it, if you stop admiring the view.", "Walk, don't run. You'll make it.", "Plenty of time. Odin is almost disappointed." };

		private static readonly string[] WontMakeIt = new string[4] { "You won't. Run, or find a roof.", "You won't make it. Find a roof.", "Not before dark. Build a fire and keep your back to it.", "You won't. The night will meet you on the road." };

		private OdinLine _line;

		private Horn _horn;

		private long _warnedDay = -1L;

		private float _nextCheck;

		private void Awake()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			_line = ((Component)this).gameObject.AddComponent<OdinLine>();
			GameObject val = new GameObject("OdinsDuskHorn_Horn");
			val.transform.SetParent(((Component)this).transform, false);
			_horn = val.AddComponent<Horn>();
		}

		private void Update()
		{
			//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) && Plugin.Enabled.Value && ClockReady())
			{
				if (KeyDown(Plugin.CheckKey.Value) && CanShow(localPlayer))
				{
					_line.Show(Report(localPlayer));
				}
				else if (!(Time.time < _nextCheck))
				{
					_nextCheck = Time.time + 1f;
					CheckDusk(localPlayer);
				}
			}
		}

		private void CheckDusk(Player player)
		{
			//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_0057: Unknown result type (might be due to invalid IL or missing references)
			//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_011f: Unknown result type (might be due to invalid IL or missing references)
			Clock(out var day, out var night, out var toNight, out var _);
			if (!night && day != _warnedDay && !(toNight > (double)(Plugin.WarnMinutes.Value * 60f)) && CanShow(player) && !player.IsSleeping() && !player.InShelter() && !((Character)player).InInterior())
			{
				bool haveBed;
				Vector3 val = Home(out haveBed);
				float num = Flat(val - ((Component)player).transform.position);
				if (!(num <= Plugin.HomeRadius.Value))
				{
					_warnedDay = day;
					float num2 = num / RunSpeed(player);
					string text = (((double)num2 <= toNight) ? Pick(MakeIt) : Pick(WontMakeIt));
					string text2 = (haveBed ? $"Your bed is {num:0} m away." : $"You have no bed. The world spawn is {num:0} m away.");
					_line.Show("Night in " + Minutes(toNight) + ".\n" + text2 + " " + text);
					_horn.Play(val);
					Plugin.Log.LogInfo((object)$"Dusk horn: night in {toNight:0} s, home {num:0} m (bed: {haveBed}), {num2:0} s at a run.");
				}
			}
		}

		private static string Report(Player player)
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: 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_00c6: Unknown result type (might be due to invalid IL or missing references)
			Clock(out var _, out var night, out var toNight, out var toDawn);
			string text = (night ? ("Night has fallen. Dawn in " + Minutes(toDawn) + ".") : ("Night in " + Minutes(toNight) + "."));
			bool haveBed;
			Vector3 val = Home(out haveBed) - ((Component)player).transform.position;
			float num = Flat(val);
			string text2 = (haveBed ? "Your bed" : "You have no bed. The world spawn");
			if (num <= Plugin.HomeRadius.Value)
			{
				return text + "\n" + (haveBed ? "You're home." : "You're at the world spawn.");
			}
			float num2 = num / RunSpeed(player);
			return $"{text}\n{text2} is {num:0} m to the {Compass(val)}, about {Minutes(num2)} at a run.";
		}

		private static bool ClockReady()
		{
			if ((Object)(object)EnvMan.instance != (Object)null && (Object)(object)ZNet.instance != (Object)null)
			{
				return EnvMan.instance.m_dayLengthSec > 0;
			}
			return false;
		}

		private static void Clock(out long day, out bool night, out double toNight, out double toDawn)
		{
			double num = EnvMan.instance.m_dayLengthSec;
			double timeSeconds = ZNet.instance.GetTimeSeconds();
			day = (long)(timeSeconds / num);
			double num2 = (timeSeconds - (double)day * num) / num;
			night = num2 >= 0.75 || num2 <= 0.25;
			toNight = (night ? 0.0 : ((0.75 - num2) * num));
			toDawn = ((num2 >= 0.75) ? ((1.25 - num2) * num) : ((num2 <= 0.25) ? ((0.25 - num2) * num) : 0.0));
		}

		private static Vector3 Home(out bool haveBed)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			PlayerProfile val = (((Object)(object)Game.instance != (Object)null) ? Game.instance.GetPlayerProfile() : null);
			haveBed = val != null && val.HaveCustomSpawnPoint();
			if (haveBed)
			{
				return val.GetCustomSpawnPoint();
			}
			Vector3 result = default(Vector3);
			if ((Object)(object)ZoneSystem.instance != (Object)null && ZoneSystem.instance.GetLocationIcon(Game.instance.m_StartLocation, ref result))
			{
				return result;
			}
			if (val == null)
			{
				return Vector3.zero;
			}
			return val.GetHomePoint();
		}

		private static float RunSpeed(Player player)
		{
			float num = 1f;
			try
			{
				if (RunSpeedFactor != null)
				{
					num = (float)RunSpeedFactor.Invoke(player, null);
				}
			}
			catch
			{
				num = 1f;
			}
			float num2 = ((Character)player).m_runSpeed * num;
			if (!(num2 > 0.5f))
			{
				return 7f;
			}
			return num2;
		}

		private static float Flat(Vector3 v)
		{
			//IL_0000: 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_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			Vector2 val = new Vector2(v.x, v.z);
			return ((Vector2)(ref val)).magnitude;
		}

		private static string Minutes(double seconds)
		{
			if (seconds < 60.0)
			{
				return "less than a minute";
			}
			int num = Mathf.RoundToInt((float)(seconds / 60.0));
			if (num != 1)
			{
				return $"{num} minutes";
			}
			return "1 minute";
		}

		private static string Compass(Vector3 offset)
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			string[] obj = new string[8] { "north", "northeast", "east", "southeast", "south", "southwest", "west", "northwest" };
			int num = Mathf.RoundToInt(Mathf.Repeat(Mathf.Atan2(offset.x, offset.z) * 57.29578f, 360f) / 45f) % 8;
			return obj[num];
		}

		private static string Pick(string[] lines)
		{
			return lines[Random.Range(0, lines.Length)];
		}

		private static bool CanShow(Player player)
		{
			if (((Character)player).IsDead() || ((Character)player).InCutscene() || ((Character)player).IsTeleporting())
			{
				return false;
			}
			if ((Object)(object)Hud.instance == (Object)null || Hud.IsUserHidden() || !Hud.instance.IsVisible())
			{
				return false;
			}
			if (!Menu.IsVisible() && !Minimap.IsOpen())
			{
				return !InventoryGui.IsVisible();
			}
			return false;
		}

		private static bool KeyDown(KeyboardShortcut key)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			if ((int)((KeyboardShortcut)(ref key)).MainKey == 0 || Typing() || !ZInput.GetKeyDown(((KeyboardShortcut)(ref key)).MainKey, false))
			{
				return false;
			}
			foreach (KeyCode modifier in ((KeyboardShortcut)(ref key)).Modifiers)
			{
				if (!ZInput.GetKey(modifier, false))
				{
					return false;
				}
			}
			return true;
		}

		private static bool Typing()
		{
			if ((!((Object)(object)Chat.instance != (Object)null) || !Chat.instance.HasFocus()) && !Console.IsVisible())
			{
				return TextInput.IsVisible();
			}
			return true;
		}
	}
	internal class Horn : MonoBehaviour
	{
		private const float EarDistance = 3f;

		private const float MaxLength = 5f;

		private const float Attack = 0.15f;

		private const float Release = 0.8f;

		private const double StartDelay = 0.05;

		private static readonly (string name, float pitch)[] Fallbacks = new(string, float)[3]
		{
			("sfx_lox_shout", 0.8f),
			("sfx_prespawn", 1f),
			("sfx_offering", 0.8f)
		};

		private readonly List<AudioSource> _sources = new List<AudioSource>();

		private int _layers;

		private float _elapsed = -1f;

		private float _length;

		private float _perLayerPeak;

		private Vector3 _toward;

		private static bool _looked;

		private static ZSFX _sound;

		private static float _pitch = 1f;

		public void Play(Vector3 home)
		{
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: 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: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			float value = Plugin.HornVolume.Value;
			ZSFX val = FindSound();
			if (value <= 0f || (Object)(object)val == (Object)null)
			{
				return;
			}
			AudioClip val2 = val.m_audioClips[Random.Range(0, val.m_audioClips.Length)];
			if ((Object)(object)val2 == (Object)null)
			{
				return;
			}
			AudioSource component = ((Component)val).GetComponent<AudioSource>();
			AudioMixerGroup val3 = (((Object)(object)component != (Object)null) ? component.outputAudioMixerGroup : null);
			if ((Object)(object)val3 == (Object)null && (Object)(object)AudioMan.instance != (Object)null)
			{
				val3 = AudioMan.instance.m_ambientMixer;
			}
			float num = (((Object)(object)component != (Object)null) ? component.volume : 1f) * (val.m_minVol + val.m_maxVol) * 0.5f;
			value *= num;
			if (value <= 0f)
			{
				return;
			}
			_layers = Mathf.Max(1, Mathf.CeilToInt(value));
			_perLayerPeak = value / (float)_layers;
			_length = Mathf.Min(5f, val2.length / _pitch);
			while (_sources.Count < _layers)
			{
				AudioSource val4 = ((Component)this).gameObject.AddComponent<AudioSource>();
				val4.playOnAwake = false;
				val4.loop = false;
				val4.spatialBlend = 1f;
				val4.rolloffMode = (AudioRolloffMode)1;
				val4.minDistance = 20f;
				val4.maxDistance = 60f;
				val4.dopplerLevel = 0f;
				val4.bypassReverbZones = true;
				val4.priority = 0;
				_sources.Add(val4);
			}
			Vector3 val5 = Ears();
			_toward = home - val5;
			_toward.y = 0f;
			_toward = ((((Vector3)(ref _toward)).sqrMagnitude > 0.01f) ? ((Vector3)(ref _toward)).normalized : Vector3.forward);
			((Component)this).transform.position = val5 + _toward * 3f;
			double num2 = AudioSettings.dspTime + 0.05;
			for (int i = 0; i < _sources.Count; i++)
			{
				AudioSource val6 = _sources[i];
				val6.Stop();
				if (i < _layers)
				{
					val6.outputAudioMixerGroup = val3;
					val6.clip = val2;
					val6.pitch = _pitch;
					val6.volume = 0f;
					val6.timeSamples = 0;
					val6.PlayScheduled(num2);
				}
			}
			_elapsed = 0f;
		}

		private void Update()
		{
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			if (_elapsed < 0f)
			{
				return;
			}
			_elapsed += Time.deltaTime;
			if (_elapsed >= _length + 0.05f)
			{
				foreach (AudioSource source in _sources)
				{
					source.Stop();
				}
				_elapsed = -1f;
				return;
			}
			((Component)this).transform.position = Ears() + _toward * 3f;
			float num = Mathf.Max(0f, _elapsed - 0.05f);
			float num2 = Mathf.Min(Mathf.Clamp01(num / 0.15f), Mathf.Clamp01((_length - num) / 0.8f));
			float volume = _perLayerPeak * num2;
			for (int i = 0; i < _layers; i++)
			{
				_sources[i].volume = volume;
			}
		}

		private static Vector3 Ears()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: 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)
			Camera mainCamera = Utils.GetMainCamera();
			if ((Object)(object)mainCamera != (Object)null)
			{
				return ((Component)mainCamera).transform.position;
			}
			if (!((Object)(object)Player.m_localPlayer != (Object)null))
			{
				return Vector3.zero;
			}
			return ((Component)Player.m_localPlayer).transform.position;
		}

		private static ZSFX FindSound()
		{
			//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_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)
			if ((Object)(object)_sound != (Object)null || _looked)
			{
				return _sound;
			}
			_looked = true;
			ZSFX[] array = Resources.FindObjectsOfTypeAll<ZSFX>();
			ZSFX[] array2 = array;
			Scene scene;
			foreach (ZSFX val in array2)
			{
				if (HasClips(val))
				{
					scene = ((Component)val).gameObject.scene;
					if (!((Scene)(ref scene)).IsValid() && (IsHorn(((Object)val).name) || IsHorn(((Object)(object)val.m_audioClips[0] != (Object)null) ? ((Object)val.m_audioClips[0]).name : "")))
					{
						_sound = val;
						_pitch = 1f;
						break;
					}
				}
			}
			if ((Object)(object)_sound == (Object)null)
			{
				(string, float)[] fallbacks = Fallbacks;
				for (int i = 0; i < fallbacks.Length; i++)
				{
					(string, float) tuple = fallbacks[i];
					string item = tuple.Item1;
					float item2 = tuple.Item2;
					GameObject val2 = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.GetPrefab(item) : null);
					ZSFX val3 = (((Object)(object)val2 != (Object)null) ? val2.GetComponentInChildren<ZSFX>(true) : null);
					if (!HasClips(val3))
					{
						val3 = null;
						array2 = array;
						foreach (ZSFX val4 in array2)
						{
							if (((Object)val4).name == item && HasClips(val4))
							{
								scene = ((Component)val4).gameObject.scene;
								if (!((Scene)(ref scene)).IsValid())
								{
									val3 = val4;
									break;
								}
							}
						}
					}
					if ((Object)(object)val3 != (Object)null)
					{
						_sound = val3;
						_pitch = item2;
						break;
					}
				}
			}
			if ((Object)(object)_sound != (Object)null)
			{
				ManualLogSource log = Plugin.Log;
				string name = ((Object)_sound).name;
				AudioClip obj = _sound.m_audioClips[0];
				log.LogInfo((object)$"The dusk horn is '{name}' (clip '{((obj != null) ? ((Object)obj).name : null)}', pitch {_pitch:0.00}).");
			}
			else
			{
				Plugin.Log.LogWarning((object)"Found no horn-like sound in the game; Odin will speak without the horn.");
			}
			return _sound;
		}

		private static bool IsHorn(string name)
		{
			string text = name.ToLowerInvariant();
			if (text.Contains("horn") && !text.Contains("thorn"))
			{
				return !text.Contains("horns");
			}
			return false;
		}

		private static bool HasClips(ZSFX z)
		{
			if ((Object)(object)z != (Object)null && z.m_audioClips != null)
			{
				return z.m_audioClips.Length != 0;
			}
			return false;
		}
	}
	internal static class HudText
	{
		private sealed class Scale : MonoBehaviour
		{
			private const float ReferenceWidth = 1920f;

			private const float ReferenceHeight = 1080f;

			private static readonly FieldRef<float> GameGuiScale = TryFindGuiScale();

			internal CanvasScaler Scaler;

			private float _logged = -1f;

			private void Update()
			{
				if (!((Object)(object)Scaler == (Object)null))
				{
					float num = ((GameGuiScale != null) ? GameGuiScale.Invoke() : 1f);
					if (num <= 0f)
					{
						num = 1f;
					}
					float num2 = Mathf.Min((float)Screen.width / 1920f, (float)Screen.height / 1080f) * num * Plugin.TextScale.Value;
					if (Mathf.Abs(Scaler.scaleFactor - num2) > 0.0001f)
					{
						Scaler.scaleFactor = num2;
					}
					if (_logged < 0f)
					{
						_logged = num2;
						Plugin.Log.LogInfo((object)$"Text scale {num2:0.###}: screen {Screen.width}x{Screen.height}, game GUI scale {num:0.##}, TextScale {Plugin.TextScale.Value:0.##}.");
					}
				}
			}

			private static FieldRef<float> TryFindGuiScale()
			{
				FieldInfo fieldInfo = AccessTools.Field(typeof(GuiScaler), "m_largeGuiScale");
				if (fieldInfo == null || fieldInfo.FieldType != typeof(float) || !fieldInfo.IsStatic)
				{
					Plugin.Log.LogWarning((object)"Couldn't find the game's GUI scale; text follows the screen size only.");
					return null;
				}
				return AccessTools.StaticFieldRefAccess<float>(fieldInfo);
			}
		}

		private static Canvas _canvas;

		public static TMP_Text Create(string name, Transform owner)
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Expected O, but got Unknown
			//IL_00b7: 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_00cc: 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_00e1: Unknown result type (might be due to invalid IL or missing references)
			TMP_Text val = (((Object)(object)MessageHud.instance != (Object)null) ? MessageHud.instance.m_messageCenterText : null);
			if ((Object)(object)val == (Object)null || (Object)(object)val.font == (Object)null || !EnsureCanvas(owner))
			{
				return null;
			}
			GameObject val2 = new GameObject(name, new Type[1] { typeof(RectTransform) });
			val2.transform.SetParent(((Component)_canvas).transform, false);
			TextMeshProUGUI obj = val2.AddComponent<TextMeshProUGUI>();
			((TMP_Text)obj).font = val.font;
			((TMP_Text)obj).fontSharedMaterial = val.fontSharedMaterial;
			((TMP_Text)obj).alignment = (TextAlignmentOptions)514;
			((TMP_Text)obj).textWrappingMode = (TextWrappingModes)1;
			((Graphic)obj).raycastTarget = false;
			((TMP_Text)obj).outlineWidth = 0.15f;
			((TMP_Text)obj).outlineColor = new Color32((byte)0, (byte)0, (byte)0, (byte)200);
			RectTransform val3 = (RectTransform)val2.transform;
			val3.pivot = new Vector2(0.5f, 0.5f);
			val3.anchoredPosition = Vector2.zero;
			return (TMP_Text)(object)obj;
		}

		private static bool EnsureCanvas(Transform owner)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_canvas != (Object)null)
			{
				return true;
			}
			GameObject val = new GameObject("OdinsDuskHorn_Canvas");
			val.transform.SetParent(owner, false);
			_canvas = val.AddComponent<Canvas>();
			_canvas.renderMode = (RenderMode)0;
			_canvas.sortingOrder = 5000;
			CanvasScaler val2 = val.AddComponent<CanvasScaler>();
			val2.uiScaleMode = (ScaleMode)0;
			val.AddComponent<Scale>().Scaler = val2;
			Plugin.Log.LogInfo((object)"On-screen text layer created.");
			return true;
		}
	}
	internal class OdinLine : MonoBehaviour
	{
		private const float ScreenY = 0.72f;

		private const float FadeIn = 0.6f;

		private const float Hold = 7f;

		private const float FadeOut = 1.5f;

		private const float TextSize = 21f;

		private static readonly Color Tint = new Color(1f, 0.86f, 0.62f);

		private TMP_Text _text;

		private float _elapsed = -1f;

		public void Show(string line)
		{
			if (EnsureText())
			{
				_text.text = line;
				_elapsed = 0f;
				SetAlpha(0f);
				((Component)_text).gameObject.SetActive(true);
			}
		}

		private void Update()
		{
			if (_elapsed < 0f || (Object)(object)_text == (Object)null)
			{
				return;
			}
			_elapsed += Time.deltaTime;
			float num = 9.1f;
			if (_elapsed >= num)
			{
				_elapsed = -1f;
				((Component)_text).gameObject.SetActive(false);
				return;
			}
			float num2 = Mathf.Min(Mathf.Clamp01(_elapsed / 0.6f), Mathf.Clamp01((num - _elapsed) / 1.5f));
			if (!HudVisible())
			{
				num2 = 0f;
			}
			SetAlpha(Mathf.SmoothStep(0f, 1f, num2));
		}

		private void SetAlpha(float alpha)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: 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)
			Color tint = Tint;
			tint.a = alpha;
			((Graphic)_text).color = tint;
		}

		private bool EnsureText()
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: 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)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_text != (Object)null)
			{
				return true;
			}
			_text = HudText.Create("OdinsDuskHorn_Line", ((Component)this).transform);
			if ((Object)(object)_text == (Object)null)
			{
				return false;
			}
			RectTransform val = (RectTransform)_text.transform;
			val.anchorMin = new Vector2(0.5f, 0.72f);
			val.anchorMax = new Vector2(0.5f, 0.72f);
			val.sizeDelta = new Vector2(1400f, 160f);
			_text.fontSize = 21f;
			return true;
		}

		private static bool HudVisible()
		{
			if ((Object)(object)Hud.instance != (Object)null && !Hud.IsUserHidden())
			{
				return Hud.instance.IsVisible();
			}
			return false;
		}

		private void OnDestroy()
		{
			if ((Object)(object)_text != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)_text).gameObject);
			}
		}
	}
	[BepInPlugin("hevyh2o.valheim.odinsduskhorn", "Odin's Dusk Horn", "0.1.3")]
	public class Plugin : BaseUnityPlugin
	{
		public const string Guid = "hevyh2o.valheim.odinsduskhorn";

		public const string Name = "Odin's Dusk Horn";

		public const string Version = "0.1.3";

		internal static ManualLogSource Log;

		internal static ConfigEntry<bool> Enabled;

		internal static ConfigEntry<KeyboardShortcut> CheckKey;

		internal static ConfigEntry<float> WarnMinutes;

		internal static ConfigEntry<float> HomeRadius;

		internal static ConfigEntry<float> TextScale;

		internal static ConfigEntry<float> HornVolume;

		private DuskWatch _watch;

		private void Awake()
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Expected O, but got Unknown
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Expected O, but got Unknown
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Expected O, but got Unknown
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Master switch.");
			CheckKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "CheckKey", new KeyboardShortcut((KeyCode)278, Array.Empty<KeyCode>()), "Shows the minutes until nightfall (or until dawn, at night) and the distance and direction to your bed. Any key or combination works.");
			WarnMinutes = ((BaseUnityPlugin)this).Config.Bind<float>("General", "WarnMinutes", 2f, new ConfigDescription("How many minutes before nightfall the horn sounds, 1 to 6. These are minutes of the game's clock as you play it (a whole Valheim day is 20 of them).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 6f), Array.Empty<object>()));
			HomeRadius = ((BaseUnityPlugin)this).Config.Bind<float>("General", "HomeRadius", 60f, new ConfigDescription("No horn when you're this close to your bed (or to the world spawn, with no bed), in metres.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 500f), Array.Empty<object>()));
			TextScale = ((BaseUnityPlugin)this).Config.Bind<float>("General", "TextScale", 1f, new ConfigDescription("Size of Odin's lines on screen, 0.5 to 2. 1 = sized to match the game's own HUD, which already follows your screen height and the game's GUI scale setting.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 2f), Array.Empty<object>()));
			HornVolume = ((BaseUnityPlugin)this).Config.Bind<float>("Sound", "HornVolume", 1f, new ConfigDescription("Horn loudness, 0 to 2. 1 = the sound at the game's own volume. 0 shows Odin's line without the horn. Also follows your in-game volume sliders.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2f), Array.Empty<object>()));
			_watch = ((Component)this).gameObject.AddComponent<DuskWatch>();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Odin's Dusk Horn 0.1.3 loaded. Odin is watching the sun.");
		}

		private void OnDestroy()
		{
			if ((Object)(object)_watch != (Object)null)
			{
				Object.Destroy((Object)(object)_watch);
			}
		}
	}
	internal static class BuildInfo
	{
		public const string Version = "0.1.3";
	}
}