Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Odins Almanac v0.1.4
plugins/OdinsAlmanac.dll
Decompiled 17 hours agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; 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("OdinsAlmanac")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.1.4.0")] [assembly: AssemblyInformationalVersion("0.1.4+39d9127df34e7e2ec15cd9e6478eef57292cfc9f")] [assembly: AssemblyProduct("OdinsAlmanac")] [assembly: AssemblyTitle("OdinsAlmanac")] [assembly: AssemblyVersion("0.1.4.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 OdinsAlmanac { internal sealed class Spell { public EnvSetup Env; public double Start; public double End = double.NaN; public float WindIntensity; public float WindFrom; } internal sealed class ForecastResult { public string BiomeName; public double Now; public Spell Current; public readonly List<Spell> Upcoming = new List<Spell>(); public bool Overridden; public bool NeverChanges; } internal static class Forecast { private const int MaxPeriods = 200; private static Func<EnvMan, BiomeSector> _getBiome; private static Func<EnvMan, string> _getEnvironmentOverride; private static Func<EnvMan, List<EnvEntry>, EnvSetup> _selectWeightedEnvironment; private static FieldRef<EnvMan, string> _forceEnv; private static readonly List<EnvEntry> Entries = new List<EnvEntry>(); private static readonly HashSet<string> LoggedBiomes = new HashSet<string>(); internal static bool Init() { try { _getBiome = AccessTools.MethodDelegate<Func<EnvMan, BiomeSector>>(AccessTools.Method(typeof(EnvMan), "GetBiome", (Type[])null, (Type[])null), (object)null, true); _getEnvironmentOverride = AccessTools.MethodDelegate<Func<EnvMan, string>>(AccessTools.Method(typeof(EnvMan), "GetEnvironmentOverride", (Type[])null, (Type[])null), (object)null, true); _selectWeightedEnvironment = AccessTools.MethodDelegate<Func<EnvMan, List<EnvEntry>, EnvSetup>>(AccessTools.Method(typeof(EnvMan), "SelectWeightedEnvironment", (Type[])null, (Type[])null), (object)null, true); _forceEnv = AccessTools.FieldRefAccess<EnvMan, string>("m_forceEnv"); return true; } catch (Exception ex) { Plugin.Log.LogError((object)("Couldn't find Valheim's weather code; a game update may have changed it. The almanac is closed. (" + ex.Message + ")")); return false; } } internal static ForecastResult Compute() { //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) EnvMan instance = EnvMan.instance; Camera mainCamera = Utils.GetMainCamera(); if ((Object)(object)instance == (Object)null || (Object)(object)mainCamera == (Object)null || (Object)(object)ZNet.instance == (Object)null || WorldGenerator.instance == null) { return null; } long environmentDuration = instance.m_environmentDuration; if (environmentDuration <= 0) { return null; } double timeSeconds = ZNet.instance.GetTimeSeconds(); BiomeSector val = _getBiome(instance); ForecastResult forecastResult = new ForecastResult { BiomeName = val.GetName(false), Now = timeSeconds }; if (!string.IsNullOrEmpty(_forceEnv.Invoke(instance)) || !string.IsNullOrEmpty(_getEnvironmentOverride(instance))) { forecastResult.Overridden = true; forecastResult.Current = MakeSpell(instance, instance.GetCurrentEnvironment(), timeSeconds, timeSeconds); return forecastResult; } Entries.Clear(); List<EnvEntry> availableEnvironments = instance.GetAvailableEnvironments(val); if (availableEnvironments != null) { Entries.AddRange(availableEnvironments); } if (Entries.Count == 0) { return null; } LogBiomeOnce(forecastResult.BiomeName); Vector3 position = ((Component)mainCamera).transform.position; bool ashlands = WorldGenerator.IsAshlands(position.x, position.z); bool deepNorth = WorldGenerator.IsDeepnorth(position.x, position.y); long num = (long)timeSeconds / environmentDuration; EnvSetup val2 = Pick(instance, num, ashlands, deepNorth); if (val2 == null) { return null; } forecastResult.Current = MakeSpell(instance, val2, timeSeconds, timeSeconds); int value = Plugin.ForecastCount.Value; Spell spell = forecastResult.Current; for (long num2 = num + 1; num2 <= num + 200; num2++) { EnvSetup val3 = Pick(instance, num2, ashlands, deepNorth); if (val3 != null && !(val3.m_name == spell.Env.m_name)) { double num3 = (spell.End = (double)num2 * (double)environmentDuration); if (forecastResult.Upcoming.Count == value) { break; } spell = MakeSpell(instance, val3, num3, num3); forecastResult.Upcoming.Add(spell); } } forecastResult.NeverChanges = forecastResult.Upcoming.Count == 0 && UniqueWeathers() <= 1; return forecastResult; } private static EnvSetup Pick(EnvMan env, long period, bool ashlands, bool deepNorth) { //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_0073: Unknown result type (might be due to invalid IL or missing references) State state = Random.state; try { Random.InitState((int)period); EnvSetup result = _selectWeightedEnvironment(env, Entries); foreach (EnvEntry entry in Entries) { if (entry.m_ashlandsOverride && ashlands) { result = entry.m_env; } if (entry.m_deepnorthOverride && deepNorth) { result = entry.m_env; } } return result; } finally { Random.state = state; } } private static Spell MakeSpell(EnvMan env, EnvSetup setup, double start, double windAt) { Spell spell = new Spell { Env = setup, Start = start }; if (setup != null) { Wind(env, setup, (long)windAt, out spell.WindIntensity, out spell.WindFrom); } return spell; } private static void Wind(EnvMan env, EnvSetup setup, long timeSec, out float intensity, out float fromBearing) { //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_0082: Unknown result type (might be due to invalid IL or missing references) State state = Random.state; float num = 0f; float num2 = 0.5f; try { int[] array = new int[4] { 1, 2, 4, 8 }; foreach (int num3 in array) { long num4 = env.m_windPeriodDuration / num3; if (num4 > 0) { Random.InitState((int)(timeSec / num4)); num += Random.value * ((float)Math.PI * 2f / (float)num3); num2 += -0.5f / (float)num3 + Random.value / (float)num3; } } } finally { Random.state = state; } intensity = Mathf.Clamp(Mathf.Lerp(setup.m_windMin, setup.m_windMax, num2), 0.05f, 1f); fromBearing = Mathf.Repeat(num * 57.29578f + 180f, 360f); } private static int UniqueWeathers() { HashSet<string> hashSet = new HashSet<string>(); foreach (EnvEntry entry in Entries) { if (entry.m_env != null) { hashSet.Add(entry.m_env.m_name); } } return hashSet.Count; } private static void LogBiomeOnce(string biome) { if (!LoggedBiomes.Add(biome)) { return; } List<string> list = new List<string>(); foreach (EnvEntry entry in Entries) { list.Add(((object)entry).ToString()); } Plugin.Log.LogInfo((object)(biome + " weather: " + string.Join(", ", list))); } } internal static class ForecastText { private enum Kind { Clear, Mist, Gloom, Rain, Storm, Snow, Ash } private const string Value = "orange"; private const string FlavorColor = "#B9B3A8"; private const string NoteColor = "#B0B0B0"; private static readonly StringBuilder Sb = new StringBuilder(); private static readonly Dictionary<string, string> Names = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase) { ["Clear"] = "Clear", ["Twilight_Clear"] = "Clear twilight", ["Heath clear"] = "Clear", ["Misty"] = "Mist", ["DeepForest Mist"] = "Forest mist", ["Darklands_dark"] = "Gloom", ["Rain"] = "Rain", ["LightRain"] = "Light rain", ["ThunderStorm"] = "Thunderstorm", ["SwampRain"] = "Swamp rain", ["Snow"] = "Snow", ["SnowStorm"] = "Snowstorm", ["Twilight_Snow"] = "Twilight snow", ["Twilight_SnowStorm"] = "Twilight snowstorm", ["Mistlands_clear"] = "Clear above the mist", ["Mistlands_rain"] = "Rain over the mist", ["Mistlands_thunder"] = "Thunder over the mist", ["Ashlands_ashrain"] = "Ash rain", ["Ashlands_misty"] = "Ash haze", ["Ashlands_storm"] = "Ash storm", ["Ashlands_CinderRain"] = "Cinder rain", ["Ashlands_SeaStorm"] = "Sea storm" }; private static readonly Dictionary<Kind, string[]> Remarks = new Dictionary<Kind, string[]> { [Kind.Clear] = new string[2] { "Fair skies. Get the boat out.", "Good drying weather. For hides, and for you." }, [Kind.Mist] = new string[2] { "Can't see your own boots. Sail slowly, or not at all.", "Fog. Everything sounds closer than it is." }, [Kind.Gloom] = new string[2] { "Gloomy. The trees like it. You won't.", "Dark at noon. Bring a torch and a friend." }, [Kind.Rain] = new string[2] { "Wet. The mead is dry, though.", "Rain on the way. Fires out, cloaks on." }, [Kind.Storm] = new string[2] { "Stay in port. The sea is in a mood.", "Thunder means Thor's drinking again. Stay in." }, [Kind.Snow] = new string[2] { "Cold enough to freeze the mead. Dress for it.", "Snow coming. Wear the fur, not the face." }, [Kind.Ash] = new string[2] { "Ash in your beard, fire in your boots.", "Hot, grey and angry. Like Odin before breakfast." } }; private static readonly string[] Points = new string[8] { "north", "north-east", "east", "south-east", "south", "south-west", "west", "north-west" }; internal static string Title(ForecastResult f) { return f.BiomeName + " forecast"; } internal static string Body(ForecastResult f) { Sb.Clear(); if (Plugin.ShowFlavor.Value) { Sb.Append("<i><color=").Append("#B9B3A8").Append('>') .Append(Remark(f)) .Append("</color></i>\n\n"); } AppendSpell("Now", f.Current, null); if (f.Overridden) { Sb.Append("\n<color=").Append("#B0B0B0").Append(">Something other than the sky is setting the weather here. No forecast until you leave it.</color>"); return Sb.ToString(); } if (f.Upcoming.Count == 0) { Sb.Append("\n<color=").Append("#B0B0B0").Append('>') .Append(f.NeverChanges ? "The weather here never changes." : "No change in sight.") .Append("</color>"); return Sb.ToString(); } for (int i = 0; i < f.Upcoming.Count; i++) { Sb.Append('\n'); AppendSpell((i == 0) ? "Next" : "Then", f.Upcoming[i], Duration(f.Upcoming[i].Start - f.Now)); } Sb.Append("\n<color=").Append("#B0B0B0").Append(">For this biome. The weather changes with it if you travel.</color>"); return Sb.ToString(); } private static void AppendSpell(string label, Spell s, string arrivesIn) { Sb.Append(label).Append(": <color=").Append("orange") .Append('>') .Append(Name(s.Env)) .Append("</color>"); if (arrivesIn != null) { Sb.Append(" in ").Append(arrivesIn); } if (label != "Now" && !double.IsNaN(s.End)) { Sb.Append(", for ").Append(Duration(s.End - s.Start)); } Sb.Append('\n'); if (Plugin.ShowWind.Value && s.Env != null) { Sb.Append(" Wind: <color=").Append("orange").Append('>') .Append(WindWord(s.WindIntensity)) .Append(", from the ") .Append(Compass(s.WindFrom)) .Append("</color>\n"); } } internal static string Name(EnvSetup env) { if (env == null) { return "Unknown"; } if (Names.TryGetValue(env.m_name, out var value)) { return value; } return Tidy(env.m_name); } private static string Tidy(string raw) { StringBuilder stringBuilder = new StringBuilder(); for (int i = 0; i < raw.Length; i++) { char c = raw[i]; if (c == '_' || c == '-') { c = ' '; } else if (char.IsUpper(c) && i > 0 && char.IsLower(raw[i - 1])) { stringBuilder.Append(' '); } stringBuilder.Append((stringBuilder.Length == 0) ? char.ToUpperInvariant(c) : char.ToLowerInvariant(c)); } return stringBuilder.ToString().Replace(" ", " ").Trim(); } private static string Remark(ForecastResult f) { if (f.Overridden) { return "This sky isn't the weather's doing. Odin won't guess."; } if (f.NeverChanges) { return "Same sky as always. Settle in."; } Spell spell = ((f.Upcoming.Count > 0) ? f.Upcoming[0] : f.Current); string[] array = Remarks[KindOf(spell.Env)]; int num = (int)(Math.Abs((long)spell.Start) / 60 % array.Length); return array[num]; } private static Kind KindOf(EnvSetup env) { if (env == null) { return Kind.Clear; } string text = env.m_name.ToLowerInvariant(); if (text.Contains("ash") || text.Contains("cinder")) { return Kind.Ash; } if (text.Contains("storm") || text.Contains("thunder")) { return Kind.Storm; } if (text.Contains("snow") || env.m_isFreezing) { return Kind.Snow; } if (text.Contains("rain") || env.m_isWet) { return Kind.Rain; } if (text.Contains("mist") || text.Contains("fog")) { return Kind.Mist; } if (text.Contains("dark") || env.m_alwaysDark) { return Kind.Gloom; } return Kind.Clear; } internal static string Duration(double seconds) { if (seconds < 60.0) { return "under a minute"; } int num = Mathf.RoundToInt((float)(seconds / 60.0)); if (num < 60) { return $"{num} min"; } if (num % 60 != 0) { return $"{num / 60} h {num % 60} min"; } return $"{num / 60} h"; } private static string WindWord(float intensity) { if (intensity < 0.2f) { return "calm"; } if (intensity < 0.4f) { return "light"; } if (intensity < 0.6f) { return "fresh"; } if (intensity < 0.8f) { return "strong"; } return "gale"; } private static string Compass(float bearing) { return Points[Mathf.RoundToInt(bearing / 45f) % 8]; } } internal class ForecastTooltip : MonoBehaviour { private const float RefreshInterval = 0.5f; private GameObject _tooltip; private RectTransform _panel; private TMP_Text _topic; private TMP_Text _text; private readonly Vector3[] _corners = (Vector3[])(object)new Vector3[4]; private CanvasGroup _group; private float _shownAt; private float _fadeOutStart = -1f; private float _fadeOutLength; private float _nextRefresh; private void LateUpdate() { bool num = CanShow(); if (num && ShowKeyDown()) { if (IsOpen() && !IsFading()) { Close(); } else { Open(); } } if (!num || !IsOpen()) { Hide(); } else { if ((Object)(object)_tooltip == (Object)null && !CreateTooltip()) { return; } if (Time.time >= _nextRefresh) { _nextRefresh = Time.time + 0.5f; ForecastResult forecastResult = Forecast.Compute(); if (forecastResult == null) { Hide(); return; } _topic.text = ForecastText.Title(forecastResult); _text.text = ForecastText.Body(forecastResult); LayoutRebuilder.ForceRebuildLayoutImmediate(_panel); } if (!_tooltip.activeSelf) { _tooltip.SetActive(true); _tooltip.transform.SetAsLastSibling(); } _group.alpha = Alpha(); Place(); } } private void OnDestroy() { if ((Object)(object)_tooltip != (Object)null) { Object.Destroy((Object)(object)_tooltip); } } private bool IsOpen() { return Time.time < _fadeOutStart + _fadeOutLength; } private bool IsFading() { return Time.time >= _fadeOutStart; } private void Open() { float num = (IsOpen() ? Alpha() : 0f); _shownAt = Time.time - num * Plugin.FadeInSeconds.Value; _fadeOutStart = Time.time + Plugin.ShowSeconds.Value; _fadeOutLength = Plugin.FadeOutSeconds.Value; _nextRefresh = 0f; } private void Close() { _fadeOutStart = Time.time; _fadeOutLength = Plugin.FadeInSeconds.Value; } private float Alpha() { float value = Plugin.FadeInSeconds.Value; float num = ((value > 0f) ? Mathf.Clamp01((Time.time - _shownAt) / value) : 1f); float num2 = ((_fadeOutLength > 0f) ? Mathf.Clamp01((Time.time - _fadeOutStart) / _fadeOutLength) : (IsFading() ? 1f : 0f)); return num * (1f - num2); } private static bool CanShow() { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsDead() || !HudVisible()) { return false; } if (!InventoryGui.IsVisible() && !Menu.IsVisible() && !Minimap.IsOpen() && !TextInput.IsVisible() && !Console.IsVisible()) { if ((Object)(object)Chat.instance != (Object)null) { return !Chat.instance.HasFocus(); } return true; } return false; } private static bool HudVisible() { if ((Object)(object)Hud.instance != (Object)null && !Hud.IsUserHidden()) { return Hud.instance.IsVisible(); } return false; } private static bool ShowKeyDown() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) KeyboardShortcut value = Plugin.ShowKey.Value; if ((int)((KeyboardShortcut)(ref value)).MainKey == 0 || !ZInput.GetKeyDown(((KeyboardShortcut)(ref value)).MainKey, false)) { return false; } foreach (KeyCode modifier in ((KeyboardShortcut)(ref value)).Modifiers) { if (!ZInput.GetKey(modifier, false)) { return false; } } return true; } private void Place() { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0035: 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_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0072: 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) //IL_007c: 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) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(Plugin.PositionX.Value * (float)Screen.width, Plugin.PositionY.Value * (float)Screen.height); _tooltip.transform.position = Vector2.op_Implicit(val); _panel.GetWorldCorners(_corners); Vector2 val2 = Vector2.op_Implicit((_corners[0] + _corners[2]) / 2f); Transform transform = _tooltip.transform; transform.position += Vector2.op_Implicit(val - val2); Utils.ClampUIToScreen(_panel); } private bool CreateTooltip() { GameObject val = FindTooltipPrefab(); if ((Object)(object)val == (Object)null) { return false; } Canvas componentInParent = ((Component)InventoryGui.instance).GetComponentInParent<Canvas>(); Canvas val2 = ((componentInParent != null) ? componentInParent.rootCanvas : null); if ((Object)(object)val2 == (Object)null) { return false; } _tooltip = Object.Instantiate<GameObject>(val, ((Component)val2).transform); ((Object)_tooltip).name = "OdinsAlmanac"; ref RectTransform panel = ref _panel; Transform child = _tooltip.transform.GetChild(0); panel = (RectTransform)(object)((child is RectTransform) ? child : null); Transform obj = Utils.FindChild(_tooltip.transform, "Topic", (IterativeSearchType)0); _topic = ((obj != null) ? ((Component)obj).GetComponent<TMP_Text>() : null); Transform obj2 = Utils.FindChild(_tooltip.transform, "Text", (IterativeSearchType)0); _text = ((obj2 != null) ? ((Component)obj2).GetComponent<TMP_Text>() : null); if ((Object)(object)_panel == (Object)null || (Object)(object)_topic == (Object)null || (Object)(object)_text == (Object)null) { Object.Destroy((Object)(object)_tooltip); _tooltip = null; return false; } Graphic[] componentsInChildren = _tooltip.GetComponentsInChildren<Graphic>(true); for (int i = 0; i < componentsInChildren.Length; i++) { componentsInChildren[i].raycastTarget = false; } _group = _tooltip.GetComponent<CanvasGroup>(); if ((Object)(object)_group == (Object)null) { _group = _tooltip.AddComponent<CanvasGroup>(); } _group.interactable = false; _group.blocksRaycasts = false; _group.alpha = 0f; return true; } private static GameObject FindTooltipPrefab() { InventoryGui instance = InventoryGui.instance; if ((Object)(object)instance == (Object)null) { return null; } UITooltip val = (((Object)(object)instance.m_playerGrid != (Object)null && (Object)(object)instance.m_playerGrid.m_elementPrefab != (Object)null) ? instance.m_playerGrid.m_elementPrefab.GetComponentInChildren<UITooltip>(true) : null); if ((Object)(object)val != (Object)null && (Object)(object)val.m_tooltipPrefab != (Object)null) { return val.m_tooltipPrefab; } UITooltip[] componentsInChildren = ((Component)instance).GetComponentsInChildren<UITooltip>(true); foreach (UITooltip val2 in componentsInChildren) { if ((Object)(object)val2.m_tooltipPrefab != (Object)null) { return val2.m_tooltipPrefab; } } return null; } private void Hide() { if ((Object)(object)_tooltip != (Object)null && _tooltip.activeSelf) { _tooltip.SetActive(false); } } } [BepInPlugin("hevyh2o.valheim.odinsalmanac", "Odin's Almanac", "0.1.4")] public class Plugin : BaseUnityPlugin { public const string Guid = "hevyh2o.valheim.odinsalmanac"; public const string Name = "Odin's Almanac"; public const string Version = "0.1.4"; internal static ManualLogSource Log; internal static ConfigEntry<KeyboardShortcut> ShowKey; internal static ConfigEntry<float> ShowSeconds; internal static ConfigEntry<float> FadeInSeconds; internal static ConfigEntry<float> FadeOutSeconds; internal static ConfigEntry<float> PositionX; internal static ConfigEntry<float> PositionY; internal static ConfigEntry<int> ForecastCount; internal static ConfigEntry<bool> ShowWind; internal static ConfigEntry<bool> ShowFlavor; private ForecastTooltip _tooltip; private void Awake() { //IL_0022: 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_006e: Expected O, but got Unknown //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Expected O, but got Unknown //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Expected O, but got Unknown //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Expected O, but got Unknown //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Expected O, but got Unknown //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; ShowKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Display", "ShowKey", new KeyboardShortcut((KeyCode)107, Array.Empty<KeyCode>()), "Key that opens the almanac. Press again to close it early, or while it's fading to bring it back."); ShowSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Display", "ShowSeconds", 15f, new ConfigDescription("How long the forecast stays fully visible after pressing ShowKey, before it starts to fade.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 60f), Array.Empty<object>())); FadeInSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Display", "FadeInSeconds", 0.3f, new ConfigDescription("How long the forecast takes to fade in. Also used when closing it with ShowKey. 0 = instant.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2f), Array.Empty<object>())); FadeOutSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Display", "FadeOutSeconds", 5f, new ConfigDescription("How long the forecast takes to fade away once ShowSeconds is up. 0 = vanish at once.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 30f), Array.Empty<object>())); PositionX = ((BaseUnityPlugin)this).Config.Bind<float>("Display", "PositionX", 0.5f, new ConfigDescription("Horizontal position of the forecast, 0 = left edge, 1 = right edge.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>())); PositionY = ((BaseUnityPlugin)this).Config.Bind<float>("Display", "PositionY", 0.72f, new ConfigDescription("Vertical position of the forecast, 0 = bottom, 1 = top.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>())); ForecastCount = ((BaseUnityPlugin)this).Config.Bind<int>("General", "ForecastCount", 2, new ConfigDescription("How many upcoming weather changes to show.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 3), Array.Empty<object>())); ShowWind = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowWind", true, "Show wind strength and direction for each kind of weather."); ShowFlavor = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowFlavor", true, "Show Odin's one-line remark about what's coming."); if (Forecast.Init()) { _tooltip = ((Component)this).gameObject.AddComponent<ForecastTooltip>(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Odin's Almanac 0.1.4 loaded. Odin has licked a finger and held it up."); } } private void OnDestroy() { if ((Object)(object)_tooltip != (Object)null) { Object.Destroy((Object)(object)_tooltip); } } } internal static class BuildInfo { public const string Version = "0.1.4"; } }